Port addresses for interfaces and peripherals
Microprocessor Z80 normally has 256 addresses in Input-Output map. But as usual, by Spectrum is situation different. E.g. Spectrum by keyboard scan uses all 16 address bits by IN instruction, this could give theoretical 65536 port addresses. However usage of upper 8 address bits is very limited by IN/OUT operations. Content of those bits may be controlled by simple port instructions like : LD A,N ; IN A,(port) - in this sequence upper 8 address bits by IN operation will take value N. Similar is if register C is used - see some literature about Z80. By most interesting instructions like INI, OUTI, INIR etc. upper 8 address bits take value of B register, which is used as loop counter - so value always changes, therefore usage of those bits is not recommended for e.g. disk interfaces and similar.
So, we have lower 8
bits, what should be enough
for lot of peripherals. Situation is unfortunately not so good.
It's well known that ULA's port address is #FE or 254. But if you
try e.g. IN 4 or IN 222 you will get same result. Sinclair and
other peripheral designers have been used incomplete decoding
logics for peripheral selection. Condition for select ULA chip is
only that A0=low, other bits are not considered. Any port address
where A0=0 e.g. #00, #F4 etc. will select ULA. This means that
ULA's I/O address is actually 1 bit long. Why everybody uses
address #FE ? Because other peripherals like ZX printer, joystick
interfaces use same primitive address decoding system. Address
in this situation must have only one bit low, bit of peripheral
what is selected. So we have practically only 8 port addresses.
But situation is even worse: by Kempston joystick is from for me
total ununderstable reason wasted even 3 bit for addressing. Port
address is #1F, so bits 5-7 are low. This is by most of games,
although every schematic for Kempston compatible interface build
has only condition that bit 5 is low for port selection, and
address should be #DF.
Note that, that all ROM routines uses always address #FE for ULA access - this is because Sinclair planned other peripherals with same address decoding logic - only one address bit low selects port.
I used this system too by floppy interface, bit 3=0 selects FDC chip. By hard disk interface I used full decoding thanks to appearance of GALs.
Here is table of used bits by must popular peripherals and 128K models:
|Used by:||Kempston-soft||Kempston-soft||Kempston-hard||128 paging||ULA|
I didn't include port
addresses of interface
1, I don't know whether decoding it uses. But I included here
port addressing bit of 128K models (other bit is A15!), because
good peripheral should work with 128K Spectrums too.
Well, we have only 3 bits left - this gives only 3 peripherals if we using incomplete address decoding. By 'full' decoding is situation much better, we could using even more than 8 address, since we may using bits 6 and 7 too. Today fortunately we have GALs, what allows easy realization of full decoding.
Other limiting factor is that, that by some peripherals like IDE hard disks we have not only one address, but 8 addresses - this requires 3 address lines more. Fortunately we may use here lines A6 and A7 too.