amiga-bootcamp/10_devices/serial.md
Ilia Sharin 0ded078134 Phase 1 continued: serial, input devices + README indexes
10_devices:
- serial.md: expanded with DB-25 pinout, custom chip UART registers,
  baud rate calculation table, open/configure/read/write patterns,
  serial debugging (KPrintF/Sushi)
- input.md: expanded with handler chain architecture diagram,
  InputEvent struct, event classes table, qualifier bits, custom
  handler with key remapping, event consumption/blocking,
  synthetic event injection, Commodities Exchange

Updated indexes:
- 07_dos/README.md — enriched descriptions for all files
- 10_devices/README.md — enriched descriptions for all files
2026-04-23 20:28:03 -04:00

3.6 KiB

← Home · Devices

serial.device — UART and RS-232 Communication

Overview

serial.device provides access to the Amiga's built-in UART (Universal Asynchronous Receiver/Transmitter) for RS-232 serial communication. The hardware UART is implemented using CIA-B shift registers and custom chip DMA. Serial I/O is fundamental for debugging (serial console), modem communication, MIDI, and inter-machine networking.


Hardware

Serial Port Pins (DB-25)

Pin Signal Direction Description
2 TxD Output Transmit data
3 RxD Input Receive data
4 RTS Output Request to send (active low)
5 CTS Input Clear to send (active low)
6 DSR Input Data set ready
7 GND Signal ground
8 CD Input Carrier detect
20 DTR Output Data terminal ready

Custom Chip Registers

Register Address Description
SERDAT $DFF030 Serial data write (transmit) — 9 bits: stop bit + 8 data
SERDATR $DFF018 Serial data read (receive) — status + received byte
SERPER $DFF032 Serial period (baud rate divider)
ADKCON $DFF09E UARTBRK bit for break signal

Baud Rate Calculation

/* SERPER value = (system_clock / baud_rate) - 1 */
/* PAL system clock for serial = 3,546,895 Hz */
/* NTSC = 3,579,545 Hz */

#define SERIAL_CLOCK_PAL   3546895
#define SERIAL_CLOCK_NTSC  3579545

UWORD serper_from_baud(ULONG baud, BOOL isPAL) {
    return (isPAL ? SERIAL_CLOCK_PAL : SERIAL_CLOCK_NTSC) / baud - 1;
}
Baud Rate SERPER (PAL) SERPER (NTSC)
1200 2955 2982
2400 1477 1491
9600 368 372
19200 184 185
31250 (MIDI) 112 113
57600 60 61
115200 29 30

Using serial.device

Open and Configure

struct MsgPort *serialPort = CreateMsgPort();
struct IOExtSer *serialReq = (struct IOExtSer *)
    CreateIORequest(serialPort, sizeof(struct IOExtSer));

/* Open serial.device unit 0: */
BYTE err = OpenDevice("serial.device", 0,
                       (struct IORequest *)serialReq, 0);

/* Configure: */
serialReq->io_SerFlags  = SERF_SHARED | SERF_XDISABLED;
serialReq->io_Baud      = 9600;
serialReq->io_ReadLen   = 8;     /* 8 data bits */
serialReq->io_WriteLen  = 8;
serialReq->io_StopBits  = 1;
serialReq->io_RBufLen   = 4096;  /* receive buffer size */
serialReq->IOSer.io_Command = SDCMD_SETPARAMS;
DoIO((struct IORequest *)serialReq);

Write Data

serialReq->IOSer.io_Command = CMD_WRITE;
serialReq->IOSer.io_Data    = "Hello Serial\r\n";
serialReq->IOSer.io_Length  = 14;
DoIO((struct IORequest *)serialReq);

Read Data

/* Check how many bytes are waiting: */
serialReq->IOSer.io_Command = SDCMD_QUERY;
DoIO((struct IORequest *)serialReq);
ULONG waiting = serialReq->IOSer.io_Actual;

if (waiting > 0) {
    serialReq->IOSer.io_Command = CMD_READ;
    serialReq->IOSer.io_Data    = buffer;
    serialReq->IOSer.io_Length  = waiting;
    DoIO((struct IORequest *)serialReq);
    /* buffer now contains received data */
}

Serial Debugging

Many developers use a null-modem cable to a terminal for kernel debugging:

/* Kprintf — ROM debug output via serial (ROMTags/exec): */
/* This bypasses serial.device entirely — writes directly to SERDAT */
void KPrintF(const char *fmt, ...);  /* available in debug ROMs */

/* Sushi/Sashimi — capture serial debug output on another Amiga */

References

  • NDK39: devices/serial.h
  • HRM: Amiga Hardware Reference Manual — Serial Port chapter
  • ADCD 2.1: serial.device autodocs