Ports and I/O Devices

Page Index

Ports (Model I)

PortPeripheral/User
78-7FChromaTRS
B0-BCNewClock-80
B5 and B9Orchestra-85
BDOrchestra-80
E8-EBSerial Port
FESprinter I / II

Ports (Model III and Model 4)

PortPeripheral/User
5FSprinter III
75/79Orch-90
7FShuffleboard III (CP/M)
80-8FRadio Shach Graphics Board (Model III)
80-83Radio Shach Graphics Board (Model 4)
80-83Grafyx Solution (Micro-Labs, Model 4)
84-87Operation Register (Model 4)
84-87Operation Register (Model 4P)
88-8BCRT Control
8C-8FGraphics Board Select 2
90-93Sound Port (Model 4)
9CModel 4P Boot ROM
B0-BCNewClock-80
B6ARCNET (Model 4P)
C0-CFHard Drive
D0-D3Network 4 (Omninet)
E0Maskable Interrupts
E4Non-Maskable Interrupts
E8-EBRS-232
ECMisc / Controls
F0-F4Floppy Drive
F8-FBPrinter
FC-FFCassette

Memory Mapped I/O Devices

Ports (Model I)

Block 78-7F - ChromaTRS


The CHROMAtrs from South Shore Computer Concepts (later Micro Control Systems) is a color graphics, sound, and joystick add-on for the TRS-80. Its heart is the Texas Instruments TMS9918A Video Display Processor - the same VDP used in the ColecoVision, TI-99/4A, MSX, and Sega SG-1000 - giving up to 256x192 resolution, 16 colors, and 32 hardware sprites. The board plugs into the expansion bus and occupies the 78H-7FH port block; the base address is jumper-selectable to any multiple of 8 (00H, 08H, ... 78H) to avoid conflicts. The port assignments below were determined by disassembly of the CHROMA/CMD driver (loaded at E400H); addresses cited refer to that driver.

PortUse
78H (120)TMS9918A VRAM Data Port. Reads and writes the VDP's dedicated 16K of video RAM. The VDP auto-increments its internal address pointer after each access, so a block of VRAM is filled or copied by repeated OUT (78H),A (or read back with IN A,(78H)). In the driver, the screen-clear loops stream data here after the address is set up (e.g. 0E468H, 0E47DH, 0E494H).
79H (121)TMS9918A Control / Register Port. Used both to set the VRAM address pointer and to load the VDP's internal registers:
  • Set VRAM address - a two-byte address word is written here (0E412H/0E414H writes the low byte then the high byte via OUT (C),L / OUT (C),H with C=79H). Before a VRAM write the driver sets bit 6 of the high byte (SET 6,H, the VDP write-enable); before a VRAM read it clears it (RES 6,H).
  • Load a VDP register - the register value is written, followed by the register number with bit 7 set (0E42EH: OUT (79H),A; 0E433H: value OR 80H then OUT (79H),A). The init routine at 0E436H loads the VDP's setup registers from a table at 0E450H.
7DH (125)Joystick input (port 1 of the pair). Together with 7EH, carries the direction and trigger bits for two Atari-compatible joysticks. The driver's input routine (0F4B5H) selects controller 0-3 and tests individual bits; trigger/fire is read from 7DH bit 7 and bit 6 (0F4D8H, 0F4E2H), and direction bits are read from 7DH bit 0 and bit 1 (0F5C9H, 0F5CFH).
7EH (126)Sound generator and joystick input (port 2 of the pair).
  • Sound - tones are produced by toggling this port between a value and zero inside timed DJNZ delay loops, generating a square wave (0EB96H-0EBA9H, 0EBC4H-0EBD5H). A value of 80H is the idle/off level.
  • Joystick - the remaining joystick bits are read here: trigger/fire from 7EH bit 7 and bit 6 (0F4C4H, 0F4CEH), and direction bits from 7EH bit 1 and bit 0 (0F5C3H, 0F5D5H).
7AH-7CH, 7FHWithin the decoded 78H-7FH block but not used by the CHROMA/CMD driver.

Note: Because the CHROMAtrs sits on the expansion bus, on a Model III or Model 4 the external I/O bus must be enabled before its ports respond. The driver does this by setting bit 4 of Port ECH (OUT (0ECH),10H at 0E400H), the same enable used by the NewClock-80 - see the Port ECH / Model III and Model 4 notes. On a Model I the bus is always live and no enable is needed.

Block B0-BC - NewClock-80


The Alpha Products NewClock-80 (released 1983, replacing the earlier TIMEDATE 80 and remaining software compatible with it) is a battery-backed clock/calendar built around an OKI MSM5832 real-time-clock chip. It plugs into the expansion bus and requires no hardware modifications. The same board design is used on the Model I, Model III, and Model 4; only the I/O-bus enable step differs (see the Model III/4 entry).

The clock presents the time and date as 13 read/write ports, one BCD digit per port. Each port returns its digit in the low nibble (bits 0-3); the upper four bits are undefined and must be masked off with AND 15 (or AND 3 for the capped tens digits). Early boards pull the unused high bits low, so reads return 0-15; later boards may leave them high, returning 240-255. Masking makes code work on both.

High Port / Low Port

The NewClock-80 is jumper-selectable between two port ranges so it can coexist with other peripherals. Both ranges expose the identical register set, bit layout, and masking - only the base address differs:

  • High Port - ports 176-188 (B0H-BCH). This is the factory default and the range used by the PORTHELP tutorial and most Alpha Products driver software.
  • Low Port - ports 112-124 (70H-7CH). This is the range used by the predecessor TIMEDATE 80 clock, which the NewClock-80 replaced while staying software compatible. Drivers that support both configurations detect the clock and add an offset of 0 (Low) or 64 (High) to a base of 112.

The register map below lists the Low Port address first, then the High Port address. The examples further down assume a High Port clock; for a Low Port clock, subtract 64 from each port number (e.g. read seconds-ones from 112 instead of 176).

Register Map (Low Port 112-124 / High Port 176-188)

FunctionTens DigitOnes DigitComment
Year124 / 188 (BCH)123 / 187 (BBH)Mask each digit with AND 15
Month122 / 186 (BAH)121 / 185 (B9H)Mask each digit with AND 15
Day120 / 184 (B8H)119 / 183 (B7H)Tens digit: mask with AND 3.
Bit 2 of the tens port is the Leap-Year bit (AND 4).
A read of the tens port > 127 indicates no clock is present
Day of Week 118 / 182 (B6H)Single port, value 0-6 (0=Sun, 1=Mon, ... 6=Sat). Mask with AND 15
Hour117 / 181 (B5H)116 / 180 (B4H)Tens digit: mask with AND 3.
Bit 2 of the tens port is AM/PM (12-hr mode only).
Bit 3 of the tens port is the 12/24-hour mode bit
Minute115 / 179 (B3H)114 / 178 (B2H)Mask each digit with AND 15
Second113 / 177 (B1H)112 / 176 (B0H)Mask each digit with AND 15.
Cannot be set (see below)

Status Bits

