Skip to content

Intel 8080 IO Ports

The Intel 8080 can address 256 input ports and 256 output ports. Programs access them with the IN and OUT instructions. This page documents the current port assignments used by the Altair emulator.

Intel 8080 IO ports and peripherals

The image shows an example of Intel 8080 IO port usage

Port assignments

The emulator decodes the port address with address & 0x17. Use the canonical addresses in this table in programs and documentation.

Address Decimal Direction Purpose
0x02 2 IN / OUT Shared-service status and command
0x03 3 OUT Shared-service request length and payload
0x04 4 IN Shared-service response length and payload
0x07 7 IN / OUT Interrupt timer rate
0x15 21 - Available
0x16 22 - Available
0x17 23 IN / OUT Countdown timers and stopwatches

Terminal and disk ports are handled by the emulator's existing console and disk interfaces.

Shared services on ports 0x02-0x04

Write a service group to OUT 0x02, then write a two-byte payload length to OUT 0x03 (low byte first), followed by exactly that many payload bytes. The first payload byte is the operation. Poll IN 0x02 until the request finishes. For a response, read its two-byte length from IN 0x04 (low byte first), then read exactly that many bytes. A response is binary-safe: zero is ordinary data and text responses do not include a trailing NUL. For a command with no response, acknowledge COMPLETE by writing 0x00 to OUT 0x02. On ERROR, read the complete error frame and acknowledge it; write RESET (0x01) to OUT 0x02 to abandon a partial request or recover an unknown state.

Group byte Service
0x10 Countdown timers
0x11 Stopwatches
0x20 Clock, date and uptime
0x21 Random numbers, system information and reboot
0x30 Environment variables and CLI commands
0x40 Weather
0x50 Chat
0x60 Sense HAT on supported host builds
0x70 File transfer

Status values from IN 0x02 are 0x00 READY, 0x01 COMPLETE, 0x02 RESPONSE_READY, 0x03 COLLECTING, 0x04 BUSY and 0xFF ERROR. A framed error response contains an error code as its first payload byte. The shared payload limit is 2048 bytes. Only one shared transaction may be active at a time. Poll with a bounded timeout. See the dcc client API for C helpers and service operation details.

dcc C example

The shared dcc client provides typed functions for common operations. This example starts a 100 ms timer and waits for it to expire:

#include "DXSVC.H"

int main(void)
{
    svc_start_timer(1, 100);
    while (svc_timer_active(1))
        ;
    return 0;
}

The same client provides svc_random_u16() and svc_access_stopwatch(). Use svc_call_service() or svc_operation_send() for other framed requests.

Countdown timers and stopwatches on 0x17

All timer operations use OUT 0x17 for a command and its parameters, and IN 0x17 for results. This dedicated interface does not use shared-service framing or acknowledgements.

OUT command Following OUT bytes IN result
0x00 None Reset interface; return to running-mask mode
0x10-0x12 Duration u16, little-endian Start millisecond timer 0-2
0x13 Duration u8 Start seconds timer 3
0x20-0x23 None Select timer 0-3; read 1 while running, 0 when expired
0x30 None Read running mask; bits 0-3 represent timers 0-3
0x40-0x42 None Reset stopwatch 0-2
0x50-0x52 None Read stopwatch seconds as four little-endian bytes
0x60-0x62 None Read stopwatch milliseconds as four little-endian bytes

Timer IDs 0-2 accept durations from 0 to 65535 milliseconds. Timer 3 accepts 0 to 255 seconds. A zero duration expires immediately. Stopwatch results are unsigned 32-bit values; read all four bytes after selecting a stopwatch.

Example 8080 assembly starts timer 1 for 100 ms and polls it:

        MVI A,11H      ; select timer 1 start
        OUT 23
        MVI A,64H      ; duration low byte: 100 ms
        OUT 23
        MVI A,00H      ; duration high byte
        OUT 23
        MVI A,21H      ; select timer 1 query
        OUT 23
WAIT:   IN 23
        CPI 01H
        JZ WAIT

Finish a multi-byte command or read all four stopwatch bytes before another port-0x17 user accesses the interface. To recover an unknown parser state, read 0x17 once and then write 0x00 to it. This resets the interface without changing running timers or stopwatch values.

Interrupt timer on 0x07

  • OUT 0x07: set the interrupt rate in hertz; zero disables it.
  • IN 0x07: read the configured rate.

This port reports the rate, not a pending-interrupt flag.

File transfer: shared group 0x70

The FT CP/M application uses the shared framing on ports 0x02/0x03/0x04. Filename requests contain 1-127 bytes without a terminating NUL.

Request payload Result
[1, filename bytes...] Open/replace session; COMPLETE, then ACK
[3] RESPONSE_READY: [state, up to 256 file bytes...]
[4] Cancel/close; COMPLETE, then ACK

State 0 means more data; 2 means EOF and may accompany final bytes. An empty EOF response is [2] with framed length 1; a full chunk has length 257. File bytes, including zero, are ordinary payload. Fully consuming a response returns READY. Other shared services can run between reads without closing the FT session. RESET while a read is BUSY cancels that session. Transfer failure returns shared error 0x21.

ESP32 uses its remote FT TCP server on port 8090. See the complete service reference for transport recovery and backend details.

Reboot

The ENV CP/M application provides a reboot menu option with user confirmation. Reboot requests use utility group 0x21, operation 0x02, and confirmation byte 0xA5, sent through the shared-service protocol.