Z80 Input/Output
Ports
Console
0x10 - 0x14Character
port 0x10- In
- 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). Once the program has touched a Screen, Keyboard or Mouse port the characters come from the focused Screen instead, one keystroke at a time, and are echoed at the text cursor.
- Out
- Prints the byte as a character (Latin-1) and draws it at the Screen’s text cursor. 0x0A prints a newline.
.org 0x8000
ld hl, msg
loop: ld a, (hl)
or a
jr z, done
out (0x10), a
inc hl
jr loop
done: halt
msg: .asciz "Hello!", 10 ; 10 is the newline: strings keep \n literally- prints
Hello!
Unsigned number
port 0x11- In
- 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.
- Out
- Prints the byte as an unsigned decimal number, 0 to 255.
.org 0x8000
in a, (0x11) ; ask for a number
add a, a ; double it
out (0x11), a ; print it
halt- input
21- prints
42
Signed number
port 0x12- In
- Same as the unsigned number port.
- Out
- Prints the byte as a signed decimal number, -128 to 127.
.org 0x8000
ld a, 5
sub 10
out (0x12), a
halt- prints
-5
Hexadecimal
port 0x13- In
- Reads a line, parses it as a hexadecimal number (
0x,$prefix orhsuffix accepted) and returns its low byte. - Out
- Prints the byte as two upper case hexadecimal digits.
.org 0x8000
ld a, 255
out (0x13), a
halt- prints
FF
16 bit number
port 0x14- In
- Same as the unsigned number port.
- Out
- 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.
.org 0x8000
ld hl, 1000
ld b, h ; high byte goes on the address bus
ld c, 0x14 ; port number
out (c), l ; prints HL
halt- prints
1000
Screen
0x20 - 0x2AScreen commands
Pixel
command 0Line
command 1Line to
command 2Move to
command 3Rectangle
command 4Rectangle outline
command 5Ellipse
command 6Ellipse outline
command 7Flood fill
command 8Clear
command 9Resize
command 10Buffering on
command 11Buffering off
command 12Present
command 13Mode cells
command 14Mode drawing
command 15The TRS-80 display
Colors
- black
0x00 - blue
0x03 - green
0x1C - cyan
0x1F - red
0xE0 - magenta
0xE3 - yellow
0xFC - white
0xFF - orange
0xF0 - gray
0x92 - dark gray
0x49
Pen color
port 0x20- In
- The current pen color, back in 3-3-2.
- Out
- Sets the color of pixels, lines, outlines and text, as one 3-3-2 byte (
RRRGGGBB).
.org 0x8000
ld a, 0xE0 ; 111 000 00: pure red
out (0x20), a ; pen color
ld a, 100
out (0x23), a ; X
ld a, 50
out (0x24), a ; Y
xor a ; command 0: pixel
out (0x27), a
halt- shows
- one red pixel at (100, 50).
Fill color
port 0x21- In
- The current fill color, back in 3-3-2.
- Out
- Sets the color the inside of a filled shape, a flood fill and a clear use, as one 3-3-2 byte.
.org 0x8000
ld a, 0x1C ; 000 111 00: pure green
out (0x21), a ; fill color
ld a, 0xFF
out (0x20), a ; white pen for the outline
ld a, 20
out (0x23), a
out (0x24), a ; from (20, 20)
ld a, 80
out (0x25), a
out (0x26), a ; to (80, 80), right and bottom excluded
ld a, 4 ; command 4: filled rectangle
out (0x27), a
halt- shows
- a green square with a white outline, 60 by 60 pixels, at (20, 20).
Pen width
port 0x22- In
- The current pen width.
- Out
- Sets how many pixels wide lines and outlines are, at least 1. A width of 0 is read as 1.
.org 0x8000
ld a, 5
out (0x22), a ; five pixels wide
ld a, 10
out (0x23), a
out (0x24), a ; from (10, 10)
ld a, 200
out (0x25), a
ld a, 150
out (0x26), a ; to (200, 150)
ld a, 1 ; command 1: line
out (0x27), a
halt- shows
- a thick white diagonal line across the Screen.
X
port 0x23- In
- The byte last written.
- Out
- The first X coordinate: the pixel, the start of a line, the left edge of a shape, the width of a resize.
.org 0x8000
ld a, 128
out (0x23), a
ld a, 96
out (0x24), a ; (128, 96), the middle of the default Screen
ld a, 3 ; command 3: move to
out (0x27), a
ld a, 200
out (0x23), a
ld a, 20
out (0x24), a
ld a, 2 ; command 2: line to
out (0x27), a
halt- shows
- a line from the middle of the Screen to (200, 20).
Y
port 0x24- In
- The byte last written.
- Out
- The first Y coordinate, the companion of the X port, and the height of a resize.
X2
port 0x25- In
- The byte last written.
- Out
- The second X coordinate: the end of a line, the right edge of a shape. Unused by the one-point commands.
Y2
port 0x26- In
- The byte last written.
- Out
- The second Y coordinate, the companion of the X2 port.
Command
port 0x27- In
- The number of the last command run, 0 before the first one.
- Out
- Runs one drawing operation on the coordinates, colors and pen width already set. The commands are listed above.
.org 0x8000
ld a, 0x03 ; 000 000 11: pure blue
out (0x21), a ; fill color
ld a, 9 ; command 9: clear to the fill color
out (0x27), a
ld a, 0xFC ; 111 111 00: yellow
out (0x21), a
ld a, 60
out (0x23), a
ld a, 40
out (0x24), a
ld a, 196
out (0x25), a
ld a, 152
out (0x26), a
ld a, 6 ; command 6: filled ellipse
out (0x27), a
halt- shows
- a yellow ellipse with a white outline on a blue Screen.
Pixel color
port 0x28- In
- The color of the pixel at (X, Y) as a 3-3-2 byte, read from the image being drawn on — the off-screen one while double buffering. Outside the Screen it reads as the background color.
- Out
- Ignored: the pixel is drawn with command 0, in the pen color.
.org 0x8000
ld a, 0xE0
out (0x20), a ; red pen
ld a, 8
out (0x23), a
out (0x24), a ; (8, 8)
xor a ; command 0: pixel
out (0x27), a
in a, (0x28) ; read the color back
out (0x13), a ; print it as hexadecimal
halt- prints
E0
Text cursor column
port 0x29- In
- The column the text cursor is on.
- Out
- Moves the text cursor to a column, in 8 by 8 character cells: 0 to 31 on the default Screen. Out of range values are clamped.
.org 0x8000
ld a, 12
out (0x29), a ; column 12
ld a, 8
out (0x2A), a ; row 8
ld hl, msg
loop: ld a, (hl)
or a
jr z, done
out (0x10), a ; the character port draws at the cursor
inc hl
jr loop
done: halt
msg: .asciz "HELLO"- prints
HELLO- shows
- the same text on the Screen, at the eighth row.
Text cursor row
port 0x2A- In
- The row the text cursor is on. Text scrolls the whole Screen up one cell row at the bottom, graphics included.
- Out
- Moves the text cursor to a row, in 8 by 8 character cells: 0 to 23 on the default Screen. Out of range values are clamped.
Keyboard
0x30 - 0x33Typed input available
port 0x30- In
- 1 when a character typed on the focused Screen is waiting to be read from the character port, else 0. During a testcase it answers for the scripted input instead, so a program that polls before reading works in both.
- Out
- Ignored.
.org 0x8000
wait: in a, (0x30) ; anything typed?
or a
jr z, wait ; poll until there is
in a, (0x10) ; take the character
out (0x10), a ; print it
halt- input
hi- shows
- the first character typed on the Screen, echoed back. Click the Screen first: that is where the keys go.
Key state
port 0x31- In
- 1 while the key whose code is in B is held down, else 0. This is how a game reads WASD or the arrows: it never consumes anything, and a key held over several reads answers 1 every time.
- Out
- Ignored.
.org 0x8000
ld c, 0x31 ; the key state port
ld b, 0x27 ; the right arrow
wait: in a, (c)
or a
jr z, wait ; poll until it is held
ld a, 'R'
out (0x10), a
halt- shows
- an R printed once the right arrow is held down on the focused Screen.
Last key pressed
port 0x32- In
- The code of the last key pressed on the Screen, 0 before the first press. It persists, so a program that polls slowly still sees the key.
- Out
- Ignored.
.org 0x8000
loop: in a, (0x32) ; the last key pressed
or a
jr z, loop
out (0x13), a ; print its code in hexadecimal
halt- shows
- the code of the first key pressed on the focused Screen, in hexadecimal.
Last key released
port 0x33- In
- The code of the last key released, 0 before the first release. With the last-pressed port it is the pair EASy68K’s task 19 answers with.
- Out
- Ignored.
Mouse
0x40 - 0x43Mouse views
Mouse X
port 0x40- In
- The X of the view selected by B (0 current, 1 last release, 2 last press), in logical Screen pixels from the left edge, independently of how the panel is zoomed.
- Out
- Ignored.
.org 0x8000
ld c, 0x42 ; the buttons port
ld b, 0 ; view 0: the current state
wait: in a, (c)
and 1 ; the left button
jr z, wait
ld c, 0x40
in a, (c) ; X
out (0x11), a
ld a, ','
out (0x10), a
ld c, 0x41
in a, (c) ; Y
out (0x11), a
halt- shows
- the pointer position printed as "x,y" as soon as the left button is held over the Screen.
Mouse Y
port 0x41- In
- The Y of the view selected by B, in logical Screen pixels from the top edge.
- Out
- Ignored.
Mouse buttons
port 0x42- In
- The buttons and modifiers of the view selected by B: bit 0 left, bit 1 right, bit 2 middle, bit 3 the double-click flag (only in the last-press view), bit 4 Shift, bit 5 Alt, bit 6 Ctrl.
- Out
- Ignored.
Mouse event count
port 0x43- In
- For the current view, how many mouse events have happened, as a byte that wraps around; for the two snapshot views, the count at the moment of the snapshot, 0 when it has not happened yet. Comparing it with the previous read is how a program tells a new click from the one it already handled.
- Out
- Ignored.
Program time
0x50 - 0x52Wait
port 0x50- In
- Waits B hundredths of a second, then answers 0. The editor stays responsive and Stop still works: the machine simply re-executes the
inwhen the time is up. In a testcase the wait completes at once. - Out
- Ignored.
.org 0x8000
ld c, 0x50
ld b, 25 ; a quarter of a second
in a, (c)
ld a, '!'
out (0x10), a
halt- prints
!
Frame sync
port 0x51- In
- Waits for the next animation frame, then answers 0. One read per frame is how an animation runs at the display’s own pace instead of as fast as the host can go; with double buffering, present the frame first and sync afterwards.
- Out
- Ignored.
.org 0x8000
ld b, 10 ; ten frames
loop: push bc
in a, (0x51) ; wait for the next frame
ld a, '.'
out (0x10), a
pop bc
djnz loop
halt- prints
..........
Elapsed time
port 0x52- In
- One byte of the number of hundredths of a second since the run started, selected by B: 0 the lowest byte, 3 the highest. A testcase reads a virtual clock that starts at zero and only moves when the program waits, so a test is reproducible.
- Out
- Ignored.
.org 0x8000
ld c, 0x50
ld b, 10 ; wait a tenth of a second
in a, (c)
ld c, 0x52
ld b, 0 ; the lowest byte of the elapsed hundredths
in a, (c)
out (0x11), a
halt- shows
- the hundredths of a second the program has been running, about 10.