; DSD-210 HANDLER FOR RT-11 V3 ; DX210.MAC 29-DEC-77 .TITLE DSD MULTI-DRIVE FLOPPY DISK HANDLER MAXDRV=3 ; CONFIGURE FOR 3 DRIVES. ; DEFINE = 2 FOR 2 DRIVES ; FLOPPY INTERFACE REGISTERS AND DEFS. RXCS=177170 ; COMMAND AND STATUS REGISTER. ;WRITE RO IN X X X X X X RO IE UN UN FN FN FN EX ; READ ERR WO X X X X X X TR IE DN WO WO WO WO WO ; RO = READ ONLY ; WO = WRITE ONLY ; ERR= ERROR DET. (CLEARED BY COMMAND INIT ; IN = CONTROLLER INIT. ; TR = TRANSFER REQUEST. ; IE = INTERRUPT ENABLED ON DONE. ; DN = DONE FLAG. ; UN = UNIT SELECT. ; FN = FUNCTION SELECT. ; 0=FILL BUFFER 1=READ BUFFER ; 2=WRITE SECTOR 3=READ SECTOR ; 4=NOT USED 5=READ STATUS ; 6=WRITE DELETED DATA ; 7=READ ERROR REGISTER ; EX = EXECUTE. RXDB=177172 ; DATA BUFFER REGISTER. ; CONTEXT CONTROLLED BY COMMAND SEQUENCE. ; AFTER AN RXCS FUNCTION IS DONE A STATUS ; IS AVAILABLEE TO BE READ IN RXDB LOW BYTE ; DR DD XX XX WP ID PA CRC ; DR = DRIVE READY - CURRENTLY SELECTED UNIT HAS ; DISK INSTALLED AND UP TO SPEED ; DD = DELETED DATA WAS READ ON LAST SECTOR ; WP = WRITE PROTECT ERROR ; ID = INITIALIZE DONE ; PA = PARITY ERROR DETECTED ; CRC= CRC ERROR DETECTED IN DATA READ ; RXVEC= 264 ; INTERRUPT VECTOR ; FORMAT OPTION IS ENTERED BY SPECIFYING A WRITE SECTOR ; FOLLOWED BY A SECTOR VALUE OF 152 AND THE DESIRED ; PHYSICAL TRACK # TO BE RE-FORMATTED. ; THE CONTROLLER THEN REQUESTS 26. SECTOR #'S IN THE ; ORDER THAT THEY ARE TO BE WRITTEN. ; ERROR CODES GIVEN BY READ ERROR STATUS FUNCT (MODE 7) ; CODE LIGHT # MEANING ; 10 2 DRIVE 0 FAILED TO HOME ON INIT, OR DIDN'T SELECT ; 20 2 DRIVE 1 FAILED TO HOME ON INIT, OR DIDN'T SELECT ; 30 2 FOUND HOME WHEN STEPPING OUT 10 TRACKS FOR INIT. ; 40 2 TRACK GREATER THAN 77. OR UNIT SELECT ERROR. ; 50 2 HOME BEFORE DESIRED TRACK FOUND. ; 70 2 DESIRED SECTOR COULD NOT BE FOUND AFTER 2 REVS. ; ; 100 3 WRITE PROTECT ERROR. ; 110 MORE THAN 40 USEC AND NO SEPERATED CLOCK FOUND. ; 120 0 NO PREAMBLE WAS FOUND ( 24 BITS OF 0'S) ; 130 0 PREAMBLE FOUND BUT NO I/O MARK WITHIN WINDOW. ; 140 0 CRC ERROR ON WHAT APPEARED TO BE HEADER. ; 150 2 HEADER TRACK ADDRESS OF A GOOD HEADER DIDN'T ; MATCH DESIRED TRACK. ; 160 0 TOO MANY TRIES FOR AN I.D. ADDRESS MARK. ; 170 0 DATA ADDRESS MARK NOT FOUND IN ALLOTED TIME. ; 200 0 CRC ERROR ON READING SECTOR FROM DISK. ; RXES STATUS BIT 11 ALSO SET. ; 210 1 PARITY ERROR (INTERFACE <=> CONTROLLER) ; RXES STATUS BIT 10 ALSO SET. ; 220 2 DRIVE 2 FAILED TO HOME ON INIT. ; 230 2 DRIVE 3 FAILED TO HOME ON INIT. ; 240 SELECTED DRIVE NOT READY ; 250 0 EXPECTED HEADER NOT FOUND AFTER TRACK FORMAT. ; 260 0 INDEX MARK NOT FOUND IN EXPECTED RANGE. ; (FORMAT NOT BEGUN) ; 270 0 INDEX MARK NOT FOUND IN EXPECTED RANGE. ; (FORMAT HAS OCCOURED) ; 300 DATA LOST FROM WEST. DIG. 1771. ; LIGHTS MEANING (DSD 210 ONLY) ; 0 FRONT DATA TYPE ERROR ; 1 FRONT PARITY ERROR: CONTROLLER TO INTERFACE. ; 2 FRONT SEEK TYPE ERRORS ; 3 FRONT WRITE PROTECT OR CONTROLLER SELFTEST ERR ; BOARD LIGHTS (DSD-210 ONLY) ; LEFT UP-LEFT CONTROLLER WAITING FOR BUS INTERFACE READY. ; L-MID UP-RGHT INIT IN PROGRESS. ; R-MID LW-LEFT READ IN PROGRESS ; RIGHT LW-RGHT WRITE IN PROGRESS. .TITLE DX V03-01 .IDENT /V03.01/ .MCALL ..V2..,.REGDEF,.DRBEG,.FORK,.DREND,.DRAST,.DRFIN ..V2.. .REGDEF .IIF NDF RX$CS2, RX$CS2=177150 .IIF NDF RX$CV2, RX$CV2=270 .IIF NDF TIM$IT,TIM$IT=0 .IIF NDF MMG$T, MMG$T=0 .IIF NDF ERL$G, ERL$G=0 .IIF NDF RXT$O, RXT$O=0 ; GLOBALS FOR USE AS SYSTEM DEVICE .GLOBL RKSYS,RFSYS,DTSYS,DSSYS,DPSYS,DXSYS,DMSYS ; DX SYSTEM DEFINITIONAL EQUATES DTSYS=0 RFSYS=0 RKSYS=0 DSSYS=0 DPSYS=0 DMSYS=0 ; KT-11 PAR ADDRESSES KISAR1=172342 KISAR3=172346 DXDSIZ= 756 ;SIZE OF RX IN 256 WORD BLOCKS DXSTS= 102022 ;RX STATUS WORD ; (FILE-STRUCTURED, SPFUN) ; ERROR LOG VALUES DXRCNT= 4000 ;RETRY COUNT IN HIGH BYTE DXNREG= 3 ;# OF REGS TO READ FOR ERROR LOG. ; DXREGA= 177340 ;START OF REGISTERS /NOT USED. DXIDS= 11377 ;-1 IN LOW BYTE FOR I/O SUCCESS ;22 IN HIGH BYTE FOR DEVICE ID DXIDEN= 11000 ;22 IN HIGH BYTE FOR DEVICE ID ;0 IN LOW BYTE FOR HARD ERROR. ; QUEUE POINTERS Q.BLK=0 Q.BUF=4 Q.PAR=12 ; CONTROL AND STATUS BITS CSGO=1 ;INITIATE FUNCTION ; FUNCTIONS (BITS 1-3) CSFBUF= 0*2 ;FILL SILO (PRE-WRITE) CSEBUF= 1*2 ;EMPTY SILO (POST-READ) CSWRT= 2*2 ;WRITE SECTOR CSRD= 3*2 ;READ SECTOR CSRDST= 5*2 ;READ STATUS CSWRTD= 6*2 ;WRITE DELETED DATA SECTOR CSMAIN= 7*2 ;MAINTENANCE CSRDWR= CSRD&CSWRT ;READ OR WRITE BIT CSUNIT= 20 ;UNIT BIT CSDONE= 40 ;DONE BIT CSINT= 100 ;INTERUPT ENABLE CSTR= 200 ;TRANSFER REQUEST CSINIT= 40000 ;RX11 INITIALIZE CSERR= 100000 ;ERROR DBDD= 100 ;DELETED DATA MARK DBIN= 4 ;RX INIT DONE INDICATOR RETRY=8. ;RETRY COUNT SPFUNC= 100000 ;SPECIAL FUNCTIONS FLAG ; GENERAL COMMENTS: ; ; THIS SERVES AS THE STANDARD RT-11 DSD-210 DEVICE ; HANDLER FOR BOTH THE SYSTEM AND NON-SYSTEM HANDLERS. ; IT ALSO PROVIDES THREE SPECIAL FUNCTION CALLS TO ; SUPPORT PHYSICAL I/O ON THE FLOPPY AS A FOREIGN VOLUM ; THE SPECIAL FUNCTIONS ARE: ; CODE ACTION ; 377 ABSOLUTE SECTOR READ. WORDCOUNT=TRACK, ; BLOCK=SECTOR ; BUFFER = 65 WORD BUFFER OF WHICH ; WORD 1 IS DELETED DATA FLAG. ; 376 ABSOLUTE SECTOR WRITE. ; ARGUMENTS SAME AS READ. ; 375 ABSOLUTE SECTOR WRITE WITH DELETED DATA. ; 1ST WORD OF 65 WORD BUFFER ALWAYS SET =0. ; ; IN STANDARD RT-11 MODE A 2:1 INTERLEAVE IS USED ON EACH ; TRACK AND A 6 SECTOR SKEW IS USED ACROSS TRACKS. ; TRACK 0 IS LEFT ALONE FOR PROPOSED ANSI COMPATABILITY. .IF NE RXT$O .DRBEG DX, RXVEC, DXDSIZ, DXSTS, RXTVTB .IFF .DRBEG DX, RXVEC, DXDSIZ, DXSTS .ENDC ; REQUEST ENTRY POINT MOV #RETRY, (PC)+ ;SET RETRY COUNT RXTRY: .WORD 0 ;RETRY COUNT MOV DXCQE, R3 ;GET POINTER TO I/O ELEMENT MOV (R3)+, R5 ;GET BLOCK NUMBER MOV #CSGO+CSRD, R4 ;FORM A GUESS AT RXCS FUNCTION MOVB (R3)+, R1 ;SAVE FUNCTION FOR LATER MOVB (R3)+, R0 ; GET LOGICAL UNIT ASL R0 ASL R0 ASL R0 ASL R0 ; POSITION FOR 210 RXCS .IF NE RXT$O ;2 SYSTEM CONFIG IF NONZERO ;LOGICAL UNIT'S CAN 4-7 MAP TO ;PHYSICAL 0-3 ON SECOND SYSTEM MOV (PC)+, R2 ;ASSUME NORMAL DX RXCS1A: .WORD RXCS BIT #100, R0 ; 2ND SYSTEM SELECTED? BEQ RXCDF ; NO - USE RXCS1A MOV (PC)+, R2 ;STORE RXCS FOR SECOND FLOPPY RXCS2A: .WORD RX$CS2 ; IN RXCSA FOR USE RXCDF: MOV R2, RXCSA ;STORE R2 IN RXCSA NOW. .IFF BIT #100, R0 ; NOT MULTI-SYSTEM, FLAG ERR BNE RXERRJ .ENDC BIC #177717, R0 ; LEAVE ONLY UNIT SELECT BITS CMP R0, #MAXDRV*CSUNIT ; INSURE VALID UNIT BGE RXERRJ ; INVALID - FORCE AN ERROR BIS R0, R4 ; SET UNIT SELECT BITS IN RXCS MOV (R3)+, R0 ;SAVE THE BUFFER ADDRESS MOV @R3, R2 ;GET WORD COUNT BPL 2$ ;TAKE ABSOLUTE VALUE ; BIC #CSEBUF, R4 ;WRITE FUNCTIONS ARE 0, 2 ; SO CLEAR 1 BIT CMPB -(R4), -(R4) ;EQUIVALENT TO ABOVE BIC NEG R2 ;MAKES IT POSITIVE 2$: ADD PC, R1 ;FORM PIC REFERENCE TO CHGTBL MOVB CHGTBL-.(R1), R3 ;GET FUNCTION MODIFIER ROR R1 ;SET C TO FLAG IF SPECIAL FUNCTION ROR R3 ;SET SIGN TO SPFUNC FLAG (NON-OBVIOUS!) ADD R3, R4 ;MODIFY FUNCTION BASED ON READ/WRITE BMI 3$ ;BRANCH IF SPECIAL FUNCTION REQUEST ASL R5 ;MAKE A LOGICAL SECTOR NUMBER ASL R5 ;BLOCK*4 ASL R2 ;MAKE WORD COUNT UNSIGNED BYTE COUNT BR 4$ ;SKIP SPECIAL FUNCTION INITING .IF NE MMG$T 3$: MOV R4, -(SP) ;SAME R4 MOV DXCQE, R4 ;R4 -> Q.BLK OF QUEUE CLR -(SP) ;STORE 0 IN THE FIRST BUF WORD JSR PC, @$PTWRD ;Q.BUF IS NOW ORIGINAL +2 MOV (SP)+, R4 ;RESTORE R4 TST (R0)+ ;ADD 2 TO R0 ALSO. .IFF 3$: CLR (R0)+ ;CLEAR DELETED DATA FLAG WORD .ENDC MOV R2, PHYTRK ;SAVE TRACK FOR LATER MOV #128., R2 ;SET THE BYTE COUNT TO 128 ;*** RESULT OF ABOVE CODE. 4$: MOV R0, BUFRAD ;SAVE FOR LATER ;BUF ADDRESS .IF NE MMG$T ;IF DX WAS LOADED IN PAR1 THEN ;WE MUST USE PAR3 IN THE ; SILO-FILL/EMPTY ROUTINE MOV #KISAR1, (PC)+ ;ASSUME DX HANDLER IS NOT IN ; PAR1 20000-40000. DXPAR: .WORD 0 ;SAVE PAR1 HERE. .ENDC MOV R5, RXLSN ;SAVE LOGICAL SECTOR NUMBER MOV R4, RXFUN2 ;SAVE RD / WRT RXCS COMMAND MOV R2, BYTCNT ;SAVE FOR LATER ;BYTE COUNT. RXINIT: CLR R3 ;SET THIS IS INITIAL INTRPT FLG RXWAIT: MOV R3, INTINT ;INTINT >0 FOR PROCESS INTERRUPT ENTRY BIS #CSINT, @RXCSA ;ENABLE FLOPPY INTERRUPTS, ;THIS SHOULD CAUSE AN INTERRUPT ; WHEN DONE IS UP RTS PC ;RETURN, WE'LL BE BACK ; WITH AN INTERUPT RXERRJ: JMP RXERR ; INTERUPT ENTRY .IF NE ERL$G RXABRJ: JMP RXABRT .DRAST DX, 5, RXABRJ .IFF .DRAST DX, 5, RXABRT ;AST ENTRY POINT TABLE .ENDC MOV (PC)+, R4 ;GET ADDRESS OF RX STATUS RXCSA: .WORD RXCS ;ONLY POINTER TO I/O PAGE MOV R4, R5 ;POINT R5 TO RX DATA BUFFER .FORK DXFBLK ;REQUEST FORK PROCESS. TST (R5)+ ;CHECK FOR ERROR, R5 -> ; DATA BUFFER WITH ERROR INFO. BMI RXERR2 ;BRANCH IF ERROR ; CODE FOR FLOPPY POWER FAIL ; BIT #DBIN, @R5 ;DID INITIALIZE APPEAR IN RXES? ; BNE RXERR2 ;BRANCH IF SO TO RETRY NEG (PC)+ ;IS THIS INITIAL INTERRUPT? C=0 IF YES INTINT: .WORD 0 ;INTERNAL INITIAL INTERUPT FLAG MOV #128., R3 ;INIT R3 FOR 128 BYTES, USED LATER BIT #CSEBUF, RXFUN2 ;READ OR WRITE INTERUPT? BNE 2$ ;BRANCH IF READ BCC 1$ ;BRANCH TO AVOID UPDATING POINTERS JSR PC, NXTSEC ;SET UP FOR NEXT WRITE 1$: JSR R0, SILOFE ;LOAD THE SILO ;SILOFE ARG LIST MOVB (R2)+, @R5 ;MOVB TO BE PLACED IN-LINE IN SILOFE .WORD CSGO+CSFBUF ;FILL BUFFER COMMAND CLRB @R5 ;ZERO FILL SECTOR INSTRUCTION WHICH ;WOULD BE USED FOR SHORT WRITES ; BR 3$ ;SKIP READ FINISHING, (C BIT IS 0) 2$: BCC 3$ ;BRANCH TO AVOID EMPTYING SILO TST RXFUN2 ;IS THIS SPECIAL FUNCTION REQUEST? BPL 4$ ;BRANCH IF NOT SPECIAL FUNCTION CALL BIT #DBDD, @R5 ;IS DELETED DATA FLAG PRESENT? BEQ 4$ ;BRANCH IF IT IS .IF NE MMG$T MOV R4, -(SP) ;SAVE R4 MOV DXCQE, R4 ;R4 -> Q.BLK OF QUEUE MOV #1, -(SP) ;STORE -1 IN FIRST WORD OF BUFFER SUB #2, Q.BUF(R4) ;MOVE Q.BUF BACK TO FIRST WORD. JSR PC, @$PTWRD ;Q.BUF IS NOT ORIGINAL+2 MOV (SP)+, R4 ;RESTORE R4. .IFF MOV BUFRAD, R2 ;GET ADDRESS OF USER BUFFER AREA INC -(R2) ;SET FLAG WORD TO 1 INDICATING .ENDC ; DELETED DATA 4$: JSR R0, SILOFE ;MOVE THE DATA INTO MEMORY FROM SILO ;SILOFE ARG LIST MOVB @R5, (R2)+ ;MOVB TO BE PLACED IN LINE IN SILOFE .WORD CSGO+CSEBUF ;EMPTY BUFFER COMMAND MOVB @R5, R2 ;DATA SLUFFER TO BE USED FOR SHORT READ JSR PC, NXTSEC ;SET UP TO READ NEXT SECTOR 3$: MOV (PC)+, R3 ;GET THE LOGICAL SECTOR NUMBER RXLSN: .WORD 0 ;LOGICAL SECTOR NUMBER KEPT HERE MOV (PC)+, R2 ;IF SPECIAL FUNCTION R3 GETS SECTOR PHYTRK: .WORD 0 ;ABSOLUTE TRACK FOR SPECIAL FUNCS TST RXFUN2 ;IS THIS SPECIAL FUNCTION? BMI DOFUNC ;BRANCH IF SPECIAL FUNCTIONS ; FLOPPY INTERLEAVE ALGORITHM MOV #8., R2 ;LOOP COUNT 1$: CMP #6400, R3 ;DOES 26 GO INTO DIVIDEND? BHI 2$ ;BRANCH IF NOT, C CLEAR ADD #171400, R3 ;SUBTRACT 26 FROM DIVIDEND, SETS C 2$: ROL R3 ;SHIFT DIVIDEND AND QUOTIENT DEC R2 ;DEC LOOP COUNT BGT 1$ ;BRANCH TILL DIVIDE DONE MOV R3, R2 ;COPY TRACK NUMBER BIC #177400, R2 ; ALLOW UP TO 255. TRACKS CLRB R3 ;REMOVE TRACK NUMBER FROM REMAINDER SWAB R3 ;GET REMAINDER CMP #12., R3 ;C=1 IF 13<=R3<=25, ELSE C=0 ROL R3 ;DOUBLE FOR 2 TO 1 INTERLEAVE ;C-BIT COMES IN FOR SECTOR GROUP ASL R2 ;ADD TRACK TO TRACK SKEW TO SECTOR ADD R2, R3 ;SKEW BY 2* TRACK ADD R2, R3 ;SKEW BY 4* TRACK ADD R2, R3 ;SKEW BY 6* TRACK ASR R2 ;REFIX TRACK NUMBER INC R2 ;PUT TRACK # IN RANGE 1-76 TO HANDLE ;ANSI FLOPPY, TRACK 0 IS LEFT ALONE 3$: SUB #26., R3 ;MODULO SECTOR INTO RANGE -26,-1 BGE 3$ ;LOOP TILL REMAINDER GOES NEGATIVE ADD #27., R3 ;PUT SECTOR IN RANGE 1,26 DOFUNC: MOV (PC)+, @R4 ;SET THE FUNCTION RXFUN2: .WORD 0 ;READ OR WRITE COMMAND ON CORRECT UNIT 1$: TSTB @R4 ;WAIT FOR TRANSFER READY BEQ 1$ ;WAIT BPL RXERR2 ;TR IS NOT UP, THATS AN ERROR MOV R3, @R5 ;SET SECTOR FOR FLOPPY 2$: TSTB @R4 ;WAIT FOR TRANSFER READY BEQ 2$ ;WAIT BPL RXERR2 ;ERROR IF TR NOT UP MOV R2, @R5 ;TR UP,SET TRACK,AND CONTINUE. BR RXWAIT RXERR2: .IF NE ERL$G MOV PC, R3 ADD #DXRBUF-., R3 ;R3 -> LOCATION TO STORE REGISTER INFO. MOV R3, R2 ;SAVE IN R2 FOR LATER MOV (R4), (R3)+ ;STORE RXCS MOV (R5), (R3)+ ;STORE STATUS RXES BIC #100, (R4) ;TURN INTERRUPTS OFF. BIS #17, (R4) ;READ ERROR REGISTER 1$: BIT #40, (R4) ;WAIT FOR READ COMPLETIN BEQ 1$ MOV (R5), (R3) ;STORE IN BUFFER ;R2 = ADDRESS OF BUFFER. MOV #DXNREG, R3 ;R3 = # OF REGISTER IN LOW BYTE ADD #DXRCNT, R3 ;TOTAL RETRY COUNT IN HIGH BYTE MOV DXCQE, R5 ;R5 -> QUEUE MOVB RXTRY, R4 ;R4 = CURRENT RETRY COUNT IN LOW BYTE DEC R4 ADD #DXIDEN, R4 ;DEVICE ID IN HIGH BYTE JSR PC, @$ELPTR ;CALL ERROR LOGGER MOV RXCSA, R4 ;RESTORE R4 = RXCS ADDRESS .ENDC DEC RXTRY ;SHOULD WE TRY AGAIN? BLE RXERR ;BRANCH IF NO, RETRY COUNT EXPIRED MOV #CSINIT, @R4 ;START A RECALIBRATE JMP RXINIT ;EXIT THROUGH START OPERATION CODE RXERR: MOV DXCQE, R4 ;R4 -> CURRENT QUEUE ELEMENT BIS #1, @-(R4) ;SET HARD ERROR IN CSW .IF NE ERL$G BR RXALLD ;EXIT ON HARD ERROR RXDONE: MOV DXCQE, R5 ;CALL ERROR LOG ON SUCCESS. MOV #DXIDS, R4 ;R4 = ID/-1, R5 -> 3RD WORD JSR PC, @$ELPTR ;OF QUEUE ELEMENT. .IFF RXDONE: .ENDC RXALLD: CLR @RXCSA ;DISABLE FLOPPY INTERRUPTS BR RXEXIT ;SKIP RX INITIALIZE FUNCTION RXABRT: MOV #CSINIT, @RXCSA ;PERFORM AN RX11 INITIALIZE RXEXIT: .DRFIN DX ;GO TO I/O COMPLETION .IF NE MMG$T NXTSEC: ;DON'T ADD TO THE VIRTUAL ADDRESS ;SINCE THE PAR ADDRESS HAS BEEN ;ADDED TO IN SILDFE FOR 128 BYTES. .IFF NXTSEC: ADD R3, BUFRAD ;UPDATE BUFFER ADDRESS .ENDC INC RXLSN ;BUMP LOGICAL SECTOR SUB R3, BYTCNT ;REDUCE THE AMOUNT LEFT TO TRANSFER BHI RETURN ;BRANCH IF WE ARE NOT DONE CLR BYTCNT ;INIT FOR POSSIBLE SHORT WRITE BIT #CSEBUF+SPFUNC,RXFUN2 ;IS THIS A READ OR SPECIAL ;FUNCTION OPERATION? BNE 1$ ;BRANCH IF EITHER, ; FOR .WRITE WE HAVE TO ZERO ; TO THE END OF A BLOCK BIT #3,RXLSN ;ARE WE AT 1ST SECTOR IN BLOCK? BNE RETURN ;BRANCH IF NOT TO CONTINUE 1$: TST (SP)+ ;POP RETURN ADDRESS FROM STACK BR RXDONE ;REQUEST DONE RETURN: RTS PC ; R3 IS 128 ON ENTRY ; THIS ROUTINE ASSUMES ERROR CAN NOT COME UP ; DURING A FILL OR EMPTY!! SILOFE: MOV (R0)+, EFBUF ;PUT CORRECT MOV INSTRUCTION IN FOR ;EITHER FILLING OR EMPTYING RX BUFFER MOV (R0)+, @R4 ;INITIATE FILL OR EMPTY BUFFER COMMAND MOV (PC)+, -(SP) ;ASSUME MAXIMUM OF BYTCNT TO MOVE FROM ;BUFFER BYTCNT: .WORD 0 ;THE BYTE COUNT IS KEPT HERE BEQ ZFILL ;BRANCH IF SEEK OR SHORT WRITE ;NOTE SEEK DOES THE EMPTY (TIME WASTER) CMP @SP, R3 ;NOW MAKE SURE COUNT IS 128 OR LESS BLOS 1$ ;BRANCH IF @SP IS 128 OR LESS MOV R3, @SP ;RESET COUNT TO 128 1$: MOV (PC)+, R2 ;PUT THE BUFFER ADDRESS IN R2 BUFRAD: .WORD 0 ;THE BUFFER ADDRESS IS KEPT HERE .IF NE MMG$T MOV @DXPAR, DXPARS ;SAVE THE CONTENET OF PAR. MOV DXCQE, R1 ;R1 -> Q.BLK OF QUEUE MOV Q.PAR(R1), @DXPAR ;STORE THE BUFFER PAR VALUE ; IN THE PAR .ENDC ;WE ARE USING. TRBYT: TSTB @R4 ;WAIT FOR TRANSFER READY BPL TRBYT ;BRANCH IF TR NOT UP EFBUF: HALT ;INSTRUCTION TO MOV OR SLUFF ; DATA FROM BUFFER GETS PLACED HERE ; MOVE DATA SLUFF DATA ;MOVB (R2)+,@R5 CLRB @R5 FILL ;MOVB @R5,(R2)+ MOVB @R5,R2 EMPTY DEC @SP ;CHECK FOR COUNT DONE BGT TRBYT ;STILL MORE TO TRANSFER .IF NE MMG$T MOV DXPARS, @DXPAR ;RESTORE THE CONTENT OF THE PAR ADD #2, Q.PAR(R1) ;ADD 128 BYTES TO THE BUFFER ADDRESS BY .ENDC ;MOVING THE PAR RATHER THAN THE VIRTUAL ;BUFFER ADDRESS. THIS AVOIDS OVERLAPPING ;A PAR BOUNDARY ON A LARGE TRANSFER. ZFILL: MOV @R0, EFBUF ;CHANGE MOV INSTRUCTION TO CORRECT ;INSTR FOR SLUFFING DATA TO/FROM BUFFER 1$: TSTB @R4 ;WAIT LOOP BEQ 1$ ;WAIT FOR SOME INDICATION ; (TRREQ, DONE) BMI EFBUF ;BRANCH IF TR CAME UP TO SLUFF DATA BIT (R0)+, (SP)+ ;BUMP R0 TO RETURN ADDR AND ; REMOVE JUNK WORD FROM STACK ; LEAVING C BIT=0 RTS R0 ;RETURN .BYTE 6*2 ;READ+GO -> WRITE DELETED+GO .BYTE -2*2 ;READ+GO -> WRITE+GO .BYTE 0*2 ;READ+GO -> READ+GO CHGTBL: .BYTE 0*2 ;READ/WRITE STAY THE SAME .EVEN DXFBLK: .WORD 0,0,0,0 ;DX FORK QUEUE ELEMENT .IF NE MMG$T DXPARS: .WORD 0 ;SAVE CONTENTS OF PAR1 OR PAR3 HERE. .ENDC .IF NE ERL$G DXRBUF: .BLKW DXNREG ;ERROR LOG STORAGE FOR .ENDC .IF NE RXT$O RXTVTB: .WORD RXVEC ;FIRST DX VECTOR .WORD DXINT-. ;INTERRUPT ENTRY .WORD 340 ;ZERO PS FUNCTION BITS. .WORD RX$CV2 ;SECOND DX VECTOR .WORD DXINT-. ;INTERRUPT ENTRY .WORD 340 .WORD 0 ;END OF TABLE .ENDC .DREND DX .END