Trailing-Edge
-
PDP-10 Archives
-
BB-4170G-SM
-
sources/dupsrv.mac
There is 1 other file named dupsrv.mac in the archive. Click here to see a list.
;<3A.MONITOR>DUPSRV.MAC.26, 7-Jun-78 15:29:25, Edit by KIRSCHEN
;REMOVE INCORRECT CHECK FOR ASCIZ IN BTCLI
;<3A.MONITOR>DUPSRV.MAC.25, 18-May-78 08:23:19, Edit by MCCLURE
; IMPROVE N IN REP MESSAGES
;<3.SM10-RELEASE-3>DUPSRV.MAC.24, 10-May-78 15:24:33, Edit by MCCLURE
; FIX BTIPR FOR .VNDDC
;<3.SM10-RELEASE-3>DUPSRV.MAC.22, 5-May-78 00:10:14, Edit by MCCLURE
; Fix .VNCNL & .VNCBL
;<3.SM10-RELEASE-3>DUPSRV.MAC.21, 1-May-78 12:57:24, Edit by MCCLURE
;<3A.MONITOR>DUPSRV.MAC.20, 11-Apr-78 15:53:00, Edit by MCCLURE
; Clear PGDLMX in DEDLIN
;<3A.MONITOR>DUPSRV.MAC.19, 6-Apr-78 16:23:44, Edit by MCCLURE
; Add new COMIOP u-code
;<3A.MONITOR>DUPSRV.MAC.18, 29-Mar-78 14:09:57, Edit by MCCLURE
; Have BTCLI and BTCPN believe KDP_0_#
;<3A.MONITOR>DUPSRV.MAC.17, 28-Mar-78 10:54:15, Edit by MCCLURE
;<3A.MONITOR>DUPSRV.MAC.16, 23-Mar-78 16:41:48, Edit by MCCLURE
; ADD THINGS WHICH GOT DROPPED
;<3A.MONITOR>DUPSRV.MAC.15, 15-Mar-78 12:20:42, Edit by MCCLURE
;<3A.MONITOR>DUPSRV.MAC.14, 9-Mar-78 11:08:40, Edit by MCCLURE
; ADD BTIPR, BTTPR, BTSTS, BTRLC, BTCLI, BTCPN
;<3A.MONITOR>DUPSRV.MAC.13, 3-Feb-78 03:38:55, Edit by MCCLURE
;<3A.MONITOR>DUPSRV.MAC.12, 31-Jan-78 03:09:20, Edit by MCCLURE
;<3A.MONITOR>DUPSRV.MAC.11, 29-Jan-78 16:36:30, Edit by MCCLURE
;<3.SM10-RELEASE-3>DUPSRV.MAC.9, 13-Jan-78 01:10:52, EDIT BY MCCLURE
;<3.SM10-RELEASE-3>DUPSRV.MAC.8, 12-Jan-78 17:27:05, EDIT BY MCCLURE
;<3.SM10-RELEASE-3>DUPSRV.MAC.7, 11-Jan-78 05:13:34, EDIT BY MCCLURE
;<3.SM10-RELEASE-3>DUPSRV.MAC.6, 3-Jan-78 10:14:36, EDIT BY MCCLURE
;<3.SM10-RELEASE-3>DUPSRV.MAC.5, 23-Dec-77 05:41:33, EDIT BY MCCLURE
;<3.SM10-RELEASE-3>DUPSRV.MAC.4, 22-Dec-77 02:56:16, EDIT BY MCCLURE
;<3.SM10-RELEASE-3>DUPSRV.MAC.3, 15-Dec-77 23:26:42, EDIT BY MCCLURE
;<3.SM10-RELEASE-3>DUPSRV.MAC.2, 14-Dec-77 09:55:45, EDIT BY MCCLURE
;<3.SM10-RELEASE-3>DUPSRV.MAC.1, 6-Dec-77 20:44:59, EDIT BY MCCLURE
;10-August-1977 DMCC
SEARCH PROLOG,PROKS
TTITLE DUPSRV
EXTN <DEDMCB>
EXTN <DUPLIM,DUPNLN,DUPN,DUPPAG,DUPTIM,DUPXPC>
EXTN <KMCACS,KMCINQ,KMCIPL,KMCFLG,KMCPAG,KMCQLN>
EXTN <NODINI,NSPQ,NSPSPC>
;THIS MODULE PROVIDES SUPPORT FOR DUP11'S WITH A KMC11 FOR NSPSRV ON A 2020
;THINGS TO CHECK
; 1) ERROR COUNTERS - SYSERR
; 2) COLLAPSE PAGES
IFNDEF FTRACE,<FTRACE==-1> ;NONZERO TO TURN ON TRACE
; TABLE OF CONTENTS FOR DUPSRV
;
;
; SECTION PAGE
; 1. DEFINITIONS
; 1.1 STG............................................... 4
; 1.2 KMC11............................................. 5
; 1.3 DUP11............................................. 7
; 1.4 DDCMP............................................. 8
; 2. PROTOTYPE MESSAGES........................................ 9
; 3. DUP11 COMIOP CODE FOR KMC11............................... 10
; 4. BOOT JSYS
; 4.1 PERFORMS BOOTSTRAP FUNCTIONS FOR KMC11............ 11
; 4.2 SEND MOP MESSAGE.................................. 13
; 4.3 INITIATE PROTOCOL................................. 14
; 4.4 TERMINATE PROTOCOL................................ 15
; 4.5 RETURN PROTOCOL STATUS............................ 16
; 4.6 RECEIVE MOP MESSAGE............................... 17
; 4.7 LOAD KMC11........................................ 18
; 4.8 DUMP THE KMC11.................................... 23
; 4.9 RETURN LINE COUNTERS.............................. 25
; 4.10 CONVERT LINE-ID TO PORT NUMBER.................... 26
; 4.11 CONVERT PORT NUMBER TO LINE-ID.................... 27
; 5. HERE TO INITIALIZE THE KMC11.............................. 28
; 6. KMC11 INTERRUPT LEVEL SERVICE............................. 32
; 7. DDCMP RECEIVER
; 7.1 DATA MESSAGE...................................... 34
; 7.2 CONTROL MESSAGE................................... 35
; 7.3 ACK MESSAGE....................................... 36
; 7.4 NAK MESSAGE....................................... 38
; 7.5 REP MESSAGE....................................... 39
; 7.6 START MESSAGE..................................... 40
; 7.7 STACK MESSAGE..................................... 41
; 7.8 JUNK MESSAGE...................................... 42
; 8. DDCMP TRANSMIT DONE....................................... 43
; 9. KMC11 CONTROL OUT INTERRUPT............................... 44
; 10. HERE FROM NSPSRV WITH OUTPUT MESSAGES..................... 45
; 11. HERE ONCE A SECOND TO CHECK THINGS........................ 46
; 12. DDCMP TRANSMITTER
; 12.1 DATA MESSAGES..................................... 47
; 12.2 REP MESSAGE....................................... 48
; 12.3 ACK MESSAGE....................................... 49
; 12.4 NAK MESSAGE....................................... 50
; 12.5 CONTROL MESSAGE................................... 51
; 12.6 DATA MESSAGES..................................... 52
; 13. HERE TO ENABLE RECEIVER................................... 53
; P1 FOR LINE SPECIFIC CODE WILL CONTAIN THE ADDRESS OF THE LINES PAGE
; MESSAGE BLOCKS LIVE IN BLOCKS OF RESIDENT SPACE
BLKSIZ=<MBKFRE*10>+1 ;SIZE OF BLOCKS IN RESIDENT SPACE
;FORMAT OF EACH MESSAGE BLOCK
MBKLNK==0 ;LH = ADR OF NEXT MESSAGE BLOCK
; RH = ADR OF MESSAGE
MBKCOD==1 ;DRIVER UNIQUE CODE
MBKLEN==2 ;LH IS DRIVER INT LOC
; RH IS LENGTH OF MESSAGE IN BYTES
;FOLLOWING VALID ONLY FOR LAST MSG BLOCK IN BLOCK
MBKFRE==3 ;LH = NUMBER OF FREE WORDS LEFT IN BLOCK
; RH = ADR OF BLOCK
;KMCINQ - QUEUE OF MESSAGE TO BE GIVEN TO THE KMC11
; FIRST WORD IS USED TO PUT THINGS INTO THE QUEUE
; 2ND WORD IS USED TO TAKE ENTRIES FROM QUEUE
; QUEUE ENTRIES ARE 2 WORDS LONG
; RH OF 1ST WORD GOES TO BSEL2
; LH OF 2ND WORD GOES TO BSEL4
; RH OF 2ND WORD GOES TO BSEL6
SUBTTL DEFINITIONS -- STG
DEFINE X (A,B)<
A==Z
Z=Z+B
>
Z=0
;PAGE OFFSETS
X PGUBAD,1 ;LH IS UNIBUS ADR OF PAGE
X PGDSTS,1 ;DDCMP STATUS
DEFSTR (DDSTA,PGDSTS(P1),35,3) ;DDCMP STATE
STADWN==0 ;KMC11 NOT RUNNING
STAMAI==1 ;MAINT MODE
STASTR==2 ;SENDING STARTS
STASTK==3 ;SENT STACK
STARUN==4 ;RUNNING
DEFSTR (DDTIM,PGDSTS(P1),32,7) ;TIMER
TIMSTR==5 ;5 SECONDS BETWEEN STARTS
TIMREP==3 ;3 SECONDS BETWEEN REPS
REPMAX==200 ;MAXIMUM NUMBER OF REPS BEFORE DECLARING LINE DOWN
DUPDSR==1B14 ;DATASET READY
DEFSTR (DDXAK,PGDSTS(P1),13,1) ;WANT TO SEND AN ACK
DEFSTR (DDNCD,PGDSTS(P1),12,3) ;NAK CODE TO SEND
DEFSTR (DDXRP,PGDSTS(P1),9,1) ;WANT TO SEND A REP
DEFSTR (DCHNG,PGDSTS(P1),8,2) ;INFORMATION FOR NSPSRV (SWAPPABLE)
DDUP==1 ;DDCMP NOW UP
DDOWN==2 ;DDCMP DOWN
X PGDOMQ,1 ;DDCMP OUTPUT MESSAGE QUEUE
; LH IS ADR OF FIRST OUTPUT MESSAGE BLOCK
; RH IS ADR OF LAST OUTPUT MESSAGE BLOCK
X PGDLMX,1 ;RH IS ADR OF MESSAGE BLOCK FOR LAST MESSAGE TRANSMITTED
X PGFCOR,1 ;RH & LH ARE ADR OF CORE BLOCKS FOR MESSAGE QUEUE
;LH ASSIGNED FIRST, RH USED FIRST
X PGDMNM,1 ;DDCMP MESSAGE NUMBERS
DEFSTR (DDRMN,PGDMNM(P1),7,8) ;RECEIVED MESSAGE NUMBER (HIGHEST)
DEFSTR (DDHXM,PGDMNM(P1),15,8) ;HIGHEST MESSAGE NUMBER TRANSMITTED
DEFSTR (DDHMA,PGDMNM(P1),23,8) ;HIGHEST MESSAGE NUMBER ACKED
DEFSTR (DDREPC,PGDMNM(P1),35,12) ;COUNTER FOR REPS
X PGDUPN,1 ;DUP11 LINE NUMBER
X PGUBAM,1 ;ADR OF UBA MAPPING REGISTER FOR PAGE
X PGZTIM,1 ;TIME LAST ZEROED COUNTERS, TICKED ONCE PER SECOND
X PGCOCN,10 ;CONTROL OUT COUNTS AS FOLLOWS
;10 = INVALID DDCMP HEADER
;12 = BAD CRC
;14 = BUFFER NOT AVAILABLE
;16 = DATASET READY TRANSITION
;20 = NXM
;22 = TRANSMIT UNDERRUN
;24 = RECEIVER UNDERRUN
;26 = KILL COMPLETE
X PGCOXX,1 ;OTHER
X PGXMCN,1 ;COUNT OF DDCMP MESSAGES TRANSMITTED
X PGNRNK,10 ;COUNT OF RECEIVED NAKS
; FIRST IS MISC NAKS, NEXT 7 ARE BY NAK CODE
X PGRMCN,1 ;COUNT OF DDCMP MESSAGES RECEIVED
X PGNXNK,10 ;COUNT OF TRNASMITTED NAKS
; FIRST IS MISC NAKS, NEXT 7 ARE BY NAK CODE
X PGKMCR,2 ;KMC11 REGISTERS WHEN KMC11 LAST HALTED
; BSEL0,,BSEL2
; BSEL4,,BSEL6
X PGLACK,2 ;LAST DDCMP ACK,NAK OR DATA MESSAGE TO UPDATE ACKED MESSAGE
X PGXBD1,4 ;1ST TRANSMIT BUFFER DESCRIPTOR LIST
X PGXMS1,140 ;1ST XMIT MESSAGE BUFFER
X PGXBD2,4 ;2ND TRANSMIT BUFFER DESCRIPTOR LIST
X PGXMS2,140 ;2ND XMIT MESSAGE BUFFER
X PGRBD1,4 ;1ST RECEIVE BUFFER DESCRIPTOR LIST
X PGRMS1,140 ;1ST INPUT MESSAGE BUFFER
X PGRBD2,4 ;2ND RECEIVE BUFFER DESCRIPTOR LIST
X PGRMS2,140 ;2ND INPUT MESSAGE BUFFER
IFN FTRACE,<
X PGTPTR,1 ;TRACE PUTTER
Z=<Z+1>&<-2> ;TRACE MUST BEGIN ON AN EVEN WORD
X PGTRCE,1 ;TRACE
>;IFN FTRACE
PURGE Z,X
SUBTTL DEFINITIONS -- KMC11
;KMC11 REGISTER BIT DEFINITIONS
BSEL0==0
BSEL1==1
KMCRUN==100000 ;RUN FLOP
KMCMCL==040000 ;MASTER CLEAR
KMCCWR==020000 ;CRAM WRITE
KMCSLU==010000 ;STEP LINE UNIT
KMCLUL==004000 ;LINE UNIT LOOP
KMCRMO==002000 ;ROM OUTPUT
KMCRMI==001000 ;ROM INPUT
KMCSUP==000400 ;STEP u-PROCESSOR
KMCRQI==000200 ;REQUEST INPUT
KMCIEO==000020 ;INTERRUPT ENABLE OUTPUT
KMCIEI==000001 ;INTERRUPT ENABLE INPUT
BSEL2==2
BSEL3==3 ;CONTAINS LINE NUMBER
KMCRDO==000200 ;READY FOR OUTPUT
KMCRDI==000020 ;READY FOR INPUT
KMCIOT==000004 ;SET FOR RECEIVE CLEARED FOR TRANSMIT
KMCTYP==000003 ;COMMAND TYPE
BASEIN==000003 ;BASE IN
CNTLIN==000001 ;CONTROL IN
BFADIN==000000 ;BUFFER ADDRESS IN
CNTLOU==000001 ;CONTROL OUT
BFADOU==000000 ;BUFFER ADDRESS OUT
BSEL4==4
BSEL5==5
;BUFFER DESCRIPTOR LIST ADDRESS (BUFFER ADR IN & OUT & CONTROL OUT)
BSEL6==6
BSEL7==7
;140000 ;ADR BITS 17 & 16 (BUFFER ADR IN & OUT & CONTROL OUT)
BFREOM==010000 ;END OF MESSAGE (BUFFER ADR OUT)
BFRENB==020000 ;BUFFER ENABLE (BUFFER ADR IN)
BFRKIL==010000 ;BUFFER KILL (BUFFER ADR IN)
CSRMSK==017770 ;MASK FOR DUP11 CSR ADR (BASE IN)
CDDCMP==100000 ;FLAG THIS A DDCMP LINE (CONTROL IN)
CHALFD==020000 ;FLAG THIS IS HALF DUPLEX (CONTROL IN)
;010000 ;ENABLE SECONDARY STATION (CONTROL IN)
;001000 ;CRC INHIBIT (CONTROL IN)
CENABL==000400 ;FLAG TO ENABLE LINE (CONTROL IN)
COUERR==000377 ;ERROR CODE (CONTROL OUT)
CRAMSZ==2000 ;SIZE OF KMC11 CRAM
DRAMSZ==2000 ;SIZE OF KMC11 DRAM
;BUFFER DESCRIPTOR LISTS ARE STRINGS OF 3 16 BIT WORDS
; 1ST WORD 16 BITS OF BUFFER ADDRESS
; 2ND WORD 16 BIT BYTE COUNT
; 3RD WORD
BDLLDS==100000 ;LAST DESCRIPTOR
BDLRSY==010000 ;RESYNC TRANSMITTER
;==006000 ;BUFFER ADDRESS 17 & 16
BDLEOM==001000 ;END OF MESSAGE
BDLSOM==000400 ;START OF MESSAGE
;MESSAGES TO THE KMC11
; BASEIN: BSEL2/ <LINE #>*400+3
; BSEL6/ <DUP11 ADR>&017770
; CONTROL IN: BSEL2/ <LINE #*400+1
; BSEL6/ FLAGS
; BF AD IN: BSEL2/ <LINE NU>*400+0+<4 IF INPUT>
; BSEL4/ BUFFER DESCRIPTOR LIST ADR
; BSEL6/ FLAGS
; BF AD OUT: BSEL2/ <LINE NU>*400+0+<4 IF RECEIVE>
; BSEL4/ BUFFER DESCRIPTOR LIST ADR
; BSEL6/ FLAGS
; CONTROL OUT: BSEL2/ <LINE NU>*400+1+<4 IF RECEIVE>
; BSEL4/ BUFFER DESCRIPTOR LIST ADR
; BSEL6/ ERROR CODE
SUBTTL DEFINITIONS -- DUP11
DUPADR==3760300 ;ADDRESS OF 1ST DUP11
DUPUBN==3 ;UNIBUS ADAPTER NUMBER FOR DUP11
DPRCSR==0 ;RECEIVER CSR
DPRDBF==2 ;(RO)RECEIVER DATA BUFFER
DPPCSR==2 ;(WO)PARAMETER CONTROL AND STATUS REGISTER
DPTCSR==4 ;TRANSMIT CONTROL AND STATUS REGISTER
DPCBLP==010000 ;EXTERNAL MAINTENCE MODE (CABLE LOOPBACK)
DPCNLP==004000 ;SYSTEMS TEST MODE (CONTROLLER LOOPBACK)
DPMAIN==014000 ;MAINTAINENCE MODE BITS
DPTDBF==6 ;TRANSMIT DATA BUFFER
SUBTTL DEFINITIONS -- DDCMP
SYN==226
IDLE==SYN ;NO SPECIAL IDLE CHARACTER
ENQ==005 ;1ST CHAR IN UNNUMBERED MESSAGES
DLE==220 ;1ST CHAR IN BOOTSTRAP MESSAGES
SOH==201 ;1ST CHAR IN NUMBERED MESSAGES
MAXOUT==10 ;MAXIMUM NUMBER OF DATA MESSAGES TO PUT IN PIPE
;NUMBERED MESSAGES
; SOH CC1 CC2 QSYNC SELECT R N A0 BCC1 DATA BCC2
; CC1&CC2 ARE TOTAL LENGTH OF DATA(BCC1 THRU BCC2 EXCLUSIVE)
; CC1 IS LOWORDER 8BITS OF LENGTH
; CC2 IS HIGH ORDER 6 BITS OF LENGTH
QSYNC==100 ;QSYNC BIT
SELECT==200 ;SELECT BIT
; R IS # OF LAST GOOD MESSAGE RECEIVED
; N IS THIS MESSAGE NUMBER
A0==1 ;A0 IS THE DESTINATION STATION ADR(ALWAYS 1)
; BCC1 IS THE 16 BIT CRC ON SOH THROUGH A0 INCLUSIVE
; DATA IS PASSED TO NCL
; BCC2 IS THE 16BIT CRC OF DATA
;UNNUMBERED MESSAGES
FILL==000 ;FILL CHARACTER
;ACK: ENQ ACK QSYNC SELECT FILL MSG# FILL A0 BCC1 BCC2
ACK==001
; MSG# IS LAST GOOD MSG RECEIVED
;NAK: ENQ NAK QSYNC SELECT RNAK MSG# FILL A0 BCC1 BCC2
NAK==002 ;NETIVE ACKNOWLEDGE
; RNAK IS NAK REASON AS FOLLOWS
NCDHBC==1 ;HEADER BCC ERROR
NCDBCC==2 ;DATA BCC ERROR
NCDREP==3 ;REP RESPONSE
NCDBTU==4 ;BUFFER TEMPORARILY UNAVAILABLE
NCDROV==5 ;RECEIVER OVERRUN
NCDMTL==6 ;MESSAGE TOO LONG
NCDHFE==7 ;HEADER FORMAT ERROR
; MSG# IS LAST GOOD MSG RECEIVED
;REP: ENQ REP QSYNC SELECT FILL FILL N A0 BCC1 BCC2
REP==003 ;REPLY TYPE
; N IS THE LAST MESSAGE# SENT
;RESET: ENQ RESET QSYNC SELECT FILL FILL N A0 BCC1 BCC2
; RESET==4 ;DC72 WILL NOT SEND THIS TYPE;WILL RESPOND WITH START
;RESAK: ENQ RESAK QSYNC SELECT FILL R FILL A0 BCC1 BCC2
RESAK==5 ;DC72 WILL NOT SEND THIS TYPE;WILL RESPOND WITH START
;START: ENQ STRT QSYNC SELECT FILL FILL N A0 BCC1 BCC2
STRT==006 ;START TYPE
; N IS NEXT NUMBERED MESSAGE TO BE SENT
;STACK: ENQ STACK QSYNC SELECT FILL R N A0 BCC1 BCC2
STACK==007 ;START ACKNOWLEDGE
; R IS NEXT EXPECTED MESSAGE # FOR RECPTION
; N IS NEXT MESSAGE # FOR TRANSMISSION
MSNMAX==377 ;MAXIMUM MESSAGE NUMBER
;WHEN A MSG IS RECEIVED CORRECTLY AN ACK IS SENT BACK;
; AN ACK IMPLIES ACK OF ALL LOWER NUMBERED MESSAGES
;WHEN A MSG IS RECEIVED INCORRECTLY A NAK MSG IS SENT BACK;
; A NAK IMPLIES ACK OF ALL LOWER NUMBERED MSGS.
SUBTTL PROTOTYPE MESSAGES
RESCD
ACKMSG: BYTE(18)ENQ+400*ACK,FILL+400*FILL,FILL+400*A0,FILL+400*FILL
NAKMSG: BYTE(18)ENQ+400*NAK,FILL+400*FILL,FILL+400*A0,FILL+400*FILL
REPMSG: BYTE(18)ENQ+400*REP,FILL+400*FILL,FILL+400*A0,FILL+400*FILL
STRTMS: BYTE(18)ENQ+400*STRT,QSYNC+SELECT+FILL+400*FILL,FILL+400*A0,FILL+400*FILL
STCKMS: BYTE(18)ENQ+400*STACK,QSYNC+SELECT+FILL+400*FILL,FILL+400*A0,FILL+400*FILL
SUBTTL DUP11 COMIOP CODE FOR KMC11
SWAPCD
COMIOP: BYTE(18)61220,61222,63234,63233,63224,16400,123600,60400
BYTE(18)103412,100405,440,63225,74524,63220,60365,101427
BYTE(18)63064,2777,4457,70000,76613,62614,114707,4003
BYTE(18)10375,16451,16517,2777,123620,103163,10375,4003
BYTE(18)140620,120440,103501,120440,103434,400,61222,2511
BYTE(18)100434,2511,10377,50220,101434,55223,55224,55225
BYTE(18)55226,55227,55222,10376,57221,43220,2517,767
BYTE(18)60360,101474,406,62400,40361,101477,100500,2777
BYTE(18)10375,123400,103105,2441,100434,2443,700,61231
BYTE(18)100434,120400,103514,100451,3020,61202,102121,2524
BYTE(18)100434,2531,600,100507,120440,103127,100533,120400
BYTE(18)102121,120440,103034,2451,457,63225,123072,60532
BYTE(18)70005,57233,47234,70213,14414,75231,56226,56227
BYTE(18)70213,120440,102555,102272,100764,102254,400,61222
BYTE(18)123620,116353,100434,521,61271,400,63232,73233
BYTE(18)67234,100607,123620,116353,63072,420,60372,101436
BYTE(18)4457,63220,60532,70000,57233,47234,70213,54620
BYTE(18)43220,101572,62560,101172,76620,56224,56225,415
BYTE(18)61230,43231,120600,102222,23421,60731,106750,23100
BYTE(18)23417,103637,1400,106441,60617,107576,100572,402
BYTE(18)62004,415,61230,120600,102243,23007,23030,60617
BYTE(18)100632,110740,110470,110545,137140,14770,62660,56226
BYTE(18)123160,740,62700,42227,401,62223,556,63236
BYTE(18)405,114643,120560,102277,17400,76560,100702,136500
BYTE(18)136500,422,76222,134560,2401,103707,2400,42223
BYTE(18)421,61230,120600,102312,123560,103724,122142,2600
BYTE(18)102722,2400,422,100732,2626,42222,2444,103331
BYTE(18)2440,600,62263,736,63236,114645,120560,1400
BYTE(18)103343,400,100746,410,63220,42700,76222,2633
BYTE(18)120560,103753,2605,400,76223,136540,454,70013
BYTE(18)2400,556,63236,114645,22144,22165,415,61230
BYTE(18)120440,1400,102775,432,100776,411,60413,63226
BYTE(18)120600,106000,23017,120560,113002,417,70006,43625
BYTE(18)1400,107033,2440,70206,136500,136520,123160,700
BYTE(18)60660,1400,1400,1400,1400,62620,60525,103556
BYTE(18)434,63235,114450,500,62705,43225,403,70006
BYTE(18)104414,60601,1400,107045,100634,404,62004,415
BYTE(18)61230,120600,106051,20400,107456,100634,22106,22127
BYTE(18)123220,501,63260,414,61311,454,70013,43620
BYTE(18)113105,451,70013,40620,1400,107107,106100,100634
BYTE(18)23140,770,62266,773,63677,62222,110520,20400
BYTE(18)107116,20420,102634,3020,110515,103634,43620,106164
BYTE(18)463,63236,445,114632,43621,76461,106152,62224
BYTE(18)56225,414,63260,61070,400,62223,120600,106136
BYTE(18)36002,22420,23140,402,62006,421,61230,120600
BYTE(18)106147,100634,105155,14400,104561,560,63236,114743
BYTE(18)400,76223,42222,104542,113040,20420,107573,62560
BYTE(18)60611,1400,107120,401,62223,104542,404,70013
BYTE(18)64214,57231,60610,117550,144620,2611,572,77236
BYTE(18)104620,2615,572,77236,104620,106627,653,77236
BYTE(18)74611,113545,43220,76607,43227,62600,160616,2605
BYTE(18)435,63235,110635,2656,404,70013,456,62671
BYTE(18)43231,601,60367,105653,405,60367,111545,620
BYTE(18)60367,105653,114567,401,62711,110545,2663,407
BYTE(18)70013,62607,110545,2677,410,70013,477,62667
BYTE(18)63271,404,70013,700,60667,62711,110545,2701
BYTE(18)110545,2703,110545,2717,74611,1400,106710,110545
BYTE(18)40367,111545,404,70013,420,62711,110545,2721
BYTE(18)100572,2727,107324,114555,60611,102172,104756,437
BYTE(18)63236,114627,105334,104737,60611,103172,110545,405
BYTE(18)70013,2743,100572,107356,114557,120600,106345,100572
BYTE(18)3002,42722,706,63236,416,110722,2633,60611
BYTE(18)107364,400,63235,110635,417,70013,57224,57223
BYTE(18)57222,57221,57220,76604,76603,76602,76601,76600
BYTE(18)60531,114762,120440,1400,112414,454,70013,43220
BYTE(18)423,62700,601,110420,417,63235,114571,605
BYTE(18)63222,426,63223,426,63235,110663,417,70006
BYTE(18)2602,120560,1400,107005,100556,100572,114567,104732
BYTE(18)60611,1400,113051,400,62222,2003,757,62660
BYTE(18)104542,626,76222,401,76223,43221,62561,105142
BYTE(18)451,70013,110446,105124,20420,113533,60600,112522
BYTE(18)473,63235,110731,774,23140,62266,451,70013
BYTE(18)43620,61620,107115,112127,100634,112541,2400,451
BYTE(18)70013,40620,1400,107107,3000,410,60671,62302
BYTE(18)621,104546,402,62223,652,63236,114645,454
BYTE(18)70013,2423,100634,422,63223,473,63235,601
BYTE(18)110734,62560,404,62223,104542,430,70013,43622
BYTE(18)1400,113160,435,63235,571,63236,414,110722
BYTE(18)563,63236,114631,111204,43622,112167,110577,572
BYTE(18)63236,114615,60562,62226,14621,42222,61230,545
BYTE(18)63235,120600,112201,110714,40620,112213,14000,14776
BYTE(18)76662,62607,110627,616,63236,114615,74607,62223
BYTE(18)42222,60602,112225,421,110626,621,61230,426
BYTE(18)70013,745,63236,401,114741,426,70013,43622
BYTE(18)112242,110654,645,63236,114615,74562,62226,42222
BYTE(18)621,61230,120600,112252,420,63223,604,63222
BYTE(18)411,60413,63226,70206,56226,56227,123220,501
BYTE(18)63260,43221,414,60661,61311,406,70006,57220
BYTE(18)43221,413,70006,56342,54441,76223,651,77236
BYTE(18)40620,1400,117245,110740,400,63223,604,63222
BYTE(18)411,110736,63223,3400,63221,63224,601,63222
BYTE(18)110746,400,63223,600,63222,432,60413,63226
BYTE(18)416,63236,70206,57220,57221,43224,10376,4003
BYTE(18)50220,76612,76600,76601,62603,60602,112361,2400
BYTE(18)110763,400,63223,77124,63124,63124,63524,76703
BYTE(18)76602,10376,57220,40620,115410,60360,115412,10376
BYTE(18)767,60360,115406,406,62400,174616,2517,174616
BYTE(18)62600,110777,70200,3200,42700,174616,417,70006
BYTE(18)64214,43620,117430,70206,432,63236,406,114741
BYTE(18)60520,117435,737,62660,170615,677,62660,403
BYTE(18)70006,57220,57221,57222,70206,76600,76601,62602
BYTE(18)70206,56224,56225,401,63220,55310,120600,116056
BYTE(18)37004,37025,465,63236,114721,37002,23023,36400
BYTE(18)36420,76604,76605,476,63236,114721,23020,36420
BYTE(18)76602,76603,76604,76605,43222,540,60662,62700
BYTE(18)411,60413,60366,115543,74564,116126,62224,60605
BYTE(18)62225,414,63260,61070,120600,116124,36420,16407
BYTE(18)60617,1400,116542,2400,404,63717,62222,542
BYTE(18)63236,114672,170615,754,43220,63260,62460,170615
BYTE(18)117157,60530,117561,406,114562,410,114562,412
BYTE(18)114562,424,63223,436,63235,605,110657,435
BYTE(18)63235,64214,757,63677,62222,600,63236,114672
BYTE(18)420,63717,62222,621,61230,54620,2633,1400
BYTE(18)117212,2605,120600,116212,170615,56226,56227,123220
BYTE(18)501,63260,414,63221,40661,61311,170616,407
BYTE(18)114632,424,70013,43221,76561,115640,14000,170616
BYTE(18)43221,76561,170616,3221,114647,402,3021,23140
BYTE(18)62006,23160,62107,115255,114662,123220,404,63000
BYTE(18)515,61271,123200,555,60660,60701,61230,120600
BYTE(18)116267,160616,402,70013,56226,56227,123220,501
BYTE(18)63260,414,61311,621,61230,114733,100572,460
BYTE(18)73013,60013,115315,64214,100414,67114,400,73233
BYTE(18)100414,402,23100,62004,23120,62105,123200,115336
BYTE(18)416,63260,61070,120600,116333,174616,404,63000
BYTE(18)114730,63220,56400,43220,76500,115347,164616,43220
BYTE(18)404,62400,164616,500,61271,761,63236,420
BYTE(18)110722,100434,117567,100572,0,0,0,0
BYTE(18)0,0,0,0,0,0,0,0
COMIOE: ;END OF COMIOP CODE
SUBTTL BOOT JSYS -- PERFORM BOOTSTRAP FUNCTIONS FOR KMC11
;BOOT JSYS IS USED TO LOAD AND DUMP KMC11
; CALL MOVEI AC1,<FUNCTION CODE>
; MOVEI AC2,<ADR OF ARGUMENT BLOCK>
; BOOT
;
;REG STRING IS BSEL0,BSEL2,BSEL4,BSEL6,MISC+NPR,INDATA,OUTDATA,INBA,OUTBA
; TABLE OF DISPATCH ADDRESSES
BOOTTB: EXP BTERR ;(0) = ACTIVATE ROM
EXP BTSMP ;(1) = SEND MOP MESSAGE
EXP BTERR ;(2) = LOAD MEMORY
EXP BTERR ;(3) = DUMP MEMORY
EXP BTIPR ;(4) = INITIALIZE PROTOCOL
EXP BTTPR ;(5) = TERMINATE PROTOCOL
EXP BTSTS ;(6) = RETURN STATUS
EXP BTERR ;(7) = WAIT FOR TO-10 DOORBELL
EXP BTRMP ;(10) = READ MOP MESSAGE
EXP BTKML ;(11) = LOAD KMC11
EXP BTKMD ;(12) = DUMP KMC11
EXP BTRLC ;(13) = RETURN LINE COUNTS
EXP BTCLI ;(14) = CONVERT LINE-ID TO PORT NUMBER
EXP BTCPN ;(15) = CONVERT PORT NUMBER TO LINE-ID
BOOTLN==.-BOOTTB
;HERE ON A BOOT JSYS
.BOOT:: MCENT ;MONITOR CONTEXT ENTRY
MOVE T1,CAPENB ;GET ENABLED CAPABILITIES
TXNN T1,SC%WHL!SC%OPR!SC%MNT ;WHEEL, OPERATOR, OR MAINTENANCE ?
ITERR (CAPX2) ;WHEEL, OPERATOR, or MAINTENANCE capability required
UMOVE Q3,1 ;GET FUNCTION CODE FROM USER
CAIL Q3,.BTROM ;CHECK RANGE OF GIVEN
CAIL Q3,.BTROM+BOOTLN ; FUNCTION CODE
BTERR: ITERR (ARGX02) ;Invalid function
; VALIDATE KMC11 ADDRESS
UMOVE Q1,2 ;GET ADDRESS OF USER'S ARGUMENT BLOCK
; DISPATCH TO PROCESSING ROUTINE BASED ON REQUESTED FUNCTION
CALL @BOOTTB-.BTROM(Q3) ;DISPATCH TO APPROPRIATE ROUTINE
ITERR () ;FAILED, RETURN ERROR TO USER
MRETNG ;SUCCESS, RETURN TO USER
;HERE TO GET KMC11 ADDRESS FROM ARGUMENT BLOCK
BTGKMA: UMOVE Q2,.BTKMC(Q1) ;GET KMC11 ADDRESS FROM USER
TRNE Q2,7 ;BE SURE FIRST KMC11 ADR
JRST BTDVX5 ;GIVE USER ERROR
MOVE T1,Q2 ;COPY KMC11 ADR FOR UBGOOD
LDB T2,[POINT 9,T1,22] ;GET UBA NUMBER & 5 BITS OF UNIBUS ADR
CAIE T2,77 ;1,,76#### ?
CAIN T2,177 ;OR 3,,76#### ?
CALL UBGOOD ;SEE IF THAT ADDRESS EXISTS
BTDVX5: ITERR (DEVX5) ;No such device
RET
;HERE TO GET A PORT NUMBER ARGUMENT
; RETURN: P1/ LINES PAGE
; T4/ DUP11 HDW ADR
BTGPRT: UMOVE P1,.BTPRT(Q1) ;GET PORT NUMBER FROM ARGUMENT BLOCK
HRRZ T4,P1 ;COPY ONLY PORT NUMBER
CAML T4,DUPNLN ;IS ARGUMENT IN RANGE ?
ITERR (ARGX19) ;Invalid unit number
LSH T4,3 ; *10
ADD T4,[DUPADR] ;MAKES THIS DUP11'S ADR
HRR P1,DUPPAG(P1) ;GET ADR OF LINES PAGE
RET
SUBTTL BOOT JSYS -- SEND MOP MESSAGE
BTSMP: CALL BTGPRT ;GET PORT NUMBER
RETSKP
SUBTTL BOOT JSYS -- INITIATE PROTOCOL
BTIPR: CALL BTGPRT ;GET PORT NUMBER
MOVE T1,[EXP KMCADR] ;GET ADDRESS OF KMC11
RDIO T1,(T1) ;GET STATUS FROM KMC11
TRNN T1,KMCRUN ;IS KMC11 RUNNING ?
RETBAD (KDPX01) ;KMC11 not running
LOAD T1,DDSTA ;GET CURRENT LINE STATE
UMOVE T2,.BTPRV(Q1) ;GET PROTOCOL VERSION NUMBER
RDIO T3,DPTCSR(T4) ;GET CURRENT MAINTENANCE MODE BITS
ANDI T3,DPMAIN ;LEAVE ONLY THE MAINTAINENCE MODE BITS
CAIN T2,.VNDDC ;STARTING DDCMP ?
JRST BTIDDC ;STARTING DDCMP
CAIN T2,.VNCNL ;INITIATING CONTROLLER LOOPBACK ?
JRST BTICNL ;YES
CAIN T2,.VNCBL ;INITIATING CABLE LOOPBACK ?
JRST BTICBL ;YES
CAIE T2,.VNMOP ;STARTING DDCMP MAINTENANCE MODE ?
JRST BTERR ;CAN'T DO THAT
;HERE TO INITIATE MAINTENANCE MODE ON LINE
BTIMOP: MOVEI T1,DPMAIN ;DUP11 MAINTENANCE MODE BITS
BCIO T1,DPTCSR(T4) ;CLEAR MAINTENANCE MODE
MOVEI T1,STAMAI ;NOW AM IN MAINTENANCE MODE
CALL DEDLIN ;DROP LINE
RETSKP
;HERE TO INITIATE DDCMP ON LINE
BTIDDC: CAIE T1,STADWN ;IS THE LINE DOWN ?
CAIN T1,STAMAI ;OR IS LINE IN MOP MODE ?
JRST BTIDC4 ;GO TRY TO DDCMP START IT
JUMPN T3,BTERR ;IF HDW LOOPED BACK LOSE
RETSKP ;ALREADY RUNNING SO WIN
BTIDC4: MOVEI T1,DPMAIN ;DUP11 MAINTENANCE MODE BITS
BCIO T1,DPTCSR(T4) ;CLEAR MAINTENANCE MODE
BTIDC6: MOVEI T1,STASTR ;NOW WANT TO SEND STARTS
CALL DEDLIN ;DROP LINE
RETSKP
;HERE TO INITIATE CONTROLLER LOOPBACK
BTICNL: MOVEI T2,DPCNLP ;BIT FOR CONTROLLER LOOPBACK
JRST BTILPB ;SET LOOPBACK
;HERE TO INITIATE CABLE LOOPBACK
BTICBL: MOVEI T2,DPCBLP ;BIT FOR FOR CABLE LOOPBACK
BTILPB: CAIE T1,STADWN ;IS THE LINE DOWN ?
CAIN T1,STAMAI ;OR IS LINE IN MOP MODE ?
JRST BTILP4
CAMN T1,T3 ;ALREADY THIS WAY ?
RETSKP ;ALREADY LOOPED BACK
JRST BTERR ;LOSE
BTILP4: MOVEI T1,DPMAIN ;MAINTAINENCE MODE BITS
BCIO T1,DPTCSR(T4) ;CLEAR BITS
BSIO T2,DPTCSR(T4) ;SET NEW FORM OF MAINTAINENCE MODE
JRST BTIDC6 ;NOW TURN ON THE LINE
SUBTTL BOOT JSYS -- TERMINATE PROTOCOL
BTTPR: CALL BTGPRT ;GET PORT NUMBER
MOVEI T1,DPMAIN ;MAINTAINENCE MODE BITS
BCIO T1,DPTCSR(T4) ;CLEAR MAINTAINENCE MODE BITS
NOINT
MOVEI T1,STADWN ;CODE FOR STOPPED
CALL DEDLIN ;CLEAN UP LINE
OKINT
RETSKP
SUBTTL BOOT JSYS -- RETURN PROTOCOL STATUS
BTSTS: CALL BTGPRT ;GET PORT NUMBER
LOAD T1,DDSTA ;GET LINE STATE
MOVEI T3,.VNMOP ;CALL IT MOP MODE
CAIN T1,STAMAI ;MAINTENANCE MODE ?
JRST BTSTS9 ;LINE IS IN MAINTAINENCE MODE
SETOM T3 ;ASSUME NOT RUNNING
CAIN T1,STADWN ;IS THE LINE STOPPED
JRST BTSTS9 ;LINE IS DOWN
MOVEI T3,.VNDDC ;ASSUME RUNNING DDCMP
RDIO T2,DPTCSR(T4) ;GET MAINTAINENCE MODE STATUS
ANDI T2,DPMAIN ;STRIP EXTRA BITS
JUMPE T2,BTSTS9 ;IF NOT MAINTAINENCE THEN RUNNING
SETOM T3 ;IN CASE INTERNAL MAINTENANCE MODE
CAIN T2,DPCNLP ;CONTROLLER LOOPBACK ?
MOVEI T3,.VNCNL ;YES
CAIN T2,DPCBLP ;CABLE LOOPBACK ?
MOVEI T3,.VNCBL ;YES
BTSTS9: UMOVEM T3,.BTPRV(Q1) ;GIVE STATE TO USER
RETSKP
SUBTTL BOOT JSYS -- RECEIVE MOP MESSAGE
BTRMP: CALL BTGPRT ;GET PORT NUMBER
RETSKP
SUBTTL BOOT JSYS -- LOAD KMC11
BTKML: CALL BTGKMA ;GET KMC11 ADR FROM ARGUMENT BLOCK
CALL BTSTOP ;STOP THE KMC11 IF RUNNING
MOVEI T1,KMCMCL ;TO CLEAR THE KMC11
WRIO T1,BSEL0(Q2) ;RESET THE KMC11
;QUICK CHECK OF KMC11 INTEGRITY
MOVEI T2,200 ;BIT PATERN FOR FIRST REGISTER
MOVE T4,Q2 ;COPY KMC11 ADR
BTCHK0: WRIO T2,@T4 ;WRITE THE REGISTER
RDIO T1,@T4 ;THEN READ IT BACK
CAME T2,T1 ;DO THE BITS MATCH ?
JRST [ TXO T1,BT%RVE ;REGISTER VERIFY ERROR
JRST KMCILL ] ;REPORT PROBLEM THEN QUIT,Q2
JUMPE T2,BTCHK2 ;DONE WITH REGISTER
LSH T2,-1 ;NEXT MASK TO TRY
JRST BTCHK0 ;TRY NEXT MASK
BTCHK2: MOVEI T2,100000 ;BIT PATERN FOR NEXT BSEL
ADDI T4,2 ;NEXT BSEL
TRNE T4,7 ;DONE ALL REGS YET ?
JRST BTCHK0 ;LOOP BACK FOR REST OF REGISTERS
;VERIFY DRAM IS OK
CALL MARCLR ;INITIALIZE THE MAR
MOVEI T4,DRAMSZ ;SIZE OF THE DRAM
MOVEI T1,041222 ;MOVE <MEM><BSEL2>
CALL KMCXCT ;READ DRAM (TO RESTORE LATER)
RDIO Q3,BSEL2(Q2) ;GET OLD CONTENTS
BTCKD0: MOVEI T3,200 ;PATERN FOR DRAM
BTCKD1: WRIO T3,BSEL2(Q2) ;SO WE WRITE INTO DRAM
MOVEI T1,122440 ;MOVE <BSEL2><MEM>
CALL KMCXCT ;WRITE DRAM
SETZ T2,
WRIO T2,BSEL2(Q2) ;CLEAR BSEL2
MOVEI T1,041222 ;MOVE <MEM><BSEL2>
CALL KMCXCT
RDIO T1,BSEL2(Q2) ;READ MEMORY
CAME T1,T3 ;RIGHT DATA ?
JRST [ TXO T1,BT%DVE ;DRAM VERIFY ERROR
JRST KMCILL ] ;REPORT ERROR THEN QUIT
JUMPE T3,BTCKD2
LSH T3,-1 ;NEXT PATERN FOR DRAM
JRST BTCKD1 ;TRY THAT ONE
BTCKD2: WRIO Q3,BSEL2(Q2) ;OLD CONTENTS OF DRAM
MOVEI T1,136440 ;MOVE <BSEL2><MEM><MARINC>
CALL KMCXCT ;RESTORE DRAM LOCATION
SOJG T4,BTCKD0 ;ON TO NEXT DRAM LOCATION
;HERE TO LOAD THE CRAM
BTKLC0: UMOVE T4,.BTKCC(Q1) ;GET COUNT FOR CRAM BYTES
UMOVE Q3,.BTKCP(Q1) ;GET POINTER FOR CRAM BYTES
JUMPLE T4,BTKLC9 ;IN CASE NOT LOADING CRAM
SETZ T3, ;FIRST ADDRESS TO LOAD
BTKLC2: WRIO T3,BSEL4(Q2) ;PUT ADR IN REGISTER
AOS T3 ;NEXT CRAM ADR
XCTBU [ILDB T1,Q3] ;GET NEXT BYTE FOR CRAM
WRIO T1,BSEL6(Q2) ;PUT DATA IN RIGHT PLACE
MOVEI T1,KMCRMO ;SELECT ROM OUTPUT
WRIO T1,BSEL0(Q2) ;SET IT
MOVEI T1,KMCRMO!KMCCWR ;NOW DO CRAM WRITE
WRIO T1,BSEL0(Q2)
SETZ T1,
WRIO T1,BSEL0(Q2) ;CLEAR UP THE KMC11
SOJG T4,BTKLC2 ;ON FOR REST OF DATA
;NOW VERIFY CRAM LOAD
UMOVE T4,.BTKCC(Q1) ;GET COUNT FOR CRAM BYTES
UMOVE Q3,.BTKCP(Q1) ;GET POINTER FOR CRAM BYTES
SETZ T3, ;FIRST ADR TO VERIFY
BTKLC4: WRIO T3,BSEL4(Q2) ;PUT ADR IN KMC11
MOVEI T1,KMCRMO ;FLAG FOR ROM OUTPUT
WRIO T1,BSEL0(Q2) ;TELL IT TO READ CRAM
RDIO T1,BSEL6(Q2) ;GET CRAM DATA
XCTBU [ILDB T2,Q3] ;GET NEXT BYTE FROM USER
UMOVEM Q3,.BTKCP(Q1) ;SAVE UPDATED CRAM POINTER
CAME T1,T2 ;IS CRAM RIGHT ?
JRST [ TXO T1,BT%CVE ;FLAG FOR CRAM VERIFY ERROR
JRST KMCILL ] ;REPORT ERROR THEN QUIT
AOS T3 ;NEXT CRAM ADR
SOJG T4,BTKLC4 ;ON TO NEXT CRAM LOCATION
BTKLC9: UMOVEM T4,.BTKCC(Q1) ;SAVE UPDATED COUNT
;HERE TO LOAD THE DRAM
BTKLD0: UMOVE T4,.BTKDC(Q1) ;GET COUNT FOR DRAM BYTES
UMOVE Q3,.BTKDP(Q1) ;GET POINTER FOR DRAM BYTES
JUMPLE T4,BTKLD9 ;IN CASE NOT LOADING DRAM
CALL MARCLR ;INITIALIZE THE MAR
MOVEI T1,136440 ;MOVE <BSEL2><MEM><MARINC>
BTKLD2: XCTBU [ILDB T2,Q3] ;GIVE NEXT BYTE TO USER
WRIO T2,BSEL2(Q2) ;PUT DATA IN BSEL2 FOR KMC11
CALL KMCXCT ;HAVE KMC11 PUT DATA INTO MEM
SOJG T4,BTKLD2 ;COUNT BYTE AND THEN DO NEXT
UMOVE T4,.BTKDC(Q1) ;GET COUNT FOR DRAM BYTES
UMOVE Q3,.BTKDP(Q1) ;GET POINTER FOR DRAM BYTES
CALL MARCLR ;INITIALIZE THE MAR
MOVEI T1,055222 ;MOVE <MEM><BSEL2><MARINC>
BTKLD4: CALL KMCXCT ;GET NEXT BYTE FROM DRAM
RDIO T2,BSEL2(Q2) ;GET DATA
XCTBU [ILDB T3,Q3] ;GET WHAT USER WANTED
UMOVEM Q3,.BTKDP(Q1) ;SAVE UPDATED DRAM POINTER
CAME T2,T3 ;DO THEY MATCH ?
JRST [ TXO T2,BT%DVE ;DRAM VERIFY ERROR
MOVE T1,T2 ;PUT IN RIGHT REGISTER
JRST KMCILL ] ;DONE WITH JSYS
SOJG T4,BTKLD4 ;LOOP BACK FOR REST OF VERIFY
BTKLD9: UMOVEM T4,.BTKDC(Q1) ;SAVE UPDATED DRAM COUNT
;HERE TO LOAD THE REGISTERS
MOVEI T1,KMCMCL ;DO A MASTER CLEAR AGAIN
WRIO T1,BSEL0(Q2)
SETZ T1, ;TO FINISH IT
WRIO T1,BSEL0(Q2)
WRIO T1,BSEL2(Q2) ;CLEAR BSEL2
WRIO T1,BSEL4(Q2) ;CLEAR BSEL4
WRIO T1,BSEL6(Q2) ;CLEAR BSEL6
UMOVE T1,.BTKSA(Q1) ;GET STARTING ADDRESS
SETZ T3, ;DEFAULT IS DON'T START
JUMPGE T1,BTKLR0 ;IN CASE NO STARTING ADDRESS
TRO T3,KMCRUN ;IF GAVE A STARTING ADR ASSUME WANTS TO RUN
LSHC T1,-^D8 ;LEAVE ONLY BRANCH ADR BITS 9,8
ANDI T1,3 ;STRIP ANY EXTRANEOUS BITS
LSH T1,^D3
LSHC T1,^D8
IORI T1,100400 ;MAKES AN UNCONDITIONAL BRANCH
CALL KMCXCT ;EXECUTE THE BRANCH
BTKLR0: UMOVE T4,.BTKRC(Q1) ;GET COUNT FOR REGISTER BYTES
UMOVE Q3,.BTKRP(Q1) ;GET POINTER FOR REGISTER BYTES
JUMPLE T4,BTKLR9 ;IN CASE NOT LOADING REGISTER
XCTBU [ILDB T1,Q3] ;GET CONTENTS FOR BSEL0
IOR T3,T1 ;INCLUDE WITH RUN BIT
MOVE T2,Q2 ;COPY KMC11 ADR
JRST BTKLR4
BTKLR2: XCTBU [ILDB T1,Q3] ;GET NEXT BYTE FROM USER
WRIO T1,(T2) ;LOAD REGISTER
BTKLR4: ADDI T2,2 ;READY FOR NEXT REGISTER
TRNE T2,7 ;LOADED ALL FOUR ?
SOJG T4,BTKLR2 ;ON TO NEXT
BTKLR9: WRIO T3,BSEL0(Q2) ;NOW SET BSEL0 (I.E. RUN FLOP)
UMOVEM T4,.BTKRC(Q1) ;SAVE UPDATED REGISTER COUNT
UMOVEM Q3,.BTKRP(Q1) ;SAVE UPDATED REGISTER POINTER
CAMN Q2,[KMCADR] ;IS THIS OUR KMC11 ?
CALL COMINI ;INITIALIZE THE COMIOP
RETSKP
KMCILL: MOVEM T1,.BTKER(Q1) ;GIVE USER ERROR CODE
BUG (INFO,KMCBRK,<KMC11 broken>,Q2)
MOVEI T1,IOX5 ;Device or data error
RET ;REPORT PROBLEM THEN QUIT
;HERE TO INITIALIZE THE COMIOP
COMINI: SKIPL P1,DUPLIM ;GET NUMBER OF DUP11'S
RET ;NONE SO DONE
MOVEI T1,KMCINQ+3 ;START PUTTING ENTRIES HERE
MOVEM T1,KMCINQ ;INITIALIZE THE PUTTER
MOVEM T1,KMCINQ+1 ;INITIALIZE THE TAKER
KMBT.8: HRR P1,DUPPAG(P1) ;GET ADR OF LINES PAGE
SETZM PGXBD1(P1) ;FIRST TRANSMIT BUFFER IS FREE
SETZM PGXBD2(P1) ;SECOND TRANSMIT BUFFER IS FREE
SETZM PGRBD1(P1) ;FIRST RECEIVE BUFFER IS FREE
SETZM PGRBD2(P1) ;SECOND RECEIVE BUFFER IS FREE
IFN FTRACE,<
MOVEI T1,PGTRCE(P1) ;GET ADR OF TRACE
MOVEM T1,PGTPTR(P1) ;SAVE PUTTER
>;IFN FTRACE
MOVEI T1,STASTR ;TRYING TO START LINE
STOR T1,DDSTA ;REMEMBER NEW STATE
MOVEI T1,1 ;QUICK TIMER
STOR T1,DDTIM ;SO WE SEND A START SOON
HRRZ T2,PGDUPN(P1) ;GET LINE NUMBER
LSH T2,3 ;MULTIPLY BY 8
ADD T2,[DUPADR] ;MAKES THIS LINES ADR
SETZ T1,
WRIO T1,(T2) ;CLEAR FIRST DUP11 REGISTER
WRIO T1,2(T2) ;CLEAR 2ND DUP11 REGISTER
WRIO T1,4(T2) ;CLEAR 3RD DUP11 REGISTER
WRIO T1,6(T2) ;CLEAR 4TH DUP11 REGISTER
HRRZ T1,PGDUPN(P1) ;THIS IS LINE NUMBER
LSH T1,^D8 ;POSITION FOR LH UNIBUS BYTE
IORI T1,BASEIN ;COMMAND TYPE
ANDI T2,CSRMSK ;STRIP EXTRA BITS
CALL KMCINP ;GIVE MSG TO KMC11
HRRZ T1,PGDUPN(P1) ;LINE NUMBER
LSH T1,^D8 ;POSITION FOR LH UNIBUS BYTE
IORI T1,CNTLIN ;WILL BE A CONTROL IN MESSAGE
MOVEI T2,CDDCMP!CENABL ;DDCMP AND ENABLE LINE
CALL KMCINP ;GIVE MSG TO KMC11
MOVEI T3,PGRBD1(P1) ;FIRST RECEIVER BUFFER
CALL RCVENB ;START THE RECEIVER ... BUFFER 1
MOVEI T3,PGRBD2(P1) ;2ND RECEIVER BUFFER
CALL RCVENB ;START THE RECEIVER ... BUFFER 2
HRR P1,PGDUPN(P1) ;GET LINE NUMBER AGAIN
AOBJN P1,KMBT.8 ;LOOP BACK FOR REST OF DUP11 LINES
RET
SUBTTL BOOT JSYS -- DUMP THE KMC11
BTKMD: CALL BTGKMA ;GET KMC11 ADR FROM ARGUMENT BLOCK
UMOVE T4,.BTKRC(Q1) ;GET COUNT FOR SAVING REGISTERS
UMOVE Q3,.BTKRP(Q1) ;POINTER FOR STORING REGISTERS
JUMPLE T4,BTKDR9 ;IN CASE DOESN'T WANT REGISTERS
MOVE T3,Q2 ;COPY KMC11 ADR
BTKDR2: RDIO T1,(T3) ;GET DATA FROM BSEL#
XCTBU [IDPB T1,Q3] ;SAVE NEXT BYTE FOR USER
SOJLE T4,BTKDR9 ;IF NO ROOM DONE
ADDI T3,2 ;ON TO NEXT REGISTER
TRNE T3,7 ;DONE ALL FOUR ?
JRST BTKDR2 ;ON FOR NEXT
CALL BTSTOP ;STOP THE KMC11 IF RUNNING
MOVEI T1,121202 ;MOVE <NPR>,<BSEL2>
CALL BTKDR6
MOVEI T1,021002 ;MOVE <IBUS 0>,<BSEL2>
CALL BTKDR6
CALL BTKDR6
CALL BTKDR6
CALL BTKDR6
BTKDR9: CALL BTSTOP ;STOP THE KMC11 IF RUNNING
UMOVEM T4,.BTKRC(Q1) ;SAVE UPDATED REG COUNTER
UMOVEM Q3,.BTKRP(Q1) ;SAVE UPDATED POINTER
;HERE TO DUMP THE KMC11 CRAM
BTKDC0: UMOVE T4,.BTKCC(Q1) ;GET COUNTER FOR CRAM DATA
UMOVE Q3,.BTKCP(Q1) ;GET POINTER FOR CRAM DATA
JUMPLE T4,BTKDC9 ;IN CASE DOESN'T WANT TO DUMP CRAM
SETZ T2, ;CRAM ADR TO DUMP NEXT
BTKDC2: WRIO T2,BSEL4(Q2) ;SELECT ADR TO DUMP
MOVEI T1,KMCRMO ;FLAG TO DUMP CRAM
WRIO T1,BSEL0(Q2) ;TELL IT TO DUMP CRAM
RDIO T1,BSEL6(Q2) ;GET LOCATION FROM CRAM
XCTBU [IDPB T1,Q3] ;PUT BYTE IN USER CORE
SOJLE T4,BTKDC9 ;COUNT BYTE
AOJA T2,BTKDC2 ;ON FOR NEXT BYTE
BTKDC9: UMOVEM T4,.BTKCC(Q1) ;SAVE UPDATED CRAM COUNTER
UMOVEM Q3,.BTKCP(Q1) ;SAVE UPDATED POINTER
;HERE TO DUMP THE KMC11 DRAM
BTKDD0: UMOVE T4,.BTKDC(Q1) ;GET COUNTER FOR DRAM DATA
UMOVE Q3,.BTKDP(Q1) ;GET POINTER FOR DRAM DATA
JUMPLE T4,BTKDD9 ;IN CASE DOESN'T WANT TO DUMP THE DRAM
CALL MARCLR ;INITIALIZE THE MAR
BTKDD2: MOVEI T1,055222 ;MOVE <MEM>,<BSEL2>,<MARINC>
CALL KMCXCT ;GET NEXT DRAM BYTE
RDIO T2,BSEL2(Q2) ;GET BYTE WE JUST PUT IN BSEL2
XCTBU [IDPB T2,Q3] ;GIVE BYTE TO USER
SOJG T4,BTKDD2 ;ON FOR NEXT BYTE
BTKDD9: UMOVEM T4,.BTKDC(Q1) ;SAVE UPDATED DRAM COUNTER
UMOVEM Q3,.BTKDP(Q1) ;SAVE UPDATED DRAM POINTER
RETSKP
;HERE TO FORCE KMC11 TO GIVE US INTERNAL INFORMATION
BTKDR6: JUMPLE T4,R ;IN CASE COUNT ALREADY EXHAUSTED
CALL KMCXCT ;XCT FIRST INSTRUCTION
ADDI T1,21 ;NEXT SOURCE & DEST
CALL KMCXCT ;EXECUTE NEXT INSTRUCTION
ADDI T1,17 ;INCREMENT SOURCE,DECREMENT DESTINATION
RDIO T2,BSEL2(Q2) ;GET DATA WE JUST FORCED TO BSEL2 & BSEL3
XCTBU [IDPB T2,Q3] ;SAVE THIS REGISTER
SOJA T4,R ;COUNT BYTE GIVEN TO USER
;HERE TO CLEAR THE MAR
MARCLR: MOVEI T1,004000 ;CLEAR MAR LOW
CALL KMCXCT ;DO IT
MOVEI T1,010000 ;CLEAR MAR HI
;CALL KMCXCT ;DO IT
;RET
;HERE TO EXECUTE A KMC11 INSTRUCTION
; CALL WITH KMC11 INSTRUCTION IN T1
KMCXCT: MOVEI T2,KMCRMI
WRIO T2,BSEL0(Q2) ;PUT BSEL1 IN KNOWN STATE
WRIO T1,BSEL6(Q2) ;LOAD BSEL6 & BSEL7
MOVEI T2,KMCRMI!KMCSUP
WRIO T2,BSEL0(Q2) ;DO ONE INSTRUCTION
SETZ T2, ;TO CLEAN UP BSEL0
WRIO T2,BSEL0(Q2) ;CLEAN OUT BSEL0
RET
;HERE TO STOP THE KMC11 AS PART OF BOOT JSYS
BTSTOP: NOINT ;PREVENT INTERRUPTS
CAMN Q2,[KMCADR] ;IS THIS OUR KMC11 ?
CALL KMCHLT ;YES SO CLEAN UP FIRST
SETZ T1, ;TO CLEAR BSEL0
WRIO T1,BSEL0(Q2) ;STOP THE KMC11
OKINT
RET
SUBTTL BOOT JSYS -- RETURN LINE COUNTERS
BTRLC: CALL BTGPRT ;GET PORT NUMBER
MOVE T1,PGZTIM(P1) ;GET TIME SINCE ZEROED COUNTERS
UMOVEM T1,.BTZTM(Q1) ;GIVE NUMBER TO USER
HRLI T4,-11 ;NUMBER OF STATUS COUNTERS
HRRI T4,PGCOCN(P1) ;POINT TO STATUS COUNTERS
MOVEI T3,.BTSCC(Q1) ;ADR OF USERS COUNT FOR STATUS COUNTERS
CALL BTRLCS ;GIVE STATUS COUNTERS TO USER
HRLI T4,-11 ;NUMBER OF RECEIVE COUNTERS
HRRI T4,PGRMCN(P1) ;POINT TO RECEIVE COUNTERS
MOVEI T3,.BTRCC(Q1) ;ADR OF USERS COUNT FOR RECEIVER COUNTERS
CALL BTRLCS ;GIVE RECEIVE COUNTERS TO USER
HRLI T4,-11 ;NUMBER OF TRANSMIT COUNTERS
HRRI T4,PGXMCN(P1) ;POINT TO TRANSMIT COUNTERS
MOVEI T3,.BTTCC(Q1) ;ADR OF USERS COUNT FOR TRANSMITTER COUNTERS
CALL BTRLCS ;GIVE TRANSMIT COUNTERS TO USER
SKIPG P1 ;DID WE ZERO COUNTERS ?
SETZM PGZTIM(P1) ;START ZERO TIMER AGAIN
RETSKP
BTRLCS: UMOVE T2,1(T3) ;GET USERS BYTE POINTER
BRLCS2: UMOVE T1,(T3) ;GET COUNT USER GAVE
SOJL T1,BRLCS8 ;CHECK FOR USER HAS ENOUGH
UMOVEM T1,(T3) ;GIVE USER UPDATED COUNTER
;PIOFF
MOVE T1,(T4) ;GET NEXT COUNTER
SKIPG P1 ;WANT TO ZERO COUNTER ?
SETZM (T4) ;CLEAR COUNTER
;PION
XCTBU [IDPB T1,T2] ;GIVE COUNTER TO USER
AOBJN T4,BRLCS2 ;LOOP BACK FOR NEXT COUNTER
BRLCS8: UMOVEM T2,1(T3) ;GIVE UPDATED POINTER TO USER
RET
SUBTTL BOOT JSYS -- CONVERT LINE-ID TO PORT NUMBER
BTCLI: CALL BTGPLX ;SETUP T4 WITH USER POINTER
; AND T3 TO POINT TO ASCIZ \KDP_0_\
BTCLI2: ILDB T1,T3 ;GET NEXT BYTE FROM OUR STRING
XCTBU [ILDB T2,T4] ;GET NEXT BYTE FROM USER STRING
JUMPE T1,BTCLI5 ;IF DONE WITH OUR STRING
CAMN T1,T2 ;DO TWO BYTES MATCH
JRST BTCLI2 ;ON FOR REST OF STRING
BTCLI5: TRC T2,60 ;STRIP EXTRA BITS
CAML T2,DUPNLN ;IS NUMBER IN RANGE ?
JRST BTERR ;LOSE
UMOVEM T2,.BTPRT(Q1) ;RETURN PORT NUMBER TO USER
RETSKP
SUBTTL BOOT JSYS -- CONVERT PORT NUMBER TO LINE-ID
BTCPN: CALL BTGPLI ;GET PORT NUMBER AND POINTERS TO LINEID
ILDB T1,T3 ;GET NEXT BYTE FOR USER
XCTBU [IDPB T1,T4] ;GIVE BYTE TO USER
JUMPN T1,.-2 ;LOOP ON FOR REST OF NAME
HRRZ T2,PGDUPN(P1) ;GET DUP11 LINE NUMBER
IORI T2,"0" ;MAKE IT ASCII
XCTBU [DPB T2,T4] ;FINISH NAME
XCTBU [IDPB T1,T4] ;MAKE IT ASCIZ
UMOVEM T4,.BTLID(Q1) ;GIVE POINTER BACK TO USER
RETSKP
;HERE TO GET PORT NUMBER AND POINTER TO LINEID FOR BTCLI & BTCPN
BTGPLI: CALL BTGPRT ;GET PORT NUMBER
BTGPLX: UMOVE T4,.BTLID(Q1) ;GET USERS POINTER
HLRZ T1,T4 ;GET PART OF BYTE POINTER
CAIN T1,777777 ;SPECIAL CASE ?
HRLI T4,440700 ;MAKE IT ASCII POINTER
MOVE T3,[POINT 7,[ASCIZ \KDP_0_\]]
RET
SUBTTL HERE TO INITIALIZE THE KMC11
DUPINI::MOVE T1,[KMCADR] ;ADR OF KMC11
CALL UBGOOD ;CHECK TO SEE IF INSTALLED
RET ;NO KMC11
MOVSI P2,-DUPN ;NUMBER OF DUP11'S ASSEMBLED FOR
MOVEI P1,KMCPAG ;POINT TO FIRST DUP11 PAGE
DPINI2: HRRZM P1,DUPPAG(P2) ;SAVE ADR OF PAGE FOR LINE
;HRL T1,P1 ;BUILD BLT POINTER
;HRRI T1,1(P1) ; TO CLEAR
;SETZM (P1) ; THE LINES
;BLT T1,777(P1) ; PAGE
HRRZM P2,PGDUPN(P1) ;SAVE LINE NUMBER IN LINES PAGE
HRRZ T1,P2 ;COPY DUP11 NUMBER
LSH T1,3 ;OFFSET FROM BASE ADDRESS
ADD T1,[DUPADR] ;MAKE ADDRESS OF THIS DUP11
CALL UBGOOD ;SEE IF IT EXISTS
JRST DPINI3 ;DON'T HAVE THE DUP11
MOVEI T1,KMCUBN ;UBA UNIT NUMBER
MOVEI T2,1 ;ONLY NEED ONE PAGE
CALL ALUBWA ;GET A UBA ADR FOR PAGE
BUG (HLT,DUPUBA,<no Unibus Address>)
HRLZM T2,PGUBAD(P1) ;SAVE UNIBUS ADR OF PAGE
HRLM T2,DUPPAG(P2) ;SAVE UNIBUS ADR OF PAGE
MOVEM T1,PGUBAM(P1) ;SAVE ADR OF UBA MAPPING REGISTER
HRRZ T2,DUPPAG(P2) ;GET ADR OF PAGE
LSH T2,-^D9 ;CONVERT TO PAGE NUMBER
IORI T2,UNBVBT ;FLAG VALID
WRIO T2,@T1 ;SET MAPPING REGISTER
MOVE T1,[.RESP1,,BLKSIZ] ;PRIORITY AND SIZE OF BLOCK TO GET
MOVX T2,RS%SE0+.RESNP ;GET IT FROM THE NETWORK POOL
CALL ASGRES ;GET THE BLOCK
BUG (HLT,DUPCOR,<No core for DUP11>)
CALL SAVBLK ;SAVE ADR OF BLOCK
ADDI P1,1000 ;ON TO NEXT LINES PAGE
AOBJN P2,DPINI2 ;LOOP BACK FOR OTHER DUP11'S
DPINI3: HRRZM P2,DUPNLN ;SAVE NUMBER OF DUP11'S
HRLZS P2 ;PUT NUMBER OF EXISTING DUP11'S IN LH
MOVNM P2,DUPLIM ;REMEMBER HOW MANY THERE ARE
SKIPL P1,DUPLIM ;GET NUMBER OF DUP11'S
RET ;NONE
MOVSI T1,(<XPCW>) ;INTERRUPT INSTRUCTION
HRRI T1,DUPXPC ;XPCW ADR FOR VECTOR A (INPUT) INTERRUPTS
SETZM 2(T1) ;CLEAR INTERRUPT FLAGS
MOVEI T3,KMCVCA ;INTERRUPT ROUTINE FOR VECTOR A
MOVEM T3,3(T1) ;SET INTERRUPT ROUTINE ADR
MOVEI T2,KMCVEC/4 ;OFFSET FOR VECTOR
ADD T2,SMTEPT+KMCUBN ;GET ADR OF VECTOR TABLE
MOVEM T1,(T2) ;SET VECTOR
ADDI T1,4 ;XPCW ADR FOR VECTOR B (OUTPUT) INTERRUPTS
SETZM 2(T1) ;FLAGS FOR VECTOR B
MOVEI T3,KMCVCB
MOVEM T3,3(T1) ;INTERRUPT ROUTINE FOR VECTOR B
MOVEM T1,1(T2) ;SET VECTOR B
SKIPN PROFLG ;WANT TO START THE KMC11 ?
RET ;DON'T START IT
;NOW BOOT THE KMC11
MOVEI T2,KMCPAG+PGXMS1 ;USE THIS FOR ARG BLOCK FOR BOOT JSYS
SETZM (T2) ;CLEAR ARG BLOCK
HRL T1,T2
HRRI T1,1(T2)
BLT T1,.BTKSA(T2) ;CLEAR ARGUMENT BLOCK
MOVE T1,[KMCADR] ;ADDRESS OF KMC11 HDW
MOVEM T1,.BTKMC(T2) ;SAVE IN ARGUMENT BLOCK
MOVEI T1,<COMIOE-COMIOP>*2 ;SIZE OF COMIOP CODE
MOVEM T1,.BTKCC(T2) ;SAVE IN ARGUMENT BLOCK
MOVE T1,[POINT 18,COMIOP] ;POINTER TO COMIOP CODE
MOVEM T1,.BTKCP(T2) ;SAVE IN ARGUMENT BLOCK
MOVSI T1,400000 ;WANT TO START AT 0
MOVEM T1,.BTKSA(T2) ;SAVE IT IN ARGUMENT BLOCK
MOVEI T1,.BTKML ;CODE FOR LOAD FUNCTION
BOOT ;LOAD THE KMC11
ERJMP [ BUG (INFO,KMCLOD,<KMC11 LOAD FAILED>)
RET ]
RET
;HERE TO STOP THE KMC11 uPROCESSOR
RESCD
KMCHLT::SAVEP ;SAVE THE P'S
MOVEI P1,KMCPAG ;DUMP INTO FIRST LINES BLOCK
MOVE P2,[KMCADR] ;ADDRESS OF THE KMC11
MOVE P3,[POINT 18,PGKMCR(P1)] ;POINT TO REG DUMP AREA
KMHLT2: RDIO T1,BSEL0(P2) ;GET NEXT REGISTER FROM THE KMC11
IDPB T1,P3 ;SAVE IT
ADDI P2,2 ;POINT TO NEXT REGISTER
TRNE P2,7 ;DONE ALL REGS YET ?
JRST KMHLT2 ;LOOP BACK FOR REST
SUBI P2,^D8 ;FIX UP KMC11 ADR
MOVEI T1,KMCRUN ;RUN FLOP
BCIO T1,BSEL0(P2) ;STOP THE uPROCESSOR
MOVE P1,DUPLIM ;LINE NUMBER
KMHLT3: HRR P1,DUPPAG(P1) ;GET ADR OF LINES PAGE
MOVEI T1,STADWN ;KMC11 IS NOT RUNNING
CALL DEDLIN ;MOURN THE DEAD LINE
HRR P1,PGDUPN(P1) ;GET THE LINE NUMBER AGAIN
AOBJN P1,KMHLT3 ;LOOP FOR REST OF DUP11 LINES
RET
;HERE FROM NSPSRV TO CHECK FOR THINGS TO DO
; USED TO TELL NSPSRV IF LINE COMES UP OR DOWN
SWAPCD
KMCTSK::SETZM KMCFLG ;HAVE CHECKED NOW
SKIPL P1,DUPLIM ;GET NUMBER OF DUP11'S
RET ;NONE
KMCTK0: HRR P1,DUPPAG(P1) ;GET LINES PAGE
PIOFF ;DISABLE INTERRUPTS
LOAD T2,DCHNG ;GET CODE FOR READY TO BEGIN
SETZRO DCHNG ;HAVE DONE IT NOW
JUMPE T2,KMCTK8 ;CHECK FOR NOTHING
HRRZ T1,PGDUPN(P1) ;COPY LINE NUMBER FOR NSPSRV
CAIE T2,DDUP ;DID LINE COME UP ?
JRST [ PION ;REENABLE INTERRUPTS
CALL DEDMCB ;TELL NSPSRV IT DIED
JRST KMCTK9 ] ;DONE
LOAD T2,DDSTA ;GET DDCMP STATUS
CAIE T2,STASTK ;HAVE WE SENT STACK ?
JRST KMCTK8 ;STRANGE - LOST RACE
MOVEI T2,STARUN ;LINE IS NOW RUNNING
STOR T2,DDSTA
PION ;REENABLE INTERRUPTS
HRRZ T1,PGDUPN(P1) ;GET LINE NUMBER AGAIN
CALL NODINI ;LET NSPSRV LINE CAME ON
KMCTK8: PION ;REENABLE INTERRUPTS
KMCTK9: HRR P1,PGDUPN(P1) ;GET LINE NUMBER AGAIN
AOBJN P1,KMCTK0
RET
;HERE TO GIVE "INPUT" TO THE KMC11
; CALL MOVE T1,(0,,LINE NUMBER*400+TYPE)
; MOVE T2,(BSEL4 DATA,,BSEL6 DATA)
; CALL KMCINP
RESCD ;CALLED FROM ALL LEVELS
KMCINP: MOVEI T3,KMCRQI!KMCIEI!KMCIEO ;WANT TO GIVE INPUT
PIOFF ;DISABLE RACE WITH INT LEVEL
BSIO T3,@[BSEL0+KMCADR] ;REQUEST INPUT
MOVE T3,KMCINQ ;GET PUTTER FOR INPUT QUEUE
CAIN T3,KMCINQ+KMCQLN-1 ;READY TO WRAP AROUND ?
MOVEI T3,KMCINQ+1 ;WRAPPING AROUND
ADDI T3,2 ;MAKE ADR OF QUEUE ENTRY
CAMN T3,KMCINQ+1 ;WILL THIS OVERFLOW THE QUEUE ?
BUG (CHK,KMCNTI,<KMC11 not taking input>)
MOVEM T1,-1(T3) ;PUT 1ST HALF IN QUEUE
MOVEM T2,(T3) ;PUT 2ND HALF IN QUEUE
MOVEM T3,KMCINQ ;SAVE UPDATED PUTTER
PION
RET
SUBTTL KMC11 INTERRUPT LEVEL SERVICE
;HERE FOR INPUT INTERRUPTS
KMCVCA: MOVEM 17,KMCACS+17 ;SAVE REG
MOVEI 17,KMCACS ;BUILD BLT POINTER
BLT 17,KMCACS+16 ;SAVE REST OF REGS
MOVE P,[-40,,KMCIPL] ;SET UP STACK
MOVE T4,[KMCADR] ;GET ADDRESS OF THE KMC11 HDW
RDIO T2,BSEL2(T4) ;GET RDI FLAG
MOVE T1,KMCINQ+1 ;GET INPUT QUEUE TAKER
CAME T1,KMCINQ ;ARE PUTTER AND TAKE DIFFERENT ?
TRNN T2,KMCRDI ;AND IS IT READY ?
BUG (HLT,KMCIII,<KMC11 illegal input interrupt>,<T1,T2>)
CAIN T1,KMCINQ+KMCQLN-1 ;TIME TO WRAP AROUND AGAIN ?
MOVEI T1,KMCINQ+1 ;YES SO POINT TO BEGINING OF QUEUE
ADDI T1,2 ;ADVANCE POINTER FOR THIS ENTRY
MOVEM T1,KMCINQ+1 ;SAVE UPDATED TAKER
MOVEI T2,KMCRQI ;WANT TO CLEAR RQUEST INPUT FLAG
CAMN T1,KMCINQ ;IS QUEUE EMPTY NOW ?
BCIO T2,BSEL0(T4) ;THIS IS LAST OF DATA
MOVE T2,(T1) ;GET 2ND WORD IN QUEUE ENTRY
MOVE T1,-1(T1) ;GET 1ST WORD IN QUEUE ENTRY
IFN FTRACE,<
LDB P1,[POINT 8,T1,27] ;GET LINE NUMBER
HRRZ P1,DUPPAG(P1) ;GET LINES PAGE
MOVE T3,PGTPTR(P1) ;GET TRACE POINTER
HRROM T1,(T3) ;SAVE SEL2
MOVEM T2,1(T3) ;SAVE SEL4 & SEL6
ADDI T3,2
CAIN T3,1000(P1) ;TIME TO WRAP AROUND ?
MOVEI T3,PGTRCE(P1) ;YES
MOVEM T3,PGTPTR(P1) ;SAVE UPDATED TRACE POINTER
>;IFN FTRACE
WRIO T2,BSEL6(T4) ;GIVE HALF OF DATA
MOVSS T2 ;GET OTHER HALF
WRIO T2,BSEL4(T4) ;GIVE OTHER HALF
WRIO T1,BSEL2(T4) ;TELL KMC11 WHAT THIS IS AND LINE #
MOVSI 17,KMCACS ;BLT POINTER TO RESTORE REGS
BLT 17,17 ;RESTORE ALL REGS
XJEN DUPXPC ;DISMISS INTERRUPT
;HERE FOR KMC11 OUTPUT INTERRUPTS
KMCVCB: MOVEM 17,KMCACS+17 ;SAVE REG
MOVEI 17,KMCACS ;BUILD BLT POINTER
BLT 17,KMCACS+16 ;SAVE REST OF REGS
MOVE P,[-40,,KMCIPL] ;SET UP STACK
MOVE P1,[KMCADR] ;ADDRESS OF THE KMC11 HARDWARE
RDIO T1,BSEL2(P1) ;GET 1ST 1/3 OF DATA (LINE NUMBER)
TRNN T1,KMCRDO ;IS RDYO SET ?
JRST KMVCB9 ;DONE WITH INTERRUPT
RDIO T2,BSEL4(P1) ;GET 2ND 1/3 OF DATA
ANDI T2,177777 ;CLEAR LH
RDIO T3,BSEL6(P1) ;GET 3RD 1/3 OF DATA
SETZ T4, ;PREPARE TO LET KMC11 KNOW WE READ IT
WRIO T4,BSEL2(P1) ;LET KMC11 KNOW WE READ IT
TRNE T1,100000 ;CHECK FOR OUTPUT OVERFLOW
JRST [ CALL KMCHLT ;STOP THE KMC11
BUG (INFO,KMCFST,<KMC11 too fast>) ;INFORMATION HAS BEEN LOST
JRST KMVCB9 ] ;DISMISS THE INTERRUPT
LDB P1,[POINT 8,T1,27] ;GET THE LINE NUMBER
HRR P1,DUPPAG(P1) ;GET PAGE ADDRESSES FOR LINE
IFN FTRACE,<
MOVE T4,PGTPTR(P1) ;GET TRACE POINTER
HRRZM T1,(T4) ;SAVE SEL2
HRLM T2,1(T4) ;SAVE SEL2
HRRM T3,1(T4) ;SAVE SEL6
ADDI T4,2
CAIN T4,1000(P1) ;TIME TO WRAP AROUND ?
MOVEI T4,PGTRCE(P1) ;YES
MOVEM T4,PGTPTR(P1) ;SAVE UPDATED TRACE POINTER
>;IFN FTRACE
TRNE T1,3 ;IS THIS BUFFER ADR OUT ?
JRST CNTRLO ;THIS IS A CONTROL OUT
ANDI T2,3777 ;STRIP PAGE NUMBER
ROT T2,-2 ;CONVERT BYTES TO PDP10 WORDS
ADDI T2,(P1) ;MAKE ADR
HRRZM T2,P2 ;SAVE ADR OF BUFFER DESCRIPTOR LIST
HRLM T2,P1 ;SAVE ADR OF BUFFER DESCRIPTOR LIST
TRNN T1,KMCIOT ;TRANSMIT OR RECEIVE ?
JRST XMTDNE ;TRANSMIT
;HERE WHEN RECEIVE DATA
LOAD T1,DCHNG ;IN CASE JUST RESTARTED
JUMPN T1,RCVFLU ;IGNORE IT UNTIL NSPSRV FGOING
HRRZ T1,P1 ;COPY PAGE ADDRESS
LSH T1,-^D9 ;CONVERT TO PAGE NUMBER
CALL MONCLR ;INVALIDATE CACHE FOR THIS PAGE
SKIPL PGRMS1-PGRBD1(P2)
SKIPGE PGRMS1+1-PGRBD1(P2)
JRST BUMHDR
LDB T1,[POINT 8,PGRMS1+1-PGRBD1(P2),9] ;GET A0
CAIE T1,A0 ;IS IT A0 ?
JRST BUMHDR ;NO
HLRZ T1,PGRMS1-PGRBD1(P2) ;GET 1ST TWO BYTES OF HEADER
ANDI T1,377 ;LEAVE ONLY LEAD CHARACTER
LOAD T2,DDSTA ;GET LINE STATUS
CAIN T1,SOH ;WAS THIS A DATA MESSAGE ?
JRST RCVDAT ;THIS WAS A DATA MESSAGE
CAIN T1,ENQ ;WAS THIS A CONTROL MESSAGE ?
JRST RCVCTL ;WE GOT A CONTROL MESSAGE
CAIE T1,DLE ;WAS THIS A MAINTENANCE MODE MESSAGE ?
JRST BUMHDR ;GARBAGE MESSAGE
MOVEI T1,STAMAI ;NOW IN MAINTENANCE MODE
CALL DEDLIN ;MOURN THE DEAD LINE
JRST RCVFLU ;DISCARD MESSAGE
;HERE WHEN MESSAGE IS DETECTED AS BAD
; I.E. A0.NE.1, NOT STARTED WITH SOH, DLE, OR ENQ
BUMHDR: DMOVE T1,PGRMS1-PGRBD1(P2) ;GET MSG HEADER
BUG (CHK,BADHDR,<bad DDCMP header>,<T1,T2>)
MOVEI T1,STADWN ;DON'T TRY TO USE LINE
CALL DEDLIN ;DECLARE LINE DOWN
JRST RCVFLU ;DISCARD MESSAGE
SUBTTL DDCMP RECEIVER -- DATA MESSAGE
;HERE WHEN RECEIVE A DATA MESSAGE
RCVDAT: CAIN T2,STARUN ;ARE WE RUNNING ?
CALL RCVAK3 ;CHECK RESPONSE FIELD
JRST RCVFLU ;NOT RUNNING OR ERROR RETURN
HLRZ T1,PGRMS1+1-PGRBD1(P2) ;GET MESSAGE NUMBER
SOS T1 ;MAKE PREVIOUS MESSAGE NUMBER
ANDI T1,377 ;LEAVE ONLY MESSAGE NUMBER
LOAD T2,DDRMN ;GET LAST MESSAGE WE RECEIVED CORRECTLY
CAME T1,T2 ;IS THIS WHAT WE EXPECTED ?
JRST RCVFLU ;NO SO IGNORE IT
;LOOP TO COPY DATA INTO BUFFER FOR NSPSRV
MOVE T1,PGRMS1-PGRBD1(P2) ;GET DDCMP HEADER AGAIN
ROT T1,^D8+2 ;PUT LOW ORDER 8 BITS OF COUNT IN RH
MOVE T2,T1 ;COPY HIGH ORDER BITS
ANDI T1,377 ;LEAVE ONLY LOW ORDER BITS
LSH T2,-2 ;POSITION HIGH ORDER BITS
ANDI T2,77*400 ;STRIP EXTRA BITS
IORB T1,T2 ;LEAVES COUNT IN RH OF T1 & T2
MOVNI P3,(T1) ;MAKE NEGATIVE COUNT AND PREPARE TO ROUND
LSH P3,^D16 ;ROUND TO NUMBER OF WORDS
HRRZ T1,PGDUPN(P1) ;COPY LINE NUMBER
CALL NSPSPC ;GET SPACE FOR THE MESSAGE
JRST [ MOVEI T1,NCDBTU ;BUFFER TEMPORARILY UNAVAILABLE
CALL XMTNAK ;SEND NAK MSG
JRST RCVFLU ]
PUSH P,T1 ;SAVE ADR OF DATA BLOCK
HRRI P3,PGRMS1+1-PGRBD1(P2) ;FINISH AOBJN POINTER TO INPUT
HRRZI P4,-1(T1) ;COPY DEST ADR
RCVDT3: HRLZ T1,(P3) ;GET NEXT 16 BITS TO COPY
HLRZ T2,1(P3) ;GET NEXT 16 BITS TO COPY
DMOVE T3,T1 ;GET ANOTHER COPY OF EACH
LSH T1,2+^D8 ;LEAVE ONLY FIRST BYTE
TLZ T3,600377 ;STRIP BITS FROM 2ND BYTE
LSH T3,2-^D8 ;POSITION BYTE
IOR T1,T3 ;INCLUDE WITH FIRST
ANDI T2,377 ;STRIP EXTRA BITS FROM FIRST BYTE
LSH T2,4+^D8 ;POSITION
IOR T1,T2 ;INCLUDE 3RD BYTE WITH 1ST AND 2ND
ANDI T4,377*400 ;STRIP EXTRA BITS FROM 4TH BYTE
LSH T4,4-^D8 ;POSITION 4TH BYTE
IOR T1,T4 ;INCLUDE WITH 1ST 3 BYTES
PUSH P4,T1 ;SAVE WORD FOR NSPSRV
AOBJN P3,RCVDT3 ;LOOP BACK FOR REST OF MESSAGE
POP P,T2 ;GET DATA ADR BACK
CALL NSPQ ;GIVE MESSAGE TO NSPSRV
LOAD T1,DDRMN ;LAST MESSAGE RECEIVED OK
AOS T1 ;NEW LAST MESSAGE RECEIVED OK
STOR T1,DDRMN ;SAVE NEW ONE
AOS PGRMCN(P1) ;COUNT MESSAGE RECEIVED CORRECTLY
CALL XMTACK ;TRY TO SEND AN ACK
JRST RCVFLU ;THEN FLUSH MESSAGE
SUBTTL DDCMP RECEIVER -- CONTROL MESSAGE
;HERE WHEN RECEIVE A CONTROL MESSAGE
RCVCTL: LDB T1,[POINT 6,PGRMS1-PGRBD1(P2),9] ;GET CONTROL TYPE
CAILE T1,7 ;IS TYPE LEGAL ?
JRST RCVKRD ;BAD MESSAGE
JRST @.+1(T1) ;DISPATCH ON MESSAGE TYPE
JRST RCVKRD ; MSG TYPE = 0
JRST RCVACK ; MSG TYPE = 1 = ACK
JRST RCVNAK ; MSG TYPE = 2 = NAK
JRST RCVREP ; MSG TYPE = 3 = REP
JRST RCVKRD ; MSG TYPE = 4 = RESET
JRST RCVKRD ; MSG TYPE = 5 = RESAK
JRST RCVSTR ; MSG TYPE = 6 = START
JRST RCVSTK ; MSG TYPE = 7 = STACK
SUBTTL DDCMP RECEIVER -- ACK MESSAGE
;HERE WHEN RECEIVE AN ACK MESSAGE
RCVACK: JRST @.+1(T2) ;DISPATCH ON LINE STATE
JRST RCVFLU ;KMC11 NOT RUNNING
JRST RCVFLU ;MAINT MODE
JRST RCVFLU ;SENDING STARTS
JRST RCVAK0 ;SENT STACK
JRST RCVAK2 ;RUNNING
;HERE WHEN RECEIVE AN ACK AFTER RECEIVING A START
RCVAK0: OPSTR <SKIPE>,DCHNG ;HAS THIS HAPPENED ONCE BEFORE ?
JRST RCVFLU ;PERHAPS IGNORE IT
CALL XMTACK ;TRY TO SEND ANOTHER ACK
MOVEI T1,DDUP ;REMEMBER IT CAME UP
STOR T1,DCHNG ;TELL NSPSRV ASAP
SETOM KMCFLG ;WANT TO RUN KMCTSK
JRST RCVFLU ;THEN DISCARD MESSAGE
;HERE WHEN RECEIVE AN ACK WHILE RUNNING
RCVAK2: CALL RCVAK3 ;PROCESS MESSAGE NUMBER
JRST RCVFLU
JRST RCVFLU
;HERE TO CHECK R FIELD IN ACK OR DATA MESSAGE
; CALLED AT INTERRUPT LEVEL
RCVAK3: LDB T3,[POINT 8,PGRMS1-PGRBD1(P2),27] ;GET R NUMBER
LOAD T1,DDHMA ;GET HIGHEST MESSAGE ACKED BEFORE
CAIN T1,(T3) ;IS THIS NEW INFORMATION
JRST [ SKIPE T1,PGDOMQ(P1) ;IS MESSAGE QUEUE EMPTY ?
RETSKP ;QUEUE NOT EMPTY SO KEEP REPPING
STOR T1,DDREPC ;CLEAR REP COUNTER
MOVEI T1,^D30 ;LONG WAIT FOR NEXT REP
STOR T1,DDTIM
RETSKP ]
SUB T3,T1 ;FIND NUMBER OF MESSAGES THIS WILL ACK
SKIPG T3 ;IN CASE NUMBERS WRAPPED 377
MOVEI T3,400(T3) ;HANDLE WRAP CASE
CAIL T3,MAXOUT+1 ;POSSIBLE ?
JRST BADRSP ;BAD RESPONSE FIELD
AOS T1 ;PLUS ONE HIGHEST MESSAGE ACKED
STOR T1,DDHMA ;SAVE UPDATED NUMBER
DMOVE T1,PGRMS1-PGRBD1(P2) ;PICK UP MSG HEADER OR ACK/NAK
DMOVEM T1,PGLACK(P1) ;SAVE FOR DEBUGING
AOS PGXMCN(P1) ;COUNT MESSAGES TRANSMITTED OK
MOVEI T1,TIMREP ;RESET REP TIMER CUZ ITS LOOKING GOOD
STOR T1,DDTIM
SETZ T1, ;CLEAR REP COUNTER
STOR T1,DDREPC
HLRZ T1,PGDOMQ(P1) ;GET FIRST MESSAGE IN QUEUE
JUMPE T1,BADRSP ;IF NONE RESPONSE WAS BAD
CAMN T1,PGDLMX(P1) ;WAS THIS LAST MESSAGE TRANSMITTED ?
SETZM PGDLMX(P1) ;FORGET POINTER
HLRZ T2,MBKLEN(T1) ;GET DRIVER INT LOC
MOVE T1,MBKCOD(T1) ;GET DRIVER UNIQUE CODE
SKIPE T2 ;WAS THERE ONE ?
CALL (T2)
HLRZ T1,PGDOMQ(P1) ;GET ADR OF MESSAGE BLOCK ADR AGAIN
HLRZ T2,MBKLNK(T1) ;GET ADR OF NEXT MESSAGE IN QUEUE
HRLM T2,PGDOMQ(P1) ;NEW FIRST MESSAGE IN QUEUE
CAIN T2,MBKFRE(T1) ;DID WE CHANGE CHUNKS ?
JRST RCVAK4 ;SAME CHUNK
SKIPN T2 ;WAS THERE A NEXT MESSAGE BLOCK ?
SETZM PGDOMQ(P1) ;NO SO QUEUE NOW EMPTY
HRRZ T1,MBKFRE(T1) ;GET CHUNK ADR FOR MESSAGE BLOCK
CALL SAVBLK ;RELEASE BLOCK
RCVAK4: JRST RCVAK3 ;CHECK FOR MORE MESSAGES TO FREE
BADRSP: DMOVE T1,PGRMS1-PGRBD1(P2) ;GET BAD DDCMP MESSAGE HEADER
BUG (INFO,BADACK,<bad DDCMP ACK>,<T1,T2>)
MOVEI T1,STADWN ;DON'T USE LINE
CALL DEDLIN ;DECLARE LINE DOWN
RET
;HERE TO FREE A BLOCK OF CORE
SAVBLK: SKIPN T2,PGFCOR(P1) ;HOLDING ANY FREE BLOCKS ?
JRST [ HRLZM T1,PGFCOR(P1) ;SAVE THIS ONE
RET ]
TRNE T2,-1 ;HOLDING TWO ?
JRST RELRES ;CAN'T HOLD ANY MORE
HRRM T1,PGFCOR(P1) ;SAVE THIS ONE ALSO
RET
SUBTTL DDCMP RECEIVER -- NAK MESSAGE
;HERE WHEN RECEIVE A NAK MESSAGE
RCVNAK: JRST @.+1(T2) ;DISPATCH ON LINE STATE
JRST RCVFLU ;KMC11 NOT RUNNING
JRST RCVFLU ;MAINT MODE
JRST RCVFLU ;SENDING STARTS
JRST RCVNK0 ;SENT STACK
JRST RCVNK3 ;RUNNING
;HERE IF RECEIVE A NAK AFTER SENDING A STACK
; THIS IS PROBABLY A REP RESPONSE SO DECLARE US UP
RCVNK0: LDB T1,[POINT 8,PGRMS1-PGRBD1(P2),27] ;GET R FIELD
JUMPN T1,RCVKRD ;IF NONZERO IS AN ERROR
JRST RCVAK0 ;TREAT AS AN ACK
;HERE IF RECEIVE A NAK WHILE RUNNING
RCVNK3: LDB T1,[POINT 6,PGRMS1-PGRBD1(P2),35] ;GET NAK CODE
CAILE T1,7 ;IS NAK CODE REASONABLE ?
SETZ T1, ;FIRST CELL IS MISC
ADDI T1,PGNRNK(P1) ;POINT TO NAK COUNTER
AOS @T1 ;COUNT NAK
SETZM PGDLMX(P1) ;RETRANSMIT FIRST MESSAGE IN QUEUE
CALL RCVAK3 ;PROCESS RESPONSE
JRST RCVFLU ;ERROR RETURN
CALL XMTDAT ;RETRANSMIT MESSAGE (IF ANY)
JRST RCVFLU ;DISCARD MESSAGE
SUBTTL DDCMP RECEIVER -- REP MESSAGE
;HERE WHEN RECEIVE A REP MESSAGE
RCVREP: JRST @.+1(T2) ;DISPATCH ON LINE STATE
JRST RCVFLU ;KMC11 NOT RUNNING
JRST RCVFLU ;MAINT MODE
JRST RCVFLU ;SENDING STARTS
JRST RCVRP0 ;SENT STACK
JRST RCVRP0 ;RUNNING
;HERE WHEN RECEIVED A REP AND NEED TO SEND AN ACK OR A NAK RESPONSE
RCVRP0: HLRZ T1,PGRMS1+1-PGRBD1(P2) ;GET MESSAGE NUMBER
ANDI T1,377 ;STRIP EXTRA BITS
LOAD T2,DDRMN ;GET LAST THING WE GOT
CAME T1,T2 ;EVERYTHING OK ?
JRST RCVRP3 ;TELL HIM WE DIDN'T GET IT
CALL XMTACK ;TRY TO SEND ACK
JRST RCVFLU
RCVRP3: MOVEI T1,NCDREP ;REASON CODE IS REP RESPONSE
CALL XMTNAK ;TRY TO SEND NAK
JRST RCVFLU
SUBTTL DDCMP RECEIVER -- START MESSAGE
;HERE WHEN RECEIVE A START MESSAGE
RCVSTR: JRST @.+1(T2) ;DISPATCH ON LINE STATE
JRST RCVFLU ;KMC11 NOT RUNNING
JRST RSTRT3 ;MAINT MODE
JRST RSTRT5 ;SENDING STARTS
JRST RSTRT3 ;SENT STACK
JRST RSTRT0 ;RUNNING
;HERE IF RECEIVE A START AFTER LINE WAS RUNNING
RSTRT0: HRRZ T1,PGDUPN(P1) ;GET LINE NUMBER
BUG (INFO,DDCSTR,<DDCMP restarted>,T1)
MOVEI T1,STASTR ;SEND STARTS AGAIN
CALL DEDLIN ;MOURN THE DEAD LINE
;HERE IF RECEIVE A START WHICH PUTS US INTO START MODE
RSTRT3: MOVEI T1,STASTR ;AM NOW SENDING STARTS
STOR T1,DDSTA ;SET NEW STATE
MOVEI T1,1 ;MINIMUM TIME
STOR T1,DDTIM ;SO WE SEND A START SOON
JRST RCVFLU ;DISCARD MESSAGE
;HERE IF RECEIVE A START WHILE SENDING STARTS
RSTRT5: DMOVE T1,STCKMS ;GET PROTOTYPE STACK MESSAGE
CALL XMTCTL ;TRY TO SEND IT
JRST RSTRT3 ;FAILED SO SEND START LATER
MOVEI T1,STASTK ;NOW CLAIM WE RECEIVED A STACK
STOR T1,DDSTA ;SAVE NEW STATUS
SETONE DDXAK ;NEED TO SEND AN ACK
JRST RCVFLU ;DISCARD MESSAGE
;HERE WHEN A LINE DIES - CLEANS UP AND LETS NSPSRV KNOW
; CALLED WITH NEW STATE IN T1
DEDLIN: LOAD T2,DDSTA ;GET LINE STATUS
MOVEI T3,DDOWN ;LINE IS DOWN
CAIN T2,STARUN ;WAS LINE RUNNING ?
STOR T3,DCHNG ;YES SO TELL NSPSRV IT DIED
STOR T1,DDSTA ;SET NEW STATE
STOR T1,DDTIM ;START TIMER ALSO
SETOM KMCFLG ;SO WE CHECK FLAG
DEDLN2: PIOFF ;STOP RACES
HLRZ T3,PGDOMQ(P1) ;GET FIRST MESSAGE IN OUTPUT MESSAGE QUEUE
JUMPE T3,DEDLN8 ;IF NONE DONE
PUSH P,MBKLEN(T3) ;SAVE DRIVER INT LOC
PUSH P,MBKCOD(T3) ;SAVE DRIVER UNIQUE CODE
HLRZ T2,MBKLNK(T3) ;GET ADR OF NEXT MESSAGE BLOCK
HRLM T2,PGDOMQ(P1) ;FORGET MESSAGE
HRRZ T1,MBKFRE(T3) ;GET ADR OF CHUNK
CAIE T2,MBKFRE(T3) ;DOES THIS CHANGE CHUNKS ?
CALL SAVBLK ;SAVE THE BLOCK FOR LATER USE
PION ;REENABLE INTERRUPTS
POP P,T1 ;GET DRIVER UNIQUE CODE
POP P,T2 ;GET DRIVER INT LOC
HLRZS T2 ;PUT DREIVER INT LOC IN RH
SKIPE T2 ;WAS THERE ONE ?
CALL (T2)
JRST DEDLN2
DEDLN8: SETZM PGDOMQ(P1) ;HAVE FLUSHED OUTPUT QUEUE
SETZM PGDLMX(P1) ;NO LAST MESSAGE NOW
SETZM PGDMNM(P1) ;INITIALIZE MESSAGE NUMBERS
PION
RET
SUBTTL DDCMP RECEIVER -- STACK MESSAGE
;HERE WHEN RECEIVE A STACK MESSAGE
RCVSTK: JRST @.+1(T2) ;DISPATCH ON LINE STATE
JRST RCVFLU ;KMC11 NOT RUNNING
JRST RCVFLU ;MAINT MODE
JRST RSTCK0 ;SENDING STARTS
JRST RSTCK0 ;SENT STACK
JRST RCVFLU ;RUNNING
RSTCK0: CALL XMTACK ;SEND AN ACK
MOVEI T1,STASTK ;CLAIM SENT A STACK
STOR T1,DDSTA
JRST RCVFLU ;DISCARD MESSAGE
SUBTTL DDCMP RECEIVER -- JUNK MESSAGE
;HERE WHEN RECEIVE A JUNK MESSAGE
RCVKRD: MOVEI T1,NCDHFE ;HEADER FORMAT ERROR
CALL XMTNAK ;COMPLAIN TO OTHER END
RCVFLU: HLRZ T3,P1 ;GET ADR OF BUFFER DESCRIPTOR
CALL RCVENB ;REENABLE RECEIVER
JRST KMVCB9 ;DISMISS INTERRUPT
SUBTTL DDCMP TRANSMIT DONE
;HERE FOR TRANSMIT DONE
XMTDNE: JUMPL T2,[SOJA T2,XMTDN5] ;IF SECOND DESCRIPTOR FLUSH MESSAGE
HLRZ T1,PGXMS1-PGXBD1(T2) ;GET FIRST CHAR IN MESSAGE
ANDI T1,377 ;STRIP EXTRA BITS
CAIE T1,ENQ ;WAS THIS A CONTROL MESSAGE ?
JRST KMVCB9 ;WAIT FOR DATA TO GO
XMTDN5: LDB T1,[POINT 8,PGXMS1+1-PGXBD1(T2),9] ;GET A0
CAIE T1,A0 ;IS IT A0 ?
BUG (CHK,MSGCLB,<DDCMP transmit message clobbered>)
SETZM (T2) ;THIS BUFFER DESCRIPTOR LIST NOW FREE
LOAD T1,DDNCD ;GET CURRENT NAK CODE
SKIPE T1 ;DO WE NEED TO SEND A NAK ?
CALL XMTNAK ;TRY TO SEND IT NOW
CALL XMTDAT ;TRY TO SEND NEXT MESSAGE
JRST KMVCB9
SUBTTL KMC11 CONTROL OUT INTERRUPT
;HERE FOR CONTROL OUT INTERRUPT
CNTRLO: ANDI T3,377 ;LEAVE ONLY ERROR CODE
ROT T3,-1 ;FOR DISPATCH
JUMPL T3,CNTLO3 ;IN CASE BUM DISPATCH
CAIL T3,10/2 ;IN RANGE ?
CAILE T3,26/2 ;IN RANGE
CNTLO3: JRST [ AOS PGCOXX(P1) ;COUNT TIMES THIS HAPPENS
JRST KMVCB9 ] ;IGNORE INTERRUPT
MOVEI T1,PGCOCN-4(P1) ;TABLE TO INCREMENT
ADD T1,T3 ;OFFSET FOR CODE
AOS (T1) ;COUNT TYPE OF INTERRUPT
JRST @.+1-4(T3) ;DISPATCH ON MESSAGE TYPE
JRST CNTL10 ;10 = INVALID DDCMP HEADER
JRST CNTL12 ;12 = BAD CRC
JRST [ MOVEI T1,NCDBTU ;14 = BUFFER NOT AVAILABLE
STOR T1,DDNCD ;SAVE REASON FOR NAK
JRST KMVCB9 ] ;DISMISS
JRST CNTL16 ;16 = DATASET READY TRANSITION
JRST CNTL20 ;20 = NXM
JRST CNTL22 ;22 = TRANSMIT UNDERRUN
JRST CNTL24 ;24 = RECEIVER UNDERRUN
JRST KMVCB9 ;26 = KILL COMPLETE
;HERE WHEN GET A CONTROL TYPE 10 = INVALID DDCMP HEADER
CNTL10: CALL FLUBFR ;FLUSH BUFFER
JRST KMVCB9
;HERE WHEN GET A CONTROL TYPE 12 = BAD CRC
CNTL12: CALL FLUBFR ;FLUSH BUFFER
MOVEI T1,NCDBCC ;NAK CODE FOR BUM CRC
CALL XMTNAK ;TRY TO SEND NAK
JRST KMVCB9 ;DISMISS
;HERE WHEN WE GET A CONTROL TYPE 16 = DATASET READY TRANSITION
CNTL16: LOAD T3,DDSTA ;GET CURRENT STATE
HRRZ T2,PGDUPN(P1) ;GET LINE NUMBER
CAIE T3,STASTK ;ARE WE SENDING STACKS ?
CAIN T3,STARUN ;OR ARE WE RUNNING ?
SKIPA T1,[EXP STASTR] ;SEND STARTS AGAIN
JRST KMVCB9 ;DISMISS
CAIN T3,STARUN ;ARE WE RUNNING ?
BUG (INFO,DSRLST,<Dataset ready lost>,T2)
MOVX T3,DUPDSR ;BIT FOR DATASET READY
XORB T3,PGDSTS(P1) ;CHANGE STATE
TXNN T3,DUPDSR ;STILL UP ?
CALL DEDLIN ;DATASET NOT READY SO DECLARE LINE DOWN
JRST KMVCB9 ;DISMISS
;HERE WHEN GET A CONTROL TYPE 20 = NXM
CNTL20: CALL KMCHLT ;KILL THE KMC11
BUG (INFO,KMCNXM,<KMC11 NXM>) ;TELL OPERATOR
JRST KMVCB9
;HERE WHEN GET A CONTROL TYPE 22 = TRANSMIT UNDERRUN
CNTL22: CALL FLUBFR ;FLUSH BUFFER
JRST KMVCB9
;HERE WHEN GET A CONTROL TYPE 24 = RECEIVER UNDERRUN
CNTL24: CALL FLUBFR ;FLUSH BUFFER
JRST KMVCB9 ;DISMISS
;HERE TO FREE BUFFER REFERENCED IN CONTROL OUT MSG
FLUBFR: HLRZ T1,PGUBAD(P1) ;GET UNIBUS ADR OF PAGE
SUB T2,T1 ;LEAVE ONLY RELATIVE ADR ON PAGE
ROT T2,-2 ;CONVERT BYTES TO WORDS
HRRZ T3,T2 ;COPY BUFFER ADR
ADDI T3,(P1) ;POINT TO BUFFER DESCRIPTOR
CAIE T3,PGRBD1(P1) ;WAS THAT FIRST RECEIVER BUFFER ?
CAIN T3,PGRBD2(P1) ;OR 2ND RECEIVER BUFFER
JRST RCVENB ;REENABLE BUFFER
CAIE T3,PGXBD1(P1) ;WAS THAT 1ST TRANSMIT BUFFER ?
CAIN T2,PGXBD2(P1) ;OR 2ND TRANSMIT BUFFER ?
SETZM (T3) ;FREE BUFFER
RET
KMVCB9: MOVSI 17,KMCACS ;BLT POINTER TO RESTORE REGS
BLT 17,17 ;RESTORE ALL REGS
XJEN DUPXPC+4 ;DISMISS INTERRUPT
SUBTTL HERE FROM NSPSRV WITH OUTPUT MESSAGES
;ACCEPTS:
; F/ DRIVER UNIQUE CODE
; T1/ DRIVER INT LOC,,DTE NUMBER
; T2/ BYTE POINTER TO NSP DATA (WITH OR WITHOUT HEADER)
; T3/ RH = COUNT OF BYTES IN DATA POINTED TO BE B
; B0 SET IF MESSAGE ALREADY SENT
;
; RETURNS:
; +1 IF NO PACKETS AND CALLED FROM SCHEDULER. REQUEST NOT
; QUEUED.
; +2 REQUEST QUEUED
;
;MAY BE CALLED FROM PI OR NON-PI LEVEL .
; ..
DCNMSO::SAVEP ;SAVE THE P'S
HRRZM T1,P1 ;SAVE THE LINE NUMBER
CAML P1,DUPNLN ;IS LINE NUMBER IN RANGE ?
RET ;NO SO LOSE RETURN
STKVAR <DRVMSG,DRVCOD,DRVLEN>
MOVEM F,DRVCOD ;SAVE DRIVER CODE
MOVEM T2,DRVMSG ;SAVE POINTER TO MESSAGE
HLRZS T2 ;LEAVE ONLY BYTE POINTER BITS
CAIE T2,441000 ;RIGHT BITS ?
BUG (CHK,MSGPTR,<Bad msg pointer>)
HRR T1,T3 ;BUILD MBKLEN
MOVEM T1,DRVLEN ;SAVE IT
MOVE P1,DUPPAG(P1) ;GET ADR OF LINES PAGE
LOAD T1,DDSTA ;GET LINE STATUS
CAIE T1,STARUN ;IS LINE RUNNING ?
RET ;CAN'T HANDLE MESSAGE
DCNMS1: SKIPE PGFCOR(P1) ;IS THERE A FREE CORE BLOCK ?
JRST DCNMS2 ;ENOUGH CORE
MOVE T1,[.RESP1,,BLKSIZ] ;PRIORITY AND SIZE OF BLOCK TO GET
MOVX T2,RS%SE0+.RESNP ;GET IT FROM THE NETWORK POOL
CALL ASGRES ;GET THE BLOCK
JRST [ CONSO PI,PIPIIP ;ARE WE AT INTERRUPT LEVEL ?
SKIPE INSKED ;FROM SCHEDULER ?
RET ;LOSE
SKIPE NSKED ;ARE WE NOSKED ?
RET ;LOSE - CAN'T BLOCK
HRLI T1,P1 ;COPY LINES BLOCK ADR
HRRI T1,SPCTST ;CHECK FOR ROOM
MDISMS ;WAIT
JRST DCNMS1 ] ;TRY AGAIN
PIOFF ;DISABLE INTERRUPTS
CALL SAVBLK ;SAVE BLOCK FOR LATER USE
PION ;REENABLE INTERRUPTS
DCNMS2: SKIPGE T4,DRVLEN ;GET LENGTH OF MESSAGE
JRST DCNMS4 ;IN CASE ALREADY SHUFFLED DATA
MOVNI T4,(T4) ;NEGATE AND PREPARE FOR ROUNDING
LSH T4,^D16 ;ROUND AND PUT IN LH OF REG
HRR T4,DRVMSG ;GET ADR OF MESSAGE
DCNMS3: MOVE T1,(T4) ;GET NEXT 4 BYTES
MOVE T2,T1 ;COPY BYTES
MOVE T3,T1 ;COPY AGAIN
LSH T1,-2-^D8 ;POSITION BYTE 1
LSH T2,-2+^D8 ;POSITION BYTE 2
TLZ T2,600377 ;STRIP EXTRA BITS
IOR T1,T2 ;INCLUDE WITH BYTE 1
LSH T3,-4-^D8 ;POSITION BYTE 3
ANDI T3,377
HRR T1,T3 ;INCLUDE BYTE 3 WITH 1ST AND 2ND
LSH T2,-2 ;POSITION BYTE 4
ANDI T2,377*400 ;MASK OFF EXTRA BITS
IOR T1,T2 ;INCLUDE WITH FIRST 3 BYTES
MOVEM T1,(T4) ;SAVE SHUFFLED WORD
AOBJN T4,DCNMS3 ;LOOP BACK FOR REST OF DATA
DCNMS4: PIOFF ;DISABLE INTERRUPTS WHILE WE QUEUE IT
SKIPN T4,PGDOMQ(P1) ;GET OUTPUT MESSAGE QUEUE FOR THE LINE
JRST [ SETZM PGDLMX(P1) ;NO PREVIOUS MSG SENT
HRRZ T3,PGFCOR(P1) ;GET BLOCK ADR
SKIPN T3 ;IS THERE ANYTHING THERE ?
MOVSS T3,PGFCOR(P1) ;NO SO GET OTHER HALF
HLLZS PGFCOR(P1) ;REMOVE FROM FREE SPACE
HRLM T3,PGDOMQ(P1) ;THIS IS FIRST MESSAGE
HRRZ T1,T3 ;COPY ADR OF CHUNK
HRLI T1,BLKSIZ-4 ;NUMBER OF FREE WORDS LEFT
JRST DCNMS6 ]
MOVEI T3,MBKFRE(T4) ;ADR OF NEXT MESSAGE BLOCK
MOVE T1,MBKFRE(T4) ;GET FREE WORD
SUB T1,[3,,0] ;ADJUST FOR NEW STATUS
JUMPGE T1,DCNMS5
HRRZ T3,PGFCOR(P1) ;GET OLD BLOCK
SKIPN T3 ;WAS THERE ONE ?
MOVSS T3,PGFCOR(P1) ;NO SO USE ONE WE JUST GOT
HLLZS PGFCOR(P1) ;NO LONGER FREE
HRRZ T1,T3 ;COPY ADR OF CHUNK
HRLI T1,BLKSIZ-4 ;NUMBER OF FREE WORDS LEFT
DCNMS5: HRLM T3,MBKLNK(T4) ;SET LINK TO NEXT
DCNMS6: MOVEM T1,MBKFRE(T3) ;SAVE FREE STUFF
MOVE T1,DRVMSG ;GET ADR OF MESSAGE
HRRZM T1,MBKLNK(T3) ;SAVE LINK WORD
MOVE T1,DRVCOD ;GET DRIVER UNIQUE CODE
MOVEM T1,MBKCOD(T3) ;SAVE IT
MOVE T1,DRVLEN ;GET LENGTH
MOVEM T1,MBKLEN(T3) ;SAVE IT
HRRM T3,PGDOMQ(P1) ;THIS IS NOW LAST MESSAGE IN QUEUE
CALL XMTDAT ;TRY TO SEND THE MESSAGE
LOAD T1,DDTIM ;GET TIMER
SKIPN T1 ;ALREADY RUNNING ?
MOVEI T1,TIMREP ;START IT
STOR T1,DDTIM
PION
JRST RSKP ;WIN RETURN
;HERE TO SEE IF WE CAN CONTINUE JOB NEEDING CORE
SPCTST: SKIPN PGFCOR(T1) ;DID WE GET SOME CORE YET ?
JRST 0(4) ;NOT YET
JRST 1(4) ;GOT SOME
SUBTTL HERE ONCE A SECOND TO CHECK THINGS
DUPCHK::MOVEI T1,^D1000 ;TIME TILL WE WANT TO CHECK AGAIN
MOVEM T1,DUPTIM
SKIPL P1,DUPLIM ;GET NUMBER OF DUP11'S
RET ;NONE
KMCHK0: HRR P1,DUPPAG(P1) ;GET PAGE ADR
AOS PGZTIM(P1) ;TIME SINCE COUNTERS ZEROED
LOAD T1,DDTIM ;GET TIMER FOR LINE
JUMPE T1,KMCHK2 ;IF TIMER NOT RUNNING WE'RE DONE
SOS T1 ;DECREMENT THE TIMER
STOR T1,DDTIM ;SAVE UPDATED TIMER
JUMPN T1,KMCHK2 ;IF TIMER DIDN'T EXPIRE DONE WITH LINE
LOAD T1,DDSTA ;GET LINE STATE
PIOFF ;DISABLE INTERRUPTS
CALL @TIMDSP(T1) ;DISPATCH ON LINE STATE
PION ;REENABLE INTERRUPTS
KMCHK2: HRR P1,PGDUPN(P1) ;GET LINE NUMBER
AOBJN P1,KMCHK0 ;LOOP BACK FOR REST OF LINES
RET ;HAVE DONE ALL LINES
TIMDSP: JRST R ;KMC11 NOT RUNNING
JRST R ;MAINT MODE
JRST XSTART ;SENDING STARTS
JRST REPCHK ;SENT STACK
JRST REPCHK ;RUNNING
SUBTTL DDCMP TRANSMITTER -- DATA MESSAGES
XSTART: MOVEI T1,TIMSTR ;IF THIS ONE DOESN'T GET RESULTS
STOR T1,DDTIM ;TRY AGAIN SOON
DMOVE T1,STRTMS ;GET PROTOTYPE START MESSAGE
CALL XMTCTL ;SEND THE START MESSAGE
RET ;FAILED - WE'LL TRY AGAIN LATER
RET
SUBTTL DDCMP TRANSMITTER -- REP MESSAGE
;HERE TO CHECK IF WE NEED TO SEND A REP MESSAGE
REPCHK: LOAD T2,DDREPC ;GET REP COUNTER
AOS T2 ;MAKE IT LARGER
CAILE T2,REPMAX ;IS THIS STILL OK ?
JRST REPHGH ;DROP LINE
STOR T2,DDREPC ;SAVE UPDATED REP COUNTER
MOVEI T1,TIMREP ;HOW LONG TO WAIT UNTIL WE SEND ANOTHER REP
STOR T1,DDTIM ;RESET TIMER
MOVE T1,REPMSG ;GET PROTOTYPE REP MESSAGE
LOAD T2,DDHMA ;HIGHEST MESSAGE ACKED
SKIPE PGDOMQ(P1) ;ANY MESSAGES IN QUEUE ?
TLOA T2,MAXOUT(T2) ;HIGHEST ACKED PLUS MAX SENT
; IF NUMBER WRAPS IS OK CUZ OF A0
MOVSS T2 ;HIGHEST ACKED IS HIGHEST SENT
TLO T2,A0*400 ;GET REST OF REP MESSAGE
CALL XMTCTL ;SEND THE REP MESSAGE
RET
RET
;HERE IF REP TIMER GOES TOO HIGH
REPHGH: HRRZ T2,PGDUPN(P1) ;GET DDCMP LINE NUMBER
CAIN T1,STARUN ;WERE WE RUNNING ?
BUG (INFO,DDCTIM,<DDCMP timed out>,T2) ;TELL OPER LINE TIMED OUT
MOVEI T1,STASTR ;SEND STARTS AGAIN
CALL DEDLIN ;DECLARE LINE DOWN
RET ;DISMISS
SUBTTL DDCMP TRANSMITTER -- ACK MESSAGE
XMTACK: LOAD T1,DDNCD ;GET NAK CODE PENDING
JUMPN T1,XMTNAK ;IF THERE IS ONE SEND IT INSTEAD
SETONE DDXAK ;WANT TO SEND AN ACK
XMTAK3: SKIPN PGXBD1(P1) ;IS FIRST BUFFER BUSY ?
SKIPE PGXBD2(P1) ;OR IS THE 2ND BUFFER BUSY ?
RET ;DON'T SEND ACK YET
OPSTR <SKIPN>,DDXAK ;DO WE WANT TO SEND AN ACK ?
RET ;NOT NOW
LOAD T1,DDRMN ;HIGHEST MESSAGE WE RECEIVED
LSH T1,^D8 ;POSITION FOR MESSAGE
IOR T1,ACKMSG ;GET PROTOTYPE ACK MESSAGE
MOVE T2,ACKMSG+1 ;GET REST OF PROTOTYPE MESSAGE
CALL XMTCTL ;SEND THE MESSAGE
RET ;FAILED
SETZRO DDXAK ;HAVE SENT ACK NOW
RET
SUBTTL DDCMP TRANSMITTER -- NAK MESSAGE
; CALL MOVEI T1,<NAK REASON CODE>
XMTNAK: STOR T1,DDNCD ;SAVE NAK REASON IN CASE NEED TO SEND LATER
LOAD T2,DDRMN ;HIGHEST MESSAGE WE RECEIVED
LSH T2,^D8 ;POSITION NUMBER
IOR T1,T2 ;PUT FOLLOWING REASON FOR NAK
IOR T1,NAKMSG ;GET PROTOTYPE NAK MESSAGE
MOVE T2,NAKMSG+1 ;GET REST OF PROTOTYPE NAK MESSAGE
CALL XMTCTL ;SEND THE MESSAGE
RET ;FAILED
LOAD T1,DDNCD ;GET NAK CODE
MOVEI T2,PGNXNK(P1) ;WHERE WE COUNT TRANSMITTED NAKS
CAIG T1,7 ;TOO LARGE TO COUNT ?
ADDI T2,(T1) ;INDEX INTO NAK TABLE
AOS (T2) ;COUNT NAKS SENT
SETZRO DDNCD ;HAVE SENT NAK NOW
RET
SUBTTL DDCMP TRANSMITTER -- CONTROL MESSAGE
XMTCTL: MOVEI T3,PGXBD1(P1) ;ASSUME 1ST XMIT BUFFER DESCRIPTOR LIST
SKIPE @T3 ;IS IT FREE ?
MOVEI T3,PGXBD2(P1) ;NOT FREE ... TRY 2ND
SKIPE @T3 ;IS IT FREE ?
RET ;CAN'T DO IT NOW ... RETURN TO CALLER
DMOVEM T1,PGXMS1-PGXBD1(T3) ;PUT MESSAGE IN BUFFER
HRLZI T1,PGXMS1-PGXBD1(T3) ;ADDRESS OF BUFFER
TLZ T1,777000 ;MAKE ADR ON PAGE
LSH T1,2 ;MAKE PDP11 ADR IN LH
ADD T1,PGUBAD(P1) ;MAKE ABSOLUTE PDP11 ADR
HRRI T1,^D6 ;BUFFER IS 6 BYTES LONG
MOVSI T2,BDLLDS!BDLRSY!BDLSOM!BDLEOM ;COMPLETE MESSAGE
TLZE T1,400000 ;CHECK UNIBUS ADR
TLO T2,004000 ;PUT IN STATUS REG
TLZE T1,200000 ;CHECK UNIBUS ADR
TLO T2,002000 ;PUT IN STATUS REG
DMOVEM T1,(T3) ;SAVE BUFFER DESCRIPTOR LIST
LSH T2,4-^D18 ;POSITION MEMORY EXTENSION BITS
ANDI T2,140000 ;LEAVE ONLY MEMORY EXTENSION BITS
TRO T2,BFRENB ;SET ENABLE
HLL T2,T1 ;COPY BUFFER ADR
SUB T2,[4*<PGXMS1-PGXBD1>,,0] ;POINT TO DESCRIPTOR
HRRZ T1,PGDUPN(P1) ;COPY LINE NUMBER
LSH T1,^D8 ;POSITION
IORI T1,BFADIN ;TYPE OF COMMAND
CALL KMCINP ;GIVE BUFFER DESCRIPTOR LIST TO KMC11
RETSKP
SUBTTL DDCMP TRANSMITTER -- DATA MESSAGES
;HERE TO CHECK POSSIBILITY OF SENDING A DATA MESSAGE
; CALLED AT INTERRUPT LEVEL OR WITH PIOFF
XMTDAT: HLRZ T1,PGDOMQ(P1) ;GET ADR OF FIRST MESSAGE IN QUEUE
SKIPE T2,PGDLMX(P1) ;GET ADR OF LAST MESSAGE SENT
HLRZ T1,MBKLNK(T2) ;GET ADR OF NEXT MESSAGE IN QUEUE
JUMPE T1,XMTAK3 ;IN CASE NONE TO SEND NOW
LOAD T3,DDHMA ;GET HIGHEST MESSAGE NUMBER ACKED
SKIPN PGDLMX(P1) ;IS THIS FIRST MSG ?
JRST XMTDT2 ;YES
LOAD T2,DDHXM ;HIGHEST MESSAGE NUMBER SENT
SUB T2,T3 ;MAKE DIFFERENCE
SKIPGE T2 ;DID NUMBERS WRAP AROUND ?
MOVEI T2,400(T2) ;YES SO ADJUST
CAIL T2,MAXOUT ;DO WE HAVE ENOUGH MESSAGES IN PIPE ?
JRST XMTAK3 ;DON'T SEND TOO MANY
XMTDT2: MOVEI T4,PGXBD1(P1) ;ASSUME 1ST XMIT BUFFER DESCRIPTOR LIST
SKIPE @T4 ;IS IT FREE ?
MOVEI T4,PGXBD2(P1) ;TRY 2ND XMIT BUFFER DESCRIPTOR LIST
SKIPE @T4 ;IS IT FREE ?
RET ;WILL TRY AGAIN LATER
SETZRO DDXAK ;DON'T NEED A EXPLICIT ACK NOW
SKIPN PGDLMX(P1) ;IS THIS FIRST MESSAGE IN QUEUE ?
STOR T3,DDHXM ;1ST MSG IN QUEUE SO RESET MSG NUMBER
HRRZM T1,PGDLMX(P1) ;REMEMBER ADR OF LAST MESSAGE SENT
HRRZ T3,MBKLEN(T1) ;GET LENGTH (BYTES) OF MESSAGE
HRRZ T2,T3 ;COPY COUNT
LSH T2,-^D8 ;LEAVE HIGH ORDER BITS OF COUNT
HRLI T2,SOH ;BEGIN DATAMESSAGE HEADER
DPB T3,[POINT 8,T2,9] ;PUT REST OF COUNT IN
LOAD T3,DDRMN ;HIGHEST MESSAGE NUMBER RECEIVED
LSH T3,^D8 ;POSITION
IOR T2,T3 ;BYTE(18)SOH+CNT*400,CNT+R*400
MOVEM T2,PGXMS1-PGXBD1(T4) ;SAVE FIRST HALF OF MSG HEADER
LOAD T3,DDHXM ;LAST MESSAGE SENT
AOS T3 ;MAKES NEW MSG NUMBER
STOR T3,DDHXM ;REMEMER WE SENT IT
IORI T3,A0*400 ;ADD A0
HRLZM T3,PGXMS1+1-PGXBD1(T4) ;SAVE REST OF MSG HEADER
HRRZ T1,PGDLMX(P1) ;GET ADR OF MESSAGE BLOCK AGAIN
HRRZ T2,MBKLEN(T1) ;GET LENGTH OF MESSAGE (BYTES)
HRLZ T1,MBKLNK(T1) ;GET ADR OF MESSAGE
HRRI T1,PGXMS1+2-PGXBD1(T4);?}HERE WERE GOING TO PUT MESSAGE
MOVEI T2,3(T2) ;PREPARE TO ROUND
LSH T2,-2 ;CONVERT BYTES TO WORDS
ADDI T2,(T1) ;LAST ADR IN MESSAGE
BLT T1,(T2) ;COPY DATA
HRLZI T1,PGXMS1-PGXBD1(T4) ;ADR OF BUFFER
TLZ T1,777000 ;MAKE RELATIVE TO START OF PAGE
LSH T1,2 ;MAKE IT A BYTE ADR
ADD T1,PGUBAD(P1) ;MAKE AN 11 ADR
HRRI T1,6 ;BYTE COUNTE FOR HEADER
MOVSI T2,BDLRSY!BDLEOM!BDLSOM ;FLAGS
TLZE T1,400000 ;CHECK UNIBUS ADR BITS
TLO T2,004000 ;INCLUDE IN STATUS
TLZE T1,200000 ;CHECK UNIBUS ADR BITS
TLO T2,002000 ;INCLUDE IN STATUS
HLR T2,T1 ;COPY ADR OF HEADER
ADDI T2,10 ;MAKES ADR OF DATA
HRR T3,PGDLMX(P1) ;GET ADR OF MESSAGE AGAIN
HRL T3,MBKLEN(T3) ;GET DATA COUNT
HLR T3,T2 ;COPY FLAGS
TRZ T3,BDLRSY ;DON'T RESYNC
TRO T3,BDLLDS ;LAST SEGMENT NOW
DMOVEM T1,(T4) ;SAVE FIRST 2 WORDS OF BUFFER DESCRIPTOR LIST
MOVEM T3,2(T4) ;SAVE SECOND BUFFER DESCRIPTOR
LSH T2,4-^D18 ;POSITION MEMORY EXTENSION BITS
ANDI T2,140000 ;LEAVE ONLY MEMORY EXTENSION BITS
TRO T2,BFRENB ;SET ENABLE
HLL T2,T1 ;COPY BUFFER ADR
SUB T2,[4*<PGXMS1-PGXBD1>,,0] ;POINT TO DESCRIPTOR
HRRZ T1,PGDUPN(P1) ;COPY LINE NUMBER
LSH T1,^D8 ;POSITION
IORI T1,BFADIN ;TYPE OF COMMAND
CALL KMCINP ;GIVE BUFFER DESCRIPTOR LIST TO KMC11
RET ;DONE
SUBTTL HERE TO ENABLE RECEIVER
; CALL MOVEI T3,PGRBD1(OR PGRBD2)(P1)
RCVENB: SETOM PGRMS1-PGRBD1(T3) ;DEBUGGIN AID
SETOM PGRMS1+1-PGRBD1(T3) ;DITTO
HRLZI T1,PGRMS1-PGRBD1(T3) ;ADR OF BUFFER
TLZ T1,777000 ;MAKE ADR RELATIVE TO PAGE
LSH T1,2 ;CONVERT TO BYTE ADR
ADD T1,PGUBAD(P1) ;MAKES RIGHT UNIBUS ADDR
HRRI T1,600 ;LENGTH OF BUFFER
MOVSI T2,BDLLDS
TLZE T1,400000 ;CHECK UNIBUS ADR
TLO T2,004000 ;PUT IN STATUS REG
TLZE T1,200000 ;CHECK UNIBUS ADR
TLO T2,002000 ;PUT IN STATUS REG
DMOVEM T1,(T3) ;SAVE BUFFER DESCRIPTOR LIST
LSH T2,4-^D18 ;COPY BUFFER ADR BITS 17 & 16
ANDI T2,140000 ;STRIP EXTRA BITS
IORI T2,BFRENB ;ENABLE BUFFER
HLL T2,T1 ;COPY BUFFER ADR
SUB T2,[4*<PGRMS1-PGRBD1>,,0] ;MAKE ADR OF BUFFER DESCRIPTOR LIST
HRRZ T1,PGDUPN(P1) ;COPY LINE NUMBER
LSH T1,^D8 ;POSITION LINE NUMBER
IORI T1,BFADIN!KMCIOT ;TYPE OF REQUEST
CALL KMCINP ;GIVE THIS TO THE KMC11
RET
TNXEND
END