.TITLE GATPKT Packet radio asynchronous driver .NLIST BEX,CND .ENABL LC ; ; Pdp11/dcn packet radio asynchronous driver ; ; This module is an extension of the network processes. It transmits and ; receives packets using the dlv11/dl11/dc11 line unit and a message format ; compatible with the WA8DED code for the TAPR-1 packet-radio interface. ; ; Conditional assembly switches ; CS.DEV = 0 ;0: dl11/dlv11, 1: dc11 ; ; External symbols ; .GLOBL .WAIT,.SKED,.STIM,.DLAY ;supervisor services .GLOBL NETINP,NETOUT ;process initialization ; ; Entry symbols ; .GLOBL PRIPAT ;input process control vector .GLOBL PROPAT ;output process control vector ; ; System definitions ; .ASECT .MCALL .COM,.CHR,.PSA,.GAT,.TAP,.PAT ;dcnlib definitions .MCALL .SETV,.CTIM,.INIT ;dcnlib macros .COM ;define common data .CHR ;define ascii code .PSA ;define process storage areas .GAT ;define net driver storage areas .TAP ;define tapr storage areas ; ; Module definitions ; POLTIM = 100. ;poll timeout NRPTIM = 2000. ;no-response timeout NRPMAX = 5 ;max timeouts INTENB = 000100 ;interrupt inable (inpcsr/outcsr) .IF EQ,CS.DEV ;conditional assembly for dl11/dlv11 INPINI = 000006 ;input configuration (inpcsr) OUTINI = 074000 ;output configuration (outcsr) .IFF ;conditional assembly for dc11 INPINI = 000021 ;input configuration (inpcsr) OUTINI = 000021 ;output configuration (outcsr) .ENDC ; ; Dlv11/dl11/duv11/du11 device register block (dev) ; . = 0 INPCSR: .BLKW 1 ;input control/status register INPBUF: .BLKW 1 ;input buffer register OUTCSR: .BLKW 1 ;output control/status register OUTBUF: .BLKW 1 ;output buffer register .PAGE ; ; Procedure segment ; ; Supervisor-state procedure ; Dsects: r2 = dev, r3 = par, r4 = reg, r5 = psa ; ; Note: calling process sets r0 = byte count, r1 = starting address. ; At completion of transfer r0 = byte count. ; .PSECT $KERI,RO,I ; ; Initialize ; NTIINI: MOV #INTENB+INPINI,INPCSR(R2) ;configure input MOV #OUTINI,OUTCSR(R2) ;configure output MOV #INT+EXTBAS,R1 ;allocate input vector .SETV MOV #POLTIM,R0 ;wait for output to get started JMP .DLAY ; NTOINI: ADD #4,R0 ;allocate output vector MOV #INT+EXTBAS,R1 .SETV NTORST: RTS PC ; ; Start block transfer input ; NTISIO: JSR PC,.WAIT ;enter wait state NTI10: CLRB ASRPCT(R5) ;start poll timer MOV #POLTIM,R0 JMP .STIM ; ; Device interrupt input ; NTIINT: MOV INPBUF(R2),R0 ;get byte/control bits BPL 1$ ;branch if no error INC PARNRY(R3) ;account for error 1$: BIC #^C377,R0 ADD ASRSTA(R5),PC ;belay BR NTIS0 ;0 channel number BR NTIS1 ;1 control code BR NTIS2 ;2 message length BR NTIS3 ;3 message data (count terminated) BR NTIS4 ;4 message data (nul terminated) ; NTIS0: CMPB R0,#CHNMAX ;state 0. is this valid channel number BHIS NTIERR ;branch if no MOVB R0,ASRHDR(R5) ;yes. save for later MOV #2*1,ASRSTA(R5) ;exit to state 1 RTS PC ; NTIS1: TSTB R0 ;state 1. is this null response BNE 1$ ;branch if no TSTB PSASTS(R5) ;yes. is process running BMI NTIRTN ;branch if yes .CTIM ;no. stop timer CLR ASRSTA(R5) ;exit to state 0 BR NTI10 ; 1$: CMPB R0,#4 ;data response. is more to follow immediately BLO 2$ ;branch if no MOVB ASRHDR(R5),PAXPOL(R3) ;yes. poll this channel again 2$: CMPB R0,#6 ;is data field nul-terminated BHIS 3$ ;branch if no MOV #2*4,ASRSTA(R5) ;yes. exit to state 4 BR 4$ ; 3$: CMPB R0,#7 ;is data field count terminated BHI NTIERR ;branch if no MOV #2*2,ASRSTA(R5) ;yes. exit to state 2 4$: CLR ASRADR(R5) ;set for possible discard MOV #-1,ASRBCT(R5) TSTB PSASTS(R5) ;is process running BMI 5$ ;branch if yes MOV REGR1(R4),ASRADR(R5) ;no. initialize transfer parameters MOV @R4,ASRBCT(R5) MOVB ASRHDR(R5),@ASRADR(R5) ;store channel number INC ASRADR(R5) 5$: MOV #1,ASRCNT(R5) BR NTIS3 ;store control code ; NTIS2: ADD #2+1,R0 ;state 2. save message length MOV R0,ASRBCT(R5) MOV #2*3,ASRSTA(R5) ;exit to state 3 NTIRTN: RTS PC ; NTIS4: TSTB R0 ;state 4. is this message end BEQ NTIEND ;branch if yes NTIS3: TST ASRADR(R5) ;state 3. is discard set BEQ 1$ ;branch if yes MOVB R0,@ASRADR(R5) ;no. store data octet INC ASRADR(R5) 1$: INC ASRCNT(R5) CMP ASRCNT(R5),ASRBCT(R5) BLO NTIRTN ;branch if more NTIEND: TST ASRADR(R5) ;end message. is discard set BEQ NTIERR ;branch if yes MOV ASRCNT(R5),@R4 ;no. return message size CLR ASRSTA(R5) ;revert to state 0 .CTIM JMP .SKED ; NTIERR: INC PARNRY(R3) ;protocol error. indicate input error CLR ASRSTA(R5) ;exit to state 0 RTS PC ; ; Input timeout ; NTIASY: INCB ASRPCT(R5) ;is max timeout exceeded CMPB ASRPCT(R5),#NRPMAX BLO 1$ ;branch if no CLRB ASRPCT(R5) ;yes. another chance MOVB #-1,PAXENB(R3) ;flag reset BR 2$ ; 1$: MOVB #1,PAXENB(R3) ;poll timeout. flag poll 2$: BIS #INTENB,OUTCSR(R2) ;tickle output side MOV #NRPTIM,R0 ;start no-response timer JMP .STIM ; ; Start block transfer output ; NTOSIO: JSR PC,.WAIT ;enter wait state BIS #INTENB,OUTCSR(R2) ;start output MOV PARTRY(R3),R0 ;start output timeout SUB R0,RESTIM(R5) JMP .STIM ; ; Device interrupt output ; NTOINT: ADD ASXSTA(R5),PC ;belay BR NTOS0 ;0 send channel number BR NTOS1 ;1 send control code BR NTOS2 ;2 send message length BR NTOS3 ;3 send message data BR NTOS4 ;4 send poll ; NTOS0: TSTB PSASTS(R5) ;state 0. is process running BPL 4$ ;branch if no TSTB PAXENB(R3) ;yes. test poll-enable switch BEQ 3$ ;branch if not set BGT 1$ ;branch if poll timeout CLRB PAXENB(R3) ;no-response timeout. send init message INC PARERR(R3) ;indicate output error MOV #INIMSG,ASXADR(R5) MOV #4*2,ASXSTA(R5) BR NTOS4 ; 1$: CLRB PAXENB(R3) ;poll timeout. select channel MOVB PAXPOL(R3),OUTBUF(R2) INCB PAXPOL(R3) ;update channel counter CMPB PAXPOL(R3),#CHNMAX BLO 2$ CLRB PAXPOL(R3) 2$: MOV #POLMSG,ASXADR(R5) ;send poll message MOV #4*2,ASXSTA(R5) RTS PC ; 3$: BIC #INTENB,OUTCSR(R2) ;shut down transmitter RTS PC ; 4$: MOV REGR1(R4),ASXADR(R5) ;start message. save pointers MOV @R4,ASXCNT(R5) NTOS1: ADD #2,ASXSTA(R5) ;bump state NTOS3: MOVB @ASXADR(R5),OUTBUF(R2) ;state 3. send octet INC ASXADR(R5) ;update pointers DEC ASXCNT(R5) BNE NTORTN ;branch if more .CTIM ;complete. clear output timeout ADD R0,RESTIM(R5) NTOASX: CLR ASXSTA(R5) ;revert to idle JMP .SKED ; NTOASY: TSTB R0 ;is this timer interrupt BEQ NTOASX ;branch if yes RTS PC ;no. stay cool ; NTOS2: MOV ASXCNT(R5),R0 ;state 2. compute message length DEC R0 MOVB R0,OUTBUF(R2) ;send it ADD #2,ASXSTA(R5) ;bump state RTS PC ; NTOS4: MOVB @ASXADR(R5),OUTBUF(R2) ;state 4. send octet INC ASXADR(R5) ;update pointers CMP ASXADR(R5),#POLEND ;is message complete BLO NTORTN ;branch if no CLR ASXSTA(R5) ;yes. revert to idle NTORTN: RTS PC ; ; Data segment ; .PSECT $KERD,RO,D ; ; Process headers ; PRIPAT: .PAT ASREND,NETINP,PRI4,<0,NTIASY,NTIINI,NTISIO,NTIINT> PROPAT: .PAT ASXEND,NETOUT,PRI3,<0,NTOASY,NTOINI,NTOSIO,NTOINT,NTORST> ; INIMSG: .ASCII <0><1><7-1>'JHOST 0' ;switch to terminal mode .ASCII 'JHOST 1' ;switch to host mode .ASCII <0> ;channel number of first poll POLMSG: .ASCII <1><1-1>'G' ;remainder of polling message POLEND = . .EVEN ; .END