Trailing-Edge
-
PDP-10 Archives
-
BB-P363B-SM_1985
-
mcb/drivers/kdpmcx.mac
There are no other files named kdpmcx.mac in the archive.
.TITLE KDPMC - COMMUNICATION IO PROCESSOR MICROCODE FOR THE DUP11
.IDENT /X1.4/
; FILE DUPEQU.MAC
;
; COPYRIGHT (c) 1980, 1981, 1982
; DIGITAL EQUIPMENT CORPORATION
; Maynard, Massachusetts
;
; 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.
;
; DISTRIBUTED SYSTEMS SOFTWARE ENGINEERING
;
; MODIFIED BY:
;
; SCOTT G. ROBINSON, 17-MAR-81 : VERSION X1.2
; - FIX HUNG DUP PROBLEMS IN XMTDON AND XMTABT
; - ENSURE PROPER HANDLING OF RTS FOR FULL DUPLEX MODE.
; - ENSURE BIT-STUFF MODE IDLE FLAGS (X.25 REQUIREMENT)
; ALAN D. PECKHAM, 4-MAR-82 : VARSION X1.3
; - MARK CHANGES MADE BY LAST FIX.
; - CHANGE HANDLING OF RTS INSTITUTED IN LAST FIX:
; AVOID TOGGLING RTS ONLY FOR NON-DEC MODE.
; ALAN D. PECKHAM, 4-MAY-82 : VARSION X1.4
; - FIX CONTROL-IN TO ACCEPT DUP MAINTENANCE MODE BITS A AND B
; IN BSEL7 BITS 2 AND 3. ISOLATE THESE BITS AND PLACE THEM
; IN DUP REGISTER XX5 INSTEAD OF CLEARING IT.
;
.SBTTL TABLE OFFSET DEFINITIONS
.NLIST CND
BIT0=1
BIT1=2
BIT2=4
BIT3=10
BIT4=20
BIT5=40
BIT6=100
BIT7=200
; RAM TABLE OFFSETS PER DDCMP/SDLC LINE
D.RSTR=0 ;TIMER RESTART VALUE
D.TIME=D.RSTR+1 ;TIMER VALUE
D.CSR=D.TIME+1 ;CSR ADDRESS (2 BYTES)
D.STS=D.CSR+2 ;STATUS
DS.CRI=BIT7 ;BIT STUFF CRC INHIBIT
DS.SLT=BIT7 ;DDCMP SELECT ON CURRENT MESSAGE
DS.QSC=BIT6 ;Q-SYNC BIT
DS.DEC=BIT5 ;DEC MODE
DS.IGN=BIT4 ;IGNORE CURRENT MESSAGE
DS.HDX=BIT3 ;HALF DUPLEX LINE
DS.SEC=BIT2 ;SECONDARY STATION
DS.DSR=BIT1 ;LAST STATE OF DATA SET READY
DS.NUM=BIT0 ;RECEIVING NUMBERED MESSAGE
D.RPTR=D.STS+1 ;RECEIVE STATE POINTER
D.SADR=D.RPTR+1 ;SECONDARY ADDRESS
D.DCC1=D.SADR+1 ;DDCMP DATA CHARACTER COUNT(LOW BYTE)
D.DCC2=D.DCC1+1 ;DDCMP DATA CHARACTER COUNT(HIGH BYTE)
; THE ABOVE TWO BYTES WILL BE USED AS THE LOCAL DELAY BUFFER FOR SDLC.
D.SILO=D.DCC1 ;TWO CHARACTER SDLC SILO
D.RDP=D.DCC2+1 ;CURRENT RECEIVE DESCRIPTOR POINTER (3 BYTES)
D.ARLP=D.RDP+3 ;ALTERNATE LINK POINTER (3 BYTES)
D.ORBC=D.ARLP+3 ;ORIGINAL RECEIVE BYTE COUNT (2 BYTES)
D.ORBA=D.ORBC+2 ;ORIGINAL RECEIVE CURRENT BUFFER ADDRESS (3 BYTES)
D.RBD=D.ORBA+3 ;CURRENT RECEIVE BUFFER DESCRIPTOR(5 BYTES)
D.RBDC=D.RBD ;CURRENT RECEIVE COUNTER
D.RBDA=D.RBDC+2 ;CURRENT RECEIVE BUFFER ADDRESS
D.RBDF=D.RBDA+2 ;FLAG BIT BYTE
DR.LST=BIT7 ;DESCRIPTOR IS LAST IN LIST
DR.ABA=BIT6 ;ALTERNATE BUFFER IS ASSIGNED
DR.CBA=BIT5 ;CURRENT BUFFER IS ASSIGNED
DR.17=BIT3 ;RCV ADDRESS BIT 17
DR.16=BIT2 ;RCV ADDRESS BIT 16
DR.FST=BIT0 ;FIRST CHARACTER IN CURRENT BUFFER
D.ERC=D.RBD+5 ;EVEN RECEIVE CHARACTER
D.XDP=D.ERC+1 ;CURRENT TRANSMIT DESCRIPTOR POINTER (3 BYTES)
D.AXLP=D.XDP+3 ;ALTERNATE TRANSMIT LINK POINTER (3 BYTES)
D.OXBC=D.AXLP+3 ;ORIGINAL TRANSMIT BYTE COUNT (2 BYTES)
D.DUMMY=D.OXBC+2 ;3 BYTES OF DUMMY DATA
D.XBD=D.DUMMY+3 ;CURRENT TRANSMIT BUFFER DESCRIPTOR (5 BYTES)
D.XBDC=D.XBD ;COUNT (LOW BYTE)
D.XBDA=D.XBDC+2 ;ADDRESS (LOW BYTE)
D.XBDF=D.XBDA+2 ;FLAG BITS BYTE
DX.LST=DR.LST ;DISCRIPTOR IS LAST IN LIST
DX.ABA=DR.ABA ;ALTERNATE XMT BUFFER ASSIGNED
DX.CBA=DR.CBA ;CURRENT XMT BUFFER ASSIGNED
DX.SYN=BIT4 ;SEND SYNCS
DX.17=BIT3 ;XMT ADDRESS BIT 17
DX.16=BIT2 ;XMT ADDRESS BIT 16
DX.EOM=BIT1 ;END OF MESSAGE
DX.SOM=BIT0 ;START OF MESSAGE
D.OXC=D.XBD+5 ;ODD TRANSMIT CHARACTER
D.SYNC=D.OXC+1 ;TRANSMIT SYNC COUNT
D.XSTS=D.SYNC+1 ;TRANSMIT STATUS FLAGS
DT.ABT=BIT0!BIT4 ;TRANSMIT ABORT PENDING
DT.AB1=BIT1 ;TRANSMIT ABORT STAGE 1 PENDING
D.LNG=60 ;LENGTH OF TABLE
; RAM OFFSET PER COMM IOP
P.MSTA=2000 ;LAST RAM LOCATION + 1
P.SLOT=P.MSTA-1 ;COMPLETION SILO NEXT OUT POINTER
P.SLIN=P.SLOT-1 ;COMPLETION SILO NEXT IN POINTER
P.PORT=P.SLIN-1 ;PORT SERVICE ROUTINE
P.PLST=P.PORT
SENTRY=6 ;SIZE OF A SILO ENTRY
NMSENT=29. ;NUMBER OF SILO ENTRIES
P.NPR=P.PLST-<SENTRY*NMSENT> ;COMPLETION SILO
SILOED=P.PLST-SENTRY ;LAST ENTRY IN SILO
P.LADR=P.NPR-<MAXDEV*2> ;TABLE OF LINE TABLE ADDRESSES
;
; SCRATCH PAD DEFINITIONS
;
SP.CHR=SP7 ;LOW BYTE OF DUP'S CSR2 (RECEIVE CHARACTER)
SP.RST=SP10 ;HIGH BYTE OF DUP'S CSR2 (RECEIVE CHARACTER STATUS)
SP.STS=SP11 ;COMM IOP STATUS REGISTER
SP.LN=SP12 ;COMM IOP LINE # CURRENTLY SELECTED
SP.RM0=SP13 ;RAM TABLE ADDRESS FOR CURRENT LINE - BITS 0-7
SP.RM1=SP14 ;RAM TABLE ADDRESS FOR CURRENT LINE - BITS 8&9
SP.SB1=SP15 ;SUBROUTINE RETURN ADDRESS (LEVEL B SUBROUTINES)
SP.SUB=SP16 ;SUBROUTINE RETURN ADDRESS (LEVEL A SUBROUTINES
SP.CS0=SP17 ;IMAGE OF CSR0 (LOW BYTE)
; DUP-11 INTERFACE RELATED EQUATES
; RECEIVE CONTROL AND STATUS REGISTERS (XX0)
; LOW BYTE
DUPDTR=BIT1 ;DATA TERMINAL READY
DUPRTS=BIT2 ;REQUEST TO SEND
DUPREN=BIT4 ;ENABLE RECEIVER
DUPRDN=BIT7 ;RECEIVE DONE
; HIGH BYTE
DUPSSY=BIT0 ;STRIP SYNC
DUPDSR=BIT1 ;DATA SET READY
;RECEIVE DATA BUFFER REGISTER -RXDBUF (XX2)
; HIGH BYTE
DUPRSM=BIT0 ;RECEIVE START OF MESSAGE
DUPREM=BIT1 ;RECEIVE END OF MESSAGE
DUPRAB=BIT2 ;RECEIVE ABORT
DUPCPE=BIT4 ;CRC/PARITY ERROR
DUPOVR=BIT6 ;OVERUN ERROR
DUPRE=BIT7 ;RECEIVE ERROR
;PARAMETER CONTROL AND STATUS REGISTER -PARCSR (XX2)
; HIGH BYTE
DUPCRI=BIT1 ;CRC INHIBIT
DUPSAM=BIT4 ;SECONDARY ADDRESS MODE
DUPDEC=BIT7 ;DEC MODE
;TRANSMIT CONTROL AND STAUS REGISTER-TXCSR (XX4)
; LOW BYTE
DUPHDX=BIT3 ;HALF DUPLEX MODE
DUPSND=BIT4 ;SEND
DUPTXD=BIT7 ;TRANSMIT DONE
; HIGH BYTE
DUPDR=BIT0 ;DEVICE RESET
;TRANSMIT DATA BUFFER REGISTER - TXDBUF (XX6)
; HIGH BYTE
DUPTSM=BIT0 ;TRANSMIT START OF MESSAGE
DUPTEM=BIT1 ;TRANSMIT END OF MESSAGE
DUPTAB=BIT2 ;TRANSMIT ABORT
;NPR CONTROL EQUATES
DATO=021 ;WORD OUT NPR
DATOB=221 ;BYTE OUT NPR
HLDBUS=002 ;HOLD BUS
;DDCMP EQUATES
SOH=201 ;START OF HEADER-NUMBERED MESSAGE
ENQ=005 ;ENQUIRY
DLE=220 ;DELETE-MAINTAINANCE MESSAGE
SYNC=226 ;SYNC CHARACTER
SYNCNT=7 ;NUMBER OF SYNC'S TO TRANSMIT
;CONTROL/BUFFER ADDRESS OUT PARAMETERS
C.BAOX=200 ;BA OUT FOR TRANSMIT OPERATION
C.BAOR=204 ;BA OUT FOR RECEIVE OPERATION
C.CLOX=201 ;CONTROL OUT FOR TRANSMIT OPERATION
C.CLOR=205 ;CONTROL OUT FOR RECEIVE OPERATION
EOM=20 ;END OF MESSAGE
;ERROR CODES
ER.ABO=6 ;RECEIVE ABORT (BIT STUFF)
ER.HBC=10 ;DDCMP HEADER BCC ERROR
ER.CRC=12 ;RECEIVE CRC ERROR
ER.NBA=14 ;NO BUFFER AVAILABLE (RECEIVE)
ER.DSR=16 ;DATA SET READY TRANSITION
ER.NXM=20 ;NON-EXISTENT MEMORY
ER.UNR=22 ;TRANSMIT UNDERRUN
ER.OVR=24 ;RECEIVE OVERRUN
ER.KIL=26 ;USER KILL
MAXDEV=16. ;MAXIMUM NUMBER OF DUP'S GEN'ED FOR
.PAGE
.SBTTL INIT - INITIALIZATION
; FILE IDLE.DUP
;+
; **INIT-INITIALIZATION ROUTINE**
;
; INPUTS:
; BRG = 0 (MASTER CLEAR)
; MAR = 0 (MASTER CLEAR)
; OUTPUTS:
; RAM IS CLEARED EXCEPT FOR THE COUNTERS IN THE POLLING LIST
; WHICH ARE SET TO MINUS ONE TO INDICATE NO ACTIVE DEVICES.
; THE ADDRESSES OF EACH LINE TABLE IS PUT IN A TABLE AT P.LADR
; THE CSR'S ARE ALSO CLEARED
;-
$KDPMC:: ;START OF CODE GLOBAL LABEL
INIT: OUT BR,SELB,OINCON ;ZERO THE INPUT CONTROL CSR
OUT BR,SELB,OOCON ;ZERO THE OUTPUT CONTROL CSR
SP BR,SELB,SP.RM1 ;CLEAR OUT RAM ADDRESS HIGH SCRATCH PAD
SP BR,SELB,SP.RM0 ;CLEAR LOW BYTE OF ADDRESS
SP BR,SELB,SP4 ;ZERO SP4
10$: MEMINC IMM,0 ;ZERO THE NEXT MEMORY LOCATION
SPBR IBUS,NPR,SP0 ;READ THE NPR CONTROL REGISTER
BRWRTE BR,ADD,SP0 ;SHIFT IT LEFT
BR7 20$ ;OVERFLOWED MAR TO 10 BITS - ALL DONE
ALWAYS 10$ ;KEEP ZEROING RAM
; MAR = 0 FROM OVERFLOW
20$:
BRWRTE IMM,MAXDEV*2 ;MAXIMUM NUMBER OF DEVICES GENED FOR TIMES 2
SP BR,SELB,SP5 ;SAVE IT IN A SCRATCH PAD
INIT1:
BRWRTE TWOA,SP4,INCMAR ;GET CURRENT LINE TIMES 2
SP BR,SELB,SP0 ;SAVE IT IN SP0
COMP BR,SP5 ;ARE WE FINISHED WITH ALL LINES
Z 40$ ;ALL DONE
SP INCA,SP4 ;ONE MORE LINE INITIALIZED
MEM IMM,377 ;INITIALIZE POLLING COUNTER TO MINUS ONE
BRWRTE IMM,P.LADR,LDMAPG ;LOAD THE BRG WITH THE ADDRESS OF
;THE LINE TABLE ADDRESS TABLE AND SET THE
;MAR HI TO THAT ADDRESS
LDMA BR,ADD,SP0 ;POINT TO THIS LINES ENTRY IN THE TABLE
MEMINC SELA,SP.RM0 ;SAVE THE LINE TABLE ADDRESS
MEM SELA,SP.RM1 ;LOW AND HI
ALWAYS NXTTBL ;"CALL" ROUTINE TO CALCULATE ADDRESS OF
;NEXT LINE'S TABLE (OFFSET BY D.TIME)
;RETURN MADE TO INIT1 WITH MAR&SP.RM0,1 SET
40$: LDMAP IMM,P.PORT ;LOAD MAR HIGH WITH ADDRESS OF PORT STATUS BYTE
LDMA IMM,P.PORT ;LOAD MAR LOW
MEMADR RDOSET,INCMAR ;ADDRESS OF ROUTINE TO CHECK FOR OUTPUT COMPLETIONS
MEMINC IMM,P.NPR ;INITIALIZE COMPLETION SILO IN POINTER
MEM IMM,377 ;INITIALIZE COMPLETION SILO OUT POINTER (LOGICAL ZERO)
;FALL INTO IDLE LOOP
.SBTTL IDLE - IDLE LOOP
;+
; **IDLE-LOOP BETWEEN PORT AND DEVICE SERVICE
;
; INPUTS:
; P.PORT = ADDRESS OF NEXT PORT SERVICE ROUTINE
;
; OUTPUTS:
; IF THE PGMCLK BIT IN THE MISC REG HAS EXPIRED,
; THE DEVICES ARE POLLED AND SERVICED BY THE TIMER ROUTINE
; IN ANY CASE, THE NEXT PORT ROUTINE IS BRANCHED TO.
;
; MAR = P.PORT
; ALL PORT ROUTINES RETURN TO IDLE
;-
IDLE: SPBR IBUS,UBBR,SP0 ;READ THE BUS REQUEST REGISTER AND
;STORE THE IMAGE IN SP0 AND THE BRG
BR4 TIMER ;BRANCH IF THE TIMER HAS EXPIRED
IDLE1: LDMA IMM,P.PORT ;LOAD MAR TO POINT TO PORT STATUS
LDMAP IMM,P.PORT ;LOAD MAR HIGH
.ALWAY MEMX,SELB,0 ;TIMER HAS NOT EXPIRED YET, CHECK THE
;DATA PORT TO SEE IF ANY PROCESSING IS REQUIRED
;RAM CONTAINS THE ADDRESS OF THE APPROPRIATE
;SERVICE ROUTINE
; RQISET --> WAITING FOR RQI TO SET
; RDICLR --> WAITING FOR RDYI TO CLEAR
; RDOSET --> WAITING FOR A COMPLETION
; RDOCLR --> WAITING FOR RDYO TO CLEAR
.SBTTL DATA PORT PROCESSING ROUTINES
;+
; **RDOCLR-WAITING FOR READY OUT TO BE CLEARED BY THE PDP-11**
;
; INPUTS:
; MAR = PORT SERVICE ROUTINE (P.PORT)
; OUTPUTS:
; THIS ROUTINE WAITS FOR READY OUT TO BE CLEARED BY THE PDP-11
; THUS SIGNALING IT IS DONE. IT ALSO CHECKS IF OUTPUT INTERRUPTS
; ARE REQUESTED IN THE MEANTIME AND WILL GENERATE ONE IF THEY WERE
; NOT REQUESTED WHEN RDYO WAS SET.
;
; WHEN RDYO IS CLEARED, CONTROL IS PASSED TO RQISET TO CHECK
; FOR PENDING PORT REQUESTS
;
; NOTE: THERE EXISTS THE POSSIBILITY OF AN INTERRUPT BEING GENERATED
; IF IEO IS CLEARED AT ANY TIME AFTER IT IS TESTED BY THE MICROPROCESSOR
; (APPROX A 1.5US WINDOW)
;-
RDOCLR:
BRWRTE IBUS,OCON ;READ CONTROL CSR BSEL2
BR7 RDOST1 ;READY OUT STILL SET, CHECK INTERRUPTS
;
; ENTER HERE IF AN OUTPUT INTERRUPT HAS ALREADY BEEN GENERATED
;
RDOCL1:
BRWRTE IBUS,OCON ;READ OUTPUT CONTROL CSR
BR7 IDLE ;READY OUT STILL SET
BRWRTE IMM,0 ;CLEAR OUTPT CONTROL CSR
OUT BR,SELB,OOCON ;..
MEMADR RQISET ;LOOK FOR RQI NEXT
ALWAYS IDLE ;BACK TO IDLE LOOP
;+
; **RDOSET-MICROPROCESSOR COMPLETION POSTING**
;
; INPUTS:
; MAR = PORT SERVICE ROUTINE (P.PORT)
; OUTPUTS:
; CHECK THE COMPLETION SILO TO SEE IF ANY COMPLETIONS ARE PENDING.
; IF THERE ARE POST THE COMPLETION TO THE PDP-11
; SILO POINTERS (P.SLOT,P.SLIN) ARE UPDATED
; AND WAIT FOR RDYO TO CLEAR (RDOCLR)
; OTHERWISE CHECK TO SEE IF THE PDP-11 HAS ANY INPUT DATA (RQISET)
;-
RDOSET:
MEMADR RQISET ;LOOK FOR RQI NEXT
LDMA IMM,P.SLOT ;SET MAR TO COMPLETION SILO NEXT OUT POINTER
LDMA MEMX,SELB ;POINT COMPLETION TO NEXT OUT ENTRY
Z IDLE ;THE POINTER IS ZERO THEREFORE THE SILO IS EMPTY
; A COMPLETION OUTPUT IS PENDING IN THE COMPLETION SILO. MAR POINTS TO THE
; NEXT ENTRY
OUT MEMI,SELB,OLINEN ;WRITE THE LINE NUMBER BYTE
; READ THE SECOND WORD OF THE COMPLETION SILO AND SET UP CSR 4
OUT MEMI,SELB,OPORT1 ;WRITE PORT BYTE 1
OUT MEMI,SELB,OPORT2 ;AND PORT BYTE 2
; READ THE THIRD WORD OF THE COMPLETION SILO AND SET UP CSR 6
OUT MEMI,SELB,OPORT3 ;WRITE PORT BYTE 3
OUT MEMI,SELB,OPORT4 ;AND PORT BYTE 4
OUT MEMI,SELB,OOCON ;WRITE THE NEW OUTPUT CNTRL CSR
; INCREMENT THE SILO NEXT OUT POINTER
LDMA IMM,P.SLIN ;SET MAR TO POINT TO COMPLETION SILO NEXT IN OFFSET
SP MEMI,SELB,SP1 ;SAVE THE NEXT IN POINTER IN SP1
SP MEMX,SELB,SP0 ;SAVE THE NEXT OUT POINTER IN SP0
MEM IMM,P.NPR ;ASSUME THE SILO IS GOING TO WRAP AROUND
BRWRTE IMM,SILOED ;OFFSET TO LAST SILO ENTRY
COMP BR,SP0 ;COMPARE CURRENT OUT POINTER WITH END OF SILO
Z 50$ ;IT WRAPPED AROUND - ALREADY SET UP
BRWRTE IMM,SENTRY ;GET THE SIZE OF A SILO ENTRY
MEM BR,ADD,SP0 ;INCREMENT NEXT OUT POINTER AND SAVE IT
; IF SILO IS NOW EMPTY "ZERO" THE NEXT OUT POINTER
50$: COMP MEMX,SP1 ;COMPARE OUT POINTER TO IN POINTER
Z 70$ ;THEY ARE THE SAME
ALWAYS 80$ ;THEY ARE DIFFERENT
70$: MEM IMM,377 ;THE SILO IS EMPTY - SET NEXT OUT POINTER
;TO A LOGICAL ZERO (-1)
80$: LDMA IMM,P.PORT ;SET MAR TO POINT TO PORT STATUS
RDOST1:
SPBR IBUS,INCON,SP0 ;READ INPUT CONTROL CSR
BR4 RDOST2 ;OUTPUT INTERRUPT REQUESTED
MEMADR RDOCLR ;STATE TO WAITING FOR READY OUT CLEARING
ALWAYS IDLE ;BACK TO IDLE LOOP
RDOST2: MEMADR RDOCL1 ;STATE TO WAITING FOR READY OUT CLEARING
BRWRTE IMM,300 ;MASK FOR BUS REQUEST AND XX4
RDOST3: OUT BR,SELB,OBR ;GENERATE AN INTERRUPT
ALWAYS IDLE ;BACK TO IDLE LOOP
;+
; **RQISET-REQUEST IN SET, THE PDP-11 HAS REQUESTED THE DATA PORTS
;
; INPUTS:
; MAR = PORT SERVICE ROUTINE (P.PORT)
; OUTPUTS:
; CHECK TO SEE IF REQUEST IN HAS BEEN SET BY THE PDP-11. IF SO,
; SET READY IN AND LET THE PDP-11 SET UP A COMMAND IN THE DATA PORTS
; IF INPUT INTERRUPTS ARE REQUESTED, GENERATE ONE
; TRANSFER CONTROL TO RDICLR TO WAIT UNTIL THE PDP-11 IS DONE
;-
RQISET: BRWRTE IBUS,INCON ;READ INPUT CONTROL CSR
BR7 10$ ;REQUEST IN SET
ALWAYS RDOSET ;SEE IF ANY COMPLETIONS TO POST
10$: SP IMM,20,SP0 ;MASK TO SET READY IN
OUT SELA,OOCON ;SET IN OUPUT CONTROL CSR
BR0 RQIST1 ;INTERRUPT ENABLE IS SET
MEMADR RDICLR ;STATE TO WAITING FOR RDYI TO CLEAR
ALWAYS IDLE ;BACK TO IDLE LOOP
RQIST1: MEMADR RDICL1 ;STATE TO WAITING FOR RDYI TO CLEAR
BRWRTE IMM,200 ;MASK FOR BUS REQUEST AND XX0
ALWAYS RDOST3 ;GENERATE AN INTERRUPT
;+
; **RDICLR-WAIT FOR READY IN TO CLEAR (DATA PORTS HAVE BEEN SET UP)**
;
; INPUTS:
; MAR = PORT SERVICE ROUTINE (P.PORT)
; OUTPUTS:
; CHECK TO SEE IF THE PDP-11 HAS CLEARED READY IN SIGNIFYING
; THAT IT HAS SET UP THE DATA PORTS. IF SO THEN DISPATCH TO THE
; PROPER ROUTINE TO HANDLE THE REQUEST BASED ON
; BIT 0&1 OF THE CONTROL CSR BSEL2
;-
; RDYI CLEAR ROUTINE IS ENTERED HERE IF INTERRUPT ENABLE WAS NOT
; SET WHEN THE COMMIOP SET READY IN. IF IN THE MEANTIME INTERRUPT ENABLE
; WAS SET, IT WILL BE SEEN HERE AND AN INTERRUPT WILL BE GENERATED
.ENABL LSB
RDICLR:
BRWRTE IBUS,OCON ;READ OUTPUT CONTROL CSR
BR4 5$ ;READY IN STILL SET
ALWAYS 10$ ;PDP-11 CLEARED RDYI. DONT BOTHER
;CHECKING FOR IEI JUST PROCESS THE DATA
5$: BRWRTE IBUS,INCON ;READ CONTROL CSR
BR0 RQIST1 ;INTERRUPT REQUESTED
RDICL1:
BRWRTE IBUS,OCON ;READ OUTPUT CONTROL CSR
BR4 IDLE ;RDYI STILL SET
10$: MEMADR RDOSET ;STATE TO WAIT FOR COMPLETIONS
; READY IN CLEAR
BRWRTE IMM,P.LADR ;GET ADDRESS OF LINE TABLE ADDR TABLE
SP BR,SELB,SP5 ;SAVE IT IN SP5
SP IBUS,LINENM,SP.LN ;READ THE LINE NUMBER
BRWRTE BR,TWOA,SP.LN ;MULTIPY IT BY TWO
LDMA BR,ADD,SP5 ;POINT TO ENTRY IN TABLE FOR THIS LINE
SP MEMI,SELB,SP.RM0 ;GET THE ADDRESS OF THIS LINE'S TABLE
;(LOW) AND SAVE IT IN SP.RM0
SP MEMX,SELB,SP.RM1,LDMAPG ;GET THE ADDRESS (HIGH) AND POINT
;THE MAR HI TO THIS ADDRESS
LDMA SELA,SP.RM0 ;SET MAR LOW
15$:
BRWRTE IMM,14,INCMAR ;SET UP DUP CSR BY SETTING ADDR BITS 16-17
OUT BR,SELB,OBR,INCMAR ;WRITE EXTENDED MEM BITS FOR OUT NPR
OUTPUT MEMI,SELB,OBA1 ;WRITE OUT LOW BYTE OF CSR ADDRESS
OUTPUT MEMI,SELB,OBA2 ;WRITE OUT HIGH BYTE
LDMA SELA,SP.RM0 ;POINT BACK TO START OF LINE TABLE
;REGISTERS FOR COMMAND ROUTINES
; MAR=LINE TABLE SP.LN=LINE NUMBER
; SP.RM0,1=LINE TABLE ADDR
; NPR OUTPUT ADDR=DEVICE CSR 0
BRWRTE IBUS,OCON ;GET ORIGINAL IMAGE OF INPUT CONTROL CSR
;READ FROM BSEL2 TO AVOID RAM BIT SET PROBLEM
;BY THIS TIME ALL BITS WILL HAVE SETTLED
BR1 20$ ;BIT 1 SET
BR0 CONIN ;BIT 1=0 AND BIT 0=1 -> CONTROL IN REQUEST
ALWAYS BAIN ;BIT 0&1=0 -> BUFFER ADDRESS IN REQUEST
20$: BR0 BASEIN ;BIT 1=1 BIT 0=1 -> BASE IN REQUEST
;BIT 1=1 BIT 0=0 -> ILLEGAL REQUEST
.DSABL LSB
; ABOVE THREE ROUTINES RETURN HERE AFTER REQUEST HAS BEEN PROCESSED
RQICL2: BRWRTE IMM,0 ;CLEAR OUT CONTROL CSR
OUT BR,SELB,OOCON ;..
SPBR IBUS,UBBR,SP0 ;READ THE MISC REGISTER
BR0 NXMERR ;IF BIT 0 SET, THEN A NON-EXISTENT MEMORY
;ERROR OCCURRED, REPORT IT.
ALWAYS IDLE ;OTHERWISE, BACK TO IDLE LOOP
.SBTTL TIMER - TIMER SERVICE
;+
; **TIMER-TIMER SERVICE ROUTINE**
;
; INPUTS:
; BRG & SP0 = IMAGE OF BUS REQUEST REGISTER
;
; OUTPUTS:
; EACH DEVICES TIMER COUNTER IS DECREMENTED AND TESTED FOR
; AN EXPIRATION. IF THE COUNTER WENT TO ZERO THE DEVICE
; IS POLLED TO SEE IF IT HAS A TRANSMIT DONE OR A RECEIVE DONE
; AND IF SO IT IS SERVICED. IF NONE OF THE DEVICES REQUIRES
; SERVICING THE MODEM TIMER IS DECREMENTED AND IF IT EXPIRED
; MODEM CHANGES ARE CHECKED.
; WHEN A DEVICE DONE SERVICE ROUTINE IS FINISHED THIS ROUTINE
; CONTINUES WITH THE NEXT DEVICE.
;-
.ENABL LSB
TIMER: BRWRTE IMM,121 ;MASK TO CLEAR ALL BUT TIMER, XX4 AND NXM
;N.B. THE TIMER WILL ALREADY BE SET TO ONE
;FROM IT EXPIRING SO THE MASK IS GUARANTEED
;TO LEAVE IT A ONE FOR RESETTING
OUT BR,AANDB,OBR ;AND THE MASK WITH THE PREVIOUS CONTENTS OF
;THE BUS REQUEST REGISTER RESETING THE
;TIMER
BRWRTE IMM,0 ;ZERO THE BRG
SP BR,SELB,SP.LN ;START WITH LINE ZERO
SP BR,SELB,SP.RM0,LDMAR ;SAVE THE ADDRESS IN RAM ADDRESS SCRATCH PAD
SP BR,SELB,SP.RM1,LDMAPG ;INITIALIZE SCRATCH PAD WITH THE HIGH BITS
ALWAYS TIMRT1 ;START POLLING
; MAIN POLLING LOOP
; RECEIVE DONE ROUTINES RETURN HERE
TIMRTN:
10$:
SPBR IBUS,UBBR,SP0 ;READ THE MISC. REGISTER
BR0 NXMERR ;NXM ERROR OCCURRED DURING LAST POLL
SP BR,INCA,SP.LN ;ONE LESS DEVICE TO POLL
BRWRTE IMM,MAXDEV ;CHECK TO SEE IF LAST DEVICE
COMP BR,SP.LN ;HAS BEEN POLLED
Z IDLE1 ;ALL DONE - BACK TO IDLE LOOP
BRWRTE IMM,P.LADR,LDMAPG ;GET STARTING ADDRESS FOR TABLE
;OF LINE TABLE ADDRESSES AND SET MAR HI
SP BR,SELB,SP0 ;SAVE IT IN SP0
BRWRTE BR,TWOA,SP.LN ;MAKE LINE NUMBER A DOUBLE BYTE INDEX
LDMA BR,ADD,SP0 ;SET ADDRESS FOR ENTRY OF THIS LINE
SP MEMI,SELB,SP.RM0 ;SAVE ADDRESS FOR THIS LINE
SP MEMX,SELB,SP.RM1,LDMAPG ;HIGH 2 BITS AND LOAD MAR HI
LDMA BR,SELA,SP.RM0 ;LOAD MAR LOW
TIMRT1:
BRWRTE MEMI,SELB ;SAVE THE RESTART VALUE IN THE BRG
;AND INCREMENT THE MAR
;IN CASE THE TIMER EXPIRED
SP MEMX,SELB,SP0 ;READ THE COUNTER FOR THIS DEVICE
Z 10$ ;THE DEVICE IS NOT ACTIVE
MEM BR,DECA,SP0 ;DECREMENT THE COUNTER AND WRITE IT
;BACK TO MEMORY
C 10$ ;LOOK AT THE NEXT DEVICE'S COUNTER
; TIMER HAS EXPIRED - SEE IF THERE ARE ANY "DONES" PENDING
; INPUTS:
; BRG = RESET VALUE
30$: MEMINC BR,SELB ;RESET THE COUNTER TO THE INITIAL VALUE
OUTPUT MEMI,SELB,IBA1 ;STORE THE LOW BYTE OF THE DEVICES
;CSR INTO THE LOW BYTE OF THE INPUT BUFFER
;ADDRESS REGISTER
OUTPUT MEMI,SELB,IBA2 ;DO THE SAME WITH THE HIGH BYTE
;AND INCRMENT THE MAR TO STATUS BYTE
BRWRTE IMM,14!DATI ;MASK TO SET EXTENDED MEMORY BITS
; DO AN INPUT NPR
OUT BR,SELB,ONPR ;START THE NPR
SP MEMX,SELB,SP.STS ;SAVE THE STATUS BYTE IN SP.STS
40$: BRWRTE IBUS,NPR ;READ THE NPR REQUEST REGISTER
BR0 40$ ;WAIT FOR THE NPR TO COMPLETE
SPBR IBUS,INDAT2,SP1 ;READ THE HIGH BYTE OF CSR 0
;SAVE IT IN SP1 FOR XMTDON
BRWRTE BR,AXORB,SP.STS ;SEE IF ANY CHANGE IN THE DSR STATE
BR1 DSRCHG ;DATA SET READY HAS CHANGED STATES
SP IBUS,IIBA1,SP0 ;READ LOW BYTE OF CSR0'S ADDRESS
SPBR IBUS,INDAT1,SP.CS0 ;READ THE LOW BYTE OF THE DEVICES CSR
BR7 60$ ;RECEIVE DONE SET
;
; SEE IF TRANSMIT DONE SET
;
45$: BRSHFT ;SHIFT THE CSR IMAGE
BR1 XMTDON ;REQUEST TO SEND SET
;
; RETURN HERE AFTER FINISHED PROCESSING THE TRANSMITTER
;
TIMRT3:
50$:
BRWRTE BR,SELA,SP.CS0 ;RE-READ IMAGE OF CSR0
BR7 RCVDON ;RECEIVE DONE WAS SET
ALWAYS 10$ ;NOT SET - RETURN
;
; RECEIVE DONE FOUND SET
;
60$:
BRWRTE IMM,2 ;PREPARE TO ADD TWO TO THIS ADDRESS
OUTPUT BR,ADD,IBA1 ;ADD TWO TO THE ADDRESS IN SP0 GETTING THE ADDRESS
; OF CSR2 WHICH CONTAINS THE RECEIVE
;CHARACTER IN THE LOW BYTE AND THE
;STATUS IN THE HIGH BYTE
BRWRTE IMM,14!DATI ;MASK TO SET EXTENDED MEMORY BITS
;AND TO START THE NPR
OUT BR,SELB,ONPR ;START THE NPR TO READ CSR2
70$: BRWRTE IBUS,NPR ;READ THE NPR STATUS REGISTER
BR0 70$ ;NPR IS NOT DONE YET
SP IBUS,INDAT1,SP.CHR ;SAVE THE CHARACTER IN A SCRATCH PAD
SP IBUS,INDAT2,SP.RST ;SAVE THE CHARACTER'S STATUS
BRWRTE BR,SELA,SP.CS0 ;RESTORE THE BRG FOR XMIT DONE TESTING
ALWAYS 45$ ;SEE IF ANY XMIT DONES
;UPON TRANSFER TO XMTDON OR RCVDON
;THE FOLLOWING LOCATIONS HAVE BEEN SET UP
;FOR ENTRY TO THE "DONE" PROCESSOR:
; SP.RM1 -> BITS 8&9 OF RAM TABLE ADDRESS
; SP.RM0 -> BITS 0-7 OF RAM TABLE ADDRESS
; MAR --> STATUS (D.STS) IN LINE TABLE
; SP.LN --> LINE NUMBER
; SP.CS0 --> IMAGE OF LOW BYTE OF CSR 0
; SP.STS --> IMAGE OF D.STS
; SP0 --> LOW BYTE OF CSR 0 ADDRESS
; SP1 --> HIGH BYTE OF CONTENTS OF CSR 0
; NPR INPUT ADDR -> DEVICE CSR 0
;IF RECV DONE,
; SP.CHR --> RECEIVED CHARACTER
; SP.RST --> RCV CHAR STATUS (CSR2 MSB)
.DSABL LSB
;% FILE DUPUSER.MAC
;INDIRECT RETURNS THROUGH PAGE ZERO
;******FOLLOWING INSTRUCTIONS MUST RESIDE IN MICRO PAGE ZERO******
;RETURN FROM INCOUT DUE TO A CALL FROM BOUT ROUTINE
BOUTR0: ALWAYS QPDATA ;GO TO QPDATA ON RETURN
;RETURN FROM INCOUT DUE TO A CALL FROM XMTSND
XMTEM0: ALWAYS XMTBC0
;RETURN FROM LSILO DUE TO A CALL FROM RB3
RB3P0: ALWAYS STORE ;GO TO STORE ROUTINE ON RETURN
.SBTTL BASEIN-BASE IN SERVICE ROUTINE
;+
;
; B A S E I N
;
;
;
;CALLED BY: RDICLR
;
;INPUTS:
; KMC BSEL3 =LINE NUMBER
; KMC SEL6 <3:12> =CSR ADDR FOR CURRENT DUP
; SP.RM0,SP.RM1 =LINE TABLE ADDRESSES
; MAR =LINE TABLE
;OUTPUTS:
; DUP CSR ADDR IS SAVED IN THE LINE TABLE (D.CSR)
; DUP IS RESET
;-
BASEIN:
;SAVE CURRENT DUP CSR ADDR IN RAM
SP IBUS,PORT3,SP0,INCMAR ;GET CSR ADDR INTO SP0
BRWRTE IMM,370,INCMAR ;MASK TO STRIP 3 LSB'S OF CSR ADDR
MEM BR,AANDB,SP0 ;STRIP THEM AND STORE IN RAM
OUTPUT MEMI,SELB,OBA1 ;SAVE CSR IN OUT ADDRESS REGISTERS
SP IBUS,PORT4,SP0 ;GET HIGH BYTE INTO SP0
BRWRTE IMM,340 ;MASK TO SET 3 MSB'S
MEM BR,AORB,SP0 ;SAVE IT IN RAM WITH 3 HIGH BITS SET TO ONES
OUTPUT MEMX,SELB,OBA2 ;SAVE HIGH BYTE OF CSR ADDRESS
BASEI1:
;DEVICE RESET THE DUP
BRWRTE IMM,DUPDR ;SET PROPER BIT (BIT 0) IN OUTDATA HB
OUTPUT BR,SELB,OUTDA2
CALLSR SP.SUB,INCOB,RQICL2,5 ;DO THE NPR TO MASTER CLEAR THE DUP
;AND RETURN TO CLEAR READY IN
; RESET IS A 2 MICRO-SECOND ONE SHOT.IT IS ASSUMED THAT BEFORE THE DUP
;IS ACCESSED AGAIN, THIS PERIOD WILL HAVE ELAPSED.
.SBTTL CONIN-CONTROL IN PROCESS ROUTINE
;+
;
; C O N T R O L I N
;
;
;
;CALLED BY: RDICLR
;
;INPUTS:
; BSEL4 (PORT1) =POLLING COUNT
; BSEL6 (PORT3) =SECONDARY ADDRESS
; BSEL7 (PORT4) =CONTROL FLAGS
; SP.RM0,SP.RM1 =LINE TABLE ADDRESS
; MAR =LINE TABLE ADDRESS
; OUT BA =DUP'S CSR 0
;OUTPUTS:
; VARIOUS LINE TABLE LOCATIONS AND DUP FUNCTIONS ARE INITIALIZED ACCORDING TO
; THE CONTROL IN PARAMETERS.THESE INCLUDE:
; DUP CSR XX0-STRIP SYNC FOR DEC MODE
; DUP CSR XX2-DEC MODE&SYNC CHARACTER FOR DDCMP OR SEC MODE,
; SEC ADDRESS FOR BITSTUFF MODE
; DUP CSR XX4-HALFDUPLEX
;-
CONIN:
BRWRTE IBUS,PORT4 ;READ BSEL 7
BR0 10$ ;ENABLE LINE IS SET
SPBR IMM,0,SP0,INCMAR ;CLEAR SP0
MEMINC DECA,SP0 ;WRITE A 377 TO D.TIME DISABLING THIS LINE
ALWAYS 20$
10$: MEMINC IBUS,PORT1 ;SET TIMER RESTART VALUE
MEMINC IBUS,PORT1 ;AND TIMER ENABLING THE LINE
BRWRTE IMM,DUPDTR!DUPREN ;VALUE TO SET DTR AND RECEIVE ENABLE
; BRG = DUPDTR!DUPREN IF ENABLE WAS REQUEST OR 0 IF DISABLE
20$: OUTPUT BR,SELB,OUTDA1,INCMAR ;VALUE TO SET OR CLEAR DTR,RCV ENABLE
BRWRTE IBUS,PORT4,INCMAR ;REREAD BSEL7
;MAR = D.STS
MEM IMM,DUPSSY ;ASSUME DEC MODE BY STORING STRIP SYNC
;BIT TEMPORARILY IN MEMORY
BR7 30$ ;IT IS DEC MODE
MEM IMM,0 ;BIT STUFF MODE - DON'T SET STRIP SYNC
30$: OUTPUT MEMX,SELB,OUTDA2 ;STORE STRIP SYNC SETTING
BRWRTE IMM,DATO ;DO AN OUTPUT NPR
OUT BR,SELB,ONPR ;REQUEST THE NPR
40$: BRWRTE IBUS,NPR ;SEE IF NPR DONE YET
BR0 40$ ;WAIT FOR IT
CONIN2:
SPBR IBUS,PORT4,SP0 ;REREAD BSEL7
BR7 10$ ;DEC MODE?
; LOAD SYNC CHARACTER/SECONDARY ADDRESS INTI XX2 LOW BYTE
OUTPUT IBUS,PORT3,OUTDA1 ;NO,SO LOAD SEC ADDRESS FIELD
MEM IMM,DS.CRI ;ASSUME CRC INHIBIT
BR1 5$ ;BRANCH IF IT IS CRC INHIBIT
MEM IMM,0 ;CLEAR D.STS
5$: BRWRTE IMM,DUPSAM!DUPCRI ;SET SECONDARY ADDRESS MODE,CRC INHIBIT
ALWAYS 20$
; UPDATE XX3
10$:
MEM IMM,SYNC ;MOVE SYNC CHARACTER TO MEMORY IN ORDER
;TO SAVE THE BRG
OUTPUT MEMX,SELB,OUTDA1 ;MOVE IT TO OUT DATA REGISTER
MEM IMM,DS.SEC!DS.DEC ;ASSUME DEC AND SEC MODE
BR4 15$ ;BRANCH IF SEC MODE
MEM IMM,DS.DEC ;NO,JUST DEC MODE
15$: BRWRTE IMM,DUPDEC ;ISOLATE DEC MODE,CRC INHIBIT
;NOTE: DUP SOULD NOT BE SET TO SECONDARY ADDRESS MODE WHILE IN DEC MODE.THIS
;WILL INHIBIT RECEIVE DONES.
20$:
OUTPUT BR,AANDB,OUTDA2 ;MODE CRC INHIBIT&AND LOAD INTO OUTADA2
CALLSB SP.SUB,IC2OUT ;WRITE IT OUT TO XX3,XX2
; UPDATE DUP XX5,XX4
CONIN3:
BRWRTE IBUS,PORT4
BRSHFT
BR4 30$ ;HALF DUPLEX MODE
;FULL DUPLEX MODE,CLEAR XX4
BRWRTE IMM,0
ALWAYS 40$
;HALF DUPLEX MODE, SET HALF DUPLEX BIT IN XX4
30$:
.IIF NE DS.HDX-DUPHDX .ERROR DS.HDX ;DS.HDX NO LONGER EQUALS DUPHDX
BRWRTE IMM,DUPHDX ;HALF DUPLEX MASK (SAME AS DX.HDX)
SP BR,SELB,SP0 ;SAVE IT IN SP0
MEM MEMX,AORB,SP0 ;SET HALF DUPLEX IN D.STS
40$:
OUTPUT BR,SELB,OUTDA1,INCMAR ;WRITE HALF DUPLEX MASK
;MAR = D.RPTR (RECV STATE POINTER)
; SET RECEIVE STATE POINTER
RSTATE RDH1 ;ASSUME DEC MODE
SPBR IBUS,PORT4,SP0 ;REREAD BSEL7 **X1.4**
BR7 50$ ;IT IS
RSTATE RB1 ;BIT STUFF MODE
;CLEAR XX5
50$: SP BR,TWOA,SP0 ;SHIFT BSEL7 BITS 2 AND 3 **X1.4**
BRWRTE IMM,30 ;TO XX5 BITS 3 AND 4 **X1.4**
OUTPUT BR,AANDB,OUTDA2,INCMAR ;FOR MAINTENANCE MODE **X1.4**
;MAR = D.SADR (SECONDARY ADDRESS)
MEMINC IBUS,PORT3 ;SAVE SECONDARY ADDRESS
BRWRTE IMM,D.XSTS ;OFFSET OF TRANSMIT ABORT STATUS
LDMA BR,ADD,SP.RM0 ;SET MAR
MEM IMM,0 ;CLEAR ANY PENDING STATUS
;WRITE TWO BYTES INTO XX4/XX5
CALLSR SP.SUB,IC2OUT,RQICL2 ;SHIP IT AND RETURN TO CALLER
.SBTTL BAIN-BUFFER ADDRESS IN SERVICE ROUTINE
;+
; B U F F E R A D D R E S S I N
;
;CALLED BY: RDICLR
;
;INPUTS:
; SEL4,BSEL7 <7:6> =BUFFER DESCRPTR LIST ADDR
; BSEL7<5:4> =KILL ASSIGN AND KILL BITS
; SP.RM0,SP.RM1 =LINE TABLE ADDRESS
; MAR =LINE TABLE
; OUT BA =DUP'S CSR ADDRESS
;OUTPUTS:
; BUFFER DESCRIPTOR ADDRESS DEFINED BY THE BA IN IS LOADED INTO
; THE APPROPRIATE (RECEIVE/TRANSMIT) DESCRIPTOR POINTER.
; IF THE CURRENT BUFFER IS THE ONE JUST ASSIGNED,LINE TABLE LOCATIONS
; (BUFFER ADDRESS,BYTE COUNT) ARE UPDATED. OTHERWISE DR.ABA IS SET (ALT ASGNED)
; IF THE CURRENT BUFFER FOR TRANSMISSION IS BEING ASSIGNED,FIRST ODD
; CHARACTER IN THE TRANSMIT BUFFER IS SAVED IN D.OXC
; IF THE CURRENT BUFFER FOR RECEPTION IS BEING ASSIGNED,DR.FST IS SET
;-
BAIN:
;LOAD RECEIVE CONTROL AND STATUS REGISTER INTO SP.CS0
OUTPUT IBUS,IOBA1,IBA1 ;SET INBA 7:0
OUTPUT IBUS,IOBA2,IBA2 ;SET INBA 15:8
BRWRTE IMM,<BIT3!BIT2!DATI> ;SET EXT BITS AND
OUT BR,SELB,ONPR ;DO IN NPR
;DETERMINE TYPE OF IO REQUIRED (RECEIVE OR TRANSMIT)
BRWRTE IBUS,OCON ;GET OUTPUT CONTROL REGISTER
BRSHFT
BR1 BARCV ;BAIN FOR RECEIVE
;BAIN FOR TRANSMIT OPERATION
BRWRTE IMM,D.XDP ;ADDRESS D.XDP
ALWAYS BAIN1
;BAIN FOR RECEIVE OPERATION
BARCV: BRWRTE IMM,D.RDP ;ADDRESS D.RDP
BAIN1:
BRWRTE BR,ADD,SP.RM0 ;BR=ADDRESS OF D.RDP OR D.XDP
SP BR,SELB,SP6 ;SET SP6=THAT ADDRESS
10$: BRWRTE IBUS,NPR ;WAIT FOR NPR COMPLETION
BR0 10$
SP IBUS,INDAT1,SP.CS0 ;LOAD RCV CSR (XX0) INTO SP.CS0
;CHECK IF THERE IS A KILL
BRWRTE IBUS,PORT4 ;GET PORT 4 INTO BR
BR4 KILLAL ;BRANCH TO KILL ROUTINE
; THIS IS A VALID BUFFER ASSIGNMENT
;(ALSO ENTRY POINT AFTER A KILL IF A NEW BUFFER IS ASSIGNED)
BAIN0:
;CHECK IF CURRENT OR ALTERNATE OPERATION
BRWRTE IMM,<D.RBDF-D.RDP> ;OFFSET TO FLAG BYTE FOR CURRENT OPERATION
LDMA BR,ADD,SP6 ;ADDRESS FLAG BYTE
SPBR MEMX,SELB,SP5 ;GET FLAGS INTO BR,SP5
BRSHFT
BR4 BAALT ;CURRENT BUFFER ALREADY ASSIGNED
;CURRENT BUFFER NOT ASSIGNED,ASSIGN CURRENT BUFFER
MEM IMM,DR.CBA ;SET CURRENT BUFFER ASSIGNED & CLEAR
;ALL OTHER BITS IN FLAG BYTE
LDMA BR,SELA,SP6 ;ADDRESS D.RDP/D.XDP
;SAVE LIST ADDRESS AT CURRENT MEMORY LOCATION
BAIN2:
MEMINC IBUS,PORT1 ;ADDRESS 7:0
MEMINC IBUS,PORT2 ;ADDRESS 15:8
SP IBUS,PORT4,SP0 ;GET EXT ADDRESS
BRWRTE IMM,300 ;BR=MASK TO ISOLATE EXT ADDRESS
BRWRTE BR,AANDB,SP0 ;BR=JUST EXT ADDRESS BITS
BRSHFT ;SHIFT IT INTO PROPER POSITION
BRSHFT
BRSHFT
BRSHFT
MEM BR,SELB ;SAVE EXT ADDRESS
;IF THE CURRENT BUFFER IS BEING ASSIGNED,DO SPECIAL THINGS
BRWRTE BR,TWOA,SP5 ;SP5 HAS FLG BITS
BR7 RQICL2 ;ALTERNATE BUFFER ASSIGNED,EXIT
;CURRENT BUFFER BEING ASSIGNED,MOVE DESCRIPTOR PARAMETRS INTO RAM
CALLSR SP.SB1,NXDSCP,RQICR2 ;RETURN TO IDLE THROUGH PAGE 2
;LABEL TO USE "ALWAYS NXDSCP" IN THE ABOVE MACRO AS AN INTER PAGE RETURRN
NXDP1=.-2
;ASIGNING ALTERNATE BUFFER
BAALT:
BRWRTE IMM,DR.ABA ;SET DR.ALT(=DX.ALT)BIT
MEM BR,AORB,SP5
SP MEMX,SELB,SP5 ;SET SP5=NEW FLAGS
BRWRTE IMM,<D.ARLP-D.RDP> ;ADDRESS ALTERNATE POINTER
LDMA BR,ADD,SP6
ALWAYS BAIN2 ;SAVE LIST POINTER IN RAM
.SBTTL XMTDON - TRANSMIT DONE
; FILE DUXMIT.MAC
;+
; **-XMTDON-ROUTINE TO LOOK FOR AND HANDLE A DUP TRANSMIT DONE**
;
; CALLED BY: TIMER
;
; INPUTS:
; SP0 = LOW BYTE OF DUP'S CSR0 ADDRESS
; SP1 = HIGH BYTE OF DUP'S CSR0 (CTS STATUS)
; SP.RM0-RM1 = RAM TABLE ADDRESS
; SP.CS0 = LOW BYTE OF CSR0 (CONTAINS STATE OF RTS & RECV. ENABLE)
; SP.LN = LINE NUMBER
; MAR AND SP.STS = STATUS BYTE IN LINE'S TABLE
; IN DATA ADDRESS = DUP'S CSR 0
;
; OUTPUTS:
; IN THE NORMAL CASE THE NEXT CHARACTER IS TRANSMITTED. SPECIAL
; CASES INCLUDE HANDLING SYNC TRANSMISSION, CRC TRANSMISSION
; AND ERROR CONDITIONS.
;-
XMTDON:
BRWRTE SELA,SP1 ;READ THE HIGH BYTE OF CSR 0
BRSHFT
BR4 10$ ;CLEAR TO SEND IS SET
ALWAYS TIMRT3 ;NO, SET CHECK FOR RECEIVE DONES
10$: BRWRTE IMM,4 ;PREPARE TO POINT TO CSR4
OUTPUT BR,ADD,IBA1 ;SET IT UP
BRWRTE IMM,14!DATI ;MASK TO SET EXTENDED MEMORY BITS
;AND START NPR
OUT BR,SELB,ONPR ;START THE NPR
20$: BRWRTE IBUS,NPR ;IS THE NPR DONE YET
BR0 20$ ;NO, WAIT FOR IT
OUTPUT IBUS,IIBA1,OBA1 ;COPY INPUT ADDRESS TO OUTPUT **X1.2**
OUTPUT IBUS,IIBA2,OBA2 ;ADDRESS **X1.2**
BRWRTE IBUS,INDAT1 ;READ THE TRANSMIT CNTROL REGISTER
;
; THE FOLLOWING TRIES TO DETERMINE WHEN A DUP IS HUNG AND ALLOW PROCESSING
; TO CONTINUE. THE DUP WILL BE UNHUNG WHEN DUPTSM AND DUPSND ARE BOTH SET
; WHEN THE MODEM IS CLOCKING. THE CASE BEING LOOKED FOR HERE IS:
; (-TXACT)(-TXDONE)(-TXSEND)
;(1 LINE REPLACED) **X1.2**
BR7 XMTDN1 ;TRANSMIT DONE SET **X1.2**
BR4 TIMRT3 ;SEND IS SET **X1.2**
BRWRTE IBUS,INDAT2 ;LOOK AT TXACT **X1.2**
BR1 TIMRT3 ;TXACT IS SET **X1.2**
; FALL INTO XMTDN1
; TRANSMIT DONE FOUND
.ENABL LSB
XMTDN1:
;(2 LINES REMOVED) **X1.2**
SP IBUS,UBBR,SP0 ;READ THE CONTENTS OF THE BUS REQ REG
BRWRTE IMM,101 ;MASK TO CLEAR ALL BUT NXM AND XX4 BITS
SP BR,AANDB,SP0 ;CLEAR THEM
BRWRTE IMM,14 ;EXTENDED MEMORY BITS
OUT BR,AORB,OBR ;SET THEM UP
BRWRTE IMM,D.XSTS ;LOOK AT TRANSMIT STATUS BYTE
LDMA BR,ADD,SP.RM0 ; LOAD THE MAR
SPBR MEMX,SELB,SP0 ;READ THE BYTE
BR4 XMTABT ;TRANSMIT ABORT PENDING
BRWRTE IMM,D.XBDF ;LOOK AT TRANSMITTER FLAGS WORD
LDMA BR,ADD,SP.RM0 ; (LOAD MAR)
BRWRTE MEMX,SELB ;READ THE FLAGS WORD
BRSHFT ;SHIFT IT RIGHT
BR4 50$ ;BUFFER IS ASSIGNED
; THIS DONE IS THE RESULT OF A BUFFER TERMINATING AND NO SUBSEQUENT BUFFERS ASSIGNED
BR0 10$ ;LAST BUFFER HAD END OF MESSAGE SET
ALWAYS TIMRT3 ;PREVIOUS BUFFER WAS NOT THE END OF
;MESSAGE - WAIT FOR THE NEXT BUFFER
;OR AN UNDERRUN ERROR
10$: BRWRTE SELA,SP.STS ;POSITION DEC-MODE BIT **X1.3**
BRSHFT ; **X1.3**
BR4 15$ ;IF SET, CLEAR RTS **X1.2**
ALWAYS TIMRT3 ;IF CLEAR, DON'T CLEAR RTS **X1.2**
15$: SP IBUS,IOBA1,SP0 ;READ THE LOW BYTE OF OUT ADDRESS (CSR 4)
BRWRTE IMM,370 ;MASK TO CHANGE IT TO CSR 0
OUTPUT BR,AANDB,OBA1 ;MAKE IT CSR 0
BRWRTE IMM,377-DUPRTS ;MASK TO CLEAR RTS
SPBR BR,AANDB,SP.CS0 ;AND IMAGE OF CSR 0
OUTPUT BR,SELB,OUTDA1 ;IMAGE OF CSR 0 WITH RTS CLEAR
ALWAYS XMTSN0 ;START THE NPR THEN RETURN TO TIMER LOOP
; BUFFER IS ASSIGNED
XMTDN3:
50$:
BRWRTE IBUS,INDAT1 ;READ THE TRANSMIT CNTROL REGISTER
BR4 55$ ;SEND SET
BRWRTE IBUS,INDAT2 ;GET THE BYTE CONTAINING TX ACTIVE
BR1 TIMRT3 ;IF SET, DON'T SET SEND YET.
;NOTE THAT THE DUP MAY GET IN AN ILLEGAL
;SET IF SEND IS DROPPED AND REASSERTED BEFORE
;TX ACTIVE CLEARS
SP IMM,DUPSND,SP0 ;MASK TO SET SEND
ALWAYS XMTSND ;"CALL" SEND ROUTINE AND RETURN TO TIMER LOOP
;
; ENTER HERE AFTER COMPLETING ONE BUFFER AND FIND ANOTHER ASSIGNED
; THE BRG CURRENTLY CONTAINS THE TRANSMIT FLAGS BYTE ROTATED
;
XMTDN4: BR7 TIMRT3 ;START OF MESSAGE SET - INDICATES PREVIOUS
;MESSAGE ENDED WITH AN EOF HENCE A TEOM
;HAS JUST BEEN SENT SO WAIT FOR NEXT TDONE
55$: SPBR MEMX,SELB,SP0 ;READ THE FLAGS AGAIN
BR0 120$ ;START OF MESSAGE FLAG SET
60$: CALLSR SP.SUB,DECNT,XMTCNT,D.XBDC ;DECREMENT THE BYTE COUNT
; ABOVE SUBROUTINE RETURNS HERE IF THE BYTE COUNT WAS NOT ZERO
; IF BYTE COUNT WAS ZERO, END OF BUFFER CONDITIONS ARE CHECKED IN XMTCNT
XMTDN2: SPBR MEMX,SELB,SP1 ;READ THE LOW BYTE OF THE ADDRESS
;AND SAVE IT IN THE BRG
MEMINC INCA,SP1 ;INCREMENT ADDRESS AND STORE IT BACK
BR0 110$ ;ODD CHARACTER (ALREADY BEEN READ)
;OTHERWISE ITS AN EVEN CHARACTER
; TRANSMIT EVEN CHARACTER
; MUST READ A WORD FROM MEMORY
;
;NO NEED TO WORRY ABOUT CARRY SINCE THERE
;CAN'T BE ON AN EVEN TO ODD INCREMENT
OUTPUT BR,SELB,IBA1 ;BUFFER ADDRESS TO IN ADDRESS FIELD
OUTPUT MEMI,SELB,IBA2 ;..
BRWRTE IMM,14 ;MASK TO ISOLATE EXTENDED MEMORY BITS
;(3 LINES REPLACED) **X1.2**
SPBR BR,AANDB,SP0 ;MASK FLAGS WORD LEAVING BR == SP0 **X1.2**
OUT INCA,ONPR ;SET EXTENDED MEM BITS AND NPR REQUEST BIT **X1.2**
OUTPUT BR,AXORB,SP0,OUTDA2 ;CLEAR ALL DUP CONTROL BITS **X1.2**
80$: BRWRTE IBUS,NPR ;READ THE NPR STATUS REGISTER **X1.2**
BR0 80$ ;NPR NOT DONE YET
OUTPUT IBUS,INDAT1,OUTDA1,INCMAR ;MOVE CHARACTER TO OUTDATA FIELD
;AND MOVE THE MAR TO ODD CHARACTER SAVE BYTE
MEM IBUS,INDAT2 ;SAVE THE ODD CHARACTER IN RAM
; "RETURN" POINT FROM XMTSYN
WRTRT:
SP IBUS,IOBA1,SP0 ;READ CURRENT OUTPUT ADDRESS (CSR4)
BRWRTE IMM,2 ;VALUE TO ADD
OUTPUT BR,ADD,OBA1 ;POINT TO CSR6
BRWRTE IMM,DATO ;MASK TO DO OUT NPR
; THIS IS THE "RETURN" POINT FROM XMTSND AND XMTSN0
XMTDN6:
OUT BR,SELB,ONPR ;DO THE NPR
90$: BRWRTE IBUS,NPR ;WAIT FOR IT TO COMPLETE
BR0 90$ ;NOT YET
ALWAYS TIMRT3 ;RETURN TO TIMER LOOP
; TRANSMIT ODD DATA CHARACTER
;
; INPUTS:
; "C" BIT IS SET OR CLEAR DEPENDING ON CARRY FROM INCREMENT OF LOW BYTE
; MAR = D.XBDA+1
110$: C 113$ ;IF CARRY SET THEN MUST INCRMENT HIGH 10 BITS OF ADDR
BRWRTE IMM,0,INCMAR ;ZERO THE BRG AND POINT MAR TO D.XBDF
ALWAYS 116$ ;OTHERWISE NO NEED TO
113$: CALLSB SP.SUB,INCMM ;INCREMENT THE BUFFER ADDRESS (HIGH 10 BITS)
;RETURNS WITH MAR POINTING TO D.XBDF
BRWRTE IMM,0 ;ZERO THE BRG
116$: OUTPUT BR,SELB,OUTDA2,INCMAR ;CLEAR ALL DUP CONTROL BITS
;AND POINT MAR TO ODD TRANSMIT CHARACTER
OUTPUT MEMX,SELB,OUTDA1 ;MOVE THE CHARACTER TO THE OUTDATA FIELD
ALWAYS WRTRT ;INCREMENT OUT ADDR BY 2 (CSR6) AND DO AN
;NPR TO WRITE OUT THE CHARACTER
;RETURN TO THE TIMER LOOP
; START OF MESSAGE SET
;
; BRG AND SP0 = (D.XBDF)
120$:
BR4 XMTSYN ;RESYNC REQUESTED
BRWRTE IBUS,INDAT2 ;READ HIGH BYTE OF CSR4
BR7 130$ ;UNDERRUN OCCURRED, SEND 2 SOM'S
.IIF NE DX.SOM-1 .ERROR ;FOLLOWING DECA WILL NO LONGER CLEAR DX.SOM FLAG
MEM DECA,SP0 ;CLEAR IT
BRWRTE SELA,SP.STS ;GET THE STATUS BYTE
BRSHFT
BR4 60$ ;DEC MODE (DDCMP)
130$:
BRWRTE IMM,DUPTSM ;START OF MESSAGE BIT
OUTPUT BR,SELB,OUTDA2 ;SET START OF MESSAGE
ALWAYS WRTRT ;COMMON CODE TO INCR OUT ADDR BY 2
;DO AN NPR AND RETURN TO TIMER LOOP
.DSABL LSB
.SBTTL RCVDON-RECEIVED CHARACTER PROCESSOR
; FILE DUPRCV.MAC
;+
; R E C E I V E C H A R A C T E R P R O C E S S O R
;
;
;CALLED BY: TIMER
;
;INPUTS:
; SP.RM0,SP.RM1 =ADDRESS OF CURRENT LINE TABLE
; SP.CS0 =DUP RECEIVE STATUS REGISTER
; SP.CHR =RECEIVED CHARACTER
; SP.RST =STATUS OF CHARACTER
;OUTPUTS:
; CHECKS FOR RECEIVE ERRORS, THEN BRANCHES TO A RECEIVE STATE PROCESSOR
; USING D.RPTR FROM LINE TABLE. RSTATE MACRO CHANGES STATE SETTINGS.
; RECIEVE STATE INITIALIZED BY CONTROL IN.
;-
RCVDON:
BRWRTE IMM,D.STS ;OFFSET TO STATUS BYTE
LDMA BR,ADD,SP.RM0 ;SET UP MAR
LDMAP SELA,SP.RM1 ;LOAD MAR HI
SP MEMI,SELB,SP.STS ;SAVE STATUS BYTE IN SP
; CHECK IF ANY ERROR ON RECEIVED CHARACTER
BRWRTE BR,SELA,SP.RST ;GET HIGH BYTE OF RECEIVE BUFFER
BR7 DUPRER ;RECEIVE ERROR ***
;CHARACTER IS ERROR FREE
;DISPATCH TO THE CURRENT RECEIVE STATE PROCESSOR.
.ALWAY MEMX,SELB,RP ;DISPATCH VIA STATE POINTER
; ***NOTE: ALL STATE PROCESSORS MUST BE IN PAGE RP
.PAGE
.SBTTL BIT-STUFF PROTOCOL RECEIVE PROCESSORS
; FILE DUPSDLC.MAC
RP=<.-START>&3000*4 ;PAGE ADDRESS OF RECEIVE STATE PROCESSORES
.SBTTL RB1-BIT STUFF RECEIVE STATE ONE
;+
;
; B I T S T U F F R E C E I V E S T A T E O N E
;
;ENTERED FROM: RCVDON
;
;INPUTS:
; MAR =RECEIVER STATE POINTER (D.RPTR)
;
;OUTPUTS:
; RECEIVE STATE POINTER IS SET TO STATE TWO
;-
.ENABL LSB ; **X1.2**
RB1:
RSTATE RB2 ;SET TO STATE 2
;(3 LINES REPLACED) **X1.2**
ALWAYS 10$ ;JOIN COMMON CODE CHAIN **X1.2**
; TO SILO AND RETURN TO TIMER
.SBTTL RB2-BIT STUFF RECEIVE STATE TWO
;+
;
; B I T S T U F F R E C E I V E S T A T E T W O
;
;ENTERED FROM: RCVDON
;
;INPUTS:
; MAR =RECEIVE STATE POINTER (D.RPTR)
;
;OUTPUTS:
; STATE POINTER IS SET TO STATE THREE
; CURRENT RECEIVED CHARACTER IS PUSHED INTO THE LOCAL TWO CHARACTER SILO
;-
RB2:
RSTATE RB3 ;SET STATE THREE
;(2 LINES REPLACED) **X1.2**
10$: BRADDR TIMRTN ;RETURN ADDRESS TO POLLING LOOP **X1.2**
ALWAYS 20$ ;CONTINUE DOWN COMMON RETURN CHAIN TO **X1.2**
; SILO AND TIMER
.SBTTL RB3-BIT STUFF RECEIVE STATE THREE
;+
;
; B I T S T U F F R E C E I V E S T A T E T H R E E
;
; ENTERED FROM: RCVDON
;
; INPUTS:
; MAR = RECEIVE STATE POINTER (D.RPTR)
; BR = HIGH BYTE OF CSR0 (SP.RST - RECEIVE CHARACTER STATUS)
; OUTPUTS:
; CHECK FOR END OF MESSAGE, IF END GOTO RBDONE
; ELSE STORE THE CHARACTER AND STAY IN THIS STATE
;-
RB3:
; CHECK IF END OF MESSAGE
BR1 RBDONE ;END OF RECEIVED MESSAGE
;NOT END OF RECEIVED MESSAGE
BRADDR RB3P0 ;RETURN ADDRESS TO STORE
; COMMON CODE PATHS FOR RB STATES ENTER HERE
20$: SP BR,SELB,SP.SUB,INCMAR ;SAVE RETURN ADDRESS
;FALL INTO LSILO
.DSABL LSB ; **X1.2**
.SBTTL LSILO-PUSH CHARACTER INTO LOCAL TWO CHARACTER SILO
;+
;
; P U S H C H A R A C T E R I N T O L O C A L S I L O
;
; CALLED BY: BIT STUFF RECEIVE STATES; RB1,RB2,RB3
;
; INPUTS:
; SP.SUB=RETURN ADDRESS
; SP.CHR=CHARACTER TO BE PUSHED INTO LOCAL TWO CHARACTER SILO
; MAR = D.SADR
;
; OUTPUTS:
; CHARACTER IN SP.CHR IS PUSHED INTO SILO
; UNDERFLOW CHARACTER FROM THE SILO IS LOADED INTO SP.CHR
; IF IN CRC INHIBIT MODE,INPUT CHARACTER IS DIRECTLY STORED
; IN MEMORY.
;-
LSILO:
BRWRTE SELA,SP.STS,INCMAR ;GET STATUS BYTE
;MAR NOW POINTS TO D.SILO
BR7 STORE ;STORE CHARACTER IF CRC INHIBIT
SP MEMX,SELB,SP0 ;TEMPORARILY STORE TOP SILO CHR IN SP0
MEMINC SELA,SP.CHR ;LOAD NEW CHARACTER INTO TOP SILO POSITION
SP MEMX,SELB,SP.CHR ;LOAD UNDERFLOW CHR. INTO SP.CHR
MEM SELA,SP0 ;STORE OLD TOP CHR INTO BOTTOM POSITION IN SILO
RTNSUB SP.SUB,P0 ;RETURN
.SBTTL RBDONE - END OF BIT STUFF MESSAGE RECEIVED
;+
;
; END OF BIT STUFF MESSAGE RECEIVED
;
; ENTERED BY: RB3
;
; INPUTS:
; MAR =RECEIVE STATE POINTER (D.RPTR)
;
; OUTPUTS:
; RECEIVE STATE POINTER RESET TO ONE
; GENERAL END OF RECEIVE MESSAGE ROUTINE CALLED
;-
RBDONE:
RSTATE RB1 ;SET RECEIVE STATE 1
CALLSR SP.SB1,EOFMSG,TIMRP2 ;CALL END OF MESSAGE ROUTINE AND
; RETURN TO TIMER'S POLLING LOOP
.SBTTL DDCMP RECEIVE STATE PROCESSORS
; FILE DUPDDCMP.MAC
;+
;
; D D C M P R E C E I V E S T A T E P R O C E S S O R S
;
;
; DDCMP RECEIVE STATE PROCESSORS FOR THE COMIOP-DUP FOLLOW.
;-
.SBTTL RDH1-RECEIVING FIRST DDCMP HEADER CHARACTER
;+
; R E C E I V I N G F I R S T D D C M P C H A R A C T E R
;
; ENTERED FROM: RCVDON
;
; INPUTS:
; MAR = RECEIVE STATE POINTER (D.RPTR)
; SP.CHR = CURRENT RECEIVE CHARACTER
; SP.LN = CURRENT LINE NUMBER
; SP.CS0 = IMAGE OF LOW BYTE OF DUP'S CSR0
;
; OUTPUTS:
; RECEIVE STATE POINTER IS SET TO THE SECOND DDCMP RECEIVE STATE.
; RECEIVE STATUS BYTE D.STS IS UPDATED TO INDICATE WHETHER A
; NUMBERED MESSAGE (SOH OR DLE) OR AN UNNUMBERED MESSAGE (ENQ) IS RECEIVED.
; A CONTROL OUT IS GENERATED IF AN ILLEGAL HEADER CHARACTER IS RECEIVED.
;IF THE CHARACTER IS LEGAL, STORE ROUTINE IS CALLED TO SAVE IT IN THE USER
;RECEIVE BUFFER.
;IF THE CHARACTER IS SYNC OR PAD,RESYNC THE RECEIVER
;-
RDH1:
; SET RECEIVE STATE TWO
RSTATE RDH2 ;SET RECEIVE STATE TWO
; SET RAM ADDRESS TO RECEIVE STATUS BYTE
BRWRTE IMM,D.STS ;OFFSET INTO BR
LDMA BR,ADD,SP.RM0
;RESET SELECT,Q-SYNC,IGNORE AND NUMBERED MESSAGE BITS
BRWRTE IMM,<377-DS.SLT-DS.QSC-DS.IGN-DS.NUM> ;MASK TO CLEAR THOSE BITS
MEM BR,AANDB,SP.STS ;CLEAR THOSE BITS AND SAVE
SP MEMX,SELB,SP.STS ;GET NEW STATUS
; DETERMINE TYPE OF MESSAGE.INPUT CHARACTER IS AVAILABLE IN SP.CHR
BRWRTE IMM,SOH ;IS IT AN SOH?
COMP BR,SP.CHR
Z 10$ ;YES,NUMBERED MESSAGE
BRWRTE IMM,ENQ ;IS IT AN ENQ?
COMP BR,SP.CHR
Z STORE ;YES,UNNUMBERED MESSAGE
BRWRTE IMM,DLE ;IS IT A DLE?
COMP BR,SP.CHR
Z 10$ ;YES,MAINTAINANCE (NUMBERED) MESSAGE
; UNRECOGNIZED START OF HEADER CHARACTER - JUST RESYNC
ALWAYS RSNCRT ;RESYNC AND RETURN TO TIMER
;A NUMBERED MESSAGE IS BEING RECEIVED(SOH OR DLE). SET 'NUMBERED MESSAGE
;BEING RECEIVED' IN D.STS
10$:
BRWRTE IMM,DS.NUM ;MASK TO SET IT
;(2 LINES REPLACED) **X1.2**
ALWAYS RDH6A ;JOIN COMMON CODE TO OR IT INTO D.STS **X1.2**
; AND STORE CURRENT CHARACTER **X1.2**
.SBTTL RDH2-RECEIVING SECOND DDCMP HEADER CHARACTER
;+
;
; R E C E I V I N G S E C O N D D D C M P C H A R A C T E R
;
; ENTERED FROM: RCVDON
;
; INPUTS:
; MAR = RECEIVE STATE POINTER (D.RPTR)
; SP.CHR = RECEIVED CHARACTER
;
; OUTPUTS:
; RECEIVE STATE POINTER IS CHANGED TO RECEIVE STATE THREE. CURRENT
; RECEIVED CHARACTER (LOW ORDER BYTE COUNT IN THE CASE OF A NUMBERED
; MESSAGE) IS SAVED IN D.DCC1. STORE ROUTINE IS CALLED TO STORE THE CURRENT
; RECEIVED CHARACTER IN THE USER RECEIVE BUFFER
;-
RDH2:
; UPDATE RECEIVE STATE POINTER TO STATE THREE
RSTATE RDH3
; SAVE CHARACTER COUNT (TYPE IF UNNUMBERED MESSAGE) IN D.DCC1
BRWRTE IMM,D.DCC1 ;ADDRESS D.DCC1
LDMA BR,ADD,SP.RM0
MEM SELA,SP.CHR ;CURRENT CHARACTER AVAILABLE IN SP.CHR
; STORE CURRENT RECEIVED CHARACTER IN USER BUFFER
ALWAYS STORE
.SBTTL RDH3-RECEIVING THIRD DDCMP HEADER CHARACTER
;+
;
; R E C E I V I N G T H I R D D D C M P C H A R A C T E R
;
; ENTERED FROM: RCVDON
;
; INPUTS:
; MAR = RECEIVE STATE POINTER (D.RPTR)
; SP.CHR = RECEIVED CHARACTER
;
; OUTPUTS:
; RECEIVE STATE POINTER IS CHANGED TO STATE FOUR OF DDCMP RECEIVE PROCESSOR.
; HIGH ORDER SIX BITS OF THE CHARACTER COUNT (MEANINGFUL ONLY TO
; NUMBERED MESSAGES) ARE STORED IN D.DCC2. Q-SYNC AND SELECT BITS ARE UPDATED
; IN D.STS.
;-
RDH3:
; SET RECEIVE STATE POINTER TO STATE FOUR
RSTATE RDH4
; SAVE HIGH ORDER SIX BITS OF BYTE COUNT (NOT MEANINGFUL FOR UNNUMBERED MESSAGE)
BRWRTE IMM,D.DCC2 ;ADDRESS D.DCC2
LDMA BR,ADD,SP.RM0
BRWRTE IMM,77 ;MASK TO STRIP HIGH ORDER 2 BITS
MEM BR,AANDB,SP.CHR ;STRIP THEM FROM CURRENT CHR AND STORE IN RAM
; UPDATE SELECT AND Q-SYNC BITS IN D.STS
SP BR,AANDB,SP.STS ;STRIP OLD SEL. Q-SYNC BITS IN SP.STS
BRWRTE IMM,D.STS ;ADDRESS D.STS
LDMA BR,ADD,SP.RM0
BRWRTE IMM,300 ;MASK TO ISOLATE NEW SELECT,Q-SYNC BITS
BRWRTE BR,AANDB,SP.CHR ;GET NEW BITS INTO BR
;(2 LINES REPLACED) **X1.2**
; STORE CURRENT RECEIVED CHARACTER IN USER RECEIVE BUFFER AND **X1.2**
; UPDATE STATUS. **X1.2**
ALWAYS RDH6A ; **X1.2**
.SBTTL RDH4-RECEIVING FOURTH DDCMP HEADER CHARACTER
;+
;
; R E C E I V I N G F O U R T H D D C M P C H A R A C T E R
; (RESPONSE FIELD)
;
; ENTERED FROM: RCVDON
;
; INPUTS:
; MAR = RECEIVE STATE POINTER (D.RPTR)
; SP.CHR = RECEIVED CHARACTER
;
; OUTPUTS:
; RECEIVE STATE POINTER IS CHANGED TO STATE FIVE OF RECEIVE PROCESSOR.
; THE CURRENT CHARACTER (RESPONSE FIELD) IS STORED IN USER RECEIVE BUFFER.
;-
RDH4:
; SET RECEIVE STATE POINTER TO STATE FIVE
RSTATE RDH5
; STORE CURRENT CHARACTER (RESPONSE FIELD) IN USER RECEIVE BUFFER
ALWAYS STORE
.SBTTL RDH5-RECEIVING FIFTH DDCMP HEADER CHARACTER
;+
;
; R E C E I V I N G F I F T H D D C M P C H A R A C T E R
; (MESSAGE NUMBER FIELD)
;
; ENTERED FROM: RCVDON
;
; INPUTS:
; MAR = RECEIVE STATE POINTER (D.RPTR)
; SP.CHR = RECEIVED CHARACTER
;
; OUTPUTS:
; RECEIVE STATE POINTER IS SET TO STATE SIX. CURRENT CHARACTER (MESSAGE
; NUMBER FIELD) IS STORED IN THE USER RECEIVE BUFFER.
;-
RDH5:
; SET RECEIVE STATE POINTER TO STATE SIX
RSTATE RDH6
;STORE CURRENT CHARACTER (MESSAGE NUMBER) IN USER BUFFER
ALWAYS STORE
.SBTTL RDH6-RECEIVING SIXTH DDCMP HEADER CHARACTER
;+
;
; R E C E I V I N G S I X T H D D C M P C H A R A C T E R
; (STATION ADDRESS FIELD)
;
; ENTERED FROM: RCVDON
;
; INPUTS:
; MAR = RECEIVE STATE POINTER (D.RPTR)
; SP,CHR = RECEIVES CHARACTER
;
; OUTPUTS:
; RECEIVE STATE POINTER IS SET TO PROCESS FIRST HEADER CRC CHARACTER.
; IF THE USER STATION IS A SECONDARY STATION AND THERE IS AN ADDRESS MISMATCH,
; THE IGNORE BIT IS SET IN D.STS.
;-
RDH6:
;SET RECEIVE STATE POINTER TO PROCESS FIRST HEADER CRC
RSTATE RHCRC1
;CHECK IF SECONDARY STATION
BRWRTE SELA,SP.STS,INCMAR ;LOAD D.STS INTO BR AND ADDRESS D.SADR
BRSHFT ;SHIFT IT RIGHT
BR1 10$ ;BRANCH IF SECONDARY STATION
; CURRENT STATION IS NOT A SECONDARY STATION, NO ADDRESS CHECKING NECESSARY
ALWAYS STORE ;STORE CHARACTER IN REC BUFFER
; CURRENT STATION IS A SECONDARY STATION.
10$:
;CHECK IF ADDRESS MATCH (MAR MUST NOW BE POINTING AT D.SADR)
COMP MEMX,SP.CHR ;ADDRESS MATCH?
Z STORE ;YES,STORE THE CHARACTER
; STATION IS A SECONDARY STATION, BUT IS NOT ADDRESSED
; SET IGNORE MODE
BRWRTE IMM,D.STS ;ADDRESS STATUS BYTE
LDMA BR,ADD,SP.RM0
BRWRTE IMM,DS.IGN ;MASK TO SET IGNORE MODE
;(1 LINE REPLACED) **X1.2**
; COMMON PATH TO UPDATE SP.STS AND STORE CHARACTER **X1.2**
RDH6A: MEM BR,AORB,SP.STS ;WRITE IT BACK INTO RAM **X1.2**
ALWAYS STORE ;STORE CURRENT CHARACTER
.SBTTL RHCRC1-RECEIVING FIRST DDCMP HEADER CRC
;+
;
; R E C E I V I N G F I R S T D D C M P H E A D E R C R C
;
; ENTERED FROM: RCVDON
;
; INPUTS:
; MAR = RECEIVE STATE POINTER (D.RPTR)
;
; OUTPUTS:
; RECEIVE STATE POINTER IS SET TO PROCESS SECOND DDCMP HEADER
; CRC CHARACTER.
;-
RHCRC1:
;SET RECEIVE STATE POINTER TO RECEIVE SECOND DDCMP HEADER CRC
RSTATE RHCRC2
; ** PAGE ONE RETURN TO TIMER FOR RECEIVE ROUTINES **
TIMRP1: ALWAYS TIMRTN ;RETURN TO THE TIMER LOOP
.IIF NE <<TIMRP1-START>/1000-1> .ERROR ;LABEL "TIMRP1" NO LONGER ON PAGE 1
.SBTTL RHCRC2-RECEIVING SECOND DDCMP HEADER CRC
;+
;
; R E C E I V I N G S E C O N D D D C M P H E A D E R C R C
;
; ENTERED FROM: RCVDON
;
; INPUTS:
; MAR = RECEIVE STATE POINTER (D.RPTR)
; BR = HIGH BYTE OF CSR 2 (SP.RST - RECEIVE CHARACTER STATUS)
;
; OUTPUTS:
; DUP HAS RECEIVED SECOND HEADER CRC CHAR.
; CHECK IF HEADER CRC IS VALID, IF NOT POST ERROR CNTRL OUT.
; IF THIS IS AN UNNUMBERED MESG, PROCESS NOW.
; ELSE (NUMBERED OR MAINT), STATE IS SET TO RECEIVE DATA.
;-
RHCRC2:
; SET RECEIVE STATE POINTER TO RECEIVE DDCMP DATA
RSTATE RDDATA
; CHECK IF THERE IS A CRC ERROR
BR4 10$ ;CRC=0,MESSAGE IS OK
ALWAYS ERR10 ;***CRC ERROR***
;CHECK IF THE CURRENT MESSAGE IS A NUMBERED MESSAGE
10$:
BRWRTE SELA,SP.STS ;LEFT SHIFT D.STS AND LOAD INTO BR
BR0 TIMRTN ;RECEIVING NUMBERED MESSAGE
;RETURN TO TIMER
;RECEIVING UNNUMBERED MESSAGE
ALWAYS MSGIN ;PROCESS ONE MESSAGE
.SBTTL RDDATA-RECEIVING DDCMP DATA CHARACTERS
;+
;
; R E C E I V I N G D D C M P D A T A C H A R A C T E R S
;
; ENTERED FROM: RCVDON
;
; INPUTS:
; MAR = RECEIVE STATE POINTER (D.RPTR)
;
; OUTPUTS:
; THE DATA BYTE COUNT IS DECREMENTED.
; IF ALL DATA IS RECEIVED, THIS IS THE FIRST CRC CHAR.
; OTHERWISE, STORE THE DATA IN BUFFER IF FOR THIS STATION.
;-
RDDATA:
;CHECK IF LAST DDCMP DATA CHARACTER
CALLSR SP.SUB,DECDCC,DECP2 ;DECREMENT DDCMP DATA CHARACTER COUNT
RDATA1:
C 10$ ;BRANCH IF COUNT NOT -1
;CURRENT CHARACTER IS THE FIRST DDCMP DATA CRC CHARACTER
ALWAYS RDCRC1
; STORE CURRENT DATA CHARACTER IN USER RECEIVE BUFFER IF THE CURRENT MESSAGE
;IS ADDRESSED TO THIS STATION.
10$:
BRWRTE SELA,SP.STS ;GET SP.STS(=D.STS)
BR4 TIMRTN ;MESSAGE NOT FOR THIS STATION
; DATA CHARACTER IS PART OF A NUMBERED MESSAGE ADDRESSED TO THIS STATION,SAVE IT
ALWAYS STORE
.SBTTL RDCRC1-RECEIVING FIRST DDCMP DATA CRC
;+
;
; R E C E I V I N G F I R S T D D C M P D A T A C R C
;
; ENTERED FROM: RDDATA
;
; INPUTS:
;
; OUTPUTS:
; RECEIVE STATE POINTER IS SET TO PROCESS SECOND DATA CRC
;-
RDCRC1:
;SET RECEIVE STATE POINTER TO SECOND DATA CRC PROCESSOR
BRWRTE IMM,D.RPTR ;ADDRESS D.RPTR (SINCE IT WAS CHANGED IN
LDMA BR,ADD,SP.RM0 ;THE PREVIOUS STATE)
RSTATE RDCRC2
ALWAYS TIMRTN ;RETURN TO TIMER
.SBTTL RDCRC2-RECEIVING SECOND DATA CRC
;+
;
; R E C E I V I N G S E C O N D D A T A C R C
;
; ENTERED FROM: RCVDON
;
; INPUTS:
; BR = HIGH BYTE OF CSR2 (SP.RST - RECEIVE CHARACTER STATUS)
; OUTPUTS:
; IF A CRC ERROR IS DETECTED ON THE CURRENT MESSAGE,A CONTROL OUT IS GENERATED.
; IF THE MESSAGE IS GOOD, MSGIN ROUTINE IS EXECUTED TO PROCESS IT
;-
RDCRC2:
; CHECK FOR CRC ERROR
BR4 MSGIN ;CRC OK,USE COMMON CODE
ALWAYS ERR12 ;***CRC ERROR ON DATA***
;+
;
; RETURN TO TIMER LOOP FROM RECEIVE STORE ROUTINES
;
; ENTERED FROM: RCVEXT (SUBR RETURN)
;
; INPUTS:
; NPR STARTED EARLIER IN STORE RECVD CHAR ROUTINES
;
; OUTPUTS:
; WAIT FOR NPR TO COMPLETE AND RETURN TO TIMER
;-
.IIF NE <NPRWP1-START>/1000-1 .ERROR ;NPRWP1 IS NOT ON PAGE ONE
NPRWP1:
BRWRTE IBUS,NPR ;READ NPR CONTROL REGISTER
BR0 NPRWP1 ;NOT DONE YET
ALWAYS TIMRTN ;RETURN TO TIMER LOOP
.SBTTL DSRCHG-DATA SET READY CHANGE
;+
; **DSRCHG-ROUTINE TO GIVE A DATA SET READY CHANGE CONTROL OUT**
;
; CALLED BY: TIMER
;
; INPUTS:
; SP0 = IMAGE OF DUP'S CSR 1 (DSR=BIT 1)
; MAR = D.STS
;
; OUTPUTS:
; MAR = D.STS
; D.STS (BIT 1) = CURRENT SETTING OF DSR
;-
DSRCHG:
.IIF NE DS.DSR-SP2 .ERROR DS.DSR ;DS.DSR NO LONGER EQUALS SP2
SP IMM,DS.DSR,SP2 ;GET MASK FOR DSR INTO SP2
MEM MEMX,AXORB,SP2 ;RECORD THE CURRENT STATE OF DSR
;IF IT WAS SET CLEAR IT, IF IT WAS CLEAR
;SET IT
CALLSR SP.SUB,COUTX,TIMRP3,ER.DSR ;QUEUE A CONTROL OUT AND
;RETURN TO TIMER LOOP
.SBTTL MSGIN-DDCMP MESSAGE PROCESSOR
;+
;
; D D C M P M E S S A G E I N
;
; ENTERED FROM: RDCRC2(NUMBERED), RHCRC2(UNNUMBERED)
;
; A COMPLETE DDCMP MESSAGE (NUMBERED OR UNNUMBERED) HAS BEEN RECEIVED WITHOUT
; A CRC ERROR.PROCESS IT.
;
; INPUTS:
; MAR = RECEIVE STATE POINTER (D.RPTR)
;
; OUTPUTS:
; RECEIVE STATE RESET TO FIRST HEADER CHAR.
; IF MESG IS FOR US, POST A BA OUT.
; ELSE, RESET BUFFER POINTERS IN LINE TABLE.
;-
MSGIN:
; INITIALIZE RECEIVE STATE POINTER
RSTATE RDH1
; CHECK IF THIS MESSAGE IS TO BE IGNORED
BRWRTE SELA,SP.STS ;SET BR=SP.STS
BR4 10$ ;IGNORE CURRENT MESSAGE
; MESSAGE IS WITHOUT ERROR AND ADDRESSED TO THIS STATION. GENERATE A BA OUT
CALLSR SP.SB1,EOFMSG,MSGIN1 ;POST THE COMPLETION AND RETURN TO MSGIN1
;CURRENT MESSAGE IS NOT FOR THIS STATION,IGNORE IT
10$:
; RECEIVE BUFFER ADDRESS AND BYTE COUNT WAS ADVANCED AT THE BEGINNING OF
;THIS MESSAGE, RESET IT.
BRWRTE IMM,D.ORBC ;ADDRESS D.ORBC
LDMA BR,ADD,SP.RM0
;SAVE ORIGINAL PARAMETERS IN SCRATCH PADS
SP MEMI,SELB,SP2 ;SAVE ORIGINAL BYTE COUNT IN SP2,3
SP MEMI,SELB,SP3
SP MEMI,SELB,SP4 ;SAVE ORIGINAL ADDRESS IN SP4,SP5&SP0
SP MEMI,SELB,SP5
SP MEMI,SELB,SP0
;*** -5 V1.1
;RESTORE THEM INTO CURRENT PARAMETERS USING NXDSCP CODE ;*** +1 V1.1
BRWRTE IMM,D.RDP ;SET UP SP6 FOR NXDSCP ;*** +1 V1.1
BRWRTE BR,ADD,SP.RM0 ; ;*** +1 V1.1
SP BR,SELB,SP6 ; ;*** +1 V1.1
CALLSB SP.SB1,NXDSC1 ; ;*** +1 V1.1
;CHECK IF Q-SYNC BIT SET
.IIF NE <MSGIN1-START>/1000-2 .ERROR ;MSGIN1 IS NOT ON PAGE TWO
MSGIN1:
BRWRTE TWOA,SP.STS ;READ STATUS REGISTER
;(2 LINES REPLACED) **X1.2**
BR7 RSNCRT ;RESYNC RECEIVER AND RETURN TO TIMER **X1.2**
ALWAYS TIMRTN ;RETURN TO TIMER **X1.2**
.SBTTL KILLAL-KILL XMT OT RCV OPERATION
;+
;
; KILL RECEIVE OR TRANSMIT BUFFERS
;
; CALLED BY: BAIN
;
; INPUTS:
; BSEL2<2> (OCON) =IN I/O (1=RECV, 0=XMIT)
; BSEL7<5> (PORT4)=KILL ASSIGN
;
; OUTPUTS:
; DEASSIGNS EITHER TRANSMIT OF RECEIVE BUFFERS DEPENDING ON THE IN I/O BIT.
; IF ASSIGNMENT IS REQUESTED(KILL ASSGN), BAIN IS RETURNED TO .
; ELSE IT RETURNS DIRECTLY TO RDICLR.
;-
KILLAL:
;DETERMINE WHETHER THE TRANSMIT OR RECEIVE OPERATION IS TO BE KILLED
BRWRTE IBUS,OCON ;GET BSEL2
BRSHFT
BR1 KILLRC ;KILL RECEIEV OPERATION
;KILL TRANSMIT OPERATION
KILLXM:
BRWRTE IMM,D.XSTS ;POINT TO TRANSMIT STATUS BYTE
LDMA BR,ADD,SP.RM0 ; LOAD THE MAR
;(1 LINE REMOVED) **X1.2**
MEM IMM,DT.ABT!DT.AB1 ;SET ABORT PENDING FLAGS
;(1 LINE REMOVED) **X1.2**
BRWRTE IMM,C.CLOX ;SET CONTROL OUT FOR XMT
ALWAYS KILCOM ;USE COMMON CODE
;KILL RECEIVE OPERATION
KILLRC:
CALLSB SP.SB1,RESYNC ;RESYNC RECEIVER
BRWRTE IMM,C.CLOR ;SET CONTROL OUT FOR RECEIVE
KILCOM:
SP BR,SELB,SP2 ;SAVE BSEL2 IMAGE
BRWRTE IMM,ER.KIL ;REASON CODE 'KILL'
SP BR,SELB,SP3 ;INTO SP3
CALLSB SP.SB1,COUT ;QUEUE CONTROL OUT
;*****FOLLWING INSTRUCTION MUST BE IN PAGE 2 DUE TO RETURN FROM COUT****
KILLC1:
BRWRTE IMM,<D.RBDF-D.RDP> ;ADDRESS FLAGS BYTE
LDMA BR,ADD,SP6
MEM IMM,<DX.EOM!DX.LST> ;CLEAR ALL BUFFER ASSIGN FLAGS
BRWRTE IBUS,PORT4 ;GET NEW PORT4 BACK
BRSHFT
BR4 BAIN0 ;NEW BUFFER ASSIGNED
RQICR2: ALWAYS RQICL2 ;NO NEW BUFFER
;******FOLLOWING INSTRUCTIONS MUST RESIDE IN PAGE TWO SINCE IT IS USED BY
.IIF LT <<.-START/1000>-2> .ERROR ;THE FOLLOWING LABELS ARE OFF PAGE 2
; CERTAIN SUBROUTINES TO RETURN TO THE PROPER PAGE OF CALLER******
;RETURN TO TIMER FROM RECEIVE ROUTINES
TIMRP2: ALWAYS TIMRTN
;RETURN FROM CONTROL OUT DUE TO A CALL FROM RERROR
RERRP2: ALWAYS ERREXT
;A RETURN FROM DECDCC DUE TO A CALL FROM RDDATA
DECP2: ALWAYS RDATA1
.IIF GT <<.-START-2>/1000>-2> .ERROR ;THE ABOVE LABELS ARE OFF PAGE 2
.SBTTL XMTSYN - TRANSMIT SYNC'S OR ZERO BITS
; FILE XMTAUX.MAC
;+
; **XMTSYN-RESYNC TRANSMITTER REQUESTED**
;
; CALLED BY: XMTDON
;
; INPUTS:
; OUTPUT NPR ADDRESS = DUP'S CSR4
; SP0 = FLAGS BYTE OF XMIT DESCRIPTOR
; MAR = FLAGS BYTE OF XMIT DESCRIPTOR
;
; OUTPUTS:
; BIT STUFF MODE - 16 ZERO BITS ARE TRANSMITTED
; DEC MODE - SYNC CHARACTERS ARE TRANSMITTER
;-
XMTSYN:
BRWRTE SELA,SP.STS ;GET THE STATUS BYTE
BRSHFT ;SHIFT THE STATUS RIGHT
BR4 80$ ;DEC MODE (DDCMP)
BRWRTE IMM,0 ;ZERO THE BRG
OUTPUT BR,SELB,OUTDA1 ;ZERO THE LOW BYTE OF OUT DATA
OUTPUT IMM,DUPTSM!DUPTEM,OUTDA2 ;SET BOTH START OF MESSAGE AND END OF MESSAGE
75$: BRWRTE IMM,377-DX.SYN ;MASK TO CLEAR RESYNC FLAG
MEM BR,AANDB,SP0 ;CLEAR IT AND WRITE NEW FLAGS WORD TO RAM
ALWAYS WRTRT ;INCREMENT OUTPUT ADDRESS BY 2,
;DO AN NPR AND RETURN TO TIMER LOOP
80$: BRWRTE IMM,SYNC ;GET SYNC CHARACTER
OUTPUT BR,SELB,OUTDA1,INCMAR ;WRITE IT TO LOW BYTE OF OUT DATA
BRWRTE IMM,DUPTSM ;START OF MESSAGE BIT
OUTPUT BR,SELB,OUTDA2,INCMAR ;WRITE IT TO HIGH BYTE
;MAR IS NOW AT D.SYNC (SYNC COUNTER)
SP MEMX,SELB,SP1 ;READ SYNC COUNTER INTO THE SCRATCH PAD
MEM DECA,SP1 ;DECREMENT THE COUNT
C WRTRT ;COUNT NOT ZERO YET - DO THE NPR
;AND RETURN TO THE POLLING LOOP
BRWRTE IMM,D.XBDF ;ADDRESS OF FLAGS BYTE IN XMIT DESCRIPTOR
LDMA BR,ADD,SP.RM0 ;RESET THE MAR TO FLAGS BYTE
ALWAYS 75$ ;CLEAR RESYNC FLAG
.SBTTL XMTCNT - DECREMENT TRANSMIT BYTE COUNT
;+
; **XMTCNT-DECREMENT XMIT COUNT RETURN
; **XMTBCZ-ZERO BYTE COUNT**
;
; CALLED BY: XMTDON
;
; INPUTS:
; INPUT AND OUTPUT ADDRESS = DUP'S CSR 4
; SP0 = D.XBDF (FLAGS BYTE)
;
; OUTPUTS:
; RETURN TO XMTDON IF BYTE COUNT NOT ZERO.
; ELSE: UNDERRUN CHECKED
; EOM SENT IF SET IN BUFFER DESC
; BUFFER ADDR OUT QUEUED.
; IF ANOTHER BUFFER IS THERE, RETURN TO XMTDON TO XMIT
; ELSE, RETURN TO TIMER
;-
; THE LABEL XMTCNT MUST RESIDE IN PAGE 2
.IIF NE <XMTCNT-START/1000-2> .ERROR ;PAGE 2 RELOCATION ERROR - XMTCNT
; TRANSMIT DECREMENT COUNT ROUTINE RETURNS HERE
XMTCNT: C XMTDN2 ;BYTE COUNT NOT ZERO
;BYTE COUNT ZERO - FALL INTO XMTBCZ
.ENABLE LSB
XMTBCZ:
BRWRTE IBUS,INDAT2 ;READ HIGH BYTE OF CSR4
BR7 XMTUNR ;UNDERRUN
BRWRTE BR,SELA!SP0 ;READ THE FLAGS WORD INTO THE BRG
BR1 160$ ;END OF MESSAGE SET
XMTBC0:
100$: CALLSB SP.SB1,BAOX ;DO A BUFFER ADDRESS OUT COMPLETION
;***NOTE*** BAOX MUST NOT DESTROY THE
;OUTPUT BUFFER ADDRESS CURRENTLY SET AT
;THE DUP'S CSR 4 OR 6
XMTBC1:
BRWRTE IMM,374 ;RESET OUT BA TO POINT TO CSR4
SP IBUS,IOBA1,SP0 ;READ OLD BA WHICH WAS CSR4 OR 6
OUTPUT BR,AANDB,OBA1 ;SET CSR4 OFFSET
BRWRTE IMM,D.XBDF ;ADDRESS OF TRANSMIT FLAGS WORD
LDMA BR,<ADD!SP.RM0> ;POINT TO FLAGS WORD
SPBR MEMX,SELB,SP0 ;READ THE FLAGS WORD TO THE BRG
BROTAT ;ROTATE IT RIGHT
BR4 XMTDN4 ;ANOTHER BUFFER - SEND NEXT CHARACTER
; NO MORE BUFFER'S ASSIGNED. IF THE PREVIOUS BUFFER HAD THE END OF MESSAGE
; FLAG SET THEN SHUT DOWN THE TRANSMITTER, OTHERWISE, WAIT FOR THE NEXT
; BUFFER OF THE MESSAGE TO BE ASSIGNED.
; IF IN BIT-STUFF MODE DON'T ABORT INSTEAD IDLE FLAGS BY NOT CLEARING
; DUPSND AND DUPTEM BITS.
BR0 110$ ;END OF MESSAGE FLAG SET **X1.2**
ALWAYS TIMRT3 ;NOT THE END OF MESSAGE - EXIT
110$: BRWRTE SELA,SP.STS ;DDCMP MODE? **X1.2**
BRSHFT ; **X1.2**
BR4 170$ ;YES, PAD THE MESSAGE **X1.2**
ALWAYS TIMRT3 ;NO, JUST IGNORE ABORTING **X1.2**
.SBTTL XMTABT - TRANSMIT ABORT PENDING
;+
; **XMTABT-TRANSMIT ABORT PENDING
;
; CALLED BY: XMTDON
;
; INPUTS:
; BRG = XMIT STATUS (D.XSTS)
; MAR = D.XSTS
; OUTPUTS:
; IF STAGE ONE, GOTO XMTAB1 TO TRANSMIT ABORT CHARS
; STAGE TWO, CHECKS FOR ASSIGNED BUFFERS.
; IF NONE, DUP SEND IS CLEARED.
;-
XMTABT:
BR1 XMTAB1 ;STAGE ONE OF ABORT PENDING
MEM IMM,0 ;CLEAR ABORT PENDING FLAG
BRWRTE IMM,D.XBDF ;OFFSET TO TRANSMIT BUFFER FLAGS
LDMA BR,ADD,SP.RM0 ;ADDRESS IT
BRWRTE MEMX,SELB ;READ THE FLAGS
BRSHFT ;SHIFT THEM RIGHT
BR4 XMTDN3 ;BUFFER ASSIGNED, START NEXT MESSAGE
;BUFFER NOT ASSIGNED, CLEAR SEND
120$: SP IMM,0,SP0 ;MASK TO CLEAR SEND
;FALL INTO XMTSND
.SBTTL XMTSND - SET OR CLEAR DUP SEND
;+
; **XMTSND-ROUTINE TO SET OR CLEAR SEND IN THE DUP
;
; CALLED BY: XMTDON
; ENTERED FROM: XMTABT
;
; INPUTS:
; SP0 = MASK TO SET OR CLEAR SEND
; SP.STS = D.STS
;
; OUTPUTS:
; START NPR TO CHANGE SEND AND RETURN TO XMTDON
;
;-
XMTSND:
BRWRTE IMM,DS.HDX ;MASK FOR HALF DUPLEX
BRWRTE BR,AANDB,SP.STS ;ISOLATE HALF DUPLEX FLAG
OUTPUT BR,AORB,OUTDA1 ;STORE "SEND" MASK IN OUT DATA LOW BYTE
XMTSN0:
BRWRTE IMM,DATOB ;MASK TO DO A BYTE OUT NPR
ALWAYS XMTDN6 ;START THE NPR AND RETURN TO TIMER LOOP
;+
; END OF MESSAGE FLAG SET - SEND A EOM
; CALLED BY: XMTBCZ
;-
160$: BRWRTE IMM,DUPTEM ;SET TRANSMIT END OF MESSAGE
OUTPUT BR,SELB,OUTDA2 ;SAVE FLAG IN OUT DATA HIGH BYTE
CALLSR SP.SUB,IC2OUT,XMTEM0 ;WRITE IT OUT TO THE DUP
;AND RETURN TO XMTBC0
;+
; END OF MESSAGE SET AND NO MORE BUFFER ASSIGNED - SEND PADS
; THIS FILLS THE DUP SILO SO THE EOM CHAR GETS TO THE LINE
; USE ABORT SEQUENCE TO SEND TWO PAD(377) CHARS.
; ENTERED FROM: XMTBCZ
;-
170$: BRWRTE IMM,D.XSTS ;ADDRESS TRANSMIT STATUS BYTE
LDMA BR,ADD,SP.RM0 ;SET THE MAR
MEM IMM,DT.ABT!DT.AB1 ;SET UP FOR AN ABORT
ALWAYS TIMRT3 ;RETURN TO TIMER LOOP
;+
; UNDERRUN ERROR
; CALLED FROM: XMTBCZ
;-
XMTUNR:
BRWRTE IMM,ER.UNR ;TRANSMIT UNDERRUN ERROR CODE
SP BR,SELB,SP3 ;SAVE IT IN SP3 FOR SUBROUTINE
CALLSR SP.SB1,COUX,XMTBC1,C.CLOX ;DO A CONTROL OUT
;AND RETURN TO XMTBC1
.DSABL LSB
.SBTTL XMTAB1 - TRANSMIT ABORT STAGE ONE
;+
; **XMTAB1-ROUTINE TO PERFORM A TRANSMIT ABORT
;
; ENTERED FROM: XMTABT
;
; INPUTS:
; INPUT AND OUTPUT ADDRESS = DUP'S CSR 4
; MAR = D.XSTS
; SP0 = (D.XSTS)
;
; OUTPUTS:
; D.XSTS IS DECREMENTED
; AN ABORT CHARACTER IS SENT
;
; D.XSTS LOW ORDER BITS WERE SET TO 11, XMTABT WILL BRANCH HERE IF
; BIT 1 IS SET. THUS TWO ABORT CHARS GET SENT.
;-
XMTAB1:
MEM DECA,SP0 ;ONE LESS ABORT TO SEND
;(2 LINES REPLACED) **X1.2**
BRWRTE IMM,377 ;SEND PAD CHARACTER **X1.2**
OUTPUT BR,SELB,OUTDA1 ;MOVE IT TO OUT DATA **X1.2**
BRWRTE SELA,SP.STS ;DDCMP MODE? **X1.2**
BRSHFT ; POSITION BIT **X1.2**
BR4 10$ ;YES, USE PAD CHARACTER **X1.2**
BRWRTE IMM,DUPTAB!DUPTEM ;NO, USE DUP ABORT AND EOM BITS **X1.2**
5$: OUTPUT BR,SELB,OUTDA2 ; (THE EOM ENSURES IDLING FLAGS LATER) **X1.2**
ALWAYS WRTRT ;RETURN TO XMTDON TO DO THE NPR
10$: BRWRTE IMM,DUPTAB!DUPTSM;ALSO SET ABORT AND START OF MESSAGE **X1.2**
ALWAYS 5$ ; **X1.2**
.PAGE
.SBTTL STORE-STORE RECEIVED CHARACTER IN CORE
; FILE DUPSTORE.MAC
;+
;
; S T O R E R E C E I V E D C H A R A C T E R
;
; ENTERED FROM: RECEIVE STATE ROUTINES
;
; INPUTS:
; SP.CHR=CURRENT RECEIVED CHARACTER
;
; OUTPUTS:
; A WORD TRANSFER IS MADE TO THE USER BUFFER IN PDP-11 CORE WHEN
; A PAIR OF CHARACTERS ARE RECEIVED. ANY CHARACTER DESTINED FOR AN EVEN CORE
; BUFFER ADDRESS IS LOCALLY BUFFERED UNTIL THE NEXT CHARACTER IS RECEIVED.HOWEVER,
; BYTE TRANSFERS ARE SOMETIMES MADE DURING CERTAIN MESSAGE AND BUFFER BOUNDRY
; CONDITIONS.
;-
STORE:
;CHECK IF A RECEIVE BUFFER IS AVAILABE
BRWRTE IMM,D.RBDF ;ADDRESS D.RBDF
LDMA BR,ADD,SP.RM0
SPBR MEMX,SELB,SP2 ;LOAD IT INTO BR AND SP2
BRSHFT
BR4 10$ ;BUFFER AVAILABLE
; A CHARACTER IS RECEIVED,BUT THERE IS NO RECEIVE BUFFER TO STORE IT
BRADDR TIMRP2 ;ULTIMATE RETURN FROM RESYNC
SP BR,SELB,SP.SB1 ;SAVE IT IN RETURN SCRATCH PAD
CALLSR SP.SUB,COUTX,RESYNC,ER.NBA ;Q PORT DATA AND RETURN TO TIMER
;NOTE: A REGULAR CONTROL OUT IS NOT SENT BECAUSE IT MODIFIES PDP-11
;MEMORY ADDRESSED BY CURRENT DESCRIPTOR POINTER. SINCE THE DESCRIPTOR
;POINTER IS INVALID AT THIS TIME, THIS IS PROHIBITED.
10$:
; DECREMENT RECEIVE BYTE COUNT
CALLSB SP.SUB,DRCNT
; NOTE: DRCNT DECREMENTS THE BYTE COUNT AND STORES IT BACK INTO RAM.
C CHKODD ;BRANCH IF COUNT NOT -1
;CURRENT BUFFER IS FULL,SO SEND BA OUT ETC BEFORE PROCESSING CURRENT CHARACTER
EOFBUF:
SPBR MEMX,SELB,SP2 ;GET THE LOW BYTE OF THE BUFFER ADDRESS
BR0 5$ ;BUFFER ENDED ON AN ODD ADDRESS THEREFORE
;THE LAST RECEIVE CHARACTER IS STILL IN THE
;KMC RAM AND IT MUST BE WRITTEN OUT
;
; OTHERWISE ALL RECEIVE DATA HAVE BEEN WRITTEN TO THE BUFFER
;
ALWAYS 10$
;
5$:
CALLSB SP.SUB,SETRBA ;SET OUTBA TO CURRENT INPUT ADDRESS IN REC BUFF
BRWRTE BR,DECA,SP2 ;BUFFER ADDRESS MUST BE DECREMENTED TO POINT
;TO EVEN BYTE ADDRESS
OUTPUT BR,SELB,OBA1 ;RESET IT
BRWRTE IMM,DATOB,INCMAR ;MASK TO DO A BYTE TRANSFER
;MAR NOW POINT TO D.ERC
OUTPUT MEMX,SELB,OUTDA1 ;GET THE EVEN RECEIVE CHARACTER
OUT BR,SELB,ONPR ;START THE NPR
10$:
BRADDR STORE ;SET UP RETURN ADDRESS TO STORE
SP BR,SELB,SP.SB1
20$: BRWRTE IBUS,NPR ;IN CASE AN NPR WAS STARTED WAIT FOR IT TO COMPLETE
BR0 20$ ;WAIT UNTIL DONE
ALWAYS BAORC ;SEND BAOUT FOR RECEIVE BUFFER COMPLETEION
;NOTE: ORIGINAL INPUT PARAMETERS TO STORE MUST BE INTACT AT THIS POINT
; CHECK IF CURRENT RECEIVE BUFFER ADDRESS IS ODD
CHKODD:
BRWRTE MEMX,SELB ;GET LOW BYTE OF BUFFER ADDR INTO BR
;MAR NOW POINT TO HIGH ADDR BYTE
BR0 STRODD ;BRANCH IF RECEIVE BUFFER ADDRESS IS ODD
; CURRENT RECEIVE BUFFER ADDRESS IS EVEN
STREVN:
;
; SP2 CONTAINS THE IMAGE OF D.RBDF
; MAR POINTS TO LOW BYTE OF BUFFER ADDRESS
;
INCMA ;MAR NOW POINTS TO HIGH BYTE OF ADDRESS
; CLEAR "FIRST CHARACTER IN BUFFER" INDICATOR
BRWRTE IMM,<377-DR.FST>,INCMAR ;MASK TO CLEAR DR.FST
;MAR POINT TO FLAGS BYTE
MEMINC BR,AANDB,SP2 ;CLEAR DR.FST
;MAR POINTS TO D.ERC
; STORE THE CURRENT RECEIVE CHARACTER IN LOCAL BUFFER
MEM SELA,SP.CHR ;STORE REC'D CHARACTER IN D.ERC
ALWAYS RCVEXT
; CURRENT RECEIVE BUFFER ADDRESS IS ODD
STRODD:
;
; SP2 CONTAINS THE IMAGE OF D.RBDF
; MAR POINTS TO LOW BYTE OF RECEIVE BUFFER ADDRESS
CALLSB SP.SUB,SETRBA ;SET OUTBA TO CURRENT INPUT ADDRESS IN REC BUFF
; LOAD ODD (CURRENT) CHARACTER INTO OUTDATA HB
BRWRTE BR,SELA,SP.CHR,INCMAR ;MOVE CHARACTER INTO BR FIRST
;MAR NOW POINTS TO D.ERC
OUTPUT BR,SELB,OUTDA2 ;NOW MOVE IT INTO OUTDATA 15:8
OUTPUT MEMX,SELB,OUTDA1 ;LOAD EVEN RECEIVE CHARACTER INTO OUTDATA 7:0
; CHECK IF THE CURRENT ODD CHARACTER IS DESTINED FOR FIRST LOCATION OF BUFFER
BRWRTE MEMX,SELA,SP2 ;LOAD IMAGE OF D.RBDF INTO BR
BR0 10$ ;BRANCH IF FIRST CHARACTER OF BUFFER
; CURRENT CHARACTER IS DESTINED FOR ODD CORE ADDRESS AND IS NOT THE FIRST
;CHARACTER IN THE BUFFER. THEREFORE IT IS SAFE TO DO A WORD TRANSFER.
BRWRTE IMM,DATO ;MASK TO START WORD OUT NPR
ALWAYS 20$ ;DO NPR AND EXIT
;NOTE: DURING THE ABOVE WORD NPR, THE CORE ADDRESS IS ODD. THE HARDWARE SHOULD
;AUTOMATICALLY IGNORE BIT0 OF CORE ADDRESS.
; CURRENT RECEIVED CHARACTER IS DESTINED FOR AN ODD CORE ADDRESS.
;BUT THIS ADDRESS HAPPENS TO BE THE FIRST LOCATION OF THE CURRENT BUFFER.
;THEREFORE DO A BYTE TRANSFER.
10$:
BRWRTE IMM,DATOB ;MASK TO SEND ONE BYTE(ODD CHARACTER)
20$:
OUT BR,SELB,ONPR ;START NPR
;NOTE: NPR COMPLETION IS CHECKED FOR AFTER
;RETURN FROM INCMEM
;FALL INTO RCVEXT
; COMMON EXIT FROM STORE ROUTINE
RCVEXT:
;INCREMENT RECEIVE BUFFER POINTER
; ADDRESS D.RBDA
BRWRTE IMM,D.RBDA
LDMA BR,ADD,SP.RM0
; INCREMENT MEMORY LOCATIONS
CALLSR SP.SUB,INCMEM,NPRWP1,1 ;INCREMENT MEMORY & RETURN
;TO WAIT FOR NPR COMPLETION
.SBTTL EOFMSG-END OF MESSAGE
;+
;
; E N D O F R E C E I V E D M E S S A G E
;
; CALLED BY: RBDONE(BIT STUFF), MSGIN(DDCMP)
;
;INPUTS:
; SP.SB1=RETURN ADDRESS
; D.RBD=CURRENT INPUT ADDRESS
;OUTPUTS:
; STORES IN RECEIVE BUFFER ANY RESIDUAL EVEN CHARACTER THAT IS SAVED
; IN THE LOCAL BUFFER (D,ERC)
; GENERATES A BAOUT. ULTIMATE RETURN TO LOCATION SPECIFIED BY SP.SB1
;-
EOFMSG:
;CHECK IF THE LAST RECEIVED CHARACTER WAS EVEN
BRWRTE IMM,D.RBDA ;SET TO POINT TO BUFFER ADDRES
LDMA BR,ADD,SP.RM0 ;SET THE MAR
SPBR MEMX,SELB,SP2 ;READ THE LOW BYTE OF THE ADDRESS
BR0 10$ ;BRANCH IF ODD
; CURRENT RECEIVE BUFFER IS EVEN,THAT MEANS LAST RECEIVED CHARACTER WAS
;DESTINED FOR AN ODD ADDRESS AND ALREADY BEEN TRANSFERED TO RECEIVE
;BUFFER.
ALWAYS BAORE ;SEND BAOUT
;CURRENT RECEIVE BUFFER ADDRESS IS ODD. THEREFORE THE PREVIOUS CHARACTER
;DESTINED FOR AN EVEN ADDRESS IS STORED LOCALLY. TRANSFER IT TO CORE
10$:
CALLSB SP.SUB,SETRBA ;SET RECEIVE BUFFER ADDRESS
BRWRTE DECA,SP2,INCMAR ;DECREMENT ADDRESS TO GET EVEN BYTE
;MAR POINTS TO D.ERC
OUTPUT BR,SELB,OBA1 ;PUT ADDR IN THE OBA REG
OUTPUT MEMX,SELB,OUTDA1 ;LOAD EVEN CHAR INTO OUT DATA
BRWRTE IMM,DATOB ;WRITE OUT RESIDUAL EVEN RECEIVED
OUT BR,SELB,ONPR ;INTO CORE
20$: BRWRTE IBUS,NPR ;AND WAIT FOR NPR TO COMPLETE
BR0 20$
;FALL INTO BAORE
.SBTTL BAORE-BA OUT FOR END OF RECEIVED MESSAGE
;+
;
; B A O U T F O R E N D O F R E C E I V E D M E S S A G E
;
; ENTERED FROM: EOFMSG
;
;INPUTS:
; SP.SB1=RETURN ADDRESS
;
;OUTPUTS:
; INPUT PARAMETERS FOR BOUT ARE SET UP
; BOUT IS EXECUTED
;-
BAORE:
;SET SP3 TO INDICATE END OF MESSAGE
BRWRTE IMM,EOM
SP BR,SELB,SP3
;SET SP2 TO INDICATE BAOUT FOR RECEIVE OPERATION
BRWRTE IMM,C.BAOR
; FOLLOWING CODE IS SHARED WITH THE ERROR ROUTINES IN DUPERR
ENTRY2:
SP BR,SELB,SP2
;SET SP6=ADDRESS OF D.RDP
BRWRTE IMM,D.RDP ;BR=D.RDP
BRWRTE BR,<ADD!SP.RM0> ;BR=ADDRESS OF D.RDP/D.XDP
SP BR,SELB,SP6 ;SP6=BR
;FALL INTO BOUT/COUT
.SBTTL BOUT/COUT-BA OR CONTROL OUT (WITH DESCRIPTOR UPDATED)
;+
;
; B A O R C O N T R O L O U T
; (CURRENT DESCRIPTOR IS UPDATED)
;
; THIS IS COMMON CODE SHARED BY THOSE BAOUT ROUTINES AND CONTROL OUT
;ROUTINES THAT REQUIRE AN UPDATE OF BYTE COUNT IN THE RECEIVE OR TRANSMIT
;DESCRIPTORS.
;
; ENTERED FROM: BAORE
; CALLED BY: KILLAL
;
;INPUTS:
; SP.SB1 -RETURN ADDRESS.
; SP2 -CODE TO INDICATE BAOUT OR CONTROL OUT (KMC CSR2 IMAGE)
; SP3 -ERROR CODE
; SP6 -ADDRESS OF D.RDP(RECEIVE) OR D.XDP(TRANSMIT)
;
;OUTPUTS:
; BYTE COUNT IN THE CURRENT TRANSMIT OR RECEIVE DESCRIPTOR IS UPDATED
;BY SUBTRACTING THE CONTENTS OF D.RBDC OR D.XBDC FROM IT.
;SP4,SP5,SP6 ARE LOADED WITH THE CURENT DESCRIPTOR ADDRESS AND QPDATA
;ROUTINE IS EXECUTED.
;-
BOUT:
COUT:
;SET OUBA TO CURRENT DESCRIPTOR
LDMA SELA,SP6 ;ADDRESS DESCRIPTOR ADDRESS POINTER
OUTPUT MEMI,SELB,OBA1 ;ADDRESS 7:0
OUTPUT MEMI,SELB,OBA2 ;ADDRESS 15:8
SP IBUS,UBBR,SP0 ;GET CURRENT BUS REQ REG
BRWRTE IMM,101 ;CLEAR ALL BUT VEC XX4,NXM
SP BR,AANDB,SP0
SP MEMX,SELB,SP1 ;GET FLAGS BYTE (MEM EXT BITS) **V0.10**
BRWRTE IMM,14 ;EXTRACT MEM EXT BITS
BRWRTE BR,AANDB,SP1 ;MASK OFF ALL OTHER BITS
OUT BR,AORB,OBR ;LOAD EXT ADDRESS BITS
;SUBTRACT CURRENT BYTE COUNT FROM ORIGINAL BYTE COUNT TO GET # OF CHARACTERS
;RECEIVED/TRANSMITTED IN THIS BUFFER
BRWRTE IMM,<D.ORBC-D.RDP> ;ADDRESS ORIGINAL BUFFER COUNT
LDMA BR,ADD,SP6
SP MEMI,SELB,SP0 ;AND SAVE IT IN SP0
SP MEMX,SELB,SP1 ;AND HIGH BYTE INTO SP1
BRWRTE IMM,<D.RBDC-D.RDP> ;ADDRESS CURRENT COUNT
LDMA BR,ADD,SP6
OUTPUT MEMI,SUB,OUTDA1 ;OUTDA1=ORG 7:0-CUR7:0
BRWRTE MEMI,SUBC,SP1 ;BR=ORG15:8-CUR15:8
OUTPUT BR,SELB,OUTDA2,INCMAR ;STORE IT IN OUTDATA 1 **V0.11**
;OUTDATA NOW CONTAINS THE NUMBER OF CHARACTERS TRANSFERED FROM/TO
;THE CURRENT BUFFER
; WRITE IT INTO CURRENT DESCRIPTOR
BRADDR BOUTR0 ;RETURN ADDRESS INTO BR **V0.11**
SP BR,SELB,SP.SUB,INCMAR ;SAVE IN SP.SUB (MAR = FLAGS)
BRWRTE MEMX,SELB ;READ FLAGS
BRSHFT ;SHIFT RIGHT
BR4 IC2OUT ;IF BUFFER ASSIGNED, WRITE NEW BC
ALWAYS QPDATA ;OTHERWISE DON'T (CAN GET HERE FROM
;KILL CODE WITH NO BUFFER ASSIGNED) **V0.11**
;CURRENT DESCRIPTOR IS NOW COMPLETELY UPDATED
.SBTTL BAORC-BA OUT FOR RECEIVE BUFFER COMPLETION
;+
;
; B A O U T F O R R E C E I V E B U F F E R C O M P L E T I O N
;
; CALLED BY: STORE
;
;INPUTS:
; SP.SB1=RETURN ADDRESS
;
;OUTPUTS:
; INPUT PARAMETERS FOR COUX ARE SET UP
; COUX IS EXECUTED
;-
BAORC:
;SET SP3 TO INDICATE END OF MESSAGE
BRWRTE IMM,0
SP BR,SELB,SP3
;SET SP2 TO INDICATE BAOUT FOR RECEIVE OPERATION
BRWRTE IMM,C.BAOR
SP BR,SELB,SP2
; SET SP6=ADDRESS OF D.RDP
BRWRTE IMM,D.RDP ;BR=D.RDP
ALWAYS ENTRY1 ;USE COMMON CODE IN COUX
.SBTTL COUTX-CONTROL OUT FOR TRANSMIT OPERATION
;+
;
; C O N T R O L O U T F O R X M T O P E R A T I O N S
;
; CALLED BY: DSRCHG,STORE,NXMERR
;
;INPUTS:
; SP.SUB=RETURN ADDRESS
; BRG =ERROR CODE
;OUTPUTS:
; A CONTROL OUT IS QUEUED WITH THE BUFFER DESCRIPTOR ADDRESS ZEROED.
;-
COUTX:
SP BR,SELB,SP3 ;SAVE ERROR CODE IN SP3
SPBR IMM,0,SP0 ;SET UP SCRATCH PADS FOR QPDATA
SP BR,SELB,SP1 ;..
SP BR,SELB,SP4 ;..
;SET SP2 TO INDICATE CONTROL OUT FOR XMT OPERATION
BRWRTE IMM,C.CLOX ;CSR2 IMAGE INTO SP2
SP BR,SELB,SP2
ALWAYS QPDAT1 ;QUEUE THE CONTROL OUT
.SBTTL BAOX/COUX-BA/CONTROL OUT FOR TRANSMIT BUFFER COMPLETION
;+
;
; B A O U T F O R X M T B U F F E R C O M P L E T I O N
;
;CALLED BY: XMTBCZ
;
;INPUTS:
; SP.SB1=RETURN ADDRESS
;
;OUTPUTS:
; INPUT PARAMETERS FOR QPDATA ARE SET UP
; A BUF ADDR OUT IS QUEUED.
;-
BAOX:
;SET SP3 TO INDICATE BUFFER COMPLETION
BRWRTE IMM,0
SP BR,SELB,SP3
;SET BRG TO INDICATE BA OUT FOR TRANSMIT OPERATION
BRWRTE IMM,C.BAOX
; FALL INTO COUX
;+
; **COUX-ROUTINE TO QUEUE A TRANSMIT CONTROL OUT WITH BUFFER ADDRESS**
;
; CALLED BY: XMTUNR
; ENTERED FROM: BAOX
;
; INPUTS:
; SP.SB1 = RETURN ADDR
; SP3 = ERROR CODE
; BRG = BSEL2 CODE (NORMALLY C.CLOX)
;
; OUTPUTS:
; PARAMETERS FOR QPDATA ARE SET UP
; SO A COMPLETION WILL BE QUEUED TO THE PDP-11
;-
COUX:
SP BR,SELB,SP2 ;PUT BSEL2 CODE IN SP2
;SET SP6=ADDRESS OF D.XDP
BRWRTE IMM,D.XDP ;BR=D.XDP
;COMMON CODE, USED BY BAORC ALSO
ENTRY1:
BRWRTE BR,ADD,SP.RM0 ;BR=ADDRESS OF D.RDP/D.XDP
SP BR,SELB,SP6 ;SP6=BR
; FALL INTO QPDATA
.SBTTL QPDATA-QUEUE PORT DATA
;+
;
; Q U E U E P O R T D A T A
;
; ENTERED AT QPDATA FROM: BOUT,COUX
; ENTERED AT QPDAT1 FROM: COUTX
;
; INPUTS:
; SP.SB1=RETURN ADDRESS
; SP.LN=LINE NUMBER
; SP2=CLO(R/T) TO SEND CONTROL OUT,=BAO(R/T) TO SEND BAOUT
; SP3 =ERROR CODE WITH THE ERROR BIT SET
; SP6 =ADDRESS OF D.RDP/D.XDP
;OUTPUTS:
; SIX BYTES OF CONTROL OUT DATA IS STUFFED INTO THE LOCAL COMPLETION SILO.
; ENTRY AT QPDATA: CALLER'S RETURN IN SP.SB1, EXECUTE STFSLO AND NXBUF
; ENTRY AT QPDAT1: CALLER'S RETURN IN SP.SUB, EXECUTE STFSLO AND RETURN
;-
QPDATA:
BRADDR NXBUF ;ADDRESS FOR STUFF SILO TO RETURN TO
SP BR,SELB,SP.SUB ;SAVE IT IN RETURN SCRATCH PAD
;GET CURRENT DESCRIPTOR ADDRESS INTO SCRATCH PADS
LDMA SELA,SP6 ;ADDRESS CURRENT DESCRIPTOR POINTER
SP MEMI,SELB,SP0 ;SP0=ADDRESS 7:0
SP MEMI,SELB,SP1 ;SP1=ADDRESS 15:8
SP MEMX,SELB,SP4 ;SP4=ADDRESS 17:16
; ADDRESS 'NEXT IN' LOCATION IN LOCAL SILO
QPDAT1:
LDMA IMM,P.SLIN ;ADDRESS NEXT IN POINTER
LDMAP IMM,P.SLIN
LDMA MEMX,SELB ;ADDRESS LOCATION POINTED TO BY P.SLIN
;STORE BYTE 0 WORD 1 INTO SILO
MEMINC SELA,SP.LN ;LOAD LINE NUMBER
MEMINC SELA,SP0 ;LOAD DESCRIPTOR ADDRESS 7:0
MEMINC SELA,SP1 ;LOAD DESCRIPTOR ADDRESS 15:0
MEM SELA,SP3 ;STORE ERROR CODE (FOR CONTROL OUT ONLY)
BRWRTE SELA,SP2 ;BUT IS THIS A CONTROL OUT?
BR0 10$ ;YES
MEM IMM,0 ;NO,CLEAR ERROR CODE
ALWAYS 20$
10$: BRWRTE IMM,0 ;CONTROL OUT,CLEAR SP3
SP BR,SELB,SP3
20$:
SP TWOA,SP4,INCMAR ;SHIFT EXT ADDRESS LEFT TO POSITION
SP TWOA,SP4
SP TWOA,SP4
SPBR TWOA,SP4
MEMINC BR,AORB,SP3 ;STORE EOM BIT AND EXT MEM BITS IF BA OUT
MEMINC SELA,SP2 ;CONTROL OUT OR BAOUT CODE
;FALL INTO STUFF SILO ROUTINE
.SBTTL STFSLO-STUFF COMPLETION SILO SUBROUTINE
;+
;
; S T U F F C O M P L E T I O N S I L O
;
; ENTERED FROM: QPDATA
;
; INPUTS:
; SP.SB1=ULTIMATE RETURN ADDRESS
; SP.SUB=RETURN FOR STUFF SILO
;
; THE THREE SILO WORDS MUST ALREADY BE IN RAM STARTING AT LOCATION
; POINTED TO BY P.SLIN.
;
; OUTPUTS:
; SILO POINTERS ARE UPDATED. IF THERE WAS A SILO OVERFLOW,BIT 16 OF
; THE FIRST WORD IS SET TO 1.
;-
STFSLO:
; CHECK IF SILO IS EMPTY OR FULL
LDMA IMM,<P.SLIN> ;GET NEXT IN
SP MEMI,SELB,SP0 ;INTO BR,SP0
BRWRTE MEMX,SELB ;AND NEXT OUT INTO THE BR
Z 30$ ;SILO IS EMPTY
COMP BR,SP0 ;NEXTIN=NEXT OUT?
Z 40$ ;YES,SILO IS FULL
; SILO IS NOT FULL
; INCREMENT NEXT IN BY ONE ENTRY LENGTH
10$:
LDMA IMM,<P.SLIN&377> ;MAR=ADDRESS OF NEXT IN POINTER
BRWRTE IMM,SILOED ;OFFSET OF LAST ENTRY
COMP BR,SP0 ;NEXT IN=LAST ENTRY IN SILO?
Z 20$ ;YES,WRAP NEXT IN
BRWRTE IMM,SENTRY ;BR=ONE ENTRY SIZE
MEM BR,ADD,SP0 ;INCREMENT P.SLIN BY ONE ENTRY SIZE
RTNSUB SP.SUB,P3 ;RETURN
; WRAP NEXT IN
20$: MEM IMM,P.NPR ;SET NEXT IN=P.NPR
RTNSUB SP.SUB,P3
; SILO IS EMPTY,SET NEXT OUT=NEXT IN
30$: MEM SELA,SP0 ;STORE NEXT IN P.SLOT
ALWAYS 10$ ;STORE ONE ENTRY
; SILO IS FULL, SET ERROR BIT IN CURRENT NEXT IN RAM LOCATION
40$:
LDMA SELA,SP0 ;LOAD MAR TO ADDRESS SILO ENTRY
SP IMM,200,SP0 ;LOAD ERROR CODE MASK
MEM MEMX,AORB,SP0 ;OR OVERRUN BIT ONTO LINE NUMBER
RTNSUB SP.SUB,P3
.SBTTL NXBUF-GET NEXT BUFFER
;+
; N E X T B U F F E R
;
; ENTERED FROM: STFSLO
;
; INPUTS:
; SP.SB1 =RETURN ADDRESS
; SP6 =ADDRESS OF D.RDP OR D.XDP
;
; OUTPUTS:
; 1) CURRENT DESCRIPTOR POINTER IS MODIFIED TO POINT
; TO THE NEXT DESCRIPTOR IN THE CURRENT LIST
; 2) IF NO MORE DESCRIPTORS ARE AVAILABLE IN THE CURRENT LIST,
; D.RDP/D.XDP IS SET TO POINT TO THE FIRST DESCRIPTOR IN THE ALTERNATE LIST.
; THE "ALTERNATE LIST ASSIGNED" BIT IS CLEARED
; 3) IF THE ALTERNATE LIST IS NOT ASSIGNED IN THE ABOVE CASE,THE"CURRENT
; LIST ASSIGNED" BIT IS CLEARED.
; 4) IF THE NEW DESCRIPTOR IS THE LAST ONE IN ITS LIST THE "LAST DESCRIPTOR
; IN LIST" INDICATOR IS SET.
;
; THIS ROUTINE; CHECKS IF CURRENT DESCRIPTOR IS LAST ON LIST
; IF SO, BRANCH TO NXLST
; OTHERWISE, ADD 6 TO LIST POINTER AND GOTO NXDSCP TO LOAD DESC
;-
NXBUF:
; CHECK IF THE CURRENT BUFFER DESCRIPTOR IS THE LAST ONE IN THE CURRENT LIST
BRWRTE IMM,<D.RBDF-D.RDP> ;ADDRESS FLAG BYTE
LDMA BR,ADD,SP6
LDMAP SELA,SP.RM1 ;SINCE STUFF SILO CHANGED PAGE
SPBR MEMX,SELB,SP0 ;LOAD FLAG BYTE INTO BR,SP0
BR7 NXLST ;LAST DESCRIPTOR IN LIST,GET NEXT LIST
; CURRENT BUFFER DESCRIPTOR IS NOT THE LAST ONE IN THE LIST
;ADD 6 TO CURRENT DESCRIPTOR ADDRESS TO GET THE NEXT DESCRIPTOR ADDRESS
LDMA SELA,SP6 ;ADDRESS CURRENT DESCRIPTOR POINTER
CALLSR SP.SUB,INCMEM,NXDP1,6. ;CALL TO INCRE PNTR BY 6
;RETURN TO NXDSCP
.SBTTL NXLST-GET NEXT BUFFER LIST
;+
;
; N E X T L I S T
;
; ENTERED FROM: NXBUF
;
; INPUTS:
; SP.SB1 =RETURN ADDRESS
; MAR,MARP=D.RBDF OR D.XBDF
; SP0 =CONTENTS OF D.RBDF OR D.XBDF
; SP6 =ADDRESS OF D.RBD OR D.XBD
;
; OUTPUTS:
; CHECK IF ALTERNATE LIST IS ASSIGNED
; IF NOT, CLEAR BUFFER ASSIGNED BIT AND RETURN
; IF SO, CLEAR ALTERNATE ASSIGNED BIT AND UPDATE CURRENT LIST PNTR
; DROP INTO NXDSCP TO LOAD NEW DESC INTO LINE TABLE.
;-
NXLST:
; CHECK IF THE ALTERNATE LIST IS ASSIGNED
; (MAR=D.RBDF FOR REC OR D.XBDF FOR XMT,SP0=ITS CONTENTS
BRWRTE TWOA,SP0 ;LEFT SHIFT
BR7 10$ ;BRANCH IF ALTERNATE LIST IS ASSIGNED
; ALTERNATE LIST IS NOT ASSIGNED. CLEAR 'CURRENT BUFFER ASSIGNED BIT AND RETURN
BRWRTE IMM,<377-DR.CBA> ;MASK TO CLEAR DR.CBA
MEM BR,AANDB,SP0 ;CLEAR IT AND STORE RESULT IN D.RBDF/D.XBDF/
;*************ONE OF THE RETURN POINTS FOR BA,CONTROL ETC.**********
RTNSUB SP.SB1,P2 ;RETURN
;********************************************************************
; ALTERNATE LIST IS ASSIGNED.
10$:
;CLEAR 'ALTERNATE LIST ASSIGNED' BIT
BRWRTE IMM,<377-DR.ABA> ;MASK TO CLEAR DS.ABA
MEM BR,AANDB,SP0 ;STORE IT IN RAM
;MOVE ALTERNATE LIST POINTER INTO CURRENT DECRIPTOR POINTER
BRWRTE IMM,<D.ARLP-D.RDP> ;OFFSET FROM CURRENT DESCRIPTOR POINTER
LDMA BR,ADD,SP6 ;ADDRESS ALTERNATE POINTER
SP MEMI,SELB,SP0 ;SP0=ADDRESS 7:0
SP MEMI,SELB,SP1 ;SP1=ADDRESS 15:8
SP MEMI,SELB,SP2 ;SP2=ADDRESS 17:16
LDMA SELA,SP6 ;ADDRESS CURRENT POINTER
MEMINC SELA,SP0 ;STORE ADDRESS 7:0
MEMINC SELA,SP1 ;STORE ADDRESS 15:8
MEM SELA,SP2 ;AND EXT ADDRESS
;FALL INTO NXDSCP
.SBTTL NXDSCP - GET NEXT DESCRIPTOR
;+
;
; **NXDSCP-ROUTINE TO LOAD THE NEXT DESCRIPTOR INTO LINE TABLE
;
; ENTERED FROM: NXLST
; CALLED FROM: BAIN
;
;INPUTS:
; SP6=ADDRESS OF THE CURRENT DESCRIPTOR FOR CURRENT OPERATION (ADDRESS
; OF D.RDP OR D.XDP)
;
; OUTPUTS:
; THE NEW DESCRIPTOR IS FETCHED FROM PDP-11 MEMORY AND STORE IN THE LINE TABLE.
; IF A TRANSMIT BUFFER, ANY ODD LEADING CHARACTER IS PREFETCHED
; IF A RECEIVE BUFFER, THE FIRST CHARACTER FLAG(DR.FST) IS SET
;-
NXDSCP:
;SET INBA TO THE CURRENT DESCRIPTOR ADDRESS
LDMA SELA,SP6 ;ADDRESS CURRENT DESCRIPTOR POINTER
OUTPUT MEMI,SELB,IBA1 ;ADDRESS 7:0
OUTPUT MEMI,SELB,IBA2 ;ADDRESS 15:8
BRWRTE IMM,1 ;START NPR
SP BR,SELB,SP0
OUT MEMI,AORB,ONPR ;ADRESS 17:16
;MOVE NEW BUFFER ADDRESS AND BYTE COUNT INTO ORIGINAL BUF ADDRESS AND COUNT AREA
5$: BRWRTE IBUS,NPR ;WAIT FOR BUFFER ADDRESS 15:0
BR0 5$
SP IBUS,INDAT1,SP4,INCMAR ;TEMPORARILY SAVE ADD 7:0 IN SP4
SP IBUS,INDAT2,SP5,INCMAR ;AND ADDRESS 15:8 IN SP5
CALLSB SP.SUB,IC2IN ;READ BYTE COUNT FROM DESCRIPTOR
SP IBUS,INDAT1,SP2,INCMAR ;SAVE LOW BYTE IN SP2
SP IBUS,INDAT2,SP3 ;AND HIGH COUNT IN SP3
;MAR IS NOW POINTING TO D.ORBC/D.OXBC
MEMINC IBUS,INDAT1 ;SAVE LOW BYTE OF COUNT
MEMINC IBUS,INDAT2 ;SAVE HIGH BYTE OF COUNT
MEMINC SELA,SP4 ;NOW STORE DESCP ADDRESS 7:0
MEMINC SELA,SP5 ;AND ADDRESS 15:8 IN RAM
; UPDATE EXTENDED ADDRESS BITS OF BUFFER & LAST DESCRIPTOR BIT
CALLSB SP.SUB,IC2IN ;READ NEXT DESCRIPTOR WORD
SP IBUS,INDAT2,SP0 ;LOAD HIGH BYTE (FLAGS,EXT ADDR)INTO SP0
MEMINC IBUS,INDAT2 ;SAVE FLAGS BYTE
; NOW SAVE COUNT AND ADDRESS IN WORKING (CURRENT) POINTERS ;+*** V1.1
; ENTRY FROM RESET IN RECEIVE ROUTINES ;+*** V1.1
NXDSC1: ;+*** V1.1
MEMINC SELA,SP2 ;SAVE COUNT, LOW BYTE
MEMINC SELA,SP3 ; HIGH BYTE
MEMINC SELA,SP4 ;SAVE BUFFER ADDRESS
MEMINC SELA,SP5 ;
SP MEMX,SELB,SP2 ;SAVE OLD FLAGS IN SP2
BRWRTE IMM,<DR.CBA!DR.ABA> ;STRIP ALL BUT THESE
BRWRTE BR,AANDB,SP2 ;AND LOAD IT NTO BR
MEM BR,AORB,SP0 ;OR IN NEW FLAGS
;CHECK IF RECEIVE OR TRANSMIT OPERATION
BRWRTE IMM,D.RDP ;SET BR TO
BRWRTE BR,ADD,SP.RM0 ;RAM ADDRESS OF D.RDP
;IF THIS IS A RECEIVE OPERATION,SP6 WILL BE EQUAL TO THIS VALUE
COMP BR,SP6 ;BR=SP6?
Z NXRBUF ;SP6=ADDRESS OF D.RDP,RECEIVE OPERATION
;TRANSMIT OPERATION,DO SPECIAL THINGS FOR IT
;READ READ CHARACTER INTO D.OXC IF THE FIRST BUFFER ADDRESS IS ODD
BRWRTE DECA,SP4,INCMAR ;SP4 HAS LOW BYTE OF BUFFER ADDRESS
BR0 30$ ;ADDRESS IS EVEN
;FIRST TRANSMIT BUFFER ADDRESS IS ODD,MOVE FIRST CHARACTER INTO D.OXC
10$:
OUTPUT BR,SELB,IBA1 ;SET ADR 7:0 OF XMT BUFFER
BRWRTE SELA,SP5 ;SP5 HAS ADR 15:8
OUTPUT BR,SELB,IBA2 ;SET ADDRESS 15:8
BRWRTE IMM,BIT3!BIT2 ;MASK TO ISOLATE EXT ADDRESS
SP BR,AANDB,SP0 ;SP0=EXT ADDRESS
OUT INCA,ONPR ;START NPR (SP0 HAS EXT ADDRESS)
20$: BRWRTE IBUS,NPR ;WAIT FOR NPR TO COMPLETE
BR0 20$
30$:
; MAR IS NOW POINTING TO D.OXC
MEMINC IBUS,INDAT2 ;SAVE ODD CHARACTER
MEMINC IMM,SYNCNT ;RESET SYNC COUNT
;RAISE REQUEST TO SEND IF IT IS NOT ALREADY SET
BRWRTE SELA,SP.CS0 ;RTS SET?
BRSHFT
BR1 NXBEXT
MEM IMM,0 ;CLEAR ABORT FLAGS **V0.7**
BRWRTE IMM,DUPRTS ;SET RTS
SPBR BR,AORB,SP.CS0 ;OR MASK WITH ORIGINAL DUP REGISTER
OUTPUT BR,SELB,OUTDA1 ;SHIP IT INTO DUP REGISTER
CALLSB SP.SUB,ADRCSR ;ADDRESS DUP
;************ ULTIMATE RETURN FOR BA & CONTROL OUT*************
NXBEXT: RTNSUB SP.SB1,P2 ;RETURN
;***************************************************************
;ASSIGNING RECEIVE BUFFER,SET FIRST CHR IN BUFFER
NXRBUF:
BRWRTE IMM,DR.LST!DR.ABA!DR.CBA!DR.17!DR.16 ;CLEAR IRRELEVANT BITS *V0.7*
SP MEMX,SELB,SP0 ;SP0=FLAGS
SP BR,AANDB,SP0 ;SAVE THE RELEVANT BITS *V0.7*
.IIF NE DR.FST-1 .ERROR ;INCA NO LONGER SETS DR.FST
MEM INCA,SP0 ;SET FIRST CHR IN BUFFER FLAG
RTNSUB SP.SB1,P2
;NOTE: RECEIVER WAS ENABLED AT CONTROL TIME
.SBTTL ERROR PROCESSING ROUTINES
;+
; **DUPRER-ERROR DETECTED BY DUP OR MICROCODE ON THE RECEIVER
;
; ENTERED FROM: RCVDON
;
; INPUTS:
; MAR = RECEIVE STATE POINTER
; OUTPUTS:
; CONTROL OUT IS GENERATED.
; FALL INTO RESYNC AND RETURN TO TIMER ROUTINE
;-
; DUP HARDWARE DETECTED RECEIVE ERROR
DUPRER:
; DUP HARDWARE HAS DETECTED AN ERROR ON RECEIVED CHARACTER. ANALYZE IT.
BR4 ERR12 ;CRC ERROR
BRWRTE TWOA,SP.RST ;SHIFT RECEIVE STATUS LEFT
BR7 OVRUN ;CHARACTER OVERRUN
;
; OTHERWISE MUST BE ABORT
;
ABORT:
BRWRTE IMM,ER.ABO ;ERROR CODE
ALWAYS RERROR ;SEND A CONTROL OUT
;
; INVALID DDCMP HEADER BCC
; ENTERED FROM: RHCRC2
;
ERR10:
BRWRTE IMM,ER.HBC ;ERROR CODE INTO BR
ALWAYS RERROR ;EXECUTE COMMON ERROR SUBROUTINE
;
; BCC ERROR ON RECEIVED MESSAGE
; ENTERED FROM: DUPRER,RDCRC2
ERR12:
BRWRTE IMM,ER.CRC ;ERROR CODE INTO BR
ALWAYS RERROR ;COMMON ERROR CODE
; CHARACTER OVERRUN
OVRUN:
BRWRTE IMM,ER.OVR ;ERROR CODE
;FALL INTO RERROR
;SEND CONTROL OUT
RERROR:
SP BR,SELB,SP3 ;ERROR CODE INTO SP3
CALLSR SP.SB1,ENTRY2,RERRP2,C.CLOR ;CONTROL OUT SUB ROUTINE
ERREXT: ;RETURN HERE AFTER SUBROUTINE
; FALL INTO RSNCRT
.SBTTL RSNCRT - RESYNC AND RETURN TO TIMER
;+
;
; **RSNCRT-RESYNC RECEIVER AND RETURN TO TIMER POLLING LOOP
;
; ENTERED FROM: DUPRER,RDH1,MSGIN
;
; INPUTS: NONE
; OUTPUTS:
; SET UP RETURN TO TIMER THEN FALL INTO RESYNC
;-
RSNCRT:
BRADDR TIMRP2 ;RETURN TO TIMER VIA PAGE 2
SP BR,SELB,SP.SB1
; ALWAYS RESYNC ;AFTER RESYNCING THE RECEIVER
; FALL INTO RESYNC
.SBTTL RESYNC-RESYNC DUP-11 RECEIVER
;+
; R E S Y N C D U P-1 1 R E C E I V E R
;
; ENTERED FROM: RSNCRT
; CALLED BY: ERREXT,KILLRC,STORE
;
;INPUTS:
; SP.SB1=RETURN ADDRESS
; SP.CS0=RECEIVE STATUS REGISTER LOW BYTE
;OUTPUTS:
; CURRENT DUP-11 RECEIVER ENABLE BIT IN ITS RECEIVE STATUS REGISTER
; IS CLEARED.IT IS THEN SET THUS INITIALIZING DUP RECEIVER LOGIC.
; RECEIVER STATE POINTER IS RESET.
; RETURN TO ADDRESSES IN PAGE TWO
;-
RESYNC:
;CLEAR RECEIVE ENABLE BIT
LDMAP SELA,SP.RM1 ;SET UP PAGE ADDRESS
BRWRTE IMM,<377-DUPREN>
SPBR BR,AANDB,SP.CS0 ;LOAD ORIGINAL STATUS WITH RCV ENABLE
OUTPUT BR,SELB,OUTDA1 ;BIT CLEARED INTO OUTDA1
CALLSB SP.SUB,ADRCSR ;SET UP OUT BA TO DUP'S CSR AND DO A
;BYTE NPR
;NOW SET RECEIVE ENABLE BIT
BRWRTE IMM,DUPREN ;MASK TO SET REC ENABLE BIT
SPBR BR,AORB,SP.CS0 ;MASK IN THE ORIGINAL STATUS
OUTPUT BR,SELB,OUTDA1 ;AND RECEIVE ENABLE BIT INTO OUTDA1
BRWRTE IMM,DATOB ;WRITE IT INTO
OUT BR,SELB,ONPR ;RECEIVE STATUS REGISTER
; ***NPR STARTED***
; RESET RECEIVE PARAMETERS
BRWRTE MEMX,SELB,INCMAR ;BR=D.STS,ADDRESS D.RPTR
;RESET RECEIVE STATE POINTER FOR DDCMP/BITSTUFF
RSTATE RDH1 ;SET DDCMP INTIAL RECEIVE STATE
BRSHFT
BR4 20$ ;BRANCH IF DEC MODE
RSTATE RB1 ;SET BIT STUFF INITIAL STATE
20$: BRWRTE IBUS,NPR ;WAIT FOR PREVIOUS NPR TO COMPLETE
BR0 20$ ;NOT YET
RTNSUB SP.SB1,P2 ;RETURN TO PAGE 2
.SBTTL SETRBA-SET OUTBA TO CURRENT INPUT ADDRESS IN USER RECEIVE BUFFER
;+
; SET OUTBA TO CURRENT INPUT ADDRESS IN RECEIVE BUFFER
;
; CALLED BY: STORE,STRODD,EOFMSG
;
; INPUTS:
; SP.SUB = RETURN ADDRESS ON PAGE 2
; MAR = D.RBDA
; OUTPUTS:
; OBA,OBR = ADDRESS POINTED TO BY MAR
; MAR = D.RBDF
;-
SETRBA:
OUTPUT MEMI,SELB,OBA1 ;SET OUTBA 7:0
OUTPUT MEMI,SELB,OBA2 ;SET OUTBA 15:0
SP IBUS,UBBR,SP0 ;SP0=BUS REQUEST REGISTER
BRWRTE IMM,101 ;MASK TO CLEAR ALL BUT VEC XX4,NXM BITS
SP BR,AANDB,SP0
BRWRTE IMM,14 ;MASK TO CLEAR UNWANTED BITS IN EXT. ADDRESS
SP BR,SELB,SP1 ;SAVE THE MASK IN SP1
BRWRTE MEMX,AANDB,SP1 ;BR=JUST THE EXT ADR
OUT BR,AORB,OBR ;OR IN THE EXT ADDRESS
RTNSUB SP.SUB,P2 ;RETURN TO PAGE 2
.SBTTL DECDCC-DECREMENT DDCMP DATA CHARACTER COUNT
;+
;
; D E C R E M E N T D D C M P D A T A C H A R A C T E R C O U N T
;
; CALLED BY: RDDATA
;
;INPUT:
; SP.SUB=RETURN ADDRESS
;OUTPUT:
; DDCMP DATA CHARACTER COUNT FOR THE CURRENT MESSAGE IS DECREMENTED BY ONE.
; C BIT IS SET IF AND ONLY IF THE NEW BYTE COUNT IS NOT -1
; COMMON CODE IN DECNT IS USED.
;-
DECDCC:
;ADDRESS DDCMP DATA CHARACTER COUNT SAVE AREA IN RAM
BRWRTE IMM,D.DCC1
ALWAYS DECNT ;EXECUTE COMMON CODE
.SBTTL DRCNT/DECNT-DECREMENT BUFFER COUNT
;+
;
; D E C R E M E N T B U F F E R B Y T E C O U N T
;
; CALLED BY: STORE
; DECNT CALLED BY: XMTDON
;
;INPUT:
; SP.SUB=RETURN ADDRESS
;OUTPUT:
; BYTE COUNT FOR THE CURRENT LINE IS DECREMENTED BY ONE
; C BIT IS SET IF AND ONLY IF THE NEW BYTE COUNT IS NOT -1
; MAR IS LEFT POINTING TO ADDRESS FOLLOWING BYTE COUNT
;
; SCRATCH PADS USED: SP1,SP.RM0,SP.SUB
;-
DRCNT:
; ADDRESS RECEIVE BYTE COUNT SAVE AREA (D.RBDC)
BRWRTE IMM,D.RBDC
;
; FOLLOWING CODE IS SHARED BY DECDCC AND DRCNT.
; INPUTS: BRG = LINE TABLE OFFSET OF BYTE COUNT
;
DECNT:
LDMA BR,ADD,SP.RM0
SP MEMX,SELB,SP1 ;GET LOW BYTE COUNT INTO SP1
MEMINC DECA,SP1 ;DECREMENT IT AND WRITE IT BACK
Z 10$ ;BRANCH IF ZERO
INCMA ;INCREMENT PAST HIGH BYTE OF COUNT
RTNSUB SP.SUB,P2 ;RETURN TO CALLLER
; BORROW FROM HIGH BYTE, DECREMENT HIGH BYTE
10$: SP MEMX,SELB,SP1 ;GET HIGH BYTE INTO SP1
MEMINC DECA,SP1 ;DECREMENT IT AND STORE IT BACK
RTNSUB SP.SUB,P2 ;RETURN
.SBTTL INCOUT/IC2OUT/INCOB-OUT NPR TO CURRENT ADDRESS+OFFSET
;+
;
; INCREMENT OUTBA AND OUTPUT SUBROUTINE
;
; CALLED BY: (INCOB): BAIN
; (IC2OUT): CONIN,XMTBCZ,COUT
;
; INPUTS:
; BR =INCREMENT
; SP.SUB =RETURN ADDRESS
; ENTRY POINTS INCOUT,IC2OUT,INCOB
;
; OUTPUTS:
; THE DEVICE ADDRESS (OUT BA 17:0) FOR AN OUT NPR OPERATION
; IS INCREMENTED BY A FACTOR EQUAL TO THE CONTENTS OF BR.
; THEN A BYTE OR WORD TRANSFER WITH OR WITHOUT BUSHOLD IS PERFORMED DEPENDING
; ON THE ENTRY POINT.
; RETURNED TO THE ADDRESS IN CURRENT PAGE SPECIFIED BY SP.SUB
; BUSHOLD ENTRYS REMOVED BECAUSE OF INTERFERENCE PROBLEMS
;
; REGISTERS USED:
; BR,UBBR,SP0,SP1,SP.SUB
;
; REGISTERS DESTROYED (OR CHANGED)
; BR,UBBR,SP0,SP1
;-
; ENTRY POINT TO DO BYTE NPR WITHOUT BUS HOLD
INCOB:
SP IMM,221,SP1 ;MASK TO DO BYTE OUT NPR ***TRICKY INSTR***
ALWAYS INCOT1 ;COMMON CODE
;ENTRY TO INCREMENT BY 2 AND DO WORD TRANSFER
IC2OUT:
BRWRTE IMM,2
; ENTRY TO DO WORD TRANSFER WITHOUT BUS HOLD
INCOUT:
SP IMM,21,SP1 ;MASK TO DO WORD OUT NPR ****TRICKY INSTR***
INCOT1:
; INCREMENT OUTBA 7:0
SP IBUS,IOBA1,SP0 ;READ OUTBA7:0 INTO SP0
OUTPUT BR,ADD,OBA1 ;ADD INCREMNT AND RESTORE(SP0 IS SELECTED
; INCREMENT OUTBA 15:0
10$: SP IBUS,IOBA2,SP0 ;READ OUTBA15:8 INTO SP0
OUTPUT BR,APLUSC,OBA2 ;ADD CARRY TO OUTBA15:8(SP0 SELECTED)
C 30$ ;CARRY,INCREMENT EXTENDED ADDRESS
20$: ALWAYS 40$ ;NPR AND RETURN
; INCREMENT OUTBA 17:16
30$: SP IBUS,UBBR,SP0 ;LOAD UBBR INTO DP0
BRWRTE IMM,4 ;ADD ONE TO EXT. ADDRESS
SP BR,ADD,SP0
BRWRTE IMM,115 ;MASK TO SET CLOCK BIT=0
OUT BR,AANDB,OBR ;STORE UPDATED VALUE INTO UBBR
;NOW DO THE NPR
40$:
SP IBUS,NPR,SP0 ;GET NPR REGISTER INTO SP0
BRWRTE IMM,155 ;STRIP NPR CONTROL BITS
BRWRTE BR,AANDB,SP0 ;SAVE RESULTS IN BR
BRWRTE BR,AORB,SP1 ;OR IN THE NEW NPR CONTROL BITS
OUT BR,SELB,ONPR ;LOAD THE NEW BYTE INTO NPR REGISTER
; WAIT FOR NPR TO COMPLETE
WAIT:
10$: BRWRTE IBUS,NPR ;WAIT FOR NPR TO COMPLTE
BR0 10$
RTNSUB SP.SUB,P0
.SBTTL ADRCSR-SET OUTBA=DUP'S CSR ADDRESS
;+
;
; SET OUTBA TO DUP CSR
;
; CALLED BY: NXDSCP, RESYNC
;
;INPUTS:
; SP.SUB =RETURN ADDRESS
; OUTDA1 = VALUE TO BE WRITTEN TO DUP'S CSR0
;OUTPUTS:
; OUTBA=ADDRESS OF CURRENT DUP
; START A BYTE NPR TO CSR0 AND WAIT FOR ITS COMPLETION
; MAR = D.STS
;-
ADRCSR:
BRWRTE IMM,D.CSR ;ADDRESS D.CSR
LDMA BR,ADD,SP.RM0
OUTPUT MEMI,SELB,OBA1 ;SET OUTBA 7:0
OUTPUT MEMI,SELB,OBA2 ;SET OUTBA 15:8
SP IBUS,UBBR,SP0 ;GET BUS REQ REG
BRWRTE IMM,101 ;KEEP VEC XX4,NXM BITS
SP BR,AANDB,SP0
BRWRTE IMM,14 ;SET EXT ADDRESS BITS
OUT BR,AORB,OBR ;SP0 IMPLIED FOR B SIDE
BRWRTE IMM,DATOB ;BYTE OUT NPR MASK
OUT BR,SELB,ONPR ;START THE NPR
ALWAYS INCIN1 ;RETURN VIA SP.SUB,P3
;USE CODE IN INCIN
;*** PAGE 3 RETURN TO TIMER FOR RECEIVE ROUTINES ***
.IIF NE <TIMRP3-START/1000-3> .ERROR ;PAGE 3 RELOCATION ERROR TIMRP3
TIMRP3: ALWAYS TIMRTN ;RETURN TO POLLING LOOP FROM DSRCHG
.SBTTL NXTTBL - ROUTINE TO CALCULATE THE ADDRESS OF THE NEXT TABLE
; FILE SUBR.MAC
;+
; **-NXTTBL-CALCULATE RAM ADDRESS OF NEXT LINE'S TABLE**
;
; CALLED FROM: INIT
;
; INPUTS:
; SP.RM0-1 = PREVIOUS RAM TABLE ADDRESS
;
; OUTPUTS:
; MAR AND SP.RM0-1 ARE SET TO ADDRESS OF NEXT TABLE ENTRY
;-
NXTTBL:
BRWRTE IMM,D.LNG ;GET THE LENGTH OF A RAM TABLE ENTRY
SP BR,ADD,SP.RM0,LDMAR ;POINT TO NEXT ENTRY AND LOAD MAR
NODST BR,ADD,SP.RM0 ;WOULD THIS LINE TABLE CROSS A PAGE BOUNDARY?
C 10$ ;YES, MAKE IT START AT THE BEGINNING OF THE
;NEXT PAGE
LDMAP SELA,SP.RM1 ;LOAD MAR HIGH
ALWAYS INIT1 ;BACK TO INITIALIZE LOOP
10$: SP APLUSC,SP.RM1,LDMAPG ;INCREMENT THE PAGE NUMBER AND LOAD
;MAR HIGH
BRWRTE IMM,0 ;ZERO THE BRG
SP BR,SELB,SP.RM0,LDMAR ;ZERO THE LOW 8 BITS OF THE MAR AND
;SP.RM0
ALWAYS INIT1 ;BACK TO INITIALIZE LOOP
.SBTTL INCIN/INCINH/IC2IN - EIGHTEEN BIT ADD TO INPUT ADDRESS
;+
; **INCIN/INCINH-ROUTINE TO DO 18 BIT TO THE INPUT ADDRESS**
;
; CALLED BY: (IC2IN): NXDSCP
;
; CALLING SEQUENCE:
; CALLSB SP.SUB,INCIN,ADDEND ;ADD "ADDEND" TO IN BA AND DO
; ;AN NPR WITH BUS HOLD CLEAR
; CALLSB SP.SUB,INCINH,ADDEND ;ADD "ADDEND TO IN BA AND DO
; ;AN NPR WITH BUS HOLD SET
; CALLSB SP.SUB,IC2IN ;ADD 2 TO IN BA AND DO AN NPR
; ;WITH BUS HOLD CLEAR
; ;N.B. CALLING SEQUENCE IS ONE INSTR LESS
;
; INPUTS:
; INPUT BUFFER ADDRESS MUST BE SET UP IN THE I/O BUS INCLUDING
; THE EXTENDED MEMORY BITS IN THE NPR CONTROL REGISTER
;
; BRG = ADDEND
;
; OUTPUTS:
; THE INPUT ADDRESS IS INCREMENTED BY THE BRG CONTENTS, THE NPR IS STARTED
; AND THE ROUTINE WAITS FOR IT TO COMPLETE.
; NOTE: BUS HOLD OPTIONS NOT USED TO PREVENT INTERFERENCE WITH OTHER
; UNIBUS DEVICES.
;-
.ENABL LSB
;*******************************
;INCINH: SP IMM,0,SP1 ;WRITE A ONE TO SP 1 ***** TRICKY INSTRUCTION ****
; SP BR,INCA,SP1 ;MAKE IT A TWO IN ORDER TO MASK ON BUS HOLD BIT
; ALWAYS 5$ ;TO COMMON CODE
;***** ABOVE CODE NOT USED******
IC2IN: BRWRTE IMM,2 ;MOST COMMON INCREMENT VALUE
;FALL INTO INCIN
INCIN:
;**************
; SP IMM,1,SP1 ;WRITE A ONE TO SCRATCH PAD ONE **** TRICKY INSTR.****
; ;LEAVES BIT 1 A ZERO TO MASK OFF BUS HOLD
;**************
5$: SP IBUS,IIBA1,SP0 ;GET THE CURRENT LOW BYTE OF THE INPUT ADDRESS
OUTPUT BR,ADD,IBA1 ;NEW LOW BYTE OF INPUT ADDRESS
SP IBUS,IIBA2,SP0 ;GET THE HIGH BYTE OF THE INPUT ADDRESS
OUTPUT APLUSC,IBA2 ;ADD ANY CARRY FROM PREVIOUS ADD TO HIGH BYTE
SP IBUS,NPR,SP0 ;GET THE NPR REGISTER CONTENTS
C 50$ ;A PLUS C CAUSED A CARRY TO EXTENDED MEMORY BITS
30$: BRWRTE IMM,16 ;MASK TO EXT. MEM. BIT OVERFLOW
SP BR,AANDB,SP0 ;MASK OFF UNWANTED BITS
OUT BR,INCA,ONPR ;START THE NPR
; THE FOLLOWING CODE SHARED WITH ADRCSR
INCIN1:
40$: BRWRTE IBUS,NPR ;READ THE NPR CONTROL REGISTER
BR0 40$ ;WAIT FOR THE NPR TO FINISH
RTNSUB SP.SUB,P3 ;RETURN TO CALLER
50$: BRWRTE IMM,4 ;VALUE TO ADD TO INCREMENT EXTENDED MEMORY
SP BR,ADD,SP0 ;ADD TO PREVIOUS EXTENDED MEM BITS
ALWAYS 30$ ;BRANCH TO COMMON CODE
.DSABL LSB
.SBTTL INCMEM - EIGHTEEN BIT ADD TO ADDRESS POINT TO BY MAR
;+
; **INCMEM-18 BIT ADD TO RAM**
;
; CALLED BY: (INCMEM): RCVEXT, NXBUF
; (INCMM): XMTDON
;
; CALLING SEQUENCE:
; CALLSB SP.SUB,INCMEM,ADDEND
; OR
; CALLSB SP.SUB,INCMM ;TO INCREMENT MEMORY BY STATE OF "C" BIT
;
; INPUTS:
; MAR = ADDRESS IN RAM OF LOW BYTE TO DO ADD
; BRG = ADDEND
; INPUTS TO INCMM:
; MAR = SAME AS ABOVE
; "C" BIT SET OR CLEAR
; OUTPUTS:
; RESULT IS IN RAM
; MAR = ORIGINAL MAR + 2
;
; USES SCRATCH PAD 0
;-
INCMEM: SP BR,SELB,SP0 ;MOVE ADDEND TO SP 0
MEMINC MEMX,ADD,SP0 ;ADD TO LOW BYTE OF RAM
INCMM:
SP MEMX,SELB,SP0 ;MOVE HIGH BYTE FROM RAM TO SP0
MEMINC BR,APLUSC,SP0 ;ADD CARRY FROM LOW BYTE
C 10$ ;LAST ADD CAUSE CARRY TO EXTENTED MEMORY BITS
RTNSUB SP.SUB,P1 ;ALL DONE
10$: SP MEMX,SELB,SP0 ;READ EXTENDED MEMORY BITS
;IN POSITIONS 2 & 3
BRWRTE IMM,4 ;INCREMENT EXTENDED MEMORY BITS
MEM BR,ADD,SP0 ;ADD "ONE" OF HIGH ORDER BITS
RTNSUB SP.SUB,P1 ;RETURN TO CALLER
.SBTTL NXMERR - NONEXISTENT MEMORY ERROR
;+
; **NXMERR-MICROPROCESSOR HAS DETECTED A NONEXISTENT MEMORY ERROR**
;
; CALLED BY: RDICLR, TIMER
;
; OUTPUTS:
; CONTROL OUT IS GENERATED
; N.B. THE NXM ERROR IS CHECKED ONLY AFTER SERVICING A USER
; REQUEST (RQI) AND AFTER SERVICING A DUP NOT AFTER EACH
; NPR. THUS THE ONLY RELEVANT INFORMATION IS THE LINE NUMBER.
;-
NXMERR:
BRWRTE IMM,100 ;MASK TO PRESERVE STATE OF XX4 BIT
OUT BR,AANDB,OBR ;CLEAR NXM ERROR BIT
CALLSB SP.SUB,COUTX,ER.NXM ;POST THE ERROR
ALWAYS IDLE ;BACK TO IDLE LOOP
;(LINES REMOVED) **X1.2**
$KDPML==.-$KDPMC+63./64. ;NUMBER OF 32 WORD BLOCKS
.END