In order to avoid undefined behaviour of programs not aware of 80 column mode, the 80 column firmware deliberately doesn't use CH but OURCH. So in order to be fully interoperable, CONIO needs to do the same. This changes introduces that behavior. So far so good.
But the 80 column firmware can also be active in 40 column mode. This scenario is not detectable with reasonable effort. Therefore the behaviour of CONIO in this scenario is _not_ improved. However, this scenario is supposed to be very uncommon - and a recent update to videomode() makes sure to not activate it anymore ourselves.
Notes:
* If a program wants to be 100% sure to not run in 40 column mode with 80 column firmware active it can call videomode(VIDEOMODE_40COL) to explicitly deactivate a potentially active 80 column firmware. However, this always implicitly clears the screen.
* In 40 column mode (contrast to 80 column mode) the 80 column firmware updates CH to reflect OURCH. So as long as CONIO only reads CH, but doesn't update it, everything works as expected. Interestingly this makes a rather useful scenario of STDIO/CONIO interoperation work: Using STDIO for screen output and CONIO for keyboard input. When cgetc() is called after cursor(1), it has to write to the screen as there's no hardware cursor on the Apple II. Those writes work as expected even in 40 column mode with active 80 column firmware as CH is only read but not written.
Certain scenarios (e.g. not running any Applesoft program at all since booting DOS 3.3) can make DOS 3.3 consider cc65 device input (e.g. getchar()) that reads a CR interpreting the command in the keyboard buffer. Setting the hibyte of the Applesoft currently executed line number to some value <> $FF (beside setting the input prompt to some value <> ']') makes DOS 3.3 understand that we're not in intermediate mode and that therefore I/O not preceded with ctrl-d mustn't be fiddled with (see DOS 3.3 routine at $A65E).
The implementation is a bit tricky as it requires to take different code paths for the //e, the //c and the IIgs. Additionally the //c only provides a VBL IRQ flag supposed to be used by an IRQ handler to determine what triggered the IRQ. However, masking IRQs on the CPU, activating the VBL IRQ, clearing any pending VBL IRQs and then polling for the IRQ flag does the trick.
As described e.g. in the Apple IIe Technote #6: 'The Apple II Paddle Circuits' it doesn't work to call PREAD several times in immediate succession. However, so far the Apple II joystick driver did just that in order to read the two joystick axis.
Therefore the driver now uses a custom routine that reads both paddles _at_the_same_time_. The code doing so requires nearly twice the cycles meaning that the overall time for a joy_read() stays roughly the same. However, twice the cycles in the read loop means half the resolution. But for the cc65 joystick driver use case that doesn't hurt at all as the driver is supposed to only detect neutral vs. left/right and up/down.
CPU accelerators are supposed to detect access to $C070 and slow down for some time automatically. However, the IIgs rather comes with a modified ROM routine. Therefore it is necessary to manually slow down the IIgs when replacing the ROM routine.