[← Home](../README.md) · [Devices](README.md) # parallel.device — Centronics Parallel Port ## Overview `parallel.device` provides I/O for the Amiga's Centronics-compatible 25-pin parallel port. Primarily used for printers, it also serves as a general-purpose 8-bit data port for hardware projects, dongles, MIDI interfaces, and inter-machine transfers (Laplink-style). The parallel port is directly connected to **CIA-A** Port B data register (`$BFE101`) with handshake lines on CIA-A and CIA-B. ```mermaid flowchart LR APP["Application"] -->|"CMD_WRITE
CMD_READ"| PAR["parallel.device"] PAR --> CIA["CIA-A Port B
($BFE101)
8 data bits"] CIA --> PORT["DB-25 Connector
(pins 2-9 = data)"] PAR --> CIAB["CIA-B
Handshake lines"] style PAR fill:#e8f4fd,stroke:#2196f3,color:#333 style CIA fill:#c8e6c9,stroke:#2e7d32,color:#333 ``` --- ## Hardware Pinout | Pin | Signal | Direction | Description | |---|---|---|---| | 1 | /STROBE | Output | Data strobe (active low) | | 2–9 | D0–D7 | I/O | 8-bit bidirectional data | | 10 | /ACK | Input | Acknowledge from printer | | 11 | BUSY | Input | Printer busy | | 12 | POUT | Input | Paper out | | 13 | SELECT | Input | Printer selected | | 14–17 | — | — | Reserved / unused | | 18–25 | GND | — | Ground | --- ## Opening ```c struct MsgPort *parPort = CreateMsgPort(); struct IOExtPar *par = (struct IOExtPar *) CreateIORequest(parPort, sizeof(struct IOExtPar)); if (OpenDevice("parallel.device", 0, (struct IORequest *)par, 0)) { Printf("Cannot open parallel.device\n"); /* Port may be in use by another application (printer, etc.) */ } ``` > [!NOTE] > Only **one** application can have the parallel port open at a time. If the port is busy (e.g., printer spooler has it), `OpenDevice` will fail. This is unlike serial.device which supports shared modes. --- ## Commands | Code | Constant | Description | |---|---|---| | 2 | `CMD_READ` | Read bytes (bidirectional mode) | | 3 | `CMD_WRITE` | Write bytes to the port | | 5 | `CMD_CLEAR` | Clear internal buffers | | 7 | `CMD_RESET` | Reset the device | | 8 | `CMD_FLUSH` | Abort all pending I/O | | 9 | `PDCMD_QUERY` | Get port status (busy, paper out, etc.) | | 10 | `PDCMD_SETPARAMS` | Configure port parameters | ### Writing Data ```c /* Send data to the parallel port: */ char printData[] = "Hello, Printer!\r\n"; par->IOPar.io_Command = CMD_WRITE; par->IOPar.io_Data = printData; par->IOPar.io_Length = sizeof(printData) - 1; DoIO((struct IORequest *)par); if (par->IOPar.io_Error) Printf("Write error: %ld\n", par->IOPar.io_Error); ``` ### Querying Status ```c par->IOPar.io_Command = PDCMD_QUERY; DoIO((struct IORequest *)par); UBYTE status = par->io_Status; if (status & IOPTF_PARBUSY) Printf("Printer busy\n"); if (status & IOPTF_PAPEROUT) Printf("Paper out\n"); if (status & IOPTF_PARSEL) Printf("Printer selected\n"); ``` ### Setting Parameters ```c /* Configure for custom use (e.g., no handshaking): */ par->IOPar.io_Command = PDCMD_SETPARAMS; par->io_ParFlags = PARF_SHARED; /* shared access (OS 2.0+) */ DoIO((struct IORequest *)par); ``` --- ## Direct Hardware Access For hardware projects that need precise control (bypassing the device driver): ```c /* Direct CIA-A Port B access: */ volatile UBYTE *ciaaPrb = (UBYTE *)0xBFE101; /* data register */ volatile UBYTE *ciaaDdrb = (UBYTE *)0xBFE301; /* data direction */ /* Set all 8 bits as output: */ *ciaaDdrb = 0xFF; /* Write a byte: */ *ciaaPrb = 0x42; /* Set as input: */ *ciaaDdrb = 0x00; UBYTE value = *ciaaPrb; ``` > [!CAUTION] > Direct hardware access bypasses the OS completely. Do not mix direct register access with parallel.device operations — close the device first or don't open it at all. --- ## Common Uses | Use Case | Method | |---|---| | Printer output | `CMD_WRITE` through printer.device (which opens parallel.device) | | Hardware dongle | Direct CIA-A Port B register read | | MIDI interface | Parallel-to-MIDI adapter with custom timing | | Amiga-to-PC transfer | Laplink cable with ParNet or ParBench software | | Sampling hardware | ADC/DAC connected to data lines | --- ## References - NDK39: `devices/parallel.h` - ADCD 2.1: parallel.device autodocs - See also: [serial.md](serial.md) — serial port I/O - See also: [cia_chips.md](../01_hardware/common/cia_chips.md) — CIA register details