.MCALL .MODULE .MODULE BSTRAP, VERSION=209, COMMENT= ; Copyright (c) 1998 by Mentec, Inc., Nashua, NH. ; All rights reserved ; ; This software is furnished under a license for use only on a ; single computer system and may be copied only with the ; inclusion of the above copyright notice. This software, or ; any other copies thereof, may not be provided or otherwise ; made available to any other person except for use on such ; system and to one who agrees to these license terms. Title ; to and ownership of the software shall at all times remain ; in Mentec, Inc. ; ; The information in this document is subject to change without ; notice and should not be construed as a commitment by Digital ; Equipment Corporation, or Mentec, Inc. ; ; Digital and Mentec assume no responsibility for the use or ; reliability of its software on equipment which is not supplied ; by Digital or Mentec, and listed in the Software Product ; Description. .SBTTL Edit History ;+ ; Facility: RT-11 Secondary Bootstrap ; ; ; Edit Who Date Description of modification ; ---- --- ---- --------------------------- ; 001 WLD 27-MAR-90 Fixed bug in B$BOOT so that ; result of MFPT is treated as ; low byte in R0. ; 002 WLD 28-MAR-90 Restored T11NOP's in KT11RG. ; Code sequences utilizing a ; TRAP on non-existent memory ; require restoration of NOP's. ; Overlay size kept same by ; deleting CLC before TST. ; 003 WLD 19-APR-90 Added code to recognize the ; KDJ11-E and to branch over ; BSTRAP code for memory cache. ; ; 186 MBG 13-Apr-90 Adding support for DH series ; interfaces. ; ; 004 WLD 15-MAY-90 Added support for new monitor ; and startup file names. ; ; 190 MBG 08-Jun-90 Added definitions for DH-related ; stuff to keep in step with SYSTEM.MAC ; ; 193 JFW 6-Jul-1990 Use FIXDF names and definition ; ; 005 WLD 15-AUG-90 For KDJ11-x processors, always check ; bus type (QBUS or UNIBUS) regardless ; of x. ; ; 006 WLD 09-JAN-91 Fixed SB conditionalization of ; LSIMOD table so that if SB=1, there ; is a controlling bit pattern to ; drive the routine at FIXPSW. The ; improper conditionalization affected ; LSI-11 and T-11 processors. These ; processors require the MFPS/MTPS ; instructions instead of referencing ; bus address 777776 ; ; (198) 16-Jul-90 MBG Added relocation info for multi-terminal handler ; hooks support ; ; (199) 14-Sep-90 MBG Fix for non-booting DL-only monitor. ; ; (200) 19-Oct-90 DBB Add test to set CF3.HI in $CNFG3--supy I&D hdw support ; ; (201) 14-Sep-90 MBG Restructure relocation list relating to DH and ; multiterminal handler hooks. Fixed bug in CLNUP ; which caused a crash on boot if a configured ; terminal interface is not available. ; ; (202) 20-Nov-90 MBG Change to code which determines availability of ; terminal interfaces, move CSR into DZCSR when ; determined it exists rather than assuming it ; does and clearing the entry if it doesn't. ; ; (204) 19-Mar-91 MBG Change to MTTINT required change to boot ; relocation tables. ; ; 007 WLD 02-JUL-91 Correct conditialization for ; the commom RT-11 monitor source. ;- ;+ ; "Just because everything is different doesn't mean that anything has ; changed." - San Francisco Oracle ; ; "We will ship no code before its time" - Parent / Williams ;- .NLIST BEX,CND .SBTTL ************************************** .SBTTL * Secondary Bootstrap For The * .IF EQ .IF NE RTE$M .SBTTL * RT-11 Emulator (RTEM) Monitor * .IFF ;NE RTE$M .IF NE VENU$C .SBTTL * VENUS (VAX 8600) Console Monitor * .IFF ;NE VENU$C .IF NE SB .SBTTL * Single Background (SB) Monitor * .IFF ;NE SB .SBTTL * Foreground/Background (FB) Monitor * .ENDC ;NE SB .ENDC ;NE VENU$C .ENDC ;NE RTE$M .IFF ;EQ .IF EQ SUP$Y .IF NE SB .SBTTL * Extended Background (XB) Monitor * .IFF ;NE SB .SBTTL * Extended Memory (XM) Monitor * .ENDC ;NE SB .IFF ;EQ SUP$Y .IF NE SB .SBTTL * Supervisor and I-D Background (ZB) Monitor * .IFF ;NE SB .SBTTL * Supervisor and I-D (ZM) Monitor * .ENDC ;NE SB .ENDC ;EQ SUP$Y .ENDC ;EQ .LIBRARY "SRC:HARDWA.MLB" ;+ ; Programmed Request and Miscellaneous Utility Macros ;- .MCALL .ASSUME .AUDIT .BR ...CMV .CKXX ;SYSMAC .MCALL .EXIT .PRINT .RCTRLO .READW .SETTOP ;SYSMAC .MCALL ..V2.. ;SYSMAC .MCALL ASCR50 .ASTX DEFALT PUT ;EDTL ;+ ; Structure Definition Macros ;- .MCALL .CF1DF .CF2DF .CHNDF .CLIDF .CSWDF ;SYSTEM .MCALL .D2BDF .DBKDF .DIEDF .DIHDF .HANDF ;SYSTEM .MCALL .HBGDF .HSRDF .HUMDF .JSWDF .MCADF ;SYSTEM .MCALL .QHKDF .SGNDF .STWDF .SYCDF .TC2DF ;SYSTEM .MCALL .TCBDF .TCFDF .TIMDF .TSTDF .XITDF ;SYSTEM .MCALL .FIXDF .CF3DF .OWNDF .THKDF ;SYSTEM ;+ ; Invoke Structure Definition Macros ;- .CKXX ;Generate CK.Rx macros ..V2.. ;Generate Version 2 Format Programmed Requests (EMT's) .CF1DF ;CONFIG First System Configuration Word Format .CF2DF ;CONFG2 Second System Configuration Word Format .CF3DF ;CONFG3 Second System Configuration Word Format .CHNDF ;Channel Control Block Format .CLIDF ;CLITYP and CLIFLG Command Processor Definitions .CSWDF ;Channel Status Word (CSW) Bit Definitions .D2BDF ;DUP to BSTRAP Communication Area Format .DBKDF ;DBLOCK Format .DIEDF ;Directory Entry Format .DIHDF ;Directory Header Format .FIXDF P=Z ;Monitor fixed area ;(use Z, not $ as first char in name) .HANDF ;Handler Prefix Area (Block 0) Format .HBGDF ;Handler .DRBEG table layout .HSRDF ;Handler Service Routine Code Definitions .HUMDF ;Handler 64-unit and UMR Flag Word Format (H.64UM) .JSWDF ;$JSW Job Status Word Bit Definitions .IF NE MMG$T .MCADF ;Job's Mapping Context Area Definitions .ENDC ;NE MMG$T .OWNDF ;ownership table values and offsets .QHKDF ;$QHOOKS Area Definition .SGNDF ;SYSGEN Option Bit Definitions .STWDF ;STATWD DCL/@File Status Bit Definitions .SYCDF ;$SYCOM Definitions .TC2DF ;Terminal Configuration word 2 bit definitions FIX$ED=0 ;define floating symbols .TCBDF ;Terminal Control Block Definitions FIX$ED=1 .TCFDF ;Terminal Configuration Bits .TIMDF ;Time Word Pair Format .IF NE MTT$Y .TSTDF ;T.STAT Contains Dynamic Terminal Status .IF NE MTY$HK .THKDF ;Multiterminal handler hooks definitions .ENDC ;NE MTY$HK .ENDC ;NE MTT$Y .XITDF ;EXIT Argument Area Definition ;+ ; Delete Structure Definition Macros (Free Up Workfile Space) ;- .MDELET .CKXX .CF1DF .CF2DF .CHNDF .CLIDF .CSWDF .MDELET .D2BDF .DBKDF .DIEDF .DIHDF .HANDF .HBGDF .MDELET .HSRDF .HUMDF .JSWDF .MCADF .QHKDF .SGNDF .MDELET .STWDF .SYCDF .TC2DF .TCBDF .TCFDF .TIMDF .MDELET .TSTDF .XITDF .OWNDF .THKDF .SBTTL Monitor Sources Version Number Audit .AUDIT .EDTGBL .BSTRAP .RMON .USR .KMON .KMOVLY .AUDIT .MTTINT .MTTEMT .XMSUBS .TRMTBL .SBTTL Local Symbol and Macro Definitions ;+ ; Conditional assembly of boot for SB, FB, XB, XM, RTEM and VENUS systems ;- .IF NE RTE$M DEFALT $LRLPZ, 4 DEFALT $RMLPZ, 4 O$FORK ==: 402 ;Define O$FORK for emulator bootstrap .ENDC ;NE RTE$M .IF NE ;If VENUS console or RTEM ... PRO$S = 0 ; ... then exclude PRO300 processor support .IFF ;NE PRO$S = 1 ;Otherwise, include PRO300 processor support .ENDC ;NE ;+ ; Note that an additional amount of space above the secondary bootstrap is ; required by RTEM for some RTEM task routines primarily to provide the ; RSX QIO requests that the primary bootstrap read routine needs to read ; the system handler and the RTEM monitor into memory. ;- BOTSTK =: 10000 ;Start of bootstrap stack .IF NE RTE$M BOTTOP =: 12000 ;Top of secondary bootstrap & RTEM task ... ; ... routines needed during bootstrap .IFF ;NE RTE$M BOTTOP =: 10000 ;Top of secondary bootstrap .ENDC ;NE RTE$M PRODSP =: 167730 ;PRO crash display address PROMSZ =: 173050 ;PRO memory size VS6.SP =: 172032 ;Stack point register for VS60 UMR.RS =: 170200-2 ; - 2 UMR.RE =: 170376 ;End of Unibus mapping registers UMR.ME =: 10000 ;UB requires more than 256. Kbytes of memory MEM.PS =: 172100-2 ; - 2 MEM.PE =: 172136 ;End of Unibus memory parity status registers CA.CSR =: 177746 ;Cache status register CA.DST =: 1 ; Bit to disable non-fatal cache error traps P7.LSS =: 177760 ;Memory lower size in 11/70 systems KWP.CS =: 172540 ;KW11-P clock CSR ID$23 =: 3 ;Processor ID for 11/23 ID$FAL =: 4 ;Processor ID for FALCON ID$J11 =: 5 ;Processor ID for J-11 ICSR0 =: 173202 ;PRO Interrupt 0 CSR KBDBUF =: 173500 ;PRO Keyboard Data Buffer NOP =: 240 ;NOP instruction PRO$CS =: 173700 ;PRO300 series System CSR MR$J11 =: 177750 ;Maintenance Register for J-11 CMR.UB =: 001000 ; UNIBUS bit in J-11 Maintenance Register CMR.ID =: ^b<11110000> ; Mask for ID field in J-11 Maintenance Reg. J11B =: ^b<00100000> ; Value of CMR.ID field for KDJ11-B processor J11E =: ^B<01010000> ; Value of CMR.ID field for KDJ11-E processor KXJ =: ^b<00110000> ; Value of CMR.ID field for KXJ processor UN.MSK = 77 ;Unit number mask to allow units 0-63 UMR.ON = 000040 ;MMR3: Turns on UNIBUS mapping JMPABS =: 000137 ;JMP @(PC)+ for PRO hooking FIXED =: 556 ;Reserved for the fake fixed area ;MUST BE AT LEAST THE SIZE OF THE FIXED AREA! ;+ ; Define T11NOP macro (for T11 'trap too slow' bug) ;- .IF NE PDT$OP .MACRO T11NOP .ENDM T11NOP .IFF ;NE PDT$OP .MACRO T11NOP NOP .ENDM T11NOP .ENDC ;NE PDT$OP ;+ ; Macros to define replacements for Bxx instructions for use ; when a long displacement is required ;- .MACRO BRDEF BARG1,BARG2 .MACRO 'BARG1'. DEST,?LOCAL BARG2 LOCAL JMP DEST LOCAL: .ENDM ;'BARG1'. .MACRO 'BARG2'. DEST,?LOCAL BARG1 LOCAL JMP DEST LOCAL: .ENDM ;'BARG2'. .ENDM ;BRDEF BRDEF BEQ,BNE ;Define BEQ. and BNE. .MACRO BR. DEST JMP DEST .ENDM ;BR. .SBTTL Start of Boot code area ;+ ; SJ conditionals RDF$L and PANI$C are supposed to go away. They ; are currently used only in BSTRAP. Until then, reserve their places ; with RSVD01 and RSVD02 ;- RSVD01 = 0 ;SJ conditional PANI$C RSVD02 = 0 ;SJ conditional RDF$L .ASECT .PSECT RT11 ;KMON is in here .ASECT ;Fill in block 0 of monitor . = 0 ;First word is RAD50 "MON" .RAD50 "MON" . = 176 ;Dummy (never) Install code .WORD 0 ;No CSR NOP ;DK and SY the same SEC ;Don't Install RETURN ;Ever . = 300 .BITS CVT$NU,GET$FD,GT$NM,XFX$XX,LK4$DV,USR$CM .BITS EIS$I,FPU$11 .BITS AI$COD,BATC$H,CONT$N,IND$ON,LNK$IF,STAR$T,U$CL,L$ANG,M$INI,U$TIL .BITS LIGH$T,RSVD01,PWF$L,RSVD02,ROL$OV,RO$M,SILN$T .BITS MQH$P2,SPC$PS,XM$FET .BITS HSR$B,HSR$O,MAT$S,MTI$M,PDT$OP,U.K. .WBYTE DL11$M .WBYTE DL11$N .WBYTE DZ11$M .WBYTE DZ11$N .WEAK DZLE$N,DZSP$D,DZST$P .WORD DZLE$N!DZSP$D!DZST$P .WWORD TPS$MK .WWORD TTYIN .WWORD TTYOUT .WWORD V.TKB .WWORD V.TPS .WWORD VT.CSR .WWORD VT.VEC .WBYTE $LRLPZ .WBYTE $RMLPZ .WWORD PATC$H .WWORD STAC$K .WBYTE SUFX$S .WBYTE SUFX$T .WBYTE X$RCBS .BITS ABOR$$,ASSI$$,B$$,BACK$$,BOOT$$,CLOS$$,COMP$$,COPY$$,CREA$$,D$$,DATE$$,DEAS$$,DELE$$,DIBO$$,DIFF$$,DIRE$$ .BITS DISM$$,DUMP$$,E$$,EDIT$$,EXEC$$,FORM$$,FORT$$,FRUN$$,GET$$,HELP$$,INIT$$,INST$$,LIBR$$,LINK$$,LOAD$$,MACR$$ .BITS MAKE$$,MOUN$$,MUNG$$,PRIN$$,PROT$$,REEN$$,REMO$$,RENA$$,RESE$$,RESU$$,SAVE$$,SET$$,SHOW$$,SQUE$$,SRUN$$,STAR$$ .BITS SUSP$$,TECO$$,TIME$$,TYPE$$,UNLO$$,UNPR$$ .EVEN .WBYTE DH11$M .WBYTE DH11$N .WEAK DHLE$N,DHSP$D,DHST$P .WORD DHSP$D!<*4>! . = 400 ;"SET" area .WORD -1 ;New style indicator .WORD $RMON+ENDBST-1000 ;Fixed area address .WORD 0 ;No sets (of course) .WORD 1000 ;Magic value. ;Replace above w/.SET eventually .IF NE RTE$M ;+ ; BPRINT ; The starting location (in core) of the standalone error processing routine. ; Fatal errors which occur when there is no valid host operating system are ; reported by this routine. This routine doesn't return!! ;- BPRINT =: 550 ;+ ; REPORT - The starting location (in core) of the error processing routine. ; All fatal errors are reported by this routine. ;- BIOERR =: 570 REPORT =: 576 ;Asect in for error report routine .IFF ;NE RTE$M ;+ ; REPORT - The starting location (in core) of the error processing routine. ; All fatal errors are reported by this routine. ;- BIOERR =: 664 REPORT =: 672 ;Asect in for error report routine .ENDC ;NE RTE$M .SBTTL Memory usage during BSTRAP ;00000--00776: primary software bootstrap ;---------------------------------------- ;00000 B$HSBT: (NOP-hard / HALT-soft boot) ;00550 BPRINT: (RTEM) ;00570 BIOERR: (RTEM) ;00576 REPORT: (RTEM) ;00664 BIOERR: (nonRTEM) ;00672 REPORT: (nonRTEM) ; ;01000--04776: 2ndary sftwre b'strap OVERLAYS ;----------------------------------- ------------------------------- ;01000 B$BOOT: STRTOV SETSIO CLNUP LDTABL LDHNDL RSTUB1 ; initial code STRTEN SETEND CLNEND LDTEND LDHEND R1END ;????? B$END: ; non-overlayable code ; ;????? FIXST: ; Pseudo-fixed area buffer ;????? FIXST+FIXED: ( <4714 (RTEM); <4716 (RT) ) ; ;04714 B$RTEV: ;04716 B$DEVN: ;04720 B$DEVS: ;04722 B$DEVU: (^rBOT nonRTEM / ^rRTE RTEM) ;04724 B$FNAM: ;04730 B$READ: ;04732 SYHTOP: ;04734 DUPFLG: ;04736 $RMSIZ: ;04740 BSTRNG: ;04774 B$SUFF: ;04776 B$SYOP: ; ;05000--05004 loaded by DUP (non-RTEM) ;05000--05016 loaded by ?????? (RTEM) OVERLAYS ;------------------------------------- ------------------------------- ;05000 B$TIME: ;05004 B$DATE: ;05006 BUFFB: RELLST: KT11RG: RSTUB2: ; " B$HIME: (RTEM) ;05010 B$SVTK: (RTEM) ;05012 B$LK50: (RTEM) ;05014 B$LKGR: (RTEM) ;05016 B$FPU: (RTEM) ; ; VECEND: R2END: ;06406 BSTTBL: ; RELEND: KT11ND: BTBLEN: ;07006 HNAMES: ;07246 end of HNAMES area ;10000 Top of stack ; RTEM reserved area ;12000 ;????? (T)MSCP rings ; .SBTTL B$BOOT - Secondary Bootstrap: Memory Size Determination ;+ ; B$BOOT - Secondary bootstrap ; Entered from the primary bootstrap (in the system handler) or from DUP ; ; The boot will simulate a smaller PDP-11 if location 'BHALT' is a HALT. ; When the CPU stops, set the top 5 bits of the SR to the top of core to use ; and then CONTINUE the CPU. ; If the SR is >= 160000 or if BHALT is not patched to HALT, the ; bootstrap determines actual core size. ; ; We are rapidly running out of space. Most of the bootstrap is now in ; overlays. If you desperately need more room in the root, use the area ; from 7206 to about 7700. 7206 is the first word after HNAMES and ; assume that the stack uses 32. words down from 10000. This gives you ; about 500 octal bytes. ; ; B$BUBR is the restart point for UB restart ;- .ENABL LSB . = 1000 B$BOOT:: .IF EQ VENU$C MOV #,@#V.KW1L ;Ensure that the clock just idles CLR @#V.KW1L+2 ;Clear PS in clock vector .IFF ;EQ VENU$C MOV #,@#V.TOY ;Ensure that the TOY clock just idles CLR @#V.TOY+2 ;Clear PS in TOY clock vector .ENDC ;EQ VENU$C CLR R3 ;Point to location 0 MOV @R3,DUPFLG ;Save flag indicating DUP vs. hardware boot MOV #BOTSTK,SP ;Set up stack for KXJ booted from host B$BUBR: CLR (R3)+ ;Traps and jumps to 0 will halt CLR (R3)+ ; with a PS of 0 MOV SP,(PC)+ ;Save SP because of possible trap clutter STKPTR: .WORD 0 ;Saved SP .IF NE RTE$M CMP @#$RTEID,# ;Is RTEM identifier present? BEQ 10$ ;If EQ, yes, proceed MOV #,R0 ;Error, wrong host system, get message address CALL BPRINT ;Use standalone error printer (doesn't return) ............ 10$: .IFF ;NE RTE$M .IF EQ VENU$C MOV #<30$>,@R3 ;If MFPT traps, we're not a FALCON, ... MOV @R3,@#V.INST ; ... 11/23, 11/73, or PRO MFPT ;Get processor type in R0 CMPB R0,# ;Is this a FALCON processor? BNE 20$ ;Branch if not INC FALCON ;Set flag indicating we're a FALCON TST @#PS ;FALCON I or FALCON II ? T11NOP COM FALCON ;We're a FALCON II, FALCON=-2 ==> memory ... MOV #<077600>,R4 ; ... gap between 77600-77776 MOV R4,@R4 ;Is there a memory gap? (map mode 2?) T11NOP NEG FALCON ;No, FALCON=+2 ==> size memory BR 30$ ............ 20$: .IF NE PRO$S ;+ ; Are we running on a PRO300 series? ;- MOV #,R0 ;R0 -> PRO300 system CSR MOV @R0,R1 ;Get a copy so we can restore later T11NOP COM @R0 ;Try to complement all the bits T11NOP MOV @R0,R2 ;Get a copy of the result MOV R1,@R0 ;Restore original contents ; XOR may trap on non-PRO, but that is ok XOR R2,R1 ;Which bits were complemented (if any)? CMP R1,#<200> ;Was bit 7 the only bit that got complemented? BNE 30$ MOV #,PROFLG ;If not, set PROS$ bit in CNFIG2 for PRO300 MOV #,BIOERR ;Hook BIOERR to display an ... MOV #,BIOERR+2 ; ... RT crash code of 5 MOV #,REPORT ;Hook REPORT to display ... MOV #,REPORT+2 ; ... an RT crash code of xx .ENDC ;NE PRO$S 30$: .IF EQ MMG$T TST FALCON ;If FALCON < 0, R4 already has MEMTOP BMI NXM MOV #,@R3 ;Set trap for non-existent memory BHALT:: BR 40$ ;**PATCH** Change to HALT for fiddling ............ MOV @#SWR,R4 ;BHALT halt enabled. Get switch register CMP R4,# ;Do normal check? BLO NXM ;No, use the switch register value 40$: CLR R4 ;Look for top of core 50$: ADD #,R4 ;Move to next 1K bank CMP R4,(PC)+ ;Reached 30K? ..28KW:: .WORD KW$30 ;**PATCH** Change to 160000 to avoid checking over 28K BEQ NXM ;Yes, 30K system with MSV11-D memory MOV @R4,R0 ;No, see if this location exists COM @R4 ;Try to flip the bits MOV @R4,R1 ;Save the result COM R1 ;Flip the bits back MOV R0,@R4 ;Restore the location CMP R0,R1 ;Was the memory writable? BEQ 50$ ;Yes, so keep trying memory NXM: .ENDC ;EQ MMG$T .IF NE PRO$S TST PROFLG ;Are we a PRO? BNE 90$ ;Yes, then we're neither QBUS nor UNIBUS .ENDC ;NE PRO$S MOV #<60$>,@R3 ;On odd address trap, go to J11 routine TST @#ODDADR ;Did we trap? MOV #<80$>,@#V.INST ;No, set up illegal instruction trap MFPT ;Test for 23/24, if we trap, QBUS CMPB R0,# ;No trap, is this the 11/23 code? BNE 80$ ;If no, QBUS, branch ;+ ;!!!!!!!!!!!!!!!! CHECK THIS OUT !!!!!!!!!!!!!!!!!! ;- MOV #<80$>,@R3 ;On illegal address trap, we are a QBUS CLR @#SWR ;Does the Switch register exist? BR 90$ ;No, branch (we're a Unibus) ............ ;+ ;!!!!!!!!!!!!!!! END CHECK !!!!!!!!!!!!!!!!!!!!!!!!!!! ;- 60$: MOV #<90$>,@#V.INST ;Illegal instruction trap MFPT ;If trap, we're a Unibus CMPB R0,# ;Are we a J11? BNE 90$ ;If not, we're a Unibus, branch MOV @#MR$J11,R0 ;R0 = contents of J11 maintenance register BICB #^c,R0 ;Isolate the CMR.ID field CMPB #,R0 ;Is this a KXJ processor? BNE 70$ ;Branch if not INC KXJFLG ;Say we're a KXJ BIS #,TSBUS ;Set KXJ bits in $CNFG2 bit list BR 90$ ............ 70$: CMPB #,R0 ;IS THIS A KDJ11-E PROCESSOR? BNE 75$ ;BR IF NOT: CHECK BUS TYPE. INC ROIFLG ;SET FLAG FOR ROI BOARD (KDJ11-E: PDP 11/93-94). 75$: BIT #,R0 ;Does this KDJ11-x have a UNIBUS? BNE 90$ ;Branch if it does 80$: BIS #,TSBUS ;We're a QBUS 90$: MOV #,@R3 ;Non-existent memory traps will CLR @R1 MOV @R3,@#V.INST ;So will illegal instruction traps .IFF ;EQ VENU$C MOV #,R4 ;Get VENUS T-11 memory size .ENDC ;EQ VENU$C .IFT ;NE RTE$M MOV #,@R3 ;Non-existent memory traps are errors MOV #,@#V.INST ;Illegal instruction traps will CLR @R1 MOV #,R2 ;R2 -> Bootstrap linkage data for RTEM CK.R2=B$HIME CK.R2 B$HIME,+2 MOV (R2)+,R4 ;Pickup highest available memory address MOV R4,R5 ;Get high address CLC ;Convert address to 32 word blocks ROR R5 .REPT 5 ASR R5 .ENDR .IFF ;NE RTE$M .IF EQ MMG$T BIC #,R4 ;Isolate top 9 bits (64W boundary) MOV R4,R5 ;Get high address SWAB R5 ;Convert address ASL R5 ; to 32 word ADC R5 ASL R5 ; blocks .ENDC ;EQ MMG$T .ENDC ;NE RTE$M .IF EQ MMG$T MOV R5,MEMSIZ ;Save memory size in 32 word blocks .ENDC ;EQ MMG$T MOV STKPTR,SP ;Clean up stack of possible trap clutter .IF NE RTE$M ;+ ; The following call is to a RTEM-11 task routine which ; does some final setup code before turning control over ; to RT-11. The following items are done: ; ; o SST traps are enabled ; o SREX$ is enabled to catch aborts ; o READ_PASS_ALL mode may be enabled ; ; On return, R0 contains the following flags: ; ; 100000 = Console terminal should be set SCOPE ; 000001 = UCF.SAV was found on system device ; ; These flags are saved in CNFMOD to later be used to setup flags ; after the resident monitor is read in. ;- CK.R2 B$SVTK,+2 CALL @(R2)+ ;Call RTEM-11 task routine MOV R0,CNFMOD ;Save flags ;;;>>>??? CK.R2 B$LK50,+2 MOV (R2)+,$VSBRO ;Save bootstrap read routine block # offset .ENDC ;NE RTE$M .BR FXDEVN .DSABL LSB .SBTTL FXDEVN - Fix Bootstrap's File Name .ENABL LSB FXDEVN::MOV #,R5 ;Point to booted device handler name MOV @R5,R0 ;Get it 10$: MOV R0,R1 ;Copy remainder so far SUB #<^r A >,R0 ;Reduce modulo 50 BHIS 10$ ;Loop until underflow, R1 has name mod 50 SUB R1,@R5 ;Remove suffix if handler passed one MOV (R5)+,@R5 ;Save name sans suffix ADD B$SUFF,-(R5) ;Insert proper suffix into handler name .BR CFIG .DSABL LSB .SBTTL CFIG - Set Bits In CONFIG Depending On Following Tests ;+ ; Set bits in CONFIG depending on the following tests. ;- .ENABL LSB CFIG:: .IF NE VENU$C MOV #,BCNFG ;This is all the VENUS T-11 needs .IFF ;NE VENU$C MOV #,R1 ;Point to TSLIST for list of possible bits CK.R1=TSLIST MOV R1,R0 ;BCNFG eventually becomes CONFIG CK.R0=CK.R1 .IF NE RTE$M CK.R0 BCNFG,-2 CK.R1 TSLSI,+2 BIC (R1)+,-(R0) ;Can't be an LSI11 if RTEM CK.R1 TSLKC,+2 BIC (R1)+,@R0 ;No clock status register in RTEM CK.R2 B$LK50,+2 BIS (R2)+,@R0 ;Set CLK50$ bit if host clock = 50 cycle CK.R2 B$LKGR,+2 TST (R2)+ ;Check clock granularity BNE 10$ ;If NE, there's a clock CK.R1 TSCLO CLR @R1 ;No clock, clear CLOCK$ bit in TSLIST .IFF ;NE RTE$M .IF EQ MMG$T TST @#PS ;Is this an LSI11 (no PSW if so)? T11NOP .ENDC ;EQ MMG$T CK.R0 BCNFG,-2 CK.R1 TSLSI,+2 BIC (R1)+,-(R0) ;If PSW, clear LSI11$ bit (not an LSI) TST @#LKCS ;PSW exists, does clock exist too? T11NOP CK.R1 TSLKC,+2 BIS (R1)+,@R0 ;Set LKCS$ bit if so BNE 10$ ;If clock exists, we're fine, set CLOCK$ too .IF NE PRO$S TST PROFLG ;Is this a PRO? BNE 10$ ;If yes, branch .ENDC ;NE PRO$S TST @#ODDADR ;PSW and no clock, do we odd address trap? T11NOP .ENDC ;NE RTE$M CK.R1 TSCLO,+2 10$: BIS (R1)+,@R0 ;Set CLOCK$ if no odd trap (03 or 23) or clock ; or PRO 300 Series .IF NE RTE$M CK.R2 B$FPU,+2 MOV (R2)+,@R1 ;Set/clr HWFPU$ bit in TSLIST based on whether ; RTEM was task built w/FPU support (/FP); FPU ; is useless without this (context gets lost). .ENDC ;NE RTE$M CFCC ;Check for FPU CK.R1 TSHWF,+2 BIS (R1)+,@R0 ;If present set bit .IF NE MMG$T TST @#MMR0 ;Test for KT11 T11NOP BIS @R1,@R0 ;If present, set bit in BCNFG CK.R1 TSKT,+2 TST (R1)+ ;Was a KT11 present? BNE 20$ ;Yes, we can run JSR R1,@#REPORT ;Error - must have KT11 .WORD NOMMGT ............ 20$: .ENDC ;NE MMG$T .IF EQ TST @#KWP.CS ;Is there a P-clock? T11NOP CK.R1 TSKW,+2 BIS (R1)+,@R0 ;Yes, set the appropriate bit in BCNFG .ENDC ;EQ .IF EQ KW11$P ;If no KW11-P support .IF EQ ;FALCON cannot have XM or RTEM TST FALCON ;Is this a FALCON processor? BNE 30$ ;Branch if yes .ENDC; EQ CMP @R5,#<^rPD > ;Is this a PDT? Branch if not a PDT. ..NOVT::BNE CFIG2 ;**PATCH** NOP to force no display (VT.CSR /-> VT) 30$: BIC #,@R0 ;Yes, we don't really have a VT or KW11P .ENDC ;EQ KW11$P .ENDC ;NE VENU$C .BR CFIG2 .DSABL LSB .SBTTL CFIG2 - Set Bits In CONFG2 Depending On Following Tests ;+ ; Set bits in CONFG2 (the extension of CONFIG) depending on the following ; device tests. ;- .ENABL LSB CFIG2:: .IF EQ VENU$C CK.R0 BCNFG2,-2 TST -(R0) ;Point to BCNFG2 .IF NE RTE$M CK.R1 TSCA,+2 BIC (R1)+,@R0 ;No cache memory if RTEM CK.R1 TS70,+2 BIC (R1)+,@R0 ;No 11/70 memory size if RTEM .IFF ;NE RTE$M .IF NE PRO$S TST PROFLG ;Running on a PRO? BNE 10$ ;Branch if yes - skip 11/70 and cache bits .ENDC ;NE PRO$S TST KXJFLG ;Running on a KXJ? BNE 10$ ;Branch if yes - skip 11/70 and cache bits TST FALCON ;Running on a FALCON? BEQ 20$ ;Branch if not BIS #,BCNFG ;Correct CONFIG -- FALCON is an LSI 10$: CMP (R1)+,(R1)+ ;Skip cache memory and 11/70 bits BR 30$ ;Skip cache memory and 11/70 code ............ 20$: TST ROIFLG ;PDP 11/93 OR PDP 11/94 (KDJ11-E: ROI BOARD)? BNE 10$ ;BR IF YES: DON'T CHECK FOR CACHE MEMORY. BIS #,@#CA.CSR ;Check for cache memory (Disable ... ; ... non-fatal cache error traps if found) T11NOP CK.R1 TSCA,+2 BIS (R1)+,@R0 ;Set if present TST @#P7.LSS ;Test for 11/70 memory size T11NOP CK.R1 TS70,+2 BIS (R1)+,@R0 ;Set bit if 11/70 30$: .ENDC ;NE RTE$M ;+ ; Check if the processor has FULL extended instruction set. ;- MOV #<3>,R3 ;Set up R3 to ... MUL R3,R3 ; ... test for EIS CMP #<3*3>,R3 ;Did it multiply right? BEQ 40$ ;Yes CLR @R1 ;No, don't set the bit CK.R1 TSEIS,+2 40$: BIS (R1)+,@R0 ;Set bit if EIS present and working ;+ ; Check for switch register, light register and other msc things. ;- .IF NE RTE$M CK.R1 TSSWR,+2 BIC (R1)+,@R0 ;No switch register for RTEM CK.R1 TSLIT,+2 BIC (R1)+,@R0 ;No light register for RTEM .IFF ;NE RTE$M MOV @#SWR,R2 ;Is there a switch register? T11NOP CK.R1 TSSWR,+2 BIS (R1)+,@R0 ;Yes, set the appropriate bit MOV #<0>,@#SWR ;Is there a light register? T11NOP CK.R1 TSLIT,+2 BIS (R1)+,@R0 ;Yes, set the LIGHT$ bit in BCNFG2 .IF EQ MMG$T ;Can't be an LSI if this is XB/XM BIT #,BCNFG ;Running on an LSI-11? BNE 50$ ;Yes, it couldn't possibly be an 11/60 .ENDC ;EQ MMG$T .ENDC ;NE RTE$M MOV R0,-(SP) ;Save R0 since MED instruction modifies it MOV #<2>,PCFIX ;Make sure if we trap, that we return to ... ; ... instruction AFTER the 100! MED6X ;MED instruction to test for 11/60 ... .WORD 100 ; ... MED sub-type (read from ???) CLR PCFIX ;Reset PC modifier MOV (SP)+,R0 ;Now restore R0 CK.R1 TS60 BIS @R1,@R0 ;Set bit if 11/60 CK.R1 TS60,+2 50$: TST (R1)+ ;Skip over the 11/60 bit ;+ ; The following tests for the existence of the commercial instruction set ; on 11/24 and 11/44. If the instruction executes R0-R3 will contain 0. If ; it does not execute, the contents of location pointed to by R1 is cleared ; when trapped to BCLR. The registers are restored and the bit is or is not ; set in BCNFG2. ;- MOV R1,-(SP) ;Save R1 MOV R0,-(SP) ;Save R0 MOV R4,-(SP) ;Save R4 CLR R4 ;Clear high byte incase DIS present CMPN ;Execute CMPN instruction (CIS) MOV (SP)+,R4 ;Restore R4 MOV (SP)+,R0 ;Restore R0 MOV (SP)+,R1 ;Restore R1 CK.R1 TSCIS,+2 BIS (R1)+,@R0 ;Set bit if CIS CK.R1 TSLD,+2 BIS (R1)+,@R0 ;Set LDREL$ on boot .IF NE PRO$S CK.R1 PROFLG,+2 BIS (R1)+,@R0 ;Set PROS$ bit if we are on PRO300 series .ENDC ;NE PRO$S CK.R1 TSBUS,CHANGE=+2 BIS (R1)+,@R0 ;Set BUS$ in CNFG2, if QBUS. More for KXJ. 60$: CLR @#V.CPU ;No more traps CLR @#V.INST ;Clear trap vector .IF EQ RTE$M MOV #,R2 ;R2 -> Table of parity status registers MOV #,R3 ;R3 -> Start of UNIBUS parity status registers 70$: ADD #<2>,R3 ;R3 -> Next parity status register ;CLC ;C=0 from ADD, which couldn't overflow CALL T4SEC ;Set carry if we trap CLR @R3 ;Disable parity if CSR exists ;;; T11NOP ;Stall not needed for next instruction CALL @(SP)+ ;Restore traps BCS 80$ ;If C-bit set, status register not there MOV R3,(R2)+ ;Store status register in parity table (PARTB) .IF NE MPT$Y CK.R1 TSMP BIS @R1,@R0 ;and set bit in BCNFG2 .ENDC ;NE MPT$Y 80$: CMP R3,# ;End of status register check routine? BLO 70$ ;No, continue testing parity status registers .ENDC ;EQ RTE$M .BR LOKFIL ............ .IFF ;EQ VENU$C MOV #,BCNFG2 ;This is all the VENUS T-11 needs BR LOKFIL ;Branch over padding ............ . = < . + VBTPAD > ;Pad so VENUS startup overlay not too big .ENDC ;EQ VENU$C .DSABL LSB .SBTTL LOKFIL - Lookup Monitor, Swap, And All Handler Files ;+ ; LOKFIL - Search for monitor, swap, and all handler files ;- .ENABL LSB LOKFIL: CLR -(SP) ;Make room for system handler block number CLR -(SP) ; and monitor file block number MOV #<1>,R0 ;Start with directory segment 1 MOV #,R3 ;Point to area for handler names 10$: ASL R0 ;Double the segment number CMP (R0)+,(R0)+ ;Offset it to get a block number (Note even #) MOV #,R1 ;Read two blocks CALL BBREAD ;Read it into BUFFB BCC 20$ JMP INPERR ;Oops, error reading ............ 20$: MOV #,R1 ;Point to the start block word MOV (R1)+,R0 ;Get start block for this segment .IF NE RTE$M ADD $VSBRO,R0 ;Add in bootstrap read offset .ENDC ;NE RTE$M .ASSUME D.STRT+2 EQ D.LENG 30$: MOV R1,R2 ;Copy directory entry pointer .ASSUME E.STAT EQ 0 BIT #,(R2)+ ;Is this a permanent file? BEQ 110$ ;No, skip it .ASSUME E.STAT+2 EQ E.NAME CMP #<^rSYS>,(R2) ;Is it a system file? BNE 110$ ;No, we're not interested .ASSUME E.STAT+2 EQ E.NAME MOV (R2)+,R5 ;Get first word of file name CMP R5,B$FNAM ;Is this the booted monitor name? BNE 40$ ;No CMP @R2,B$FNAM+2 ;Is it really? BNE 40$ ;No MOV R0,@SP ;Yes, we found the monitor BR 110$ ;So much for this file ............ ;+ ; Continue File Lookup ;- 40$: CMP R5,#<^rSWA> ;Is this SWAP.SYS? BNE 50$ ;No CMP @R2,#<^rP > ;Is it really? BNE 50$ ;No MOV R0,SWPBLK ;Yes, we found SWAP.SYS MOV E.LENG(R1),SWPSIZ ;Save the swap file size BR 110$ ;Done with this file ............ 50$: TST @R2 ;Get second word of file name BNE 110$ ;Non-zero, can't be a handler, not interested CMP R5,B$DEVN ;Is this the system handler? BNE 60$ ;No MOV R0,2(SP) ;Yes, save block number of handler file BR 110$ ;Don't put it in the regular handler list ............ 60$: .IF NE PRO$S SUB B$SUFF,R5 ;Take the suffix out of first word CMP R5,#<^rPI > ;Do we have the PI handler? BNE 70$ ;No MOV R0,PIBLK ;Yes, save block number of handler file BR 110$ ;Don't put it in the regular handler list ............ .ENDC ;NE PRO$S 70$: .IF EQ RTE$M .IF NE MMG$T CMP R5,#<^rUB > ;Is it UB? BNE 90$ ;If not, branch CMP UBBLK,#<1> ;Is this a UB restart? BNE 80$ ;If not, branch CLR UBBLK ;Reset UBBLK BR 110$ ;Go out ............ 80$: TST TSBUS ;Is this a UNIBUS? BNE 110$ ;Branch if not - ignore it .IF NE PRO$S TST PROFLG ;Is this a PRO? BNE 110$ ;If yes, ignore UB .ENDC ;NE PRO$S TST # ;Was UB support sysgened in? BEQ 110$ ;If not, branch MOV R0,UBBLK ;Yes, save block number of UBX.SYS BR 110$ ;Don't put it in the regular handler list ............ .ENDC ;NE MMG$T .ENDC ;EQ RTE$M 90$: CMP R3,#> ;More than 40. handlers here? BHIS 110$ ;Yes, can't remember any more SUB B$SUFF,-(R2) ;Take the suffix out of a possible name MOV (R2)+,R5 ;Get the non-suffixed name .IF EQ BATC$H CMP R5,#<^rBA > ;Do we have the BATCH handler? BEQ 110$ ;Yes, ignore it .ENDC ;EQ BATC$H 100$: SUB #<^r A >,R5 ;Reduce name to get RAD50 last character BHI 100$ ;Loop until overflow BNE 110$ ;No, not a handler MOV -(R2),(R3)+ ;Save handler name MOV R0,(R3)+ ;Save starting block number ;+ ; Continue with next directory segment ;- 110$: BIT #,@R1 ;End of directory segment? BNE 120$ ;Yes, try for another ADD E.LENG(R1),R0 ;Bump file starting block number by entry size ADD #,R1 ;Skip over this entry ... ADD BUFFB+D.EXTR,R1 ; ... including extra words BR 30$ ;Try for more ............ 120$: MOV BUFFB+D.NEXT,R0 ;Get next segment number BNE 10$ ;Do more CLR @R3 ;Terminate the handler list .BR 130$ ;+ ; All directory work is done. Size and initialize total system RAM with ; good parity for those processors with parity memory. For XM, turn on ; Memory Management. On the PRO3xx, build a option slot id # table at ; the top of low memory. For XM, MEMTOP is stuffed by KT11RG routine. ;- 130$: .IF EQ MMG$T MOV R4,MEMTOP ;Save top of low memory for non-XM .ENDC ;EQ MMG$T .IF NE RTE$M MOV MEMSIZ,TOTMEM ;Total system RAM = usable memory .IFF ;NE RTE$M .IF NE VENU$C MOV @#MEMSIZ,@#TOTMEM ;VENUS is non-XM system, no KT-11 .IFF ;NE VENU$C MOV @SP,R0 ;Get starting block of monitor file BEQ 140$ ;If zero we couldn't find monitor file ADD #,R0 ;Point to block for overlay MOV #/2,R1 ;Get number of words to read CALL BBREAD ;Read the overlay into BUFFB BCS INPERR ;Error CALL KT11RG- ;Set up memory management .ENDC ;NE VENU$C .ENDC ;NE RTE$M MOV (SP)+,MONBLK ;Save monitor block number for later .IF NE BEQ 140$ ;If zero we couldn't find monitor file .ENDC ;NE MOV (SP)+,R0 ;Get block number of system handler BEQ NOHAND ;What! Not there! .IF NE RTE$M SUB $VSBRO,R0 ;Subtract out bootstrap read offset .ENDC ;NE RTE$M .IF EQ AI$COD TST SWPBLK ;Did we find SWAP.SYS? BNE DVREAD ;Yes, go read in system handler JSR R1,@#REPORT ;SWAP.SYS was not found .WORD NSWAP ;No swap file error ............ .IFF ;EQ AI$COD MOV #-1,SWPBLK ;Safety feature in case a swap occurs because ;of monitor corruption. At most, only last ;block of a 65536. block device can be ;corrupted. BR DVREAD ;Go read in system handler .ENDC ;EQ AI$COD 140$: JSR R1,@#REPORT ;Specified monitor not on volume .WORD NOMON ;No monitor error message ............ .IF NE RTE$M TRPERR: JSR R1,@#REPORT ;Unexpected trap to 4 or 10 .WORD UNXTRP ;Unexpected trap error message .ENDC ;NE RTE$M .DSABL LSB ;+ ; The start-up code is in a unique overlay that overlays code starting ; at B$BOOT. INPERR and most of the following code cannot be overlaid ; so that the start-up overlay must not go beyond this point. Also ; make sure that no data that is needed by the start-up code is stored ; in the above region. ;- B$END:: ;End of region that will be overlaid .ASSUME <.-B$BOOT> GE .ASSUME <.-B$BOOT> GE .ASSUME <.-B$BOOT> GE .ASSUME <.-B$BOOT> GE .ASSUME <.-B$BOOT> GE .IF NE MMG$T .ASSUME <.-B$BOOT> GE .ENDC ;NE MMG$T .SBTTL The root starts here INPERR: CALLR @#BIOERR ;Die on error B.RDER: CALL B.READ ;Do a read (R0, R1, and R2 already set) BCS INPERR ;Just return on success RETURN NOHAND: JSR R1,@#REPORT ;Specified handler not on volume .WORD NOHNDL ;No handler error message .SBTTL INSTAL - Install handlers ;+ ; NOTE: INSTAL MUST REMAIN IN ROOT!!! ;- .ENABL LSB INSTAL: CALL T4SEC ;Set carry if we trap MOV R2,R5 ;Point to start of handler header ADD #,R5 ;Point to handler options word .IF NE MMG$T TST INSTUB ;Are we trying to install UB? BNE 10$ ;If yes, br - skip SYSGEN options check .ENDC ;NE MMG$T CMP @R5,B$SYOP ;Do the SYSGEN options match? SEC ;Set carry in case next instr branches BNE 100$ ;No, ignore the handler 10$: ADD #,R5 ;Point to CSR address in handler .IF EQ VENU$C TST @(R5)+ ;Check for CSR present T11NOP .IFF ;EQ VENU$C TST (R5)+ ;Bump counter to keep it in line .ENDC ;EQ VENU$C BCS 100$ ;No CSR, install it .ASSUME H.ICSR+2 EQ H.IDK .ASSUME H.ICSR+4 EQ H.ISY NONSYS: TST (R5)+ ;Is there an install routine? BEQ 100$ ;No CALL SAVRG1 ;Call it 100$: RETURN ;Restore vectors at 4 and 10 and return ............ .IF NE PRO$S GTPIHD: TST # ;Does monitor include PI support? BEQ NOHAND ;Branch if not MOV (PC)+,R0 ;Get starting block number of PI handler PIBLK: .WORD 0 BEQ NOHAND CALL BBRD1 ;Read 1 block of PI into BUFFB BCS INPERR ;Error RETURN .ENDC ;NE PRO$S .DSABL LSB .SBTTL DVREAD - Read UB, SY, Fake Fixed Area And Monitor Into Memory ;+ ; DVREAD - Save system handler data, read UB and SY into top of memory ; ; Read fake fixed area into memory at FIXST and put whatever real ; information we have into it. (Overlay LDHNDL) ; Read PI or UB, then SY into memory (Overlay LDHNDL) ; Read system relocation information into BUFFB (Overlay LDHNDL) ; Read monitor into memory below SY (Overlay LDHNDL) ; Load monitor tables (Overlays LDTABL and RLMON2) ; ; Upon entering: ; R0 = System handler block number (saved in SYBLK) ; R4 = Top of available low memory (first unavailable word) ; (saved in SYHSAV) ;- .ENABL LSB DVREAD: MOV R0,(PC)+ ;Save the system handler start block SYBLK: .WORD 0 ;System handler start block MOV R4,(PC)+ ;Save the original top of available low memory SYHSAV: .WORD 0 ;original top of available low memory DVRD3: MOV MONBLK,R0 ;Get block number of start of monitor file .IF NE RTE$M SUB $VSBRO,R0 ;Subtract out bootstrap read offset .ENDC ;NE RTE$M ADD #,R0 ;Compute block number for LDHNDL overlay MOV #/2,R1 ;Get number of words to read MOV #,R2 ;Get address of B$BOOT for LDHNDL CALL B.RDER ;Do the read (check for error) CALL DVRD2+ ;Install UB and SY MOV MONBLK,R0 ;Get block number of start of monitor file .IF NE RTE$M SUB $VSBRO,R0 ;Subtract out bootstrap read offset .ENDC ;NE RTE$M ADD #,R0 ;Compute block # for table load overlay MOV #/2,R1 ;Get number of words to read MOV #,R2 ;Read over earlier code at B$BOOT CALL B.RDER ;Do the read (check for error) ADD #,R5 ;Point to system handler at correct offset MOV R5,SYENTR(R4) ;Save system handler entry in $SYS in monitor MOV R5,$ENTRY+2(R4) ;Store the handler entry point .IF NE RTE$M MOV #<$RTELK>,R1 ;Protect the linkage routine pointer and ID CALL PROTEC ; just in case..... .ENDC ;NE RTE$M CALL LDTABL+ ;Load the monitor tables CALL @(SP)+ ;Relocate USR/KMON stuff ;@SP contains address of LOCATE in USR CALL RLMON2+ ;Set up some more pointers .DSABL LSB .SBTTL Call overlay routines ;+ ; Call overlays SETSIO, CLNUP, and STRTOV (GTHNDL and STRTUP) ;- MOV MONBLK,R0 ;Get block number of start of monitor file .IF NE RTE$M SUB $VSBRO,R0 ;Subtract out bootstrap read offset .ENDC ;NE RTE$M ADD #,R0 ;Compute block number for SETSIO overlay MOV #/2,R1 ;Get number of words to read MOV #,R2 ;Get address of B$BOOT for SETSIO CALL B.RDER ;Do the read (check for error) CALL SETSIO+ ;Switch to system handler for I/O ;+ ; After SETSIO is read in, RTEM no longer needs the read offset $VSBRO ;- MOV MONBLK,R0 ;Get block number of start of monitor file ADD #,R0 ;Compute the block # for start up overlay MOV #/2,R1 ;Get number of words to read MOV #,R2 ;Get address of B$BOOT for SETSIO CALL B.RDER ;Do the read (check for error) CALL CLNUP+ ;Do multi-term setup, PI installation, ; & FALCON break vector setup if needed. MOV MONBLK,R0 ;Get block number of start of monitor file ADD #,R0 ;Compute blk # for STRTOV (GTHNDL) overlay MOV #/2,R1 ;Get number of words to read MOV #,R2 ;Get address of second half of BUFFB CALL B.RDER ;Do the read (check for error) CALLR GTHNDL+ ;Install handlers and start the system .SBTTL CHK64 - Check for 64 unit support ;+ ; CHK64 is in the root because overlays LDHNDL and STRTOV (GTHNDL) call it. ; ; Input: R2 = start address of buffer containing blk 0 of handler ; R0 = start block of SY (LDHNDL only) ; ; Output: C clear, R2 = 1 letter device name ; C set, R2 destroyed ;- .ENABL LSB CHK64: ADD #,R2 ;Point to 64 unit owner flag TST (R2)+ ;is it zero? BEQ 20$ ;If yes, branch, no 64 unit support MOV @R2,R2 ;Get 64 unit word (H.64UM) BIC #^c,R2 ;Isolate HUM.64 bits. Are they zero? BEQ 20$ ;If yes, branch, no 64 unit support CMP R2,#<^rZ > ;Is it a letter? BHI 20$ ;If not, branch, no 64 unit support CMP R0,SYBLK ;Is this SY? BNE 10$ ;If not, branch MOV R2,SY64 ;Save the SY 1 letter device name 10$: TST (PC)+ ;Skip over error return 20$: SEC ;Error return RETURN ;from whence we came .DSABL LSB .IF NE MMG$T .SBTTL UBTST - Test for UMR ;+ ; Test for UB ; ; For UB to be used, all handlers must have HUM.UB set and at least one ; handler must have HUM.DM set. The way to find this is to AND all the ; HUM.UB bits and OR all HUM.DM bits ; ; After all the handlers have passed through UBTST, UB will be used ; if both UBFLG and DMFLG are nonzero. ; ; If DMFLG is nonzero, bit CF3.DM will be set in $CNFG3. ; ; On entry: ; R2 = pointer to HUM.64 word in handler (block 0, offset 100) ; ; On output: ; contents of R2 are destroyed ; No other registers are used ; ;- .ENABL LSB UBTST: MOV @R2,-(SP) ;Save HUM.64 word MOV @SP,R2 ;Get UB flags BIC #^c,R2 ;Isolate HUM.UB bit TST R2 ;Is the bit set? BNE 10$ ;If yes, branch CLR (PC)+ ;Say no UB support UBFLG: .WORD HUM.UB ;If UBLFG = 0 at end, can't use UB BR 20$ ;Go out 10$: MOV @SP,R2 ;Get UB flags again BIC #^c,R2 ;Isolate HUM.DM bit TST R2 ;Is the bit set? BEQ 20$ ;If not, branch BIS #,(PC)+ ;Set the bit DMFLG: .WORD 0 MOV @SP,R2 ;Get UB flags again BIC #^c,R2 ;Isolate HUM.PU bits ADD R2,UMRS ;Save them 20$: TST (SP)+ ;Clean up the stack 30$: RETURN ;from whence we came .DSABL LSB .SBTTL UBRSTR - Restart UB after monitor exists ;+ ; If UB fails to load, we must restart. There are 2 types of restart: ; ; 1. Restart before the monitor is complete. This is fairly easy ; and is done at SETSIO. ; ; 2. Restart after the monitor is complete. This is harder and requires ; that we reread the entire bootstrap and start again almost from ; scratch. The restart code for this is in overlays RSTUB1 & RSTUB2. ; ; We need 2 overlays instead of 1 because RSTUB1 is read into B$BOOT and ; needs all of BUFFB to read in the primary driver. RSTUB1 then reads RSTUB2 ; into BUFFB. RSTUB2 will read the bootstrap into locations 1000-4777. ;- UBRSTR: MOV MONBLK,R0 ;Get block number of start of monitor file ADD #,R0 ;Compute block number for RSTUB1 overlay MOV #</2>,R1 ;Get number of words to read MOV #,R2 ;Get address of B$BOOT for RSTUB1 CALL B.RDER ;Do the read (check for error) CALLR RSTUB1+ ;Set up restart after UB fail .ENDC ;NE MMG$T .SBTTL BCLR - Trap To 4 Interceptors BCLR: CLR @R1 ;Trap means this configuration nyet ADD (PC)+,@SP ;Offset the PC for two word MED instruction PCFIX: .WORD 0 BRTI: RTI ;Untrap ............ BSEC: BIS #,2(SP) ;Trap means non-existent memory RTI ............ .IF NE PRO$S ;+ ; This is for displaying software crash codes on PRO series processors ;- .ENABL LSB BERR05: MOV #<5>,R1 ;I/O error is crash code 5 BR 10$ ;Join display crash code code ............ BERRXX: MOV @R1,R0 ;R0 -> text string (byte after crash code) CLR R1 ;Keep high byte 0 BISB -(R0),R1 ;Get software crash code into R1 10$: MOV #<"TR>,R0 ;Identify it as an RT software crash ... CALLR @#PRODSP ;Go display the crash code ............ .DSABL LSB .ENDC ;NE PRO$S BADINS: NOP ;PDP-11 entry for $GTVEC NOP ;PDP-11 entry for $GTCSR ;PDP-11 entry for $GTSLT JSR R1,@#REPORT ;Conflicting options .WORD CNFSGN .SBTTL PROTEC - Protect Vector(s) In Monitor Bit Map ;+ ; PROTEC - Protect a vector in the monitor bit map ; ; R1 = Vector address ; ; CALL PROTEC ;- .ENABL LSB PROTEC: JSR R5,SAVREG ;Preserve all registers ASR R1 ;To protect the vector, compute ASR R1 ; double word number MOV R1,R2 ;Copy offset of vector (word pair) BIC #^c,R1 ;Isolate the bit pair within the byte ASR R2 ;Shift to get byte ASR R2 ; containing bits ADD R4,R2 ;Add monitor relocation bias BISB PROBTS(R1),LOWMAP(R2) ;Protect two words 10$: RETURN .DSABL LSB PROBTS: .BYTE ^b<11000000>,^b<00110000>,^b<00001100>,^b<00000011> .SBTTL SAVREG,BREAD - Register Save, System Device Read Subroutines SAVRG1: MOV R5,-(SP) ;Stack target address as R5 value SAVREG: MOV R4,-(SP) ;Save ... MOV R3,-(SP) ; ... registers ... MOV R2,-(SP) ; ... five (from JSR) ... MOV R1,-(SP) ; ... through ... MOV R0,-(SP) ; ... zero MOV R5,-(SP) ;Stack the coroutine return address MOV 12.(SP),R5 ;Set R5 to be incoming value CALL @(SP)+ ;Call the caller back MOV (SP)+,R0 ;Restore ... MOV (SP)+,R1 ; ... the ... MOV (SP)+,R2 ; ... registers ... MOV (SP)+,R3 ; ... that ... MOV (SP)+,R4 ; ... we ... MOV (SP)+,R5 ; ... saved RETURN ;Return to caller's caller ............ BREAD1::MOV R0,AREA+2 ;Stuff the block # of start of handler .READW #,#0,R2,R1 ;Read the handler RETURN ;Return C=0 or C=1 to caller ............ BBRD1: MOV #,R1 ;Read 1 block into BUFFB BBREAD: MOV #,R2 ;Point to boot buffer B.READ: JSR R5,SAVREG ;Save registers around the call CALLR @B$READ ;Do the read, then restore regs ............ .ENABL LSB T4SEC: MOV @#V.CPU,10$ ;Save the old trap-to-4 address MOV #,@#V.CPU ;Set trap to simply set Carry MOV @#V.INST,20$ ;Save the old trap-to-10 address MOV #,@#V.INST ;Set trap to simply set Carry CALL @(SP)+ ;Call our caller, who may trap MOV (PC)+,@(PC)+ ;Restore the old trap vector 10$: .WORD 0, V.CPU MOV (PC)+,@(PC)+ ;Restore the old trap vector 20$: .WORD 0, V.INST RETURN .DSABL LSB .SBTTL BCNFG,TSLIST - Configuration Bits And Test List ;+ ; BCNFG2, BCNFG and TSLIST must be in order ;- BCNFG2::.WORD 0 ;Boot CONFG2 word BCNFG:: .WORD LSI11$ ;Boot CONFIG word ;+ ; Set of bit masks for CONFIG ;- TSLIST:: TSLSI: .WORD LSI11$ ;CONFIG bit for LSI-11 CPU TSLKC: .WORD LKCS$ ;CONFIG bit for clock status register TSCLO: .WORD CLOCK$ ;CONFIG bit for clock present TSHWF: .WORD HWFPU$ ;CONFIG bit for FPU present .IF NE MMG$T TSKT: .WORD KT11$ ;CONFIG bit for memory management present .ENDC ;NE MMG$T .IF EQ TSKW: .WORD KW11P$ ;CONFIG bit for KW11-P clock present .ENDC ;EQ ;+ ; Start of CONFG2 (BCNFG2) options ; !!!!!!!!!!!!!!!!! MUST BE KEPT IN THIS ORDER!!!!!!!!!!!!!! ;- TSCA: .WORD CACHE$ ;CONFG2 bit for cache memory TS70: .WORD PDP70$ ;CONFG2 bit for PDP-11/70 CPU TSEIS: .WORD EIS$ ;CONFG2 bit for EIS instructions TSSWR: .WORD SWREG$ ;CONFG2 bit for switch register present TSLIT: .WORD LIGHT$ ;CONFG2 bit for lights present TS60: .WORD PDP60$ ;CONFG2 bit for PDP-11/60 CPU TSCIS: .WORD CIS$ ;CONFG2 bit for CIS instructions TSLD: .WORD LDREL$ ;CONFG2 bit force handler refresh .IF NE PRO$S PROFLG: .WORD 0 ;CONFG2 Professional 300 series machine ... .ENDC ;NE PRO$S ; ... zero replaced by PROS$ if running on PRO TSBUS: .WORD 0 ;CONFG2 bit for bus type .IF NE MPT$Y TSMP: .WORD MPTY$ ;CONFG2 bit for memory parity present .ENDC ;NE MPT$Y .SBTTL Bootstrap Impure Data Area .IF EQ RTE$M FALCON: .WORD 0 ;Set non-zero if FALCON processor is booted .ENDC ;EQ RTE$M KXJFLG::.WORD 0 ;Set non-zero if KXJ processor is booted ROIFLG: .WORD 0 ;ROI BOARD (KDJ11-E: PDP 11/93-94) FLAG MEMTOP: .WORD 0 ;Top of memory (top of low 28K in XM) SWPSIZ::.WORD 0 ;Size of SWAP.SYS file SWPBLK::.WORD 0 ;Starting block number of swap file AREA:: .BLKW 5 ;Area for READ EMT MONBLK: .WORD 0 ;Starting block of the monitor file G$VEC: .WORD BADINS ;On PRO, this is hooked to point to $GTVEC MEMSIZ::.WORD 0 ;Size of usable system memory in 32. word blks TOTMEM::.WORD 0 ;Size of total system memory in 32. word blks .IF EQ RTE$M PARTB:: ;Parity CSR table .REPT 16. .WORD 0 .ENDR PARTBE: .IFF ;EQ RTE$M $VSBRO: .WORD 0 ;Bootstrap read offset (for VS:) CNFMOD: .WORD 0 ;High bit set in CRT .ENDC ;EQ RTE$M .IF NE MMG$T UBBLK: .WORD 0 ;Start block of UBX.SYS ; 0 -> don't use UB ; 1 -> restart - don't use UB ; any other value -> use UB UMRS: .WORD 0 ;UMR's to pass to UB STRTUB: .WORD 0 ;Address of UBSTRT SYH.BP: .WORD 0 ;Ptr to SY primary bootstrap (loc 62) SYH.BL: .WORD 0 ;Byte length of SY primary bootstrap (loc 64) SYH.RE: .WORD 0 ;Ptr to SY primary bootstrap read rtn (loc 66) PARFLG: .WORD 0 ;-1 -> use Q.PAR (old-style) versions for SY ;0 -> use Q.MEM (new-style) versions for SY INSTUB: .WORD 0 ;nonzero -> we are installing UB ;0 -> we are NOT installing UB .ENDC ;NE MMG$T SY64: .WORD 0 ;SY 1 letter device name .SBTTL Bootstrap Error Message Text .IF NE MMG$T .BYTE 7 ;Crash code for no KT11 NOMMGT: .ASCIZ "No KT11" .ENDC ;NE MMG$T .BYTE 11 ;Crash code for SWAP.SYS not found NSWAP: .ASCIZ "SWAP.SYS not found" .BYTE 3 ;Crash code for handler file not found NOHNDL: .ASCIZ "Handler file not found" .BYTE 10 ;Crash code for swap file too small SPTSML: .ASCIZ "Swap file too small" ERRHND: .ASCIZ "?BOOT-W-Error reading handler" .BYTE 6 ;Crash code for monitor file not found NOMON: .ASCIZ "Monitor file not found" .BYTE 2 ;Crash code for conflicting SYSGEN options CNFSGN: .ASCIZ "Conflicting SYSGEN options" .BYTE 13 ;Crash code for can't load system handler NOLDSY: .ASCIZ "Failure to load system handler" .IF NE RTE$M UNXTRP: .ASCIZ "Unexpected trap" ILHOST: .ASCII .ASCII "?BOOT-U-Host system incorrect for RTEM"<200> .ENDC ;NE RTE$M .EVEN .SBTTL FIXST - Read the fake fixed area here ;+ ; The size of the fixed area is in MAXOFF which is defined in RMON. ; Make sure that this area is at least MAXOFF long. ; ; When you change the RT check, make sure that you change the RTEM ; check (and vice versa). ;- FIXST:: ;Read fixed offsets into memory at FIXST .IF NE RTE$M .SBTTL Fixed Storage Locations For RTEM-11 (Monitor I/O Check) .ASSUME < . + FIXED > LE B$RTEV ;RTEM check (Boot code may not go beyond this) . = B$RTEV ;Boot looks here for ID match .WORD RTS$ID ;RAD50 word to identify RTEM monitor version .IFF ;NE RTE$M .ASSUME < . + FIXED > LE B$DEVN ;RT check .ENDC ;NE RTE$M .SBTTL Fixed Storage Locations For Primary Boot And DUP ;+ ; The following must be kept in order. ;- .ASSUME . LE B$DEVN ;Boot can not go any farther than 4716 . = B$DEVN ;Required location for DUP interface SAVSTR: .WORD 0 ;B$DEVN: Booted device (RAD50) .WORD 0 ;B$DEVS: Booted device (RAD50) sans suffix .IF EQ RTE$M .WORD <^rBOT> ;B$DEVU: Booted unit (^rBOT) .IFF ;EQ RTE$M .WORD <^rRTE> ;B$DEVU: Booted unit (flag for RTEM) .ENDC ;EQ RTE$M .WORD 0 ;B$FNAM: First half of RAD50 monitor filename .WORD 0 ; Second half of RAD50 filename .WORD 0 ;B$READ: Start of primary bstrap read routine SYHTOP::.WORD 0 ;Pointer to top of system handler DUPFLG::.WORD 0 ;0 if booted by DUP (date & time valid) $RMSIZ::.WORD <$RMEND-KMON> ;Monitor size in bytes SAVEND: .SBTTL BSTRNG - Boot Message .ASSUME . EQ 4740 ;Check addresses BSTRNG:: ;**PATCH** Boot message text .ASCII "-"" " .IF DF SYSG$N .ASCII "(S)" ;If sysgened monitor .ENDC ;DF SYSG$N .ASCII " " ...CMV PART=PREFIX,TYPE=I ...CMV PART=RELEASE,TYPE=I .ASCII "." ...CMV PART=VERSION,TYPE=I .ASCII " " ..PLVL:: ;**PATCH** Patch level letter(s) ...CMV PART=SUFFIX,TYPE=Z .EVEN .ASSUME < . > LE B$SUFF ;Check address . = B$SUFF ASCR50 040,040,SUFX$H ..SUFF::.WORD ...V2 ;**PATCH** Handler filename suffix (RAD50) .WORD +++ BUFFB ==: B$HIME HNAMES ==: BUFFB + < 2 * BK.BYT > .SBTTL The root ends here .SBTTL The overlays start here ;+ ; Notes on Overlays ; ; BSTRAP uses many overlays. Most of the time they go into BUFFB, ; which is 2 blocks long and is located at 5006. ; ; For the times when BUFFB is full and another overlay is needed, ; B$BOOT (location 1000) may be used. B$BOOT up to B$END may be ; overlayed after this code has been executed. ; ; In an overlay, any reference to variables or subroutines in the root ; must be absolute. An example is subroutine BRTI in the root. In overlay ; LDTABL, it is called by CALL BRTI+ because LDTABL is read ; in at B$BOOT. In overlay SETSIO, the same routine is called by CALL @#BRTI. ; ; Any references in one overlay to something in another overlay must be biased ; by the second overlay. For example, overlay LDTABL calls FIXPSW in overlay ; RELLST that is in BUFFB. The call in LDTABL is CALL @#FIXPSW+. ; ; Be careful when you make an overlay. Another overlay may assume a variable ; you moved is still in the root, or it may be in the buffer you overlayed. ; ; Note that after RELLST has been read into BUFFB, ; BUFFB cannot be reused until SETSIO is done. ; ; ; Overlays in order Buffer read into Read in from ; ; KT11RG BUFFB root ; LDHNDL B$BOOT root ; fixed area FIXST LDHNDL ; RELLST BUFFB LDHNDL ; Note: Do not reuse BUFFB until SETSIO is done ; LDTABL B$BOOT root ; SETSIO B$BOOT root ; Note: BUFFB may now be reused ; CLNUP B$BOOT root ; BSTTBL last 1/4 of BUFFB CLNUP ; STRTOV B$BOOT root ; RSTUB1 B$BOOT root ; RSTUB2 BUFFB RSTUB1 ; ; Notes for RTEM: ; ; When reading in overlays for RTEM, you must subtract out the ; bootstrap read offset ($VSBRO) until the monitor is complete ; (after SETSIO is done). After SETSIO, you do not need $VSBRO. ;- .SBTTL Overlay RELLST - Relocation list ;+ ; RELLST - List of locations within RMON that must be relocated ; ; RELLST is read into BUFFB ;- .ASSUME < . & BD.BLK > EQ 0 ;Overlay must start on a block boundary RELLST:: .WORD $H2UB ;Default OKRTN .IF EQ MTT$Y .WORD $XOFF ;Address of single terminal's XOFF flag .ENDC ;EQ MTT$Y .WORD $RTSPC ;Default ERRRTN .WORD BLETCH ;TRAP4 low address limit to ignore .WORD BARF ;TRAP4 high address limit to ignore .WORD VOMIT ;$RMON addr in G$VAL .WORD USRLOC ;Location of USR now .WORD $USRLC ;Address of 'normal' USR .WORD QCOMP ;Queue completion routine .WORD $KMLOC ;Address of KMON .WORD SYSLOW ;Lowest used location in system .WORD CORPTR+2 ;Free core list .WORD SYNCH ;.SYNCH routine address .WORD $TCFIG ;Address of term. set option word .WORD $INDDV ;Address for IND device name and unit (ASCII) .WORD GETVEC ;Fixed offset pointer to $GTVEC routine .WORD $QHOOK ;Pointer to first queue hook (Q2CAHK) .WORD Q2CAHK+QH.CNX ;Pointer to next CACHE queue hook .WORD $XTTNR ;Pointer to char reject hook .WORD $XTTPS ;Pointer to TTout status change hook .WORD $XTTPB ;Pointer to TTout data change hook .IF NE MMG$T .WORD Q2CAHK+QH.UNX ;Pointer to next UB queue hook .WORD C2CAHK+FH.UNX ;Pointer to still another UB queue hook .WORD U2UBHK+UH.UNX ;Pointer for next UB hook .WORD A2UBHK+AH.RQE ;Pointer to UB's Reque .ENDC ;NE MMG$T .WORD SPEW ;Addr of $PNAME in C$STAT .IF NE UNI$64 .WORD CRAP ;Addr of $PNAME-4 in LK4DE2 .WORD KECK ;Addr of $PNAM2 in C$STAT .ENDC ;NE UNI$64 .IF NE SPC$PS .WORD BANE ;Addr of $RMON in dispatch? .ENDC ;NE SPC$PS .WORD TTIBUF ;TTY ring buffer - input .WORD TTIBUF+2 .WORD TTIBUF+6 .WORD TTIBUF+10 .WORD TTOBUF ;TTY ring buffer - output .WORD TTOBUF+4 .WORD TTOBUF+6 .IF NE HSR$B ;If high speed ring buffer support .WORD PHSRRT ;High speed ring buffer pointers .WORD HSRB .WORD HSRBEP .WORD HSRBRP .WORD HSRBGP .IF NE < ! > ;If multiple DL11's or no multi-term. support .WORD PHSRRB .ENDC ;NE < ! > .ENDC ;NE HSR$B ;If multi-terminal and high speed output ... .IF GT * ; ... ring buffer and multiple DL11s .WORD PHSRBO ;High speed output ring bfr. pointers .WORD HSROPP .WORD HSROEP .WORD HSRORP .WORD HSROGP .ENDC ;GT * .IF EQ MTT$Y ;If single terminal .IF NE SYT$K ;and system tasking .WORD ZZZZZZ .ENDC ;NE SYT$K .ENDC ;EQ MTT$Y .WORD IMPLOC ;Impure area pointer .WORD $NULJB .WORD TTIUSR .WORD TTOUSR .IF NE TIME$R .WORD FUDGE1 .WORD FUDGE2 .ENDC ;NE TIME$R .WORD BKGND1 .WORD BKGND2 .WORD BKGND3 .WORD CNTXT .WORD BCNTXT .WORD PBSYCH ;Pointer to background system channel .WORD SWIPTR .WORD SWOPTR .WORD .$CRTN .IF EQ MMG$T .WORD RMONSP .IFF ;EQ MMG$T .WORD P1EXT ;Pointer to kernel PAR 1 externalization .WORD $TRPLS ;Fixed offset pointer to FIXTRP vector list .WORD TRPLST+4 .WORD TRPLST+10 .WORD TRPLST+14 .IF NE FPU$11 & ^c ;If FPU support and not SB/XB/ZB .WORD BGFPPT .ENDC ;NE FPU$11 & ^c .ENDC ;EQ MMG$T .IF NE MTT$Y ;Multi-terminal (all systems) .WORD BKCNSL ;Pointer to console TCB .WORD TTITPT ;Dispatch list for special input characters .WORD TTOTPT ;Dispatch list for special output characters .IF GT ;More than 1 DL11 .IF EQ HSR$B ;No high speed ring buffer .WORD PDLTB0 ;-> DLTBL .ENDC ;EQ HSR$B .WORD PDLTB1 ;-> DLTBL .ENDC ;GT .IF NE ;DL-11 or DH series modem control .WORD DLCRP1 ;Reference to DLWCAR .WORD DLCRP2 ;Reference to DLWCAR .ENDC ;NE .IF NE MTI$M ;Modem time-out .WORD PDLCS1 ;-> DLCSR in MTTINT .WORD DLTMCP ;-> DL11 modem time out routine .ENDC ;NE MTI$M .IF NE DZ11$N ;DZ-11 support .WORD PBMSK1 ;-> BITMSK in MTTINT .WORD PBMSK2 ; " .WORD PBMSK3 ; " .IF GT ;More than 1 DZ11 .WORD PDZTB0 ;-> DZTBL in MTTINT .WORD PDZTB1 ; " .WORD PDZCS0 ;-> DZCSR in MTTINT (DZ CSR table) .WORD PDZCS1 ; " .ENDC ;GT .IF NE DZMD$M ;DZ-11 modem control .WORD PDZTCT ;-> DZTCTB table of DZ TCB pointers .WORD PBMSK4 ;-> BITMSK in MTTINT .WORD PBMSK5 ; " .WORD DZTMCP ;DZ11 modem time out routine .ENDC ;NE DZMD$M .IF NE MTY$HK .WORD PBMSK6 ;-> BITMSK in MTTINT .WORD PBMSK7 ; " .ENDC ;NE MTY$HK .ENDC ;NE DZ11$N .IF NE DH11$N ;DH-11 support CTRL$N = 0 .REPT DH11$N .IRP .C.,<\CTRL$N> .WORD DHCTF'.C.' ;DH controller '.C.' info block, first .WORD DHCTL'.C.' ; and last TCB pointers .ENDR ;.C. CTRL$N = CTRL$N + 1 .ENDR ;DH11$N .WORD DHIT00 ;Reference to DHTBL .IF NE MTY$HK .WORD MTYHK1 ;Address of DL to DH translation table .WORD MTYHK2 ;Address of DH to DL translation table .WORD MTYHK3 ;Address of DH to DL translation table .ENDC ;NE MTY$HK .ENDC ;NE DH11$N .IF NE MTY$HK ;Multiterminal handler hooks support .WORD $THKPT ;Pointer to terminal hooks data structure .WORD THOOKS+THK.TC ;Pointer to TCBLST .WORD THOOKS+THK.OE ;Pointer to MTOENB routine .WORD THOOKS+THK.BK ;Pointer to MTYBRK routine .WORD THOOKS+THK.CT ;Pointer to MTYCTL routine .WORD THOOKS+THK.ST ;Pointer to MTYSTA routine .ENDC ;NE MTY$HK .ENDC ;NE MTT$Y .IF NE MMG$T .WORD TRPLST ;Must be last in the list .ENDC ;NE MMG$T .WORD 0 ;End of list of addresses .SBTTL VECLST - List Of Vector Locations To Be Set Up (in overlay RELLST) ;+ ; VECLST - Vector locations that must be set up ; ; Format: ; .WORD location to load (ignoring the low bit, a flag called ...REL) ; .WORD contents of location (relocate with monitor bias if ...REL=1) ; .WORD contents of location+2 ;- ...REL =: 1 VECLST:: ;Note: load of loc 0 must be first .WORD ;Location 0 BIC R0,R0 ; (000) gets a hard ... .IF EQ MMG$T .EXIT ; ... (002) .EXIT .IFF ;EQ MMG$T .ASTX ; ... (002) .ASTX .ENDC ;EQ MMG$T .WORD , TRAP4, PR7 ; (004) Traps to 4 .WORD ,TRAP10, ; (010) Traps to 10, C=1 .IF EQ PWF$L .WORD , , HALT ; (024) Halt on power failure .IFF ;EQ PWF$L .WORD ,TRAPPF, PR7 ; (024) Trap on power failure .ENDC ;EQ PWF$L .WORD , EMTPRO, PR0 ; (030) Monitor calls .IF NE MMG$T .WORD ,TRAPTR, PR7 ; (034) TRAP's .ENDC ;NE MMG$T .WORD <$JSW>, USWAP$, 0 ; (044) $JSW & USR load addr. ..TFIL ==: < . + 4 > ;**PATCH** Initial console fill characteristics .WORD <$SYPTR!...REL>, $RMON, 0 ; (054) At $SYPTR->RMON, no TT ;Setup boot std vectors .WORD ,TTIINT, PR7 ; (060) Terminal input int. .WORD ,TTOINT,PR7 ; (064) Terminal output int. .IF NE KW11$P .WORD V.KW1L, , RTI ; (100) Skip line-time clk int .ENDC ;NE KW11$P .WORD , LKINT, ; (104) Timer vec, PRI=7, C=1 .IF EQ MPT$Y .WORD V.MEM, , HALT ; (114) Halt on mem parity err .IFF ;EQ MPT$Y .WORD ,TRAPMP, PR7 ; (114) Memory parity error .ENDC ;EQ MPT$Y .WORD 0 ;End of list ............ VECHI: .IF NE MMG$T ;+ ; BPT and IOT are in this list because the DX (RX01) bootstrap read ; routine uses them because it has only 64 words in its primary bootstrap. ; RX01 boot ROMs only read in the first sector of the RX01 bootstrap and ; then it has to read the rest of itself in! Therefore we must defer ; initializing these vectors until after we have done all the I/O we are ; going to do with the bootstrap read routine. The CORUPT routine is called ; to initialize vectors that need to be preserved until the real system ; handler can take control. The call to it is in SETSIO. ;- .WORD V.BPT!...REL, TRAPBP, PR7 ;(014) Break point traps .WORD V.IOT!...REL, TRAPIO, PR7 ;(020) IOT's .ENDC ;NE MMG$T .WORD ,TTIINT, PR7 ; (060) Terminal input int. .WORD ,TTOINT,PR7 ; (064) Terminal output int. .IF EQ FPU$11 .WORD V.FPP, , HALT ; (244) FPU exceptions halt .IFF ;EQ FPU$11 .WORD , FPPINT, PR7 ; (244) FPU exceptions .ENDC ;EQ FPU$11 .IF NE MMG$T .WORD , TRAPMM, PR7 ; (250) MMU fault trap routine .ENDC ;NE MMG$T .WORD 0 ;End of list .BR LDSTRT ;CORUPT code assumes LDSTRT follows ............ ;+ ; Minus one argument used to generate warning message on write locked disks. ;- LDSTRT: .ASCIZ "!RUN SY:LD" ..BLDS::.ASCIZ ".SYS /C:-1" ;Set LD clean(must end w/ 0 byte) ............ ATFILE: .IF NE STAR$T .ASCII "@" ..UPDA ==: . ;Update patch location .IF NE .ASCIZ "START" ;Start-up file name is START% ;for RTEM and VENUS. .IFF ;NE .ASCIZ "STRT" ;Start-up file name is STRT%% ;for SB, FB, XB, XM, ZB, ZM, & AI. .ENDC ;NE .ENDC ;NE STAR$ .EVEN .IF EQ RTE$M .SBTTL LSIMOD - Code Modification List For LSI11's (in overlay RELLST) ;+ ; Code modification list for LSI11 processors. This list must follow the ; start file data! In each portion of the list, the first word controls the ; load order, then come addresses and the word(s) to load at those addresses. ;- LSIMOD: .IF EQ SB .WORD ^B<11011010> .WORD M$SV11 MSV11:: .WORD KW$28 .IFF ;EQ SB .WORD ^B<01101101> .ENDC ;EQ SB .WORD GETPSW ;Load 2 words at GETPSW to stack the PS MFPS -(SP) NOP .WORD PUTPSW ;Load 3 words at PUTPSW to set the PS MTPS 2(SP) NOP .WORD RMONPS MFPS R4 BIC (R5)+,R4 MTPS R4 .IFF ;EQ RTE$M .SBTTL RTEMOD - Code Modification List For RTEM (in overlay RELLST) ;+ ; Code modification list for RTEM. First word controls the load order, ; then come addresses and words to load. ;- RTEMOD: .WORD ^b<0101001010101001> ;Load 2, 1, 2, 2, 2, 2, 1, 2, 2 words .WORD $RMON ;Load 2 words at RMON to CALLR $INTN CALLR @(PC)+ .WORD .$INTN .WORD GTVECT ;Load 1 word at GTVECT for no VT11 vector .WORD 0 .WORD GETPSW ;Load 2 words at GETPSW to stack the PS CALLR @(PC)+ .WORD .$GTPS .WORD PUTPSW ;Load 2 words at PUTPSW to set the PS CALLR @(PC)+ .WORD .$PTPS ;*** Critical Ordering *** .WORD DRINTN ;Load 2 words at DRINTN for $FORK pointer .WORD 0 ; (dummy - really 1 word at DRINTN+2) P$FORQ: .WORD .$FORQ .WORD DRINTN-2 ;Load 2 words at DRINTN - 2 for $INTEN pointer .WORD 0 ; (dummy - really 1 word at DRINTN) P$INTN: .WORD .$INTN ;*** End Critical Ordering *** .ASSUME P$INTN EQ .ASSUME EQ 0 ;So DRVTBL is: 0, $INTEN, $FORK .WORD BCNTXT+4+<..SDTM*2> ;Load 1 word at EMTLST to NOP .SDTTM .WORD *2+1 ; (NOP request, but address check R0) ; Should use EMTCAL for TOOBIG, a global .WORD FATAL ;Load 2 words at FATAL for system halt message JSR R1,@(PC)+ .WORD .$FATA .WORD RTICML ;Load 2 words at RTICML to exit from an EMT CALLR @(PC)+ .WORD .$RTIC ;+ ; More code modification list for RTEM ;- .WORD ^b<0101101011010101> ;Load 2, 2, 2, 3, 2, 3, 2 words .WORD D$ATE ;Load 2 words at D$ATE to pick up the date CALL @(PC)+ ; (Subroutine $GTDAT returns to CALL + 6 !!!) .WORD .$GTDA .WORD EXIHOK ;Load 2 words at 'EXIT' to release jobs LUNs CALL @(PC)+ .WORD .$DARL .WORD EXRDKM ;Load 2 words at EXRDKM to read the KMON CALL @(PC)+ .WORD .$RDKM .WORD GTIHOK ;Load 3 words at G$TIM to get the time CALL @(PC)+ .WORD .$GTTI RETURN .WORD ENSHOK ;Load 2 words at $ENSYS + 4 to stack the PS CALLR @(PC)+ .WORD .$GETE .WORD RMONPS ;Load 3 wrds at RMONPS to lower pri., pop R5 CALL @(PC)+ ; (= Enable ASTs) .WORD .$SPL0 TST (R5)+ .WORD RTICMN ;Load 2 words at RTICMN to exit interrupt CALLR @(PC)+ .WORD .$RTIC ;+ ; Even more code modification list for RTEM ;- .WORD ^b<010101001> ;Load 2, 1, 2, 2, 2 words. .WORD FPSHOK ;Load 2 words at FPSTST to store FPU status CALL @(PC)+ .WORD .$FPST .WORD SCNALL ;Load 1 word at SCNALL to stack MOVB (PC)+,-(SP) .WORD SCNALL+4 ;Load 2 words at SCNALL + 4 to start idle loop CALLR @(PC)+ .WORD .$IDLP .WORD CRRHOK ;Load 2 words at $CRRTI to exit completion rtn CALLR @(PC)+ .WORD .$CRTI .WORD $RQSIG ;Load 2 words at $RQSIG to set signifcnt event CALLR @(PC)+ .WORD .$RQSG ;+ ; Modifications for terminal I/O ;- .WORD ^b<01> ;Load 2 words .WORD DLIHOK ;Load 2 words at DLIHOK to call $INTN JSR R5,@(PC)+ .WORD .$INTN .IF EQ ;If no High Speed Ring Buffer support .WORD ^b<110> ;Load 1, 3 words .IFF ;EQ .IF NE ;If Input and Output High Speed Ring Buffers .WORD ^b<11001> ;Load 2, 1, 3 words .IFF ;NE .ERROR ; HSR$O and HSR$B Must both be used together for RTEM-11; .ENDC ;NE .ENDC ;EQ .IF NE HSR$B ;If High Speed Ring Buffer support .WORD FRQHOK ;Load 2 words at DLIINT to call $FORQ JSR R5,@(PC)+ .WORD .$FORQ .ENDC ;NE HSR$B .IF EQ HSR$O ;If no High Speed Output Ring Buffer support .WORD DLOHOK ;Load 1 word at DLOHOK so don't do .INTEN BR .+12 ; or a SAVE30 .IFF ;EQ HSR$O .WORD DLOHOK ;Load 1 words at DLOINT to skip $INTN and FORQ BR .+14 .ENDC ;EQ HSR$O .WORD TTOENB ;Load 3 words at TTOENB to enable output CALL @(PC)+ ; interrupts .WORD .$RSTT NOP ;+ ; MORE Modifications for terminal I/O ;- .WORD ^b<0101010101001001> ;Load 2, 1, 2, 1, 2, 2, 2, 2, 2 words .WORD MTTGET ;Load 2 words at MTTGET to stack the PS CALL @(PC)+ .WORD .$GETP .WORD MTTGET+12 ;Load 1 word at MTTGET, NOP as $GETPS rtns +6 .WORD NOP .WORD MTTHOK ;Load 2 words at MTTGET to restore the PS CALL @(PC)+ .WORD .$PTPS .WORD ERRHOK ;Load 1 word at ERRCOM so TT output interrupt BR .+14 ; doesn't get turned back on (fixes loss of ; TT output when access non-allocated device, ; and 300 baud error messages. NOPs the ; BIC #xxx,@TTPS and the BIS #ENABL,@TTPS .WORD TTPS ;Load 2 words at TTPS to set TPB address .WORD 0 ; (dummy so next gets relocated) .WORD .$TPB .WORD TTKB ;Load 2 words at TTKB to set TPS address .WORD 0 ; (dummy so next gets relocated) .WORD .$TPS .WORD TTKS ;Load 2 words at TTKS to set TKB address .WORD 0 ; (dummy so next gets relocated) .WORD .$TKB .WORD SCROLL ;Load 2 words at SCROLL to set TKS address .WORD 0 ; (dummy so next gets relocated) .WORD .$TKS .WORD RCTHOK ;Load 2 words at R$CTLO to reset CTRL/O CALL @(PC)+ .WORD .$RSCT ;+ ; Mark-time hooks for RTEM-11 ;- .IF GT ;If more than ONE terminal !! .WORD ^b<01010000> ;Load 1 , 1 , 1 , 1, 2 , 2 words .IFF ;GT ;If not more than ONE terminal !! .WORD ^b<101> ;Load 2 , 2 words .IFT ;GT ;If more than ONE terminal !! .WORD TTIINT ;Load 1 word at TTIINT to NOP GETPSW NOP .WORD TTIINT+2 ;Load 1 word at TTIINT+2 to NOP GETPSW+2 NOP .WORD DLOINT ;Load 1 word at DLOINT to NOP GETPSW NOP .WORD DLOINT+2 ;Load 1 word at DLOINT+2 to NOP GETPSW+2 NOP .ENDC ;GT .WORD TIMIO ;Load 2 words at TIMIO to call .$MRKT CALL @(PC)+ .WORD .$MRKT .WORD CMTHOK ;Load 2 words to CMTHOK to call .$CMKT CALL @(PC)+ .WORD .$CMKT .WORD 0 ;End of list (or mask if patch linkages exist) RTEMP:: .BLKW < $LRLPZ * 4 > ;Room for patch linkages ; ( = room for '$LRLPZ' 3 word patches) .WORD 0 ;End of patch list .ENDC ;EQ RTE$M .SBTTL PSW Reference List (in overlay RELLST) .IF EQ RTE$M MOVB (SP)+,@(PC)+ ;MOVB (SP)+,@#PS PUTPSW MOV @(PC)+,-(SP) ;MOV @#PS,-(SP) GETPSW CLRB @(PC)+ ;CLRB @#PS SPL 0 PSWPDP: MOVB (PC)+,@(PC)+ ;MOVB #--,@#PS SPL N .WORD PS .WORD PS .WORD PS PSWPD2: .WORD PS MTPS (SP)+ ;MTPS (SP)+ PUTPSW MFPS -(SP) ;MFPS -(SP) GETPSW MTPS (PC)+ ;MTPS #0 SPL 0 PSWLSI: MTPS (PC)+ ;MTPS #--, NOP SPL N NOP NOP .WORD 0 NOP .IFF ;EQ RTE$M CALL @(PC)+ ;JSR PC,$PTPSW PUTPSW CALL @(PC)+ ;JSR PC,$GETPS GETPSW CALL @(PC)+ ;JSR PC,$SPL0 SPL 0 PSWRTE: CALL @(PC)+ ;JSR PC,$SPL7 SPL N .$PTPS .$GETP .$SPL0 PSWVR2: .$SPL7 PSWNOP: NOP .SBTTL $LINKB - List Of RTEM Linkage Monitor Addresses (in overlay RELLST) ;+ ; $LINKB ; ; FUNCTIONAL DESCRIPTION: ; ; ********************************************************* ; *** If this changes, you must change RTEDEF.MAC *** ; *** This list is NOT order dependant,as is RTEDEF.MAC *** ; *** Though it should be kept in order if possible. *** ; ********************************************************* ; ; This table is used to setup address linkages between the ; monitor and the host system linkage routines. The RTEM ; secondary bootstrap connects these linkages after it is ; read into memory by the RTEM bootstrap task. ; ; The address of the linkage table is stored in the RTEM linkage ; pointer ($RTELK) in low memory. RTEM device drivers use the ; linkage pointer to call linkage routines. ; ; Besides these pointers into RMON, the linkage table contains ; pointers to various of the linkage routines. The order of ; these pointers is fixed. If the linkage routines are NOT in ; a resident COMMON, they follow the impure linkage data in ; memory. If they are in a COMMON, there may be a 'hole' in ; the RTEM address space between the end of the impure linkage ; data and the start of the resident COMMON. ; ; FORMAT OF AN ENTRY IN $LINKB TABLE: ; ; .WORD Address of RMON data ; .WORD Offset into linkage table of corresponding pointer ; ; The secondary bootstrap relocates the RMON address depending ; on the size of 'memory', and stores the resultant value in ; the appropriate offset of the linkage table. ;- $LINKB:: .WORD EXUSER, .EXUSE ; -> EXUSER in RMON .WORD FPPFLG, .FPPFL ; -> FPPFLG " .WORD INTACT, .INTAC ; -> INTACT " .WORD INTLVL, .INTLV ; -> INTLVL " .WORD LKQUE, .LKQUE ; -> LKQUE " .WORD PSCLOK, .PSCLO ; -> PSCLOK " .WORD RMONSP, .RMONS ; -> RMONSP " .WORD SAVE30, .SAVE3 ; -> SAVE30 " .WORD $SYS, .SYS ; -> $SYS " .WORD TASKSP, .TASKS ; -> TASKSP " .WORD TIKCTR, .TIKCT ; -> TIKCTR " .WORD TTRSET, .TTRSE ; -> TTRSET " .WORD $ENSYS, .$ENSY ; -> $ENSYS " .WORD $FORK, .$FORK ; -> $FORK " .WORD $INTEN, .$INTE ; -> $INTEN " N = 0 .REPT $RMLPZ .IRP K \N .WORD $RMON, .$RMP'K ; RMON patch linkages .ENDR N = < N + 1 > .ENDR .WORD 0 ; End of list ;+ ; Following commented out, to allow LINK w/RTEDEF, rather than assembly w/it ; .ASSUM <.-$LINKB-2/2> EQ <$RMLE-$RMLS> ;- .ENDC ;EQ RTE$M .SBTTL FIXPSW - Fix References To The PS (in overlay RELLST) .ENABL LSB FIXPSW: .IF EQ RTE$M MOV #PSWPDP+,R3 ;Point to non-LSI PS reference BIT #,@#BCNFG ;Booting on an LSI11 machine? BEQ 40$ ;No, don't update LSI11 pointers MOV #PSWLSI+,R3 ;Point to LSI PS reference table MOV #LSIMOD+,R0 ;Point to LSI modification list .IFF ;EQ RTE$M MOV #PSWRTE+,R3 ;Point to RTEM PS reference table MOV #RTEMOD+,R0 ;Point to RTEM modification list .ENDC ;EQ RTE$M MOV (R0)+,R2 ;Get mask for loading and relocating .IF EQ CMP @#MEMTOP,# ;Is there an MSV11 here? BLOS 10$ ;No, I/O page starts at 160000 MOV @#MEMTOP,MSV11 ;Yes, I/O page starts above 28K .ENDC ;EQ 10$: MOV (R0)+,R1 ;Yes, get address of PS reference(s) ADD R4,R1 ;Offset the pointer 20$: MOV (R0)+,(R1)+ ;Modify the code ASR R2 ;Do more or do another group? .IF NE RTE$M BCC 30$ ;If CC, no more this block ADD @#$RTELK,@R0 ;Second word, if any, gets 'linked' MOV @(R0)+,(R1)+ ;Use real address of linkage routine ASR R2 ;Check for another word to do 30$: .ENDC ;NE RTE$M BCS 20$ ;More in this block BNE 10$ ;Do another block .IF NE RTE$M MOV (R0)+,R2 ;At end of code modification list? BNE 10$ ;If NE, no MOV #,R0 ;R0 -> past $INTN/$FORQ entries in DRVTBL MOV SYHTOP-,R1 ;R1->past $INTN/$FORQ ptrs in SY hdlr MOV #<$RMON>,R2 ;R2 -> RMON ADD R4,R2 ;Relocate RMON pointer ADD R4,R0 ;Relocate DRVTBL pointer MOV -(R0),-(R1) ;Setup system handler $FORQ pointer SUB R2,@R0 ;DRVTBL entry = $FORQ - $RMON (USR adjusts it) MOV @R0,O$FORK(R2) ;FORK fixed offset = $FORQ - $RMON MOV -(R0),-(R1) ;Setup system handler $INTN pointer SUB R2,@R0 ;DRVTBL entry = $INTN - $RMON (USR adjusts it) .ENDC ;NE RTE$M ;+ ; Fix references to the PS in the monitor ;- 40$: .IF NE MTT$Y .WEAK PSWMTI MOV #PSWMTI,R0 ;R0 -> PS reference chain in MTTINT BNE 50$ ;If defined, it links to PS reference ; chain in RMON .ENDC ;NE MTT$Y MOV #PSWLST,R0 ;R0 -> PS reference chain in RMON 50$: ADD R4,R0 ;Relocate the address of the reference MOV (R0)+,R2 ;Get address of next reference MOV @R0,R1 ;Get type of reference: <0 => unusual .IF NE RTE$M BLT 60$ ;Reference is special (two words only) CLR R1 ;Clear reference type, its SPL 7 MOV PSWNOP,2(R0) ;NOP third word of reference 60$: ADD R3,R1 ;Get special reference type from table MOV PSWVR2-PSWRTE(R1),@R0 ;Get table offset to subroutine address ADD @#$RTELK,@R0 ;Add linkage table address to offset MOV @(R0)+,-(R0) ;Store absolute pointer to linkage routine MOV @R1,-(R0) ;Set up referencing instruction .IFF ;NE RTE$M BGT 70$ ;Reference is of the form SPL n, n <> 0 ADD R3,R1 ;Get special reference type from table MOV PSWPD2-PSWPDP(R1),@R0 ;Set PS if non-LSI, NOP if LSI MOV @R1,-(R0) ;Set up referencing instruction BR 80$ ;Do more 70$: MOV PSWPD2-PSWPDP(R3),2(R0) ;Set PS if non-LSI, NOP if LSI MOV @R3,-(R0) ;Set up referencing instruction .ENDC ;NE RTE$M 80$: MOV R2,R0 ;Point to next reference BNE 50$ ;Do more .BR RELMON ;+ ; RELMON - Relocate monitor constants by load relocation bias ;- RELMON: MOV #RELLST+,R0 ;Point to relocation list MOV (R0)+,R1 ;Get special monitor locations 90$: ADD R4,R1 ;Bias the pointer ADD R4,@R1 ;Now relocate the word in the RMON MOV (R0)+,R1 ;Get the next pointer BNE 90$ ;Loop if more RELVEC: MOV (R0)+,R1 ;Now point to the word pair to load and ... ; ... lowbit = 1 means relocate to monitor! 100$: MOV (R0)+,-(SP) ;Push value to load onto stack ROR R1 ;Is monitor relocation required? BCC 110$ ;Branch if not ADD R4,@SP ;Add in monitor relocation bias 110$: ASL R1 ;Restore nice even pointer! MOV (SP)+,(R1)+ ;Load a pair ... MOV (R0)+,(R1)+ ; ... of locations MOV (R0)+,R1 ;Get next location to load BNE 100$ ;If more, continue loading and relocating RETURN ............ CORUPT: MOV #VECHI+,R0 ;Point to relocation list CALL RELVEC ;Relocate vectors above 120 ;+ ; Set up startup commands. ;- MOV #,R1 ;R1 -> Chain buffer (ASCIZ command area) MOV R1,R2 ;R2 -> Chain buffer ;;; MOV #LDSTRT+,R0 ;Point to LD CLEAN string 120$: MOVB (R0)+,(R1)+ ;Move it into the chain area BNE 120$ ;Branch till done DEC R1 ;Reposition the pointer CMPB #<' >,@R0 ;NULL extension? BNE 130$ ;No, continue moving into chain area INC R0 ;Yes, reposition the pointer 130$: MOVB (R0)+,(R1)+ ;Move into chain area part II BNE 130$ ;Branch till done DEC R1 ;Reposition the pointer 140$: TST (PC)+ ;Should startup file be stored? ..NIND:: .WORD STAR$T ;**PATCH** Zero to disable startup command file BEQ 160$ ;Don't include startup file 150$: MOVB (R0)+,(R1)+ ;Move @file into buffer (also ... ; ... if LD CLEAN is stored) BNE 150$ ;Branch till done 160$: SUB R2,R1 ;Get the command string byte count ... MOV R1,-(R2) ; ... and store in location 510 RETURN .DSABL LSB ;+ ; XMREL - Relocate extended memory allocation table address. Upon ; returning, R1 => 2nd word of the table ;- .IF NE MMG$T XMREL:: MOV #<$XMPTR>,R1 ;Get addr of free mem table (2nd word) ADD R4,R1 ;Relocated, of course RETURN ;Back to caller .ENDC ;NE MMG$T .SBTTL Miscellaneous Overlaid Data (in overlay RELLST) .BYTE 4 ;Crash code for insufficient memory NOCORE: .ASCIZ "Insufficient memory" .EVEN RELEND:: .ASSUME < RELEND - RELLST > LE < 2 * BK.BYT > ;Overlay must be at most 2 blks . = < < . + BD.BLK > / BK.BYT > * BK.BYT ;Adjust loc counter to block boundary .IF EQ ;If not RTEM and not VENUS console .SBTTL Overlay KT11RG - Set Up KT11 Registers, Enable Memory Mapping ;+ ; KT11RG - Set up memory management registers, size and write good parity. ; ; Memory management registers are set up. Memory management is left ; enabled only for XM systems. For systems with memory management, ; total system RAM is sized. All systems have all available RAM ; rewritten so as to have good parity. ; ; If the processor has 22 bit addressing it is enabled. ; ; Due to size constraints KT11RG is an overlay which is read into memory ; starting at BUFFB. Thus make sure non-PIC references are relocated ; correctly. ;- .ENABL LSB .ASSUME < . & BD.BLK > EQ 0 ;Overlay must start on a block boundary KT11RG::CALL @#T4SEC ;Set the carry on traps to 4 & 10. MOV @#MEMSIZ,@#TOTMEM ;Assume that we have a non-XM system without ; ... a KT-11 in case we can't size via KT-11 MOV R4,-(SP) ;Save memory size for FB TST @#MMR0 ;Do we have a KT-11? T11NOP ;Delay for T-11 BCS 30$ ;Branch if not BIS #,@#MMR3 ;Try to turn on 22 bit addressing. .IF NE PRO$S TST @#PROFLG ;Is this a PRO300 series processor? BEQ 10$ ;No, keep checking CLR R0 ;Guarantee no sign extension BISB @#PROMSZ,R0 ;Get # of 16KW blocks of memory SWAB R0 ;Shift left 9 bits to ... ASL R0 ; ... get # of 32-word blocks of memory SUB #,R0 ;Don't use last 1KW; preserve config table MOV R0,CHKLIM ;Mark the upper bound .ENDC ;NE PRO$S ;+ ; Initialize Memory Management. ;- 10$: MOV #,@#PS ;Go to kernel mode, set previous = user MOV #,R3 ;R3->KERNEL I - Space addr register 0 (PAR 0) MOV #,R1 ;R1->KERNEL I - Space descriptor reg 0 (PDR 0) MOV #,R2 ;R2->USER I - Space address register 0 (PAR 0) MOV #,R0 ;R0->USER I - Space descriptor reg 0 (PDR 0) MOV #<7.>,R4 ;R4 = counter CLR R5 ;Start at 0 20$: MOV R5,(R3)+ ;Set KERNEL PAR ... MOV R5,(R2)+ ; ... and USER PAR MOV #,@R1 ;Set KERNEL PDR (4K, no system trap/abort ... MOV (R1)+,(R0)+ ; ... action) and USER PDR ADD #,R5 ;Bump to next 4K SOB R4,20$ ;Loop until all 7 sets done. MOV #,@R3 ;Make KERNEL PAR7 -> I/O page MOV @R3,@R2 ;Same for USER PAR7 MOV #,@R1 ;Set KERNEL PDR (4K, no system trap/abort ... MOV @R1,@R0 ; ... action, bypass cache) and USER PDR INC @#MMR0 ;Turn on the KT-11 ;+ ; Now size memory into 32 word blocks ;- MOV #,R0 ;R0 -> beginning of PAR6 CLR -(R3) ;Set up PAR6 to physical location 0 (C=0) BR 70$ ;Skip wrap-around check ;+ ; Wraparound check for non-KT11 systems ;- 30$: CLR R0 ;Begin at loc. 0 (C=0) 40$: MOV @R0,R1 ;Rewrite the memory MOV R1,(R0)+ ; with good parity T11NOP ;If second instr. traps then first did too BCS 50$ ;C-bit is set if memory is non-existent or ROM CMP R4,R0 ;Done clearing? BHI 40$ ;No, continue clearing (BHI -> C=0) 50$: BR 90$ ;Done initializing parity memory 60$: MOV #,R0 ;R0 -> beginning of PAR6 CLR R4 ;R4 -> location 0 MOV @R4,R1 ;Save physical location 0 MOV @R0,R2 ;Save original contents of first word in PAR6 COM @R0 ;Complement first word in PAR6 MOV @R4,R5 ;Save physical location 0 again MOV @R0,R4 ;Save modified contents of first word in PAR6 COM R4 ; and attempt to change it back to original MOV R2,@R0 ;Restore original contents of 1st word in PAR6 CMP R2,R4 ;Did we hit non-RAM? BNE 80$ ;Branch if yes CMP R1,R5 ;Did memory wrap to physical location 0? BNE 80$ ;Branch if so ; CMP setting Z=1 implies C=0 70$: MOV @R0,R1 ;Rewrite the memory MOV R1,(R0)+ ; with good parity T11NOP ;If second instr. traps then first did too BCS 80$ ;C-bit is set if memory is non-existent or ROM CMP #,R0 ;Done clearing? BHI 70$ ;No, continue clearing (BHI -> C=0) & ... ADD #,@R3 ; ... adjust map register (in 32. wd blks) CMP @R3,(PC)+ ;End of memory? CHKLIM: .WORD PARCIO ;Assume 22-bit system BLO 60$ ;No, there is more - branch ;+ ; Memory size found ;- 80$: MOV @R3,R2 ;Store memory size (/32 words) in R2 MOV R2,@#TOTMEM ;Save total memory size in 32 word blocks MOV #,@R3 ;Restore PAR6 90$: MOV (SP)+,R4 ;Restore memory size for FB TST @#MMR0 ;Do we have a KT-11? T11NOP ;Delay for T-11 BCS 130$ ;Branch if not .IF NE MMG$T MOV #,R4 ;Assume that low memory is a full 28K CMP R2,R4 ;Is memory at least 28K? BHIS 100$ ;Branch if yes MOV R2,R4 ;Shorten low memory size to total size 100$: MOV R2,@#MEMSIZ ;Save extended memory size ... ; ... in 32 word blocks ;+ ; Now convert R4 to contain the number of bytes of low memory ; (Sign bit of R4 must be 0 because high value of R4 is 001600) ;- ASR R4 ;Convert to # of bytes by shifting left 6 ... ASR R4 ; ... (sneakily by shifting right 2 ... SWAB R4 ; ... then swap bytes) MOV R4,@#MEMTOP ;Save top of low memory for XM ;I&D+ MOV #,@#KISAR1 ;Map kernel PAR1 to MCA MOV #,R0 ;R0 = total size of MCA region MOV #,R1 ;R1 -> beginning of MCA region 101$: CLR (R1)+ ;Clear a word SOB R0,101$ ;Continue until entire region is cleared MOV #,@#KISAR1 ;Remap kernel PAR1 ;I&D- .ENDC ;NE MMG$T .IF NE PRO$S ;+ ; Build low memory table for PRO ;- TST @#PROFLG ;Is this a PRO300 series processor? BEQ 120$ ;No, don't build table CLR R0 ;Prepare to find configuration table BISB @#PROMSZ,R0 ;Get 32KB top of system RAM boundary SWAB R0 ;Convert to ... ASL R0 ; ... PAR value ... SUB #,R0 ; ... of last 4KW page MOV R0,@#KISAR1 ;Map to it through kernel PAR1 MOV #,R0 ;Point to # of option slots MOV #<-1>,-(R4) ;Terminate low memory table .ASSUME SLOT0 EQ CTI-4 MOV @R0,R1 ;R1 = # of option slots MOV R1,R3 ;R3 = # of option slots ASL R3 ;4 bytes per ... ASL R3 ; ... option slot entry (id and status) SUB R3,R0 ;R0 -> last option slot device id 110$: MOV (R0)+,-(R4) ;Copy device id # into low memory table TST (R0)+ ;Skip over status word SOB R1,110$ ;Continue copying device id numbers MOV #,@#KISAR1 ;Remap kernel PAR1 120$: .ENDC ;NE PRO$S .IF EQ MMG$T CLR @#MMR0 ;Turn off memory management CLR @#MMR3 ;Turn off 22-bit addressing .ENDC ;EQ MMG$T 130$: .IF NE MMG$T TST @#UBBLK ;Are we using UB? BEQ 160$ ;If not, branch CMP @#TOTMEM,# ;Do we have enough memory (>256.KB)? BLOS 150$ ;If not, branch MOV #,R0 ;R0 -> Start of UNIBUS mapping registers - 2 140$: ADD #<2>,R0 ;R -> Next Unibus mapping register TST @R0 ;Does CSR exist? T11NOP ;Delay for T11 BCS 150$ ;If C-bit set, status register not there CMP R0,# ;Are we at the end of the UMR registers? BLO 140$ ;If not, branch CMP (PC)+,(PC)+ ;Skip over next instruction 150$: CLR @#UBBLK ;Say no UB 160$: .ENDC ;NE MMG$T RETURN ;Restore vectors at 4 and 10 and return .DSABL LSB KT11ND:: .ASSUME < KT11ND - KT11RG > LE < 2 * BK.BYT > ;Overlay must be at most 2 blks . = < < . + BD.BLK > / BK.BYT > * BK.BYT ;Adjust loc counter to block boundary .ENDC ;EQ .SBTTL Overlay CLNUP - Clean up before starting the system ;+ ; Do not destroy R4 ; ; CLNUP is read in at B$BOOT ;- .ASSUME < . & BD.BLK > EQ 0 ;Overlay must start on a block boundary CLNUP:: .IF EQ MTT$Y MOV #V.TKB,R1 ;Get TT input interrupt vector CALL @#PROTEC ;Protect it MOV #V.TPS,R1 ;Get TT output interrupt vector CALL @#PROTEC ;Protect it .IFF ;EQ MTT$Y ;.IF NE MTT$Y .SBTTL RELTCB - Relocate TCB Pointers (in overlay CLNUP) ;+ ; RELTCB - This routine relocates the list of pointers to the TCB's. Upon ; completion, the pointers within each TCB is relocated. ; ; Uses: R0, R1, R2, R3, R5 ;- .ENABL LSB RELTCB: MOV #/2,R5 ;Get count of TCB pointers MOV #,R0 ;Point to TCB pointers ... ADD R4,R0 ; ... and relocate it 10$: TST (R0)+ ;Is the pointer zero? BEQ 20$ ;Yes, no pointer here ADD R4,-2(R0) ;Relocate a TCB pointer 20$: SOB R5,10$ ;Loop until no more. ;+ ; See if the device exists and if so is the device installed. ;- .IF NE RTE$M MOV @#$RTELK,R1 ;Point to memory linkage table MOV .$TKS(R1),-(SP) ;Stack address of pseudo TKS .ENDC ;NE RTE$M MOV #,-(SP) ;Initialize TCB counter ADD #,R0 ;Point to first TCB 30$: .IF NE RTE$M MOV 2(SP),T.CSR(R0) .ENDC ;NE RTE$M MOV T.VEC(R0),R1 ;Get the hardware vector address MOV T.CSR(R0),R2 ;Get the CSR address .IF EQ RTE$M BEQ. 90$ ;None, skip this TCB CMP R2,MEMTOP+ ;Is CSR in real memory? (If MSV11) BLO 40$ ;Yes, not in I/O page, it's not here CALL T4SEC+ ;Set carry in case we trap TST @R2 ;Is the device present? ;;; T11NOP ;Stall not needed for next instruction CALL @(SP)+ ;Restore the vectors at 4 and 10 BCC 50$ ;If C-bit cleared the device is installed 40$: CLR T.CSR(R0) ;If set, no hardware. Clear CSR location BR. 90$ ;Go on to next TCB ; Hardware exists, relocate the pointers within the TCB 50$: .IF NE DZ11$N BIT #,T.STAT(R0) ;Is this TCB for a DZ? BEQ 58$ ;Nope... TSTB T.PUN(R0) ;First line on this controller? BNE 58$ ;Nope... MOV T.PRI(R0),R3 ;R3 = Controller number (priority) BIC #^C<3>,R3 ;All but low two bits ASL R3 ;Make index into CSR table ADD R4,R3 ;Relocate the index MOV T.CSR(R0),DZCSR(R3) ;Move CSR to DZ CSR table 58$: .ENDC ;NE DZ11$N .ENDC ;EQ RTE$M MOV R0,R3 ;Copy TCB pointer ADD #,R3 ;Point to the input ring buffer pointer ADD R4,(R3)+ ;Relocate T.IRNG ADD R4,(R3)+ ;Relocate TST (R3)+ ;Skip the character count (T.ICTR) ADD R4,(R3)+ ;Relocate T.IGET ADD R4,(R3)+ ;Relocate T.ITOP ADD #,R3 ;Skip over input ring buffer ADD R4,(R3)+ ;Relocate T.OPUT TST (R3)+ ;Skip the output character count (T.OCTR) ADD R4,(R3)+ ;Relocate T.OGET ADD R4,(R3)+ ;Relocate T.OTOP ; Protect and initialize interrupt vectors .IF NE TSTB T.PUN(R0) ;First unit on a controller? BNE 60$ ;No, no need to protect (always 0 for DL's) .ENDC ;NE CALL PROTEC+ ;Protect the input vector MOV @#V.DL11,(R1)+ ;Copy DL input interrupt address MOV R1,R5 ;Save pointer to input PS MOV T.PRI(R0),(R1)+ ;Set the priority in the new PS CALL PROTEC+ ;Protect the output interrupt address MOV @#V.DL11+4,(R1)+ ;Copy DL output interrupt address MOV @R5,@R1 ;Set the same priority in the output new .IF NE BIT #,T.STAT(R0) ;Is this TCB for a DZ or DH? BEQ 70$ ;Neither, must be a DL... .IF NE DZ11$N .IF NE DH11$N BIT #,T.STAT(R0) ;Is it for a DZ? BEQ 55$ ;No, must be DH... .ENDC ;NE DH11$N ADD #,-(R5) ;Fix the input interrupt address ADD #,-(R1) ;Fix the output interrupt address MOV #,@R2 ;Enable interrupts on DZ11 .IF NE DH11$N BR 60$ .ENDC ;NE DH11$N .ENDC ;NE DZ11$N .IF NE DH11$N 55$: ADD #,-(R5) ;Fix input ADD #,-(R1) ; and output interrupt addresses .ENDC ;NE DH11$N ; Set characteristics for this line 60$: .IF NE DZ11$N .IF NE DH11$N BIT #,T.STAT(R0) ;This TCB for a DZ? BEQ 65$ ;Nope, must be a DH... .ENDC ;NE DH11$N MOV @R0,R1 ;Get the terminal configuration word BIC #^C,R1 ;Extract initial line speed (in high byte) BISB T.CNF2(R0),R1 ;Set low byte with low byte of config 2 ASLB R1 ;Shift to line ... ASLB R1 ; ... parameter ... ASLB R1 ; ... setting BISB T.PUN(R0),R1 ;Add physical unit # to current line par BIS #,R1 ;Set receiver clock on and 8 level code MOV R1,DZ.LPR(R2) ;Set line parameters. .IF NE DH11$N BR 68$ .ENDC ;NE DH11$N .ENDC ;NE DZ11$N .IF NE DH11$N 65$: MOV T.CNF2(R0),R1 ;R1 = Terminal configuration word 2 ; xxxxxxxx/xxxOPSDD ADD #,R1 ;Toggle the parity odd/even bit ; xxxxxxxx/xx?EPSDD BIC #^C,R1 ;Discard unimportant bits ; xxxxxxxx/xxxEPSDD SWAB R1 ; xxxEPSDD/xxxxxxxx ASR R1 ; xxxxEPSD/Dxxxxxxx ASR R1 ; xxxxxEPS/DDxxxxxx ASR R1 ; xxxxxxEP/SDDxxxxx ROLB R1 ; xxxxxxEP/DDxxxxx? Carry= S ROL -(SP) ; xxxxxxEP/DDxxxxx? (SP) = S ASR R1 ; xxxxxxxE/PDDxxxxx (SP) = S ASR R1 ; xxxxxxxx/EPDDxxxx (SP) = S ROR (SP)+ ; xxxxxxxx/EPDDxxxx Carry= S RORB R1 ; xxxxxxxx/SEPDDxxx MOV R1,-(SP) ;Save line parameter bits .Assume T.CNFG EQ 0 MOV @R0,R1 ;R1 = Terminal configuration word 1 BIC #^C,R1 ;Strip to line speed CMP R1,#DHSPSK ;Compare to DH skew speed BLT 652$ ; if < DZ 3600 baud, use it BGT 651$ ; if > DZ 3600 baud, skew it MOV #<7400+400>,R1 ; if = DZ 3600 baud, replace it ; (with DH code for 38.4kb) 651$: SUB #400,R1 ;Skew the code for DH speeds 652$: BIS R1,@SP ;Merge with parameter bits .REPT 4 ;Match transmit speed to receive ASL R1 .ENDR BIS (SP)+,R1 ;Merge in receive and parameter bits ;+ ; ; *** Begin Kluge *** ; The following kluge is due to the fact that adjacent odd/even ; channels on DH interfaces must operate at baud rates from the ; same group. ; ; If the user SYSGENs an odd number of lines for a given controller, ; the last line used on that controller will be an even-numbered ; channel. If the speed to which it is initialized is from a group ; different from the default speed (which the odd channel will have ; automatically initialized with), the even channel will operate ; unpredictably. ; ; The following code forces the odd channel of a given pair to the ; same settings as the even channel, since the settings will be ; over-ridden if the channel has been selected. ; MOVB T.PUN(R0),-(SP) ;Get the channel number BIS #1,@SP ; select the ODD channel of the pair ;;; .Assume DH.CSR EQ 0 MOVB (SP)+,@R2 ;Now select it on the DH MOV R1,DH.LPR(R2) ; set the line parameter register 6525$: ; ;- *** End Kluge *** MOVB T.PUN(R0),@R2 ;Select the DH line MOV R1,DH.LPR(R2) ;Set the DH Line parameter register MOV #,R1 ;R1 = Receiver enable .IF NE DHMD$M .Assume T.CNFG EQ 0 BIT #,@R0 ;Is line to be remote? BEQ 653$ ;Nope... MOV #,R1 ;Yes, configure DH line for modem 653$: .ENDC ;NE DHMD$M MOV R1,DH.LCR(R2) ;Set line control register ;;; .Assume DH.CSR EQ 0 MOV #,@R2 ;Enable interrupts .ENDC ;NE DH11$N 68$: BR 90$ ;** BR Chain ** .ENDC ;NE ; Start the DL line 70$: .IF NE RTE$M TST R2 ;Is this the console CSR under RTEM-11 BEQ 90$ ;Branch if not, don't POKE it CLR 2(SP) ;Zap fake CSR address for other than the ; console terminal under RTEM-11. .ENDC ;NE RTE$M .IF NE PRO$S TST PROFLG+ ;Is this PRO300 series machine? BNE 80$ ;Branch if yes .ENDC ;NE PRO$S MOV #,@R2 ;Enable receiver interrupts 80$: .IF NE DLMD$M ;If DL11 modem control BIT #,@R0 ;Is it a remote terminal? BEQ 90$ ;No, don't enable BIS #,@R2 ;Yes, set dataset interrupt enable .ENDC ;NE DLMD$M 90$: ADD #,R0 ;Bump pointer to next TCB DEC @SP ;Count down the unit number BNE. 30$ ;Not done yet .IF NE RTE$M BIT (SP)+,(SP)+ ;Clean up stack .IFF ;NE RTE$M MOV (SP)+,R0 ;Pop the stack .ENDC ;NE RTE$M .ENDC ;NE MTT$Y .IF EQ ;If not RTEM and not VENUS console TST FALCON+ ;Are we flying with a FALCON? BEQ 100$ ;Branch if we are not MOV #,R1 ;Point to FALCON break vector + 4 MOV #,-(R1) ;Set up with PS of kernel mode and PRIO 7 MOV #<170000>,-(R1) ;And point to MACRO ODT code CALL PROTEC+ ;Protect the vector from marauders 100$: .ENDC ;EQ .IF NE PRO$S TST PROFLG+ ;Are we on PRO300 series machine? BEQ 120$ ;Branch if not MOV MONBLK+,R0 ;Get blk # of start of monitor file ADD #,R0 ;Compute block number for rel table MOV #/2,R1 ;Get number of words to read MOV #>,R2 ;Read into last quarter of BUFFB CALL B.RDER+ ;Do the read (check for error) CALL GTPIHD+ ;Read PI install code into BUFFB MOV $ENTRY+PI.NUM(R4),R3 ;Get PI entry point for install code MOV #,R5 ;Point to PI install code at ... CALL SAVRG1+ ; ... system entry point and call it BCC 110$ ;Branch on success CALLR BADINS+ ;Else print fatal error ............ 110$: CALL PROTEC+ ;VD end-of-frame interrupt vector ADD #<4>,R1 ;Get VD end-of-transfer ... CALL PROTEC+ ; ... interrupt vector MOV #<200>,R1 ;This is temporarily here for ... CALL PROTEC+ ; ... KB receiver vector MOV #<204>,R1 ;This is temporarily here for... CALL PROTEC+ ; ... KB transmitter vector MOV #<230>,R1 ;This is temporarily here for... CALL PROTEC+ ; ... clock vector .IF NE MTT$Y TST @#KBDBUF ;Tweak interrupt controller 0 MOV #<31>,@#ICSR0 ;Turn on KB output interrupts .ENDC ;EQ MTT$Y BR 150$ ............ .ENDC ;NE PRO$S 120$: .IF EQ VENU$C MOV #,R1 ;Get CONFIG bits for clock and status BIC BCNFG+,R1 ;Clear status bits BNE 150$ ;If bits exist don't turn on clock MOV #<1>,@#LKPB ;Turn clock on (set P interval count) MOV #,@#LKCS ;Set proper bits (L or P clock) in CSR .BR 150$ ............ .IFF ;EQ VENU$C ;+ ; TOY (Time of Year) Clock Initialization ; ; This code initializes the TOY clock and the VAX interval time. ;- MOV @#LKVEC,@#V.TOY ;Set the TOY clock interrupt vector MOV @#LKVEC+2,@#V.TOY+2 ; MOV #,R1 ;Protect the TOY clock vector CALL PROTEC+ ; MOV #,R0 ;R0 -> TWCR MOV #,R1 ;R1 -> TRDR MOV R1,R2 ;R2 -> TRDR MOVB #,@R0 ;Select Counter 3 Mode Register CMPB #,(R2)+ ;Is the clock dead? (R2 now -> TRDR+1) BEQ 130$ ;No, alive and well CMPB #,@R2 ;Is the clock dead? (R2 -> TRDR+1) BEQ 130$ ;No, alive and well MOVB #,@R0 ;Select Master Mode Register CMPB #,@R1 ;Is low byte right? BNE 130$ ;No CMPB #,@R2 ;Is high byte right? BNE 130$ ;No MOVB #,@R0 ;Select Counter 3 Mode Register CMPB #,@R1 ;Is low byte right? BNE 130$ ;No CMPB #,@R2 ;Is high byte right? BNE 130$ ;No MOVB #,@R0 ;Select Counter 4 Mode Register CMPB #,@R1 ;Is low byte right? BNE 130$ ;No CMPB #,@R2 ;Is high byte right? BNE 130$ ;No MOVB #,@R0 ;Select G3 load register TSTB @R1 ;Is low byte clear? BNE 130$ ;No TSTB @R2 ;Is high byte clear? BNE 130$ ;No MOVB #,@R0 ;Select G4 load register TSTB @R1 ;Is low byte clear? BNE 130$ ;No TSTB @R1 ;Is high byte clear? BEQ 140$ ;Yes ;+ ; TOY Clock is dead or setup incorrectly, start from ground 0 ;- 130$: MOV #,R3 ;R3 -> TWDR MOV R3,R5 ;R5 -> TWDR MOVB #,@R0 ;Re-init it completely MOVB #,@R0 ;Select Master Mode Register MOVB #,(R5)+ ; init lo byte (now R5 -> TWDR+1) MOVB #,@R5 ; and hi byte MOVB #,@R0 ;Stop counters 3 and 4 MOVB #,@R0 ;Select Counter 3 Mode Register MOVB #,@R3 ; and init Group 3 modes (lo byte) MOVB #,@R5 ; " (hi byte) MOVB #,@R0 ;Select Counter 4 Mode Register MOVB #,@R3 ; and init Group 4 modes (lo byte) MOVB #,@R5 ; " (hi byte) MOVB #,@R0 ;Select G3 load register CLRB @R3 ; clear it (lo byte) CLRB @R5 ; " (hi byte) MOVB #,@R0 ;Select G4 load register CLRB @R3 ; clear it (lo byte) CLRB @R5 ; " (hi byte) MOVB #,@R0 ;Load 3 and 4 (NOT armed yet) 140$: BISB #,@#MCSR0 ;Allow the TOY to interrupt .ENDC ;EQ VENU$C 150$: RETURN .DSABL LSB CLNEND:: .ASSUME LE ;Overlay must be at most B$END-B$BOOT . = < < . + BD.BLK > / BK.BYT > * BK.BYT ;Adjust loc counter to block boundary .SBTTL Overlay LDTABL - Load monitor, PI, UB tables overlay ;+ ; The stack on entry to LDTABL: ; ; ----------------- ; | subr rtn addr | top of stack ; ----------------- ; |KMON or USR blk#| ; ------------------------- ; SY | block number | ; ----------------- ; | handler size | ; ----------------- ; | device size | ; ----------------- ; | handler status| ; ------------------------ ; PI | block number | ; or ----------------- ; UB | handler size | ; ----------------- ; | device size | ; ----------------- ; | handler status| ; ----------------- ; ; On entry: ; R3 = USR block number ; R4 = RMON bias - Do NOT modify R4 ; ; On exit: ; Top of the stack contains the address of LOCATE in the USR ; R0, R1, R5 destroyed ; ; LDTABL is read in at B$BOOT ;- .ENABL LSB .ASSUME < . & BD.BLK > EQ 0 ;Overlay must start on block boundary LDTABL::MOV (SP)+,(PC)+ ;Save return address SAVRET: .WORD 0 ;Return address for LDTABL routine MOV (SP)+,R0 ;R0 = KMON or USR block number MOV (SP)+,$DVREC+2(R4) ;Store the SY handler block number MOV (SP)+,$HSIZE+2(R4) ;Store the system device handler size MOV @#B$DEVS,$PNAME+2(R4) ;Store the system device name in PNAME .IF NE UNI$64 MOV @#B$DEVS,$PNAM2+2(R4) ;Store the system device name in PNAM2 MOV @#SY64,R1 ;Get the one-letter system device name BEQ 10$ ;Branch if not 64-unit handler MOV R1,$PNAM2+2(R4) ;Store the 1-letter system device name .IF NE OWN$ER MOV #,$OWNER+4(R4) ;Flag as 64-unit handler .ENDC ;NE OWN$ER 10$: .ENDC ;NE UNI$64 MOV @#B$SUFF,HSUFFX(R4) ;Load the suffix into RMON .IF NE MMG$T MOV @SP,$SYSCH+4(R4) ;Store system device size if XM .ENDC ;NE MMG$T MOV @SP,$DVSIZ+2(R4) ;Store system device size in table MOV (SP)+,SYDVSZ(R4) ;Store system device size into RMON MOV (SP)+,$STAT+2(R4) ;Store system dev status word in $STAT .IF NE PRO$S TST @#PROFLG ;Are we on a PRO300 series machine? BEQ 30$ ;Branch if not MOV @#G$VEC,R1 ;Get PI entry point (it's relocated) SUB #<8.>,R1 ; (R1 -> PILQE) MOV R1,$ENTRY+PI.NUM(R4) ;Save PI entry point SUB #,R1 ;R1 -> PISTRT (start of PI handler) MOV (SP)+,$DVREC+PI.NUM(R4) ;Save block number of PI ADD @SP,R1 ;R1 -> PIEND MOV (SP)+,$HSIZE+PI.NUM(R4) ;Save PI handler size (in bytes) MOV (SP)+,$DVSIZ+PI.NUM(R4) ;Save PI device size MOV (SP)+,$STAT+PI.NUM(R4) ;Save PI status word MOV #PILST+,R5 ;R5 -> PI monitor pointers 20$: MOV (R5)+,-(R1) ;Set up pointer ADD R4,@R1 ;Relocate it TST @R5 ;More? BNE 20$ ;Yes, do it BR 40$ ;Rejoin common processing ............ 30$: TST # ;Have we sysgened a slot for PI? BEQ 40$ ;Branch if we haven't CLR $PNAME+PI.NUM(R4) ;Free up PI slot for another handler .IF NE UNI$64 CLR $PNAM2+PI.NUM(R4) ;Free up PI slot for another handler .ENDC ;NE UNI$64 40$: .ENDC ;NE PRO$S .IF NE MMG$T TST @#UBBLK ;Are we using UB? BEQ 60$ ;If not, branch MOV @#STRTUB,R1 ;Get UB start (UBSTRT) ADD #,R1 ;R1 -> UBLQE MOV R1,$ENTRY+UB.NUM(R4) ;Save UB entry point (UBLQE) MOV (SP)+,$DVREC+UB.NUM(R4) ;Save block number of UB MOV @#STRTUB,R1 ;Get UB start (UBSTRT) ADD @SP,R1 ;R1 -> UBEND MOV (SP)+,$HSIZE+UB.NUM(R4) ;Save UB handler size (in bytes) MOV (SP)+,$DVSIZ+UB.NUM(R4) ;Save UB device size MOV (SP)+,$STAT+UB.NUM(R4) ;Save UB status word MOV #UBLST+,R5 ;R5 -> UB monitor pointers 50$: MOV (R5)+,-(R1) ;Set up pointer ADD R4,@R1 ;Relocate it TST @R5 ;More? BNE 50$ ;Yes, do it BR 70$ ;Merge below ............ 60$: TST # ;Have we SYSGEN'ed a slot for UB? BEQ 70$ ;Branch if not CLR $PNAME+UB.NUM(R4) ;Free up UB slot for another handler .IF NE UNI$64 CLR $PNAM2+UB.NUM(R4) ;Free up UB slot for another handler .ENDC ;NE UNI$64 70$: .ENDC ;NE MMG$T MOV #,-(SP) ;Stack pointer to USR reloc. routine CMP R0,R3 ;Did we read the KMON? BNE 80$ ;Yes, it really is in memory CLR KMLOC(R4) ;No, indicate no KMON in memory CLR KMONIN(R4) ;Exit to RMON will read it in MOV #,@SP ;Don't relocate KMON stuff 80$: ADD R4,@SP ;Relocate the address in the USR MOV @#SWPBLK,$SWPBL(R4) ;R4 = Reloc. bias. Set up swap blocks MOV R3,$MONBL(R4) ;Store USR block number MOV #,-(SP) ;Set a PS of priority 7 CALL BRTI+ ;Go set up PR7 CALL @#FIXPSW+ ;Go fix monitor PS references ; and relocate some monitor pointers CALLR @SAVRET ;Return to caller ............ .IF NE PRO$S PILST: .WORD $FORK .WORD $INTEN .IF NE MMG$T .WORD $OSPTW ;Q.PAR version of $PUTWR .WORD $OSPTB ;Q.PAR version of $PUTBY .WORD $OSGTB ;Q.PAR version of $GETBY .WORD $MPPHY .WORD $RELOC .ENDC ;NE MMG$T .WORD 0 ;End of PI handler pointer list .ENDC ;NE PRO$S .IF NE MMG$T ;+ ; UBLST is the same size as the table in UB. UB will NEVER have ; timer support (TIM$IT = 1) or error logging (ERL$G = 1) ;- UBLST: .WORD $FORK .WORD $INTEN .WORD $OSPTW ;Q.PAR version of $PUTWR .WORD $OSPTB ;Q.PAR version of $PUTBY .WORD $OSGTB ;Q.PAR version of $GETBY .WORD $MPPHY .WORD $RELOC .WORD 0 ;End of UB handler pointer list .ENDC ;NE MMG$T .DSABL LSB .SBTTL RLMON2 - Relocate more pointers (in overlay LDTABL) ;+ ; Relocate more RMON pointers and put some values into the RMON fixed area. ;- .ENABL LSB RLMON2: MOV (SP)+,(PC)+ ;Save return address SVRET1: .WORD 0 .IF NE MMG$T ;+ ; Because of size constraints, code to relocate address of XM ; free memory allocation table resides in bootstrap buffer (BUFFB) ;- CALL @#XMREL+ ;Call to relocate XM pointers MOV @#MEMSIZ,-(R1) ;Store memory size in mem. alloc table SUB 2(R1),@R1 ;Subtract out low 28K and MCA region BHIS 10$ ;Branch if we have at least 28K CLR @R1 ;We have no extended memory 10$: ADD #,R1 ;Point to RMON stack MOV R1,SP ;Switch to it! PUT #,SP ;Reset the USER mode stack to BOTSTK .ENDC ;NE MMG$T .IF NE RTE$M ;+ ; Relocate linkage table pointers into RMON ;- MOV #<$LINKB+2+>,R0 ;-> linkage table list 20$: ADD @#$RTELK,@R0 ;Add address of linkage table to offset ADD R4,-(R0) ;Relocate the pointer into RMON and ... MOV (R0)+,@(R0)+ ; ... move it up into the linkage table. TST (R0)+ ;End of list? BNE 20$ ;If NE, no .ENDC ;NE RTE$M ;+ ; Update values in RMON ;- MOV @#MEMSIZ,$MSIZ(R4) ;Store usable memory sz (in 32 word blks) MOV @#TOTMEM,$RAMSZ(R4) ;Store total memory size (in 32 word blks) BIS @#BCNFG,CONFIG(R4) ;Store hardware configuration word in ... BIS @#BCNFG2,CONFG2(R4) ; ... RMON as well as the extension word .IF EQ RTE$M CALL @#T4SEC ;Set carry if we trap CLR @#SDSDR0 ;Check if supervisor/I&D space hardware exists T11NOP ;Stall for late nonexistent memory trap BCS 2220$ ;Branch if no supervisor/I&D space hardware BIS #,CONFG3(R4) ;Set bit for supervisor/I&D space BR 22$ ;Continue for all monitors 2220$: .IF NE SUP$Y JSR R1,@#REPORT ;Invalid processor for ZB/ZM (11/34) .WORD INVPRO+ ;Fatal .ENDC ;NE SUP$Y 22$: .IF NE MPT$Y MOV @#FALCON,R3 ;Is this a FALCON? .IF NE PRO$S BIS @#PROFLG,R3 ; or a PRO? .ENDC ;NE PRO$S BNE 30$ ;Branch if so CLR @#CA.CSR ;Enable cache error interrupts if CSR exists ;;; T11NOP ;Stall not needed for next instruction: CALL .IFTF ;NE MPT$Y 30$: CALL @(SP)+ ;Restore traps .IFT ;NE MPT$Y ;+ ; Move the parity CSR table into RMON. ;- MOV #,R3 ;Point to parity CSR table in RMON ADD R4,R3 ;Relocate pointer .ENDC ;NE MPT$Y MOV #,R1 ;Point to same table in bootstrap 40$: MOV (R1)+,R0 ;Get next memory parity CSR address BEQ 50$ ;Branch if this one doesn't exist .IF NE MPT$Y MOV #,@R0 ;Enable parity and clear error bits .IFF ;NE MPT$Y CLR @R0 ;Disable parity and clear error bits .ENDC ;NE MPT$Y 50$: .IF NE MPT$Y MOV R0,(R3)+ ;Move the CSR into RMON .ENDC ;NE MPT$Y CMP R1,# ;Done? BLO 40$ ;No, loop .ENDC ;EQ RTE$M .IF NE KW11$P ;+ ; Protect KW11P vector ;- BISB @#PROBTS+<&3>,LOWMAP+(R4) .ENDC ;NE KW11$P .IF NE PRO$S TST @#PROFLG ;Running on a PRO300 series? BEQ 60$ ;Branch if not MOV @#G$VEC,GETVEC(R4) ;Patch in $GTVEC (needed here for SY:) BIC #,CONFIG(R4) ;Force clock to 60 hz on PRO300 series 60$: .ENDC ;NE PRO$S .IF NE > ;+ ; Set up the time constants if 50 Hz ;- HRTZ50::BIT #,CONFIG(R4) ;50 HERTZ clock? BEQ 70$ ;No, don't change number of ticks MOV #,GTM.HI(R4) ;Yes change number of ticks. Hi order MOV #,GTM.LO(R4) ;Double precision. Low order word 70$: .ENDC ;NE > ;+ ; Set date and time if booted from DUP ;- TST @#DUPFLG ;Booted from hardware or DUP? BNE 80$ ;Not equal => hardware. Don't pass date & time MOV #,R3 ;DUP - R3 points to passed time and date MOV (R3)+,$TIME+TIM.HI(R4) ;Move stored time ... MOV (R3)+,$TIME+TIM.LO(R4) ; ... to RMON .ASSUME B$DATE EQ B$TIME+4 MOV @R3,DATES(R4) ;Move in the date 80$: .IF NE MMG$T BISB @#PROBTS+<&3>,LOWMAP+(R4) ;Protect MMU TST #UB.NUM ;Was UB support sysgenned in? BEQ 90$ ;If not, branch BIS #CF3.US,CONFG3(R4) ;Yes, set bit in CONFG3 90$: .ENDC ;NE MMG$T .IF NE PWF$L TST @#KXJFLG ;Is this a KXJ? BEQ 100$ ;Branch if not MOV #NOP,FATAL(R4) ;Replace RESET at FATAL in RMON with NOP 100$: .ENDC ;NE PWF$L CALLR @SVRET1 ;Return to caller .IF NE SUP$Y .SBTTL Supervisor mode only error message .BYTE 14 ;Crash code for ZB/ZM invalid processor-11/34 INVPRO: .ASCIZ "Invalid processor for ZB/ZM monitor" .EVEN .ENDC ;NE SUP$Y .DSABL LSB LDTEND:: .ASSUME LE ;Ovly. must be at most B$END-B$BOOT . = < < . + BD.BLK > / BK.BYT > * BK.BYT ;Adjust loc counter to block boundary .SBTTL Overlay LDHNDL - Load and install PI, UB, SY ;+ ; Upon entering: ; R0 is block number on system device of start of handler .SYS file ; = block 0 ; R2 -> BUFFB which contains the handler header block ; R4 is top of low memory (first unused word) ; ; Output: ; R4 = new top of low memory ; ; LDHNDL is read in at B$BOOT ;- .ENABL LSB .ASSUME < . & BD.BLK > EQ 0 ;Overlay must start on block boundary LDHNDL::MOV H.SIZ(R2),R1 ;Get handler size in bytes .IF EQ TST H.UNIT(R2) ;Is handler sysgened for 64-unit support? BEQ 10$ ;Branch if not SUB #<32.>,R1 ;If so, chop off extended owner table 10$: .ENDC ;EQ .IF NE RTE$M MOV R1,-(SP) ;Save current size of handler ADD #,R1 ;Force handler length to be BIC #,R1 ; double-word bound for RP02/3's SUB R1,@SP ;@SP = Negative difference ADD (SP)+,@#SYHTOP ;Correct pointer to end of system handler .ENDC ;NE RTE$M MOV R4,R2 ;Copy memory top address for the input call SUB R1,R4 ;Compute new top of used low memory ADD #,R1 ;Include room for header block too! SUB R1,R2 ;Compute address to start reading handler BCC 20$ ;Branch if handler fits JMP 100$ ;Can't fit handler file in memory 20$: ;CLC ;C=0 from BCC ROR R1 ;Convert byte count to word count CMP R2,# ;Will it fit above this bootstrap? BHIS 30$ ;Branch if handler fits JMP 100$ ;Nope, can't fit handler above bootstrap 30$: CALL @#B.RDER ;Read the handler file (check for error) .IF EQ TST H.UNIT(R2) ;Is handler sysgened for 64-unit support? BEQ INSSWT ;Branch if not SUB #<32.>,H.SIZ(R2) ;If yes, chop off extended owner table .ENDC ;EQ INSSWT: BR 40$ ;Modified to NOP before SY: is loaded ............ MOV @#TOTMEM,R1 ;Pass total system RAM size in R1 CALL @#INSTAL ;Try to install handler BCC 40$ ;Branch on success .IF NE MMG$T TST @#INSTUB ;Are we trying to install UB? BEQ BADIN1 ;If not, branch SEC RETURN ............ .ENDC ;NE MMG$T BADIN1: CALLR @#BADINS ;Handler installation error ............ 40$: MOV (SP)+,R1 ;Save return address in R1 .IF NE MMG$T TST @#INSTUB ;Are we trying to install UB? BNE 60$ ;If yes, branch MOV R2,-(SP) ;Save R2 ADD #,R2 ;Point to UMR flags CLR @#PARFLG ;Use Q.MEM (new-style) versions of $PUTWR, etc MOV @R2,-(SP) ;Put UMR flags on stack BIC #^c,@SP ;Clear all except these two bits CMP #,(SP)+ ;Are both bits set? BEQ 50$ ;If yes, branch, we're already set up COM @#PARFLG ;Say to use Q.PAR (old-style) versions 50$: CALL @#UBTST ;Test for UMRness MOV (SP)+,R2 ;Restore R2 MOV #,R5 ;Point to save loc for SY primary bootstrap MOV H.BPTR(R2),(R5)+ ;Save SY primary bootstrap ptr (loc 62) MOV H.BLEN(R2),(R5)+ ;Save primary bootstrap byte len (loc 64) MOV H.READ(R2),@R5 ;Save ptr to pri bootstrap read rtn (loc 66) 60$: .ENDC ;NE MMG$T MOV R2,-(SP) ;Save R2 CALL @#CHK64 ;Check for 64 unit support MOV (SP)+,R2 ;Restore R2 ADD #,R2 ;Point to handler option word .ASSUME H.GEN-2 EQ H.DSTS MOV -(R2),-(SP) ;Remember system handler status ... .ASSUME H.DSTS-2 EQ H.DSIZ MOV -(R2),-(SP) ; ... and device size ... .ASSUME H.DSIZ-2 EQ H.SIZ MOV -(R2),-(SP) ; ... and handler size in bytes .IF NE RTE$M ADD #,@SP ;Force handler length to be BIC #,@SP ; double-word bound for RTEM VS handler .ENDC ;NE RTE$M INC R0 ;Remember the system handler or UB block MOV R0,-(SP) ; number at the block with real code CALLR @R1 ;Return from LDHNDL ............ INPER1: CALLR @#BIOERR ;Die on error .SBTTL DVRD2 - Read fake fixed area, UB, PI, SY into mem. (in ovly. LDHNDL) ;+ ; Upon entering: ; R0 = System handler block number (saved in SYBLK) ; R4 = Top of available low memory (first unavailable word) ; (saved in SYHSAV) ; On exit: ; R3 = USR block number ; R5 = system handler entry point ;- DVRD2: MOV (SP)+,(PC)+ ;Save return address RETADR: .WORD 0 ;Return address from this overlay MOV @#MONBLK,R0 ;Get monitor start block .IF NE RTE$M ;If RTEM SUB @#$VSBRO,R0 ;Subtract out bootstrap read offset .ENDC ;NE RTE$M ADD #,R0 ;Start of fixed area MOV #,R1 ;Word count to read MOV #,R2 ;Where to read into CALL @#B.READ ;Read the monitor fixed area into memory BCS INPER1 ;Branch on error MOV #,R2 ;Get start of fake fixed area MOV R2,@#$SYPTR ;Location 54 points to fake fixed area for now MOV @#MEMSIZ,ZMEMSZ(R2) ;Fill in real memory size ... MOV #,ZMEMPT(R2) ; ... and pointer to total memory MOV @#BCNFG,ZCNFG1(R2) ;Store CONFIG and ... MOV @#BCNFG2,ZCNFG2(R2) ; ... CONFG2 values MOV @#B$SUFF,ZHSUFF(R2) ;Store the monitor suffix MOV #,R0 ;Point to boot information MOV (R0)+,R3 ;R3 = device unit number BIC #^c,R3 ;Make sure there are no unwanted bits MOVB R3,ZSYUNI+1(R2) ;Set system unit number we booted MOV (R0)+,ZMONAM(R2) ;Move the first word of B$FNAM in ... MOV (R0)+,ZMONAM+2(R2) ; ... and the second word, too .IF NE RTE$M BIS #,ZSYSGE(R2) ;Set RTEM$ bit in SYSGEN .ENDC ;NE RTE$M MOV @#G$VEC,R3 ;$GTCSR on non-PRO is an error .IF NE PRO$S TST @#PROFLG ;Are we on a PRO300 series machine? BEQ 70$ ;Branch if not CALL @#GTPIHD ;Read first block of PI into BUFFB CALL LDHNDL ;Read PI into memory MOV R4,R3 ;R3 -> start of PI handler (PILQE-6) ADD #<14.>,R3 ;R3 -> $GTVEC routine in PI MOV R3,@#G$VEC ;Store pointer to $GTVEC routine in PI 70$: .ENDC ;NE PRO$S TST (R3)+ ;R3 -> $GTCSR code in PI or BADINS+2 in BSTRAP MOV #,INSSWT ;System handler must be installed MOV R4,@#SYHTOP ;Remember top of sys handler .IF NE MMG$T MOV @#UBBLK,R0 ;Is UBX.SYS on the system disk? BEQ 90$ ;If not, branch CALL @#BBRD1 ;Read block 0 of UB BCS 90$ ;If can't read UB, continue without it MOV SP,@#INSTUB ;Say we're installing UB CALL LDHNDL ;Load UB into low mem above SY and install BCS 80$ ;If error, branch MOV R4,@#SYHTOP ;Save new top of low memory MOV R4,@#STRTUB ;R4->start of UB (UBSTRT or UBLQE-6) BR 90$ ;Merge below ............ 80$: CLR @#UBBLK ;Say no UB MOV @#SYHTOP,R4 ;Get back old value of top of low mem 90$: CLR @#INSTUB ;Clear installing UB flag .ENDC ;NE MMG$T MOV @#SYBLK,R0 ;Get system handler start block number CALL @#BBRD1 ;Read install code for system handler BCS INPER1 ;Error CALL LDHNDL ;Load system handler into low memory MOV R4,R5 ;Save the handler entry point ;+ ; Read in the relocation list ;- MOV @#MONBLK,R0 ;Get starting block of monitor file .IF NE RTE$M SUB @#$VSBRO,R0 ;Subtract out bootstrap read offset .ENDC ;NE RTE$M ADD #,R0 ;Point to block for relocation list MOV #/2,R1 ;Get number of words to read CALL @#BBREAD ;Read the list into BUFFB BCS INPER1 ;Error ;+ ; Compute monitor load address just below the system handler ;- ADD #BOOTSZ-,R0 ;Bump block number over boot blocks MOV R0,R3 ;Copy the KMON block number and point ... ADD #,R3 ; ... beyond KMON at USR in monitor file .IF NE RTE$M ADD @#$VSBRO,R3 ;Add in bootstrap read offset .ENDC ;NE RTE$M MOV @#$RMSIZ,R1 ;R1 = number of bytes to read SUB R1,R4 ;Get load point of monitor BLO 100$ ;Too low, give error message ;CLC ;C=0 from BLO=BCS ROR R1 ;Compute number of words to read MOV R4,R2 ;Copy the load location CMP R2,# ;Is the start of the KMON below bootstrap top BHIS 110$ ;No, it all fits CMP R2,# ;Will the KMON fit in at all? BLO 100$ ;Nope, can't boot his monitor here SUB #,R1 ;Decrease word count to read MOV R3,R0 ;Start reading at the USR ADD #,R2 ;Increase load location by KMON size CMP R2,# ;Can we fit it without the KMON? BHIS 110$ ;Yes, go read the monitor without KMON 100$: JSR R1,@#REPORT ;Give a message .WORD NOCORE+ ;Insufficient memory ;+ ; Read monitor, load monitor tables with system handler information ;- 110$: CALL @#B.RDER ;Read monitor into memory (check for error) SUB #,R4 ;Subtract the location KMON was linked to .IF NE RTE$M TST @#CNFMOD ;Is the console a CRT? BPL 120$ ;Branch if not, no modifications needed. ;+ ; .SET TT SCOPE TAB NOCRLF ;- BIS #,DLTCB(R4) ;Set SCOPE, TAB BIC #,DLTCB(R4) ;Set NOCRLF 120$: BIS #,SYSGEN(R4) ;Set RTEM$ bit in SYSGEN BIT #<1>,@#CNFMOD ;Was UCF.SAV found on boot? BEQ 130$ ;Branch if not, don't enable UCF BIS #,CLIFLG-$RMON(R4) ;Enable UCF processing 130$: .ENDC ;NE RTE$M MOV R0,-(SP) ;Save block number of KMON or USR CALLR @RETADR ;Return to DVREAD .DSABL LSB LDHEND:: .ASSUME LE ;Ovly. must be at most B$END-B$BOOT . = < < . + BD.BLK > / BK.BYT > * BK.BYT ;Adjust loc counter to block boundary .SBTTL Overlay STRTOV - Install non-SY handlers and start system ;+ ; Do not destroy R4 ; ; STRTOV is read in at B$BOOT ; ; On entry: ; R4 = RMON bias - R4 remains unchanged through all GTHNDL ; All other registers are destroyed ; ; Block 0 (and possibly another block) of each handler is read into ; BUFFB (5006). The handlers may need all of BUFFB for their install code. ; ; GTHNDL is read into B$BOOT (with STRTOV overlay). ;- .ENABL LSB .ASSUME < . & BD.BLK > EQ 0 ;Overlay must start on block boundary STRTOV:: .SBTTL GTHNDL in overlay STRTOV - Install other handlers ;+ ; Search through the table of device handlers for those that exist ; in the system, find them and install them ;- GTHNDL: .RCTRLO ;Ensure we speak with the right fills CLR LDFLG ;Init LD present flag MOV #<$ENTRY>,R1 ;Point to $ENTRY table ADD R4,R1 ;Bias the pointer into RMON MOV R1,-(SP) ;Save pointer to $ENTRY table 10$: MOV (R1)+,R2 ;Get $ENTRY value CMP R2,#<-1> ;End of table? BEQ 60$ ;Yes, go process rest of handlers in HNAMES MOV $PNAME-<$ENTRY+2>(R1),R0 ;Get handler name BEQ 10$ ;Nothing here; try next $PNAME entry CMP @#B$DEVS,R0 ;Is this handler the system device? BNE 20$ ;No TST R2 ;Is it resident? BEQ 50$ ;No, so it's not the real system device ;+ ; Is BIS at 20$ really necessary? I think that checking $DVREC is no longer ; needed with this algorithm, since we never try to install a handler twice. ;- 20$: TST R2 ;Is it resident? ;;;>>> BIS $DVREC-$ENTRY(R1),R2 ;Is it resident or already installed? BNE 10$ ;If so, try next $PNAME entry MOV #,R3 ;Point to list of existing handler names 30$: TST (R3)+ ;Skip previous block number MOV (R3)+,R2 ;Get a handler name BEQ 40$ ;No more here CMP R2,R0 ;Is this the right handler? BNE 30$ ;No, look for more CALL TRYINS ;Yes, try to install it BR 10$ ;Go do next $PNAME entry ............ 40$: .IF NE BATC$H CMP R0,#<^rBA > ;Is this the batch handler BEQ 10$ ;Yes, leave the name in the tables .ENDC ;NE BATC$H 50$: CLR $PNAME-<$ENTRY+2>(R1) ;Clear $PNAME for another handler to use .IF NE UNI$64 CLR $PNAM2-<$ENTRY+2>(R1) ;Clear $PNAM2 for another handler to use .ENDC ;NE UNI$64 BR 10$ ;Try next $PNAME entry ............ 60$: MOV #,R3 ;Point to list of existing handler names 70$: TST (R3)+ ;Skip previous block number MOV (R3)+,R2 ;Get a handler name BEQ 120$ ;No more here CLR R5 ;No empty slot yet MOV @SP,R1 ;Point to $ENTRY table 80$: CMP (R1)+,#<-1> ;End of table? BEQ 110$ ;Yes, try to install this handler from HNAMES MOV $PNAME-<$ENTRY+2>(R1),R0 ;Get handler name BNE 100$ ;Non-zero, might be right TST R5 ;Empty slot? BNE 100$ ;Yes, don't replace it ..INSA:: ;**PATCH** NOP to not install all handlers 90$: MOV R1,R5 ;Save empty slot pointer 100$: CMP R2,R0 ;Does $PNAME entry match HNAMES entry? BEQ 70$ ;Yes, we've already tried this one! BR 80$ ;No, keep looking for a possible match ............ 110$: MOV R5,R1 ;End of table, is there an empty slot? BEQ 70$ ;No, don't install the handler CALL TRYINS ;Yes, try to install it BR 70$ ;Go do next HNAMES entry ............ 120$: .IF NE MMG$T ;+ ; Both UBFLG and DMFLG must be non-zero if we are to use UB ;- TST @#DMFLG ;Are there any DMA handlers? BEQ 125$ ;If not, branch BIS #CF3.DM,CONFG3(R4) ;Set DMA flag in CONFG3 125$: TST @#UBBLK ;Is UB on the system? BEQ 140$ ;If not, branch TST @#UBFLG ;Are any handlers ready for UB? BEQ 130$ ;If not, branch TST @#DMFLG ;Do any handlers need UB? BNE 140$ ;If yes, branch 130$: TST (SP)+ ;Pop $ENTRY address from stack CALLR @#UBRSTR ;Go set up for restart ............ 140$: .ENDC ;NE MMG$T ;+ ; Relocate non-system resident handlers ;- MOV (SP)+,R1 ;Point to $ENTRY table 150$: MOV (R1)+,R0 ;Get a handler entry BEQ 150$ ;Non-resident so do nothing INC R0 ;End of table? BEQ 160$ ;Yes, done with installation ;+ ; Relocate non-system resident handlers ;- CMP R0,$ENTRY+2(R4) ;Is this the system device or PI? BHI 150$ ;Yes, don't relocate it ADD R4,-2(R1) ;Relocate a resident handler BR 150$ ;Loop through all entries ............ 160$: CALLR STRTUP ;Go start the system .DSABL LSB .SBTTL TRYINS in overlay STRTOV ;+ ; TRYINS will try to install the handlers. If a handler does not ; install, its block number in HNAMES is set to zero. ; ; On entry ; R0 = handler name from $PNAME ; R1 = corresponding slot in $ENTRY - 2 ; R2 = handler name from HNAMES (=R0) ; R3 = pointer to handler block number in HNAMES ; R4 = RMON bias ;- .ENABL LSB TRYINS: TST -(R1) ;Yes, back up the pointer 10$: MOV @R3,R0 ;Get handler block number on the system BEQ 80$ ;We've already tried to install this one! MOV R1,-(SP) ;Save entry pointer CALL @#BBRD1 ;Read a device handler prefix of 1 block MOV (SP)+,R1 ;Restore entry pointer BCC 30$ ;Branch if read was successful .PRINT # ;Error reading handler 20$: .IF NE BATC$H CMP $PNAME-$ENTRY(R1),#<^rBA > ;Is this the batch handler BEQ 80$ ;Yes, leave the name in the tables .ENDC ;NE BATC$H CLR $PNAME-$ENTRY(R1) ;Clear $PNAME for another handler to use .IF NE UNI$64 CLR $PNAM2-$ENTRY(R1) ;Clear $PNAM2 for another handler to use .ENDC ;NE UNI$64 BR 80$ ;Go get next handler ............ 30$: MOV (PC)+,@(PC)+ ;Patch INSTAL code for non-system handlers ... TST @R5 ; ... TST @R5 instead ... .WORD NONSYS ; ... of TST (R5)+ CALL @#INSTAL ;Try to install handler BCS 20$ ;Branch on failure INC @R3 ;Bump the handler block number MOV @R3,$DVREC-$ENTRY(R1) ;Store the handler block on the system MOV #,R2 ;Point to handler parameters MOV (R2)+,$HSIZE-$ENTRY(R1) ;Store the handler size .ASSUME H.SIZ+2 EQ H.DSIZ MOV (R2)+,$DVSIZ-$ENTRY(R1) ;Store the device size in blocks .ASSUME H.DSIZ+2 EQ H.DSTS MOV (R2)+,$STAT-$ENTRY(R1) ;Store device stat word in $STAT MOV -(R3),$PNAME-$ENTRY(R1) ;Store the device name .IF NE UNI$64 MOV @R3,$PNAM2-$ENTRY(R1) ;Store the device name .ENDC ;NE UNI$64 MOV #,R2 ;Point to start of block 0 CALL @#CHK64 ;Check for 64 unit support BCS 60$ ;If no 64 unit, branch .IF EQ SUB #<32.>,$HSIZE-$ENTRY(R1) ;Sub. ext. unit tbl. from handlr size .ENDC ;EQ .IF NE UNI$64 MOV R5,-(SP) ;Save R5 MOV #<$PNAM2>,R0 ;Point to $PNAM2 table ADD R4,R0 ;Relocate it MOV #<$SLOT>,R5 ;Max table size 40$: CMP R2,(R0)+ ;Was this letter already used? BEQ 50$ ;If yes, branch, no 64 unit support SOB R5,40$ ;Go to end of table MOV R2,$PNAM2-$ENTRY(R1) ;Save 1 letter device name in $PNAM2 .IF NE OWN$ER MOV #<$ENTRY>,R0 ;Point to $ENTRY table ADD R4,R0 ;Bias the pointer into RMON MOV R1,R2 ;Get current address in $ENTRY SUB R0,R2 ;R2 = index into $ENTRY for this device ASL R2 ;Index * 2 ADD #<$OWNER>,R2 ;Add start of $OWNER table ADD R4,R2 ;Bias the pointer into RMON MOV #,@R2 ;Flag 64-unit handler in $OWNER table .ENDC ;NE OWN$ER 50$: MOV (SP)+,R5 ;Restore R5 .ENDC ;NE UNI$64 60$: CMP (R3)+,#<^rLD > ;Is this the LD handler BNE 70$ ;Branch if not INC (PC)+ ;Make LD flag NE to show LD is present LDFLG: .WORD 0 ;Flag <> 0 => LD is present 70$: .IF NE MMG$T MOV #,R2 ;Point to UB flags in the handler CALL @#UBTST ;Test for UMR'ness .ENDC ;NE MMG$T 80$: CLR @R3 ;Zero block #, so we don't try install twice TST (R1)+ ;Point to next $PNAME entry RETURN .DSABL LSB .SBTTL STRTUP - Start Up System (in overlay STRTOV) .ENABL LSB STRTUP: .IF NE MMG$T TST @#UBBLK ;Is UB on the system? BEQ 10$ ;If not, branch MOV R4,R3 ;Get pointer to RMON ADD #<$ENTRY+UB.NUM>,R3 ;Point to UB $ENTRY MOV #,R0 ;BSTRAP read routine (monitor) MOV #,R1 ;Go to DRCALL using the monitor MOV @#UMRS,R5 ;Put the UMR's into R5 BIS #<100000>,R5 ;Set high bit - 2nd call to UB CALL DRCALL(R4) ;Call DRCALL BCC 10$ ;If handler loads, branch CALLR @#UBRSTR ;Error - go restart UB ............ 10$: .ENDC ;NE MMG$T CLR R0 ;Prevent any swaps ... .SETTOP ; ... by SETTOPing to 0 .IF EQ AI$COD CMP SWPSIZ+,# ;SWAP file too small? BLO NOSWAP ;Yes, give error .ENDC ;EQ AI$COD TST LDFLG ;Was LD.SYS present? BEQ 20$ ;No, assumption correct MOVB #<' >,@#XIT.AS ;Enable (uncomment) the LD CLEAN cmnd 20$: BIS #,@#$JSW ;Set to execute start-up command(s) TST (PC)+ ;Should we be silent? ..SLNT:: .WORD SILN$T ;**PATCH** Non-zero to not print boot string BNE 30$ ;Yes, skip the boot message .PRINT # ;Print the boot string 30$: TST (PC)+ ;Should we be silent? ..TTQU:: .WORD ;**PATCH** Non-zero SET TT QUIET BEQ 40$ ;No BIS #,STATWD(R4) ;SET TT QUIET bit 40$: TST (PC)+ ;Should we SET KMON IND? ..INDR:: .WORD IND$ON ;**PATCH** non-zero => SET KMON IND BEQ 50$ ;No, don't SET KMON IND BIS #,STATWD(R4) ;SET KMON IND 50$: .IF NE > ;If Multiterm & (DZ modem or multi-term t/o) TST (PC)+ ;Check word for ODT ..DZOD:: ;**PATCH** Non-zero to start without DZ polling MTODT:: .WORD 0 ;If set ODT BNE 60$ ;Set - skip around .IF NE DZMD$M ;If DZ11 modem control CALL DZMCTL(R4) ;Start DZ11 ring polling .ENDC ;NE DZMD$M .IF NE MTI$M ;If multiterminal time-out CALL DLMPOL(R4) ;Start DL11 ring polling .ENDC ;NE MTI$M .ENDC ;NE > 60$: CLR R0 ;Must do hard exit - bye .EXIT ............ NOSWAP: JSR R1,@#REPORT ;Swap file is too small .WORD SPTSML .DSABL LSB STRTEN:: .ASSUME LE ;Ovly. must be at most B$END-B$BOOT . = < < . + BD.BLK > / BK.BYT > * BK.BYT ;Adjust loc counter to block boundary .SBTTL Overlay SETSIO - Set up UB, SY, switch to monitor calls for I/O ;+ ; At the end of this routine, we have a monitor ; ; Input: ; R4 = RMON bias ; ; SETSIO is read in at B$BOOT ;- .ENABL LSB .ASSUME < . & BD.BLK > EQ 0 ;Overlay must start on a block boundary SETSIO:: .IF NE MMG$T TST @#UBBLK ;Do we load UB? BEQ 20$ ;If not, branch MOV #<$CSW>,R0 ;Point to channel 0 ADD R4,R0 ;Relocate it MOV #,(R0)+ ;Open chan. for input, dev index UB.NUM CLR (R0)+ ;Start block is 0 (non-file structured one) MOV #<-1>,(R0)+ ;Length is -1 (no limit) CLR (R0)+ ;No data length CLRB (R0)+ ;No pending requests CLRB @R0 ;Device unit number is 0 MOV R4,R3 ;Get pointer to RMON ADD #<$ENTRY+UB.NUM>,R3 ;Point to UB $ENTRY MOV R3,-(SP) ;Save it MOV @R3,R3 ;Get UBLQE address TST (R3)+ ;Point to UBCQE CLR @R3 ;Clear it MOV (SP)+,R3 ;Restore UB $ENTRY pointer MOV #,R0 ;BSTRAP read routine (chicken and egg) ; call with R0 = block ; R1 = count ; R2 undefined MOV #,R1 ;Indicate BSTRAP pseudo-$LOAD SY: MOV @#UMRS,R5 ;R5 = SY UMR's required for UB CALL DRCALL(R4) ;Call handler, if request to do so BCC 10$ ;If handler loads, branch MOV @#SYHSAV,R4 ;Restore top of low memory before UB CLR @#UBBLK ;Indicate no UB handler TST (SP)+ ;Pop return address from stack CALLR @#DVRD3 ;Go back and try again ............ 10$: CLR @#UMRS ;Clear SY UMR's, they're already taken care of .ENDC ;NE MMG$T 20$: MOV #,R0 ;Point to boot information BIC #^c,@R0 ;Make sure there are no unwanted bits MOVB @R0,SYUNIT+1(R4) ;Set system unit number we booted .IF NE MMG$T MOVB @R0,$SYSCH+C.UNIT(R4) ;Set so KMON can use $SYSCH in RWSYS .ENDC ;NE MMG$T .IF NE UNI$64 ;+ ; If unit numbers greater than 7 are made bootable, then the following ; code to setup DKASSN and SYASSN is already set up to handle such. ;- MOV @#SY64,R1 ;Get one-letter system name BEQ 30$ ;Branch if it is not an extended unit device ADD #<^r 0 >,R1 ;Add in "0" RAD50 bias in middle position CMP @R0,#<7> ;Is unit greater than 7? BLOS 40$ ;Branch if not MOV @R0,R3 ;Get unit number BIC #^c<70>,R3 ;Isolate high octal digit of unit number ASL R3 ;Multiply ASL R3 ; by 4 ADD R3,R1 ;Add in to complete middle position bias BR 40$ ;Join common code ............ .ENDC ;NE UNI$64 30$: MOV @#B$DEVS,R1 ;Get default system name 40$: ADD (R0)+,R1 ;Add the ASCII unit number in ADD #<^r 0>,R1 ;Make the number RAD50 MOV R1,DKASSG(R4) ;Update DK pseudo-assignments (DKn) MOV R1,SYASSG(R4) ;Update SY pseudo-assignment (SYn) MOV (R0)+,MONAME(R4) ;Move the first word into RMON MOV (R0)+,MONAME+2(R4) ; and the second word, too .IF EQ RTE$M TST (R0)+ ;Don't change READ routine till after DRCALL .IF NE MMG$T TST @#PARFLG ;Do we use Q.PAR (old-style) versions? BEQ 50$ ;If not, branch MOV #PSTART+,R3 ;Get start of Q.PAR versions MOV #MSTART+,R1 ;Get start of Q.MEM versions MOV (R3)+,(R1)+ ;Replace Q.MEM versions of GETBYT, ... MOV (R3)+,(R1)+ ; ... PUTBYT, and PUTWRD with ... MOV (R3)+,(R1)+ ; ... Q.PAR versions 50$: .ENDC ;NE MMG$T MOV (R0)+,R1 ;Point to the top of the system handler MOV #HNDLST+,R3 ;Point to start of pointer list .IF NE TST @#SY64 ;Does system handler support extended units BEQ 60$ ;Branch if not SUB #<32.>,R1 ;If yes, skip back over extended owner table .ENDC ;NE 60$: MOV (R3)+,-(R1) ;Set up pointer ADD R4,@R1 ;Relocate it TST @R3 ;More? BNE 60$ ;Yes, do it .ENDC ;EQ RTE$M MOV #<$CSW>,R0 ;Point to channel 0 ADD R4,R0 ;Relocate it MOV #,(R0)+ ;Open channel for input, device index 2 CLR (R0)+ ;Start block is 0 (non-file structured one) MOV #<-1>,(R0)+ ;Length is -1 (no limit) CLR (R0)+ ;No data length CLRB (R0)+ ;No pending requests MOVB @#B$DEVU,@R0 ;Device unit number is system unit MOV R4,R3 ;Get pointer to RMON ADD #<$ENTRY+2>,R3 ;POINT TO SY $ENTRY MOV R3,-(SP) ;Save it MOV @R3,R3 ;Get SY xxLQE address TST (R3)+ ;Point to SY xxCQE CLR @R3 ;Clear it MOV (SP)+,R3 ;Restore SY $ENTRY pointer ;+ ; Use of I/O programmed requests in the handler load routine is not allowed ; because the terminal vectors have not been set up yet. ; ; I'm not sure if this is absolutely necessary, but it is recommended that ; handler load routines not decrease their priority, since BSTRAP has a ; PRIORITY 7 window around all monitor/vector modifications. This window ; includes the call to the handler load routine. ;- MOV #,R0 ;BSTRAP read routine (chicken and egg) ; call with R0 = block ; R1 = count ; R2 undefined MOV #,R1 ;Indicate BSTRAP pseudo-$LOAD SY: MOV @#G$VEC,R5 ;R5 -> $GTVEC routine for PRO CALL DRCALL(R4) ;Call handler, if if request to do so BCC 70$ ;If handler loads, branch JSR R1,@#REPORT ;Error - "failure to load system handler" .WORD NOLDSY ............ 70$: MOV @R3,R2 ;Get the system handler entry point SUB #,R2 ;Point to vector entry in .DRBEG header CLR R3 ;Assume fixed vector(s) MOV (R2)+,R1 ;Does handler have multiple vectors? BPL 100$ ;Branch if not, pointing to actual vector ASL R1 ;Double offset, dump sign bit ADD R1,R2 ;Compute address of vector table MOV (R2)+,R1 ;Get next vector address or offset BPL 90$ ;Branch if fixed vector list MOV (R2)+,-(SP) ;Get hardware ID # for device in option slot CALL @R5 ;Call $GTVEC with @SP = vector A of device MOV (SP)+,R3 ;R3 = base vector BCC 80$ ;Traverse floating vector list CALLR @#BADINS ;If cannot find device, give error ............ 80$: MOV (R2)+,R1 ;Does handler have multiple vectors? 90$: ADD R3,R1 ;Add in base vector (0 if fixed vector) 100$: BLE 110$ ;If minus or zero, end of vector table - exit CALL @#PROTEC ;Protect the vector in the bit map MOV R2,@R1 ;Move the interrupt entry point offset ADD (R2)+,(R1)+ ;Relocate it MOV (R2)+,@R1 ;Set up interrupt priority BR 80$ ;Get next vector ............ 110$: CALL @#CORUPT+ ;Setup vectors above 120 & chain area CLR -(SP) ;Set new PS with PR0 CALL @#BRTI ;Go set the priority .IF NE MMG$T TST @#UBBLK ;Are we using UB? BEQ 11$ ;If not, branch BIS #UMR.ON,@#MMR3 ;Turn on UMR support 11$: .ENDC ;NE MMG$T MOV #,@#B$READ ;All further READs use the monitor! RETURN .SBTTL System handler relocation table in overlay SETSIO .IF EQ RTE$M HNDLST::.WORD $FORK .WORD $INTEN .IF NE TIM$IT .WORD $TIMIO .ENDC ;NE TIM$IT .IF NE ERL$G .WORD $ERLOG .ENDC ;NE ERL$G .IF NE MMG$T MSTART: .WORD $PUTWR ;Q.MEM version of $PUTWR .WORD $PUTBY ;Q.MEM version of $PUTBY .WORD $GETBY ;Q.MEM version of $GETBY .WORD $MPPHY .WORD $RELOC .ENDC ;NE MMG$T .WORD 0 ;End of system handler pointer list ............ .IF NE MMG$T PSTART: .WORD $OSPTW ;Q.PAR version of $PUTWR .WORD $OSPTB ;Q.PAR version of $PUTBY .WORD $OSGTB ;Q.PAR version of $GETBY .ENDC ;NE MMG$T .ENDC ;EQ RTE$M .DSABL LSB SETEND:: .ASSUME LE ;Ovly. must be at most B$END-B$BOOT . = < < . + BD.BLK > / BK.BYT > * BK.BYT ;Adjust loc counter to block boundary .IF NE MMG$T .SBTTL Overlay RSTUB1 - Restart UB overlay 1 ;+ ; RSTUB1 reads the primary driver from SY into BUFFB and then into memory ; locations 0-776. It then reads in RSTUB2 and then jumps to it. ; ; RSTUB1 is read into B$BOOT ;- .ENABL LSB .ASSUME < . & BD.BLK > EQ 0 ;Overlay must start on a block boundary RSTUB1: MOV #SYH.RE,R3 ;Pointer to save area MOV -(R3),R1 ;Get size of primary driver in bytes (SYH.BL) ASR R1 ;R1 = word count of primary driver MOV R1,-(SP) ;Save it MOV -(R3),R0 ;R0 -> primary boot code in handler (SYH.BP) ASR R0 ;Make it words CLR R5 ;MOVB with no sign extend BISB R0,R5 ;R5 = word offset from start of block to boot ADD R5,R1 ;R1 = word count to read ASL R5 ;Make word offset byte offset CLRB R0 ;High byte is block number containing boot SWAB R0 ;R0 = block # of boot in low byte ADD @#SYBLK,R0 ;Get the absolute block number MOV #BUFFB,R2 ;Read into BUFFB CALL @#B.RDER ;Read 2 blocks of SY (die on error) ;+ ;Note that I haven't purged the stack ;- MOV R5,-(SP) ;Save R5 MOV R2,-(SP) ;and R2 CALL SAVMMU ;Save state of MMU RESET ;As we were in the beginning CALL RESMMU ;Restore MMU state (RESET turns it off) MOV @#MONBLK,R0 ;Get block number of start of monitor file ADD #RSTUB2/1000,R0 ;Compute the block number for RSTUB2 overlay MOV #1,R1 ;Read 1 word MOV #BUF,R2 ;Get address of BUF CALL @#B.RDER ;Read 1 word to reset controller for correct ;unit number CALL CLRMMU ;Turn off MMU MOV (SP)+,R2 ;Restore R2 MOV (SP)+,R5 ;and R5 ADD R5,R2 ;R2 -> start of primary boot CLR R0 ;Where to move primary boot MOV (SP)+,R1 ;# of words to move 30$: MOV (R2)+,(R0)+ ;Move primary driver into memory SOB R1,30$ ;Starting at location 0 MOV #BRTI,@#V.KW1L ;Ensure that clock just idles CLR @#V.KW1L+2 ;Clear PS in clock vector MOV @#SYH.RE,@#B$READ ;Restore ptr to primary driver read rtn MOV @#MONBLK,R0 ;Get block number of start of monitor file ADD #RSTUB2/1000,R0 ;Compute the block number for RSTUB2 overlay MOV #R2END-RSTUB2/2,R1 ;Get number of words to read MOV #BUFFB,R2 ;Get address of BUFFB for RSTUB2 CALL @#B.RDER ;Do the read (check for error) JMP @#RSTUB2+ ;Second part of restart after UB fail CLRMMU: CALL CATCH4 ;Ignore non-existent memory traps CLR @#MMR0 ;Disable memory management CLR @#MMR3 ;Disable UMR support RETURN SAVMMU: CALL CATCH4 ;Ignore non-existent memory traps ;+ ; The following MOVs must use an intermediate register, because the ; source operand may not exist and can abort the instruction causing ; a trap-to-4. The abort can cause the destination operand to not ; be used. In this case, the PC might not be incremented by 2, and ; the next instruction executed would be at the in-line data location. ;- MOV @#MMR0,R0 ;R0 = Current MMR0 contents MOV R0,(PC)+ ;Save it in-line MMUSTA: .BLKW MOV @#MMR3,R0 ;R0 = Current MMR3 contents MOV R0,(PC)+ ;Save it in-line UMRSTA: .BLKW RETURN RESMMU: CALL CATCH4 ;Ignore non-existent memory traps MOV MMUSTA,@#MMR0 ;Restore MMU state MOV UMRSTA,@#MMR3 ;Restore UMR state RETURN CATCH4: MOV #V.CPU,R0 ;R0 -> Non-existant memory trap MOV @R0,TR4ADR ;Save trap address MOV #RTIINS,(R0)+ ;Store the vector address MOV @R0,TR4PS ;Save trap PS CLR @R0 ;PR0, kernel state CALL @(SP)+ ;Call back caller TR4ADR = .+2 MOV #.-.,@#V.CPU ;Restore NXM Vector PC TR4PS = .+2 MOV #.-.,@#V.CPU+2 ; and PS RETURN ;Return to caller's caller RTIINS: RTI BUF: .BLKW 1 ;1 word buffer for read to reset ;booted unit number .DSABL LSB R1END:: .ASSUME LE ;Ovly. must be at most B$END-B$BOOT . = < < . + BD.BLK > / BK.BYT > * BK.BYT ;Adjust loc counter to block boundary .SBTTL Overlay RSTUB2 - Restart UB overlay 2 ;+ ; RSTUB2 saves the communications area (4716-4736, 5000-5004) in the second ; block of BUFFB and reads the bootstrap (blocks 1-4 of the monitor file) ; into memory locations 1000-4777. It restores certain parts of the commun- ; ications area and jumps almost to the start of the bootstrap and restarts. ; ; RSTUB2 is read into BUFFB ;- .ENABL LSB .ASSUME < . & BD.BLK > EQ 0 ;Overlay must start on a block boundary RSTUB2::MOV #,R0 ;Get start of save area MOV #,R1 ;Save it in the second block of BUFFB MOV #/2,R2 ;Get number of words to save 10$: MOV (R0)+,(R1)+ ;Save them SOB R2,10$ MOV @#B$TIME+TIM.HI,(R1)+ ;Save booted time ... MOV @#B$TIME+TIM.LO,(R1)+ ; ... (second word of booted time) MOV @#B$DATE,(R1)+ ;Save booted date MOV @#MONBLK,R0 ;Point to start of monitor file INC R0 ;Point to block 1 of monitor MOV #<4*BK.WD>,R1 ;Read in 4 blocks (blocks 1-4) MOV #,R2 ;Start reading in at location 1000 CALL @#B.RDER ;Read in using the monitor MOV #,R0 ;Get start of save area MOV #,R1 ;Get area to restore to MOV (R0)+,(R1)+ ;Restore B$DEVN CMP (R0)+,(R1)+ ;Skip over B$DEVS MOV (R0)+,(R1)+ ;Restore B$DEVU MOV (R0)+,(R1)+ ;Restore B$FNAM (first word) MOV (R0)+,(R1)+ ;Restore B$FNAM (second word) MOV (R0)+,(R1)+ ;Restore B$READ CMP (R0)+,(R1)+ ;Skip SYHTOP MOV (R0)+,(R1)+ ;Restore DUPFLG CMP (R0)+,(R1)+ ;Skip $RMSIZ MOV #,R1 ;Point to B$TIME MOV (R0)+,(R1)+ ;Restore B$TIME (first word) MOV (R0)+,(R1)+ ;Restore B$TIME (second word) .ASSUME B$DATE EQ B$TIME+4 MOV (R0)+,(R1)+ ;Restore B$DATE CLR R3 ;THIS MAY HAVE TO GO MOV #<1>,@#UBBLK ;Say we're restarting without UB CALLR @#B$BUBR ;Jump to restart point for UB .DSABL LSB R2END:: .ASSUME < R2END - RSTUB2 > LE BK.BYT ;Overlay must be at most 1 block . = < < . + BD.BLK > / BK.BYT > * BK.BYT ;Adjust loc counter to block boundary .ENDC ;NE MMG$T .SBTTL Overlay BSTTBL - PI bootstrap table ;+ ; BSTTBL is read into the last quarter of BUFFB ; ; HKPC13 is an unused hook here and in RMON. It is unused because ; of the restriction that you cannot build a PRO system with powerfail ; messages (PWF$L = 1). It is included here for completeness ; only. It must remain commented out. ; ; HKPC13 corresponds to PI hook PIHK13 in PI and PIOVR. PIHK13 is ; also commented out. Because of the PI design, if HKPC13 is unused, ; PIHK13 must also be unused. ; ; BSTRAP can be modified to conditionalize HKPC13 for PWF$L. But ; PI is shipped prebuilt, and there is no way to modify it. ;- .ASSUME < . & BD.BLK > EQ 0 ;Overlay must start on a block boundary BSTTBL:: .IF NE PRO$S .BYTE 3. .BYTE 1. .WORD ^b<010> ;REL/ABS bit map .WORD LKVEC .WORD TTKB .WORD 204 .BYTE 3. .BYTE 200+2. .WORD ^b<111> .WORD LKINT .WORD TTIIN2 .WORD SAVE30 .IF NE MTT$Y .BYTE 10. .BYTE 3. .WORD ^b<1111111111> ;ABS/REL bit map .WORD HKPC03 .WORD HKPC03+2 .WORD HKPC04 .WORD HKPC04+2 .WORD HKPC05 .WORD HKPC05+2 .WORD HKPC07 .WORD HKPC07+2 .WORD TTIINT .WORD TTIINT+2 .IF NE HSR$B ;If High Speed Ring Buffer support .BYTE 2. .BYTE 4. .WORD ^b<11> ;ABS/REL bit map .WORD HKPC09 .WORD HKPC09+2 .IFF ;NE HSR$B ;If no High Speed Ring Buffer support .BYTE 2. .BYTE 5. .WORD ^b<11> ;ABS/REL bit map .WORD HKPC08 .WORD HKPC08+2 .ENDC ;NE HSR$B .IF NE MTI$M ;If multiterminal time-out .BYTE 4. .BYTE 6. .WORD ^b<1111> ;ABS/REL bit map .WORD HKPC01 .WORD HKPC01+2 .WORD HKPC02 .WORD HKPC02+2 .ENDC ;NE MTI$M .IFF ;NE MTT$Y ;If not multiterminal .BYTE 14. .BYTE 7. .WORD ^b<11111111111111> ;REL/ABS bit map .WORD HKPC06 .WORD HKPC06+2 .WORD TTIINT .WORD TTIINT+2 .WORD HKPC10 .WORD HKPC10+2 .WORD TTOENB .WORD TTOENB+2 .WORD HKPC12 .WORD HKPC12+2 ;+ ; The next two words must remain commented out (see above)!!! ; .WORD HKPC13 ; .WORD HKPC13+2 ;- .WORD NULHOK .WORD NULHOK+2 .WORD PC1HOK .WORD PC1HOK+2 .ENDC ;NE MTT$Y .WORD 0. ;Terminate bootstrap table for PI .ENDC ;NE PRO$S BTBLEN ==: . .ASSUME < BTBLEN - BSTTBL > LE 256. ;Overlay must be smaller than 128. wds . = < < . + BD.BLK > / BK.BYT > * BK.BYT ;Adjust loc counter to block boundary .SBTTL End Of Boot Clean Up BOOTSZ ==: < . + BD.BLK > / BK.BYT ;Size of bootstrap in blocks . = < BOOTSZ * BK.BYT > ;Move top of ASECT to a block boundary ENDBST ==: . .END