Three extra status bits are packed into two of the ports:

  • Leap-Year bit - Port 184 (B8H), bit 2: LEAP = INP(184) AND 4. Returns 4 if next February has 29 days, 0 otherwise. The day-tens digit is read with AND 3 to mask this bit off.
  • 12/24-hour mode bit - Port 181 (B5H), bit 3: MODE = INP(181) AND 8. Returns 8 for 24-hour mode, 0 for 12-hour mode.
  • AM/PM bit - Port 181 (B5H), bit 2: AMPM = INP(181) AND 4. In 12-hour mode, returns 4 for PM and 0 for AM. Meaningless in 24-hour mode.

A driver can also test for the clock's presence by reading the day-tens port (120 Low / 184 High): a value greater than 127 indicates no clock is installed at that range.

Reading the Clock (Examples)

SEC  = (INP(177) AND 15) * 10 + (INP(176) AND 15)

MIN  = (INP(179) AND 15) * 10 + (INP(178) AND 15)

HOUR = (INP(181) AND 3)  * 10 + (INP(180) AND 15)

DAY  = (INP(184) AND 3)  * 10 + (INP(183) AND 15)

MNTH = (INP(186) AND 15) * 10 + (INP(185) AND 15)

YEAR = (INP(188) AND 15) * 10 + (INP(187) AND 15)

DOW  = INP(182) AND 15

The parentheses around every (15 AND INP(...)) term are mandatory because of BASIC's order of operations.

Setting the Clock

The same ports accept OUT to set the time and date - for example OUT 179, MIN/10 then OUT 178, MIN-INT(MIN/10)*10. Two cautions:

  • Seconds cannot be set. Any OUT to ports 177 or 176 resets the seconds to zero regardless of the value sent.
  • The hour-tens port carries the mode bits. When writing port 181 you must OR in the desired 12/24 and AM/PM bits along with the hour-tens digit, e.g. OUT 181, HOURMODE OR AMPM OR (HOUR/10) then OUT 180, HOUR-INT(HOUR/10)*10.

Note: On a Model I the clock ports are always live and need no enabling. On a Model III or Model 4 the external I/O ports must be enabled first - see the NewClock-80 entry under Ports (Model III and Model 4).

Block B5/B9/BD - Orchestra-80 and Orchestra-85:

The Orchestra-80 (1980) and Orchestra-85 (1981) were music synthesizer add-ons for the TRS-80 Model I, designed by Jon Bokelman and sold by Software Affair. Both plug into the expansion bus. Each output port is a simple 8-bit digital-to-analog converter: the playback routine repeatedly writes successive sample values to the port(s) in a tight timed loop, generating the waveform directly. (The Model III / Model 4 equivalent is the Orchestra-90, which uses ports 75 and 79 - see the Model III and Model 4 section.)

PortUse
BDH (189)Orchestra-80 - single (monophonic) D/A converter. The driver writes each computed sample byte to this port with OUT (0BDH),A; writing 00H silences the output.
B5H (181)
B9H (185)
Orchestra-85 - two D/A converters for true stereo output. The playback loop alternates OUT (0B9H),A and OUT (0B5H),A, sending one channel's sample to each port. One port feeds the left output and the other the right.

Note: The Orchestra-85's stereo ports (B5H, B9H) fall within the same B0H-BCH block used by the NewClock-80. The two devices cannot share that port range simultaneously; a NewClock-80 would need to be set to its Low Port (112-124 / 70H-7CH) configuration to coexist with an Orchestra-85.

Block E8-EB - Serial Port


Port E8

This port is mainly used for UART reset and initialization. Writing any byte to 0E8H resets the RS-232 interface. It also acts as the RS-232 status register port. Bits in this port represent signals such as Clear to Send (CTS), Data Set Ready (DSR), Carrier Detect, and Ring Indicator.

BitInput (= UART Status)Output (= Set UART Parameter)
B01 = CTS (Clear to Send) activeWriting any value resets UART
B11 = DSR (Data Set Ready) activeWriting any value resets UART
B21 = RLSD (Carrier Detect) activeUnused / No control
B31 = Ring Indicator activeWriting any value resets UART
B4UnusedWriting any value resets UART
B5UnusedWriting any value resets UART
B6UnusedWriting any value resets UART
B7Bit 7 being read as input signals a reset actionWriting any value resets UART

Port E9

This port is used for setting the RS-232 baud rate. Different values written here configure the baud rate of the UART.

BitDIP Switch Settings (Input)Output (= Set UART Parameter)
7Parity 0=Odd Set Baud Rate (all bits): Bits 0-3 = Receive Speed Bits 4-7 = Transmit Speed Speed Codes (Binary / Hex): 0000 0000b (00H) = 50 baud 0001 0001b (11H) = 75 baud 0010 0010b (22H) = 100 baud 0011 0011b (33H) = 134.5 baud 0100 0100b (44H) = 150 baud 0101 0101b (55H) = 300 baud 0110 0110b (66H) = 600 baud 0111 0111b (77H) = 1,200 baud 1000 1000b (88H) = 1,800 baud 1001 1001b (99H) = 2,000 baud 1010 1010b (AAH) = 2,400 baud 1011 1011b (BBH) = 3,600 baud 1100 1100b (CCH) = 4,800 baud 1101 1101b (DDH) = 7,200 baud 1110 1110b (EEH) = 9,600 baud 1111 1111b (FFH) = 19,200 baud
6-B5Word Length
  • 00 = 5
  • 01 = 7
  • 10 = 6
  • 11 = 8
4Stop bits
  • 0 = 1 Stop Bit
  • 1 = 2 Stop Bits
3Parity 0=Enable
2Unused
1Unused
0Unused

Port EA

This port acts as the UART control and status register. Reading this port gives status bits like data available, parity, and transmission buffer status. Writing here configures parameters like parity enable/disable and can enable or disable the UART.

BitInput (= UART Status)Output (= Set UART Parameter)
0unused0=RTS on
1unused0=DTR on
2unused1=Transmit Enable
31=Parity Error1=No Parity
41=Framing Error0=1-Stop bit
51=Overrun ErrorWord Length [Bits 5 and 6]: 00=5, 01=7, 10=6 11=8
60=Data sent (TBMT)See Above
71=Data Available1=Even Parity, 0=Odd Parity

Port EB

The data register for RS-232. Reading from 0EBH reads the received data byte from the serial line, and writing to it sends a data byte out on the serial line.

Block FE - Sprinter I / II

Used by the Sprinter I and Sprinter II to control speed-up.

Sprinter I

  • OUT 254,0 - Disable the sprinter and return the Model I to 1.77Mhz
  • OUT 254,1 - Tell the Sprinter I that there is a hardware switch attached, and to use that switch to control speed.

Sprinter II

