TRS-80 – Internals – Device Control Blocks

Device Control Blocks

There are 3 main DCB’s – Keyboard, Video, and Printer, each of which starts with a recognition code followed by the routine address and then some variable storage.

The Numeric Indentifier Value serves a dual purpose in that Bits 1 and 0 signify whether the device can be used for input and/or output. Bit 1 (the left bit) covers OUTPUT, and Bit 0 (the right bit) covers INPUT. High means can be used, and low means cannot.


Keyboard DCB

Model I

4015H
Recognition Code. Keyboard is 01. 01 in Binary is “01” to designate that the Keyboard cannot be used for output, but can be used for input.
4016H-4017H
Keyboard Driver Address in LSB, MSB Format.
  • Level II = 03E3H
  • DOS = 4516H
  • Exatron = 375CH.
4018H-401AH
Unsused
401BH-401CH
DCB ASCII Identifier Value of “KI”.

Model III

4015H
Recognition Code. Keyboard is 01.
4016H-4017H
Keyboard Driver Address in LSB, MSB Format.
  • Level II = 3024H
  • DOS = 44EBH
4018H
Status of RIGHT SHIFT key.
4019H
Status of CAPS LOCK.
  • 0 = Upper Case
  • Non-0 = Lower Case
401AH
Interrupt Counter to Flash Cursor. Counts to 7.
401BH
Flag byte for cursor change.
  • 0 = SPACE
  • 1 = Cursor Character
401CH
Cursor Blink Flag.
  • 0 = Blink
  • Non-0 = No Blink

Video Display DCB

Model I

401DH
Recognition Code. Video Display is 07, which, in Binary, gives the rightmost 2 digits as “11” to designate that the Video display can be used for both output and input.
401EH-401FH
Video Display Driver Address in LSB, MSB Format.
  • Level II = 0458H
  • DOS = 4505H
  • Exatron = 0458H
4020H-4021H
Cursor Position in LSB, MSB Format.
4022H
Storage for the character at the cursor.
4023H-4024H
DCB ASCII Identifier Value of “DO”.

Model III

401DH
Recognition Code. Video Display is 07.
401EH-401FH
Video Display Driver Address in LSB, MSB Format. Default is 0473H.
4020H-4021H
Cursor Position in LSB, MSB Format.
4022H
Storage for the character at the cursor. If 0, Blink is INACTIVE.
4023H
Cursor Character in ASCII. Acceptable values between 32 and 255. Default is 176.
4024H
Character Set In Use.
  • 0 = Regular Character Set
  • 1 = Alternate Character Set

Line Printer DCB

Model I

4025H
Recognition Code. Line Printer is 06, which, in Binary, gives the rightmost 2 digits as “10” to designate that the Line Printer can be used for output, but cannot be used for input.
4026H-4027H
Line Printer Driver Address in LSB, MSB Format. Default is 058DH.
4028H
Storage for MAXIMUM LINES PER PAGE + 1.
4029H
Storage for NUMBER OF LINES ALREADY PRINTED + 1.
402AH
Unused
401BH-401CH
DCB ASCII Identifier Value of “PR”.

Model III

4025H
DCB Numeric Identifier Value. Line Printer is 06.
4026H-4027H
Line Printer Driver Address in LSB, MSB Format. Default is 03C2H.
4028H
Storage for MAXIMUM LINES PER PAGE + 1.
4029H
Storage for NUMBER OF LINES ALREADY PRINTED + 1.
402AH
Storage for CURRENT PRINTER TAB POSITION.
402BH
Storage for MAXIMUM LINE LENGTH – 2.
402CH
Default Value for MAXIMUM LINE LENGTH – 2.

RS-232 DCB (Model III Only)

RS-232 INPUT DCB

41E5H
Recognition Code. Set at 01. 01 in Binary is “01” to designate that the RS-232 Input DCB cannot be used for output, but can be used for input.
41E6H-41E7H
RS-232 INPUT Driver Address in LSB, MSB Format. Default is 301EH, which jumps to 365AH.
41E8H
Storage for INPUT BUFFER (1 byte).
41E9H
Control Bytes:
  • Bit 2 = RS-232 On/Off
  • Bit 1 = Wait/No Wait
41EAH
Control Bytes
41EBH-41CAH
DCB ASCII Identifier Value of “RI”.

What does the routine do?

  1. Zero the RS-232 input buffer at 41E8H.
  2. Test Bit 2 of the control bytes (41E9H) to see if the RS-232 is on or off, aborting if off, and, at 3667H, polling the RS-232 Status Register of 0EAH otherwise.
  3. Bit 7 is tested to see if DATA READY is on or off, and if data is ready, jumps out of the loop to 367AH. Otherwise, Bit 1 is tested to see the status of WAIT/NO WAIT, and if NO WAIT is set, exits. If WAIT was set, then the BREAK key is checked, exiting if hit, and endlessly circling back to 3667H to poll again otherwise.
  4. At 367AH, the RS-232C Data Register at port 0EBH is polled, and the result put into the RS-232 INPUT BUFFER memory location of 41E8H before exiting.

RS-232 OUTPUT DCB

