.TITLE MOSVII - MOS VIILNI DEVICE DRIVER ROUTINES ; THERE ARE TWO ENTRIES FOR EACH DEVICE IN THE DCTS - ; THE TWO MUST HAVE THEIR LINK DEVICES SET CORRECTLY. ; ALSO, THIS IS A WORD INTERFACE SO ALL TRANSFERS ARE ; ROUNDED UP AND MUST START ON WORD BOUNDARIES. .INSRT ../moscnf-1.sml .INSRT ../mosmac.sml .INSRT ../mostbl.sml VIIDBG = 0 ; SET TO ONE TO GET ERROR MSGS .ENABL ISD .LIST ME $CNFIG .PAGE $DFDCT .PAGE $DFIOR .PAGE $DFIST .NLIST ME .LIST MEB .CSECT MOS .GLOBL .VIIII ;NET INPUT INITIALIZE ROUTINE .GLOBL .VIIOI ;NET OUTPUT INITIALIZE ROUTINE .GLOBL .VIIIT ;NET INPUT TRANSFER ROUTINE .GLOBL .VIIOT ;NET OUTPUT TRANSFER ROUTINE .GLOBL VIIIIN ;NET INPUT INTERRUPT ROUTINE .GLOBL VIIOIN ;NET OUTPUT INTERRUPT ROUTINE .GLOBL $IOCMP ;I/O COMPLETION ENTRY POINT .GLOBL TYPE ;A FEW THINGS TO HACK THE SYSTEM .GLOBL $MVITP,$MVIBT ;CODE SPACE TOP/BOTTOM .SBTTL VII INTERFACE ASSIGNMENTS ; REGISTERS VIICSR = 00 ; VII COMMAND STATUS REGISTER VIIWC = 02 ; VII BYTE COUNT REG VIIAL = 04 ; VII ADDR REG (LO) VIIAH = 06 ; VII ADDR REG (HI) ; COMMAND STATUS REG BITS VII.ENB = 1 ; Enable Operation VII.DENB = 2 ; Enable DMA VII.HEN = 4 ; Host Relay Enable (Rcv) VII.CPB = 4 ; Clear Packet Buffer (Xmit) VII.STE = 10 ; Self Test Enable (Rcv) VII.UNT1 = 10 ; Unused (Xmit) VII.LPB = 20 ; Digital Loopback (Rcv) VII.INR = 20 ; Initialize Ring (Xmit) VII.RSET = 40 ; Reset VII.IEN = 100 ; Interrupt Enable VII.RDY = 200 ; Done VII.DPR = 400 ; Data Present (Rcv) VII.RFS = 400 ; Refused (Xmit) VII.NXM = 1000 ; Non Existent Memory VII.OVR = 2000 ; Overrun VII.ODB = 4000 ; Odd Byte Count (Achtung, mein Fuehrer) (Rcv) VII.UNT2 = 4000 ; Unused (Xmit) VII.LDE = 10000 ; Link Data Error (Rcv) VII.OPT = 10000 ; Output Timeout (Xmit) VII.RNOK = 20000 ; Ring Not OK VII.BDF = 40000 ; Bad Format in Operation VII.NIR = 100000 ; Not in Ring ; CONSTANTS (SOME FUNDAMENTAL) .IF NE, P1103 NLMSEC = 205 ; NUMBER OF LOOPS/MSEC FOR $LOOP .IFF .IF NE, P1120 NLMSEC = 203 ; NUMBER OF LOOPS/MSEC FOR $LOOP .IFF .ERROR NEED TO SPECIFY NLMSEC .ENDC .ENDC ; STATIC TIMER VALUES VIIRT = 10. * NLMSEC ; 10 MSEC DELAY FOR RELAY CLOSE ; RELAY SHOULD TAKE AT MOST THIS LONG ; THIS IS NOT NEEDED BECAUSE VIIRI IS BROKEN, SEE BELOW ; ; VIITT = 10. * NLMSEC ; TIME TO WAIT WHILE A FORCED MESSAGE ; ; GOES OUT VIIFMX = 8. ; MAX NUMBER OF TIMES TO TRY TO ; INIT RING WITH A SINGLE MESSAGE VIIMX = 2044. ; MAX MESG LENGTH VIIHL = 2 ; HEADER LENGTH VIIIER = VII.DPR!VII.OVR!VII.BDF ; INPUT AND OUTPUT ERRORS VIIOER = VII.OPT!VII.RFS!VII.OVR!VII.BDF VIIIHE = VII.NXM!VII.NIR ; FATAL ERRORS VIIOHE = VII.NXM!VII.NIR ; SHOULD NEVER BE OUT OF RING ; VII.OVR SHOULD BE VIIOHE WHEN ; HARDWARE FIXED .PAGE .SBTTL VII INTERFACE OUTPUT INITIALIZATION ROUTINE ; ; CALLED WITH: R2 - ADDRESS OF DCT ; $MVITP: .VIIOI: $PUSH R0 MOV DCTLNK(R2),R0 ; NEED TO GO GET RELAY TURNED ON? BIT #DF.OFL,DCTFLG(R0) BEQ 1$ $PUSH R2 ; YES, CALL RCV INIT ROUTINE MOV R0,R2 CALL .VIIII $POP R2 BIS #DF.OFL,DCTFLG(R0) ; SINCE INT VECTOR NOT SET UP 1$: MOV DCTCSR(R2),R0 CLR VIIAH(R0) ; THESE DON'T CLEAR ON INIT MOV #VII.IEN,VIICSR(R0) BIC #DF.OFL,DCTFLG(R2) $POP R0 RTS PC .PAGE .SBTTL VII INTERFACE INPUT INITIALIZATION ROUTINE ; ; CALLED WITH: R2 - ADDRESS OF DCT ; ; THIS CODE IS RESPONSIBLE FOR CLOSING THE RELAY, MOSTLY. THERE IS CODE ; IN SEVERAL PLACES TO DO TOKEN REGENERATION, BUT SINCE THERE ARE CURRENTLY ; MANY DIFFICULTIES THE PROBLEMS AND ALGORITHMS FOR RING/ENTRY AND TOKEN ; RECREATION ARE DESCRIBED HERE. ; ; THE PROBLEM WITH THE RELAY IS THAT THE VII.NIR BIT IS USELESS. IT IS ; SIMPLY VII.HEN INVERTED, AND THUS TELLS US NOTHING OF THE SENSE OF THE ; RELAY. INSTEAD, WE WAIT A FIXED TIMED FOR THE RELAY TO CLOSE. ; ; ONCE THE RELAY CLOSES, THE MODEMS MUST ALL RELOCK ONTO FREQUENCY. ; THE TIME TAKEN FOR THIS VARIES GREATLY, DEPENDING ON THE NUMBER ; OF NODES IN THE RING AND THE PHASE OF THE MOON. IF THE FINE ADJUST ; HASN'T LOCKED ON IN 200 MSEC, THE COARSE ADJUST TAKES OVER. IT CAN ; TAKE UP TO 7 OR SO OF THESE FOR THE MODEMS TO REALLY LOCK ON. ; ; THERE IS ANOTHER PROBLEM IN THAT TOKEN CREATION IS INHIBITED UNLESS ; THE TOKEN TIMER (AND ONLY THAT TIMER) HAS TIMED OUT. THUS, IF THE FLAG TIMER ; TIMES OUT AND ALERTS YOU TO RING DOWN, YOU ARE UNABLE TO DO ANYTHING ; ABOUT IT, AND YOU DON'T KNOW YOU CAN'T. THESE TWO PROBLEMS MAKE HASH ; OF ALL THE OLD ALGORITHMS, SO I HAVE A NEW SIMPLE ONE FOR INITIALIZING ; THE RING, BOTH WHEN IT DIES AND YOU ENTER: ; ; 1) ON OUTPUT, TURN OUTPUT ON ; 2) IF RING NOT UP, SET FORCE ; 3) ON INTRERRUPT, IF OUTPUT TIMED OUT TRY AGAIN ; 4) UNLESS A COUNT EXCEEDED A MAXIMUM, IN WHICH CASE PUNT ; ; ; THE FOLLOWING CODE MAY BE USEFUL IF WE WANT TO HACK THE MODEM STUFF ; ; VIIMT = 200. * 130. ; CAN BE UP TO SEVEN OF THESE 300 MSEC ; ; PERIODS FOR THE MODEM TO SETTLE, TRY ONE ; ; MOV #VIIMT,R1 ; WAIT FOR MODEM SYNCH ;12$: $LOOP R1,11$ ; TIME OUT EVENTUALLY .VIIII: $PUSH R0, R1 MOV DCTCSR(R2),R0 CLR VIIAH(R0) MOV #VII.IEN,VIICSR(R0) BIS #VII.HEN,VIICSR(R0) ; TURN ON RELAY ; THIS CODE HAS BEEN REMOVED SINCE IT IS USELESS AT THE MOMENT ; UNTIL PROTEON GIVES US BETTER HARDWARE TO TELL WHEN THE RELAY ; IS REALLY CLOSED. ; INSTEAD, THE CODE BELOW WAITS FOR A FIXED AMOUNT OF TIME. ; ; MOV #VIIRT,R1 ; WAIT FOR BOUNCE ;1$: BIT #VII.NIR,VIICSR(R0) ; BEQ 2$ ; $LOOP R1,1$ ; TIME OUT EVENTUALLY ; BUGHLT ; REALLY NEED TO DO BETTER HERE MOV #VIIRT,R1 ; WAIT FOR BOUNCE 11$: $LOOP R1,11$ ; TIME OUT EVENTUALLY ; THIS CODE REMOVED BECAUSE VIIRI DOESN'T WORK ; ;2$: BIT #VII.RNOK,VIICSR(R0) ; RING UP? ; BEQ 3$ ; YES ; MOV DCTLNK(R2),R0 ; MOV DCTCSR(R0),R0 ; CALL VIIRI ; TRY INIT RING 3$: BIC #DF.OFL,DCTFLG(R2) $POP R1, R0 RTS PC .PAGE .SBTTL VII INPUT TRANSFER INITIALIZATION ROUTNE ; ; CALLED WITH: R2 - POINTER TO DEVICE CONTROL TABLE (DCT) ; ; RETURNS WITH: R0 THRU R5 - UNCHANGED ; .VIIIT: $PUSH R0,R1 MOV DCTBR(R2),R1 CMP R1,#VIIHL+2 ; LONG ENOUGH FOR MINIMAL MSG? BLT 1$ CMP R1,#VIIMX ; NOT TOO LONG? BGT 1$ BIT #1,R1 ; WORD XFER? BNE 1$ BIT #1,DCTUVA(R2) ; WORD ADDRESS? BEQ 2$ 1$: BUGHLT ; THIS CODE REMOVED BECAUSE VIIRI DOESN'T WORK ; ;2$: MOV DCTCSR(R2),R0 ; RING UP? ; BIT #VII.RNOK,VIICSR(R0) ; BEQ 3$ ; YES ; ; $PUSH R0 ; MOV DCTLNK(R2),R0 ; MOV DCTCSR(R0),R0 ; CALL VIIRI ; TRY INIT RING ; $POP R0 2$: 3$: MOV DCTCSR(R2),R0 ; SET UP XFER MOV DCTUVA(R2),VIIAL(R0) ASR R1 ; AND CONVERT TO MINUS WORDS NEG R1 MOV R1,VIIWC(R0) BIS #VII.ENB!VII.DENB,VIICSR(R0) ; ENAB (CLRS I/P P/B) .IF NE, VIIDBG BIT #VII.RDY,VIICSR(R0) ; READY CLEARED? BEQ 4$ MOV #NRCLR,R0 ; NOPE, BARF CALL TYPE ; JUST LEAVE AND HOPE IT WORKS .ENDC 4$: BIS #DF.ACT,DCTFLG(R2) ; INDICATE ACTIVE $POP R1,R0 RTS PC .PAGE .SBTTL VII OUTPUT TRANSFER INITIALIZATION ROUTINE ; ; CALLED WITH: R2 - POINTER TO DEVICE CONTROL TABLE (DCT) ; ; RETURNS WITH: R0 THRU R5 - UNCHANGED ; .VIIOT: $PUSH R0,R1 MOV DCTBR(R2),R1 CMP R1,#VIIHL+2 ; LONG ENOUGH FOR MINIMAL MSG? BLT 1$ CMP R1,#VIIMX ; NOT TOO LONG? BGT 1$ BIT #1,R1 ; WORD XFER? BNE 1$ BIT #1,DCTUVA(R2) ; WORD ADDRESS? BEQ 2$ 1$: BUGHLT 2$: CLR VIIFRC ; CLEAR FORCING FLAG MOV DCTCSR(R2),R0 ; SET UP XFER MOV DCTUVA(R2),VIIAL(R0) ASR R1 ; CONVERT TO MINUS WORDS NEG R1 MOV R1,VIIWC(R0) ; AND GO BIS #VII.ENB!VII.DENB!VII.CPB,VIICSR(R0) .IF NE, VIIDBG BIT #VII.RDY,VIICSR(R0) ; READY CLEARED? BEQ 4$ $PUSH R0 MOV #NRCLR,R0 ; NOPE, BARF CALL TYPE ; JUST LEAVE AND HOPE IT WORKS $POP R0 .ENDC 4$: BIT #VII.RNOK,VIICSR(R0) ; RING UP? BEQ 3$ ; YES BIS #VII.INR,VIICSR(R0) ; NO, TRY TO BRING UP WITH THIS XFER INC VIIFRC ; AND FLAG AS DOING SO MOV #RINIT,R0 ; MENTION DOING SO CALL TYPE 3$: BIS #DF.ACT,DCTFLG(R2) ; INDICATE ACTIVE $POP R1,R0 RTS PC .PAGE .SBTTL VII INPUT INTERRUPT HANDLER ; ; CALLED WITH: R0 - ADDRESS OF DEVICE CONTROL TABLE ; (SP) - OLD R0 ; VIIIIN: $PUSH R1,R2 MOV DCTCSR(R0),R1 BIT #DF.ACT,DCTFLG(R0) ; BUSY? BEQ 1$ ; NOPE, LOSSAGE BIT #VII.RDY,VIICSR(R1) ; DID HE COMPLETE? BNE 2$ ; YAH, GO HACK 1$: BUGHLT 2$: BIT #VIIIHE,VIICSR(R1) ; HARD ERR? BEQ 3$ ; NOPE BUGHLT 3$: MOV DCTQH(R0),R2 ; GET IORB BIT #VIIIER,VIICSR(R1) ; ANY ERRORS? BEQ 4$ BIS #I.ERR,IRSTA(R2) ; LOG 4$: MOV VIIWC(R1),IRBX(R2) ; MOVE NEG OF NUM WORDS LEFT IN ASL IRBX(R2) ; GET BYTES BIT #VII.ODB,VIICSR(R1) ; ACHTUNG, MEIN FUEHRER BEQ 5$ DEC IRBX(R2) 5$: ADD DCTBR(R0),IRBX(R2) ; INDICATE NUMBER OF BYTES DONE BIC #DF.ACT,DCTFLG(R0) ; CLEAR, AS IOCMR WILL SET IF NEEDED $POP R2,R1 ; AND WE'RE DONE JMP $IOCMP .PAGE .SBTTL VII OUTPUT INTERRUPT HANDLER ; ; CALLED WITH: R0 - ADDRESS OF DEVICE CONTROL TABLE ; (SP) - OLD R0 ; VIIOIN: $PUSH R1,R2 MOV DCTCSR(R0),R1 BIT #DF.ACT,DCTFLG(R0) ; BUSY? BEQ 1$ ; NOPE, ERROR BIT #VII.RDY,VIICSR(R1) ; DID HE COMPLETE? BNE 2$ ; YAH, GO HACK 1$: BUGHLT 2$: BIT #VIIOHE,VIICSR(R1) ; HARD ERR? BEQ 3$ ; NOPE BUGHLT 3$: BIT #VII.OPT,VIICSR(R1) ; TIMED OUT? BEQ 5$ ; NO, GO TO STANDARD FINISH CODE ; CODE BELOW REMOVED AND REPLACED WITH CODE TO RETRY UP TO A MAXIMUM ; NUMBER OF TIMES DUE TO HARDWARE LOSSAGE ; ; TST VIIFRC ; WERE WE INITING RING? ; BEQ 4$ ; NO, HAVE A TRY AT BRINGING IT UP ; BUGHLT .IF NE, VIIDBG $PUSH R0 MOV #TMOUT,R0 ; MENTION DOING SO CALL TYPE $POP R0 .ENDC CMP VIIFRC, #VIIFMX ; HAD WE HAD TO MANY TRIES? BGE 5$ ; TOO MANY, PUNT 4$: BIS #VII.ENB,VIICSR(R1) ; NOPE, TRY AGAIN BIT #VII.RNOK,VIICSR(R1) ; RING UP? BEQ 44$ ; YES BIS #VII.INR,VIICSR(R1) ; NO, TRY TO BRING UP WITH THIS XFER INC VIIFRC ; GOD I AM STARTING TO HATE THIS KLUDGE .IF NE, VIIDBG MOV #RINIT,R0 ; MENTION DOING SO CALL TYPE .ENDC 44$: $POP R2,R1,R0 $RTT ; WHAT THE HELL, THIS CODE WAS BOGUS IN THE OLD IMPLEMENTATION BUT ; IT MAKES SENSE NOW. PROBABLY ALL THIS CODE SHOULD BE TRASHED AND ; REDONE, BUT LET'S LEAVE IT FOR NOW. 5$: .IF NE, VIIDBG BIT #VII.RNOK,VIICSR(R1) ; IS RING UP NOW? BEQ 6$ $PUSH R0 MOV #CBRUM,R0 ; NO, BARF CALL TYPE $POP R0 .ENDC 6$: MOV DCTQH(R0),R2 ; GET IORB BIT #VIIOER,VIICSR(R1) ; ANY ERRORS? BEQ 7$ BIS #I.ERR,IRSTA(R2) ; LOG 7$: MOV VIIWC(R1),IRBX(R2) ; MOVE NEG OF NUM WORDS LEFT IN ASL IRBX(R2) ; GET BYTES ADD DCTBR(R0),IRBX(R2) ; INDICATE NUMBER OF BYTES DONE BIC #DF.ACT,DCTFLG(R0) ; CLEAR, AS IOCMR WILL SET IF NEEDED $POP R2,R1 ; AND WE'RE DONE JMP $IOCMP ; .PAGE ; .SBTTL BRING UP RING BY FORCING A SHORT MESSAGE ; ;; ;; ATTEMPT TO INIT RING BY FORCING OUT A MESSAGE ;; ASSUMES R0 POINTS TO VII REGISTERS ;; ; ;VIIRI: $GETPS -(SP) ; MAKE SURE NOT INTERRUPTED ; $DSABL ; $PUSH R1 ; ; BIT #VII.RNOK,VIICSR(R0) ; REALLY NOT THERE? ; BEQ 5$ ; SOMEBODY ELSE FIXED? ; ; BIT #VII.ENB,VIICSR(R0) ; OP IN PROGESS? ; BNE 5$ ; PUNT (MAYBE SHOULD FORCE?) ; ;2$: MOV #VIITM,VIIAL(R0) ; GET SHORT MSG ; MOV #-VIITL,VIIWC(R0) ; MOV #VII.ENB!VII.DENB!VII.CPB!VII.INR,VIICSR(R0) ; MOV #VIITT,R1 ; PUSH IT OUT ONTO RING ;3$: BIT #VII.RDY,VIICSR(R0) ; BNE 4$ ; $LOOP R1,3$ ; TIME OUT EVENTUALLY ; BUGHLT ; ;4$: MOV #VII.IEN,VIICSR(R0) ; BIT #VII.RNOK,VIICSR(R0) ; MAKE IT? ; BEQ 5$ ; YES ; $PUSH R0 ; MOV #CBRUM,R0 ; NO, BARF ; CALL TYPE ; $POP R0 ; ;5$: $POP R1 ; $GETPS (SP)+ ; RTS PC .PAGE .SBTTL DATA AREA .CSECT MOSDAT, STATIC ; RING INITIALIZATION VIIFRC: .WORD 0 ; FLAG AS TRYING TO INIT ; UNUSED SINCE VIIRI BROKEN ; ; .. = . ;VIITM: .BYTE 377, 0 ; .BLKW 77 ; SHORT MESSAGE (THE RING LIKES ZEROS) ; VIITL = . - .. ; LENGTH OF TOKEN MESSAGE CBRUM: .ASCIZ <15><12>/Can't bring ring up/<15><12> .EVEN NRCLR: .ASCIZ <15><12>/No ready clear/<15><12> .EVEN RINIT: .ASCIZ <15><12>/Reinitializing ring/<15><12> .EVEN TMOUT: .ASCIZ <15><12>/Timeout/ .EVEN $MVIBT: .END