CommandSpeedWait State Used?
OUT 254,01.77 MHzNo Wait State
OUT 254,11.52 MHzNo Wait State
OUT 254,21.33 MHzNo Wait State
OUT 254,31.19 MHzNo Wait State
OUT 254,45.32 MHzNo Wait State
OUT 254,53.55 MHzNo Wait State
OUT 254,62.66 MHzNo Wait State
OUT 254,72.13 MHzNo Wait State
OUT 254,81.77 MHzWait State Present
OUT 254,91.52 MHzWait State Present
OUT 254,101.33 MHzWait State Present
OUT 254,111.19 MHzWait State Present
OUT 254,125.32 MHzWait State Present
OUT 254,133.55 MHzWait State Present
OUT 254,142.66 MHzWait State Present
OUT 254,152.13 MHzWait State Present

Port FF - Cassette / Video / Mode

Port FFH (255) is the Model I's combined cassette, video-mode, and (on output) Level II latch port. It is the busiest single port on the machine, used continuously by the cassette routines in the Level II BASIC ROM.

DirectionUse
Input (IN A,(0FFH))Cassette read. Bit 7 is the incoming cassette data bit; the ROM cassette read routines poll this port waiting for clock and data transitions. Bit 6 reflects the 32/64-character video mode latch.
Output (OUT (0FFH),A)Cassette write, video mode, and cassette motor. Bits 0-1 set the cassette output level (the ROM toggles these to write bits), bit 2 controls the cassette relay (motor on/off), and bit 3 selects 32- vs 64-character video mode. Writing here is how the ROM records to tape and switches the display width.

Note: On the Model III and Model 4 the cassette hardware moved into the FC/FD/FE/FF block - see Block FC/FD/FE/FF - Cassette under Ports (Model III and Model 4).

Ports (Model III and Model 4)

Note: Tandy tended to allocate ports in groups of 4.

Port 5F - Sprinter III:

The SPRINTER III was controlled both by a jumper on the card and a software switch. The jumper on the card set the speed multiplier and that was the only way to control that. The software control was just on (high) or off (low).

PortCommandEffect
5FH (95)OUT 95,X (X odd)High speed ON (bit 0 = 1). OUT 95,1 is the usual form.
5FH (95)OUT 95,X (X even)High speed OFF / normal speed (bit 0 = 0). OUT 95,0 is the usual form.

Block 75/79 - Orchestra-90:

The Orchestra-90 is a pair of simple 8-bit digital-to-analog converters - one per stereo channel, with no command, status, or control registers

Each channel's output is the sum of the currently sounding voices: the player accumulates the active voice samples in the accumulator (ADD A,(HL) per voice) and then writes the mixed byte to that channel's port. The two ports are written one after the other

PortUse
79H (121)Orchestra-90 D/A converter, channel A. Write-only. The player writes the mixed sample byte for one stereo channel with OUT (79H),A with 00H corresponding to the converter's mid/silent level.
75H (117)Orchestra-90 D/A converter, channel B. Write-only. The other stereo channel's mixed sample byte is written with OUT (75H),A, immediately following the write to 79H in the same loop iteration.

