Start of Disassembly ; PERQ T2/T4 Rom Bootstrap - CPU diagnostics and ; then boot from link, floppy and 5.25" hard drive ; in that order ; ; This was produced by combining bits from the ; the T1 bootstrap with the changes file. It ; should be OK ; ; Register usage in general identical to T1 bootstrap ; 0000: 0000C002000E R00,Stack Reset,if true then Continue ; Start machine ; Stack Reset clears SP _and_ Incs DDS. DDS = 1 0001: 0080D047000E SrcRstOp:= 80,if true then Continue ; Set power control ; bit for a PERQ 1 0002: 0000C000000E R00,if true then Continue ; test sequencer increment 0003: 0000C000000E R00,if true then Continue 0004: 0000C03FF703 R00,if true then Goto 0008 ; Test Goto (bit 3) 0005: 0000C03FFA03 R00,if true then Goto 0005 ; Loop here if goto failed 0006: 0000C000000A R00,if true then Return ; Trivial subroutine - just ; return. Check sequencer stack. 0007: 0000D2BFEC03 R00 xor 00,if true then Goto 0013 ; XOR R0 (=0) with ; 0. Result had better be 0. Goto next bit of the ; test. 0008: 0000C03FEF03 R00,if true then Goto 0010 ; Test goto (bit 4) 0009: 00FFD040FF0E FFFF,if true then Continue ; Goto test seq returns here ; clear zero flag by setting all R bits. 000A: 0000C03FF383 R00,if NotEqual then Goto 000C ; This jump should ; occur (last result was non-zero). 000B: 0000D07FF403 00,if true then Goto 000B ; Loop here if conditional ; jump failed 000C: 00FFD040FF0E FFFF,if true then Continue ; Clear zero flag again 000D: 0000D07FF4D3 00,if Equal then Goto 000B ; Go to error loop if ; jump happens - i.e. zero flag stuck. Also clear ; zero flag (set R bits to 0) 000E: 0000D07FCED3 00,if Equal then Goto 0031 ; This jump should ; occur (last result was 0). If not fall into ; second error loop. Z flag is set by this instruction 000F: 0000D07FF003 00,if true then Goto 000F ; second error loop - ; loop here if conditional jumps failed. 0010: 0000C03FE703 R00,if true then Goto 0018 ; Test goto (bits 3,4) 0011: 0000C03FF901 R00,if true then Call 0006 ; Test nesting - call ; trivial subroutine. It should return to next location 0012: 0000C000000A R00,if true then Return ; which is a return to the ; original routine. This tests the sequencer stack 0013: 0101D87F2483 R01 := 01,if NotEqual then Goto 00DB ; Set R1=1, and ; check that R0 Xor 0 (from location 7) was in fact ; 0. If not, goto another error loop. 0014: 0101D2BFEA03 R01 xor 01,if true then Goto 0015 ; Check if R1(=1) ; XOR 1 is 0. 0015: 0202D87F2483 R02 := 02,if NotEqual then Goto 00DB ; Set R2=2 ; If XOR failed, goto error loop. 0016: 0202D2BFE603 R02 xor 02,if true then Goto 0019 ; Now test ; bit 2 of XOR (R2=2 XOR 2) 0017: 0001C2BF8803 R00 xor R01,if true then Goto 0077 ; Get here ; after register test (from location 005C). R0 was ; set to 1 - check bit 1 of XOR. 0018: 0000C03FDF03 R00,if true then Goto 0020 ; Test goto (bit 5) 0019: 0404D87F2483 R04 := 04,if NotEqual then Goto 00DB ; if last XOR test ; (location 0016) failed, goto error loop. Test 001A: 0404D2BFE403 R04 xor 04,if true then Goto 001B ; bit 2 of XOR in ; the same way 001B: 0808D87F2483 R08 := 08,if NotEqual then Goto 00DB ; End of bit 2 test, ; start bit 3 test 001C: 0808D2BFE203 R08 xor 08,if true then Goto 001D ; which is just the ; same. 001D: 1010D87F2483 R10 := 10,if NotEqual then Goto 00DB ; Error loop ; if bit 3 failed, start bit 4 test. 001E: 1010D2BFC403 R10 xor 10,if true then Goto 003B ; Bit 4 test in the ; same way. 001F: 0000D87F6903 R00 := 00,if true then Goto 0096 ; ; continue (get here after ALU test from 0095). ; Clear R0. 0020: 0000C03FBF03 R00,if true then Goto 0040 ; Test goto (bit 6) 0021: E600C00F9E0E Out 61 := RE6,if true then Continue ; Get here from ; 0030. Write display address register 0022: E600C00F9E0E Out 61 := RE6,if true then Continue ; Write it again ; Why ? 0023: E600C00F9C0E Out 63 := RE6,if true then Continue ; Write to Memory ; Configuration port. Enable parity interrupt and ; display 0024: E400D87E1001 RE4 := 00;if true then Call 01EF ; Set up boot ; byte counter. Call Z80 reset routine 0025: 0004D04FBA0E Out 45 := 04,if true then Continue ; Get here from ; return at 01C3. Turn off Z80 reset, and allow Z80 ; to run. 0026: E800D87E8E01 RE8 := 00,if true then Call 0171 ; Clear Checksum ; accumulator. Call delay routine to wait for ; Z80 to initiallise 0027: 0006D04FBA0E Out 45 := 06,if true then Continue ; Enable Z80 ; interrupts. 0028: 0000C03E4601 R00,if true then Call 01BC ; Go and check for ; interrupts. 0029: 00AAD04FBB0E Out 44 := AA,if true then Continue ; Write SOM ; to Z80 system 002A: 0002D04FBB0E Out 44 := 02,if true then Continue ; 2 data bytes ; in Z80 message 002B: 0003D04FBB0E Out 44 := 03,if true then Continue ; 1st one - it's ; a message for the floppy system. 002C: 000AD04FBB0E Out 44 := 0A,if true then Continue ; 2nd one - it's ; the boot command. Boot from floppy disk. 002D: 0005D04FBA0E Out 45 := 05,if true then Continue ; Enable ; Microprocessor (Z80) Interrupts. 002E: E402DBBECE03 RE4 := RE4 - 02,if true then Goto 0131 ; Decrement ; byte counter and continue 002F: E600D8400C0E RE6 := 0C00,if true then Continue ; Get here from ; 00A1. Set up RE6 with value to load into Memory ; configuration registers. 0030: 0040D05EDE03 40,Fetch,if true then Goto 0021 ; Perform memory ; read to check that type of access. 0031: 0001D07FF083 01,if NotEqual then Goto 000F ; last instuction (@000E) ; should have cleared the Z flag. Go to error loop if not ; This instuction should clear Z (R=0001) 0032: 0008D07FF0D3 08,if Equal then Goto 000F ; Go to error loop if ; zero. This instuction should also clear Z (R=0008) 0033: 0000C03FF0D3 R00,if Equal then Goto 000F ; Go to error if zero 0034: 0000D040010E 0100,if true then Continue ; Clear Z (R=0100) 0035: 0000C03FF0D3 R00,if Equal then Goto 000F ; Go to error if zero 0036: 0000D040400E 4000,if true then Continue ; Clear Z (R=4000) 0037: 0000D07FF0D3 00,if Equal then Goto 000F ; Go to error if zero 0038: 0000C03FF901 R00,if true then Call 0006 ; Call the trivial subroutine ; This simply returns to the next location 0039: 0000C03FEE01 R00,if true then Call 0011 ; Call nested subroutine ; test. Check sequencer stack. 003A: 0000D842F803 R00 := 00,Stack Reset ,if true then Goto 0007 ; ; Clear R0, Increment DDS, go to next test. DDS = 2 ; Sequencer tested OK. 003B: 2020D87F2483 R20 := 20,if NotEqual then Goto 00DB ; Goto error loop ; if bit 4 XOR test failed (from location 001E). Start bit 5 test. 003C: 2020D2BFC203 R20 xor 20,if true then Goto 003D ; Test bit 5 003D: 4040D87F2483 R40 := 40,if NotEqual then Goto 00DB ; and bit 6 003E: 4040D2BFBE03 R40 xor 40,if true then Goto 0041 ; more of bit 6 003F: 0005D04FDE0A Out 21 := 05,if true then Return ; Get here from 0130 ; Clear data accepted flag and return to caller ; End of read link routine. 0040: 0000C03F7F03 R00,if true then Goto 0080 ; test goto (bit 7) 0041: 8080D87F2483 R80 := 80,if NotEqual then Goto 00DB ; Error loop for ; XOR bit 6 (from location 003E). Start testing bit 7 0042: 8080D2BFA203 R80 xor 80,if true then Goto 005D ; More of bit ; 7 test. This is very repetitive! 0043: 0101D2BF2483 R01 xor 01,if NotEqual then Goto 00DB ; Get here after ; first set of XOR tests - from 0076. Check that ; registers have retained their values, starting ; with R1 (=1) 0044: 0202D2BF2483 R02 xor 02,if NotEqual then Goto 00DB ; Check R2 0045: 0404D2BF2483 R04 xor 04,if NotEqual then Goto 00DB ; Check R4 0046: 0808D2BF2483 R08 xor 08,if NotEqual then Goto 00DB ; Check R8 0047: 1010D2BF2483 R10 xor 10,if NotEqual then Goto 00DB ; Check R10 0048: 2020D2BF2483 R20 xor 20,if NotEqual then Goto 00DB ; Check R20 0049: 4040D2BF2483 R40 xor 40,if NotEqual then Goto 00DB ; Check R40 004A: 8080D2BF2483 R80 xor 80,if NotEqual then Goto 00DB ; Check R80 004B: 0000C03F2483 R00,if NotEqual then Goto 00DB ; Error if R80 failed. 004C: FF00D280010E RFF xor 0100,if true then Continue ; Check RFF. These ; Tests take 2 microinstructions, as Z field is ; needed for a constant (for XOR) and an address for ; Goto. 004D: 0000C03F2483 R00,if NotEqual then Goto 00DB 004E: FE00D280020E RFE xor 0200,if true then Continue ; Check RFE 004F: 0000C03F2483 R00,if NotEqual then Goto 00DB 0050: FD00D280040E RFD xor 0400,if true then Continue ; Check RFD 0051: 0000C03F2483 R00,if NotEqual then Goto 00DB 0052: FB00D280080E RFB xor 0800,if true then Continue ; Check RFB 0053: 0000C03F2483 R00,if NotEqual then Goto 00DB 0054: F700D280100E RF7 xor 1000,if true then Continue ; Check RF7 0055: 0000C03F2483 R00,if NotEqual then Goto 00DB 0056: EF00D280200E REF xor 2000,if true then Continue ; Check REF 0057: 0000C03F2483 R00,if NotEqual then Goto 00DB 0058: DF00D280400E RDF xor 4000,if true then Continue ; Check RDF 0059: 0000C03F2483 R00,if NotEqual then Goto 00DB 005A: BF00D280800E RBF xor 8000,if true then Continue ; Check RBF 005B: 0000C03F2483 R00,if NotEqual then Goto 00DB 005C: 0001D842E803 R00 := 01,Stack Reset ,if true then Goto 0017 ; End of Register test - Increment DDS (DDS = 4). Go ; to next test. 005D: 0000C03F2483 R00,if NotEqual then Goto 00DB ; End of bit 7 test (from ; location 0042). 005E: FF00D840010E RFF := 0100,if true then Continue ; test bit 8 005F: FF00D280010E RFF xor 0100,if true then Continue 0060: 0000C03F2483 R00,if NotEqual then Goto 00DB 0061: FE00D840020E RFE := 0200,if true then Continue ; test bit 9 0062: FE00D280020E RFE xor 0200,if true then Continue 0063: 0000C03F2483 R00,if NotEqual then Goto 00DB 0064: FD00D840040E RFD := 0400,if true then Continue ; test bit 10 0065: FD00D280040E RFD xor 0400,if true then Continue 0066: 0000C03F2483 R00,if NotEqual then Goto 00DB 0067: FB00D840080E RFB := 0800,if true then Continue ; test bit 11 0068: FB00D280080E RFB xor 0800,if true then Continue 0069: 0000C03F2483 R00,if NotEqual then Goto 00DB 006A: F700D840100E RF7 := 1000,if true then Continue ; test bit 12 006B: F700D280100E RF7 xor 1000,if true then Continue 006C: 0000C03F2483 R00,if NotEqual then Goto 00DB 006D: EF00D840200E REF := 2000,if true then Continue ; test bit 13 006E: EF00D280200E REF xor 2000,if true then Continue 006F: 0000C03F2483 R00,if NotEqual then Goto 00DB 0070: DF00D840400E RDF := 4000,if true then Continue ; test bit 14 0071: DF00D280400E RDF xor 4000,if true then Continue 0072: 0000C03F2483 R00,if NotEqual then Goto 00DB 0073: BF00D840800E RBF := 8000,if true then Continue ; test bit 15 0074: BF00D280800E RBF xor 8000,if true then Continue 0075: 0000C03F2483 R00,if NotEqual then Goto 00DB 0076: 0000D282BC03 R00 xor 00,Stack Reset ,if true then Goto 0043 ; XOR ; tested OK. Increment DDS - DDS=3. Go to next test. 0077: 0002D87F2483 R00 := 02,if NotEqual then Goto 00DB ; Get here from ; location 0017. Test bits of register 0. Bit 1 ; starts here. 0078: 0002C2BF8603 R00 xor R02,if true then Goto 0079 0079: 0004D87F2483 R00 := 04,if NotEqual then Goto 00DB ; test bit 2 of ; register 0 (and R-R ALU ops) 007A: 0004C2BF8403 R00 xor R04,if true then Goto 007B ; test bit 2 007B: 0008D87F2483 R00 := 08,if NotEqual then Goto 00DB ; test bit 3 007C: 0008C2BF8203 R00 xor R08,if true then Goto 007D 007D: 0010D87F2483 R00 := 10,if NotEqual then Goto 00DB ; test bit 4 007E: 0010C2BF7E03 R00 xor R10,if true then Goto 0081 ; Always go 007F: E505D2BEB003 RE5 xor 05,if true then Goto 014F ; Get here from ; 013E. Was last message a NAK? 0080: 0000C03EFF03 R00,if true then Goto 0100 ; Test goto (bit 8) 0081: 0020D87F2483 R00 := 20,if NotEqual then Goto 00DB ; test bit 5 of ; R-R ALU ops 0082: 0020C2BF7C03 R00 xor R20,if true then Goto 0083 ; test bit 5 0083: 0040D87F2483 R00 := 40,if NotEqual then Goto 00DB ; test bit 6. 0084: 0040C2BF5D03 R00 xor R40,if true then Goto 00A2 ; always go. 0085: 0001C2BF2101 R00 xor R01,if true then Call 00DE ; Get here from ; 00B4. Now do the ALU test with using the ; SHL R0 feature of the routine 00DE. Test bit 0 0086: 0002C2BF2101 R00 xor R02,if true then Call 00DE ; test bit 1 0087: 0004C2BF2101 R00 xor R04,if true then Call 00DE ; test bit 2 0088: 0008C2BF2101 R00 xor R08,if true then Call 00DE ; test bit 3 0089: 0010C2BF2101 R00 xor R10,if true then Call 00DE ; test bit 4 008A: 0020C2BF2101 R00 xor R20,if true then Call 00DE ; test bit 5 008B: 0040C2BF2101 R00 xor R40,if true then Call 00DE ; test bit 6 008C: 0080C2BF2101 R00 xor R80,if true then Call 00DE ; test bit 7 008D: 00FFC2BF2101 R00 xor RFF,if true then Call 00DE ; test bit 8 008E: 00FEC2BF2101 R00 xor RFE,if true then Call 00DE ; test bit 8 008F: 00FDC2BF2101 R00 xor RFD,if true then Call 00DE ; test bit 10 0090: 00FBC2BF2101 R00 xor RFB,if true then Call 00DE ; test bit 11 0091: 00F7C2BF2101 R00 xor RF7,if true then Call 00DE ; test bit 12 0092: 00EFC2BF2101 R00 xor REF,if true then Call 00DE ; test bit 13 0093: 00DFC2BF2101 R00 xor RDF,if true then Call 00DE ; test bit 14 0094: 00BFC2BF2101 R00 xor RBF,if true then Call 00DE ; test bit 15 0095: 0000C002E003 R00,Stack Reset ,if true then Goto 001F ; Increment DDS (DDS = 6). Go to next test. 0096: 01FFD840FF0E R01 := FFFF,if true then Continue ; Get here from ; 001F (which cleared R0). Set all bits of R1. 0097: 0000C13F4A03 R00 and R00,if true then Goto 00B5 ; Look at ; R0 and R0 (= 0 and 0). Continue. 0098: 01FFD280FF0E R01 xor FFFF,if true then Continue ; Get here from ; 00CA. R1 has just been set to all 1's by NOT ; operation. Test them. 0099: 0001C8FF2483 R00 := not(R01),if NotEqual then Goto 00DB ; Go to error loop if all bits were not set originally. ; Set R0 to 0 (by flipping all of R1 bits with NOT). 009A: 0000C03F2483 R00,if NotEqual then Goto 00DB ; Go to error loop ; if R0 was not set to 0 by last operation. Not has ; failed. 009B: 0277D840770E R02 := 7777,if true then Continue ; set R2 to ; 0111011101110111 009C: 0000CB3F3403 R00 := R00 + R00,if true then Goto 00CB ; See what 0+0 gives. Go to next bit of ; routine 009D: 0402C33F2483 R04 + R02,if NotEqual then Goto 00DB 009E: 0002CBBF2483 R00 := R00 - R02,if NotEqual then Goto 00DB 009F: 0004CABF2703 R00 := R00 xor R04,if true then Goto 00D8 00A0: E700D846000E RE7 := 00,CtrlRstOp := 00,if true then Continue ; Start ; of system disk bootstrap. Get here from 00F5 ; if link bootstrap no attempted. Disable raster ; operations, and clear address pointer 00A1: 0040D05FD003 40,Store,if true then Goto 002F ; set up 1 word ; memory write to test access. Go to next part of the ; routine. 00A2: 0080D87F2483 R00 := 80,if NotEqual then Goto 00DB ; end of bit ; 6 R-R ALU test. Start bit 7 test. Get here from 0084. 00A3: 0080C2BF2101 R00 xor R80,if true then Call 00DE ; test bit 7 00A4: 0000D840010E R00 := 0100,if true then Continue ; test bit 8 00A5: 00FFC2BF2101 R00 xor RFF,if true then Call 00DE 00A6: 0000D840020E R00 := 0200,if true then Continue ; test bit 9 00A7: 00FEC2BF2101 R00 xor RFE,if true then Call 00DE 00A8: 0000D840040E R00 := 0400,if true then Continue ; test bit 10 00A9: 00FDC2BF2101 R00 xor RFD,if true then Call 00DE 00AA: 0000D840080E R00 := 0800,if true then Continue ; test bit 11 00AB: 00FBC2BF2101 R00 xor RFB,if true then Call 00DE 00AC: 0000D840100E R00 := 1000,if true then Continue ; test bit 12 00AD: 00F7C2BF2101 R00 xor RF7,if true then Call 00DE 00AE: 0000D840200E R00 := 2000,if true then Continue ; test bit 13 00AF: 00EFC2BF2101 R00 xor REF,if true then Call 00DE 00B0: 0000D840400E R00 := 4000,if true then Continue ; test bit 14 00B1: 00DFC2BF2101 R00 xor RDF,if true then Call 00DE 00B2: 0000D840800E R00 := 8000,if true then Continue ; test bit 15 00B3: 00BFC2BF2101 R00 xor RBF,if true then Call 00DE 00B4: 0001D8427A03 R00 := 01,Stack Reset ,if true then Goto 0085 ; End of R-R ALU XOR test. Increment DDS (DDS =5) ; and go back to next test. 00B5: 0001C13F2483 R00 and R01,if NotEqual then Goto 00DB ; Get here ; from 0096. Last operation was 0 and 0. Go to ; Error loop if it failed. Now calculate 0 and 1 in ; each bit 00B6: 0100C13F2483 R01 and R00,if NotEqual then Goto 00DB ; check 0 & 1, ; calculate 1 & 0. 00B7: 0101C93F2483 R01 := R01 and R01,if NotEqual then Goto 00DB ; Check ; 1 & 0, Set R1 = 1&1 in each bit. 00B8: 01FFD280FF0E R01 xor FFFF,if true then Continue ; Check all ; bits of R1 (XORs are known to work by now). R1 ; should still be FFFF 00B9: 0000C1FF2483 R00 or R00,if NotEqual then Goto 00DB ; Check result ; of 1 and 1, calculate 0 or 0 00BA: 0001C9FF2483 R00 := R00 or R01,if NotEqual then Goto 00DB ; Check ; result of 0 or 0, calculate 0 or 1 00BB: 00FFD280FF0E R00 xor FFFF,if true then Continue ; Check result ; of 0 or 1 00BC: 0000D87F2483 R00 := 00,if NotEqual then Goto 00DB 00BD: 0100C9FF4103 R01 := R01 or R00,if true then Goto 00BE ; calculate ; 1 or 0 00BE: 01FFD280FF0E R01 xor FFFF,if true then Continue ; test 1 or 0 ; (should be 1) 00BF: 0101C9FF2483 R01 := R01 or R01,if NotEqual then Goto 00DB ; ; Go if error on 1 or 0. Calculate 1 or 1. 00C0: 01FFD280FF0E R01 xor FFFF,if true then Continue ; test 1 or 1 00C1: 0000CAFF2483 R00 := R00 xnor R00,if NotEqual then Goto 00DB ; Calculate 0 xnor 0 (should be 1's in all bits) 00C2: 00FFDA80FF0E R00 := R00 xor FFFF,if true then Continue ; test xnor ; result. 00C3: 0001C2FF2483 R00 xnor R01,if NotEqual then Goto 00DB ; If ; 0 xnor 0 failed, goto error loop. Calculate ; 1 xnor 0 (should be 0) in all bits. 00C4: 0100C2FF2483 R01 xnor R00,if NotEqual then Goto 00DB ; Go if xnor ; errored. Calculate 1 xnor 0 (again, should be 0) 00C5: 0101CAFF2483 R01 := R01 xnor R01,if NotEqual then Goto 00DB ; test ; this xnor. Go to error loop if it failed. Calculate ; 1 xnor 1 (=1) in all bits. 00C6: 01FFD280FF0E R01 xor FFFF,if true then Continue ; test it. 00C7: 0000C8BF2483 R00 := not(R00),if NotEqual then Goto 00DB ; Go to ; Error loop if xnor failed. Flip all bits in R0 (=0) ; using ALU not. 00C8: 00FFDA80FF0E R00 := R00 xor FFFF,if true then Continue ; flip them ; back again using xor (which is known to work). 00C9: 0100C0BF2483 not(R01),if NotEqual then Goto 00DB ; test R0 - ; go to error loop if NOT fails. 00CA: 0100D8FF6703 R01 := not(00),if true then Goto 0098 ; Set R1 to ; all ones. 00CB: 0002CB3F2483 R00 := R00 + R02,if NotEqual then Goto 00DB ; Get here ; from 009C. Go to error loop if 0+0 <> 0, and ; set R0 to 0+7777. 00CC: 0077DA80770E R00 := R00 xor 7777,if true then Continue ; Check to ; see if it got to the right value, and also set R0 to ; 0 if it did. 00CD: 0200CB3F2483 R02 := R02 + R00,if NotEqual then Goto 00DB ; Go to ; error loop if it failed. Test 7777+0 in the same ; way. 00CE: 0277D280770E R02 xor 7777,if true then Continue 00CF: 0000C03F2483 R00,if NotEqual then Goto 00DB ; Go to error loop if ; 7777+0 failed. 00D0: 0488D840880E R04 := 8888,if true then Continue ; Set R4 to ; 1000100010001000. 00D1: 0400DB3F2D03 R04 := R04 + 00,if true then Goto 00D2 ; Check ; 8888 + 0 in the same sort of way. 00D2: 0488D280880E R04 xor 8888,if true then Continue 00D3: 0404CB3F2483 R04 := R04 + R04,if NotEqual then Goto 00DB ; Go to ; Error loop if 8888+0 failed. Calculate ; 8888 + 8888 (which test the _generate_ section of ; the carry logic) 00D4: 0410D280110E R04 xor 1110,if true then Continue ; Check that ; gave the right value. 00D5: 0000C03F2483 R00,if NotEqual then Goto 00DB ; Go to error loop if ; Carry generate failed. 00D6: 0489D840880E R04 := 8889,if true then Continue ; set R4 to ; 1000100010001001. 00D7: 0204C33F6203 R02 + R04,if true then Goto 009D ; Add this to ; 7777. This tests the _propagate_ section of the ; carry logic. The result should be 0. 00D8: 0004CBBF2483 R00 := R00 - R04,if NotEqual then Goto 00DB ; Go to the ; error routine if propagate failed. Set R0 to 0-8889 ; (=7777) 00D9: 0002CABF2303 R00 := R00 xor R02,if true then Goto 00DC ; Compare ; result with 7777. Go to next bit. 00DA: 0100C03F1FE3 R01,if Greater then Goto 00E0 ; Check that Greater ; flag was set. Fall into error loop if not. Set R = FFFF ; using register R1, and go to next bit of the routine. 00DB: 0000C03F2403 R00,if true then Goto 00DB ; Another error loop - ; loop here if anything went wrong. 00DC: 0000C03F2483 R00,if NotEqual then Goto 00DB ; Get here from ; 00D9. Go to error loop if subtract failed. 00DD: 0001D0422503 01,Stack Reset ,if true then Goto 00DA ; End of ; ALU tests. Increment DDS (=7), and go to next test. ; Set R = 1 00DE: 0000CB3F2483 R00 := R00 + R00,if NotEqual then Goto 00DB ; part ; of the R-R ALU checking code. This doubles R0 ; (effectively shifting the only 1 left by 1 bit), and ; then goes to the error loop if the last operation ; failed. This saves instructions, as the Z field ; does not need to be used twice/test. 00DF: 0000C000000A R00,if true then Return ; Exit to next bit test. 00E0: 0101D33F24E3 R01 + 01,if Greater then Goto 00DB ; Get here from ; 00DA. Test that FFFF is _not_ greater, and go to ; error loop if it fails. 00E1: 0000C03F24E3 R00,if Greater then Goto 00DB ; Calculate FFFF+1, and check that it's not greater either. 00E2: 08FFD8407F0E R08 := 7FFF,if true then Continue ; Set R8 to ; 011111111111111 (largest +ve number) 00E3: 0801D33F1B03 R08 + 01,if true then Goto 00E4 ; Increment R8 - ; +ve + +ve should always give +ve, even if sign bit ; changes. This is specifically checked for by the ; CC pal. 00E4: 0001D3BF19E3 R00 - 01,if Greater then Goto 00E6 ; Go if no error (it ; was still +ve). Also Decrement R0 (=0). 00E5: 0000C03F2403 R00,if true then Goto 00DB ; Go to error loop if ; last jump failed. 00E6: 0000C03F24E3 R00,if Greater then Goto 00DB ; Check that 0 - +ve ; is -ve. Go to error loop if not. Put 0 on ; the R bus. 00E7: 0100C03F16F3 R01,if GreaterEqual then Goto 00E9 ; 0 is >= 0, so ; jump should occur. Put FFFF on R bus. 00E8: 0000C03F2403 R00,if true then Goto 00DB ; Go to error loop if it ; didn't. 00E9: 0800C03F24F3 R08,if GreaterEqual then Goto 00DB ; Check that FFFF is ; not GreaterEqual (from location 00E7). Go to error loop ; if flag set. Put 7FFF (in R8) on R. 00EA: 0000C03F13F3 R00,if GreaterEqual then Goto 00EC ; 7FFF is >= 0, so ; this jump should occur. Put 0 (in R0) onto R 00EB: 0000C03F2403 R00,if true then Goto 00DB ; If last jump didn't occur, ; go to error loop. 00EC: 0100C03F1193 R01,if LessEqual then Goto 00EE ; 0 is <= 0, so this ; jump should again occur ; put FFFF (in R1) onto R 00ED: 0000C03F2403 R00,if true then Goto 00DB ; If it didn't, go to ; error loop 00EE: 0800C03F0F93 R08,if LessEqual then Goto 00F0 ; FFFF = -1 <=0, so ; this jump should occur. Put 7FFF (in R8) onto ; R lines. 00EF: 0000C03F2403 R00,if true then Goto 00DB ; Go to error loop if ; LessEqual failed. 00F0: 0000C03F2493 R00,if LessEqual then Goto 00DB ; Go to error loop ; if 7FFF (+ve) set LessEqual flag. Put 0 on R 00F1: 1000D8FF0C53 R10 := not(00),if C19 then Goto 00F3 ; This jump ; should occur, as the C19 flag is inverted. Set R10 ; = FFFFF. 00F2: 0000C03F2403 R00,if true then Goto 00DB ; Go to error loop if the ; C19 flag is stuck high. 00F3: 1001D33EEC53 R10 + 01,if C19 then Goto 0113 ; Increment R10 (which ; should set the C19 flag (and thus make it 0), and check ; that the last NOT operation did not affect C19. Go to ; next bit of the routine if everything was OK. 00F4: 0000C03F2403 R00,if true then Goto 00DB ; Otherwise go to error loop 00F5: 0000C03F5F83 R00,if NotEqual then Goto 00A0 ; Get here from 0118 ; Go if flag was non-zero - i.e. another machine is ; not pulling the signal low externally. Continue here ; for link boot 00F6: 01FFD87F0803 R01 := FF,if true then Goto 00F7 00F7: 0101DB30000C R01 := R01 + 01,if true then LoadS 0FFF ; ; load S register with top address of WCS - data ; is loaded _downwards_. Set R1 to 0100 - total ; count of WCS locations to be written 00F8: 0005D04FDE0E Out 21 := 05,if true then Continue ; Set flag output ; and start data cycle. 00F9: 0000C03F0101 R00,if true then Call 00FE ; Call Read link subroutine 00FA: 02E5D280140E R02 xor 14E5,if true then Continue ; Compare read data ; with magic number - 012345 octal. 00FB: 0000C03F0683 R00,if NotEqual then Goto 00F9 ; Go back and try again ; if magic number not found 00FC: 0000C03F0101 R00,if true then Call 00FE ; Read in 1 word from the ; link. Loop back to here from 012A after each WCS ; location written 00FD: 0200C03EDA03 R02,if true then Goto 0125 ; Place it on the R lines and ; continue 00FE: 0000C00F5F0E [In A0] R00,if true then Continue ; Set up read from ; link status port. 00FF: 0002513ED203 I/OB and 02,if true then Goto 012D ; Check data ; available bit. Go to next bit of routine 0100: 0000C03FF603 R00,if true then Goto 0009 ; End of goto tests - ; Back to main program ! 0101: 0000C03EFD09 R00,if true then Repeat 0102 ; Decrement S and ; go to location 102. S now points to the next-to-last ; location in the control store. 0102: 01FFD840070E R01 := 07FF,if true then Continue ; Set up loop counter 0103: 0000C03EE5D3 R00,if Equal then Goto 011A ; This jump is _not taken_ ; at first. Will go to 011A when all locations are ; written, as last instruction at 0119 set the zero ; flag. 0104: 00CBD0FEDD03 not(CB),if true then Goto 0122 ; Set up R lines for ; low byte of the microinstruction 0105: 0000C00EFE07 R00, WCSH, if true then GotoS 0101 ; Store high microcode ; section for last instruction (set to 0 by last ; instruction). Continue ; This has written 00000000000A to the last location ; of the control store (Look at the scrambler table in ; the TechRef. This is an unconditional return ; instruction. 0106: 0000D0C00A0E not(0A00),if true then Continue ; Set R lines for ; Middle microcode word (=0A00) 0107: 0000D0CDFA07 not(00), WCSM, if true then GotoS 0105 ; Store last ; microcode word middle section, and continue 0108: 0000D0F0000C not(00),if true then LoadS 0FFF ; Load S with last ; address of test microprogram (=FFF). Set R lines to ; complement of 'low' microcode word (=0) 0109: 0000C00CF907 R00,WCSL, if true then GotoS 0106 ; Store low ; microcode word, and go to next part 010A: 0000D875550C R00 := 00,if true then LoadS 0AAA ; Get here from ; 0115. Start of looping test. Clear R0 (used as a ; counter, and load internal sequencer counter (S) ; with 0AAA 010B: 0001DB3EF409 R00 := R00 + 01,if true then Repeat 010B ; loop on this ; instruction, incrementing R0. Decrement S (the ; repeat phrase), and stop when S goes past 0. 010C: 00ABD2800A0E R00 xor 0AAB,if true then Continue ; Check that ; R0 got to the right value. 010D: 0000C03F2483 R00,if NotEqual then Goto 00DB ; Go to error loop if ; it didn't. 010E: 0056D840050E R00 := 0556,if true then Continue ; Load R0 with ; count for the second test. 010F: 0000C03AAA0C R00,if true then LoadS 0555 ; Load S for second test. 0110: 0001DBBEEF09 R00 := R00 - 01,if true then Repeat 0110 ; Decrement ; R0 and S, stop when S goes past 0. 0111: 0000C03F2483 R00,if NotEqual then Goto 00DB ; Check that last ; decrement on R0 set it to 0 also. Go to error ; loop if not. 0112: 0000C002F703 R00,Stack Reset ,if true then Goto 0108 ; Increment ; DDS (DDS = 9), and go to next test. 0113: 0001D3BF2453 R00 - 01,if C19 then Goto 00DB ; Get here from 00F3. Last ; operation caused carry out of bit 19, so this jump ; should not occur. Decrement 0 (in R0), which ; should again cause a carry from bit 19 0114: 0000C03F2453 R00,if C19 then Goto 00DB ; Go to error loop if ; no carry from bit 19 0115: 0000C002F503 R00,Stack Reset ,if true then Goto 010A ;End of ; Conditional branch tests. Increment DDS (DDS=8) and ; go to next test. 0116: 0400D840010E R04 := 0100,if true then Continue ; System Bootstrap ; Starts here. The PERQ can boot from 3 devices, ; perqlink, the floppy, or the hard disk. ; Load R4 with word count in a hard disk sector ; (used by hard disk boot). 0117: 0000C00F5F0E [In A0] R00,if true then Continue ; Read perqlink ; status input port 0118: 0004513F0A03 I/OB and 04,if true then Goto 00F5 ; Look at flag ; bit. This is set if a boot is being attempted ; over the link 0119: 0101DBBEFC09 R01 := R01 - 01,if true then Repeat 0103 ; Decrement ; loop counter, decrement S, and go back to 0103. 011A: 0000D04FBA0E Out 45 := 00,if true then Continue ; The WCS now ; contains a microprogram consisting of 7ff INC(R0)'s ; followed by a return. This instruction clears the ; interrupt enable port. 011B: 0000D877FF01 R00 := 00,if true then Call 0800 ; Clear R0 (which will ; incremented by the test program), and call this ; test program in the WCS. 011C: 00FFD280070E R00 xor 07FF,if true then Continue ; WCS test program ; returns here. Check that R0 now contains the correct ; value - i.e. it was incremented the right number of ; times by the test code. 011D: 0000C03F2483 R00,if NotEqual then Goto 00DB ; If not, then ; go to error loop. 011E: 0000C002E903 R00,Stack Reset ,if true then Goto 0116 ; WCS ; is good. Increment DDS (DDS = 10) and go to ; system bootstrap 011F: 0000C00EE607 R00, WCSH, if true then GotoS 0119 ; Write high word. ; This code fragment writes 0001DB00000A to the other ; locations in the WCS. This is R0:=R0+1,Continue. 0120: 0080D0C00E0E not(0E80),if true then Continue ; set up middle ; word of subsequent microinstructions. 0121: 0001D0CDE007 not(01), WCSM, if true then GotoS 011F ; set up ; high word and write middle word. 0122: 0000C00CDF07 R00,WCSL,if true then GotoS 0120 ; Get here from ; 0104. Store low word of all subequent ; microcinstructions 0123: 0000C03F0101 R00,if true then Call 00FE ; Get here from 0125 ; Read next word from the link. 0124: 0200C03ED703 R02,if true then Goto 0128 ; Place it on the R ; bus and continue 0125: 0000C00CDC07 R00,WCSL,if true then GotoS 0123 ; Get here from ; 00FD. Write word to low part of WCS and continue 0126: 0000C03F0101 R00,if true then Call 00FE ; Get here from 0128 ; Read next word from link 0127: 0200C03ED303 R02,if true then Goto 012C ; put it on the R bus 0128: 0000C00DD907 R00,WCSM,if true then GotoS 0126 ; Get here from ; 0124. Store word in middle WCS section and continue 0129: 0101DB88D509 DstRstOp ,R01 := R01 - 01,if true then Repeat 012A ; Decrement loop counter (R1), decrement address ; (S register) and continue at 012A. 012A: 0000C03F0383 R00,if NotEqual then Goto 00FC ; Loop back to ; 00FC if counter not got to 0. 012B: 0000C030FF03 R00,if true then Goto 0F00 ; When all locations ; written, get to here. Jump to start of downloaded ; code. End of link bootstrap. 012C: 0000C00ED607 R00,WCSH,if true then GotoS 0129 ; Get here from ; 0128. Save word in high part of WCS and continue 012D: 0000C03F01D3 R00,if Equal then Goto 00FE ; Get here from 00FF. If ; data available bit is not set then go back and ; try again. 012E: 000DD04FDE0E Out 21 := 0D,if true then Continue ; Set transmit ; done (=data accepted output) 012F: 0000C00F5D0E [In A2] R00,if true then Continue ; Set up read of ; link data. 0130: 0200483FC003 R02 := IOD,if true then Goto 003F ; read in link data, ; and go to next bit of the routine 0131: E640D87EBCE3 RE6 := 40,if Greater then Goto 0143 ; Get here from ; 002E. The Z80 has just been given a boot command. ; Initiallise counter. Go if all words in current ; boot message have not been stored. 0132: E601DBBECC03 RE6 := RE6 - 01,if true then Goto 0133 ; Decrement ; fifo data counter. Get here after discarding ; other messages (from 0152) 0133: AAFFD87EAB93 RAA := FF,if LessEqual then Goto 0154 ; Go to hard ; disk boot if counter has gone past 0. 0134: 0000C03E4601 R00,if true then Call 01BC ; Wait for an interrupt 0135: E5AAD2BEC903 RE5 xor AA,if true then Goto 0136 ; Look at ; first byte received from Z80. Is it SOM? 0136: 0000C03ECD83 R00,if NotEqual then Goto 0132 ; Round again if not 0137: 0000C03E4601 R00,if true then Call 01BC ; Wait for interrupt ; and next byte from Z80 (count) 0138: E4E5C87EC603 RE4 := RE5,if true then Goto 0139 ; Save it. 0139: E800D87E4601 RE8 := 00,if true then Call 01BC ; Wait for ; interrupt, and next byte from the Z80. 013A: E503D2BEC403 RE5 xor 03,if true then Goto 013B ; Is this a ; message from the floppy system? 013B: E401DBBEAF83 RE4 := RE4 - 01,if NotEqual then Goto 0150 ; Decrement ; count. Go if message _not_ from floppy system. 013C: 0000C03E4601 R00,if true then Call 01BC ; Get another interrupt ; (and hence a byte from the Z80). 013D: E502D2BEC103 RE5 xor 02,if true then Goto 013E ; Is it a ; CmdBlkData message? 013E: E401DBBF8083 RE4 := RE4 - 01,if NotEqual then Goto 007F ; Go ; if not. 013F: 0000C03E4601 R00,if true then Call 01BC ; Read Data Block byte count ; from Z80 system. First get another byte. 0140: E4E5C87E4601 RE4 := RE5,if true then Call 01BC ; Store it in RE4 (= ; counter), and get another byte. 0141: E500C020700E RE5,LdShift := 8F,if true then Continue ; Set up new ; byte (=counter high byte) on R lines. Set up shifter to ; shift left 8 bits. 0142: E4E409FEBC03 RE4 := shift or RE4,if true then Goto 0143 ; Assemble word ; from 2 bytes. High byte came second. 0143: 0000C03E4601 R00,if true then Call 01BC ; Get and store next word ; from boot message. Call interrupt subroutine, and ; thus get next byte from the Z80 system 0144: 02E5C87E4601 R02 := RE5,if true then Call 01BC ; Store byte in R02. ; Get next byte by calling interrupt subroutine. 0145: E500C020700E RE5,LdShift :=8F,if true then Continue ; Set R lines to ; new byte. Set up shifter to Shift left 8 bits. 0146: 020209FEB703 R02 := shift or R02,if true then Goto 0148 ; Assemble 2 ; bytes to make a word. Low byte was read first (I/O system ; is Z80 based) 0147: 0200C03EB603 R02,if true then Goto 0149 ; Provide word to store (= ; new word from Disk system) 0148: E700C01FB803 RE7,Store,if true then Goto 0147 ; Set up address and start ; Store cycle 0149: E7FFD280170E RE7 xor 17FF,if true then Continue ; Compare address to ; limit (=3*800h-1). Thus 0800 48-bit words are to be ; read and stored. 014A: E701DB3FD183 RE7 := RE7 + 01,if NotEqual then Goto 002E ; Increment ; address. Go around again if not enough words stored. 014B: 0000D04FBA0E Out 45 := 00,if true then Continue ; Reset Z80 system. 014C: 0200D87E5801 R02 := 00,if true then Call 019E ; Call write ; Control store from RAM routine. Clear R2, which ; is used to hold the word fetched from RAM, and is ; added to the checksum 014D: 0000C03E81D3 R00,if Equal then Goto 017D ; If the checksum was 0 ; (and hence no errors), then execute loaded microcode. 014E: AAFFD87EAB03 RAA := FF,if true then Goto 0154 ; Go to hard disk boot. 014F: AAFFD87EABD3 RAA := FF,if Equal then Goto 0154 ; Get here from 007F. ; Go to hard disk boot if floppy disk boot received ; a NAK from the Z80. Otherwise fall into the ; 'discard message' routine at 0150. 0150: 0000C03E4601 R00,if true then Call 01BC ; Go here from 013B if ; message from Z80, but not from floppy task. Wait for ; interrupt (and hence read 1 byte from the Z80). 0151: E401DBBEAD03 RE4 := RE4 - 01,if true then Goto 0152 ; Decrement ; message byte counter. 0152: 0000C03ECDD3 R00,if Equal then Goto 0132 ; Go back if all bytes ; in message have been read. 0153: 0000C03EAF03 R00,if true then Goto 0150 ; round again if not 0154: 0802D87E1001 R08 := 02,if true then Call 01EF ; Hard disk ; boot starts here, as on the T1. Load ; #disks counter (only 2 disks allowed on the ; T2) and call the Z80 reset routine, which also ; enables the disk state machine 0155: B700D87EA903 RB7 := 00,if true then Goto 0156 ; Load port image ; (and disk enable) register 0156: B7C0D10FAC0E Out 53 := RB7 and C0,if true then Continue ; Write ; port image to DIB. This is a bug, brought over from the ; T1, where bits 6 and 7 are the drive select bits. They're ; the register select bits on the T2, of course. 0157: 0100D8FE3501 R01 := not(00),if true then Call 01CA ; Load test-ready ; loop counter and call test-ready routine 0158: DA00D87E93D3 RDA := 00,if Equal then Goto 016C ; Go if hard disk was ; Ready 0159: B720DB3EA503 RB7 := RB7 + 20,if true then Goto 015A ; Increment hard ; disk select bit, which is never written! 015A: 0801DBBEA303 R08 := R08 - 01,if true then Goto 015C ; Decrement hard ; drive count 015B: 0100C03EA003 R01,if true then Goto 015F ; Get here from 015D. Store ; low word of address in current location. 015C: 0100D87E94D3 R01 := 00,if Equal then Goto 016B ; Go to error routine if ; hard drive count has got to 0. and no drive became ; ready. Set up address/data counter for memory test. ; Another minor bug, I think 015D: 0101DB9FA403 R01 := R01 - 01,Store,if true then Goto 015B ; Decrement ; address amd start store cycle at that address. 015E: 000163BE9F03 MDI - R01,if true then Goto 0160 ; Read in data and compare ; it to what was written 015F: 0100C01EA103 R01,Fetch,if true then Goto 015E ; Start fetch cycle at ; same address. 0160: E601D87E9083 RE6 := 01,if NotEqual then Goto 016F ; Get here from ; 015E. Load DDS increment (so DDS goes to 11) and ; got to error routine if value read was not correct. 0161: 0101D3BE9D03 R01 - 01,if true then Goto 0162 ; Look at address-1 0162: 0000C03E9B53 R00,if C19 then Goto 0164 ; Go if address counter ; underflowed 0163: 0000C03EA203 R00,if true then Goto 015D ; Go round again and test next ; location. 0164: 0100D87E9903 R01 := 00,if true then Goto 0166 ; Reload address pointer ; with 0 0165: 000163BE9803 MDI - R01,if true then Goto 0167 ; compare it to what ; was written earlier 0166: 0101DB9E9A03 R01 := R01 - 01,Fetch,if true then Goto 0165 ; Decrement ; address and fetch next word 0167: E602D87E9083 RE6 := 02,if NotEqual then Goto 016F ; Load DDS increment ; (so DDS goes to 12), and go to error routine if value ; incorrect 0168: 0101D3BE9603 R01 - 01,if true then Goto 0169 ; Look at address-1 0169: 0000C03EA953 R00,if C19 then Goto 0156 ; Go back and look at ; hard disk if counter underflowed 016A: 0000C03E9903 R00,if true then Goto 0166 ; Check next location 016B: E603D87E9003 RE6 := 03,if true then Goto 016F ; Set increment to 3, so ; DDS gets to 13. Go to Error routine. 016C: DB01D87E2A01 RDB := 01,if true then Call 01D5 ; Get here from 0158 if ; hard disk was ready. ; Call restore heads to trk0 routine ; Load head register. 016D: DA00D87E8701 RDA := 00,if true then Call 0178 ; Load cylinder register. ; Call routine to read hard disk boot sectors into RAM ; and thence to the WCS. 016E: E604D87E82D3 RE6 := 04,if Equal then Goto 017D ; Go and execute ; loaded microcode if checksum OK. Otherwise set DDS ; increment (so that DDS =14) and fall into error routine. 016F: 0000C03E8B01 R00,if true then Call 0174 ; Error routine. Set ; DDS and loop. Moved from T1/0174. Call DDS setting ; routine 0170: 0000C03E8F03 R00,if true then Goto 0170 ; loop here after setting ; DDS on error. 0171: AAFFD840FF0E RAA := FFFF,if true then Continue ; A little delay ; subroutine moved from T1/0176. Load Loop counter ; (RAA) 0172: 0000C00000DA R00,if Equal then Return ; Exit if counter has ; reached 0 0173: AA01DBBE8D03 RAA := RAA - 01,if true then Goto 0172 ; Round again if ; the counter is not 0. 0174: 0000C0028E01 R00,Stack Reset ,if true then Call 0171 ; Set DDS routine ; moved from T1/179. Increment DDS and delay a bit. 0175: E601DBBE8903 RE6 := RE6 - 01,if true then Goto 0176 ; Decrement ; #times to increment. 0176: 0000C03E8B83 R00,if NotEqual then Goto 0174 ; Go back and increment ; DDS again if not done it enough times 0177: 0000C000000A R00,if true then Return ; exit. 0178: DC17D87E8603 RDC := 17,if true then Goto 0179 ; Load last sector ; number into sector register 0179: E700D840170E RE7 := 1700,if true then Continue ; Load RAM address to ; store last sector in 017A: E800D87E8403 RE8 := 00,if true then Goto 017B ; Clear checksum ; accumulator 017B: DC0FD3BE7E03 RDC - 0F,if true then Goto 0181 ; Compare sector number ; with 15 017C: E3DBC87E7C03 RE3 := RDB,if true then Goto 0183 ; Get here from 0181 or ; 0182. Load head # into DIB parameter register. 017D: E613D87E8B01 RE6 := 13,if true then Call 0174 ; Execute loaded ; microcode (moved from T1/17E). Increment DDS by ; 19 decimal (i.e. to 29), and continue 017E: 0000C03E2A0E R00,if true then Continue ; Continue - Why on earth ; was the routine moved ??? 017F: 0000D04FBA0E Out 45 := 00,if true then Continue ; Reset Z80 system. 0180: 0000C037FF03 R00,if true then Goto 0800 ; Execute loaded microcode at ; location 0800. 0181: DB01D87E83E3 RDB := 01,if Greater then Goto 017C ; get here from 017B ; Select head 1. Go if required sector on this head. 0182: DB00D87E8303 RDB := 00,if true then Goto 017C ; Otherwise select head ; 0. 0183: E3B7C9FE7B03 RE3 := RE3 or RB7,if true then Goto 0184 ; Get here from ; 017C. OR old parameter into DIB parameter register 0184: E3C0D1CFAC0E Out 53 := RE3 or C0,if true then Continue ; Write it ; to the DIB head/control register. 0185: D905D87E5B01 RD9 := 05,if true then Call 01A4 ; Load RD9 with state ; machine BRead command. Call routine to set up DMA and ; state machine parameters. 0186: D918D1CFAD0E Out 52 := RD9 or 18,if true then Continue ; Start state ; machine on BRead instruction. 0187: E000D87E3821 RE0 := 00,if IntrPend then Call 01C7 ; Clear result ; register and check for interrupts 0188: E0FFD100070E RE0 and 07FF,if true then Continue ; Look at return code 0189: 0000C03E70D3 R00,if Equal then Goto 018F ; Go if no interrupt ; occurred to set return value. 018A: E020D13E7403 RE0 and 20,if true then Goto 018B ; Look at drive fault bit 018B: E008D13E94D3 RE0 and 08,if Equal then Goto 016B ; Go and set DDS to ; 13 if drive fault. Look at State Machine Completed bit. 018C: E007D13E70D3 RE0 and 07,if Equal then Goto 018F ; Go and try again if ; command not completed. Look at status bits. 018D: E006D13E6CD3 RE0 and 06,if Equal then Goto 0193 ; Go if command completed ; correctly. Look at error results only 018E: E604D87E9083 RE6 := 04,if NotEqual then Goto 016F ; Set DDS to 14 if ; state machine error occurred. 018F: 0101DBBE6F03 R01 := R01 - 01,if true then Goto 0190 ; Decrement retry ; count 0190: E604D87E9053 RE6 := 04,if C19 then Goto 016F ; Set DDS to 14 and go ; to error routine if retry counter undeflowed. 0191: AA08D87E8D01 RAA := 08,if true then Call 0172 ; Otherwise wait a bit. 0192: 0000C03E7803 R00,if true then Goto 0187 ; and go back to check for ; interrupts again. 0193: 0018D04FAD0E Out 52 := 18,if true then Continue ; Re-enable state ; machine 0194: DC01DBBE6A03 RDC := RDC - 01,if true then Goto 0195 ; Decrement Sector ; number 0195: E704CBBE84F3 RE7 := RE7 - R04,if GreaterEqual then Goto 017B ; Decrement ; address by 100h. Go round again if not all sectors have ; been read. 0196: 0200D87E6103 R02 := 00,if true then Goto 019E ; Clear last word ; fetched register. Go to copy-RAM-to WCS routine. 0197: E700C03E6709 RE7,if true then Repeat 0198 ; Get here from 019B ; Decrement S register. Set flags according to RAM ; address (in RE7) 0198: 0000C03E5FE3 R00,if Greater then Goto 01A0 ; Go round ; again if address is >0 0199: E802C300000A RE8 + R02,if true then Return ; add last word into ; checksum and exit. 019A: E802CB3E5C01 RE8 := RE8 + R02,if true then Call 01A3 ; Add last ; word into checksum and fetch another. 019B: 0000C00C6807 R00,WCSL,if true then GotoS 0197 ; Write word into ; low part of control store and continue 019C: E802CB3E5C01 RE8 := RE8 + R02,if true then Call 01A3 ; Get here ; from 01A1. Add last word into checksum and fetch ; another 019D: 0000C00D6507 R00,WCSM,if true then GotoS 019A ; Write new word into ; middle of WCS and continue 019E: E700D840180E RE7 := 1800,if true then Continue ; Load WCS from ; RAM - moved from T1/01A7. Load address counter with ; last address+1 019F: 0000C030000C R00,if true then LoadS 0FFF ; Load S register ; (Microcode address pointer) 01A0: E802CB3E5C01 RE8 := RE8 + R02,if true then Call 01A3 ; Add last ; word to checksum, and fetch a new word 01A1: 0000C00E6307 R00,WCSH, if true then GotoS 019C ; Store new word ; (on R lines at 01A2) into high part of control ; store and continue 01A2: 02006800000A R02 := MDI,if true then Return ; Copy data into R2 ; (and on R lines) and exit 01A3: E701DB9E5D03 RE7 := RE7 - 01,Fetch,if true then Goto 01A2 ; Fetch ; word from RAM. Decrement address pointer (RE7) and ; Start fetch cycle 01A4: 0000D04FAF0E Out 50 := 00,if true then Continue ; Set up state machine ; and DMA for sector read. Clear register file pointer. 01A5: 0000D0CFAE0E Out 51 := not(00),if true then Continue ; Write sync bytes ; to register fike 01A6: 00F0D0CFAE0E Out 51 := not(F0),if true then Continue 01A7: DB00C08FAE0E Out 51 := not(RDB),if true then Continue ; Write Head to ; register file 01A8: DC00C020FC0E RDC,LdShift:=03,if true then Continue ; Place sector number ; on R lines. Set up shifter to extract 4 bit field ; starting at bit 0 01A9: 0000008FAE0E Out 51 := not(shift),if true then Continue ; write sector ; nybble to register file. 01AA: DA00C08FAE0E Out 51 := not(RDA),if true then Continue ; Output low ; cylinder address to register file 01AB: 0000D04FAE0E Out 51 := 00,if true then Continue ; More Sync bytes 01AC: 0000D04FAE0E Out 51 := 00,if true then Continue 01AD: DC00C020FC0E RDC,LdShift:=03,if true then Continue ; Place sector ; number on R lines. Set up shifter to extract low nybble 01AE: 0000008FAE0E Out 51 := not(shift),if true then Continue ; Write sector ; nybble to register file again. 01AF: DA00C020B40E RDA,LdShift:=4B,if true then Continue ; Set shifter to ; shift right 4 bits. Place cylinder address on R lines. 01B0: D8F0193E4E03 RD8 := shift and F0,if true then Goto 01B1 ; Read high ; nybble of cylinder address into RD8 01B1: D8DBC9FE4D03 RD8 := RD8 or RDB,if true then Goto 01B2 ; OR in head ; address 01B2: D800C08FAE0E Out 51 := not(RD8),if true then Continue ; Store it in the ; register file 01B3: 0000D04FAE0E Out 51 := 00,if true then Continue ; More sync bytes 01B4: 0000D04FAE0E Out 51 := 00,if true then Continue 01B5: 0100D8CFAE0E Out 51,R01 := not(00),if true then Continue 01B6: 0002D04FBF0E Out 40 := 02,if true then Continue ; Select DMA channel ; 2 (Hard disk) 01B7: 0000D04FA90E Out 56 := 00,if true then Continue ; Clear DMA header low ; address register 01B8: 00DFD04FA80E Out 57 := DF,if true then Continue ; Write header high ; address and count register. Set for 2 header quadwords 01B9: E700C00FAB0E Out 54 := RE7,if true then Continue ; Write DMA address ; low word. 01BA: 00E7A0A03C0E not(Ustate),BMUX:=RE7,LdShift:=C3,if true then Continue ; Set shifter to shift right by 12 bits. Read top 4 bits ; of address into BMUX, and hence into uState 15:12. 01BB: 0000000FAA0A Out 55 := shift,if true then Return ; Write top DMA address ; nybble (shifted into bits 0-3 of R) into DMA address ; register. Return to caller. 01BC: 0100D8FE4203 R01 := not(00),if true then Goto 01BD ; Check for ; Interrupt subroutine moved/modified from ; T1/01B9. Load loop counter 01BD: E500D87E3823 RE5 := 00,if IntrPend then Goto 01C7 ; Check for ; interrupts after clearing result register. 01BE: AA40D87E8D01 RAA := 40,if true then Call 0172 ; Set up delay counter ; and call delay routine 01BF: 0101DBBE3D03 R01 := R01 - 01,if true then Goto 01C2 ; Decrement ; loop counter and continue 01C0: 0000C00F2B0E [In D4] R00,if true then Continue ; Interrupt ; server for Z80 Data out ready. Read ; Z80 output FIFO 01C1: E5FF5900000A RE5 := I/OB and 00FF,if true then Return ; Load ; Fifo into RE5 and return 01C2: 0000C03E4283 R00;if NotEqual then Goto 01BD ; Get here from ; 01BF. Go back and try again if counter did not ; get to 0 01C3: 0000C43EAB0B R00,hold ,if true then Leappop 0154 ; Device ; failed to interrupt. Go to hard disk boot and ; try again. 01C4: E605D87E9003 RE6 := 05,if true then Goto 016F ; Interrupt ; server for OIO Y interrupt. Load RE6 with DDS ; increment and go to error routine 01C5: 0000C000008A R00,if NotEqual then Return ; get here from 01D1 ; Exit if it was ready. 01C6: E605D87E9003 RE6 := 05,if true then Goto 016F ; Load RE6 with DDS ; increment and got to error routine. 01C7: 0000C000E306 R00,if true then vector 01C0 ; Interrupt service ; routine - Go on interrupt vector 01C8: 0000C00F2C0E [In D3] R00,if true then Continue ; Interrupt server ; for hard disk interrupt. Read disk status port. 01C9: E0FF5900070A RE0 := I/OB and 07FF,if true then Return 01CA: 0000C00F2C0E [In D3] R00,if true then Continue ; Read hard disk ; status port. 01CB: 0080513E1803 I/OB and 80,if true then Goto 01DD ; test drive ready ; bit and go to next bit of the routine. 01CC: E607D87E8B03 RE6 := 07,if true then Goto 016F ; Interrupt server for ; Network interrupt. Load RE6 with value to increment DDS ; by and go to error routine. 01CD: 0001D040005A 0001,if C19 then Return ; Get here from 01E0. Exit if ; counter has got to 0 - hard disk has taken too long ; to spin up. Set R lines to 1 (and hence clear Z flag) 01CE: 0000C03E3503 R00,if true then Goto 01CA ; Go and test hard disk ; ready signal again. 01CF: 000000000000 shift;if true then Jump0 01D0: 0000C00F2A0E [In D5] R00,if true then Continue ; Z80 Data Input ; interrupt server. Read Z80 status port. 01D1: 0080513E3A03 I/OB and 80,if true then Goto 01C5 ; Look at ; Z80 ready bit. 01D2: 0040D04FAC0E Out 53 := 40,if true then Continue ; Get here from 01E4. ; Write low cylinder step count (=3F) and start head ; stepping. 01D3: 0100D8FE1A03 R01 := not(00),if true then Goto 01E5 ; Load retry count ; and continue 01D4: E609D87E9003 RE6 := 09,if true then Goto 016F ; Line counter overflow ; ISR. Load RE6 with DDS increment and go to error ; routine. 01D5: 0000C00F2C0E [In D3] R00,if true then Continue ; Read hard disk status ; port. 01D6: E0FF5900070E RE0 := I/OB and 07FF,if true then Continue ; Mask out ; unused bits 01D7: E0D0D13E1E03 RE0 and D0,if true then Goto 01E1 ; Look at Unit Ready, ; Seek Complete and Track 0 bits, then continue 01D8: E60AD87E9003 RE6 := 0A,if true then Goto 016F ; OIO X ISR. Load ; RE6 with DDS increment and go to error routine. 01D9: 000000000000 shift,if true then Jump0 ; NOP 01DA: 000000000000 shift,if true then Jump0 ; NOP 01DB: 000000000000 shift,if true then Jump0 ; NOP 01DC: E60BD87E9003 RE6 := 0B,if true then Goto 016F ; Memory ; Parity ISR. Load RE6 with DDS increment and go to ; error routine 01DD: 0000D04000DA 0000,if Equal then Return ; Get here from 01CB. If the ; Hard disk is ready, set the 0 flag and return 01DE: AAF4D840010E RAA := 01F4,if true then Continue ; Load delay counter 01DF: 0000C03E8D01 R00,if true then Call 0172 ; Call delay subroutine 01E0: 0101DBBE3203 R01 := R01 - 01,if true then Goto 01CD ; Decrement loop ; counter and contine 01E1: 0000C00000DA R00,if Equal then Return ; Get here from 01D7. Exit ; if drive OK and heads restored. 01E2: B7C0D1CFAC0E Out 53 := RB7 or C0,if true then Continue ; Clear Direction ; bit on DIB. 01E3: 0080D04FAC0E Out 53 := 80,if true then Continue ; Write high cylinder ; count (=3F) 01E4: 0000C03E2D03 R00,if true then Goto 01D2 ; continue 01E5: E000D87E3821 RE0 := 00,if IntrPend then Call 01C7 ; get here from 01D3. ; Look for hard disk ready interrupt. Service interrupt if ; it exists. First clear hard disk status register 01E6: E0FFD100070E RE0 and 07FF,if true then Continue ; Look at hard disk ; status (set by ISR) 01E7: 0001D07E14D3 01,if Equal then Goto 01EB ; if status is 0 (i.e. no ; interrupt occurred, then go. 01E8: E020D13E1603 RE0 and 20,if true then Goto 01E9 ; Look at drive fault ; bit. 01E9: E0D0D13E94D3 RE0 and D0,if Equal then Goto 016B ; Set DDS to 13 and ; go to error loop if drive fault. Look at Ready / track0 ; bits. 01EA: E040D10000DA RE0 and 0040,if Equal then Return ; Exit if head restored ; OK. Look at seek complete bit. 01EB: 0101DBBE2AD3 R01 := R01 - 01,if Equal then Goto 01D5 ; get here from 01E7 ; if no interrupt. Decrement retry counter. Go round again ; if seek completed OK, but heads not on Trk 0 01EC: E604D87E9053 RE6 := 04,if C19 then Goto 016F ; Go to error routine (and ; set DDS to 14) if counter undeflowed 01ED: AA08D87E8D01 RAA := 08,if true then Call 0172 ; Load delay count and ; wait a bit 01EE: 0000C03E1A03 R00,if true then Goto 01E5 ; Go round again and look for ; and interrupt again. 01EF: 0000D04FBA0E Out 45 := 00,if true then Continue ; Z80 Reset ; routine (moved and edited from T1/01FC). ; Set Z80 reset bit 01F0: 0000D04FAD0E Out 52 := 00,if true then Continue ; Disable ; disk state machine 01F1: 00C0D04FAC0E Out 53 := C0,if true then Continue ; Clear DIB control ; Register. 01F2: 0018D04FAD0E Out 52 := 18,if true then Continue ; Enable disk ; state machine and interrupts 01F3: 0000C000000A R00,if true then Return ; Exit 01F4: 000000000000 shift,if true then Jump0 01F5: 000000000000 shift,if true then Jump0 01F6: 000000000000 shift,if true then Jump0 01F7: 000000000000 shift,if true then Jump0 01F8: 000000000000 shift,if true then Jump0 01F9: 000000000000 shift,if true then Jump0 01FA: 000000000000 shift,if true then Jump0 01FB: 000000000000 shift,if true then Jump0 01FC: 000000000000 shift,if true then Jump0 01FD: 000000000000 shift,if true then Jump0 01FE: 000000000000 shift,if true then Jump0 01FF: 000000000000 shift,if true then Jump0