Retrocomputing Stack Exchange is a question and answer site for vintage-computer hobbyists interested in restoring, preserving, and using the classic computer and gaming systems of yesteryear. Join them; it only takes a minute:

The Apple II uses memory mapped I/O and soft switches to do many things. One thing has confused me though: why are some soft switches only activated when written to?

For example, 80COLON ($C00D) and 80COLOFF ($C00C) turn on/off the 80-column display but these switches have to be written to to trigger. You would think that perhaps reading them would be the way to determine their state, but that is not the case. Instead, that is done by reading 80COL ($C01F).

But then you can look at something like MIXEDOFF and MIXEDON ($C051 and $C052) which turns off the mixed graphics and text (at the bottom) mode. These switches can be triggered by either a a read or a write. Once again, you cannot determine their state by reading them, but rather reading MIXED at $C01B.

I have been under the assumption that soft switches basically work by some special circuitry detecting if their address line is active and then the desired operation will happen. You would think that if a write was required, it would be because of the address lines first getting set up and then letting the R/W signal from the 6502 pulsing to actually trigger the switch. But then why are there some that are R/W and some which are R/O?

The reason why I was recently thinking about this is because of how the 80-column display works. The hardware obviously needs to bank switch for every other column since the even columns are stored in bank 0 and the odd columns are stored in bank 1. What this means is that (I believe) calls to 80STOREON ($C000) and 80STOREOFF ($C001) are hit to bank switch for every other character and then need to be switched back so as not to confuse with the main bank 0 zero page, stack, etc. Of course, with bank switching you also are supposed to disable interrupts and then re-enable them when coming back to the main bank.

All this switching and interrupt handling takes a lot of cycles. When the 6502 does a read, it takes a minimum of 4 cycles. For a write, the processor effectively reads the address first before writing it which ends up taking at least 5 cycles. I started thinking why wouldn't the soft switches be implemented to support "read triggering" instead of the more expensive "write triggering"? Sure, it's a tiny fraction of time being spent for the extra cycle, but why not design it to save that tiny fraction? What would be the reason that they would have designed it only with write-triggered soft switches?

EDIT: while there are potential differences between read/write cycle times, they are identical for LDA/STA Absolute addressing which would have been the mode used for a soft switch anyway. As such, cycle concerns are invalid.

BTW, it's quite common for I/O addresses in all sorts of architectures to have different meanings for read and write. That's because electrically, it's easy to grab the R/W line and hook it up to a gate. Nobody cares about CPU cycles while designing these electronics, what one does care about is gate count.
– dirktNov 21 '17 at 17:39

3

"For a write, the processor effectively reads the address first before writing it which ends up taking at least 5 cycles" -- where did this come from? It's not true.
– JeremyPNov 24 '17 at 10:44

@JeremyP: Common myth from a misunderstanding of Apple's 1979 reference manual: 'Note that a "write" operation on the Apple's 6502 microprocessor actually performs a "read" before the "write"'. Applesoft's POKE uses STA (zp),Y which did 2 accesses on the 6502, but only 1 on the 65C02. More here.
– Nick WestgateMay 29 at 4:11

1 Answer
1

Simply because they have been added later. To be exact with the introduction of the IIe/IIc. Originally all Apple II soft switches (including the Language Card) did work just by address selection. Direction was ignored. Usually writes were used, as they do not destroy any register content. Only the RMW instructions must be avoided, as they trigger the soft switch twice.

When the IIe (and IIc) included additional Hardware, new, prior unused locations were needed. For one, not many were left, thus the trick was to use locations that have, until then, been only used to read data, now in other context with writing. For example, the keyboard at $C000 was a read only resource before on the II/II+. Now writing to $C000 activated 80STOREOFF on the IIe/IIc. Since the signal was already to be included in the select logic to reuse locations like $C000 is was also used for any other new soft switch - as a side effect preserving the ability to use the same locations as readable information in some future II-series machines. Handling soft switches via writes was at the same time made a general recommendation.

So, just always write and you're on the safe side.

The hardware obviously needs to bank switch for every other column since the even columns are stored in bank 0 and the odd columns are stored in bank 1.

The hardware doesn't have to do any switching, as the video circuit has its own address scheme. If at all, a/your program has to do so to access either location.

All this switching and interrupt handling takes a lot of cycles. When the 6502 does a read, it takes a minimum of 4 cycles. For a write, the processor effectively reads the address first before writing it which ends up taking at least 5 cycles.

Mind to explain this in detail. In my text book 6500 reads and writes are equally just one cycle. An LDA $C000 takes exactly 4 cycles, same as a STA $C000 does. Are you mixing this up with RMW operations, like INC, ROL, TSB or alike?

You are correct, LDA/STA absolute 16-bit both take 4 cycles. However, the reference I see at 6502.org states potential differences for AbsoluteX, AbsoluteY and IndirectYzp (however they would be equivalent if a page boundary is crossed on the LDA operations). I suppose the switch would always been an absolute so the cycle time would be the same!
– bjbNov 20 '17 at 20:14

3

Writes that add a register to an address can take a cycle longer than reads because the 6502 can't do 16-bit arithmetic in a single cycle. So there's a cycle where the register has been added to the low byte of the address but any carry that may exist has not yet been applied to the top byte. Read instructions just do the read and, only if that address was wrong, then read again, as reading is considered non-destructive. Writing is considered destructive so for those the 6502 reads for the first access, throws that away, then writes after the full 16-bit result is definite.
– TommyNov 20 '17 at 21:06

1

@Tommy Thats all fine and true. Just this is about accessing Woz' soft switch logic. In all my Apple II years, I never felt the need to use an indexed access. That'll be a total waste of cycles - not to mention that seting up the index would take even more, taint a register (x or y) and require more code. STA ABS of an arbitary value is simply the way Woz had in mind when going that way instead of using values within an addressed location.
– RaffzahnNov 20 '17 at 21:15

2

@Raffzahn my comment explains the phenomena referenced in bjb's comment, and helps to reinforce why he saw that some writes take longer, but not all do. Nothing about my comment is contradicted by yours, nothing in my comment relates to your answer beyond reinforcing disabuse of the idea that writes are always slower.
– TommyNov 20 '17 at 22:15

1

The absolute index and indirect indexed address modes of the 6502 will cause it to compute the low byte of the required address while reading the high byte. On the cycle following the read of the high byte, the CPU will read the address formed by concatenating that byte with the computed low byte while it computes the value (fetched_MSB+1) and also determines if the value it's reading will be usable. If the value is not usable, the CPU will then perform the required access using either the fetched or computed MSB along with the computed LSB. Compared with other CPUs, the 6502 doesn't...
– supercatNov 20 '17 at 22:19