The Z80 has 8 bit I/O addresses. The Amstrad CPC uses 16-bit I/O address. This breaks the Z80 (well, parts of it). Why did they do that?
Some say it was to save money. But they could have made the same cost savings while still using 8-bit I/O.
I dig deeper to find the real reason the Amstrad's I/O works the way it does: https://bread80.com/2024/09/30/the-genius-of-amstrad-i-o-addresses/
It's such a common design choice on Z80 systems that it makes you wonder what Zilog were thinking when they invented some of the block I/O instructions. Sure nothing was likely to ever need 65536 IO devices, but nobody really wanted to do full address decoding either.
Quote from: Bread80 on 15:47, 30 September 24The Z80 has 8 bit I/O addresses. The Amstrad CPC uses 16-bit I/O address. This breaks the Z80 (well, parts of it). Why did they do that?
Some say it was to save money. But they could have made the same cost savings while still using 8-bit I/O.
I dig deeper to find the real reason the Amstrad's I/O works the way it does: https://bread80.com/2024/09/30/the-genius-of-amstrad-i-o-addresses/
found a typo in the article
to adress a setting to the gate array, you use
LD B,#7F
LD C,settings
OUT (C),C
not OUT (C),B
I'm not sure if I understand the main argument:
QuoteWhile the OUT (C),C instruction puts the full 16-bits of the BC register pair on the address bus it can only put the eight bits of the C register on the data bus. If the usage of the B and C registers where swapped the gate array's data bus would only 'see' the I/O port address in the C register with no way to read the settings data.
If the usage of the B and C registers were swapped, instead of command 'OUT (C),C' the command 'OUT (C),B' needs to be used.
Quote from: lightforce6128 on 16:31, 30 September 24I'm not sure if I understand the main argument:
QuoteWhile the OUT (C),C instruction puts the full 16-bits of the BC register pair on the address bus it can only put the eight bits of the C register on the data bus. If the usage of the B and C registers where swapped the gate array's data bus would only 'see' the I/O port address in the C register with no way to read the settings data.
If the usage of the B and C registers were swapped, instead of command 'OUT (C),C' the command 'OUT (C),B' needs to be used.
the swap if for IO address, not data
I'm not convinced by the argument either.
* The gate array see the data bus, whetever register or memory (OUTI) was used.
* With only the LSB (C) decoded, and B used for the value, you would get the same software benefits, without sacrificing the block I/O.
I haven't seen all interviews from Amstrad engineers, I still suspect cheapness and/or laziness.
Quote from: Bread80 on 15:47, 30 September 24The Z80 has 8 bit I/O addresses. The Amstrad CPC uses 16-bit I/O address. This breaks the Z80 (well, parts of it). Why did they do that?
Some say it was to save money. But they could have made the same cost savings while still using 8-bit I/O.
I dig deeper to find the real reason the Amstrad's I/O works the way it does: https://bread80.com/2024/09/30/the-genius-of-amstrad-i-o-addresses/
It is totally wrong, that the Z80 only had 8 bit I/O addresses. Sounds like click-bait :P
The Z80 has 16bit I/O, not only in the Amstrad. So the CPC did not break something. It just uses the full 16bit to keep the decoding as cheap as possible.
The only "break" is, that you can't use OUT (n),A and the OTIR/INIR commands any more.
Systems like the MSX, the PCW and the Enterprise are using the lower 8bit only to keep the old 8080 way and possibilities.
But they can still use the upper 8bit as well, if they like, so full 16bit! That has nothing to do with "breaking". It was just a decision not to use it probably because of the limitations you would have when using full 16bit.
The ZX Spectrum is using a very crazy mixture of both 8 and 16bits, which makes both possible - use 8bit I/O including OUT (n),A/OTIR/INIR but also using an extended 16bit range.
The advantage of using the full 16bit is obvious: E.g. the CPC can map the full MSX port range into one single "slot" at #FFxx using the AMSDAP, while keeping all its other ports without collisions.
Does anyone know what it looked like when CPC had 6502?
https://www.cpcwiki.eu/index.php/Mainboard_Versions#CPC464_version_0_Prototype ;D
Quote@Bread80
Instead of connecting the gate array's data pins to the data bus they could have connected them to address lines A8 to A15.
How brilliantly OUT (n),A works then. :o
n - addres, A -data goes to A8-15
And you can throw 244, and only add 8 new inputs to GA :picard: ;D
Actually I'm glad the CPC uses 16 bit I/O. It just provides way more I/O addresses compared to 256 only. And right today, way more than 256 I/O addresses are used anyway.
Quote from: lightforce6128 on 16:31, 30 September 24If the usage of the B and C registers were swapped, instead of command 'OUT (C),C' the command 'OUT (C),B' needs to be used.
That's a good point. I'll have a rethink...
Quote from: Bread80 on 12:47, 01 October 24Quote from: lightforce6128 on 16:31, 30 September 24If the usage of the B and C registers were swapped, instead of command 'OUT (C),C' the command 'OUT (C),B' needs to be used.
That's a good point. I'll have a rethink...
And on the other hand block I/O can't be used. But constructions like
INC B:INI
can do the same (and also allow to check for certain conditions).
EDIT: Some OUT (n),A can be used (see SF2 programming, few other expansions...)
Quote from: Prodatron on 20:59, 30 September 24It is totally wrong, that the Z80 only had 8 bit I/O addresses. Sounds like click-bait :P
Zilog disagrees: "I/O device at one of 256 possible ports".
Quote from: Prodatron on 20:59, 30 September 24The only "break" is, that you can't use OUT (n),A and the OTIR/INIR commands any more.
If the design makes instructions unusable then they've broken functionality of the Z80.
I've removed the article so I can take on board the feedback and rework it.
Quote from: Bread80 on 12:53, 01 October 24If the design makes instructions unusable then they've broken functionality of the Z80.
... broken functionality of the CPC.
Z80 not documented in assembler OUT(BC),r. OUT (An),A OUT (nA), n... etc.
LD bc,#bc0d
OUT (c),c
LD bc,#bfff
OUT (c),c
JR -4
This code may corrupt CRTC or Z80. What happens after a week of running this code? I wouldn't be able to sleep during this experiment.
The same can be done between AY and 8255.
Quote from: Bread80 on 13:24, 01 October 24I've removed the article so I can take on board the feedback and rework it.
No, its very good topic.
Quote from: Bread80 on 12:53, 01 October 24Quote from: Prodatron on 20:59, 30 September 24It is totally wrong, that the Z80 only had 8 bit I/O addresses. Sounds like click-bait :P
Zilog disagrees: "I/O device at one of 256 possible ports".
Zilog also did not mention that you can (nearly) fully use IXH,IXL,IYH,IYL :D
But it is a fact that the Z80 puts B on the upper 8 bits of the address bus for I/O (and A for IN/OUT (n) ).
See here from the
official Zilog documentation:
https://www.zilog.com/docs/z80/um0080.pdf
QuoteIn the IN A and OUT n, A instructions, the I/O device's n address appears in the lower half
of the address bus (A7–A0), while the Accumulator content is transferred in the upper half
of the address bus. In all Register Indirect input output instructions, including block I/O
transfers, the contents of the C Register are transferred to the lower half of the address bus
(device address) while the contents of Register B are transferred to the upper half of the
address bus.
This clearly describes the 16bit I/O possibilities of the Z80.
That does not only work on the CPC, but on the MSX, PCW, Enterprise, etc. you can use 16bit I/O as well, the 16bit address bus is there anyway (but they usually don't do that on those systems).
Quote from: Bread80 on 12:53, 01 October 24Quote from: Prodatron on 20:59, 30 September 24The only "break" is, that you can't use OUT (n),A and the OTIR/INIR commands any more.
If the design makes instructions unusable then they've broken functionality of the Z80.
Ok, somehow that is true for these 5 instructions ( INIR, INDR, OTIR, OTDR, OUT(n),A ). However you can still use unrolled block-IO instructions with 16bit I/O, so you are not sooo much broken :) (I agree to McArti, it's a good topic!)
Quote from: Prodatron on 13:57, 01 October 24This clearly describes the 16bit I/O possibilities of the Z80.
I see it as a warning about what's on the A8-A15 lines, because I might think Lo or Hi or 3-state.
I believe that the 'I' register is important in mode 2 interrupts, but I don't believe that during the refresh 'I' on lines A8-A15 it is some kind of deliberate design. This is a consequence of the fact that the z80 has registers in pairs.
I think the 16-bit address on the bus during IO might not have been initially documented, but was added to later revisions as so many people relied upon it and so Zilog just made it official (including retaining it on later CPU models). I suspect that by the time the CPC was designed, it was a documented "feature" although I don't have a source for when it was done.
Quote from: Bread80 on 12:53, 01 October 24If the design makes instructions unusable then they've broken functionality of the Z80.
You can use them, you just have to be aware of the nuance that the countdown of the the value in B affects the port number.
Quote from: Bread80 on 13:24, 01 October 24I've removed the article so I can take on board the feedback and rework it.
Nah, keep it up. There might be one or two little details that can be refined but overall it's still a good bit of documentation.
Read I/O used one register only.
LD A,#BF
IN A, (n)
n - can be used as a variable yet.
Quote from: andycadley on 14:38, 01 October 24I think the 16-bit address on the bus during IO might not have been initially documented, but was added to later revisions as so many people relied upon it and so Zilog just made it official
So maybe for OUT(C),r they reused some logic/microcode from LD (BC),A , so it was more an accident, that the B register is put to the upper 8 address bits?
I couldn't find a hint how the 8080 handles IN/OUT (n). The documentations I found didn't mention, that A is used for the upper 8bits.
If the upper 8bits are just random on a 8080, and only Zilog introduced this for the Z80, then they seem to have it in mind to provide 16bit I/O support.
QuoteNote that the I/O port address is duplicated onto both AD0-AD7 and A8-A15
http://www.bitsavers.org/components/intel/MCS80/MCS80_85_Users_Manual_Jan83.pdf page 35 (2-12)
About 8085AOUT 0-255
About
8080, page 68 (4-4)
Quote from: McArti0 on 18:46, 01 October 24QuoteNote that the I/O port address is duplicated onto both AD0-AD7 and A8-A15
http://www.bitsavers.org/components/intel/MCS80/MCS80_85_Users_Manual_Jan83.pdf page 35 (2-12) About 8085A
OUT 0-255
About 8080, page 68 (4-4)
So only the Z80 was able to handle 16bits? Not even the 8085 in a useful way?
https://dn790009.ca.archive.org/0/items/Zilog_Z80-CPU_Technical_Manual/Zilog_Z80-CPU_Technical_Manual.pdf
page 35 manual 1976
page 54
opcode list
B-> A8-A15
in 1976.
Quote from: Prodatron on 20:09, 01 October 24Quote from: McArti0 on 18:46, 01 October 24QuoteNote that the I/O port address is duplicated onto both AD0-AD7 and A8-A15
http://www.bitsavers.org/components/intel/MCS80/MCS80_85_Users_Manual_Jan83.pdf page 35 (2-12) About 8085A
OUT 0-255
About 8080, page 68 (4-4)
So only the Z80 was able to handle 16bits? Not even the 8085 in a useful way?
Quote from: Prodatron on 20:09, 01 October 24Quote from: McArti0 on 18:46, 01 October 24QuoteNote that the I/O port address is duplicated onto both AD0-AD7 and A8-A15
http://www.bitsavers.org/components/intel/MCS80/MCS80_85_Users_Manual_Jan83.pdf page 35 (2-12) About 8085A
OUT 0-255
About 8080, page 68 (4-4)
So only the Z80 was able to handle 16bits? Not even the 8085 in a useful way?
8085 can be justified, because it has a data bus multiplexed with addresses. AD0-AD7. Copy A0-A7 to A8-A15 allowed easy use of IO with disentangled addresses from data. So I guess everyone used 8085 IO from A8-A15.
Quote from: Bread80 on 12:53, 01 October 24Quote from: Prodatron on 20:59, 30 September 24It is totally wrong, that the Z80 only had 8 bit I/O addresses. Sounds like click-bait :P
Zilog disagrees: "I/O device at one of 256 possible ports".
Don't thrust these guys, they discontinued producing the chip ;)
"hey, the high byte is hooked up for IO but if we just say that the market will decide we're not actually 8080 compatible... put the truth later in the datasheet since the managers won't read that far"