For exactly this range of addresses, $9010..$901F, the logic inside the VIC-20 will not only select the VIC chip, but also VIA #1.

Generally, using mirrors instead of the standard base addresses of the I/O chips is not a good idea. Of course the hardware of the VIC-20 is fixed nowadays, in principle, but that doesn't mean some people wouldn't like to extend the I/O register area with new peripheral chips. Those extensions then will most probably turn addresses, which were mirrors of the "old" I/O chips into register addresses of the new chips. Then, your program using a mirror address produces an unnecessary incompatibility, and won't work with the extended hardware.

(This is not a purely academic argument: there were programs on the C64, that didn't anymore produce sound on the C128, when the mirrors of the SID chip at $D400 (which were at $D500, $D600, $D700) disappeared, due to finer address decoding for the MMU and VDC. Even though the MMU deselected itself in C64 mode, the address decoding remained - and you could even use VDC in C64 mode, but that's another story).

There is no rule without exception: when you access the standard I/O registers of VIA #1 and VIA #2, you are actually also using mirrors. This time however, that usage was explicitly sanctioned by Commodore themselves: the base addresses are given as $9110 and $9120 in the Programmer's Reference Manual, but this went as follows:

- VIC selects in the whole range $9000 .. $90FF,- VIA #1 selects in the range $9000..$93FF, when also bit 4 of the address is set, and- VIA #2 also selects in the range $9000..$93FF, when bit 5 of the address is set.

That means, in the range $9000..$90FF, you can access VIC on its own at $9000 (and at some other addresses), but the "original" base addresses of VIA #1 and #2 (at $9010 and $9020) are unusable, as they overlap with VIC. The first usable mirrors of those registers *are* at $9110 and $9120, and that's the reason they are used.

Writes to addresses, where two or three of the chips "collide" will write the value into all the registers involved (so you inevitably "shot" some register contents in VIA #1 during your attempts), and when read, the chips throw the register values on the data bus simultaneously, allowing for all funny results (most probably, a wired-AND of the values because of the NMOS logic involved). Neither are effects you'd want to use in non-experimental code.

so you inevitably "shot" some register contents in VIA #1 during your attempts

I had no idea .

Generally, using mirrors instead of the standard base addresses of the I/O chips is not a good idea. Of course the hardware of the VIC-20 is fixed nowadays, in principle, but that doesn't mean some people wouldn't like to extend the I/O register area with new peripheral chips. Those extensions then will most probably turn addresses, which were mirrors of the "old" I/O chips into register addresses of the new chips. Then, your program using a mirror address produces an unnecessary incompatibility, and won't work with the extended hardware.

(This is not a purely academic argument: there were programs on the C64, that didn't anymore produce sound on the C128, when the mirrors of the SID chip at $D400 (which were at $D500, $D600, $D700) disappeared, due to finer address decoding for the MMU and VDC. Even though the MMU deselected itself in C64 mode, the address decoding remained - and you could even use VDC in C64 mode, but that's another story).

Absolutely good reasons not to use those mirrors. With all the new hardware projects coming out, plus any projects I might potentially want to do with my VIC in the future, it would be best to leave those non-standard locations alone.

I got a little carried away decoding that area. It could've been done much simpler, but I was planning ahead, in case I might think of other items to put in that area. (I have, but that discussion would be more suited to the Hardware subforum.) Anyway, it seemed a waste to have the VIAs take up 768 locations, with gaps. I reduced the VIAs' occupancy to 64 locations (with gaps), and creating 6x32 addresses for more I/O, plus 512 bytes of RAM tucked away in I/O space.

Recently, I got someone who knows how to program a GAL to replace the two ICs and diode logic I used. Should make things much much neater -- and be a little more versatile -- when I get around to installing it.