Start of Disassembly ; PERQ T1 Rom Bootstrap - CPU diagnostics and ; then boot from link, floppy and Micropolis drive ; in that order ; ; Useful register assignments in the disk routines : ; R01 - Retry counter ; R04 - Address decrement ; RD8 - DIB parameter ; RD9 - State Machine Command ; RDA - Cylinder ; RDB - Head ; RDC - Sector ; RE0 - disk status ; RE2 - DIB command ; RE4 - boot counter ; RE7 - RAM address ; RE8 - Checksum accumulator ; 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: E400D87E0301 RE4 := 00,if true then Call 01FC ; 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: E800D87E8901 RE8 := 00,if true then Call 0176 ; Call delay ; subroutine to wait while Z80 initiallises. Clear ; Checksum accumulator (RE8) 0027: 0006D04FBA0E Out 45 := 06,if true then Continue ; Enable Z80 ; interrupts. 0028: 0000C03E4601 R00,if true then Call 01B9 ; 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 01B9 ; 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 01B9 ; 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 01B9 ; 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 01B9 ; 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 01B9 ; Read Data Block byte count ; from Z80 system. First get another byte. 0140: E4E5C87E4601 RE4 := RE5,if true then Call 01B9 ; 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 01B9 ; 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 01B9 ; 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 01A7 ; 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 017E ; 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 01B9 ; 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: 0804D87E0301 R08 := 04,if true then Call 01FC ; Get here ; If Z80 failed to interrupt (amongst other things) ; Call Z80 reset routine. 0155: 0008D04FAD0E Out 52 := 08,if true then Continue ; Enable ; disk state machine. 0156: B700D87EA803 RB7 := 00,if true then Goto 0157 ; Clear port image ; register. 0157: B7C0D10FAC0E Out 53 := RB7 and C0,if true then Continue ; Select hard ; drive. 0158: 0018D04FAD0E Out 52 := 18,if true then Continue ; Enable disk state ; machine 0159: 0100D8FE3501 R01 := not(00),if true then Call 01CA ; Load outer retry ; counter (R1). Wait for hard disk to go ready. 015A: DA00D87E91D3 RDA := 00,if Equal then Goto 016E ; Go if hard disk ; disk became ready. 015B: B740DB3EA303 RB7 := RB7 + 40,if true then Goto 015C ; Increment hard ; disk number 015C: 0801DBBEA103 R08 := R08 - 01,if true then Goto 015E ; Decrement disk ; counter 015D: 0100C03E9E03 R01,if true then Goto 0161 ; Store low 16 bits of address ; in current location 015E: 0100D87E92D3 R01 := 00,if Equal then Goto 016D ; Go if all disks ; have been tested. Set up address (and data) counter for ; memory test 015F: 0101DB9FA203 R01 := R01 - 01,Store,if true then Goto 015D ; Decrement ; address and start store cycle. 0160: 000163BE9D03 MDI - R01,if true then Goto 0162 ; Compare fetched data ; with address (=stored value) 0161: 0100C01E9F03 R01,Fetch,if true then Goto 0160 ; Fetch the data back ; again from the current address. 0162: E601D87E8B83 RE6 := 01,if NotEqual then Goto 0174 ; Set DDS to 11 and ; go to error routine if they're not the same. 0163: 0101D3BE9B03 R01 - 01,if true then Goto 0164 ; Test to see if enough ; locations have been tested. 0164: 0000C03E9953 R00,if C19 then Goto 0166 ; Go if they have. 0165: 0000C03EA003 R00,if true then Goto 015F ; Still some to test. Go back, ; and do the next one. 0166: 0100D87E9703 R01 := 00,if true then Goto 0168 ; Set up address for ; readback address test. 0167: 000163BE9603 MDI - R01,if true then Goto 0169 ; Compare data read with ; correct value (=address in R1) 0168: 0101DB9E9803 R01 := R01 - 01,Fetch,if true then Goto 0167 ; Decrement ; address and start fetch cycle. 0169: E602D87E8B83 RE6 := 02,if NotEqual then Goto 0174 ; If they are ; not the same, then set DDS to 12 and got to error ; routine. 016A: 0101D3BE9403 R01 - 01,if true then Goto 016B ; test to see if all the ; locations have been tested. 016B: 0000C03EA853 R00,if C19 then Goto 0157 ; If so, then go back and ; select the next hard disk. 016C: 0000C03E9703 R00,if true then Goto 0168 ; If not, then go back and ; test the next location. 016D: E603D87E8B03 RE6 := 03,if true then Goto 0174 ; Increment DDS to 13 ; and go to error loop if disk did not become ready. 016E: DB00D87E1001 RDB := 00,if true then Call 01EF ; Call subroutine to ; restore heads to track 0. Clear Head address 016F: DA00D87E7E01 RDA := 00,if true then Call 0181 ; Load sectors from ; hard disk into RAM and thence to WCS. Clear Cylinder ; address 0170: 0000C03E81D3 R00,if Equal then Goto 017E ; If microcode was good, then ; execute it. 0171: DA01DB3E8D03 RDA := RDA + 01,if true then Goto 0172 ; Increment ; cylinder number 0172: DB01D87E7E01 RDB := 01,if true then Call 0181 ; Select head 1, and ; read in bootstrap. 0173: E604D87E81D3 RE6 := 04,if Equal then Goto 017E ; Set DDS increment to ; 4 (so DDS gets to 14). Go and execute loaded microcode ; if it was good, else fall into error routine. 0174: 0000C03E8601 R00,if true then Call 0179 ; Error routine to ; Set DDS. Call DDS increment routine. 0175: 0000C03E8A03 R00,if true then Goto 0175 ; Loop here after ; setting DDS to show error. 0176: AAFFD840FF0E RAA := FFFF,if true then Continue ; A little delay ; subroutine. Set up delay counter (RAA) 0177: 0000C00000DA R00,if Equal then Return ; Exit if counter has ; reached 0 0178: AA01DBBE8803 RAA := RAA - 01,if true then Goto 0177 ; Decrement ; counter and go round again. 0179: 0000C0028901 R00,Stack Reset ,if true then Call 0176 ; Increment ; DDS and delay a bit. 017A: E601DBBE8403 RE6 := RE6 - 01,if true then Goto 017B ; Decrement ; counter (#times to increment DDS in RE6). 017B: 0000C03E8683 R00,if NotEqual then Goto 0179 ; If counter ; has not reached 0, then go back and decrement DDS ; again. 017C: 0000C000000A R00,if true then Return ; DDS is at the right ; value, so exit. 017D: E008D2BE6503 RE0 xor 08,if true then Goto 019A ; Get here from ; 0199. Compare result code to 08 (=OK) 017E: E613D87E8601 RE6 := 13,if true then Call 0179 ; Set DDS to DDS+19 ; (decimal). This sets DDS to 29, in readyness for the ; VFY microcode pulled from the disk. 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: DC17D87E3C01 RDC := 17,if true then Call 01C3 ; Call routine to ; Enable disk state machine and interrupts. Load ; Sector register with sector number of _last_ microcode ; sector. 0182: E700D840170E RE7 := 1700,if true then Continue ; Load address ; pointer with start address of this sector 0183: E800D87E7B03 RE8 := 00,if true then Goto 0184 0184: D8DAC87E1401 RD8 := RDA,if true then Call 01EB ; Copy Cylinder parameter ; (in RDA) into parameter register (RD8), and then ; call write-to-DIB routine. 0185: E200D87E2A01 RE2 := 00,if true then Call 01D5 ; Load CylLow command, ; and call write-cmd routine. 0186: DA00C020B40E RDA,LdShift:=4B,if true then Continue ; Place cylinder ; parameter on the R lines, and set shifter to shift ; right by 4 bits. 0187: D8F0193E7703 RD8 := shift and F0,if true then Goto 0188 ; Read top ; 4 bits of cylinder into parameter register. 0188: D8DBC9FE1401 RD8 := RD8 or RDB,if true then Call 01EB ; OR in ; head address (in RDB), and write address to DIB. 0189: E220D87E2A01 RE2 := 20,if true then Call 01D5 ; Send CylHigh Command 018A: 0100D8FE7403 R01 := not(00),if true then Goto 018B ; Load Retry counter 018B: AA40D87E8801 RAA := 40,if true then Call 0177 ; Load delay count ; (RAA) and call delay routine 018C: 0101DBBE7203 R01 := R01 - 01,if true then Goto 018D ; Decrement retry ; count 018D: E604D87E8B53 RE6 := 04,if C19 then Goto 0174 ; If too many retries, ; then set DDS to 14 and go to error routine 018E: E040D87E2421 RE0 := 40,if IntrPend then Call 01DB ; Load result ; register (RE0), which will be changed by the ISR. ; Check for seek complete interrupt 018F: E040D13E6F03 RE0 and 40,if true then Goto 0190 ; Look at seek complete ; bit 0190: E0B0D93E7483 RE0 := RE0 and B0,if NotEqual then Goto 018B ; If not ; seek complete then go round again. Mask out error ; bits (Unit Ready, Fault, Seek Error) 0191: E030D2BE6D03 RE0 xor 30,if true then Goto 0192 ; Flip Seek Error ; and fault bits. Result should be 0 if drive OK 0192: E604D87E8B83 RE6 := 04,if NotEqual then Goto 0174 ; If not, then ; set DDS to 14 and go to error loop. 0193: D905D87E5201 RD9 := 05,if true then Call 01AD ; Set up DMA and disk ; register file for sector read. Load RD9 with ; state machine command - BRead 0194: D800D87E1401 RD8 := 00,if true then Call 01EB ; Load parameter 0 into ; DIB 0195: E210D87E2A01 RE2 := 10,if true then Call 01D5 ; Write it as a command - ; turn off drive special features. 0196: D958D1CFAD0E Out 52 := RD9 or 58,if true then Continue ; Send command ; (along with NotReset, Interrupt enable and BusEn) to ; the disk state machine. Start disk reading. 0197: E000D87E2421 RE0 := 00,if IntrPend then Call 01DB ; Clear result ; register and check for command complete interrupt 0198: 0101DBBE64D3 R01 := R01 - 01,if Equal then Goto 019B ; Decrement ; retry counter. Go if no interrupt 0199: E00FD93E8203 RE0 := RE0 and 0F,if true then Goto 017D ; Look at ; state machine status. Go to next bit of the ; routine. 019A: 0100C03E62D3 R01,if Equal then Goto 019D ; Go if command completed ; OK, otherwise go round again. 019B: 0000C03E6883 R00,if NotEqual then Goto 0197 ; Go round again if counter ; did not get to 0 019C: E604D87E8B03 RE6 := 04,if true then Goto 0174 ; Interrupt timed ; out. Increment DDS to 14 and go to error loop. 019D: DC01DBBE5A03 RDC := RDC - 01,if true then Goto 01A5 ; Decrement ; sector number. Get here from 019A 019E: E700C03E6009 RE7,if true then Repeat 019F ; Get here from 01A2. ; Decrement S register and continue. Place RAM address ; on R lines (and hence set flags) 019F: 0000C03E56E3 R00,if Greater then Goto 01A9 ; Go arround again if ; RAM address (RE7) is >0. 01A0: E802C300000A RE8 + R02,if true then Return ; Set flags for final ; checksum and exit. 01A1: E802CB3E5301 RE8 := RE8 + R02,if true then Call 01AC ; Add new ; (middle) word into checksum, and fetch another 01A2: 0000C00C6107 R00,WCSL,if true then GotoS 019E ; Store new word in ; low part of the WCS 01A3: E802CB3E5301 RE8 := RE8 + R02,if true then Call 01AC ; Get here from ; 01AA. Add last word into checksum, and fetch another one 01A4: 0000C00D5E07 R00,WCSM,if true then GotoS 01A1 ; Store new word ; into middle part of WCS. 01A5: E704CBBE6CF3 RE7 := RE7 - R04,if GreaterEqual then Goto 0193 ; ; Get here from 019D. Decrement start address. and ; go back for another sector if sector count did ; not get to 0 01A6: 0200D87E3C01 R02 := 00,if true then Call 01C3 ; All the sectors ; transfered. Enable state machine and interrupt and ; fall into Copy boot from RAM to WCS. 01A7: E700D840180E RE7 := 1800,if true then Continue ; Copy boot program ; from RAM into WCS. Load address register (RE7) with ; number of 16 bit words to transfer (and hence last ; address + 1). 01A8: 0000C030000C R00,if true then LoadS 0FFF ; Load S register (microcode ; address pointer) 01A9: E802CB3E5301 RE8 := RE8 + R02,if true then Call 01AC ; add next ; 16 bit word to the checksum register (RE8). Fetch another ; word. 01AA: 0000C00E5C07 R00,WCSH,if true then GotoS 01A3 ; Store new word (on ; R lines (at location 01AB)) into high part of WCS. 01AB: 02006800000A R02 := MDI,if true then Return ; Copy data into R2, and ; exit 01AC: E701DB9E5403 RE7 := RE7 - 01,Fetch,if true then Goto 01AB ; Decrement ; address, set up memory fetch cycle using new address. 01AD: 0000D04FAF0E Out 50 := 00,if true then Continue ; Set up Disk ; register file and DMA for hard disk read. First, ; clear register file pointer 01AE: 0000D0CFAE0E Out 51 := not(00),if true then Continue ; Write sync ; bytes to register file 01AF: 00F0D0CFAE0E Out 51 := not(F0),if true then Continue 01B0: 0000D0CFAE0E Out 51 := not(00),if true then Continue 01B1: DC00C08FAE0E Out 51 := not(RDC),if true then Continue ; Write sector ; number to register file 01B2: DA00C08FAE0E Out 51 := not(RDA),if true then Continue ; Write cylinder ; low byte 01B3: 0000D04FAE0E Out 51 := 00,if true then Continue ; More sync bytes 01B4: 0000D04FAE0E Out 51 := 00,if true then Continue 01B5: DC00C08FAE0E Out 51 := not(RDC),if true then Continue ; Sector again 01B6: DA00C020B40E RDA,LdShift:=4B,if true then Continue ; Set up shifter for ; shift right 4 bits. Place Cylinder address (RDA) on R ; lines 01B7: D8F0193E4703 RD8 := shift and F0,if true then Goto 01B8 ; Read high nybble ; of cylinder address into RD8 01B8: D8DBC9FE2203 RD8 := RD8 or RDB,if true then Goto 01DD ; OR in the ; head number, and go to next part of routine 01B9: 0100D8FE4503 R01 := not(00),if true then Goto 01BA ; Check for ; interrupt routine. Set up loop counter. 01BA: E500D87E2423 RE5 := 00,if IntrPend then Goto 01DB ; Check for ; interrupts. 01BB: AA40D87E8801 RAA := 40,if true then Call 0177 ; Set up ; delay counter and call delay routine. 01BC: 0101DBBE4203 R01 := R01 - 01,if true then Goto 01BD ; Decrement ; loop counter. 01BD: 0000C03E4583 R00,if NotEqual then Goto 01BA ; Go arround again ; until the counter reaches 0. 01BE: 0000C43EAB0B R00,hold ,if true then Leappop 0154 ; It didn't ; work. Pop 1 level off return stack (= this ; routine), and go to try again. 01BF: E608D2BE3D03 RE6 xor 08,if true then Goto 01C2 ; Get here from ; 01C9. Flip Interrupt bit. The result should ; be 0 if the DSM initiallised OK. 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: E0FF5900078A RE0 := I/OB and 07FF,if NotEqual then Return ; Get ; here from 01BF. Read disk status into RE0. Exit if ; DSM didn't initiallise OK. 01C3: 0018D04FAD0A Out 52 := 18,if true then Return ; Get here from 01FE ; also. Write to Disk State Machine register. Enable ; Interrupts and reset disk state machine. Return 01C4: E605D87E8B03 RE6 := 05,if true then Goto 0174 ; Interrupt server ; for OIO Y interrupt. Load RE6 with value to increment ; DDS by and go to error routine. 01C5: 0000C000008A R00,if NotEqual then Return ; get here from 01D1 ; Exit if it was ready. 01C6: E605D87E8B03 RE6 := 05,if true then Goto 0174 ; Load RE6 with ; DDS increment and go to error routine. 01C7: 0018D04FAD0A Out 52 := 18,if true then Return ; Get here from ; 01DA. Set BusEn low, and exit. 01C8: 0000C00F2C0E [In D3] R00,if true then Continue ; Interrupt server ; for hard disk interrupt. Read disk status port. 01C9: E60F593E4003 RE6 := I/OB and 0F,if true then Goto 01BF ; Copy ; disk state machine status bits into RE6, and go ; to error test routine. 01CA: 0000C00F2C0E [In D3] R00,if true then Continue ; Read hard disk ; status port. 01CB: 0080513E1803 I/OB and 80,if true then Goto 01E7 ; test drive ready ; bit and go to next bit of the routine. 01CC: E607D87E8B03 RE6 := 07,if true then Goto 0174 ; 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 01EA. 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: E3B7C9FE2803 RE3 := RE3 or RB7,if true then Goto 01D7 ; Part of ; the write-to-micropolis routine. RE3 contains 1 nybble ; of the parameter to write to the DIB. OR in the drive ; number (in RB7), and continue 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: E3D8C87E3001 RE3 := RD8,if true then Call 01CF ; Get here from 01EE ; Copy the low nybble into RE3, and call the write-to-DIB ; routine. 01D3: 0018D04FAD0A Out 52 := 18,if true then Return ; Bring BusEn low ; again to latch the low nybble, and exit. 01D4: E609D87E8B03 RE6 := 09,if true then Goto 0174 ; Line counter ; overflow ISR. Load RE6 with DDS increment and ; go to error routine. 01D5: E2B7C1CFAC0E Out 53 := RE2 or RB7,if true then Continue ; Write-cmd- ; to-DIB routine. RE2 contains a command (Function, ; CylHigh, CylLow) in bits 4,5. OR in the Drive number in ; RB7, and write the result to the DIB port. 01D6: 0000C03E2603 R00,if true then Goto 01D9 ; continue 01D7: E330D1CFAC0A Out 53 := RE3 or 30,if true then Return ; Get here from ; 01CF. OR the load command (xx11xxxx) into the parameter, ; and write it to the disk command port. Then exit. 01D8: E60AD87E8B03 RE6 := 0A,if true then Goto 0174 ; X (OIO) ISR ; load RE6 with DDS increment and go to error ; routine. 01D9: 0058D04FAD0E Out 52 := 58,if true then Continue ; get here from 01D6. ; Set BusEn high to latch command 01DA: 0000C03E3803 R00,if true then Goto 01C7 ; continue 01DB: 0000C000E306 R00,if true then vector01C0 ; Interrupt service ; routine. Go on interrupt vector. 01DC: E60BD87E8B03 RE6 := 0B,if true then Goto 0174 ; Memory ; parity ISR. Load RE6 with DDS increment and ; go to error routine. 01DD: D800C08FAE0E Out 51 := not(RD8),if true then Continue ; Get here from ; 01B8. Write high cylinder and head address to register ; file. 01DE: 0000D04FAE0E Out 51 := 00,if true then Continue ; Send more ; sync bytes. 01DF: 0000D04FAE0E Out 51 := 00,if true then Continue 01E0: 0100D8CFAE0E Out 51,R01 := not(00),if true then Continue ; Also set up ; retry counter for main routine. 01E1: 0002D04FBF0E Out 40 := 02,if true then Continue ; Select DMA channel ; 2 (Disk Channel) 01E2: 0000D04FA90E Out 56 := 00,if true then Continue ; Clear DMA header ; low address register. 01E3: 00DFD04FA80E Out 57 := DF,if true then Continue ; Write header high ; address and count register. Set for 2 header quadwords 01E4: E700C00FAB0E Out 54 := RE7,if true then Continue ; Write low 16 ; bits of the DMA address 01E5: 00E7A0A03C0E not(Ustate),Bmux=RE7,LDShift:=C3,if true then Continue ; Set up shifter to shift right by 12 bits. Read ; top 4 bits off address into BMUX, and then into ; bits 15-12 of uState register. 01E6: 0000000FAA0A Out 55 := shift,if true then Return ; Read top ; 4 bits into bottom 4 bits of R, and thus to the ; DMA high address register. Exit back to caller. 01E7: 0000D04000DA 0000,if Equal then Return ; Get here from 01CB ; Return if drive ready. Set ; R lines to 0. 01E8: AAF4D840010E RAA := 01F4,if true then Continue ; Set up delay count in ; RAA 01E9: 0000C03E8801 R00,if true then Call 0177 ; Call delay subroutine. 01EA: 0101DBBE3203 R01 := R01 - 01,if true then Goto 01CD ; Decrement main ; counter, and go to next section 01EB: D800C020B40E RD8,LdShift:=4B,if true then Continue ; Write a parameter ; to the micropolis DIB. Set up the shifter to shift ; right by 4 bits. Place the parameter (in RD8) on the ; R lines. 01EC: E30F193E3001 RE3 := shift and 0F,if true then Call 01CF ; Extract the ; High nybble of the parameter. Call the routine to ; write it to the DIB port. 01ED: 0058D04FAD0E Out 52 := 58,if true then Continue ; Set the BusEn line ; to latch the high nybble. 01EE: D80FD93E2D03 RD8 := RD8 and 0F,if true then Goto 01D2 ; Select the ; low nybble of the parameter. Go to the next bit of the ; subroutine. 01EF: D840D87E1401 RD8 := 40,if true then Call 01EB ; Restore Micropolis ; drive heads to track 0. ; Load RESTORE command into RD8 and Call write-to-DIB 01F0: E210D87E2A01 RE2 := 10,if true then Call 01D5 ; Write Function command ; to DIB. Send restore command. 01F1: 0100D8FE0D03 R01 := not(00),if true then Goto 01F2 ; Set up ; retry counter in R1. 01F2: E000D87E2421 RE0 := 00,if IntrPend then Call 01DB ; Clear result ; register and check for interrupts. Disk ISR (at ; 01C8) writes status into RE0. 01F3: E0FFD100070E RE0 and 07FF,if true then Continue ; Mask out unused ; bits and set flags. 01F4: 0001D07E07D3 01,if Equal then Goto 01F8 ; If result is 0, then ; nothing happened. Go and try again. 01F5: E020D13E0903 RE0 and 20,if true then Goto 01F6 ; look at fault bit. 01F6: E010D13E92D3 RE0 and 10,if Equal then Goto 016D ; if Fault then ; go to routine to set DDS to 13 and go to error loop. ; look at seek error bit. 01F7: E040D13E92D3 RE0 and 40,if Equal then Goto 016D ; if seek error ; then go and set DDS to 13 and error. :Look at Seek ; complete bit 01F8: 0101DB8000DA R01 := R01 - 0001,if Equal then Return ; Decrement ; retry count. When reached from 01F4, then the condition ; is always false. When reached from 01F7, then it returns ; when seek complete. 01F9: E604D87E8B53 RE6 := 04,if C19 then Goto 0174 ; If the retry counter ; gets to 0, then increment DDS by 4 (to 14), and go ; to error routine. 01FA: AA08D87E8801 RAA := 08,if true then Call 0177 ; Delay for a short ; period. 01FB: 0000C03E0D03 R00,if true then Goto 01F2 ; Go back and check for ; another interrupt 01FC: 0000D04FBA0E Out 45 := 00,if true then Continue ; Z80 Reset Routine ; Called from 0024. Set Z80 reset bit. 01FD: 0000D04FAC0E Out 53 := 00,if true then Continue ; Clear DIB ; data port - clear hard disk control registers. 01FE: 0000C03E3C03 R00,if true then Goto 01C3 ; Go to next ; bit of the routine. 01FF: 000000000000 shift,if true then Jump0