30A2
IM 1
Set the INTERRUPT MODE to 1.
30A4
LD SP,407DH
Set up stack pointer to point to 407DH.
30A7
OUT (0E4H),A
Send the value held in Register A to Port E4H which is the Non-Maskable Interrupt Latch. Sending a 0 to E4 will turn off all Non-Maskable Interrupts.
30AC
LD HL,37E6H
Let HL = 37E6H which will be the memory location that Port 89H feeds.
30AF
LD A,0FH
Let A = 0FH (Decimal: 15) as A will be a counter
30B1
LD C,89H
Let C = 89H as the Port which will feed (HL)
30B3
OUT (88H),A
Send the value held in Register A to Port 88H which is the CRT Controller Control Register..
30B5
OUTD
This command takes the byte held in the memory location pointed to by HL and writes it to Port C. HL and B are then both decremented.
30B8
If A is still positive, then LOOP back up to 30B3H.
30BD
OUT (0ECH),A
Output 38H (Binary: 0011 1000) to Port ECH.
NOTE: Port ECH stores miscellaneous controls.
- Bit 3: Alt. char. [0 = disable, 1 = enable]
- Bit 4: I/O bus [0 = disable, 1 = enable]
- Bit 5: Video waits [0 = disable, 1 = enable] ? Model 4 ONLY
- Bit 6: CPU clock speed [0 = 2 mhz, 1 = 4 mhz]
30BF
LD A,04H
Let A = 04H (Binary: 0000 0100).
30C1
OUT (0E0H),A
OUTput 04H (Binary: 0000 0100) to Port E0H which stores the Maskable Interrupt. By sending Bit 2 HIGH, that chooses 4046H as the Maskable Interrupt Jump
30C3 - This is in the middle of the machine setup routine - While this is a pass through to set up the machine / warm boot, it is also a jump point for a failure to boot from anything AND is a VECTOR jump from 3012H.
30C5
OUT (0F4H),A
OUTput 81H (Binary: 10000001) to Port F4H which is the Floppy drive select and options register. For OUTPUT:
- Bit 0: Drive 0 Select
- Bit 1: Drive 1 Select
- Bit 2: Drive 2 Select
- Bit 3: Drive 3 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)
30C7
OUT (0E8H),A
OUTput 81H (Binary: 10000001) to Port E8H which is the RS-232 Status Register and Master Reset. Outputting ANYTHING to this port will reset the RS-232.
30CB
OUT EAH,A
OUTput 6FH (Binary: 0110 1111) to Port EAH.
NOTE: Port EAH is the RS-232 UART Control Register/Status Register. For output:
- Bit 0: Data Terminal Ready
- Bit 1: Request to End
- Bit 2: Break
- Bit 3: Parity Enable
- Bit 4: Stop Bits
- Bit 5: Select
- Bit 6: Word Length
- Bit 7: Parity (0=Odd, 1=Even)
30CD
LD HL,36AAH
Let HL = 36AAH
30D0
LD DE,4000H
let DE = 4000H
30D3
LD BC,004CH
Let BC = 004CH (Decimal: 76 Bytes)
30D6
LDIR
Moves the byte from (HL) to (DE), then HL and DE are incremented, and BC is decremented until BC is zero. Interrupts CAN fire during this command.
30DA
OUT (0F0H),A
Send 0CH (Binary: 0000 1100) to port F0H which is the Floppy Disk Command/Status Register. 0000 1100 is the command to RESTORE (0000), LOAD HEAD AT THE BEGINNING (1), VERIFY ON (1), 6ms STEP (00).
30DC
LD DE,41E2H
LET DE = 41E2H
30DF
LD C,46H
LET C = 46H (Decimal = 70).
30E1
LDIR
Moves the byte from (HL) to (DE), then HL and DE are incremented, and BC is decremented until BC is zero. HL is 365EH. Interrupts CAN fire during this command.
30E3
GOSUB to 3518H to initials the Port 84H settings
30E6
IN A,(0F0H)
INput from Port F0H which is the FDC Status port on input. Input Results:
- Bit 0: Busy
- Bit 1: Index/DRQ
- Bit 2: Track 0/Data Lost
- Bit 3: CRC error
- Bit 4: Seek error/Record not found
- Bit 5: If Reading, Record Type, if Writing, Write Fault/Head loaded
- Bit 6: Write Protect
- Bit 7: Not ready
30E8
LD C,A
Let Register C = Register A.
30EA
If A is ZERO (meaning that Port F0H returned FFH), JUMP to 3076H
30EC
If A wasn't ZERO, then GOSUB to 304BH
30EF
If the NOT ZERO flag is set, JUMP to 3079H.
30F1
IN A,(0F0H)
INput from Port F0H which is the FDC Status port on input. Input Results:
- Bit 0: Busy
- Bit 1: Index/DRQ
- Bit 2: Track 0/Data Lost
- Bit 3: CRC error
- Bit 4: Seek error/Record not found
- Bit 5: If Reading, Record Type, if Writing, Write Fault/Head loaded
- Bit 6: Write Protect
- Bit 7: Not ready
30F3
LD C,A
Let Register C = Register A.
30F4
BIT 2,A
Test Bit 2 of Register A. That Bit is for "TRACK 0 FOUND".
30F6
If Bit 2 of Register A is LOW, then skip the next instruction and JUMP to 30F9H.
30F8
LD B,A
Let Register B = Register A
30F9
AND 81H
MASK Register A against 81H (Binary: 1000 0001) to keep only Bits 0 and 7, which would be BUSY and NOT READY.
30FB
DEC A
Decrement Register A by 1. By doing this, a Port 81H status of NOT BUSY and NOT READY will return a ZERO FLAG.
30FC
If the Decremented Register A is ZERO, then JUMP to back to 30ECH to keep polling the drive.
30FE
LD A,B
Let Register A = Register B
30FF
OR A
Set the Flags for Register A
3100
If A was ZERO, then JUMP back to 3079H to trigger the "CASS?" routine.
3104
LD A,C
Let Register A = Register C
3105
AND 98H
MASK Register A against 98H (Binary: 1001 1000) to keep only Bits 3, 4, and 7 (which are CRC ERROR, SEEK ERROR, and NOT READY).
3107
If none of those 3 errors are present, then JUMP to down to 314EH which tests for a Hard Drive.
3109
LD D,03H
If we are here, then we have either a CRC ERROR, SEEK ERROR, or NOT READY. Let Register D = 03H.
310B
LD A,81H
Let Register A = 81H.
310D
OUT (0F4H),A
OUTput 81H (Binary: 10000001) to Port F4H which is the Floppy drive select and options register. For OUTPUT:
- Bit 0: Drive 0 Select
- Bit 1: Drive 1 Select
- Bit 2: Drive 2 Select
- Bit 3: Drive 3 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)
310F
DEC A
Decrement Register A (so make Register A = 80H or 1000 0000.
3110
OUT (0E4H),A
Send a Bit 7 HIGH to Port E4H which is the Non-Maskable Interrupt Latch. Sending a Bit 7 HIGH to E4 will ENABLE INTRQ Interrupts.
3112
LD HL,313BH
LET HL = 313BH
3115
LD (404AH),HL
Put 313BH into (404AH) and (404BH)
311A
LD (4049H),A
Put C3H into (4049H).
NOTE: 4049H is the RST 0 NMI Vector.
311D
LD C,0F3H
Let C = F3H.
NOTE: Port F3H is the FDC Data Register (the data byte to be READ or WRITTEN to disk).
311F
LD HL,4300H
Let HL = 4300H, which is the standard memory location for loading a BOOT sector into.
3124
OUT (0F2H),A
OUTput 01H to Port F2H which is the Floppy Disk Sector Register, telling the FDC we want to deal with Sector 1.
312B
IN A,(0F0H)
INput from Port F0H which is the FDC Status port on input. Input Results:
- Bit 0: Busy
- Bit 1: Index/DRQ
- Bit 2: Track 0/Data Lost
- Bit 3: CRC error
- Bit 4: Seek error/Record not found
- Bit 5: If Reading, Record Type, if Writing, Write Fault/Head loaded
- Bit 6: Write Protect
- Bit 7: Not ready
312D
AND 02H
MASK the results of Port F0H with 02H (Binary: 0010) so that only Bit 1 (Index) is live.
312F
If Bit 1 of F0H (the Index) is LOW, JUMP to 312BH.
3131
INI
Read a byte from Port C into the memory location pointed to by HL, then DECrement HL and INCrement B. Z is set if B ? 1 = 0; otherwise it is reset.
3133
LD A,C1H
LET A = C1H (Binary: 1100 0001)
3135
OUT (0F4H),A
OUTput C1H (Binary: 1100 0001) to Port F4H which is the Floppy drive select and options register. For OUTPUT:
- Bit 0: Drive 0 Select
- Bit 1: Drive 1 Select
- Bit 2: Drive 2 Select
- Bit 3: Drive 3 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)
3137
INI
Read a byte from Port C into the memory location pointed to by HL, then DECrement HL and INCrement B. Z is set if B ? 1 = 0; otherwise it is reset.
NOTE: Port C1H is the hard drive controller board control register. Sending a 0 resets the hard drive controller board.
+ 3139
LOOP back to to 3135H.
NOTE: Ultimately an interrupt will fire and pull us out of this seemingly endless loop.