Device I/O Instructions
(Typically never used by an application programmer, but used extensively in the O/S to control all peripherals such as terminals, printers and disk drives. I suspect they are also used for later functions such as bank switching and the EP's real-time clock.)
I/O devices may have up to three 17-bit Device Registers, accessible to the programmer, implemented by their hardware interface. By convention, Device Register 3 is the Status Register.
All I/O devices also have a BUSY flag and a DONE flag.
Start a device by setting its BUSY flag (after loading relevant device registers). The device signals an INTERRUPT REQUEST whilst its DONE flag is set.
(The MASK instruction can/could be used to limit which devices generate an interrupt. Not sure if this is supported post the Mk 4)
17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
0 | 0 | 0 | 0 | 1 | 1=A-Reg 0=B-Reg | Function or Skip Condition | Mode | Device Code |
B9:B7 | Mnemonic | Action |
1 | DATI1 | Read Device Register 1 |
2 | DATI2 | Read Device Register 2 |
3 | DATI3 | Read Device Register 3 |
4 | DATO1 | Write Device Register 1 |
5 | DATO2 | Write Device Register 2 |
6 | DATO3 | Write Device Register 3 |
7 | SKIP | Test for SKIP CONDITION |
Function or Skip Condition (B11:B10)
B11:B10 | Function | SKIP IF |
0 | No Operation | BUSY |
1 | START (Set BUSY, Clear DONE) | NOT BUSY |
2 | STOP (Clear BUSY, Clear DONE) | DONE |
3 | IOPLS (Input/Output Pulse) | NOT DONE |
Device Codes (B6:B1)
In | Out | Standard Assignment |
20 | 60 | Alpha-numeric Keyboard |
50 | 40 | Visual Display Unit |
30 | Line Printer | |
34 | Serial Printer | |
66 | 67 | IBM I/O Writer |
11 | 33 | Paper Tape |
70 | 70 | Disc |
Example code to read a single sector from disk (actually part of the LOS bootstrap)
(The bootstrap is deliberately simple for toggling in. It loads one sector starting at sector 0 into core starting at address 0. Interrupts are off on power-up, so the bootstrap sits in a tight loop just after this waiting to be overwritten by a jump to an lower address. The sector is still coming in to core via DMA.)
004400 | CLEAR B | |
010670 | DATO3B | Load sector No to reg 3 |
010570 | DATO2B | Load target core address to reg 2 |
011470 | DATO1B SBCD | Load reg 1 and start |
The OS bootstrap
The OS bootstrap is a little more complex as it supports both Hawk and Lark drives, but the principle is the same. Rather than simply loading sector 0 from the drive, it loads sector 200. Obviously this can be changed and it make one wonder what other sectors could be booted instead?
100 | 010670 | DATO3B | |
101 | 011470 | DATO1B SBCD | |
102 | 210107 | LDA 107 | Load A with boot sector number |
103 | 015570 | ||
104 | 012770 | ||
105 | 020104 | JUMP 104 | |
106 | 020200 | JUMP 200 | Jump into the boot sector |
107 | 000200 | Sector No 200 |
For DD1600 (Hawk) as Unit 70:
Reg A all zeros
Reg B Bit 17: 1 for fixed or 0 for exchangeable
Reg B Bits 16-15: drive code (0 to 3)Reg B Bits 14-1: MUST be zero
For DD9600 (Lark) as Unit 70:
Reg A set to 100(8) i.e. Bit 7
Reg B Bit 17-16: drive code (0 to 3)
Reg B Bits 15-11: surface code (0 to 3)
Reg B Bits 10-1: all zerosExample code to send a single character to a terminal
Example code to read a single character from a terminal