Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

all in and out instructions are 16-bits #10

Open
janko-jj opened this issue Jul 28, 2024 · 4 comments
Open

all in and out instructions are 16-bits #10

janko-jj opened this issue Jul 28, 2024 · 4 comments
Labels
bug Something isn't working

Comments

@janko-jj
Copy link

janko-jj commented Jul 28, 2024

All in and out instructions are 16-bit:

  1. where ever the "port C" is mentioned it should be "port at the address contained in the BC register pair"

  2. where "port $n" is mentioned it should be a "port at the address formed from the content of A as the higher bits of the address and $n as the lower bits of the address."

Reference:

In the original Z80 documentation: https://www.zilog.com/docs/z80/um0080.pdf the last paragraph on the page 61:

"In 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
."

(emphasis mine)

@deeptoaster deeptoaster added the bug Something isn't working label Sep 4, 2024
@deeptoaster
Copy link
Owner

Page 296 (310 in the PDF) clarifies that

The contents of Register C are placed on the bottom half (A0 through A7) of the address bus to select the I/O device at one of 256 possible ports. The contents of Register B are placed on the top half (A8 through A15) of the address bus at this time.

Similarly on page 295 (309 in the PDF)

The operand n is placed on the bottom half (A0 through A7) of the address bus to select the I/O device at one of 256 possible ports. The contents of the Accumulator also appear on the top half (A8 through A15) of the address bus at this time.
...

Example

Register C contains 07h, Register B contains 10h, and byte 7Bh is available at the peripheral device mapped to I/O port address 07h. Upon the execution of an IN D, (C) command, the D Register contains 7Bh.

And on page 33 (47 in the PDF)

In each case, the port number is provided on the lower eight bits of the address bus during any I/O transaction.

So it sounds like for the actual documented behavior, the port number is indeed only eight bits—it just happens that the address bus is updated with eight high bits as well, which are ignored.

@janko-jj
Copy link
Author

janko-jj commented Sep 5, 2024

Nothing is ignored, it is how actually 16 bit I/O addresses are accessed in the real hardware designs.
If some hardware implementation uses only the lower part of addresses for I/O it's not a property of the CPU but of that specific hardware. The CPU was designed to use all 16 bits of address for I/O and there are such implementations, e.g. ZX Spectrum Next depends on it.

@janko-jj
Copy link
Author

janko-jj commented Sep 5, 2024

The "page 33 (47 in the PDF)" is a kind of simplified and incomplete introductory description, but the precise description of the full 16-bit I/O addressing implemented in CPU does appear later in the text.

@janko-jj
Copy link
Author

janko-jj commented Sep 25, 2024

The summary of the official docs and my comments:

"page 33 (47 in the PDF)" --has indeed "port number is provided on the lower eight bits"

but then:

page 61 Explains that the address bus for these instruction is formed in full 16-bits and how (e.g. A on the upper 8 bits or for BC, "the contents of Register B are transferred to the upper half of the address bus."

Page 295 (309 in the PDF) "The contents of the Accumulator also appear on the top half (A8 through A15) of the address bus at this time."

Page 296 (310 in the PDF) "The contents of Register B are placed on the top half (A8 through A15) of the address bus at this time."

Now, if the word "possible" of the "select the I/O device at one of 256 possible ports" part of some sentences from the manual is confusing, it's clear that the "possible" could not be prescriptive in sense of impossibility of more, as it's clearly explained that the 16-bit address (in total 65536 different addresses when using all bits A15..A0) is generated by the CPU and it is documented how that 16-bit address is formed, for each instruction.

The convention of the manual is, however, that a single byte n which is a part of the in a,(n) or out (n),a instructions is called a "port number". But the whole manual consistently documents that the total number of bits available by the Z80 for the in and out operations is whole 16 bits formed by both B and C or by A and "n" byte for the IN/OUT involving A register.

The reason for this name for "n" from these A-related instructions is that the predecessor of Z80, the Intel 8080 CPU, had only accumulator-based "IN" and "OUT" instructions where 8-bit device addresses were documented. Also, the "undocumented" document written in 1998 http://z80.info/z80undoc3.txt has the following: "2.3.2) I/O Instructions: The I/O instructions use the whole of the address bus, not just the lower 8 bits. So in fact, you can have 65536 I/O ports in a Z80 system (the Spectrum uses this). IN r,(C), OUT (C),r and all the I/O block instructions put the whole of BC on the address bus. IN A,(n) and OUT (n),A put A*256+n on the address bus." That could suggest that maybe Zilog didn't initially document all 16-bits of the address (e.g. as of 1998 when that txt was not written) but reading the official Zilog manual now, the 16-bit addresses for IN and OUT are consistently documented.

So I still claim that your reference should be clear when you describe IN and OUT:

  • where ever the "port C" is mentioned it should be "port at the 16-bit address contained in the BC register pair"

  • where "port $n" is mentioned it should be a "port at the 16-bit address formed from the content of A as the higher bits of the address and $n as the 8 lower bits."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants