Z80 Input/Output
A Z80 has no system calls. Programs reach the outside world with in and out, which address one of 256 ports: out (n), a sends A to port n, in a, (n) reads a byte back. The (c) forms (out (c), r and in r, (c)) take the port number from C,
which lets a program compute it.
The emulator connects the five ports below to the console. Every other port behaves like an
empty bus: writes are dropped and reads answer 0xFF. Reading a connected port
with nothing to read pauses the program until a line has been typed, so in never fails, it only waits.
0x00 Character
Prints the byte as a character (Latin-1). 0x0A prints a newline.
Returns the next character of the input line, pausing for input when the line has been consumed. The line ends with a newline character (0x0A).
.org 0x8000
ld hl, msg
loop: ld a, (hl)
or a
jr z, done
out (0), a
inc hl
jr loop
done: halt
msg: .asciz "Hello!", 10 ; 10 is the newline: strings keep \n literally
0x01 Unsigned number
Prints the byte as an unsigned decimal number, 0 to 255.
Reads a line, parses it as a decimal number and returns its low byte. Stops the program with an error when the line is not a number.
.org 0x8000
in a, (1) ; ask for a number
add a, a ; double it
out (1), a ; print it
halt
0x02 Signed number
Prints the byte as a signed decimal number, -128 to 127.
Same as the unsigned number port.
.org 0x8000
ld a, 5
sub 10
out (2), a
halt
0x03 Hexadecimal
Prints the byte as two upper case hexadecimal digits.
Reads a line, parses it as a hexadecimal number (0x, $ prefix or h suffix accepted) and returns its low byte.
.org 0x8000
ld a, 255
out (3), a
halt
0x04 16 bit number
Prints the 16 bit number made of the high byte of the port address (register B when using out (c),r) and the byte written, as an unsigned decimal number.
Same as the unsigned number port.
.org 0x8000
ld hl, 1000
ld b, h ; high byte goes on the address bus
ld c, 4 ; port number
out (c), l ; prints HL
halt