PDP-11 RX02 Bootstraps

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.