Trailing-Edge
-
PDP-10 Archives
-
BB-J992D-SB_1984
-
hbsc.p11
There are 30 other files named hbsc.p11 in the archive. Click here to see a list.
.SBTTL HBSC - line protocol driver
; this section contains the bsc (or bisync) and hasp task.
; this task uses line driver subroutines to communicate with
; an ibm-compatable bsc device, point-to-point.
; many error and statistical counters are kept.
; communication with the translate task is by sending and
; receiving messages, and by changing and observing status
; bits in the task control block.
.REPT 0
COPYRIGHT (c) 1982,1981,1980, 1979
DIGITAL EQUIPMENT CORPORATION, maynard, mass.
THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
TRANSFERRED.
THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
CORPORATION.
DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
.ENDR
; REVISION HISTORY
; 3(001) BS MODIFY (UN)/SUSPEND ROUTINES TO ALLOW CALLING FROM ANY TASK
;
; 3(002) BS SUSPEND DEVICE IF MORE THAN 2 MESSAGES QUEUED TO IT
;
; 3(003) BS CLEAR SYSTEM SUSPEND AFTER ACK RECEIVED FOR EMULATION
;
; 3(004) BS UNSUSPEND DEVICE ONLY FIRST TIME INPUT PERMISSION IS GRANTED
;
; 3(005) BS SEND NULL MESSAGE IF DEVICE STATUS CHANGED AND NO MESSAGES
;
; 3(006) BS SUSPEND DEVICE AFTER ONE MESSAGE IF FE SHORT ON CHUNKS
;
; 3(007) BS INCREASE TIME TO SEE IF OTHER SIDE IS BIDDING
;
; 3(010) BS SEND NULL MESSAGES ONLY AFTER LINE IS SIGNED ON
;
; 3(011) BS REDUCE THE WAIT TIME BETWEEN SENDING MESSAGES WITH HASP
;
; 3(012) BS TERMINATE TRANSMISSION IN 2780/3780 IF LINE IS DISABLED
;
;
; 3(013) BS INDICATE COMMUNICATIONS ESTABLISHED IN LINE FLAGS
; SET H/W ABORT IF DSR GOES AWAY AFTER COMMUNICATION ESTABLISHED
;
; 3(014) BS SET AND CLEAR CDR ACTIVE BIT FOR SIGNON
;
; 3(015) BS SET H/W ABORT FOR HASP IF RX OR TX TIMES OUT OR ERROR
;
; 3(016) BS SET H/W ABORT FOR 3780/2780 IF RX OR TX PROBLEM
;
; 3(017) BS SET ALL DEVICE ACTIVE BITS FOR 2780/3780/HASP H/W ABORT
;
; 3(020) BS SET DEVICE ACTIVE BIT FOR 3780/2780 DEVICE ABORT
;
; 3(021) BS CLEAR DEVICE ACTIVE BIT FOR 3780/2780 ABORT ACK FROM PDP-10
;
; 3(022) BS CLEAR DTR WHEN LINE IS DISABLED TO HANG UP LINE
;
;
; 3(023) BS FREE SIGNON MESSAGE SENT TO BSC FROM XLHASP AFTER IT IS PUT IN
; TRANSMISSION BLOCK
;
; 3(024) KR If we receive input permission request from HASP while input
; is already running, set new TCIRH bit to indicate input request
; was held
;
; 4(025) BS MODIFY CODE TO ACCEPT TRAILING BCB AND 2 FCS BYTES FROM IBM
; IN LARGE MESSAGES.
;
; 4(026) BS MODIFY CODE TO READ AND SEND TRANSPARENT MESSAGES CORRECTLY
;
; 4(027) BS CORRECT FCS CODE TO TEST AND SET PUNCH STATUS CHANGE
;
; 4(030) BS SEND NAK INSTEAD OF EOT TO REFUSE INPUT PERMISSION IN 3780 MODE
;
; 4(031) BS ACCEPT SIGNON CONTROL RCB IN EMULATION TO HANDLE DISCONNECT
; MESSAGE AND ROUTE MESSAGE TO CONSOLE
;
; 4(032) BS ACCEPT TRANSMIT ABORT SCB IN HASP MODE AND TREAT AS END OF FILE
;
; 4(033) SMJ Fix HSRXPM so that the BCB is stored correctly if a "reset
; BCB count" BCB is read. This means that the 3 bits (160)
; are cleared before the next expected BCB is stored.
;
; 4(034) RLS MAKE CHANGES REFLECTING NEW STORAGE MGT. MAINLY SEND GARBAGE
; TO FRECHK INSTEAD OF IDLE.
;
; 4(035) RLS 30-JUL-80
; HSCDOT - DROP CALL TO HSTSUS TO CHECK FOR CHANGE IN DEVICE STATUS
; AND USE INLINE CODE...CLEAR TCHGST IN TCST2 ONLY IF NULL MSG IS
; SUCCESSFULLY SENT. FLUSH FCN HSTSUS.
;
; 4(036) RLS 3-SEP-80
; HSINIT - DON'T CLEAR LF.SON, NOW SET OR CLEARED INITIALLY IN
; LINE ENABLE CODE.
;
; 4(037) RLS 2-OCT-80
; REMOVE (011) EDIT AND RESTORE OLD CODE: 1 SEC IDLE ACK'S,
; IMMEDIATE DATA ACKS
; 4(040) RLS 17-OCT-80
; ADD DETECTION OF SOH-ENQ SEQUENCE TO HSARSP; RETURN RESPONSE
; CODE 7 TO HSPXM2 WHICH CAUSES IMMEDIATE ABORT. DISCOVERED WHEN
; IN LOOPBACK MODE, ONE LINE SAW BID AND FIRED UP BUT BID SENDER
; APPARENTLY LOST ACK0 AND KEPT BIDDING. UNFORTUNATELY THE FIRST
; SIDE THEN TREATED BIDS AS SIMPLY STRANGE MSGS. EVENTUALLY IT
; ABORTED AFTER A LONG TIME. IBM CODE ALWAYS CAUSES IMMEDIATE
; LINE ABORT WHEN SOH-ENQ RECEIVED AFTER INITIAL BID COMPLETE.
;
; 4(041) KR 31-Oct-80
; Code used absolute limit on block size (398.) but still
; sometimes overflowed (for example in transparent mode).
; Changed it to use LB.MBL and to correctly never exceed it.
;
; 4(042) KR 17-Oct-80
; Add 2780/3780 flow control (primarily WACKO routine).
; 4(043) RLS 26-FEb-81
; add detection of DLE-EOT for hangup; TCDIS set in TCST2 of BSC
; tcb when detected.
; uniformly reply NAK for bid refusal (2780/3780)(WACK is also
; acceptable).
; use XNRTY,RNRTY for retry counts for transmission,reception.
; calling sequence for DQRXPM changed.
; detect transparent bid(DLE-ENQ) in HSPLIN.
; 4(044) KR 26-Feb-81
; Fix HSEOB to check for duplicate messages by checking for BCB
; equal to previous received message and flush if so.
; Following scenario gave rise to this fix:
; IBM DEC
; <- msg(1) - received ok
; -> msg(2) - received ok
; <- msg(3) - lost in noise
; (time out)
; -> NAK - lost in noise
; (time out)
; <- NAK - recieved ok
; -> msg(2) - received ok
; 4(045) RLS 9-Mar-81
; Fix DQBCTL to treat LF.DIS as a line disable.
; Also make BSC sleep at DQBCTL til EBINTR event occurs instead
; of timing out.
; 4(046) rls 12-Mar-81
; Begin centralizing device active bit hacking.
; Create new functions SACTI,SACTO,CACTI,CACTO. Eliminate HSTAOA,
; HSTAIA,HCLAOA,HCLAIA. Rewrite HSACMP function.
; 4(047) RLS 07-APR-81
; Changes reflecting use of message headers for data storage.
; 4(050) RLS 17-APR-81
; Transform static flow control to static/line control
; 4(051) RLS Add checking for DLE-EOT to DQXNAV in TTD loop.
; 4(052) RLS 5-MAR-82 gco 4.2.1248
; do HSDISL when DSR drops rather than DQFLSM.
; 4(053) RLS 16-MAR-82 gco 4.2.1269
; Add data integrity checker under conditional DB.SEQ.
; 4(054) RLS 18-MAR-82 GCO 4.2.1274
; Clear LS.ERR after transmitter errors have been cleaned up.
; 4(055) RLS 21-MAR-82 GCO 4.2.1282
; Check for dsr on before check for aborts at LINCTL.
; Add signon event traces
; 4(056) RLS 14-APR-82 GCO 4.2.1315
; Check for ENQ response to data message in 2780/3780
; 4(057) RLS 15-APR-82 GCO 4.2.1322
; Flush XNRTY,RNRTY usage...use LB.ERC
; 4(060) RLS 15-APR-82 GCO 4.2.1323
; make DQXNAV think about about bad line conditions.
; 4(061) RLS 19-APR-82 GCO 4.2.1327
; Have to check LS.ERR after waking up after T.WRT call, not
; just EBALR wakeup.
; 4(062) RLS GCO 4.2.1329 - INFLO,OUTFLO : distinguish HASP and non-HASP
; flow conditions.
; 4(063) RLS 18-JUN-82 GCO 4.2.1392
; do input abort processing similar to input eof. Do eot
; processing according to IBM conventions.
; 4(064) RLS 29-JUN-82 GCO 4.2.1412
; apply threshold(NORPLY) to number of successive attempts at
; communications ending with LF.HWA set(LB.NHA counter)
; 4(065) RLS 05-JUL-82 GCO 4.2.1419
; set TCHGST in HSINIT - make status get sent when no signon
; is sent
; 4(066) RLS 06-JUL-82 GCO 4.2.1421
; in DQDTAS check for LF.OFL when bid fails and don't clear TCOPR
; if so.
; 4(067) RLS 16-JUL-82 GCO 4.2.1450
; in DQXNAV, make sure R4/line number on exit
; 4(070) RLS 27-JUL-82 GCO 4.2.1466
; make sure DLE-EOT receipt causes return to control level
; 4(071) RLS 09-AUG-82 GCO 4.2.1485
; delineate hasp/non-hasp in LF.HWA situations
; 4(072) RLS 17-SEP-82 GCO 4.2.1511
; split HMSGTC into transparent and non-transparent branches
; to do special character handling.
; 4(073) RLS 22-OCT-82 GCO 4.2.1521
; in HSRQPT, check for permission already granted before sending
; a permission request.
VHBSC=072
VEDIT=VEDIT+VHBSC
.SBTTL LINSTR,LINCTL - where all transactions start
; enter here from the dispatcher
LINSTR: MOV TCLCB(R5),R4 ;point r4 to lcb
BEQ 1$ ;does not exist, exit
BIT #LS.ENB,(R4) ;is the line enabled ?
BEQ 1$ ;not enabled yet
BIT #LF.EIP,(R4) ;check if we are still doing it
BEQ 2$ ;no - ok to initialize
1$: ;no, set up wait and exit
DSCHED ,#20 ;wait for a while
BR LINSTR ;check again
2$: CALL @T.INI(R5) ;initialize the line driver
.IF NE,DB.SEQ
CALL PCHKI ;init sequence checker
.ENDC ;.IF NE,DB.SEQ
BR LINCTL
; here to be in bsc "control" mode.
; wait for the line to be enabled and for data set ready. then,
; if "output permission requested" is set, bid for the line.
; otherwise just listen for a bid. if a bid arrives we must
; get permission from the pdp-10 before replying "ACK-0".
LINCT0: DSCHED #EBINTR,#10 ;sleep til something happens
LINCTL: BIC #TCEOT,TCST2(R5) ;new aborts will need eot again
MOV TCLCB(R5),R4 ;point R4 to lcb
CALL CLRALR ;flush any alarm debris hanging around
BIC #LS.ERR,(R4) ;clear error bit
BIC #LF.LAP!LF.DIP,LB.FGS(R4) ;clear these in case line just aborted
BIT #LS.ENB,(R4) ;is the line enabled?
BEQ 21$ ;no, see if genuine disable
BIT #LF.DIS,LB.FGS(R4) ;line disabled by dte ?
BNE 21$ ;treat this as disable command from 10
BIT #TCDIS,TCST2(R5);check for disconnect state
BNE 21$ ;yes - disable from the line
CALL HSCMDS ;check modem status
BCC 11$ ;dsr is on
; here if the data set is not ready.
BIT #LF.CME,LB.FGS(R4) ; communications established ? 3(013)
BEQ LINCT0 ;no need to do more til we establish contact
BIS #LF.HWA,LB.FGS(R4) ;indicate a h/w abort
21$: JMP HSDISL ;start disable sequence
11$: BIT #LF.HWA,LB.FGS(R4) ;check for hard aborts
BEQ 15$
BIT #LF.CME,LB.FGS(R4) ;only a problem if we were talking
BEQ 15$
INC LB.NHA(R4) ;count it
.IF NE,FT.HSP
CMP #TTHASP,LB.DVT(R4) ;in HASP, this is always fatal
BEQ 21$ ;its dead
.ENDC ;.IF NE,FT.HSP
CMP LB.NHA(R4),#NORPLY ; too many?
BGE 21$ ; yes - declare line down
BR 16$
15$: CLR LB.NHA(R4) ;clear the successive abort counter
16$: BIC #LF.HWA,LB.FGS(R4) ;clear the abort
BIT #TCOAB!TCOAC!TCIAB!TCIAC,TCFG2(R5) ;abort in progress?
BEQ DSRON ;no - try something
CALL DQFLSM ;flush the queue
BR LINCT0 ; and try again.
.SBTTL DSRON - 2780/3780...receive bid
; here when we have data-set-ready and the line is enabled.
; check for hasp line and if not default is 2780/3780.
.ENABL LSB
DSRON:
12$:
.IF NE,FT.HSP
CMPB #TTHASP,LB.DVT(R4) ;hasp line?
BNE 13$ ;no, must be 2780 or 3780
JMP HSPLIN ;yes, it is hasp line
.ENDC ;.IF NE,FT.HSP
; here the line is 2780 or 3780
13$: BIT #TCOPR,TCFG2(R5) ;has output permission been requested?
BEQ 15$
14$: JMP DQDTAS ;yes, bid for the line.
15$: CALL @T.RED(R5) ;no, see if other side is bidding
MOV #2*JIFSEC,LB.ALR(R4) ;wait about 2 seconds to make sure
CLR R4 ;no data as yet
CALL MSGGTC ;get character
BCS 16$ ;none.
CALL CLRALR ;flush the alarm
CMPB #EBCENQ,R1 ;an ENQ?
BEQ RCVBID ;yes - go do bid
CMPB #EBCDLE,R1 ;check for disconnect
BNE 16$ ;no - nothing else here
CALL MSGGTC ;maybe
BCS 16$ ;died early
CMPB #EBCEOT,R1 ;EOT?
BNE 16$ ;no - very confusing
CALL RCVDSC ;record intent of other end to disconnect
; here if we get an unrecognizable unsolicited message.
16$: CALL MSGGTT ;end message and wait the second
JMP LINCTL ;look for a bid again.
RCVBID: CALL TENQ ;record this
CALL MSGGTE ;process bid request
CALL HSETCE ;communications established 3(013)
CALL DQRQIP ;request input permission
BCS 17$ ;refused, clear the line.
CALL DQRECV ;accepted, receive data
JMP LINCTL ;when done, check again.
; here when input permission is refused. send a NAK(WACK also valid) to refuse bid.
17$: CALL DQSNAK ;send NAK when input permission refused 4(030)
JMP LINCTL ;start over. 4(030)
.DSABL LSB
.SBTTL line event recording functions
RCVDSC: BIS #TCDIS,TCST2(R5) ;disconnect
ATRACE <(SP),R5,JIFCLK>
RCVDIS: RETURN
TENQ: TRACE TRCLIN,<(SP),R5,JIFCLK> ;received an ENQ
RCVENQ: RETURN
TACK0: TRACE TRCLIN,<(SP),R5,JIFCLK> ;received ACK0
RCVAK0: SAVE R4
MOV TCLCB(R5),R4 ;point to lcb
INC LB.OC1(R4) ;count message sent successfully
P4J: RESTOR R4
RETURN
TACK1: TRACE TRCLIN,<(SP),R5,JIFCLK> ;received ACK1
RCVAK1: BR RCVAK0
TIACK: TRACE TRCLIN,<(SP),R5,JIFCLK> ;received implicit ACK(HASP)
RCVIAK: BR RCVAK0
TEOT: TRACE TRCLIN,<(SP),R5,JIFCLK> ;received EOT
RCVEOT: SAVE R4
MOV TCLCB(R5),R4 ;get pointer to lcb
INC LB.IC6(R4) ;count aborts
BR P4J
TNAK: TRACE TRCLIN,<(SP),R5,JIFCLK> ;received NAK
RCVNAK: SAVE R4
MOV TCLCB(R5),R4 ;point to lcb
INC LB.OC2(R4) ;count naks received
BR P4J
TTMO: TRACE TRCLIN,<(SP),R5,R4,R0,JIFCLK> ;time out on receive
RSPTMO: SAVE R4
MOV TCLCB(R5),R4 ;point to lcb
INC LB.IC7(R4) ;count invalid messages due to timeout
BR P4J
TCRF: TRACE TRCLIN,<(SP),R5,R4,R0,JIFCLK> ;received cruft
RCVCRF: SAVE R4
MOV TCLCB(R5),R4 ;point to lcb
INC LB.OC4(R4) ;record invalid reply to data
BR P4J
TWACK: TRACE TRCLIN,<(SP),R5,JIFCLK> ;received WACK
RCVWAK: SAVE R4
MOV TCLCB(R5),R4 ;point to lcb
INC LB.OC6(R4) ;count wacks received
BR P4J
TTTD: TRACE TRCLIN,<(SP),R5,JIFCLK> ;received TTD
RCVTTD: SAVE R4
MOV TCLCB(R5),R4 ;point to lcb
INC LB.IC5(R4) ;count ttd messages
BR P4J1
TRVI: TRACE TRCLIN,<(SP),R5,JIFCLK> ;recieved RVI
RCVRVI: SAVE R4
MOV TCLCB(R5),R4 ;point to lcb
INC LB.OC9(R4) ;count rvis received
BR P4J1
TBCC: TRACE TRCLIN,<(SP),R5,JIFCLK> ;received BCC error
RCVBCC: SAVE R4
MOV TCLCB(R5),R4 ;point to lcb
INC LB.IC2(R4) ;count instances of bad bcc
P4J1: RESTOR R4
RETURN
.IF NE,FT.HSP
TBCB: TRACE TRCLIN,<(SP),R5,JIFCLK> ;received BCB error
RCVBCB: INC TCBCBE(R5) ;count bcb errors received
RETURN
.ENDC ;.IF NE,FT.HSP
.SBTTL DQDTAS - 2780/3780...bid for the line
; here when we have data to send. bid for the line.
DQDTAS: MOV LB.EQN(R4),LB.RTY(R4) ;number of tries to get the line
11$: BIT #TCOAB!TCOAC,TCFG2(R5) ;has stream been aborted?
BEQ 12$ ;no.
CALL DQFLSM ;yes, flush the queue
BIC #TCOPR,TCFG2(R5) ;no longer bidding
JMP LINCT0 ; and try again.
12$: MOV #ENQMSG,R0 ;send an ENQ
MOV #ENQLEN,R1
CALL CTLMSG ;send bid message and read response
MOV LB.EQW(R4),LB.ALR(R4) ;time to wait for reply
CLR R4 ;no data yet
CALL MSGGTC ;get character from receiver
BCS 15$ ;nothing received
CALL CLRALR ;flush alarm now
CMPB #EBCENQ,R1 ;did we get an ENQ?
BNE 14$ ;no, check for ACK
BIC #TCOPR,TCFG2(R5) ;no longer bidding
JMP RCVBID ;yes - go process bid
; come here if the response to ENQ is not ENQ
14$: CMPB #EBCDLE,R1 ;is it DLE?
BNE 15$ ;no.
CALL MSGGTC ;yes, get next char
BCS 15$ ;timeout
CMPB #EBCAK0,R1 ;is it ACK-0?
BNE 15$ ;no.
CALL TACK0 ;yes - record it
; we have ACK-0, granting permission to send data.
CALL MSGGTE ;end of message
BIS #TCOPG,TCFG2(R5) ;note output permission granted
BIC #TCOPR,TCFG2(R5) ;no longer bidding
CALL HSETCE ;communications established 3(013)
MOV TCLCB(R5),R4 ;point to lcb
CALL DQAWXL ;awaken xlate task
CALL DQXMIT ;go transmit
MOV TCLCB(R5),R4 ;point to lcb
CALL DQAWXL ;awaken xlate task
JMP LINCTL ;back to bsc control mode
; here when the response to ENQ is bidrefusal(NAK,WACK) or is unrecognizable
; finish waiting if necessary and bid again.
15$: CALL MSGGTT ;empty the receiver and wait
MOV TCLCB(R5),R4 ;point to lcb
INC LB.OC8(R4) ;record nonaffirmative bid response
BIT #TCOPR,TCFG2(R5) ;still want to bid for the line?
BEQ 16$ ;no.
DEC LB.RTY(R4) ;yes, have we tried often enough?
BGE 11$ ;no, try again.
16$: BIT #LF.OFL,LB.FGS(R4) ;check if offline and trying to get restarted
BNE 30$ ;yes - do not clear bid flag
BIC #TCOPR,TCFG2(R5) ;yes, no longer bidding
CALL DQAWXL ;awaken the xlate task
BIT #LF.CME,LB.FGS(R4) ;are we trying to restablish the link?
BEQ 20$ ;no - initial bid
BIS #LF.HWA,LB.FGS(R4) ;yes - looks like the other end is dead
20$: MOV #10.,-(SP) ;retry count
CALL DQSEOT ;send EOT to clear the line
BCC 21$
BIT #LS.ENB,(R4) ;failed - check for permanent reasons
BEQ 21$ ;can't ever suc
DEC (SP)
BGT 20$ ;try again
21$: TST (SP)+
30$: JMP LINCTL ;back to control mode
.SBTTL DQFLSM - abort all line io
DQFLSM: MOV TCLCB(R5),R4 ;point to lcb
BIS #LF.LAP,LB.FGS(R4) ;line abort in progess
ATRACE <(SP),R4,(R4),LB.FGS(R4),TCST2(R5),TCFG2(R5)>
.IF NE,FT.HSP
CMPB #TTHASP,LB.DVT(R4) ;check for hasp line
BEQ 8$ ;yes, continue
.ENDC ;.IF NE,FT.HSP
MOV LB.MSG(R4),R0 ;no, point to last message
BEQ 7$ ;no message, continue
CALL FREMSG ;flush it
CLR LB.MSG(R4) ;clear line pointer to message
7$: BIC #LF.OFL,LB.FGS(R4) ;device is no longer off line
8$: CALL DEQCHK ;check for incoming - anything here has not
BCS 11$ ;been ack'd...I think.
9$: CALL FRECHK ;throw them away
BR 8$
11$: CALL DEQMSG ;check for outgoing
BCS 13$ ;got them all
12$: CALL FREMSG ;send it the message to free
BR 11$ ;get more messages
; here when the message queue is empty. wait a bit to be sure
; it stays that way.
13$: DSCHED #EBINTR!EBQMSG,#10. ;wait a short while
CALL DEQCHK ;any more incoming?
BCC 9$ ;yes - toss them
CALL DEQMSG ;any messages?
BCC 12$ ;yes, free them and wait some more
.IF NE,FT.HSP
CMP #TTHASP,LB.DVT(R4) ;hasp line?
BNE 21$ ;no.
; multileaving processing
CALL BLOHSP ;blow away all the devices
23$: RETURN
.ENDC ;.IF NE,FT.HSP
; 2780/3780 processing
21$: BIT #TCOAB!TCIAB,TCFG2(R5) ;is stream still in abort state?
BNE 25$
MOV LB.TCD(R4),R3 ;now flush anything left queued to the 10
CALL QDRAIN
RETURN ;no, just return.
25$: MOV LB.TCD(R4),R1 ; get the xlate tcb
BIT #TCOAB,TCFG2(R5) ;yes, output abort?
BEQ 14$ ;no. check for input abort.
BIS #TCOAC,TCFG2(R5) ;yes, flag output abort complete
BIS #TCOAB,TCFG2(R1) ; make sure xlate knows what is happening
14$: BIT #TCIAB,TCFG2(R5) ;input abort?
BEQ 15$ ;no.
BIS #TCIAC,TCFG2(R5) ;yes, complete input abort.
BIS #TCIAB,TCFG2(R1) ; make sure xlate knows what is happening
15$: SIGNAL R1,EBINTR ; rudely awaken the xlate task
BR 13$ ;wait for "abort" to clear.
.IF NE,FT.HSP
;BLOHSP aborts all devices on an a HASP line
; R4/LCB
BLOHSP: SAVE <R0,R1>
MOV LB.NTC(R4),R1 ;get max dev #
BEQ 23$ ;field not setup
22$: MOV R1,R0 ;point to lcb
ASL R0 ; *2
ADD R4,R0
MOV LB.TCD(R0),R0 ;point to xlate tcb
30$: BIT #TCIAB!TCOAB,TCFG2(R0) ;device stream aborted?
BEQ 26$
CALL HSAWXL ;yes - wake the xlate task
DSCHED #EBINTR,#10. ;wait for xlate to abort
;but can't trust the sequencing
BR 30$
26$: MOV R0,R3 ;now flush anything left queued to the 10
CALL QDRAIN
SOB R1,22$ ;loop for all devices
BIC #TCIAC!TCIAB!TCOAC!TCOAB,TCFG2(R5) ;clear abort
23$: RESTOR <R1,R0>
RETURN
.ENDC ;.IF NE,FT.HSP
.SBTTL HSDISL - disable line and release all storage
HSDISL: MOV TCLCB(R5),R4 ;point to lcb
ATRACE <R4,(R4),LB.FGS(R4),TCST2(R5),TCFG2(R5)>
BIS #LF.DIP,LB.FGS(R4) ;line disable in progress
BIC #LS.ENB,(R4) ;mark line disabled in case it isn't already
CALL @T.KIL(R5) ;stop all line activity
CALL ABTLIN ;abort all io on line
CALL HSTBTS ;set all device active bits for 10
CALL DQFLSM ;clean up io debirs
BIT #LF.CME,LB.FGS(R4);if we have been talking - need to disconnect
BEQ 20$
BIT #TCDIS,TCST2(R5) ;unless he disconnected from us
BNE 20$
CALL HSCMDS ;or unless he hung up the line already
BCS 20$
BIS #LS.ENB,(R4) ;enable line long enogh to send disconnect
BIC #LS.ERR,(R4) ;clear error bit
CALL DQSDIS ;send disconnect message
DSCHED ,#JIFSEC*3 ;wait awhile and repeat
CALL DQSDIS ;send disconnect message
BIC #LS.ENB,(R4)
CALL @T.KIL(R5) ;make sure driver is quiesced
20$: CALL HSRMRL ;release all received messages
CALL HSRLOM ;also all outgoing messages
MOV R4,R0 ; get lcb for arg
CALL @T.DOF(R5) ;drop dtr
MTPS #BR7 ;prevent interference during last cleanup
MOV #PDL,SP ;get scheduler pdl
CALL FLSTCB ;release all tcb's and associated buffers
CALL FLOSHR ;recalculate available resources
BIC #LF.EIP!LF.LAP!LF.DIP,LB.FGS(R4) ;disable no longer in progress
BIS #LF.DAC,LB.FGS(R4) ;line abort,disable complete
JMP SKDINI ;restart scheduler
.SBTTL DQXMIT - 2780/3780...message tranmission
; we have received ack-0 response to bid enq. send messages.
DQXMIT: BIS #TCAK1,TCST2(R5) ;note ack-1 needed next
; and doing output.
11$: MOV TCLCB(R5),R4 ;point to lcb
MOV LB.ERC(R4),LB.RTY(R4) ;retry count is 15.
BIC #TCNRD,TCST2(R5) ;no "no responses" yet
BIT #TCOAB,TCFG2(R5) ;has transmission been aborted?
BEQ 2$
CALL 16$ ;yes, send eot and exit.
RETURN
2$: BIC #LS.ERR,(R4) ;clear any previous errors
BIT #LF.OFL,LB.FGS(R4) ;did device go off line before ?
BEQ 22$ ;no, continue as before
BIC #LF.OFL,LB.FGS(R4) ;yes, clear the flag that says it did
TST LB.MSG(R4) ;any messages ready to transmit again ?
BNE 13$ ;retransmit message
22$: CALL DEQMSG ;no, get message to send
BCC 12$ ;got one.
CALL DQXNAV ;worry about no msgs available.
MOV TCLCB(R5),R4 ;this could have been munged
BCC 9$ ;try to do something now
CALL 16$ ;line cruftiness
RETURN
9$: BIT #TCOEC,TCFG2(R5) ;check terminating conditions
BNE 23$ ;EOF
BIT #LF.OFL,LB.FGS(R4) ; check for device offline
BEQ 11$ ;no - must be a message now
21$: BIS #TCOPR,TCFG2(R5) ;yes - remember we were sending
23$: BIC #TCORN!TCOPG,TCFG2(R5) ;no longer doing output
RETURN
; here if there is a message available to send.
12$: MOV R0,LB.MSG(R4) ;store message pointer
; here to send the message again.
13$: MOV LB.MSG(R4),R0 ;point to message
MOV MSGLEN(R0),LB.ALR(R4) ;no more than one jiffie per char
ADD LB.CSD(R4),LB.ALR(R4) ;plus clear-to-send delay
CALL @T.WRT(R5) ;start sending message
BCS 16$ ;only fails for line disable or abort set
CALL @T.RED(R5) ;set up to read response
DSCHED #EBINTR!EBALR
BIT #LS.ERR,(R4) ;check for hard error wakeup
BNE 14$
BIT #EBINTR,TCWKEV(R5) ;interrupt
BNE 15$ ;yes
INC LB.TTO(R4) ;count transmitter timeouts
14$: CALL @T.KIL(R5) ;error - zonk the hardware
BIC #LS.ERR,(R4) ;clear error bit
CALL @T.RED(R5) ;reissue the read
;the protocol will handle the error
DSCHED ,#10. ;displace timeouts...in case transmitter quit
;early in message
; here if the transmission of the data message was successful.
15$: CALL CLRALR ;flush alarm now
CALL DQXRSP ;read and analyze response
BCC 19$ ;successful acknowledgment
;WACK falls through, LB.RTY has been incremented
; so it doesn't count as a failure
MOV TCLCB(R5),R4 ;point to lcb
BIT #LS.ENB,(R4) ;is the line still enabled?
BEQ 16$ ;no - die gracefully
BIT #TCDIS,TCST2(R5) ;is the other end hanging up??
BNE 16$ ;yes - die with similar grace
BIT #LF.OFL,LB.FGS(R4) ;did device go off line
BNE 21$ ;stop transmitting and bid for the line again
BIT #TCOAB,TCFG2(R5) ;has operation been aborted?
BNE 16$ ;yes, error return.
DEC LB.RTY(R4) ;no, decrement retry count
BGT 18$ ;send enq or data
CALL 16$ ;error - blow away the stream
RETURN
; here to terminate the message stream because
; the 10 requested termination, because we received
; an EOT in response to a data block, because of transmitter
; error or timeout or because the retry counter ran out.
16$: TRACE TRCLIN,<R5,2(SP),(R4),LB.FGS(R4),TCFG2(R5),TCST2(R5)>
CALL @T.KIL(R5) ;make sure the driver is quiescent
CALL CLRALR ;make sure alarm is flushed
CALL DQSEOT ;send eot if necessary to clear line
CALL DQABRO ;flag output aborted.
BIC #TCORN!TCOPG,TCFG2(R5) ;no longer doing output
MOV TCLCB(R5),R4 ;point to lcb
BIC #LF.OFL,LB.FGS(R4) ;device no longer considered off line
MOV LB.MSG(R4),R0 ;is there a message trying to go?
BEQ 17$ ;no
CALL FREMSG ;yes - flush it
CLR LB.MSG(R4) ;there is no longer a message to go [1(624)]
17$: RETURN
; here to send an ENQ or data because the response was unreasonable
18$: CMP R0,#2 ;DQXRSP indicates send ENQ?
BEQ 13$ ;no, just send data.
MOV #ENQMSG,R0 ;yes, send ENQ
MOV #ENQLEN,R1
CALL CTLMSG
BR 15$ ;analyze response to ENQ 3(016)
; here when a block has been transmitted successfully.
19$: CALL XLCLRM ;clear the message buffer
JMP 11$ ;try for another message
;this subroutine clears the transmitted message buffer after
;a message has been successfully transmitted
XLCLRM: MOV TCLCB(R5),R4 ;point to lcb
MOV LB.MSG(R4),R0 ;point to message sent
BEQ 29$ ;no message, buffer has been cleared
CALL FREMSG ;send it the message to free
CLR LB.MSG(R4) ;no longer a message being sent
BIS #TCORN,TCFG2(R5) ;flag output running
BIC #TCOPG,TCFG2(R5) ;clear "output permission granted"
DEC LB.MSC(R4) ;one fewer msg waiting to transmit
CALL XLCSAB ;set or clear the device active bit
29$: RETURN
.SBTTL DQXRSP - 2780/3780...read and analyze the response
; on return:
; C is clear if the block is acknowledged.
; C is set if the block is not acknowledged.
; if LS.ABO is set, the operation is aborted.
; otherwise:
; R0 = 1, send ENQ or (if too many retries) EOT
; R0 = 2, send data again or (if too many retries) EOT
DQXRSP: MOV TCLCB(R5),R4 ; point to lcb
CALL KOSHL ;check out the line
BCC 9$ ;all is kosher
;something broken
CLR R4 ;flag no data yet
8$: CALL MSGGTT ;clean up after ourselves
CALL CLRALR ;flush alarm
BR 12$
9$: MOV #3*JIFSEC,LB.ALR(R4) ;wait for three seconds max
CLR R4 ;flag no data yet
CALL MSGGTC ;get data from reader
BCS 13$ ;nothing.
CALL CLRALR ;flush alarm
CMPB #EBCDLE,R1 ;start with dle?
BEQ 14$ ;yes - probably ACK, WACK or RVI
CMPB #EBCNAK,R1 ;NAK?
BEQ 18$ ;yes.
CMPB #EBCEOT,R1 ;EOT?
BEQ 19$ ;yes.
CMPB #EBCENQ,R1 ;ENQ?
BNE 11$ ;no - nothing we would expect
CALL TENQ ;yes - other side didn't hear us or has aborted
BR 25$ ;...send the data message again
; here if the response to a message is omitted or unrecognizable
11$: CALL MSGGTT ;flush remainder of message
; and wait the three seconds
CALL TCRF ;record it
12$: MOV #1,R0 ;indicate reply with "ENQ"
SEC ; flag block not acknowledged
RETURN
; here if timeout
13$: CALL KOSHL ;check error status
BCS 8$
BIS #TCNRD,TCST2(R5) ;flag timeout
BR 11$ ;treat as garbage
; here if the first character of the response is "dle".
14$: CALL MSGGTC ;get second character
BCS 11$ ;not there, unrecognizable
CMPB #EBCWAK,R1 ;is response "wack"?
BEQ 20$ ;yes.
CMPB #EBCRVI,R1 ;no, is it "rvi"?
BEQ 21$ ;yes.
CMPB #EBCEOT,R1 ;check disconnect command
BEQ 22$ ;yes - set the state
BIT #TCAK1,TCST2(R5) ;no, do we want ack-1?
BEQ 15$ ;no. we want ack-0
CMPB #EBCAK1,R1 ;yes, is this ack-1?
BEQ 16$ ;yes.
CMPB #EBCAK0,R1 ;no, ack-0?
BEQ 17$ ;yes.
BR 11$ ;no, unrecognizable.
; here if we are looking for ack-0
15$: CMPB #EBCAK0,R1 ;is this ack-0?
BEQ 31$ ;yes.
CMPB #EBCAK1,R1 ;no, ack-1?
BEQ 32$ ;yes
BR 11$ ;no, unrecognizable.
; here when we have received the proper ack
16$: CALL TACK1 ;record it
30$: MOV #TCAK1,R1 ;bit to change
XOR R1,TCST2(R5) ;complement ack-0/ack-1 bit
CALL MSGGTE ;end of message
BIC #TCNRD,TCST2(R5) ;we have received a response
CLC ;indicate success
RETURN
31$: CALL TACK0 ;recieved proper ack-0
BR 30$
; here if we have the wrong ack. if we have previously had
; no response, resend the last data message (i.e., treat as nak).
; otherwise, send an enq.
32$: CALL TACK1 ;recieved wrong ack-1
BR 33$
17$: CALL TACK0 ;record it
33$: BIT #TCNRD,TCST2(R5) ;have we timed out before?
BEQ 11$ ;no, send an enq.
BR 25$
; here if we receive a nak or wrong ack after timeout
18$: CALL TNAK ;record it
25$: CALL MSGGTE ;end of message
MOV TCLCB(R5),R4 ;point to lcb
BIC #TCNRD,TCST2(R5) ;we have received a response
TST LB.MSG(R4) ;check if we have previously received WACK
BEQ 12$ ;yes - this should be ENQ'd as inappropriate
MOV #2,R0 ;indicate data to be sent again
SEC ;indicate failure--send msg again
RETURN
22$: CALL RCVDSC ;record intent of other end to disconnect
CALL MSGGTE ;terminate msg
SEC
RETURN ;fail
; here on receiving eot in response to a message
19$: CALL TEOT ;record it
CALL MSGGTE ;end of message
CALL EOTRSP ;this is special
SEC ;indicate failure
RETURN
; here on receiving wack in response to a data message
20$: CALL TWACK ;record it
CALL MSGGTE ;end of message
MOV TCLCB(R5),R4 ;point to lcb
INC LB.RTY(R4) ;dont decrement retry count
CALL XLCLRM ;clear the message buffer
BIC #TCNRD,TCST2(R5) ;we have received a response
BR 12$ ;ask for the ack now
; here if we receive an rvi in response to a data message.
; since it is complicated to unbuffer and later continue
; the transmission, we define "unbuffering" as sending
; all of the data. thus we can mearly treat rvi as ack.
21$: CALL TRVI ;record it
BR 30$ ;treat as ack.
EOTRSP: MOV TCLCB(R5),R4 ;received EOT in response to data message
BIT #LF.SIM,LB.FGS(R4) ;check mode
BEQ 15$ ;termination
BIS #TCOAB,TCFG2(R5) ;emulation - this is an abort
BIS #TCEOT,TCST2(R5) ;no need to send an eot
BR 16$
15$: BIS #LF.OFL,LB.FGS(R4) ;device went off line
16$: TRACE TRCLIN,<(SP),R5,TCST2(R5),TCFG2(R5),LB.FGS(R4)>
RETURN
.SBTTL DQXNAV - 2780/3780...TTD transmission
; subroutine called when data is not available.
; this will be because either the message stream is complete
; or because there is more data to come but it is not here yet.
; on return:
;
; C clear -- message stream complete(EOF),device offline, message to send
; C set -- message stream incomplete - line failure or output aborted
DQXNAV: MOV TCLCB(R5),R4 ;point to lcb
CALL KOSHL ;check for bad things
BCC 11$ ;no - proceed
10$: MOV TCLCB(R5),R4 ;point to lcb because callers expect this
SEC ;yes, indicate transmission incomplete
RETURN
; here if the transmission has not been aborted.
11$: BIC #LS.ERR,(R4) ;clear any previous errors
TST TCMSG1(R5) ;is data available yet? [2(773)]
BNE 15$ ;yes, process it. [2(773)]
BIT #TCOEF,TCFG2(R5) ;no, is this the end of the stream?
BEQ 13$ ;no, data is just delayed.
SAVE LB.OC7(R4) ;protect this statistic
CALL DQSEOT ;no, send eot.
RESTOR LB.OC7(R4)
BCS DQXNAV ;transmitter timeout
BIS #TCOEC,TCFG2(R5) ;set "eof completed" bit
8$: CLC ;flag transmission successful
RETURN
; here if we got transmitter timeout trying to send the eot.
; its too bad, but the whole stream must be considered
; aborted.
; also come here if we got an error sending the ttd
; or receiving its response.
12$: CALL HSETHA ;set h/w abort 3(016)
CALL DQABRO ;abort the stream
SEC ;signal failure
RETURN
; here if the data is just delayed. wait 2 seconds. if there
; is still no data, send "ttd" and receive its nak,
; then check again.
13$: DSCHED #EBQMSG,#2*JIFSEC ;wait for time to expire
; or for a message
TST TCMSG1(R5) ;is there a message?
BNE 15$ ;yes, go send it.
BIT #TCOAB,TCFG2(R5) ;check aborts
BNE 10$
MOV #TTDMSG,R0 ;no, send ttd
MOV #TTDLEN,R1
CALL CTLMSG ;send message
INC LB.OC5(R4) ;count ttds sent
MOV #3*JIFSEC,LB.ALR(R4);set the alarm
CLR R4 ;no data yet
CALL MSGGTC ;get first char of response
BCS 30$ ;none.
CMPB #EBCDLE,R1 ;check for DLE-EOT
BEQ 18$ ;maybe
CMPB #EBCEOT,R1 ;IS IT EOT?
BEQ 16$ ;yes, receiver aborted.
CMPB #EBCNAK,R1 ;no, is it nak?
BNE 31$ ;no.
CALL TNAK ;record it
CALL MSGGTE ;yes, end of message
MOV TCLCB(R5),R4 ;point to lcb
MOV LB.ERC(R4),LB.RTY(R4) ;reset retry counter
BR DQXNAV ;send ttd unless abort or eof.
; here if the response to ttd is not "nak" or "eot"
30$: CALL KOSHL ;check error status
BCS 10$
CALL TTMO ;no response
BR 14$
31$: CALL TCRF ;invalid response
14$: CALL MSGGTT ;end of message and wait
MOV TCLCB(R5),R4 ;point to lcb
INC LB.OC3(R4) ;count invalid responses to ttd
DEC LB.RTY(R4) ;check retries
BLE 12$ ;other end is in trouble
BR DQXNAV ;try to send anyway.
; here if there is now a message available.
15$: CMP #TTDMSG,LB.CMA(R4);if last control msg was TTD
BNE 8$
INC LB.CMA(R4) ;make it not but leave it recognizable for debugging
BR 8$ ;if somebody else croaks as a result of this that
; is probably a bug anyhow.
18$: CALL MSGGTC ;got d dle...look for d eot
BCS 30$
CMPB #EBCEOT,R1 ;got something
BNE 31$ ;strange
CALL RCVDSC ;record intent of other end to disconnect
CALL MSGGTE ;terminate msg
BR 10$ ; and abort the transmission
; here if we get eot in response to ttd. the receiver has
; aborted the transmission.
16$: CALL TEOT ;record it
25$: CALL MSGGTT ;end of message and wait
CALL EOTRSP ;this is special
BR 10$ ;indicate no more to transmit now
.SBTTL DQRQIP - 2780/3780...signal input permission requested to 10
; subroutine to request input permission.
;
; on return:
;
; C is set if permission has been refused, clear if granted.
DQRQIP: MOV TCLCB(R5),R4 ;point to lcb
BIT #LF.OFL,LB.FGS(R4) ;check if we were previously receiving
BNE 12$ ;yes - grant permission automatically
BIS #TCIPR!TCIWR,TCFG2(R5) ;request input permission
; and note it was req. [2(770)]
CALL SACTI ;set device active
CALL DQAWXL ;awaken xlate task
MOV #<JIFSEC*2>/3,R0 ;wait up to 2/3 sec
11$: DSCHED #EBINTR,R0 ;for "grant" signal
BIT #TCIPG,TCFG2(R5) ;were we given permission?
BNE 12$ ;yes, send ack-0
MOV TCTIM(R5),R0 ;no, is time up?
BNE 11$ ;no, keep waiting.
BIC #TCIPR,TCFG2(R5) ;yes, no longer requesting
CALL DQAWXL ;wake up xlate task
SEC ;indicate permission refused
RETURN
; here if permission has been granted.
12$: BIC #TCIPR,TCFG2(R5) ;no longer requesting
BIC #LF.OFL,LB.FGS(R4) ;no longer offline either
CALL DQAWXL ;wake up xlate task
CLC ;indicate permission granted
RETURN
; subroutine to awaken the translate task
; R4 points to the lcb
DQAWXL: SIGNAL LB.TCD(R4),EBINTR ;inform xlate task something is up
RETURN
.SBTTL DQRECV - 2780/3780...receive messages
; subroutine to process input message stream. called when we
; receive an enq in control mode.
DQRECV: CALL INFLO ;see if too few chunks
BCC DQREC1 ;no, go accept bid
; here to refuse the bid by sending "nak".
DQSNAK: MOV #NAKMSG,R0 ;refuse the bid.
MOV #NAKLEN,R1
BIS #LS.LWR,@TCLCB(R5) ;dont follow with a read
CALL CTLMSG
RETURN
; here if there are enough chunks that we can accept the bid.
DQREC1: MOV #AK0MSG,TCCMA(R5) ;accept the bid
MOV #AK0LEN,TCCMC(R5)
BIC #TCAK1,TCST2(R5) ;next ack will be ack-1
; here to receive the next transmission block
11$: MOV TCLCB(R5),R4 ;point to lcb
MOV LB.ERC(R4),LB.RTY(R4)
12$: CALL KOSHL ;check error status
BCS 15$
MOV TCLCB(R5),R4 ;no, point to lcb
BIC #LS.ERR,(R4) ;clear any previous errors
MOV TCCMA(R5),R0 ;any control message to send?
BEQ 13$ ;no, just issue a read
MOV TCCMC(R5),R1 ;yes, get address and count
35$: CALL CTLMSG ;send the msg
BR 32$
; here if there is no prompting control message.
; just issue a read.
13$: CALL @T.RED(R5) ;read the text block
32$: CLR TCCMA(R5) ;don't send control msg twice
MOV #<3*JIFSEC>+<JIFSEC/4>,LB.ALR(R4);set the response alarm
CLR R4 ;no data yet
CALL MSGGTC ;get input character
BCS 14$ ;timeout
CALL CLRALR ;flush alarm now
CMPB #EBCEOT,R1 ;end of transmission?
BNE 33$
CALL TEOT ;record it
JMP 25$ ;yes, end of file or abort
33$: CMPB #EBCENQ,R1 ;NO, "ENQ"?
BEQ 20$ ;yes, give positive response.
CMPB #EBCDLE,R1 ;no, data link escape?
BEQ 17$ ;yes, read transparent text
CMPB #EBCSTX,R1 ;no, start of text?
BEQ 16$ ;yes, read normal data
CMPB #EBCSOH,R1 ;start of header?
BEQ 16$ ;treat the same as stx
CALL TCRF ;record cruft
BR 44$
; here on invalid message or timeout
14$: CALL KOSHL ;check error status
BCS 44$
CALL TTMO ;record time out
44$: CALL MSGGT2 ;end of msg and wait 2 sec from start
MOV TCLCB(R5),R4 ;point to lcb
DEC LB.RTY(R4) ;had enough (20 sec worth?)
BGT 12$ ;no, try again.
36$: CALL HSETHA ;yes, set the h/w line abort 3(016)
BR 23$
; here if the stream has been aborted, probably by the
; pdp-10. send eot and return.
15$: CALL DQSEOT ;send eot (unless not needed)
RETURN
; here on stx to process a normal (non-transparent) message
16$: CALL BLKMSG ;check for blocked messages
CALL DQRNRM ;process the block
BR 18$ ;analyze c bit and r0 value
; here on "dle" to read a transparent data message
17$: CALL MSGGTC ;get next char to determine case
BCS 14$
CMPB #EBCSTX,R1 ;DLE-STX => transparent data
BEQ 27$
CMPB #EBCSOH,R1 ;as does DLE-SOH
BNE 30$
27$: CALL BLKMSG ;check for blocked messages
CALL DQRXPM ;read text
; here after reading a text block to respond as
; indicated by DQRXRM or DQRNRM.
18$: BCC 19$ ;success
; error in message, send nak or eot.
CALL DQRNRP ;set up a nak
BCS 24$ ;retry counter exhausted, abort
BR 12$ ;send nak and read data again.
; message read successfully, acknowledge it.
19$: MOV #TCAK1,R0 ;complement ack-0/ack-1 bit
XOR R0,TCST2(R5)
BIS #TCIRN,TCFG2(R5) ;flag input running
BIC #TCIPG,TCFG2(R5) ;clear "input permission granted"
; here to give positive response: ack-0, ack-1 or wack.
21$: CALL DQRPRP ;set up ack-0, ack-1 or wack
JMP 11$ ;send it and wait for next transmission block
; here on enq - repeat last response
20$: CALL TENQ ;record this
BIT #LS.CTL,@TCLCB(R5);check if last msg was a control msg
BEQ 39$ ;if not, ENQ is not appropriate
CALL MSGGTE ;end of input text
MOV TCLCB(R5),R4 ;get the lcb
DEC LB.RTY(R4) ;don't do this forever
BLE 36$
37$: MOV LB.CMA(R4),R0 ;other end didn't understand last msg
CMP #WAKMSG,R0 ;if last response was WACK - check if it still is
BEQ 21$
MOV LB.CMC(R4),R1 ;send it again
JMP 35$
; here if the message after a message ending in etx
; (which was acked) did not start with eot or enq.
22$: CALL MSGGT2 ;end of input and wait 2 sec since start
; here if the message after the last message did
; not start with enq or eot, or on transmitter timeout.
23$: CALL DQSEOT ;send eot if necessary
; here to abort the message stream.
24$: MOV TCLCB(R5),R4 ;point to lcb
TRACE TRCLIN,<R5,TCST2(R5)>
CALL DQABRI ;flag stream aborted
BIC #TCXET,TCST2(R5) ;dont expect eot next
BR 26$ ;clear grant and running flags and return.
; here on receiving "eot". if the last message did not end
; with etx this means abort.
25$: CALL MSGGTE ;end of message
CALL DQREOT ;receive eot
BCS 24$ ;this is an abort
; here to clear grant and running flags and return.
26$: BIC #TCIPG!TCIRN,TCFG2(R5) ;clear grant and running flags
RETURN
; DLE control sequence of some kind
30$: CMPB #EBCEOT,R1 ;check for disconnect
BNE 31$
CALL RCVDSC ;record intent of other end to disconnect
CALL MSGGTE ;terminate msg
BR 26$
31$: ;DLE-garbage
BIT #TCXET,TCST2(R5);check for great expectations of an EOT
BNE 22$
39$: CALL TCRF ;record cruft
JMP 44$ ;nothing else is really valid here so it's either
;garbage or unxpected...whatever the difference is.
BLKMSG: BIC #TCXET,TCST2(R5) ;not expecting an eot at this point
10$: BIT #TCIEC,TCFG2(R5) ;check for input eof pending
BNE 20$ ;yes - messages are blocked back to back
RETURN ;no - begin new message
20$: DSCHED #EBINTR ;wait til xlate task wakes us
BR 10$ ;and check again
.SBTTL DQRPRP - 2780/3780...positive response to received message
; subroutine to set up a positive response, either ack-0, ack-1
; or wack.
DQRPRP: BIT #TCXET,TCST2(R5) ;last message end in etx?
BNE 11$ ;yes, always send ack.
CALL INFLO ;shall we send WACK?
BCS 12$ ;yes, go do it
11$: BIT #TCAK1,TCST2(R5) ;yes, send ack-1?
BEQ 13$ ;no, ack-0.
MOV #AK1MSG,R0 ;yes.
MOV #AK1LEN,R1
BR 14$
; here if there are not many chunks left. send "wack" to
; acknowledge the message but start an enq-wack exchange
; until we have plenty of chunks again.
12$: MOV #JIFSEC,R1 ;wait seconds before sending WACK
;...this was shortened from the normal 2 seconds
; to accomodate a marginal DN22.
16$: DSCHED #EBINTR,R1
BIT #TCIAB,TCFG2(R5);check for abort
BEQ 15$ ;none, continue
JMP DQSEOT ;yes, send EOT
15$: CALL INFLO ;check conditions now (we may be able to send an ACK)
BCC 11$ ;yup, go send ACK
MOV TCTIM(R5),R1 ;check if time up
BGT 16$ ;no - don't WACK yet
MOV TCLCB(R5),R0 ;point to lcb
INC LB.IC4(R0) ;count WACK's sent
MOV #WAKMSG,R0
MOV #WAKLEN,R1
BR 14$
; here to send ACK-0
13$: MOV #AK0MSG,R0
MOV #AK0LEN,R1
14$: MOV R0,TCCMA(R5) ;store control message address
MOV R1,TCCMC(R5) ; and count
RETURN ;read next block
.SBTTL DQRNRP - 2780/3780...negative response to received message
; subroutine to set up a negative response, either NAK
; or EOT.
; on return:
; C clear -- set up a NAK
; C set - retry counter exhausted, abort the stream.
DQRNRP: MOV TCLCB(R5),R4 ;point to lcb
DEC LB.RTY(R4) ;should we send nak again?
BLE 11$ ;no, abort the stream.
10$: INC LB.IC3(R4) ;yes, increment nak counter
MOV #NAKMSG,TCCMA(R5) ;set up a nak
MOV #NAKLEN,TCCMC(R5)
CLC ;give success return
RETURN
; here if the retry counter is exhausted.
11$: CALL HSETHA ;set the h/w abort 3(016)
SEC ;flag counter exhausted
RETURN
.SBTTL DQREOT - 2780/3780...receiving process received EOT
; on return:
; C clear -- we have reached end of file
; C set -- the EOT aborted the stream.
DQREOT: MOV TCLCB(R5),R4 ;point r4 to lcb
BIS #TCEOT,TCST2(R5) ;no eot needed to abort
BIT #TCXET,TCST2(R5) ;are we expecting this eot?
BEQ 11$ ;no, this is an abort.
BIC #TCXET,TCST2(R5) ;yes, no longet expecting eot
BIC #TCIRN!TCIPG,TCFG2(R5) ;no longer doing input
DEC LB.IC6(R4) ;uncount aborts
CALL DQAWXL ;awaken xlate task
.IF NE,DB.SEQ
CALL PCHKI ;init sequence checker
.ENDC ;.IF NE,DB.SEQ
CLC ;signal eof
RETURN
; here if the eot is unexpected. this is abort.
11$: BIS #LF.OFL,LB.FGS(R4) ;sender is offline
SEC ;signal abort
RETURN
.SBTTL DQRNRM - 2780/3780...read a non-transparent message
; on return:
; C clear - all ok, reply with ack or wack
; C set - error in message:
; R0 = 1 - send "NAK" or (if too many retries) "EOT"
; R0 = 2 - send nothing (let sender time out)
DQRNRM: KGLOAD #0 ;initialize kg11-a
BIC #TCDTA,TCST2(R5) ;no data as yet
CALL GETMHD ;get a message header
BCC 11$ ;got one.
CALL MSGGT2 ;terminate reading and wait 2 sec
BR DQRNRE ;give error return.
11$:
; here to get next character of block.
DQRNRC: CALL MSGGTC ;get character
BCS DQRNTO ;timeout
; here to process the character in r1
DQRNRA: BIT #300,R1 ;control character?
BNE 11$ ;no.
MOVB EBCSPC(R1),R2 ;yes, get its code
MOV DQRNRD(R2),R2 ;get dispatch address
BEQ 11$ ;not a data link control char
JMP (R2) ;data link control -- dispatch
; here if the character is not a data-link control character.
11$: KGACUM R1 ;accumulate bcc
BIS #TCDTA,TCST2(R5) ;we have some real data
CALL MSGAPC ;append to output string
BCS DQRNRT ;out of chunks
TST MSGLEN(R0) ;is message unreasonably long?
BGT DQRNRC ;no, get another character.
CALL TCRF ;record crufty data
BR DQRNRT
; here if we run out of chunks, get read timeout, or the message gets too long.
DQRNTO: CALL KOSHL ;check error status
BCS DQRNRT
CALL TTMO ;record time out
DQRNRT: CALL MSGGT2 ;terminate the read and wait 2 sec
CALL FREMSG ;send it partial msg to free
DQRNRE: MOV #2,R0 ;allow timeout to happen
; here to give error exit from dqrnrm.
DQRNRX: BIC #TCXET,TCST2(R5) ;not expecting eot next
SEC ;signal failure
RETURN
; dispatch table for data link control characters
DQRNRD: .WORD 0 ;CODE 0 = miscellaneous
.WORD DQRNRC ;CODE 2 = SYN
.WORD 12$ ;CODE 4 = ETB
.WORD 11$ ;CODE 6 = ETX
.WORD 14$ ;CODE 10 = IUS
.WORD 0 ;CODE 12 = IRS
.WORD 18$ ;CODE 14 = ENQ
.WORD 0 ;CODE 16 = DLE
; here on receiving an ETX. this is the last message in the stream.
11$: BIS #TCXET,TCST2(R5) ;flag last message
; here on receiving etb or, from above, etx. this is the
; last block in the message. on the ibm 2780 etx and etb provide
; the irs function.
12$: KGACUM R1 ;accumulate bcc
CALL DQRBCC ;check bcc
BCS DQRNTO ;timeout
BIT #TCOBS,TCFG1(R5) ;old bsc protocol?
BEQ 13$ ;no, irs already in data
MOV #EBCIRS,R1 ;yes, include an explicit irs
CALL MSGAPC ; to simplify xlate
BCS DQRNRT ;out of chunks
13$: CALL DQRNDM ;do the end processing
BCS 17$ ;bad bcc
BIT #TCXET,TCST2(R5) ;check for etx seen
BEQ 20$
BIS #TCIEC,TCFG2(R5) ;yes - set eof
20$: RETURN
; here on receiving an IUS. on the ibm 2780 this also
; provides the IRS function. in any case it is
; followed by two characters of bcc.
14$: KGACUM R1 ;include ius in bcc
CALL DQRBCC ;include next two chars in bcc
BCS DQRNTO ;timeout
KGTEST ;is bcc right?
BNE 16$ ;no.
BIT #TCOBS,TCFG1(R5) ;yes, using old bsc?
BEQ 15$ ;no, no irs function.
MOVB #EBCIRS,R1 ;yes, include an irs
CALL MSGAPC ; to simplify xlate.
BCS DQRNRT ;out of chunks.
; here to absorb the optional syn's and stx that
; may appear between blocks.
15$: CALL MSGGTC ;get next character (after bcc)
BCS DQRNTO ;timeout
CMPB #EBCSYN,R1 ;skip syncs
BEQ 15$
CMPB #EBCSTX,R1 ;is this stx?
BNE DQRNRA ;no, include in data
KGACUM R1 ;yes, include in bcc
JMP DQRNRC ;but not in data
; here if the bcc proves to be bad.
16$: CALL MSGGT2 ;terminate read and wait 2 sec
17$: CALL FREMSG ;send it the bad msg to be freed
CALL TBCC ;record bad BCC
MOV #1,R0 ;give "nak" reply
BR DQRNRX ;give error return.
; here if we find an enq in the data. this is probably a ttd
; or forward abort. in either case, send a nak.
18$: BIT #TCDTA,TCST2(R5) ;have we had any real data?
BNE 19$ ;yes, this is forward abort.
CALL MSGGTE ;no, end of input.
CALL FREMSG ;send it message to free
CALL TTTD ;record it
MOV TCLCB(R5),R4 ;point to lcb
INC LB.RTY(R4) ;dont count this nak towards
; retry threshold
DEC LB.IC3(R4) ;or in statistics
MOV #1,R0 ;indicate send nak
JMP DQRNRX ;give error return
; here if the enq is a forward abort rather than part of a ttd.
19$: CALL MSGGT2 ;end of input and wait 2 sec
CALL FREMSG ;flush the msg
MOV #1,R0 ;indicate send nak
JMP DQRNRX ;will probably get aborting eot
DQRNDM: CALL MSGGTE ;end of message processing
KGTEST ;did bcc come out zero?
BNE 10$ ;no, there is a bcc error.
CALL KOSHL ;check error status
BCS 10$ ;if we can't ack the message, don't queue it
MOV TCLCB(R5),R4 ;yes, point to lcb
.IF NE,DB.SEQ
CALL PCHK ;call sequence checker
.ENDC ;.IF NE,DB.SEQ
INC LB.IC1(R4) ;count a block received successfully
MOV LB.TCD(R4),R1 ;point to translate task
INC TCIMC(R1) ;count this message
SAVE R0
CALL CNTMSG ;find number of chunks in message
ADD R0,LB.RES(R4) ;reserve this many for xlate
RESTOR R0
CALL QUEMSG ; send it the block
CLC ;flag success
RETURN
10$: SEC
RETURN
.IF NE,DB.SEQ
;PCHK - force all input files to have sequentially numbered records
; used to detect protocol bugs at the lowest level
; assumes lines begin with a 4 digit line number beginning at 0000
;
; R0/message to queued to xlate task
PCHK: SAVE <R0,R1,R2,R3,R4>
CALL FMSGI
MOV MSGPTR(R0),R1
MOV CHLEN(R0),R2
10$: CALL LSCAN ;scan for beg of this line
BCS 20$ ;end of message
CALL LCHK ;check this line
BCC 10$
20$: RESTOR <R4,R3,R2,R1,R0>
RETURN
LCHK: MOV #4,R3
CLR LCHKN
10$: CALL PNXTCH ;get next digit
BCC 15$
RETURN
15$: SUB #360,R4
MOV R4,-(SP)
MOV LCHKN,R4 ;get current accumulated number
ASL R4
ADD R4,(SP)
ASL R4
ASL R4
ADD (SP)+,R4
MOV R4,LCHKN ;the new accumulated number
SOB R3,10$
SUB LCHKP,R4 ;done - check sequentiality
DEC R4
BNE 20$ ;loser
MOV LCHKN,LCHKP ;new previous line number
CLC
RETURN
20$: STOPCD BUG
LSEQER: RETURN
LCHKP: 0 ;previous line number
LCHKN: 0 ;current accumulator
PCHKI: MOV #-1,LCHKP ;init line number sequence checking
CLR LCHKN
RETURN
PNXTCH: DEC R2 ;R1/ptr,R2/byte cnt
BLE 10$
CLR R4
BISB (R1)+,R4
CLC
RETURN
10$: MOV (R0),R0
BNE 20$
SEC
RETURN
20$: MOV R0,R1
TST (R1)+
MOV (R1)+,R2
BR PNXTCH
LSCAN: CALL PNXTCH ;find next line beginning
BCS 25$
CMPB R4,#113 ;scan for .
BNE 26$
CLC
25$: RETURN
26$: CMPB R4,#EBCESC
BNE LSCAN
CALL PNXTCH ;gobble carriage control
BCC LSCAN
RETURN
.ENDC ;.IF NE,DB.SEQ
.SBTTL DQRXPM - 2780/3780...read a transparent message
; the DLE has already been read.
; R1/character following DLE (should be STX or SOH)
; on return:
; C clear - all ok, reply ACK or WACK
; C set - failure:
; R0 = 1 - send NAK or (if retry counted to zero) ENQ
; R0 = 2 - send nothing (let sender time out)
DQRXPM: KGLOAD #0 ;initialize kg11-a
CMPB #EBCSOH,R1 ;[1007]is it soh?
BEQ 11$ ;[1007]yes, do as though an stx.
CMPB #EBCSTX,R1 ;is it stx?
BEQ 11$ ;yes.
CALL TCRF ;record cruft
CALL MSGGT2 ;no, terminate read, wait 2 sec
BR DQRXPE ; and ignore message
; here to begin reading a record.
11$: CALL GETMHD ;get a message header
BCC 12$ ;got one
CALL MSGGT2 ;terminate reading and wait 2 sec
BR DQRXPE ;give error return.
12$: BIS #MSGTSP,MSGFGS(R0) ;flag message as transparent
KGLOAD #0 ;initialize kg11-a
DQRXPC: CALL MSGGTC ;get character from block
BCS DQRXTO ;timeout
CMPB #EBCDLE,R1 ;is it dle?
BEQ DQRXPB ;yes.
; here on a non-dle character or on a dle following a dle.
; append the character to the message being built.
DQRXPG: KGACUM R1 ;no, accumulate in bcc
CALL MSGAPC ;build message for translator
BCC DQRXPC ;ok - get next character.
JMP DQRXPT ;ugh, terminate the message.
; here on dle character except a dle following a dle
DQRXPB: CALL MSGGTC ;get next character (after dle)
BCS DQRXTO ;timeout
BIT #300,R1 ;control character?
BNE 11$ ;no, invalid.
MOVB EBCSPC(R1),R2 ;yes, get its code
MOV DQRXPD(R2),R2 ;get dispatch address
BEQ 11$ ;not a valid character in this context
JMP (R2) ;dispatch to char handler
; here on invalid character after dle.
11$: CALL MSGGT2 ;terminate reading and wait 2 sec
CALL FREMSG ;flush the garbage
MOV TCLCB(R5),R4 ;point to lcb
INC LB.IC8(R4) ;count invalid chars after dle
MOV #1,R0 ;respond with nak
SEC ;signal failure
RETURN
; here if we must ignore the message because of chunk depletion
; or receive timeout.
DQRXTO: CALL KOSHL ;check error status
BCS DQRXPT
CALL TTMO ;record time out
DQRXPT: CALL MSGGT2 ;terminate reading and wait 2 sec
CALL FREMSG ;flush the garbage
DQRXPE: MOV #2,R0 ;indicate no response
; here to give the error return from DQRXPM
DQRXPX: BIC #TCXET,TCST2(R5) ;not expecting eot next
SEC ;flag failure
RETURN
; dispatch table for special characters after DLE
DQRXPD: .WORD 0 ;CODE 0 = miscellaneous
.WORD DQRXPC ;CODE 2 = SYN
.WORD 12$ ;CODE 4 = ETB
.WORD 11$ ;CODE 6 = ETX
.WORD 13$ ;CODE 10 = IUS
.WORD 0 ;CODE 12 = IRS
.WORD 0 ;CODE 14 = ENQ
.WORD DQRXPG ;CODE 16 = DLE
; here on DLE ETX. this is the last message of the stream.
11$: BIS #TCXET,TCST2(R5) ;expect eot next
; here on dle etb and (from above) dle etx. this is the last
; record in the message.
12$: KGACUM R1 ;accumulate bcc
CALL DQRBCC ;accumulate next two chars, too
BCS DQRXPT ;timeout
CALL DQRNDM ;do the end processing
BCS 16$ ;bad bcc
BIT #TCXET,TCST2(R5) ;check for etx seen
BEQ 20$
BIS #TCIEC,TCFG2(R5) ;yes - set eof
20$: RETURN
; here on DLE IUS. this signals that a BCC will follow.
; on the IBM 2780 it also performs the IRS function.
13$: KGACUM R1 ;accumulate bcc
CALL DQRBCC ;accumulate next two chars, too
BCS DQRXPT ;timeout
KGTEST ;is bcc ok?
BNE 15$ ;no.
; here to absorb the optional syncs between records.
14$: CALL MSGGTC ;get next character
BCS 17$ ;timeout
CMPB #EBCSYN,R1 ;sync?
BEQ 14$ ;yes, ignore them.
CMPB #EBCDLE,R1 ;no, dle?
BNE 17$ ;no, invalid continuation.
CALL MSGGTC ;yes, get next character
BCS 17$ ;timeout
CMPB #EBCSYN,R1 ;syn? (dle syn)
BEQ 14$ ;yes, ignore it.
CMPB #EBCSTX,R1 ;no, stx?
BNE 17$ ;no, error: stx mandatory
KGACUM #EBCDLE ;yes, load "dle" into bcc
KGACUM R1 ;include stx in bcc
JMP DQRXPC ;but not in data
; here on bcc error.
15$: CALL MSGGT2 ;terminate reading and wait 2 sec
16$: CALL FREMSG ;flush the garbage
CALL TBCC ;record bad BCC
MOV #1,R0 ;reply with a nak (or eot)
BR DQRXPX ;give error return.
; here on invalid character sequence between blocks,timeouts and aborts
17$: CALL MSGGT2 ;terminate reading and wait 2 sec
CALL FREMSG ;flush the garbage
MOV TCLCB(R5),R4 ;point to lcb
CALL KOSHL ;check error status
BCS 25$
INC LB.IC9(R4) ;count invalid sequences
25$: JMP DQRXPE ;give error return.
.SBTTL DQRBCC - read BCC
; subroutine to accumulate the next two characters of the
; message into the BCC
; R3 = chars gotten from this chunk already
; R4 = pointer to current chunk (initially 0)
; on return:
; C clear means all ok
; C set means timeout
; the crc accumulation register will be 0 only if the crc checks
DQRBCC:
.IF NE,DEBUG
KGSAVE -(SP) ;save current bcc accumulator
CLR -(SP) ;sapce for the received bcc
.ENDC ;.IF NE,DEBUG
CALL MSGGTC ;get next character
BCS 11$ ;timeout
KGACUM R1 ;accumulate in bcc
.IF NE,DEBUG
MOVB R1,(SP)
.ENDC ;.IF NE,DEBUG
CALL MSGGTC ;get second character
BCS 11$ ;timeout
KGACUM R1 ;accumulate in bcc
.IF NE,DEBUG
MOVB R1,1(SP)
;trace caller,bsc task,calculated BCC,received BCC
TRACE TRCBCC,<4(SP),R5,6(SP),6(SP)>
CMP (SP)+,(SP)+ ;check if ok
BEQ 10$
BIT #TRCBCC,TRCBTS ;stop if we are interested in bcc's
BEQ 10$
STOPCD BCE
.IFTF
10$: CLC ;flag success
.IFT
RETURN
.ENDC ;.IF NE,DEBUG
11$:
.IF NE,DEBUG
TST (SP)+
TST (SP)+
SEC
.ENDC ;.IF NE,DEBUG
RETURN
.SBTTL CTLMSG - send a control message and start reading response.
; R0 points to the text of the message
; R1 contains the length of the message proper, pads must be counted in
; R5 points to the tcb
; LS.LWR is set if no response is expected.
; on return:
;
; R4/lcb ptr
; C is clear if the message went, set if we timed out
; or had an error.
CTLMSG: MOV TCLCB(R5),R4 ;point to lcb
BIT #LS.ENB,(R4) ;just for the hell of it
BEQ 69$ ;whadayano!
ADD LB.TRL(R4),R1 ;add count of trailing pads(driver dependent)
MOV R1,LB.ALR(R4) ;allow 1 tick per character
ADD LB.CSD(R4),LB.ALR(R4) ;plus clear-to-send delay
PIOFF #BR4 ;protect line driver from scheduler til all setup
CALL @T.CTL(R5) ;send the message
;DQCNTL cannot fail
BIT #LS.LWR,(R4) ;should we expect a response?
BNE 11$ ;no.
CALL @T.RED(R5) ;yes, set up to read response.
BCS 14$ ;couldn't get chunks
11$: PION
DSCHED #EBINTR!EBALR
BIT #LS.ERR,(R4) ;check for transmitter hardware error
BNE 12$ ;yes - take error path
BIT #EBINTR,TCWKEV(R5) ;did transmitter finish in time?
BNE 15$ ;yes
; here when the transmitter timed out. stop it and
; indicate error.
12$: TRACE TRCLIN,<(SP),R5,TCWKEV(R5),(R4)>
BIT #LS.ERR,(R4) ;check for hard error wakeup
BNE 16$
INC LB.TTO(R4) ;count timeouts
16$: CALL @T.KIL(R5) ;stop the transmitter [1(637)]
BIC #LS.ERR,(R4) ;clear error bit
BIT #LS.LWR,(R4) ;did we kill a read also?
BEQ 13$ ;no
CALL @T.RED(R5) ;yes - start it again
13$: DSCHED ,#10. ;wait awhile to skew timeouts since the caller
; will think everything is ok
69$: CALL 15$ ;return error here for the few cases where the
SEC ;caller must be sure that the control message suc'd
RETURN
15$: BIC #LS.LWR,(R4) ;clear "last" bit
CALL CLRALR ;flush alarm now
CLC ;yes, indicate success
RETURN
14$: PION
TRACE TRCLIN,<(SP),R5,TCWKEV(R5),(R4)>
BR 15$
.SBTTL STOBCC - append BCC to message
; subroutine to store into a message the BCC value accumulated in the KG11 so far.
; on return:
; C clear - BCC stored, KG11-a BCC register zero.
; C set - out of chunks.
STOBCC: KGSAVE -(SP) ;get current bcc
MOVB (SP),R1 ;get first byte
KGACUM R1 ;accumulate in bcc
CALL MSGAPC ;append to string
BCS 12$ ;out of chunks
MOVB 1(SP),R1 ;get second byte of bcc
KGACUM R1 ;accumulate in bcc
CALL MSGAPC ;append to string
BCS 12$ ;out of chunks
.IF NE,FT.CHK
KGTEST ;is total bcc now zero?
BEQ 11$ ;yes.
STOPCD BCE ;no, bcc accumulation error.
11$:
.ENDC ;.IF NE,FT.CHK
MOV (SP)+,R1 ;delete bcc from stack
TRACE TRCBCC,<R5,R0,R1>;trace bsc task,message,calculated bcc
CLC ;signal ok
RETURN
; here if we run out of chunks
12$: CALL FREMSG ;flush the garbage
MOV (SP)+,R1 ;delete bcc from stack
SEC ;signal error
RETURN
.SBTTL DQABRO - 2780/3780...abort output
; subroutines to abort the message stream due to the device
; at the other end of the line. for example, running out
; of retries will abort the stream.
; to simplify the coding of the bsc routines, these subroutines
; can be called several times for the same abort -- subsequent
; calls for a message stream are no-ops.
; subroutine to abort an output stream
DQABRO: TRACE TRCABO,<(SP),R5,R1> ;trace abort call
.IF NE,DEBUG
BIT #TRCABO,TRCHLT ;are we asked to stop on abort?
BEQ 11$ ;no.
STOPCD DBG ;yes, debug stop.
11$:
.ENDC ;.IF NE,DEBUG
MOV TCLCB(R5),R4 ;no, point to lcb
MOV LB.TC1(R4),R1 ;point to bsc tcb
BIS #TCOAB,TCFG2(R1) ;signal abort
MOV LB.TCD(R4),R1 ;point to translation task
BIS #TCOAB,TCFG2(R1) ;signal abort, too.
CALL SACTO ;set the device active
RETURN
.SBTTL DQABRI - 2780/3780...abort input
DQABRI: TRACE TRCABO,<(SP),R5,R1> ;trace abort call
.IF NE,DEBUG
BIT #TRCABO,TRCHLT ;are we asked to stop on abort?
BEQ 11$ ;no.
STOPCD DBG ;yes, debug stop.
11$:
.ENDC ;.IF NE,DEBUG
MOV TCLCB(R5),R4 ;no, point to lcb
MOV LB.TC1(R4),R1 ;point to bsc tcb
BIS #TCIAB,TCFG2(R1) ;signal abort
MOV LB.TCD(R4),R1 ;point to translation task
BIS #TCIAB,TCFG2(R1) ;signal abort, too.
CALL SACTI ;set device active for input
RETURN
.SBTTL ABTLIN - abort all io on line
ABTLIN: MOV TCLCB(R5),R4 ;abort all io on line
.IF NE,FT.HSP
CMP #TTHASP,LB.DVT(R4) ;check for HASP
BNE 10$ ;2780/3780
CALL HSABTO ;abort HASP output devices
CALL HSABTI ;abort HASP input devices
RETURN
.ENDC ;.IF NE,FT.HSP
10$: CALL DQABRO ;abort 2780/3780 output
CALL DQABRI ;abort 2780/3780 input
RETURN
.SBTTL DQSEOT - 2780/3780...send EOT to abort or EOF
; the device at the other end to control state. this
; is used to abort the stream and after receiving
; acknowledgment of the last message in an output stream.
;
; to simplify the coding of the error routines this
; subroutine may be called redundently. extra calls for a
; particular message stream are ignored.
;
; on return:
;
; C is set if the message failed because of error or
; transmitter timeout, clear if the message was sent
; ok or if no message needed to be sent.
;
; all registers but R5 are destroyed.
DQSEOT: BIT #TCEOT,TCST2(R5) ;do we need an eot to clear the line?
BNE 11$ ;no, one is enough.
MOV #EOTMSG,R0 ;send an eot
MOV #EOTLEN,R1
BIS #LS.LWR,@TCLCB(R5) ;last message of the stream
CALL CTLMSG
BCS 10$ ;failed to send it
BIS #TCEOT,TCST2(R5) ;suc'd, only one required per stream
INC LB.OC7(R4) ;count aborting eot's sent
10$: RETURN
; here if there is no need to send a message
11$: CLC ;indicate success
RETURN
DQSDIS: MOV #DISMSG,R0 ;send disconnect sequence
MOV #DISLEN,R1
BIS #LS.LWR,@TCLCB(R5) ;last message of the stream
CALL CTLMSG
RETURN
; this subroutine check s for input and output aborts
; and flushes all messages queued to the bsc task
HSCKAB: ;r4/lcb
CALL HSWALX ;wake up all xlate tasks
CLR TCDTB(R5) ;initialize device for abort
11$: INC TCDTB(R5) ;start with console and inc
CMP TCDTB(R5),LB.NTC(R4) ;done with all devices
BHI 12$ ;yes, exit
MOV TCDTB(R5),R1 ;need device # in r1
CALL HSCKDO ;do abort processing
;r0/device xlate tcb
BR 11$ ; for all devices
12$: CLC ;indicate success
RETURN
.SBTTL HSPLIN - HASP...multileaving protocol functions
.IF NE,FT.HSP
; the following code (from here to end of this module)
; is used only if line is in hasp-mode.
;
; here if the line is found to be in hasp mode.
HSPLIN: MOV TCLCB(R5),R4 ;get lcb ptr
MOV #JIFSEC,LB.ALR(R4) ;for acking once in 2 secs
BIT #TCOPG,TCFG2(R5) ;is bid complete?
BEQ 11$ ;no.
BIC #LS.ERR,(R4) ;clear any previous errors
BIT #TCDIDO,TCBSCF(R5) ;were we xmitting last?
BNE 13$ ;yes, prepare to receive now
BR 19$ ;no, go xmit
; here when bid is not complete.
11$: CALL HSCKAB ;check for aborts
BIT #TCOPR,TCFG2(R5) ;see if requested bid?
BNE 16$ ;yes, try bidding SOH-ENQ
CALL @T.RED(R5) ;see if other side is bidding
CLR R4 ;no data as yet
CALL MSGGTC ;get character from msg read
BCS 15$ ;none
12$: CMPB #EBCDLE,R1 ;check for transparent bid
BNE 9$
CALL MSGGTC ;maybe - check for ENQ following
BCS 15$
CMPB #EBCEOT,R1 ;check for disconnect
BNE 10$ ;nope
8$: CALL RCVDSC ;record intent of other end to disconnect
CALL MSGGTE ;terminate msg
BR 14$
9$: CMPB #EBCSOH,R1 ;recvd soh?
BNE 15$ ;no, unrecognized response
CALL MSGGTC ;yes,get next char
BCS 15$ ;none
10$: CMPB #EBCENQ,R1 ;enq following soh or dle ?
BNE 15$ ;no, unrecognized response
CALL TENQ ;record this
CALL HSETCE ;communications established
CALL HSINIR ;yes, initialize message headers
BCS 14$ ;trouble transmitting ACK0
; here SOH-ENQ sequence has been received. an ACK0 has been sent.
; get ready to receive response
13$: CALL HSRECV ;go receive data
14$: JMP LINCTL ;when done check again
15$: CALL MSGGTT ;end message and wait the second
BR 20$ ;wait and wake up all xlate tasks
; here when we have data to send , bid for the line
16$: MOV LB.EQN(R4),LB.RTY(R4) ;no. of tries to get the line
18$: MOV #BIDMSG,R0 ;send soh-enq bid sequence
MOV #BIDLEN,R1 ;length of the bid sequence
CALL CTLMSG ;send as control msg
MOV LB.EQW(R4),LB.ALR(R4) ;time to wait for reply
CLR R4 ;no data yet
CALL MSGGTC ;get char from recver
BCS 21$ ;nothing recvd
CMPB #EBCDLE,R1 ;is it dle?
BNE 9$ ;no, check for soh-enq sequence
CALL MSGGTC ;get next char
BCS 21$ ;none
CALL CLRALR ;flush alarm now
CMPB #EBCEOT,R1 ;disconnect ?
BEQ 8$ ;yes
CMPB #EBCAK0,R1 ;is it ack0 after dle?
BNE 21$ ;no, unrecognized msg
CALL TACK0 ;yes - record it
CALL MSGGTE ;clear the receiver
CALL HSETCE ;communications established
BIC #TCDIDO,TCBSCF(R5) ;operation was receive
; here we have received acknowledgement for the bid
; the line is marked as bid complete and set to send messages
; after awakening allthe xlate device tasks
CALL HSINIT ;initialize bcb,fcs and mark line bid
19$: MOV TCLCB(R5),R4 ;point to lcb
CALL HSWALX ;awaken all translate tasks
CALL HPXMIT ;go transmit signon block
20$: MOV TCLCB(R5),R4 ;point to lcb
CALL HSWALX ;awaken all translate tasks
JMP LINCTL
; here when the response to bid is unrecognizable - finish waiting if
; necessary and bid again.
21$: CALL MSGGTT ;empty the receiver and wait
MOV TCLCB(R5),R4 ;point to lcb
CALL KOSHL ;check error status
BCS 25$
INC LB.OC8(R4) ;record unrecognizable bid response
BIT #TCOPR,TCFG2(R5) ;still want to bid for the line?
BEQ 20$ ;no.
22$: DEC LB.RTY(R4) ;yes, have we tried often enough?
BNE 18$ ;no, try again
25$: BIC #TCOPR,TCFG2(R5) ;yes, no longer bidding
BR 20$ ;awaken all xlate tasks
; this subroutine initializes bcb and fcs bytes besides clearing the receiver
; and marking line as bid complete.
HSINIT: BIC #TCOPR,TCFG2(R5) ;no longer bidding
BIS #TCOPG,TCFG2(R5) ;bid complete
CLR TCSDM(R5) ;initialize dev ptr
CLR TCDPG(R5) ;permission cell
CLR TCRQPT(R5) ;for sending req to hasp
MOV #200,TCTBCB(R5) ;initialize transmit block count
MOV #200,TCXBCB(R5) ;initialize receive block count
MOV #104301,TCTFCS(R5) ;initialize transmit fcs
MOV #104301,TCPFCS(R5) ;and prev fcs too
BIS #TCHGST,TCST2(R5) ;note that status is changed
CLC ;indicate success
RETURN
; this subroutine sends an ack0 and initializes BCB and FCS bytes
HSINIR: CALL MSGGTE ;clear the receiver
MOV #AK0MSG,R0 ;set up to send ack0
MOV #AK0LEN,R1
CALL CTLMSG ;send the conrol message
BIS #TCDIDO,TCBSCF(R5) ;last operation was xmit
CALL HSINIT ;initilize bcb and fcs
11$: RETURN
.SBTTL HSRECV - HASP...receive messages
HSRECV: CALL INFLO ;check on line flow control thresholds
BR HSPXM5 ;yes - go try to send something
.SBTTL HPXMIT - HASP...send messages or ACK0 if idle
HPXMIT: CALL HSCMDS ;data set ready?
BCS HSPXAB ;no, abort output
MOV TCLCB(R5),R4 ;point to lcb
BIT #LS.ENB,(R4) ;line disabled?
BEQ HSPXAB ;yes....gone
CLR TCCMA(R5) ;so we dont send it again
MOV LB.ERC(R4),LB.RTY(R4) ;retry count is 15.
BIC #LS.ERR,(R4) ;clear any previous errors
CALL HSGTMS ;get message to xmit (if any)
TST LB.MSG(R4) ;did we get a message
BNE HSPXM1 ;yes, start sending
HSPXM4: MOV #AK0MSG,R0 ;no, set up to send an ak0
MOV #AK0LEN,R1 ;length of ack0 msg
CALL CTLMSG ;send the ack0
BIS #TCDIDO,TCBSCF(R5) ;just did output
BR HSRECV ;start receiving now
; here with a message to be sent in LB.MSG
HSPXM1: MOV TCLCB(R5),R4 ;point to lcb for re-entry
MOV LB.MSG(R4),R0 ;point to message
BEQ HSPXM4 ;send ack0 if no message
MOV MSGLEN(R0),LB.ALR(R4) ;no more than one jiffie per char
ADD LB.CSD(R4),LB.ALR(R4) ;plus clear-to-send delay
CALL @T.WRT(R5) ;start sending message
BCS HSPXAB ;only fails for line disable or abort set
BIS #TCSTMS!TCDIDO,TCBSCF(R5) ;a message was sent, expect ack
CALL @T.RED(R5) ;setup to read response
DSCHED #EBALR!EBINTR ;wait for msg to go
BIT #LS.ERR,(R4) ;check for hard error wakeup
BNE 14$
BIT #EBINTR,TCWKEV(R5) ;timed out?
BNE HSRECV ;no, got an interrupt.
14$: CALL @T.KIL(R5) ;stop the transmitter [1(637)]
INC LB.TTO(R4) ;count transmitter timeouts
BIC #LS.ERR,(R4) ;clear error bit
CALL @T.RED(R5) ;reissue the read
DSCHED ,#10. ;displace timeouts...in case transmitter quit
;early in message
BR HSRECV ;and let the protocol handle the recovery
; here to terminate the message stream because
; the 10 requested termination, because of transmitter
; error or timeout or because the retry counter ran out.
HSPXAB: CALL HSETHA ;set h/w abort 3(015)
MOV TCLCB(R5),R4 ;point to lcb
CALL @T.KIL(R5) ;kill all dq/dup action
CALL CLRALR ;make sure alarm is flushed
CALL HSABTO ;flag output aborted.
CALL HSRLOM ;release all out going messages
CALL HSABTI ;inputs also
CALL HSRMRL ;release messages
RETURN
; here if the transmission of the data message was successful.
; here to receive data or response from hasp
HSPXM5:
MOV TCLCB(R5),R4 ;point to lcb
MOV LB.ERC(R4),LB.RTY(R4)
HSPXM2: CALL HSCMDS ;dsr on?
BCS HSPXAB ;no, abort input
MOV TCLCB(R5),R4 ;point to lcb
BIT #LS.ENB,(R4) ;line disabled?
BEQ HSPXAB ;yes, abort operation
BIC #LS.ERR,(R4) ;clear any previous errors
CALL HSARSP ;read and analyze response
MOV TCLCB(R5),R4 ;point to lcb
BIT #LF.HWA,LB.FGS(R4) ;h/w abort ? 3(015)
BNE 20$ ;yes, abort the streams 3(015)
;no 3(015)
ASL R0 ;no, for word pointer
11$: MOV 12$(R0),R2 ;get adr of response routine
JMP (R2) ;jump to the routine
; table of addresses of response routines
12$: .WORD 13$ ;R0=0, received an ACK0
.WORD 34$ ;R0=1, received good data
.WORD 16$ ;R0=2, received NAK
.WORD 18$ ;R0=3, BCC error in receive data
.WORD 17$ ;R0=4, unrecognized data
.WORD 23$ ;R0=5, BCB error in received data
.WORD 21$ ;R0=6, BCB error in xmit reported by hasp
.WORD 20$ ;R0=7, SOH-ENQ(BID) received - abort line
.WORD 40$ ;R0=8., failed to get chunks while building msg
; here when an ack0 is received
13$: BIT #FCSUNV,TCRFCS(R5)
BEQ 14$
TRACE TRCFLO,<(SP),R5,TCRFCS(R5)>
14$: BIC #FCSUNV,TCRFCS(R5);ACK0 => clear universal suspend
BIC #TCDSP,TCFG2(R5)
BIT #TCSTMS,TCBSCF(R5) ;was a message sent?
BEQ 15$ ;no, we must have sent an ack0
CALL HSMSAK ;yes, release message
JMP HPXMIT ;attempt to send another message without waitng
; here when line is idling, i,e recvd ack0 for ack0
; or when a wait to do after receive of data
15$: DSCHED #EBINTR!EBQCHK!EBQMSG,#JIFSEC ;wait for something to happen
JMP HPXMIT ;and think about it
; here when a message has been received correctly.
34$: BIT #20,TCRBCB(R5) ;was bcb for bypass?
BNE 36$ ;yes.
BIT #40,TCRBCB(R5) ;was it reset bcb?
BNE 36$ ;yes, note it was set to receive count in HSARSP
TST TCERB(R5) ;error in received bcb?
BNE 37$ ;yes, bypass inc of expected
INC TCXBCB(R5) ;expect this bcb for next
BR 36$ ;and use block as is
37$: SAVE R1 ;check for duplicate block
MOV TCERB(R5),R1 ;get error BCB
INC R1
BIC #20,R1 ;clear possible overflow
CMPB TCXBCB(R5),R1 ;was it ?
BNE 38$ ;no - continue with error
CLR TCERB(R5) ;yes - not an error
38$: RESTOR R1
36$: BIC #160,TCXBCB(R5) ;make it modulo 16
BIT #TCSTMS,TCBSCF(R5);was a message sent ?
BEQ 35$ ;no
CALL HSMSAK ;yes - release the message
35$: JMP HPXMIT ;attempt to send another message without waitng
; here when a nak is received
16$:
26$: DEC LB.RTY(R4) ;decrement retry count
BGT 27$
JMP HSPXAB ;tried enough, abort output
27$: JMP HSPXM1 ;send data again
; here when unrecognized data received.
17$: CALL TCRF ;record invalid reply
BR 19$ ;retry before giving up
; here when message received with bad bcc
18$: CALL HSRMRL ;release messages formed
19$: MOV TCLCB(R5),R4 ;point to lcb
DEC LB.RTY(R4) ;tried enough times?
BLE 20$ ;yes, abort input
40$: MOV #NAKMSG,TCCMA(R5) ;set up nak reply
MOV #NAKLEN,TCCMC(R5) ;length of message
JMP HSPXM2 ;try reading again
20$:
.IF NE,DEBUG
BIT #TRCABO,TRCHLT
BEQ 69$
STOPCD DBG
69$:
.ENDC ;.IF NE,DEBUG
INC LB.IC6(R4) ;count aborts
JMP HSPXAB ;flag streams aborted
; here when a bcb error has been reported by hasp
21$: INC LB.OC3(R4) ;count bcb errors on xmit
BR 26$ ;treat the bcb error as nak
23$: BR 18$ ;release messages and send nak
.SBTTL HSMSAK - HASP...process ACK of message sent
; this subroutine is called to process the acknowledgement
; received for a message sent. it frees the message
; and takes care of signon message acks also.
.ENABL LSB
HSMSAK: MOV TCLCB(R5),R4 ;point to lcb
MOV LB.MSG(R4),R0 ;point to message sent
BNE 10$
STOPCD BUG
10$: CALL FREMSG ;flush the garbage
CLR LB.MSG(R4) ;no longer a message to send
CALL TIACK ;record implicit ack
CLR TCERB(R5) ;clear any prev bcb error indicator
BIC #TCSTMS!TCDTMS,TCBSCF(R5) ;last message sent accounted for
BIT #TCHGST,TCST2(R5) ;are we in process of changing status?
BNE 68$
MOV TCTFCS(R5),TCPFCS(R5) ;make transmitted fcs as previous
68$: MOV R4,R1 ;keep r4 intact with lcb pointer
BIT #TCSONM,TCBSCF(R5) ;was the message a signon?
BEQ 11$ ;no.
BIC #TCSONM,TCBSCF(R5) ;signon accounted for
BIS #LF.SON,LB.FGS(R4) ;indicate signed on
MOV LB.TCD+6(R1),R1 ;point to card reader xlate tcb
BIC #TCOTC!TCDMP,TCFG1(R1) ;signon complete.
MOV #223,TCCTP(R1) ;restore original rcb
TRACE TRCLIN,<R5,JIFCLK>
SNTSON:
11$: RETURN
.DSABL LSB
.SBTTL HSGTMS - HASP...create transmission block
; this subroutine gets transmission block full of device
; messages (if any) or status, grant, or request messages.
; it looks for signon block and if found that goes as a
; lone block in the t.b..
HSGTMS: BIT #LF.SIM,LB.FGS(R4) ;check for sim line
BEQ 10$ ;if not, don't worry about signon
BIT #LF.SON,LB.FGS(R4) ;if so, ...worry!
BNE 10$ ;already signed on
CALL HSONB ;not signed on - wait patiently til we get a signon msg
BCS 11$ ;trouble in making t.b.
BR 12$ ; send it alone as a record
10$: CALL HSRQPT ;check request permission to xmit
CALL HSDPG ;check for any device permission granted
CALL HSMTBK ;make transmission block
BCC 13$ ;no errors in building t.b.
11$: CLR TCSTB(R5) ;out of chunks, can't send message
BR 13$ ;set up lb.msg also
12$: BIS #TCSONM,TCBSCF(R5) ;indicate signon being sent
13$: MOV TCLCB(R5),R4 ;point to lcb
MOV TCSTB(R5),LB.MSG(R4) ;set up t.b. adr
CLC ;indicate success
RETURN
.SBTTL HSRQPT - HASP...check for permission requests to send
; this subroutine checks for any requests for transmission
; to be sent to hasp. a request is never sent twice and
; for that a flag tcowr (output was requested) is set
; once the request is sent to hasp. this ensures all
; outstanding requests to go thru.
HSRQPT: MOV TCLCB(R5),R4 ;point to lcb
TST TCRQPT(R5) ;request already sitting there?
BNE 13$ ;yes, exit
MOV #1,R1 ;start with console output
11$: MOV TCLCB(R5),R2 ;point to lcb
ASL R1 ;dev no * 2
ADD R1,R2 ;add offset for the device
ASR R1 ;restore dev no
MOV LB.TCD(R2),R2 ;point to device's xlate tcb
BEQ 12$ ;just in case tcb pointer is wiped
BIT #TCOPR,TCFG2(R2) ;request outstanding?
BNE 14$ ;yes, check if request was sent
12$: INC R1 ;advance to next device
CMP R1,LB.NTC(R4) ;done with all devices?
BLOS 11$ ;no, loop for next device
CLR TCRQPT(R5) ;no request to send
13$: RETURN
14$: BIT #LF.SIM,LB.FGS(R4) ;sim mode?
BEQ 24$ ;no.
CMPB #222,TCCTP(R2) ;console out msg?
BNE 24$ ;no.
25$: BIS #TCOPG!TCORN,TCFG2(R2) ;set grant, permit run
BIC #TCOPR,TCFG2(R2) ;clear request bit
BR 12$ ;check for other devices
24$: CMPB #221,TCCTP(R2) ;output permission unneccessary if
BEQ 25$ ;operator display request (console output)
CMPB #RCBCTL,TCCTP(R2) ;check for signon
BNE 15$ ;its not
BIS #TCORN!TCOPG,TCFG2(R2) ;give it run and grant
BIC #TCOPR,TCFG2(R2) ;clear the request
RETURN ;dont set for signon
15$: BIT #TCOWR!TCOPG!TCORN,TCFG2(R2) ;was request sent before
;or already granted?
BNE 12$ ;yes, try next device
BIS #TCOWR,TCFG2(R2) ;request gone in the t.b.
MOV TCCTP(R2),TCRQPT(R5) ;save rcb for message building
INC TCCRQT(R2) ;count requests sent
RETURN
.SBTTL HSDPG - HASP...check for permission grants to send
; this subroutine checks for any permissions grants to be sent to hasp.
; rcb for the device is set in TCDPG offset in bsc tcb.
HSDPG: TST TCDPG(R5) ;pending permission?
BNE 13$ ;yes, exit
MOV #1,R1 ;start with console input
11$: MOV TCLCB(R5),R2 ;point to lcb
ASL R1 ;device no * 2
ADD R1,R2 ;get device's
ASR R1 ;restore dev no
MOV LB.TCD(R2),R2 ;translate tcb adr
BEQ 12$ ;just in case tcb pointer is wiped
BIT #TCIPG!TCIRN,TCFG2(R2) ;input permission granted?
BNE 14$ ;yes, check if request is on
12$: INC R1 ;move to next device
CMP R1,LB.NTC(R4) ;done with all the devices
BLOS 11$ ;no, loop for the next one
CLR TCDPG(R5) ;no permisssions to send
13$: RETURN
14$: BIT #TCIPH,TCFG1(R2) ;permission already sent?
BEQ 12$ ;yes, check next device
CALL HSUNSP ;unsuspend the device
MOV TCCTP(R2),TCDPG(R5) ;set rcb for the device
BIC #TCIPH,TCFG1(R2) ;input permission sent to hasp
RETURN
.SBTTL HSONB - HASP...build signon message to send to host
; here to build a signon block to be sent to host
HSONB: CLR TCSTB(R5) ;no signon to send yet
5$: MOV LB.LNU(R4),R1 ;get the line #
SWAB R1 ;put in left byte
ADD #RCBCTL,R1 ;make it signon i.d.
CALL DEQMID ;look for signon block
BCC 11$ ;found it
MOV #3,R1
CALL HSAWXL ;have to wait - wake cdr task
CALL 20$ ;check if all is ok
RETURN
20$: DSCHED #EBINTR!EBQMSG,#30.
CALL HSCMDS ;check modem status
BCS 10$ ;line went away
BIT #LS.ENB,(R4) ;check if whole world went to hell while
BEQ 10$ ; we were sawing logs
BIT #TCOAB!TCIAB,TCFG2(R5) ;line still up - check aborts
BNE 10$ ;yeeecchh!
CLC ;it all suc's
RETURN
10$: CALL HSETHA ;make sure whole world knows
CALL HSWALX ;death mode - wake everybody
SEC ;complain and allow further disintegration
RETURN
11$: MOV R0,-(SP) ;save message pointer for later 3(023)
MOV R0,-(SP) ;save message pointer
CALL MSGSUP ;set up transmission block
BCS 16$ ;out of chunks
MOV R0,TCSTB(R5) ;save pointer to t.b.
CALL MSGHDR ;set up BCB,FCS etc in t.b. header
BCS 16$ ;ran out of chunks in msghdr
MOV (SP)+,R4 ;message ptr in R4
MOV CHLEN(R4),R2 ;get bytes in current chunk
BEQ 12$ ;empty header
MOV MSGPTR(R4),R3 ;get ptr to 1st byte
BR 13$
12$: MOV (R4),R3 ;point to data chunk
BEQ 14$ ;end of message
MOV R3,R4 ;save chunk ptr for ref later
MOV CHLEN(R3),R2 ;length of data in chunk
BEQ 12$ ;empty chunk
ADD #CHDAT,R3 ;point to start of data
13$: MOVB (R3)+,R1 ;get with actual signon message from chunk
KGACUM R1 ;accumulate BCC
CALL MSGAPC ;append char to message
BCS 17$ ;out of chunks
SOB R2,13$ ;loop till done with chunk
BR 12$ ;get next chunk
14$: CLR R1 ;put a zero RCB to indicate EOB
KGACUM R1 ;accumulate RCB(0) IN BCC
CALL MSGAPC ;append the RCB (00)
BCS 17$ ;out of chunks
CALL HSTRL ;set trailer to message
BCS 17$ ;out of chunks
MOV TCLCB(R5),R4 ;point to lcb
DEC LB.MSC(R4) ;one less message to xmit
MOV (SP)+,R0 ;get message pointer 3(023)
CALL FREMSG ;flush the garbage
CLC ;indicate success
15$: RETURN
; OUT OF CHUNKS
16$: RESTOR R0 ;flush top msg ptr - 2 on stack here
17$: CALL 20$ ;ruminate awhile- 1 copy of msg ptr on stack here
RESTOR R0 ;get the msg ptr
BCC 11$ ;and try to build the transmission block again
25$: CALL FREMSG ;flush the message
SEC
RETURN
.SBTTL HSCDEF - HASP...check for dump or eof on output
; and when all messages are sent, indicates so to xlate
;
; Parameters: R0/xlate tcb
; R1/device id
; R4/lcb
; Returns: R0/transmission block ptr
; R4/message
HSCDEF: SAVE R3
MOV R0,R3 ;preserve the xlate tcb for awhile
CALL DEQMID ;get message for device, i.d in r1
;remember i.d. is in r1
BCC 12$ ;got a message
BIC #TCOTC,TCFG1(R3) ; last output to device done
11$: SEC ;indicate no messages for device
BR 30$
12$: DEC TCMSC(R3) ;count down messages to go for device
SAVE R1
MOV TCCTP(R3),R1 ;get device number
TST TCCHKQ(R3) ;any chunks queued to xlate task ?
BEQ 21$ ;no, check queued messages
25$: CALL HCLRAC ;yes, clear device active bit
BR 22$ ;restore registers and continue
21$: CALL HSETAC ;no, set the device active bit
22$: RESTOR R1
MOV R0,TCSDM(R5) ;ptr to device message saved
MOV R0,R4 ;return message here
MOV TCSTB(R5),R0 ;r0 must point to t.b. built
CLC ;indicate message found
30$: RESTOR R3
RETURN
.SBTTL HSMTBK - HASP...build transmission block from device msgs
; this subroutine makes a transmission block from different
; or same device records. the block may also contain
; request for device output permission as last record only
; or may have the last record as device permission granted
; for a request previously made. the devices are polled
; for data in the following priorities:
; console output, card reader, line printer and lastly
; card punch output (if any)
HSMTBK: CALL HSCDOT ;check for output data & make message
BCS 19$ ;out of chunks
MOV TCSTB(R5),R0 ;point to message t.b. if output to go
BNE 11$ ;yes, go set up header
CLC ;no, exit
19$: RETURN
11$: CALL MSGHDR ;set up bcb, fcs etc.
BCS 30$ ;out of chunks
MOV TCLCB(R5),R4 ;get line block [4(41)]
MOV LB.MBL(R4),TCSLFT(R5) ;store maximum block size [4(41)]
SUB MSGLEN(R0),TCSLFT(R5) ;minus what we just put in [4(41)]
SUB #5,TCSLFT(R5) ;minus room for trailer and BCC [4(41)]
;i.e. zero RCB, [DLE], ETB, BCC1, BCC2
TST TCERB(R5) ;any bcb errors in last receive?
BNE 23$ ;yes, make a complaint and send
TST TCDPG(R5) ;any dev grants to go
BNE 24$ ;send alone
TST TCRQPT(R5) ;any permissions to ask
BNE 24$ ;yes, send alone
CLR TCDTB(R5) ;no current device in t.b.
BIT #TCDSP,TCFG2(R5) ;output suspended?
BNE 23$ ;send requests only
24$: MOV TCSDM(R5),R4 ;any message left
BEQ 12$ ;none
MOV TCSTB(R5),R0 ;t.b. must be set up
25$: MOV CHLEN(R4),R2 ;get data amount in header
BEQ 14$ ;empty head
MOV MSGPTR(R4),R3 ;get ptr to 1st byte
BR 15$
12$: INC TCDTB(R5) ;start from console output
20$: MOV TCDTB(R5),R1 ;any messages for this device?
MOV TCLCB(R5),R4 ;point to lcb
CMP R1,LB.NTC(R4) ;done with all devices?
BHI 23$ ;yes, check for requests
CALL HSCKDO ;check device for output
;r0/device xlate tcb
BCS 12$ ;suspended or permission not granted
CALL HSCDEF ;check for device message
BCS 12$ ;none there
;r0/transmission block
;r4/message
CMP MSGLEN(R4),TCSLFT(R5) ;does this message fit in t.b.
BLE 25$ ;yes, put it in t.b.
23$: CALL HSCKRQ ;check for requests
30$: BCS 29$ ;out of chunks
RETURN
14$: MOV (R4),R3 ;point to data chunk
BEQ 17$ ;end of current device message
MOV R3,R4 ;save chunk ptr for looping over message
MOV CHLEN(R3),R2 ;length of data in this chunk
BEQ 14$ ;empty chunk
ADD #CHDAT,R3 ;point to start of data in chunk
;the following loop copies device message chunks into t.b.
15$: MOVB (R3)+,R1 ;get char from chunk
KGACUM R1 ;accumulate bcc
CALL HSCKTP ;check for transparent output
BCS 29$ ;out of chunks
16$: CALL MSGAPC ;append char to message
BCS 29$ ;out of chunks
SOB R2,15$ ;loop till done with the chunk
BR 14$ ;start with next chunk
; here on end-of-device message or end of record also
17$: MOV TCLCB(R5),R4 ;point to lcb
DEC LB.MSC(R4) ;one less message to send
BIS #TCDTMS,TCBSCF(R5) ;its a data message
MOV TCSDM(R5),R4 ;point to message just put in tb
SUB MSGLEN(R4),TCSLFT(R5) ;this much space left
SUB MSGLEN(R4),MSGSNL(R0) ;deplete syn count
MOV R4,R0 ;device message pointer in r0
CALL FREMSG ;flush the garbage
CLR TCSDM(R5) ;clear message pointer
MOV TCSTB(R5),R0 ;point back to message being formed
TST MSGSNL(R0) ;do we need to append a syn
BGT 20$ ;not yet, any more data for the device
BIT #TCTSP,TCFG1(R5) ;output transparent?
BEQ 18$ ;no, insert syn only
CMP TCSLFT(R5),#2 ;need at least two holes left
BLT 20$ ;can't oblige
MOV #EBCDLE,R1 ;insert dle-syn in transparency
CALL MSGAPC ;append to the message
BCS 29$ ;out of chunks
DEC TCSLFT(R5) ;one byte less space left
18$: CMP TCSLFT(R5),#1 ;need at least one holes left
BLT 20$ ;can't oblige
MOV #EBCSYN,R1 ; syn alone for non-transparent
CALL MSGAPC ;append to message
BCS 29$ ;out of chunks
DEC TCSLFT(R5) ;one byte less
MOV #SYNLEN,MSGSNL(R0) ;reset syn length counter
BR 20$ ;check for more data
; here if trouble building message
29$: STOPCD HSA ;trouble building message
; this subroutine checks for transparent mode on output
; and inserts dle before a data dle or syn for tranparency.
HSCKTP: MOV R1,-(SP) ;save r1, it has the original character
BIT #TCTSP,TCFG1(R5) ;output transparent?
BEQ 11$ ;no.
CMPB #EBCDLE,R1 ;a dle?
BNE 12$ ;no, check for syn
CALL MSGAPC ;append a dle before dle
BCS 13$ ;failure return
11$: MOV (SP)+,R1 ;restore r1, orignal char
CLC ;indicate success
RETURN
12$: CMPB #EBCSYN,R1 ;is it a syn?
BNE 11$ ;no, exit
MOV #EBCDLE,R1 ;append a dle
CALL MSGAPC ;before the syn
BCC 11$ ;for clean exit
13$: MOV (SP)+,R1 ;restore original char
SEC ;indicate failure
RETURN
; this subroutine checks if there is data to xmit
HSCDOT: TST TCERB(R5) ;any bcb errors in last receive?
BNE 14$ ;yes.
TST TCRQPT(R5) ;any request to go?
BNE 14$ ;yes, setup message
TST TCDPG(R5) ;any permission grants?
BNE 14$ ;yes, setup msg
BIT #TCDSP,TCFG2(R5) ;all output suspended ?
BNE 16$ ;yes. don't send any output
CLR TCDTB(R5) ;initialise device for t.b.
TST TCSDM(R5) ;any message left from last time
BNE 14$ ;lets get that out first
11$: INC TCDTB(R5) ;start with console
MOV TCLCB(R5),R4 ;point to lcb
CMPB TCDTB(R5),LB.NTC(R4) ;device # in limits
BLOS 12$ ;yes, check device for messages
BIT #LF.SIM,LB.FGS(R4) ; simulation mode ?
BEQ 19$ ;no,support, send message
;yes, check for signon
BIT #LF.SON,LB.FGS(R4) ;is the line signed on ?
BEQ 18$ ;no, don't send null message
19$: BIT #TCHGST,TCST2(R5) ;check if status of device changed
BEQ 16$ ; no change - continue
CALL 14$ ;send an fcs
BCS 15$ ;failed
BIC #TCHGST,TCST2(R5) ; status changed noticed
BR 13$ ;suc'd
18$:
;end of code to send a null message
16$: CLR TCSTB(R5) ;nothing to send
13$: CLC ;success
RETURN
12$: MOV TCDTB(R5),R1 ;device for t.b.
MOV TCLCB(R5),R4 ;get the lcb
CALL HSCKDO ;allowed to output?
;r0/device xlate tcb
BCS 11$ ;no, check next device
14$: CALL MSGSUP ;setup message
BCS 15$ ;failed
MOV R0,TCSTB(R5) ;point to t.b.
BR 13$ ;return
15$: SEC ;signal failure
RETURN
.SBTTL HSCKRQ - HASP...build permission requests and grants to send
; subroutine to check requests to be sent
; or any permission granted to be sent to hasp
HSCKRQ: MOV TCSTB(R5),R0 ;point to t.b. formed
CMP TCSLFT(R5),#3 ;room for request? [4(41)]
BLT 69$ ;no, just put in zero RCB [4(41)]
TST TCERB(R5) ;any bcb error to complain to remote?
BNE 21$ ;yes.
TST TCRQPT(R5) ;any request permission to go?
BEQ 15$ ;no, check for permission granted
MOVB #RCBRQP,R1 ;get rcb for request block
KGACUM R1 ;accumulate in bcc
CALL MSGAPC ;append to the message
BCS 14$ ;out of chunks
MOVB TCRQPT(R5),R1 ;device rcb goes into srcb place
CLR TCRQPT(R5) ;request taken care of
11$: MOV #3,R2 ;for scb and zero rcb
12$: KGACUM R1 ;accumulate srcb in bcc
CALL MSGAPC ;append char to message
BCS 14$ ;out of chunks
13$: CLR R1 ;zero byte for scb(eor) and rcb
SOB R2,12$ ;append them to end message
17$: CALL HSTRL ;set trailer for the message
BCS 14$ ;out of storage
CLC ;success
RETURN
14$: SEC ;signal failure
RETURN
; here for any permission grants to be sent
15$: TST TCDPG(R5) ;any grants to go
BNE 16$ ;yes, set up rcb and srcb in message
69$: CLR R1 ;clear for zero rcb
MOV #1,R2 ;put rcb(00) at end of data
BR 12$ ;to indicate end-of-block
16$: MOV #RCBPRG,R1 ;get rcb for permission grant
KGACUM R1 ;include in bcc
CALL MSGAPC ;append the rcb to message
BCS 14$ ;out of chunks
MOV TCDPG(R5),R1 ;set up srcb as the device's rcb
CLR TCDPG(R5) ;permission grant sent
BR 11$ ;set up the trailer also
; here for bcb error reporting to remote
21$: MOV #RCBCBE,R1 ;get rcb for bcb error
KGACUM R1 ;accumulate in bcc
CALL MSGAPC ;append to message
BCS 14$ ;out of chunks
MOV TCERB(R5),R1 ;set srcb to expected bcb count
BR 11$ ;put srcb and rcb(00)
.SBTTL HSTRL - HASP...build transmission block trailer
; here to set trailer DLE-ETB and crc and the pads at the end of the t.b.
HSTRL: MOV R4,-(SP) ;save r4
MOV TCLCB(R5),R4 ;point to lcb 4(026)
BIT #LF.TSP,LB.FGS(R4) ;output transparent? 4(026)
BEQ 11$ ;no, use etb 4(026)
MOV #EBCDLE,R1 ;yes, insert dle-etb 4(026)
CALL MSGAPC ;append the char to message 4(026)
BCS 13$ ;out of chunks 4(026)
11$: MOV #EBCETB,R1 ;now the etb
KGACUM R1 ;must be included in bcc
CALL MSGAPC ;append char to message
BCS 13$ ;out of chunks
CALL STOBCC ;append bcc
BCS 13$ ;out of chunks
CALL XLPADS ;append pads at the end
BCS 13$ ;out of chunks
CALL MSGAPE ;return unused chunks
MOV TCSTB(R5),LB.MSG(R4) ;point to message to be sent
CLC ;signal success
12$: MOV (SP)+,R4 ;restore r4
RETURN
13$: CLR LB.MSG(R4) ;signal failure
SEC ;indicate failure
BR 12$ ;and exit
.SBTTL MSGHDR - HASP...build a transmission block header
; to set up BCB, FCS etc.
MSGHDR: BIT #TCTSP,TCFG1(R5) ;output transparent?
BNE 15$ ;yes, then dont include stx
MOV #EBCSTX,R1 ;hasp needs stx in bcc
KGACUM R1 ;count in bcc
15$: TST TCERB(R5) ;bcb error to report?
BNE 13$ ;yes, set up different tbcb
MOV TCTBCB(R5),R1 ;get current bcb
KGACUM R1 ;include in bcc
CALL MSGAPC ;append bcb to message
BCS 11$ ;out of chunks
CMPB TCTBCB(R5),#BCBINI ;reset bcb?
BEQ 12$ ;yes, don't increment for next
INC TCTBCB(R5) ;block count for transmit
12$: BIC #160,TCTBCB(R5) ;make bcb modulo 16
14$: MOVB TCTFCS+1(R5),R1 ;get first fcs byte
KGACUM R1 ;include fcs byte in bcc
CALL MSGAPC ;append it to message
BCS 11$ ;out of chunks
MOVB TCTFCS(R5),R1 ;get second fcs byte to transmit
KGACUM R1 ;include in bcc
CALL MSGAPC ;append to message
;ret suc/fail from MSGAPC
11$: RETURN
13$: ;here for header to report bcb error
MOV TCRBCB(R5),R1 ;get recvd bcb
BIC #177760,R1 ;make count
ADD #220,R1 ;make bcb for bypass
MOV R1,TCPBCB(R5) ;keep track of this bcb sent
KGACUM R1 ;include in bcc
CALL MSGAPC ;and message to go
BCS 11$ ;exit with c set for error
BR 14$ ;join the main path
.SBTTL HSARSP - HASP...process received transmission block
; this module processes data received from hasp
; on return R0 = 0,1,2,3 or 4 depending on whether
; we received ACK0,DATA,NAK,status or unrecognized
; message block.
HSARSP: MOV TCLCB(R5),R4 ;no, point to lcb
CALL CLRALR ;clear any existing alarm
MOV TCCMA(R5),R0 ;any control message to send?
BEQ 11$ ;no, just issue a read
MOV TCCMC(R5),R1 ;yes, get address and count
9$: CALL CTLMSG ;send control message
CLR TCCMA(R5) ;dont send message twice
BIS #TCDIDO,TCBSCF(R5) ;last oper was xmit
11$: MOV #3*JIFSEC,LB.ALR(R4) ;set alarm - t.read called earlier
CLR R4 ;no data yet
BIC #TCDIDO,TCBSCF(R5) ;last operation was read
CALL MSGGTC ;get input character
BCS 5$ ;timeout
CALL CLRALR ;flush alarm
10$: CMPB #EBCSTX,R1 ;start of text?
BEQ 22$ ;yes.
CMPB #EBCDLE,R1 ;no, data link escape?
BEQ 14$ ;yes,ack0 or stx next
CMPB #EBCSOH,R1 ;soh?
BEQ 18$ ;possibly non-transparent data
CMPB #EBCNAK,R1 ;nak?
BEQ 17$ ;yes,process nak
CMPB #EBCENQ,R1 ;enq?
BNE 12$ ;no - not good stuff
CALL TENQ ;record this
BIT #LS.CTL,@TCLCB(R5) ;was last message a control msg?
BEQ 12$ ;no - cruftiness
CALL MSGGTE ;terminate this msg
MOV TCLCB(R5),R4 ;yes - send it again
DEC LB.RTY(R4) ;count these so we don't hang here
BLE 12$
;ignore retry limit - host must abort
8$: MOV LB.CMA(R4),R0 ;still ok - get the last control msg
MOV LB.CMC(R4),R1
BR 9$
5$: CALL KOSHL ;check error status
BCS 6$
CALL TTMO ;record time out
BR 6$
; here when received data is unrecognizable.
12$: CALL TCRF ;record it
6$: CALL HSRXPT ;release messages and return
RETURN ;returns R0/4
; here when DLE is recvd
14$: CALL MSGGTC ;get next char
BCS 5$ ;timeout
CMPB #EBCAK0,R1 ;ack0?
BEQ 16$ ;yes,process ack0
CMPB #EBCEOT,R1 ;dle-eot?
BEQ 29$ ;yes - other end is disconnecting
CMPB #EBCSTX,R1 ;is it transparent data?
BNE 12$ ;no, unrecognized data
BIS #TCITSP,TCBSCF(R5) ;yes, set transparency flag
BR 23$ ;receive meassge
; here to process receipt of an ack0
16$: CALL TACK0 ;record it
CALL MSGGTE ;clear the receiver
CLR R0 ;indicate received ack0
RETURN
;here when a nak is received.
17$: CALL TNAK ;record it
CALL MSGGTE ;end message
MOV #2,R0 ;indicate nak received
RETURN
; here when soh is received in non-transparent mode
18$: KGLOAD #0 ;initialize kg11-a
19$: CALL MSGGTC ;get next char
BCS 5$ ;timeout
KGACUM R1 ;accumulate in bcc
CMPB #EBCENQ,R1 ; is this a bid ??
BEQ 30$ ;yes - abort line immediately
CMPB #EBCSTX,R1 ;stx after soh?
BNE 12$ ;unrecognized seq 4(026)
BIC #TCITSP,TCBSCF(R5) ;non-transparent mode
21$: CALL HSRXPM ;get the received message
RETURN
22$: BIC #TCITSP,TCBSCF(R5) ;indicate non-transparent mode
23$: KGLOAD #0 ;initialize kg11-a
BR 21$ ;and receive message
29$: CALL RCVDSC ;record intent of other end to disconnect
BR 31$
30$: CALL TENQ ;record this
31$: CALL MSGGTE ;terminate reading
MOV #7,R0 ;;(040) unexpected bid sequence - abort line
TRACE TRCLIN,<(SP),R5,TCST2(R5)>
RETURN
.SBTTL HSRXPM - HASP...process received non-transparent block
; here for processing received data ( device request, permission
; grant, or data block )
HSRXPM: CLR TCRMSG(R5) ;initialize ptr to start of current messages
CLR TCCRCB(R5) ;& current received rcb
CLR TCSRCB(R5) ; and srcb
BIC #^C<TCHGST>,TCST2(R5);clear status except for status change bit
CLR TCERB(R5) ;clear any prev bcb error flag
; check the bcb received against expected
CALL HMSGTC ;get char from block
BCS 15$ ;timeout
MOVB R1,TCRBCB(R5) ;save received bcb
.IF NE,DEBUG
MOV TCXBCB(R5),R2 ;put expected bcb
SWAB R2 ;in left side
BISB R1,R2 ;and received in right bye
TRACE TRCBCB,R2 ;trace bcb expected,received
.ENDC ;.IF NE DEBUG
CMPB TCXBCB(R5),R1 ;bcb match?
BEQ 14$ ;yes.
TSTB R1 ;proper bcb (high order bit must be set)
BPL 13$ ;no, error
BIT #20,R1 ;ignore (bypass bcb check) bcb?
BNE 14$ ;yes, bypass checking
BIT #40,R1 ;reset bcb?
BNE 11$ ;yes.,put receive bcb in expected
MOV TCRBCB(R5),TCERB(R5) ;mark bcb error and save bcb
CALL TBCB ;record BCB error
BR 14$ ;proceed as normal bcb
13$: CALL TBCB ;record BCB error
CALL MSGGTT ;clear receiver after 2-sec wait
MOV #5,R0 ;bcb error in recvd data
RETURN
11$: BIC #160,R1 ;clear extra bits in bcb, other than count
MOVB R1,TCXBCB(R5) ;Store next expected BCB into task block
; now set up fcs (function control seq recd) from hasp
14$: CALL HSTFCB ;set fcs byte
15$: BCS HSRXTO ;timeout
HSRXP1: CALL HSTRCB ;set rcb and srcb bytes
BCS HSRXTO ;timeout
BIT #TCETB,TCST2(R5) ;received eob?
BEQ 11$ ;no.
CALL HSEOB ;received e-o-b.
RETURN
; check rcb for error, request or permission for device
11$: CMPB #220,TCCRCB(R5) ;request for device?
BEQ HSRQMS ;yes, process request message
12$:
CMPB #240,TCCRCB(R5) ;permission grant message?
BEQ HSRQMS ;yes, permission message
13$:
CMPB #340,TCCRCB(R5) ;bcb error reported by hasp?
BNE 14$ ;no
JMP HSETBC ;yes, error in last xmit
14$:
MOV TCRMSG(R5),R0 ;any messages formed yet?
BEQ 16$ ;no, start a new one
15$: CMPB TCCRCB(R5),MSGID(R0) ;message for current device?
BEQ 20$ ;yes
MOV MSGNXT(R0),R0 ;no, check next message in chain
BNE 15$ ;for match with device
16$: CALL GETMHD ;get a message header
BCC 19$ ;got one
17$: CALL HSRXPT ;terminate message and flush things
MOV #8.,R0 ;indicate chunk depletion
18$: RETURN
19$: MOV TCRCID(R5),MSGID(R0) ;put received i.d in message
MOV TCRMSG(R5),MSGNXT(R0) ;link message in chain
MOV R0,TCRMSG(R5) ;update current message ptr
BIT #TCITSP,TCBSCF(R5) ;input transparency?
BEQ 20$ ;no, normal mode
BIS #MSGTSP,MSGFGS(R0) ;flag message as transparent
20$: MOV TCCRCB(R5),R1 ;set up record header
CALL MSGAPC ;rcb at beginning of record
BCS HSRXET ;out of chunks
MOV TCSRCB(R5),R1 ;srcb also
CALL MSGAPC ;in message to xlate
BCS HSRXET ;out of chunks
CMPB #RCBCTL,TCCRCB(R5) ;is it a signon record?
BNE 21$
JMP HSRSON ;yes, received a signon
21$: CALL HMSGTC ;get first scb of the record
BCS HSRXTO ;timeout
CALL MSGAPC ;put char in message
BCS HSRXET ;out of chunks
TSTB R1 ;end-of-file (dataless record)
BNE 22$ ;get next char
BR HSRXP1 ;eof received
22$: CMPB #100, R1 ;is this a transmission abort scb ?
BEQ 21$ ;yes, get end of record (scb=0)
TSTB R1 ;no, check for legal scb
BMI 23$ ;legal scb?
25$: CALL MSGGTT ;terminate reading
JMP HSEOB1 ;give error return
23$: BIT #100,R1 ;dup string?
BEQ 30$ ;yes, get dup char
MOV R1,R2 ;get the scb char
BIC #177700,R2 ;get count of non-dup chars
BEQ 25$ ;zero count illegal
24$: CALL HMSGTC ;get char
BCS HSRXTO ;timeout
CALL MSGAPC ;put char in mesage to xlate
SOB R2,24$ ;loop for all char of string
BR 21$ ;get next scb
30$: BIT #40,R1 ;dup char blank?
BEQ 21$ ;yes, look for next scb
MOV #1,R2 ;get the non-blank char
BR 24$ ;put it in message being built
; here for error return
HSRXTO: CALL TTMO ;record time out
HSRXET: CALL HSRXPT ;receive timeout or out of chunks
RETURN
.SBTTL HSRQMS - HASP...process request for input permission
; here when hasp requested permission for (input) a device
HSRQMS: MOV TCSRCB(R5),R1 ;srcb has the rcb of the requested device
BIC #177770,R1 ;get the device # from rcb
MOV R4,-(SP) ;save r4
MOV TCLCB(R5),R4 ;point to the lcb
ASL R1 ;dev no * 2
MOV R1,R2 ;preserve dev no * 2 in r1
ADD R4,R2 ;point to the device's
MOV LB.TCD(R2),R2 ;translate tcb
CMPB #240,TCCRCB(R5) ;is it permission granted msg?
BEQ 11$ ;yes
BIT #TCIRN,TCFG2(R2) ; is input already running 3(024)
BEQ 5$ ; no, just continue 3(024)
BIS #TCIRH,TCFG1(R2) ; yes, set bit to remember it 3(024)
BR HSRQM1 ; and exit 3(024)
5$: ; new label 3(024)
BIS #TCIPH,TCFG1(R2) ;send reply when permission granted.
CALL HSDRIP ;request input permission
BR HSRQM1 ;check next character for rcb
11$: ASR R1 ;get back the device number
CMPB R1,LB.NTC(R4) ;if out of limit, check for rcb
BHI 20$ ;yes, its out of limits
CMPB TCSRCB(R5),TCCTP(R2) ;does it match the rcb?
BEQ 21$ ;yes.
20$: CLR R1 ;initialize device # for hunt
22$: INC R1 ;for match thru all devices
CMPB R1,LB.NTC(R4) ;within limits
BLOS 23$ ;its in limits
STOPCD HDO ;device out of limits
23$: MOV R1,R2 ;r1 has to be preserved
ASL R2 ;device # * 2
ADD R4,R2 ;point to device's xlate tcb
MOV LB.TCD(R2),R2
CMPB TCSRCB(R5),TCCTP(R2) ;match?
BNE 22$ ;no, loop till match found
21$: BIS #TCOPG!TCORN,TCFG2(R2) ;set output permission granted?
BIC #TCOPR!TCOWR!TCDSP,TCFG2(R2) ;no pending requests
SIGNAL R2,EBINTR ;signal interrupt condition to xlate
12$: INC TCCDPG(R2) ;count permissions recvd
HSRQM1: MOV (SP)+,R4 ;restore r4
HSRQM2: CALL HMSGTC ;get the scb(00) for eor
BCS HSRXTO ;timeout
TSTB R1 ;it must be zero scb
BNE 13$ ;its not, format error
JMP HSRXP1 ;yes, look at next rcb
13$:
.IF NE,DEBUG
BIT #TRCABO,TRCHLT
BEQ 69$
STOPCD DBG
69$:
.ENDC ;.IF NE,DEBUG
CALL MSGGTT ;clear receiver
CALL HSRMRL ;release received messages
MOV #5,R0 ;wrong data format received
RETURN
.SBTTL HSRSON - HASP...process received signon message
; here when received rcb indicates a signon record
HSRSON: TRACE TRCLIN,<R5,JIFCLK>
RCVSON: CALL HMSGTC ;get next character
BCS 11$ ;timeout
BIT #TCETB,TCST2(R5) ;did we receive etb?
BNE 20$ ;yes.
CALL MSGAPC ;append char to message
BCC HSRSON ;loop for next character
BR 15$
11$: CALL TTMO ;record time out
15$: CALL HSRXPT ;error return for timeout or out of chunks
RETURN
20$: CALL HSEOB ;process end of block
RETURN
; here when hasp reported a bcb error in xmit
HSETBC: MOV #240,TCTBCB(R5) ;send a reset bcb
BR HSRQM2 ;receive the rest of the message
.SBTTL HSEOB - HASP...end of received transmission BLOCK PROCESSING
; R3 = chars gotten from this chunk already
; R4 = pointer to current chunk (initially 0)
.ENABL LSB
HSEOB: CALL DQRBCC ;accumulate next two characters
BCC 10$
CALL TTMO ;record time out
CALL HSRXPT ;timeout
RETURN
10$: CALL MSGGTE ;terminate reading
KGTEST ;is bcc correct?
BNE 14$ ;no. got bcc error
MOV TCLCB(R5),R4 ;point to lcb
INC LB.IC1(R4) ;count blocks recvd successfully
MOV TCRMSG(R5),R0 ;yes, que messages formed (if any)
BEQ 13$ ;data-less message, must be status block
12$: MOV MSGID(R0),R1 ;get message i.d.
CMPB #RCBCTL,R1 ;signon record?
BNE 18$ ;no
MOV #3,R1 ;yes, que it up for card reader
18$: BIC #177770,R1 ;get device # from i.d.
.IF NE DEBUG
BNE 19$ ;halt only for zero dev
STOPCD DBG ;error from ibm
19$:
.ENDC ;.IF NE DEBUG
ASL R1 ;dev no * 2
MOV R1,R2 ;preserve r1
ADD R4,R2 ;point to device's
MOV LB.TCD(R2),R2 ;xlate tcb
CMPB #RCBCTL,MSGID(R0) ;if this is a signon record
BNE 23$
BIS #TCIRN,TCFG2(R2) ; set TCIRN so any fast device requests for
; cdr will be remembered instead of generating
; a permission grant immediately - note that
; this can happen before 10 gets around to
; issuing grant for the signon record and,
; since none was requested, things are unmatched
BR 24$
23$: BIT #TCIRN,TCFG2(R2); check if input already running
BNE 25$ ;yes - no need to drip
24$: CALL HSDRIP ;indicate input coming
25$:
SAVE R1 ;check for duplicate message
MOV TCERB(R5),R1 ;get the error BCB
BEQ 50$ ;no error
BIT #60,R1 ;was it an error because of reset or ignore BCB
BNE 50$ ;yes - all is kosher
INC R1 ;no -check for previous BCB
BIC #20,R1 ;flush overflow
CMPB TCXBCB(R5),R1 ;was it ?
BNE 50$ ;no - not a duplicate, must have skipped one
TRACE TRCLIN,<R5,R0,R1,R2>;trace BSC task,duplicate message,BCB,xlate task
RESTOR R1
MOV MSGNXT(R0),-(SP);save next msg in chain
16$: CALL FREMSG ;flush the garbage
BR 20$
50$: RESTOR R1
INC TCIMC(R2) ;one more message queued to xlate
CALL BSCFLO ;check flow control for BSC task
MOV MSGNXT(R0),-(SP) ;get next message in chain
MOV R2,R1 ;copy TCB into correct register for QUEMSG
SAVE R0
CALL CNTMSG ;find number of chunks in message
MOV TCLCB(R5),R4 ;make sure we have the lcb
ADD R0,LB.RES(R4) ;reserve this many for xlate
RESTOR R0
CALL QUEMSG ;que message for the devices translate task
20$:
MOV (SP)+,R0
BNE 12$ ;yes, que it
CLR TCRMSG(R5) ;clear message ptr
13$: CALL HSCHST ;check for status change
CLC ;indicate success
MOV #1,R0 ;indicate real data received
RETURN
; here for bcc error
14$: CALL TBCC ;record BCC error
.DSABL LSB
HSEOB1: MOV TCRMSG(R5),R0 ;any messages to release
BEQ HSEOB2 ;none left
15$: MOV MSGNXT(R0),-(SP) ;get next message to free
CALL FREMSG ;flush the garbage
MOV (SP)+,R0
BNE 15$ ;yes, loop till done
HSEOB2: CALL TBCC ;record bad BCC
CLR TCERB(R5) ;clear bad bcb indicator
CLR TCRMSG(R5) ;clear received message ptr
MOV #5,R0 ;indicate invalid data
RETURN
; here for error return on chunk depletion or timeout
HSRXPT:
;trace task,line sts,wake events,current receive block,current output msg
TRACE TRCLIN,<(SP),R5,@TCLCB(R5),TCWKEV(R5),R4,R0>
CALL MSGGTT ;clear receiver
CALL HSRMRL ;release messages formed
MOV TCLCB(R5),R4 ;point to lcb
INC LB.IC7(R4) ;count messages ignored
MOV #4,R0 ;unrecog messages
RETURN
; this subroutine gets a character from
; input and checks for DLE or SYN and excludes them from bcc
HMSGTC: CALL MSGGTC ;get character
BCS 15$ ;timeout
BIT #TCITSP,TCBSCF(R5) ;input transparent?
BEQ 10$ ;no - go check special characters
;yes - handle special characters different
CMPB #EBCDLE,R1 ;transparent mode - check for DLE
BNE 14$ ;its not a DLE so it can't be special
CALL MSGGTC ;look at char after DLE
BCS 15$ ;timeout
10$: CMPB #EBCSYN,R1 ;check for special characters
BEQ HMSGTC ;yes - flush it
CMPB #EBCETB,R1 ;received ETB?
BNE 14$ ;no
BIS #TCETB,TCST2(R5) ;mark ETB recvd
14$: KGACUM R1 ;include in bcc
CLC ;indicate success
15$: RETURN
.SBTTL HSTFCB - HASP...extract fcs from transmission block
; this subroutine sets the fcs from hasp
HSTFCB: CALL HMSGTC ;get fcs char
BCS 11$ ;timeout
MOVB R1,TCRFCS+1(R5) ;save fcs byte recd
CALL HMSGTC ;get next fcs byte
BCS 11$ ;none there
MOVB R1,TCRFCS(R5) ;save second byte of fcs
11$: RETURN
; this subroutine sets up the rcb and srcb
HSTRCB: CLR TCCRCB(R5) ;initialize recvd rcb
CLR TCSRCB(R5) ;initialize recvd srcb
CALL HMSGTC ;get rcb byte
BCS 12$ ;timeout
BIT #TCETB,TCST2(R5) ;ETB received?
BNE 12$ ;yes.
MOVB R1,TCCRCB(R5) ;save received rcb
BEQ 14$ ;EOB received
;4(031)- route control message to console in emulation
MOV R4, -(SP)
MOV TCLCB(R5), R4 ;point to lcb
BIC #177400, R1 ;clear junk
CMPB R1,#RCBCTL ;is it a signon ?
BNE 20$ ;no, treat normally
BIT #LF.SIM,LB.FGS(R4) ;yes, is it simulation mode ?
BEQ 20$ ;no, treat normally
MOVB #221,TCCRCB(R5) ;yes,save console in as current rcb
MOVB #221,R1 ;send message to console in
20$: MOV (SP)+,R4
;4(031)- end of code to route control message to console in emulation
CMPB R1,#220 ;check for legal rcb's
BHIS 11$
TRACE TRCLIN,<R5,2(SP),R1,TCRFCS(R5)> ;trace task,caller,rcb,fcs bytes
BR 1$
11$: BIC #177770,R1 ;find device type
MOV R1,TCRDVT(R5) ;save current device type
MOV R4,-(SP) ;save r4, it has ptr to rec chunk
MOV TCLCB(R5),R4 ;point to lcb
MOV LB.LNU(R4),R1 ;get line no. in left byte
SWAB R1
ADD TCCRCB(R5),R1 ;put rcb in right byte
MOV R1,TCRCID(R5) ;save current i.d. received
MOV (SP)+,R4 ;restore r4
CALL HMSGTC ;get srcb byte
BCS 12$ ;timeout
MOVB R1,TCSRCB(R5) ;save srcb received
12$: RETURN
14$: CALL HMSGTC ;get the next char
BCS 12$ ;timeout
BIT #TCETB,TCST2(R5) ;received ETB yet?
BNE 12$ ;yes.
TST R1 ;check for extra zero rcb's inserted by HARRIS 1600
BEQ 14$ ;ignore them
CMPB #128., R1 ;(025) is it a bcb ?
BNE 1$ ;(025) no, error
CALL HMSGTC ;(025) yes, read fcs byte #1
BCS 1$ ;(025) timeout, error
CALL HMSGTC ;(025) read fcs byte #2
BCS 1$ ;(025) timeout, error
CALL HMSGTC ;(025) look for etb
BCS 1$ ;(025) timeout, error
BIT #TCETB,TCST2(R5) ;(025) received etb yet?
BNE 12$ ;(025) yes.
1$: ;(025)
SEC ;indicate error
RETURN
.SBTTL HSCHST - HASP...process status block
; here for status block processing
HSCHST: MOV TCRFCS(R5),R1
MOV TCLCB(R5),R4 ;point to lcb
MOV R4,R2 ;save for ref
BIT #FCSUNV,R1 ;suspend all?
BEQ 11$ ;no, check for card reader
BIS #TCDSP,TCFG2(R5) ;set universal suspend bit
BR 12$ ;start checking devices
11$: BIC #TCDSP,TCFG2(R5) ;unsuspend system
12$: ;here to check card reader or lpt
ADD #6,R2 ;find device's
BIT #LF.SIM,LB.FGS(R4) ;simulate mode?
BNE 13$ ;yes, treat device as cdr
ADD #2,R2 ;lpt for support mode
13$: MOV LB.TCD(R2),R2 ;point to device's xlate tcb
BIT #FCSRD1,R1 ;device suspended?
BNE 14$ ;no.
BIS #TCDSP,TCFG2(R2) ;suspend the device
BR 15$ ;check next device
14$: BIC #TCDSP,TCFG2(R2) ;unsuspend device
15$: MOV R4,R2 ;get ptr to lcb
ADD #2,R2 ;point to device's
MOV LB.TCD(R2),R2 ;xlate tcb
BIT #FCSCSL,R1 ;console suspended?
BNE 16$ ;no
BIS #TCDSP,TCFG2(R2) ;suspend console output
BR 17$ ;check next device
16$: BIC #TCDSP,TCFG2(R2) ;unsuspend console
17$: MOV R4,R2 ;get ptr to lcb
ADD #12,R2 ;point to punch 4(027)
MOV LB.TCD(R2),R2 ;xlate tcb
BEQ 19$ ;jump if no punch
BIT #FCSPU1,R1 ;punch suspended?
BNE 18$ ;no
BIS #TCDSP,TCFG2(R2) ;suspend punch device
RETURN
18$: BIC #TCDSP,TCFG2(R2) ;unsuspend the device
19$: RETURN
.SBTTL HSDRIP - HASP...signal input permission request for device
; subroutine to request input permission.
; on entry R1= device number of the requested device * 2
; R2= device's xlate tcb ptr
; this subroutine is called by HSRXPM while processing
; the received record for device permission
;
; on return:
HSDRIP: BIS #TCIPR!TCIWR,TCFG2(R2) ;request input permission
ASR R1 ;get dev # back
CALL HSETAC ;set the active bit
MOV R4,-(SP) ;save r4
BIT #TCIOM,TCFG1(R2) ;device in input mode?
BNE 14$ ;yes.
STOPCD HSE ;asking input permission from output device
14$:
BIT #TCIPG!TCIRN,TCFG2(R2) ;permission granted?
BNE 13$ ;yes
; and note it was req. [2(770)]
CALL HSUSPD ;suspend device if not running
CALL HSAWXL ;wake up xlate task
13$: MOV (SP)+,R4
RETURN
.SBTTL HSUSPD,HSUNSP - HASP...device suspend/unsuspend
; subroutine to suspend a device when input permission refused
HSUSPD: MOV R2,-(SP)
MOV R3,-(SP)
MOV R5,R3 ;point R3 to calling tcb
MOV TCLCB(R3), R3 ;point to lcb
MOV LB.TC1(R3), R3 ;point to bsc tcb
ASL R1 ;dev no * 2
MOV SUSTBL(R1),R2 ;R1 has device # on entry
ASR R1
BIT R2,TCTFCS(R3) ;don't if already clear
BEQ 10$
BIC R2,TCTFCS(R3) ;suspend the device
BIS #TCHGST,TCST2(R3) ;indicate status changed
TRACE TRCFLO,<4(SP),R5,R1,TCTFCS(R5)>
10$: MOV (SP)+,R3
MOV (SP)+,R2
RETURN
SUSTBL: .WORD 0 ;start of suspend table
.WORD FCSCSL ;suspend console output
.WORD FCSCSL ;suspend console input
.WORD FCSRD1 ;suspend card reader
.WORD FCSPR1 ;suspend line printer
.WORD FCSPU1 ;suspend card punch
; this subroutine unsuspends a device when input permission
; is granted for that device
; R1=device #
HSUNSP: MOV R2,-(SP)
MOV R3,-(SP)
MOV R5, R3 ;point R3 to calling tcb
MOV TCLCB(R3), R3 ;point to lcb
MOV LB.TC1(R3), R3 ;point to bsc tcb
ASL R1 ;dev no * 2
MOV SUSTBL(R1),R2 ;get the unsuspend word for device
ASR R1
BIT R2,TCTFCS(R3) ;check if already done
BNE 10$ ; and don't do it again
BIS R2,TCTFCS(R3) ;unsuspend the device
BIS #TCHGST,TCST2(R3) ;indicate status changed
TRACE TRCFLO,<4(SP),R5,R1,TCTFCS(R5)>
10$: MOV (SP)+,R3
MOV (SP)+,R2
RETURN
.SBTTL HSABRO,HSABRI - HASP...device stream aborts
; this subroutine sets abort flag for a device stream.
HSABRO: ASL R1 ;r1 has dev no
MOV TCLCB(R5),R4 ;point to lcb
ADD R1,R4 ;device's xlate tcb
ASR R1 ;restore dev no
MOV LB.TCD(R4),R4 ;get pointer to
BEQ 12$ ;for missing tcb
BIT #TCIOM,TCFG1(R4) ;output dev?
BNE 12$ ;no.
BIS #TCOAB,TCFG2(R4) ;set abort flag
TRACE TRCABO,<(SP),R4>
.IF NE,DEBUG
BIT #TRCABO,TRCHLT
BEQ 69$
STOPCD DBG
69$:
.ENDC ;.IF NE,DEBUG
12$: RETURN
; this subroutine sets input abort flag for a device.
HSABRI: ASL R1 ;on entry r1 has dev no
MOV TCLCB(R5),R4 ;point to lcb
ADD R1,R4 ;get device's
ASR R1 ;get dev # back
MOV LB.TCD(R4),R4 ;point to xlate tcb
BEQ 12$ ;for missing tcb??
BIT #TCIOM,TCFG1(R4) ;input device?
BEQ 12$ ;no, exit
BIS #TCIAB,TCFG2(R4) ;set abort flag
TRACE TRCABO,<(SP),R4>
.IF NE,DEBUG
BIT #TRCABO,TRCHLT
BEQ 69$
STOPCD DBG
69$:
.ENDC ;.IF NE,DEBUG
12$: RETURN
; this subroutine sets abort for all output devices
HSABTO: MOV TCLCB(R5),R4 ;point to lcb
TRACE TRCABO,<(SP),R4>
MOV LB.NTC(R4),R1 ;get max device #
11$: CALL HSABRO ;abort the device
SOB R1,11$ ;all done
BIS #TCOAB,TCFG2(R5) ;set output abort started by bsc
MOV TCLCB(R5),R4 ;point to lcb
RETURN
; this subroutine sets abort for all input devices.
HSABTI: MOV TCLCB(R5),R4 ;point to lcb
TRACE TRCABO,<(SP),R4>
MOV LB.NTC(R4),R1 ;get max device #
11$: CALL HSABRI ;abort the device
SOB R1,11$ ;loop till all done
BIS #TCIAB,TCFG2(R5) ;set input abort started by bsc
MOV TCLCB(R5),R4 ;point to lcb
RETURN
.ENDC ;.IF NE,FT.HSP
.SBTTL BSCFLO,INFLO,OUTFLO - HASP...device/line flow control
;input flow control
.IF NE,FT.HSP
BSCFLO: ;check flow control thresholds for BSC task
; and suspend/unsuspend dev input appropriately
; R2/xlate tcb ptr
SAVE <R1>
MOV TCCTP(R2),R1 ;get the device type
BIC #177770,R1 ;isolate device number
CMP TCIMC(R2),#DSRFIT;check msgs queued to xlate for that stuffy feeling
BLT 10$ ;branch if not too full
CALL HSUSPD ;suspend the device
BR 20$
10$: CMP TCIMC(R2),#DHNGRY;not too full , check emptiness
BGT 20$ ;let it be
CALL HSUNSP ;unspend the device
20$: RESTOR <R1>
RETURN
.ENDC ;.IF NE,FT.HSP
.ENABL LSB
INFLO: SAVE <R0,R4> ;check line flow control thresholds
; and do universal suspend/unspend accordingly
MOV TCLCB(R5),R4 ;get the lcb
MOV LB.FRE(R4),R0 ;calc the available resources
SUB LB.RES(R4),R0
.IF EQ,FT.HSP
CMP R0,#CHDRTH ;have we plenty of chunks?
BLT 30$ ;no
.IFF
CMP #TTHASP,LB.DVT(R4) ;check if HASP device
BNE 29$ ;no - simple test
CMP R0,#CHDRTH ;have we plenty of chunks?
BGE 20$ ;yes
;no - shut off hasp input
; here to send a universal suspension to hasp
10$: BIT #FCSUNV,TCTFCS(R5) ;check if already suspended
BNE 35$ ;yes - don't bother
BIS #FCSUNV,TCTFCS(R5) ;set suspend
BIS #TCHGST,TCST2(R5) ;indicate status chnge
; here if there are enough chunks to receive data
20$:
CMP R0,#CHSRPL ;have we got enough to restart line
BLT 35$ ;let current state ride
BIT #FCSUNV,TCTFCS(R5) ; check if already clear
BEQ 25$ ;yes - don't do again
BIC #FCSUNV,TCTFCS(R5) ;unsuspend hasp data
BIS #TCHGST,TCST2(R5) ;set up to receive
.ENDC ;.IF EQ,FT.HSP
25$: ;on the input
.IF NE,FT.HSP
TRACE TRCFLO,<4(SP),R5,LB.FRE(R4),LB.RES(R4),TCTFCS(R5)>
.IFF
TRACE TRCFLO,<4(SP),R5,LB.FRE(R4),LB.RES(R4)>
.ENDC ;.IF NE,FT.HSP
INPON: CLC
BR 35$
.IF NE,FT.HSP
29$: CMP R0,#CHDRTH ;2780/3780 - plenty of chunks?
BGE 25$ ;yes
.ENDC ;.IF NE,FT.HSP
30$: ;off the input
.IF NE,FT.HSP
TRACE TRCFLO,<4(SP),R5,LB.FRE(R4),LB.RES(R4),TCTFCS(R5)>
.IFF
TRACE TRCFLO,<4(SP),R5,LB.FRE(R4),LB.RES(R4)>
.ENDC ;.IF NE,FT.HSP
INPOFF: SEC
35$: RESTOR <R4,R0> ;flush the resource calc
RETURN
.DSABL LSB
;output flow control
.ENABL LSB
OUTFLO: ;check if device is suspended for output
;R3/xlate tcb for device
SAVE <R1,R2,R4>
MOV TCLCB(R3),R4 ;get the line block
MOV LB.TC1(R4),R2 ;get the BSC task
BIT #TCDSP,TCFG2(R3) ;device output suspended ?
BNE 5$ ;yes - no need to look further
BIT #TCSTG,TCFG1(R3) ;is the xlate task suspended for storage?
.IF EQ,FT.HSP
BEQ 10$ ;if not, all is ok
.IFF
BNE 5$ ;if so, off the ten
CMP #TTHASP,LB.DVT(R4) ;check if HASP device
BNE 10$ ;no - just say ok
MOV LB.TC1(R4),R2 ;get the BSC task
MOV TCCTP(R3),R1 ;get the device type
CMP #360,R1 ;never suspended for signon device
BEQ 10$
BIC #177770,R1 ;isolate generic type
ASL R1 ;word offset
BIT SUSTBL(R1),TCRFCS(R2) ;check if we have received a device suspend
BEQ 5$ ;yes - answer "no!" to the burning question
BIT #FCSUNV,TCRFCS(R2) ;check universal suspend
BEQ 10$ ;no - all is go
.ENDC ;.IF EQ,FT.HSP
5$:
.IF NE,FT.HSP
TRACE TRCFLO,<6(SP),R5,LB.FRE(R4),LB.RES(R4),TCRFCS(R2)>
.IFF
TRACE TRCFLO,<6(SP),R5,LB.FRE(R4),LB.RES(R4)>
.ENDC ;.IF NE,FT.HSP
OUTOFF: SEC ;tell caller to go away
BR 15$
10$: MOV LB.FRE(R4),-(SP) ;calc the available resources
SUB LB.RES(R4),(SP)
.IF NE,FT.HSP
CMP #TTHASP,LB.DVT(R4) ;check if HASP device
BNE 11$ ;no - just say ok
CMP (SP)+,#HLDRTH ;have we plenty of chunks?
BLT 5$ ;no - off the ten
BR 12$ ;yes - on the ten
.ENDC ;.IF NE,FT.HSP
11$: CMP (SP)+,#XLDRTH ;have we plenty of chunks?
BLT 5$ ;no - off the ten
12$: ;the 10 should go on
.IF NE,FT.HSP
TRACE TRCFLO,<6(SP),R5,LB.FRE(R4),LB.RES(R4),TCRFCS(R2)>
.IFF
TRACE TRCFLO,<6(SP),R5,LB.FRE(R4),LB.RES(R4)>
.ENDC ;.IF NE,FT.HSP
OUTON: CLC ;tell caller it's ok to stuff it
15$: RESTOR <R4,R2,R1>
RETURN
.DSABL LSB
.SBTTL HSAWXL,POKBSC - task wakers
; subroutine to awaken the translate task
; r1 = has the device # whose xlate task needs to be awakened.
; r4 points to the lcb
.ENABL LSB
HSAWXL: SAVE R4
ADD R1,R4 ;point to specific device's
ADD R1,R4 ;point to specific device's
MOV LB.TCD(R4),R4 ;get adr of xlate tcb
10$: BEQ 12$ ;for missiing or released tcb's
SIGNAL R4,EBINTR ;signal interrupt condition to xlate task
12$: RESTOR R4
RETURN
;wake the BSC task
POKBSC: SAVE R4
MOV TCLCB(R5),R4 ;get the calling task's lcb
MOV LB.TC1(R4),R4 ;get the line's BSC task
BR 10$
.DSABL LSB
; this subroutine wakes up all device's xlate tasks
HSWALX: ;R4/lcb
MOV LB.NTC(R4),R1 ;max dev number
BEQ 11$ ;exit if zero tcbs
12$: CALL HSAWXL ;wake the xlate task
SOB R1,12$ ;loop for all devices
11$: RETURN
.SBTTL device active sets/clears
SACTO: ;set device active for 2780/3780 output
CALL ODEV ; get proper device code
BR HSACMP ; and set the bit
SACTI: CALL IDEV ;set device active for 2780/3780 input
BR HSACMP
CACTO: CALL ODEV ;clear device active for 2780/3780 output
BR HSAMPC
CACTI: CALL IDEV ;clear device active for 2780/3780 input
BR HSAMPC
ODEV: MOV TCLCB(R5),R1 ;set device code for 2780/3780 output direction
MOV LB.LNU(R1),R0 ;get line number
BIT #LF.SIM,LB.FGS(R1) ;simulation or support ?
BEQ 10$ ;support
MOV #3,R1 ;simulation, must be cdr
RETURN
10$: MOV #4,R1 ;support, must be lpt
RETURN
IDEV: MOV TCLCB(R5),R1 ;set device code for 2780/3780 input direction
MOV LB.LNU(R1),R0 ;get line number
BIT #LF.SIM,LB.FGS(R1) ;simulation or support ?
BEQ 10$ ;support
MOV #4,R1 ;simulation, must be lpt
RETURN
10$: MOV #3,R1 ;support, must be cdr
RETURN
; subroutine to set all the device active bits when a hardware abort occurs.
.ENABL LSB
HSTBTS:.IF NE,DEBUG
BIT #TRCABO,TRCHLT ;check for abort halt
BEQ 1$
STOPCD DBG
1$:
.ENDC ;.IF NE,DEBUG
SAVE R0
MOV #-1,-(SP) ;push active status
BR 20$
;this subroutine clears the device active bits on an abort or on a line disable
DABCLR: SAVE R0
CLR -(SP) ; push active status
20$: MOV TCLCB(R5),R0 ;point to lcb
MOV LB.LNU(R0),R0 ;get line number
BIC #177770,R0 ;clear junk
ASL R0 ;make even
ASL R0 ;point to first word of 2 word status
MOV (SP),D60ACT(R0) ;set active status bits
MOV (SP)+,D60ACT+2(R0) ;set active status bits
RESTOR R0
RETURN
.DSABL LSB
HSETAC: SAVE R0 ;set hasp device active
;r1/dev code
MOV TCLCB(R5),R0 ;get the lcb
MOV LB.LNU(R0),R0 ;but only to retrieve line number
CALL HSACMP ;set the bit
RESTOR R0
RETURN
HCLRAC: SAVE R0 ;clear hasp device active bit
;r1/dev code
MOV TCLCB(R5),R0 ;get the lcb
MOV LB.LNU(R0),R0 ;but only to retrieve line number
CALL HSAMPC ;clear the bit
RESTOR R0
RETURN
;the following routines set or clear the device and any device
;active bits.
;to clear a device active bit, the entry is: jsr pc, hsampc
;to set a device active bit, the entry is: jsr pc, hsacmp
;if no devices are active, the any device active bit is cleared
;on entry: r0 = the line number
; r1 = the device number
;this is the entry point to clear a device active
HSAMPC: SAVE <R0,R1,R2>
CALL HSACT ;find the bit and word
BIC R1,D60ACT(R0) ;clear the active bit
BR HSAXIT
;this is the entry point to set a device active
HSACMP: SAVE <R0,R1,R2>
CALL HSACT ;find the bit and word
BIS R1,D60ACT(R0) ;set the active bit
HSAXIT: RESTOR <R2,R1,R0>
RETURN
;convert line number to offset into status table
HSACT: BIC #177770,R0 ;clear junk
ASL R0 ;make line number even
ASL R0 ;point to first word of
;two word status
BIC #177400,R1 ;clear junk
MOV R1,R2 ;get device number
CMP #360,R2 ;is this a signon ?
BNE 20$ ;no, continue 3(014)
MOV #223,R2 ;yes, convert to cdr 3(014)
MOV R2,R1 ;convert to cdr 3(014)
20$:
BIC #177770,R2 ;get offset into device table
BEQ 21$ ;yes, error
ASL R2 ;make even
CMP R2,#12 ;is the device unknown ?
BLE 22$ ;no, continue
21$: STOPCD RNG ;out of range
22$:
JMP @HSASER-2(R2) ;set or clear the unit bit
;these are the handlers for the setting or clearing of a device active bit
;console out handler
HSCTYO: MOV #B7,R1 ;get unique unit bit
RETURN ;set in 1st word
;CONSOLE IN HANDLER
HSCTYI: MOV #B6,R1 ;get unique unit bit
RETURN ;set in 1st word
;CARD READER HANDLER
HSDCDR: CALL UDEV ;get unit bit
SWAB R1 ;left half of 1st word
RETURN ;set in 1st word
;LINE PRINTER HANDLER
HSDLPT: CALL UDEV ;get unit bit
BR HSCET2 ;right half of 2nd word
;card punch handler
HSDCDP: CALL UDEV ;get unit bit
SWAB R1 ;left half of 2nd word
HSCET2: INC R0 ;mask 2nd word
INC R0
RETURN
UDEV: SUB #220,R1 ;generate mask for unit
BMI 9$
ASR R1
ASR R1
ASR R1
ASR R1
CMP R1,#7 ;check range
BLE 10$
5$: STOPCD RNG ;bad news
9$: CLR R1 ;must be 2780/3780 device
10$: MOVB UTAB(R1),R1 ;get the mask
BIC #177400,R1 ;in case its the last one
RETURN
UTAB: .BYTE B0,B1,B2,B3,B4,B5,B6,B7
;dispatch table to device handlers for setting and clearing active bit
HSASER: .WORD HSCTYO ;console out
.WORD HSCTYI ;console in
.WORD HSDCDR ;card reader
.WORD HSDLPT ;line printer
.WORD HSDCDP ;card punch
.SBTTL test/set miscellaneous line conditions
; subroutine to indicate communications established
HSETCE: MOV R4,-(SP) ;save r4
MOV TCLCB(R5),R4 ;point to lcb
BIS #LF.CME,LB.FGS(R4) ;indicate communication established
MOV (SP)+,R4 ;restore r4
RETURN
; subroutine to set h/w abort
HSETHA: MOV R4,-(SP) ;save r4
MOV TCLCB(R5),R4 ;point to lcb
BIT #LS.ENB,(R4) ;if line was disabled - no hardware abort
BEQ 10$
BIS #LF.HWA,LB.FGS(R4) ;indicate a h/w abort
10$: CALL HSTBTS ;set all the active bits 3(017)
MOV (SP)+,R4 ;restore r4
RETURN
KOSHL: SAVE R4
MOV TCLCB(R5),R4
BIT #LS.ENB,(R4) ;check if all is kosher with line
BEQ 10$
CALL HSCMDS ;check if DSR is still up
BCS 10$ ;no - he gave up
BIT #TCIAB!TCOAB,TCFG2(R5)
BNE 10$
BIT #TCDIS,TCST2(R5)
BNE 10$
CLC ;all is ok
BR 15$
10$: TRACE TRCLIN,<2(SP),R4,(R4),TCFG2(R5),TCST2(R5)>
SEC
15$: RESTOR R4
RETURN
;the following subroutine checks the modem status
HSCMDS: SAVE <R0,R1>
MOV TCLCB(R5),R0 ;point to lcb
CLR R1 ;clear for status
CALL @T.DTS(R5) ;get modem status
BIT #B2,R1 ;data set ready?
BEQ 11$ ;no
BIT #B1,R1 ;DTR up?
BEQ 11$ ;no, set c
CLC ;indicate success, DSR on
BR 15$
11$: SEC ;no, set carry
15$: RESTOR <R1,R0>
RETURN
.SBTTL HSCKDO - check if device can do output
; this subroutine checks if the device is permitted to
; do output to hasp. if c set -- cannot output
;
; Parameters: R1/device number
; R4/LCB
;
; Returns: R0/device xlate tcb
; R1/id for device msg
HSCKDO: MOV R1,R0 ;for ref later
ASL R0
ADD R4,R0 ;get device's tcb adr
MOV LB.TCD(R0),R0 ;using device # in r1 as index
BEQ 12$ ;for non-existant xlate tcb
BIT #TCOAB!TCIAB,TCFG2(R0) ;device output or input aborted?
BNE 10$ ;no
11$: BIT #TCORN,TCFG2(R0) ;output permission granted?
BEQ 12$ ;no, can't do output
BIT #TCDSP, TCFG2(R0) ;device suspended ?
BNE 12$ ;yes, cannot do output
;no, set up for message
MOV LB.LNU(R4),R1 ;get line number
SWAB R1 ;put line # in left byte
ADD TCCTP(R0),R1 ;make i.d. for the device msg
CLC ;yes, all o.k for output
RETURN
10$: CALL HSDOAB
12$: SEC ;indicate cannot do output
RETURN
HSDOAB: SAVE R0 ;r0/xlate tcb
;r4/lcb
MOV LB.LNU(R4),R1 ;get line number
SWAB R1 ;in left byte
ADD TCCTP(R0),R1 ;make i.d. for the device message
SAVE R1
12$: CALL DEQMID ;is there a message for device?
BCS 13$ ;no message
14$: CALL FREMSG ;flush the garbage
mov (sp),r1 ;get the i.d.
BR 12$ ;check for more messages
13$: DSCHED #EBQMSG,#10.
MOV (SP),R1 ;get the i.d.
CALL DEQMID ;any messages for device
BCC 14$ ;yes, free them
16$: RESTOR R1
RESTOR R0
CLC
RETURN
.SBTTL miscellaneous cruft
; subroutine to release messages formed from current block
HSRMRL: MOV TCRMSG(R5),R0 ;any messages formed?
BEQ 12$ ;none
11$: MOV MSGNXT(R0),-(SP) ;get next message in chain
CALL FREMSG ;flush the garbage
MOV (SP)+,R0
BNE 11$ ;go release it
CLR TCRMSG(R5) ;clear so we dont release again
12$: RETURN
; this subroutine releases all outgoing messages if any
HSRLOM: MOV TCLCB(R5),R4 ;point to lcb
MOV LB.MSG(R4),R0 ;message to be released?
BEQ 11$ ;no, check for any device msg stuck
CALL FREMSG ;flush the garbage
CLR LB.MSG(R4) ;clear message ptr
11$: MOV TCSDM(R5),R0 ;any dev msg stuck in bsc
BEQ 12$ ;no, exit
CALL FREMSG ;flush the garbage
CLR TCSDM(R5) ;clear dev message ptr
12$: RETURN