Note: During playback the driver also manipulates port ECH (the Model 4 control / wait-state register - LD A,10H : OUT (0ECH),A and runs with interrupts disabled. This is timing setup for the cycle-counted sample loop, not a function of the Orchestra-90 hardware itself

7FH - Shuffleboard III Memory Control (CP/M):

The Memory Merchant Shuffleboard III (1981/1982) is a plug-in board that adds a full 64K CP/M 2.2 environment to the Model III. It plugs into the Z-80 socket and one nearby socket with no cut traces or soldering, supplying an onboard Z-80A, 16K of RAM, and a CP/M boot ROM. The board is controlled entirely by writing a single map byte to output port 7FH (127), which reconfigures the Model III's memory map between native TRS-80 and CP/M layouts.

BitFunction
Bit 0Map enable. 0 = TRS-80 memory configuration; 1 = CP/M memory configuration.
Bit 1ROM enable. 0 = CP/M boot ROM disabled; 1 = CP/M boot ROM enabled (mapped over low memory).
Bit 2RAM enable. 0 = 16K Shuffleboard RAM disabled; 1 = 16K Shuffleboard RAM enabled (block 4 at C000H-FFFFH).
Bits 3-7Not used.

Although three bits give eight combinations, only four map-byte values are used:

Map ByteConfiguration
0Normal TRS-80: Level III ROM at 0000H-37FFH, keyboard at 3800H-3BFFH, video at 3C00H-3FFFH, 48K RAM in three blocks from 4000H. Users and programs always see this or map byte 5.
564K CP/M: four 16K RAM blocks filling 0000H-FFFFH (block 4 is the onboard Shuffleboard RAM at C000H-FFFFH).
7CP/M system config I (transparent - used during console/disk I/O): 2K CP/M ROM at 0000H, ROM-expansion reserve to 1FFFH, then RAM blocks 1-4. Never seen by user programs.
3CP/M system config II (transparent - used during console/disk I/O). Never seen by user programs.

80H - Radio Shack Graphics Board (Model III ONLY):

The Model III High-Resolution Graphics Board operates using port-mapped addressing and is based on the MC6845 CRTC chip.

PortUse
80HInput: OPTIONSRD* (Not used)
Output: OPTIONS* (CPU writes to Options Register)

Port 80H Bit Map:
  • Bit 0: GRAPHICS/ALPHA*. Selects which side fo the video output multiplexer is active.
  • Bit 1: Not used
  • Bit 2: X Register Decrement/Increment*
  • Bit 3: Y Register Decrement/Increment*
  • Bit 4: Read X Register Sit/Clock*
  • Bit 5: Write X Register Sit/Clock*
  • Bit 6: Read Y Register Sit/Clock*
  • Bit 7: Write Y Register Sit/Clock*
81HInput: VIDRAMRD* (CPU reads from Video RAM)
Output: VIDRAM* (CPU writes to Video RAM)
82HInput: YREGRD* (CPU reads from the Y Register)
Output: YREG* (CPU writes to the Y Register)
83HInput: XREGRD* (CPU reads from the X Register)
Output: XREG* (CPU writes to the X Register)
84H-87HDual addressed. These ports are mapped to the identical functions as 80H-83H.
88H-8FHCRTC Enable (VSEL*): Ports 88H and 89H are used to program the internal registers of the CRTC. Because A1 and A2 are not terms in the decoding equation, the CRTC ports are dual addressed four times within the 88H through 8FH range.

80H - Radio Shack Graphics Board (Model 4 ONLY):

PortUse
80HInput: Reserved.
Output: Graphics board register
81HInput: Graphics board RAM read.
Output: Graphics board RAM write.
82HInput: Reserved.
Output: Graphics board Y register.
83HInput: Reserved.
Output: Graphics board X register.

80H-83H - Grafyx Solution (Micro-Labs, Model 4):

The Grafyx Solution is a third-party high-resolution graphics board from Micro-Labs, Inc., and is not the Radio Shack graphics board documented above; the two are competing products that happen to share the 80H-8FH port region. On the Model 4 it gives a maximum resolution of 640 x 240 (153,600 individually accessible points) and carries 20,480 bytes of its own read/write memory that does not occupy the TRS-80 address space — 19,200 bytes hold the 640 x 240 bitmap (saved as 75 consecutive 256-byte records) and the remaining 1,280 bytes are free for the user. Because the board's memory is reached only through the X/Y address ports rather than being memory-mapped, it does not conflict with normal TRS-80 RAM.

The board is programmed entirely through four consecutive ports. The manual documents these in decimal (the values used by the BASIC OUT and INP statements); the hexadecimal equivalents are shown for cross-reference.

PortUse
128 (80H)X register. Selects the byte column, value 0-79. Each X value addresses one byte = 8 horizontal dot positions, so the X coordinate (0-639) is divided by 8 and the remainder discarded: OUT 128,INT(X/8).
129 (81H)Y register. Selects the scan line, value 0-239, sent directly: OUT 129,Y.
130 (82H)Data byte (read/write). The 8-bit value at the current X,Y address; bit 7 (value 128) is the leftmost dot, bit 0 (value 1) the rightmost. Read the current byte with A=INP(130), then OR in a bit to set it or AND with 255 minus the bit value to clear it, and write it back with OUT 130,A.
131 (83H)Control register. Selects the display mode and the auto increment/decrement behaviour of the X and Y registers (bit map below).

Control register (port 131 / 83H) bit map: Each function has a "sum value"; add the sum values of every bit you want ON to get the value to output. An asterisk (*) marks an active-low/complemented function as named in the manual.

BitSum valueDefinition
01graphics / alpha*
12640 x 240 / 512 x 192* (resolution / mode select)
24X register dec/inc* (1 selects decrement)
38Y register dec/inc* (1 selects decrement)
416X clock-after-read* (0 clocks after read)
532Y clock-after-read*
664X clock-after-write* (0 clocks after write)
7128Y clock-after-write*

Setting the right bits lets the X and/or Y address auto-increment or auto-decrement after each data read and/or write, so a horizontal or vertical run of bytes can be written without re-sending the address each time. For example, to auto-increment X after every write in 640 x 240 mode, turn on bits 0, 1, 4, 5, and 7, giving 1+2+16+32+128 = 179.

Common control values:

StatementEffect
OUT 131,252Normal display, no hi-res (computer behaves as if the board were not installed)
OUT 131,253Hi-res 640 x 240 (512 x 192 in Model III mode) with text overlay
OUT 131,255Hi-res 640 x 240 with the text screen turned off

The three basic modes — Normal, hi-res with text overlay, and hi-res with text off — are selected by the two least-significant bits of the control byte. Pressing the orange reset key also forces the board back to Normal Display mode. The contents of graphics memory are preserved across mode changes, so a picture re-appears when hi-res is re-enabled.

84H - Operation Register (Model 4 ONLY):

PortUse
84HMod 4 - various controls. 80 micro, March 84, p. 122. Input is reserved. Output:
  • Bits 1-0: Video memory, keyboard memory, and Model III ROM.
    • 1|0 ....
    • 0|0: Model III ROMs Enabled, Video/Keyboard = Model 3
    • 1|0: Model III ROMs Disabled, Video/Keyboard = Model 3
    • 0|1: Model III ROMs Disabled, Video/Keyboard = Model 4 (In)
    • 1|0: Model III ROMs Disabled, Video/Keyboard = Model 4 (Out)
  • Bit 2: Video display mode (0 = 64x16, 1 = 80x24).
  • Bit 3: Reverse Video.
  • Bits 6-4: RAM bank select
    • 6|5|4 ....
    • 0|0|0: Lower 32K Ram in Bank 0, Upper 32K RAM in Bank 1
    • 0|1|0: Lower 32K Ram in Bank 0, Upper 32K RAM in Bank 2
    • 0|1|1: Lower 32K Ram in Bank 0, Upper 32K RAM in Bank 3
    • 1|1|0: Lower 32K Ram in Bank 2, Upper 32K RAM in Bank 1
    • 1|1|1: Lower 32K Ram in Bank 3, Upper 32K RAM in Bank 1
  • Bit 7: Video page select (64x16 mode): 0 = page 0, 1 = page 1.

84H - Operation Register (Model 4P ONLY):

PortUse
84HMod 4P - Various Operation Controls - Write Only
  • Bits 1-0: Mode Select*
    • 0|0: Mode 0
    • 0|1: Mode 1
    • 1|0: Mode 2
    • 1|1: Mode 3
  • Bit 2: Video display mode (0 = 64x16, 1 = 80x24).
  • Bit 3: Reverse Video (0=Inverse Video Disabled, 1=Enabled).
  • Bit 4: Page to be mapped as a new page (0=U64K/L32K, 1=U64K/U32K)
  • Bit 5: Enable/Disable Mapping of a New Page (0=Page Mapping Disabled, 1=Page Mapping Enabled)
  • Bit 6: Point to the page where the new page is to be mapped (0=L64/U32K Page, 1=L64K/L32K Page)
  • Bit 7: Video Memory Page (0=Page 0 of Video Memory, 1=Page 1 of Video Memory)

Mode Select combined with the Port 9C ROM Enabled/Disabled form the memory map for the Model 4P:

Mode84H
Bit 1
84H
Bit 0
9CH
Bit 0
Map
0001
AddressAllocationAmount
0000‑0FFFBoot ROM4K
1000-37FFRAM (Read Only)10K
37E8-37E9Printer Status (Read Only)2
3800-3BFFKeyboard1K
3C00-3FFFVideo1K
4000-FFFFRAM48K
0000
AddressAllocationAmount
0000‑37FFRAM (Read Only)14K
37E8-37E9Printer Status (Read Only)2
3800-3BFFKeyboard1K
3C00-3FFFVideo1K
4000-FFFFRAM48K
1011
AddressAllocationAmount
0000‑0FFFBoot ROM4K
0000-0FFFRAM (Write Only)4K
1000-37FFRAM10K
3800-3BFFKeyboard1K
3C00-3FFFVideo1K
4000-FFFFRAM48K
1010
AddressAllocationAmount
0000‑37FFRAM14K
3800-3BFFKeyboard1K
3C00-3FFFVideo1K
4000-FFFFRAM48K
210N/A
AddressAllocationAmount
0000‑F3FF RAM64K
F400-F7FFKeyboard1K
F800-FFFFVideo2K
311N/A
AddressAllocationAmount
0000‑FFFFRAM64K

Block 88/89/8A/8B - CRT Control

PortUse
88HCRT controller control register.
89HCRT controller data register.
8AHCRT controller control register.
8BHCRT controller data register.

Block 8C/8D/8E/8F - Graphics Board:

PortUse
8CH-8FHGraphics board select 2.

Block 90/91/92/93 - Sound Port (Model 4 ONLY):

PortUse
90HModel 4 sound port. Any of the sound routines used on the Model I and Model III that uses port FFH can be changed to this and then the Model 4's built in speaker can be used! Only BIT 0 was used for output: 0=Low, 1=High.

Block 9C/9D/9E/9F - Boot ROM (Model 4P Only):

PortUseReadWrite
9CH Switch the Model 4P Boot ROM in or OUT. N/A Bit 0: 0=Boot ROM Disabled, 1=Boot ROM Enabled

Block B0-BC - NewClock-80 (Model III and Model 4):

The Alpha Products NewClock-80 uses the identical port set and bit layout on the Model III and Model 4 as it does on the Model I - the High Port configuration occupies ports 176-188 (B0H-BCH), one BCD digit per port, each masked with AND 15 (or AND 3 for the capped tens digits). For the full register map, status-bit definitions, and read/set examples, see the NewClock-80 entry under Ports (Model I). The Model III version of the board also works in the Model 4.

Enabling the Ports (Model III and Model 4)

Unlike the Model I, the Model III and Model 4 do not expose the external I/O bus by default. Before any INP or OUT to the NewClock-80 ports will work, the external I/O bus must be enabled by setting bit 4 of Port ECH (236 decimal). From BASIC:

OUT 236, 16

That enables the ports until the next OUT 236 clears the bit. BASIC re-issues an OUT 236 each time a program exits to the >_ prompt, which disables them again. To stop BASIC from doing this, on a Model III you can:

POKE 16912, 16

Do not execute that POKE on a Model I. Because Port ECH also controls cassette, video, character set, and (on the Model 4) CPU clock speed, drivers should read the current ECH shadow value, OR in only bit 4, and write the whole byte back rather than overwriting the other control bits. See the Port ECH entry for the full bit map.

Assembly-Language Enable

In machine code the same enable is done by OR-ing bit 4 (10H) into the cached ECH control byte and writing it out. On the Model III the ECH shadow is kept at 4210H; on the Model 4 it is at 0076H. For example (Model III):

LD   A,(4210H)   ; current ECH control byte
OR   10H         ; set bit 4 (enable I/O bus)
LD   (4210H),A   ; update the shadow
OUT  (0ECH),A    ; enable external I/O ports

The clock digits are then read with IN A,(C) stepping C down through the port addresses, masking each nibble (AND 0FH, or AND 03H for the day-tens and hour-tens digits) and combining the tens and ones digits into a BCD value.

B6H - ARCNET (Model 4P Only):

PortUse
B6HArcnet Board (Input/Output).

C0H-CFH - Hard Drive:

PortUse
C0HWrite Protection.
Write/Output: Reserved.
Read/Input: Hard disk write protect:
  • Bit 0 (INTRQ): Interrupt Request
  • Bit 1 (HWPL): If set, at least one hard drive is currently write protected
  • Bit 4 (WPD4): If set, hard drive 4 is currently write protected
  • Bit 5 (WPD3): If set, hard drive 3 is currently write protected
  • Bit 6 (WPD2): If set, hard drive 2 is currently write protected
  • Bit 7 (WPD1): If set, hard drive 1 is currently write protected
C1HHard disk controller board control register (Read/Write). ROM equate: HCNTL.
  • Bit 2: RUMORED to enable wait state support on a 8X300 Controller Board
  • Bit 3: If set, enable controller
  • Bit 4: If set, reset controller
Known command values used by the Network 4 Transporter ROM (SERVR routine):
  • 10H (0001 0000): Wake up / assert reset — written first to power on the hard disk controller
  • 0CH (0000 1100): Software reset — written after the wake-up delay to reset the controller (bits 3 and 2 set)
  • 16H: Restore, slow mode — issued as the first seek command after reset; the ROM polls HSTAT (CFH) bit 7 via RLA in a tight loop until the busy flag clears before issuing the next command
  • 10H: Restore, fast mode — issued immediately after the slow restore completes
Note: The Network 4 ROM refers to this port by the equate name HCNTL and uses it exclusively during the server-side hard disk initialisation sequence (SERVR). It is not used in the client-side network boot path.
C2H-C3HModel II with 8x300 Controller - Hard disk device ID register.
Output: Reserved.
Input: Hard disk device ID register.
C4HModel II with 8x300 Controller - Hard disk CTC channel 0.
C5HModel II with 8x300 Controller - Hard disk CTC channel 1.
C6HModel II with 8x300 Controller - Hard disk CTC channel 2.
C7HModel II with 8x300 Controller - Hard disk CTC channel 3.
C8HHard Disk Data Register (Read/Write).
Register 0 for WD1010 Winchester Disk Controller Chip.
C9HHard Disk Write Pre-Comp Cyl.
Register 1 for WD1010 Winchester Disk Controller Chip.
Write/Output: The RWC start cylinder number = The value stored here divide by 4.
Read/Input: Error Register:
  • Bit 0: Per the WD1010-00 Spec Sheet, this is DAM Not Found. The Radio Shack 15M HD Service Mauals says that this bit is reserved and forced to 0
  • Bit 1: Track 0 Error (Restore Command)
  • Bit 2: Aborted Command
  • Bit 4: ID Not Found Error
  • Bit 5: CRC Error - ID Field
  • Bit 6: CRC Error - Data Field
  • Bit 7: Bad Block Detected
CAHHard Disk Sector Count (Read/Write).
Register 2 for WD1010 Winchester Disk Controller Chip. This is used only for multiple sector access. Internally decrements when used.
CBHHard Disk Sector Number (Read/Write).
Register 3 for WD1010 Winchester Disk Controller Chip.
CCHHard Disk Cylinder LSB (Read/Write).
Register 4 for WD1010 Winchester Disk Controller Chip.
CDHHard Disk Cylinder MSB (Read/Write).
Register 5 for WD1010 Winchester Disk Controller Chip. Since the maximum number of cylinders is 1024, only Bits 0 and 1 are used (1023 = 0000 0011 + 1111 1111).
CEHHard Disk Sector Size / Drive # / Head # (Read/Write).
Register 6 for WD1010 Winchester Disk Controller Chip.
  • Bits 0-2: Head Number (0-7)
  • Bits 3-4: Drive Number (00=DSEL1, 01=DSEL2, 10=DSEL3, 11=DSEL 4)
  • Bits 5-6: Sector Size (00=256, 01=512, 10=1024, 11=128)
  • Bit 7: Extension (if this is set, Error Checking and Correction codes are in use and the R/W data [sector length + 7 bytes] do not check or generate CRC)
CFH Hard Disk Error Status Register (Read Only).
Register 7 for WD1010 Winchester Disk Controller Chip.
Read = Status Register  |  Write = Command Register (Instruction Set).
Read / Input — Status Register
BitNameMeaning
7BusyController busy
6Drive ReadyDrive ready (DRDY)
5Write FaultWrite fault (WF)
4Seek CompleteSeek complete (SC)
3Data RequestBuffer ready for transfer (DRQ)
2Reserved (forced to 0)
1Cmd In ProgressCommand in progress (CIP)
0ErrorError exists (OR of bits 1–7)
Write / Output — Command Register Instruction Set
Command Hex
(field=0)
Bits
7654 3210
Restore10H 0001 dcba
Seek70H 0111 dcba
Read Sector20H 0010 im00
Write Sector30H 0011 0m00
Scan ID40H 0100 0000
Write Format50H 0101 0000
d c b a Step rate field (Restore & Seek):
  • 0000 = 35 µs
  • 00011111 = 0.5–7.5 ms in 0.5 ms steps
i Interrupt enable status (Read Sector):
  • 0 = interrupt when the data request line (DRQ*) is enabled
  • 1 = interrupt at end of command
m Multiple sector flag (Read & Write Sector):
  • 0 = one sector
  • 1 = multiple sectors
The 4P ROM is known to send three commands to this port: 16H Restore, 20H Read one sector, 70H Seek.

Block D0/D1/D2/D3 - Network 4 (Omninet / Corvus Transporter):

Network 4 uses an Omninet RS-422 network interface (the Corvus Transporter chip). The four ports D0–D3 serve overlapping dual roles depending on read vs. write direction and the current state of the Transporter's internal 16-bit address pointer. Port equates and all behavioural detail below are confirmed by the Network 4 Transporter ROM disassembly (ROM Version 01.01.00).

PortEquateDirUse
D0HOMOUTOutputOutput to Transporter with automatic address pointer increment. Each byte written advances the internal pointer by one. Used with the Z80 OTIR instruction to load commands and data into the Transporter's zero-page buffer before issuing a strobe.
OMINPLInputInput from Transporter with automatic address pointer increment. Used with the Z80 INIR instruction to burst-read a full 256-byte sector from the Transporter data area (MSB pointer pre-set to 04H) directly into a memory buffer in one operation.
D1HOLSBOutputOmninet Address Pointer: LSB. Sets the low byte of the Transporter's internal 16-bit address pointer. The LSB must always be written before the MSB. Writing 00H to both OLSB (D1H) and OMSB (D3H) resets the pointer to zero (the start of the Transporter's zero-page command/response buffer).
D2HOMINInputInput from Transporter without automatic pointer increment. Used to poll a specific byte in the Transporter's buffer — typically a result/response byte — in a tight loop until it changes from FFH (the Transporter's "not yet ready" sentinel), as implemented by the OMWAIT routine. After the value changes from FFH, OMWAIT issues four EX (SP),HL delay instructions before re-reading to guard against the value being mid-transition, then returns the final byte in register A.
OSTROBOutputOmninet Strobe Port. Writing to this port issues a command strobe to the Transporter, causing it to execute the command loaded into its buffer via OMOUT/D0H. The STROBE routine issues two zero-valued strobes (for address 0) followed by the caller's actual strobe value; before each write it polls OMSTAT (D3H input) in a tight loop, shifting bit 7 into carry via RLA and looping while carry is clear, ensuring the Transporter is ready before each strobe.
D3HOMSBOutputOmninet Address Pointer: MSB. Sets the high byte of the Transporter's internal address pointer. Always write OLSB (D1H) first, then OMSB. To point at the Transporter's received-data area, write 04H here (full pointer = 0400H).
OMSTATInputTransporter Status Register. Bit 7 is the ready flag. The STROBE routine reads this port and executes RLA to shift bit 7 into the carry flag; the loop repeats while carry is clear (NC = not ready). When carry is set the Transporter is ready to accept a strobe write on D2H.

Boot-time initialization sequence:

  1. Port ECH bit 4 is set to enable the I/O bus: the byte at RAM address 4210H is OR'd with 10H and written back to ECH, then stored.
  2. The Transporter is reset: address pointer is set to 0 (OUT 00H to D1H, then D3H), FFH is written as the response code (OUT to D0H), then 20H (ASCII space = Reset Command) followed by three zero bytes for the response address. A strobe is issued to station address 1, then OMWAIT is called with A=0 to wait for the response at zero-page offset 0. The returned value in A is this station's Transporter address.
  3. If the address equals 63H (ASCII '?') the machine is the network server and jumps to the hard-disk boot path (SERVR). Otherwise it reads the boot-pointer sector over the network (OREAD routine, 8 retries with random back-off on error) and loads the appropriate boot volume.

Special flag at address 6FF0H: On startup the ROM reads the 16-bit word at 6FF0H and compares it with 5041H (ASCII 'PA'). If they match, the WAITR delay routine runs for approximately 4 seconds (inner loop counts 1–65536, outer loop repeats 32 times) to protect against rapid power-cycling. After the flag check, DE (= 5041H) is written to 6FF0H to set the flag for the next boot. Once the boot file has been fully loaded, the two-byte start address extracted from the load record is written back to 6FF0H, clearing the flag, and execution jumps there.

Block E0/E1/E2/E3: Maskable Interrupts:

PortUseInput/ReadOutput/Write
E0HMaskable Interrupt
  • Bit 0 - 3365H (Cassette Routine with E set to HIGH; Rising Edge Interrupt)
    Not applicable on the Model 4P
  • Bit 1 - 3669H (Cassette Routine with E set to LOW; Falling Edge Interrupt)
    Not applicable on the Model 4P
  • Bit 2 - 4046H (Real Time Clock Interrupt)
  • Bit 3 - 403DH (External I/O Bus Interrupts)
  • Bit 4 - 4206H (RS-232 Transmit Holding Register is Empty)
  • Bit 5 - 4209H (RS-232 Receive Data Register is Full)
  • Bit 6 - 4040H (RS-232/UART Error - Parity Error, Framing Error, or Data Overrun)
  • Bit 7 - 4043H (Reserved)
Inputting from each bit would be the status of that item. 0=False, 1=True Outputting to each bit would be 0=Disable, 1=Enable.
So outputting Bit 2 = 0 would disable the reasl time clock interrupt, and 1 = enabled.

Block E4/E5/E6/E7: Non-Maskable Interrupts:

PortUseInput/ReadOutput/Write
E4H Select NMI options/read NMI status
  • Bit 0: RESERVED
  • Bit 1: RESERVED
  • Bit 2: RESERVED
  • Bit 3: RESERVED
  • Bit 4: RESERVED
  • Bit 5: Reset Status
    (0 = False/Asserted, 1 = True/Negated)
  • Bit 6: DRQ Status
    (0 = False/Asserted, 1 = True/Negated). The Model 4P calls this "Motor Off"
  • Bit 7: INTRQ Status
    (0 = False/Asserted, 1 = True/Negated)
  • Bit 0: RESERVED
  • Bit 1: RESERVED
  • Bit 2: RESERVED
  • Bit 3: RESERVED
  • Bit 4: RESERVED
  • Bit 5: RESERVED
  • Bit 6: Enable or Disable DRQ Interrupt
    (0 = Disable, 1 = Enable)
  • Bit 7: Enable or Disable INTRQ Interrupt
    (0 = Disable, 1 = Enable)

Block E8/E9/EA/EB - RS-232:

Note: A Model I will set itself up based on the switches on the card. A Model III will default to 300 baud, 8 Bit Word, 1 Stop Bit, and No Parity.

PortUseWrite/Output
Master Reset
Read/Input
Modem Status
E8HRS-232 Status Register and Master ResetAny byte will reset the RS-232
  • Bit 0: Copy of serial input pin UART (Pin 20 of the DB-25)
  • Bit 1: UART Control Register (0=Disable, 1=Enable)
  • Bit 4: Ring Indicator (Pin 22 of the DB-25)
  • Bit 5: Carrier Detect (Pin 8 of the DB-25)
  • Bit 6: Data Set Ready (Pin 6 of the DB-25)
  • Bit 7: Clear to Send (Pin 5 of the DB-25)
