
; UCSD PASCAL I.5 INTERPRETER (FILE "rkboot.mac")


         .NLIST  TTM
         .TITLE  RK05 BOOTSTRAP LOADER
         ;
         ; COPYRIGHT (C) 1978 REGENTS OF THE UNIVERSTIY OF CALIFORNIA.
         ; PERMISSION TO COPY OR DISTRIBUTE THIS SOFTWARE OR DOCUMEN-
         ; TATION IN HARD COPY OR SOFT COPY GRANTED ONLY BY WRITTEN LICENSE
         ; OBTAINED FROM THE INSTITUTE OF INFORMATION SYSTEMS.  ALL RIGHTS
         ; RESERVED.  NO PART OF THIS PUBLICATION MAY BE REPRODUCED, STORED
         ; IN A RETRIEVAL SYSTEM ( E.G., IN MEMORY, DISK, OR CORE) OR BE
         ; TRANSMITTED BY ANY MEANS, ELECTRONIC, MECHANICAL, PHOTOCOPY,
         ; RECORDING, OR OTHERWISE, WITHOUT PRIOR WRITTEN PERMISSION FROM THE
         ; PUBLISHER.
         ;
         ;
 R0=%0
 R1=%1
 BK=%2
 R2=%2
 BASE=%3
 R3=%3
 IPC=%4
 R4=%4
 MP=%5
 R5=%5
 SP=%6
 PC=%7
 RCSR = 177560
 XCSR = 177564
 XCSR = 177564
 XBUF = 177566
 DTID = 6
 DELENG = 26.
 CR = 15
 LF = 12
 BUZZ = 7
 NSEGS = 16.
 DATASZ = -10    ; OFFSET TO LOCAL DATA SIZE IN JTAB
 SYUNIT = 404
 SEG    = 422
 MEMTOP = 424
 CRTCTRL= 476
 SEGTBL = 540
         .ASECT
 .=0
         NOP
         BR      BOOT1
         .WORD NXM
         .WORD 341
         .WORD 173000            ; BAD INSTRUCTION REBOOTS
         .WORD 340
         . = 34
         .WORD   READ            ;CALL DRIVER VIA TRAP
         .WORD 340
 BOOT1:  MOV     @#RKDA,R0       ; GRAB DISK ADDRESS USED FOR BOOT READ
         ROL     R0
         ROL     R0
         ROL     R0
         ROL     R0
         BIC     #177770,R0      ; ZAP ALL BUT UNIT BITS
         ADD     #9.,R0
         MOV     R0,RKUNIT
         JMP     BOOT

 ; RK05 DISK HANDLER

 RKDA    = 177412                ;RK DISK ADDRESS

 RKUNIT: .WORD

 READ:   MOV     #14,R3          ;PHYSICAL BLOCK TO RK DISK ADD.
         BR      2$              ;ENTER BLOCK # COMPUTATION
 1$:     ADD     #20,R3          ;CONVERT DISK ADDRESS
 2$:     SUB     #14,R0
         BPL     1$
         ADD     R3,R0           ;R0 HAS DISK ADDRESS
 5$:     MOV     #RKDA,R3        ;POINT TO HARDWARE DISK ADDR REGISTER
         BIC     #17777,@R3      ;LEAVE THE UNIT NUMBER
         BIS     R0,(R3)         ;PUT DISK ADDRESS INTO CONTROLLER
         MOV     R2,-(R3)        ;BUFFER ADD.
         MOV     R1,-(R3)        ;WORD COUNT
         NEG     (R3)            ;(NEGATIVE)
         MOV     #5,-(R3)        ;START DISK READ
 3$:     TSTB    (R3)            ;WAIT UNTIL COMPLETE
         BPL     3$
         TST     (R3)            ;ANY ERRORS?
         BMI     BIOERR          ;HARD HALT ON ERROR
         ADD     R1,R2           ; POINT R2 ABOVE LAST IO FOR THE
         ADD     R1,R2           ; BENEFIT OF LOADER (R1 IS WORDS!)
         MOV     (SP)+,@SP
         RTS     PC

 BIOERR: JSR     R0,BOMB
         .ASCIZ  <CR><LF><BUZZ>'?IO ERROR WHILE BOOTING?'<CR><LF>
         .EVEN

 NOCORE: JSR     R0,BOMB
         .ASCIZ  <CR><LF><BUZZ>'?NOT ENOUGH CORE TO BOOT?'<CR><LF>
         .LIST   BEX
         .EVEN

         .=400
 BOOT:   MOV     #20000,SP       ;SET STACK POINTER
         MOV     #1,R0           ; BLOCK #
         MOV     #1280.,R1       ; WORD COUNT
         MOV     #1000,R2        ; BUF ADDR
         TRAP                    ; READ REST OF BOOT AND DIR!
         ; CORE DETERMINATION
         .ENABL  LSB
         CLR     R2              ;LOOK FOR TOP OF CORE
 2$:     ADD     #4000,R2        ;MOVE TO NXT 1K BANK
         CMP     R2, (PC)+       ;REACHED 28K YET ?
 $MEMRY: .WORD 160000    ;CHANGE HERE TO LOWER TOP O' MONITR
         BEQ     NXM             ;YES, DO A 28K SYSTEM
         TST     @R2             ;NO, SEE IF THIS LOC EXISTS
         BR      2$              ;KEEP GOING IF WE DIDN'T TRAP
         .DSABL LSB
 NXM:    MOV     R2,MEMSIZ       ; STASH MEMORY SIZE FOR LATER
         CMP     R2,#100000      ; DO WE HAVE AT LEAST 16K?
         BLO     NOCORE
         MOV     #NOBOMB,@#4     ; AVOID BLOWUP FOR BAD MEM NOW
         BIS     #100,@#177546
         JSR     R0,DIRSRCH      ; FIND THE CODE FILE FOR THE SYSTEM
         .ASCIZ  <15>'SYSTEM.PASCAL?'<CR><LF>
         MOV     (R1)+,FSTSYS    ; SAVE FIRST BLOCK FOR SYSTEM CODE
         JSR     R0,DIRSRCH      ; NOW LOOK FOR THE INTERPRETER .SAV FILE
         .ASCIZ  <15>'SYSTEM.PDP-11?'<CR><LF>
         MOV     (R1)+,R0        ; BLOCK # OF INTERP
         MOV     @R1,R1          ; LAST BLOCK # IN INTERP
         SUB     R0,R1           ; NOW R1 IS # BLOCKS TO READ
         SWAB    R1              ; MAKE # WORDS FOR READ
         MOV     R1,INTSIZ       ; SAVE INTERPRETER SIZE FOR LATER
         MOV     #20000,R2       ; MEM ADDR TO READ INTERP INTO
         TRAP                    ; PERFORM DISK READ
         MOV     FSTSYS,R0       ; NOW READ SEGTBL FROM PASCAL CODE INTO INTERP
         MOV     #NSEGS*2,R1     ; # WORDS TO READ
         MOV     #DIREC,R2       ; AND THE MEMADDR
         TRAP                    ; PERFORM THE READ
         MOV     #DIREC,R0       ; SOURCE OF SEGDESC...THEN
         MOV     #20000+SEGTBL,R2 ; RELOCATE DISK ADDRS
         MOV     #NSEGS,R1       ; LOOP COUNTER
 1$:     MOV     RKUNIT,(R2)+    ; PUT UNIT # INTO SEGTBL
         MOV     (R0)+,@R2       ; COPY IN REL DISK BLOCK
         ADD     FSTSYS,(R2)+    ; ADD START ADDR TO REL ADDR ALRDY THERE
         MOV     (R0)+,(R2)+
         DEC     R1
         BNE     1$
         MOV     #20004+SEGTBL,R0 ; POINT R0 AT LENG OF SEG 0
         MOV     MEMSIZ,R2       ; SET UP MEM ADDR TO READ ROUTINE
         SUB     @R0,R2          ; GET HIGH ADDR...SUBTRACT CODE LENGTH
         MOV     R2,SP           ; THIS IS STACK FOR SYSTEM ENTRY..STASH IT
         MOV     @R0,R1          ; NOW # WORDS TO READ
         ASR     R1              ; MAKE # WORDS...ASSUME < 32K BYTES
         MOV     -(R0),R0        ; FINALLY, GET DISK ADDR
         TRAP                    ; AND READ IN SYSTEM CODE
         TST     -(R2)           ; R2 WAS ABOVE HIGH MEM...NOW @ HIGH MEM WORD
         MOV     R2,20000+SEG    ; SET UP SEG STATE IN INTERP
         MOV     R2,20000+MEMTOP ; SET TOP OF MEM PTR...USED IN CXP
         MOV     RKUNIT,20000+SYUNIT     ; SET UP SYSTEM UNIT #
         SUB     -(R2),R2        ; R2 NOW POINTS @ JTAB OF OUTER BLOCK
         MOV     SP,MP           ; SET UP MP & BASE TO CBP WILL
         SUB     DATASZ(R2),MP   ; TO THEMSELVES
         MOV     #400,@MP        ; FUNNY PARAM TO SYSTEM!!!!!!!!!
         SUB     #14,MP
         MOV     MP,BASE         ; ALL REGS SET UP NOW
         CLR     -(SP)           ; SET UP FOR RTI
         MOV     20040,R0        ; GRAB INTERP ENTRY POINT
         MOV     R0,-(SP)        ; AND PUSH ON STACK FOR RTI
         MOV     #FINALE,R0
         MOV     #100000,R1      ; WHERE WE COPY FINALE CODE
         MOV     #<FINEND-FINALE>/2,BK   ; WORD COUNT OF FINALE CODE
 FINLOOP:MOV     (R0)+,(R1)+
         DEC     BK
         BNE     FINLOOP
         MOV     #20000,R0
         CLR     R1
         MOV     INTSIZ,BK
         JMP     @#100000

 FINALE: MOV     (R0)+,(R1)+
         DEC     BK
         BNE     FINALE
         BIS     #100,@#RCSR
         MOV     PC,IPC
         ADD     #CBP.OP-.,IPC
         NOP
         RTI
 CBP.OP: .BYTE   128.+66.,1      ; CALL BASE PROCEDURE #1
 FINEND = .

 MEMSIZ: .WORD   ; SIZE OF MEMORY IN BYTES
 INTSIZ: .WORD   ; SIZE IN WORDS OF INTERPRETER
 FSTSYS: .WORD   ; FIRST DISK BLOCK OF PASCAL CODE FILE
 .PAGE
 DIRSRCH:MOV     #DIREC+DTID,R1  ; R1 POINTS AT DTID OF EACH DIR ENTRY
 DIRLOOP:MOV     R1,R4           ; R4 IS USED FOR TITLE COMPARE
         MOV     R0,R3           ; R3 IS TITLE TO LOOK FOR (IN CODE STREAM)
         MOVB    @R0,R2          ; NUMBER OF BYTES IN NAME(STRING VAR)
 1$:     CMPB    (R3)+,(R4)+     ; CHECK EACH BYTE FOR EQUAL
         BNE     2$              ; WOOPS, NEQ...CHECK NEXT ENTRY OR BOMB
         DEC     R2              ; OK SO FAR...DECREMENT LOOP COUNTER
         BPL     1$              ; LOOP FOR LENG+1 CHARS
         ; EUREKA! WE HAVE FOUND IT...RETURN WITH R1 POINTING AT ENTRY
         SUB     #DTID,R1        ; RETURN R1 AT START OF ENTRY
         ADD     #18.,R0         ; POINT R0 PAST STRING IN CODE
         RTS     R0              ; AND RETURN
 2$:     ADD     #DELENG,R1      ; SKIP R1 TO NEXT DIRECTORY ENTRY
         CMP     R1,#ENDDIR      ; CHECK IF WE HAVE GONE OFF END OF DIR
         BLO     DIRLOOP         ; IF NOT, CHECK NEXT ENTRY
         .NLIST  BEX
         JSR     R0,BOMB         ; OH WELL, NO SYSTEM FILE...TIME TO CROAK
         .ASCII  <CR><LF><BUZZ>'?YOU DON'<47>'T HAVE A '<200>
         .LIST   BEX
         .EVEN
         INC     R0              ; SKIP R0 PAST LENGTH BYTE

 BOMB:   MOVB    (R0)+,R1
         BMI     XBOMB           ; IF MINUS IN STRING, RETURN
         BEQ     HALTER
 1$:     TSTB    @#XCSR          ; WAIT UNTIL DL11 DONE BIT
         BPL     1$
         MOVB    R1,@#XBUF
         BR      BOMB
 XBOMB:  ROR     R0              ; RETURN TO USER...WORD BOUND R0
         ADC     R0
         ROL     R0
         RTS     R0

 NOBOMB: MOV     (SP)+,@SP
         RTS     PC
 HALTER: HALT
         BR      HALTER

 BOOTSZ  = . + 777 / 1000
 .       = BOOTSZ * 1000
 DIREC = 2000
 ENDDIR = DIREC + 4000
         .END

; +------------------------------------------------------------------+
; |                                                                  |
; |                     F     I     N     I     S                    |
; |                                                                  |
; +------------------------------------------------------------------+