.TITLE MOSCHA - MOS CHAOS DEVICE DRIVER ROUTINES ; THERE ARE TWO ENTRIES FOR EACH DEVICE IN THE DCTS - THE RECEIVE ; SIDE MUST COME FIRST, AND THE TWO MUST HAVE THEIR LINK DEVICES ; SET CORRECTLY. ALSO, THE TRANSMIT SIDE MUST HAVE AS ITS INTERRUPT ; VECTOR A LOCATION WHICH WILL NEVER RECEIVE AN INTERRUPT. ; ALL INTERRUPTS ARE CALLED THROUGH THE PREPROCESSOR WHICH ; LOOKS LIKE THE READ SIDE HANDLER TO MOS. ; ALSO, IT'S A WORD DEVICE SO ALL TRANSFERS MUST START ON WORD ; BOUNDARIES AND BE AN EVEN NUMBER OF BYTES LONG. (DOESN'T MAKE ; SENSE TO PAD SINCE THE ADDRESS IS THE LAST BYTE, AND IF IT'S ; WRONG?) ACTUALLY, SINCE THE TRANSFER IS DONE IN SOFTWARE, I ; COULD GET AROUND THIS RESTRICTION, BUT IT'S A ROYAL PAIN OF ; LITTLE WORTH. FSTMOV = 1 ; SET TO ONE FOR UNROLLED MOV .INSRT ../moscnf-1.sml .INSRT ../mosmac.sml .INSRT ../mostbl.sml .ENABL ISD .LIST ME $CNFIG .PAGE $DFDCT .PAGE $DFIOR .PAGE $DFIST .NLIST ME .LIST MEB .CSECT MOS .GLOBL .CHAI ;NET INITIALIZE ROUTINE .GLOBL .CHAIT ;NET INPUT TRANSFER ROUTINE .GLOBL .CHAOT ;NET OUTPUT TRANSFER ROUTINE .GLOBL CHAIN ;NET INTERRUPT ROUTINE .GLOBL CHADDR ;ADDRESS OF CHAOS INTERFACE .GLOBL $IOCMR ;I/O COMPLETION EXIT .GLOBL $MCHTP,$MCHBT ;CODE SPACE TOP/BOTTOM .SBTTL CHAOS INTERFACE REGISTER ASSIGNMENTS ; ; CHACSR = 0 ;COMMAND AND STATUS REG CHAWBF = 2 ;WRITE BUFFER (WRITE) CHANUM = 2 ;INTERFACE ADDRESS (READ) CHARBF = 4 ;READ BUFFER CHARBC = 6 ;RECEIVED BIT COUNTER CHAXMT = 12 ;READ TO XMIT ; COMMAND STATUS REG BITS CH.TBSY = 1 ;TRANSMITTER BUSY CH.LPBK = 2 ;LOOPBACK CH.SPY = 4 ;NETWORK SPY CH.REN = 10 ;RECEIVE ENABLE CH.RIEN = 20 ;RECEIVE INTERRUPT ENABLE CH.TIEN = 40 ;TRANSMIT INTERRUPT ENABLE CH.ABRT = 100 ;TRANSMISSION ABORTED CH.TDN = 200 ;TRANSMIT DONE CH.TCLR = 400 ;TRANSMIT CLEAR CH.LC = 17000 ;RECEIVE LOST COUNT CH.RST = 20000 ;INTERFACE RESET CH.CRC = 40000 ;RECEIVE CRC ERROR CH.RDN = 100000 ;RECEIVE DONE ; RECIEVED BIT COUNTER BITS CH.RBCN = 7777 ;BIT COUNTER CH.OVFL = 30000 .PAGE .SBTTL SOME CHAOS CONSTANTS CHAWHL = 2 ;HEADER(TRAILER) LENGTH CHARHL = 6 ;4 BYTES OF HEADER ADDED BY HARDWARE CHARMX = 776 ;MAX PACKER SIZES CHAWMX = > .PAGE .SBTTL FAST MOVE INFO .IF NE, FSTMOV NCOPIES = 20 ; factor loop is unrolled (must be power of 2) NMSK = -NCOPIES ; used to figure how far into the loop to jump NSHFT = 4 ; log of copies, used for divide by shift .ENDC .PAGE .SBTTL CHAOS INTERFACE INITIALIZATION ROUTINE ; ; CALLED WITH: R2 - ADDRESS OF DCT ; $MCHTP: .CHAI: $PUSH R0,R1 MOV DCTCSR(R2),R0 MOV #CH.RST,CHACSR(R0) ; CLEAR MOV CHANUM(R0),CHADDR ; STORE AWAY MOV DCTLNK(R2),R0 ; GET COMPANION DEVICE MOV R0,R1 ; SET UP OTHER VECTOR ADD #DCTIHX,R1 MOV R1,@DCTIVA(R0) MOV DCTIVA(R0),R1 MOV #340,2(R1) BIC #DF.OFL,DCTFLG(R2) ; INDICATE DEVICE ON-LINE BIC #DF.OFL,DCTFLG(R0) ; DO BOTH SIDES $POP R1,R0 RTS PC ; RETURN .PAGE .SBTTL CHAOS INPUT TRANSFER INITIALIZATION ROUTNE ; ; CALLED WITH: R2 - POINTER TO DEVICE CONTROL TABLE (DCT) ; ; RETURNS WITH: R0 THRU R5 - UNCHANGED ; .CHAIT: $PUSH R0 CMP DCTBR(R2),#CHARHL ; LONG ENOUGH FOR MINIMAL MSG? BLT 1$ CMP DCTBR(R2),#CHARMX BGT 1$ BIT #1,DCTBR(R2) ; WORD PACKET? BNE 1$ BIT #1,DCTUVA(R2) ; EVEN ADDR? BEQ 2$ 1$: BUGHLT 2$: MOV DCTCSR(R2),R0 BIS #CH.REN,CHACSR(R0) ; ENABLE BIS #CH.RIEN,CHACSR(R0) ; ENABLE INTERRUPT BIS #DF.ACT,DCTFLG(R2) ; INDICATE ACTIVE $POP R0 RTS PC .PAGE .SBTTL CHAOS OUTPUT TRANSFER INITIALIZATION ROUTINE ; ; CALLED WITH: R2 - POINTER TO DEVICE CONTROL TABLE (DCT) ; ; RETURNS WITH: R0 THRU R5 - UNCHANGED ; .CHAOT: $PUSH R0,R1,R3,R4 MOV DCTBR(R2),R1 ; PKT LEN CMP R1,#CHAWHL ; LONG ENOUGH FOR MINIMAL MSG? BLT 1$ CMP R1,#CHAWMX ; TOO LONG? BGT 1$ BIT #1,R1 ; WORD PACKET? BNE 1$ BIT #1,DCTUVA(R2) ; EVEN ADDR? BEQ 2$ 1$: BUGHLT 2$: ASR R1 ; CONVERT TO WORDS MOV DCTCSR(R2),R0 ; SET UP XFER BIS #CH.TCLR,CHACSR(R0) ; CLEAR MOV DCTUVA(R2),R3 ; SET UP TRANSFER MOV R0,R4 ADD #CHAWBF,R4 .IF EQ, FSTMOV ; USE UNROLLED CODE? 3$: MOV (R3)+,@R4 ; DA BIG BLT $LOOP R1,3$ .IFF MOV R1,R0 ; R1 pass count, R0 remainder .IF NE, P11E ; If proc with EIS ASH #-NSHFT,R1 ; Figure out how many passes .IFF ; Nope, do it the hard way .REPT NSHFT ASR R1 .ENDR .ENDC INC R1 ; Plus one for incomplete one BIC #NMSK,R0 ; Now find out how many there NEG R0 ; Need to skip the others ASL R0 ; Make into an offset JMP CHXTBL(R0) CHXLP: .REPT NCOPIES ; Table MOV (R3)+,@R4 .ENDR CHXTBL: $LOOP R1,CHXLP ; Do remaining complete passes MOV DCTCSR(R2),R0 .ENDC MOV CHAXMT(R0),R3 ; START XMITTER BIS #CH.TIEN,CHACSR(R0) ; AND GO BIS #DF.ACT,DCTFLG(R2) ; INDICATE ACTIVE $POP R4,R3,R1,R0 RTS PC .PAGE .SBTTL CHAOS INTERRUPT HANDLER ; ; CALLED WITH: R0 - ADDRESS OF DEVICE CONTROL TABLE ; (SP) - OLD R0 ; CHAIN: $PUSH R1,R2,R3,R4 MOV DCTCSR(R0),R1 BIT #DF.ACT,DCTFLG(R0) ; INPUT SIDE BUSY? BEQ CHAOP ; NO, TRY OUTPUT BIT #CH.RDN,CHACSR(R1) ; DID HE COMPLETE? BEQ CHAOP ; NO, TRY OUTPUT MOV DCTQH(R0),R2 ; GET IORB BIT #CH.OVFL,CHARBC(R1) ; OVERFLOWED? BNE 1$ BIT #CH.CRC,CHACSR(R1) ; ANY ERRORS? BEQ 2$ 1$: BIS #I.ERR,IRSTA(R2) ; LOG 2$: MOV CHARBC(R1),R3 ; INDICATE NUMBER OF BYTES DONE BIC #-CH.RBCN-1,R3 INC R3 $ASH -3,R3 ; CONVERT TO BYTES CMP R3,DCTBR(R0) ; TOO LONG? BLE 3$ MOV DCTBR(R0),R3 BIS #I.ERR,IRSTA(R2) ; FLAG AND TRUNCATE 3$: MOV R3,IRBX(R2) ; NOTE AS LENGTH ASR R3 ; CONVERT TO WORDS MOV R1,R4 ADD #CHARBF,R4 MOV DCTUVA(R0),R2 .IF EQ, FSTMOV ; USE UNROLLED CODE? 4$: MOV @R4,(R2)+ ; BLT $LOOP R3,4$ .IFF MOV R3,R1 ; R1 pass count, R3 remainder .IF NE, P11E ; If proc with EIS ASH #-NSHFT,R1 ; Figure out how many passes .IFF ; Nope, do it the hard way .REPT NSHFT ASR R1 .ENDR .ENDC INC R1 ; Plus one for incomplete one BIC #NMSK,R3 ; Now find out how many there NEG R3 ; Need to skip the others ASL R3 ; Make into an offset JMP CHRTBL(R3) CHRLP: .REPT NCOPIES ; Table MOV @R4,(R2)+ .ENDR CHRTBL: $LOOP R1,CHRLP ; Do remaining complete passes MOV DCTCSR(R0),R1 .ENDC BIC #CH.RIEN,CHACSR(R1) ; CLEAR, CROCK HARDWARE BIC #DF.ACT,DCTFLG(R0) ; CLEAR, AS IOCMR WILL SET IF NEEDED CALL $IOCMR CHAOP: MOV DCTLNK(R0),R0 ; NOW DO OUTPUT SIDE BIT #DF.ACT,DCTFLG(R0) ; BUSY? BEQ CHADN BIT #CH.TDN,CHACSR(R1) ; DID HE COMPLETE? BEQ CHADN ; NO, FINISH MOV DCTQH(R0),R2 ; GET IORB BIT #CH.ABRT,CHACSR(R1) ; O/P ERRORS? BEQ 1$ BIS #I.ERR,IRSTA(R2) ; LOG 1$: MOV DCTBR(R0),IRBX(R2) ; INDICATE NUMBER OF BYTES DONE BIC #CH.TIEN,CHACSR(R1) ; CLEAR, CROCK HARDWARE BIC #DF.ACT,DCTFLG(R0) ; CLEAR, AS IOCMR WILL SET IF NEEDED CALL $IOCMR CHADN: $POP R4,R3,R2,R1,R0 ; AND WE'RE DONE $RTT .PAGE .SBTTL DATA AREA .CSECT MOSDAT, STATIC CHADDR: .WORD 0 $MCHBT: .END