PortUseWrite/OutputRead/Input
E9HRS-232 Baud Rate Select and Sense Switches
  • 0000 0000 (00H) - Baud: 50
  • 0001 0001 (11H) - Baud: 75
  • 0010 0010 (22H) - Baud: 100
  • 0011 0011 (33H) - Baud: 134.5
  • 0100 0100 (44H) - Baud: 150
  • 0101 0101 (55H) - Baud: 300
  • 0110 0110 (66H) - Baud: 600
  • 0111 0111 (77H) - Baud: 1,200
  • 1000 1000 (88H) - Baud: 1,800
  • 1001 1001 (99H) - Baud: 2,000
  • 1010 1010 (AAH) - Baud: 2,400
  • 1011 1011 (BBH) - Baud: 3,600
  • 1100 1100 (CCH) - Baud: 4,800
  • 1101 1101 (DDH) - Baud: 7,200
  • 1110 1110 (EEH) - Baud: 9,600
  • 1111 1111 (FFH) - Baud: 19,200
RESERVED. Used only on the Model I as it reads the dip switches as follows:
  • Bit 0-2 = Baud Rate Select (50-1200; 5=300 Baud; 7=1200 Baud)
  • Bit 4 = Parity (0 = Enabled, 1 = Disabled)
  • Bits 5-6 = Word Length Select (00 = 5, 01=6, 10=7, 11=8)
  • Bit 7 = Parity (0 = Odd, 1 = Even)
PortUseWrite/Output
UART Control Register
Read/Input
UART Status Register
EAHRS-232 UART Control Register and Status Register
  • Bit 0: Data Terminal Ready (1=DTR Off) (Pin 20 of the DB-25)
  • Bit 1: Request to Send (1=RTS Off) (Pin 4 of the DB-25)
  • Bit 2: Break (1=Send Break Signal)
  • Bit 3: Parity Enable (0 = Enable Parity, 1 = Disable Parity)
  • Bit 4: Stop Bits (0 = 1 Stop Bit, 1 = 2 Stop Bits)
  • Bits 5-6: Select Word Length (00 = 5, 01 = 7, 10 = 6, 11 = 8)
  • Bit 7: Parity (0 = Odd, 1 = Even)
  • Bits: 0-2 = Unused
  • Bit 3: Parity Error (1=True)
  • Bit 4: Framing Error (1=True)
  • Bit 5: Overrun Error (1=True)
  • Bit 6: Data Sent (1=True)
  • Bit 7: Data Ready (1=True)
PortUseWrite/Output
Read/Input
EBHRS-232 RegisterUART Transmit Holding RegisterUART Receive Holding Register

Misc:

PortUseWrite/Output
Read/Input
ECH Various Controls
  • Bit 0: Supposedly not used, but is on the Model III to test to see if the clock is on [0=off, 1=on].
  • Bit 1: Cass motor [0 = on, 1 = off]
    On the Model 4P this turns sound on (0) and sound off (1)
  • Bit 2: Double width [0 = normal (64 or 80), 1 = double (32 or 40)]
  • Bit 3: Alternate character set [0 = Disabled (Kana), 1 = Enabled (Misc)]
  • Bit 4: External I/O bus [0 = Disabled, 1 = Enabled]
  • Bit 5: Video waits [0 = disable, 1 = enable]
    On the Model 4P this is not used
  • Bit 6: CPU clock speed [0 = 2 mhz, 1 = 4 mhz] - Model 4 and 4P ONLY
  • Bit 7: Reserved
Clear the Real Time Clock Interrupt

A quick note on Bit 5 (thanks to George Phillips). Bit 5 of Port ECH is supported on both the Model III and Model 4 and is set to ENABLE at 345CH. There is a latch connected to this bit that always has the current value. This latch has a wire connecting to both the Z-80 bus and the video circuitry which which mediates acccess to video RAM, so the processing of this bit is actually handled by separate hardware and not the ROM.

An example of this bit can be shown via the short program 10 CLS:FORI=0TO1023:POKE15360+I,191:NEXT. If run once with POKE 16912,0 and run again with POKE 16912,32, hash lines as the screen refreshes can be seen in one but not the other.

The Seatronics Super Speed-Up Board uses bits 6 and 7 of ECH to select the Z-80 Clock Rate:

Bit 6Bit 7Speed
002 Mhz
104 Mhz
015.3 Mhz
118 Mhz

Floppy Drive:

