.MCALL .MODULE .MODULE MBOOT,VERSION=12,COMMENT=,AUDIT=YES ; 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 RT-11 magtape primary bootstrap .MCALL .ASSUME .IIF NDF MBT$16,MBT$16=0 ;This conditional will determine mini-handler ;and BPI ;0= 800 BPI - MT,MM ;1= 1600 BPI - MS,MM ;TMSCP (MU) is present for either one .SBTTL Symbol definitons ;+ ;TM11/TU10/TS03 device registers ;- MTS = 172520 ;Status register MTC = MTS+2 ;Command register MTBRC = MTC+2 ;Byte record counter MTCMA = MTBRC+2 ;Current menory address ;+ ;TM11/TU10/TS03 register bit assignments ;- TMSPF = 60011 ;Space forward TMRD = 60003 ;Read TMBSP = 60013 ;Backspace TMREST = 10000 ;Control reset TMEOF = 40000 ;Tape mark seen ;+ ;TJU16 device registers ;- MTCS1 = 172440 ;Control and status 1 MTWC = MTCS1+2 ;Word count MTBA = MTWC+2 ;Memory address MTFC = MTBA+2 ;Frame count MTCS2 = MTFC+2 ;Control and status 2 MTDS = MTCS2+2 ;Drive status MTTC = MTCS1+32 ;Tape control ;+ ;TJU16 register bit assignments ;- TJSPF = 31 ;Space forward TJRD = 71 ;Read TJBSP = 33 ;Backspace TJREST = 40 ;Control reset TJEOF = 4 ;Tape mark seen TJ8BPI = 1300 ;Density and format (800 BPT, NRZ) ;+ ;TS11 registers ;- TSDB = 172520 ;TS11 data register TSTSR = TSDB+2 ;TS11 status register ;+ ;TS11 function codes ;- CC.SRF = 100010 ;Space records forward CC.SRR = 140410 ;Space records reverse CC.RDN = 100001 ;Read forward CC.WRC = 140004 ;Set characteristics TSSPF = 77777 ;This is the record count for space forward ;+ ;TMSCP registers ;- MU$CSR = 174500 ;Control register for TMSCP UDAIP = MU$CSR ;Address and polling register UDASA = MU$CSR+2 ;Status and address register ;+ ;TMSCP ownership flags. ;- GO = 1 ;GO value OWN = 100000 ;UDA owns ring buffer entry FLAG = 40000 ;UDA should interrupt on ring transition ;+ ;TMSCP COMMAND PACKET OFFSETS ;Generic Command Packet Offsets and Field Lengths: ;- P.CRF = 0 ;4 Command reference number P.UNIT = 4 ;2 Unit Number ; = 6 ;2 Reserved P.OPCD = 10 ;1 Opcode ; = 11 ;1 Reserved P.MOD = 12 ;2 Modifiers P.BCNT = 14 ;4 Byte count P.BUFF = 20 ;12 Buffer descriptor P.CSIZ = 100 ;40 Total length of a packet ;+ ;REPOSITION Command Packet Offsets and Field Lengths: ;- P.RECC = 14 ;4 Replacement block number P.TMGC = 20 ;4 Tape Mark Count or N/A ;+ ;Set controller characteristics (TMSCP) ;- P.HTMO = 20 ;2 Host timeout ;+ ;TMSCP END AND ATTENTION MESSAGE OFFSETS ;Generic End Packet Offsets and Field Lengths: ;- P.CRF = 0 ;4 Command reference number P.UNIT = 4 ;2 Unit number ; = 6 ;2 Reserved P.OPCD = 10 ;1 Opcode (also called endcode) P.FLGS = 11 ;1 End message flags P.STS = 12 ;2 Status P.BCNT = 14 ;4 Byte count P.MSIZ = 100 ;40 Total length of a packet. ;+ ;READ, REPOSITION, WRITE, WRITE TAPE MARK end ;- P.POS = 34 ;4 Position (Object count) P.TRBC = 40 ;4 Tape record byte count (READ end) P.RCSK = 14 ;4 Records skipped (REPOSITION end) P.TMSK = 20 ;4 Tape Marks Skipped (REPOSITION end) ;+ ;TMSCP Status and Event codes ;- ST.MSK = 37 ;Status/event code mask ; = 0 ;Status/event code bit offset ; = 5 ;Status/event code field size ST.SUB = 40 ;Sub-code multiplier ST.SUC = 0 ;Success ST.OFL = 3 ;Unit-Offline ST.AVL = 4 ;Unit available ST.WPR = 6 ;Write Protected ST.BOT = 15 ;BOT Encountered ST.TM = 16 ;Tape mark encountered ST.RDT = 20 ;Record data truncated ST.POL = 21 ;Position lost ST.SEX = 22 ;Serious exception ST.LED = 23 ;LEOT detected ;+ ;TMSCP Control Packet Opcodes ;- OP.SCC = 4 ;Set controller characteristics OP.ONL = 11 ;ONLINE Command OP.RD = 41 ;READ Command OP.REP = 45 ;REPOSITION Command ;Read command opcodes bit 0 position is always a one. OP.END = 200 ;End packet flag (see note below) ;+ ;Note: End packet opcodes are formed by ORing the end packet flag to the ;command opcode. For example, OP.RD!OP.END = OP.RD endcode. If the ;endcode is OP.END alone then the command was unknown. If the endcode is ;OP.SEX!OP.END then the command ended with a serious exception. ;- ;+ ;TMSCP COMMAND MODIFIERS ;Generic Command Modifiers: ;- MD.CSE = 20000 ;Clear serious exception MD.RWD = 2 ;Rewind MD.REV = 10 ;Reverse ;+ ;Other symbolic definitions ;- MTSPC = TJSPC ;Get MT handler entry for space forward MTREAD = TJREAD ;MT handler entry for read MTBSPC = TJBSPC ;MT handler entry for backspace TSCB = 530 ;Absolute address of TSCBUF TSMB = TSCB+10 ;Absolute address of TSSBUF TPS = 177564 ;Terminal print status TPB = TPS+2 ;Terminal print buffer HNDSIZ = 210 ;Number of bytes to read in for handler RTCNT = 12 ;Retry count for magtape errors NOP = 240 ;Value of NOP instruction .SBTTL Mainline boot routine ;+ ;MBOOT ;Determines if TS11, TJU16, TM11 or TMSCP was the booted device. Moves ;appropriate handler to 400(8). Skips past HDR1* of first file on tape ;following this boot, then reads the secondary boot into core starting at ;1000. The secondary boot is assumed to be a SAV image, and the only ;locations honored in the first block are 40 and 42. When the secondary ;boot is completely in core, it is started at the address specified at 40. ;- .ASECT . = 0 .ENABL LSB NOP ;All boots must start with NOP BR MBOOT ;Branch around vectors at 4 and 10 ;+ ;Illegal memory reference trap vector ;- TMHERE ;Address of memory exception routine 340 ;+ ;Illegal instruction trap ;- HERR ;Address of boot error message routine 340 MBOOT: TST @#MTCS1 ;See if TJU16 present BR MTSTRT ;If we get here, TJU16 is present on ;configuration. ;+ ;The only way to get here is if not TJU16. MTCS1 reference caused TRAP to 4. ;Assume that we are using TM11, TS11, or TMSCP. ;- TMHERE: MOV #<400>,R4 ;Point R4 to handler area MOV #,R5 ;Get loop count for handler transfer (+10) .IF EQ MBT$16 ;If not 1600 BPI MOV #NOTMSCP,4 ;Setup address of memory exception for TM & TS MOV #TUSPC,R1 ;R1 -> start of TMSCP handler ;such a beast TST @#MU$CSR ;See if TMSCP tape MOV R0,TU.UNT ;Save unit number MOV R2,TU.RNG ;Save pointer to rings BR COPTU ;Go do common routine to read in handler NOTMSCP:MOV #TMSPC,R1 ;R1 -> start of TM11 handler .IFF ;If 1600 BPI MOV #TSSPC,R1 ;R1 -> start of TS11 handler .ENDC ;EQ MBT$16 COPHND: MOV (R1)+,(R4)+ ;Move specific handler in starting at 400 DEC R5 ;Decreament word count BHI COPHND ;Loop until done BR MTSTRT ;Move in the correct handler. Must branch ;to get past .MODULE and clock vector ;+ ;MTSTRT ;At this point, the proper magtape handler is at 400, and the word at 402 can ;Be tested by the secondary boot to determine what device is. 402 will be ;equal to TJSPF if booting a TJU16 tape, TMSPF if TM11, TSSPF if booting a ;TS11, and TUSPF if a TMSCP tape. ;- .=120 MTSTRT: MOV #<1000>,SP ;Set initial stack to 1000 MOV #HERR,4 ;Set vector at 4 so that any further error ;Cause boot error message CALL 400 ;Space past HDR1* (MT SPACE FORWARD) BVS HERR ;Unexplained error BCC HERR ;No EOF so it's not our tape MOV SP,R1 ;Start reading secondary boot into 1000 5$: CALL 412 ;Read first block (MT READ) BVC 10$ ;Branch if no error CALL RETRY ;Otherwise, backspace for retry BR 5$ 10$: BCS HERR ;If C bit set premature EOF - give error MOV @#1040,(PC)+ ;Save the start address STADDR: .WORD 0 ;Start address for next routine to execute 15$: CALL 412 ;Read next blocks (MT READ) BVC 20$ ;Branch if no error CALL RETRY ;Otherwise, backspace for retry BR 15$ 20$: BCS 25$ ;EOF detected - start secondary boot ADD SP,R1 ;Bump core address for next read BR 15$ ;And go read it in 25$: CMP STADDR,SP ;Is start address within program? (SP=1000) BLO 30$ ;Branch if not - just halt on this error CALLR @STADDR ;Start secondary boot program 30$: HALT ;No start address ;+ ;Retry ;- RETRY: DEC (PC)+ ;Give up after 10 errors RTCNT BEQ HERR ;No errors left CALL 426 ;Back up space (MT BACK SPACE) BLOS HERR ;Replaces BVS and BCS HERR CvZ=1 RETURN .DSABL LSB .SBTTL Supporting routines ;+ ;Routine to print BOOT I/O error message ;- .ENABL LSB HERR: MOV #BMSG,R0 5$: TSTB @#TPS ;Wait for printer ready BPL 5$ MOVB (R0)+,@#TPB ;Print character BPL 5$ ;And wait for ready BR . BMSG: .ASCIZ <15><12>"?BOOT-U-I/O error"<15><12><200> .EVEN .DSABL LSB .IF EQ MBT$16 ;If not 1600 BPI COPTU: MOV (R1)+,(R4)+ ;Move specific handler in starting at 400 DEC R5 ;Decreament word count CMP R5,#/2 ;Copy just the call routines BHI COPTU ;Loop until done MOV #MUDO,R1 ;Point to general routine for TMSCP boo BR COPHND ;Copy the rest TUSPC: JSR R5,<.+TBLEND-.> ;Forward space one block .WORD OP.REP ;Reposition command .WORD MD.CSE ;Clear serious excep .WORD 77777 ;Flag word to indicate spacing (# of ;records to space - something big) TUREAD: JSR R5,<.+TBLEND-.> ;Read one block .=412 .WORD OP.RD ;Read command .WORD MD.CSE .WORD 1000 ;Flag word (low byte cleared) to ;indicate read. Also contains byte ;count (512.) NOP ;Pad so TKBSPC .=426 TUBSPC: JSR R5,<.+TBLEND-.> ;Backspace one block .WORD OP.REP ;Reposition command .WORD MD.CSE!MD.REV ;Rewind and same as TKSPC .WORD 1 ;Pointer to ring for port (number of ;records to space (exactly one) TBLEND: ;Mark end of specially placed calles for TMSCP .ENDC ;EQ MBT$16 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; TM11, TS11, TJU16 and TMSCP mini-handlers ; ; ; ; All handlers are capable of spacing forward to eof, readingone 256 ; ; word block, or backspacing one record. After MBOOT has determined ; ; which device is being used, the handler for the appropriate device ; ; is moved to start at 400(8) (they are pic), and they are used from ; ; then on at that place in core to support all the I/O done by MBOOT ; ; and MSBOOT. ; ; ; ; Each handler has three entry points: ; ; 400: Spaces forward to tape mark ; ; 412: Reads one 256 word record ; ; 426: Backspaces over one record ; ; ; ; On return from the handler, condition codes serve as flags: ; ; If C=1 EOF occurred during operation ; ; IF V=1 An error occured during operation ; ; IF C=0 and V=0 The operation was successful ; ; ; ; The V bit should always be checked before the C bit, because if ; ; the V bit is set, the C bit will always be set. ; ; ; ; Both handlers avoid use of interrupts ; ; ; ; R0 and R2 are corrupted ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; . = 400 .SBTTL TJU16 handler .ENABL LSB TJSPC: MOV #TJSPF,R0 ;Code to space forward into R0 CLR R2 ;Maximum number of records possible BR 5$ NOP ;Pad with word to start next command at 412 TJREAD: MOV #TJRD,R0 ;Code to read into R0 MOV #<-256.>,@#MTWC ;Read one block BR 5$ TJBSPC: MOV #TJBSP,R0 ;Code to backspace into R0 MOV #<-1>,R2 ;One record 5$: MOV #MTDS,R4 ;Get drive status register TSTB @R4 ;Wait for drive ready BPL 5$ ;Branch if not .IF NE MBT$16 ;If 1600 BPI MOV #<2300>,@#MTTC ;Set phase encoded 1600 BPI mode .ENDC ;NE MBT$16 BIS #,@#MTCS2 ;Reset drive in case error 10$: TSTB @R4 ;Wait for reset to complete BPL 10$ ;Branch if not MOV R2,@#MTFC ;Set frame count for space funcs MOV R1,@#MTBA ;Set memory address for transfer MOV R0,@#MTCS1 ;Initiate function 15$: TSTB @R4 ;Wait for drive to finish BPL 15$ ;Branch if not BIT #,@R4 ;Tape mark seen on operation? BNE 20$ ;Yes, set carry (V is already clear from TSTB) TST @#MTCS1 ;Any errors? BPL 25$ ;No SEV ;Yes, set overflow to signal error 20$: SEC ;Set carry to signal EOF 25$: RETURN TJEND: ;End of TJU16 handler .IF GT .ERROR /2 ;Over by this many words .ENDC ;GT .DSABL LSB .IF EQ MBT$16 ;If not 1600 BPI .SBTTL TM11 HANDLER .ENABL LSB TMSPC: MOV #TMSPF,R0 ;Space forward code into R0 CLR R2 ;Maximum number of records possible BR 5$ NOP ;Pad so that next command starts at 412 TMREAD: MOV #TMRD,R0 ;Read code into R0 MOV #<-512.>,R2 ;One 256 word block NOP ;Pad so TMBSPC is at TMSPC+24 BR 5$ TMBSPC: MOV #TMBSP,R0 ;Backspace code into R0 MOV #<-1>,R2 ;One record 5$: MOV #MTC,R4 ;Get command register TSTB @R4 ;Wait for drive ready BPL 5$ ;Branch if not BIS #,@R4 ;Reset controller in case of error 10$: TSTB @R4 ;And wait for the reset BPL 10$ ;Branch if not MOV R2,@#MTBRC ;Set frame or byte count MOV R1,@#MTCMA ;Set transfer address MOV R0,@R4 ;and initiate command 15$: TSTB @R4 ;Wait for ready BPL 15$ ;Branch if not BIT #,@#MTS ;Tape mark seen? BNE 20$ ;Yes, set carry and return TST @R4 ;Any errors? BPL 25$ ;No, just return SEV ;Yes, set V bit to indicate error 20$: SEC ;Set carry to indicate EOF 25$: RETURN TMEND: ;End of TM11 handler .DSABL LSB .IF GT .ERROR /2 ;Over by this many words .ENDC ;GT .IFF ;If 1600 BPI .SBTTL TS11 handler ;+ ;This is the MBOOT mini-handler for the TS11 the entry points are the same ;as the MT and TJ handlers. TS11DO is the TS11 message packet driver routine. ;- .ENABL LSB TSSPC: MOV #TSSPF,R2 ;Set up for space to TM JSR R5,TS11DO ;Execute a space to TM .WORD CC.SRF ;Space to TM function code TSREAD: MOV R1,R2 ;R2 = address JSR R5,TS11DO ;Execute read block @R1 .WORD CC.RDN ;Read function code NOP ;Pad so TSBSPC=MTBSPC NOP ;Pad so TSBSPC=MTBSPC TSBSPC: MOV #<1>,R2 ;Reverse 1 record JSR R5,TS11DO ;Execute backspace .WORD CC.SRR ;Backspace function TS11DO: BR TSSET ;First time through, initialize TS11 ;NOP ;Note, BRANCH is changed to NOP after 1st time MOV #TSCB+6,R0 ;Point to end of TS command buffer MOV #<1000>,@R0 ;Read count, not used otherwise CLR -(R0) ;High order address or zero MOV R2,-(R0) ;Count or buffer address MOV (R5)+,-(R0) ;Function code MOV (SP)+,R5 ;Restore R5 MOV #TSTSR,R2 ;Point to status register 5$: TSTB @R2 ;Wait for ready bit BPL 5$ ;Branch if not done MOV R0,-2(R2) ;Start operation 10$: TSTB @R2 ;Wait for ready bit BPL 10$ ;Branch until done TST @R2 ;Special condition? BPL 25$ ;Branch if no BIT #<12>,@R2 ;Termination class of 0 or 2? BNE 15$ ;Branch if no (issue hard error) TST @#TSMB+6 ;EOF? BMI 20$ ;Branch if yes 15$: SEV ;Set V bit 20$: SEC ;EOF bit 25$: RETURN TSCBUF: .WORD CC.WRC,TSMB,0,16 ;TS command buffer TSSBUF: .WORD TSMB,0,16,0,0,0,0 ;TS message buffer ;+ ;Note that this is the end of the actual handler. The following routine is ;only called the first time the handler is entered. It can then be written ;over by the stack with no adverse effects. ; ;Note and attention message with interrupts disabled can occur here. It will ;be indicated in the TSTSR as a termination class of 202 and takes about a ;second to clear. Meanwhile any new command is ignored. If it occurs we ;must wait till only the subsystem ready is set. ;- TSSET: MOV #,TS11DO ;Write over BR instruction to ensure once only MOV #TSCB,@#TSTSR-2 ;Tell TS11 'We're ready for him!' 30$: CMP #<200>,@#TSTSR ;Is the TS11 really ready? BNE 30$ ;Branch if no ;Note if the controller is corrupted we will ;hang here BR TS11DO ;Return to start TSEND: ;End of TS11 handler .DSABL LSB .IF GT ;SEE NOTE ABOVE ABOUT STACK .ERROR /2 ;Over by this many words .ENDC ;GT .ENDC ;EQ MBT$16 .IF EQ MBT$16 ;If not 1600 BPI .SBTTL TMSCP handler .ENABL LSB ;+ ; This subroutine clears the MSCP command buffer and inserts the generic ; parameters required my most command. ; R5 contains the op code ; R4 will be used to point to the command buffer ;- MUDO: MOV (PC)+,R2 ;Get pointer to rings TU.RNG: .WORD 0 ;Contains pointer to rings MOV R2,R4 ;R4 -> Message buffer + 2 TST (R4)+ ;Get packet address MOV @R4,R4 ;In R4 CMP (R4)+,(R4)+ ;Point to UNIT offset in command buf. .ASSUME EQ 4 MOV (PC)+,(R4)+ ;Select the unit number. TU.UNT: .WORD 0 ;Contains unit number CLR (R4)+ ;Now point beyond to opcode word and ;clear out word .ASSUME EQ 10 MOV (R5)+,(R4)+ ;Select the opcode. .ASSUME EQ 12 MOV (R5)+,(R4)+ ;Set modifiers for command .ASSUME EQ 14 .ASSUME EQ 14 MOV @R5,(R4)+ ;Is this a space or a read or space ; forward/backward depends on low byte ; off. 14 on buffer (P.BCNT or P.RECC) CLR (R4)+ ;Clear high part of byte count CLR @R4 ;Clear low part of buffer address TSTB @R5 ;Read or space forward/backward? BNE 10$ ;Not a read, skip next .ASSUME EQ 20 MOV R1,@R4 ;Read into loc 1000 10$: BIS #,@R2 ;Own the message buffer MOV @R2,4(R2) ;Make it same in the port a reply buf. TST @#UDAIP ;Read the AIP to start it 15$: TST @R2 ;Is message ownership bit clear BMI 15$ ;Loop till it is MOV (SP)+,R5 ;Restore R5 MOV -2(R2),R4 ;Get the response packet address ADD #,R4 ;Point to status word .ASSUME EQ 12 TSTB @R4 ;Test success and point to status word .ASSUME EQ 0 BEQ 20$ ;Then go get next. CMPB #,@R4 ;TM? BEQ 25$ ;Say EOF found. CMPB #,@R4 ;BOT? BEQ 20$ ;Yes, treat as success SEV ;None recoverable error RETURN 20$: TST (PC)+ ;Make sure C/V bits are clear 25$: SEC ;TM found, set for retries CLV ;No error unless C set for TM found RETURN TUEND: ;End of TMSCP handler .DSABL LSB .IF GT <+-174> .ERROR <+-174>/2 ;Over by this many words .ENDC ;GT <+-174> .ENDC ;EQ MBT$16 .END