.MCALL .MODULE .module DY,VERSION=107,COMMENT=,AUDIT=YES .Nlist bex .psect dydvr ;Force PSECT ordering for programme portion. .psect dyboot .psect program .psect mesage con Vermes: .asciz /DY Extended Handler, V2c, 9-Sep-86/ ;1 Modifications for the Dilog DQ419 DY controller ;1 *********************************************** ;1 Allow use of double sided drives; ;1 Allow use of full 22-bit addressing if DY$22B non-zero; ;1 ONLY ON SIGMA/DILOG BOARDS - MTI 22-BIT ADDRESSING IS DIFFERENT!!!! ;1 Allow to be a mapped handler under TSX-plus; ;1 Pinch Peter Miedecke's good ideas from his V4 handler. ;1 Provide FORMAT function to allow formatting under TSX safely! ;1 Add ideas for other controllers ;1 Chester Wilson, Charleville, Australia ;1 1-Nov-85 ;1F - Fix bug in mmgt formatting code (bic -> bis) ;1G - Add writing home block to initialization (for DIR & BUP) ;2 - Reorganize problems with memory mapping which caused disaster on ; crossing page boundaries under TSX. ;2a - Bug fix in WDT code ;2b - [9-Apr-86] Further, ibid, & add patch "adc (sp)" ;2c - [9-Sep-86] Remove error checking code from handler format code or ; tells you you have a disc with an error because it is unformatted! .Sbttl Ideas for different controllers: (users, please add your own!) .if eq 1 Sigma/Dilog DQ419: (default) 22 bit addressing is enabled by setting the bit in the command. An extra phase is added to all cycles requiring a memory access. In this cycle the high-order address is passed to the controller, as six bits right justified. The bits and are not used. MTI: (select if MTI$$ is set non-zero) - CODE NOT TESTED FOR THIS YET! 22 bit addressing is enabled by setting the bit in the command. An extra phase is added to all cycles requiring a memory access. In this cycle the high order four bits of the address are passed to the controller, right justified. Bits 16 and 17 still need to be set in the command word as per a DEC 18-bit controller. General Robotics: DSD: .endc .Sbttl TSX Problem: .if eq 1 TSX makes assumptions about its devices, and refuses to allow its assumptions to be altered. DY is forced into being an 18-bit handler and may not be mapped. This is hopeless, and I hope an option will become available in later versions of TSX to get around this. Call it DA and assign DA DY, DA0 DY0, and DA1 DY1 on all start-up files and you obviate this problem in a messy way. Otherwise you must patch either a TSX object file or the TSX.SAV file. Sigh. .endc .Sbttl FORMAT function details .if eq 1 SPFUN 200: Requires values in buffer - First byte: 0 = side 0, NZ = side 1 Second byte: 0 = single density, NZ = double and Block Number: 0 = soft, NZ = hard format The Sigma/Dilog protocol is assumed. I hope this goes for all controllers! Command: 10 + <20 if unit 1> + <400 if double dens> + <1000 for side 1> Followed by (in data register) 111 for soft format, or 222 for hard format. .endc ; COPYRIGHT (c) 1984 BY ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ALL RIGHTS RESERVED. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED ; ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND 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. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY ; TRANSFERRED. ; ; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE ; AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT ; CORPORATION. ; ; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS ; SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. .SBTTL MACROS AND DEFINITIONS .ENABL LC .MCALL .DRDEF .ADDR .ASSUME .BR .DSTATUS=342 SYSPTR = 54 PNPTR = 404 .MACRO BNE. LABEL,?ALT BEQ ALT JMP LABEL ALT: .ENDM .IIF NDF DYT$O, DYT$O = 0 .IIF NDF DY$DD, DY$DD = 0 .IIF NDF DY$CS2 DY$CS2 == 177150 .IIF NDF DY$VC2 DY$VC2 == 270 .iif df TSX$P mmg$t=1 .iif ndf mmg$t mmg$t=0 .iif eq mmg$t dy$22b == 0 ;1 If memory management, .iif ndf DY$22B DY$22B == 1 ;1 default to 22-bit addressing .iif ndf mti$$ mti$$ == 0 ;1 Default to NOT MTI controller .DRDEF DY,6,FILST$!SPFUN$!VARSZ$,494.,177170,264 ;Bits in CSR CSGO = 1 ;"GO" bit ;10,4,2: used for commands CSUNIT = 20 ;Set if unit 1 CSDONE = 40 ;Set if done (-> interrupt if CSINT set) CSINT = 100 ;Set if desire interrupt CSTR = 200 ;Set when ready for next piece of data CSDN = 400 ;Set for double density CSHEAD = 1000 ;Set for head 1 (= side 1 of disc) cs22bit = 2000 ;1 Set if full 22-bit addressing required CSRX02 = 4000 ;Set if RX02 controller csma16 = 10000 ;Extended memory: MTI bit 16 csma17 = 20000 ;ibid, bit 17 CSINIT = 40000 ;Set by user to re-init DY CSERR = 100000 ;Set if error DNERR = 20 ;Density error (see ESDNER) ; - Commands CSFBUF = 0*2 ;Fill buffer CSEBUF = 1*2 ;Empty buffer CSWRT = 2*2 ;Write CSRD = 3*2 ;Read csdnft = 4*2 ;1 Set media density/format CSRDST = 5*2 ;Read status CSWRTD = 6*2 ;Write deleted data CSMAIN = 7*2 ;Read error code .ASSUME CSRD&2 NE 0 .ASSUME CSWRT&2 EQ 0 .ASSUME CSWRTD&2 EQ 0 ;Data Register Bits ESCRC = 1 ;CRC Error ESPAR = 2 ;Side Ready (double sided disc in place) ESID = 4 ;Init done ESSID1 = 10 ;AC low [? differs between DILOG & DEC] ESDNER = 20 ;Density error ESDN = 40 ;Density of disc in drive (1 = double) ESDD = 100 ;Deleted data ESDRY = 200 ;Drive ready DDNBLK = DYDSIZ*2 DYNREG = 3 RETRY = 8. SPFUNC = 100000 ;SPFUN flag in command word fmt$fn = 200 ;1 Format function SIZ$FN = 373 ;Read volume size WDD$FN = 375 ;Write deleted data WRT$FN = 376 ;Write track/sector RED$FN = 377 ;Read track/sector .SBTTL INSTALLATION CHECKS .ASECT . = 176 INSCSR: . = 200 NOP BIT #CSRX02,@INSCSR ;Make sure controller is RX02 BNE O.GOOD BR O.BAD FINDRV: .ADDR #DEVNAM,R0 .ADDR #DAREA+1,-(SP) EMT .DSTATUS BCS O.BAD MOV DAREA+4,R1 ;Check to see if handler loaded BEQ O.BAD BR O.GOOD DAREA: .BLKW 4 DEVNAM: .RAD50 /DY / BAREA: .BYTE 17,10 .BLKW .BLKW .WORD 256. .WORD 0 .IIF GT,<.-356> .ERROR .SBTTL SET OPTIONS .DRSET CSR, 160000, O.CSR, OCT .IF EQ DYT$O .DRSET VECTOR, 500, O.VEC, OCT .IFF; EQ DYT$O .DRSET VECTOR, +1, O.VEC, OCT .DRSET CSR2, 160000, O.CSR2, OCT .DRSET VEC2, +1+6, O.VEC2, OCT .ENDC .DRSET RETRY RETRY, O.RTRY, NUM .IF NE ERL$G .DRSET SUCCES, -1, O.SUCC, NO .ENDC .DRSET WRITE, 1, O.WP, NO BTCSR = ++1000 O.CSR: CMP R0,R3 BLO O.BAD MOV R0,INSCSR .ADDR #BAREA+4,R1 .ADDR #1000,R2 MOV R2,(R1) MOV #BTCSR/1000,-(R1) TST -(R1) MOV R0,R3 MOV R1,R0 EMT 375 BCS O.BAD MOV R3,(R2) MOV R1,R0 INCB 1(R0) EMT 375 BCS O.SYWL MOV R1,R0 DECB 1(R0) MOV #1,2(R0) EMT 375 BCS O.BAD .IF EQ DYT$O MOV R3,DYCSA .IFF MOV R3,DYCSR .ENDC O.GOOD: TST (PC)+ O.BAD: SEC RETURN O.SYWL: ADD #2,@SP BR O.BAD .IF EQ DYT$O O.VEC: CMP R0,R3 BHIS O.BAD BIT #3,R0 BNE O.BAD MOV R0,DYSTRT BR O.GOOD .IFF; EQ DYT$O O.CSR2: CMP R0,R3 BLO O.BAD MOV R0,DYCSR2 BR O.GOOD O.VEC: O.VEC2: CMP R0,#500 BHIS O.BAD BIT #3,R0 BNE O.BAD .ADDR #DY$VTB-1,R3,ADD MOV R0,@R3 BR O.GOOD .ENDC O.RTRY: CMP R0,R3 BHI O.BAD MOV R0,DRETRY BNE O.GOOD BR O.BAD .IF NE ERL$G O.SUCC: MOV #0,R3 N.SUCC: .ASSUME O.SUCC+4 EQ N.SUCC MOV R3,SCSFLG BR O.GOOD .ENDC O.WP: NOP CLR R3 N.WP: .ASSUME O.WP+4 EQ N.WP MOV R3,O.WPF MOV R1,R3 CMP R3,#DYT$O*2+1 BHI O.BAD .ADDR #DYWPRO,R0 ADD R3,R0 MOVB (PC)+,(R0) O.WPF: .BLKW 1 CALL FINDRV BCS O.GOOD CMP @#SYSPTR,R1 BHI 10$ MOV #100000,DYW1-DYLQE(R1) 10$: ADD R3,R1 MOVB O.WPF,DYWPRO-DYLQE(R1) BR O.GOOD .IIF GT,<.-1000> .ERROR .SBTTL DRIVER REQUEST ENTRY POINT .ENABL LSB .DRBEG DY BR DYENT DYWPRO: .REPT DYT$O+1 .BYTE 0,0 .ENDR .ASSUME . LE DYSTRT+1000 .IF NE ERL$G SCSFLG: .WORD 0 .ENDC .ASSUME . LE DYSTRT+1000 .IF NE DYT$O .DRVTB DY,DY$VEC,DYINT .DRVTB ,DY$VC2,DYINT .ASSUME . LE DYSTRT+1000 .ENDC DYENT: MOV (PC)+,(PC)+ DRETRY: .WORD RETRY .ASSUME . LE DYSTRT+1000 DYTRY: .WORD 0 MOV DYCQE,R5 MOV (R5)+,R3 .if eq dy$22b ;1 If require 22-bit addressing, set MOV #CSGO!CSRD!CSINT,R4 .iff ;1 relevant bit in CSR word. mov #csgo!csrd!csint!cs22bit,r4 .endc clr (pc)+ ;1 Flag to provide interrupt jump rawflg: 0 ;1 without customary processing. MOVB (R5)+,R1 MOVB (R5)+,R0 BIC #^C<7>,R0 MOV R0,R2 ASR R0 .IF EQ DYT$O BNE 5$ .ENDC BCC 1$ BIS #CSUNIT,R4 1$: .IF NE DYT$O MOV (PC)+,-(SP) DYCSR = . .WORD DY$CSR .ASSUME . LE DYSTRT+1000 ASR R0 BNE 5$ BCC 2$ MOV (PC)+,(SP) DYCSR2 = . .WORD DY$CS2 .ASSUME . LE DYSTRT+1000 2$: MOV (SP)+,DYCSA .ENDC cmpb r1,#fmt$fn ;1 Check for format spfun bne 25$ ;1 jmp format ;1 25$: ;1 .IF EQ DY$DD ASL R2 .ADDR #SAVDEN,R2,ADD MOV R2,(PC)+ DENPTR: .WORD 0 BIS @R2,R4 .IFF BIS #CSDN,R4 CMPB R1,#SIZ$FN BNE 3$ .IF EQ MMG$T MOV #DDNBLK,@(R5)+ .IFF MOV #DDNBLK,-(SP) MOV DYCQE,R4 CALL @$PTWRD .ENDC JMP DYDONE .ENDC 3$: .IF EQ MMG$T MOV (R5)+,R0 .IFF .if eq dy$22b ;1 Code differs between 18 & 22 bit addressing CALL @$MPPTR MOV (SP)+,R0 MOV R4,(PC)+ 35$: .BLKW MOV (SP)+,R4 BIT #1700,R4 BNE. DYERR SWAB R4 BIS 35$,R4 .iff ;1 call @$mpptr ;1 Mpptr returns full 22 bit address mov 2(sp),r0 ;1 but it is left-shifted 4 places ash #-4,r0 ;1 too far for us. mov r0,(pc)+ ;1 Hold high-order address for later. himem: 0 ;1 (needs extra step in fill/empty buffer) mov (sp)+,r0 ;1 Low order bits tst (sp)+ ;1 .endc ;1 (Note no use made of 18-bit bits in CSR ;1 if Sigma/Dilog board) .ENDC MOV @R5,WRDCNT BPL 4$ ASL (PC)+ DYW1: .WORD .-. .ASSUME . LE DYSTRT+1000 BCS 33$ CLR -(SP) MOVB Q.UNIT-Q.WCNT(R5),(SP) BIC #<^C3>,(SP) .ADDR #DYWPRO,(SP),ADD; TO UNIT OFFSET TSTB @(SP)+ BNE. DYERR 33$: ADD #CSWRT-CSRD,R4 NEG WRDCNT 4$: ASL R1 BEQ 6$ MOV R1,R5 ADD PC,R1 ADD CHGTBL-.(R1),R4 .IF EQ DY$DD SUB #377*400!SIZ$FN*2,R5 BEQ 7$ .ENDC .IF EQ MMG$T CLR (R0)+ .IFF MOV R4,-(SP) MOV DYCQE,R4 CLR -(SP) CALL @$PTWRD .if df tsx$p add #2,r0 ;1 If TSX, can't trust R0 to hold legal addr adc (sp) .iff TST (R0)+ .endc MOV (SP)+,R4 .ENDC BR 7$ 5$: JMP DYERR 6$: ASL R3 TST @R5 .if eq mmg$t ;1 BEQ DYDONE .iff ;1 bne 65$ ;1 jmp dydone ;1 65$: ;1 .endc ;1 .IF EQ DY$DD TST @R2 BNE 7$ ASL R3 .ENDC 7$: MOV R0,BUFRAD MOV R3,DYLSN MOV R4,(PC)+ DYFUN2: .WORD 0 .IF EQ DY$DD MOV R5,(PC)+ SIZFLG: .WORD 0 .ENDC MOV #CSINT,R0 CALL INWAIT .BR DYINIT .DSABL LSB .SBTTL START TRANSFER OR RETRY .ENABL LSB DYINIT: .IF EQ DY$DD TST SIZFLG BNE 4$ CALL INWAIT BIT #ESDRY,(R5) .if eq mmg$t ;1 BEQ DYERR .iff ;1 bne d0 ;1 jmp dyerr ;1 d0: ;1 .endc ;1 mov (r5),r1 ;1 Get density of side 0 bic #^c,r1 ;1 mov r1,(pc)+ ;1 d1: 0 ;1 add #cshead,r0 ;1 Set up to check side 1 mov (r5),r1 ;1 bit #espar,r1 ;1 See if double sided drive. beq 111$ ;1 No. Leave R1<>D1 inc rawflg ;1 Take it errors and all. call inwait ;1 mov (r5),r1 ;1 Get density of side 1 tst (r4) ;1 bmi 111$ ;1 If error, none on this side. bic #^c,r1 ;1 111$: mov #494.,-(sp) ;1 Assume DX, single sided. cmp r1,d1 ;1 See if same both sides. bne 112$ ;1 Differ - give him first side only asl (sp) ;1 Same - double whatever it be 112$: tst d1 ;1 See if double density beq 113$ ;1 Single. asl (sp) ;1 113$: ;1 .IF EQ MMG$T MOV (SP)+,@BUFRAD .IFF MOV DYCQE,R4 CALL @$PTWRD .ENDC BR DYDONE .ENDC 4$: .IF NE MMG$T MOV R0,DYFUN2 .ENDC BIT #1*2,R0 BNE 5$ CALL DOSILO 5$: CALL DOXFER BIT #1*2,R0 BEQ 7$ TST R0 BPL 6$ BIT #ESDD,@R5 BEQ 6$ .IF EQ MMG$T MOV BUFRAD,R2 INC -(R2) .IFF MOV R4,R1 MOV DYCQE,R4 MOV #1,-(SP) SUB #2,Q.BUFF-Q.BLKN(R4) .if df tsx$p cmp q.buff-q.blkn(r4),#140000 ;1 Differs in TSX mapping .iff ;1 (PAR6 lower boundary) CMP Q.BUFF-Q.BLKN(R4),#20000 .endc BHIS 55$ ADD #20000,Q.BUFF-Q.BLKN(R4) SUB #200,Q.PAR-Q.BLKN(R4) 55$: CALL @$PTWRD MOV R1,R4 .ENDC 6$: CALL DOSILO 7$: TST R0 BMI DYDONE MOV R3,R2 ASL R2 ADD R2,(PC)+ BUFRAD: .WORD 0 .IF NE MMG$T BCC 8$ .if ne dy$22b ;2 inc himem ;2 .iff ;2 ADD #10000,R0 .endc ;2 .ENDC 8$: INC (PC)+ DYLSN: .WORD 0 SUB R3,(PC)+ WRDCNT: .WORD 0 BHI 4$ BIT #1*2,R0 BNE DYDONE MOV #1,WRDCNT .if df tsx$p mov r4,-(sp) ;1 Mapping returns low order in r4 .iif ne mti$$, bic #,r0 ;1 MTI board needs these reset. call mapadr ;1 Get physical mapping of ZERO .word map-zero ;1 mov r4,bufrad ;1 Low order in r4 .if ne mti$$ ;1 If MTI board, need to juggle mem addr bits asr r3 ;1 to put bits bcc 111$ ;1 16 and 17 into bis #csma16,r0 ;1 their correct positions 111$: asr r3 ;1 in the status bcc 112$ ;1 word. bis #csma17,r0 ;1 112$: ;1 .endc ;1 mov r3,himem ;1 High order in r3 mov (sp)+,r4 .iff .ADDR #ZERO,R3 MOV R3,BUFRAD .IF NE MMG$T .if eq dy$22b ;1 If not 22-bit addressing clear CSR bits BIC #30000,R0 .iff ;1 If 22-bit addressing, clear HIMEM .iif ne mti$$, bic #,r0 ;1 Needed also if MTI board. clr himem ;1 .endc ;1 .ENDC .endc .IF EQ DY$DD MOV #3,R1 BIT #CSDN,R0 BEQ 9$ ASR R1 9$: BIT R1,DYLSN .IFF BIT #1,DYLSN .ENDC BNE 4$ .SBTTL DONE WITH I/O, FINISH UP AND EXIT DYDONE: .IF NE ERL$G TST SCSFLG BNE 10$ MOV DYCQE,R5 MOV #DY$COD*400+377,R4 CALL @$ELPTR .ENDC 10$: dyhome: ;1 CLR @DYCSA 11$: .DRFIN DY DYABRT: MOV (PC)+,-(SP) DYCSA: .WORD DY$CSR .ASSUME . LE DYSTRT+1000 MOV #CSINIT,@(SP)+ CLR DYFBLK+2 BR 11$ DYERR: MOV DYCQE,R4 BIS #HDERR$,@-(R4) BR 10$ .DSABL LSB .SBTTL INWAIT - START FUNCTION AND WAIT FOR INTERRUPT FROM FLOPPY INWAIT: MOV (SP)+,INTRTN MOV R0,@DYCSA RETURN .SBTTL INTERRUPT ENTRY POINT .DRAST DY,5,DYABRT .FORK DYFBLK CALL SETDY bpl intdsp ;1 If ok, always give it back to him. tst rawflg ;1 If error, see if he wants it straight bne 20$ ;1 He does. clr rawflg ;1 br dyerr2 ;1 20$: clr rawflg ;1 dec dytry ;1 INTDSP: JMP @(PC)+ INTRTN: .WORD 0 .SBTTL ERROR HANDLING - CHANGE DENSITY, RETRY DYERR2: .if eq dy$dd ;1 Code pinched from earlier version of bit #esdner,(r5) ;1 handler. If you just leave it bne 1$ ;1 as per DEC, it gets itself bit #escrc,(r5) ;1 mucked up on error and I have bne 5$ ;1 not bothered to fathom why. bit #cshead,r0 ;1 All ideas will be pondered. beq 5$ ;1 bit #csdn,r0 ;1 bne 5$ ;1 1$: ;1 MOV DENPTR,R2 BIC (R2)+,R0 NEGB -(R2) INCB (R2)+ BIS -(R2),R0 BMI 4$ BCS 3$ ASR DYLSN BR 4$ 3$: ASL DYLSN 4$: MOV R0,DYFUN2 CMP DYTRY,#RETRY BNE 5$ CALL SETDY BR 9$ .endc 5$: .IF NE ERL$G .ADDR #DYRBUF,R3 MOV R3,R2 MOV @R4,(R3)+ MOV @R5,(R3)+ MOV #CSMAIN!CSGO,@R4 6$: BIT #CSTR,(R4) BEQ 6$ MOV R3,(R5) 61$: BIT #CSDONE,(R4) BEQ 61$ MOV DRETRY,R3 SWAB R3 ADD #DYNREG,R3 MOV DYCQE,R5 MOV DYTRY,R4 ADD #DY$COD*400-1,R4 CALL @$ELPTR MOV DYCSA,R4 7$: .ENDC MOV #CSINIT,@R4 MOV #CSINT,R0 CALL INWAIT 9$: DEC DYTRY BEQ DYERR JMP DYINIT .SBTTL DOSILO - INITIATE A SILO FILL OR EMPTY COMMAND .Enabl lsb ;2 DOSILO: MOV (SP)+,INTRTN MOV WRDCNT,R2 BIC #6*2,R0 BPL 1$ MOV R3,R2 1$: .if ne dy$22b ;2 .if ne mti$$ ;2 mov himem,-(sp) ;2 Set up the bits within the command asr (sp) ;2 register for MTI boards, at the same bcc 11$ ;2 time shifting the high order memory bis #csma16,r0 ;2 address two places to the right. 11$: asr (sp) ;2 This leaves the top four bits right bcc 12$ ;2 justified in (sp). We can't leave it bis #csma17,r0 ;2 there as if there's an error we must not 12$: mov (sp)+,(pc)+ ;2 have the stack altered. mtihi: 0 ;2 .endc .endc MOV R0,@R4 CMP R3,R2 BLOS 2$ MOV R2,R3 BEQ INTDSP 2$: MOV BUFRAD,R2 .if ne dy$22b ;1 If using 22-bit addressing, need to allow 3$: bitb #cstr!csdone,@r4;1 for extra transfer step to get the beq 3$ ;1 high-order word of the address across. bpl dyerr2 ;1 mov r3,@r5 ;1 4$: bitb #cstr!csdone,@r4;1 beq 4$ ;1 bpl dyerr2 ;1 mov r2,@r5 ;1 5$: bitb #cstr!csdone,(r4);1 beq 5$ ;1 .if eq mti$$ ;2 mov himem,(r5) ;1 .iff ;2 mov mtihi,(r5) ;2 .endc return ;1 .iff ;1 BR DYDOFN .endc ;1 .Dsabl lsb .SBTTL DOXFER - START A SECTOR READ OR WRITE DOXFER: MOV (SP)+,INTRTN ;1 Leave mov r0,(r4) till later MOV WRDCNT,R2 MOV DYLSN,R3 TST R0 BMI DYDOF1 ;1 Need to mov r0,(r4) yet bic #cshead,r0 ;1 Side 0 till proven otherwise cmp r3,#26.*76. ;1 See if on side 1 blo 5$ ;1 Side 0 it is. bis #cshead,r0 ;1 Side 1 it is. sub #26.*76.,r3 ;1 5$: cmp #26.*76.,r3 ;1 Check validity as possible to get bhi 6$ ;1 values which work but are rubbish. jmp dyerr ;1 Always an error if as big as this. 6$: mov r0,@r4 ;1 Must delay this to after head calc MOV #8.,R2 2$: CMP #26.*200,R3 BHI 3$ ADD #-26.*200,R3 3$: ROL R3 DEC R2 BGT 2$ MOVB R3,R2 CLRB R3 SWAB R3 CMP #12.,R3 ROL R3 ASL R2 ADD R2,R3 ADD R2,R3 ADD R2,R3 ASR R2 INC R2 4$: SUB #26.,R3 BGE 4$ ADD #27.,R3 BR DYDOFN .SBTTL DYDOFN - START A TRANSFER OR SILO OPERATION DYDOF1: mov r0,@r4 ;1 DYDOFN: BITB #CSTR!CSDONE,@R4 BEQ DYDOFN BPL .DYERR2 ;1 MOV R3,@R5 1$: BITB #CSTR!CSDONE,@R4;TRANSFER OR DONE? BEQ 1$ BPL .DYERR2 ;1 MOV R2,@R5 RETURN .dyerr2:jmp dyerr2 ;1 .SBTTL SETDY - SET UP REGISTERS SETDY: MOV DYFUN2,R0 MOV #128.,R3 .IF EQ DY$DD TST @DENPTR BNE 1$ ASR R3 1$: .ENDC MOV DYCSA,R4 MOV R4,R5 TST (R5)+ RETURN .Sbttl FORMAT function ;1 format: ;1 add #csdnft-csrd,r4 ;1 Reset command to Set Density/Format .if ne mmg$t ;1 mov r4,-(sp) ;1 Need R4 for CQE pointer if MMGT mov dycqe,r4 ;1 call @$gtbyt ;1 If first byte non-zero, side 1 tstb (sp)+ ;1 beq 10$ ;1 bis #cshead,(sp) ;1 10$: call @$gtbyt ;1 If second byte non-zero, double density tstb (sp)+ ;1 beq 20$ ;1 bis #csdn,(sp) ;1F (bic -> bis ! ) 20$: mov (sp)+,dyfun2 ;1 .iff ;1 mov dycqe,r5 ;1 mov q$buff(r5),-(sp);1 Address of user buffer tstb @(sp) ;1 If first byte non-zero, side 1 beq 10$ ;1 bis #cshead,r4 ;1 10$: ;1 inc (sp) ;1 If second byte non-zero, double density tstb @(sp)+ ;1 beq 20$ ;1 bis #csdn,r4 ;1 20$: mov r4,dyfun2 ;1 .endc ;1 30$: inc rawflg ;1 Get error back from INWAIT if needed mov #csint,r0 ;1 call inwait ;1 Don't care if get error as disc unformatted mov r0,(r4) ;1 Actual Format command 50$: bitb #cstr!csdone,(r4);1 beq 50$ ;1 bpl 70$ ;1 mov #111,r0 ;1 Soft format tst @dycqe ;1 unless block number non-zero. beq 60$ ;1 asl r0 ;1 60$: ;1 call fmt ;1 Send keyword for formatting ;1 and wait for interrupt. tst (r4) ;1 See if error bpl 80$ ;1 70$: jmp dyerr ;1 80$: jmp dyhome ;1 fmt: ;1 inc rawflg ;1 mov (sp)+,intrtn ;1 mov r0,(r5) ;1 return ;1 .Sbttl . TSX High Memory Mapping .If eq 1 Called by call mapadr .word map-address returns r3 / high order physical address r4 / low order physical address .Endc .if df TSX$P Mapadr: clr r3 ;Clear high order physical address mov pc,r4 map: sub @(sp),r4 ;Get virtual address of desired loc add #2,(sp) ;So we return properly. cmp r4,#120000 ;Mapped? blo 10$ ;No - no problems. mov r4,-(sp) ;Yes. Hold virtual address mov @#172352,r4 ;Get PAR5 value ashc #6,r3 ;Convert to physical address bic #160000,(sp) ;Remove offset from virtual address add (sp)+,r4 ;Add to physical address offset adc r3 ;(Need high order bits right-justified) 10$: return .endc .SBTTL TABLES, FORK BLOCK, END OF DRIVER ZERO: .WORD 0 .IF EQ DY$DD .WORD CSRDST-CSRD+SPFUNC .WORD 0 .ENDC .WORD CSWRTD-CSRD+SPFUNC .WORD CSWRT-CSRD+SPFUNC .WORD CSRD-CSRD+SPFUNC CHGTBL: .IF EQ DY$DD SAVDEN: .WORD CSDN,CSDN .IF NE DYT$O .WORD CSDN,CSDN .ENDC .ENDC DYFBLK: .WORD 0,0,0,0 .IF NE ERL$G DYRBUF: .BLKW DYNREG .BLKW 4 .ENDC .SBTTL BOOTSTRAP READ ROUTINE .DRBOT DY,BOOT1,READ1 . = DYBOOT+40 BOOT1: JMP @#BOOT-DYBOOT .ENABL LSB . = DYBOOT+210 UNTRED: .WORD CSGO+CSRD+CSDN .WORD CSGO+CSRD+CSDN+CSUNIT READ1: MOV @#B$DEVU,R3 BR 100$ READ: MOV BTUNIT,R3 100$: ASL R3 MOV UNTRED-DYBOOT(R3),REDCMD 1$: ASL R0 2$: mov r0,-(sp) ;1 Keep for next sector bic #cshead,redcmd ;1 Side 0 till proven otherwise cmp r0,#26.*76. ;1 See if on side 1 blo 25$ ;1 Side 0 it is. bis #cshead,redcmd ;1 Side 1 it is. sub #26.*76.,r0 ;1 25$: ;1 MOV (PC)+,R5 BOTCSR: .WORD DY$CSR MOV (PC)+,(R5)+ REDCMD: .WORD 0 ;1 MOV R0,-(SP) (move earlier) MOV R0,R3 MOV R0,R4 CLR R0 BR 4$ 3$: SUB #23.,R3 4$: INC R0 SUB #26.,R4 BPL 3$ CMP #-14.,R4 ROL R3 5$: SUB #26.,R3 BPL 5$ ADD #27.,R3 MOV BOTCSR,R4 CALL WAIT MOV R3,@R5 CALL WAIT MOV R0,@R5 6$: BIT #CSDONE,@R4 BEQ 6$ TST @R4 BMI RTRY MOV (PC)+,(R4) EMTCMD: .WORD CSEBUF+CSGO+CSDN;STORE EMTY BUFFER COMMAND HERE MOV #64.,R3 BIT #CSDN,EMTCMD BEQ 7$ ASL R3 7$: CMP R1,R3 BHIS 8$ MOV R1,R3 8$: CALL WAIT MOV R3,@R5 CALL WAIT MOV R2,@R5 9$: BIT #CSDONE,@R4 BEQ 9$ TST @R4 BMI RTRY MOV (SP)+,R0 SUB R3,R1 BLE 10$ ADD R3,R2 ADD R3,R2 INC R0 BR 2$ WAIT: BITB #CSTR!CSDONE,@R4;TRANSFER OR DONE? BMI 11$ BEQ WAIT RTRY: MOV (SP)+,R0 BITB #DNERR,@R5 BEQ BIOERR BIC #CSDN,REDCMD BIC #CSDN,EMTCMD BR 1$ 10$: CLC 11$: RETURN .DSABL LSB . = DYBOOT+576 BOOT: BIT #CSDONE,@BOTCSR BEQ BOOT MOV #10000,SP MOV R0,(PC)+ BTUNIT: .WORD 0 MOV #2,R0 MOV #<4*400>,R1 MOV #1000,R2 CALL READ MOV #READ1-DYBOOT,@#B$READ MOV #B$DNAM,@#B$DEVN MOV BTUNIT,@#B$DEVU JMP @#B$BOOT .DREND DY .Sbttl Programme Portion for Formatting Discs .psect program .psect data limit: .limit ;Programme linked limits hlimit: 0 ;For new high memory limit area: .blkw 7 ;EMT area defext: .rad50 / / ;CSI default extensions line: .blkb 100. ;For input line. iniseg: 0 ;For number of directory segments tell: 0 ;NZ if wants device size ffmt: 0 ;NZ if wants disc formatted buffer: 0 ;.byte .psect mesage con hmes: .ascii /DY Commands:/ .ascii # /H (without any file) - Type this text# .ascii # The device specified should be a DY floppy,# .ascii # write-enabled.# .ascii # /H - hard format;# .ascii # /F - soft format;# .ascii # /D - double density;# .ascii # /S - both sides.# .ascii # /S:0 - side 0 only (default);# .ascii # /S:1 - side 1 only.# .ascii # /I - initialize directory when formatted# .ascii # (default 4 segments), or# .ascii # /I:n for n segments (1 to 31.)# .ascii # /T - tell size of disc (in blocks)# .ascii # /Z - equivalent to /F/D/S/I# .ascii # (/D and /S imply /F unless /H is specified.# .byte 0 illsw: .ascii \?DY-E-Illegal Switch or Value for Switch /\<200> illswh: .asciz \Type /H for help.\ .psect program jsw=44 ttlc$=40000 userrb=53 error=4 cr=15 lf=12 .mcall .sreset,.csigen,.wait,.print,.ttyou,.spfun,.writw Badrun: bisb #error,@#userrb Start:: .sreset bis #ttlc$,@#jsw .csigen limit+2,#defext,,#line mov r0,hlimit cmp line,#"/h beq 10$ cmp line,#"/H bne 20$ 10$: .print #hmes br start 20$: .wait #3 bcc 30$ .print #vermes br start 30$: clr r1 ;Block Number = Soft/Hard clr r2 ;First byte = Side 0/1 clr r3 ;Second byte = Single/Double Dens clr iniseg ;Number of segments in directory clr tell ;Doesn't want to be told size clr ffmt ;Doesn't want disc formatted mov (sp)+,r5 ;Number of switches beq noswt nexswt: clr r0 ;Clear option value mov (sp)+,r4 ;Option itself bpl 10$ mov (sp)+,r0 10$: bicb #40,r4 ;Make switch upper case. cmpb r4,#'H bne 20$ inc r1 ;/H - Hard format required inc ffmt br endswt 20$: cmpb r4,#'D bne 30$ inc r3 ;/D - Double density required inc ffmt ;Implies formatting br endswt 30$: cmpb r4,#'S bne 50$ inc ffmt ;/S -> /F tst r4 ;/S - see if value specified bmi 40$ ;Yes - side specified. mov #2,r2 ;No - do both sides. br endswt 40$: cmp r0,#2 bhi illswt mov r0,r2 br endswt 50$: cmpb r4,#'I ;/I:n - initialize disc with n bne 60$ ; directory segments. mov #4,iniseg ;Default is 4 segments tst r4 bpl endswt tst r0 beq illswt cmp r0,#32. bhis illswt mov r0,iniseg br endswt 60$: cmpb r4,#'F bne 70$ inc ffmt ;/F - soft formatting br endswt 70$: cmpb r4,#'T bne 80$ inc tell ;/T - tell him size of disc br endswt 80$: cmpb r4,#'Z ;/Z = /F/S/D/I bne illswt inc ffmt ; = /F mov #2,r2 ; = /S inc r3 ; = /D mov #4,iniseg ; = /I:4 endswt: dec r5 bne nexswt br go illswt: .print #illsw .ttyou r4 .print #illswh jmp badrun noswt: inc tell ;No switches -> /T only (to be harmless?) .br go .Sbttl Actual Programme Machinations .Enabl lsb go: tst ffmt ;Does he want formatting? beq endfmt mov r2,r5 ;0 = side 0, 1 = side 1, 2 = both bic #^c1,r2 10$: movb r2,buffer ;Buffer contains .BYTE , movb r3,buffer+1 .spfun #area,#3,#fmt$fn,#buffer,#1,r1 ;Block no. == bcs spferr inc r2 dec r5 cmp r5,r2 beq 10$ endfmt: mov iniseg,r1 ;Does he want it initialized? bne 20$ ;Yes. jmp trytell 20$: .spfun #area,#3,#siz$fn,#length,#0,#0 ;Get size bcs sizerr mov r1,dir ;Number of segments asl r1 sub r1,length ;Length less number of blocks taken by sub #6,length ; directory and boot blocks add #6,r1 ;Block upon which first file starts mov r1,ffile .writw #area,#3,#dir,#dircnt,#6 ;Write first directory block bcs direrr .writw #area,#3,#block1,#400,#1 ; and the home block. bcs homerr trytell: tst tell beq endtell .spfun #area,#3,#siz$fn,#length,#0,#0 ;Get size bcs sizerr .print #siz1 mov length,r0 call wdt .print #siz2 endtell: jmp start .psect mesage con siz1: .ascii /Size of disc is /<200> siz2: .ascii / blocks (decimal)/<0> .Dsabl lsb .Sbttl Directory & Home Block Data .psect data ;--------------------------------------------------------------------------- ;Directory Data dir: ;Portion of directory 0 ;Number of segments 0 ;Next segment in use 1 ;Number of highest in use 0 ;Number of extra bytes ffile: 0 ;Block on which data starts 1000 ;Empty area 0,0,0 ;Filename.ext length: 0 ;Length 0,0 4000 ;End of segment dircnt = <.-dir> / 2 ;Number of words in this bit. ;--------------------------------------------------------------------------- ;Block 1 (Home Block) initializing data block1: .word 0 .rept 101 .ascii / / .endr .=. ;(so we can see what loc we're up to) .rept 34 0 .endr .=. .rept 202 .ascii / / .endr 0 0 .=. .rept 7 .ascii / / .endr 1 6 .rad50 /V05/ .ascii /RT11A / .ascii /DECRT11A / ;--------------------------------------------------------------------------- .psect program spferr: ;SPFUN error on formatting .print #sperr mov #'0,r0 tst r2 beq 10$ inc r0 10$: movb r0,sper1 .print #sper1 jmp badrun .Sbttl Assorted Errors sizerr: .print #sizer ;SPFUN error getting size jmp badrun direrr: .print #direr ;WRITE error getting directory jmp badrun homerr: .print #homer ;Error writing home block jmp badrun .psect mesage con sperr: .ascii \?DY-E-Error Formatting Disc (side \<200> sper1: .asciz \0)\ sizer: .asciz \?DY-E-Error Reading Device Size\ direr: .asciz \?DY-E-Error Writing Directory\ homer: .asciz \?DY-E-Error Writing Home Block\ .psect program .Sbttl WDT - Write a signed or unsigned decimal number to the terminal .If eq 1 Called by: mov number,r0 call wdt .endc DECTAB: .WORD 10.,100.,1000.,10000.,-1 WDT: mov r0,-(sp) bge 10$ mov #'-,r0 .ttyou mov (sp),r0 neg r0 bic #100000,r0 10$: mov r3,-(sp) mov r2,-(sp) mov r0,r2 clr -(sp) mov #dectab,r3 20$: cmp r0,(r3) ;Compare value with subtractors blo 40$ mov (r3)+,-(sp) ;Stack next subtractor if relevant tst (r3) bpl 20$ 40$: mov (sp)+,r3 ;Get next subtractor beq 70$ ;Last one zero, in case number = 0. mov #60,r0 ;Initalize digit 50$: sub r3,r2 blt 60$ inc r0 br 50$ 60$: add r3,r2 .ttyou br 40$ 70$: add #60,r2 mov r2,r0 .ttyou mov (sp)+,r2 mov (sp)+,r3 mov (sp)+,r0 return .end start