PortUse
F0HFDC Command/Status:
Input (depends on what the inquiry is in relation to: I=Restore, Seek, and Step, II = Read/Write Sector, III = Read/Write Track and Read Address:
  • Bit 0:
    • [I] BUSY = HIGH indicates command in progress
    • [II/III] Busy = HIGH indicates command Is under execution.
  • Bit 1:
    • [I] INDEX = HIGH indicates index mark detected from drive
    • [II/III] DATA REQUEST = HIGH indicates index mark detected from drive.
  • Bit 2:
    • [I] TRACK 0 = HIGH indicates Read/Write head is positioned to Track 0
    • [II/III] LOST DATA = HIGH indicates the computer did not respond to DRQ in one byte time.
  • Bit 3:
    • [I] CRC ERROR = HIGH indicates a CRC error was found in the ID field
    • [II/III] CRC ERROR = If BIT 4 is set, an error is found in one or more ID fields otherwise it indicates error in data field.
  • Bit 4:
    • [I] SEEK ERROR = HIGH indicates the desired track was not verified
    • [II/III] RECORD NOT FOUND = HIGH indicates the desired track, sector, or side were not found.
  • Bit 5:
    • [I] HEAD LOADED = HIGH indicates the head is loaded and engaged
    • [II/III] RECORD TYPE/WRITE FAULT = On Read Record, HIGH indicates the record-type code from data field address mark (1: Deleted Data Mark, 0: Data Mark). On any write, HIGH indicates a Write Fault.
  • Bit 6:
    • [I] PROTECTED = HIGH indicates Write Protect is activated
    • [II/III] PROTECTED = On Read Record or Read Track, not used. On any write: it indicates a Write Protect.
  • Bit 7: NOT READY = HIGH indicates the drive is not ready

Output:

Bits   765 | 4 | 3 | 2 | 1 0
00-0F: 000 | 0 | h | V | R R = Restore
10-1F: 000 | 1 | h | V | R R = Seek
20-3F: 001 | T | h | V | R R = Step
40-5F: 010 | T | h | V | R R = Step In
60-7F: 011 | T | h | V | R R = Step Out
80-9E: 100 | m | S | E | C 0 = Read Sector
A0-BF: 101 | m | S | E | C A = Write Sector
C0,C4: 110 | 0 | 0 | E | 0 0 = Read Address
D0-DF: 110 | 1 | x | x | x x = Force Interrupt
E0-E4: 111 | 0 | 0 | E | 0 0 = Read Track
F0-F4: 111 | 1 | 0 | E | 0 0 = Write Track
									

Legend:

RR = Stepping Motor Rate (00=6ms, 01=12ms, 10=20ms, 11=30ms)

h = Head Load Flag (1: load head at beginning, 0: unload head)

V = Track Number Verify Flag (0: no verify, 1: verify on dest track)

T = Track Update Flag (0: no update, 1: update Track Register)

A = Data Address Mark (0: FB, 1: F8 (deleted DAM))

C = Side Compare Flag (0: disable side compare, 1: enable side comp)

E = 15 ms delay (0: no 15ms delay, 1: 15 ms delay)

S = Side Compare Flag (0: compare for side 0, 1: compare for side 1)

m = Multiple Record Flag (0: single record, 1: multiple records)

xxxx = Interrupt Condition Flags (1111 = Immediate interrupt, Index pulse, Ready to not ready transition, Not ready to ready transition)

Output Examples:

  • 00H: Restore
  • 80H (1000 0000): Read single sided single sector
  • A0H (1010 0000): Write single normal sector
  • A1H (1010 0001): Write single sector read protect
  • C0H (1100 0000): Read address, no delay
  • D0H (1101 0000): Reset; puts FDC in mode 1 (INTRQ; "000" terminate command without interrupt)
  • E0H (1110 0000): Read track, no delay
  • F0H (1111 0000): Write track, no delay
F1HFDC Track/Cylinder Register (regardless if READ or WRITE)
F2HFDC Sector Register (regardless if READ or WRITE)
F3HFDC Data Register (the data byte to be read or WRITTEN to disk)
F4HSelect drive and options.
Output/Write:
  • Bit 0: Drive 0 Select (0=No Select, 1=Select)
  • Bit 1: Drive 1 Select (0=No Select, 1=Select)
  • Bit 2: Drive 2 Select (0=No Select, 1=Select)
  • Bit 3: Drive 3 Select (0=No Select, 1=Select)
  • Bit 4: Side Select (0 = Select Side 0, 1 = Select Side 1)
  • Bit 5: Write Precompensation (0 = Disable WP, 1 = Enable WP)
  • Bit 6: Wait State Generation (0 = Disable WSG, 1 = Enable WSG)
  • Bit 7: Density Select (0 = Single/FM, 1 = Double/MFM)

Block F8/F9/FA/FB - Printer:

PortUseInput/Read
LPIN*
Output/Write
LPOUT*
F8 Line printer address port:
  • Bit 4: Printer Fault (1=True, 0=False)
  • Bit 5: Device Selected (1=True, 0=False)
  • Bit 6: Out of Paper (1=True, 0=False)
  • Bit 7: Busy (1=True, 0=False)
ASCII Byte to send to the line printer to be printed

Block FC/FD/FE/FF - Cassette:

PortUseInOut
FC/FD/FE/FF Cassette port Bit 7: Data Bit (0 = Low, 1 = High)
  • Bits 0-1: 00=0.85 Volts
  • 10=0.0 Volts01 = 0.46 Volts

Model 4P: Bit 0 is the cassette output level, no other bit is used, as the Model 4P does not support cassette storage, this port is only used to generate sound that was to be output via cassette port. The Model 4P sends data to onboard sound circuit.

Memory Mapped I/O Devices

AddressUse
3000-37DBNO MEMORY here at all (but see Tic-Toc-80 below, which decodes 37DC-37DF)
37DC-37DFTic-Toc-80 clock (B.T. Enterprises, third-party Model I add-on)
37E0Disk drive select latch
37E1-37EFTRSDOS v2.3 Disk Registers
37E4Cassette drive latch (Select Cassette Drive)
37E8Line printer data port when storing
37E8Line printer status port when loading
37ECDisk command register when storing
37ECDisk status register when loading
37EDDisk track register
37EEDisk sector register
37EFDisk data register
3801-3880Keyboard memory
3C00-3FFFVideo display memory

37DC-37DF - Tic-Toc-80 Clock (Model I)

The Tic-Toc-80 from B.T. Enterprises (Centereach, NY) is a battery-backed real-time clock for the TRS-80 Model I, built around the same OKI MSM5832 RTC chip used by the NewClock-80. Unlike the NewClock-80, it is not accessed through Z-80 I/O ports: it decodes four memory-mapped addresses, 37DCH-37DFH (14300-14303), and is driven through an Intel 8255 PPI (AM8255APC) that latches stable control signals for the slow clock chip - so it keeps working even with speed-up mods installed. The board plugs onto the Model I Expansion Interface "Screen Printer Port" / I/O bus and requires no modifications on most machines.

Note: These four addresses fall inside the 3000H-37DFH region listed above as unused. There is no internal memory there, but an external board such as the Tic-Toc-80 can decode addresses in that range. The Tic-Toc-80 also requires +5V on pin 39 of the Screen Printer Port (pin 37 is ground); Radio Shack cut this trace on some buffered-cable Expansion Interfaces, and it must be restored for the board to work.

Interface Registers

AddressUse
37DCH (14300)Data register. Reads or writes the currently selected MSM5832 register. Each register returns a BCD digit in the low nibble; mask with AND 0FH.
37DDH (14301)Register-select. Write the MSM5832 register number (0-CH) here to choose which time/date digit the data register accesses.
37DEH (14302)Read/Write control (to the time processor). Write 20H (32) to select read mode, or 50H (80) to select write mode.
37DFH (14303)Interface-chip control register. Write 90H (144) for normal/read mode - this is the idle state and protects the clock from accidental changes by a runaway program. Write 80H (128) to enable loading the time-processor register order.

Access Sequence

To read the clock: set the interface chip to read (37DFH), set the time processor to read (37DEH), select a register (37DDH), then read the digit from the data register (37DCH); repeat the select/read pair for each register. To set the clock the sequence is the same but with write values, finishing by returning both the time processor and the interface chip to read mode.

Register Map (MSM5832)

Thirteen registers (0-CH) hold the time and date as BCD digits in the low nibble. Three registers pack extra status bits into the upper nibble of the tens digit, the same way the underlying MSM5832 does:

RegisterFunctionComment
0 / 1Seconds (units / tens)Tens range 0-5. Cannot be set to a nonzero value - the chip resets seconds to 0 on write.
2 / 3Minutes (units / tens)Tens range 0-5.
4 / 5Hours (units / tens)Register 5 also carries the mode bits: bit D2 = AM/PM (1=PM, 0=AM, 12-hour mode only), bit D3 = 12/24-hour mode (1=24-hour, 0=12-hour). These must be written together with the hour-tens digit as one word.
6Day of weekSingle register, value 0-6 (0=Mon ... 6=Sun).
7 / 8Day of month (units / tens)Register 8 bit D2 = Leap-Year flag (1=leap year), written together with the day-tens digit as one word.
9 / AMonth (units / tens)
B / CYear (units / tens)

The supplied SETIME2/SRC driver reads each register pair, masks the low nibble, and converts the two BCD digits to a single binary value (MSD x 10 + LSD via repeated ADD A,A shifts) before storing the