;MSX-11 DECTAPE DRIVER ;RESEMBLES DOS DECTAPE DRIVER BUT MEM MGT INCLUDED ;VERSION NUMBER: V000B .GLOBL DTINT .TITLE DT .GLOBL DT ;DECTAPE DRIVER VERSION 1 23 JULY 70 ; PRESENTLY CONTAINS ONLY ROUTINE FOR TRANSFER ;N.B. - ENTIRE PREFIX TABLE NOT REALLY NEEDED BUT THE TRANSFER OFFSET ;IS EXPECTED. STD BUFFER SIZE IS NOT USED HERE, NOR ARE BITMAP POINTERS ;ETC. HOWEVER, THE DRIVER IS VERY CLOSE TO A DOS-11 DRIVER WITH SUITABLE ;MODS TO ACCESS EXTENDED SPACE. WE ASSUME STATIC UMR ALLOCATION IF AN 11/70 ;OR 11/44 OR 11/24 IS USED, SO THIS DRIVER WOULD IN THAT CASE SET UP THE ;UMR ALLOCATED TO IT AT ASSEMBLY TIME AND TRANSFER THERE. THE MAPPING ;LOGIC HERE ASSUMES 18 BIT ADDRESSING ONLY. SINCE NOBODY MUCH USES ;TC11 DECTAPE ANYMORE, THIS DRIVER SERVES AS AN EXAMPLE. THE DOS RF11 ;DRIVER OR SOME SUCH BEAST CAN BE USED AS AN EXAMPLE OF A DISK DRIVER ;TO USE. GENERALLY ONLY A TRANSFER AND INTERRUPT ENTRY ARE NEEDED ;IN THESE. THIS DRIVER HAS IMPURE CODE (UGH!) BUT IS KNOWN TO WORK. ;STANDARD DRIVER TABLE: DT: .WORD 0 ;BUSY FLAG (DDB ADDR WHEN BUSY) .BYTE 37,300 ;FACILITY INDICATOR .BYTE 16. ;STD BUFF SIZE/16. .BYTE DT.INT-DT ;POINTER TO INT SVCE .BYTE 340 ;INT SVCE PRIORITY .BYTE 0 ;DESPATCH TABLE .... .BYTE DT.TFR-DT ;...FOR TRANSFER ONLY! .BYTE 0 .BYTE 0 .BYTE 0 ;SPARE DT.NAM: .RAD50 'DT' .WORD DT.DIR ;FIXED MFD BLOCK .WORD 0,0,0,0,0,0,0,0 ;POINTERS FOR BIT MAP ACCESS ;REGISTER ASSIGNMENTS: R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 DT.INT: JMP DT.ISV ;SERVICE INTERRUPTS. ;SET UP TRANSFER: DT.TFR: CLR DT.RTC ;CLEAR RETRY COUNT DT.PR1: MOV DT,R0 ;GET ADDRESS OF DDB ... MOV #DT.CBA,R1 ;... & OF HWR BLOCK CLR @R1 CMP (R0)+,(R0)+ ;SKIP USER LINE IN DDB MOV (R0)+,DT.BRQ ;SAVE BLOCK NO FOR LATER ; MOV (R0)+,@R1 ;SET READY MEMORY ADDR ... JSR R5,S.RSAV ;SAVE REGS FOR MAPPING OP. MOV DT,R0 BIC #60,12(R0) ;ZERO H.O. ADDR BITS IN FUNC MOV 6(R0),@#DT.CBA ;PREPARE KNL ADDR MOV 20(R0),R1 ;GET TCB ADDR BEQ 1$ ;SKIP RELOC IF KNL ADD #34,R1 ;POINT AT APR SAVE AREA OF TCB MOV 6(R0),R2 ;GET VIRTUAL MEM. ADDR MOV R2,R3 ;COPY FOR SAVING ASH #-12.,R2 ;GET APR # BIC #^C16,R2 ;MAKE WORD INDEX ADD R1,R2 ;POINT AT USER'S APR SAVED MOV @R2,R2 ;GET IT MOV R3,R1 ;COPY AGAIN ASH #-6,R1 ;SHOVE OUT DISPL. IN BLK OF 64 BYTES BIC #176000,R1 ;NO SIGN EXTENDS! ADD R1,R2 ;FORM PHYSICAL BLOCK MOV R2,R1 ;COPY FOR LATER ASH #-10.,R1 ;READY THE MASK BIC #^C60,R1 ;SAVE ONLY H.O. ADDR BITS BIS R1,12(R0) ;SET THEM IN CMD MASK ASH #6,R2 ;SHIFT BLK # UP BIC #77,R2 ;TO LOOK LIKE ADDR BIC #^C77,R3 ;AND GET DISPLACEMENT BIS R3,R2 ;MAKE LOW 16 PHYS ADDR BITS MOV R2,@#DT.CBA ;STASH IN DT: HARDWARE 1$: JSR R5,S.RRES ;BACK WITH REGS TST (R0)+ ;PASS OLD ADDRESS .IF DF,IO$WDS MOV (R0)+,-(R1) ;... & WORD COUNT .IFF ;NORMAL MSX CASE GIVES BYTE COUNTS TO THE DRIVERS. ADJUST FOR WC ;HERE SINCE DT: NEEDS A WORD COUNT. MOV (R0)+,-(SP) ;GET BYTE COUNT ASR (SP) ;MAKE A WC MOV (SP)+,-(R1) ;THEN SET UP WC .ENDC DT.PR2: CLRB DT.ISV ;SET INT'RUPT SW. TO SRCH MOV DT.BRQ,DT.BCK ;SET BLK CTRL FOR SRCH MOV #100,R3 ;USED IN NEXT SEQUENCE MOV R3,DT.TAC ;SET TURN AROUND COUNT mOV @R0,-(SP) ;GET UNIT, DIRECTION & FUNC BIC #170301,@SP ;CLEAR POSS. GARBAGE BIS R3,@SP ;ADD IN INT ENB BIT ; BITB @SP,@PC ;WRITE REQD? BITB #2,@SP ;WRITE REQUIRED? BEQ .+6 ;(READ O.K. ALRDY)***** ADD #12,@SP ;IF SO GET DECTAPE EQUIV. MOVB @SP,DT.FRQ ;SAVE FUNC FOR LATER ; MOVB @PC,@SP ;RESET FUNC TO SRCH (INT ENB) MOVB #303,@SP ;RESET FUNCT TO SEARCH, INT ENABLED ASL R3 ;(NOW CONTAINS 200)***** BIT @SP,#4000 ;TRAVEL FORWARD? BNE .+4 INC R3 ;IF SO R3 NOW 201 & SO ... MOVB R3,DT.SSW ;MAKING BPL OR BMI AS REQD MOV (SP)+,-(R1) ;SET DECTAPE CONTROL RTS PC ;RETURN TO CALLER FOR NOW ;***** CARE USED AS LITERAL BY PREVIOUS INSTRUCTION!!! ;INTERRUPT SERVICE (A) - SEARCH IN PRORESS: DT.SIP: TST @#DT.CCM ;CHECK STATUS BMI DT.SER ;IF ERROR GO INVESTIGATE CMP @#DT.CDT,DT.BRQ ;CHECK BLOCK FOUND BEQ DT.BFD ;IF ONE REQD, GO ACTION BMI DT.SXT ;GET TO BLOCK THIS WAY? DT.SSW=.-1 ;(BPL IF TRAVEL BACKWARD) DT.TA1: BICB #40,@#177776 ;DROP PRIORITY ASRB #0 ;HOW MANY TURNS? DT.TAC=.-2 BCS DT.BER ;IF 6 CAN'T FIND BLOCK MOV #4000,-(SP) ;OTHERWISE MUST TURN AROUND MOV #2,-(SP) ;ASSUME TRAVEL NOW FWD RORB DT.SSW ;CHECK DIRECTION BCS DT.TA2 ;IF FWD OMIT NEXT NEG 2(SP) ;IF BWD, REVERSE EVERYTHING NEG @SP DT.TA2: SUB (SP)+,DT.BRQ ;ALLOW 2 BLKS FOR 2ND TURN ADD (SP)+,@#DT.CCM ;SWITCH STATUS ROLB DT.SSW ;RESET DIR SW (C BIT REVERSES) DT.SXT: INCB @#DT.CCM ;CONTINUE SEARCH RTI ;WAIT NEXT BLOCK ;BLOCK FOUND - CHECK TRAVEL CORRECT: DT.BFD: CMP #0,#0 ;TRAVEL AS ORIGINALLY STORED? DT.BRQ=.-4 ;(IMPURE IMPURE !!! UGH!!!) DT.BCK=.-2 BNE DT.TA1 ;IF NOT MUST TURN AGAIN INCB DT.ISV ;RESET INT'RUPT SW FOR TFR MOVB #0,@#DT.CCM ;MOVE IN CORRECT FUNC DT.FRQ=.-4 BR DT.SXT ;... & GO SET UNDERWAY ;INTERRUPT SERVICE (B) - TRANSFER COMPLETE (?): DT.ISV: BR .+2 ;INTERRUPT SWITCH .... BR DT.SIP ;FOR SRCH COMES HERE! BICB #40,@#177776 ;DROP PRIORITY JSR R5,S.RSAV ;SAVE USER REGS ON XFER COMPLETE .GLOBL S.RSAV,S.RRES MOV DT,R0 ;GET DDB ADDR MOV #DT.CCM,R1 ;GET STATUS ADDR MOV #10,R3 ;SET MAGIC CONSTANT TST @R1 ;ERROR CAUSE INT'RUPT? BMI DT.TER ;IF SO GO & SEE WHY MOVB R3,@R1 ;OTHERWISE STOP TAPE ... DT.TXT: MOV 14(R0),PC ;... & TAKE COMPLETE RETN ;SEARCH ERROR - DETERMINE CAUSE: DT.SER: TST @#DT.TST ;IN END ZONE? BMI DT.TA1 ;_.K. MEANS TURN AROUND BICB #40,@#177776 ;DROP PRIORITY JSR R5,S.RSAV ;SAVE ALL USER REGS. MOV DT,R0 ;(R0) DECTAPE DDB ADDR MOV #DT.TST,R1 ;GET DECTAPE STATUS ;DT.EXT: MOV (R1)+,16(R0) ;PUT TAPE STAT IN DDB DT.EXT: MOV (R1)+,12(R0) ;PUT TAPE STAT IN DDB DT.STP: MOVB #10,@R1 ;STOP TAPE IN CASE BR DT.TXT ;BLOCK NOT FOUND IN SEARCH: DT.BER: MOV DT,R0 ;(R0) DECTAPE DDB ADDR MOV #DT.CCM,R1 ;GET CONTR_L ADDRESS MOV #-10,12(R0) ;SET ERR WORD IN DDB FOR BLK NOT FOUND ; MOV #-10,16(R0) ;SET ERR WORD IN DDB FOR BLK NOT FOUND BR DT.STP ;TRANSFER ERROR: DT.TER: BIT #43000,-(R1) ;PARITY OR TIMING ERROR BEQ DT.EXT ;BRANCH IF NOT ;RECOVERABLE ERRORS(TIMING OR PARITY) SEC ROLB (PC)+ ;RETRY 8 TIMES DT.RTC: .WORD 0 BCS DT.EXT ;BRANCH IF RETRIES FAILED JSR PC,DT.PR1 ;OTHERWISE TRY AGAIN JSR R5,S.RRES ;RESTORE USER REGISTERS RTI ;THEN GO BACK TO USER. ;MISCELLANEOUSDEFINITIONS: V.SXIT=42 V.RSAV=44 V.RRES=46 DT.DIR=100 DT.TST=177340 DT.CCM=177342 DT.CBA=177346 DT.CDT=177350 DT.NRE=402 DT.IRE=404 DT.FRE=1415 DT.BRE=1416 ; ;DECTAPE LINKBLOCK AND DDB ;STATICALLY ALLOCATED HERE -- STANDALONE MSX VERSION ; .GLOBL DT0 DT0: .WORD DTDDB ;DDB POINTER .WORD 0 ;NO LOGICAL NAME .BYTE 1,0 ; .RAD50 /DT/ .BLKW 14. ;SPARES FOR MSX .WORD 0,0,0,DT DTDDB: .WORD 0 ;CALL ADDR .REPT 25. .WORD 0 .ENDR DTINT: JSR R5,MX.PST ;POST THE INTERRUPT FOR BSX .WORD 240 ;AT PRIO 5, NO REG SAVES JMP DT.ISV ;THEN DO THE REAL SERVICE .END