Trailing-Edge
-
PDP-10 Archives
-
tops20v41_monitor_sources
-
monitor-sources/kdpsrv.mac
There are 20 other files named kdpsrv.mac in the archive. Click here to see a list.
;<4-1-FIELD-IMAGE.MONITOR>KDPSRV.MAC.2, 25-Feb-82 20:26:08, EDIT BY DONAHUE
;UPDATE COPYRIGHT DATE
;<4.MONITOR>KDPSRV.MAC.23, 3-Jan-80 08:09:16, EDIT BY R.ACE
;UPDATE COPYRIGHT DATE
;<4.MONITOR>KDPSRV.MAC.22, 2-Jan-80 10:05:34, EDIT BY PLATUKIS
;Restructure routine RCVAK3 to continue processing message, even if
; bad ACK field. Corrected NAK reason codes. Restructured PGDSTS
; word of station table.
;<4.MONITOR>KDPSRV.MAC.21, 8-Oct-79 10:55:34, EDIT BY GRANT
;TCO 4.2515 - Fix DUP maintenance mode bit definitions for loopback
;<4.MONITOR>KDPSRV.MAC.20, 27-Sep-79 12:15:39, EDIT BY WEISBACH
;TCO 4.2491 - Fix range checking of DUP number on BOOT JSYS calls in routines
;BTGPRT and BTIDC0.
;<OSMAN.MON>KDPSRV.MAC.1, 10-Sep-79 15:40:25, EDIT BY OSMAN
;TCO 4.2412 - Move definition of BUGHLTs, BUGCHKs, and BUGINFs to BUGS.MAC
;<4.MONITOR>KDPSRV.MAC.18, 24-Aug-79 13:50:43, EDIT BY WEISBACH
; Return updated byte pointer to user on a DDCMP read.
;<4.MONITOR>KDPSRV.MAC.17, 9-Jul-79 10:01:48, EDIT BY R.ACE
; Redefine PGLSTS word in line table and correct polling algorithm
; for stations in start state.
;<4.MONITOR>KDPSRV.MAC.16, 13-May-79 12:41:21, EDIT BY WEISBACH
; Make the read and write DDCMP message functions understand byte pointers.
; Correct problem of ^Cing a program during the execution of the BTINI
; function resulting in a RESBAZ bugchk.
;<4.MONITOR>KDPSRV.MAC.15, 1-Apr-79 10:43:03, EDIT BY WEISBACH
; Ensure that resident buffer released when an error is encountered while
; sending a DDCMP message (@BTSDD).
;<4.MONITOR>KDPSRV.MAC.13, 25-Mar-79 12:45:29, EDIT BY WEISBACH
; Fix potential races caused by RELRES's turning the PI system back on.
;<4.MONITOR>KDPSRV.MAC.12, 21-MAR-79 edit by MBEGUN
;Don't try to send implicit acks for multidrop lines at XMTAK3
;<4.MONITOR>KDPSRV.MAC.11, 18-Mar-79 11:48:00, EDIT BY WEISBACH
; Read MOP and DDCMP return one word too many to user.
;<4.MONITOR>KDPSRV.MAC.10, 11-Mar-79 13:51:43, EDIT BY WEISBACH
; Make timeout work properly for MOP protocol
; Also remove outdated table of contents
;<4.monitor>kdpsrv.mac.9 6-mar-79 edit mbegun - remove race at
;kdpchk - turn pioff for scheduler tests
;<4.MONITOR>KDPSRV.MAC.8, 4-Mar-79 17:45:42, Edit by KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<4.MONITOR>KDPSRV.MAC.7, 4-Mar-79 11:12:12, EDIT BY WEISBACH
; Correct password code for ENTER-MOP-MODE messages and set line server
; to default to NSP at protocol termination
;<4.MONITOR>KDPSRV.MAC.6, 13-Feb-79 16:54:03, EDIT BY WEISBACH
; Zero PGLINQ after reading a MOP message.
;<4.MONITOR>KDPSRV.MAC.5, 29-Jan-79 08:33:10, EDIT BY WEISBACH
;<4.MONITOR>KDPSRV.MAC.4, 4-Jan-79 11:00:15, EDIT BY WEISBACH
; Add support for MOP protocol
;<4.MONITOR>KDPSRV.MAC.29, 5-DEC-78 12:00:00, Edit by MBEGUN
; Restructure data base and add support for full duplex multi-drop stations
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976,1977,1978,1979,1980,1981,1982 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
SEARCH PROLOG,PROKS
TTITLE KDPSRV
EXTN <DEDMCB>
EXTN <KDPLIM,KDPNLN,KDPN,KDPPAG,KDPTIM,KDPXPC>
EXTN <KMCACS,KMCINQ,KMCIPL,KDPFLG,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
; P1 FOR LINE SPECIFIC CODE WILL CONTAIN THE ADDRESS OF THE LINES PAGE
; P4 FOR STATION SPECIFIC CODE WILL CONTAIN THE ADDRESS OF STATION TABLE
; 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 FOR LINE PAGE
X PGUBAD,1 ;LH IS UNIBUS ADR OF PAGE
X PGSTAL,1 ;STATION LIST -- DDCMP LINE TABLE
DEFSTR (DDSTT,PGSTAL(P1),35,18) ;TOP OF STATION LIST
DEFSTR (DDSTB,PGSTAL(P1),17,18) ;BOTTOM OF STATION LIST
X PGCSTA,1 ;POINTER TO CURRENT STATION
X PGLINQ,1 ;INPUT MESSAGE QUEUE
X PGLOUQ,1 ;OUTPUT MESSAGE STATION QUEUE
X PGLSTS,1 ;LINE STATUS
DUPDSR==1B13 ;DATA SET READY
DEFSTR(LINSR,PGLSTS(P1),35,2) ;SERVER
NSPL==0 ;NSP LINE
DCPL==1 ;DCP LINE
DEFSTR(DDINP,PGLSTS(P1),33,5) ;# OF QUEUED INPUT BUFFERS
DEFSTR(DDINT,PGLSTS(P1),28,1) ;PSI FLAG
DEFSTR(DDSSP,PGLSTS(P1),17,4) ;STARTUP PRESET COUNTER
X PGLINT,1 ;FORK #,,INTERRUPT CHANNEL ASSIGNMENT
X PGKDPN,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 PGSTCC,1 ;STARTUP COUNTER
DDSTIC==2 ;INITIAL STARTUP COUNT
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
;catch all
;1= header bcc error
;2= data bcc error
;3= rep response
;8= buffer unavailable
;9= receiver overrun
;16= message too long
;17= header format error
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 (see PGNRNK)
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
; DATA BASE NEEDED FOR MOP PROTOCOL
X PGMSTS,1 ;MOP STATUS WORD
DEFSTR (MOPSTS,PGMSTS(P1),35,2) ;MOP STATUS
MPPRI==1 ;PRIMARY MODE
MPSEC==2 ;SECONDARY MODE
MPERR=400000 ;ERROR IN MOP MSG EXCHANGE(MUST BE SIGN BIT)
DEFSTR (MOPTMR,PGMSTS(P1),17,12) ;MOP TIMEOUT COUNTER
PRITMO==^D15 ;SPECIAL TIMEOUT WHEN STILL IN PRIMARY MODE
MOPTMO==3 ;TIME-OUT
X PGMPSW,1 ;PASSWORD TO ENTER MOP MODE
X PGMXHD,3 ;MOP XMIT MESSAGE HEADER
DEFSTR (MPBPTR,PGMXHD(P1),35,36) ;POINTER TO THE MOP MSG XMITTED
DEFSTR (MPBADR,PGMXHD(P1),35,18) ;ADDRESS OF THE MOP BUFFER
DEFSTR (MPPOST,PGMXHD+1(P1),35,18) ;MOP POST ADDRESS
DEFSTR (MPFLGS,PGMXHD+1(P1),17,18) ;FLAGS
MPSHRT=1 ;MOP BUFFER IS A SHORT BUFFER
MPXSEC=2 ;SENDING SECONDARY BOOTSTRAP
DEFSTR (MPBLEN,PGMXHD+2(P1),35,18) ;LENGTH OF MOP BUFFER
X PGMXBF,2 ;BUFFER FOR SHORT MOP MESSAGES
X PGMRHD,2 ;MOP RECEIVE MESSAGE HEADER
DEFSTR (MPRPTR,PGMRHD(P1),35,36) ;POINTER TO THE MOP MSG RECVD
DEFSTR (MPRADR,PGMRHD(P1),35,18) ;ADDRESS OF THE MOP BUFFER
DEFSTR (MPRLEN,PGMRHD+1(P1),35,18) ;LENGTH OF THE BUFFER (BYTES)
IFN FTRACE,<
X PGTPTR,1 ;TRACE PUTTER
Z=<Z+1>&<-2> ;TRACE MUST BEGIN ON AN EVEN WORD
X PGTRCE,1 ;TRACE
>;IFN FTRACE
;OFFSETS FOR STATION TABLE ENTRIES
Z=0
X PGDLNK,1 ;LINE TABLE THREAD
DEFSTR (DDLNK,PGDLNK(P4),35,18) ; FORWARD THREAD
DEFSTR (DDBAK,PGDLNK(P4),17,18) ; BACK LINK
X PGDADR,1 ;STATION ID
DEFSTR (DDDRP,PGDADR(P4),17,8) ;DROP# OF STATION
DEFSTR (DDLMX,PGDADR(P4),35,8) ;LAST MESSAGE XMTED PREVIOUS INTERVAL
X PGDSTS,1 ;DDCMP STATUS
DEFSTR (DDSTA,PGDSTS(P4),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(P4),32,7) ;TIMER
TIMSTR==5 ;5 SECONDS BETWEEN STARTS
TIMREP==3 ;3 SECONDS BETWEEN REPS
REPMAX==10 ;MAXIMUM NUMBER OF REPS BEFORE DECLARING LINE DOWN
DEFSTR (DDXAK,PGDSTS(P4),17,1) ;want to send an ack
DEFSTR (DDNCD,PGDSTS(P4),15,6) ;nak code to send
DEFSTR (DDXRP,PGDSTS(P4),9,1) ;WANT TO SEND A REP
DEFSTR (DCHNG,PGDSTS(P4),8,3) ;INFORMATION FOR NSPSRV (SWAPPABLE)
DEFSTR (DDSEL,PGDSTS(P4),5,1) ;SEND SELECT
DEFSTR (DDACI,PGDSTS(P4),4,1) ;ACTIVE/IDLE INDICATOR FOR SLAVES
DEFSTR (DDSFC,PGDSTS(P4),3,4) ;STARTUP FAILURE COUNTER
MAXSTR==10 ;MAXIMUM STARTUPS TO TRY BEFORE GIVING UP
DDUP==1 ;DDCMP NOW UP
DDOWN==2 ;DDCMP DOWN
DDPT==3 ;INDICATOR FOR XMIT COMPLETE
DDSF==4 ;INDICATOR FOR STARTUP FAILURE
X PGDOMQ,1 ;DDCMP OUTPUT MESSAGE QUEUE
; LH IS ADR OF FIRST OUTPUT MESSAGE BLOCK
; RH IS ADR OF LAST OUTPUT MESSAGE BLOCK
X PGOLST,1 ;THREAD FOR OUTPUT MESSAGE STATION QUEUE
;LH IS BACK POINTER ,, RH IS FORWARD POINTER
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(P4),7,8) ;RECEIVED MESSAGE NUMBER (HIGHEST)
DEFSTR (DDHXM,PGDMNM(P4),15,8) ;HIGHEST MESSAGE NUMBER TRANSMITTED
DEFSTR (DDHMA,PGDMNM(P4),23,8) ;HIGHEST MESSAGE NUMBER ACKED
DEFSTR (DDREPC,PGDMNM(P4),35,12) ;COUNTER FOR REPS
X PGDPRI,1 ;STATION POLLING PRIORITY
DEFSTR (DDSPC,PGDPRI(P4),35,18) ;STATION PRIORITY COUNTER
DEFSTR (DDIPC,PGDPRI(P4),17,18) ;INITIAL PRIORITY COUNT
X PGLTIM,1 ;TIME LAST ZEROED COUNTERS
X PGLCOC,10 ;CONTROL OUT COUNTS - AS FOR DUP
X PGLRNK,10 ;COUNT OF RECEIVED NAKS
X PGLXNK,10 ;COUNT OF XMIT NAKS
DDLSZ==Z
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
;INPUT DATA BUFFERS FOR VT62
;QUEUE HEADER IS PGLINQ(P1)
;LH IS TAIL
;RH IS HEAD
;EACH DATA BUFFER CONTAINS A TWO WORD HEADER
MSHDR==2
INDLNK==0 ;LH SYSTEM LINE #, RH LINK TO NEXT BUFFER OR ZERO
INDCNT==1 ;BYTE COUNT OF DATA
MAXIN==^D40 ;MAXIMUM NUMBER OF INPUT BUFFERS KDPSRV WILL MAINTAIN
SUBTTL DEFINITIONS -- DUP11
DUPADR==3760300 ;ADDRESS OF 1ST DUP11
DUPUBN==3 ;UNIBUS ADAPTER NUMBER FOR DUP11
DPRCSR==0 ;RECEIVER CSR
DPDTR==000002 ;DATA TERMINAL READY
DPRDBF==2 ;(RO)RECEIVER DATA BUFFER
DPPCSR==2 ;(WO)PARAMETER CONTROL AND STATUS REGISTER
DPTCSR==4 ;TRANSMIT CONTROL AND STATUS REGISTER
DPCBLP==004000 ;EXTERNAL MAINTENCE MODE (CABLE LOOPBACK)
DPCNLP==010000 ;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==^D8 ;BUFFER TEMPORARILY UNAVAILABLE (rjp)
NCDROV==^D9 ;RECEIVER OVERRUN (rjp)
NCDMTL==^D16 ;MESSAGE TOO LONG (rjp)
NCDHFE==^D17 ;HEADER FORMAT ERROR (rjp)
; 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 DEFINITIONS -- MOP
.MPLDT==0 ;MEMORY LOAD WITH TRANSFER ADDRESS
.MPRQD==4 ;REQUEST MEMORY DUMP
.MPMOP==6 ;ENTER MOP MODE
.MPRQP==8 ;PROGRAM REQUEST
.MPDMC==^D12 ;DMC DEV CODE
MPSPRQ==0 ;PROGRAM REQUEST FOR SECONDARY BOOTSTRAP
.BTPSW==1 ;PASSWORD IN BOOT BLOCK
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
;table of legal NAK reason codes. used to offset into line table
;PGNRNK and PGNXNK...
naktbl: 0
1 ;offset NAK reason 1
2 ;offset NAK reason 2
3 ;offset NAK reason 3
0
0
0
0
4 ;offset NAK reason 8
5 ;offset NAK reason 9
0
0
0
0
0
0
6 ;offset NAK reason 16
7 ;offset NAK reason 17
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 BTINI ;(0) = ENTER MOP MODE
EXP BTLSB ;(1) = LOAD SECONDARY BOOTSTRAP
EXP BTSMP ;(2) = SEND MOP MESSAGE
EXP BTERR ;(3) = DUMP MEMORY
EXP BTIPR ;(4) = INITIALIZE PROTOCOL
EXP BTTPR ;(5) = TERMINATE PROTOCOL
EXP BTSTS ;(6) = RETURN STATUS
EXP RSKP ;(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
EXP BTSTA ;(16) = SET TERMINAL STATE (ACTIVE/IDLE)
EXP BTSSP ;(17) = SET START PRIORITY
EXP BTSTP ;(20) = SET TERMINAL PRIORITY
EXP BTSDD ;(21) = SEND DDCMP MESSAGE
EXP BTRDD ;(22) = RECEIVE DDCMP
EXP BTCHN ;(23) = ASSIGN SOFTWARE INTERRUPT CHANNEL
EXP BTSLS ;(24) = SET LINE SERVICE TYPE
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 T1,.BTPRT(Q1) ;GET PORT NUMBER FROM ARGUMENT BLOCK
HRRZ T4,T1 ;COPY DUP#
CAML T4,KDPNLN ;IS ARGUMENT IN RANGE ?
ITERR (ARGX19) ;Invalid unit number
LSH T4,3 ; *10
ADD T4,[DUPADR] ;MAKES THIS DUP11'S ADR
HRR P1,T1 ;GET DUP #
HRR P1,KDPPAG(P1) ;GET ADR OF LINES PAGE
LOAD P4,DDSTT ;GET TOP OF STATION LIST
JUMPE P4,[ HRR P4,PGCSTA(P1) ;POINT TO POINT?
RET ] ;ALL SET
HLRZS T1 ;GET DROP FROM USER
SKIPN T1 ;DID USER GIVE A DROP#
RET ;NO, USE THIS ONE
LOAD T3,DDSTB ;REMEMBER FOR END OF SEARCH
BTGPR1: LOAD T2,DDDRP ;GET THIS DROP #
CAMN T2,T1 ;IS THIS THE ONE
RET ;GOT IT
CAMN P4,T3 ;END OF LIST??
ITERR (ARGX19) ;INVALID DROP
LOAD P4,DDLNK ;GET NEXT LINE TABLE
JRST BTGPR1 ;LOOP THROUGH LINE TABLES
SUBTTL BOOT JSYS --MOP -- INITIALIZE A NEIGHBORING COMPUTER
BTINI:
CALL BTGPRT ; GET THE DUP HDW ADDR (T4) & LINE PAGE (P1)
CALL BTIMOP ; PUT LINE IN MAINTENANCE MODE
; may want to do this first when successful, i.e. answer is back
JFCL ; THERE IS NO ERROR RETURN
MOVE Q2,PGMPSW(P1) ; GET THE BOOT PASSWORD
MOVEI T1,MPPRI ;WE ARE NO IN PRIMARY MODE
STOR T1,MOPSTS ;STORE IN MOP STATUS WORD
HRRI T1,PGMXBF(P1) ; THIS WILL BE A SHORT MESSAGE
MOVEI T2,MPSHRT ; REMEMBER THIS
STOR T2,MPFLGS ; FOR LATER
HRLI T1,(<POINT 8,0,17>) ; MAKE A BYTE POINTER
PUSH P,T1 ; SAVE IT FOR BELOW
MOVEM Q2,(T1) ;PUT PASSWORD INTO MESSAGE
MOVEM Q2,1(T1) ;NEED IT FOUR TIMES
MOVEI T2,.MPMOP ; ENTER MOP MODE CODE
DPB T2,T1 ; PUT INTO MESSAGE
MOVEI T3,5 ; LENGTH OF MESSAGE
POP P,T2 ; GET BACK POINTER TO MESSAGE BUFFER
MOVE T1,PGKDPN(P1) ;SET LINE #
MOVEI F,0 ;NO SPECIAL POST ROUTINE
CALL XMTMOP ; go transmitt the MOP msg
RET ;DIDN'T MAKE IT???
MOVEI T1,MPRTST ;DISMISS UNTIL A MESSAGE RETURNED FROM SATELLITE
HRL T1,P1 ;SO SCHEDULER TEST KNOWS WHERE TO LOOK
MDISMS ;DISMISS UNTIL ANSWER COMES FROM SATELITE
MOVE T1,PGMSTS(P1) ;GET THE MOP STATUS WORD
TLNE T1,MPERR ;ERROR?
RET ;YES
;RESUME HERE WHENT THE SATELLITE HASE RESPONDED TO THE
; ENTER-MOP-MODE MESSAGE
MOVE T3,PGMRHD(P1) ;GET THE RECEIVED BUFFER BYTE PTR
ILDB T1,T3
CAIE T1,.MPRQP ; PROGRAM REQUEST?
JRST [CALL RELMOP ;RELEASE BUFFER
RET ] ;RETURN BAD
ILDB T1,T3 ; DEVTYPE FIELD
CAIE T1,.MPDMC ; ON A DMC11?
JRST [CALL RELMOP ;RELEASE BUFFER
RET ] ;RETURN BAD
ILDB T1,T3 ; SKIP MOP VERSION FIELD
LOAD T1,MPRLEN ; GET RECEIVED MSG LENGTH
CAIG T1,3 ; ANY MORE?
JRST BTEMOK ; NO, ALL OKAY
ILDB T1,T3 ; GET PGM TYPE FIELD
CAIE T1,MPSPRQ ; REQUESTING SECONDARY BOOTSTRAP
JRST [CALL RELMOP ;RELEASE BUFFER
RET ] ;RETURN BAD
BTEMOK: CALL RELMOP ;RELEASE RECEIVE BUFFER
MOVEI T1,MPSEC ;WE ARE NOW IN SECONDARY MODE
STOR T1,MOPSTS ;STORE THIS FACT IN MOP STATUS WORD
RETSKP ;RETURN OKAY
SUBTTL BOOT JSYS --MOP-- LOAD SECONDARY BOOTSTRAP LOADER.
BTLSB:
CALL BTGPRT ;GET DUP HDW ADDR AND LINE PAGE
LOAD T1,DDSTA ; GET LINE STATUS
CAIE T1,STAMAI ; IN MAINTENANCE MODE?
RET ; NO, THAT'S AN ERROR
MOVE T1,[.RESP1,,200] ; GET BUFFER FOR MOP MESSAGE HEADER + DATA
MOVE T2,[RS%SE0+.RESNP] ; SET BUFFER SPACE
CALL ASGRES ;
RET ; CAN'T
MOVE T2,[<.MPLDT>_12] ; MOP LOAD WITH TRANSFER CODE
MOVEM T2,(T1) ; STORE IN MESSAGE
MOVE P3,T1 ; MESSAGE STARTING ADDRESS
MOVEI P3,177(P3) ; LAST WORD IN BUFFER
MOVX T2,6B7 ; LOAD ADDRESS IS 6
MOVEM T2,1(T1) ; STORE IN MESSAGE
MOVEM T2,(P3) ; TRANSFER ADDRESS IS ALSO 6
MOVE T2,[POINT 8,0,15] ; POINTER TO START OF MOP MSG.
HRR T2,T1 ; ...
HRRI T1,2(T1) ;PUT USER MSG AT 2ND WORD
XCTU [HRL T1,.BTSEC(Q1)] ;GET ADDR OF USER DATA
XBLTUM [BLT T1,-1(P3)] ;MOVE THE DATA
LOAD T1,MPFLGS ;GET MOP XMIT FLAGS
TXO T1,MPXSEC ;INDICATE WE ARE SENDING SECONDARY BOOTSTRAP
TXZ T1,MPSHRT ;NOT A SHORT MESSAGE
STOR T1,MPFLGS
MOVEI T3,772 ;MESSAGE LENGTH
CALL SECSHF ;POSITION FOR KMC
MOVE T1,PGKDPN(P1) ;SET LINE #
MOVEI F,MOPQ ;ON RETURN QUEUE TO USER
CALL XMTMOP ; go transmitt the MOP msg
RET ;DIDN'T MAKE IT???
RETSKP
SUBTTL BOOT JSYS --MOP-- REQUEST UPLINE DUMP
BTDMP: ;NOT YET IMPLEMENTED.
SUBTTL BOOT JSYS --MOP-- SEND MOP MESSAGE
BTSMP:
CALL BTGPRT ;GET PORT NUMBER(t4=dup hdw addr,p1=line page)
LOAD T1,DDSTA ;GET LINE STATUS
CAIE T1,STAMAI ;IN MAINTENANCE MODE?
RET ;NO, ERROR
MOVEI T1,0 ;NOW IN LOAD MODE
STOR T1,MOPSTS ;SHOW SO IN MOP STATUS WORD
UMOVE P2,.BTCNT(Q1) ;GET LENGTH OF DATA
MOVEI T1,3(P2) ;PREPARE TO ROUND
LSH T1,-2 ;# OF WORDS
MOVE P3,T1 ;TAKE A COPY FOR LATER
HRLI T1,.RESP1 ;PRIORITY 1
MOVE T2,[RS%SE0+.RESNP] ;GET SPACE FROM NET POOL
CALL ASGRES
RET ;%% ADD ERROR CODE
MOVE T2,T1 ;COPY ADDR OF BUFFER
HRLI T2,(<POINT 8,>) ;MAKE THE BYTE POINTER
ADD P3,T1 ;COMPUTE END OF BUFFER FOR BLT
BTSMP0: XCTU [HRL T1,.BTLPT(Q1)] ;GET ADDR OF USER DATA
XBLTUM [BLT T1,-1(P3)] ;MOVE THE DATA
LOAD T1,MPFLGS ;GET MOP XMIT FLAGS
TXZ T1,MPXSEC ;THIS IS NOT SECONDARY BOOTSTRAP
TXZ T1,MPSHRT ;NOT A SHORT MESSAGE
STOR T1,MPFLGS
MOVE T3,P2 ;XMTMOP NEEDS IT THIS WAY
CALL SHFFLE ;POSITION FOR KMC
MOVE T1,PGKDPN(P1) ;SET LINE #
MOVEI F,MOPQ ;PUT RESULTING MOP ANSWER ON USER QUEUE
CALL XMTMOP ;go transmitt the MOP msg
RET ;DIDN'T MAKE IT???
RETSKP
SUBTTL BOOT JSYS --MOP-- RECEIVE MOP MESSAGE
BTRMP:
CALL BTGPRT ;GET PORT NUMBER
LOAD T1,DDSTA ;GET LINE STATUS
CAIE T1,STAMAI ;IN MAINTENANCE MODE?
RET ;NO, ERROR
BTRMP0: SKIPGE PGMSTS(P1) ;DID OTHER SIDE EVER ANSWER?
RET ;NO,ERROR
SKIPN T1,PGMRHD(P1) ;IS QUEUE EMPTY
JRST [MOVEI T1,MPRTST ;WAIT FOR SOME INPUT TO COME
HRL T1,P1 ;SAVE ADDRESS
MDISMS ;DISMISS UNTIL INPUT
JRST BTRMP0 ;TRY AGAIN
]
SKIPN PGLINQ(P1) ;IS IT FOR THE USER?
JRST [CALL RELMOP ;ERROR, RELEASE BUFFER AND RETURN
RET ] ;ERROR CODE
LOAD T3,MPRLEN ;LENGTH OF RECEIVED BUFFER
XCTU [HRRZ T2,.BTCNT(Q1)] ;GET LENGTH OF USERS BUFFER
CAMLE T3,T2 ;ENOUGH ROOM?
RET ;NO
UMOVEM T3,.BTCNT(Q1) ;RETURN ACTUAL SIZE OF BUFFER
ADDI T3,3 ;ROUND TO WORDS
LSH T3,-2
XCTU [HRRZ T2,.BTMPT(Q1)] ;ADDR OF USER DATA
ADD T3,T2 ;END ADDR OF BLT
HRRZ T1,PGMRHD(P1) ;ADDR OF DATA BUFFER
HRL T2,T1 ;FOR THE BLT
XBLTMU [BLT T2,-1(T3)] ;GIVE DATA TO USER
PIOFF
SETZM PGMRHD(P1) ;SAY NO BUFFER ANYMORE
SETZM PGLINQ(P1) ;ZERO THIS TOO
CALL RELRES ;RELEASE THE BLOCK
PION
RETSKP
SUBTTL BOOT JSYS -- SEND A DDCMP MESSAGE
;ARGUMENT BLOCK
; .BTPRT/ DROP#,,LINE#
; .BTMSG/ ADDR OF DATA
; .BTLEN/ BYTE COUNT OF MESSAGE
;ERROR RETURN TAKEN IF MESSAGE QUEUE IS FULL
BTSDD: CALL BTGPRT ;GET PORT NUMBER
UMOVE P2,.BTLEN(Q1) ;GET LENGTH OF DATA
MOVEI T1,3(P2) ;PREPARE TO ROUND
LSH T1,-2 ;# OF WORDS
MOVE P3,T1 ;TAKE A COPY FOR LATER
HRLI T1,.RESP1 ;PRIORITY 1
MOVE T2,[RS%SE0+.RESNP] ;GET SPACE FROM NET POOL
CALL ASGRES
RET ; ERROR
MOVE T2,T1 ;COPY ADDR OF BUFFER
UMOVE T3,.BTMSG(Q1) ;GET USER'S DATA POINTER
TLNN T3,-1 ;IF LH ALL ZERO
JRST BTSDD1 ;THE DO WORD BLTs
HLRZ T4,T3 ;STANDARD ASCII POINTER?
CAIN T4,-1
HRLI T3,440700 ;YES
HRLI T1,(<POINT 8,>) ;DESTINATION BYTE POINTER
PUSH P,P2 ;WILL NEED THIS LATER
BTSDD0: XCTBU [ILDB T4,T3] ;GET A BYTE FROM USER
IDPB T4,T1 ;STORE IN RESIDENT BUFFER
SOJG P2,BTSDD0 ;REPEAT UNTIL DONE
UMOVEM T3,.BTMSG(Q1) ;RETURN UPDATED POINTER TO USER
POP P,P2 ;PUT BYTE LENGTH BACK FOR BELOW
JRST BTSDD2
BTSDD1: ADD P3,T1 ;COMPUTE END OF BUFFER FOR BLT
HRL T1,T3 ;USER DATA ADDRESS FOR BLT
XBLTUM [BLT T1,-1(P3)] ;MOVE THE DATA
BTSDD2: HRLI T2,(<POINT 8,>) ;MAKE THE BYTE POINTER
MOVE T1,PGKDPN(P1) ;SET LINE #
HRLI T1,DCPPST ;ADDR FOR COMPLETION
MOVE T3,P2 ;GET LENGTH OF DATA
HRRZ F,T2 ;BUFFER ADDR FOR COMPLETION POSTING
TXO T3,1B1 ;MARK THIS MESSAGE FROM DCP
CALL DCNMSO ;QUEUE THE MESSAGE TO KMC
JRST [MOVE T1,F ;GET BACK THE RESIDENT BUFFER ADDRESS
CALLRET RELRES] ;FREE THE BUFFER
RETSKP ;SUCCESS
SUBTTL BOOT JSYS -- INITIATE PROTOCOL
BTIPR: CALL BTIDC0 ;INSURE STATION TABLE EXITS
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: SETZM PGMSTS(P1) ;INITIALIZE MOP STATUS
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: JUMPN P3,BTIDC4 ;MULTI-DROP??
SETZ T2, ;NO MAINTENANCE MODE BITS
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
BSIO T2,DPTCSR(T4) ;SET NEW FORM OF MAINTAINENCE MODE
MOVEI T1,DPDTR ;WANT DATA TERMINAL READY SET
BSIO T1,DPRCSR(T4) ;SET IT
SETZRO DDACI ;SET POLLING STATUS ACTIVE
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 INSURE STATION TABLE EXIST FOR A POTENTIALLY NEW STATION
BTIDC0: UMOVE T1,.BTPRT(Q1) ;GET TERMINAL ID
HRR P1,T1 ;GET LINE NUMBER
CAML P1,KDPNLN ;IS IT IN RANGE
ITERR(ARGX19) ;NO
HRR P1,KDPPAG(P1) ;GET LINES PAGE
HLRZ P3,T1 ;REMEBER DROP
SKIPN P3 ;POINT TO POINT?
RET ;ALL DONE
HRR P4,PGCSTA(P1) ;GET A STATION TABLE
SKIPN PGSTAL(P1) ;IS THIS FIRST STATION TO START
JRST DDINI0 ;YES, LINK A STATION TABLE AND CONTINUE
BTIDC1: SETZM P4 ;INIT STATION SCAN
BTIDC2: CALL NXTSTA ;GET THE NEXT STATION
JRST DDINI ;CREATE A NEW STATION
LOAD T1,DDDRP ;GET DROP OF THIS STATION
CAMN T1,P3 ;IS THIS IT?
RET ;YES, ALL SET
JRST BTIDC2 ;SCAN THE STATION LIST
;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 BTIDC4
CAMN T2,T3 ;ALREADY THIS WAY ?
RETSKP ;ALREADY LOOPED BACK
JRST BTERR ;LOSE
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
MOVEI T1,DPDTR ;NO LONGER TRYING
BCIO T1,DPRCSR(T4) ;CLEAR DAT TERMINAL READY
MOVEI T1,NSPL ;SET DEFAULT LINE SERVER TO NSP
STOR T1,LINSR
NOINT
MOVEI T1,STADWN ;CODE FOR STOPPED
CALL DEDLIN ;CLEAN UP LINE
OKINT
CALL RELMOP ;RELEASE ANY MOP MESSAGES
MOVE T1,PGLINQ(P1) ;CHECK IN ANY MSGS IN Q ARE MOP MSGS
TLNN T1,-1 ;IF SO, HAS ZERO IN LH
SETZM PGLINQ(P1) ;YES, ZERO Q POINTER. BUFFER ALREADY RELEASED
RETSKP
;HERE FOR BOOT JSYS FUNCTIONS TO SET SLAVE STATION PARAMETERS
;SET POLLING STATUS ACTIVE/IDLE
BTSTA: CALL BTGPRT ;GET STATION
UMOVE T1,.BTCOD(Q1) ;GET ACTIVE/IDLE INDICATOR
STOR T1,DDACI ;SET IT
RETSKP
;SET RELETIVE STARTUP FREQUENCY COUNTER
;THIS WILL DETERMINE HOW MANY CYCLES THRU THE ACTIVE POLLING LIST MUST
;BE DONE BETWEEN SENDING DDCMP STARTS
BTSSP: CALL BTGPRT ;GET STATION
UMOVE T1,.BTPRI(Q1) ;GET STARTUP COUNTER
STOR T1,DDSSP ;SET IT
RETSKP
;SET A STATIONS RELETIVE POLLING PRIORITY (1 IS HIGH)
BTSTP: CALL BTGPRT ;GET STATION
UMOVE T1,.BTPRI(Q1) ;GET TERMINAL PRIORITY
STOR T1,DDSPC ;SET IT
RETSKP
;SET INTERRUPT CHANNEL FOR INDICATION OF INPUT AVAILABLE FOR USER
BTCHN: CALL BTGPRT ;SET UP P1
UMOVE T1,.BTCOD(Q1) ;GET INTERRUPT CHANNEL
AOS T1 ;INDEX BY 1
HRL T1,FORKX ;GET USER'S FORK#
MOVEM T1,PGLINT(P1) ;SAVE IT
RETSKP
;SET LINE TYPE OF LINE SERVICE (DDCMP OR NSP)
BTSLS: CALL BTGPRT ;SET UP P1
UMOVE T1,.BTCOD(Q1) ;GET LINE SERVICE FLAG
CAIE T1,DCPL ;RUNNING LINE AS DDCMP ONLY?
CAIN T1,NSPL ;OR AS NSP?
SKIPA
RET ;NOT IT RANGE
STOR T1,LINSR ;SET THE VALUE
RETSKP ;RETURN OKAY
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 A DDCMP MESSAGE
;HERE TO RECEIVE A DATA MESSAGE OR A COMPLETION POSTING
;COMPLETION POSTINGS AND DATA MESSAGES RESIDE ON THE SAME QUEUE
;ARGUMENT BLOCK
; .BTPRT/ LINE#
; .BTMSG/ ADDR OF BUFFER TO RECEIVE MESSAGE
; .BTLEN/ SIZE OF BUFFER (8 BIT BYTES)
;RETURNS
; .BTPRT/ DROP#,,LINE#
; .BTMSG/ DATA
; .BTLEN/ ACTUAL BYTE COUNT OF DATA RETURNED
; OR COMPLETION POSTING CODE
; STATION CAME UP = 400000,,1
; STATION DIED = 400000,,2
; XMIT COMPLETE = 400000,,3
;ERROR RETURN IF BUFFER TOO SMALL
BTRDD: CALL BTGPRT ;GET PORT NUMBER
SKIPN T1,PGLINQ(P1) ;IS QUEUE EMPTY
JRST [ XCTU [SETZM .BTLEN(Q1)] ;YES
RETSKP]
SKIPG P3,INDCNT(T1) ;DATA??
JRST [UMOVEM P3,.BTLEN(Q1) ;NO, GIVE IT TO USER
JRST BTRDD1 ] ;CONTINUE
HRRZ P3,INDCNT(T1) ;GET SIZE OF MESSAGE
XCTU [HRRZ T2,.BTLEN(Q1)] ;GET LENGTH OF USERS BUFFER
CAMLE P3,T2 ;ENOUGH ROOM?
ITERR() ;NO
;%% ADD CODE
UMOVEM P3,.BTLEN(Q1) ;RETURN ACTUAL SIZE OF BUFFER
UMOVE T2,.BTMSG(Q1) ;GET USER'S BUFFER POINTER
TLNN T2,-1 ;IF LH 0 THEN USER
JRST BTRDD0 ;WORD BLTs
HLRZ T4,T2 ;STANDARD ASCII POINTER?
CAIN T4,-1
HRLI T2,440700 ;YES
MOVE T4,[POINT 8,MSHDR(T1)] ;BYTE POINTER TO RECEIVE DATA
BTRDD2: ILDB T3,T4 ;GET A BYTE FOR USER
XCTBU [IDPB T3,T2] ;DEPOSIT IN USER SPACE
SOJG P3,BTRDD2 ;LOOP TIL DONE
UMOVEM T2,.BTMSG(Q1) ;RETURN UPDATED BYTE POINTER
JRST BTRDD1
BTRDD0: ADDI P3,3 ;ROUND TO WORDS
LSH P3,-2
ADD P3,T2 ;END ADDR OF BLT
HRLI T2,MSHDR(T1) ;ADDR OF DATA BUFFER
XBLTMU [BLT T2,-1(P3)] ;GIVE DATA TO USER
BTRDD1: MOVE T2,INDLNK(T1) ;GET TERMINAL #
XCTU [HLLM T2,.BTPRT(Q1)] ;GIVE IT TO USER
PIOFF
LOAD T4,DDINP ;COUNT OF RCV MSGS QUEUED
SOS T4 ;GOT RID OF ONE
STOR T4,DDINP ;SAVE IT
HRRZS T1 ;CLEAR LEFT HALF FOR RELRES
HRRZ P2,INDLNK(T1) ;GET ADDR OF NEXT MESSAGE
JUMPE P2,[ SETZM PGLINQ(P1) ;QUEUE EMPTY
JRST BTRDD3 ] ;YES
HRRM P2,PGLINQ(P1) ;POINT AT NEXT ENTRY
BTRDD3: CALL RELRES ;RELEASE THE BLOCK
PION
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 (KMCBRK,<<Q2,D>>)
MOVEI T1,IOX5 ;Device or data error
RET ;REPORT PROBLEM THEN QUIT
;HERE TO INITIALIZE THE COMIOP
COMINI: SKIPL P1,KDPLIM ;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,KDPPAG(P1) ;GET ADR OF LINES PAGE
HRR P4,PGCSTA(P1) ;GET ADR OF DDCMP LINE TABLE
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,PGKDPN(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,PGKDPN(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,PGKDPN(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,PGKDPN(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,KDPNLN ;IS NUMBER IN RANGE ?
JRST BTERR ;LOSE
UMOVEM T2,.BTPRT(Q1) ;RETURN PORT NUMBER TO USER
XCTBU [ILDB T1,T4] ;GET 0 BYTE FROM USER STRINT
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,PGKDPN(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
KDPINI::MOVE T1,[KMCADR] ;ADR OF KMC11
CALL UBGOOD ;CHECK TO SEE IF INSTALLED
RET ;NO KMC11
MOVSI P2,-KDPN ;NUMBER OF DUP11'S ASSEMBLED FOR
MOVEI P1,KMCPAG ;POINT TO FIRST DUP11 PAGE
DPINI2: HRRZM P1,KDPPAG(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,PGKDPN(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 (DUPUBA)
HRLZM T2,PGUBAD(P1) ;SAVE UNIBUS ADR OF PAGE
HRLM T2,KDPPAG(P2) ;SAVE UNIBUS ADR OF PAGE
MOVEM T1,PGUBAM(P1) ;SAVE ADR OF UBA MAPPING REGISTER
HRRZ T2,KDPPAG(P2) ;GET ADR OF PAGE
LSH T2,-^D9 ;CONVERT TO PAGE NUMBER
IORI T2,UNBVBT ;FLAG VALID
WRIO T2,@T1 ;SET MAPPING REGISTER
SETZ P3, ;INDICATE POINT TO POINT
CALL DDINI ;SET DDCMP LINE TABLE
MOVEI T1,50521 ;BOOT PASSWORD FOR ENTER-MOP-MODE
HRLS T1 ;IS CURRENTLY
MOVEM T1,PGMPSW(P1) ;CANNED
ADDI P1,1000 ;ON TO NEXT LINES PAGE
AOBJN P2,DPINI2 ;LOOP BACK FOR OTHER DUP11'S
DPINI3: HRRZM P2,KDPNLN ;SAVE NUMBER OF DUP11'S
HRLZS P2 ;PUT NUMBER OF EXISTING DUP11'S IN LH
MOVNM P2,KDPLIM ;REMEMBER HOW MANY THERE ARE
SKIPL P1,KDPLIM ;GET NUMBER OF DUP11'S
RET ;NONE
MOVSI T1,(<XPCW>) ;INTERRUPT INSTRUCTION
HRRI T1,KDPXPC ;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 (KMCLOD)
RET ]
RET
SUBTTL HERE TO INIT DDCMP LINE TABLE
; P3/ DROP OF STATION OR ZERO FOR POINT TO POINT
DDINI: MOVE T1,[.RESP1,,DDLSZ] ;GET A CORE BLOCK
MOVX T2,RS%SE0+.RESNP ;FROM THE NET POOL
CALL ASGRES ;FOR THE LINE TABLE
BUG (DDLCOR)
MOVE P4,T1 ;COPY ADDRESS
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 (DUPCOR)
CALL SAVBLK ;SAVE ADR OF BLOCK
MOVEI T1,STASTR ;GET START STATE
STOR T1,DDSTA ;MARK ELIGABLE FOR STARTS
JUMPN P3,DDINI0 ;POINT TO POINT?
MOVEI T1,1 ;ASSUME POINT TO POINT
STOR T1,DDDRP
JRST DDINI2 ;ALL SET
DDINI0: STOR P3,DDDRP ;SAVE DROP #
MOVEI T1,1 ;GET A ONE
STOR T1,DDSPC ;INIT STATION PRIORITY COUNTER
STOR T1,DDIPC ;INIT PRESET COUNT
MOVEI T1,DCPL ;MARK DCP ONLY
STOR T1,LINSR ;IN LINE PAGE
CALL INSTA ;THREAD THIS STATION
DDINI2: HRRM P4,PGCSTA(P1) ;MARK LAST STATION AS SELECTED
RET
;INSERT A LINE TABLE IN A STATION LIST
;INPUT /P1 LINE PAGE FOR DUP
; /P4 DDCMP LINE TABLE
;LINE TABLE IS LINKED AND STATION LIST IN LINE PAGE IS UPDATED
RESCD
INSTA: PIOFF
LOAD T1,DDSTB ;GET END OF STATION LIST
JUMPE T1,INSTA1 ;FIRST ENTRY??
HRRM P4,(T1) ;UPDATE PREVIOUS LIST TAIL
STOR P4,DDSTB ;UPDATE POINTER IN STATION LIST
STOR T1,DDBAK ;SET BACK LINK
LOAD T1,DDSTT ;GET TOP OF LIST
STOR T1,DDLNK ;LINK NEW ENTRY
HRLM P4,(T1) ;UPDATE BACK POINTER OF FORWARD LINK
PION
RET
;INITIALIZE NEW STATION LIST
INSTA1: STOR P4,DDSTT ;TOP OF LIST
STOR P4,DDSTB ;LIST TAIL
STOR P4,DDLNK ;LINK FIRST ENTRY TO ITSELF
STOR P4,DDBAK
PION
RET
;REMOVE A STATION FROM THE STATION LIST
REMSTA: PIOFF
LOAD T1,DDLNK ;GET FORWARD LINK
LOAD T2,DDBAK ;GET BACK LINK
CAMN T1,T2 ;IS THIS LAST STATION ON LIST?
CAME T1,P4
JRST REM1 ;NO, CONTINUE
SETZM PGDLNK(P4) ;UNLINK STATION
SETZM PGSTAL(P1) ;STATION LIST EMPTY
PION
RET
REM1: HRRM T1,PGDLNK(T2) ;UPDATE BACK LINK
HRLM T2,PGDLNK(T1) ;UPDATE FORWARD LINK
LOAD T2,DDSTT ;GET TOP OF STATION LIST
CAMN T2,P4 ;WAS IT THIS ONE
STOR T1,DDSTT ;YES, UPDATE IT
LOAD T1,DDBAK ;GET BACK BACK LINK
LOAD T2,DDSTB ;GET TAIL OF STATION LIST
CAMN T2,P4 ;WAS IT THIS ONE
STOR T1,DDSTB ;YES UPDAT IT
PION
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,KDPLIM ;LINE NUMBER
KMHLT3: HRR P1,KDPPAG(P1) ;GET ADR OF LINES PAGE
HRR P4,PGCSTA(P1) ;GET ADR OF DDCMPLINE TABLE
MOVEI T1,STADWN ;KMC11 IS NOT RUNNING
CALL DEDLIN ;MOURN THE DEAD LINE
HRR P1,PGKDPN(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
KDPTSK::SETZM KDPFLG ;HAVE CHECKED NOW
SKIPL P1,KDPLIM ;GET NUMBER OF DUP11'S
RET ;NONE
KMCTK0: SETZ P4, ;CLEAR STATION TABLE
HRR P1,KDPPAG(P1) ;GET LINES PAGE
KMCTK1: CALL NXTSTA ;GET STATION TABLE ADDR
JRST KMCTK9 ;ALL DONE WITH THIS LINE
PIOFF ;DISABLE INTERRUPTS
LOAD T3,DCHNG ;GET CODE FOR READY TO BEGIN
SETZRO DCHNG ;HAVE DONE IT NOW
JUMPE T3,KMCTK8 ;CHECK FOR NOTHING
HRRZ T1,PGKDPN(P1) ;COPY LINE NUMBER FOR NSPSRV
CAIE T3,DDUP ;DID LINE COME UP ?
JRST [ PION ;REENABLE INTERRUPTS
LOAD T2,LINSR ;GET LINE SERVER
CALL DEDDSP(T2) ;TELL SERVER 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
SETZRO DDSFC ;CLEAR STARTUP FAILURE COUNTER
PION ;REENABLE INTERRUPTS
HRRZ T1,PGKDPN(P1) ;GET LINE NUMBER AGAIN
LOAD T2,LINSR ;GET LINE SERVER
CALL INIDSP(T2) ;LET SERVER LINE CAME ON
KMCTK8: PION ;REENABLE INTERRUPTS
SKIPE PGSTAL(P1) ;POINT TO POINT
JRST KMCTK1 ;NO, LOOP THRU STATION LIST
KMCTK9: HRR P1,PGKDPN(P1) ;GET LINE NUMBER AGAIN
AOBJN P1,KMCTK0
RET
DEDDSP: JRST DEDMCB
JRST DEDDCP ;POST STATION DOWN
INIDSP: JRST NODINI ;TELL NSPSRV LINE CAME UP
JRST DCPINI ;POST STATION ON LINE
;HERE TO FIND NEXT STATION IN STATION LIST
;P4/ ADDR OF PREVIOUS STATION OR ZERO TO INITIATE SCAN
;
;RETURNS
; +2 WITH ADDR OF NEXT STATION IN P4
; OR
; +1 IF CALLED WITH P4 POINTING AT LAST STATION (END OF SCAN)
RESCD ;CALLED FROM ALL LEVELS
NXTSTA: SKIPN T1,PGSTAL(P1) ;POINT TO POINT
JRST [ HRR P4,PGCSTA(P1) ;GET ADR OF DDCMP LINE TABLE
RETSKP ]
HLRZS T1 ;GET END OF STATION LIST
CAMN T1,P4 ;IS THIS IT
RET ;FINISHED ALL STATIONS
SKIPN P4 ;FIRST TIME THRU
MOVE P4,T1 ;YES GET END OF LIST
LOAD P4,DDLNK ;GET NEXT STATION
RETSKP ;PROCESS THIS STATION
;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: TLNN T2,777 ;%% DEBUG %%
JFCL ;%%%%%%%%%%%
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 (KMCNTI)
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 (KMCIII,<<T1,D>,<T2,D>>)
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,KDPPAG(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 KDPXPC ;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 (KMCFST) ;INFORMATION HAS BEEN LOST
JRST KMVCB9 ] ;DISMISS THE INTERRUPT
LDB P1,[POINT 8,T1,27] ;GET THE LINE NUMBER
HRR P1,KDPPAG(P1) ;GET PAGE ADDRESSES FOR LINE
HRR P4,PGCSTA(P1) ;GET ADR FOR DDCMP LINE TABLE
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
LOAD T2,DDDRP ;GET DROP OF SELECTED STATION
CAME T1,T2 ;MATCH?
JRST RCVFLU ;NO, IGNORE
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
JRST RCVMOP ;THIS IS POSSIBLY A MOP 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 (BADHDR,<<T1,D>,<T2,D>>)
MOVEI T1,STADWN ;DON'T TRY TO USE LINE
; CALL DEDLIN ;DECLARE LINE DOWN
AOS PGLCOC(P4) ;%%% KMC SHOULD NOT GET HERE %%%
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,PGKDPN(P1) ;COPY LINE NUMBER
LOAD T4,LINSR ;GET LINE SERVICE INDICATOR
CALL @KDPSPC(T4) ;GET SPACE FOR 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 P5,-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 P5,T1 ;SAVE WORD FOR NSPSRV
AOBJN P3,RCVDT3 ;LOOP BACK FOR REST OF MESSAGE
POP P,T2 ;GET DATA ADR BACK
LOAD T4,LINSR ;GET LINE SERVICE INDICATOR
CALL @KDPQ(T4) ;GIVE MESSAGE TO SERVER(NSP/DCP)
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
KDPSPC: JRST NSPSPC ;NSP ASSIGN BUFFER
JRST DCPSPC ;DCP ASSIGN BUFFER
KDPQ: JRST NSPQ ;QUEUE MESSAGE TO NSP
JRST DCPQ ;QUEUE MESSAGE TO DCP
SUBTTL DDCMP INTERFACE SERVICE ROUTINES
;THESE ROUTINES PROVIDE SERVICE FOR DIRECT USER ACCESS
;TO DDCMP LINES -- THESE ROUTINES PARELLEL ROUTINES IN NSP
;HERE TO GET A BUFFER SET UP FOR INPUT
;ACCEPTS T2/BYTE COUNT OF RECEIVED MESSAGE
;RETURNS T1/ADDR OF BUFFER
DCPSPC: LOAD T3,DDINP ;HOW MANY ALREADY BUFFERED
CAILE T3,MAXIN ;ARE WE FULL
RETBAD ;YES
STKVAR<DCPLEN> ;GET SOME TEMP STORAGE
MOVEM T2,DCPLEN ;REMEMBER DATA BYTE COUNT
MOVEI T1,4*MSHDR+3(T2) ;BYTE COUNT OF BUFFER
LSH T1,-2 ;CONVERT TO WORDS
HRLI T1,.RESP1 ;PRIORITY 1
MOVE T2,[RS%SE0+.RESNP] ;FROM NET POOL
CALL ASGRES ;GET THE SPACE
RETBAD ;COULDN'T
LOAD T3,DDINP ;GET # OF BUFFERS
AOS T3 ;COUNT NEW ONE
STOR T3,DDINP ;SAVE IT
LOAD T2,DDDRP ;GET SYSTEM LINE #
HRLZM T2,INDLNK(T1) ;PUT IT IN HEADER
MOVE T4,DCPLEN ;GET BACK BYTE COUNT
MOVEM T4,INDCNT(T1) ;PUT IT IN HEADER
ADDI T1,MSHDR ;POINT AT DATA
RETSKP
;HERE TO LINK A BUFFER TO INPUT QUEUE
;T2/ ADDRESS OF BUFFER
DCPQ: SUBI T2,MSHDR ;POINT AT MESSAGE HEADER
DCPQ1: SKIPN T1,PGLINQ(P1) ;ANYTHING IN QUEUE
JRST [ HRRM T2,PGLINQ(P1) ;NO, START IT
HRLM T2,PGLINQ(P1)
JRST DCPQ2 ]
HLRZS T1 ;GET TAIL
HRRM T2,INDLNK(T1) ;LINK THIS IN
HRLM T2,PGLINQ(P1) ;MAKE IT THE TAIL
DCPQ2: SETONE DDINT ;REQUEST INTERRUPT
RET
;HERE TO POST TRANSMIT COMPLETE
;T1/ BUFFER ADDR
DCPPST: HRRZI T3,DDPT ;COMPLETION POSTING
TLO T3,400000 ;SET STATUS BIT
MOVEM T3,INDCNT(T1) ;IN MESSAGE HEADER
LOAD T3,DDDRP ;GET DROP
HRLZM T3,INDLNK(T1) ;PUT IN MESSAGE HEADER
MOVE T2,T1 ;BUFFER ADDR FOR DCPQ
LOAD T3,DDINP ;GET COUNT OF BUFFERED MESSAGES
AOS T3 ;COUNT THIS ONE
STOR T3,DDINP
CALL DCPQ1 ;QUEUE IT AS INPUT MESSAGE
SETONE DDINT ;CAUSE AN INTERRUPT
RET
;HERE TO QUEUE AN INPUT MESSAGE TO POST LINE GOING UP OR DOWN
;T3/DDUP,DDOWN OR DDSF
DEDDCP:
DCPINI: PUSH P,T3 ;SAVE CONDITION INDICATOR
SETZM T2 ;ZERO MESSAGE LENGTH (HEADER ONLY)
CALL DCPSPC ;GET A BUFFER
JRST [ POP P,T1 ;NO BUFFER AVAILABLE
STOR T1,DCHNG ;TRY AGAIN NEXT TIME
SETOM KDPFLG
RET ]
SUBI T1,MSHDR ;POINT AT HEADER
POP P,T3 ;GET BACK CONDITION
TLO T3,400000 ;SET STATUS BIT
MOVEM T3,INDCNT(T1) ;IN MESSAGE HEADER
MOVE T2,T1 ;BUFFER ADDR FOR DCPQ
CALL DCPQ1 ;QUEUE IT
RET
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 KDPFLG ;WANT TO RUN KDPTSK
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 rcvak5 ;nothing new to do
SUB T3,T1 ;FIND NUMBER OF MESSAGES THIS WILL ACK
cail t3,0 ;must be between 0 and 10
caile t3,maxout ;to be a valid ack
caia
jrst rcvak6 ;valid continue processing
addi t3,400 ;handle wrap case
cail t3,0 ;try again
caile t3,maxout ;0 leq A-R leq 10
jrst rcvak5 ;not a vaild R field..
rcvak6: 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(P4) ;GET FIRST MESSAGE IN QUEUE
JUMPE T1,rcvak5 ;IF NONE RESPONSE WAS BAD
CAMN T1,PGDLMX(P4) ;WAS THIS LAST MESSAGE TRANSMITTED ?
SETZM PGDLMX(P4) ;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(P4) ;GET ADR OF MESSAGE BLOCK ADR AGAIN
HLRZ T2,MBKLNK(T1) ;GET ADR OF NEXT MESSAGE IN QUEUE
HRLM T2,PGDOMQ(P4) ;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(P4) ;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
rcvak5: SKIPE T1,PGDOMQ(P4) ;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
;HERE TO FREE A BLOCK OF CORE
SAVBLK: SKIPN T2,PGFCOR(P4) ;HOLDING ANY FREE BLOCKS ?
JRST [ HRLZM T1,PGFCOR(P4) ;SAVE THIS ONE
RET ]
TRNE T2,-1 ;HOLDING TWO ?
JRST RELRES ;CAN'T HOLD ANY MORE
HRRM T1,PGFCOR(P4) ;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,^D17 ;is nak code reasonable?
SETZ T1, ;FIRST CELL IS MISC
move t2,naktbl(t1) ;retrieve offset into table
addi t2,pgnrnk(p1) ;point to nak counter
aos (t2) ;count nak
SETZM PGDLMX(P4) ;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,PGKDPN(P1) ;GET LINE NUMBER
BUG (DDCSTR,<<T1,D>>)
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,2 ;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 KDPFLG ;SO WE CHECK FLAG
DEDLN2: PIOFF ;STOP RACES
HLRZ T3,PGDOMQ(P4) ;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(P4) ;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(P4) ;HAVE FLUSHED OUTPUT QUEUE
SETZM PGDLMX(P4) ;NO LAST MESSAGE NOW
SETZM PGDMNM(P4) ;INITIALIZE MESSAGE NUMBERS
SETZRO DDLMX
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
LDB P3,[POINT 8,PGRMS1-PGRBD1(T3),35] ;SAVE 3RD BYTE OF MESSAGE
CALL RCVENB ;REENABLE RECEIVER
SKIPN PGSTAL(P1) ;MULTI-DROP LINE?
JRST KMVCB9 ;NO, ALL DONE
TRNE P3,SELECT ;DID STATION DESELECT
CALL SELSTA ;YES, SELECT NEXT STATION
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 P3,[POINT 8,PGXMS1+1-PGXBD1(T2),9] ;GET A0
SETZM P4 ;CLEAR STATION TABLE ADDR
XMTDN6: CALL NXTSTA ;GET NEXT STATION IN LIST
BUG (MSGCLB)
LOAD T3,DDDRP ;DROP OF SELECTED STATION
CAME P3,T3 ;MATCH?
JRST XMTDN6 ;LOOP TO FIND STATION
SETZM (T2) ;THIS BUFFER DESCRIPTOR LIST NOW FREE
LOAD T2,DDSTA ;GET STATE
CAIN STAMAI ;IN MAINTENANCE MODE?
JRST MOPDNE ;DO MOP COMPLETION STUFF
MOVEI T1,TIMREP ;GET REP INTERVAL
CAIN T2,STASTR ;SENDING STARTS?
MOVEI T1,TIMSTR ;YES, USE START TIMER
LOAD T2,DDTIM ;GET CURRENT TIMER
SKIPN T2 ;STATION IDLE?
STOR T1,DDTIM ;YES, SET REP TIMER
HRR P4,PGCSTA(P1) ;GET CURRENTLY SELECTED STATION
LOAD T1,DDNCD ;GET CURRENT NAK CODE
SKIPE T1 ;DO WE NEED TO SEND A NAK ?
CALL XMTNAK ;TRY TO SEND IT NOW
LOAD T1,DDSEL ;IS STATION WAITING FOR SELECT
JUMPN T1,[LOAD T1,DDSTA ;YES,GET STATE
CALL @SELDSP(T1) ;SEND A MESSAGE
JRST .+1]
SKIPN PGOLST(P4) ;ANY OUTPUT FOR THIS STATION
JRST [SKIPN P4,PGLOUQ(P1) ;ANY OUTPUT QUEUED?
HRR P4,PGCSTA(P1) ;NO, JUST CHECK FOR ACK
JRST .+1]
CALL XMTDAT ;TRY TO SEND SOME DATA
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: MOVX T3,DUPDSR ;BIT FOR DATASET READY
XORB T3,PGLSTS(P1) ;CHANGE STATE
TXNE T3,DUPDSR ;STILL UP ?
JRST KMVCB9 ;CAME ON - DISMISS
LOAD T3,DDSTA ;GET CURRENT STATE
CAIE T3,STASTK ;ARE WE SENDING STACKS ?
CAIN T3,STARUN ;OR ARE WE RUNNING ?
SKIPA T1,[EXP STASTR] ;SEND STARTS AGAIN
JRST KMVCB9 ;DISMISS
HRRZ T2,PGKDPN(P1) ;GET LINE NUMBER
CAIN T3,STARUN ;ARE WE RUNNING ?
BUG (DSRLST,<<T2,D>>)
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 (KMCNXM) ;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 KDPXPC+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
; B1 SET IF MESSAGE FROM DCP
;
; 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,KDPNLN ;IS LINE NUMBER IN RANGE ?
RET ;NO SO LOSE RETURN
STKVAR <DRVMSG,DRVCOD,DRVLEN,DRVFLG>
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 (MSGPTR)
HRR T1,T3 ;BUILD MBKLEN
MOVEM T1,DRVLEN ;SAVE IT
MOVEM T3,DRVFLG ;SAVE FLAGS
MOVE P1,KDPPAG(P1) ;GET ADR OF LINES PAGE
TXNN T3,1B1 ;DCP DATA
;%% NOT GOOD ENOUGH
HRR P4,PGCSTA(P1) ;GET STATION TABLE ADDRESS
LOAD T1,DDSTA ;GET LINE STATUS
CAIE T1,STARUN ;IS LINE RUNNING ?
RET ;CAN'T HANDLE MESSAGE
DCNMS1: SKIPE PGFCOR(P4) ;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 DRVFLG ;ALREADY SHUFFLED ?
JRST DCNMS4 ;IN CASE ALREADY SHUFFLED DATA
MOVE T3,DRVLEN ;GET LENGTH OF MESSAGE
HRR T2,DRVMSG ;GET ADR OF MESSAGE
CALL SHFFLE
DCNMS4: PIOFF ;DISABLE INTERRUPTS WHILE WE QUEUE IT
HLRZ T1,PGLOUQ(P1) ;GET TAIL OF STATION OUTPUT QUEUE
JUMPE T1,[HRRM P4,PGLOUQ(P1) ;FIRST ENTRY,SET HEAD
MOVE T1,P4 ;GET TAIL
JRST .+1]
HRR T3,PGLOUQ(P1) ;GET HEAD
HRRM T3,PGOLST(P4) ;SET FORWARD THREAD
HRLM T1,PGOLST(P4) ;SET BACK THREAD
HRLM P4,PGLOUQ(P1) ;SET NEW TAIL
SKIPE T4,PGDOMQ(P4) ;ANY OUTPUT MESSAGE QUEUE FOR THE LINE
JRST DCNMSA ;YES
SETZM PGDLMX(P4) ;NO PREVIOUS MSG SENT
HRRZ T3,PGFCOR(P4) ;GET BLOCK ADR
SKIPN T3 ;IS THERE ANYTHING THERE ?
MOVSS T3,PGFCOR(P4) ;NO SO GET OTHER HALF
HLLZS PGFCOR(P4) ;REMOVE FROM FREE SPACE
HRLM T3,PGDOMQ(P4) ;THIS IS FIRST MESSAGE
HRRZ T1,T3 ;COPY ADR OF CHUNK
HRLI T1,BLKSIZ-4 ;NUMBER OF FREE WORDS LEFT
JRST DCNMS6
DCNMSA: 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(P4) ;GET OLD BLOCK
SKIPN T3 ;WAS THERE ONE ?
MOVSS T3,PGFCOR(P4) ;NO SO USE ONE WE JUST GOT
HLLZS PGFCOR(P4) ;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(P4) ;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
KDPCHK::SAVEP ;SAVE THE P'S
MOVEI T1,^D1000 ;TIME TILL WE WANT TO CHECK AGAIN
MOVEM T1,KDPTIM
SKIPL P1,KDPLIM ;GET NUMBER OF DUP11'S
RET ;NONE
KMCHK0: pioff
HRR P1,KDPPAG(P1) ;GET PAGE ADR
HRR P4,PGCSTA(P1) ;GET DDCMP LINE TABLE
LOAD T1,DDSTA
CAIN T1,STAMAI ;MAINTENANCE MODE?
JRST [CALL MOPSEC ;YES, DO MOP STUFF
PION ;TURN INTERRUPTS BACK ON
JRST KMCHK3] ;GO ON
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
SKIPE PGSTAL(P1) ;MULTIPOINT?
JRST [CALL SELSTA ;YES, SELECT NEW STATION
JRST KMCHK2] ;CONTINUE FOR REMAINING LINES
LOAD T1,DDSTA ;GET LINE STATE
CALL TIMDSP(T1) ;DISPATCH ON STATE
KMCHK2: PION ;REENABLE INTERRUPTS
LOAD T1,DDINT ;WAS AN INTERRUPT REQUESTED
SKIPE T1
JRST [ SETZRO DDINT ;DID IT NOW
HRRZ T1,PGLINT(P1) ;GET CHANNEL
JUMPE T1,.+1 ;IS THERE ONE?
SOS T1 ;ZERO INDEX
HLRZ T2,PGLINT(P1) ;FORK#
CALL PSIRQ ;SEND INTERRUPT
JRST .+1 ]
KMCHK3: HRR P1,PGKDPN(P1) ;GET LINE NUMBER
AOBJN P1,KMCHK0 ;LOOP BACK FOR REST OF LINES
RET ;HAVE DONE ALL LINES
TIMDSP: JRST R ;KMC NOT RUNNING
JRST R ;MAINTENANCE MODE
JRST XSTART ;SENDING STARTS
JRST REPCHK ;RECEIVED STACK
JRST REPCHK ;RUNNING
SUBTTL HERE TO PROCESS END OF SELECTION INTERVAL
;CALLED AT INTERRUPT LEVEL OR WITH PIOFF
SELSTA: SETZRO DDTIM ;CLEAR REP TIMER
CALL GTNXT ;SELECT NEXT STATION
RET ;NO ELIGABLE STATIONS
LOAD T1,DDHMA ;HIGHEST MESSAGE ACKED
LOAD T2,DDLMX ;HIGHEST XMITTED
CAMLE T2,T1 ;ANY OUTSTANDING?
JRST REPCHK ;SEND A REP
LOAD T1,DDHXM ;HIGHEST MESSAGE XMITTED LAST INTERVAL
CAIN T1,377 ;TIME TO WRAP AROUND?
SETZM T1 ;YUP
STOR T1,DDLMX ;REMEMBER FOR NEXT TIME
SETONE DDXAK ;SEND AN ACK (IF NO DATA)
LOAD T1,DDSTA ;GET STATE
CALL @SELDSP(T1) ;DISPATCH ON STATE
RET
SELDSP: JRST R ;KMC NOT RUNNING
JRST R ;MAINTENANCE
JRST XSTART ;SENDIND STARTS
JRST XMTDAT ;RECEIVED STACK
JRST XMTDAT ;RUNNING
SUBTTL HERE TO SELECT NEXT STATION TO POLL
; A STATION IS ELEGIBLE TO BE POLLED IF IT IS RUNNING AND ACTIVE OR IN
;STARTUP. ACTIVE/IDLE STATE IS SET VIA THE BOOT JSYS. IF NO ELEGIBLE STATION
;IS FOUND AFTER ONE PASS THRU THE STATION TABLES A TIMER IS SET TO INITIATE
;A SCAN IN ONE SECOND AND THE ROUTINE EXITS NON SKIP.
; IN ORDER TO REDUCE POLLING DELAYS DUE TO UNRESPONSIVE STATIONS, STATIONS
;WHICH ARE IN STARTUP ARE NOT POLLED AS FREQUENTLY AS STATIONS WHICH ARE
;RUNNING. ONLY ONE STARTUP IS ATTEMPTED EVERY N TIMES ALL RUNNING STATIONS
;ARE POLLED. THE PARAMETER N IS PGSTCC IN THE LINE TABLE AND MAY BE SET VIA
;THE BOOT JSYS.
; ACTIVE STATIONS ARE POLLED ACCORDING TO PRIORITY VALUE BETWEEN 1 AND N
;WHERE 1 IS HIGHEST. THE RELETIVE FREQUENCY OF POLLING ANY TWO STATIONS
;WILL BE THE RATIO OF THERE PRIORITY VALUES. PRIORITY VALUES DEFAULT TO 1
;RESULTING IN ROUND ROBIN POLLING OF ACTIVE STATIONS OR CAN BE SET USING THE
;BOOT JSYS.
GTNXT: SETZB T1,T2 ;CLR ELIGABLE STATION COUNTER,LOOP COUNT
HRRZ T3,P4 ;REMEMBER CURRENT STATION
GTNXT1: LOAD P4,DDLNK ;GET NEXT STATION
LOAD T4,DDSTT ;GET TOP OF STATION LIST
CAMN P4,T4 ;ARE WE AT TOP?
JRST [LOAD T2,DDSSP ;PICK UP PRIORITY COUNT
SKIPG PGSTCC(P1) ;IF ZERO MUST BE RESET
MOVEM T2,PGSTCC(P1) ;OK RESET COUNT
SOS PGSTCC(P1) ;DECREMENT COUNT ANYWAY
JRST .+1]
;DETERMINE IF THIS STATION IS ELIGABLE
LOAD T4,DDACI ;GET POLLING STATUS
JUMPG T4,GTNXT2 ;IDLE?
LOAD T4,DDSTA ;GET STATE
MOVEI P2,STASTK ;ASSUME MUST BE RUNNING
SKIPG PGSTCC(P1) ;ARE STARTS ALLOWED
MOVEI P2,STASTR ;YES
CAMGE T4,P2 ;STATION ACTIVE?
JRST GTNXT2 ;NO
LOAD P2,DDSPC ;GET STATION'S PRIORITY COUNTER
SOJE P2,GTNXT3 ;SELECT THIS STATION IF COUNTER ZERO
STOR P2,DDSPC ;SAVE UPDATED COUNT
AOS T1 ;MARK AN ACTIVE STATION
GTNXT2: CAME P4,T3 ;ONCE THRU YET?
JRST GTNXT1 ;NO, KEEP TRUCKIN
;HERE WHEN THRU STATION LIST
JUMPG T1,GTNXT1 ;CONTINUE IF THERE ARE ACTIVE STATIONS
MOVEI T1,1 ;QUICK TIMER
STOR T1,DDTIM ;FOR THIS SELECTION INTERVAL
RET ;RETURN FAILURE
GTNXT3: LOAD T1,DDIPC ;GET INITIAL PRIORITY COUNT
STOR T1,DDSPC ;RESET STATION COUNTER
CAIE T4,STASTR ;IS THIS A START
JRST GTNXT4 ;NO, CONTINUE
CALL REMSTA ;REMOVE STATION FROM STATION LIST
CALL INSTA ;INSERT IT AT END OF LIST
LOAD T1,DDSSP ;GET INITIAL START COUNT
MOVEM T1,PGSTCC(P1) ;YES, RESET COUNTER
LOAD T1,DDSFC ;GET STARTUP FAILURE COUNTER
CAILE T1,MAXSTR ;IS IT TOO HIGH
JRST [SETZM PGDSTS(P4) ;MARK LINE DOWN
MOVEI T3,DDSF ;POST A STARTUP FAILURE
STOR T3,DCHNG ;AT SCHEDULER LEVEL
SETOM KDPFLG ;REQUEST THE SERVICE
JRST GTNXT] ;SELECT ANOTHER STATION
AOS T1 ;COUNT THIS STARTUP
STOR T1,DDSFC ;SAVE IT
GTNXT4: SETONE DDSEL ;MARK STATION FOR SELECT
MOVEM P4,PGCSTA(P1) ;SET STATION SELECTED
RETSKP ;RETURN SUCCESS
SUBTTL DDCMP TRANSMITTER -- DATA MESSAGES
XSTART: SETZRO DDXAK ;DON'T NEED AN ACK NOW
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: SETZRO DDXRP ;CLEAR INDICATOR
LOAD T2,DDREPC ;GET REP COUNTER
LOAD T1,DDSTA ;GET STATE FOR REPHGH
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(P4) ;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
CALL XMTCTL ;SEND THE REP MESSAGE
RET
RET
;HERE IF REP TIMER GOES TOO HIGH
REPHGH: HRRZ T2,PGKDPN(P1) ;GET DDCMP LINE NUMBER
CAIN T1,STARUN ;WERE WE RUNNING ?
BUG (DDCTIM,<<T2,D>>) ;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: SKIPE PGSTAL(P1) ;MULTIDROP?
JRST XMTAK4 ;YUP, TRY TO SEND THE ACK
SKIPN PGXBD1(P1) ;IS FIRST BUFFER BUSY ?
SKIPE PGXBD2(P1) ;OR IS THE 2ND BUFFER BUSY ?
RET ;DON'T SEND ACK YET
XMTAK4: 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
move t2,naktbl(t1) ;form table offset
addi t2,pgnxnk(p1) ;point to nak counter
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
LOAD T4,DDDRP ;GET DROP#
DPB T4,[POINT 8,T2,9] ;PUT IT IN MESSAGE
LOAD T4,DDSEL ;GET SELECT FLAG
JUMPN T4,[ TRO T1,SELECT!QSYNC ;YES,PUT IT IN MESSAGE
SETZRO DDSEL ;SENT IT NOW
JRST .+1 ] ;CONTINUE
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,PGKDPN(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(P4) ;GET ADR OF FIRST MESSAGE IN QUEUE
SKIPE T2,PGDLMX(P4) ;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(P4) ;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
HLRZ P2,MBKLNK(T1) ;GET LINK
JUMPN P2,XMTDT4 ;LAST MESSAGE
HRRZ T2,PGOLST(P4) ;GET FORWARD STATION THREAD
SKIPE T2 ;IS THIS A RE-XMIT TO IDLE LINE?
CAMN T2,P4 ;IS THIS THE LAST MESSAGE FOR LINE?
JRST [SETZM PGLOUQ(P1) ;YES,MARK QUEUE EMPTY
JRST XMTDT3]
HLRZ P3,PGOLST(P4) ;GET BACK THREAD
HRRM P3,PGOLST(T2) ;UPDATE FORWARD STATION
HRLM T2,PGOLST(P3) ;UPDATE BACK STATION
HRRZ P5,PGLOUQ(P1) ;GET HEAD OF QUEUE
CAMN P5,P4 ;WAS THIS THE HEAD
HRRM T2,PGLOUQ(P1) ;YES,UPDATE IT
HLRZ P5,PGLOUQ(P1) ;GET THE TAIL
CAMN P5,P4 ;WAS THIS THE TAIL?
HRLM P3,PGLOUQ(P1) ;YES,UPDATE IT
XMTDT3: SETZM PGOLST(P4) ;CLEAR THE ENTRY
XMTDT4: SKIPN PGDLMX(P4) ;IS THIS FIRST MESSAGE IN QUEUE ?
STOR T3,DDHXM ;1ST MSG IN QUEUE SO RESET MSG NUMBER
HRRZM T1,PGDLMX(P4) ;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
LOAD P2,DDSEL ;GET SELECT FLAG
JUMPN P2,[ TRO T2,SELECT!QSYNC ;YES,PUT IT IN MESSAGE
SETZRO DDSEL ;SENT IT NOW
JRST .+1 ] ;CONTINUE
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
LOAD T2,DDDRP ;GET DROP#
DPB T2,[POINT 8,T3,27] ;ADD IT TO MESSAGE
HRLZM T3,PGXMS1+1-PGXBD1(T4) ;SAVE REST OF MSG HEADER
HRRZ T1,PGDLMX(P4) ;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(P4) ;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,PGKDPN(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,PGKDPN(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
SUBTTL TRANSMIT MOP MESSAGE
; T1/0,,line #
; t2/byte pointer to buffer
; t3/data length in bytes
; F/0,,POST ROUTINE
XMTMOP: ;
HRRM F,PGMXHD+1(P1) ;FOR INTERRUPT ROUTINES
STOR T3,MPBLEN ;SAVE THE BUFFER LENGTH
XMTMP0: MOVEI T4,PGXBD1(P1) ;1ST SMIT BUFFER DESCRIPTOR LIST
SKIPE @T4 ;IS IT FREE?
MOVEI T4,PGXBD2(P1) ;2ND XMIT BUFFER DESCRIPTOR LIST
SKIPE @T4 ;IS IT FREE?
RET ;NO, LOSE. !!!THIS CANNOT HAPPEN FOR MOP!!!
STOR T2,MPBPTR ;STORE NOW THAT WE'RE REALLY GOING TO GO
PUSH P,T2 ;SAVE T2
HRRZ T2,T3 ;MOP MSG LENGTH IN BYTES
LSH T2,-^D8 ;LEAVE ONLY HIGH ORDER BITS
HRLI T2,DLE ;PUT IN MAINTENANCE MSG ID
DPB T3,[POINT 8,T2,9] ;PUT IN LOWER ORDER 8 BITS OF COUNT
TRO T2,SELECT!QSYNC ;NECESSARY FOR MAINTENANCE MSGS.
MOVEM T2,PGXMS1-PGXBD1(T4) ;STORE 1ST HALF OF MSG HEADER
SETZ T2, ;
LOAD T2,DDDRP ;GET THE STATION ADDRESS
LSH T2,^D8 ;POSITION TO RIGHT PLACE
HRLZM T2,PGXMS1+1-PGXBD1(T4) ;STORE REST OF HEADER IN MSG
POP P,T1
HRLZS T1 ;GET ADDRESS IN LH
HRRI T1,PGXMS1+2-PGXBD1(T4) ;DATA PART OF MESSAGE GOES HERE
MOVEI T2,3(T3) ;BYTE COUNT ROUNDED UP
LSH T2,-2 ;BYTES TO WORDS
ADDI T2,(T1) ;LAST ADDRESS FOR THE BLT
BLT T1,(T2) ;BLT THE DATA INTO MESSAGE
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
HRLS T3 ;GET BYTE COUNT IN LH
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,PGKDPN(P1) ;COPY LINE NUMBER
LSH T1,^D8 ;POSITION
IORI T1,BFADIN ;TYPE OF COMMAND
CALL KMCINP ;GIVE BUFFER DESCRIPTOR LIST TO KMC11
HRLZI T1,MPERR ;RESET TIME-OUT ERROR FLAG
ANDCAM T1,PGMSTS(P1)
MOVEI T1,PRITMO ;SPECIAL TIMEOUT DURING PRIMARY STATE
LOAD T2,MOPSTS ;GET THE MOP STATUS
CAIE T2,MPPRI ;IF IN PRIMARY USE LONGER TIMEOUT
MOVEI T1,MOPTMO ;USE NORMAL TIMEOUT
STOR T1,MOPTMR ;START THE TIMER
RETSKP ;DONE
subttl RECEIVE A MOP MESSAGE
RCVMOP:
LOAD T1,DDSTA ;GET THE LINE STATUS
CAIE T1,STAMAI ;IS IT IN MAINTENANCE MODE?
JRST RCVFLU ;NO, FLUSH AND IGNORE THE MESSAGE
SKIPN PGMXHD(P1) ;ARE WE EXPECTING THIS MESSAGE?
JRST RCVFLU ;NO, IGNORE THE MESSAGE
SKIPL PGMSTS(P1) ;IGNORE INPUT IF ERROR ALREADY DETECTED
SKIPE PGMRHD(P1) ;IS THERE ALREADY A MSG BEING PROCESSED
JRST RCVFLU ;YES, DON'T ACCEPT ANY MORE.
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
CALL MOPSPC ;GET SPACE FOR MOP MESSAGE
JRST RCVFLU
PUSH P,T1 ;SAVE ADDRESS OF BUFFER
HRRI P3,PGRMS1+1-PGRBD1(P2) ;FINISH AOBJN POINTER TO INPUT
HRRZI P5,-1(T1) ;WHERE TO PUT SHUFFLED MESSAGE
RCVMP3: 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 P5,T1 ;SHUFFLED WORD
AOBJN P3,RCVMP3 ;LOOP BACK FOR REST OF MESSAGE
POP P,P2 ;GET BUFFER ADDRESS BACK
CALL MOPPST ; POST
JRST RCVFLU ;THEN FLUSH THE MESSAGE
SUBTTL MOP INTERFACE SERVICE ROUTINES
MOPSPC: STOR T2,MPRLEN ;STORE LENGTH OF MESSAGE
MOVEI T1,3(T2) ;PREPARE TO ROUND
LSH T1,-2
HRLI T1,.RESP1 ;PRIORITY 1
MOVE T2,[RS%SE0+.RESNP] ;GET FROM NET POOL
CALL ASGRES
RET ;CAN'T
HRLI T1,(<POINT 8,>) ;MAKE A POINTER
STOR T1,MPRPTR ; SAVE IN DATABASE
RETSKP ;ADDRESS OF BUFFER IN T1
MOPQ: HRRZM P2,PGLINQ(P1) ;PUT INTO QUEUE
RETSKP
MOPPST: MOVEI T1,0 ;RESET TIMER SO THAT
STOR T1,MOPTMR ;TIMEOUT WILL NOT OCCUR
CALL RLXMOP ;RELEASE TRANSMIT BUFFER
LOAD T3,MPPOST ;GET POST ROUTINES ADDRESS
SKIPN T3 ;IS THERE A SPECIAL POST ROUTINE?
RET ;NO
CALL (T3) ;CALL THE POST ROUTINE
JRST [HRLZI T1,MPERR ;INDICATE TO JSYS LEVEL AN ERROR
IORM T1,PGMSTS(P1)
JRST .+1 ]
RET
;ROUTINE TO RELEASE A RESIDENT BUFFER FOR XMITTING OF MOP MSGS
RLXMOP: MOVEI T1,0
EXCH T1,PGMXHD(P1) ;NO LONGER EXPECTING INPUT
JUMPE T1,R ;RETURN IF NONE
HRRZS T1 ;FOR RELRES
LOAD T2,MPFLGS ;GET FLAGS
TRNN T2,MPSHRT ;SHORT MESSAGE?
CALL RELRES ;RELEASE THE RESIDENT BUFFER
RET
;ROUTINE TO RELEASE A RESIDENT BUFFER FOR RECV OF MOP MSGS
RELMOP: PIOFF
MOVEI T1,0
EXCH T1,PGMRHD(P1) ;ZERO POINTER TO BUFFER
HRRZS T1 ;FOR RELRES
SKIPE T1 ;NOTHING TO RELEASE
CALL RELRES ;NO, RELEASE RESIDENT BUFFER
PION
RET
;ONCE-A-SECOND ROUTINE FOR MOP
MOPSEC:
LOAD T1,MOPTMR
JUMPE T1,R ;TIMER NOT RUNNING; DON'T UPDATE
SOS T1 ;COUNT DOWN MOP TIMES
STOR T1,MOPTMR ;PUT BACK UPDATED
SKIPE T1 ;HAVE WE TIMED OUT?
RET ;NO, DON'T DO ANYTHING MORE
HRLZI T1,MPERR ;INDICATE A TIME-OUT ERROR
IORM T1,PGMSTS(P1) ;IN STATUS WORD
CALL RLXMOP ;RELEASE BUFFER SINCE NO LONGER EXPECT INPUT
RET
;SCHEDULER TEST TO SEE IF SOME MOP INPUT HAS COME IN
MPRTST: SKIPE PGMRHD(T1)
JRST 1(4) ;THERE IS ONE
MOVE T1,PGMSTS(T1) ;CHECK ERROR STATUS
TLNE T1,MPERR ;TEST FOR TIMEOUT
JRST 1(4) ;THERE IS AN ERROR, RE-SCHEDULE PROCESS
JRST 0(4) ;THERE IS NEITHER INPUT NOR ERROR CONDITION
MOPDNE:
MOVEI T1,PRITMO ;SPECIAL TIMEOUT DURING PRIMARY STAT
LOAD T2,MOPSTS ;GET THE MOP STATUS
CAIE T2,MPPRI ;IF IN PRIMARY USE LONGER TIMEOUT
MOVEI T1,MOPTMO ;TIME-OUT PERIOD
STOR T1,MOPTMR ;START COUNT-DOWN
JRST KMVCB9
;ROUTINE TO SHUFFLE THE DATA FOR THE KMC
;INPUTS ARE:
; T2/BYTE POINTER TO THE DATA
; T3/ NUMBER OF BYTES IN THE BUFFER
SECSHF:
PUSH P,T3 ;PRESERVE T3
MOVNI T4,(T3) ;NEGATE AND PREPARE FOR ROUNDING
LSH T4,^D16 ;ROUND AND PUT IN LH OF REG
HRR T4,T2 ;GET ADR OF MESSAGE
PUSH P,T2 ;SAVE ADDRESS OF MESSAGE
MOVE P3,T2 ;GET BYTE POINTER
ROT P3,6 ;POSITION POSITION FIELD
ANDI P3,77 ;GET POSITION OF 1ST BYTE IN WORD
MOVNS P3 ;MAKE NEGATIVE
SECSH0: MOVE T1,(T4) ;GET NEXT WORD FROM BUFFER
MOVE T2,1(T4) ;AND NEXT
LSH T1,^D36(P3) ;POSITION
LSH T2,4(P3) ;POSITION
IOR T1,T2 ;AND COMBINE
MOVE T2,T1 ;COPY BYTES
LSH T1,-^D20 ;POSITION
LSH T2,-4 ;POSITION
ANDI T1,177777
ANDI T2,177777
MOVSS T1
IOR T1,T2
MOVEM T1,(T4) ;SAVE SHUFFLED WORD
AOBJN T4,SECSH0 ;LOOP BACK FOR REST OF DATA
POP P,T2 ;RESTORE T2
POP P,T3
RET
SHFFLE:
PUSH P,T3 ;PRESERVE T3
MOVNI T4,(T3) ;NEGATE AND PREPARE FOR ROUNDING
LSH T4,^D16 ;ROUND AND PUT IN LH OF REG
HRR T4,T2 ;GET ADR OF MESSAGE
PUSH P,T2 ;SAVE ADDRESS OF MESSAGE
SHFFL0: 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,SHFFL0 ;LOOP BACK FOR REST OF DATA
POP P,T2
POP P,T3
RET
TNXEND
END