mirror of
https://github.com/PDP-10/stacken.git
synced 2026-05-01 06:09:11 +00:00
1269 lines
33 KiB
Plaintext
1269 lines
33 KiB
Plaintext
.SBTTL DNCOMM - MAIN LOOP AND CLOCK ROUTINES 23-OCT-87
|
||
|
||
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
|
||
; 1976,1979,1980,1981,1984,1987,1988.
|
||
;ALL RIGHTS RESERVED.
|
||
;
|
||
;
|
||
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
|
||
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
|
||
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
|
||
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
|
||
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
|
||
;TRANSFERRED.
|
||
;
|
||
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
|
||
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
|
||
;CORPORATION.
|
||
;
|
||
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
|
||
;SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL.
|
||
|
||
VRCOMM=066 ;FILE EDIT NUMBER
|
||
|
||
.SBTTL PARITY INTERRUPT, EMT, TRAP, ETC.
|
||
|
||
.IF GE <PDP11-34>
|
||
;HERE ON A PARITY CONTROL INTERRUPT
|
||
|
||
MP.INT: MOV MP.REG,#0 ;SAVE FOR INTERESTED PARTIES
|
||
.IF NE FT.HLP
|
||
RESET
|
||
SAVE <R0,R1>
|
||
JSR R0,CKTCRL
|
||
.ASCIZ \MEMORY PARITY ERROR MP.REG=\
|
||
.EVEN
|
||
MOV MP.INT+4,R0
|
||
JSR PC,CKTOCT
|
||
JSR PC,CM.INT
|
||
.ENDC;.IF NE FT.HLP
|
||
STOPCD MEM
|
||
.ENDC;.IF GE <PDP11-34>
|
||
|
||
|
||
|
||
;HERE ON A BUS TIMEOUT
|
||
|
||
NXMINT: TST TRPPC ;SOMEBODY REQUESTING TRAP INTERCEPT?
|
||
BEQ 100$ ;NO, GO DIE IN PEACE
|
||
MOV (P)+,TRPDPC ;YES, REMEMBER TRAP PC AND
|
||
MOV (P)+,TRPDPS ; PS WORDS IN CASE ANYONE CARES
|
||
MOV TRPSP,P ;RESET THE STACK TO KNOWN STATE
|
||
MOV 4(P),6(P) ;CONCOCT AN RTI BLOCK
|
||
MOV TRPPC,4(P) ; TO RESTORE PI ET AL ON INTERCEPT
|
||
MOV (P)+,TRPSP ;POP A LEVEL OF NXM INTERCEPTING
|
||
MOV (P)+,TRPPC ; . . .
|
||
RTI ;INTERCEPT TRAP, RESETTING PI LEVELS ETC.
|
||
|
||
100$:
|
||
.IF NE FT.HLP
|
||
SAVE <R0,R1>
|
||
JSR R0,CKTCRL
|
||
.ASCIZ \BUS TRAP\
|
||
.EVEN
|
||
JSR PC,CM.INT
|
||
.ENDC;.IF NE FT.HLP
|
||
STOPCD NXM ;DIE IN USUAL WAY
|
||
;HERE ON A ILLEGAL INSTRUCTION
|
||
ILSINT:
|
||
.IF NE FT.HLP
|
||
SAVE <R0,R1>
|
||
JSR R0,CKTCRL
|
||
.ASCIZ \ILL\
|
||
.EVEN
|
||
BR ILSCOM
|
||
.ENDC;.IF NE FT.HLP
|
||
|
||
|
||
;HERE ON A BPT
|
||
BPTINT: ;DIE IN USUAL WAY
|
||
.IF NE FT.HLP
|
||
SAVE <R0,R1>
|
||
JSR R0,CKTCRL
|
||
.ASCIZ \BREAK POINT\
|
||
.EVEN
|
||
BR ILSCOM
|
||
.ENDC;.IF NE FT.HLP
|
||
|
||
|
||
.IF EQ FT.TSK
|
||
;HERE ON A IOT INSTRUCTION
|
||
IOTINT: ;DIE IN USUAL WAY
|
||
.IF NE FT.HLP
|
||
SAVE <R0,R1>
|
||
JSR R0,CKTCRL
|
||
.ASCIZ /IOT/
|
||
.EVEN
|
||
BR ILSCOM
|
||
.ENDC;.IF NE FT.HLP
|
||
.ENDC;.IF EQ FT.TSK
|
||
;HERE ON A EMT INSTRUCTION
|
||
EMTINT: ;DIE IN USUAL WAY
|
||
.IF NE FT.HLP
|
||
SAVE <R0,R1>
|
||
JSR R0,CKTCRL
|
||
.ASCIZ /EMT/
|
||
.EVEN
|
||
BR ILSCOM
|
||
.ENDC;.IF NE FT.HLP
|
||
|
||
;HERE ON RANDOM INTERRUPT
|
||
ERRINT: ;DIE IN USUAL WAY
|
||
.IF NE FT.HLP
|
||
SAVE <R0,R1>
|
||
JSR R0,CKTCRL
|
||
.ASCIZ /FATAL ERROR/
|
||
.EVEN
|
||
BR ILSCM0
|
||
ILSCOM: JSR R0,CKTSTR
|
||
.ASCIZ \ INSTRUCTION\
|
||
.EVEN
|
||
ILSCM0: JSR PC,CM.INT
|
||
.ENDC;.IF NE FT.HLP
|
||
|
||
STOPCD ILS
|
||
|
||
|
||
.IF NE FT.HLP
|
||
CM.INT: MOV 6(P),R0
|
||
JSR PC,CKTYPC ;TYPE " @PC=<VALUE><CR><LF>"
|
||
RESTORE <R0,R1>
|
||
RTS R0
|
||
.ENDC ;.IF NE FT.HLP
|
||
.IF NE FT.HLP
|
||
CKTYPC: ;TYPE " @PC=<VALUE><CR><LF>
|
||
JSR R0,CKTSTR
|
||
.ASCIZ \ @PC=\
|
||
.EVEN
|
||
JSR PC,CKTOCT
|
||
JSR PC,CKCRLF
|
||
RTS PC
|
||
.ENDC
|
||
;HERE ON A TRAP INSTRUCTION
|
||
Q=0 ;OFFSET FOR PC ON STACK
|
||
TRPINT: SUB #2,(P) ;BACKUP TO TRAP INSTRUCTION
|
||
|
||
.IIF NE FTDL10, MOV @DL10AD,#0 ;SAVE DL10 STATUS HERE
|
||
; TWIDDLE SW ;PUT SWICHES HERE
|
||
MOV %5,-(P) ;SAVE REGISTERS
|
||
MOV %4,-(P)
|
||
MOV %3,-(P)
|
||
MOV %2,-(P)
|
||
MOV %1,-(P)
|
||
MOV %0,-(P)
|
||
CRSPDL: MOV P,#0 ;FOR THOSE WHO READ DUMPS
|
||
Q=14 ;OFFSET FOR PC HAS CHANGED
|
||
.IF NE DEBUG
|
||
.IF EQ FT.SLB
|
||
.IF NE NLINES
|
||
MOV #FRSTLB,J ;GET LINE BLOCK ADR FOR FIRST LINE
|
||
BR 21$
|
||
20$: MOV LB.SLA(J),DQ ;GET SYNCHRONOUS LINE HDW ADR
|
||
MOV DQ,R0 ;COPY ADDRESS OF DEVICE
|
||
MOV J,R1 ;COPY LINE BLOCK ADDRESS
|
||
ADD #LB.CRS,R1 ;POINT TO SAVE AREA
|
||
MOV (R0)+,(R1)+ ;SAVE SYNCHRONOUS LINE HDW STATE
|
||
MOV (R0)+,(R1)+ ;SAVE TRANSMITTER STATUS
|
||
MOV (R0)+,(R1)+
|
||
MOV (R0)+,(R1)+
|
||
.IF NE FTDQ11
|
||
DQREGS PRA
|
||
MOV 6(DQ),(R1)+
|
||
DQREGS SRA
|
||
MOV 6(DQ),(R1)+
|
||
DQREGS PTA
|
||
MOV 6(DQ),(R1)+
|
||
DQREGS STA
|
||
MOV 6(DQ),(R1)+
|
||
.ENDC;.IF NE FTDQ11
|
||
21$: MOV LB.LNK(J),J ;GET ADR OF NEXT LINE BLOCK
|
||
BNE 20$
|
||
.ENDC;.IF NE NLINES
|
||
.ENDC;.IF EQ FT.SLB
|
||
.ENDC;.IF NE DEBUG
|
||
|
||
CLR R0 ;HESITATE
|
||
27$: SOB R0,27$
|
||
RESET
|
||
|
||
.IF NE FT.HLP
|
||
JSR R0,CKTCRL
|
||
.ASCIZ \TRAP\
|
||
.EVEN
|
||
MOVB @Q(P),R0 ;GET CODE IF ANY
|
||
BEQ 30$
|
||
JSR PC,CKTBOC ;TYPE CODE AND BLANK
|
||
30$:
|
||
MOV Q(P),R0
|
||
JSR PC,CKTYPC ;TYPE " @PC=<VALUE><CR><LF>
|
||
.ENDC
|
||
.IIF NE FT.DTE, JSR PC,DTERLD ;ASK -10 TO RELOAD US
|
||
|
||
;THE PROGRAM ENTRY INTO THE M9301 ROM TAKES IN R0 THE ADDRESS
|
||
; OF A FOUR WORD ARGUMENT BLOCK. THE ARGUMENTS IN THIS BLOCK ARE
|
||
; AS FOLLOWS.
|
||
; 1) THIS IS THE SERIAL NUMBER OF THIS 11 (DEFAULT'S TO OUR
|
||
; NODE NUMBER FOR CONVENIENCE)
|
||
; 2) THIS IS THE NODE NUMBER OF THE TEN THAT WE WANT TO BOOT
|
||
; US. (ZERO MEANS ANY TEN)
|
||
; 3) THIS IS THE NUMBER OF THE DQ-11 TO USE WHEN BOOTING
|
||
; 4) THIS IS THE ADDRESS OF AN ASCIZ STRING TO PASS AS A
|
||
; COMMAND STRING TO NETLDR. ZERO IMPLIES NO COMMAND STRING
|
||
|
||
|
||
;THE FOLLOWING MACRO BUILDS THE PARAMETER BLOCK FOR THE ROM.
|
||
|
||
.MACRO NETLDR S,N,L,TEXT
|
||
.WORD S
|
||
.WORD N
|
||
.WORD L
|
||
.IF NB <TEXT>
|
||
.WORD .+2
|
||
.ASCIZ \TEXT\
|
||
.EVEN
|
||
.IFF
|
||
.WORD 0
|
||
.ENDC
|
||
.ENDM ;NETLDR
|
||
|
||
.IF NE FT.ROM
|
||
GO.ROM: JSR R0,ROMADR ;GO BOOT FROM THE PROM
|
||
|
||
.IF NE FTNTLD ;IF THE USER SPECIFIED THE PARMS,
|
||
LDCNFG ;THEN USE HIS CONFIG.
|
||
.IFF ;OTHERWISE USE THE DEFAULT
|
||
NETLDR OURNNM,0,0 ;SERIAL=OURNNM,NODE=0,DQ=0,NO TEXT.
|
||
.ENDC
|
||
.ENDC; FT.ROM
|
||
|
||
.IIF NE FT.MOP,JMP MOPDMP ;IF A DN22, GO USE MOP HACK
|
||
|
||
.IF EQ FT.MOP!FT.ROM ;IF NEITHER ROM OR MOP
|
||
MOVB @Q(P),R0 ;GET STOPCD(IF ANY)
|
||
BEQ 97$
|
||
.IF NE FTDL10
|
||
BIT #DL.PEN,@DL10AD ;IS PORT ENABLED ?
|
||
BEQ 95$
|
||
MOV DL10AD,R1 ;POINT INTO WINDOW
|
||
MOV R0,DL.STP(R1) ;SAVE STOP CODE FOR LOSER
|
||
.ENDC;.IF NE FTDL10
|
||
95$: HALT
|
||
97$: MOV Q(P),R0 ;GET TRAP ADR
|
||
HALT
|
||
JMP BEGIN ;RESTART
|
||
.ENDC; FT.ROM!FT.MOP
|
||
;JMP HERE ON SOME IMPOSSIBLE ERRORS
|
||
|
||
SYSERR: TRAP
|
||
|
||
|
||
.CKTTS
|
||
.SBTTL TRAP INTERCEPT SET/CLEAR
|
||
|
||
;TRPST -- SET UP FOR INTERCEPTION OF NXM ERRORS (ANYTHING THROUGH TRAP 4)
|
||
;CALL IS:
|
||
;
|
||
; JSR R0,TRPST
|
||
; .WORD ADR
|
||
;
|
||
;WHERE ADR IS THE INTERCEPT TRAP ADDRESS WHICH SHOULD GAIN CONTROL SHOULD
|
||
;A TRAP THROUGH 4 OCCUR.
|
||
;
|
||
;THE CALLER MUST NOT HAVE ANY DATA PUSHED ONTO THE STACK (HE MUST BE
|
||
;READY TO "RTS PC" TO HIS CALLER!!!
|
||
;
|
||
;YOU MAY NEST AS MANY CALLS TO TRPST AS THERE IS STACK SPACE (I.E., YOU
|
||
;DON'T HAVE TO WORRY ABOUT THE "TRAP" RESOURCE, IT IS RECURSIVE).
|
||
;
|
||
;THE TRAP INTERCEPT WILL BE AUTOMATICALLY CLEARED WHEN THE CALLER EXECUTES
|
||
;HIS "RTS PC".
|
||
;
|
||
;ON A TRAP, THE TRAP SERVICE ROUTINE IS ENTERED WITH THE STACK AND PI AT
|
||
;THE SAME LEVEL AS AT THE CALL TO TRPST (E.G., YOU MAY POINT THE TRAP
|
||
;ADDRESS AT THE ROUTINE'S "RTS PC", SEE DTEINI FOR AN EXAMPLE).
|
||
;
|
||
;THE CARRY BIT IS PRESERVED, ALL OTHER CONDITION CODE BITS ARE LOST.
|
||
|
||
TRPST: MOV @#PS,-(P) ;SAVE THE CURRENT PI/PROCESSOR STATUS
|
||
MOV TRPSP,-(P) ;SAVE THE OLD (CURRENT) STACK
|
||
MOV TRPPC,-(P) ; AND PC WORDS
|
||
MOV P,TRPSP ;SET THE NEW TRAP STACK
|
||
MOV (R0)+,TRPPC ; AND PC WORDS.
|
||
MOV R0,-(P) ;ADDRESS OF CALLER TO BE CALLED
|
||
MOV 10(P),R0 ;RESTORE R0 FOR CALLER
|
||
JSR PC,@(P)+ ;AND CALL OUR CALLER
|
||
|
||
;HERE WHEN OUR CALLER HAS FINISHED AND "RTS PC"'ED BACK TO US TO CLEAR
|
||
;THE TRAP INTERCEPT
|
||
|
||
MOV (P)+,TRPPC ;RESTORE PREVIOUS LEVEL'S PC
|
||
MOV (P)+,TRPSP ; AND STACK WORDS
|
||
BIT (P)+,(P)+ ;POP OFF TWO MORE JUNK WORDS
|
||
RTS PC ;RETURN TO CALLER'S CALLER
|
||
;TRPCL -- UNDO A CALL TO TRPST
|
||
;CALL IS:
|
||
;
|
||
; JSR PC,TRPCL
|
||
;
|
||
;MUST BE CALLED AT SAME STACK LEVEL AS TRPST CALL.
|
||
|
||
TRPCL: MOV (P)+,10(P) ;FINAL RETURN ADDRESS
|
||
BIT (P)+,P ;POP OFF JUNK (TRPST JSR) WORD
|
||
MOV (P)+,TRPPC ;RESTORE PREVIOUS LEVEL'S PC
|
||
MOV (P)+,TRPSP ; AND STACK WORDS.
|
||
BIT (P)+,P ;POP OFF ANOTHER JUNK WORD
|
||
RTS PC ;AND RETURN
|
||
.SBTTL POWER FAIL INTERRUPT
|
||
|
||
PWFINT: TWIDDLE ;COUNT POWER FAIL TRAPS
|
||
MOV #PWFINU,PWFVEC ;ON POWER RESTART, RESTART US
|
||
CLR R0 ;INITIALIZE SOB
|
||
SOB R0,. ;WAIT FOR POWER RESTART
|
||
|
||
;IF THE SOB FALLS THROUGH TO HERE (SEVERAL CLOCK TICKS LATER) THEN WE
|
||
;HAVE A SPURIOUS POWER FAIL CONDITION.
|
||
|
||
TWIDDLE ;AN INTERESTING EVENT IN ITSELF
|
||
; BR PWFINU ;ASSUME POWER FAIL RESTART
|
||
.SBTTL NORMAL STARTUP AND POWER FAIL RESTART
|
||
|
||
;HERE ON EITHER POWER FAIL RESTART, OR SUPRIOUS POWER FAIL INTERRUPT
|
||
|
||
PWFINU: TWIDDLE ;COUNT POWER FAIL RESTARTS
|
||
CLR R0 ;INIT FOR SOB LOOP
|
||
SOB R0,. ;WAIT FOR THINGS TO SETTLE DOWN
|
||
|
||
;NORMAL NODE STARTUP
|
||
|
||
BEGIN: RESET ;CLEAR THE WORLD
|
||
MOV #PDL,P ;GET A GOOD STACK
|
||
CLR TRPPC ;NO TRAP INTERCEPT IN EFFECT
|
||
MOV #PWFINT,PWFVEC ;RESET POWER FAIL IN CASE POWER RESTART
|
||
|
||
.IF NE FT.87S+FT.D20
|
||
;THE FIRST TIME THROUGH HERE THE ROM HAS LEFT R1 POINTING TO THE
|
||
;STATUS REGISTER FOR THE DTE THAT LOADED US. SAVE THAT INFO FOR USE
|
||
;LATER ON. ON A POWER-FAIL RESTART, R1 WILL BE JUNK SO WE ASSUME
|
||
;THAT .PRDTE WILL STILL BE THE CORRECT DTE. IF NOT, THEN TENSEC (OR
|
||
;SOMEONE) WILL NOTICE AND CLEAR IT, FORCING TENSEC TO START SCANNING
|
||
;FOR AN EXTANT DTE. SIMILARLY, IF BOOTED VIA A SYNC LINE TENSEC WILL
|
||
;EVENTUALLY FIND A WORKING DTE (IF ANY EXIST). THE ONLY REAL REASON
|
||
;THIS CODE EXISTS IS TO FORCE THE -11 TO USE THE DTE FROM WHICH IT
|
||
;WAS LOADED ON THE OFF CHANCE THE -11 HAS MORE THAN ONE DTE.
|
||
|
||
BIC #TE.BNX-1,R1 ;ADJUST TO START OF REGISTERS
|
||
CMP R1,#TE.BAS ;IS R1 POINTING TO A DTE?
|
||
BLO 5$ ;BELOW FIRST DTE, FORGET IT
|
||
CMP R1,#TE.BAS+<TE.NNN*TE.BNX> ;IS R1 POINTING TO A DTE?
|
||
BHIS 5$ ;ABOVE LAST DTE, FORGET IT
|
||
MOV R1,.PRDTE ;VALID DTE, SAVE OUR LOADING DTE
|
||
ADD #TE.STW,R1 ;OFFSET TO DTE STATUS REGISTER
|
||
MOV R1,.PRSTA ;SAVE DTE STATUS REG ADR ALSO
|
||
5$:
|
||
.ENDC;.IF NE FT.87S+FT.D20
|
||
|
||
JSR PC,CHK.11 ;BE SURE HDW ALL HERE
|
||
.WORD MYNAME
|
||
RCOUNT: TWIDDLE ;COUNT RESTARTS
|
||
MOV #NXMINT,NXMVEC ;SET BUS TRAP LOCATION
|
||
.SBTTL INITIALIZATION CODE
|
||
|
||
;ENABLE THE MEMORY PARITY OPTION
|
||
.IF GE <PDP11-34>
|
||
MP.ARM: MOV #MP.ENB,MP.REG ;ARM PARITY OPTION
|
||
.ENDC;.IF GE <PDP11-34>
|
||
|
||
.IF NE FTDL10
|
||
09$: BIT #DL.PEN,@DL10AD ;IS DL10 PORT ENABLED ?
|
||
BNE 09$ ;IF SO WAIT FOR 10
|
||
.ENDC
|
||
Z=ROMLOW&160000
|
||
.IF NE Z-160000 ;IF ROM PROG IN READ/WRITE MEMORY - BETTER BE CAREFUL
|
||
MOV #ROMLOW,PHYLIM
|
||
.ENDC
|
||
;THE FOLLOWING ZEROES HIGH CORE FOR DUMPS
|
||
.IF NE FTCLEAR
|
||
MOV PRGEND,R0 ;FIRST LOCATION TO ZERO
|
||
10$: CLR (R0)+ ;CLEAR HIGH CORE
|
||
CMP R0,PHYLIM
|
||
BNE 10$
|
||
.ENDC;.IF NE FTCLEAR
|
||
;INITIALIZE CHUNKS
|
||
CLR FRECNT ;NO CHUNKS YET
|
||
CLR LSTFRE ;NO CHUNKS YET
|
||
MOV PRGEND,R2 ;ADR OF CHUNK
|
||
15$: MOV R2,R0 ;COPY ADR OF CHUNK
|
||
ADD #CNKSIZ,R2 ;MAKE ADR OF NEXT CHUNK
|
||
CMP R2,PHYLIM
|
||
BHI 20$ ;EXIT IF WE'RE AT THE END OF MEMORY
|
||
JSR PC,FRECNK ;FREE CHUNK
|
||
BR 15$
|
||
20$:
|
||
MOV FRECNT,FREMAX
|
||
|
||
;INITIALIZE THE QUEUES
|
||
.MACRO X Q
|
||
MOV #Q'.QUE,Q'.PTR
|
||
MOV #Q'.QUE,Q'.TKR
|
||
.ENDM X
|
||
X QI
|
||
X QO
|
||
X NC
|
||
.IIF NE,FT.DCP, X NS ;NSP QUEUE
|
||
.IIF NE DEVN, X DV
|
||
.IIF NE FTDL10, CLR T10QUE ;CLEAR TO-10 QUEUE POINTER
|
||
.IIF NE FT.DTE, JSR PC,DTEINI ;INIT DTE DATA BASE IF WE HAVE ONE
|
||
.IIF NE DMCN, JSR PC,DMCONC ;SET UP THE DMC-11 MESSAGE BUFFER POOL
|
||
;HERE TO INITIALIZE THE DDCMP LINES
|
||
INI.10:
|
||
.IF NE NTLINE
|
||
.IF NE,FT.DCP
|
||
.IIF NE FTDCP3!FTDCP4, JSR PC,NSPINI ; CLEAR DCP DATABASE
|
||
.ENDC
|
||
MOV #FRSTLB,J ;ADR OF FIRST BLOCK
|
||
BR 13$
|
||
10$: MOV #<LB.SIZ-LB.ZER>/2,R0 ;ESTABLISH COUNTER
|
||
MOV J,R1 ;MAKE ADDR OF WORD TO ZERO
|
||
ADD #LB.ZER,R1
|
||
12$: CLR (R1)+
|
||
SOB R0,12$
|
||
BIC #^C<LS.MPT>,(J) ;VIRGIN LINE STATUS
|
||
JSR PC,DDCINI ;DO DDCMP INITIALIZATION
|
||
13$: MOV LB.LNK(J),J ;GET ADR OF NEXT BLOCK
|
||
BNE 10$
|
||
.ENDC;.IF NE NTLINE
|
||
|
||
;INITIALIZE THE STATION CONTROL BLOCKS
|
||
MOV #<SEQLIM*2>,R0
|
||
20$: CLRB SQNTAB-1(R0)
|
||
SOB R0,20$
|
||
MOV #OURSCB,SB ;GET STATION BLOCK
|
||
30$: JSR PC,CLRSCB ;CLEAR REST OF BLOCK
|
||
SB.ADV 30$ ;CLEAR NEXT BLOCK ALSO
|
||
.IF NE FTDL10!FT.DTE
|
||
CLR TENSCB ;NO PATH TO THE TEN
|
||
.ENDC ;END .IF NE FTDL10!FT.DTE
|
||
MOV #OURSCB,SB ;OUR SCB ADR AGAIN
|
||
BIS #SBF.SQ!SBF.IC!SBF.IU!SF.HID,@SB ;FLAG BLOCK IN USE
|
||
MOV SB,SQNTAB ;1ST NONSEQUENTIAL NODE IS US
|
||
;INITIALIZE THE DEVICES
|
||
.IF NE DEVN
|
||
DDBINI: MOV FIRDDB,J ;GET FIRST DEVICE BLOCK
|
||
10$: BIC #DS.QUE!DS.ACT,@J ;CLRDDB WON'T HIT THESE BITS
|
||
.IF NE FT.TSK
|
||
MOV J,R0
|
||
ADD #DB.TSK,R0
|
||
CLR (R0)+ ;AND WON'T GET THESE
|
||
CLR (R0)+
|
||
CLR (R0)+
|
||
CLR (R0)
|
||
.ENDC;.IF NE FT.TSK
|
||
|
||
JSR PC,CLRDDB ;CLEAN OUT DEVICE BLOCK
|
||
|
||
.IF NE FT.CTY!TTYN!RDAN
|
||
BIT #DS.TTY,@J ;WAS THIS A TTY ?
|
||
.IF NE FT.RDA
|
||
BNE 14$ ; YES
|
||
BIT #RDEASC,DB.RDT(J) ;ASCII RDX ?
|
||
.ENDC
|
||
BEQ 90$ ; NO
|
||
|
||
;INITIALIZE ASCII TTY AND RDA DEVICES
|
||
|
||
14$: MOV J,R0 ;POINT TO BYTES TO CLEAR
|
||
ADD #DB.TZR,R0
|
||
MOV #DB.TSZ-DB.TZR,R1 ;AND GET THERE NUMBER
|
||
11$: CLRB (R0)+ ;AND CLEAR THEM
|
||
SOB R1,11$
|
||
CLR DB.TOB(J) ;NO TTY OUTPUT YET
|
||
CLR DB.TOB+2(J)
|
||
.IF NE FT.TSK
|
||
MOV #DB.KQU,DB.KPT(J) ;INITIALIZE KEYBOARD PUTER
|
||
MOV #DB.KQU,DB.KTK(J) ;INITIALIZE KEYBOARD TAKER
|
||
.ENDC;.IF NE FT.TSK
|
||
.IF NE FT.RDA
|
||
BIT #RDEASC,DB.RDT(J) ;ASCII RDX ?
|
||
BNE 15$ ; YES, DONT DO IT
|
||
.ENDC
|
||
MOV #RSTMSG,DB.STR(J) ;START UP MESSAGE
|
||
15$:
|
||
.IF NE FT.CTY
|
||
CMP J,#CTYDDB ;IS THIS CTY ?
|
||
BEQ 44$ ;IF SO DON'T INITIALIZE DL11
|
||
.ENDC;.IF NE FT.CTY
|
||
MOV DB.DHB(J),R3 ;GET ADR OF DH/DZ11 BLOCK FOR LINE
|
||
MOV DB..LN(J),R2 ;SET UP LINE # FOR DH/DZ.INI
|
||
.IF NE FT.RDA
|
||
BIT #DS.TTY,@J ;IS IT TTY?
|
||
BEQ 67$ ; NO
|
||
.ENDC
|
||
|
||
;ASCII TTY ONLY
|
||
|
||
.IF NE TTYN
|
||
JINDEX JMP,DB.TYP(J),R0,29$
|
||
29$: .WORD 30$ ; DH-11
|
||
.WORD 31$ ; DZ-11
|
||
|
||
30$:
|
||
.IF EQ TTYDHN
|
||
TRAP ; NO DH TTYS!
|
||
.IFF
|
||
SAVE <#TTDHOU,#TTDHIN,DB.LCB(J)>
|
||
JSR PC,DH.INI ; INITIALIZE THE DH11 AND LCB
|
||
BR 40$ ; CONTINUE
|
||
.ENDC ;.IF EQ TTYDHN
|
||
|
||
31$:
|
||
.IF EQ TTYDZN
|
||
TRAP ; DO DZ TTYS!
|
||
.IFF
|
||
SAVE <#TTDZOU,#TTDZIN,DB.LCB(J)>
|
||
JSR PC,DZ.INI
|
||
.ENDC ;.IF EQ TTYDZN
|
||
.ENDC ; TTYN
|
||
|
||
40$: ADD #6,P ; POP THE ARGS TO DH/DZ.INI
|
||
|
||
.IF NE FTDN11
|
||
BITB #40,DB.DVT(J) ;IS IT AUTO-DIAL LINE?
|
||
BEQ 44$ ;NO, CONTINUE
|
||
BIC #^CDNDISP,DB.DNS(J) ;CLEAR DIAL BIT & TIMER
|
||
JSR PC,DNADDR ;R1=DNTAB,R2=HDW
|
||
BIC #7,R2 ;INITIALIZE
|
||
MOV #DN..ME,(R2)+ ;SET MASTER ENABLE IN FIRST UNIT
|
||
CLR (R2)+ ;CLR 2ND UNIT
|
||
CLR (R2)+ ;CLR 3RD UNIT
|
||
CLR (R2)+ ;CLR 4TH UNIT
|
||
MOV J,2(R1) ;PUT DDB ADDRESS INTO DNBLK
|
||
.ENDC;.IF NE FTDN11
|
||
|
||
44$: JSR PC,BEGXMT ;START LINE TYPING
|
||
BR 90$ ;THE TTY LINE IS INITIALIZED
|
||
.ENDC;.IF NE FT.CTY!TTYN!RDAN
|
||
|
||
;ASCII RDA
|
||
|
||
.IF NE FT.RDA
|
||
67$: JINDEX JMP,DB.TYP(J),R0,69$
|
||
69$: .WORD 70$ ; DH-11 RDA
|
||
.WORD 71$ ; DZ-11 RDA
|
||
|
||
70$:
|
||
.IF EQ RDADHN
|
||
TRAP ; NO DH-11 RDAS!
|
||
.IFF
|
||
SAVE <#RDDHOU,#RDDHIN,DB.LCB(J)>
|
||
JSR PC,DH.INI ; SET UP DH AND LINE BLOCK
|
||
BR 40$
|
||
.ENDC ;.IF EQ RDADHN
|
||
|
||
71$:
|
||
.IF EQ RDADZN
|
||
TRAP ; NO DZ-11 RDAS!
|
||
.IFF
|
||
SAVE <#RDDZOU,#RDDZIN,DB.LCB(J)>
|
||
JSR PC,DZ.INI
|
||
BR 40$
|
||
.ENDC ;.IF EQ RDADZN
|
||
.ENDC ;.IF NE FT.RDA
|
||
|
||
;STEP TO NEXT DDB
|
||
|
||
90$: MOV DB.LNK(J),J ;GET NEXT DEVICE BLOCK
|
||
BEQ 99$
|
||
JMP 10$ ;CLEAR IT OUT
|
||
99$:
|
||
.ENDC;.IF NE DEVN
|
||
;INITIALIZE THE TTY'S
|
||
.IF NE <FT.CTY+TTYN+RDAN>
|
||
MOV #TI.QUE,TI.PTR ;POINTER TO TTY INPUT SILO
|
||
MOV #TI.QUE,TI.TKR
|
||
.IIF NE FT.CTY, BIS #100,CTISTS ;ENABLE CTY KEYBOARD
|
||
.ENDC;.IF NE <FT.CTY+TTYN+RDAN>
|
||
|
||
.IF NE FT.TSK
|
||
TSKINI: MOV #RUNQUE,R0 ;POINT TO 1ST RUN QUEUE
|
||
MOV #TKPMAX,R1 ;GET THE NUMBER OF QUEUES
|
||
12$: CLR (R0)+ ;AND CLEAR THEM
|
||
SOB R1,12$
|
||
CLR TASK ;FLAG NO CURRENT JOB
|
||
CLR L.TASK
|
||
MOV #FIRTSK,J ;GET FIRST TASK BLOCK ADR
|
||
20$: BEQ 30$
|
||
MOV TK.JSA(J),R0 ; START ADDR
|
||
CMP #1,RCOUNT+2 ; RESTARTING ?
|
||
BEQ 25$ ; YES, WE ARE
|
||
MOV TK.RSA(J),R0 ; NO, USE RESTART ADDR
|
||
25$: JSR PC,TSKBEG ; START TASK
|
||
MOV TK.LNK(J),J ; NEXT TASK, PLEASE
|
||
BR 20$
|
||
30$:
|
||
.ENDC;.IF NE FT.TSK
|
||
CLR PS ;ENABLE INTERRUPTS
|
||
|
||
.IIF NE FT.87S+FT.D20,JSR PC,RINIDB ;RING THE -10'S CHIMES (KEEP DTELDR HAPPY)
|
||
|
||
;START THE CLOCK
|
||
MOV #CLKENB,CLKWRD
|
||
.SBTTL MAIN PROGRAM LOOP
|
||
|
||
LOOP:
|
||
;COMMON BUG IS TO CLEAR THIS
|
||
ASSERT 0 EQ #ERRINT
|
||
ASSERT #NXMINT EQ NXMVEC ;AND CHECK BUS TRAP LOCATION ALSO
|
||
ASSERT #7*40 CLEAR IN PS ;CHECK TO SEE PION
|
||
ASSERT #PDL EQ P ;DID SOMEONE GARBAGE STACK ?
|
||
MOV #2$,NXMVEC ;RESET BUS TRAP VECTOR
|
||
MOV @SW,SW ;DISPLAY IN THE LIGHTS
|
||
2$: MOV #NXMINT,NXMVEC ;RESET BUS TRAP VECTOR
|
||
MOV #PDL,P ;IN CASE WE TRAPPED
|
||
SPL 0 ;REENABLE INTERRUPTS
|
||
TST JIFFLG ;HAS CLOCK TICKED ?
|
||
BEQ 4$
|
||
JSR PC,JIFSCN ;YES SO DO ONCE PER TICK CODE
|
||
CLR JIFFLG ;RESET FLAG FOR NEXT TIME
|
||
4$:
|
||
|
||
.IF NE <FT.CTY+TTYN+RDAN>
|
||
QUEGET TI,5$ ;GET NEXT ENTRY ON TTY INPUT QUEUE
|
||
JSR PC,RECINT ;GO HANDLE INPUT
|
||
BR 4$ ;NOW GO BACK FOR MORE
|
||
5$:
|
||
.ENDC;.IF NE <FT.CTY+TTYN+RDAN>
|
||
|
||
;HERE TO CHECK DDCMP
|
||
|
||
.IF NE NTLINE
|
||
QUEGET QI,20$ ;GET ENTRY FROM QUEUE
|
||
JMP DDCINP ;CHECK DDCMP INPUT
|
||
|
||
20$: ;CHECK OUTPUT QUEUE
|
||
QUEGET QO,30$ ;GET ENTRY FROM QUEUE
|
||
; ASSERT J BETWEEN #LBLK0 #<LBLK0+<NTLINE*LB.SIZ>>
|
||
TRACE DD
|
||
JMP DDCXMT ;TRY TO SEND SOMETHING
|
||
|
||
.ENDC;.IF NE NTLINE
|
||
30$: ;CHECK NCL QUEUE
|
||
.IF NE,FT.DCP
|
||
JSR PC,NSPCHK ;CHECK TO SEE WHAT IS TO BE DONE
|
||
.ENDC; NE,FT.DCP
|
||
QUEGET NC,40$ ;GET STATION WHICH WANTS ATTENTION
|
||
BIT #SBF.IU,@SB ;IS BLOCK STILL IN USE ?
|
||
BEQ 30$ ;WHERE TO GO WHEN NONE
|
||
TRACE NC
|
||
.IIF NE FT.SNK, CLR J
|
||
JSR PC,NCLCHK ;GO CHECK STATION
|
||
40$:
|
||
|
||
.IF NE DEVN
|
||
QUEGET DV,50$ ;GET ENTRY FROM QUEUE
|
||
TRACE DV ;KEEP TRACKS
|
||
JSR PC,@DB.OPC(J) ;DISPATCH TO ROUTINE
|
||
50$:
|
||
.ENDC;.IF NE DEVN
|
||
.IIF NE FTDL10, JSR PC,LOOPDL ;CHECK ON 10'S ACTIVITIES
|
||
.IIF NE FT.DTE, JSR PC,LOOPDT ;DITTO
|
||
.IIF NE FT.TSK, JSR PC,LOOPTK ;SEE WHAT CAN BE DONE FOR TASKS
|
||
JMP LOOP ;NOW REPEAT ALL THIS UNTILL
|
||
;YOU GET IT WRONG
|
||
.SBTTL QUEUE PUT,GET ROUTINES
|
||
;
|
||
;HERE TO QUEUE INPUT AND OUTPUT (DDCMP)
|
||
;
|
||
.IF NE NTLINE
|
||
QUEPUT QO CODE ;PROCEDURE FOR INSERTING IN THE QO QUEUE
|
||
QUEPUT QI CODE ;PROCEDURE FOR INSERTING IN THE QI QUEUE
|
||
.ENDC ; .IF NE NTLINE
|
||
;
|
||
.SBTTL CHUNK HANDLING ROUTINES
|
||
|
||
;CHUNK CONVENTIONS
|
||
; CHUNK SIZE IS A POWER OF TWO
|
||
; ADR OF CHUNK IS A MULTIPLE OF CHUNK SIZE
|
||
; FIRST WORD OF CHUNK IS A LINK TO THE NEXT CHUNK ADR OR 0
|
||
; 2ND WORD OF CHUNK IS A POINTER TO NEXT BYTE IN CHUNK TO FILL
|
||
;CABLTB -- "BLT" A BYTE STREAM, ALLOCATING NEW CHUNK (ERSGET)
|
||
;CGBLTB -- "BLT" A BYTE STREAM, ALLOCATING NEW CHUNK (GETCNK)
|
||
;CALL: MOV <SRC>,R1
|
||
; MOV <CNT>,R2
|
||
; JSR PC,CABLTB
|
||
; RETURN
|
||
;
|
||
;WHERE <SRC> IS SOURCE BYTE ADDRESS, AND <CNT> IS THE COUNT OF BYTES TO BE
|
||
;COPIED.
|
||
;
|
||
;CABLTB AND CGBLTB WILL MAKE A COPY OF THE BYTE STREAM POINTED TO BY R1/R2,
|
||
;STARTING WITH A NEW FRESH CHUNK. FOR CGBLTB, IF A NEW STREAM COULDN'T BE
|
||
;STARTED, RETURN IS "BEQ".
|
||
;
|
||
;ON RETURN, R0 POINTS TO FIRST CHUNK IN RESULTANT COPY, R1/R2 UPDATED.
|
||
|
||
CABLTB: JSR PC,ERSGET ;GET A CHUNK OR ELSE
|
||
BNE CMBLTB ;WE GOT IT
|
||
TRAP ;"OR ELSE" GOT US INSTEAD
|
||
|
||
CGBLTB: JSR PC,GETCNK ;GET A CHUNK IF CONVENIENT
|
||
BNE CMBLTB ;WE GOT IT
|
||
RTS PC ;WE DIDN'T GET IT, SO IT GOES
|
||
|
||
CMBLTB: MOV R2,CN.LEN(R0) ;PRESET FINAL COPYED LENGTH
|
||
MOV R0,-(P) ;SAVE START OF COPYED BYTE STREAM
|
||
ADD #CN.NCT,R0 ;FIRST DATA BYTE WITHIN NEW BYTE STREAM
|
||
JSR PC,CNBLTB ;COPY THE DATA, ALLOCATING AS NEEDED
|
||
MOV (P)+,R0 ;RESTORE ORIGINAL NEW COPY ADDRESS
|
||
RTS PC ;RETURN WITH COPYED BYTE STREAM
|
||
;CNBLTB -- "BLT" A BYTE STREAM, ALLOCATING NEW CHUNKS AS NEEDED
|
||
;CALL: MOV <DST>,R0
|
||
; MOV <SRC>,R1
|
||
; MOV <CNT>,R2
|
||
; JSR PC,CNBLTB
|
||
; RETURN
|
||
;
|
||
;WHERE <DST> IS THE DESTINATION BYTE ADDRESS TO START STORING THE COPIED BYTE
|
||
;STREAM; <SRC> IS THE SOURCE BYTE ADDRESS TO COPY FROM; AND <CNT> IS THE NUMBER
|
||
;OF BYTES TO BE COPIED.
|
||
;
|
||
;ON RETURN, R0/R1/R2 UPDATED.
|
||
|
||
.REPT 0
|
||
CNBLTB: MOVB (R1)+,(R0)+ ;COPY ANOTHER BYTE
|
||
ADVCNK R0 EXTEND ;ALLOCATE NEW CHUNK IF NEEDED
|
||
ADVCNK R1 FREE ;FREE UP STALE CHUNK IF FINISHED
|
||
SOB R2,CNBLTB ;LOOP FOR ENTIRE BYTE STREAM
|
||
RTS PC ;RETURN WITH COPYED BYTES
|
||
.ENDR ;.REPT 0
|
||
|
||
CNBLTB: MOV R3,-(P) ;SAVE A REGISTER
|
||
1$: MOV #CNKSIZ-1,R3 ;PROTOTYPE CHUNK BOUNDRY TESTER
|
||
|
||
;LOOP COPYING BYTES
|
||
|
||
10$: MOVB (R1)+,(R0)+ ;COPY ANOTHER BYTE
|
||
BIT R3,R0 ;ADVCNK R0 EXTEND
|
||
BNE 14$ ;CONTINUE
|
||
JSR PC,GTCKR0 ; EXTEND
|
||
14$: BIT R3,R1 ;ADVCNK R1 FREE
|
||
BNE 16$ ;CONTINUE
|
||
JSR PC,FRCKR1 ; FREE
|
||
16$: SOB R2,10$ ;LOOP FOR ENTIRE BYTE STREAM
|
||
17$: MOV (P)+,R3 ;RESTORE SCRATCH REGISTER
|
||
RTS PC ;RETURN WITH COPYED BYTES
|
||
;AVCKRN -- ADVANCE TO NEXT CHUNK IN CHAIN, NEITHER FREEING NOR ALLOCATING
|
||
|
||
;ACVKR0 - R0 CHUNK ADDRESS
|
||
|
||
AVCKR0: BIT #CNKSIZ-1,R0 ;IF NOT AT A CHUNK BOUNDARY
|
||
BNE 10$ ;EXIT ITS OK
|
||
MOV -CNKSIZ(R0),R0 ;ELSE ADVANCE TO THE NEXT CHUNK
|
||
BEQ 10$ ;AND EXIT IF NONE
|
||
ADD #2,R0 ;ELSE SKIP THE LINK WORD
|
||
10$: RTS PC
|
||
|
||
|
||
;AVCKR3 - R3 CHUNK ADDRESS
|
||
|
||
AVCKR3: BIT #CNKSIZ-1,R3 ;IF NOT AT A CHUNK BOUNDARY
|
||
BNE 10$ ;EXIT ITS OK
|
||
MOV -CNKSIZ(R3),R3 ;ELSE ADVANCE TO THE NEXT CHUNK
|
||
BEQ 10$ ;AND EXIT IF NONE
|
||
ADD #2,R3 ;ELSE SKIP THE LINK WORD
|
||
10$: RTS PC
|
||
;GTCKRN -- ADVANCE TO NEXT CHUNK IN CHAIN, ALLOCATING NEW CHUNK IF REQUIRED
|
||
|
||
;GTCKR0 - R0 CHUNK ADDRESS
|
||
|
||
GTCKR0: BIT #CNKSIZ-1,R0 ;IF NOT END OF CHUNK, EXIT
|
||
BNE 10$
|
||
SAVE <R2>
|
||
MOV R0,R2
|
||
MOV -CNKSIZ(R0),R0 ;IS THERE A NEXT CHUNK ALREADY?
|
||
BNE 5$ ;YES, DON'T HAVE TO ALLOCATE A NEW ONE
|
||
JSR PC,ERSGET ;ALLOCATE A NEW CHUNK
|
||
MOV R0,-CNKSIZ(R2) ;AND LINK IT IN
|
||
5$: RESTORE <R2>
|
||
TST (R0)+ ;AND BE SURE TO POINT TO THE DATA
|
||
10$: RTS PC
|
||
|
||
|
||
;GTCKR1 - R1 CHUNK ADDRESS
|
||
|
||
GTCKR1: BIT #CNKSIZ-1,R1 ;IF NOT AT END OF CHUNK,EXIT
|
||
BNE 10$
|
||
SAVE <R0>
|
||
MOV -CNKSIZ(R1),R0 ;IS THERE A NEXT CHUNK ALREADY?
|
||
BNE 5$ ;YES, USE IT
|
||
JSR PC,ERSGET ;GET NEXT CHUNK
|
||
MOV R0,-CNKSIZ(R1) ;LINK NEW CHUNK TO PREVIOUS
|
||
5$: MOV R0,R1 ;COPY CHUNK ADR
|
||
TST (R1)+ ;SKIP LINK SLOT
|
||
RESTORE <R0>
|
||
10$: RTS PC
|
||
|
||
|
||
;GTCKR2 - R2 CHUNK ADDRESS
|
||
|
||
GTCKR2: BIT #CNKSIZ-1,R2 ;IF NOT AT END OF CHUNK,EXIT
|
||
BNE 10$
|
||
SAVE <R0>
|
||
MOV -CNKSIZ(R2),R0 ;IS THERE A NEXT CHUNK ALREADY?
|
||
BNE 5$ ;YES, USE IT
|
||
JSR PC,ERSGET ;GET NEXT CHUNK
|
||
MOV R0,-CNKSIZ(R2) ;LINK NEW CHUNK TO PREVIOUS
|
||
5$: MOV R0,R2 ;COPY CHUNK ADR
|
||
TST (R2)+ ;SKIP LINK SLOT
|
||
RESTORE <R0>
|
||
10$: RTS PC
|
||
;GTCKR3 - R3 CHUNK ADDRESS
|
||
|
||
GTCKR3: BIT #CNKSIZ-1,R3 ;IF NOT AT END OF CHUNK,EXIT
|
||
BNE 10$
|
||
SAVE <R0>
|
||
MOV -CNKSIZ(R3),R0 ;IS THERE A NEXT CHUNK ALREADY?
|
||
BNE 5$ ;YES, USE IT
|
||
JSR PC,ERSGET ;GET NEXT CHUNK
|
||
MOV R0,-CNKSIZ(R3) ;LINK NEW CHUNK TO PREVIOUS
|
||
5$: MOV R0,R3 ;COPY CHUNK ADR
|
||
TST (R3)+ ;SKIP LINK SLOT
|
||
RESTORE <R0>
|
||
10$: RTS PC
|
||
|
||
|
||
;GTCKR4 - R4 CHUNK ADDRESS
|
||
|
||
GTCKR4: BIT #CNKSIZ-1,R4 ;IF NOT AT END OF CHUNK,EXIT
|
||
BNE 10$
|
||
SAVE <R0>
|
||
MOV -CNKSIZ(R4),R0 ;IS THERE A NEXT CHUNK ALREADY?
|
||
BNE 5$ ;YES, USE IT
|
||
JSR PC,ERSGET ;GET NEXT CHUNK
|
||
MOV R0,-CNKSIZ(R4) ;LINK NEW CHUNK TO PREVIOUS
|
||
5$: MOV R0,R4 ;COPY CHUNK ADR
|
||
TST (R4)+ ;SKIP LINK SLOT
|
||
RESTORE <R0>
|
||
10$: RTS PC
|
||
;FRCKRN -- ADVANCE TO NEXT CHUNK, FREEING OLD STALE CHUNK
|
||
|
||
;FRCKR0 - R0 CHUNK ADDRESS
|
||
|
||
FRCKR0: BIT #CNKSIZ-1,R0 ;WAS THAT LAST CHAR IN CHUNK ?
|
||
BNE 10$
|
||
SUB #CNKSIZ,R0 ;MAKE ADR OF CHUNK
|
||
MOV (R0),-(P) ;SAVE ADR OF NEXT CHUNK
|
||
JSR PC,FRECNK ;RELEASE DEAD CHUNK
|
||
MOV (P)+,R0 ;GET ADR OF NEXT CHUNK
|
||
BEQ 10$
|
||
TST (R0)+ ;SKIP LINK WORD
|
||
10$: RTS PC
|
||
|
||
|
||
;FRCKR1 - R1 CHUNK ADDRESS
|
||
|
||
FRCKR1: BIT #CNKSIZ-1,R1 ;WAS THAT LAST CHAR IN CHUNK ?
|
||
BNE 10$
|
||
SAVE <R0>
|
||
MOV R1,R0
|
||
SUB #CNKSIZ,R0 ;MAKE ADR OF CHUNK
|
||
MOV (R0),R1 ;SAVE ADR OF NEXT CHUNK
|
||
BEQ .+4
|
||
TST (R1)+ ;SKIP LINK WORD
|
||
JSR PC,FRECNK ;RELEASE DEAD CHUNK
|
||
RESTORE <R0>
|
||
10$: RTS PC
|
||
;GETCNK -- GET A FREE CHUNK IF LOTS AVAILABLE
|
||
;ERSGET -- GET A FREE CHUNK IF ANY AVAILABLE
|
||
; CALL JSR PC,GETCNK
|
||
; RETURN WITH CHUNK ADR IN R0
|
||
;
|
||
;ON RETURN, "BEQ" IS ERROR, "BNE" IS SUCCESS
|
||
|
||
GETCNK: CMP #ERSCNT,FRECNT ;DO WE HAVE ENOUGH ?
|
||
BMI ERSGET ;IF WE DO GIVE HIM ONE
|
||
TWIDDLE ;MORE CORE MIGHT HELP
|
||
NOCNKS: CLR R0 ;CAN'T AFFORD TO GIVE HIM ONE
|
||
RTS PC
|
||
|
||
ERSGET: PIOFF ;SET LEVEL 7
|
||
DEC FRECNT ;COUNT CHUNK OUT OF LIST
|
||
.IF EQ DGUTS
|
||
ASSERT PL ;BE SURE SOME STILL LEFT
|
||
.IFF
|
||
BPL ERSGT0
|
||
CTYMSG LSW ;REPORT FAILURE, AND RETURN VALUE =0
|
||
INC FRECNT
|
||
PION
|
||
BR NOCNKS
|
||
ERSGT0:
|
||
.ENDC ; .IF EQ DGUTS
|
||
MOV FIRFRE,R0 ;GET ADR OF FIRST FREE CHUNK
|
||
ASSERT NE ;HOPE WE GOT ONE
|
||
ASSERT CHUNK R0 ;IS CHUNK ADDRESS REASONABLE
|
||
TST @R0
|
||
ASSERT NE
|
||
ASSERT CHUNK @R0 ;CHECK ALSO ON HIS FRIEND
|
||
MOV @R0,FIRFRE ;RESET ADR OF FIRST FREE CHUNK
|
||
PION ;RESTORE PROCESSOR LEVEL
|
||
CLRCNK R0 ;ZERO THE WHOLE THING, OR JUST THE LINKAGES
|
||
TRACE CN
|
||
CLZ ;SET PS SO CALLER KNOWS HE WON A CHUNK
|
||
RTS PC ;DISMISS CALL
|
||
;FRECNL -- FREE UP A CHAIN OF LINKED CHUNKS
|
||
;CALL: MOV <ADR>,R0
|
||
; JSR PC,FRECNL
|
||
; RETURN
|
||
|
||
FRECNL: MOV CN.MLK(R0),-(P) ;SAVE NEXT LINKED LIST OF CHUNKS
|
||
JSR PC,FRECKS ;FREE UP THIS LINKED LIST OF CHUNKS
|
||
MOV (P)+,R0 ;RESTORE ADDRESS OF NEXT LINKED LIST
|
||
BNE FRECNL ;AND FREE IT UP TOO
|
||
RTS PC ;ALL DONE
|
||
|
||
|
||
|
||
;FRECKS -- FREE UP LINKED LIST OF CHUNKS
|
||
; CALL: MOV R0,<ADR OF 1ST CHUNK>
|
||
; JSR PC,FRECKS
|
||
|
||
FRECKS: TST R0
|
||
10$: BEQ FCNK99 ;IF NO CHUNKS LEFT DISMISS
|
||
TRACE CN
|
||
MOV @R0,-(P) ;SAVE ADR OF NEXT CHUNK
|
||
JSR PC,FRECNK ;FREE FIRST CHUNK
|
||
MOV (P)+,R0 ;GET ADR OF NEXT CHUNK
|
||
BR 10$
|
||
|
||
|
||
|
||
;FRECNK -- FREE UP (DEALLOCATE) USED CHUNK
|
||
; CALL: MOV R0,<ADR OF CHUNK>
|
||
; JSR PC,FRECNK
|
||
; RETURN
|
||
|
||
FRECNK:
|
||
SET.CD CNK
|
||
ASSERT FRECNT LO FREMAX;HAVE WE FREED ONE TOO MANY CHUNKS ?
|
||
ASSERT CHUNK R0 ;CHECK ADDRESS IS REASONABLE
|
||
ASSERT NE R0
|
||
BIC #CNKSIZ-1,R0 ;BE SURE IT POINTS TO START OF CHUNK
|
||
CMP R0,PRGEND
|
||
BLO FCNK99
|
||
CMP R0,PHYLIM
|
||
BHIS FCNK99
|
||
PIOFF ;SET LEVEL 7
|
||
CLR @R0 ;CLEAR LINK WORD IN NEW FREE CHUNK
|
||
TST LSTFRE ;IS THERE ALREADY AN OLDEST CHUNK ?
|
||
BNE 5$
|
||
MOV R0,FIRFRE ;NEW FIRST CHUNK
|
||
BR 7$
|
||
5$: MOV R0,@LSTFRE ;SET LINK WORD IN PREVIOUS OLDEST CHUNK
|
||
7$: MOV R0,LSTFRE ;SAVE ADDRESS OF OLDEST CHUNK
|
||
PION ;RESTORE PROCESSOR LEVEL
|
||
INC FRECNT
|
||
FCNK99: RTS PC
|
||
.SBTTL CLOCK (KW11) ROUTINES
|
||
|
||
;HERE BECAUSE CLOCK INTERRUPTED
|
||
CLKINT: ASSERT #<15.*60.> GE JIFFLG ;MAKE SURE LOW LEVEL IS RUNNING
|
||
INC JIFFLG ;ONE MORE JIFFY
|
||
ADD #1,LOWUP ; UP TIME OF NODE GOES UP
|
||
ADC HIGHUP
|
||
DEC SECTIC ;COUNT DOWN TO THE NEXT SECOND
|
||
BNE 10$ ;SKIP IF NOT AN EVEN SECOND
|
||
INC SECFLG ;INDICATE A SECOND HAS PASSED
|
||
MOV #JIFSEC,SECTIC ;RESTART SECOND TIMER
|
||
10$: ;
|
||
PROFILE ;JUST INCASE SOMEONE IS INTERESTED
|
||
RTI ;AND THAT'S ALL
|
||
;HERE AT LOW LEVEL WHEN CLOCK HAS GONE OFF
|
||
|
||
JIFSCN:
|
||
|
||
;THIS CODE ENABLES ONE TO CHANGE THE SPEED OF A DH LINE ON THE FLY
|
||
;WITH DDT11
|
||
|
||
.IF DF DIDLLS
|
||
MOV #0,J
|
||
DHHLC=.-2
|
||
BEQ $10$
|
||
PIOFF
|
||
CLR DHHLC
|
||
BIC #17,(J)
|
||
BIS #0,(J)
|
||
DHHLN=.-2
|
||
MOV #0,4(J)
|
||
DHHLO=.-4
|
||
PION
|
||
$10$:
|
||
.ENDC ; .IF DF DIDLLS
|
||
|
||
|
||
;HERE TO CHECK ALL DDB'S ONCE EACH TICK
|
||
.IF NE DEVN
|
||
MOV FIRDDB,J ;GET FIRST DEVICE BLOCK
|
||
10$: SPL 7 ;INHIBIT INTERRUPTS
|
||
TSTB DB.TIM(J) ;IS TIMER RUNNING FOR DEVICE ?
|
||
BLE 20$
|
||
DECB DB.TIM(J)
|
||
BNE 20$
|
||
MOVB DB.TIM+1(J),R0 ;GET TIMER TYPE CODE
|
||
CLR DB.TIM(J)
|
||
SPL 0 ;ENABLE INTERRUPTS
|
||
JSR PC,@DB.TPC(J) ;DISPATCH TO DEVICE DEPENDENT ROUTINE
|
||
20$: SPL 0 ;ENABLE INTERRUPTS
|
||
MOV DB.LNK(J),J ;GET NEXT DEVICE BLOCK ADR
|
||
BNE 10$
|
||
.ENDC;.IF NE DEVN
|
||
;HERE TO CHECK TASKS ONCE EACH TICK
|
||
.IF NE FT.TSK
|
||
MOV #FIRTSK,J ;GET ADR OF FIRST TASK BLOCK
|
||
30$: TST TK.TIM(J) ;ARE WE TIMING ?
|
||
BEQ 36$ ;IF NOT DONE
|
||
DEC TK.TIM(J) ;COUNT TIMER
|
||
BNE 36$
|
||
BIC #TK.SLP,@J ;CLEAR SLEEP BIT
|
||
JSR PC,TSKWAK ;WAKE THE TASK
|
||
36$: MOV TK.LNK(J),J ;GET NEXT TASK BLOCK
|
||
BNE 30$
|
||
.ENDC;.IF NE FT.TSK
|
||
|
||
;HERE TO CHECK DM11-BB'S EVERY 167 MS (EVERY 10 TICKS)
|
||
.IF NE FTDM11!NDZ11
|
||
SUB JIFFLG,DSCLCK ;COUNT DOWN THE DATA-SET TIMER
|
||
BGT 40$ ;DON'T CHECK MODEMS TILL NEGATIVE
|
||
.IIF NE FTDM11,JSR PC,DMSCN ;CALL DM11 CLOCK ROUTINE IN DNDM11
|
||
.IIF NE NDZ11,JSR PC,DZSCN
|
||
MOV #DSCSPD,DSCLCK ;RESET TIMER FOR NEXT TIME
|
||
40$:
|
||
.ENDC
|
||
|
||
;HERE TO CALL NCL SO IT CAN RE-ROUTE ANY MESSAGES IT MAY NEED TO
|
||
JSR PC,NCLJIF ;DO NCL JIFFY PROCESSING
|
||
|
||
;HERE TO SEE IF IT'S TIME TO DO DDCMP REP CHECKING. THIS IS DONE
|
||
;EVERY "REPSPD" TICKS
|
||
.IF NE NTLINE
|
||
SUB JIFFLG,RPCLCK ;COUNT OFF THE JIFFYS
|
||
BGT 50$ ;IF STILL POS THEN DON'T CHECK YET
|
||
JSR PC,REPCHK ;CHECK FOR DDCMP TIMEOUTS
|
||
MOV #REPSPD,RPCLCK ;RESET TIMER FOR NEXT CHECK
|
||
50$:
|
||
.ENDC ;.IF NE NTLINE
|
||
|
||
|
||
;HERE TO SEE IF A SECOND HAS PASSED, AND IF SO CALL THE ROUTINE
|
||
;THAT PROCESSES ONCE / SECOND STUFF
|
||
TST SECFLG ;HAS A SECOND PASSED ?
|
||
BEQ 90$ ;IF NOT, DON'T CALL SECOND SCAN
|
||
JSR PC,SECSCN ;A SECOND HAS PASSED, CALL SECSCN
|
||
CLR SECFLG ;RESET IT FOR NEXT TIME
|
||
90$: RTS PC ;RETURN BACK TO THE MAIN LOOP
|
||
;HERE ONCE PER SECOND
|
||
SECSCN:
|
||
.IF NE FTDL10!FT.DTE
|
||
JSR PC,TENSEC ;DO DL10/DTE SECOND SCAN
|
||
.ENDC
|
||
|
||
;HERE ONCE A SECOND TO CHECK EACH LINE
|
||
SEC.10:
|
||
.IF NE NTLINE
|
||
MOV #FRSTLB,J ;SCAN LINE BLOCK STARTING WITH FIRST
|
||
BR 90$
|
||
05$:
|
||
; JSR PC,SL.SEC ;DRIVER ONCE PER SEC CHECK
|
||
.IF NE FT.MPT
|
||
BIT #LS.MPT,(J) ;IF MULTIPOINT
|
||
BEQ 10$
|
||
BITB #MP.SEL,LB.MPS(J) ;AND IF SELECTED
|
||
BEQ 90$
|
||
TSTB LB.MPT(J) ;AND IF SELECTION TIMER RUNNING
|
||
BEQ 10$
|
||
DECB LB.MPT(J) ; DECREMENT TIME LEFT
|
||
;IF TIME RAN OUT
|
||
BNE 10$
|
||
JSR PC,SELNXT ;MUST FORCE SELECT TO BE SENT
|
||
.IF NE FTTRIB
|
||
TST LB.MPL(J) ;IF YOU'RE A TRIBUTARY
|
||
BNE 9$
|
||
BISB #MP.SNM,LB.MPS(J) ;YOU MUST SEND A SELECT
|
||
CLRB LB.MPT(J) ;AND STOP THE TIMER
|
||
BR 10$
|
||
9$:
|
||
.ENDC
|
||
BITB #MP.SFF,LB.MPS(J) ;IF COUNTER RAN OUT
|
||
BNE 07$
|
||
.IF NE FT.RDM!FT.RDP
|
||
JSR R0,RDESST ;IF A RDE DEV, REPORT THE STATE
|
||
.BYTE 0,240
|
||
.ENDC
|
||
JSR PC,L.DOWN ;PUT THE STATION OFFLINE
|
||
BR 90$
|
||
07$: DECB LB.MPS(J) ;DECREMENT THE FAILURE COUNTER
|
||
.ENDC
|
||
10$:
|
||
40$: TSTB LB.BNN+1(J) ;IF BOOT MODE, ITS TIMER IS RUNNING
|
||
BEQ 90$ ;IF NOT WE ARE DONE
|
||
INCB LB.BNN+1(J)
|
||
BNE 90$
|
||
CLR LB.BNN(J) ;REVOKE EXCLUSIVE LICENSE
|
||
|
||
90$: MOV LB.LNK(J),J ;NOW TRY THE NEXT LINE BLOCK
|
||
BNE 05$ ;IF THERE IS ONE
|
||
.ENDC;.IF NE NTLINE
|
||
.IF NE FTDCP3!FTDCP4 ;NSP CODE HAS CLOCK STUFF TOO
|
||
JSR PC,NSPSEC ;CALL IT
|
||
.ENDC
|
||
;HERE ONCE A SECOND TO CHECK EACH SCB
|
||
SECNCL: MOV #OURSCB,SB ;GET 1ST STATION BLOCK
|
||
BR 82$
|
||
10$: BIT #SBF.IU,@SB ;IS BLOCK IN USE ?
|
||
BEQ 82$ ;IF NOT DON'T CHECK IT
|
||
MOV SB,DNA ;SAVE DESTINATION ADR
|
||
JSR PC,NCLQRQ
|
||
MOV #SQNTAB,SQNODE
|
||
20$: MOV @SQNODE,SNA ;IS THERE A SOURCE FOR THIS SLOT ?
|
||
BEQ 80$ ;BRANCH IF DONE WITH SEQUENTIAL NODES
|
||
MOV SB,R0 ;COPY SCB POINTER
|
||
ADD #SB.IMQ-CN.MLK,R0 ;POINT TO INPUT MSG QUEUE
|
||
JSR PC,TIMQUE ;CHECK FOR ANTIQUE ENTRIES
|
||
.WORD FRECKS
|
||
TSTB SB.TIM(SB) ;ARE WE TIMING ?
|
||
BEQ 50$
|
||
DECB SB.TIM(SB) ;DECREMENT TIMER
|
||
BNE 50$ ;BRANCH IF TIMER HASN'T GONE OFF
|
||
JSR PC,NCLSEC ;GO DO ONCE A SECOND NCL STUFF
|
||
50$: ADD #2,SQNODE ;ADVANCE TO NEXT SEQUENTIAL NODE
|
||
ADD #SQNSIZ,SB ;ADVANCE TO NEXT SNA
|
||
BR 20$
|
||
80$: MOV DNA,SB ;GET SCB ADR AGAIN
|
||
82$: SB.ADV 10$ ;GET NEXT STATION BLOCK
|
||
;HERE ONCE A SECOND TO CHECK DEVICES
|
||
.IF NE DEVN
|
||
SECDEV: MOV FIRDDB,J ;GET FIRST DEVICE BLOCK
|
||
Z=DS.COR
|
||
.IIF NE FT.TSK,Z=Z!DS.PAU
|
||
10$: BIT #Z,@J ;DOES DEVICE WANT TO RUN AGAIN ?
|
||
BEQ 20$
|
||
TWIDDLE ;COUNT TIMES THIS HAPPENS
|
||
BIC #Z,@J ;CLEAR REQUEST
|
||
JSR PC,QUEDEV ;REQUEST EXECUTION
|
||
20$: SPL 7 ;INHIBIT INTERRUPTS
|
||
TSTB DB.TIM(J) ;IS SECONDS TIMER RUNNING
|
||
BPL 22$
|
||
INCB DB.TIM(J) ;IF SO INCREMENT IT
|
||
BNE 22$
|
||
MOVB DB.TIM+1(J),R0 ;IF TIMER RAN OUT, GET FUNCTION CODE
|
||
CLR DB.TIM(J)
|
||
SPL 0 ; ENABLE INTERRUPTS
|
||
JSR PC,@DB.TPC(J) ;AND SERVICE THE TIMER
|
||
22$: SPL 0 ;ENABLE INTERRUPTS
|
||
.IF NE FTDN11
|
||
.IF NE FT.RDA
|
||
BIT #RDEASC,DB.RDT(J)
|
||
BNE 23$
|
||
.ENDC
|
||
BIT #DS.TTY,@J ;IS THIS A TTY ?
|
||
BEQ 30$
|
||
.IF NE FT.CTY
|
||
CMP J,#CTYDDB
|
||
BEQ 30$
|
||
.ENDC;.IF NE FT.CTY
|
||
23$: BITB #DNTIME,DB.DNT(J) ;DN11 TIMER GOING?
|
||
BEQ 30$ ;NO, CHECK DATASET STATUS
|
||
.IF NE FT.CHK
|
||
BITB #40,DB.DVT(J) ;AUTO DIAL LINE?
|
||
ASSERT NE ;IT HAD BETTER BE!
|
||
BITB #DNDIAL,DB.DNS(J) ;UNDER CONTROL OF DN11/801?
|
||
ASSERT NE ;IT HAD BETTER BE!
|
||
.ENDC;.IF NE FT.CHK
|
||
DECB DB.DNT(J) ;DECREMENT TIMER
|
||
MOVB DB.DNT(J),R0 ;AND GET NEW VALUE
|
||
BITB #DNTIME,R0 ;TIMER EXPIRED?
|
||
BNE 30$ ;NO, DONE
|
||
BIC #177477,R0 ;CLEAR UNWANTED BITS
|
||
ASL R0 ;PUT CODE
|
||
ASL R0 ;INTO RIGHT
|
||
ASL R0 ;PLACE
|
||
SWAB R0
|
||
JSR PC,@DNTDSP(R0) ;EXECUTE TIMER ROUTINE
|
||
BR 30$ ;DO NEXT DDB
|
||
.ENDC;.IF NE FTDN11
|
||
30$: MOV DB.LNK(J),J ;GET NEXT DEVICE BLOCK
|
||
BNE 10$
|
||
.ENDC;.IF NE DEVN
|
||
|
||
;HERE IS THE ONCE / SECOND STUFF FOR TASKS.
|
||
.IF NE FT.TSK
|
||
MOV TASK,J ;GET ADDR OF RUNNING TASK
|
||
BEQ 40$ ;SKIP IF NONE
|
||
SUB SECFLG,TK.QTM(J) ;COUNT DOWN HIS QUANTUM
|
||
40$:
|
||
.ENDC
|
||
|
||
|
||
;HERE IS SOME CODE THAT SUPPORTS THE SINK MACRO
|
||
ND LPTSNK,0 ;USE THE LPT FOR SINK ONLY IF REQUESTED
|
||
.IF NE LPTSNK
|
||
SINK LP0DDB
|
||
.IFF
|
||
SINK CTYDDB
|
||
.ENDC ;.IF NE LPTSNK
|
||
|
||
CTYMSG ;CTY LOGGING
|
||
;
|
||
;******** here is a convenient place for source macro calls ******
|
||
;
|
||
|
||
|
||
;HERE TO CHECK IF A MINUTE HAS PASSED, AND IF SO CALL ONCE/MINUTE CODE
|
||
SUB SECFLG,MINTIC ;COUNT DOWN TO NEXT MINUTE
|
||
BGT 90$ ;BRANCH IF HASN'T PASSES
|
||
JSR PC,MINSCN ;BRANCH TO ONCE/MINUTE ROUTINE
|
||
MOV #60.,MINTIC ;RESET MINUTE TICKER
|
||
90$: RTS PC ;POP BACK TO MAIN LOOP
|
||
|
||
;HERE IS THE ONCE / MINUTE CODE (A GOOD PLACE FOR DEBUGING CHECKS)
|
||
MINSCN:
|
||
RTS PC ;POP BACK TO MAIN LOOP
|
||
;HERE TO CHECK FOR DDCMP REP TIMEOUTS
|
||
.IF NE NTLINE
|
||
REPCHK: MOV #FRSTLB,J ;SCAN LINE BLOCKS STARTING WITH THE FIRST
|
||
BR 10$
|
||
15$:
|
||
.IIF NE FTDUP11,JSR PC,DUPJIF ;KISS THE DUP'S A ONCE IN A WHILE
|
||
.IF NE FT.MPT
|
||
BIT #LS.MPT,(J) ;IF NOT MULTIPOINT, GO AHEAD AND CHECK IT
|
||
BEQ 12$
|
||
BITB #MP.SEL,LB.MPS(J) ;ELSE IF NOT SELECTED,SKIP THE LINE
|
||
BEQ 10$
|
||
.ENDC
|
||
12$: DEC LB.REP(J) ;POKE THE TIMER
|
||
BGT 10$
|
||
JSR PC,DDCSEC ;IF TIMER RAN OUT, DO SOMETHING
|
||
10$: MOV LB.LNK(J),J ;STEP TO NEXT BLOCK, AND LOOP
|
||
BNE 15$
|
||
RTS PC ;EXIT IF NO BLOCK
|
||
.ENDC ;.IF NE NTLINE
|
||
;HERE TO TIME ENTRIES IN A QUEUE
|
||
; CALL MOV #FOO,R0 ;POINTER TO FIRST ENTRY IN QUEUE
|
||
; JSR TIMQUE
|
||
; .WORD WHERE ;TO GO WHEN ENTRY HAS EXPIRED
|
||
; RETURN
|
||
TIMQUE: BR 20$
|
||
10$: MOV R1,R0
|
||
20$: MOV CN.MLK(R0),R1 ;GET POINTER TO NEXT MSG
|
||
BEQ 90$ ;IF NO MORE WE ARE DONE
|
||
DEC CN.TIM(R1) ;DECREMENT TIMER
|
||
BNE 10$
|
||
TWIDDLE ;COUNT DEAD MSGS
|
||
MOV CN.MLK(R1),CN.MLK(R0) ;DELINK OBSOLETE MSG
|
||
MOV R0,-(P) ;SAVE GOOD POINTER
|
||
MOV R1,R0 ;POINT TO DEAD MSG
|
||
MOV @2(P),R1 ;GET ADR OF WHERE TO GO
|
||
JSR PC,@R1 ;DISPOSE OF MESSAGE
|
||
MOV (P)+,R0 ;GET GOOD POINTER BACK
|
||
BR 20$
|
||
90$: ADD #2,@P
|
||
RTS PC
|
||
|