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.
Note that the disk controller always loads one more sector than specified in the control word, so in the case we can leave the sector count at zero, and it will still load one sector.
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