1
0
mirror of https://github.com/PDP-10/stacken.git synced 2026-03-09 12:05:58 +00:00
Files
Lars Brinkhoff 6e18f5ebef Extract files from tape images.
Some tapes could not be extracted.
2021-01-29 10:47:33 +01:00

3320 lines
94 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
.TITLE KDUPMC - COMMUNICATION IO PROCESSOR MICROCODE FOR THE DUP11
;
; COPYRIGHT (C) 1978
; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. 01754
;
; THIS SOFTWARE IS FURNISHED UNDER A LICENSE FOR USE ONLY ON
; A SINGLE COMPUTER SYSTEM AND MAY BE COPIED ONLY 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
; EXCEPT FOR USE ON SUCH SYSTEM AND TO ONE WHO AGREES TO
; THESE LICENSE TERMS. TITLE TO AND OWNERSHIP OF THE
; SOFTWARE SHALL AT ALL TIMES REMAIN IN DEC
;
; THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO CHANGE
; WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED AS A COM-
; MITMENT BY DIGITAL EQUIPMENT CORPORATION.
;
; DEC ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY
; OF ITS SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY
; DEC.
;
; DISTRIBUTED SYSTEMS SOFTWARE ENGINEERING
;
.SBTTL TABLE OFFSET DEFINITIONS
.IDENT /V1.0A/
; FILE DUPEQU.MAC
.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
BRWRTE IBUS,PORT4 ;REREAD BSEL 7
BR7 50$ ;IT IS
RSTATE RB1 ;BIT STUFF MODE
;CLEAR XX5
50$: BRWRTE IMM,0
OUTPUT BR,SELB,OUTDA2,INCMAR
;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
BRWRTE IBUS,INDAT1 ;READ THE TRANSMIT CNTROL REGISTER
BR7 XMTDN1 ;TRANSMIT DONE SET
ALWAYS TIMRT3 ;TRANSMIT NOT DONE - RETURN
; TRANSMIT DONE FOUND
.ENABL LSB
XMTDN1:
OUTPUT IBUS,IIBA1,OBA1 ;COPY INPUT ADDRESS TO OUTPUT
OUTPUT IBUS,IIBA2,OBA2 ;ADDRESS
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$: 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
SP BR,AANDB,SP0 ;MASK FLAGS WORD
OUT INCA,ONPR ;SET EXTENDED MEM BITS AND NPR REQUEST BIT
BRWRTE IMM,0 ;ZERO THE BRG
OUTPUT BR,SELB,OUTDA2 ;CLEAR ALL DUP CONTROL BITS
80$: BRWRTE IBUS,NPR ;READ THE NPR STATUS REGISTER
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 121$ ;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)
121$:
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
;-
RB1:
RSTATE RB2 ;SET TO STATE 2
BRADDR TIMRTN ;ULTIMATE RETURN ADDRESS
SP BR,SELB,SP.SUB,INCMAR ;STORE IN RETURN SCRATCH PAD
ALWAYS LSILO ;JUMP TO ROUTINE TO SILO CHARACTER
;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
BRADDR TIMRTN ;RETURN ADDRESS TO POLLING LOOP
SP BR,SELB,SP.SUB,INCMAR
ALWAYS LSILO ;PUSH SILO AND RETURN TO 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
SP BR,SELB,SP.SUB,INCMAR ;SAVE RETURN ADDRESS
;FALL INTO LSILO
.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
MEM BR,AORB,SP.STS ;OR IT IN INTO D.STS
ALWAYS STORE ;STORE FIRST DDCMP CHARACTER IN RECEIVE BUFFER
.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
MEM BR,AORB,SP.STS ;UPDATE D.STS
; STORE CURRENT RECEIVED CHARACTER IN USER RECEIVE BUFFER
ALWAYS STORE
.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
MEM BR,AORB,SP.STS ;WRITE IT BACK INTO RAM WITH IGNORE BIT SET
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,SP4 ;SAVE ORIGINAL BYTE COUNT IN SP4,SP3
SP MEMI,SELB,SP3
SP MEMI,SELB,SP2 ;SAVE ORIGINAL ADDRESS IN SP2,SP1&SP0
SP MEMI,SELB,SP1
SP MEMI,SELB,SP0
;RESTORE THEM INTO CURRENT PARAMETERS
MEMINC SELA,SP4 ;RESTORE BYTE COUNT
MEMINC SELA,SP3
MEMINC SELA,SP2 ;RESTORE BUFFER ADDRESS IN CURRENT AREA
MEMINC SELA,SP1
MEMINC SELA,SP0
;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
ALWAYS PATCHA ;JUMP TO PATCH, PATCH BRANCHES TO
;RSNCRT OR TIMRTN ON BR7
.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
SP MEMX,SELB,SP0 ;READ THE STATUS BYTE
BRWRTE IMM,DT.ABT!DT.AB1 ;ABORT PENDING FLAG
MEM BR,AORB,SP0 ;OR IT BACK TO MEMORY
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 A160$ ;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
BR0 A170$ ;END OF MESSAGE FLAG SET
ALWAYS TIMRT3 ;NOT THE END OF MESSAGE - EXIT
.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
;-
A160$: 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
;-
A170$: 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
BRWRTE IMM,DUPTAB ;DUP TRANSMIT ABORT BIT
OUTPUT BR,SELB,OUTDA2 ;MOVE IT TO OUT DATA
ALWAYS WRTRT ;RETURN TO XMTDON TO DO THE NPR
.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
MEMINC SELA,SP2 ;SAVE LOW BYTE OF COUNT
MEMINC SELA,SP3 ;SAVE HIGH BYTE
MEMINC SELA,SP4 ;SAVE BUFFER ADDRESS IN CURRENT AREA
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
.SBTTL PATCH - PATCH AREA
;+
; **PATCHA - PATCH MSGIN
; ENTERED FROM: MSGIN
; INPUTS:
; BRG = SP.STS SHIFTED LEFT ONE
; OUTPUTS:
; GOTO RSNCRT IF Q-SYNC SET (LS.QSC)
; GOTO TIMRTN IF NOT
;-
PATCHA: BR7 RSNCRT ;RESYNC RECEIVER AND RETURN TO TIMER
ALWAYS TIMRTN ;RETURN TO TIMER
$KDPML==.-$KDPMC+63./64. ;NUMBER OF 32 WORD BLOCKS
.END