One of the benefits to hacking on the old Commodore 64 is that the user port exposes quite a few bidirectional IO pins which can be easily programmed from BASIC. The Amstrad CPC doesn't really have these in the same fashion. Well, ok, it does - if you count the joystick pins as "input" and the printer port pins as "output". But having a fully programmable IO controller is helpful.
So I breadboarded a basic IO board a couple months ago using an 8255 PIO and some TTL logic to handle address decoding. This worked fine on the Amstrad CPC464 but it didn't work on the CPC6128. A bit of digging into the method used for address decoding showed what I did wrong.
The Amstrad CPC base peripheral IO list can be found here. The peripheral IO is decoded by the high 8 bits of the address bus - each peripheral attaches an address line (and /IORQ) to the relevant chip /CS line. The expansion peripheral line is A10, and the "selection" decoding lines are A9 and A8. So, A10 needs to be low, and A8+A9 let you either address multiple peripherals or the registers inside the peripheral itself.
This was easy - a bit of logic to say /CS = low IFF /IORQ is low and A10 is high.
This is fine on an unexpanded CPC464 but the CPC6128 floppy disk controller decodes A10 low, A8 low AND A7 low. A7 is the "FDD peripheral expansion" line. So my 8255 PPI board was being accessed the same time that the FDD controller was. This caused all kinds of random lights to blink and the system to get highly confused.
The logic now is /CS = low IFF /IORQ is low, A10 is high and A7 is high.
Strictly speaking, I should ensure that A7-A4 are 1110 - ie, A4 is low, the rest are high.
According to the CPC464 manual, when A10 is low, A4 low is "user", A5 low is "RS232" (for the Amstrad/PACE RS232 adaptor), A6 low is "future", and A7 low is "disk".