Код:
.DRBOT DX,BOOT1,READ
. = DXBOOT+14
.WORD READS-DXBOOT
.WORD 340
.WORD WAIT-DXBOOT
.WORD 340
. = DXBOOT+34 ;34-52 USEABLE
BOOT1: MOVB UNITRD-DXBOOT(R0),RDCMD ;SET READ FUNCTION FOR CORRECT UNIT
REETRY: MOV @PC,SP ;INIT SP WITH NEXT INSTRUCTION
MOV #200,R2 ;AREA TO READ IN NEXT PART OF BOOT
CLR R0 ;SET TRACK NUMBER
BR B2$ ;OUT OF ROOM HERE, GO TO CONTINUATION
. = DXBOOT+56
UNITRD: .BYTE CSGO+CSRD ;READ FROM UNIT 0, SETS WEIRD BUT OK PS
.BYTE CSGO+CSRD+CSUNIT ;READ FROM UNIT 1
. = DXBOOT+70 ;PAPER TAPE VECTORS
WAIT: TST @R4 ;IS TR, ERR, DONE UP? INT ENB CAN'T BE
BEQ WAIT ;LOOP TILL SOMETHING
BMI REETRY ;START AGAIN IF ERROR
RTIRET: RTI ;RETURN
. = DXBOOT+120
READS: MOV (PC)+,R4 ;R4 -> RX STATUS REGISTER
BOTCSR: .WORD DX$CSR
MOV R4,R5 ;R5 WILL POINT TO RX DATA BUFFER
MOV (PC)+,(R5)+ ;INITIATE READ FUNCTION
RDCMD: .WORD 0 ;GETS FILLED WITH READ COMMAND
IOT ;CALL WAIT SUBROUTINE
MOV R3,@R5 ;LOAD SECTOR NUMBER INTO RXDB
IOT ;CALL WAIT SUBROUTINE
MOV R0,@R5 ;LOAD TRACK NUMBER INTO RXDB
IOT ;CALL WAIT SUBROUTINE
MOV #CSGO+CSEBUF,@R4 ;LOAD EMPTY BUFFER FUNCTION INTO RXCS
BROFFS = READF-. ;USE FOR COMPUTING BR OFFSET
RDX: IOT ;CALL WAIT SUBROUTINE
TSTB @R4 ;IS TRANSFER READY UP?
BPL RTIRET ;BRANCH IF NOT, SECTOR MUST BE LOADED
MOVB @R5,(R2)+ ;MOVE DATA BYTE TO MEMORY
DEC R1 ;CHECK BYTE COUNT
BGT RDX ;LOOP AS LONG AS WORD COUNT NOT UP
CLR R2 ;KLUDGE TO SLUFF BUFFER IF SHORT WD CNT
BR RDX ;LOOP
B2$: MOV SP,R1 ;SET TO BIG WORD COUNT
INC R0 ;SET TO ABSOLUTE TRACK 1
MOV @PC,R3 ;ABSOLUTE SECTOR 3 FOR NEXT PART
.ASSUME BPT EQ 3
BPT ;CALL READS SUBROUTINE
;SECTOR 2 OF RX BOOT
BOOT2: CMPB (R3)+,(R3)+ ;BUMP TO SECTOR 5
BPT ;CALL READS SUBROUTINE
CMPB (R3)+,(R3)+ ;BUMP TO SECTOR 7
BPT ;CALL READS SUBROUTINE
BIT #CSUNIT,RDCMD ;CHECK UNIT ID
BNE BOOT ;BRANCH IF BOOTING UNIT 1, R0=1
CLR R0 ;SET TO UNIT 0
BR BOOT ;NOW WE ARE READY TO DO THE REAL BOOT
READ: MOV (PC)+,@(PC)+ ;MODIFY READ ROUTINE
.WORD 167
.WORD RDX-DXBOOT
MOV (PC)+,@(PC)+
.WORD READF-RDX-4
.WORD RDX-DXBOOT+2
MOV #READ1-DXBOOT,@#B$READ ;CALLS TO B$READ WILL GO TO READ1
MOV #TRWAIT-DXBOOT,@#20 ;LETS HANDLE ERRORS DIFFERENTLY
CLR @#JSW ;CLEAR JSW SINCE THE DX BOOT IN SYSCOM AREA
TST HRDBOT ;DID WE REACH HERE VIA A HARDWARE BOOT?
BEQ READ1 ;YES, DON'T SET UP UNIT NUMBER
MOV @#B$DEVU,R3 ;NO, SET UP UNIT NUMBER
MOVB UNITRD-DXBOOT(R3),RDCMD ;STORE UNIT NUMBER
READ1: ASL R0 ;CONVERT BLOCK TO LOGICAL SECTOR
ASL R0 ;LSN=BLOCK*4
ASL R1 ;MAKE WORD COUNT BYTE COUNT
1$: MOV R0,-(SP) ;SAVE LSN FOR LATER
MOV R0,R3 ;WE NEED 2 COPIES OF LSN FOR MAPPER
MOV R0,R4
CLR R0 ;INIT FOR TRACK QUOTIENT
BR 3$ ;JUMP INTO DIVIDE LOOP
2$: SUB #23.,R3 ;PERFORM MAGIC TRACK DISPLACEMENT
3$: INC R0 ;BUMP QUOTIENT, STARTS AT TRACK 1
SUB #26.,R4 ;TRACK=INTEGER(LSN/26)
BPL 2$ ;LOOP - R4=REM(LSN/26)-26
CMP #-14.,R4 ;SET C IF SECTOR MAPS TO 1-13
ROL R3 ;PERFORM 2:1 INTERLEAVE
4$: SUB #26.,R3 ;ADJUST SECTOR INTO RANGE -1,-26
BPL 4$ ;(DIVIDE FOR REMAINDER ONLY)
ADD #27.,R3 ;NOW PUT SECTOR INTO RANGE 1-26
BPT ;CALL READS SUBROUTINE
MOV (SP)+,R0 ;GET THE LSN AGAIN
INC R0 ;SET UP FOR NEXT LSN
TST R1 ;WHATS LEFT IN THE WORD COUNT
BGT 1$ ;BRANCH TO TRANSFER ANOTHER SECTOR
RETURN
READF: TST @R4 ;ERROR, DONE, OR TR UP?
BEQ READF ;BR IF NOT
BMI BIOERR ;BR IF ERROR
TSTB @R4 ;TR OR DONE?
BPL READFX ;BR IF DONE
MOVB @R5,(R2)+ ;MOVE DATA BYTE TO MEMORY
DEC R1 ;CHECK BYTE COUNT
BGT READF ;LOOP IF MORE
MOV #1,R2 ;SLUFF BUFFER IF SHORT WD CNT
;DON'T DESTROY LOC 0
BR READF ;LOOP
TRWAIT: TST @R4 ;ERROR, DONE, OR TR UP?
BMI BIOERR ;HARD HALT ON ERROR
BEQ TRWAIT ;BR IF NOT
READFX: RTI
. = DXBOOT+606
BOOT: MOV #10000,SP ;SET STACK POINTER
MOV R0,-(SP) ;SAVE THE UNIT NUMBER
MOV #2,R0 ;READ IN SECOND PART OF BOOT
MOV #<4*400>,R1 ;EVERY BLOCK BUT THE ONE WE ARE IN
MOV #1000,R2 ;INTO LOCATION 1000
CLR (PC)+ ;CLEAR TO SHOW HARDWARE BOOT
HRDBOT: .WORD 1 ;INITIALLY SET TO 1
CALL READ ;GO READ IT IN
MOV #READ1-DXBOOT,@#B$READ ;STORE START LOCATION FOR READ ROUTINE
MOV #B$DNAM,@#B$DEVN ;STORE RAD50 DEVICE NAME
MOV (SP)+,@#B$DEVU ;STORE THE UNIT NUMBER
JMP @#B$BOOT ;START SECONDARY BOOT
.DREND DX