amiga-bootcamp/01_hardware/ocs_a500/paula_serial.md
Ilia Sharin 21751c0025 docs(amiga): complete AmigaOS 3.1/3.2 developer reference — 172 files across 17 sections
Comprehensive technical documentation covering:
- Hardware: OCS/ECS/AGA custom chip registers, Copper & Blitter deep dives
- Boot sequence: cold boot through startup-sequence
- Binary format: HUNK executable spec, relocation, debug info
- Linking & ABI: .fd files, LVO tables, register calling conventions
- Exec kernel: tasks, interrupts, memory, signals, semaphores
- AmigaDOS: file I/O, FFS/OFS layout, CLI/Shell scripting
- Graphics: planar bitmaps, Copper programming, HAM/EHB modes
- Intuition: screens, windows, IDCMP, BOOPSI
- Devices: trackdisk, SCSI, serial, timer, audio, keyboard
- Libraries: utility, expansion, IFFParse, locale, ARexx
- Networking: bsdsocket API, SANA-II, TCP/IP stack comparison
- Toolchain: GCC, vasm/vlink, SAS/C, NDK, debugging
- Reverse engineering: IDA/Ghidra setup, compiler fingerprints, case studies
- CPU & MMU: 68040/060 emulation libs, PMMU, cache management
- Driver development: SANA-II, Picasso96/RTG, AHI audio

All files include breadcrumb navigation. No local paths or proprietary content.
2026-04-23 12:17:35 -04:00

3.4 KiB

← Home · Hardware · OCS

Paula — Serial Port

Overview

Paula contains a hardware UART (Universal Asynchronous Receiver/Transmitter) for the Amiga's serial port. It is a simple, non-buffered serial interface — no FIFO, single transmit and single receive register.

The serial port operates at RS-232 voltage levels (via external level shifter on the A500/A1000). The A2000 and A3000 route through a MAX232 equivalent.

Registers

Register Offset Dir Description
SERPER $DFF032 W Serial period and word length
SERDAT $DFF030 W Serial data transmit
SERDATR $DFF018 R Serial data receive + status

SERPER — Baud Rate Configuration

bit 15:    LONG — 0 = 8-bit words, 1 = 9-bit words
bit 14-0:  Period — clock divider for baud rate

Baud rate formula:

Baud = System clock / (Period + 1)
Baud Rate PAL Period NTSC Period
300 11811 11929
1200 2952 2981
2400 1476 1490
4800 737 745
9600 368 372
19200 183 186
38400 91 92
115200 30 30

SERDAT — Transmit

bit 15-11: Must be 1 (stop bits framing)
bit 10:    Stop bit
bit 9-0:   Data word (8 or 9 bits, MSB first relative to wire)

To transmit a byte (8-bit mode):

; Wait for TBE (transmit buffer empty) interrupt or poll
WaitTBE:
    btst    #0, SERDATR+1    ; TBE = bit 0 of SERDATR high byte... 
                              ; Actually check INTREQR bit TBE
    beq.s   WaitTBE

; Send byte $41 ('A'), 8-bit framing: $3C01 prefix + data
move.w  #($3FC0 | 0x41), SERDAT+custom

Correct framing for 8-bit word:

SERDAT = $3C00 | byte_value    ; bits[15:10] = %111111 (stop + start framing)

SERDATR — Receive

bit 15: OVRUN — overrun error (data was not read before next byte arrived)
bit 14: RBF   — receive buffer full (data ready to read)
bit 13: TBE   — transmit buffer empty
bit 12: TSRE  — transmit shift register empty
bit 11: RXD   — current state of RXD pin
bit  9: STP   — stop bit of received word
bit 8-0: Data — received byte (8 or 9 bits)

Read a byte:

/* Wait for RBF */
while (!(custom.serdatr & SERDATF_RBF))
    ;
UBYTE ch = custom.serdatr & 0xFF;

/* Acknowledge interrupt */
custom.intreq = INTF_RBF;

Interrupt Sources

Event INTENA/INTREQ bit IPL
TBE (transmit buffer empty) bit 0 INTF_TBE 1
RBF (receive buffer full) bit 11 INTF_RBF 5

RBF fires at IPL 5 — relatively high priority, since the receive register has no FIFO and an overrun loses data.

serial.device

AmigaOS provides serial.device for managed serial access:

  • Supports baud rates, parity, stop bits, word length
  • Provides buffered read/write via IOExtSer structure
  • Handles CMD_READ, CMD_WRITE, SDCMD_SETPARAMS, SDCMD_QUERY
  • Multiple opens are not supported — one opener at a time
#include <devices/serial.h>

struct IOExtSer *ser_req; /* allocated IOExtSer */
OpenDevice("serial.device", 0, (struct IORequest *)ser_req, 0);

ser_req->io_Baud      = 9600;
ser_req->io_RBufLen   = 4096;
ser_req->IOSer.io_Command = SDCMD_SETPARAMS;
DoIO((struct IORequest *)ser_req);

References