CPCWiki forum

General Category => Programming => Topic started by: Bread80 on 15:47, 30 September 24

Title: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: Bread80 on 15:47, 30 September 24
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/
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: andycadley on 15:59, 30 September 24
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.
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: roudoudou on 16:16, 30 September 24
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
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: lightforce6128 on 16:31, 30 September 24
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.
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: roudoudou on 18:09, 30 September 24
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
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: m_dr_m on 20:31, 30 September 24
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.  
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: Prodatron on 20:59, 30 September 24
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.
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: McArti0 on 08:03, 01 October 24
Does anyone know what it looked like when CPC had 6502?
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: robcfg on 08:24, 01 October 24
https://www.cpcwiki.eu/index.php/Mainboard_Versions#CPC464_version_0_Prototype  ;D
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: McArti0 on 09:20, 01 October 24
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


Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: Bread80 on 12:04, 01 October 24
Quote from: roudoudou on 16:16, 30 September 24not OUT (C),B

Thank you, fixed now.
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: GUNHED on 12:44, 01 October 24
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. 
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: Bread80 on 12:47, 01 October 24
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...
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: GUNHED on 12:52, 01 October 24
Quote from: Bread80 on 12:47, 01 October 24
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...
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...)
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: Bread80 on 12:53, 01 October 24
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.
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: Bread80 on 13:24, 01 October 24
I've removed the article so I can take on board the feedback and rework it.
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: McArti0 on 13:40, 01 October 24
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.

Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: McArti0 on 13:43, 01 October 24
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.
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: Prodatron on 13:57, 01 October 24
Quote from: Bread80 on 12:53, 01 October 24
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".
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 24
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.
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!)
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: McArti0 on 14:29, 01 October 24

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.
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: andycadley on 14:38, 01 October 24
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.
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: McArti0 on 14:55, 01 October 24
Read I/O used one register only. 
LD A,#BF
IN A, (n)

n - can be used as a variable yet.
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: Prodatron on 16:10, 01 October 24
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.
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: McArti0 on 18:46, 01 October 24
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 8085A



OUT 0-255

About 8080, page 68 (4-4)
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: Prodatron on 20:09, 01 October 24
Quote from: McArti0 on 18:46, 01 October 24
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 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?
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: McArti0 on 21:03, 01 October 24
https://dn790009.ca.archive.org/0/items/Zilog_Z80-CPU_Technical_Manual/Zilog_Z80-CPU_Technical_Manual.pdf

page 35 manual 1976
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: McArti0 on 21:12, 01 October 24
page 54

opcode list

B-> A8-A15

in 1976.
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: McArti0 on 06:08, 02 October 24
Quote from: Prodatron on 20:09, 01 October 24
Quote from: McArti0 on 18:46, 01 October 24
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 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 24
Quote from: McArti0 on 18:46, 01 October 24
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 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.
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: GUNHED on 13:50, 02 October 24
Quote from: Bread80 on 12:53, 01 October 24
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".
Don't thrust these guys, they discontinued producing the chip  ;)
Title: Re: The Genius of Amstrad I/O Addresses (Blog Article)
Post by: pelrun on 07:29, 03 October 24
"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"
Powered by SMFPacks Menu Editor Mod