1
0
mirror of https://github.com/PDP-10/its.git synced 2026-02-02 06:51:04 +00:00
Files
PDP-10.its/src/system/ioelev.432

4947 lines
135 KiB
Plaintext
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
;;; -*-PALX-*-
;;; Copyright (c) 1999 Massachusetts Institute of Technology
;;; See the COPYING file at the top-level directory of this project.
.TITLE IOELEVEN
.SBTTL DEFINITIONS
;;; note that the .IFM macro must be used only at toplevel
;;; (non-conditionalized) in PALX because it doesn't do the expansion of .IFM
;;; when conditionalized out, therefore it doesn't match it with the
;;; following .ENDC and the .ENDC will be seen at toplevel and end the
;;; conditionalization one is in. This will screw the code running on
;;; another one of the machines even if it doesn't signal an error in your
;;; assembly. --PGS
.LIF NZ 0
.FATAL USE PALX DUMMY!!
;NOTE THAT THIS PROGRAM IS DESIGNED FOR 11/40'S. TO RUN ON AN
;11/10, MACRO OUT THE SOB INSTRUCTIONS. DOES NOT USE EIS NOR FIS.
A=%0 ;TEMP/ARG/CHAR
B=%1 ;TEMP/ARG
C=%2 ;TEMP/ARG
D=%3 ;TEMP/ARG
H=%4 ;USUALLY INDEX IN HARDWARE UNIT TABLES
I=%5 ;USUALLY LINE NUMBER TIMES 2
SP=%6 ;STACK POINTER
PC=%7 ;PROGRAM POINTER
PS=177776 ;PROGRAM STATUS
SWR=177570 ;SWITCHES
.MACRO RTI
.ENDM ;FUCKING PALX!
RTI=RTT ;11/40 HARDWARE MISFEATURE
.IF P1
.PRINT /MACHINE NAME = /
.TTYMAC MNAM
%TTYFLG==%TTYFLG+1
.PRINT /MNAM
/
%TTYFLG==%TTYFLG-1
.MACRO .IFM MCHN ;REFERS TO PDP11 NAME
.IF IDN MCHN,MNAM
.ENDM .IFM
.MACRO MCONDX MCHN ;REFERS TO ITS SYSTEM NAME, USUALLY THE SAME
.IF IDN MCHN,MNAM
.ENDM MCONDX
.MACRO FUBAR
.ENDC
.ENDC
.ENDM FUBAR
.MACRO MNAME BODY ;INSERT ITS SYSTEM NAME INTO BODY IN PLACE OF "MCHN"
.IRP MCHN,<MNAM>
BODY
.ENDM
.ENDM MNAME
.ENDM ;TTYMAC
.ENDC ;P1
VERSION==%FNAM2
.IFM MX-DL ;MX'S DL-10 PDP11
.MACRO MCONDX MCHN
.IF IDN MCHN,MX
.ENDM MCONDX
.MACRO FUBAR
.ENDC
.ENDM FUBAR
.MACRO MNAME BODY
.IRP MCHN,<MX>
BODY
.ENDM
.ENDM MNAME
DL10P==1 ;HAS DL10
DTE20P==0 ;DOES NOT HAVE DTE20
NODDT==0 ;HAS DDT
NFTTY==102 ;2 * # OF FIRST TTY THIS 11
NDHS==1 ;NUMBER OF DH11'S
NDHUN==15 ;NUMBER OF UNUSED DH11 LINES
DHIBAS==320 ;DH11 INTERRUPT VECTOR BASE
DHCBAS==160020 ;CSR of first DH11
NDLS==1 ;NUMBER OF DL11'S
CTYP==0 ;FIRST DL11 NOT T00 (CTY)
NMPTYS==0 ;NUMBER OF TTYS ON MULTIPLEXED LINE (REST IN PEACE)
;MPXIDX==2*27 ;TTY INDEX OF LINE THAT MULTIPLEXED TTYS RUN OVER
NDMS==0 ;HAS DM11BB MODEM SCANNER (BUT IT'S NOT CONNECTED TO ANYTHING)
GOULDP==0 ;DOESN'T HAVE GOULD LPT (ANYMORE)
T300P==1 ;TRIDENT T-300 AND 2561 CONTROLLER
CHAOSP==2 ;HAS TWO CHAOS NET INTERFACES
CHSBTB=0 ;CHAOSNET INTERFACE IS NEW, DOESN'T GET HUNG ANY MORE
CHAD0==440 ;CHAOSNET ADDRESS OF THIS PDP11 ITSELF
DLCADR==1440 ;CHAOSNET ADDRESS OF PDP10 CONNECTED VIA DL10 (MX)
CHAD1==3040 ;SECOND INTERFACE
TEN11P==0 ;NO TEN-11 INTERFACE
ETHERP==0 ;NO ETHERNET
FTPULS==0 ;INITIALLY, MX DOES NOT GENERATE TEST PACKETS
FTGARB==1 ;SAVE LAST GARBAGE PACKET RECEIVED
MAXBSZ==250. ;MAXIMUM TYPEOUT BUFFER SIZE
.MACRO ASPIRP BODY ;DEFINE LINE NUMBERS WITH AUTOSPEED
.ENDM ASPIRP
.ENDC ;MX-DL
.IFM MX ;MX CONSOLE 11
DL10P==0 ;DOES NOT HAVE DL10
DTE20P==1 ;HAS DTE20
NODDT==0 ;HAS DDT AND KLDCP
NFTTY==0 ;2 * # OF FIRST TTY THIS 11
NDHS==2 ;NUMBER OF DH11'S
NDHUN==0 ;NUMBER OF UNUSED DH11 LINES
DHIBAS==310 ;DH11 INTERRUPT VECTOR BASE
DHCBAS==160020 ;CSR of first DH11
NDLS==1 ;NUMBER OF DL11'S
CTYP==1 ;FIRST DL11 IS T00 (CTY)
NMPTYS==0 ;NUMBER OF TTYS THAT GO THROUGH MULTIPLEXED LINE (NONE)
NDMS==2 ;has 2 DM11BB modem scanners (really DH11AD)
GOULDP==0 ;DOESN'T HAVE GOULD LPT
T300P==0 ;TRIDENT T-300 AND 2561 CONTROLLER
CHAOSP==0 ;NO CHAOS NET INTERFACE
TEN11P==0 ;NO TEN-11 CHAOS INTERFACE
ETHERP==0 ;NO ETHERNET
MAXBSZ==250. ;MAXIMUM TYPEOUT BUFFER SIZE
.MACRO ASPIRP BODY ;DEFINE LINE #S WITH AUTOSPEED
.IRP N,<1,3,4,5,6,7,10,11,12,13,14,15,16,17>
BODY
.ENDM
.ENDM ASPIRP
TKS==177560
TKB==177562
TPS==177564
TPB==177566
.ENDC ;MX
.IFM AI ;AI'S CHAOS-ETHER-GATEWAY PDP11
;THIS IS A PDP11/10, WE HAVE TO REDEFINE A FEW THINGS
.MACRO RTT
.ENDM
RTI==2
RTT==2
.MACRO SOB REG,TAG
DEC REG
BNE TAG
.ENDM SOB
DL10P==0 ;HAS NO DL10
DTE20P==0 ;DOES NOT HAVE DTE20
NODDT==1 ;DOESN'T HAVE DDT (USE CARPET)
NFTTY==0 ;2 * # OF FIRST TTY THIS 11
NDHS==0 ;NUMBER OF DH11'S
NDHUN==0 ;NUMBER OF UNUSED DH11 LINES
DHIBAS==320 ;DH11 INTERRUPT VECTOR BASE
DHCBAS==160020 ;CSR of first DH11
NDLS==0 ;NUMBER OF DL11'S (ACTUALLY HAS ONE, BUT WE'RE NOT USING IT NOW)
CTYP==0 ;FIRST DL11 NOT T00 (CTY)
NMPTYS==0 ;NUMBER OF TTYS ON MULTIPLEXED LINE
NDMS==0 ;HAS NO DM11BB MODEM SCANNERS
GOULDP==0 ;DOESN'T HAVE GOULD LPT
T300P==0 ;TRIDENT T-300 AND 2561 CONTROLLER
CHAOSP==2 ;HAS TWO CHAOS NET INTERFACES
CHSBTB==0 ;CHAOSNET INTERFACE IS NEW-STYLE, DOES NOT GET HUNG
CHAD0==426 ;CHAOSNET ADDRESS OF THIS PDP11 ITSELF (AI-MC-CROSS-STREET SUBNET)
CHAD1==3072 ;SECOND INTERFACE (9TH FLOOR LISP MACHINE SUBNET)
CHADD==426 ;The DOVER protocol translator only works for this address
TEN11P==0 ;USES TEN-11 INTERFACE FOR CHAOS NET TO AI-10 (NOT ANY MORE!)
T11ADR==2026 ;CHAOSNET ADDRESS OF PDP10 CONNECTED VIA TEN-11 INTERFACE (AI)
NT11BF==3 ;THREE BUFFERS IN EACH DIRECTION FOR TEN-11 INTERFACE
ETHERP==1 ;ETHERNET
ETHHSN==6 ;MY HOST NUMBER BYTE, JNC SAYS I SHOULD USE 6
NDVRBF==6 ;6 DOVER BUFFERS
DVRADR==1002 ;PUP ADDRESS OF DOVER
FTPULS==0 ;INITIALLY, AI DOES NOT GENERATE TEST PACKETS
FTGARB==1 ;DON'T SAVE LAST GARBAGE PACKET RECEIVED (LOW ON CORE) (not that low)
MAXBSZ==250. ;MAXIMUM TYPEOUT BUFFER SIZE
.MACRO ASPIRP BODY ;DEFINE LINE NUMBERS WITH AUTOSPEED
.ENDM ASPIRP
.ENDC ;AI
.IIF NDF NDHS, .ERROR MACHINE NAME NOT RECOGNIZED
.IIF NZ DL10P, .IIF Z NFTTY, .ERROR TTY # 0 DOESN'T WORK WITH DL10 PROTOCOL
;ASSIGN TTY INDICES, HARDWARE INDICES, ETC.
TX==NFTTY ;TTY INDEX
HX==0 ;HARDWARE INDEX
NCT==0 ;NUMBER OF TTYS
;SYSTEM CONSOLE (OUT OF ORDER)
.IFNZ CTYP
TX==TX+2
NCT==NCT+1
.ENDC
;DH11 LINES
NFDHTY==TX
TX==TX+<32.*NDHS>
NCT==NCT+<16.*NDHS>
HX==HX+<2*NDHS>
NLDHHX==HX-2 ;UNITS 0-NLDHHX INCLUSIVE ARE DH11S
TX==TX-<2*NDHUN> ;COMPENSATE FOR UNUSED LINES
NLDHTY==TX-2 ;LAST DH11 LINE INCLUSIVE
NCT==NCT-NDHUN
;DL11 LINES
NFDLTY==TX
NFDLHX==HX
TX==TX+<2*NDLS>-<2*CTYP>
HX==HX+<2*NDLS>
NLDLHX==HX-2
NCT==NCT+NDLS-CTYP
;MULTIPLEXOR LINES
NFMPTY==TX
MPKHWR==HX
TX==TX+<2*NMPTYS>
HX==HX+2
NCT==NCT+NMPTYS
NLTTY==NFTTY+<2*NCT> ;2 * # OF FIRST TTY NOT THIS 11
LASTTY==NLTTY-2 ;LAST VALID TTY INDEX
.IFNZ NDMS ;DM11-BB MODEM SCANNER
;1.1-1.4 MODEM CHANNEL #
DMBSY==20 ;1.5 SCAN BUSY (R.O.)
DMSCN==40 ;1.6 SCANNER ON
DMIEN==100 ;1.7 INTERRUPT ENABLE
DMDON==200 ;1.8 DONE - SCANNER HAS FOUND SOMETHING
DMSTP==400 ;1.9 STEP SCANNER TO NEXT LINE (W.O.) 1.2 USEC.
;2.1 MAINTENANCE MODE
DMCLR==2000 ;2.2 CLEAR RTS, DTR, SEC TX, LINE EN FOR ALL LINES (W.O.)
DMCSN==4000 ;2.3 CLEAR SCAN - CLEAR CSR AND MODEM STATUS MEMORY (W.O.) 19 USEC
DM2RX==10000 ;2.4 SECONDARY RECIEVE CHANGED ON SELECTED MODEM (R.O.)
DMCTS==20000 ;2.5 CLEAR TO SEND CHANGED ON SELECTED MODEM (R.O.)
DMCAR==40000 ;2.6 CARRIER DETECT CHANGED ON SELECTED MODEM (R.O.)
DMRNG==100000 ;2.7 RING CHANGED ON SELECTED MODEM (R.O.)
LINENB==1 ;1.1 ENABLE SCANNING OF LINE
LINDTR==2 ;1.2 DATA TERMINAL READY
LINRQS==4 ;1.3 REQUEST TO SEND (FORCE BUSY ON 103E)
LIN2TX==10 ;1.4 SECONDARY TRANSMIT
LIN2RX==20 ;1.5 SECONDARY RECEIVE (R.O.)
LINCTS==40 ;1.6 CLEAR TO SEND (R.O.)
LINCAR==100 ;1.7 CARRIER DETECT (R.O.)
LINRNG==200 ;1.8 RING (R.O.)
.ENDC ;NDMS
; KW11-L LINE FREQ CLOCK
LKS=177546 ;1.8 CLOCK FLAG
;1.7 INTER ENB
HNGDLY==3*60. ;CLEAR TO SEND OFF FOR 3 SECONDS => HANGUP
.IFNZ GOULDP
;DEFINITIONS FOR GOULD LPT
GLPCSR=166000 ;COMMAND STATUS REGISTER (NONSTANDARD)
;COMMAND CODES
%GCFF==0 ;TOP-OF-FORM COMMAND
%GCGRF==1 ;GRAPHIC MODE COMMAND
%GCCUT==2 ;CUT COMMAND (NO CUTTER ON THIS MACHINE, THOUGH)
%GCON==3 ;TURN PRINTER ON
%GCOFF==4 ;TURN PRINTER OFF
%GCLSL==5 ;LAST LINE (GRAPHIC MODE). => 2 MORE SCAN LINES.
%GCION==6 ;INTERRUPT ON
%GCIOF==7 ;INTERRUPT OFF
%GCADV==201 ;ADVANCE ONE LINE
;STATUS BITS
%GSNRD==400 ;NOT READY
%GSDON==2000 ;TRANSFER COMPLETE
%GSBSY==4000 ;BUSY
%GSVAC==10000 ;VACUUM FAULT
%GSPAP==20000 ;PAPER LOW
%GSTIM==40000 ;TIMEOUT
%GSERR==50400 ;ALL ERROR BITS
GLPWC=166002 ;NEGATIVE WORD COUNT REG
GLPCA=166004 ;CURRENT ADDRESS REG
GLPBSZ==132. ;BUFFER SIZE (# CHARS PER LINE)
NGLPBF==7 ;NUMBER OF BUFFERS
GB.STA==0 ;BUFFER STATE - DON'T CHANGE ORDER OF %GB CODES
%GBIDL==0 ;0 IDLE
%GBMP==2 ;2 ACTIVE AT M.P. LEVEL
%GBWRT==4 ;4 IN WRITE QUEUE
%GBPI==6 ;6 ACTIVE AT P.I. LEVEL
%GBDMA==8 ;8 ACTIVE AT D.M.A. LEVEL
GB.NXT==2 ;CIRC POINTER TO NEXT BUFFER
GB.FF==4 ;IF NON-ZERO, FF BEFORE THIS BUFFER
GB.NL==6 ;NUMBER OF BLANK LINES BEFORE THIS BUFFER
GB.PNT==10 ;-> NEXT BYTE TO INSERT
GB.DAT==12 ;DATA BEGINS HERE
GB.LEN==GB.DAT+GLPBSZ ;TOTAL NUMBER OF BYTES PER BUFFER
.ENDC ;GOULDP
.IFNZ CHAOSP
;DEFINITIONS OF CHAOS NET HARDWARE
;USUAL ADDRESS IS 764140 . USUAL INTERRUPT VECTOR IS 270 .
CAICSR=164140 ;COMMAND STATUS REG
CH%CSR==0
%CABSY==1 ;0 XMT BUSY (RO)
%CALUP==2 ;1 LOOP BACK (R/W)
%CASPY==4 ;2 RECIEVE MSGS FOR ANY DESTINATION (R/W)
%CARCL==10 ;3 CLEAR THE RECEIVER, IT CAN NOW GOBBLE ANOTHER MSG (WO)
%CAREN==20 ;4 RCV INT ENB (R/W)
%CATEN==40 ;5 XMT INT ENB (R/W)
%CATAB==100 ;6 TRANSMIT ABORTED BY ETHER CONFLICT (RO)
%CATDN==200 ;7 TRANSMIT DONE. SET WHEN TRANSMITTER IS DONE
%CATCL==400 ;8 CLEAR THE TRANSMITTER, MAKING IT READY (WO)
;9-12 LOST COUNT (RO) [# MSGS RCVED WITH RCV BFR FULL]
; WHEN MSG IS WAITING IN BUFFER, THIS COUNTS
; THE MESSAGES THAT MATCHED OUR DESTINATION OR
; WERE BROADCAST, BUT COULDN'T BE RECIEVED.
; WHEN RECEIVER IS RE-ENABLED (WRITE 1 INTO %CARDN)
; THE COUNT IS THEN CLEARED.
; WHEN A MESSAGE IS LOST, RECEIVER ZAPS ETHER
; SO TRANSMITTER WILL ABORT (IF MESSAGE WAS DESTINED
; TO US.)
%CARST==20000 ;13 I/O RESET (WO)
%CAERR==40000 ;14 CRC ERROR (RO)
%CARDN==100000 ;15 RCV DONE.
CAIMYN=164142 ;MY # (READ ONLY)
CH%MYN==2 ;RETURNS THE [SOURCE] HOST# OF THIS INTERFACE.
CAIWBF=164142 ;WRITE BUFFER (WRITE ONLY)
CH%WBF==2 ;FIRST WAIT FOR TDONE. (OR SET IT VIA CSR)
;FIRST WORD IN RESETS TRANSMITTER AND CLEARS TDONE.
;STORE INTO THIS REGISTER TO WRITE WORDS OF MESSAGE,
;LAST WORD IN IS DESTINATION ADDRESS, THEN READ CAIXMT.
;SOURCE ADDRESS AND CHECK WORD PUT IN BY HARDWARE.
CAIRBF=164144 ;READ BUFFER (READ ONLY)
CH%RBF==4 ;THE FIRST WORD READ WILL BE FILLED TO THE LEFT
;TO MAKE THE MESSAGE RECIEVED A MULTIPLE OF 16 BITS.
;IF THE NUMBER OF DATA BITS IN THE MESSAGE WAS A
;MULTIPLE OF 16, THIS WORD WILL BE THE FIRST WORD PUT
;INTO THE BUFFER BY THE TRANSMITTING HOST.
;THE LAST 3 WORDS READ ARE DESTINATION, SOURCE, CHECK.
CAIRBC=164146 ;RECEIVE BIT COUNTER (READ ONLY)
CH%RBC==6 ;WHEN A MESSAGE HAS BEEN RECEIVED THIS IS ONE LESS THAN
;THE NUMBER OF BITS IN THE MESSAGE (16 X THE
;NUMBER OF WORDS INCLUDING THE THREE OVERHEAD WORDS.)
;AFTER THE LAST WORD (THE CRC WORD) HAS BEEN READ, IT IS 7777
;BITS 10 AND 11 ARE THE HIGH ORDER BITS, AND IF THEY ARE ONE,
;THEN THERE WAS A BUFFER OVERFLOW
CAIXMT=164152 ;READING THIS INITIATES TRANSMISSION (!!)
CH%XMT==12 ;THE VALUE READ IS ONE'S OWN HOST#.
;REFERENCING ADDRESSES IN THE GROUP OF 8 WORDS NOT LISTED HERE, OR
;USING COMBINATIONS OF READ/WRITE NOT LISTED HERE, WILL TYPICALLY CAUSE
;STRANGE AND BIZARRE EFFECTS.
;PACKET DEFINITIONS
;THESE ARE FOR 4K PACKET BUFFERS AND FOR THE ORIGINAL CHAOSNET PROTOCOL
PKMAX==256. ;MAXIMUM LENGTH OF PACKET (INCLUDING ALL HARDWARE WORDS)
DATMAX==488. ;MAXIMUM NUMBER OF DATA BYTES
PKHDW==8 ;NUMBER OF HEADER WORDS
PKTMXW==<DATMAX/2>+PKHDW ;MAX WORDS THROUGH PACKET SWITCH (SEE MOVDH ETC.)
PKOP==1 ;BYTE INDEX OF THE OPCODE OF THE PACKET
%CORFC==1
%COOPN==2
%COCLS==3
%COANS==5
%COSNS==6
%COSTS==7
%CORUT==10
%COLOS==11
%COEOF==14
%COUNC==15
PKNBYT==2 ;WORD INDEX OF NUMBER OF BYTES IN PACKET
PKNBMS==170000 ;MASK FOR THE NUMBER OF BYTES
PKFC==2 ;WORD INDEX FOR THE FORWARD COUNT
PKFCMS==7777 ;IT IS THE TOP 4 BITS
PKDHST==4 ;DESTINATION HOST
PKDIND==6 ; " " " INDEX
PKSHST==10 ;SOURCE HOST
PKSIND==12 ;SOURCE INDEX
PKPKN==14 ;THE PACKET NUMBER
PKACN==16 ;THE ACK PACKET NUMBER
PKDAT==20 ;THE START OF THE DATA
.ENDC ;CHAOSP
;STANDARD MACROS
.MACRO PUSH X
.IRP Y,<X>
MOV Y,-(SP)
.ENDM
.ENDM
.MACRO POP X
.IRP Y,<X>
MOV (SP)+,Y
.ENDM
.ENDM
.MACRO CALL X
JSR PC,X
.ENDM
.MACRO RET
RTS PC
.ENDM
.MACRO SETOM LOC
ZZ===%COMPAT ;DON'T CARE WHETHER .+2 OR .+4 GETS STORED
%COMPAT===0
MOV PC,LOC
%COMPAT===ZZ
.ENDM
.MACRO MASK LEVEL
PUSH PS
MOV #<LEVEL>_5,PS
.ENDM
.MACRO UNMASK
POP PS
.ENDM
.MACRO W
.=.+2
.ENDM
.MACRO T TAG ;usage is T TAG: <crlf> STMNT
.=.-NFTTY
TAG
.=.+NFTTY
.ENDM
.MACRO CONC A,B,C,D,E,F,G
A'B'C'D'E'F'G
.ENDM
.MACRO INFORM A,B,C,D,E,F,G
.IF P1
.PRINT /A'B'C'D'E'F'G
/
.ENDC
.ENDM
.MACRO MSG X
.NCHR ZZ,^\X\
.WORD ZZ
.ASCII \X\
.EVEN
.ENDM
.MACRO .IREPT N,BOD
.REPT N
BOD
.ENDR
.ENDM
.IFNZ DL10P
.SBTTL DL10 CONTROL AREA
ZZ==.
.=100000
DLXCSR: W ;DL10 11-SIDE CONTROL & STATUS REG
;1.1-1.2 PIA
DLXIEN==4 ;1.3 ENABLE DLX11I TO INTERRUPT
DLXEEN==10 ;1.4 ENABLE ERRORS TO INTERRUPT
;1.5 UNUSED
DLXPRT==40 ;1.6 PORT ENABLE (R.O.)
DLXZWC==100 ;1.7 CLEAR DLXWCO (W.O.)
DLXWCO==200 ;1.8 WORD COUNT OVERFLOW
DLXZPA==400 ;1.9 CLEAR DLXPAR (W.O.)
DLXPAR==1000 ;2.1 PAR ERR IN 10 MEM
DLXZNX==2000 ;2.2 CLEAR DLXNXM (W.O.)
DLXNXM==4000 ;2.3 NXM IN 10 MEM
DLXZ10==10000 ;2.4 CLEAR DLX10I (W.O.)
DLX10I==20000 ;2.5 INTERRUPT PDP10
DLXZ11==40000 ;2.6 CLEAR DLX11I (W.O.)
DLX11I==100000 ;2.7 INTERRUPT PDP11
VERS: W ;.BYTE FIRST LINE, # OF LINES
;SET BY -10. USED TO CHECK CONSISTENCY.
DLXUP: W ;CHECK FOR UP-NESS IN BOTH DIRECTIONS
;INCREMENTED BY 11 EVERY 1/60 SECOND, SETOM'ED BY 10 EVERY 1/2 SEC.
TTYST: W ;LINE# TO START OUTPUT ON (I.E. SET OUTPUT DONE)
;SET BY 10, CLEARED BY 11
TYILIN: W ;TYPEIN STATUS WORD - LINE NUMBER
;SET BY 11, CLEARED BY 10 - INTERRUPTS 10
TYICHR: W ;TYPEIN CHARACTER - GOES WITH PRECEDING WORD
TYOSTS: W ;STATUS WORD (OUTPUT DONE LINE #)
;SET BY 11, CLEARED BY 10 - INTERRUPTS 10
TYOBSZ: W ;BUFFER SIZE FOR LINE WITH OUTPUT DINE (SET BY 11)
TYOPNT: W ;BUFFER POINTER FOR TTY OUTPUT
;SET BY 10
TYOCNT: W ;BUFFER LENGTH FOR TTY OUTPUT
;SET BY 10
TYOLIN: W ;LINE NUMBER FOR TTY OUTPUT
;SET BY 10, CLEARED BY 11
HNGLIN: W ;0000NN - LINE # NN HUNG UP
;01RTNN - LINE # NN HAS SPEED RCV=R, XMT=T (SEE TTYTYP FOR CODES)
;SET BY 11, CLEARED BY 10 - INTERRUPTS 10
LPRLIN: W ;LINE NUMBER FOR SETTING LINE PARAMETERS
;SET BY 10, CLEARED BY 11
LPRLPR: W ;DH11 LPR REGISTER FOR SETTING LINE PARAMETERS
;SET BY 10
LPRBSZ: W ;BUFFER SIZE FOR SETTING LINE PARAMETERS
;SET BY 10
EXDSTS: W ;STATUS WORD (EXAMINE/DEPOSIT 11 CORE)
;1 = EXAMINE, 2 = DEPOSIT
;SET BY 10, CLEARED BY 11
EXDADR: W ;ADDRESS FOR ABOVE
;SET BY 10
EXDDAT: W ;DATA WORD FOR ABOVE
;SET BY 10 (DEPOSIT) OR 11 (EXAMINE)
GLPPTR: W ;BUFFER POINTER FOR GOULD OUTPUT
GLPCTR: W ;NUMBER OF BYTES YET TO BE GOBBLED
GLPTER: W ;ERROR STATUS, SET BY 11
GLPGRF: W ;GRAPHIC MODE IF NON-ZERO, SET BY 10
;CHAOS NET SHARED VARIABLES
DLCINI: W ;WHEN THIS IS NON-ZERO, 11 RESETS ITS POINTERS AND CLEARS IT
DLCSP1: W ;SEND PACKET 1 (ILDB POINTER)
DLCSP2: W ;SEND PACKET 2
DLCSS1: W ;SEND STATE 1 (0 IDLE, 1 TO 11, 2 OUTPUT DONE)
DLCSS2: W ;SEND STATE 2
DLCRP1: W ;RECEIVE PACKET 1 (ILDB POINTER)
DLCRP2: W ;RECEIVE PACKET 2
DLCRS1: W ;RECEIVE STATE 1 (0 IDLE, 1 READY FOR INPUT FROM 11, 2 INPUT DONE)
DLCRS2: W ;RECEIVE STATE 2
;^ ADD MORE HERE, E.G. IMP
.IFNZ T300P
;DISK AREA. 14. WORDS 48. WORDS INTO THE DL-10 AREA.
.=100000+<60*2>
DSCCHK: W ;MUST BE 2561 OCTAL TO MAKE SURE WE HAVE CORRECT PDP-10 PROGRAM
DSCREQ: W ;0 MEANS NO REQUEST. NON-ZERO MEANS 10 HAS PENDING REQUEST TO 11.
DSCDON: W ;0 MEANS NOT DONE, NON-ZERO MEANS 11 IS TELLING 10 IT'S DONE.
;NEXT 2 WORDS WRITTEN BY 11 TO TELL STATUS OF OPERATION
DSCFLT: W ;0 NO FAULT
%DFRST==100000 ; BIT 15=POWER CYCLED OR UNIBUS HUNG, SO CONTROLLER WAS RESET
; BIT 12=Q ERROR, BIT 11=CMD NXM, BIT 10=CMD PAR
; IF ONE OF THESE BITS IS ON, BITS 1-0 AND DSCSTS ARE THE ERROR ADDRESS
; BITS 7-0 SYSTEM FAULT CODE IF LEFT BYTE IS ZERO
; SEE THE 2561 OEM MANUAL FOR MEANING OF FAULT CODES
DSCSTS: W ;STATUS FROM 2561:
%DSRTR==100000 ;COMMAND WAS RETRIED
%DSECH==40000 ;UNCORRECTABLE DATA ERROR (ECC HARD)
%DSECC==20000 ;CORRECTED DATA ERROR
%DSIDE==10000 ;ID ERROR
%DSHCE==4000 ;ADDRESS ERROR (HEADER COMPARE ERROR)
%DSPRT==2000 ;WRITE-PROTECT STATUS OF SECTOR (ABORTS WRITE COMMAND)
%DSALT==1000 ;ALTERNATE-SECTOR STATUS (ABORTS READ, WRITE, AND CHECK)
%DSOVR==400 ;FIFO OVER-RUN, NOT CORRECTED BY 1 RETRY
%DSSKE==200 ;SEEK ERROR FROM DRIVE
%DSOFL==100 ;DRIVE OFF-LINE OR FAULT
%DSFLT==20 ;DRIVE FAULT
%DSNXM==10 ;NXM ON PDP11 MEMORY
%DSPAR==4 ;PARITY ERROR IN PDP11 MEMORY
%DSSFL==2 ;SYSTEM FAULT, SEE LOW BYTE OF DSCFLT
%DSWLK==1 ;DRIVE WRITE-LOCKED, WRITE ABORTED
;FOLLOWING WORDS ARE WRITTEN BY 10 TO TELL WHAT TO DO
DSCCMD: W ;COMMAND OPCODE:
;%DMNOP==0 ;DO NOTHING
;%DMCST==1 ;READ OUT CONTROLLER STATE (NOT USEFUL SINCE NOT RETURNED TO 10)
%DMSNS==2 ;SENSE DRIVE STATE. DSCSTS GETS CODE FOR DRIVE TYPE IN
; BITS 14-8 (10 FOR T-300), AND %DSWLK, %DSFLT, %DSOFL, %DSSKE
%DMTST==3 ;TEST SPECIFIED DRIVE (RUNS DIAGNOSTICS)
%DMREC==4 ;RECALIBRATE
%DMSEK==5 ;SEEK
%DMWRT==6 ;WRITE DATA
;%DMFMT==7 ;WRITE FORMAT
;%DMPWT==10 ;WRITE AND SET WRITE-PROTECT BIT
;%DMAWT==11 ;WRITE AND SET ALTERNATE-SECTOR BIT
;%DMCHK==12 ;READ AND CHECK ECC BUT DON'T STORE DATA
;%DMLWT==14 ;LONG WRITE, WILL WRITE ECC AS WELL AS DATA
%DMRED==20 ;READ DATA. ADD 1-10 FOR VARIOUS RECOVERY FEATURES AS
; DOCUMENTED IN THE 2561 OEM MANUAL.
;%DMRID==40 ;READ IF FIELD, NOT USEFUL SINCE NOT RETURNED TO 10
DSCDRV: W ;UNIT NUMBER
DSCCYL: W ;CYLINDER ADDRESS (THESE ARE COPIED BACK BY THE 11 IN CASE OF ERROR)
DSCHED: W ;HEAD ADDRESS
DSCSEC: W ;SECTOR ADDRESS
;WORD COUNT IS ALWAYS 12.*256.
;IF WE PUT IN SEEK-OVERLAP AN ATTENTION FEATURE WILL BE NEEDED
;THAT WOULD ALSO BE USED FOR DISK POWER-UP SIGNALLING
;THESE WORDS ARE SET UP BY THE 10 AS BYTE-POINTERS TO THE DATA
;TO BE TRANSFERRED. EACH BYTE POINTER CAN TRANSFER AT MOST 256 PDP10 WORDS
;DUE TO BRAIN-DAMAGE IN THE DL10, SO THERE ARE 4 OF THEM
DSCPNT: .BLKW 4
.ENDC ;T300P
DLXHGH::
.=ZZ
.ENDC ;DL10P
.IFNZ DTE20P
.SBTTL DTE20 CONTROL AREA
;LOCATIONS 400-437 ARE JUST BETWEEN US AND ITS
;LOCATIONS 440-457 ARE KNOWN ABOUT BY KLDCP ALSO
;EPTDDT==441 ;START ADDRESS OF PDP10 NON TIME SHARING DDT
DTEFLG==444 ;NON TIME SHARING TYPEIN/TYPEOUT DONE FLAG (SET BY 11, CLEARED BY 10)
DTEF11==450 ;USED BY NON TIMESHARING TYPEIN COMMAND TO RETURN THE CHAR (SET BY 11)
DTECMD==451 ;NON TIME SHARING COMMAND (SET BY 10)
;COMMANDS THAT CAN GO IN DTECMD:
;0-377 CHAR TO BE TYPED OUT
%DTTYI==3400 ;TYPE IN, CHAR RETURNED IN DTEF11
%DTCLN==1001 ;60 CYCLE CLOCK ON
%DTCLF==1000 ;60 CYCLE CLOCK OFF
;THERE ARE MILLIONS OF OTHERS, BUT WHO NEEDS 'EM?
DTECLK==445 ;60 CYCLE CLOCK FLAG (SET BY 11, CLEARED BY 10)
;DTESWR==457 ;SIMULATED SWITCH REGISTER (SET BY 11)
;THE FOLLOWING LOCATIONS ARE ONLY USED IN TIME SHARING AND NOT KNOWN ABOUT BY KLDCP
DTEVER==400 ;I/O VERSION NUMBER. .BYTE FIRST LINE, NUMBER OF LINES.
;SET BY 10, CHECKED BY 11
DTECHK==401 ;INCREMENTED BY 11 60 TIMES PER SECOND, SETOMED BY 10 EVERY 1/2 SECOND
;USED TO CHECK THAT 10 IS GETTING INTERRUPTS OK
DTEINP==402 ;CONTROLS "BYTE TRANSFERS" FROM 11 TO 10 (INPUT DIRECTION).
;SET BY 10 TO REQUEST A TRANSFER, SETOM'ED BY 11 WHEN XFER COMPLETE.
;10 SHOULD SET UP DTEBPI IN EPT AND DO DATAO DTE, BEFORE SETTING DTEINP.
;SEE COMMENTS BELOW DTEOUT FOR WHAT GOES IN DTEINP.
DTEOUT==403 ;CONTROLS "BYTE TRANSFERS" FROM 10 TO 11 (OUTPUT DIRECTION).
;SET BY 10 TO REQUEST A TRANSFER, SETOM'ED BY 11 WHEN TRANSFER STARTS.
;EACH SIDE KNOWS WHEN TRANSFER IS IN PROGRESS, DOESN'T TRY TO START
; ANOTHER UNTIL IT HAS RECEIVED HARDWARE TRANSFER-DONE INTERRUPT.
;10 SHOULD SET UP DTEBPO IN EPT BEFORE SETTING DTEOUT.
;RH IS #BYTES EXPECTED, LH IS COMMAND+LINE#. COMMANDS ARE:
%DTTYO==1000 ;TELETYPE OUTPUT
;%DTETI==2000 ;ETHERNET INPUT
;%DTETO==3000 ;ETHERNET OUTPUT
;^ ADD MORE COMMANDS HERE. NOTE: THE 4.1 BIT IS 1 FOR OUTPUT, 0 FOR INPUT.
DTELSP==404 ;LINE# TO SET SPEED OF (SET BY 10, SETOMED BY 11)
DTELPR==405 ;DH11 LINE-PARAMETER-REGISTER,,BUFFER SIZE
DTEOST==406 ;LINE# TO START OUTPUT ON (SET OUTPUT DONE). (SET BY 10, SETOMED BY 11)
;407 NOT USED
DTETYI==410 ;TELETYPE INPUT
;LH=LINE#, RH=CHAR RECEIVED. (SET BY 11, SETOM'ED BY 10)
DTEODN==411 ;TELETYPE OUTPUT DONE
;LH=LINE#, RH=BUFFER SIZE. (SET BY 11, SETOM'ED BY 10)
DTEHNG==412 ;HANGUP/DIALIN WORD (SET BY 11, SETOM'ED BY 10)
;0000NN - LINE # NN HUNG UP
;01RTNN - LINE # NN HAS SPEED RCV=R, XMT=T (SEE TTYTYP FOR CODES)
;^ ADD MORE HERE, NOT TO EXCEED LOCATION 437
;.IFNZ DTE20P
;IOELEVEN RESIDES IN THE BOTTOM 14K OF THE CONSOLE PDP11, ALONG WITH 11DDT.
;I.E. LOCATIONS 0-70000. BE SURE TO USE .;11DDT 14K VERSION OF DDT.
;THE UPPER 14K CONTAIN KLDCP. THE FOLLOWING CALLS TO KLDCP ARE USED.
;THEY RETURN WITH C-BIT SET IF THEY LOSE (MICROCODE HUNG).
;NOTE: KLDCP ENJOYS CLOBBERING REGISTER 0 (A). I DON'T
;KNOW IF ALL THESE CALLS DO, BUT WE'LL ASSUME THAT THEY DO.
TENSW=EMT!145 ;UPDATE LOCATION DTESWR FROM THE SWITCHES
EXAM=EMT!103 ;EXAMINE PDP10 MEMORY
;BEFORE CALL, REGISTER A HAS ADDRESS OF 3 BYTES CONTAINING PDP10 ADDRESS (LOW BITS FIRST)
;AFTER CALL, REGISTER A HAS ADDRESS OF 3 WORDS CONTAINING CONTENTS (LOW BITS FIRST)
EXAMT=EMT!104 ;EXAMINE PDP10 MEMORY
;.WORD PDP10-ADDRESS
;.WORD ADDRESS OF 3-WORD DATA BLOCK
DPOS=EMT!105 ;DEPOSIT PDP10 MEMORY
;BEFORE CALL, REGISTER A HAS ADDRESS OF 3 WORDS CONTAINING CONTENTS
;AND REGISTER B HAS ADDRESS OF 3 BYTES CONTAINING ADDRESS
DPOST=EMT!106 ;DEPOSIT PDP10 MEMORY
;.WORD PDP10-ADDRESS
;.WORD ADDRESS OF 3-WORD DATA BLOCK
D10MON=EMT!111 ;DEPOSIT PDP10 MEMORY, -1
;.WORD PDP10-ADDRESS
$PMSG=EMT!25 ;PRINT MESSAGE ON TTY
;.WORD ADDRESS OF ASCIZ MESSAGE
$CNTLC=100004 ;JUMP HERE TO "CONTROL C" BACK TO KLDCP
;WHEN KLDCP IS IDLE, AND IN "ITS MODE", IT DOES JSR PC,3000
;WHICH CALLS IOELEVEN'S MAIN PROGRAM. RETURN WITH "C" SET
;TO READ AND EXECUTE ONE KLDCP COMMAND LINE. RETURN WITH "C"
;CLEAR TO PRINT KL10 HALTED OR CLOCK ERROR STOP MESSAGE.
;LOCATIONS 3004, 3006 MUST CONTAIN .RAD50/IOELEV/
;IOELEV WILL RUN ON KLDCP'S STACK.
;.IFNZ DTE20P
;INFORMATION ABOUT THE DTE20.
;EXCEPT FOR BYTE TRANSFER, WE USE THE TIME-TESTED SUBROUTINES PROVIDED BY KLDCP.
;THE INTERRUPT VECTOR IS AT 774, BUT WE CAN'T USE IT BECAUSE WOULD HAVE
;TO COORDINATE THINGS WITH KLDCP, WHICH IS OBVIOUSLY IMPOSSIBLE.
DLYCNT=174400 ;2.6-2.7 UNIBUS ADDRESS EXTENSION FOR BYTE TRANSFER DMA
;1.1-2.5 14-BIT 2'S COMPLEMENT OF NUMBER OF HALF-MICROSECONDS
; TO DELAY BETWEEN PI0 INTERRUPTS IN BYTE TRANSFER
TO10AD=174420 ;ADDRESS (WORD OR BYTE) OF TO-10 BYTE TRANSFER DATA
TO10BC=174414 ;1.1-2.3 NEGATIVE BYTE COUNT, 2.7 LAST XFER
;NORMALLY SET BY 10 WITH DATAO DTE,
;TO10 XFER STARTS WHEN BOTH TO10AD AND TO10BC HAVE BEEN LOADED
TO11AD=174422 ;ADDRESS (WORD OR BYTE) OF TO-11 BYTE TRANSFER DATA
TO11BC=174416 ;1.1-2.3 NEGATIVE BYTE COUNT FOR TO-11 BYTE TRANSFER
;2.5=1 => TO-11 TRANSFER IS 8-BIT BYTES, =0 => 16-BIT WORDS
;2.6=1 => "ASCIZ" MODE (WHICH WE DON'T USE, OF COURSE)
;2.7=1 => LAST XFER, UPON COMPLETION INTERRUPT BOTH 10 AND 11
; =0 => ONLY INTERRUPT 11. 11 CAN CHANGE TO11AD, TO11BC, CONTINUE.
;TO11 XFER STARTS WHEN BOTH TO11AD AND TO11BC HAVE BEEN LOADED
;THE TRANSFER HAPPENS USING DMA (NPR) IN 11, PI LEVEL 0 IN 10.
STATUS=174434 ;DTE20 STATUS REGISTER
;READS:
%STDNI==100000 ;2.7 TO10 XFER DONE WITHOUT ERROR
%STERI==20000 ;2.5 TO10 XFER ABORTED BY ERROR
;2.4 DATA OUT OF DTE RAM IS ALL ZERO (MAINT)
%STINV==4000 ;2.3 PDP10 IS INTERRUPTING PDP11
;2.2 DEPOST OR EXAMINE WORD ONE (MAINT)
;2.1 PDP11 MEMORY PARITY ERROR IN TO10 XFER
;1.9 PDP11 IS INTERRUPTING PDP10
%STDNO==200 ;1.8 TO11 XFER DONE WITHOUT ERROR
;1.7 E BUFFER SELECT (MAINT)
;1.6 TO11 XFER STOPPED DUE TO ZERO BYTE (IN ASCIZ MODE)
;1.5 TO11 XFER OR PDP10 EXAMINE ENCOUNTERED EBUS PARITY ERROR
;1.4 1 => RESTRICTED MODE
;1.3 0 => EXAMINE/DEPOSIT IN PROGRESS, 1 => DONE
%STERO==2 ;1.2 TO11 XFER ABORTED BY ERROR
;1.1 1 => DTE ENABLED TO INTERRUPT PDP11
;WRITES:
%STCLI==51000 ;2.6+2.4+2.1 CLEAR TO10 XFER DONE AND ERROR FLAGS
%STUNV==2000 ;2.2 CLEAR PDP10 INTERRUPTING PDP11
%STINX==400 ;1.9 SET PDP11 INTERRUPTING PDP10
%STCLO==121 ;1.7+1.5+1.1 CLEAR TO11 XFER DONE AND ERROR FLAGS
;1.6 ENABLE INTERRUPTS
;1.4 DISABLE INTERRUPTS
DIAG1=174430 ;DIAGNOSTIC WORD 1, INCLUDES FLAGS
%D1ERR==4000 ;2.3 KL10 CLOCK ERROR STOP
%D1RUN==2000 ;2.2 KL10 RUN INDICATOR (1 IF 11 WANTS 10 TO RUN)
%D1HLT==1000 ;2.1 KL10 HALT INDICATOR (1 IF 10 DOES A JRST 4)
DIAG3=174436 ;DIAGNOSTIC WORD 3, INCLUDES FLAGS
%D3BYT==1 ;1.1 WRITING 0 SETS TO10 XFER IN WORD MODE, 1 BYTE MODE
;THERE'S NOTHING ELSE OF THE SLIGHTEST USE IN THIS REGISTER,
;SO IT'S OK TO WRITE IT AT ANY TIME.
.ENDC ;DTE20P
.SBTTL LOW CORE
.IFZ DTE20P ;IF USING DTE20, THESE ARE SET UP BY KLDCP
.=4
TRAP4
340
TRAP10
340
; TRAP14 ;SET UP BY 11DDT
; 340
.=20
TRAP10 ;IOT
340
PWRFAL
340
TRAP10 ;EMT
340
TRAP10 ;TRAP
340
.ENDC ;DTE20P
;CHAOS NET INTERRUPT VECTORS ARE UNFORTUNATELY NOT IN A REASONABLE ARRAY
.IFGE CHAOSP-1
.=270
.WORD CHS0BK,5_5
;274 IS INTERVAL TIMER
.ENDC ;CHAOSP-1
.IFGE CHAOSP-2
.=230
.WORD CHS1BK,5_5
;234 IS INTERVAL TIMER
.ENDC ;CHAOSP-2
.IFGE CHAOSP-3
.=240
.WORD CHS2BK,5_5
;244 IS INTERVAL TIMER
.ENDC ;CHAOSP-3
.IFGE CHAOSP-4
.ERROR WHERE DOES THE FOURTH CHAOSNET INTERRUPT VECTOR GO?
.ENDC ;CHAOSP-4
.IFNZ ETHERP
.=400
ETHOBK
5_5
ETHIBK
5_5
ETHOBK ;COLLISION
5_5
.ENDC ;ETHERP
.IFNZ T300P
.=254
DSKBRK
240 ;BR5
.ENDC ;T300P
.=300
.REPT NDMS ;DM11s go in floating vectors
CONC DM,\.RPCNT+1,BRK
240 ;INTERRUPTS ON BR4 BUT WE MASK TO BR5 ANYWAY
.ENDR ;NDMS
.IFNZ NDLS
.=60
DL1IBK ;FIRST DL11 LINE IS PDP11'S CONSOLE TTY, DIFFERENT ADDRESS
240 ;AGAIN INTERRUPTS ON BR4 BUT MASK TO BR5 SO CAN USE DH11 ROUTINES W/O FEAR
DL1OBK
240
.ENDC ;NDLS
.=310
.REPT NDLS-1 ;DL11S AFTER THE FIRST ARE IN FLOATING VECTORS
CONC DL,\.RPCNT+2,IBK
240
CONC DL,\.RPCNT+2,OBK
240
.ENDR
.=DHIBAS ;DON'T RELY ON RANDOM FLOATING VECTOR TO
;COME OUT RIGHT, E.G. IF THERE IS A DL11
;THERE WHICH WE AREN'T USING.
.REPT NDHS ;DH11S ARE IN FLOATING VECTOR AFTER DL11[E]S
CONC DH,\.RPCNT+1,IBK ;DH11 #n RECEIVE
240
CONC DH,\.RPCNT+1,OBK ;DH11 #n TRANSMIT & ERROR
240
.ENDR ;NDHS
.=100
CLKBRK ;KW11-L 60-CYCLE CLOCK
300 ;ON BR6
.IFNZ GOULDP
.=174
GLPBRK
300 ;BR5 BUT NEED TO LOCK OUT CLOCK SO MASK 6
.ENDC ;GOULDP
.IFG NMPTYS
.=56
MPXENB::0 ;NONZERO TO ENABLE MULTISCHLUNKER
.ENDC
.IFZ DTE20P ;IF DTE20, KLDCP SUPPLIES THE STACK
.=1000
STKBAS::
JMP INIT ;START AT 1000 IS CONVENTIONAL
.IFF ;DTE20P
.=3000 ;ENTRY VECTOR
JMP @#INIT
SADR=.-2 ;ARG OF THE JMP@# IS CHANGED AFTER INITIALIZATION
.RAD50 /IOELEV/
.ENDC ;DTE20P
.SBTTL TEN-11 CHAOSNET COMMUNICATION AREA
.IFNZ TEN11P
T11BFL==8+<2*PKTMXW> ;BYTE LENGTH OF A PACKET BUFFER
;FIRST 8 BYTES ARE BUFFER-FULL FLAG AND CKSM
.IIF NE T11BFL-<<T11BFL/4>*4>, .ERROR T11BFL NOT MULTIPLE OF 4
.IIF NE .-1004, .ERROR CHAOSNET TEN-11 COMMUNICATION AREA NOT AT RIGHT ADDRESS
;THIS AREA IS SHARED WITH THE PDP10 VIA TEN-11 INTERFACE.
.WORD "CH,1 ;ERROR CHECK AND VERSION NUMBER
T11I10: .WORD 0,0 ;SET NON-ZERO BY 11 TO REINITIALIZE 10
T11I11: .WORD 0,0 ;SET NON-ZERO BY 10 TO REINITIALIZE 11
.WORD T11BFL,NT11BF ;BUFFER SIZE, NUMBER OF BUFFERS
.BLKW 8 ;SPARE WORDS
T11OBF: .BLKB T11BFL*NT11BF ;TO-10 BUFFERS
T11OBE==. ;END OF TO-10 BUFFERS
T11IBF: .BLKB T11BFL*NT11BF ;FROM-10 BUFFERS
T11IBE==. ;END OF FROM-10 BUFFERS
;THE FIRST 32-BIT WORD OF A BUFFER IS 0 IF IDLE, OR
;NON-ZERO IF BUFFER IS TO BE SENT TO OTHER MACHINE.
;THE SECOND 32-BIT WORD IS THE CHECKSUM, WHICH IS
;COMPUTED BY ADDING ALL THE 32-BIT WORDS, IGNORING OVERFLOW,
; AND LOGICALLY SHIFTING RIGHT ONE BIT AFTER EACH ADD; BITS SHIFTED
; OUT ON THE RIGHT ARE BROUGHT BACK IN ON THE LEFT.
;IF THE NUMBER OF 16-BIT WORDS IS ODD, THE LEFT-OVER ONE BETTER BE 0.
.ENDC ;TEN11P
.SBTTL CONFIGURATION
; TABLES INDEXED BY H (PER HARDWARE UNIT)
.MACRO DHTE AD ;DH11 REGISTER ADDRESS GENERATOR
.REPT NDHS
<AD>+<20*.RPCNT>
.ENDR
.ENDM
.MACRO DLTE AD ;DL11 REGISTER ADDRESS GENERATOR, FIRST IS WIERD
.IFNZ NDLS
177560+<<AD>&7>
.REPT NDLS-1
<AD>+<10*.RPCNT>
.ENDR
.ENDC ;NDLS
.ENDM
.MACRO DMTE AD ;DM11 register address generator
.REPT NDMS
<AD>+<10*.RPCNT> ;a DM11 eats 8 locations
.ENDR
.ENDM
DMCSR: DMTE 170500 ;first DM11 is at 170500
DMLSR: DMTE 170502 ;selected line status at 170502
DHSCR: DHTE DHCBAS ;SYSTEM CONTROL REGISTER
;1.1-1.4 LINE NUMBER
;1.5-1.6 MEMORY ADDRESS EXTENSION
DHRENB==100 ;1.7 RECEIVER INTERRUPT ENABLE
;1.8 RECEIVER INTERRUPT
;1.9 CLEAR NXM FLAG
;2.1 MAINTENANCE MODE
DHSNXM==2000 ;2.2 NXM FLAG (GENERATES XMT INTERRUPT)
;2.3 MASTER CLEAR
DHSENB==10000 ;2.4 STORAGE SILO FULL INTERRUPT ENABLE
DHTENB==20000 ;2.5 TRANSMITTER & NXM INTERRUPT ENABLE
;2.6 STOARGE FULL INTERRUPT
DHTDON==100000 ;2.7 TRANSMITTER DONE INTERRUPT
DLKS==DHSCR
DLTE 175610 ;KEYBOARD STATUS REGISTER
;1.1 PAPER TAPE READER ENABLE (WO)
;1.2 DATA TERMINAL READY (RW)
;1.3 REQUEST TO SEND (RW)
;1.4 SECONDARY TRANSMIT DATA [OR MAKE BUSY] (RW)
;1.5 UNUSED
;1.6 DATASET INTERRUPT ENABLE (RW)
;1.7 RECEIVE INTERRUPT ENABLE (RW)
;1.8 RECEIVE DATA READY (RO)
;1.9 UNUSED
;2.1 UNUSED
;2.2 SECONDARY RECEIVE DATA (RO)
;2.3 RECEIVE ACTIVE (RO)
;2.4 CARRIER DETECT (RO)
;2.5 CLEAR TO SEND (RO)
;2.6 RING INDICATOR (RO)
;2.7 DATASET STATUS CHANGE (RO)
DHNRC: DHTE DHCBAS+2 ;NEXT RECEIVED CHARACTER
;1.1-1.8 THE CHARACTER
;1.9-2.3 LINE NUMBER
%DXPAR==10000 ;2.4 CHAR HAS WRONG PARITY
%DXBRK==20000 ;2.5 FRAMING ERROR (BREAK)
%DXOVR==40000 ;2.6 OVERRUN, PREVIOUS CHARS LOST
;2.7 1 => THIS WORD VALID
DLKB==DHNRC
DLTE 175612 ;KEYBOARD INPUT REGISTER
;1.1-1.8 RECEIVED DATA
;2.4 PARITY ERROR (RO)
;2.5 FRAMING ERROR (RO)
;2.6 OVERRUN (RO)
;2.7 OR OF ERROR BITS (RO)
DHLPR: DHTE DHCBAS+4 ;LINE PARAMETER REGISTER
;1.1-1.2 CHARACTER LENGTH 0=5, 1=6, 2=7, 3=8 (PARITY BIT EXTRA)
;1.3 1 => EXTRA STOP BIT
;1.5 ENABLE PARITY
;1.6 0 -> EVEN PARITY, 1 => ODD
;1.7-2.1 RECEIVER SPEED
; 0 OFF, 1 50, 2 75, 3 110, 4 134.5, 5 150, 6 200, 7 300
; 10 600, 11 1200, 12 1800, 13 2400, 14 4800, 15 9600, 16 A, 17 B
;2.2-2.5 TRANSMITTER SPEED, SAME CODES AS RECEIVER
;2.6 HALF DUPLEX
;2.7 ECHOPLEX
DHCA: DHTE DHCBAS+6 ;CURRENT ADDRESS
DLCA==DHCA
.IREPT NDLS,0
DHBC: DHTE DHCBAS+10 ;BYTE COUNT (MINUS)
DLBC==DHBC
.IREPT NDLS,0 ;POSITIVE FOR DLS
DHBAR: DHTE DHCBAS+12 ;BUFFER ACTIVE REGISTER
;BIT = 1 IF XMT ACTIVE ON CORRESP LINE, NUMBERED RIGHT TO LEFT
DLPS==DHBAR
DLTE 175614 ;PRINTER STATUS
;1.1 SEND BREAK (RW)
;1.3 LOOP BACK (RW)
;1.6 INTERRUPT ENABLE (RW)
;1.7 TRANSMITTER READY (RO)
DHBCR: DHTE DHCBAS+14 ;BREAK CONTROL REGISTER
;BIT = 1 => SEND BREAK ON CORRESP LINE, NUMBERED RIGHT TO LEFT
DLPB==DHBCR
DLTE 175616 ;PRINTER BUFFER
;1.1-1.8 DATA TO TRANSMIT
DHSSR: DHTE DHCBAS+16 ;SILO STATUS REGISTER
;1.1-1.6 SILO ALARM LEVEL
;1.7-1.8 READ EXTENDED ADDRESS (R.O.)
;1.9-2.5 SILO FILL LEVEL (R.O.)
;2.7 MAINTENANCE PATTERN (W.O.)
DHOAC: .IREPT NDHS,0 ;BIT ON IF SOFTWARE THINKS LINE'S TRANSMITTER IS ACTIVE
DLOAC==DHOAC
.IREPT NDLS,0 ;NON-ZERO IF LINE'S TRANSMITTER IS ACTIVE
DHTYNO: .IREPT NDHS, NFDHTY+<32.*.RPCNT> ;TTY INDEX OF FIRST LINE ON THIS DH11
DLTYNO==DHTYNO
.IIF NZ CTYP,0 ;TTY INDEX OF LINE ON THIS DL11
.IREPT NDLS-CTYP,NFDLTY+<2*.RPCNT>
STROUT: .IREPT NDHS, STRDH ;OUTPUT-START ROUTINES
.IREPT NDLS, STRDL
.IIF NZ NMPTYS, STRMPK
.BLKB NFTTY ;AVOID LABEL OVERLAPPAGE
;TABLES INDEXED BY I (PER LINE)
T HDWR: ;HARDWARE UNIT INDEX, GOES IN H
.IIF NZ CTYP, NFDLHX
.REPT NDHS
ZZ==.RPCNT*2
.REPT 16.
ZZ ;16 LINES ON EACH DH-11
.ENDR
.ENDR
.=.-<2*NDHUN>
.IREPT NDLS-CTYP,NFDLHX+<2*.RPCNT>+<2*CTYP>
.IREPT NMPTYS, MPKHWR ;MULTIPLEXOR-KLUDGE TTYS
T DHLSEL: ;DH11 LINE SELECT WORDS
.IIF NZ CTYP, 0 ;NONE FOR CTY
.REPT NDHS
.REPT 16.
DHTENB+DHRENB+.RPCNT
.ENDR
.ENDR
T DHLBIT: ;BIT CORRESPONDING TO THIS LINE IN DHBAR, ETC.
.IIF NZ CTYP, 0 ;NONE FOR CTY
.REPT NDHS
.REPT 16.
1_.RPCNT
.ENDR
.ENDR
T BUFPNT: ;BUFFER POINTERS
.IREPT NCT, BUFFRS+<.RPCNT*MAXBSZ>
T BUFSIZ: ;BUFFER SIZES (I.E. AMOUNT TO USE AT CURRENT SPEED)
.REPT NCT
0 ;SET DURING INITIALIZATION
.ENDR
T NRMIPC: ;NORMAL INPUT CHARACTER PROCESSING ROUTINES
.IIF NZ CTYP, RCV ;CTY NORMAL INPUT
.REPT 16.*NDHS
DHNRMI ;DH11 TTY NORMAL INPUT
.ENDR
.=.-<2*NDHUN>
.IREPT NDLS-CTYP,RCV ;DL11 NORMAL INPUT
.IREPT NMPTYS, RCV ;NORMAL INPUT FOR TTYS ON MULTIPLEXOR-KLUDGE
.IIF NE .-NRMIPC-NLTTY, .ERROR BARF AT NRMIPC
.IFNZ NMPTYS
.=NRMIPC+MPXIDX
MPXINP ;INPUT FROM THE MULTIPLEXED LINE IS SPECIAL
.=NRMIPC+NLTTY
.ENDC
T TTYIPC: ;CURRENT INPUT CHAR PROCESSING ROUTINES
.BLKW NCT ;SET UP AT INIT TIME
.IIF NE .-TTYIPC-NLTTY, .ERROR BARF AT TTYIPC
T AUTOSP: ;IF NON-ZERO, LINE GOES INTO AUTOSPEED WHEN DIALED UP
.REPT NCT ;IF MINUS ALSO WHEN BREAK SEEN
ZZ===.
ASPIRP ^\
.IIF EQ .RPCNT+<NFTTY/2>-N,+1 ;THIS LINE AUTOSPEED ON DIALUP
.IIF EQ .RPCNT+<NFTTY/2>+N,-1 ;ALSO ON BREAK
\
.IIF EQ .-ZZ, 0 ;THIS LINE NOT AUTOSPEED
.ENDR
.IIF NE .-AUTOSP-NLTTY, .ERROR BARF AT AUTOSP
.IFM MX
M2LMAP: ;MAP FROM DM11-BB CHANNEL NUMBERS TO TTY INDICES
2*1 ;0 T01
0 ;1 NONE
0 ;2 NONE
2*4 ;3 T04
2*5 ;4 T05
2*6 ;5 T06
2*7 ;6 T07
2*10 ;7 T10
2*11 ;10 T11
2*12 ;11 T12
2*13 ;12 T13
2*14 ;13 T14
2*15 ;14 T15
2*16 ;15 T16
2*17 ;16 T17
0 ;17 NONE
2*21 ;20 T21
2*22 ;21 T22
2*23 ;22 T23
2*24 ;23 T24
2*25 ;24 T25
2*26 ;25 T26
2*27 ;26 T27
2*30 ;27 T30
2*31 ;30 T31
2*32 ;31 T32
2*33 ;32 T33
2*34 ;33 T34
2*35 ;34 T35
2*36 ;35 T36
2*37 ;36 T37
2*40 ;37 T40
.ENDC ;MX
.IIF NE NDMS, .IIF NE .-M2LMAP-<40*NDMS>, .ERROR Too few M2LMAP entries for DM11s.
.IFNZ NDMS
T DIALED: ;0 IF LINE NOT DIALED UP (OR NO MODEM CONTROL ON THIS LINE)
.REPT NCT ;+ IF DIALED UP (CLEAR TO SEND IS ON)
0 ;- IF CLEAR TO SEND DROPPED, INC EACH TICK, REACHES 0 => HUNG UP
.ENDR
.ENDC ;NDMS
T TTYHNG: ;DIALUP/HANGUP STATUS WAITING TO BE SENT TO 10 (0 IF NONE)
.REPT NCT
0
.ENDR
T TYPING: ;POSITIVE IF LINE IS TYPING OUT FOR 10
.REPT NCT ; WHICH MEANS -10 SHOULD BE INFORMED WHEN TYPEOUT IS FINISHED
0 ;0 FOR NO -10 TYPEOUT, MINUS TO SEND <CALL> AFTER TYPEOUT
.ENDR
;MISC VARIABLES
DLXOFF: -1 ;NON-ZERO IF DL10 PORT TURNED OFF BY 10
NO.ITS: -1 ;NON-ZERO IF HAVEN'T ESTABLISHED COMMUNICATION WITH ITS YET
VERSN: .BYTE NFTTY/2,NCT ;I/O VERSION NUMBER
DMINI: 0 ;NON-ZERO => MODEM SCANNER JUST TURNED ON, GETTING INITIAL STS
WAKE: 0 ;CLOCK INTERRUPT WAKE UP MAIN PROGRAM FLAG
HNGSIG: 0 ;NUMBER OF NON-ZERO TTYHNG WORDS
10RQ: 0 ;LIGHT HACKS
LITHSE: 7
.IFNZ DTE20P
CLKENB: 0 ;KL10 WANTS 11 TO RELAY CLOCK INTERRUPTS
KLDCPF: 0 ;NON-ZERO => USER WANTS TO GIVE A COMMAND TO KLDCP
DDTMOD: 0 ;NON-ZERO => DDT MODE TTY INPUT
DDTCHR: -1 ;NON-NEGATIVE => CHAR TYPED FOR DDT
CURSWR: 52525 ;LAST SWITCHES SENT TO -10
OUTCMD: 0 ;0 IF OUTPUT TRANSFER IDLE
;ELSE CURRENT COMMAND / 400
OUTSVI: -1 ;LINE# OF CURRENT OUTPUT TRANSFER
OUTSVC: -1 ;#BYTES OF CURRENT OUTPUT TRANSFER
INPCMD: 0 ;0 IF INPUT TRANSFER IDLE
;ELSE CURRENT COMMAND / 400
INPSVI: -1 ;LINE# OF CURRENT INPUT TRANSFER
INPSVC: -1 ;#BYTES OF CURRENT INPUT TRANSFER
.ENDC ;DTE20P
.IFNZ NMPTYS
MPXOAC: 0 ;0 IDLE, -1 SENDING HEADER, 1 SENDING DATA
MPXOLN: 0 ;2 x MPXK# OUTPUTTING FOR
MPXSEL: NFMPTY ;TTY INDEX SELECTED FOR MPX INPUT
MPXPNT: .IREPT NMPTYS,0 ;POINTER TO CRUFT TO SEND TO EACH MPXED LINE
MPXNBT: .IREPT NMPTYS,0 ;# BYTES TO SEND, 0 IF IDLE
MPXHED: .BYTE 0,0 ;MPX OUTPUT HEADER: 200+MPXK#, BYTE COUNT
.ENDC ;NMPTYS
.SBTTL CHAOSNET VARIABLES & TABLES
.IFNZ CHAOSP
NSUBNT==80. ;MAXIMUM CAPACITY 80. SUBNETS
.IFNZ DL10P ;DL10 UNSHARED
DLCRBN: 0 ;CURRENT RECEIVE (11 to 10) BUFFER (0 OR 2)
DLCNXT: .WORD 2,0 ;FOR SWITCHING BUFFERS
DLCIBF: .BLKW PKMAX ;DL10 INPUT BUFFER
.ENDC ;DL10P
.IFNZ TEN11P ;TEN11 UNSHARED
T11OBP: T11OBF ;NEXT BUFFER TO 10
T11IBP: T11IBF ;NEXT BUFFER FROM 10
T11IBA: 0 ;NON-ZERO MEANS INPUT BUFFER ACTIVE, T11IBP NEEDS ADVANCING
;THIS IS SEPARATE FROM CHISTS+CHXT11 FOR GOOD REASONS
T11CKE: 0 ;COUNT OF TEN-11 CHECKSUM ERRORS
T11TIM: 0 ;TIMEOUT ON TRANSMISSION OF PACKET TO 10
.ENDC ;TEN11P
.IFNZ ETHERP
ETHSBN==2 ;SUBNET WHICH IS THE ETHERNET
.SEE ETHHSN ;MY HOST NUMBER BYTE (DEFINED IN MACHINE CONFIGURATION AREA)
ETHMXH==15.-1 ;MAXIMUM NUMBER OF HOPS (-1 => BUG IN XEROX PROGRAMS)
ETHIBF: .BLKW PKTMXW+1 ;INPUT FROM ETHERNET BUFFERED HERE (+1 HARDWARE BUG?)
ETHHDW==PKHDW-2 ;ALLOW FOR OVERLAP OF CHAOSNET HEADER AND 2-WORD ETHERNET HEADER
;THIS IS THE OFFSET (IN WORDS) WHERE THE ETHERNET PACKET STARTS
;HERE IS A PACKET USED TO BUILD THE ETHERNET BROADCAST GATEWAY INFO. WHAT A CROCK.
EGTBUF: .BLKW PKHDW ;SPACE FOR CHAOSNET HEADER
EGTPLN: 0 ;PUP LENGTH
201 ;PUP TYPE 201
EGTPID: .WORD 0,0 ;PUP IDENTIFIER
0 ;DESTINATION (BROADCAST)
.WORD 0,2 ;DEST SOCKET 2
EGTSRC: .BYTE ETHHSN,ETHSBN ;SOURCE (ME)
.WORD 0,2 ;SOURCE SOCKET 2
EGTSBN: ;; FOR EACH SUBNET, .BYTE GATE-NET, TARGET-NET, HOP-COUNT, GATE-HOST
.BLKW 2*NSUBNT
0 ;PUP CHECKSUM
.IF DF NDVRBF
DVRHST: 0 ;ZERO IF IDLE, OR FOREIGN HOST USING
DVRIDX: 0 ;FOREIGN INDEX
DVRLIX: 0 ;LOCAL INDEX (AOS EACH TIME)
DVRTIM: 0 ;COUNTS UP TO IDLE THE FOREIGN HOST
DVRRTR: 0 ;COUNTS UP FOR RETRANSMISSION
DVRBFL==2*<PKHDW+10.+<DATMAX/2>+1> ;NUMBER OF BYTES IN A DOVER BUFFER (HOLDS PUP IN CHAOSNET PACKET)
DVRBUF: .BLKB DVRBFL*NDVRBF ;RING OF BUFFERS HERE
DVRBF2: .BLKW PKHDW+2 ;BUFFER FOR SENDING STS/OPN/CLS BACK (ALSO END OF RING)
DVRBFP: DVRBUF ;POINTER TO NEXT BUFFER TO GO OUT TO DOVER
DVRMSK: 0 ;MASK OF WHICH BUFFERS CONTAIN PACKETS (MSB = DVRBFP PKT)
.IIF GT NDVRBF-16., .ERROR NDVRBF MAXIMUM OF 16. ALLOWED
DVRPKP: 0 ;IF NON-ZERO, POINTER TO SPECIAL PACKET TO SEND
DVRID: 0 ;ID FOR NEXT PACKET EXPECTED BY DOVER, THIS PACKET IS OR
; WILL BE IN THE BUFFER DVRBFP POINTS AT
DVROFS: 0 ;ID OFFSET, SUBTRACT FROM CHAOS ID TO GET PUP ID
NDVRFK: 0 ;*** TEMPORARY KLUDGE ***
.ENDC ;NDVRBF
.ENDC ;ETHERP
PULSAR: 0 ;COUNTS DOWN TO 0 THEN TRIGGERS TRANSMISSION OF A "TEST MESSAGE"
PULSON: FTPULS ;IF THIS IS NON-ZERO, FEATURE IS ENABLED, VALUE IS TICKS BETWEEN PULSES
USECBL: 0 ;IF NON-ZERO, 10 TALKING TO SELF STILL GOES THROUGH CABLE
NCHX==DL10P+TEN11P+CHAOSP+<2*ETHERP> ;NUMBER OF ENTRIES IN SOURCE AND SINK TABLES
.IIF DF NDVRBF, NCHX==NCHX+1
;METERS ETC.
.IFNZ FTGARB
CHSGBF: .BLKW PKMAX ;HOLDS LAST PACKET THAT CAME IN WITH A CHECKSUM ERROR
CHSGBH: 0 ;UNIBUS ADDRESS OF INTERFACE THAT ABOVE CAME IN ON
CHSGBS: 0 ;STATUS REGISTER THAT GOES WITH ABOVE
CHSGBC: 0 ;BIT COUNT THAT GOES WITH ABOVE
.ENDC ;FTGARB
;FOLLOWING HAVE SEPARATE ENTRIES FOR EACH CABLE
NPKSGB: .IREPT CHAOSP+ETHERP,0 ;COUNTS THE NUMBER OF PACKETS RECEIVED WITH CHECKSUM ERRORS
HPKSGB: .IREPT CHAOSP+ETHERP,0 ;HIGH-ORDER WORD OF COUNTER
NPKSRL: .IREPT CHAOSP+ETHERP,0 ;COUNTS THE NUMBER OF PACKETS RAM LOST,
; I.E. DIDN'T COME IN WITH A CHECKSUM ERROR BUT AFTER
; READING IT OUT HAD ONE. EITHER THE PACKET WAS THE
; WRONG LENGTH, OR THE RAM IS LOSING, OR HARDWARE
; CLOBBERAGE. FOR ETHERNET IS PUP CKSM ERR COUNT
;THIS WORD ALSO IS WHERE BIT COUNT ERRORS WOULD END UP
HPKSRL: .IREPT CHAOSP+ETHERP,0 ;HIGH-ORDER WORD OF COUNTER
CHSRLH: 0 ;UNIBUS ADDRESS OF INTERFACE THAT ABOVE LAST HAPPENED ON.
CHSRLC: 0 ;RESIDUAL BIT COUNT FOR ABOVE
NPKSLS: .IREPT CHAOSP,0 ;NUMBER OF PACKETS LOST ACCORDING TO LOSS COUNT IN HARDWARE
HPKSLS: .IREPT CHAOSP,0 ;HIGH-ORDER WORD OF COUNTER
NPKSAB: .IREPT CHAOSP+ETHERP,0 ;NUMBER OF TRANSMISSIONS ABORTED (BY COLLISION OR RECEIVE-BUSY)
HPKSAB: .IREPT CHAOSP+ETHERP,0 ;HIGH-ORDER WORD OF COUNTER
NPKSI: .IREPT NCHX,0 ;TOTAL NUMBER OF PACKETS IN ON EACH SOURCE
HPKSI: .IREPT NCHX,0 ;HIGH-ORDER WORD OF COUNTER
NPKSO: .IREPT NCHX,0 ;TOTAL NUMBER OF PACKETS OUT ON EACH SINK
HPKSO: .IREPT NCHX,0 ;HIGH-ORDER WORD OF COUNTER
NPKSIG: 0 ;NUMBER OF PACKETS IGNORED AT CHIFLS
NPKSBD: .IREPT NCHX,0 ;NUMBER OF PACKETS BAD AT CHSIHB
HPKSBD: .IREPT NCHX,0 ;HIGH-ORDER WORD OF COUNTER
NPKSRF: 0 ;NUMBER OF PACKETS FOR WHICH ROUTING FAILED
RFSBNT: -1 ;2* SUBNET# OF LAST ROUTING FAILURE
;"INTERFACE ADDRESSES"
; A NEGATIVE INTERFACE ADDRESS IS THE UNIBUS ADDRESS OF A CHAOS INTERFACE.
; A ZERO INTERFACE ADDRESS MEANS THE DL10
; A POSITIVE INTERFACE ADDRESS MEANS THE TEN-11, VALUE BETTER BE OCTAL 1011.
CHSIBF: .BLKW PKMAX*CHAOSP ;INPUT BUFFER FOR PACKETS IN FROM CHAOS HDWR
;THIS IS WHAT IS SENT BACK IN RESPONSE TO RFC TO "STATUS".
;FOR NOW, JUST THE NAME OF THE MACHINE.
HSTNAM:
.ENDC ;CHAOSP ;FUCK A DOG, PALX!
.IFM MX-DL
.ASCII \MX-IO/11\
.ENDC
.IFM AI
.ASCII \AI-CHAOS-11\
.ENDC
.IFNZ CHAOSP ;FUCK A DOG, PALX!
.IIF GE .-HSTNAM-32., .ERROR HSTNAM TOO LONG
.IREPT 32.-<.-HSTNAM>, .BYTE 0 ;PAD ON THE RIGHT WITH 0'S
;CHAOSNET INPUT SOURCE AND OUTPUT SINK TABLES
;NOTE WELL, THE CODE RELIES ON THE ORDER OF THESE INDICES
.IIF NZ DL10P, CHXDLC==0 ;DL10 INDEX
.IIF NZ TEN11P, CHXT11==2*DL10P ;TEN11 INDEX
CHXCHS==2*<DL10P+TEN11P> ;FIRST CHAOS INDEX
.IIF NZ ETHERP, CHXETH==CHXCHS+<2*CHAOSP> ;ETHERNET INDEX
.IIF NZ ETHERP, CHXEGT==CHXETH+2 ;ETHERNET GATEWAY-INFO-BROADCAST KLUDGE INDEX
.IIF DF NDVRBF, CHXDVR==CHXEGT+2 ;DOVER PROTOCOL TRANSLATOR
.MACRO CHXCHK TAG
.IIF NE .-TAG-NCHX-NCHX, .ERROR TAG WRONG LENGTH TABLE
.ENDM CHXCHK
;CHAOSNET INPUT SOURCE TABLES
CHIBFP: ;BUFFER POINTER
.IIF NZ DL10P, DLCIBF ;DL10 INPUT BUFFER
.IIF NZ TEN11P, 0 ;CURRENT TEN11 INPUT BUFFER (SET FROM T11IBP+8)
.IREPT CHAOSP, CHSIBF+<PKMAX*2*.RPCNT> ;CHAOS INPUT BUFFER
.IIF NZ ETHERP, ETHIBF ;ETHERNET
.IALSO EGTBUF ;..
.IIF DF NDVRBF, 0 ;CURRENT DOVER BUFFER, COULD BE CHAOS OR PUP
CHXCHK CHIBFP
CHIHDL: .IREPT NCHX, 0 ;LENGTH OF HEADER IN WORDS, PACKET CURRENTLY IN BFR
CHISTS: .IREPT NCHX, 0 ;STATUS (0 IDLE, +1 HAS INPUT, -1 BEING OUTPUT)
CHILNG: .IREPT NCHX, 0 ;LENGTH OF CONTAINED PACKET IN WORDS
CHIOUX: .IREPT NCHX, 1 ;DESTINATION OUTPUT SINK INDEX (-1 IF DIRECTED TO PDP11 ITSELF)
CHICBA: .IREPT NCHX, 0 ;DESTINATION CABLE ADDRESS
CHIRFL: ;ADDRESS OF REFILL ROUTINE
.IIF NZ DL10P, DLCRFL
.IIF NZ TEN11P, T11RFL
.IREPT CHAOSP, CHSRFL
.IIF NZ ETHERP, ETHRFL ;ETHERNET
.IALSO CPOPJ ;..
.IIF DF NDVRBF, DVRRFL
CHXCHK CHIRFL
CHIHWR: ;POINTER TO HARDWARE
.IIF NZ DL10P, 1 ;NOT USED
.IIF NZ TEN11P, 3 ;NOT USED
.IREPT CHAOSP, CAICSR+<400*.RPCNT> ;QUAD-CHAOS INTERFACES HAVE TO BE 200 APART
.IIF NZ ETHERP, 164200 ;AND WE MAKE IT 400 BECAUSE ETHERNET GETS IN WAY
.IALSO 5 ;NOT USED
.IIF DF NDVRBF, 7 ;NOT USED
;CHAOSNET OUTPUT SINK TABLES
CHOHWR==CHIHWR ;POINTER TO HARDWARE
CHOSTS: .IREPT NCHX, 0 ;STATUS (0 IDLE, +1 TRANSMITTING, -1 RETRANSMITTING
; AFTER TRANS ABORT, +2 DELAYING AFTER TRANSMIT ABORT BEFORE RETRANSM)
CHOINX: .IREPT NCHX, 1 ;CURRENTLY-ACTIVE CHIxxx INDEX
CHOXMT: ;START TRANSMISSION ROUTINE
.IIF NZ DL10P, DLCXMT
.IIF NZ TEN11P, T11XMT
.IREPT CHAOSP, CHSXMT
.IIF NZ ETHERP, ETHXMT ;ETHERNET
.IALSO 1 ;NOT USED (CHXEGT)
.IIF DF NDVRBF, DVRPKT ;DOVER
CHXCHK CHOXMT
CHXSBN: ;SUBNET NUMBER +400 FOR STATUS SERVER
.IIF NZ DL10P, DLCADR/400+400
.IIF NZ TEN11P, T11ADR/400+400
.REPT CHAOSP
CONC CHAD,\.RPCNT,/400+400
.ENDR ;CHAOSP
.IIF NZ ETHERP, ETHSBN+400 ;ETHERNET
.IALSO 776 ;NOT REAL (ETHERNET GATEWAY)
.IIF DF NDVRBF, 777 ;NOT REAL (DOVER)
CHXCHK CHXSBN
CHXRTF: .IREPT NCHX, 0 ;NON-ZERO MEANS BROADCAST ROUTING INFO TO THIS GUY
.IFNZ CHSBTB
CHSIDL: .IREPT NCHX, 0 ;NUMBER OF TICKS WAITING FOR TRANSMIT-DONE
CHSRST: .IREPT NCHX, 0 ;NUMBER OF TIMES HAD TO RESET HUNG INTERFACE
.ENDC ;CHSBTB
;;; SUBNET/ROUTING TABLES
;INDEX BY TWICE SUBNET NUMBER
SBNTYP: .IREPT NSUBNT, 0 ;TYPE OF CONNECTION TO THIS SUBNET:
; 0 VIA GATEWAY, WITH AUTOMATIC ROUTING
; -1 VIA GATEWAY, PATCHED IN BY HUMAN, DON'T CHANGE
; 1 HARDWARE CONNECTION
SBNADR: ;ADDRESS OF CONNECTION TO THIS SUBNET
;NETWORK ADDRESS IF SBNTYP NEGATIVE OR ZERO
;INDEX IN SOURCE/SINK TABLES IF SBNTYP GREATER THAN ZERO
0 ;0 USED FOR UNKNOWN SUBNETS. WHEN IN DOUBT, BROADCAST.
0 ;1 9TH FLOOR CABLE
0 ;2 (NOT CURRENTLY USED)
440 ;3 MX, ASSUME VIA MX-IO-11
426 ;4 AI, ASSUME VIA AI-CHAOS-11
.IREPT NSUBNT-5, 0 ; WHEN IN DOUBT, BROADCAST
SBNCST: .IREPT NSUBNT, 1000 ;COST OF ROUTING VIA CURRENT GATEWAY, SEE CHAORD
;NOW FILL IN TABLES FOR HARDWARE CONNECTIONS THAT EXIST ON THIS MACHINE
;INCLUDING TRANSFINITE HAIR FOR ETHERNET GATEWAY INFO PACKET
ZZ==.
.IFNZ DL10P
DLCSBN==DLCADR/400 ;SUBNET PDP10 ON OTHER END OF DL10 IS ON
.=SBNTYP+<DLCSBN*2>
1
.=SBNADR+<DLCSBN*2>
CHXDLC
.=SBNCST+<DLCSBN*2>
10. ;DIRECT 10/11 CONNECTION COSTS 10.
.ENDC ;DL10P
.IFNZ TEN11P
T11SBN==T11ADR/400 ;SUBNET PDP10 ON OTHER END OF TEN11 IS ON
.=SBNTYP+<T11SBN*2>
1
.=SBNADR+<T11SBN*2>
CHXT11
.=SBNCST+<T11SBN*2>
10. ;DIRECT 10/11 CONNECTION COSTS 10.
.ENDC ;TEN11P
.ENDC ;CHAOSP
.IFM MX-DL
CBLCST=11. ;CABLE CONNECTION COSTS 11.
.ENDC
.IFM AI
CBLCST=22. ;AI COSTS MORE 'CAUSE IT'S SICK
.ENDC
.IFNZ CHAOSP ;sweet fucking jesus, palx
;HAIR FOR MULTIPLE CABLE INTERFACES
.REPT CHAOSP
CONC IZZZ==CHAD,\.RPCNT
IZZ==<IZZZ/400>*2
.=SBNTYP+IZZ
1
.=SBNADR+IZZ
CHXCHS+<.RPCNT*2>
.=SBNCST+IZZ
CBLCST ;THE CABLE COST
.ENDR ;CHAOSP
.IFNZ ETHERP
.=SBNTYP+<ETHSBN*2>
1
.=SBNADR+<ETHSBN*2>
CHXETH
.=SBNCST+<ETHSBN*2>
11.
.ENDC ;ETHERP
.=ZZ
;;; CLOCKS
4SEC: 0 ;4-SECOND CLOCK COUNTER
15SEC: 0 ;15-SECOND CLOCK COUNTER
.ENDC ;CHAOSP
;PATCH AREA
PAT: PATCH: .BLKW 100
.SBTTL RING BUFFERS
.MACRO RING SIZE
99$ ;IN-POINTER
99$ ;OUT-POINTER
0 ;NUMBER OF WORDS IN RING
<SIZE> ;MAX NUMBER ALLOWED
<2*<SIZE>>+99$ ;MAX ADDRESS ALLOWED
99$ ;MIN ADDRESS ALLOWED
99$: .BLKW <SIZE> ;BUFFER
.ENDM
RINGIN==0
RINGOT==2
RINGCT==4
RINGSZ==6
RINGTP==10
RINGBT==12
RINGBF==14
; DEFINE THE RING BUFFERS
TYORNG: RING <NCT*2> ;OUTPUT-DONE RING, CONTENTS = LINE NUMBER PDP10 STYLE
;HAS TO BE EXTRA BIG BECAUSE THE OUTPUT DONES PUT IN ON
;STARTUP FILL IT UP, THEN SOMETIMES ITS PUTS ONE IN
;BEFORE IT TAKES ANY OUT.
TYIRSZ==NCT*20 ;8 CHARS PER TTY (2 WORDS PER CHAR)
TYIRNG: RING TYIRSZ ;TTY INPUT RING, FIRST WORD IS CHARACTER, SECOND LINE NUMBER
;MOV #RING,B
;MOV WORD,A
;CALL PUT
PUT: CMP RINGCT(B),RINGSZ(B)
BLT 1$
BPT ;BLOATED
1$: PUSH C
MOV RINGIN(B),C
MOV A,(C)+
CMP C,RINGTP(B)
BLO 2$
MOV RINGBT(B),C
2$: MOV C,RINGIN(B)
POP C
INC RINGCT(B)
RET
;MOV #RING,B
;CALL GET
;WORD RETURNED IN A
; IT IS AN ERROR TO CALL THIS IF RING IS EMPTY
GET: TST RINGCT(B)
BGT 1$
BPT ;EMPTY
1$: PUSH C
MOV RINGOT(B),C
MOV (C)+,A
CMP C,RINGTP(B)
BLO 2$
MOV RINGBT(B),C
2$: MOV C,RINGOT(B)
POP C
DEC RINGCT(B)
RET
CLRING: CLR RINGCT(B) ;CLEAR A RING
MOV RINGBT(B),RINGIN(B)
MOV RINGBT(B),RINGOT(B)
RET
.IFNZ DTE20P
.SBTTL DTE20 SUBROUTINES
;THE DTE20 MUST NOT BE HACKED AT INTERRUPT LEVEL, BECAUSE KLDCP USES IT TOO.
;THE FOLLOWING THREE LOCATIONS ARE ARGS TO/FROM THE FOLLOWING TWO SUBROUTINES.
LH: 0 ;LOW 16 BITS OF LEFT HALF
RH: 0 ;LOW 16 BITS OF RIGHT HALF
SNB: 0 ;SIGN BIT (0 IF +, NON-0 IF -)
;JSR B,HWEXAM
; .WORD ADDR
;EXAMINE PDP10 LOC, SPLIT INTO HALFWORDS, SET LH, RH, SNB
;RETURNS WITH "Z" SET IF LOCATION HAS POSITIVE SIGN, "Z" CLEAR IF MINUS SIGN
HWEXAM: PUSH <A,C> ;SAVE REGS
PUSH <#0,(B)+> ;PUT PDP10 ADDRESS ONTO PDL
MOV SP,A ;SET UP POINTER TO ADDRESS
EXAM ;EXAMINE LOCATION, SET A TO POINT TO 3-WORD RESULT BUFFER
BCS UHUNG ;BRANCH IF UCODE HUNG
MOV (A)+,RH ;LOW 16 BITS => RH
MOV (A)+,C ;PICK UP MIDDLE 16 BITS
MOV (A)+,A ;PICK UP HIGH 4 BITS
ROR A ;LSHC <A,C>,-2 TO GET PDP10 LH INTO C
ROR C
ROR A
ROR C
MOV C,LH
BIC #177775,A ;LEAVE SIGN BIT IN 1.2 OF A
MOV A,SNB
ADD #4,SP ;POP ADDRESS OFF PDL
POP <C,A> ;RESTORE REGS
TST SNB
RTS B ;RETURN SKIPPING IN-LINE PARAMETER
;JSR B,HWDEP
; .WORD ADDR
;ASSEMBLE LH, RH, SNB INTO PDP10 AND DEPOSIT IN ADDR
HWDEP: PUSH <A,B,C>
MOV LH,C
CLR A
TST SNB
BEQ 1$
MOV #2,A
1$: ASL C
ROL A
ASL C
ROL A
PUSH <A,C,RH> ;PUSH HIGH, MIDDLE, AND LOW BITS
MOV SP,A ;POINTER TO DATA
PUSH <#0,(B)> ;PUSH HIGH AND LOW ADDRESS
MOV SP,B ;POINTER TO ADDRESS
DPOS ;DO THE DEPOSIT
BCS UHUNG ;BRANCH IF UCODE HUNG
ADD #10.,SP ;POP ADDRESS AND DATA OFF PDL
POP <C,B,A>
TST (B)+ ;SKIP TRAILING PARAMETER
RTS B
UHUNG: $PMSG
.WORD 1$
SETOM NO.ITS ;GIVING UP
JMP $CNTLC
1$: .ASCIZ/?MICROCODE HUNG/
.ENDC ;DTE20P
.IFNZ DL10P
.SBTTL MAIN LOOP FOR DL10
MAIN:
.IIF NZ TEN11P, CALL T11WAK ;CHECK UP ON TEN-11 INTERFACE
.IFNZ ETHERP
TST CHXRTF+CHXETH ;NEED TO BROADCAST ROUTING INFO TO ETHERNET?
BEQ 666$
CALL ETHRUT
666$:
.ENDC ;ETHERP
BIT #DLXPRT,DLXCSR ;PORT TO 10 ENABLED?
BNE 1$ ;YES
SETOM NO.ITS ;NO, FLAG THERE IS NO ITS
SETOM DLXOFF ;AND THAT WE THINK DL10 PORT IS OFF
BR MAIN ;AND WAIT FOR IT TO TURN ON
1$: TST DLXOFF ;DID DL10 JUST TURN ON?
BEQ 4$ ;NO, IT WAS ON BEFORE
CLR DLXOFF ;YES, SO REMEMBER THAT
MOV VERS,A ;CHECK VERSION SUPPLIED BY -10
BEQ 2$ ;ZERO OK (MUST BE SALVAGER)
CMP A,VERSN
BEQ 2$
BPT ;-10 AND -11 PROGRAMS NOT SAME CONFIG
2$:
4$: BIT #DLXPAR+DLXNXM,DLXCSR ;ERROR ACCESSING MEMORY?
BEQ 5$ ;NO
BPT ;DON'T GO OFF DESTROYING PEOPLE'S FILES
;WAIT FOR -10 TO REQUEST SERVICE, OR CLOCK TO TICK
5$: CLR 10RQ
BIT #DLX11I,DLXCSR ;10 REQUESTING SERVICE?
BEQ 10$
SETOM 10RQ
BIS #DLXZ11,DLXCSR ;YES, CLEAR FLAG
BR CHKOST ;AND GO CHECK FOR THINGS TO DO
10$: TST WAKE ;NO, CHECK ANYWAY IF 60 CYCLE CLOCK HAS TICKED
BEQ MAIN ;NEITHER, JUST WAIT
CLR WAKE ;CLOCK HAS TICKED, CLEAR FLAG
INC DLXUP ;AND INCREMENT COUNTER 10 IS SUPPOSED
BEQ 11$ ; TO SETOM EVERY 1/2 SEC
CMP DLXUP,#15.*60. ;IF IT DOESN'T TOUCH IT FOR 15 SECONDS,
BLE 12$ ; CONSIDER IT DOWN. NOTE THAT PARITY SWEEPS
SETOM NO.ITS ; THROUGH LARGE MEMORY CAN TAKE SEVERAL SECONDS
MOV #15.*60.,DLXUP ;DON'T LET COUNTER OVERFLOW
BR 12$ ;BUT CHECK FOR COMMANDS ANYWAY (SALVAGER DISK)
11$: CLR NO.ITS ;-10 HAS SETOMED COUNTER, IT'S UP
12$: ;FALL INTO CHKOST
; CHECK FOR OUTPUT-START FROM -10
CHKOST: MOV TTYST,A ;LINE# TO START OUTPUT
BEQ CHKOUT ;NONE.
CLR TTYST ;TELL -10 IT'S BEEN PICKED UP
MOV #TYORNG,B
MASK 5 ;DON'T INTERFERE WITH P.I. LEVEL
CALL PUT ;PUT IN RING, LATER WILL SEND IT BACK TO 10
UNMASK
; CHECK FOR TTY OUTPUT SENT BY -10
CHKOUT: MOV TYOLIN,I ;OUTPUT TO BE DONE?
BEQ CHKIN ;NO.
MOV TYOCNT,C ;YES, GET NUMBER OF CHARS
CALL TYOSER ;CALL OUTPUT HANDLER
CLR TYOLIN ;TELL 10 WE'VE GOBBLED THE OUTPUT
BIS #DLX10I,DLXCSR ;GIVE TRANSFER-COMPLETE INTERRUPT
; CHECK FOR TTY INPUT TO BE SENT TO -10
CHKIN: TST TYIRNG+RINGCT
BEQ CHKDON ;NO STATUS TO BE STORED
TST TYILIN
BNE CHKDON ;PREVIOUS STATUS NOT PICKED UP
MOV #TYIRNG,B
CALL GET
MOV A,TYICHR ;GIVE INPUT CHARACTER TO 10
CALL GET
MOV A,TYILIN ;GIVE LINE NUMBER TO 10
BIS #DLX10I,DLXCSR ;SEND INTERRUPT TO 10
; CHECK FOR OUTPUT-DONE TO BE SENT TO -10
CHKDON: TST TYORNG+RINGCT
BEQ CHKHNG ;NO STATUS TO BE STORED
TST TYOSTS
BNE CHKHNG ;PREVIOUS STATUS NOT PICKED UP
MOV #TYORNG,B
CALL GET
MOV A,I
ASL I
MOV BUFSIZ(I),TYOBSZ ;TELL -10 HOW MANY CHARS TO GIVE
MOV A,TYOSTS ;GIVE OUTPUT DONE TO 10
BIS #DLX10I,DLXCSR ;WITH INTERRUPT
; CHECK FOR HANGUPS TO BE SENT TO -10
CHKHNG: TST HNGSIG ;ANY HANGUPS TO BE REPORTED?
BEQ CHKLPR ;NO
TST HNGLIN
BNE CHKLPR ;PREVIOUS STATUS NOT PICKED UP
MOV #LASTTY,I ;SCAN OVER ALL LINES
1$: MASK 5
MOV TTYHNG(I),A ;GET HANG-UP STATUS
BNE 2$ ;BRANCH IF FOUND SOMETHING TO REPORT
UNMASK
TST -(I)
CMP I,#NFTTY
BHIS 1$
BPT ;HNGSIG OUT OF PHASE WITH TTYHNG
2$: CLR TTYHNG(I) ;GOT STATUS, CLEAR IT
DEC HNGSIG ;DECREASE COUNT OF FROBS WAITING TO BE SIGNALLED
UNMASK ;NOW IT'S OK TO INTERRUPT AND SET TTYHNG
MOV A,HNGLIN ;GIVE LINE NUMBER AND OTHER DATA TO 10
BIS #DLX10I,DLXCSR ;WITH INTERRUPT
; CHECK FOR REQUEST FROM -10 TO SET LINE PARAMETERS
CHKLPR: MOV LPRLIN,I ;LINE PARAMETERS TO BE SET?
BEQ CHKCHS ;NO.
ASL I ;YES, GET LINE INDEX
MOV LPRLPR,A ;AND DH11 PARAMETER REGISTER VALUE
MOV LPRBSZ,B ;AND BUFFER SIZE
CALL SPARAM ;CALL PARAMETER SETTER
CLR LPRLIN ;TELL 10 IT IS DONE
; CHECK FOR CHAOS NET ACTIVITY
CHKCHS:
.IFNZ CHAOSP
CALL DLCWAK ;WAKEUP DL10-CHAOSNET STUFF
.ENDC ;CHAOSP
.IFNZ T300P
CALL DSKSTR ;CHECK FOR DISK REQUEST
.ENDC ;T300P
; CHECK FOR EXAMINE/DEPOSIT REQUEST FROM -10
CHKEXD: TST EXDSTS ;EXAMINE/DEPOSIT?
BEQ CHKGLD ;NO.
MOV EXDADR,A ;GET ADDRESS
CMP EXDSTS,#2
BNE 21$
MOV EXDDAT,(A) ;DEPOSIT
21$: MOV (A),EXDDAT ;EXAMINE
CLR EXDSTS ;IT IS DONE
;CHECK FOR GOULD LPT OUTPUT
CHKGLD:
.IF EQ GOULDP
; CLR GLPCTR ;IF NO GOULD, FLUSH OUTPUT FOR IT
; SETOM GLPTER ;AND SAY "NOT READY"
TST 10RQ
BEQ 20$
;10 WANTED US TO DO SOMETHING, PLAY WITH THE LIGHTS
MOV LITHSE,A
ROL A
ROL LITHSE
20$: MOV LITHSE,GLPTER
.IFF
TST GLPCTR ;ANY BYTES IN BUFFER?
BEQ 1$
CALL GLPTYO ;YES, OUTPUT THEM
1$: MOV GLPERR,GLPTER ;COPY ERROR STATUS FROM P.I. LEVEL TO -10
.ENDC ;DONE HERE SO NO USE OF DL10 AT P.I. LEVEL
; BR MAINX
MAINX: JMP MAIN ;THAT'S IT
MAINE::
.ENDC ;DL10P
.IFNZ DTE20P
.SBTTL MAIN LOOP FOR DTE20
MAIN: BIT #%D1RUN,DIAG1 ;IS KL10 RUNNING?
BEQ TENDED ;NO, LOSE!
BIT #%D1ERR+%D1HLT,DIAG1 ;HAS KL10 CLOCK STOPPED FOR HARDWARE ERROR? OR JRST 4
BNE TENDED ;YES, LOSE!
TST KLDCPF ;MAYBE USER WANTS TO GIVE A KLDCP COMMAND?
BNE KLDCPR ;YES, RETURN TO KLDCP
TSTB @DLKS+NFDLHX ;CTY INPUT?
BPL 10$ ;TEST KBD BEFORE CLK SINCE MIGHT BE MORE THAN
; 1/60'TH SECOND PER TRIP AROUND THE LOOP.
MASK 5 ;YES, SIMULATE INTERRUPT
CALL DL1IBK ;CAN'T USE REAL INTS BECAUSE WOULD INTERFERE WITH KLDCP
10$: TSTB LKS ;60 CYCLE CLOCK TICK?
BMI CLKSER ;YES
BIT #%STINV,STATUS ;REQUEST FROM 10?
BNE TENSER ;YES, SERVICE IT.
BIT #%STDNI,STATUS ;TO10 XFER COMPLETE?
BNE INPDON ;YES, SERVICE IT.
BIT #%STDNO,STATUS ;TO11 XFER COMPLETE?
BNE OUTDON ;YES, SERVICE IT.
BIT #%STERI+%STERO,STATUS
BNE LOSSAG ;BYTE TRANSFER LOST
BR MAIN ;CLOSE LOOP
;60-CYCLE CLOCK SERVICE
CLKSER: CLR LKS ;CLEAR CLOCK FLAG
TST CLKENB ;DOES 10 WANT CLOCK INTERRUPTS?
BEQ 1$
D10MON ;YES, GIVE ONE
DTECLK ;SET CLOCK FLAG IN LOW CORE
BCS UHUNG
MOV #%STINX,STATUS ;AND SEND INTERRUPT
1$: CMP SWR,CURSWR ;MAYBE NEED TO UPDATE 10'S SWITCHES
BEQ 2$
MOV SWR,CURSWR
TENSW ;LET KLDCP DO IT
BCS UHUNG
2$: JSR B,HWEXAM ;INCREMENT COUNTER -10 IS SUPPOSED
DTECHK ; TO SETOM EVERY HALF-SECOND
CLR LH
CLR SNB
INC RH
BEQ 3$
CMP RH,#15.*60. ;IF IT DOESN'T SETOM IT FOR 15 SECONDS
BLE 4$ ;THEN IT IS DOWN. NOTE THAT PARITY SWEEPS
SETOM NO.ITS ;THROUGH LARGE MEMORY CAN TAKE SEVERAL SECONDS.
MOV #15.*60.,RH ;DON'T LET COUNTER OVERFLOW
BR 4$
3$: CLR NO.ITS ;IT SETOMED COUNTER, IT'S UP.
4$: JSR B,HWDEP ;PUT COUNTER BACK
DTECHK
MASK 6 ;NOW SIMULATE BR6 CLOCK INTERRUPT
CALL CLKBRK
BR TENSER ;AND GO SERVICE 10 (IN CASE LOST INTERRUPT)
; HERE IF KL10 HALTS
TENDED: SETOM NO.ITS
CLC
RET ;LET KLDCP PRINT THE MESSAGE
; BYTE TRANSFER ENCOUNTERED HARDWARE LOSSAGE
LOSSAG: BPT
BR LOSSAG
; USER WANTS TO GIVE A KLDCP COMMAND
KLDCPR: CLR KLDCPF
SEC
RET
TENSER: JMP TENSR0
; HERE WHEN TO10 BYTE TRANSFER COMPLETE
INPDON: MOV #%STCLI,STATUS ;CLEAR FLAGS IN DTE20
MOV INPCMD,A ;GET COMMAND FOR XFER THAT JUST FINISHED
BNE 1$
BPT ;WOOPS, NO XFER IN PROGRESS
1$: CLR INPCMD ;NO XFER IN PROGRESS NOW
MOV INPSVI,I
MOV INPSVC,C
CALL @FINAL-2(A) ;CALL APPROPRIATE FINISHER ROUTINE
BR MAIN
; HERE WHEN TO11 BYTE TRANSFER COMPLETE
OUTDON: MOV #%STCLO,STATUS ;CLEAR FLAG
MOV OUTCMD,A ;GET COMMAND FOR XFER THAT JUST FINISHED
BNE 1$
BPT ;WHOOPS, NO XFER IN PROGRESS
1$: CLR OUTCMD ;NO XFER IN PROGRESS NOW
MOV OUTSVI,I
MOV OUTSVC,C
CALL @FINAL-2(A) ;CALL APPROPRIATE FINISHER ROUTINE
BR MAINJ
; HERE TO START TO10 BYTE TRANSFER. HWEXAM OF DTEINP HAS BEEN DONE.
INPSER: D10MON ;VALUE HAS BEEN PICKED UP, SETOM IT
DTEINP
BIT #1000,LH ;RIGHT GENDER OF COMMAND?
BEQ OUTSR1 ;YES
BR MAINJ ;(USED TO BE BPT) NO, IGNORE, MAYBE ITS BEING RELOADED
; HERE TO START TO11 BYTE TRANSFER. HWEXAM OF DTEOUT HAS BEEN DONE.
OUTSER: D10MON ;VALUE HAS BEEN PICKED UP, SETOM IT
DTEOUT
BIT #1000,LH ;RIGHT GENDER OF COMMAND?
BNE OUTSR1 ;YES
BR MAINJ ;(USED TO BE BPT) NO, IGNORE, MAYBE ITS BEING RELOADED
OUTSR1: MOV RH,C ;GET BYTE COUNT
MOVB LH,I ;GET LINE#
MOVB LH+1,A ;GET COMMAND TIMES 2
BEQ MAINJ ;CLEARING CORE? IGNORE ZERO COMMAND
BLE OUTSR2
CMP A,#LBEGIN
BGT OUTSR2
CALL @BEGIN-2(A) ;CALL APPROPRIATE BEGIN-XFER ROUTINE
BIT #2,A
BNE 1$
MOV A,INPCMD ;REMEMBER CRUFT FOR XFER IN PROGRESS
MOV I,INPSVI
MOV C,INPSVC
BR MAINJ
1$: MOV A,OUTCMD ;REMEMBER CRUFT FOR XFER IN PROGRESS
MOV I,OUTSVI
MOV C,OUTSVC
MAINJ: JMP MAIN
OUTSR2: BR MAINJ ;BAD COMMAND FROM 10 (USED TO BE BPT) JUST IGNORE IT
;TABLE OF ROUTINES TO PROCESS DATA TRANSFER COMMANDS FROM -10
BEGIN: TYOSER ;%DTTYO
;ETHISR ;%DTETI
;ETHOSR ;%DTETO
LBEGIN==.-BEGIN
;TABLE OF ROUTINES TO FINISH UP DATA TRANSFERS
FINAL: TYOFIN ;%DTTYO
;ETHIFN ;%DTETI
;ETHOFN ;%DTETO
;CHECK FOR COMMANDS FROM 10, STORE STATUS IN ANY STATUS WORDS
;THAT 10 HAS SET BACK TO -1
TENSR0: MOV #%STUNV,STATUS ;CLEAR 10 INTERRUPTING 11 FLAG
JSR B,HWEXAM ;CHECK FOR A NON-TIMESHARING COMMAND
DTECMD
MOV RH,A ;IS THERE ONE?
BEQ TENSR1 ;NO, GO CHECK FOR TIMESHARING STUFF
CLR LH
CLR SNB
CMP A,#377
BHI 2$
1$: TSTB TPS ;CHAR TO BE TYPED, WAIT FOR READY
BPL 1$
MOVB A,TPB ;TYPE IT OUT
9$: CLR RH ;CLEAR OUT THE COMMAND
JSR B,HWDEP
DTECMD
D10MON ;TELL 10 IT'S DONE
DTEFLG
JMP MAIN
2$: CMP A,#%DTTYI
BNE 5$
CLR RH ;SNB,LH,RH NOW HAS ZERO
SETOM DDTMOD ;KEYBOARD INPUT WANTED
TST DDTCHR ;TEST IF READY
BMI 3$ ;IF NO INPUT, GIVE ZERO
MASK 5
MOV DDTCHR,RH ;GIVE THE CHAR
COM DDTCHR ;MAKE NEGATIVE
UNMASK
3$: JSR B,HWDEP
DTEF11
BR 9$
5$: CMP A,#%DTCLN
BNE 6$
SETOM CLKENB
BR 9$
6$: CMP A,#%DTCLF
BNE 7$
CLR CLKENB
BR 9$
7$: BPT ;SOME COMMAND WE DON'T IMPLEMENT
BR 9$ ;IF CONTINUED, IGNORE IT
;CHECK FOR ITS UP/DOWN
TENSR1: TST NO.ITS ;IF SYSTEM ISN'T UP,
BNE MAINJ ;DON'T TRY TO HACK TS STUFF
INC DLXOFF ;OTHERWISE, FIRST TIME THROUGH HERE
BNE CHKOST ;WE CHECK THE VERSION
JSR B,HWEXAM
DTEVER
TST RH ;STORED?
BNE 1$
DEC DLXOFF ;NO, DON'T LOOK AT IT
BR MAINJ ;PROBABLY CORE BEING CLEARED
1$: CMP RH,VERSN
BEQ CHKOST
BPT ;-10 AND -11 PROGRAMS NOT SAME VERSION
CHKOST: JSR B,HWEXAM ;CHECK FOR 10 WANTING OUTPUT START
DTEOST
BNE CHKTRN ;BRANCH IF LOCATION DTEOST IS -1
D10MON ;HAVING PICKED IT UP, SET BACK TO -1
DTEOST
MOV RH,A
MOV #TYORNG,B
MASK 5 ;DON'T INTERFERE WITH P.I. LEVEL
CALL PUT
UNMASK
CLR DDTMOD ;SYSTEM UP, TURN OFF DDT MODE
MOV #-1,DDTCHR ;..
CHKTRN: TST INPCMD
BNE 1$ ;INPUT IN PROGRESS, DON'T START AGAIN
JSR B,HWEXAM ;CHECK FOR DATA TRANSFER COMMAND
DTEINP
BNE 1$ ;DTEINP -1, NO REQUEST
JMP INPSER
1$: TST OUTCMD
BNE CHKLSP ;OUTPUT IN PROGRESS, DON'T START AGAIN
JSR B,HWEXAM ;CHECK FOR DATA TRANSFER COMMAND
DTEOUT
BNE CHKLSP ;DTEOUT -1, NO REQUEST
JMP OUTSER
CHKLSP: JSR B,HWEXAM ;CHECK FOR SET LINE SPEED COMMAND
DTELSP
BNE CHKTYI
MOV RH,I ;GET LINE#
ASL I
CMP I,#NFTTY ;VALIDATE IT
BLO 1$ ;IGNORE IF BAD
CMP I,#LASTTY
BHI 1$
JSR B,HWEXAM ;GET LPR,,BUFFERSIZE
DTELPR
MOV LH,A
MOV RH,B
CALL SPARAM ;DO IT
1$: D10MON ;DONE, SETOM
DTELSP
CHKTYI: TST TYIRNG+RINGCT
BEQ CHKODN ;NO TTY INPUT WAITING
JSR B,HWEXAM
DTETYI
BEQ CHKODN ;PREVIOUS CHAR NOT PICKED UP
MOV #TYIRNG,B
CALL GET
MOV A,RH ;CHAR
CALL GET
MOV A,LH ;LINE#
CLR SNB
JSR B,HWDEP ;GIVE 10 LINE#,,CHAR
DTETYI
MOV #%STINX,STATUS ;INTERRUPT THE 10
CHKODN: TST TYORNG+RINGCT
BEQ CHKHNG ;NO OUTPUT DONES WAITING
JSR B,HWEXAM
DTEODN
BEQ CHKHNG ;PREVIOUS STATUS NOT PICKED UP
MOV #TYORNG,B
CALL GET ;GET LINE# WITH OUTPUT DONE
MOV A,LH
ASL A
MOV BUFSIZ(A),RH
CLR SNB
JSR B,HWDEP ;GIVE 10 LINE#,,BUFFERSIZE
DTEODN
MOV #%STINX,STATUS ;INTERRUPT THE 10
CHKHNG: TST HNGSIG
BEQ MAINX ;NO HANGUPS/DIALINS WAITING
JSR B,HWEXAM
DTEHNG
BEQ MAINX ;PREVIOUS STATUS NOT PICKED UP
MOV #LASTTY,I ;SCAN OVER ALL LINES
1$: MASK 5
MOV TTYHNG(I),A ;GET HANG-UP STATUS
BNE 2$ ;BRANCH IF FOUND SOMETHING TO REPORT
UNMASK
TST -(I)
CMP I,#NFTTY
BHIS 1$
BPT ;HNGSIG OUT OF PHASE WITH TTYHNG
2$: CLR TTYHNG(I) ;GOT STATUS, CLEAR IT
DEC HNGSIG ;DECREASE COUNT OF FROBS WAITING TO BE SIGNALLED
UNMASK ;NOW IT'S OK TO INTERRUPT AND SET TTYHNG
MOV A,RH ;GIVE LINE NUMBER AND OTHER DATA TO 10
CLR LH
CLR SNB
JSR B,HWDEP
DTEHNG
MOV #%STINX,STATUS ;INTERRUPT THE 10
MAINX: JMP MAIN
.ENDC ;DTE20P
.IFZ DL10P+DTE20P
.SBTTL MAIN LOOP FOR AI
MAIN:
.IIF NZ TEN11P, CALL T11WAK ;CHECK UP ON TEN-11 INTERFACE
.IIF Z TEN11P, CALL CHSRUN ;DAMNED THING GETS WEDGED
.IFNZ ETHERP
TST CHXRTF+CHXETH ;NEED TO BROADCAST ROUTING INFO TO ETHERNET?
BEQ 666$
CALL ETHRUT
666$:
.ENDC ;ETHERP
TST WAKE ;CLOCK TICK?
BEQ MAIN ;NO, JUST WAIT
CLR WAKE ;CLOCK HAS TICKED, CLEAR FLAG
BR MAIN ;NOT MUCH TO DO, NO TTYS
.ENDC ;DL10P+DTE20P
.SBTTL OUTPUT HANDLERS
TYOSER: ASL I ;CONVERT -10 LINE# TO -11 TTY INDEX
CMP I,#NFTTY
BLO 11$
CMP I,#LASTTY
BLOS 12$
11$: BPT ;10 GAVE BAD LINE#
12$: MOV HDWR(I),H ;GET HARDWARE INDEX
MOV BUFPNT(I),D ;AND ADDRESS OF TYPEOUT BUFFER
CMP BUFSIZ(I),C ;MAKE SURE THERE IS ROOM IN BUFFER
BHIS 2$
BPT ;THERE ISN'T
2$: MOV C,B ;MUSTN'T CLOBBER BYTE COUNT IN C
.IFNZ DL10P
MOV #TYOPNT,A ;GET CRUFT FROM DL10
3$: MOVB @A,(D)+ ;COPY BUFFER
SOB B,3$
.ENDC ;DL10P
.IFNZ DTE20P
MOV D,TO11AD ;SET UP BYTE TRANSFER
NEG B
BIC #050000,B ;SET LAST, BYTE; CLEAR ASCIZ, 2.4
MOV B,TO11BC ;START XFER
RET
TYOFIN: MOV HDWR(I),H ;COMES BACK WHEN XFER COMPLETE
.ENDC ;DTE20P
;BUFFER HAS BEEN LOADED, START DEVICE
MASK 5 ;DON'T LET DEVICE INTERRUPT
MOV BUFPNT(I),D
CALL @STROUT(H) ;CALL DEVICE-DEPENDENT ROUTINE
MOV #40000,TYPING(I) ;TELL 10 WHEN OUTPUT FINISHES (LARGE POSITIVE NUMBER)
UNMASK
RET
;GIVE MESSAGE. A -> .WORD LENGTH,MSG. I HAS LINE NUMBER.
GIVMSG: PUSH <C,D>
MOV (A)+,C ;C HAS BYTE COUNT, A HAS ADDRESS
MOV A,D ;PUT ADDRESS IN D
MOV HDWR(I),H
MASK 5
CALL @STROUT(H) ;START OUTPUT TO LINE
UNMASK
POP <D,C>
RET
ASPACK: MNAME ^%
MSG ^\
<EFBFBD>Connected to MCHN'.\%
DWNMSG: MSG ^\
<EFBFBD>ITS is down.\
IBOMSG: MSG ^\IBO\
;DEVICE-DEPENDENT OUTPUT START ROUTINES (CALL AT PI LEVEL 5)
;H HDWR IDX, I TTY IDX, D BUFFER POINTER, C NUMBER OF BYTES
STRDH: BIC DHLBIT(I),@DHBAR(H) ;IF LINE ALREADY TRANSMITTING, STOP IT
;IT SHOULDN'T OUGHT TO BE...
MOV DHLSEL(I),@DHSCR(H) ;HARDWARILY SELECT THIS LINE
MOV D,@DHCA(H) ;SET XMT ADDRESS
NEG C ;HARDWARE LIKES NEGATIVE BYTE COUNTS
MOV C,@DHBC(H) ;SET XMT COUNT
BIS DHLBIT(I),@DHBAR(H) ;START TRANSMISSION HARDWARILY
BIS DHLBIT(I),DHOAC(H) ;SOFTWARILY ALSO
RET
STRDL: MOV D,DLCA(H)
MOV C,DLBC(H)
CLR @DLPS(H)
MOV #300,@DLPS(H) ;CAUSE INTERRUPT
SETOM DLOAC(H)
CPOPJ: RET
.IFNZ NMPTYS
STRMPK: TST MPXENB
BEQ CPOPJ
MOV D,MPXPNT-NFMPTY(I) ;QUEUE OUTPUT
MOV C,MPXNBT-NFMPTY(I)
STRMPX: PUSH I
TST MPXOAC ;START THE MPXR
BNE 10$ ;ALREADY BUSY
CLR I
MOV #NMPTYS,D
2$: MOV MPXNBT(I),C ;FIND MPX KLUDGE LINE WANTS TO OUTPUT
BNE 15$
TST (I)+
SOB D,2$
10$: POP I
RET
15$: MOV I,MPXOLN ;SAVE LINE# OUTPUT ON
ASR I ;SET UP HEADER
ADD #200,I
MOVB I,MPXHED
MOVB C,MPXHED+1
MOV #-1,MPXOAC ;SEND HEADER
MOV #MPXIDX,I
MOV HDWR(I),H
MOV #MPXHED,D
MOV #2,C
CALL @STROUT(H)
BR 10$
.ENDC ;NMPTYS
.IFNZ GOULDP
.SBTTL GOULD LPT OUTPUT (M.P. LEVEL)
.IIF Z DL10P, .ERROR GOULD LPT ONLY CODED FOR DL10
.ERR BY THE WAY, THESE ROUTINES DON'T WORK WORTH GUBBISH
GLPTYO: MOV GLPOIP,H ;GET NEXT BUFFER
CMP GB.STA(H),#%GBMP
BEQ 2$ ;BRANCH IF M.P. ACTIVE
BLT 1$ ;BRANCH IF IDLE BUFFER AVAIL
RET ;NO FREE BUFFERS
1$: CALL GLPBGB ;GOBBLE A BUFFER
2$: MOV GB.PNT(H),D
MOV GLPCTR,C ;SET UP BYTE COUNTER
MOV GLPGRF,GLPGF1 ;COPY ARG FROM 0 FOR SPEED
TST GLIMBF ;CHAR SAVED FROM LAST TIME?
BEQ GLPNCL
CLR GLIMBF ;YES, PRINT IT
MOVB GLIMBO,A
CALL GLPPUT
MOVB GLIMBO+1,A ;SECOND CHAR?
BEQ GLPNCL
CLR GLIMBO
CALL GLPPUT
;CHARACTER PROCESSING LOOP
;C HAS # CHARS YET TO GO, D HAS WHERE TO PUT THEM, H -> BUFFER
;A WILL HAVE CHAR
GLPNCL: MOV GLPPTR,A ;GET NEXT CHAR
TST GLPGF1
BNE GLPNRM ;GRAPHIC MODE, NO CHARACTER PROCESSING
CMP A,#177 ;ESCAPE?
BEQ GLPESC
CMP A,#40 ;CONTROL?
BGE GLPNRM ;NO, NORMAL PRINTING
CMP A,#14 ;CHECK FOR SPECIAL CONTROLS
BNE 10$
8$: CLR GLPROW ;START NEW PAGE
TST GLPCOL ;IN MIDDLE OF LINE?
BEQ 9$ ;NO, OK
CALL GLPBWW ;OTHERWISE, HAIR
CLR GLPFIL ;HACK HACK MAKE FF NEXT LINE
BR GLPNB1
9$: SETOM GB.FF(H)
BR GLPNXC
10$: CMP A,#12
BNE 12$
INC GLPROW
CMP GLPROW,#GLPRMX
BHIS 8$ ;SKIP OVER PERFORATION
TST GLPCOL
BNE GLPNBF ;IF NOT A BLANK LINE, FINISH BUFFER
INC GB.NL(H)
BR GLPNXC
12$: CMP A,#11
BNE 15$
13$: MOV #40,A ;TAB - SPACE OVER
CALL GLPPUT
BIT #7,GLPCOL
BNE 13$
BR GLPNXC
15$: CMP A,#15
BEQ GLPNXC ;IGNORE CR
CMP A,#33
BNE 16$
MOV #'$,A ;PRINT ALTMODE AS DOLLAR
BR GLPNRM
16$: BIS #100,A ;RANDOM CONTROL AS UPARROW, LETTER
MOVB A,GLIMBO+1
MOV #'^,A
CALL GLPPUT
MOVB GLIMBO+1,A
CLR GLIMBO
GLPNRM: CALL GLPPUT ;HERE FOR NORMAL CHARACTER
GLPNXC: DEC C ;HERE TO GOBBLE CHARACTER
BGT GLPNCL ;BRANCH IF MORE CHARS TO GO
BR GLPEND ;BUFFER EMPTIED
GLPNBF: CALL GLPBWW ;HERE TO ADVANCE TO NEXT BUFFER
GLPNB1: CMP GB.STA(H),#%GBIDL ;NEXT BUFFER AVAIL?
BNE GLPEN1 ;NO, STOP
CALL GLPBGB ;YES, GOBBLE IT
BR GLPNXC
GLPESC: DEC C ;HERE FOR TWO CHAR ESC SEQ
BEQ GLPEND ;-10 FORGOT 2ND CHAR, FLUSH
MOV GLPPTR,A ;GET & DECODE 2ND CHAR
CMP A,#105 ;EOF
BEQ GLPEOF
BR GLPNXC ;OTHER CHARS ARE IGNORED
GLPEOF: CLR GLPFIL
CLR GLPROW
CALL GLPBWW ;EOF, WRITE LAST BUFFER
GLPEN1: DEC C ;GOBBLE A CHARACTER
GLPEND: MOV C,GLPCTR ;HERE WHEN DONE, RELEASE 10'S BUFFER
CMP GB.STA(H),#%GBMP ;BUFFER ACTIVE AT M.P. LEVEL?
BNE 1$ ;IF NOT, DON'T CLOBBER GB.PNT
MOV D,GB.PNT(H) ;IF SO, REMEMBER AMT OF STUFF IN CURRENT BUFFER
1$: RET ;RETURN TO MAIN LOOP
;OUTPUT PRINTING CHAR IN A
GLPPUT: CMP D,GLPLIM ;LINE OVERFLOW?
BLO 5$ ;NO
CALL GLPBWW ;YES, DONE WITH THIS BUFFER
INC GLPROW ;OUGHT TO CHECK FOR PERFORATION, BUT...
CMP GB.STA(H),#%GBIDL ;MORE BUFFERS?
BNE 6$ ;NO
CALL GLPBGB
5$: MOVB A,(D)+ ;DROP CHAR IN BUFFER
INC GLPCOL ;AND ADVANCE COLUMN
RET
6$: MOVB A,GLIMBO ;NO BUFFERS, SAVE CHAR BEING PRINTED
SETOM GLIMBF ;SET FLAG SO WILL BE PRINTED NEXT TIME
TST (SP)+ ;STOP THE WORLD
BR GLPEN1
;GOBBLE IDLE BUFFER H -> FOR M.P. RETURNS GB.PNT(H) IN D.
GLPBGB: MOV #%GBMP,GB.STA(H) ;ACTIVATE AT M.P. LEVEL
CLR GB.FF(H) ;INIT THE BUFFER
CLR GB.NL(H)
CLR GLPCOL ;START LINE IN COLUMN 0
MOV H,D ;INIT INSERT POINTER
ADD #GB.DAT,D
MOV D,GB.PNT(H)
MOV H,GLPLIM ;SET UP MAX. VALUE OF GB.PNT
ADD #GB.LEN,GLPLIM
RET
;GIVE BUFFER H -> TO P.I. LEVEL
GLPBWW: BIT #1,D ;MUST BE EVEN NUMBER OF BYTES
BEQ 1$
CLRB (D)+
1$: PUSH A ;INTERFACE GETS BYTES IN WRONG ORDER
MOV P,A ;COMPUTE NUMBER OF WORDS IN LINE
SUB H,A
SUB #GB.DAT,A
ASR A
BNE 4$
CLR (D)+ ;CAN'T HAVE ZERO-LENGTH LINE
INC A
4$: MOV A,GB.PNT(H) ;SAVE WORD COUNT FOR P.I. LEVEL
2$: SWAB -(D)
SOB A,2$
POP A
TST GLPFIL ;IF STARTING NEW FILE,
BNE 5$
SETOM GLPFIL
SETOM GB.FF(H) ; BE SURE TO GET NEW PAGE
5$: MOV #%GBWRT,GB.STA(H) ;QUEUE TO P.I. LEVEL
MOV GB.NXT(H),H ;ADVANCE TO NEXT BUFFER
MOV H,GLPOIP
MASK 6 ;STOP P.I. LEVEL (HAVE TO LOCK OUT GLPBRK & CLKBRK)
TST GLPOAC ;PRINTER ON?
BNE 3$ ;YUP
MOV #%GCOFF,@#GLPCSR ;NO, CLEAR OLD STUFF IN INTERFACE
TST GLPGF1 ;AND PUT IN LOW-SPEED GRAPHIC MODE IF NECC
BEQ 6$
MOV #%GCGRF,@#GLPCSR
MOV #%GCLSL,@#GLPCSR ;LOW SPEED (COME ON, THIS IS ONLY A KL10!)
6$: MOV #%GCON,@#GLPCSR ;TURN IT ON
MOV #%GCION,@#GLPCSR ;TURN ON INTERRUPTS
SETOM GLPOAC
; PUSH @#PS ;FAKE AN INTERRUPT
; CALL GLPBRK ;IS THIS NECESSARY?
3$: UNMASK
RET
;GOULD LPT VARIABLES
GLPCOL: 0 ;CURRENT COLUMN NUMBER
GLPROW: 0 ;CURRENT ROW NUMBER
GLPRMX==67. ;NUMBER OF LINES PER PAGE
GLPLIM: 0 ;ADDRESS OF END OF CURRENT BUFFER
GLPOAC: 0 ;NON-ZERO => GOULD LPT P.I. ACTIVE
GLPGF1: 0 ;NON-ZERO => GOULD LPT IN GRAPHIC MODE
GLIMBO: 0 ;SAVE CHAR HERE WHEN RUN OUT OF BUFFERS
GLIMBF: 0 ;NON-ZERO => CHAR IN GLIMBO
GLPFIL: 0 ;NON-ZERO => IN MIDDLE OF A FILE
GLPTIM: 10. ;COUNT DOWN WHEN LOSING
GLPERR: 0 ;NON-ZERO => ERROR STATUS FROM P.I.
.ENDC ;GOULDP
.SBTTL T-300 DISK
.IFNZ T300P
;DISK UNIBUS REGISTERS
DSKCRA=176700 ;COMPLETION REGISTER A
%DAPON==100000 ;SPONTANEOUS COMPLETION DUE TO POWER-ON. DISK NUMBER
; IN LOW BITS OF COMMAND-COMPLETION REGISTER B
%DACQE==10000 ;CONSISTENCY ERROR IN COMMAND QUEUE
%DANXM==4000 ;NXM ERROR IN COMMAND QUEUE
%DAPAR==2000 ;PARITY ERROR IN COMMAND QUEUE
;LOW 2 BITS OF COMMAND COMPLETION REGISTER A AND
;COMMAND COMPLETION REGISTER B CONTAIN THE ADDRESS
;OF THE PARITY OR NXM ERROR
DSKCRB=176702 ;COMPLETION REGISTER B
DSKCSR=176704 ;COMMAND/STATUS REGISTER
%DCCPL==100000 ;COMMAND IS COMPLETE, RESET BY %DCACK. READ-ONLY
%DCDER==40000 ;"DMA ERROR", RESET ONLY BY SYSTEM RESET.
;1=NORMAL, 0=ERROR
;BITS 30004 ALWAYS ON
%DCMNT==4000 ;HOST-ADAPTOR MAINTENANCE MODE
%DCRST==2000 ;RESET. WRITE-ONLY.
%DCACK==1000 ;ACKNOWLEDGE COMMAND COMPLETION. WRITE-ONLY
%DCCMD==400 ;TAKE COMMAND FROM CTRA/CTRB. WRITE-ONLY
%DCRDY==200 ;READY TO TAKE A COMMAND. READ-ONLY
%DCTIE==100 ;COMMAND TRANSMISSION (%DCRDY) INTERRUPT ENABLE
%DCCIE==40 ;COMMAND COMPLETION (%DCCPL) INTERRUPT ENABLE
%DCPCY==20 ;POWER JUST CYCLED ON OR OFF. READ-ONLY
%DCPON==10 ;POWER ON. READ-ONLY
%DCDMA==2 ;DMA IN PROGRESS. READ-ONLY
%DCBOT==1 ;BOOT (READ DRIVE 0 SECTOR 0 INTO MEMORY 0). WRITE-ONLY
DSKCTA=176706 ;COMMAND TRANSMISSION A (ADDRESS OF RQB HIGH BITS)
DSKCTB=176710 ;COMMAND TRANSMISSION B (ADDRESS OF RQB LOW BITS)
;176714 DUPLICATES DSKCSR FOR UNKNOWN REASONS
;DISK REQUEST BLOCK. WE ONLY HAVE ONE SINCE NO SEEK OVERLAP.
RQBACT: 0 ;NON-ZERO IF REQUEST ACTIVE AND EXPECTING COMPLETION
RQBID: 0 ;RETURNED IN CCRB WHEN COMMAND COMPLETES
RQBSTS: 0 ;STATUS STORED BY 2561, COPIED INTO DSCSTS
RQBFLT: 0 ;FAULT CODE IN HIGH BYTE, BITS 1-0 HIGH BITS OF LINK ADDRESS
RQBLNK: 0 ;LINK ADDRESS TO NEXT RQB (MUST BE ZERO)
RQBCMD: 0 ;COMMAND CODE, COPIED FROM DSCCMD
RQBDRV: 0 ;UNIT NUMBER, COPIED FROM DSCDRV
RQBCYL: 0 ;CYLINDER NUMBER, COPIED FROM DSCCYL
RQBHED: 0 ;HEAD NUMBER, COPIED FROM DSCHED
RQBSEC: 0 ;SECTOR NUMBER, COPIED FROM DSCSEC
RQBWC: 0 ;POSITIVE WORD COUNT (ALWAYS 12.*256.)
RQBMA: 0 ;MEMORY ADDRESS (ALWAYS DSKBUF)
RQBMAH: 0 ;MEMORY ADDRESS HIGH (ALWAYS 0)
; BITS 1-0 BITS 17-16 OF ADDRESS. BIT 6 MA INCR INH
RQBID1: 0 ;RETURNS RECORD ID 1
RQBID2: 0 ;RETURNS RECORD ID 2
RQBMNT: .BLKW 27. ;DIAGNOSTIC DATA MAY BE RETURNED
;DISK BUFFER. HOLDS ENOUGH 12-BIT BYTES IN 16-BIT WORDS TO MAKE 1024. 36-BIT WORDS
DSKBUF: .BLKW 3.*1024.
;ROUTINE TO START DISK IF IT IS READY AND THERE IS A REQUEST.
DSKSTR: TST DSCREQ ;ANY REQUEST FROM 10?
BEQ 99$ ;NO, EXIT
CMP DSCCHK,#2561
BNE 99$ ;CHECK WORD WRONG, DON'T TOUCH DISK
TST RQBACT ;PREVIOUS OPERATION FINISHED?
BEQ 10$
BPT ;NO, MUST BE BUG IN 10?
10$: TSTB DSKCSR ;TEST IF READY FOR COMMAND TRANSMISSION
BPL 99$ ;NO, WAIT
CLR DSCDON ;YES, CLEAR 10/11 COMMUNICATION FLAGS
CLR DSCREQ
CLR RQBLNK ;SET UP RQB FROM 10'S PARAMETERS
MOV DSCCMD,RQBCMD
MOV DSCDRV,RQBDRV
MOV DSCCYL,RQBCYL
MOV DSCHED,RQBHED
MOV DSCSEC,RQBSEC
MOV #12.*256.,RQBWC
MOV #DSKBUF,RQBMA
CLR RQBMAH
CMP RQBCMD,#%DMWRT ;IF A WRITE COMMAND, MUST COPY DATA BUFFER
BNE 30$
MOV #DSKBUF,D
.REPT 4 ;TAKES 4 BYTE POINTERS TO DO IT
MOV #DSCPNT+<2*.RPCNT>,H
.REPT 3 ;EACH BYTE POINTER HAS 768 12-BIT BYTES
MOV #256.,C
CALL MOVHD
.ENDR
.ENDR
30$: CLR DSKCTA ;GIVE ADDRESS OF RQB TO 2561
MOV #RQBID,DSKCTB
SETOM RQBACT ;TELL INTERRUPT LEVEL INTERRUPT EXPECTED
MOV #%DCCMD+%DCCIE,DSKCSR ;GIVE COMMAND, ENABLE COMPLETION INTERRUPT
99$: RET ;DONE
;CALL HERE WHEN DISK INTERRUPTS
DSKBRK: PUSH <A,B,C,D,H,I> ;SAVE ALL REGISTERS
MOV DSKCSR,A
BIT #%DCPCY,A ;POWER CYCLED?
BNE 5$ ;YES, RESET CONTROLLER AND IGNORE INTERRUPT
BIT #%DCMNT,A ;NO, MAINTAINENCE MODE
BEQ 4$ ;OK
BPT ;BLEAH, MUST BE BROKEN
BR 5$
4$: BIT #%DCDER,A ;WHAT ABOUT UNIBUS ERROR
BNE 10$
BPT
5$: MOV #%DCRST,DSKCSR ;RESET THE CONTROLLER AND TURN OFF INTERRUPTS
TST RQBACT ;DID THIS LOSE IN THE MIDDLE OF A DISK OPERATION?
BEQ 99$ ;NO, DISMISS
MOV #%DFRST,A ;YES, GIVE ERROR STATUS
CLR B
BR 20$
10$: BIT #%DCCPL,A ;TEST FOR COMMAND COMPLETION
BPL 99$ ;NO, IGNORE INTERRUPT
MOV DSKCRA,A ;GET COMPLETION STATUS
MOV DSKCRB,B
MOV #%DCACK+%DCCIE,DSKCSR ;ACKNOWLEDGE COMPLETION, ENABLE MORE INTERRUPTS
TST RQBACT ;EXPECTED?
BEQ 99$ ;NO, IGNORE
BIT #%DAPON,A ;POWER-UP INDICATION?
BNE 99$ ;FOR NOW, IGNORE IT
BIT #%DACQE+%DANXM+%DAPAR,A
BEQ 30$ ;OK, NO COMMAND-QUEUE ERROR
MOV #%DCRST,DSKCSR ;RESET CONTROLLER (I DON'T KNOW IF IT NEEDS IT)
20$: MOV A,DSCFLT ;COMMAND-QUEUE ERROR, GIVE STATUS TO PDP10
MOV B,DSCSTS
BR 80$
30$: CLR DSCFLT ;CLEAR HIGH BYTE
MOVB RQBFLT+1,DSCFLT ;PICK UP FAULT CODE, PUT IN LOW BYTE
BEQ 35$ ;IF FAULT CODE IS NON-ZERO, THE THING MAY BE FROZEN,
MOV #%DCRST,DSKCSR ;SO RESET IT. OTHERWISE ERROR SEEMS TO HAPPEN OVER AND OVER
35$: MOV RQBSTS,DSCSTS ;GIVE STATUS TO PDP10
MOV RQBCYL,DSCCYL ;STORE BACK DISK ADDRESS, MAY BE USEFUL TO PDP10
MOV RQBHED,DSCHED
MOV RQBSEC,DSCSEC
BIT #%DMRED,RQBCMD ;IF COMMAND WAS READ, COPY BUFFER BACK
BEQ 80$
MOV #DSKBUF,D
.REPT 4 ;TAKES 4 BYTE POINTERS TO DO IT
MOV #DSCPNT+<2*.RPCNT>,H
.REPT 3 ;EACH BYTE POINTER HAS 768 12-BIT BYTES
MOV #256.,C
CALL MOVDH
.ENDR
.ENDR
80$: SETOM DSCDON ;SIGNAL PDP10 OPERATION IS COMPLETE
BIS #DLX10I,DLXCSR ;AND INTERRUPT THE PDP10
CLR RQBACT ;NO LONGER EXPECTING COMPLETION ON THE RQB
99$: POP <I,H,D,C,B,A> ;RESTORE REGISTERS AND EXIT INTERRUPT
RTI
.ENDC ;T300P
.SBTTL SET LINE PARAMETERS
;LINE INDEX IN I
;DH11 PARAM REG IN A
;BUFFER SIZE IN B
SPARAM: CMP I,#NFTTY
BGE 1$
BPT
1$: CMP I,#LASTTY
BLE 2$
BPT
2$: CMP B,#1. ;MINIMUM BUFFER SIZE ONE CHARACTER
BGE 3$
MOV #1.,B
3$: CMP B,#MAXBSZ ;MAXIMUM BUFFER SIZE <MAXBSZ> CHARACTERS
BLE 4$
MOV #MAXBSZ,B
4$: MOV B,BUFSIZ(I) ;SET AMOUNT OF BUFFER TO BE USED FROM NOW ON
MOV HDWR(I),H ;(BUT NO LONGER DO WE ATTEMPT DYNAMIC BUFFER ALLOCATION)
CMP H,#NLDHHX
BHI 5$
MASK 5 ;LINE IS A DH11, HAVE TO SET LINE PARAM REG
MOV DHLSEL(I),@DHSCR(H) ;SELECT THE LINE
MOV A,@DHLPR(H) ;GIVE LINE-PARAMETER REG TO DH11
UNMASK
5$: MOV A,LPRVAL(I) ;STORE LPR IN CASE SOMEONE IS CURIOUS
RET
.SBTTL DH11 INPUT INTERRUPT
.REPT NDHS
CONC DH,\.RPCNT+1,<IBK: JSR H,DHIBK>
2*.RPCNT
.ENDR
DHIBK: MOV (H),H ;PICK UP HARDWARE INDEX
PUSH <A,B,I>
1$: MOV @DHNRC(H),A ;RECIEVE A CHARACTER
BPL DHIEX ;EXIT INTERRUPT IF NO MORE CHARS
MOV A,I ;EXTRACT LINE NUMBER
SWAB I
BIC #177760,I
ASL I
ADD DHTYNO(H),I
.IFNZ NDHUN
CMP I,#NLDHTY ;IGNORE NON-EXISTENT LINES
BHI 1$
.ENDC
CALL @TTYIPC(I) ;CALL LINE HACKER
BR 1$ ;AND CHECK FOR MORE
DHIEX: POP <I,B,A,H>
RTI
;NORMAL DH11 INPUT
DHNRMI: BIT #%DXPAR,A
BEQ 1$ ;IGNORE IF PARITY ERROR
10$: RET
1$: BIT #%DXBRK,A ;IF BREAK,
BEQ RCV
TST AUTOSP(I) ;AND LINE WANTS AUTOSPEED-ON-BREAK FEATURE
BPL 10$
ASPMD: MOV #DHASP,TTYIPC(I) ;PUT IT IN AUTOSPEED MODE
MOV DHLSEL(I),@DHSCR(H) ;AND SET HARDWARE TO 1200 BAUD
MOV #023103,@DHLPR(H)
RET
;CHAR IN A RECEIVED FROM LINE IN I
RCV: BIC #177400,A ;8-BIT CHAR RECEIVE
RCV.FW: TST NO.ITS ;ENTER HERE FOR FULL WORD RECEIVE
BEQ 10$
21$: MOV #DWNMSG,A ;ITS DOWN, GIVE MESSAGE
12$: CALL GIVMSG
RET
10$: MOV #TYIRNG,B
CMP RINGCT(B),#TYIRSZ-2
BGT 11$
CALL PUT ;FIRST PUT THE CHARACTER
MOV I,A
ASR A
CALL PUT ;THEN THE TENNISH LINE NUMBER
RET
11$: MOV #IBOMSG,A ;INPUT BUFFER OVERFLOW
BR 12$
.IFNZ NMPTYS ;HANDLE INPUT FROM THE MULTIPLEXOR LINE
MPXINP: TST MPXENB
BEQ RCV
MOV MPXSEL,I ;CURRENT INPUT LINE
TSTB A ;SPECIAL CHAR?
BMI 1$
JMP @TTYIPC(I) ;NO, RECEIVE ON APPROP LINE
1$: MOV A,I ;SPECIAL CHAR, EXTRACT LINE#
BIC #177700,I
;FOLLOWING FEATURE COMMENTED OUT SINCE IT CAUSES 11 TO LOOP
; WHEN NEXT INPUT ARRIVES -- NOT OBVIOUS HOW TO FIX.
; CMP I,#77 ;SELECT NON-MULTIPLEX INPUT?
; BEQ 3$ ;YES, DO SO
ASL I
ADD #NFMPTY,I
CMP I,#LASTTY
BHI 2$ ;OUT OF RANGE, IGNORE
MOV I,MPXSEL ;INPUT SELECT, SAVE LINE#
2$: RET
3$: MOV #MPXIDX,MPXSEL ;SELECT PASS THROUGH
RET
.ENDC ;NMPTYS
;AUTOSPEED MODE COMES HERE WHEN CHAR RECIEVED
DHASP: BIC #177400,A ;CLEAR FRAMING ERR, ETC.
BEQ ASP10 ;11 0'S = 110 BAUD
CMP A,#200 ;7 0'S, 1 = 150 BAUD
BEQ ASP15
CMP A,#170 ;3 0'S, 4 1'S, 0 = 300 BAUD
BEQ ASP30
CMP A,#370 ;300/600 IS NOW RUBOUT, NOT I
BEQ ASP36
CMP A,#146 ;1 0, 2 1'S, 2 0'S, ... = 600
BEQ ASP60
CMP A,#340 ;5 0'S, 3 1'S ? MYSTERY TO ME
BEQ ASP60
CMP A,#015 ;CR = 1200
BEQ ASP120
CMP A,#215 ;CR WITH EITHER PARITY
BEQ ASP120
MOV A,#. ;SAVE GARBAGE FOR DEBUGGING
RET ;SOMETHING ELSE, IGNORE
ASP10: MOV #006307,A ;110 IN, 110 OUT, NO PARITY, 8 BITS, EXTRA STPBT
MOV #5,B
MOV #12200,-(SP)
BR ASPX
ASP15: MOV #012503,A ;150 IN, 150 OUT, NO PARITY, 8 BITS
MOV #7,B
MOV #13300,-(SP)
BR ASPX
ASP30: MOV #016703,A ;300 IN, 300 OUT, NO PARITY, 8 BITS
MOV #15.,B
MOV #14400,-(SP)
BR ASPX
ASP36: MOV #020703,A ;300 IN, 600 OUT, NO PARITY, 8 BITS
MOV #30.,B
MOV #14100,-(SP)
BR ASPX
ASP60: MOV #021003,A ;600 BAUD, NO PARITY, 8 BITS
MOV #30.,B
MOV #11100,-(SP)
BR ASPX
ASP120: MOV #023103,A ;1200 IN, 1200 OUT, NO PAR, 8 BITS
MOV #60.,B
MOV #15500,-(SP)
BR ASPX
ASPX: CALL SPARAM ;SET BUFFER SIZE AND HARDWARE SPEED
MOV I,A ;SET UP SET-SPEED COMMAND TO -10
ASR A
BIS (SP)+,A
TST TTYHNG(I) ;IF THIS IS NEW STATUS FOR 10,
BNE 11$
INC HNGSIG ;INDICATE STATUS WAITING
11$: MOV A,TTYHNG(I) ;SAVE THIS LINE'S LATEST STATUS
MOV #ASPACK,A ;ACKNOWLEDGE TO USER THAT HE WON
CALL GIVMSG
DEC TYPING(I) ;IF NO WAKEUP FOR 10, HIT CALL WHEN TYPING DONE
MOV NRMIPC(I),TTYIPC(I) ;AND TAKE LINE OUT OF AUTOSPEED MODE
RET
.SBTTL DH11 OUTPUT INTERRUPTS
.REPT NDHS
CONC DH,\.RPCNT+1,<OBK: JSR H,DHOBK>
2*.RPCNT
.ENDR
DHOBK: MOV (H),H ;GET HARDWARE UNIT NUMBER
BIT #DHSNXM,@DHSCR(H) ;IS THIS INTERRUPT DUE TO NXM?
BEQ 1$
BPT ;YES
1$: BIC #DHTDON,@DHSCR(H) ;HARDWARE KLUDGE TO MAKE INTERRUPTS WIN
PUSH <A,B,C,I>
MOV DHOAC(H),C ;SEE WHICH BAR BITS HAVE TURNED OFF
BIC @DHBAR(H),C
BIC C,DHOAC(H)
MOV DHTYNO(H),I
ADD #15.*2,I
2$: BIT DHLBIT(I),C
BEQ 4$
.IFNZ NMPTYS
CMP I,#MPXIDX
BNE 3$
CALL MPXDON
.ENDC ;NMPTYS
3$:
.IFNZ NDHUN
CMP I,#NLDHTY ;IGNORE NON-EXISTENT LINES
BHI 4$
.ENDC
CALL XMTDON
4$: SUB #2,I
CMP I,DHTYNO(H)
BGE 2$
DHOEX: POP <I,C,B,A,H>
RTI
XMTDON: TST TYPING(I) ;HERE WHEN OUTPUT FINISHES
BGT 1$ ;BRANCH IF -10 WANTS TO KNOW ABOUT IT
BEQ 3$ ;BRANCH IF NOTHING TO DO
MOV #32,A ;SEND A CALL
CALL RCV
BR 3$
1$: MOV I,A
ASR A ;PUT TENNISH LINE NUMBER INTO RING
MOV #TYORNG,B ;MAIN PROG LEVEL WILL LATER TELL -10
CALL PUT
3$: CLR TYPING(I)
RET
.IFNZ NMPTYS ;OUTPUT DONE ON MULTIPLEXED LINE
MPXDON: PUSH <C,D,H,I>
TST MPXOAC
BGE 1$
NEG MPXOAC ;SENT HEADER, NOW SEND DATA
MOV MPXOLN,A
MOV MPXPNT(A),D
MOV MPXNBT(A),C
CLR MPXNBT(A)
CALL @STROUT(H)
BR 9$
1$: MOV MPXOLN,I ;OUTPUT IS DONE ON THAT LINE NOW
ADD #NFMPTY,I
CALL XMTDON
CLR MPXOAC ;MPX IDLE
CALL STRMPX ;LOOK FOR NEW STUFF TO DO
9$: POP <I,H,D,C>
RET
.ENDC ;NMPTYS
.SBTTL DL11 INTERRUPTS
.REPT NDLS
CONC DL,\.RPCNT+1,<IBK: JSR H,DLIBK>
NFDLHX+<2*.RPCNT>
CONC DL,\.RPCNT+1,<OBK: JSR H,DLOBK>
NFDLHX+<2*.RPCNT>
.ENDR
DLIBK: MOV (H),H ;GET HARDWARE INDEX OF INTERRUPTING UNIT
PUSH <A,B,I>
MOV @DLKB(H),A ;GET RECEIVED CHARACTER
MOV DLTYNO(H),I ;GET LINE NUMBER RECEIVED ON
.IFNZ DTE20P
BNE 2$ ;ONLY T00 CAN RETURN TO KLDCP
BIT #20000,A ;IF BREAK KEY IS HIT
BEQ 1$
SETOM KLDCPF ;USER WANTS TO RETURN TO KLDCP
BR DLBKEX ;FOR ONE COMMAND LINE
1$: TST DDTMOD ;IF IN DDT MODE,
BEQ 2$
BIC #-200,A ; HANDLE INPUT DIFFERENTLY
MOV A,DDTCHR
BR DLBKEX
2$:
.ENDC ;DTE20P
CALL @TTYIPC(I)
DLBKEX: POP <I,B,A,H>
RTI
DLOBK: MOV (H),H ;GET HARDWARE INDEX OF INTERRUPTING UNIT
TST DLOAC(H)
BEQ DLBKX1 ;NOT SUPPOSED TO BE TYPING OUT, IGNORE INT
DEC DLBC(H) ;GOT ANY MORE CHARACTERS?
BLT DLBKX2 ;NO, GO GIVE OUTPUT DONE
MOV DLCA(H),-(SP) ;YES, GIVE NEXT CHARACTER
MOVB @(SP)+,@DLPB(H)
INC DLCA(H)
DLBKX1: POP H
RTI
DLBKX2: PUSH <A,B,I> ;OUTPUT DONE
MOV DLTYNO(H),I ;GET TTY INDEX OF INTERRUPTING LINE
CLR DLOAC(H) ;OUTPUT NO LONGER ACTIVE ON THIS LINE
CALL XMTDON
BR DLBKEX
.SBTTL CLOCK INTERRUPT
;NOTE - IT IS IMPORTANT THAT THIS BE AT A HIGHER INTERRUPT LEVEL THAN THE CHAOS NET
CLKBRK: SETOM WAKE ;WAKE UP MAIN LOOP
.IFNZ GOULDP
PUSH @#PS ;CHECK GOULD LPT
CALL GLPBRK ;(LOSES INTERRUPTS)
DEC GLPTIM ;TIME TO CHECK GOULD LPT?
BGT 13$ ;NOT YET
MOV #10.*60.,GLPTIM
BIT #%GSNRD,@#GLPCSR ;YES, LOSING?
BNE 14$ ;PROBABLY
CLR GLPERR ;PROBABLY NOT
BR 13$ ;(CAN'T TELL FOR SURE IF %GCON NOT DONE)
14$: MOV @#GLPCSR,GLPERR ;LPT LOSING, TELL 10
CALL GLPRST ;AND MAKE SURE BUFFERS DON'T CHOKE UP
.ENDC ;GOULDP
13$: PUSH <A,B,I>
.IFNZ NDMS ;MODEM SCANNER GETS SHUT OFF SOMEHOW
CLR A ;loop over the DM11s, turning them on
MOV #NDMS,B
259$: BIT #DMSCN,@DMCSR(A)
BEQ 14$
BIT #DMIEN,@DMCSR(A)
BNE 15$
14$: MOV #DMSCN+DMIEN,@DMCSR(A) ;ENABLE SCANNER INTERRUPTS
15$: TST (A)+ ;next DM11
SOB B,259$ ;until all DM11s done
.ENDC ;NDMS
.IFNZ CHAOSP ;WAKE-UP OUTPUT LINKS IN RE-TRANSMIT DELAY
MOV #CHXCHS,I
50$: MOV CHOHWR(I),A ;ADDRESS OF HARDWARE CSR
TST CHOSTS(I) ;IF ZERO, IS IDLE, DON'T WANT INTERRUPT ENABLE
BEQ 51$ ;NOTE THAT THIS RUNS MASKED HIGHER THAN CHAOS INT LVL
BIS #%CATEN,(A) ;RE-ENABLE INTERRUPT IF OFF
51$:
.IFNZ CHSBTB
BIT #%CATDN,(A) ;TRANSMIT-DONE?
BNE 59$
INC CHSIDL(I) ;NO, KEEP TIME-OUT
CMP CHSIDL(I),#60. ;IF TRANSMIT-DONE STUCK OFF FOR 1 SECOND,
BLO 59$
MOV #%CARST,(A) ; THEN RESET THE INTERFACE
; MOV #%CAREN+%CATEN,(A) ;INTERRUPT ENABLES WILL TURN THEMSELVES BACK ON IF NECESSARY!
INC CHSRST(I) ;COUNT NUMBER OF TIMES HAD TO DO THIS
59$:
.ENDC ;CHSBTB
.IFG CHAOSP-1
TST (I)+
CMP I,#CHXCHS+CHAOSP+CHAOSP
BLO 50$
.ENDC ;CHAOSP-1
DEC PULSAR ;TIME TO GENERATE TEST PACKET TO CHAOS NET?
BGT 66$ ;NOT YET
MOV PULSON,PULSAR ;RE-INITIALIZE COUNTER
.REPT CHAOSP ;YES, AWAKEN ALL TRANSMIT INTERRUPT SIDES
BIS #%CATEN,@CHOHWR+CHXCHS+<2*.RPCNT>
.ENDR
.IFNZ TEN11P
TST CHOSTS+CHXT11 ;AWAITING BUFFER FROM 10?
BNE 65$ ;YES, COUNT TIMEOUT
CLR T11TIM ;NO, RESET TIMEOUT
65$: INC T11TIM
.ENDC ;TEN11P
66$: DEC 4SEC ;TIME FOR 4-SECOND CLOCK?
BGT 90$
MOV #4*60.,4SEC ;YES
MOV #<NSUBNT-1>*2,I ;INCREMENT ROUTING COSTS
71$: TST SBNTYP(I) ;THIS GUY'S COSTS SUPPOSED TO INCREMENT?
BNE 72$ ;NOPE
CMP SBNCST(I),#1000 ;DON'T INCREMENT TOO HIGH AND OVERFLOW
BHIS 72$
INC SBNCST(I) ;YEP
72$: SUB #2,I
BPL 71$
DEC 15SEC ;TIME FOR 15-SECOND CLOCK? (REALLY 16)
BGT 90$
MOV #4,15SEC ;YES
.REPT CHAOSP ;TELL CABLES TO BROADCAST %CORUT PACKETS
SETOM CHXRTF+CHXCHS+<2*.RPCNT>
BIS #%CATEN,@CHOHWR+CHXCHS+<2*.RPCNT>
.ENDR
.IIF NZ ETHERP, SETOM CHXRTF+CHXETH ;TELL ETHERNET TO BROADCAST ROUTING
90$: ;CAN'T DO IT NOW BECAUSE WRONG INTERRUPT LEVEL
.ENDC ;CHAOSP
.IF DF NDVRBF
INC DVRTIM ;TIME OUT DOVER CONNECTION
CMP DVRTIM,#15.*60. ;IF IDLE FOR 15 SECONDS, FLUSH
BLO 15$
CLR DVRHST
CLR DVRMSK
15$: INC DVRRTR ;COUNT UP RETRANSMISSION COUNTER
.ENDC ;NDVRBF
.IFNZ NDMS ;GOT ANY TTYS WITH MODEM CONTROL?
MOV #NFTTY,I ;CHECK FOR HANGUPS
16$: TST DIALED(I) ;HANGUP IN PROGRESS ON THIS LINE?
BPL 17$ ;NO
INC DIALED(I) ;YES, TIMED OUT?
BMI 17$
CLR DIALED(I) ;YUP, LINE IS HUNG UP
MOV I,A ;TELL -10 ABOUT IT
ASR A
TST TTYHNG(I) ;IF THIS IS NEW STATUS FOR 10,
BNE 18$
INC HNGSIG ;INDICATE STATUS WAITING
18$: MOV A,TTYHNG(I) ;SAVE THIS LINE'S LATEST STATUS
17$: ADD #2,I
CMP I,#LASTTY
BLO 16$
.ENDC ;NDMS
POP <I,B,A>
ROR SWR ;LOW BIT OF SWITCHES => DDT
BCC CLKEX
BPT
CLKEX: RTI
.IFNZ NDMS
.SBTTL MODEM CONTROL
;;; hack multiple DM interrupt vectors
.REPT NDMS
CONC DM,\.RPCNT+1,<BRK: JSR H,DMBRK>
2*.RPCNT
.ENDR ;NDMS
DMBRK: PUSH <A,B,I>
MOV (H),A ;get the device offset in A
MOV @DMCSR(A),I ;GET ASSOCIATED TTY INDEX
BIC #177760,I ;gives us channel (0-17) on this DM11
;; now add <device # * 16.> to get offset into table for any DM
MOV A,B ;device offset in B, is 2*device number
ASL B
ASL B
ASL B ;multiply by 8 for offset in B
ADD B,I ;add to I for offset for this channel
ASL I ;now get word offset in I by shifting
;; get index into map between DM channels and TTY indices
MOV M2LMAP(I),I
BEQ 90$ ;EXIT IF THIS LINE NOT UNDER MODEM CONTROL
; TST @DMCSR(A) .SEE DMRNG
; BPL 10$
; TST DIALED(I) ;RINGING. IS LINE DIALED UP ALREADY?
; BNE 10$ ;YES, NOT SUPPOSED TO BE RINGING
; MOV #LINENB+LINDTR,@DMLSR(A) ;ANSWER THE PHONE
10$: BIT #LINCTS,@DMLSR(A) ;DO WE HAVE CLEAR-TO-SEND?
BEQ 20$ ;NO
TST DIALED(I) ;YES, WHAT WAS PREVIOUS STATE?
BEQ 13$ ;WAS OFF, THIS IS A DIALUP
BPL 90$ ;WAS ON, IGNORE
NEG DIALED(I) ;WAS HANGING UP, ABORT IT
BR 90$
13$: INC DIALED(I) ;LINE IS NOW DIALED UP
TST DMINI ;IF GETTING INITIAL STATE,
BNE 90$ ;DON'T HACK AUTOSPEED
TST AUTOSP(I) ;IF IT HAS AUTOSPEED,
BEQ 90$
MOV HDWR(I),H ;HACK THAT
CALL ASPMD
BR 90$
20$: TST DIALED(I) ;CTS DROPPED
BMI 90$ ;ALREADY KNOWN ABOUT, IGNORE
MOV #-HNGDLY,DIALED(I) ;OTHERWISE START HANGUP TIMEOUT
90$: BIC #DMDON,@DMCSR(A) ;RESTART SCANNER
POP <I,B,A>
POP H
RTI
.ENDC ;NDMS
.IFNZ GOULDP
.SBTTL GOULD PRINTER P.I. LEVEL
GLPBRK: BIT #%GSBSY,@#GLPCSR
BEQ 1$
RTI ;LPT BUSY, WAIT
1$: BIT #%GSDON,@#GLPCSR
BNE 2$
RTI ;LPT BUSY OTHER FLAVOR
2$: PUSH <A,B,H>
BIT #%GSERR,@#GLPCSR ;LPT LOSING?
BEQ GLPBR1
CALL GLPRST ;YUP, RESET THE BUFFERS
MOV @#GLPCSR,GLPERR ;AND TELL 10
GLPOFF: CLR GLPOAC ;HERE TO STOP P.I.
MOV #%GCIOF,@#GLPCSR
MOV #5000.,A ;LPT SOMETIMES BUSY FOR A WHILE
1$: BIT #%GSBSY,@#GLPCSR ;HAVE TO WAIT SO TONER PUMPS WILL
BEQ 2$ ;REALLY TURN OFF
SOB A,1$
2$: MOV #%GCOFF,@#GLPCSR
GLPEX: POP <H,B,A>
RTI
GLPFIN: MOV #%GBIDL,GB.STA(H) ;DONE WITH THIS BUFFER
MOV GB.NXT(H),H ;CHECK NEXT
MOV H,GLPOOP
GLPBR1: MOV GLPOOP,H ;CHECK ON BUFFERS
CMP GB.STA(H),#%GBDMA ;FINISH DMA XFER?
BEQ GLPFIN ;YES
CMP GB.STA(H),#%GBWRT ;QUEUED OR ALREADY ACTIVE AT P.I.?
BLT GLPOFF ;NO, STOP
MOV #%GBPI,GB.STA(H) ;YES, ACTIVATE IT AT P.I.
TST GB.FF(H) ;NEED FF?
BEQ 1$
MOV #%GCFF,@#GLPCSR ;YES
CLR GB.FF(H)
BR GLPEX
1$: TST GB.NL(H) ;NEED BLANK LINES?
BEQ 2$
DEC GB.NL(H) ;YES, GIVE ONE
MOV #%GCADV,@#GLPCSR
BR GLPEX
2$: MOV H,B ;SET UP TEXT ADDR
ADD #GB.DAT,B
MOV GB.PNT(H),A ;SET UP TEXT WORD COUNT
NEG A
MOV A,@#GLPWC
MOV B,@#GLPCA ;START XFER
MOV #%GBDMA,GB.STA(H) ;FLAG BUFFER ACTIVE AT DMA LEVEL
BR GLPEX
GLPRST: PUSH H
MOV #GLPBFF,H ;FLUSH ALL BUFFERS
MOV H,GLPOOP
MOV H,GLPOIP
3$: CLR (H)+
MOV (H),H
CMP H,#GLPBFF
BNE 3$
MOV #60.*10.,GLPTIM ;SET TIMEOUT
POP H
RET
.ENDC ;GOULDP
.IFNZ CHAOSP
.SBTTL CHAOSNET ROUTINES
;ALL ROUTINES ON THIS PAGE CALLED WITH INTERRUPTS MASKED, INDEX IN I.
;REFILL FROM CHAOS INTERFACE
CHSRFL: BIS #%CAREN,@CHIHWR(I) ;TURN ON RECEIVER INTERRUPTS
RET ;WILL NOTICE INPUT LATER
.IFNZ DL10P
;LOOPS BACK TO HERE WHEN DISCARDING A PACKET
DLCRF1: CMP (SP)+,(SP)+ ;POP <D,H>
POP A
INC DLCSS1(A) ;2 ;INDICATE BUFFER HAS BEEN COPIED
BIS #DLX10I,DLXCSR ;AND INTERRUPT THE PDP10
;DROP INTO DLCRFL
;REFILL FROM DL10
DLCRFL: CALL DLCCHK ;SEE IF DL10 IS DISABLED
BNE 99$ ;BRANCH IF YES
MOV #2,A ;CHECK BOTH 10 TO 11 BUFFERS SO CAN'T GET OUT OF PHASE WITH 10
10$: CMP DLCSS1(A),#1 ;10 SAYS BUFFER READY?
BEQ 11$ ;YES
SUB #2,A ;NO, TRY NEXT
BPL 10$
BR 99$ ;NONE READY
11$: PUSH A ;SAVE CURRENT 10 TO 11 BUFFER
ADD #DLCSP1,A ;OUTPUT READY, GET IT
MOV #DLCIBF,B ;COPY INTO BUFFER
.REPT PKHDW ;FIRST GET HEADER
MOV (A),(B)+
.ENDR
PUSH <A,B>
CALL CHSIHD ;PROCESS HEADER, GET LENGTH, DEST
BVS DLCRF1 ;BRANCH IF PACKET NO GOOD
POP <D,H>
PUSH C
SUB CHIHDL(I),C ;GET NUMBER OF DATA WORDS TO FOLLOW
CALL MOVHD ;MOVE THOSE WORDS
POP <C,A> ;RESTORE LENGTH, 10 TO 11 BUFFER NUMBER
INC DLCSS1(A) ;2 ;INDICATE BUFFER HAS BEEN COPIED
BIS #DLX10I,DLXCSR ;AND INTERRUPT THE PDP10
TST B ;SWAB IF NOT TO 10-COMPATIBLE DEST
CALL SWAB10
INC CHISTS(I) ;INDICATE BUFFER READY TO SEND
99$: RET
;TRANSMIT TO DL10 OUTPUT SINK
;REQUIRES I TO BE SET UP, SMASHES ALL REGS.
DLCXMT: CALL DLCCHK ;DL10 DISABLED?
BNE 70$ ;YES, DISCARD PACKET
MOV DLCRBN,A ;GET CURRENT 11 TO 10 BUFFER NUMBER
CMP DLCRS1(A),#1 ;BUFFER READY?
BNE 80$ ;NO, WAIT
MOV CHOINX+CHXDLC,D ;GET ADDRESS OF BUFFER TO BE SENT OVER
MOV CHILNG(D),C ;AND LENGTH
MOV CHIBFP(D),D
MOV A,H ;GET POINTER TO DL10 MAGIC IDPB WORD
ADD #DLCRP1,H
CALL MOVDH ;COPY WORDS INTO PDP10
INC DLCRS1(A) ;SIGNAL DATA AVAILABLE TO PDP10
BIS #DLX10I,DLXCSR ;AND INTERRUPT IT
MOV DLCNXT(A),DLCRBN ;SWITCH BUFFERS
70$: JMP CHSODN ;TRANSMISSION IS DONE ALREADY
80$: MOV #1,CHOSTS+CHXDLC ;TRANSMISSION AWAITING BUFFER FROM 10
RET
;CALL HERE WHEN DL10 INTERRUPTS, CLOBBERS ALL.
DLCWAK: MASK 5
TST CHOSTS+CHXDLC ;DL10 HUNG ON TRANSMIT?
BEQ 10$
MOV #CHXDLC,I ;YES, WAKE IT UP
CALL DLCXMT
10$: TST CHISTS+CHXDLC ;DL10 INPUT ACTIVE?
BNE 20$
MOV #CHXDLC,I ;NO, TRY TO GET SOME
CALL DLCRFL
TST CHISTS(I) ;GOT SOME?
BLE 20$
CALL CHSOUT ;YES, START TRANSMISSION
20$: CALL CHSRUN ;DO ANYTHING ELSE REQUIRED
UNMASK
RET
;RETURN 'NE' IF DL10 IS DISABLED, BASHES NOTHING.
DLCCHK: TST DLXOFF
BNE 99$
TST NO.ITS
BNE 99$
TST DLCINI ;RE-INITIALIZE?
BEQ 99$ ;NO, EVERYTHING IS OK.
CLR DLCRBN ;YES
TST CHOSTS+CHXDLC ;WAS OUTPUT HUNG ON DL10?
BEQ 90$
PUSH <A,B,C,D,I,H> ;YES, SIGNAL OUTPUT DONE ON DL10
MOV #CHXDLC,I
CALL CHSODN
POP <H,I,D,C,B,A>
90$: CLR DLCINI ;SIGNAL INIT DONE, RETURN 'EQ'
99$: RET
.ENDC ;DL10P
;FAST BLOCK MOVE
;THESE CAN MOVE AT MOST 256. WORDS
;MOV (H),(D)+
;SOB C,.-2
MOVHD: SUB #256.,C ;GET -#WDS LESS THAN MAXIMUM
ADD C,C ;CONVERT TO BYTES
SUB C,PC ;JUMP INTO MOVE TABLE
.REPT 256.
MOV (H),(D)+
.ENDR
RET
;MOV (D)+,(H)
;SOB C,.-2
MOVDH: SUB #256.,C ;GET -#WDS LESS THAN MAXIMUM
ADD C,C ;CONVERT TO BYTES
SUB C,PC ;JUMP INTO MOVE TABLE
.REPT 256.
MOV (D)+,(H)
.ENDR
RET
.IFNZ TEN11P
;REFILL FROM TEN-11 INTERFACE
T11RFL: CALL T11CHK ;CHECK FOR DISABLE
BNE 99$ ;BRANCH IF DISABLED
MOV T11IBP,A
TST T11IBA ;WAS INPUT BUFFER IN USE?
BEQ 10$
CLR (A)+ ;YES, INDICATE BUFFER IS NOW EMPTY
CLR (A)
CLR T11IBA
ADD #T11BFL-2,A ;ADVANCE POINTER
CMP A,#T11IBE
BLO 7$
MOV #T11IBF,A
7$: MOV A,T11IBP
10$: TST (A) ;INPUT BUFFER CONTAIN A PACKET?
BEQ 99$ ;NO
SETOM T11IBA ;YES, INPUT BUFFER NOW ACTIVE
ADD #8,A ;GET INPUT FROM PDP10
MOV A,CHIBFP+CHXT11 ;AS CURRENT INPUT BUFFER
CALL CHSIHD ;PROCESS THE HEADER
BVS T11RFL ;BRANCH IF PACKET NO GOOD
PUSH <A,B,C,H> ;COMPUTE CHECKSUM BEFORE SWABBING
INC C ;C GETS NUMBER OF 32-BIT WORDS
ASR C
CLR D ;CLEAR LOW WORD OF CHECKSUM
CLR H ;CLEAR HIGH WORD OF CHECKSUM
SUB #PKFCMS+1,PKFC(A) ;DECREMENT FWD COUNT (IS HIGH END OF WORD)
;FWD COUNT HAS TO BE PUT BACK FOR CHECKSUM COMPUTATION
21$: ADD (A)+,H ;ADD HIGH HALFWORD TO HIGH SUM
ADD (A)+,D ;ADD LOW HALFWORD TO LOW SUM
ADC H ;CARRY INTO HIGH SUM
MOV D,B ;NOW ROTATE RIGHT DOUBLE
ROR B
ROR H
ROR D
SOB C,21$
MOV T11IBP,A ;NOW COMPARE CHECKSUM
CMP H,4(A)
BNE 30$
CMP D,6(A)
BNE 30$
POP <H,C,B,A>
ADD #PKFCMS+1,PKFC(A) ;INCREMENT FWD COUNT (IS HIGH END OF WORD)
TST B ;SWAB IF NOT TO 10-COMPATIBLE DEST
CALL SWAB10
INC CHISTS(I) ;INDICATE BUFFER READY TO SEND
99$: RET
30$: POP <H,C,B,A> ;CHECKSUM ERROR
INC T11CKE ;COUNT CHECKSUM ERRORS
BR T11RFL ;AND IGNORE PACKET
;TRANSMIT TO TEN11 OUTPUT SINK
;REQUIRES I TO BE SET UP, SMASHES ALL REGS.
T11XMT: CALL T11CHK ;TEN11 DISABLED?
BNE 70$ ;YES, DISCARD PACKET
TST @T11OBP ;OUTPUT BUFFER EMPTY?
BNE 80$ ;NO, WAIT
MOV CHOINX+CHXT11,D ;GET ADDRESS OF BUFFER TO BE SENT OVER
MOV CHIBFP(D),B
MOV CHILNG(D),C ;AND LENGTH
MOV PKNBYT(B),A
BIT #1,A ;IF ODD NUMBER OF BYTES, CLEAR THE EXTRA ONE
BEQ 5$
BIC #PKNBMS,A
ADD B,A
CLRB PKDAT-1(A) ;NOTE, AT THIS POINT BYTES ARE SWAPPED
5$: MOV T11OBP,A ;COPY INTO TEN11 OUTPUT BUFFER
ADD #8,A
PUSH <H,C>
10$: MOV (B)+,(A)+
SOB C,10$
MOV (SP),C ;NOW COMPUTE CHECKSUM
INC C ;C GETS NUMBER OF 32-BIT WORDS
ASR C
BCS 11$
CLR (A)+ ;IF ODD NUMBER OF 16-BIT WORDS, CLEAR THE EXTRA ONE
11$: CLR D ;CLEAR LOW WORD OF CHECKSUM
CLR H ;CLEAR HIGH WORD OF CHECKSUM
MOV T11OBP,A
ADD #8,A
21$: ADD (A)+,H ;ADD HIGH HALFWORD TO HIGH SUM
ADD (A)+,D ;ADD LOW HALFWORD TO LOW SUM
ADC H ;CARRY INTO HIGH SUM
MOV D,B ;NOW ROTATE RIGHT DOUBLE
ROR B
ROR H
ROR D
SOB C,21$
MOV T11OBP,A ;STORE CHECKSUM INTO OUTPUT BUFFER
MOV H,4(A)
MOV D,6(A)
POP <C,H>
SETOM (A) ;SIGNAL PRESENCE OF PACKET TO PDP10
ADD #T11BFL,A ;ADVANCE POINTER
CMP A,#T11OBE
BLO 30$
MOV #T11OBF,A
30$: MOV A,T11OBP
70$: CLR T11TIM ;NO TIMEOUT, 10 IS TAKING PACKETS
JMP CHSODN ;TRANSMISSION IS DONE ALREADY
80$: MOV #1,CHOSTS+CHXT11 ;TRANSMISSION AWAITING BUFFER FROM 10
RET
;WHACK YOUR TEN11
T11WAK: MASK 5
MOV #CHXT11,I
CALL T11CHK ;IS 10 UP?
BNE 30$ ;IT'S DOWN, PUNT IT
TST CHOSTS(I) ;TEN11 HUNG ON TRANSMIT?
BEQ 10$
CALL T11XMT ;YES, WAKE IT UP
10$: TST CHISTS+CHXT11 ;TEN11 INPUT ACTIVE?
BNE 20$
MOV #CHXT11,I ;NO, TRY TO GET SOME
CALL T11RFL
TST CHISTS(I) ;GOT SOME?
BLE 20$
CALL CHSOUT ;YES, START TRANSMISSION
20$: CALL CHSRUN ;DO ANYTHING ELSE REQUIRED
UNMASK
RET
30$: TST CHOSTS(I) ;TRANSMITTING TO DEAD TEN-11?
BEQ 20$
CLR T11TIM ;YES, FLUSH IT
CALL CHSODN
BR 20$
;CHECK TEN-11 INTERFACE, DO RESET IF NECESSARY, RETURN 'NE' IF DISABLED.
;SMASHES NOTHING.
T11CHK: CMP T11TIM,#5*60. ;10 TAKING 5 SECONDS TO RESPOND?
BLO 5$
SETOM T11I10 ;YES, DECLARE IT DOWN, REINITIALIZE PROTOCOL
5$: TST T11I10 ;IS 10 DONE INITIALIZING?
BNE 99$ ;NO, DO NOTHING
TST T11I11 ;ARE WE SUPPOSED TO INITIALIZE?
BEQ 99$ ;NO, IT'S OK
MOV #T11OBF,T11OBP ;YES, REINITIALIZE POINTERS
MOV #T11IBF,T11IBP
PUSH A
MOV #T11OBF,A ;INITIALIZE INPUT AND OUTPUT BUFFER HEADERS
10$: CLR (A)+ ;CLEAR INTER-MACHINE SIGNAL WORD
CLR (A)+
ADD #T11BFL-4,A ;SKIP THE REMAINING WORDS
CMP A,#T11IBE
BLO 10$
CLR T11IBA ;IDLE THE INPUT
POP A
TST CHOSTS+CHXT11 ;WAS OUTPUT HUNG ON TEN11?
BEQ 90$
PUSH <A,B,C,D,H,I> ;YES, SIGNAL OUTPUT DONE ON TEN11
MOV #CHXT11,I
CALL CHSODN
POP <I,H,D,C,B,A>
90$: CLR T11I11 ;SIGNAL INIT DONE, RETURN 'EQ'
CLR T11I11+2
99$: RET
.ENDC ;TEN11P
;THIS ROUTINE PROCESSES THE HEADER OF PACKET IN INPUT BUFFER FOR SOURCE I
;RETURN DESTINATION OUTPUT SINK INDEX IN B (-1 IF THIS IS FOR US (PDP11 ITSELF)),
;PACKET BUFFER POINTER IN A, AND LENGTH IN WORDS IN C.
;RETURNS WITH OVERFLOW SET IF PACKET IS DISCARDED BECAUSE OF
;TOO MUCH FORWARDING, BAD ADDRESS, TOO BIG, CRUFTY, ETC.
;OTHERWISE RETURNS WITH MINUS INDICATOR SET IF PACKET DIRECTED TO 11.
CHSIHD: ADD #1,NPKSI(I) ;COUNT PACKETS IN FROM THIS SOURCE
ADC HPKSI(I)
MOV CHIBFP(I),A ;POINTER TO PACKET
TSTB (A) ;CHECK FOR MUPPET
BNE CHSIHB ;DISCARD, WE DON'T SUPPORT THEM
MOV #PKHDW,CHIHDL(I) ;SET HEADER LENGTH
ADD #PKFCMS+1,PKFC(A) ;INCREMENT FWD COUNT (IS HIGH END OF WORD)
BCS CHSIHB ;BRANCH IF FORWARDING LOOP
MOV PKNBYT(A),C ;GET BYTE COUNT
BIC #PKNBMS,C
CMP C,#DATMAX
BHI CHSIHB ;TOO LONG, LOSES
INC C ;MAKE WORD COUNT
ASR C
ADD CHIHDL(I),C ;ADD IN LENGTH OF HEADER
MOV C,CHILNG(I) ;SAVE FOR LATER USE
;; NOW ROUTE THIS PACKET
MOV #-1,B ;MAGIC INDEX MEANING "MYSELF"
MOV PKDHST(A),D ;GET DESTINATION ADDRESS
;HERE WE HAVE HAIR FOR MULTIPLE CHAOSNETS
.REPT CHAOSP
CONC <CMP D,#CHAD>,\.RPCNT ;ADDRESSED TO PDP11 ITSELF?
BEQ 50$ ;YES, LET CHSRUN HANDLE IT LATER
.ENDR ;CHAOSP
CMPB PKOP(A),#%CORUT ;ROUTING INFO PACKET?
BEQ 40$ ;YES, ADDRESS TO PDP11
TST USECBL ;SUPPOSED TO USE CABLE EVEN TO TALK TO SELF?
BEQ 20$
CMP I,#CHXCHS ;YES, IS THIS COMING FROM CABLE?
BHIS 20$ ;YES, ROUTE REGULAR WAY
MOV #CHXCHS,B ;NO, SEND TO SELF ON FIRST CABLE
MOV #CHADD,D
BR 39$
20$: MOVB PKDHST+1(A),B ;GET SUBNET ADDRESSED TO
CMP B,#NSUBNT
BLO 21$
CLR B ;OUT OF RANGE, USE 0
21$: ASL B ;MAKE INDEX INTO SUBNET TABLES
TST SBNTYP(B) ;IS THIS A DIRECT HARDWARE CONNECTION?
BGT 38$ ;YES, SEND TO IT
MOV SBNADR(B),D ;NO, GO VIA GATEWAY
BEQ CHSIRF ;HAVEN'T GOT A GATEWAY, AND BROADCAST CODE NOT WORKING YET
MOVB SBNADR+1(B),B ;GET SUBNET GATEWAY IS ON
ASL B ;MAKE INDEX INTO TABLES
CMP B,#NSUBNT*2
BHIS CHSIRF ;OUT OF RANGE, CAN'T GET THERE FROM HERE
TST SBNTYP(B) ;IS THIS A DIRECT CONNECTION?
BLE CHSIRF ;NO, CAN'T GET THERE FROM HERE (SHOULDN'T HAPPEN!)
38$: MOV SBNADR(B),B ;GET SINK INDEX
39$: MOV D,CHICBA(I) ;STORE CABLE ADDRESS OF IMMEDIATE DEST (GATEWAY)
.IIF NDF NDVRBF, 50$: ;IF NO DOVER, ALL TO-11 PACKETS COME HERE
40$: MOV B,CHIOUX(I) ;STORE SINK INDEX, SET INDICATORS
RET ;NOTE THAT MOV CLEARS OVERFLOW
.IF DF NDVRBF
50$: CMP PKDIND(A),DVRLIX ;DIRECTED TO DOVER?
BNE 40$ ;NO, TO 11
CMP PKSHST(A),DVRHST
BNE 40$ ;NOT DOVER-CONNECTED HOST
CMP PKSIND(A),DVRIDX
BNE 40$ ;RIGHT HOST, WRONG PROCESS
MOV #CHXDVR,B ;ROUTE PACKET TO DOVER GATEWAY
BR 40$
.ENDC ;NDVRBF
;HERE FOR ROUTING FAILURE. METER, RETURN WITH OVERFLOW SET.
CHSIRF: INC NPKSRF
MOV B,RFSBNT ;SAVE 2* SUBNET TRYING TO GET TO
;FALL INTO CHSIHB
;HERE WHEN CHSIHD SEES A GARBAGE PACKET. RETURN WITH OVERFLOW SET.
CHSIHB: ADD #1,NPKSBD(I) ;GOD-DAMN BRAIN-DAMAGE
ADC HPKSBD(I)
SEV
RET
;SWAB PACKET COMING FROM PDP-10 OR ETHERNET (BYTES LEFT TO RIGHT)
;IF GOING TO INCOMPATIBLE DESTINATION. CALL RIGHT AFTER CHSIHD.
SWAB10: BMI CHSSWB ;SWAB IF TO-11
CMP CHOXMT(B),#CHSXMT ;CHECK DESTINATION TYPE
BEQ CHSSWB ;PDP11 OR CHAOSNET, SWAB IT OUT
5$: RET ;PDP10 OR ETHERNET, LEAVE ALONE
;SWAB PACKET COMING FROM PDP-11 OR CHAOSNET (BYTES RIGHT TO LEFT)
;IF GOING TO INCOMPATIBLE DESTINATION. CALL RIGHT AFTER CHSIHD.
SWAB11=.
BMI 5$ ;RETURN IF TO-11
CMP CHOXMT(B),#CHSXMT ;CHECK DESTINATION TYPE
BEQ 5$ ;PDP11 OR CHAOSNET, LEAVE ALONE
;PDP10 OR ETHERNET, SWAB IT OUT
;DROPS THROUGH INTO CHSSWB
;THIS ROUTINE SWABS THE PACKET FOR THE SOURCE IN I.
;CALLED WITH NUMBER OF WORDS IN PACKET IN C.
;CLOBBERS A, C, AND D.
;SUITABLE FOR CALLING RIGHT AFTER CHSIHD RETURNS.
CHSSWB: MOV CHIBFP(I),A ;ADDRESS OF PACKET
SUB CHIHDL(I),C ;GET LENGTH OF DATA AREA IN WORDS
BLE 99$ ;EMPTY
MOVB PKOP(A),D ;GET OPCODE
BPL 5$ ;BRANCH IF NON-DATA
BIT #100,D ;CHECK FOR BINARY DATA
BEQ 10$ ;NO, GO SWAB
99$: RET
5$: TSTB CHSBIN(D) ;CONTROL, LOOK UP OPCODE
BNE 99$ ;BINARY, NO SWAB
10$: ADD CHIHDL(I),A ;POINT TO DATA AREA OF BUFFER
ADD CHIHDL(I),A ;BYTES, WATSON, BYTES!
SUB #PKTMXW,C ;GET -#WDS LESS THAN MAXIMUM
ADD C,C ;CONVERT TO BYTES
SUB C,PC ;JUMP INTO SWAB TABLE
.REPT PKTMXW
SWAB (A)+
.ENDR
RET
;BYTE TABLE INDEXED BY OPCODE, NON-ZERO IF BINARY
;BINARY OPERATIONS ARE 2 (%COOPN), 7 (%COSTS), 10 (%CORUT)
CHSBIN: .BYTE 0,0,2,0,0,0,0,7,10,0,0,0,0,0
.BYTE 0,0 ;SPARES IN CASE MORE OPCODES ADDED
.EVEN
;TRANSMIT PACKET FROM INPUT SOURCE I TO OUTPUT SINK, IN B.
;SMASHES ALL REGISTERS. CHISTS(I), CHIOUX(I), CHICBA(I) MUST BE ALREADY SET UP.
CHSOUT: TST B ;THIS DESTINED TO PDP11?
BMI CHSOUX ;YES, LET CHSRUN PICK IT UP LATER
TST CHOSTS(B) ;IS SINK BUSY?
BNE CHSOUX ;YES, CAN'T SEND NOW, WILL TRY AGAIN LATER
NEG CHISTS(I) ;NO, SET SOURCE STATUS TO CONNECTED
MOV I,CHOINX(B) ;CONNECT SINK TO SOURCE
MOV B,I ;SET UP SINK INDEX
ADD #1,NPKSO(I)
ADC HPKSO(I)
JMP @CHOXMT(I) ;GO START TRANSMISSION TO SINK
;CALL HERE WHEN OUTPUT IS DONE ON SINK I.
CHSODN: CLR CHOSTS(I) ;IDLE THE SINK
PUSH I
MOV CHOINX(I),I ;GET CORRESPONDING SOURCE
CLR CHISTS(I) ;IDLE IT
CALL @CHIRFL(I) ;TELL SOURCE IT'S DONE, TRY TO GET MORE INPUT
POP I
CHSOUX: RET
;CALL HERE AFTER EACH PACKET TRANSFER TO INITIATE AS MANY ADDITIONAL TRANSFERS
;AS POSSIBLE. BASHES ALL REGISTERS. ON DL10 AND TEN11, WE COULD ACTUALLY DO SEVERAL
;TRANSFERS BEFORE RETURNING.
CHSRUN:
.IF DF NDVRBF
CALL DVRRFL ;WAKE UP DOVER, MIGHT BE TIME TO RETRANSMIT
.ENDC ;NDVRBF
MOV #<NCHX-1>*2,I ;SCAN ALL INPUT SOURCES
CHSRN1: TST WAKE ;GIVE UP IF CLOCK HAS TICKED, LET TTYS RUN
BNE CHSOUX
TST CHISTS(I) ;IS THIS SOURCE LOOKING FOR A SINK?
BLE CHSRN3
CHSRN2: MOV CHIOUX(I),B ;GET SINK IT WANTS TO SEND TO
BMI FOR11 ;BRANCH IF FOR PDP11
TST CHOSTS(B) ;SINK AVAILABLE?
BNE CHSRN3 ;NO, LET INPUT SIT
CALL CHSOUT ;YES, ATTEMPT TO TRANSMIT
BR CHSRUN ;LOOK FOR MORE WORK
CHSRN3: SUB #2,I ;NEXT INPUT SOURCE
BGE CHSRN1
RET ;NOTHING LEFT TO DO
FOR11: MOV CHIBFP(I),A ;PACKET FOR PDP11, CHECK IT OUT
MOVB PKOP(A),B ;GET OPCODE
CMP B,#%CORUT ;IF ROUTING INFO, GOBBLE IT
BEQ CHARUT
CMP B,#%CORFC ;ALL WE KNOW IS RFC TO CERTAIN CONTACT NAMES
BNE FOR11J ;BARF AT JUNK PACKETS
CALL SERVE ;RUN THE SERVER
BEQ FOR11X ;IT DIDN'T LIKE IT
FOR11R: PUSH <PKDHST(A),PKDIND(A)> ;INTERCHANGE SOURCE AND DESTINATION
MOV PKSHST(A),PKDHST(A)
MOV PKSIND(A),PKDIND(A)
POP <PKSIND(A),PKSHST(A)>
CALL CHSIHD ;ROUTE
BVS FOR11X ;NO GOOD, FLUSH (SOURCE IN PACKET WAS WRONG)
CALL SWAB11 ;SWAB IF GOING TO 11-INCOMPATIBLE DEST
BR CHSRN2 ;FIRE IT OFF (CHISTS IS ALREADY 1)
FOR11X: CLR CHISTS(I) ;DISCARD THIS PACKET
CALL @CHIRFL(I)
BR CHSRUN ;LOOK FOR MORE WORK
;PACKET FROM RANDOM PLACE DIRECTED TO 11, TELL HIM TO GO AWAY
FOR11J: CMP B,#%COLOS ;DON'T BARF AT LOS PACKETS
BEQ FOR11X
MOV #<%COLOS*400>,(A)
MOV #6$-5$-1,PKNBYT(A)
MOV #5$,B
MOV A,C
ADD #PKDAT,C
1$: MOVB (B)+,(C)+
BNE 1$
BR FOR11R ;SEND OFF THE LOS
5$: .ASCIZ /Packet unrecognized by gateway-11/
6$: .EVEN
;ROUTING PACKET
CHARUT: MOV CHILNG(I),C ;GET NUMBER OF DATA WORDS
SUB #PKHDW,C
ASR C ;MAKE NUMBER OF 2 WORD PAIRS
BEQ FOR11X ;MIGHT BE ZERO-LENGTH
MOV A,D
ADD #PKDAT,D ;POINT TO START OF PACKET'S DATA
61$: MOV (D)+,B ;GET SUBNET BEING TALKED ABOUT
CMP B,#NSUBNT ;ONE WE KNOW ABOUT?
BHIS 62$ ;NO, FORGET IT
ASL B ;MAKE WORD INDEX
TST SBNTYP(B) ;IS THIS AN AUTO ROUTING TYPE SUBNET?
BNE 62$ ;NO, DON'T MUNG OUR FIXED ROUTING INFO
CMP (D),SBNCST(B) ;COMPARE COSTS
BHI 62$ ;NEW ONE WORSE (IF EQUAL, SWITCH TO EQUALIZE LOAD)
MOV (D),SBNCST(B) ;SAVE BEST COST
MOV PKSHST(A),SBNADR(B) ;AND HOST ADDRESS THIS CAME FROM AS BEST BET
62$: TST (D)+ ;SKIP COST
SOB C,61$
BR FOR11X ;DONE WITH PACKET
.SBTTL CHAOS NET SERVERS
;CALLED WITH PACKET IN A.
;MUST PRESERVE A,I.
;RETURN 'EQ' IF NO GOOD, 'NE' IF MODIFIED PACKET TO BE RETURNED TO SOURCE
;CURRENTLY WE SERVE THE FOLLOWING CONTACT NAMES:
; STATUS - RETURNS ANS WITH THE NAME OF THE MACHINE, LATER WILL HAVE OTHER DATA
; PULSAR - RETURNS ANS WITH DATA OF 1 BYTE, VALUE OF PULSON AS AN ASCII DIGIT,
; I.E. "0" MEANS OFF, "1" MEANS 60 PER SECOND, ETC.
; IF CONTACT NAME IN RFC IS FOLLOWED BY A SPACE AND AN ASCII DIGIT,
; SETS PULSON TO THAT STATUS.
; DOVER - DOVER PROTOCOL TRANSLATOR
;NOTE THAT WE DON'T USE THE MOST WINNING STRING COMPARE IN THE WORLD,
;THIS CODE ASSUMES IT DOESN'T MATTER WHAT HAPPENS IF AN RFC TO
;AN UNKNOWN CONTACT NAME IS DONE, AS LONG AS THE 11 DOESN'T CRASH.
SERVE: MOV #SRVTBL,B ;ADDRESS OF SERVER TABLE
10$: MOV (B)+,D ;ADDRESS OF CONTACT NAME FOR THAT SERVER
BEQ 99$ ;EXIT IF TABLE EXHAUSTED, 'EQ' IN COND CODE
MOV A,C
ADD #PKDAT,C ;ADDRESS OF CONTACT NAME IN THIS RFC
11$: TSTB (D) ;END OF STRING?
BEQ 20$ ;YUP, RUN THIS SERVER
CMPB (C)+,(D)+ ;DO STRING COMPARE
BEQ 11$ ;MATCHES
TST (B)+ ;DOESN'T MATCH, TRY NEXT
BR 10$
99$: RET
20$: JMP @(B)+ ;CALL SERVER, IT CAN RETURN EQ OR NE
SRVTBL: .WORD 1$,STSSRV ;STATUS - RETURN HOST NAME AND METERS
.WORD 2$,PLSSRV ;PULSAR - SET AND GET PULSAR RATE
.IIF DF NDVRBF, .WORD 3$,DVROPN ;DOVER - DOVER PROTOCOL TRANSLATOR
.WORD 0 ;END OF TABLE
1$: .ASCIZ /STATUS/
2$: .ASCIZ /PULSAR/
3$: .IIF DF NDVRBF, .ASCIZ /DOVER/
.EVEN
;SERVERS MUST PRESERVE A (PACKET), AND I, AND RETURN 'NE' IF TO BE SENT BACK TO SOURCE.
;NOTE THAT C POINTS AT THE NEXT BYTE AFTER THE CONTACT NAME
STSSRV: MOV A,B ;RFC TO "STATUS", CHANGE INTO ANS CARRYING APPROPRIATE DATA.
MOV #32.+<12.*NCHX>+<24.*CHAOSP>+<12.*ETHERP>,PKNBYT(A) ;SET BYTE LENGTH, CLEAR FORWARDING COUNT
ADD #PKDAT,B
MOV #HSTNAM,D ;SEND NAME OF HOST
MOV #32.,C
45$: MOVB (D)+,(B)+
SOB C,45$
CLR D ;NOW STORE METERING INFO FOR EACH SUBNET
50$: MOV CHXSBN(D),(B)+ ;STORE SUBNET NUMBER+400
MOV #4,(B)+ ;ASSUME NOT A CABLE
MOV NPKSI(D),(B)+
MOV HPKSI(D),(B)+
MOV NPKSO(D),(B)+
MOV HPKSO(D),(B)+
.IFNZ ETHERP
CMP D,#CHXETH ;ETHERNET HAS SOME OF THESE COUNTERS
BNE 55$
MOV #12.,-10.(B) ;THERE ARE 4 MORE DOUBLE-WORDS
MOV NPKSAB-CHXCHS(D),(B)+
MOV HPKSAB-CHXCHS(D),(B)+
CLR (B)+
CLR (B)+
MOV NPKSGB-CHXCHS(D),(B)+
MOV HPKSGB-CHXCHS(D),(B)+
MOV NPKSRL-CHXCHS(D),(B)+
MOV HPKSRL-CHXCHS(D),(B)+
BR 59$
.ENDC ;ETHERP
55$: CMP CHIRFL(D),#CHSRFL ;CHAOSNET CABLE?
BNE 59$ ;NO, THAT'S ALL
MOV #16.,-10.(B) ;YES, THERE ARE 6 MORE DOUBLE-WORDS
MOV NPKSAB-CHXCHS(D),(B)+
MOV HPKSAB-CHXCHS(D),(B)+
MOV NPKSLS-CHXCHS(D),(B)+
MOV HPKSLS-CHXCHS(D),(B)+
MOV NPKSGB-CHXCHS(D),(B)+
MOV HPKSGB-CHXCHS(D),(B)+
MOV NPKSRL-CHXCHS(D),(B)+
MOV HPKSRL-CHXCHS(D),(B)+
CLR (B)+ ;I DON'T KEEP TRACK OF BIT COUNT ERRS SEPARATELY
CLR (B)+
MOV NPKSBD(D),(B)+
MOV HPKSBD(D),(B)+
59$: TST (D)+
CMP D,#2*NCHX
BLO 50$
RETANS: MOVB #%COANS,PKOP(A) ;RETURN THIS PACKET TO SOURCE AS AN 'ANS'
RET ;NOTE CONDITION CODES HAVE 'NE'
PLSSRV: MOVB PKNBYT(A),C ;GET BYTE COUNT, SHOULD BE SMALL
CMP C,#8 ;6 FOR PULSAR, 1 FOR SPACE, 1 FOR CHARACTER
BLO 20$ ;NOT GIVEN AN ARGUMENT, JUST READ STATUS
MOVB PKDAT+7(A),C ;YES, GET THE ARGUMENT
SUB #'0,C ;CONVERT TO BINARY (CHEAPO!)
MOV C,PULSON ;CHANGE PULSON STATUS
20$: MOV #1,PKNBYT(A) ;SET BYTE LENGTH, CLEAR FORWARDING COUNT
MOV PULSON,C ;RETURN PULSAR STATUS
ADD #'0,C ;IN ASCII
MOVB C,PKDAT(A)
BR RETANS
.SBTTL CHAOSNET INTERRUPT HANDLER
;INTERRUPT HANDLER ENTRIES
.REPT CHAOSP
CONC CHS,\.RPCNT,BK:
JSR I,CHSBRK
CHXCHS+<.RPCNT*2>
.ENDR
;SUBROUTINE TO ENABLE CHAOSNET INTERFACE IN H,I TO RECEIVE NEXT PACKET
CHINXT: MOVB 1(H),A ;GET CSR BITS 9-12 (LOST COUNT)
ASR A
BIC #-20,A
ADD A,NPKSLS-CHXCHS(I)
ADC HPKSLS-CHXCHS(I)
BIS #%CARCL+%CAREN,(H) ;MAKE READY TO RECEIVE ANOTHER MESSAGE
RET
;COMMON CHAOS INTERRUPT ROUTINE
CHSBRK: MOV (I),I ;GET SOURCE/SINK INDEX
PUSH <A,B,C,D,H> ;SAVE ALL REGISTERS
MOV CHIHWR(I),H ;GET HARDWARE ADDRESS
MOV (H),A .SEE CH%CSR ;GET CSR
BPL CHSBK1 ;TEST RECEIVE DONE, BRANCH IF NOT
.SEE %CARDN ;PALX SCREWS UP IF THIS IS ON PREVIOUS LINE!
TST CHISTS(I) ;MAKE SURE INPUT BUFFER IS IDLE
BNE CHSBK1 ;BUSY, DON'T LOOK AT RECEIVE DONE NOW
BIT #%CAERR,A ;CRC ERROR?
BNE CHICRC ;JUMP IF YES
MOV CH%RBC(H),C ;BIT COUNT -1
SUB #47.,C ;ADD 1, THEN SUBTRACT 3*16. FOR HARDWARE WORDS
.IREPT 4, ASR C ;CONVERT TO NUMBER OF WORDS
CMP C,#256.
BHI CHIFLS ;THIS CAN ONLY HAPPEN IF HARDWARE BROKEN
ADD #CH%RBF,H ;POINT H TO RECEIVE DATA REG
MOV CHIBFP(I),D ;COPY PACKET INTO BUFFER
CALL MOVHD
TST (H) ;READ OUT THE 3 HARDWARE LEADER WORDS
CMP (H),(H)
SUB #CH%RBF,H ;RESTORE H
BIT #%CAERR,(H) ;WAS IT READ CORRECTLY OUT OF RAM?
BNE CHIGBG ;NO, GARBAGE
CMP CH%RBC(H),#7777 ;WAS PACKET CORRECT LENGTH?
BNE CHIGBG ;NO, GARBAGE
CALL CHINXT ;DONE WITH HARDWARE, ENABLE FOR NEXT
CALL CHSIHD ;PROCESS HEADER, GET LENGTH, DEST
BVS CHIFL0 ;BRANCH IF NO GOOD
CALL SWAB11 ;SWAB IF NOT GOING TO 11-COMPATIBLE DEST
INC CHISTS(I) ;INDICATE BUFFER READY TO SEND
PUSH I
CALL CHSOUT ;SEND IT OUT
POP I
MOV CHIHWR(I),H ;RESTORE H
TST CHISTS(I) ;INPUT BUFFER STILL BUSY?
BEQ CHSBK1
BIC #%CAREN,(H) ;YES, CLEAR RECEIVE INTERRUPT ENABLE
BR CHSBK1 ;GO CHECK ON OUTPUT SIDE
;HERE WHEN A PACKET WAS RECEIVED WITHOUT ERROR, BUT AFTER
;READING OUT OF THE RAM, CRC ERROR WAS SET. EITHER THE
;PACKET WAS THE WRONG LENGTH, OR THE RAM FAILED, OR THE
;HARDWARE RANDOMLY CLOBBERED IT.
;WE ALSO GET HERE IF THE BIT COUNT WAS NOT -1 AFTER ALL WORDS WERE READ.
CHIGBG: ADD #1,NPKSRL-CHXCHS(I) ;LOG THE ERROR
ADC HPKSRL-CHXCHS(I)
MOV H,CHSRLH
MOV CH%RBC(H),CHSRLC
BR CHIFLS ;GO RESET RECEIVER AND CHECK OUTPUT STATUS
;HERE WHEN A PACKET IS RECEIVED WITH A CRC ERROR. DISCARD IT,
;BUT ALSO SAVE IT IN CHSGBF, CHSGBH, CHSGBS, CHSGBC FOR DEBUGGING (IF FTGARB).
CHICRC: ADD #1,NPKSGB-CHXCHS(I)
ADC HPKSGB-CHXCHS(I)
.IFNZ FTGARB
MOV H,CHSGBH
MOV (H),CHSGBS
MOV CH%RBC(H),CHSGBC
ADD #CH%RBF,H
MOV #CHSGBF,D
MOV #PKMAX,C
CALL MOVHD
SUB #CH%RBF,H ;DROP INTO CHIFLS
.ENDC ;FTGARB
;HERE TO IGNORE AN INPUT PACKET AND ENABLE HARDWARE FOR NEXT
CHIFLS: CALL CHINXT
CHIFL0: INC NPKSIG
;HERE TO CHECK ON TRANSMIT SIDE
CHSBK1: TSTB (H) .SEE %CATDN ;TRANSMIT DONE?
BPL CHSBKX ;NO, EXIT
.IFNZ CHSBTB
CLR CHSIDL(I) ;CLEAR TRANSMIT-DONE TIME-OUT
.ENDC ;CHSBTB
MOV CHOSTS(I),A ;WAS OUTPUT IN PROGRESS?
BEQ CHSBK6 ;NO, LOOK FOR OUTPUT
CMP A,#2 ;TRANSMIT ABORT DELAY COMPLETED?
BEQ 10$
BIT #%CATAB,(H) ;NO, TRANSMIT ABORTED?
BEQ CHSBK4 ;NO
ADD #1,NPKSAB-CHXCHS(I) ;YES, METER IT, AND SET CHOSTS TO
ADC HPKSAB-CHXCHS(I)
INC CHOSTS(I) ;2 IF THIS IS FIRST TIME, OR 0 IF SECOND TIME
BEQ CHSBK4 ;LOST TWICE IN A ROW, GIVE UP
BR CHSBK5 ;TURN OFF INTERRUPT, DELAY FOR A WHILE
10$: MOV #-1,CHOSTS(I) ;TRANSMIT ABORT DELAY COMPLETED, SET CHOSTS TO -1
CALL CHSXM0 ;INITIATE RE-TRANSMISSION (CHOSTS ALREADY SET)
BR CHSBKX ;DISMISS
CHSBK4: CALL CHSODN ;OUTPUT DONE
CHSBK6: PUSH I
CALL CHSRUN ;INITIATE MORE TRANSFERS
POP I
TST CHOSTS(I) ;DID IT INITIATE TRANSMISSION?
BNE CHSBKX ;YES, LEAVE INTERRUPT ENABLED.
MOV CHOHWR(I),H ;RESTORE H
TST CHXRTF(I) ;TIME TO BROADCAST ROUTING INFO?
BNE CHORUT ;YES
TST PULSON ;IS THIS FEATURE TURNED ON?
BEQ CHSBK5 ;NO, FLUSH
CMP PULSAR,PULSON ;NOTHING TO DO. TIME FOR A TEST MESSAGE?
BNE CHSBK5 ;NOPE, GO IDLE
MOV #52525,CH%WBF(H) ;WRITE A PACKET OF 3 HEADER WORDS, 0, 52525
CLR CH%WBF(H)
MOV #-1,CH%WBF(H) ;TO HOST -1, WHICH IS NON-EXISTENT
CHSBK7: TST CH%XMT(H) ;INITIATE TRANSMISSION, DON'T ENABLE INTERRUPT
CHSBK5: BIC #%CATEN,(H) ;GO IDLE, CLEAR TRANSMIT INTERRUPT ENABLE
;HERE TO EXIT FROM CHAOS INTERRUPT. RESTORE REGS AND RETURN FROM INT
CHSBKX: POP <H,D,C,B,A,I>
RTI
.IIF NZ CH%WBF-CH%MYN, .ERR FOO CODE ASSUMES CH%WBF = CH%MYN
;BROADCAST A PACKET FULL OF ROUTING INFO, SINCE WE ARE MORE OR LESS A GATEWAY
CHORUT: MASK 6 ;INHIBIT CLOCK INTERRUPTS SO COSTS DON'T CHANGE
ADD #CH%WBF,H ;ADDRESS WRITE BUFFER
MOV #%CORUT*400,(H) ;OPCODE
MOV #2*<NSUBNT-1>,A ;COUNT SUBNETS WHICH WE KNOW ANYTHING ABOUT (REASONABLE COST)
CLR B
5$: CMP SBNCST(A),#1000
BHIS 6$
ADD #4,B ;THIS ONE WILL GENERATE 2 WORDS
6$: SUB #2,A
BPL 5$
MOV B,(H) ;BYTE COUNT
CLR (H) ;DESTINATION
CLR (H) ;..
MOV (H),(H) ;SOURCE = CH%MYN
CLR (H) ;SOURCE INDEX
CLR (H) ;PACKET NUMBER
CLR (H) ;ACK NUMBER
MOV #2*<NSUBNT-1>,A ;GO THROUGH SUBNET TABLES
MOVB 1(H),C ;GET SUBNET THIS IS GOING OUT ON
ASL C
MOV SBNCST(C),C ;GET COST OF GETTING TO US FROM GUY WHO RECEIVES THIS
10$: CMP SBNCST(A),#1000 ;WAS THIS ONE INCLUDED IN BYTE COUNT?
BHIS 11$ ;NO, DON'T PUT IT IN PACKET
MOV A,B ;FIRST WORD IS SUBNET NUMBER
ASR B
MOV B,(H)
MOV SBNCST(A),B ;SECOND WORD IS COST
ADD C,B ;WHICH MUST INCLUDE COST OF GETTING TO US
MOV B,(H)
11$: SUB #2,A ;NEXT SUBNET
BPL 10$
CLR (H) ;BROADCAST THIS PACKET
SUB #CH%WBF,H ;RESTORE H
CLR CHXRTF(I) ;CLEAR REQUEST FOR ROUTING PACKET
UNMASK
BR CHSBK7 ;FIRE IT OFF, DON'T ENABLE TRANSMIT-DONE INTERRUPT
;INITIATE TRANSMISSION ON CHAOS INTERFACE
;CALL WITH SINK NUMBER IN I, AT PI LEVEL OR MASKED. BASHES ALL REGS.
CHSXMT: INC CHOSTS(I) ;SET CHOSTS TO 1, TRANSMIT STARTING
CHSXM0: MOV CHOHWR(I),H ;GET HARDWARE ADDRESS
MOV CHOINX(I),B ;GET SOURCE SUPPLYING THE PACKET
MOV CHIBFP(B),D ;GET PACKET ADDRESS
ADD #CH%WBF,H ;ADDRESS THE WRITE BUFFER
MOV CHILNG(B),C ;GET WORD COUNT
CALL MOVDH ;COPY INTO HARDWARE
MOV CHICBA(B),(H) ;STORE CABLE DESTINATION
SUB #CH%WBF,H ;RESTORE H
TST CH%XMT(H) ;TRIGGER TRANSMISSION
BIS #%CATEN,(H) ;ENABLE DONE INTERRUPT
RET ;PI LEVEL WILL PICK UP OUTPUT
.ENDC ;CHAOSP
.IFNZ ETHERP
.SBTTL ETHERNET SUPPORT
;ENABLE NEXT ETHERNET PACKET TO COME IN.
;SINCE WE ONLY HAVE ONE BUFFER, THIS SETS UP THE TRANSFER RATHER
;THAN JUST ENABLING THE INTERRUPT AS THE CHAOSNET DOES.
;THAT WOULDN'T WORK ANYWAY, BECAUSE THE HARDWARE IS SO TOTALLY BRAIN-DAMAGED.
ETHRFL: MOV CHIHWR(I),H
ADD #10,H
MOV #-<PKTMXW-ETHHDW+1>,(H)+ ;- WORD COUNT, +1 FOR HARDWARE BUG
MOV #ETHIBF+<ETHHDW*2>,(H)+ ;BUFFER ADDRESS
MOV #101,(H) ;START, INTERRUPT-ENABLE
RET
;INCOMING PUP TOO BIG. WE DON'T HAVE FRAGMENTATION, SO SEND A PUP ERROR REPORT
ETHBIG: MOV #ETHIBF+PKDAT,A ;COPY PUP HEADER INTO DATA FIELD
MOV A,C
MOV #ETHIBF+PKDAT+20.,B
.IREPT 10.,< MOV (A)+,(B)+ >
MOV #517.,(B)+ ;PACKET TOO LARGE ERROR
MOV #DATMAX,(B)+ ;MAX NUMBER OF BYTES ALLOWED
MOV #50$,A
5$: MOVB (A)+,(B)+ ;ASCII MESSAGE
BNE 5$
INC B ;MESSAGE LENGTH IS EVEN. INCLUDE CHECKSUM IN COUNT.
SUB #ETHIBF+PKDAT,B ;GET PUP LENGTH
MOV B,(C)+ ;BUILD PUP HEADER NOW
MOV #4,(C)+ ;PUP TYPE = ERROR
CMP (C)+,(C)+ ;PUP ID SAME
.IREPT 3,< MOV 6(C),(C)+ > ;DESTINATION = ORIGINAL SOURCE
MOV #<ETHSBN*400+ETHHSN>,(C)+ ;SOURCE = ME
.IREPT 2,< CLR (C)+ > ;SOURCE PORT ZERO
CALL ETHOUT ;TRANSMIT
JMP ETHINX ;DISMISS
;The ascii message. This isn't as destroyed as it looks.
50$: .ASCIZ/UP Pot oalgr eotf tii n ahCoanstep caek.t/
.EVEN
;INPUT INTERRUPT
ETHIBK: PUSH <A,B,C,D,H,I>
MOV #CHXETH,I
MOV CHIHWR(I),H
MOV 14(H),A ;PICK UP STATUS
CLR 14(H) ;CLEAR RECEIVE INTERRUPT ENABLE
CMP ETHIBF+PKDAT-2,#1000 ;TYPE = PUP?
BNE ETHIIX ;NO, IGNORE PACKET
TST 10(H) ;CHECK RESIDUAL WORD COUNT
BEQ ETHBIG ;PACKET TOO BIG, RESPOND WITH PUP ERROR
TST A ;CHECK COMBINED INPUT ERRORS BIT
BMI 70$ ;ERROR, IGNORE PACKET
MOV ETHIBF+PKDAT+10,A ;GET DESTINATION HOST
BEQ 5$ ;AND SEE IF BROADCAST OR SELF
CMP A,#<ETHSBN*400+ETHHSN>
BNE 11$ ;NO, ROUTE AS REGULAR MESSAGE
5$: CMPB ETHIBF+PKDAT+2,#1 ;PUP TYPE = ECHO-ME?
BEQ ETHECO ;YES, ECHO IT (MAYBE TAKE THIS OUT AFTER 11 DEBUGGED)
CMPB ETHIBF+PKDAT+2,#200 ;GATEWAY INFORMATION REQUEST?
BNE 10$
TST ETHIBF+PKDAT+12 ;NOT REALLY UNLESS DESTINATION SOCKET IS 2
BNE 10$
CMP ETHIBF+PKDAT+14,#2
BNE 10$
TST CHISTS+CHXEGT ;PSEUDO DEVICE AVAILABLE?
BNE ETHIIX
MOV #ETHIBF+PKDAT+4,A ;YES, SEND HIM SOME INFO
MOV #EGTPID,B
.IREPT 2,< MOV (A)+,(B)+ > ;COPY PUP ID
ADD #6,A ;COPY SOURCE HOST AND SOCKET INTO DESTINATION
.IREPT 3,< MOV (A)+,(B)+ >
CALL ETHRT1
MOV #CHXETH,I ;I CLOBBERED BY ETHRT1
BR ETHIIX
10$: TST A ;DON'T HARASS REST OF NET WITH BROADCASTS
BEQ ETHIIX
11$: MOV #ETHIBF+PKDAT,A ;CHECK THE CHECKSUM
CALL PUPCKT
BNE 60$ ;BAD, COUNT AS RAM ERROR
.IF DF NDVRBF
CMP ETHIBF+PKDAT+10,DVRHST ;SEE IF ADDRESSED TO DOVER USER
BNE 12$
CMP ETHIBF+PKDAT+14,DVRIDX
BNE 12$
CALL DVRPUP ;YES, PROCESS
MOV #CHXETH,I
BR ETHIIX
.ENDC ;NDVRBF
;TRANSLATE PUP AND SEND TO CHAOSNET
12$: MOV #ETHIBF,A ;FILL IN CHAOSNET HEADER
MOV #<%COUNC*400>,(A)+ ;PKOP
MOV ETHIBF+PKDAT+0,B ;PKNBYT (TOTAL PUP LENGTH = CHAOS DATA LENGTH)
INC B ;ROUND UP TO AN EVEN NUMBER
ASR B
ASL B
MOV B,(A)+
MOV ETHIBF+PKDAT+10,(A)+ ;PKDHST
MOV ETHIBF+PKDAT+14,(A)+ ;PKDIND (LOW HALF OF PUP PORT)
MOV ETHIBF+PKDAT+16,(A)+ ;PKSHST
MOV ETHIBF+PKDAT+22,(A)+ ;PKDIND (LOW HALF OF PUP PORT)
MOV ETHIBF+PKDAT+6,(A)+ ;PKPKN (LOW HALF OF PUP ID)
MOV #100001,(A)+ ;PKACN = PROTOCOL NUMBER
CALL CHSIHD ;PROCESS THIS HEADER, GET LENGTH, DEST
BVS ETHIIX ;IGNORE IF NO GOOD
CALL SWAB10 ;SWAB IF NOT GOING TO 10-COMPATIBLE DEST
INC CHISTS(I) ;INDICATE BUFFER READY TO SEND
CALL CHSOUT ;SEND IT OUT
BR ETHINX ;ETHRFL WILL BE CALLED WHEN NECESSARY
60$: ADD #1,NPKSRL-CHXCHS(I) ;COUNT ERRORS (SOFTWARE CHECKSUM)
ADC HPKSRL-CHXCHS(I)
BR ETHIIX
70$: ADD #1,NPKSGB-CHXCHS(I) ;COUNT ERRORS (HARDWARE CHECKSUM)
ADC HPKSGB-CHXCHS(I)
ETHIIX: CALL ETHRFL ;AND READ ANOTHER PACKET
ETHINX: POP <I,H,D,C,B,A>
RTI
;ETHERNET PUP ECHO PROTOCOL
ETHECO: MOV #ETHIBF+PKDAT+10,A ;INTERCHANGE SOURCE AND DESTINATION
MOV A,B ;I DON'T BOTHER CHECKING CHECKSUM, BUT I DO GENERATE IT
.IREPT 3, PUSH (A)+
.IREPT 3,< MOV (A)+,(B)+ >
.IREPT 3, POP -(A)
MOV #<ETHSBN*400+ETHHSN>,(A) ;FIX SOURCE TO BE ME
INCB ETHIBF+PKDAT+2 ;SET PUP TYPE = 2 (I AM AN ECHO)
CALL ETHOUT ;SEND BACK OUT ON THE ETHERNET
BR ETHINX
;GENERAL PURPOSE ROUTINE FOR TRANSMITTING INTERNALLY-GENERATED PUPS TO
;THE ETHERNET. FIXES THE DESTINATION ADDRESS (THIS IS HOW OTHER
;HOSTS FIGURE OUT WHAT SUBNET THEY ARE ON!), COMPUTES THE PUP CHECKSUM,
;AND INTERFACES TO THE PACKET SWITCH. CALLED WITH SOURCE INDEX IN I.
;CALL THIS WITH A PACKET THAT ALREADY HAS ITS BYTES IN ETHERNET ORDER.
;BASHES ALL REGISTERS.
ETHOUT: MOV CHIBFP(I),A
ADD #PKDAT,A ;ADDRESS OF PUP
TST 10(A) ;ONLY IF NOT BROADCASTING,
BEQ 10$
TSTB 11(A) ;DESTINATION ADDRESS HAVE NETWORK NUMBER?
BNE 10$
MOVB #ETHSBN,11(A) ;NO, PUT IT IN
10$: CALL PUPCKS ;INSERT CHECKSUM
MOV #CHXETH,B
MOV B,CHIOUX(I)
INC CHISTS(I)
JMP CHSOUT
;INITIATE TRANSMISSION ON ETHER INTERFACE
;CALL WITH SINK NUMBER IN I, AT PI LEVEL OR MASKED. BASHES ALL REGS.
;PACKET IS ALREADY SWABBED INTO ETHERNET BYTE ORDER (REVERSE OF CHAOSNET).
ETHXMT: INC CHOSTS(I) ;SET CHOSTS TO 1, TRANSMIT STARTING
CLR A ;NO OUTPUT START DELAY
ETHXM0: MOV CHOHWR(I),H ;GET HARDWARE ADDRESS
MOV CHOINX(I),B ;GET SOURCE SUPPLYING THE PACKET
MOV CHIBFP(B),D ;GET PACKET ADDRESS
ADD #PKDAT,D ;GET PUP ADDRESS
MOV #1000,-(D) ;SMASH LAST 2 WORDS OF CHAOS HEADER. TYPE=PUP
MOV #ETHHSN,-(D) ;STORE SOURCE ADDRESS
MOVB 14(D),1(D) ;STORE DESTINATION ADDRESS
MOV 4(D),B ;GET PUP SIZE IN BYTES
ADD #5,B ;CONVERT TO WORDS, ALLOW FOR ETHERNET HEADER
ASR B
NEG B ;HARDWARE WANTS IT NEGATIVE
MOV B,(H)+ ;OUTPUT WORD COUNT
MOV D,(H)+ ;OUTPUT BUFFER ADDRESS
MOV A,2(H) ;OUTPUT START DELAY
MOV #101,(H) ;START OUTPUT, ENABLE INTERRUPT
RET ;PI LEVEL WILL FINISH
;OUTPUT DONE/ABORTED INTERRUPT
ETHOBK: PUSH <A,B,C,D,H,I>
MOV #CHXETH,I
MOV CHOHWR(I),H
MOV 4(H),A ;PICK UP STATUS BEFORE WRITING IT
CLR 4(H) ;CLEAR INTERRUPT ENABLE
TST A ;CHECK FOR ERROR
BPL 10$
ADD #1,NPKSAB-CHXCHS(I)
ADC HPKSAB-CHXCHS(I)
NEG CHOSTS(I) ;ERROR, ENTER RETRANSMIT MODE
BPL 10$ ;ALREADY RETRANSMITTED ONCE, PUNT
MOV #25.,A ;WAIT 1 MS (DON'T BOTHER BEING RANDOM)
CALL ETHXM0 ;START TRANSMISSION AGAIN
BR ETHINX ;AND EXIT
10$: CALL CHSODN ;TRANSMISSION FINISHED
CALL CHSRUN ;FIND MORE WORK TO DO
BR ETHINX ;DISMISS
;CHECKSUM PUP ADDRESSED BY A. BASHES A,B,C.
PUPCKS: CALL PUPCK1 ;COMPUTE CHECKSUM
MOV B,(A) ;STORE CHECKSUM
RET
;RETURN 'EQ' IF CHECKSUM MATCHES
PUPCKT: CALL PUPCK1 ;COMPUTE CHECKSUM
CMP (A),#-1 ;PACKET CHECKSUMMED?
BEQ 5$ ;NO, ALWAYS MATCH
CMP B,(A) ;RETURN WITH CC SET FROM NEW AND OLD CKSMS
5$: RET
;A POINTS AT PACKET, RETURN WITH A -> CHECKSUM AND CHECKSUM IN B. BASH C.
PUPCK1: MOV (A),C ;GET LENGTH
DEC C ;IN WORDS NOT COUNTING CHECKSUM
ASR C
CLR B ;BUILD CHECKSUM IN B
10$: ADD (A)+,B ;ONE'S COMPLEMENT ADD
ADC B
BPL 11$ ;TRANSFER SIGN BIT INTO CARRY
SEC
11$: ROL B ;AND LEFT CYCLE
SOB C,10$
INC B ;GRONK MINUS ZERO
BEQ 15$
DEC B
15$: RET
;BROADCAST ETHERNET GATEWAY INFO
ETHRUT: MASK 5 ;ENTER SUITABLE LEVEL FOR HACKING NET
TST CHISTS+CHXEGT ;IS THE PSEUDO SOURCE THAT EMITS THE
BNE 99$ ; PACKET AVAILABLE? IF NOT, PUNT.
CLR CHXRTF+CHXETH ;CLEAR REQUEST FLAG
MOV #EGTPID,A
CLR (A)+ ;PUP ID ZERO
CLR (A)+
CLR (A)+ ;BROADCAST DESTINATION
CLR (A)+ ;TO SOCKET 2
MOV #2,(A)+
CALL ETHRT1 ;BUILD AND SEND GATEWAY INFO
99$: UNMASK
RET
BADSBP: .WORD BADSUB ;POINTER INTO BAD SUBNETS
BADSUB: ;SUBNETS THAT SHOULD NOT HAVE INFORMATION SENT
;ABOUT. THIS LIST MUST BE IN INCREASING ORDER
;AND MUST END IN 377.
.BYTE 004 ;AI CHAOS 11 pseudo subnet (only AI PDP-10 (RIP) is on this)
.BYTE 010 ;Tech Square LCSnet (unused)
.BYTE 011 ;Tech Square LCS asynchronous line net (IP)
.BYTE 012 ;Tech Square VII LCSnet (IP)
.BYTE 014 ;Symbolics: Los Angeles-Chatsworth land line
.BYTE 020 ;CHAOS MIT IN subnet (ask JNC)
.BYTE 027 ;Experimental asynchronous line net
.BYTE 030 ;Experimental radio broadcast net
.BYTE 040 ;Symbolics: Tech Square-Vassar St. microwave link
.BYTE 041 ;Symbolics: Cambridge-Palo Alto land line
.BYTE 042 ;Symbolics: Palo Alto-Chatsworth land line
.BYTE 047 ;Symbolics: Cambridge-Chatsworth land line
.BYTE 054 ;S-1: 10Mb Ethernet
.BYTE 055 ;S-1: Pronet ring
.BYTE 056 ;S-1: serial line subnet
.BYTE 057 ;S-1: serial line subnet
.BYTE 061 ;Symbolics: Cambridge-Cambridge land line
.BYTE 062 ;Symbolics: Cambridge-Washington land line
.BYTE 064 ;Symbolics: Cambridge-Houston land line
.BYTE 070 ;Symbolics: Chatsworth-Westwood land line
.BYTE 072 ;Atari: Cambridge-MIT land line
.BYTE 073 ;Atari: Cambridge-Sunnyvale land line
.REPT 8
.BYTE 377 ;SPARES
.ENDR
.BYTE 377
.EVEN
ETHRT1: MOV #BADSUB,BADSBP ;INITIAL BAD SUBNET POINTER
MOV #EGTSBN,A ;FILL IN GATEWAY INFORMATION IN THE PUP
CLR I ;I SUBNET*2, A EGTSBN POINTER
10$: ;; FOR EACH SUBNET, .BYTE GATE-NET, TARGET-NET, HOP-COUNT, GATE-HOST
CLR B ;FOR NON-GATEWAY, USE 0 AS GATEWAY ADDRESS
TST SBNTYP(I) ;HARDWARE CONNECTION?
BGT 11$
MOV SBNADR(I),B ;NO, GET GATEWAY ADDRESS
11$: cmpb i,#60
bhi 20$ ;dover, as of 1-Dec-83 can't handle more than 60
;; FILTER OUT KNOWN BAD SUBNETS
CMPB I,@BADSBP ;MAYBE UPDATE POINTER
BHI 115$ ; NO UPDATE NEEDED
INC BADSBP
115$: CMPB I,@BADSBP ;THIS TIME, CHECK FOR EQUALITY
BEQ 20$ ;PUNT
;; END FILTER
MOV SBNCST(I),C ;GET COST
CMP C,#1000 ;IF NOT REACHABLE, DON'T PUT IN PACKET
BHIS 20$
.IREPT 3, ASR C ;DIVIDE BY 8 TO GET APPROXIMATE HOP COUNT
CMP C,#ETHMXH ;DON'T PUT MORE THAN MAXHOPS
BLOS 12$
MOV #ETHMXH,C
12$: MOV I,D ;GET TARGET-NET
ASR D
SWAB B
MOVB B,(A)+ ;STORE IN WIERD XEROX BYTE ORDER
MOVB D,(A)+
MOV B,(A)+
MOVB C,-2(A)
20$: TST (I)+ ;NEXT SUBNET
CMP I,#NSUBNT*2
BLO 10$
SUB #EGTSBN,A ;NUMBER OF DATA BYTES IN PUP
ADD #22.,A ;FOR HEADER AND CHECKSUM
MOV A,EGTPLN ;SET PUP LENGTH
MOV #CHXEGT,I ;SET UP TO TRANSMIT TO ETHERNET
JMP ETHOUT
.ENDC ;ETHERP
.IF DF NDVRBF
.SBTTL DOVER PROTOCOL TRANSLATOR
;RFC PACKET IN A. MUST PRESERVE I, AND RETURN 'EQ'.
DVROPN: MOV PKPKN(A),C
MOV PKSIND(A),B
MOV PKSHST(A),A
PUSH I
CALL 5$
POP I
SEZ
RET
;SET UP DOVER TO TALK TO HOST IN A, INDEX IN B, PKT# IN C, SENDING BACK AN OPN
;OR SENDING A LOS IF BUSY. MUST WATCH FOR DUPLICATE RFC'S
;MUST BE CALLED WITH CHAOS AND ETHER INTERRUPTS MASKED
5$: TST DVRHST ;BUSY?
BEQ 10$ ;NO
CMP A,DVRHST
BNE DVRBSY ;YES, TALKING TO ANOTHER HOST
CMP B,DVRIDX
BNE DVRBSY ;YES, TALKING TO ANOTHER GUY SAME HOST
BR 11$ ;DUPLICATE RFC
10$: CLR DVRTIM ;FLUSH TIMEOUT
MOV A,DVRHST
MOV B,DVRIDX
INC DVRLIX ;ESTABLISH UNIQUE LOCAL INDEX
BNE 11$
INC DVRLIX ;DON'T USE 0
11$: CLR DVRMSK ;CLEAR THE BUFFER RING
CLR DVRID ;FIRST PACKET TO SEND TO DOVER IS PACKET 0
INC C ;C := FIRST PACKET ID THAT WILL COME IN FROM CHAOS
MOV C,DVROFS
MOV #%COOPN*400,B ;SEND AN OPN
BR DVRST1 ;REST IS LIKE STS
DVRBSY: TST DVRPKP ;SPECIAL BUFFER BUSY?
BNE CPOPJ0 ;YES, PUNT
MOV #DVRBF2,C ;SEND A CLS
MOV #%COCLS*400,(C)+
MOV #4,(C)+
MOV A,(C)+
MOV B,(C)+
MOV #CHADD,(C)+
CLR (C)+
CLR (C)+
CLR (C)+
MOV #"BU,(C)+
MOV #"SY,(C)+
MOV #DVRBF2,DVRPKP
BR DVRRFL
;HERE TO SEND STS TO GUY CONNECTED TO DOVER
;MUST BE MASKED AGAINST CHAOS INTERRUPTS
DVRSTS: MOV #%COSTS*400,B
DVRST1: MOV #DVRBF2,A ;USE THIS BUFFER
MOV #4,D ;NUMBER OF BYTES
DVRST2: MOV A,C
MOV B,(A)+ ;OPCODE
MOV D,(A)+ ;NUMBER OF BYTES
MOV DVRHST,(A)+ ;DESTINATION HOST
MOV DVRIDX,(A)+ ;DESTINATION INDEX
MOV #CHADD,(A)+ ;SOURCE HOST
MOV DVRLIX,(A)+ ;SOURCE INDEX
CLR (A)+ ;NO PACKET NUMBER
CMP B,#%COLOS*400 ;IF SENDING LOS, PUNT THE REST
BEQ 20$
MOV DVRID,B
DEC B ;LAST PACKET ACKNOWLEDGED BY DOVER
ADD DVROFS,B ;CONVERT TO CHAOSNET ID
MOV B,(A)+ ;ACKNOWLEDGE PACKET NUMBER
MOV B,(A)+ ;RECEIPT
MOV #NDVRBF,(A)+ ;WINDOW SIZE
20$: MOV C,DVRPKP ;CAUSE PACKET TO GET SENT
;DROP INTO DVRRFL
;HERE TO GET ANOTHER PACKET FROM THE DOVER. THIS CAN BE EITHER A CHAOSNET
;PACKET TO BE SENT BACK TO THE APPROPRIATE GUY, OR A PUP TO GO TO THE DOVER
DVRRFL: MOV #CHXDVR,I ;THIS MIGHT NOT BE SET UP WHEN CALLED
TST CHISTS(I) ;PACKET SOURCE ONLY EMANATES ONE AT A TIME
BNE CPOPJ0
CMP CHIBFP(I),DVRPKP ;FINISHED SENDING SPECIAL PACKET?
BNE 10$
CLR DVRPKP ;YES, MAKE READY FOR ANOTHER
10$: CLR CHIBFP(I) ;THIS PACKET NO LONGER BEING SENT
MOV DVRPKP,A ;GOT SPECIAL PACKET TO SEND?
BNE 30$ ;YES, SEND IT
TST DVRMSK ;GOT NEXT BUFFER TO SEND TO DOVER?
BPL CPOPJ0 ;NO
CMP DVRRTR,#60. ;1-SECOND RETRANSMISSION INTERVAL ELAPSED?
BLO CPOPJ0 ;NO, DON'T SEND YET
CLR DVRRTR ;SENDING, RESET RETRANSMISSION TIMER
MOV DVRBFP,A
BIC #PKFCMS,PKFC(A) ;CLEAR FORWARDING COUNT SINCE SENDING AGAIN
30$: MOV A,CHIBFP(I) ;SEND THIS PACKET
CALL CHSIHD ;ROUTE HIM
BVS DVRRFL ;BAD, IGNORE
CMP B,#CHXCHS ;SWAB IF SENDING TO 10, BUT NOT ETHERNET
BHIS 35$
CALL CHSSWB
35$: INC CHISTS(I) ;INDICATE BUFFER READY TO SEND
RET
;CALLED WITH A PUP IN ETHIBF WHICH IS FROM THE DOVER AND ADDRESSED
;TO THE GUY WHO'S TRYING TO PRINT ON IT. MUST BE MASKED AGAINST ETHER & CHAOS INTERRUPTS.
DVRPUP: MOVB ETHIBF+PKDAT+2,B
CMP B,#31 ;EFTP ACKNOWLEDGE?
BNE DVRPP1
CMP ETHIBF+PKDAT+6,DVRID ;ACKNOWLEDGING EXPECTED PACKET?
BNE CPOPJ0 ;NO, IGNORE IT
INC DVRID ;YES, ADVANCE ID, POINTER, AND PACKET-PRESENCE MASK
MOV DVRBFP,A
ADD #DVRBFL,A
CMP A,#DVRBF2
BLO 11$
MOV #DVRBUF,A
11$: MOV A,DVRBFP
ASL DVRMSK
SETOM DVRRTR ;FAKE RETRANSMIT TIMER TO SEND NEXT PUP RIGHT AWAY
TST CHISTS+CHXDVR ;PACKET SOURCE BUSY?
BEQ DVRSTS ;NO, SEND AN ACKNOWLEDGEMENT TO THE CHAOSNET
CPOPJ0: RET
DVRPP1: MOV #22.,A ;RELATIVE ADDRESS OF ASCII STRING
CMP B,#33 ;EFTP ABORT?
BEQ DVRERR
MOV #44.,A ;RELATIVE ADDRESS OF ASCII STRING
CMP B,#4 ;PUP ERROR?
BNE CPOPJ0 ;IGNORE ANYTHING ELSE
DVRERR: CLR DVRMSK ;DON'T SEND ANYTHING MORE TO THE DOVER
MOV ETHIBF+PKDAT,C ;PUP LENGTH
SUB A,C
SUB #2,C ;GET LENGTH OF ASCII STRING
ADD #ETHIBF+PKDAT,A ;GET ADDRESS OF ASCII STRING
MOV #DVRBUF+PKDAT,B ;BUILD A LOS PACKET TO SEND BACK
MOV C,D ;SAVE BYTE LENGTH
INC C
ASR C ;WORD COUNT
BEQ 11$
10$: MOV (A)+,(B)
SWAB (B)+ ;ALTO HAS BYTES IN THE WRONG ORDER
SOB C,10$
11$: MOV #%COLOS*400,B ;SEND A LOS
MOV #DVRBUF,A
CALL DVRST2
CLR DVRHST ;KILL CONNECTION
RET
;HERE IS A PACKET DIRECTED TO THE DOVER. DO GOOD THINGS WITH IT.
;NOTE, IT HAS ALREADY BEEN SWABBED INTO ETHERNET BYTE ORDER.
DVRPKT: MOV CHOINX(I),B ;GET SOURCE SUPPLYING THE PACKET
MOV CHIBFP(B),A ;GET ADDRESS OF PACKET
CLR DVRTIM ;FOREIGN HOST IS NOT IDLE
MOVB PKOP(A),B ;DATA PACKET?
BMI 50$ ;YES
CMP B,#%COSNS
BNE 11$
TST CHISTS+CHXDVR
BNE 90$
CALL DVRSTS ;SNS => STS
BR 90$
11$: CMP B,#%COCLS
BEQ 12$ ;CLS OR LOS PUNTS THE CONNECTION
CMP B,#%COLOS
BNE 13$
12$: CLR DVRHST
BR 90$
13$: CMP B,#%COEOF ;NOTE THAT EOF IS TREATED VERY MUCH LIKE DATA!
BNE 90$ ;IGNORE ANYTHING RANDOM
50$: MOV PKPKN(A),B ;GET ID OF DATA PACKET
SUB DVROFS,B
MOV DVRBFP,D ;FIND WHERE IN THE BUFFER IT GOES
MOV #100000,C ;AND GET MASK BIT FOR IT
SUB DVRID,B ;B := ID RELATIVE TO NEXT EXPECTED
BEQ 53$
CMP B,#NDVRBF
BHIS 90$ ;IGNORE DUPLICATE OR NOT IN WINDOW
51$: ADD #DVRBFL,D
CMP D,#DVRBF2
BLO 52$
MOV #DVRBUF,D
52$: CLC
ROR C
SOB B,51$
53$: BIT C,DVRMSK ;ALREADY HAVE PACKET?
BNE 90$ ;YES, IGNORE
BIS C,DVRMSK ;NO, STORE IT AWAY
MOV D,C
ADD #PKDAT,D ;BUILD PUP
MOV PKNBYT(A),B
BIC #PKNBMS,B
MOV B,(D)
ADD #22.,(D)+ ;PUP LENGTH
MOV #30,(D)+ ;PUP TYPE
TST (A) ;WAS THIS DATA OR EOF?
BMI 54$ ;DATA
SUB (PC),-2(D) ;EOF, SET PUP TYPE TO 32
54$: CLR (D)+ ;PUP ID HIGH
MOV PKPKN(A),(D) ;PUP ID LOW
SUB DVROFS,(D)+ ; CORRECTED
MOV #DVRADR,(D)+ ;DESTINATION HOST
CLR (D)+ ;DESTINATION SOCKET HIGH
MOV #20,(D)+ ;DESTINATION SOCKET LOW
MOV DVRHST,(D)+ ;SOURCE HOST
CLR (D)+ ;SOURCE SOCKET HIGH
MOV DVRIDX,(D)+ ;SOURCE SOCKET LOW
ADD #PKDAT,A
INC B
ASR B ;NUMBER OF DATA WORDS
;*** TEMPORARY KLUDGE ***
PUSH <A,D,B> ;PUSH B LAST!!
;*** END TEMPORARY KLUDGE ***
BEQ 56$
55$: MOV (A)+,(D)+ ;MOVE THE DATA
SOB B,55$
56$: MOV C,A
ADD #PKDAT,A
MOV #<%COUNC*400>,(C) ;PKOP
MOV 10(A),PKDHST(C)
MOV (A),PKNBYT(C) ;SHOULD BE ENOUGH TO GET IT ROUTED TO ETHERNET
CALL PUPCKS ;STORE APPROPRIATE CHECKSUM
;*** TEMPORARY KLUDGE ***
POP <B,D,A> ;LOOK FOR SOME KIND OF MACHINE FAILURE
TST B
BEQ 79$
70$: CMP (D)+,(A)+
BNE 75$
SOB B,70$
BR 79$
75$: DVRFKT=.
NOP ;PUT A BPT HERE IF YOU LIKE
INC NDVRFK
CLR DVRMSK ;DO IT ALL OVER AGAIN
79$:
;*** END TEMPORARY KLUDGE ***
CALL DVRRFL ;SEND THIS PACKET MAYBE
90$: MOV #CHXDVR,I
JMP CHSODN ;THIS PACKET HANDLED
.ENDC ;NDVRBF
.IFNZ DL10P
.SBTTL TRAP HANDLING
TRAP14: HALT ;BPT WITH NO RUG IN CORE
TRAP10: BPT ;ILLEGAL INSTRUCTION
TRAP4: NOP ;PATCH BPT HERE IF YOU WANT
CMP (SP),#MAIN ;IF TRAP4 IN MAIN LOOP...
BLO CRASH
CMP (SP),#MAINE
BHIS CRASH
BIT #DLXPRT,DLXCSR ;AND DL10 PORT TURNED OFF
BNE CRASH
TST DLXOFF ;AND WE THOUGHT IT WAS ON
BNE CRASH
RESTRT: MOV #STKBAS,SP ;THEN RESTART MAIN LOOP
CLR -(SP) ;WHICH WILL WAIT FOR DL10 PORT TO TURN ON
MOV #MAIN,-(SP)
RTI
CRASH: BPT ;OTHERWISE, CRASH
PWRFAL: RESET ;POWER FAIL OR UP - IF FAIL, HALT DURING RESET
MOV #20,B ;WAIT 2 SECONDS TO
1$: CLR A ; MAKE SURE POWER IS REALLY ON
SOB A,.
SOB B,1$
JMP INIT ;POWER SEEMS UP, RESTART PROGRAM
.ENDC ;DL10P
.IFNZ NODDT ;IF NO DDT OR OTHER "OPERATING SYSTEM", SET UP TRAP HANDLERS
TRAP4:
.=4
.WORD TRAP4,340,TRAP10,340,TRAP14,340,TRAP10,340,PWRFAL,340,TRAP10,340,TRAP10,340
.=TRAP4
;ILLEGAL ADDRESS, UNIBUS NXM, STACK OVERFLOW
TRAP4: BPT
0
;ILLEGAL INSTRUCTION, IOT, EMT
TRAP10: BPT
0
;POWER FAILURE OR RESTORE
PWRFAL: HALT
0
;BPT (OR TRACE)
TRAP14: .REPT 7 ;SAVE REGISTERS WHERE CARPET CAN FIND THEM
MOV %0+.RPCNT,BPTACS+<.RPCNT*2>
.ENDR
CLR BPTGO
SETOM BPTFLG
5$: TST BPTGO
BEQ 5$
CLR BPTFLG
.REPT 7
MOV BPTACS+<.RPCNT*2>,%0+.RPCNT
.ENDR
RTI
BPTFLG: 0 ;NON-ZERO IF GOT A BPT
BPTGO: 0 ;NON-ZERO TO PROCEED
BPTACS: .BLKW 7 ;REGS EXCEPT PC
.ENDC ;NODDT
.SBTTL INITIALIZATION
GO::
INIT: CLR PS
.IFNZ DL10P
RESET
MOV #STKBAS,SP
TST 14
BNE 1$ ;BPT ALREADY SET UP BY RUG
MOV #TRAP14,14
MOV #340,16
1$:
.ENDC ;DL10P
.IFNZ NODDT ;NO OPERATING SYSTEM
RESET
MOV #STKBAS,SP
.ENDC ;NODDT
SETOM DLXOFF ;REINITIALIZE VARIOUS VARIABLES
SETOM NO.ITS
.REPT CHAOSP ;IDLE CHAOS NET INTERFACES
CLR CHISTS+CHXCHS+<2*.RPCNT>
CLR CHOSTS+CHXCHS+<2*.RPCNT>
.ENDR
.IIF NZ T300P, CLR RQBACT
.IFNZ NCT
MOV #NFTTY,I
76$: MOV NRMIPC(I),TTYIPC(I)
ADD #2,I
CMP I,#LASTTY
BLE 76$
MOV #TYORNG,B ;CLEAR THE TYPOUT-DONE RING
CALL CLRING
MOV #<NFTTY/2>,A ;GIVE OUTPUT DONE ON ALL LINES
78$: CALL PUT
INC A
CMP A,#<NFTTY/2>+NCT
BLO 78$
.ENDC ;NCT
.IFNZ NDMS
;;; Turn on DM11-BBs
CLR B ;iterated over DM11 units
MOV #NDMS,H
5$: MOV #DMCLR+DMCSN,@DMCSR(B) ;CLEAR SCANNER MEMORY
2$: BIT #DMBSY,@DMCSR(B)
BNE 2$
CLR I ;iterated over modem channels
;; turn on connected modem channels for one DM11
CLR A ;counter for channels per unit
3$: TST M2LMAP(I)
BEQ 4$
MOV A,@DMCSR(B)
MOV #LINENB,@DMLSR(B)
4$: TST (I)+
INC A
CMP A,#16.
BLT 3$
TST (B)+
SOB H,5$ ;next DM11
;; treat first-time interrupts differently
SETOM DMINI
CLR B
MOV #NDMS,A
6$: MOV #DMSCN+DMIEN,@DMCSR(B) ;enable scanner interrupts
TST (B)+
SOB A,6$ ;on all DMs
MOV #20000.,A
SOB A,. ;DELAY 50 MILLISECONDS
CLR DMINI ;WHILE P.I. LEVEL GETS INITIAL STATUS
.ENDC ;NDMS
.IFG NDHS
;TURN ON DH11'S
MOV #NLDHHX,H
DHINIL: MOV DHSCR(H),A ;DEVICE ADDRESS
MOV #100000,16(A) ;TURN ON SILO MAINTENANCE MODE, SUSPECTED OF
;LOSING
MOV #4000,(A) ;RESET DH11
MOV 16(A),B ;CHECK SILO STATUS
BIC #300,B ;THESE BITS ARE IN RAM & DON'T CLEAR
BEQ DHSWIN ;SHOULD HAVE CLEARED MAINTENANCE MODE AND OTHER CRUD
DHSLUZ: BPT ;LOSE
DHSWIN: MOV #DHRENB+DHTENB,(A) ;NOW ENABLE INTERRUPTS ON DH11
SUB #2,H
BGE DHINIL
.ENDC ;NDHS
;TURN ON DL11S
.IFG NDLS
MOV #NLDLHX,H
MOV #NDLS-1,A
21$:
.IIF NZ DTE20P, BEQ 22$ ;NO KBD INT ON KL10 CTY DUE TO KLDCP LOSSAGE
MOV #103,@DLKS(H) ;ACTIVATE KEYBOARD INTERRUPT, D.T.R., READER
22$: MOV #100,@DLPS(H) ;ACTIVATE PRINTER INTERRUPT
SUB #2,H
DEC A
BPL 21$
.ENDC ;NDLS
;SET LINE PARAMETERS AND ALLOCATE BUFFERS
.IFNZ NCT
MOV #NFTTY,I
10$: MOV LPRVAL(I),A
MOV BUFSIZ(I),B
CALL SPARAM
ADD #2,I
CMP I,#LASTTY
BLE 10$
.ENDC ;NCT
;TURN ON CLOCK
.IIF Z DTE20P, MOV #100,@#LKS ;NO CLOCK INTERRUPTS IF KLDCP IS HACKING CLOCK TOO
.IFNZ DTE20P
;INITIALIZE DTE20
MOV #37774,DLYCNT ;DMA TO BANK 0, 2 USEC DELAY
MOV #%D3BYT,DIAG3 ;DO TO10 TRANSFERS IN BYTE MODE
MOV #MAIN,SADR ;ONLY DO INIT ONCE
.ENDC ;DTE20P
.IIF NZ TEN11P, SETOM T11I10 ;CAUSE 10 TO REINITIALIZE TEN-11 CHAOS
.REPT CHAOSP
MOV CHIHWR+CHXCHS+<2*.RPCNT>,H ;ADDRESS THE INTERFACE
CONC <CMP CH%MYN(H),#CHAD>,\.RPCNT ;CHECK THE HOST NUMBER SWITCHES AGAINST THE PROGRAM
BEQ .+4
BPT
BIS #%CAREN,(H) ;ENABLE CHAOS NET INPUT INT
.ENDR ;CHAOSP
.IFNZ ETHERP
MOV CHIHWR+CHXETH,H ;ADDRESS THE INTERFACE
MOV 16(H),A ;GET HOST NUMBER SWITCHES
COMB A ;FIX XEROX MISTAKE
CMPB A,#ETHHSN ;CHECK HOST NUMBER SWITCHES
BEQ .+4
BPT
MOV #CHXETH,I ;ENABLE TO RECEIVE FIRST ETHERNET PACKET
CALL ETHRFL
.ENDC ;ETHERP
;GO
JMP MAIN
.IFNZ GOULDP
.SBTTL GOULD PRINTER BUFFERS
GLPOIP: GLPBFF ;NEXT BUFFER IN AT M.P. LEVEL
GLPOOP: GLPBFF ;NEXT BUFFER OUT AT P.I. LEVEL
.REPT NGLPBF ;ASSEMBLE THE BUFFERS
0 .SEE GB.STA
GLPBFF ;DUE TO PALX BUG, LEAVE .SEE ON NEXT LINE
.SEE GB.NXT
GLPBFF==.-4
0 .SEE GB.FF
0 .SEE GB.NL
0 .SEE GB.PNT
.BLKB GLPBSZ
.ENDR
.ENDC ;GOULDP
.SBTTL "TTYTYP" PARAMETER FILE
T LPRVAL:
.BLKW NCT ;DH11 PARAMETER REG
BUFFRS: ;BEGIN ALLOCATING BUFFERS HERE
.IIF NZ NCT, INFORM <BEGINNING OF BUFFERS = >,\BUFFRS
ZZ===<BUFFRS+<NCT*MAXBSZ>+3777>/4000 ;NUMBER OF K USED
.IRP ZZZZ,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16>
.LIF EQ ZZ-.IRPCNT ;THIS IS A CRETINOUS CROCK TO GET IT COME OUT IN DECIMAL
INFORM <HIGHEST LOCATION USED = >,\BUFFRS+<NCT*MAXBSZ>,< (>,ZZZZ,<K)>
.ENDR
.IFNZ NCT ;TTYTYP FILE ONLY IF WE HAVE TTYS
.IF P2 ;SPEED UP THE ASSEMBLY
OFF==69105 ;KLUDGES SO I DON'T HAVE TO PUT KEYWORD PARAMETERS INTO PALX
40K==40000
80K==80000
.MACRO SPEED BAUD
ZZ==-1
.IIF EQ BAUD-OFF, ZZ==0
.IIF EQ BAUD-50, ZZ==1
.IIF EQ BAUD-75, ZZ==2
.IIF EQ BAUD-110, ZZ==3
.IIF EQ BAUD-134, ZZ==4
.IIF EQ BAUD-150, ZZ==5
.IIF EQ BAUD-200, ZZ==6
.IIF EQ BAUD-300, ZZ==7
.IIF EQ BAUD-600, ZZ==10
.IIF EQ BAUD-1200, ZZ==11
.IIF EQ BAUD-1800, ZZ==12
.IIF EQ BAUD-2400, ZZ==13
.IIF EQ BAUD-4800, ZZ==14
.IIF EQ BAUD-9600, ZZ==15
.IIF EQ BAUD-80K, ZZ==16
.IIF EQ BAUD-40K, ZZ==17
.IIF LT ZZ, .ERROR UNRECOGNIZED SPEED "BAUD"
.ENDM SPEED
.MACRO IPARM N,ODFLT,IDFLT,MUMLST
.IF GE <2*N>-NFTTY
.IF LE <2*N>-LASTTY
%%.ISPEED==-1
%%.SPEED==-1
.IRP MUM,<MUMLST>
.IF NB <MUM>
ZZ==0
.IRPC MUMB,<MUM>
.IIF GE .IRPCNT-2, .MEXIT
.IIF IDN MUMB,S, .IIF EQ .IRPCNT, ZZ==1
.IIF IDN MUMB,P, .IIF EQ .IRPCNT-1, ZZ==ZZ+1
.IIF IDN MUMB,I, .IIF EQ .IRPCNT, ZZ==1
.IIF IDN MUMB,S, .IIF EQ .IRPCNT-1, ZZ==ZZ+1
.ENDM
.IIF EQ ZZ-2, %%.'MUM
.ENDC
.ENDM
.IF LT %%.ISPEED
.IIF LT %%.SPEED, %%.ISPEED==IDFLT
.IELSE %%.ISPEED==%%.SPEED
.ENDC
.IIF LT %%.SPEED, %%.SPEED==ODFLT
SPEED %%.ISPEED
IZZ==ZZ
SPEED %%.SPEED
; BUFFER SIZE IS 1/2 SECOND'S TYPING
; BUT WILL BE SUBJECT TO LIMIT OF MAXBSZ
.IIF LT ZZ-7, BZZ==5.
.IIF EQ ZZ-7, BZZ==15.
.IIF EQ ZZ-10, BZZ==30.
.IIF EQ ZZ-11, BZZ==60.
.IIF EQ ZZ-12, BZZ==90.
.IIF EQ ZZ-13, BZZ==120.
.IIF EQ ZZ-14, BZZ==240.
.IIF EQ ZZ-15, BZZ==480.
.IIF GT ZZ-15, BZZ==1000.
.=LPRVAL+<2*N> ;ASSEMBLE LINE PARAMETER WORD
.IIF NE ZZ-3, <ZZ*2000>+<IZZ*100>+3 ;ISPEED, OSPEED, NO PARITY, 8 BITS, FULL DUPLEX
.IELSE <ZZ*2000>+<IZZ*100>+3+4 ;110 BAUD EXTRA STOP BIT
.=BUFSIZ+<2*N>
BZZ ;ASSEMBLE BUFFER SIZE
.ENDC
.ENDC
.ENDM IPARM
;MACROS USED IN THE TTYTYP FILE:
.MACRO TTDPRT TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,300,300,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDPRT
.MACRO TTDMRX TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,600,600,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDMRX
.MACRO TTDTRM TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,1200,1200,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDTRM
.MACRO TTDLPT TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,9600,9600,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDLPT
.MACRO TTDLA36 TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,300,300,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDLA36
.MACRO TTDIML TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,50K,25K,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDIML
.MACRO TTDVT TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,9600,9600,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDVT
.MACRO TTDTEK TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,1200,1200,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDTEK
.MACRO TTDLSR TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,2400,2400,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDLSR
.MACRO TTDDPT TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,2400,2400,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDDPT
.MACRO TTDGT40 TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,4800,4800,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDGT40
.MACRO TTDRAY TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,9600,9600,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDRAY
.MACRO TTDH19 TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,9600,9600,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDRAY
.MACRO TTD11 TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,4800,4800,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTD11
.MACRO TTDRAN TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,FOO,FOO,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDRAN
.MACRO TTDTV TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,FOO,FOO,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDTV
.MACRO TTDGRN TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,9600,9600,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDGRN
.MACRO TTDSTY TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,FOO,FOO,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDSTY
.MACRO REPEAT N,FOO
FAKOUT: .REPT N
FAKOUT===0
.ENDM
NSTTYS==0 ;WE'RE NOT INTERESTED IN PSEUDO-TTYS
N11TYS==0 ;NOR IN PDP11 TVS
.INSRT SYSTEM;TTYTYP >
.EXPUNGE ZZ,IZZ,IZZZ,BZZ,OFF,40K,80K,%%.ISPEED,%%.SPEED
.EXPUNGE TT,TY,TO,TP,TCT,HOR,VER,ROL,SPEED,ISPEED
.ENDC ;P2
.ENDC ;NCT
.END INIT