.NLIST .INCLUDE /ASCII.MAC/ .INCLUDE /HWDF.MAC/ .INCLUDE /DSMAC.MAC/ .INCLUDE /MYMAC.MAC/ .LIST MODULE NAME=, VER=<2.2PL>, COMM=, TYPE= .NLIST .INCLUDE /XXDPCM.MAC/ .INCLUDE /XXDPDF.MAC/ .LIST FROM HMINIT IMPORT IN$ENG FROM HMROOT IMPORT D$RUNI, D$RCSR EXPORT QUALIFIED X$XDRV EXPORT QUALIFIED SYCSR., D$PUFD, DR$TRA, DR$DEV, DR$OPN, DR$RST .SBTTL RK05 device structure ; Registers DKCSR. =: ^O<177404> ; csr DK.STS =: ^O<-4> ; drive status register DK.ERR =: ^O<-2> ; error register DK.CSR =: ^O<0> ; control status register DK.WC =: ^O<2> ; word count (negative, increment until 0) DK.BUF =: ^O<4> ; current bus address register DK.DA =: ^O<6> ; disk address register ; ; Status ; DK.RDY =: ^O<100> ; ; CSR definitions ; DKERR$ =: ^O<100000> ; operation complete ("drive ready") DKRDY$ =: ^O<200> ; operation complete ("drive ready") DKWL. =: ^O<7*2> ; 16 ; Write Lock DKDRS. =: ^O<6*2> ; 14 ; Drive Reset DKRDC. =: ^O<5*2> ; 12 ; Read Check DKSIK. =: ^O<4*2> ; 10 ; Seek DKWRC. =: ^O<3*2> ; 06 ; Write Check DKRID. =: ^O<2*2> ; 04 ; Read DKWRT. =: ^O<1*2> ; 02 ; Write DKRST. =: ^O<0*2> ; 00 ; Controller Reset DKGO$ =: ^O<1> ; Go ; ; Disk Addr ; DKSEC. =: ^O<17> ; sector address bits (3..0) DKHID. =: ^O<20> ; head (4) DKCYL. =: ^O<40> ; cylinder (n*DKCYL.) (12..5) DKDN. =: ^C<^O<160000>> ; disk No (mask) (15..13) SYCSR. =: DKCSR. ; csr .PSECT XXDP9 .SBTTL Driver Transfer function X$XDRV: ; ; Separate driver code exists for each XXDP-supported system device ; ; DP.UFD = 0 ;3 ; UFD directory start block (from init) ; DP.SPC = 2 ;"FN.T" ; space filled "filnam.typ" ; DPSPC. = 10. ; ; 10-char name (6+1+3) ; DP.TER = 12 ;.WORD 0 ; 1-word zero terminator ; DPBBS. = 14 ; block length ; D$RLOW: D$PUFD: .WORD 3 ; ; first UFD/directory block (savm)(boot) D$PSPC: B.LKB 12 ; ; .ASCIZ "filnam.typ"<0> .BYTE 0 E.VEN D$PMON: .WORD ^D<24> ;30 ; first xmonitor block (savm)(boot) ; ; DR$TRA - Driver transfer function ; ; in R5 -> IOB ; IO.BLK ; IO.BUF ; IO.WCT ; DR.UNI ; ; CALL @DR.TRA(R5) ; ; fine R0/R1 unchanged ; R2..R4 burnt ; ; fail abort "? RD ERR" ; ; While the boot and the driver both support partial block reads, ; all monitor system device reads are for full blocks (see MO$CHN). ; PROCEDURE DR$TRA BEGIN PUSH LET R4 := #^O<13> LET DR.STS(R5) :B= #0 REPEAT LET R4 := R4 - #1 IF RESULT IS LE LEAVE LOOP LET R3 := (R5) ; CSR LET R1 := IO.BLK(R5) LET R2 := #^D<12> ; 12 sectors LET R0 := #0 LOOP LET R1 := R1 - R2 IF RESULT IS LO LEAVE LOOP LET R0 := R0 + #DKHID. END LET R1 := R1 + R2 LET R0 := R0 + R1 LET R1 :B= DR.UNI(R5) CCC LET R1 := R1 R.ROTATE 4 LET R0 := R0 SET.BY R1 LET DK.DA(R3) := R0 LET DK.WC(R3) := IO.WCT(R5) LET DK.WC(R3) := - DK.WC(R3) LET DK.BUF(R3) := IO.BUF(R5) LET (R3) := #DKRID.!DKGO$ REPEAT UNTIL #DKERR$!DKRDY$ SET.IN (R3) IF RESULT IS PL GOTO 100$ IF #40000 SET.IN (R3) LEAVE LOOP LET (R3) := #DKRST.!DKGO$ REPEAT UNTIL #DKERR$!DKRDY$ SET.IN (R3) UNTIL RESULT IS MI LET DR.STS(R5) :B= DR.STS(R5) - #1 LET R0 := #M$SRER JmpAbt 100$: POP ; restore R1/R1 RETURN END DR$TRA .SBTTL Get Device, Open File, Restore Driver functions (driver) ; ; DR$DEV - Get device name/unit/media function ; ; in R5 -> IOB ; ; CALL DR.DEV(R5) ; ; out R0 -> D$RDEV: drTdev structure ; ; Translate the DR.UNI ordinal to DV.UNI ascii ; Called by GetDev service and the Enable command ; PROCEDURE DR$DEV BEGIN LET R0 :B= DR.UNI(R5) + #'0 ; unit ordinal, asciify it LET D$RDEV+DV.UNI :B= R0 ; store past "DK" .ADDR R0 := #D$RDEV ; point to it RETURN END DR$DEV D$RDEV: .ASCII "DK" ;0 ;\ DV.NAM - driver device name ("DK") .ASCII <0> ;2 ;| DV.UNI - driver device unit ("0") .BYTE DVRK5. ;3 2 ;/ DV.MED - driver device media code ; ; DR$OPN - Open file function ; ; No status is sent back to the caller because only succesful opens return. ; Failed opens issue abort. ; ; in IO.SPC .ASCIZ "filnam.typ" ; ; CALL DR.OPN(R5) ; ; out R0 burnt ; R1 -> .ASCIZ "filnam.typ" ; DR.FNM .RAD50 /filnamtyp/ ; DI.SBL .WORD n ; start block file ; ; fail abort "? NOT FOUND filnam.typ" ; R0 = 0 ; PROCEDURE DR$OPN BEGIN CALL DU$LOO ; lookup LET R3 := R1 ; R1 -> entry filnamtyp LET R2 := R5 + #DR.FNM ; copy filnamtyp and first block LET (R2)+ := (R3)+ ; DR.FIL LET (R2)+ := (R3)+ ; DR.NAM LET (R2)+ := (R3)+ ; DR.TYP LET (R2) := 4(R3) ; DR.SBL - first file block RETURN END DR$OPN ; ; DU$LOO - Lookup file ; ; in IO.SPC -> .ASCIZ "filnam.typ" ; ; fine R1 -> directory entry: .RAD50 /filnamtyp/ ; fail abort "? NOT FOUND" ; PROCEDURE DU$LOO BEGIN LET DR.STS(R5) :B= #0 ; reset errors LET IO.BLK(R5) := @IO.UFD(R5) LET R3 := #0 ReaBlk ; read directory LET DR.ENT(R5) := #0 ; Block Loop 10$: LET R4 := DR.BUF(R5) ; R4 -> buffer TST (R4)+ ; R4 -> buffer record (skip next block link) LET R3 := R3 + #^D ; 28. entries per block ; Entry Loop LOOP LET DR.ENT(R5) := DR.ENT(R5) + #1 ; next (or first) entry IF DR.ENT(R5) HI R3 THEN ; if no more entries LET DR.ENT(R5) := DR.ENT(R5) - #1 ; no - backup ReaNxt ; read next directory block GOTO 60$ ; end of file GOTO 10$ ; restart block loop END IF (R4) NE #0 THEN ; if non empty/deleted entry? ; convert rad50 directory entry .ADDR R2 := #D$PSPC ; R2 -> driver spec ascii buffer LET R1 := R4 ; R1 -> .RAD50 /filnamtyp/ SpcAsc ; unradify LET R0 := R5 + #IO.SPC ; R0 -> I/O ascii spec CmpSpc ; and the verdict is? GOTO 40$ ; missmatch LEAVE LOOP ; match - we are done 40$: END LET R4 := R4 + #^O<22> ;18. ; next entry END ; and off we go again LET R1 := R4 ; R1 -> result ascii filespec RETURN ; File not found message and abort 60$: LET DR.STS(R5) :B= DR.STS(R5) + #1 ; DR.STS = 1 - file not found error .ADDR4 R0 := #M$SFNF ; R0 = "? NOT FOUND" (.ADDR R0 := #M$SFNF) ?? TypBrk ; LET R0 := R5 + #IO.SPC TypBrk ; "? NOT FOUND filnam.typ" LET R0 := #0 ; no message JmpAbt ; begone END DU$LOO ; ; DR$RST - Restore monitor function ; ; XXDP needs a special function to read the monitor disk image because it is a contiguous file. ; ; in IO.WCT = word count ; IO.BUF = store address ; IO.BLK = monitor relative block ; D$PMON is the monitor base block ; ; CALL DR.RST(R5) ; ; out IO.BUF = restored area ; ; DR$RST reads the MFD to get D$PMON (which ENABLE can modify) ; The assumption is that an ENABLED disk has the same monitor version ; PROCEDURE DR$RST BEGIN LET IO.BLK(R5) := IO.BLK(R5) + D$PMON ; relocate monitor block CALL @DR.TRA(R5) ; transfer RETURN END DR$RST ; Driver error messages M$SFNF: .ASCIZ "? NOT FOUND: " M$SRER: .ASCIZ "? RD ERR" .IF EQ * .EVEN .ENDC .IF EQ DKDR.V-3 E.VEN .ENDC .IF EQ DKDR.V-3 B.LKW 200 .ENDC .SBTTL Boot engine .ASECT . = ^O<0> BBSZ =: ^O<1000> ; boot block size BBCNT =: ^O ; boot block count X$XLOW: ; XXDP boot enters at location zero, like everyone else ; boot communication area PROCEDURE BO$PRI BEGIN NOP ;0000 ; boot primary entry point GOTO BO$CON ;0002 ; continuation END BO$PRI .WORD .+2 ;0004 ; bus trap vector .WORD 0 ;0006 ; .WORD .+2 ;0010 ; cpu trap vector .WORD 0 ;0012 ; B.LKW ;0014 ; bpt vector skipped B.LKW ;0016 ; B$OCSR: .WORD DKCSR. ;0020 ; CSR address (patch point) (note) PROCEDURE BO$CON BEGIN NOP ;0022 ; boot continuation GOTO BO$ENG ;0024 ; boot mainline END BO$CON .IF EQ DKDR.V-1 B.LKB 42 .ENDC .IF EQ DKDR.V-2 B.LKB 12 .WORD 0, 0 ;0040 B.LKB 24 .ENDC .IF EQ DKDR.V-3 .WORD 0 ;0026 .WORD 0 ;0030 .WORD 0 ;0032 .WORD 0 ;0034 .WORD 0 ;0036 .WORD 0 ;0040 .WORD 0 ;0042 .WORD 0 ;0044 .WORD 0 ;0046 .WORD 0 ;0050 .WORD 0 ;0052 .WORD 0 ;0054 .WORD 0 ;0056 .WORD 0 ;0060 .WORD 0 ;0062 .WORD 0 ;0064 .WORD 0 ;0066 .ENDC ; ; BO$ENG - Boot engine and start ; PROCEDURE BO$ENG BEGIN LET R5 := B$OCSR ; R5 -> RK11 csr LET R2 := DK.DA(R5) ; only disk addres LOOP LET R2 := R2 OFF.BY #DKDN. SET.BY #1*DKCYL.+1 ; only disk addres, Cyl 1, Sec 1 (block No 24) LET DK.DA(R5) := R2 ; set LET DK.WC(R5) := #^O<-7400> ; word count, 15. sectors LET DK.BUF(R5) := #^O<1000> ; address LET (R5) := #DKRID.!DKGO$ REPEAT UNTIL #DKERR$!DKRDY$ SET.IN (R5) IF RESULT IS PL THEN LEAVE LOOP END LET R0 := (R5) LET R1 := DK.ERR(R5) LET (R5) := #DKRST.!DKGO$ HALT LET DK.DA(R5) := R2 LET (R5) := #DKDRS.!DKGO$ ; drive reset REPEAT UNTIL #DK.RDY SET.IN DK.STS(R5) END LET (R5) := #DKWL.!DKGO$ ; write lock LET R2 := R2 OFF.BY #DKDN. CLC LET R2 := R2 L.ROTATE 4 LET D$RUNI := R2 LET (R5) := #DKRST.!DKGO$ LET D$RCSR := R5 ; IOB csr JUMPTO IN$ENG END BO$ENG B.LKB <^O> ; boot round-up END DKDRV .END