This page sets out the source code for a few RX02 bootstraps, as well as some comments about them.
Brief summary
These are the key things that I’ve learned about RX02 bootloaders:
- The UNIBUS RX02 controller is the RX211 (M8256).
- The QBUS RX02 controller is the RXV21 (M8029).
- The bootstrap for the RX211 (UNIBUS) and RXV21 (QBUS) are identical.
- The boot sectors (to be loaded by the bootstrap) are always on Track 1 (not Track 0) of the disk.
- Both single-density and double-density disks each have 26 sectors per track. Those sectors are numbered 1 through 26. Physical and logical sector numbering is identical (ie – the sector numbers as recorded in the ID fields run sequentially, there is no physical interleave of sectors).
- Single-density disks have 128-byte sectors. Double-density disks have 256-byte sectors.
- The boot sectors are odd-numbered sectors, commencing at Sector 1. This is true for both single-density and double-density boot disks. Perhaps this is done for interleave reasons (to avoid waiting for the disk to complete a full revolution when the bootstrap is ready to request the next sector). The even-numbered sectors are not loaded by the bootstrap.
- DEC’s RX01/RX02 Pocket Service Guide (DEC Order Number EK-RX012-PS-002) has a bootstrap at Table 1-10 that works perfectly well for booting a double-density disk on Unit 0. I’ll call this the PSG DY Bootstrap.
- An RX02 can boot single-density or double-density disks. However, in each case the boot sectors must include the boot block for a DY (RX02) device.
- RX02 bootstraps are density-specific. A double-density bootstrap won’t boot a single-density RX02 disk, and vice versa.
- An RX01 disk (which is always single-density) won’t boot on an RX02 drive, because the boot sectors will contain a DX (RX01) boot block.
- The PSG DY Bootstrap doesn’t include any instructions for modifying it to boot from Unit 1, or to boot single-density RX02 disks. Both modifications are possible, and are shown below on this page.
- DEC’s PDP-11 Microcomputer Interfaces Handbook 1983-84 (DEC Order Number EB-23144-18) includes at Page 484 both single-density and double-density bootstraps for the RXV21. I will call these the Handbook SDEN RX02 Bootstrap and the Handbook DDEN RX02 Bootstrap. There are two significant problems with these bootstraps. Firstly, the double-density bootstrap has 6 errors and deficiencies in it. The corrections are described below on this page. Secondly, both bootstraps only load 512 bytes, and this is insufficient for RT-11 V5.3. This problem is also described further below.
- Once the bootstrap has loaded the boot sectors into RAM, the bootstrap then jumps to Address O’000000. This is usually done by way of a CLR PC instruction (O’005007).
- Register R0 must be updated by the bootstrap before jumping to Address O’000000. R0 must be O’000000 if the boot drive was Unit 0, or O’000001 if the boot drive was Unit 1. RT-11 V5.3 will otherwise fail to boot.
The RX01/RX02 Pocket Service Guide DY Bootstrap
The PSG DY Bootstrap appears at Table 1-10 of the RX01/RX02 Pocket Service Guide (DEC Order Number EK-RX012-PS-002). A thumbnail image of that table is shown here on the right. Click on it for a full-size version.
The PSG DY Bootstrap has the following main features:
- It only works with double-density RX02 disks
- It resides in memory commencing at O’002000
- The start address is O’002000
- It loads 1024 bytes into RAM commencing at O’000000 and ending at O’001777
- Those 1024 bytes are sequentially Sectors 1, 3, 5 and 7 of Track 1
- It then clears register R0 and jumps to O’000000 (by doing a CLR PC)
I have re-created the source code for the PSG DY Bootstrap.
Here it is:
1 .TITLE PSG BOOTSTRAP FOR RX211/RXV21 2 3 ; THIS IS THE RX211/RXV21 BOOTSTRAP THAT APPEARS IN 4 ; THE RX01/RX02 POCKET SERVICE GUIDE (DEC ORDER NUMBER 5 ; EK-RX012-PS-002). IT BOOTS ONLY DOUBLE-DENSITY 6 ; DISKS. 7 ; 8 ; MALCOLM MACLEOD - 11 JUNE 2017 9 10 000000 .ASECT 11 002000 .=002000 12 13 177170 RX2CS = 177170 ; RXV21 CONTROL/STATUS REGISTER 14 177172 RX2DB = 177172 ; RXV21 DATA BUFFER REGISTER 15 000200 WRDCNT = ^D128 ; 128 FOR DBL-DEN, 64 FOR SGL-DEN 16 100240 MASK = 100240 ; BIT 15=ERR, 7=XFER-RQST, 5=DONE 17 18 002000 012701 177170 MOV #RX2CS,R1 ; PUT ADDR OF RX2CS INTO R1 19 002004 012700 100240 MOV #MASK,R0 ; PUT BIT MASK INTO R0 20 002010 005002 CLR R2 ; CLEAR BUS ADDR (DMA DEST'N ADDR) 21 002012 012705 000200 MOV #WRDCNT,R5 ; PUT WORD COUNT (128) INTO R5 22 002016 012704 000401 MOV #401,R4 ; TRACK 1, SECTOR 1 23 002022 012703 177172 $1: MOV #RX2DB,R3 ; PUT ADDR OF RX2DB IN R3 24 25 ; CHECK THAT THE RXV21 IS READY 26 27 002026 030011 $2: BIT R0,(R1) ; APPLY MASK TO RX2CS 28 002030 001776 BEQ $2 ; LOOP UNTIL ERR, XFER-RQST OR DONE 29 002032 100440 BMI QUIT ; HALT IF ERR IS SET 30 31 ; INITIATE A READ-SECTOR COMMAND 32 33 002034 012711 000407 MOV #407,(R1) ; DEN=DDEN, UNIT=0, FN=RD-SECTOR, GO 34 002040 030011 $3: BIT R0,(R1) ; APPLY MASK TO RX2CS 35 002042 001776 BEQ $3 ; LOOP UNTIL ERR, XFER-RQST OR DONE 36 002044 100433 BMI QUIT ; HALT IF ERR IS SET 37 ; CODE ASSUMES THAT XFER-RQST IS NOW SET (IGNORES DONE) 38 002046 110413 MOVB R4,(R3) ; WRITE SECTOR NUMBER TO RX2DB 39 002050 000304 SWAB R4 ; SWAP TRACK NUMBER TO BITS 0-7 40 002052 030011 $4: BIT R0,(R1) ; APPLY MASK TO RX2CS 41 002054 001776 BEQ $4 ; LOOP UNTIL ERR, XFER-RQST OR DONE 42 ; CODE ASSUMES THAT XFER-RQST (NOT ERR OR DONE) IS NOW SET 43 002056 110413 MOVB R4,(R3) ; WRITE TRACK NUMBER TO RX2DB 44 45 ; RXV21 IS NOW READING SECTOR DATA INTO ITS OWN BUFFER 46 47 002060 000304 SWAB R4 ; SWAP TRACK NUMBER TO BITS 15-8 48 002062 030011 $5: BIT R0,(R1) ; APPLY MASK TO RX2CS 49 002064 001776 BEQ $5 ; LOOP UNTIL ERR, XFER-RQST OR DONE 50 002066 100422 BMI QUIT ; HALT IF ERR IS SET 51 52 ; CODE ASSUMES THAT XFER-RQST IS NOW SET (IGNORES DONE) 53 54 ; THE SECTOR DATA IS NOW IN RXV21'S DATA BUFFER. 55 ; PREPARE TO TRANSFER SECTOR DATA FROM RXV21 TO RAM BY DMA 56 57 002070 012711 000403 MOV #403,(R1) ; DEN=DDEN, UNIT=ANY, FN=EMPTY-BUF, GO 58 002074 030011 $6: BIT R0,(R1) ; APPLY MASK TO RX2CS 59 002076 001776 BEQ $6 ; LOOP UNTIL ERR, XFER-RQST OR DONE 60 002100 100415 BMI QUIT ; HALT IF ERR IS SET 61 ; CODE ASSUMES THAT XFER-RQST IS NOW SET (IGNORES DONE) 62 002102 010513 MOV R5,(R3) ; LD WORD COUNT INTO RX2WC VIA RX2DB 63 002104 030011 $7: BIT R0,(R1) ; APPLY MASK TO RX2CS 64 002106 001776 BEQ $7 ; LOOP UNTIL ERR, XFER-RQST OR DONE 65 002110 100411 BMI QUIT ; HALT IF ERR IS SET 66 ; CODE ASSUMES THAT XFER-RQST IS NOW SET (IGNORES DONE) 67 002112 010213 MOV R2,(R3) ; LD BUS ADDRS INTO RX2BA VIA RX2DB 68 69 ; DATA (256 BYTES) IS NOW BEING COPIED TO RAM VIA DMA 70 71 002114 060502 ADD R5,R2 ; ADD 128 DEC TO BUS ADDRESS 72 002116 060502 ADD R5,R2 ; ADD 128 DEC TO BUS ADDRESS 73 002120 122424 CMPB (R4)+,(R4)+ ; INCREMENT SECTOR NUMBER BY 2 74 002122 120427 000007 CMPB R4,#7 ; SECTORS 1, 3, 5 & 7 WILL BE READ 75 002126 003737 BLE $2 ; LOOP BACK AND DO NEXT SECTOR 76 002130 005000 CLR R0 ; BOOT DOESN'T WORK WITHOUT THIS 77 002132 005007 CLR PC ; GO TO ADDR ZERO 78 002134 000000 QUIT: HALT 79 80 000001 .END
You can also download the source code and assembly listing files for the PSG DY Bootstrap here if you need them:
Dual-Density RX02 Bootstrap
I’ve modified the PSG DY Bootstrap so that:
- It can boot from Unit 0 (Drive 0) or Unit 1 (Drive 1)
- It can boot either dual-density or single-density disks
To modify the PSG DY Bootstrap so that it boots from Unit 1:
- Change the word at 002036 from 000407 to 000427.
- At the tail end of the listing, delete the CLR R0 instruction and replace it with a MOV #0,R0 instruction. Note this lengthens the bootstrap by one word, and therefore will require some branch instructions to be updated as well, because they use relative address.
- In the new MOV #0,R0 instruction, change the word at 002130 from 000000 to 000001.
- Update the relative addresses in the various branch instructions (this affects the words at addresses 2032, 2044, 2066, 2100 and 2110). See the listing below.
To modify the PSG DY Bootstrap so that it works with single-density disks:
- Change the word at 2014 from 000200 to 00100 (this sets the WRDCNT to 64, for 128-byte sectors).
- Change the word at 002036 from 000407 to 000007 (this selects single-density in the read-sector command).
- Change the word at 002072 from 000403 to 000003 (this selects single-density in the empty-buffer command).
- Change the word at 002124 from 000007 to 000017 (so we read up to and including sector D’15).
The listing below includes self-modifying code (at lines 92 to 100) so that it can attempt to boot a single-density disk, if the initial attempt to boot a dual-density disk fails.
Here is the listing:
1 .TITLE DUAL-DENSITY BOOTSTRAP FOR RX02 2 3 ; THIS BOOTSTRAP IS DERIVED FROM THE RX211/RXV21 4 ; BOOTSTRAP THAT APPEARS IN THE RX01/RX02 POCKET SERVICE 5 ; GUIDE (DEC ORDER NUMBER EK-RX012-PS-002). 6 ; 7 ; IT HAS BEEN MODIFIED SO THAT: 8 ; * IT CAN BE USED FOR UNIT 0 OR UNIT 1 9 ; * IT WILL FIRST ATTEMPT TO BOOT A DOUBLE-DENSITY DISK. 10 ; IF THAT FAILS, IT WILL THEN ATTEMPT TO BOOT A 11 ; SINGLE-DENSITY DISK. 12 ; 13 ; THE CODE SHOWN BELOW IS FOR UNIT 0. TO BOOT FROM UNIT 1: 14 ; * CHANGE THE WORD AT 002036 FROM 000407 TO 000427 15 ; * CHANGE THE WORD AT 002132 FROM 000000 TO 000001 16 ; 17 ; MALCOLM MACLEOD - 11 JUNE 2017 18 19 000000 .ASECT 20 002000 .=002000 21 22 177170 RX2CS = 177170 ; RXV21 CONTROL/STATUS REGISTER 23 177172 RX2DB = 177172 ; RXV21 DATA BUFFER REGISTER 24 000200 WRDCNT = ^D128 ; 128 FOR DBL-DEN, 64 FOR SGL-DEN 25 100240 MASK = 100240 ; BIT 15=ERR, 7=XFER-RQST, 5=DONE 26 27 002000 012701 177170 START: MOV #RX2CS,R1 ; PUT ADDR OF RX2CS INTO R1 28 002004 012700 100240 MOV #MASK,R0 ; PUT BIT MASK INTO R0 29 002010 005002 CLR R2 ; CLEAR BUS ADDR (DMA DEST'N ADDR) 30 002012 012705 000200 MOV #WRDCNT,R5 ; PUT WORD COUNT (128) INTO R5 31 002016 012704 000401 MOV #401,R4 ; TRACK 1, SECTOR 1 32 002022 012703 177172 $1: MOV #RX2DB,R3 ; PUT ADDR OF RX2DB IN R3 33 34 ; CHECK THAT THE RXV21 IS READY 35 36 002026 030011 $2: BIT R0,(R1) ; APPLY MASK TO RX2CS 37 002030 001776 BEQ $2 ; LOOP UNTIL ERR, XFER-RQST OR DONE 38 002032 100441 BMI QUIT ; HALT IF ERR IS SET 39 40 ; INITIATE A READ-SECTOR COMMAND 41 42 002034 012711 000407 MOV #407,(R1) ; DEN=DDEN, UNIT=0, FN=RD-SECTOR, GO 43 002040 030011 $3: BIT R0,(R1) ; APPLY MASK TO RX2CS 44 002042 001776 BEQ $3 ; LOOP UNTIL ERR, XFER-RQST OR DONE 45 002044 100434 BMI QUIT ; HALT IF ERR IS SET 46 ; CODE ASSUMES THAT XFER-RQST IS NOW SET (IGNORES DONE) 47 002046 110413 MOVB R4,(R3) ; WRITE SECTOR NUMBER TO RX2DB 48 002050 000304 SWAB R4 ; SWAP TRACK NUMBER TO BITS 0-7 49 002052 030011 $4: BIT R0,(R1) ; APPLY MASK TO RX2CS 50 002054 001776 BEQ $4 ; LOOP UNTIL ERR, XFER-RQST OR DONE 51 ; CODE ASSUMES THAT XFER-RQST (NOT ERR OR DONE) IS NOW SET 52 002056 110413 MOVB R4,(R3) ; WRITE TRACK NUMBER TO RX2DB 53 54 ; RXV21 IS NOW READING SECTOR DATA INTO ITS OWN BUFFER 55 56 002060 000304 SWAB R4 ; SWAP TRACK NUMBER TO BITS 15-8 57 002062 030011 $5: BIT R0,(R1) ; APPLY MASK TO RX2CS 58 002064 001776 BEQ $5 ; LOOP UNTIL ERR, XFER-RQST OR DONE 59 002066 100423 BMI QUIT ; HALT IF ERR IS SET 60 61 ; CODE ASSUMES THAT XFER-RQST IS NOW SET (IGNORES DONE) 62 63 ; THE SECTOR DATA IS NOW IN RXV21'S DATA BUFFER. 64 ; PREPARE TO TRANSFER SECTOR DATA FROM RXV21 TO RAM BY DMA 65 66 002070 012711 000403 MOV #403,(R1) ; DEN=DDEN, UNIT=ANY, FN=EMPTY-BUF, GO 67 002074 030011 $6: BIT R0,(R1) ; APPLY MASK TO RX2CS 68 002076 001776 BEQ $6 ; LOOP UNTIL ERR, XFER-RQST OR DONE 69 002100 100416 BMI QUIT ; HALT IF ERR IS SET 70 ; CODE ASSUMES THAT XFER-RQST IS NOW SET (IGNORES DONE) 71 002102 010513 MOV R5,(R3) ; LD WORD COUNT INTO RX2WC VIA RX2DB 72 002104 030011 $7: BIT R0,(R1) ; APPLY MASK TO RX2CS 73 002106 001776 BEQ $7 ; LOOP UNTIL ERR, XFER-RQST OR DONE 74 002110 100412 BMI QUIT ; HALT IF ERR IS SET 75 ; CODE ASSUMES THAT XFER-RQST IS NOW SET (IGNORES DONE) 76 002112 010213 MOV R2,(R3) ; LD BUS ADDRS INTO RX2BA VIA RX2DB 77 78 ; DATA (256 BYTES) IS NOW BEING COPIED TO RAM VIA DMA 79 80 002114 060502 ADD R5,R2 ; ADD 128 DEC TO BUS ADDRESS 81 002116 060502 ADD R5,R2 ; ADD 128 DEC TO BUS ADDRESS 82 002120 122424 CMPB (R4)+,(R4)+ ; INCREMENT SECTOR NUMBER BY 2 83 002122 120427 000007 CMPB R4,#7 ; SECTORS 1, 3, 5 & 7 WILL BE READ 84 002126 003737 BLE $2 ; LOOP BACK AND DO NEXT SECTOR 85 002130 012700 000000 MOV #0,R0 ; BOOT DEVICE IS UNIT 0 86 002134 005007 CLR PC ; GO TO ADDR ZERO 87 88 ; ERRORS ALWAYS BRANCH TO HERE. ON FIRST ERROR (DURING 89 ; DDEN ATTEMPT) WE CHANGE TO SDEN MODE AND TRY AGAIN. ON 90 ; SECOND ERROR, WE HALT. 91 92 002136 000005 QUIT: RESET ; RESET ALL I/O DEVICES 93 002140 012700 002000 MOV #START,R0 ; LOAD R0 WITH START ADDRESS 94 002144 012701 000400 MOV #400,R1 ; SETUP MASK BYTE 95 002150 006260 000014 ASR 14(R0) ; CHANGE WRDCNT TO 64 DECIMAL 96 002154 040160 000036 BIC R1,36(R0) ; CHANGE READ-SECTOR CMD TO SDEN 97 002160 040160 000072 BIC R1,72(R0) ; CHANGE EMPTY-BUFFER CMD TO SDEN 98 002164 012760 000017 000124 MOV #17,124(R0) ; CHANGE LAST SECTOR TO D'15 99 002172 005060 000136 CLR 136(R0) ; PUT HALT AT QUIT LOCATION 100 002176 000700 BR START ; GO BACK AND TRY SDEN MODE 101 102 000001 .END
You can also download the source code and assembly listing files for my Dual-Density DY Bootstrap here if you need them:
Microcomputer Interfaces Handbook Double-Density RX02 Bootstrap
The PDP-11 Microcomputer Interfaces Handbook 1983-84 (DEC Order Number EB-23144-18) includes at Pages 484-485 separate ODT Bootstraps for double-density and single-density RX02 disks.
A copy of Pages 484-485 is available here.
Whoever typed up the Handbook DDEN RX02 Bootstrap must have been having a very bad day. It contains the following 6 errors and deficiencies:
- The word at 1032 should be 100437 (not 100445)
- The word at 1046 should be 110413 (not 100437)
- The word at 1062 should be 030011 (not 100431)
- The word at 1100 should be 100414 (not 010414)
- The word at 1124 should be 000007 (not 000003)
- The word at 1136 (120427) should be deleted as it is not used
The first 3 errors in the list above result in a BMI (“branch if minus”) instruction to an address that is outside the range of the bootstrap (they would each branch to address 001146). The second and third errors also happen to be entirely wrong instructions: both are erroneous BMI instructions (to address 1146) when in fact 1046 should be a “MOVB R4,(R3)” instruction and 1062 should be a “BIT R0,(R1)” instruction.
The fourth error is a simple typo (a “0” was left out after the first digit).
The fifth error is perhaps more a deficiency than an error. The bootstrap only transfers a total of 512 bytes (being Sectors 1 and 3, each of 256 bytes) to RAM. Presumably this was adequate for early versions of RT-11. However, it is not sufficient for RT-11 V5.3, which requires 1024 bytes to be transferred. If you only transfer 512 bytes, RT-11 V5.3 will not boot up on the first attempt after power cycling the PDP-11. Strangely, if you then re-enter and re-run the bootstrap a second or subsequent time, RT-11 V5.3 will run. For this reason, I don’t recommend using this bootstrap for RT-11 V5.3 unless you relocate it to address O’002000, and modify the word at 1124 so that all 1024 bytes get loaded. The code below is relocatable, so moving it to O’002000 doesn’t change any of the values to be entered via ODT, other than the start address.
The sixth error is simply a redundant word. The word at 1136 (120427) is never executed and is not referenced by any instruction.
Here is the Handbook DDEN RX02 Bootstrap with all 6 errors/deficiencies corrected. Note that it is now relocated to O’002000.
1 .TITLE DBL-DENSITY BOOTSTRAP FOR RXV21 2 3 ; THIS IS THE RXV21 DOUBLE-DENSITY BOOTSTRAP THAT APPEARS 4 ; AT PAGE 484 OF THE PDP-11 MICROCOMPUTER INTERFACES 5 ; HANDBOOK 1983-84 (DEC ORDER NUMBER EB-23144-18). 6 ; 7 ; NOTE: THE DEC BOOTSTRAP HAS SIX ERRORS AND DEFICIENCIES 8 ; IN IT (AT ADDR 1032, 1046, 1062, 1100, 1124 and 1136). 9 ; THOSE ERRORS ARE CORRECTED IN THE SOURCE CODE BELOW. 10 ; 11 ; NOTE THAT CORRECTING THE DEFICIENCY AT 1124 (SO THAT 12 ; 1024 BYTES ARE LOADED, RATHER THAN 512) ALSO REQUIRES 13 ; THIS BOOTLOADER TO BE RELOCATED TO ADDRESS 002000. 14 ; 15 ; MALCOLM MACLEOD - 11 JUNE 2017 16 17 000000 .ASECT 18 002000 .=002000 19 20 177170 RX2CS = 177170 ; RXV21 CONTROL/STATUS REGISTER 21 177172 RX2DB = 177172 ; RXV21 DATA BUFFER REGISTER 22 000200 WRDCNT = ^D128 ; 128 FOR DBL-DEN, 64 FOR SGL-DEN 23 100240 MASK = 100240 ; BIT 15=ERR, 7=XFER-RQST, 5=DONE 24 002132 QUIT = GO-2 ; DEC HACK: BRANCHES TO A HALT 25 26 002000 012700 100240 MOV #MASK,R0 ; PUT BIT MASK INTO R0 27 002004 012701 177170 MOV #RX2CS,R1 ; PUT ADDR OF RX2CS INTO R1 28 002010 005002 CLR R2 ; CLEAR BUS ADDR (DMA DEST'N ADDR) 29 002012 012705 000200 MOV #WRDCNT,R5 ; PUT WORD COUNT (128) INTO R5 30 002016 012704 000401 MOV #401,R4 ; TRACK 1, SECTOR 1 31 002022 012703 177172 $1: MOV #RX2DB,R3 ; PUT ADDR OF RX2DB IN R3 32 33 ; CHECK THAT THE RXV21 IS READY 34 35 002026 030011 $2: BIT R0,(R1) ; APPLY MASK TO RX2CS 36 002030 001776 BEQ $2 ; LOOP UNTIL ERR, XFER-RQST OR DONE 37 002032 100437 BMI QUIT ; HALT IF ERR IS SET 38 39 ; INITIATE A READ-SECTOR COMMAND 40 41 002034 012711 000407 MOV #407,(R1) ; DEN=DDEN, UNIT=0, FN=RD-SECTOR, GO 42 002040 030011 $3: BIT R0,(R1) ; APPLY MASK TO RX2CS 43 002042 001776 BEQ $3 ; LOOP UNTIL ERR, XFER-RQST OR DONE 44 002044 100432 BMI QUIT ; HALT IF ERR IS SET 45 ; CODE ASSUMES THAT XFER-RQST IS NOW SET (IGNORES DONE) 46 002046 110413 MOVB R4,(R3) ; WRITE SECTOR NUMBER TO RX2DB 47 002050 000304 SWAB R4 ; SWAP TRACK NUMBER TO BITS 0-7 48 002052 030011 $4: BIT R0,(R1) ; APPLY MASK TO RX2CS 49 002054 001776 BEQ $4 ; LOOP UNTIL ERR, XFER-RQST OR DONE 50 ; CODE ASSUMES THAT XFER-RQST (NOT ERR OR DONE) IS NOW SET 51 002056 110413 MOVB R4,(R3) ; WRITE TRACK NUMBER TO RX2DB 52 53 ; RXV21 IS NOW READING SECTOR DATA INTO ITS OWN BUFFER 54 55 002060 000304 SWAB R4 ; SWAP TRACK NUMBER TO BITS 15-8 56 002062 030011 $5: BIT R0,(R1) ; APPLY MASK TO RX2CS 57 002064 001776 BEQ $5 ; LOOP UNTIL ERR, XFER-RQST OR DONE 58 002066 100421 BMI QUIT ; HALT IF ERR IS SET 59 60 ; CODE ASSUMES THAT XFER-RQST IS NOW SET (IGNORES DONE) 61 62 ; THE SECTOR DATA IS NOW IN RXV21'S DATA BUFFER. 63 ; PREPARE TO TRANSFER SECTOR DATA FROM RXV21 TO RAM BY DMA 64 65 002070 012711 000403 MOV #403,(R1) ; DEN=DDEN, UNIT=ANY, FN=EMPTY-BUF, GO 66 002074 030011 $6: BIT R0,(R1) ; APPLY MASK TO RX2CS 67 002076 001776 BEQ $6 ; LOOP UNTIL ERR, XFER-RQST OR DONE 68 002100 100414 BMI QUIT ; HALT IF ERR IS SET 69 ; CODE ASSUMES THAT XFER-RQST IS NOW SET (IGNORES DONE) 70 002102 010513 MOV R5,(R3) ; LD WORD COUNT INTO RX2WC VIA RX2DB 71 002104 030011 $7: BIT R0,(R1) ; APPLY MASK TO RX2CS 72 002106 001776 BEQ $7 ; LOOP UNTIL ERR, XFER-RQST OR DONE 73 002110 100410 BMI QUIT ; HALT IF ERR IS SET 74 ; CODE ASSUMES THAT XFER-RQST IS NOW SET (IGNORES DONE) 75 002112 010213 MOV R2,(R3) ; LD BUS ADDRS INTO RX2BA VIA RX2DB 76 77 ; DATA (256 BYTES) IS NOW BEING COPIED TO RAM VIA DMA 78 79 002114 060502 ADD R5,R2 ; ADD 128 DEC TO BUS ADDRESS 80 002116 060502 ADD R5,R2 ; ADD 128 DEC TO BUS ADDRESS 81 002120 122424 CMPB (R4)+,(R4)+ ; INCREMENT SECTOR NUMBER BY 2 82 002122 120427 000007 CMPB R4,#7 ; SECTORS 1, 3, 5 & 7 WILL BE READ 83 002126 003735 BLE $1 ; LOOP BACK AND DO SECTOR NUMBER 3 84 002130 012700 000000 MOV #0,R0 ; PUT UNIT NUMBER OF BOOT DRIVE IN R0 85 002134 005007 GO: CLR PC ; GO TO ADDR ZERO 86 87 000001 .END
You can also download the source code and assembly listing files for the Handbook DDEN RX02 Bootstrap here if you need them:
Microcomputer Interfaces Handbook Single-Density RX02 Bootstrap
As mentioned earlier, the PDP-11 Microcomputer Interfaces Handbook 1983-84 (DEC Order Number EB-23144-18) also includes at Pages 484-485 an ODT Bootstrap for single-density RX02 disks.
The good news is that this bootstrap has less issues than its double-density counterpart. However, there are still a couple of changes that should be made, if you want to use this bootstrap to load RT-11 V5.3:
- The word at 1124 should be 000017 (not 000007)
- The word at 1136 (000003) should be deleted as it is not used
The first change suggested above relates to the total number of bytes transferred by the bootstrap. The bootstrap only transfers a total of 512 bytes (being Sectors 1, 3, 5 & 7, each of 128 bytes) to RAM. As mentioned earlier, this is not sufficient for RT-11 V5.3, which requires 1024 bytes to be transferred (see comments earlier about the behaviour of RT-11 V5.3 if only 512 bytes are transferred). For this reason, I recommend relocating this bootstrap to address O’002000, and modifying the word at 1124 so that 1024 bytes (being the 8 odd-numbered sectors from D’01 to D’15) get loaded. The code below is relocatable, so moving it to O’002000 doesn’t change any of the values to be entered via ODT, other than the start address.
The second change is simply removing a redundant word. The word at 1136 (000003) is never executed and is not referenced by any instruction.
Here is the Handbook SDEN RX02 Bootstrap with both changes made. Note that it is now relocated to O’002000.
1 .TITLE SGL-DENSITY BOOTSTRAP FOR RXV21 2 3 ; THIS IS THE RXV21 SINGLE-DENSITY BOOTSTRAP THAT APPEARS 4 ; AT PAGE 484 OF THE PDP-11 MICROCOMPUTER INTERFACES 5 ; HANDBOOK 1983-84 (DEC ORDER NUMBER EB-23144-18). 6 ; 7 ; NOTE: THE DEC BOOTSTRAP HAS TWO DEFICIENCIES IN IT 8 ; (AT ADDR 1124 AND 1136). THOSE DEFICIENCIES ARE 9 ; CORRECTED IN THE SOURCE CODE BELOW. 10 ; 11 ; NOTE THAT CORRECTING THE DEFICIENCY AT 1124 (SO THAT 12 ; 1024 BYTES ARE LOADED, RATHER THAN 512) ALSO REQUIRES 13 ; THIS BOOTSTRAP TO BE RELOCATED TO ADDRESS 002000. 14 ; 15 ; MALCOLM MACLEOD - 11 JUNE 2017 16 17 000000 .ASECT 18 002000 .=002000 19 20 177170 RX2CS = 177170 ; RXV21 CONTROL/STATUS REGISTER 21 177172 RX2DB = 177172 ; RXV21 DATA BUFFER REGISTER 22 000100 WRDCNT = ^D64 ; 128 FOR DBL-DEN, 64 FOR SGL-DEN 23 100240 MASK = 100240 ; BIT 15=ERR, 7=XFER-RQST, 5=DONE 24 002132 QUIT = GO-2 ; DEC HACK: BRANCHES TO A HALT 25 26 002000 012700 100240 MOV #MASK,R0 ; PUT BIT MASK INTO R0 27 002004 012701 177170 MOV #RX2CS,R1 ; PUT ADDR OF RX2CS INTO R1 28 002010 005002 CLR R2 ; CLEAR BUS ADDR (DMA DEST'N ADDR) 29 002012 012705 000100 MOV #WRDCNT,R5 ; PUT WORD COUNT (64) INTO R5 30 002016 012704 000401 MOV #401,R4 ; TRACK 1, SECTOR 1 31 002022 012703 177172 $1: MOV #RX2DB,R3 ; PUT ADDR OF RX2DB IN R3 32 33 ; CHECK THAT THE RXV21 IS READY 34 35 002026 030011 $2: BIT R0,(R1) ; APPLY MASK TO RX2CS 36 002030 001776 BEQ $2 ; LOOP UNTIL ERR, XFER-RQST OR DONE 37 002032 100437 BMI QUIT ; HALT IF ERR IS SET 38 39 ; INITIATE A READ-SECTOR COMMAND 40 41 002034 012711 000007 MOV #7,(R1) ; DEN=SDEN, UNIT=0, FN=RD-SECTOR, GO 42 002040 030011 $3: BIT R0,(R1) ; APPLY MASK TO RX2CS 43 002042 001776 BEQ $3 ; LOOP UNTIL ERR, XFER-RQST OR DONE 44 002044 100432 BMI QUIT ; HALT IF ERR IS SET 45 ; CODE ASSUMES THAT XFER-RQST IS NOW SET (IGNORES DONE) 46 002046 110413 MOVB R4,(R3) ; WRITE SECTOR NUMBER TO RX2DB 47 002050 000304 SWAB R4 ; SWAP TRACK NUMBER TO BITS 0-7 48 002052 030011 $4: BIT R0,(R1) ; APPLY MASK TO RX2CS 49 002054 001776 BEQ $4 ; LOOP UNTIL ERR, XFER-RQST OR DONE 50 ; CODE ASSUMES THAT XFER-RQST (NOT ERR OR DONE) IS NOW SET 51 002056 110413 MOVB R4,(R3) ; WRITE TRACK NUMBER TO RX2DB 52 53 ; RXV21 IS NOW READING SECTOR DATA INTO ITS OWN BUFFER 54 55 002060 000304 SWAB R4 ; SWAP TRACK NUMBER TO BITS 15-8 56 002062 030011 $5: BIT R0,(R1) ; APPLY MASK TO RX2CS 57 002064 001776 BEQ $5 ; LOOP UNTIL ERR, XFER-RQST OR DONE 58 002066 100421 BMI QUIT ; HALT IF ERR IS SET 59 60 ; CODE ASSUMES THAT XFER-RQST IS NOW SET (IGNORES DONE) 61 62 ; THE SECTOR DATA IS NOW IN RXV21'S DATA BUFFER. 63 ; PREPARE TO TRANSFER SECTOR DATA FROM RXV21 TO RAM BY DMA 64 65 002070 012711 000003 MOV #3,(R1) ; DEN=SDEN, UNIT=ANY, FN=EMPTY-BUF, GO 66 002074 030011 $6: BIT R0,(R1) ; APPLY MASK TO RX2CS 67 002076 001776 BEQ $6 ; LOOP UNTIL ERR, XFER-RQST OR DONE 68 002100 100414 BMI QUIT ; HALT IF ERR IS SET 69 ; CODE ASSUMES THAT XFER-RQST IS NOW SET (IGNORES DONE) 70 002102 010513 MOV R5,(R3) ; LD WORD COUNT INTO RX2WC VIA RX2DB 71 002104 030011 $7: BIT R0,(R1) ; APPLY MASK TO RX2CS 72 002106 001776 BEQ $7 ; LOOP UNTIL ERR, XFER-RQST OR DONE 73 002110 100410 BMI QUIT ; HALT IF ERR IS SET 74 ; CODE ASSUMES THAT XFER-RQST IS NOW SET (IGNORES DONE) 75 002112 010213 MOV R2,(R3) ; LD BUS ADDRS INTO RX2BA VIA RX2DB 76 77 ; DATA (128 BYTES) IS NOW BEING COPIED TO RAM VIA DMA 78 79 002114 060502 ADD R5,R2 ; ADD 64 DEC TO BUS ADDRESS 80 002116 060502 ADD R5,R2 ; ADD 64 DEC TO BUS ADDRESS 81 002120 122424 CMPB (R4)+,(R4)+ ; INCREMENT SECTOR NUMBER BY 2 82 002122 120427 000017 CMPB R4,#17 ; ODD SECTORS D'01-D'15 WILL BE READ 83 002126 003735 BLE $1 ; LOOP BACK AND DO NEXT SECTOR 84 002130 012700 000000 MOV #0,R0 ; PUT UNIT NUMBER OF BOOT DRIVE IN R0 85 002134 005007 GO: CLR PC ; GO TO ADDR ZERO 86 87 000001 .END
You can also download the source code and assembly listing files for the Handbook SDEN RX02 Bootstrap here if you need them:
General comments
I’ve examined the sector data on Track 1 of a single-density RX02 RT-11 V5.3 disk. I did this using ImageDisk. On the single-density disk, it is clear that there is non-zero data in Sectors 1, 3, 5, 7, 9, 15 and 17 (in Sector 13 the data was all zeroes).
The boot menu that is on the M8189 (KDF11-BA) is capable of booting both single-density and double-density RX02 disks. I assume it tries one density first, and if that fails, it then tries the other density. However, I’ve not examined the code on the M8189 to confirm this.
There are other RX02 bootstraps that I have not examined. For example, there is a DY bootstrap on the M9312.
My test environment
All the above bootstraps were tested with the following hardware/software:
- PDP-11/23 Processor (M8186)
- 256KB of RAM (A Fourth Generation Systems LS256-1 board)
- Camintonn CM-DLV11-J 4-Channel Serial Interface. This is very similar to a DLV11-J (M8043)
- Dilog DQ419 RX02-compatible floppy-drive controller
- Mitsubishi M2896-63-02U 8-inch floppy drive
- RT-11 V5.3 single-density and double-density RX02 boot disks
Useful Resources
I found these documents useful when producing the source code files shown on this page:
RX02 Floppy Disk System User’s Guide (Dec Order Number EK-RX02-UG-001): Comprehensive information about programming the RX02 controllers.
DEC’s RX01/RX02 Pocket Service Guide (DEC Order Number EK-RX012-PS-002). This document includes bootstrap loaders for the RX8/RX28, RX11/RXV11 and RX211/RXV211. It also includes a summary of the registers used on the RX01/RX02 controllers.
Alan Rosenthal’s PDP-11 instruction reference: Useful detailed description of the PDP-11 instruction set.
PDP-11 Macro-11 Language Reference Manual (DEC Order Number AA-5075A-TC)
PDP-11 Keypad Editor User’s Guide (DEC Order Number AA-H853A-TC)
Other useful websites:
Henk Gooijen’s RX01/RX02 webpage: An excellent introduction to the RX01/RX02 drives and the DEC controllers for them. Lots of really useful information here.
Wikipedia’s PDP-11 architecture webpage: Helpful introduction to the PDP-11 instruction set and architecture.
Diane’s PDP-11 Page: Lots of useful information about setting up a minimal PDP-11 system. Includes information on bootstraps, traps and ODT.