I/O Port Bus

All 65 536 ISA I/O ports — how devices register handlers and how the WASM CPU dispatches reads and writes.

ISA I/O space

x86 has a separate 16-bit I/O address space (ports 0x0000–0xFFFF) accessed with IN and OUT instructions. v86 implements this as a flat array of 65 536 handler records in src/io.js. When WASM executes IN AL, DX, it calls the JS import io_port_read8(DX) → JS dispatches to the registered device handler.

Read/Write Dispatch Flow

WASMGuest executes IN AL, 0x60
CPU encodes port 0x60, size=1 (byte)
WASM → JSCalls imported function
io_port_read8(0x60) — crosses WASM/JS boundary
io.jsLooks up port handler
io_port_map[0x60].read8 — registered by PS/2 device at init
ps2.jsDevice handler runs
Dequeues next scancode from keyboard FIFO, returns byte value
JS → WASMReturns to WASM
Return value (e.g. 0x1C = "A" pressed) placed in AL register

Port Assignment Map

Click any row for details about that port range.

Port RangeDeviceIRQ / Note
0x0000–0x001F
DMA Controller 1
ch 0–3
0x0020–0x003F
PIC 1 (8259A)
master
0x0040–0x0047
PIT Timer (8254)
IRQ 0
0x0060, 0x0064
PS/2 Controller (8042)
IRQ 1, 12
0x0061
A20 Gate / PC Speaker
sys ctrl
0x0070–0x0071
RTC / CMOS
IRQ 8
0x0080–0x008F
DMA Page Registers
ch 0–7
0x00A0–0x00BF
PIC 2 (8259A)
slave
0x00C0–0x00DF
DMA Controller 2
ch 4–7
0x0170–0x0177, 0x0376
IDE Secondary
IRQ 15
0x01F0–0x01F7, 0x03F6
IDE Primary
IRQ 14
0x0220–0x0233
SoundBlaster 16
IRQ 5
0x0280–0x029F
NE2000 Network Card
IRQ 9
0x02F8–0x02FF
UART COM2
IRQ 3
0x03C0–0x03DF
VGA Registers
0x03F0–0x03F7
Floppy Controller
IRQ 6
0x03F8–0x03FF
UART COM1
IRQ 4
0x0CF8–0x0CFF
PCI Configuration
0xE000–0xE0FF (var)
Virtio I/O Port BAR
PCI IRQ

Port Handler Record

Per-port handler record

Each of the 65 536 ports has a record with up to 6 functions (read8, read16, read32, write8, write16, write32) plus a device back-reference. Unregistered ports have null handlers and return 0xFF on reads.

FunctionCalled whenTypical return
read8(port)Guest: IN AL, port8-bit device register value
read16(port)Guest: IN AX, port16-bit value (or two 8-bit reads chained)
read32(port)Guest: IN EAX, port32-bit value (PCI config data etc.)
write8(port, val)Guest: OUT port, AL
write16(port, val)Guest: OUT port, AX
write32(port, val)Guest: OUT port, EAX

VGA Port Breakdown (0x03C0–0x03DF)

VGA has the most complex port layout — 14 registers spread across a 32-byte window.

PortNameDescription
0x3C0AC Index+DataAttribute Controller: write index, then data alternately. Controls color palette, overscan, display mode.
0x3C2Misc Output (W) / Input Status 0 (R)Clock select, sync polarity, page select (write); feature bits, CRT interrupt (read).
0x3C4Sequencer IndexSelects sequencer register: reset, clocking mode, map mask, character map, memory mode.
0x3C5Sequencer DataReads/writes the selected sequencer register.
0x3C6DAC PEL MaskMasks bits passed to palette DAC (normally 0xFF).
0x3C7DAC State / DAC Read IndexRead: DAC state. Write: set read index for DAC palette reads.
0x3C8DAC Write IndexSelect DAC palette entry to write (0–255).
0x3C9DAC DataRead/write R,G,B bytes for selected palette entry (6 bits each, 0–63).
0x3CAFeature Control (R)Reads back the feature control register.
0x3CCMisc Output (R)Reads back the miscellaneous output register.
0x3CEGC IndexGraphics Controller index: set/reset, enable S/R, color compare, rotate, read map, mode, misc, color don't care, bitmask.
0x3CFGC DataRead/write selected Graphics Controller register.
0x3D4CRTC IndexCRT Controller: selects from 25 registers (htotal, hdisplay end, cursor, start/end, vretrace, etc.).
0x3D5CRTC DataRead/write selected CRTC register.
0x3DAInput Status 1Vertical retrace and display enable bits. Also resets AC flip-flop for attribute controller access.