41EDH
Recognition Code. Set at 02. 02 in Binary is “10” to designate that the RS-232 Output DCB can be used for output, but cannot be used for input.
41EEH-41EFH
RS-232 OUTPUT Driver Address in LSB, MSB Format. Default is 3021H, which jumps to 3680H.
41F0H
Storage for OUTPUT BUFFER (1 byte).
41F1H
Control Bytes:
  • Bit 2 = Driver On/off
  • Bit 1 = Wait/no Wait
41F2H
Control Bytes
41F3H-41F4H
DCB ASCII Identifier Value of “RO”.

What does the routine do?

  1. Bit 2 of 41F1H is tested to see if the RS-232 is active, aborting if not.
  2. Polling the RS-232 UART Control Register/Status port 0EAH.
  3. If the READY TO SEND bit is high, jump to 369C, and otherwise test bit 1 of 41F1H to see if the RS-232 is active (aborting if not and checking for a BREAK if it is). So long as BREAK wasn’t hit, endlessly loop back to the poll.
  4. At 369CH, the RS-232 output buffer at 41F0H is checked to see if there is a character waiting to output. If yes, then that byte is sent to port 0EBH; otherwise the value held in Register C is sent.
  5. The output buffer is then set to 00H and the routine exits.

RS-232 Initialization DCB

41F5H
Recognition Code. Set at 02. 02 in Binary is “10” to designate that the RS-232 Initialization DCB can be used for output, but cannot be used for input.
41F6EH-41F7H
RS-232 Initialization Driver Address in LSB, MSB Format. Default is 301BH, which jumps to 35FBH.
41F8H
Storage for BAUD RATE (1 byte) Bits 7-4 for SEND BAUD and Bits 3-0 to RECEIVE BAUD.
41F9H
Storage for Parity, Word Length, and Stop Bits.
  • Bit 7: 0=Odd Parity, 1=Even Parity
  • Bits 6-5: 00=5 Bit Word, 01=6 Bit Word, 10=7 Bit Word, 11=8 Bit Word.
  • Bit 4: 0=1 Stop Bit, 1=02 Stop Bits.
  • Bit 3: 0=Enable Parity, 1=Disable Parity.
  • Bit 2: 0=Transmitter OFF, 1=Transmitter ON
  • Bit 1: 0=Set DTR Low (Ready), 1=Set DTR High.
  • Bit 0: 0=Set RTS Signal Low (Data is Ready), 1=Set RTS Signal High (No Active Request).
41FAH
Wait for Serial I/O: 0=Do Not Wait, Non-Zero=Wait.
41FBH-41FCH
DCB ASCII Identifier Value (2 bytes). Keyboard is “RN”.

What does the routine do?

  1. Interrupts are disabled.
  2. The RS-232 UART Control Register/Status port (0EAH) is polled into Register A to make sure that the RS-232 exists; exiting if it doesn’t.
  3. If the RS-232 exists, Register A is XOR’d just to get a non-zero value into A, which is then sent to the RS-232 Status Register and Master Reset port of 0E8H, resetting it.
  4. The Baud Rate is the then fetched from 41F8H and sent to the RS-232 Baud Rate Select port of 0E9H.
  5. The configuration values at 41F9H are fetched and, so long as they weren’t a 0, are sent to the RS-232 UART Control Register/Status port of 0EAH.
  6. 41E8H-41EAH (RS232 Input DCB buffer and control bytes) and 41F0H-41F2H (RS232 Output DCB buffer and control bytes) are then zeroed.
  7. The WAIT SWITCH at 41FAH is then checked and if it was not zero, Bit 1 of 41E9H and 41F1H are set to match and Bit 2 of 41E9H and 41F1H are set to indicate the RS-232 is active. The RS-232 Status Register of port 0E8 is then polled into Register A.
  8. Finally, Interrupts are re-enabled.

ROUTE DCB (Model III Only)

421DH
Recognition Code. Set at 01. 01 in Binary is “01” to designate that the ROUTE DCB cannot be used for output, but can be used for input.
421EH-421FH
Route Driver Address in LSB, MSB Format. Default is 3739H.
4220H-4221H
Route DESTINATION 2 letter Identifier Value.
  • KI = Keyboard
  • MM = Main Memory
  • NL = Null
  • PR = Printer
  • RI = RS-232 Input
  • RO = RS-232 Output
  • RN = RS-232 Initialization
4222H-4223H
Route SOURCE 2 letter Identifier Value.

What does the routine do?

  1. The character at 4220H (destination) is put into a variable. If that character was an “R” then the character of 4221H overwrites that variable, so that variable will either be K, D, P or I, O, N.
  2. The routine at 375EH is called to parse a 15 byte table at 376CH (which has driver addresses for each of K, D, P, I, and O) and, if there is a letter match, puts the corresponding address into HL (and then the top of stack); exiting if nothing found.
  3. The same steps are taken with the characters at 4222H-4223H (source) except that HL is not pushed to the stack.
  4. The stack now has the address of the destination (from steps 1 and 2) and HL holds the address of the source (from step 3).
  5. HL (source) is copied to DE and the stack (destination) is popped into HL, so HL holds the destination driver address and DE holds the source driver address.
  6. A 3 byte LDIR is executed to copy the the destination address (HL) over the source address (DE), thus setting the source routine to actually point to the destination routine.