Trailing-Edge
-
PDP-10 Archives
-
decus_20tap4_198111
-
decus/20-0125/gidus.p11
There are 2 other files named gidus.p11 in the archive. Click here to see a list.
.NLIST TTM,CND
.TITLE GIDUS GT40 INTERACTIVE DISPLAY UTILITY SYSTEM
.SBTTL GENERAL PARAMETER DEFINITIONS
.ENABL AMA
.MCALL GRAPHIC
GRAPHIC
;
; REGISTER DEFINITIONS
R0=%0
R1=%1
R2=%2
R3=%3
R4=%4
R5=%5
SP=%6
PC=%7
SWR=177570 ; SWITCH REGISTER
PSW=177776 ; PROCESSOR STATUS WORD
STACK=37700 ; LOWER STACK BOUND
;
; DEVICE REGISTERS
;
IS.GT=175610 ; GT40 INPUT STATUS REGISTER
IB.GT=175612 ; GT40 INPUT BUFFER REGISTER
OS.GT=175614 ; GT40 OUTPUT STATUS REGISTER
OB.GT=175616 ; GT40 OUTPUT BUFFER REGISTER
;
IS.KB=177560 ; KEYBOARD INPUT STATUS REGISTER
IB.KB=177562 ; KEYBOARD INPUT BUFFER REGISTER
;
LKS.CL=177546 ; CLOCK STATUS REGISTER
;
; SCREEN AND SCROLLING PARAMETERS
;
.RADIX 10
LST.SC=23 ; Y POSITION OF LAST LINE (RASTER UNITS)
CHR.SC=72 ; NUMBER OF CHARACTERS PER LINE
LSZ.SC=CHR.SC+8 ; NUMBER OF BYTES PER LINE
DST.SC=24 ; VERTICAL DISTANCE BETWEEN CHARACTERS
.PAGE
.SBTTL SPECIAL CHARACTERS
.RADIX 8
;
CR.CH=15 ; CARRIAGE RETURN
LF.CH=12 ; LINE FEED
EOS.CH=37 ; CLEAR SCREEN
CRS.CH=137 ; CURSOR IS UNDERSCORE
BEL.CH=7 ; BELL
LFT.CH=10 ; LEFT ARROW (BACK SPACE)
RT.CH=30 ; RIGHT ARROW (CTRL X)
UP.CH=32 ; UP ARROW (CTRL Z)
DWN.CH=13 ; DOWN ARROW (VT)
HME.CH=35 ; HOME UP (GIDUS COMMAND)
SP.CH=40 ; SPACE
RUB.CH=177 ; RUBOUT
SO.CH=16 ; SHIFT-OUT
SI.CH=17 ; SHIFT-IN
CMD.CH=1 ; COMMAND SIGNAL (^A)
ADD.CH=2 ; ADD FILE SIGNAL (^B)
.PAGE
.SBTTL DISPLAY RESTART
;
; ALLOW DISPLAY RE-START FROM 0
;
.=0
;
; RE-START THE DISPLAY FILE IF TEMPORARY
; DJMP LANDS HERE
;
DJMP,FIRST.
.PAGE
.SBTTL INTERRUPT VECTORS
.=4
.WORD $BSINT,000 ; BUS ERROR, LEVEL 0
.=60
KB$VEC: .WORD $KBINT,200 ; KEYBOARD INTERRUPT, LEVEL 4
.=100
.WORD $CLINT,300 ; CLOCK INTERRUPT, LEVEL 6
.=300
DL$VEC: .WORD $DLINT,340 ; DL-11 INTERRUPT, LEVEL 7
.=320
.WORD $STINT,200 ; STOP INTERRUPT, LEVEL 4
.WORD $LPINT,200 ; L.P. INTERRUPT, LEVEL 4
.WORD $TMINT,340 ; TIME-OUT INTERRUPT, LEVEL 7
.PAGE
.SBTTL LOCAL MACROS
;
.MACRO CALL ..ROUT ; MACRO TO CALL A ROUTINE
JSR PC,..ROUT ; VIA THE PC
.ENDM
;
.MACRO RETURN ; MACRO TO DO A RETURN
RTS PC ; VIA THE PC
.ENDM
;
.MACRO SAVREG ; MACRO TO SAVE REGISTERS
JSR R0,$SAVRG ; SAVE THE REGISTERS
.ENDM
;
.MACRO RESREG ; MACRO TO RESTORE REGISTERS
JSR R0,$RESRG ; RESTORE THE REGISTERS
.ENDM
;
.MACRO PUSH .. ; MACRO TO
MOV ..,-(SP) ; PUSH ONTO STACK
.ENDM
;
.MACRO POP .. ; MACRO TO POP
MOV (SP)+,.. ; OFF STACK
.ENDM
;
.MACRO SOB ..R,..DEST ; MACRO TO SIMULATE SOB INSTRUCTION
DEC ..R ; DECREMENT THE REGISTER
BGT ..DEST ; BRANCH BACK IF GREATER
.ENDM
;
.MACRO ENABLE ..DN ; MACRO TO ENABLE A DISPLAY FILE
MOV #..DN,R5 ; GET DISPLAY NUMBER
CALL $ENABL ; AND ENABLE IT
.ENDM
;
.MACRO DISABL ..DN ; MACRO TO DISABLE A DISPLAY FILE
MOV #..DN,R5 ; GET THE DISPLAY NUMBER
CALL $DSABL ; AND DISABLE IT
.ENDM
.PAGE
; OCTAL FORMAT MACRO
;
; THIS MACRO IS USED TO SET UP A CALL TO
; THE OCTAL FORMATTING ROUTINE
;
.MACRO FORMAT ..WORD,..AREA,..SIZE
SAVREG ; SAVE ALL REGISTERS
MOV ..WORD,R5 ; GET WORD TO BE FORMATTED
MOV #'..AREA,R1 ; GET POINTER TO OUTPUT
MOV #'..SIZE,R2 ; GET NUMBER OF DIGITS
CALL $FRMAT ; FORMAT THE NUMBER
RESREG ; RESTORE THE REGISTERS
.ENDM
.PAGE
; STATS$ - STATUS MACRO
;
; THIS MACRO IS USED TO SET UP THE STATUS/POINTER WORD
; IN THE DISPLAY FILE TABLE. ALL ARGUMENTS SHOULD BE
; PRESENT AND (WITH THE EXCEPTION OF ..PT) HAVE A VALUE OF
; OF 1(ON) OR 0(OFF)
;
; ..EX 1 = DISPLAY FILE EXISTS
; ..EN 1 = DISPLAY FILE ENABLED
; ..WP 1 = WRITE PROTECTED (DISPLAY FILE CANNOT BE DELETED)
; ..ND 1 = NO DISABLE (DISPLAY FILE CANNOT BE DISABLED)
; ..LP 1 = LIGHT PEN INTERRUPTS ALLOWED
; ..RL 1 = DISPLAY FILE MAY BE MOVED
; ..PT POINTER TO NEXT DISPLAY FILE
;
.MACRO STATS$ ..EX,..EN,..WP,..ND,..LP,..RL,..PT
..=000000
.IF GT,..EX
..=100000 ; DISPLAY FILE EXISTS
.ENDC
.IF GT,..EN
..=..!40000 ; DISPLAY FILE IS ENABLED
.ENDC
.IF GT,..WP
..=..!20000 ; DISPLAY FILE IS WRITE PROTECTED
.ENDC
.IF GT,..ND
..=..!10000 ; DISPLAY FILE MAY NOT BE DISABLED
.ENDC
.IF GT,..LP
..=..!4000 ; L.P. INTERRUPTS ALLOWED
.ENDC
.IF GT,..RL
..=..!2000 ; DISPLAY FILE MAY BE MOVED
.ENDC
..=..!..PT ; POINTER
.WORD .. ; STATUS WORD
.ENDM
.PAGE
.SBTTL GIDUS DISPLAY FILE TABLE
;
; GIDUS DISPLAY FILE TABLE
;
; 64(10) ENTRIES - ONE PER DISPLAY FILE
; 3 WORDS PER ENTRY - START/LAST/STATUS-POINTER
;
; STATUS WORD IS AS FOLLOWS:
;
; BITS MEANING
;
; 15 DISPLAY FILE EXISTS
; 14 DISPLAY FILE ENABLED
; 13 DISPLAY FILE WRITE PROTECTED
; 12 DISPLAY FILE CANNOT BE DISABLED
; 11 L.P. INTERRUPTS ALLOWED
; 10 DISPLAY FILE MAY BE MOVED
; 9-6 RESERVED
; 5-0 POINTER TO NEXT DISPLAY FILE IN LIST
;
; MASK BITS
;
EX.BIT=100000 ; EXISTS BIT
EN.BIT=40000 ; ENABLED BIT
WP.BIT=20000 ; WRITE-PROTECT BIT
ND.BIT=10000 ; NO DISABLE BIT
RL.BIT=2000 ; RELOCATION BIT
PT.BIT=77 ; POINTER BITS
;
$$DFT: .WORD FIRST.,STATS.-2 ; FIRST DISPLAY FILE
DF$FIR: STATS$ 1,1,1,1,0,0,1
.WORD CDF.,0 ; CHARACTER DISPLAY FILE
DF$CDF: STATS$ 1,1,1,0,0,0,2
.WORD STATS.,MESAG.-4 ; STATUS DISPLAY FILE
DF$STA: STATS$ 1,1,1,0,0,0,3
.WORD MESAG.,MP.-2 ; MESSAGE DISPLAY FILE
DF$MSG: STATS$ 1,1,1,1,0,0,4
.WORD MP.,AP.-2 ; MAIN POINTER
DF$MP: STATS$ 1,1,1,0,0,1,5
.WORD AP.,OMSG.-2 ; AUXILLARY POINTER
DF$AP: STATS$ 1,1,1,0,0,1,77
.WORD OMSG.,GCMND.-2 ; OPTION MESSAGE FILE
DF$OMS: STATS$ 1,0,1,0,0,0,0
.WORD GCMND.,OPTR.-2 ; GIDUS COMMAND DISPLAY FILE
DF$CMD: STATS$ 1,0,1,0,0,0,0
.WORD OPTR.,LAST.-2 ; OPTION POINTER
DF$OPT: STATS$ 1,0,1,0,0,1,0
;
; USER DISPLAY FILES
;
DF$USR:
.REPT 54.
.WORD 0,0
STATS$ 0,0,0,0,0,0,0
.ENDR
;
.WORD LAST.,DHALT.-2 ; LAST DISPLAY FILE
STATS$ 1,1,1,1,0,0,0
DF$TOP: .WORD 0 ; FIRST FREE WORD OF CORE
.PAGE
.SBTTL PROGRAM MAINLINE
$START: RESET ;
RESET ; FIX THINGS
RESET ;
MOV #37776,SP ; SET STACK TO TOP OF CORE
MOV #STACK,R1 ; GET UPPER MEMORY BOUND
CALL $CDINI ; INITIALIZE CHARACTER DISPLAY FILE
SUB DF$TOP,R1 ; SUBTRACT LOWER BOUND
ASR R1 ; FORM WORD COUNT
FORMAT R1,ST.FRE,5 ; FORMAT INTO STATUS DISPLAY
MOV #100,@#IS.KB ; ENABLE KEYBOARD INTERRUPTS
MOV #100,@#IS.GT ; ENABLE DL-11 INTERRUPTS
MOV #100,@#LKS.CL ; ENABLE CLOCK INTERRUPTS
MOV #FIRST.,@#DPC ; START THE DISPLAY
ST.NUL: WAIT ; WAIT FOR INTERRUPT
TST GC$TRC ; TEST TRACE ADDRESS
BEQ ST.NUL ; IF ZERO NO TRACE
FORMAT @GC$TRC,ST.TRC,6 ; OTHERWISE FORMAT LOCATION
BR ST.NUL ; WAIT FOR NEXT INTERRUPT
.PAGE
.SBTTL CHARACTER DISPLAY FILE INITIALIZATION
; THIS SUBROUTINE INITIALIZES THE CHARACTER
; DISPLAY FILE, AND CREATES CHARACTER POINTERS
;
CD$FST: .WORD 0 ; Y POSITION OF FIRST LINE
CD$OLD: .WORD 0 ; PREVIOUS # OF LINES IN USE
CD$NEW: .WORD 8. ; DESIRED # OF LINES (DEFAULT 8)
;
$CDINI: SAVREG ; SAVE THE REGISTERS
CMP CD$OLD,CD$NEW ; SHOULD A SETUP BE DONE ?
BEQ CD.1 ; NO, SIMPLY CLEAR EXISTING FILE
CALL $CDSET ; YES, CREATE THE DISPLAY FILE
CD.1: MOV CD$FST,R2 ; GET Y POSITION OF FIRST LINE
MOV CD$NEW,R0 ; GET NUMBER OF LINES
MOV #CDF.+12.,R1 ; R1 IS CDF. POINTER
CD.2: TST (R1)+ ; POINT PAST FIRST WORD
CLR (R1)+ ; CLEAR X POSITION
MOV R2,(R1)+ ; INSERT Y POSITION
SUB #DST.SC,R2 ; UPDATE Y POSITION
TST (R1)+ ; POINT PAST CHAR INST.
MOV #CHR.SC/2,R3 ; NUMBER OF WORDS PER LINE
CD.3: CLR (R1)+ ; BLANK OUT THE LINE
SOB R3,CD.3 ; LOOP FOR ALL WORDS
SOB R0,CD.2 ; LOOP FOR ALL LINES
CLR CDF.X ; RESET CURSOR POSITION
CLR DL$CNT ; CLEAR CHARACTER COUNT
SUB #CHR.SC,R1 ; BACK UP POINTER TO FIRST CHAR
MOV R1,DL$PNT ; AND SAVE POINTER
RESREG ; RESTORE THE REGISTERS
RETURN ; AND RETURN
.PAGE
; THIS ROUTINE IS USED TO CREATE THE CHARACTER DISPLAY FILE
; WHICH BEGINS AT ADDRESS CDF. + 12. AND USES AS MUCH FREE
; CORE AS IS NECESSARY IN ORDER TO SET UP THE DESIRED NUMBER
; OF LINES USED FOR SCROLLING. EACH LINE OF THIS DISPLAY
; FILE STARTS WITH A POINT INSTRUCTION, FOLLOWED BY A 0
; X CO-ORDINATE, AND A Y CO-ORDINATE THAT VARIES WITH THE
; VERTICAL POSITION OF THE LINE. NEXT IS THE CHAR INSTRUCTION
; WHICH IS FOLLOWED BY CHR.SC NUMBER OF BYTES
;
CD$END: .WORD 0 ; LAST WORD + 2 OF DISPLAY FILE
;
$CDSET: CMP CD$NEW,#31. ; TOO MANY LINES ?
BLE CD.4 ; NO, CONTINUE
MOV #31.,CD$NEW ; YES, SO SET 31 MAXIMUM
CD.4: TST CD$NEW ; ARE THERE ENOUGH LINES ?
BGT CD.5 ; YES, CONTINUE
MOV #1,CD$NEW ; NO, SO SET 1 MINIMUM
CD.5: MOV CD$NEW,CD$OLD ; SAVE NUMBER OF LINES
CLR CD$FST ; WHERE DOES TOP LINE BELONG ?
MOV #CDF.+12.,R0 ; R0 POINTS TO CDF
MOV CD$NEW,R1 ; NUMBER OF LINES IN R1
CD.6: ADD #DST.SC,CD$FST ; FIND TOP LINE POSITION BY ADDING
MOV #POINT!INT2!BLKOFF,(R0)+; FIRST WORD OF EACH LINE
CLR (R0)+ ; CLEAR X POSITION
CLR (R0)+ ; AND Y POSITION
MOV #CHAR,(R0)+ ; INSERT CHAR INST.
MOV #CHR.SC/2,R2 ; # OF WORDS PER LINE
CD.7: CLR (R0)+ ; BLANK OUT LINE
SOB R2,CD.7 ; LOOP FOR ALL WORDS
SOB R1,CD.6 ; LOOP FOR ALL LINES
MOV #DJMP,(R0)+ ; DISPLAY FILE ENDS WITH
MOV #STATS.,(R0)+ ; A DJMP TO NEXT FILE
MOV R0,CD$END ; FIRST FREE WORD
MOV R0,DF$TOP ; OF CORE
TST -(R0) ; SUBTRACT 2 FROM R0
MOV R0,DF$CDF-2 ; AND SAVE IN DISPLAY TABLE
DEC CD$FST ; FIXUP TOP LINE POSITION
RETURN ; AND RETURN
.PAGE
.SBTTL BUS ERROR INTERRUPT ROUTINES
; TIME-OUT INTERRUPT ROUTINE
;
; RESTART THE DISPLAY IMMEDIATELY
;
$TMINT: BIT #100,@#DSR ; IS THIS A SHIFT INTERRUPT ?
BNE TM.OUT ; NO, IT IS A TIME-OUT
MOV #1,@#DPC ; IF SHIFT THEN RESUME DISPLAY
RTI ; AND RETURN FROM INTERRUPT
;
TM.OUT: MOV #FIRST.,@#DPC ; IF TIME-OUT, THEN RE-START
RTI ; AND RETURN FROM INTERRUPT
;
; $BSINT - BUS ERROR
; MOST LIKELY ODD ADDRESS REFERENCE
;
$BSINT: MOV #ER$ADD,R4 ; FATAL "? ODD ADDRESS REFERENCE ?"
CALL $ERROR ; PRINT THE ERROR
INC @#DSR ; RING THE BELL
BR . ; AND HANG UP
.PAGE
.SBTTL KEYBOARD INTERRUPT ROUTINE
;
; THIS ROUTINE INPUTS ONE CHARACTER FROM THE LK40
; KEYBOARD AND SENDS IT TO THE 10. IF THE CHARACTER
; IS "EOS.CH" (ASCII 37) THE CHARACTER DISPLAY FILE
; IS CLEARED
;
$KBINT: SAVREG ; SAVE THE REGISTERS
MOVB @#IB.KB,R0 ; GET THE KEYBOARD CHARACTER
BIC #177600,R0 ; CLEAR THE TOP BYTE AND PARITY
CMP R0,#HME.CH ; GIDUS COMMAND ?
BNE KB.0 ; NO, CONTINUE
CALL GC.SET ; YES DO SETUP
BR KB.RET ; AND RETURN
KB.0: CMP R0,#LFT.CH ; LEFT ARROW ?
BNE KB.1 ; NO, CONTINUE
COMB CL$LFT ; YES, CHANGE STATE
CLRB CL$RT ; DISABLE MOVEMENT TO RIGHT
BR KB.RET ; AND RETURN
KB.1: CMP R0,#RT.CH ; RIGHT ARROW ?
BNE KB.2 ; NO, CONTINUE
COMB CL$RT ; YES, CHANGE STATE
CLRB CL$LFT ; DISABLE MOVEMENT TO LEFT
BR KB.RET ; AND RETURN
KB.2: CMP R0,#UP.CH ; UP ARROW ?
BNE KB.3 ; NO, CONTINUE
COMB CL$UP ; YES, CHANGE STATE
CLRB CL$DWN ; DISABLE MOVEMENT DOWN
BR KB.RET ; AND RETURN
KB.3: CMP R0,#DWN.CH ; DOWN ARROW ?
BNE KB.4 ; NO, CONTINUE
COMB CL$DWN ; YES, CHANGE STATE
CLRB CL$UP ; DISABLE MOVEMENT UP
BR KB.RET ; AND RETURN
KB.4: CMP R0,#EOS.CH ; CLEAR SCREEN ?
BNE KB.SND ; NO SEND THE CHARACTER
CALL $CDINI ; YES - INITIALIZE THE SCREEN
BR KB.RET ; AND RETURN FROM INTERRUPT
KB.SND: TST $IO$ ; WAS I/O IN PROGRESS
BEQ KB.5 ; NO, SEND THE CHARACTER
CMP R0,#3 ; WAS IT A CTRL/C ?
BNE KB.RET ; NO SO DON'T SEND IT
MOV #$DLINT,@#DL$VEC ; YES, RESTORE CHARACTER MODE
CLR $IO$ ; CLEAR THE I/O FLAG
MOV #"CH,ST.DL ; DL-11 IN CHARACTER MODE
MOV #"TI,ST.ATE ; RESTORE GIDUS-STATE
KB.5: TSTB @#OS.GT ; IS THE 10 READY
BPL KB.5 ; WAIT IF NOT READY
MOVB R0,@#OB.GT ; SEND THE CHARACTER
KB.RET: RESREG ; RESTORE THE REGISTERS
RTI ; RETURN FROM INTERRUPT
.PAGE
.SBTTL DL-11 INTERRUPT ROUTINE
;
; THIS ROUTINE INPUTS ONE CHARACTER FROM THE 10
; AND ADDS IT TO THE DISPLAY FILE. IF NECESSARY
; THE DISPLAY FILE IS SCROLLED
;
DL$CNT: .WORD 0 ; CHARACTER COUNT
DL$PNT: .WORD 0 ; CHARACTER POINTER
;
$DLINT: SAVREG ; SAVE THE REGISTERS
MOVB @#IB.GT,R0 ; GET THE CHARACTER
BIC #177600,R0 ; CLEAR TOP BYTE AND PARITY
CMP R0,#CMD.CH ; ENTER COMMAND MODE ?
BNE DL.0 ; NO, PROCESS CHARACTER
MOV #"CO,ST.DL ; YES, INDICATE IN STATUS DISPLAY
INC $IO$ ; SET THE I/O FLAG
MOV #$RCINT,@#DL$VEC ; TRAP INTERRUPTS AT $RCINT
MOV ST.ATE,ST.OLD ; SAVE GIDUS STATE
MOV #"RC,ST.ATE ; INDICATE GIDUS STATE
MOV #9.,RC$CNT ; SET COMMAND BYTE COUNT
MOV #RC$CMD,RC$PNT ; SET COMMAND BUFFER POINTER
CLR RC$SUM ; CLEAR CHECKSUM
BR DL.RET ; AND RETURN
DL.0: CMP R0,#ADD.CH ; ENTER ADDFILE MODE ?
BNE DL.1 ; NO, PROCESS CHARACTER
TST AD$ABF ; CAN NEXT BLOCK BE ACCEPTED ?
BNE DL.RET ; NO, DO NOT ACCEPT
MOV #"AD,ST.DL ; ADDING, INDICATE IN STATUS DISPLAY
INC $IO$ ; SET I/O FLAG
MOV #$ADINT,@#DL$VEC ; TRAP INTERRUPTS AT $ADINT
MOV ST.ATE,ST.OLD ; SAVE GIDUS STATE
MOV #"RC,ST.ATE ; INDICATE RECEIVING
BR DL.RET ; AND RETURN
DL.1: CMP R0,#BEL.CH ; IS THIS A BELL ?
BNE DL.NOB ; NO SO CONTINUE
INC @#DSR ; YES SO RING
BR DL.RET ; AND RETURN
DL.NOB: CMP R0,#CR.CH ; CARRIAGE RETURN ?
BEQ DL.RET ; YES, SO IGNORE
CMP R0,#RUB.CH ; FILLER ?
BEQ DL.RET ; YES, SO IGNORE IT
CMP R0,#LF.CH ; LINE FEED ?
BNE DL.CHR ; NO, SO PRINT CHARACTER
CALL $SCROL ; <LF>, SO SCROLL
BR DL.RET ; AND RETURN
;
DL.CHR: CMP DL$CNT,#CHR.SC ; ENOUGH ROOM ON LINE ?
BGE DL.RET ; NO, SO IGNORE
CMP R0,#40 ; PRINTABLE CHARACTER ?
BLT DL.RET ; NO, SO IGNORE
MOVB R0,@DL$PNT ; INSERT THE CHARACTER
INC DL$PNT ; INCREMENT POINTER
INC DL$CNT ; INCREMENT CHARACTER COUNT
ADD #14.,CDF.X ; MOVE CURSOR
DL.RET: RESREG ; RESTORE THE REGISTERS
RTI ; RETURN FROM INTERRUPT
.PAGE
.SBTTL SCROLLING ROUTINE
;
; THIS ROUTINE IS CALLED WHENEVER THE 10
; OUTPUTS A LINE FEED. EVERY LINE IS
; SHIFTED UP ONE POSITION, AND THE BOTTOM
; LINE BECOMES AVAILABLE FOR OUTPUT
;
$SCROL: MOV CD$NEW,R0 ; NUMBER OF LINES
MOV #CDF.+12.,R1 ; CDF. POINTER
SC.LUP: ADD #DST.SC,4(R1) ; SHIFT LINE UP
CMP 4(R1),CD$FST ; IS THIS LINE AVAILABLE
BLE SC.SNT ; NO, CONTINUE SHIFTING
MOV #LST.SC,4(R1) ; MAKE THIS THE LAST LINE
MOV R1,DL$PNT ; GET POINTER
ADD #8.,DL$PNT ; AND FIX IT UP
CLR DL$CNT ; CLEAR CHARACTER COUNT
CLR CDF.X ; RESET CURSOR
MOV DL$PNT,R2 ; POINTER TO LINE
MOV #CHR.SC/2,R3 ; NUMBER OF WORDS PER LINE
SC.1: CLR (R2)+ ; BLANK OUT LINE
SOB R3,SC.1 ; LOOP FOR ALL WORDS
;
SC.SNT: ADD #LSZ.SC,R1 ; POINT TO NEXT LINE
SOB R0,SC.LUP ; LOOP FOR ALL LINES
RETURN ; RETURN
.PAGE
.SBTTL STOP INTERRUPT ROUTINE
;
; THIS ROUTINE IS EXECUTED EACH TIME THE DISPLAY
; STOPS. IF THERE IS NOTHING TO DO THE DISPLAY
; RESUMES IMMEDIATELY, ELSE A DISPATCH TO THE
; APPROPRIATE ROUTINE IS MADE.
ST$FNC: .WORD 0 ; FUNCTION CODE
;
; STOP INTERRUPT DISPATCH TABLE
;
ST$DIS: ST.RES ; FUNCT = 0 - RESUME
ST.STP ; FUNCT = 1 - STOP DISPLAY
;
$STINT: SAVREG ; SAVE THE REGISTERS
MOV ST$FNC,R0 ; GET THE FUNCTION CODE
ASL R0 ; FORM WORD OFFSET
CALL @ST$DIS(R0) ; DISPATCH TO ROUTINE
RESREG ; RESTORE THE REGISTERS
CLR ST$FNC ; INDICATE NOTHING PENDING
MOV #1,@#DPC ; RESUME THE DISPLAY
RTI ; RETURN FROM INTERRUPT
;
;
;
;
;
;
ST.RES: RETURN ; RETURN IMMEDIATELY
;
ST.STP: TST (SP)+ ; IGNORE RETURN ADDRESS
RESREG ; RESTORE THE REGISTERS
CLR ST$FNC ; CLEAR FUNCTION CODE
RTI ; AND RETURN FROM INTERRUPT
.PAGE
.SBTTL LIGHT PEN INTERRUPT ROUTINE
;
LP$FLG: .WORD 0 ; ENABLED/DISABLED FLAG
LP$HIT: .WORD 0 ; WAIT FOR HIT FLAG
LP$DPC: .WORD 0 ; DPC AT TIME OF HIT
;
LP$X: .WORD 0 ; X POSITION OF HIT
LP$Y: .WORD 0 ; Y POSITION OF HIT
LP$DIS: .WORD 0 ; DISPLAY NUMBER LAST HIT
;
$LPINT: TST LP$FLG ; IS LIGHT PEN ENABLED ?
BEQ LP.1 ; YES, PROCESS INFORMATION
MOV #1,@#DPC ; ELSE RESUME THE DISPLAY
RTI ; AND RETURN IMMEDIATELY
;
LP.1: SAVREG ; SAVE THE REGISTERS
INC LP$FLG ; DISABLE LIGHT PEN (FOR A MOMENT)
CLR LP$HIT ; CLEAR THE WAIT CONDITION
MOV @#DPC,LP$DPC ; SAVE THE DPC OF HIT
MOV @#XSTAT,LP$X ; SAVE X POSITION
MOV @#YSTAT,LP$Y ; SAVE Y POSITION
MOV #1,@#DPC ; RESUME THE DISPLAY
MOV #$$DFT,R0 ; R0 POINTS TO DISPLAY TABLE
CLR R1 ; R1 CONTAINS DISPLAY NUMBER
LP.2: CMP @R0,LP$DPC ; HIT IN THIS DISPLAY ?
BHI LP.3 ; NO IT OCCURRED BEFORE
CMP 2(R0),LP$DPC ; HIT IN THIS DISPLAY ?
BHIS LP.FND ; YES, RETURN DISPLAY NUMBER
LP.3: ADD #6,R0 ; NO, POINT TO NEXT DISPLAY
INC R1 ; GET NEXT DISPLAY NUMBER
CMP R1,#77 ; ARE WE THROUGH
BLE LP.2 ; NO CONTINUE CHECKING
CLR R1 ; ELSE 0 = BAD HIT
LP.FND: MOV R1,LP$DIS ; SET UP DISPLAY NUMBER
CLR LP$FLG ; RE-ENABLE LIGHT PEN
MOV #"LE,ST.LP ; RESET STATUS DISPLAY
RESREG ; RESTORE THE REGISTERS
RTI ; RETURN FROM INTERRUPT
.PAGE
.SBTTL CLOCK INTERRUPT ROUTINE
;
; THIS ROUTINE COUNTS OFF A SPECIFIED NUMBER OF
; CLOCK TICS. WHEN THE COUNT REACHES ZERO THE
; ROUTINE CHECKS WHETHER ANY MOVEMENT ARROWS
; ARE ENABLED. IF SO THE ROUTINE CHECKS WHETHER
; MP. IS ENABLED (BIT 15 OF SWR) OR AP. ENABLED
; (BIT 1 OF SWR). NOTE THAT ONLY ONE POINTER MAY
; BE ENABLED IN THIS MANNER AND THE MAIN POINTER
; ALWAYS HAS PRECEDENCE OVER THE AUXILLARY POINTER.
;
CL$RT: .BYTE 0 ; 1 = MOVE TO RIGHT
CL$LFT: .BYTE 0 ; 1 = MOVE TO LEFT
CL$UP: .BYTE 0 ; 1 = MOVE UP
CL$DWN: .BYTE 0 ; 1 = MOVE DOWN
;
CL$CNT: .WORD 2 ; NUMBER OF TICS TO WAIT
; BETWEEN MOVES
CL$TIC: .WORD 2 ; RE-INITIALIZING VALUE FOR CL$CNT
;
$CLINT: DEC CL$CNT ; DECREMENT COUNT
BLE CL.0 ; CLOCK HAS TICKED AWAY
JMP CL.RET ; ELSE RETURN
CL.0: MOV CL$TIC,CL$CNT ; RESET COUNT
BIT #100000,@#SWR ; MP. ENABLED ?
BEQ CL.AP ; NO, SO CHECK AP.
TSTB CL$RT ; MOVE RIGHT ?
BEQ CL.1 ; NO, CONTINUE
CMP MP.X,#MAXX ; CAN GO RIGHT ?
BGE CL.1 ; NO, CONTINUE
INC MP.X ; MOVE TO THE RIGHT
CL.1: TSTB CL$LFT ; MOVE LEFT ?
BEQ CL.2 ; NO, CONTINUE
TST MP.X ; CAN GO LEFT ?
BLE CL.2 ; NO, CONTINUE
DEC MP.X ; MOVE TO LEFT
CL.2: TSTB CL$UP ; MOVE UP ?
BEQ CL.3 ; NO, CONTINUE
CMP MP.Y,#MAXY ; CAN GO UP ?
BGE CL.3 ; NO CONTINUE
INC MP.Y ; MOVE UP
CL.3: TSTB CL$DWN ; MOVE DOWN ?
BEQ CL.FRM ; NO, CONTINUE
TST MP.Y ; CAN GO DOWN ?
BLE CL.FRM ; NO, CONTINUE
DEC MP.Y ; MOVE DOWN
CL.FRM: FORMAT MP.Y,ST.MPY,4 ; FORMAT THE NEW
FORMAT MP.X,ST.MPX,4 ; X & Y POSITION
BR CL.RET ; AND RETURN
.PAGE
;
CL.AP: BIT #1,@#SWR ; AP. ENABLED ?
BEQ CL.RET ; NO, SO RETURN
TSTB CL$RT ; YES, MOVE RIGHT ?
BEQ CL.4 ; NO, CONTINUE
CMP AP.X,#MAXX ; YES, CAN MOVE RIGHT ?
BGE CL.4 ; NO, SO CONTINUE
INC AP.X ; MOVE TO RIGHT
CL.4: TSTB CL$LFT ; MOVE LEFT ?
BEQ CL.5 ; BO, CONTINUE
TST AP.X ; CAN MOVE LEFT ?
BLE CL.5 ; NO, CONTINUE
DEC AP.X ; MOVE TO LEFT
CL.5: TSTB CL$UP ; MOVE UP ?
BEQ CL.6 ; NO, CONTINUE
CMP AP.Y,#MAXY ; CAN MOVE UP ?
BGE CL.6 ; NO, CONTINUE
INC AP.Y ; MOVE UP
CL.6: TSTB CL$DWN ; MOVE DOWN ?
BEQ CL.FRA ; NO, CONTINUE
TST AP.Y ; CAN MOVE DOWN ?
BLE CL.FRA ; NO, CONTINUE
DEC AP.Y ; MOVE DOWN
CL.FRA: FORMAT AP.Y,ST.APY,4 ; FORMAT X & Y POSITION
FORMAT AP.X,ST.APX,4 ; INTO STATUS DISPLAY
CL.RET: RTI ; RETURN FROM INTERRUPT
.PAGE
.SBTTL GIDUS COMMAND INTERPRETER
;
; THIS SET OF ROUTINES ARE USED TO ACCEPT KEYBOARD
; COMMANDS AND PROCESS THEM. NOTE THAT $GCINT IS
; AN ALTERNATE INTERRUPT ROUTINE FOR THE GT40
; KEYBOARD. INTERRUPTS ARE PROCESSED HERE WHEN IN
; "GIDUS MODE", AND ARE PROCESSED BY $KBINT
; WHEN IN "HOST MODE"
;
GC$TRC: .WORD 0 ; TRACE VARIABLE
GC$ADR: .WORD 0 ; EXAMINE/MODIFY ADDRESS
GC$ARG: .WORD 0 ; COMMAND ARGUMENT
GC$PNT: .WORD 0 ; COMMAND CHARACTER POINTER
;
; COMMAND DISPATCH TABLE
;
GC$DIS: .WORD "DI,GC.DI ; DISABLE COMMAND
.WORD "EN,GC.EN ; ENABLE COMMAND
.WORD "SP,GC.SP ; SPEED COMMAND
.WORD "EX,GC.EX ; EXAMINE COMMAND
.WORD "MO,GC.MO ; MODIFY COMMAND
.WORD "TR,GC.TR ; TRACE COMMAND
.WORD "DE,GC.DE ; DELETE COMMAND
.WORD "HE,GC.HE ; HELP COMMAND
.WORD "OF,GC.OF ; OFF COMMAND
.WORD "LE,GC.LE ; ENABLE L.P. COMMAND
.WORD "LD,GC.LD ; DISABLE L.P. COMMAND
.WORD "RE,GC.RE ; RESET COMMAND
.PAGE
; GIDUS COMMAND SET UP ROUTINE
;
; THIS ROUTINE IS CALLED TO ENABLE GIDUS COMMANDS
; WHEN "HOME" IS HIT DURING "HOST MODE"
;
GC.SET: MOV #GC.END,GC.HLP ; DISABLE HELP SUB-FILE
MOV #" ,R0 ; PREPARE TO BLANK
MOV #7,R1 ; OUT COMMAND LINE
MOV #GC.LNE,R2
GC.CLR: MOV R0,(R2)+ ; BLANK OUT 7 WORDS
SOB R1,GC.CLR ; FOR A TOTAL OF 14 CHARACTERS
MOV #7,R5 ; ENABLE GIDUS COMMAND
CALL $ENABL ; DISPLAY FILE
MOV #GC.LNE,GC$PNT ; SET UP CHARACTER POINTER
CLR GC$ADR ; CLEAR INPUT ADDRESS
CLR GC$ARG ; AND INPUT ARGUMENT
MOV #$GCINT,@#KB$VEC ; TRAP FURTHER KB INTERRUPTS
MOV #"GI,ST.ATE ; CHANGE GIDUS STATE
RETURN ; RETURN TO $KBINT
.PAGE
; $GCINT - GIDUS COMMAND INTERRUPT ROUTINE
;
$GCINT: SAVREG ; SAVE THE REGISTERS
MOVB @#IB.KB,R0 ; GET THE INPUT CHARACTER
BIC #177600,R0 ; CLEAR TOP BYTE AND PARITY
CMP R0,#HME.CH ; IS THIS A HOME?
BNE GC.1 ; NO, CONTINUE
MOV #7,R5 ; YES, DISABLE COMMAND
CALL $DSABL ; DISPLAY FILE
MOV #$KBINT,@#KB$VEC ; RESET INTERRUPT VECTOR (HOST)
MOV #"TI,ST.ATE ; CHANGE GIDUS STATE
BR GC.RET ; AND RETURN
GC.1: CMP R0,#CR.CH ; CARRIAGE RETURN ?
BEQ GC.PRC ; YES, PROCESS COMMAND
MOV GC$PNT,R1 ; NO, R1 BECOMES CHAR. POINTER
CMP R0,#RUB.CH ; IS THIS A RUBOUT?
BNE GC.2 ; NO, CONTINUE
CMP R1,#GC.LNE ; YES, IS THERE ANYTHING TO ZAP
BLOS GC.2 ; NO, CONTINUE
MOVB #' ,-(R1) ; ABRA CADABRA - DISAPPEAR
MOV R1,GC$PNT ; RESET POINTER
BR GC.RET ; AND RETURN
GC.2: CMP R0,#SP.CH ; IS THIS A PRINTING CHARACTER ?
BLT GC.RET ; NO, RETURN
CMP R0,#'Z ; IS IT UPPER CASE ?
BLE GC.2.5 ; NO, SO GOOD CHARACTER
SUB #32.,R0 ; YES, SO FORCE UPPER CASE
GC.2.5: CMP R1,#GC.LNE+14. ; GOOD CHAR, IS THERE ROOM ?
BHIS GC.RET ; NO, IGNORE AND RETURN
MOVB R0,(R1)+ ; YES, ADD THE CHARACTER
MOV R1,GC$PNT ; RESET THE POINTER
GC.RET: RESREG ; RESTORE THE REGISTERS
RTI ; RETURN FROM INTERRUPT
.PAGE
.SBTTL GIDUS COMMAND PROCESSING ROUTINE
;
; THIS ROUTINE IS CALLED WHEN A GIDUS COMMAND
; IS TERMINATED BY A CARRIAGE RETURN
;
GC.PRC: MOV #" ,R0 ; R0 IS USED TO
MOV #GC.ANS,R1 ; BLANK OUT COMMAND REPLY
MOV R0,(R1)+ ;
MOV R0,(R1)+ ; CLEAR SIX CHARACTERS
MOV R0,(R1)+ ;
MOV #GC.END,GC.HLP ; DISABLE HELP SUB-FILE
MOV #GC.LNE,R0 ; R0 POINTS TO START OF COMMAND
MOV GC$PNT,R1 ; R1 POINTS AT END OF COMMAND
CALL GC.NUM ; GET THE NUMBER
MOV #GC.LNE,R0 ; R0 POINTS TO START OF COMMAND
MOV #12.,R1 ; 12 COMMANDS IN TOTAL
MOV #GC$DIS,R2 ; R2 POINTS TO DISPATCH TABLE
GC.LUK: CMP @R0,(R2)+ ; IS THIS THE COMMAND ?
BNE GC.3 ; NO, CONTINUE LOOKING
JMP @0(R2) ; YES, EXECUTE THAT COMMAND
GC.3: TST (R2)+ ; NO, POINT TO NEXT COMMAND
SOB R1,GC.LUK ; AND TRY AGAIN
;
GC.FIN: MOV #7,R1 ; INVALID COMMAND OR THROUGH
MOV #" ,R0 ; BLANK OUT THE COMMAND
MOV #GC.LNE,R2 ; LINE
GC.4: MOV R0,(R2)+ ; 7 WORDS = 14 CHARACTERS
SOB R1,GC.4
MOV #GC.LNE,GC$PNT ; RESET THE CHARACTER POINTER
BR GC.RET ; AND RETURN
.PAGE
; GC.NUM - RETURNS COMMAND ARGUMENT IN GC$ARG
;
GC.NUM: CLR R5 ; CLEAR WORD TO BE FORMED
GC.LUP: CMP R0,R1 ; ARE WE THROUGH LINE ?
BLO GC.5 ; NO, CONTINUE
MOV R5,GC$ARG ; YES, SAVE ARGUMENT
RETURN ; AND RETURN
GC.5: MOVB (R0)+,R2 ; GET NEXT CHARACTER
CMP R2,#'0 ; IS IT A DIGIT ?
BLT GC.LUP ; NO, CONTINUE
CMP R2,#'7 ; IS IT AN OCTAL DIGIT ?
BGT GC.LUP ; NO CONTINUE
SUB #60,R2 ; YES, CONVERT TO BINARY
ASL R5 ;
ASL R5 ; SHIFT ONE OCTAL DIGIT
ASL R5 ;
BIS R2,R5 ; INSERT THE DIGIT
BR GC.LUP ; CONTINUE TIL THROUGH
.PAGE
GC.DI: MOV GC$ARG,R5 ; GET DISPLAY FILE NUMBER
CALL $DSABL ; DISABLE THAT DISPLAY FILE
BR GC.FIN
;
GC.EN: MOV GC$ARG,R5 ; GET DISPLAY FILE NUMBER
CALL $ENABL ; ENABLE THAT DISPLAY FILE
BR GC.FIN
;
GC.SP: MOV #12,R5 ; SET SPEED = 12 - SPEED
SUB GC$ARG,R5
MOV R5,CL$TIC ; AND SAVE AS NUMBER OF TICS
BR GC.FIN
;
GC.EX: MOV GC$ARG,GC$ADR ; SAVE ARGUMENT AS ADDRESS
FORMAT @GC$ADR,GC.ANS,6 ; PRINT THAT LOCATION
BR GC.FIN
;
GC.MO: MOV GC$ARG,@GC$ADR ; MOVE ARGUMENT @ADDRESS
BR GC.FIN
;
GC.TR: MOV GC$ARG,GC$TRC ; SAVE ARGUMENT AS TRACE ADDRESS
MOV GC$ARG,GC$ADR ; AND EXAMINE ADDRESS
BR GC.FIN
;
GC.DE: MOV GC$ARG,R5 ; GET DISPLAY NUMBER
CALL $DELET ; AND DELETE IT
BR GC.FIN
;
GC.HE: MOV #GC.HLP,R0 ; ALTER THE DJMP
MOV #GC.HLP+2,@R0 ; TO POINT TO NEXT WORD
BR GC.FIN
;
GC.OF: MOV #ME.END,ME.ON ; TURN OFF ERROR MESSAGE
BR GC.FIN
;
GC.LE: CLR LP$FLG ; INDICATE L.P. ENABLED
MOV #"LE,ST.LP ; SHOW ENABLED IN STATUS DISPLAY
BR GC.FIN
;
GC.LD: INC LP$FLG ; INDICATE L.P. DISABLED
MOV #"LD,ST.LP ; SHOW DISABLED IN STATUS DISPLAY
BR GC.FIN
;
GC.RE: TST GC$ARG ; HOW MANY LINES ?
BEQ GC.RE1 ; IF ZERO THEN DON'T CHANGE
MOV GC$ARG,CD$NEW ; ELSE SAVE
GC.RE1: CALL $RESET ; DO THE RESET
BR GC.FIN ; AND RETURN
.PAGE
.SBTTL RECEIVE COMMAND ROUTINE
; $RCINT - RECEIVE INTERRUPT ROUTINE TO FILL COMMAND BUFFER
;
; RECEIVER BUFFER
;
RC$CMD: .WORD 0 ; COMMAND WORD
RC$BCT:
RC$DIS: .WORD 0 ; BLOCK COUNT OR DISPLAY #
RC$STA:
RC$X: .WORD 0 ; BLOCK #, STATUS, OR XPOS
RC$Y: .WORD 0 ; Y POSITION
RC$SUM: .WORD 0 ; CHECKSUM
;
RC$PNT: .WORD 0 ; BUFFER POINTER
RC$CNT: .WORD 0 ; BUFFER BYTE COUNT
;
$IO$: .WORD 0 ; I/O FLAG
RC$OPT: .WORD 0 ; REQUESTING OPTION FLAG
;
$RCINT: SAVREG ; SAVE THE REGISTERS
MOVB @#IB.GT,R0 ; GET THE INCOMING BYTE
BIC #177400,R0 ; CLEAR TOP BYTE
ADD R0,RC$SUM ; ADD INTO CHECKSUM
DEC RC$CNT ; DECREMENT THE BYTE COUNT
BLE RC.CMD ; PROCESS THE COMMAND IF THROUGH
MOVB R0,@RC$PNT ; ELSE BUFFER THIS BYTE
INC RC$PNT ; AND BUMP THE POINTER
RC.RET: RESREG ; RESTORE THE REGISTERS
RTI ; AND RETURN FROM INTERRUPT
.PAGE
; RECEIVE COMMAND DISPATCH TABLE
;
RC$DSP: .WORD RC.NC ; [0] INVALID COMMAND
.WORD RC.EN ; [1] ENABLE DISPLAY FILE
.WORD RC.DS ; [2] DISABLE DISPLAY FILE
.WORD RC.MOV ; [3] MOVE DISPLAY FILE
.WORD RC.RMP ; [4] REQUEST MAIN POINTER
.WORD RC.RAP ; [5] REQUEST AUX. POINTER
.WORD RC.DL ; [6] DISABLE LIGHT PEN
.WORD RC.EL ; [7] ENABLE LIGHT PEN
.WORD RC.RLH ; [8] REQUEST LAST L.P. HIT
.WORD RC.RNH ; [9] REQUEST NEW L.P. HIT
.WORD RC.RAD ; [10] REQUEST TO ADD DISPLAY
.WORD RC.ANB ; [11] ADD NEXT BLOCK
.WORD RC.DEL ; [12] DELETE DISPLAY FILE
.WORD RC.SND ; [13] RE-SEND LAST TRANSMISSION
.WORD RC.CLR ; [14] CLEAR CDF.
.WORD RC.RST ; [15] RESET GIDUS
.WORD RC.OPT ; [16] REQUEST OPTION HIT
;
;
RC.CMD: MOV 14.(SP),@#PSW ; RESTORE PSW (ALLOW INTERRUPTS)
TSTB RC$SUM ; TEST CHECKSUM - WAS IT GOOD ?
BEQ RC.1 ; YES, CONTINUE WITH PROCESSING
MOVB #66,TR$STA ; STATUS = "CHECKSUM ERROR"
JMP $TRMIT ; TRANSMIT
;
RC.1: MOV RC$CMD,R0 ; GET COMMAND WORD
BLT RC.NC ; IF NEGATIVE THEN NO COMMAND
CMP R0,#16. ; VALID COMMAND ?
BGT RC.NC ; > 13, NO SUCH COMMAND
MOVB TR$STA,TR$OLD ; SAVE LAST STATUS
CLRB TR$STA ; DEFAULT STATUS IS GOOD
ASL R0 ; FORM BYTE OFFSET
JMP @RC$DSP(R0) ; EXECUTE THE COMMAND
.PAGE
.SBTTL COMMAND UTILTY ROUTINES
;
RC.NC: MOVB #9.,TR$STA ; STATUS = "NO COMMAND"
JMP $TRMIT ; TRANSMIT
;
RC.EN: MOV RC$DIS,R5 ; GET DISPLAY NUMBER
CALL $ENABL ; AND ENABLE IT ($ENABL SETS STATUS)
JMP $TRMIT ; TRANSMIT
;
RC.DS: MOV RC$DIS,R5 ; GET DISPLAY NUMBER
CALL $DSABL ; AND DISABLE IT ($DSABL SETS STATUS)
JMP $TRMIT ; TRANSMIT
;
RC.MOV: MOV RC$DIS,R5 ; GET DISPLAY NUMBER
CLR SE$MOD ; DIRECT SEARCH MODE
CALL $SERCH ; GET DISPLAY STATUS
BIT #EX.BIT,4(R4) ; DOES THIS DISPLAY EXIST ?
BNE RC.M1 ; YES, CONTINUE CHECKING
INCB TR$STA ; NO, STATUS = "NO SUCH DISPLAY"
JMP $TRMIT ; TRANSMIT
RC.M1: BIT #RL.BIT,4(R4) ; CAN DISPLAY BE MOVED ?
BNE RC.M2 ; YES, MOVE IT
MOVB #4,TR$STA ; STATUS = "CANNOT MOVE DISPLAY"
JMP $TRMIT ; TRANSMIT
RC.M2: MOV @R4,R4 ; GET ADDRESS OF FIRST WORD
TST (R4)+ ; POINT TO X POSITION
MOV RC$X,(R4)+ ; INSERT X AND Y
MOV RC$Y,(R4)+ ; POSITION FROM COMMAND
CMP R5,#4 ; MAIN POINTER MOVED ?
BNE RC.M3 ; NO, CONTINUE
FORMAT MP.X,ST.MPX,4 ; YES, SO FORMAT X
FORMAT MP.Y,ST.MPY,4 ; AND Y POSITION
RC.M3: CMP R5,#5 ; AUXILLARY POINTER MOVED ?
BNE RC.M4 ; NO, CONTINUE
FORMAT AP.X,ST.APX,4 ; YES, SO FORMAT X
FORMAT AP.Y,ST.APY,4 ; AND Y POSITION
RC.M4: JMP $TRMIT ; TRANSMIT
;
RC.RMP: MOV MP.Y,R0 ; GET MAIN POINTER(Y)
CALL TR.Y ; AND BUFFER IT
MOV MP.X,R0 ; GET MAIN POINTER(X)
CALL TR.X ; AND BUFFER IT
JMP $TRMIT ; TRANSMIT
;
RC.RAP: MOV AP.Y,R0 ; GET AUX. POINTER(Y)
CALL TR.Y ; AND BUFFER IT
MOV AP.X,R0 ; GET AUX. POINTER(X)
CALL TR.X ; AND BUFFER IT
JMP $TRMIT ; TRANSMIT
.PAGE
; COMMAND UTILITY ROUTINES (CONTINUED)
;
RC.DL: MOV #1,LP$FLG ; DISABLE THE LIGHT PEN
MOV #"LD,ST.LP ; INDICATE IN STATUS DISPLAY
JMP $TRMIT ; TRANSMIT
;
RC.EL: CLR LP$FLG ; ENABLE THE LIGHT PEN
MOV #"LE,ST.LP ; INDICATE IN STATUS DISPLAY
JMP $TRMIT ; TRANSMIT
;
RC.RLH: MOV LP$Y,R0 ; GET LAST HIT(Y)
CALL TR.Y ; AND BUFFER IT
MOV LP$X,R0 ; GET LAST HIT(X)
CALL TR.X ; AND BUFFER IT
MOVB LP$DIS,TR$DIS ; GET LAST FILE HIT
TST RC$OPT ; IS THIS AN OPTION ?
BNE RC.OP1 ; YES, SO PROCESS THE REMAINING
JMP $TRMIT ; TRANSMIT
;
RC.RNH: TST LP$FLG ; IS LIGHT PEN ENABLED ?
BEQ RC.R1 ; YES, WAIT FOR HIT
MOVB #5,TR$STA ; ELSE STATUS = "L.P. DISABLED"
JMP $TRMIT ; TRANSMIT
RC.R1: MOV #1,LP$HIT ; SET WAIT FLAG
MOV #"LW,ST.LP ; AND SHOW IN STATUS
RC.R2: TST LP$HIT ; AND TWIDDLE THUMBS
BNE RC.R2 ; UNTIL WE GET A HIT
BR RC.RLH ; PROCESS THE HIT
;
RC.DEL: MOV RC$DIS,R5 ; GET DISPLAY NUMBER
CALL $DELET ; AND DELETE IT
JMP $TRMIT ; TRANSMIT
;
RC.SND: MOVB TR$OLD,TR$STA ; RESET STATUS
JMP $TRMIT ; AND RE-TRANSMIT LAST BLOCK
;
RC.CLR: CALL $CDINI ; INITIALIZE CDF.
JMP $TRMIT ; TRANSMIT
;
RC.RST: MOV RC$DIS,CD$NEW ; GET DESIRED NUMBER OF LINES
CALL $RESET ; AND RESET GIDUS
JMP $TRMIT ; TRANSMIT
;
RC.OPT: DISABL 10 ; DISABLE THE POINTER
ENABLE 6 ; ENABLE THE PROMPT
INC RC$OPT ; INDICATE AN OPTION HIT
BR RC.RNH ; GET LIGHT PEN HIT
RC.OP1: DISABL 6 ; DISABLE THE PROMPT
MOV #740.,OP$X ; MOVE THE OPTION POINTER
MOV LP$Y,OP$Y
ENABLE 10 ; AND ENABLE THE POINTER
JMP $TRMIT ; AND TRANSMIT
.PAGE
.SBTTL REQUEST TO ADD
;
; THIS ROUTINE PERFORMS THE FOLLOWING FUNCTIONS:
;
; [1] CHECKS IF THERE IS A FREE DISPLAY SLOT FOR FILE
; [2] CHECKS IF THERE IS ENOUGH CORE FOR THE FILE
; [3] SETS A MEMORY LIMIT BEYOND WHICH THE ADDITION CANNOT GO
; [4] SETS UP MEMORY AREA FOR ADDITION
;
RC.RAD: MOV #1,AD$FLG ; INDICATE ADDITION NOT ALLOWED
CMP DU$CNT,#77 ; IS THERE A DISPLAY SLOT ?
BLE RC.R3 ; YES, CONTINUE CHECKING
MOVB #7,TR$STA ; NO, STATUS = "NO DISPLAY SLOT"
JMP $TRMIT ; TRANSMIT STATUS
RC.R3: MOV RC$BCT,R0 ; GET FILE SIZE
ADD #10.,R0 ; ADD SAFETY FACTOR
MOV #STACK,R1 ; GET UPPER MEMORY BOUND
SUB DF$TOP,R1 ; SUBTRACT LOWER MEMORY BOUND
CMP R0,R1 ; IS THERE ENOUGH CORE ?
BLT RC.R4 ; YES, ALLOW THE ADDITION
MOVB #6,TR$STA ; NO, STATUS ="NOT ENOUGH CORE"
JMP $TRMIT ; TRANSMIT
RC.R4: MOV R0,AD$LIM ; SAVE SIZE FOR CHECK
ADD DF$TOP,AD$LIM ; DON'T ALLOW ADDITION PAST
MOV DF$TOP,AD$RST ; GET RESET POINTER
MOV DF$TOP,AD$PNT ; AND ACTIVE POINTER
CLR AD$FLG ; ALLOW ADDITION
MOVB #11.,TR$STA ; STATUS = "SEND NEXT BLOCK"
JMP $TRMIT ; TRANSMIT
.PAGE
.SBTTL ADD NEXT BLOCK COMMAND
;
; THIS ROUTINE PERFORMS THE FOLLOWING FUNCTION
;
; [1] CHECK FOR NULL BLOCK (I.E. DISPLAY FILE SENT)
; [2] CHECK FOR VALID BYTE COUNT
; [3] CHECK IF LIMIT EXCEEDED
; [4] UPDATE FILE POINTERS
; [5] TELL 10 TO SEND BLOCK
;
RC.ANB: MOV #1,AD$ABF ; DON'T ALLOW BLOCK
MOV RC$BCT,R0 ; GET BYTE COUNT
BLE RC.LST ; IF ZERO THEN LAST BLOCK
CMP R0,#200 ; VALID BYTE COUNT ?
BLE RC.A1 ; YES
MOVB #12.,TR$STA ; NO, STATUS = "BAD BLOCK SIZE"
JMP $TRMIT ; TRANSMIT
RC.A1: MOV AD$RST,R1 ; GET START ADDRESS
ADD R0,R1 ; ADD BYTE COUNT
CMP R1,AD$LIM ; DOES IT EXCEED LIMIT ?
BLO RC.A2 ; NO
MOVB #6,TR$STA ; STATUS = "NOT ENOUGH CORE"
JMP $TRMIT ; TRANSMIT
RC.A2: TST AD$FLG ; ADDITONS ALLOWED ?
BEQ RC.A3 ; YES
MOVB #14.,TR$STA ; NO, STATUS = "ADDITION NOT ALLOWED"
JMP $TRMIT ; TRANSMIT
RC.A3: MOV AD$RST,AD$PNT ; UPDATE ACTIVE POINTER
CLR AD$SUM ; CLEAR THE CHECKSUM
MOV R0,AD$CNT ; CLEAR THE BYTE COUNT
MOVB #11.,TR$STA ; STATUS = "SEND NEXT BLOCK"
CLR AD$ABF ; CLEAR THE ALLOW BLOCK FLAG
JMP $TRMIT ; TRANSMIT
.PAGE
.SBTTL LAST BLOCK ROUTINE
;
; THIS ROUTINE PERFORMS THE FOLLOWING FUNCTIONS
;
; [1] INSERTS DISPLAY INFORMATION INTO THE FIRST
; AVAILABLE DISPLAY SLOT
; [2] INFORMS 10 OF THE DISPLAY SLOT CHOSEN
; [3] UPDATE STATUS DISPLAY WITH
; NUMBER OF DISPLAYS, NUMBER DISABLED, AND FREE CORE
;
RC.LST: MOV #$$DFT,R0 ; R0 POINTS TO DISPLAY TABLE
CLR R1 ; R1 IS DISPLAY NUMBER
RC.L1: BIT #EX.BIT,4(R0) ; IS THIS SLOT IN USE
BEQ RC.L2 ; NO, SO USE IT
ADD #6,R0 ; ELSE POINT TO NEXT SLOT
INC R1 ; AND BUMP DISPLAY NUMBER
CMP R1,#77 ; ARE WE THROUGH ?
BLT RC.L1 ; NO, SO CONTINUE
RC.L2: MOV DF$TOP,(R0)+ ; INSERT FIRST ADDRESS
MOV AD$RST,@R0 ; AND LAST ADDRESS
SUB #2,(R0)+ ; POINT TO LAST WORD
MOV RC$STA,@R0 ; INSERT THE STATUS WORD
BIS #EX.BIT,@R0 ; SET THE EXIST BIT
BIC #EN.BIT,@R0 ; CLEAR THE ENABLED BIT
MOVB R1,TR$DIS ; BUFFER THE DISPLAY NUMBER
FORMAT R1,ST.LST,2 ; AND SHOW IN STATUS DISPLAY
INC DU$CNT ; INCREMENT THE USED COUNT
FORMAT DU$CNT,ST.USE,2 ; AND FORMAT INTO STATUS DISPLAY
INC DS$CNT ; INCREMENT THE DISABLED COUNT
FORMAT DS$CNT,ST.DIS,2 ; AND FORMAT INTO STATUS DISPLAY
MOV AD$RST,DF$TOP ; UPDATE LOWER MEMORY BOUND
MOV #STACK,R1 ; GET UPPER MEMORY BOUND
SUB DF$TOP,R1 ; SUBTRACT LOWER BOUND
ASR R1 ; FORM WORD COUNT
FORMAT R1,ST.FRE,5 ; FORMAT THE FREE CORE
CLRB TR$STA ; ADDITION COMPLETED
JMP $TRMIT ; TRANSMIT
.PAGE
.SBTTL ADD FILE INTERRUPT ROUTINE
;
; STATUS WORDS
;
AD$LIM: .WORD 0 ; ADDITION CAN'T GO BEYOND
AD$CNT: .WORD 0 ; BYTE COUNT
AD$SUM: .WORD 0 ; CHECKSUM
AD$PNT: .WORD 0 ; ACTIVE POINTER
AD$RST: .WORD 0 ; RESET POINTER
AD$FLG: .WORD 0 ; ALLOW FLAG
AD$ABF: .WORD 0 ; ALLOW NEXT BLOCK FLAG
;
$ADINT: SAVREG ; SAVE THE REGISTERS
MOVB @#IB.GT,R0 ; GET THE LAST CHARACTER
BIC #177400,R0 ; CLEAR THE TOP BYTE
ADD R0,AD$SUM ; ADD INTO CHECKSUM
DEC AD$CNT ; DECREMENT THE BYTE COUNT
BLE AD.1 ; IF ZERO THEN THROUGH
MOVB R0,@AD$PNT ; ELSE BUFFER THE BYTE
INC AD$PNT ; BUMP THE POINTER
AD.RET: RESREG ; RESTORE THE REGISTERS
RTI ; RETURN FROM INTERRUPT
;
AD.1: MOV 14.(SP),@#PSW ; ALLOW INTERRUPTS
TSTB AD$SUM ; IS THE CHECKSUM GOOD ?
BNE AD.2 ; NO
BIC #1,AD$PNT ; YES MAKE THE LAST BYTE EVEN
MOV AD$PNT,AD$RST ; UPDATE RESET ADDRESS
MOVB #15.,TR$STA ; INDICATE BLOCK RECEIVED
JMP $TRMIT
;
AD.2: MOV AD$RST,AD$PNT ; RESET ACTIVE POINTER
MOVB #66,TR$STA ; INDICATE CHECKSUM ERROR
JMP $TRMIT ; TRANSMIT
.PAGE
.SBTTL TRANSMISSION ROUTINE
;
; TRANSMIT BUFFER
;
TR$STA: .BYTE 0 ; STATUS BYTE
TR$XL: .BYTE 0 ; X POSITION
TR$XH: .BYTE 0
TR$YL: .BYTE 0 ; Y POSITION
TR$YH: .BYTE 0
TR$DIS: .BYTE 0 ; DISPLAY NUMBER
TR$SUM: .BYTE 0 ; CHECK SUM
.BYTE 0 ; FILLER
;
TR$OLD: .BYTE 0 ; LAST STATUS
;
.EVEN
$TRMIT: MOV #"TR,ST.ATE ; INDICATE "TRANSMITTING"
CLR TR$SUM ; CLEAR THE CHECKSUM
CLR RC$OPT ; TURN OFF OPTION FLAG
MOV #TR$STA,R4 ; R4 IS BUFFER POINTER
MOV #6,R3 ; BYTE COUNT
TR.LUP: MOVB (R4)+,R5 ; GET THE NEXT BYTE
ADD R5,TR$SUM ; ADD INTO CHECKSUM
CMP R5,#74 ; IS IT A SPECIAL CHARACTER
BGE TR.1 ; YES, SO BYPASS
BIS #100,R5 ; ELSE MAKE PRINTABLE
TR.1: CALL $SEND ; AND SEND IT
SOB R3,TR.LUP ; DO SO FOR ALL CHARACTERS
CLR R5 ; GET READY TO GET LOW BYTE
BISB TR$SUM,R5 ; GET CHECKSUM
ASR R5 ;
ASR R5 ; SHIFT R5 FOUR PLACES
ASR R5 ; IN ORDER TO GET HIGH 4 BITS
ASR R5 ;
BIS #100,R5 ; MAKE IT PRINTABLE
CALL $SEND ; SEND FIRST HALF OF CSUM
MOVB TR$SUM,R5 ; GET CHECKSUM
BIC #177760,R5 ; CLEAR ALL EXCEPT LOW 4 BITS
BIS #100,R5 ; MAKE PRINTABLE
CALL $SEND ; SEND LAST HALF OF CHECKSUM
MOV #$DLINT,DL$VEC ; RESET INTERRUPT VECTOR
CLR $IO$ ; CLEAR I/O FLAG
MOV ST.OLD,ST.ATE ; RESTORE GIDUS STATE
RESREG ; RESTORE THE REGISTERS
MOV #"CH,ST.DL ; RESTORE DL-11 STATE
RTI ; RETURN FROM INTERRUPT
;
TR.X: MOVB R0,TR$XL ; GET LOW BYTE
BICB #340,TR$XL ; ONLY WANT FIVE BITS
ASL R0 ; SHIFT R0 UP
ASL R0 ;
ASL R0 ; THREE BITS
SWAB R0 ; SWAP THE BYTES
MOVB R0,TR$XH ; GET HIGH BYTE
BICB #340,TR$XH ; ONLY WANT FIVE BITS
RETURN ; RETURN
;
BICB #340,TR$YL ; ONLY WANT FIVE BITS
ASL R0 ; SHIFT R0 UP
ASL R0 ;
ASL R0 ; THREE BITS
SWAB R0 ; SWAP THE BYTES
MOVB R0,TR$YH ; GET HIGH BYTE
BICB #340,TR$YH ; ONLY WANT FIVE BITS
RETURN ; RETURN
;
TR.Y: CALL TR.X ; FORMAT INTO X FIELD
MOVB TR$XL,TR$YL ; AND MOVE INTO
MOVB TR$XH,TR$YH ; Y FIELD
RETURN ; AND RETURN
.PAGE
$SEND: TSTB @#OS.GT ; IS 10 READY
BPL $SEND ; WAIT UNTIL READY
MOVB R5,@#OB.GT ; SEND THE CHARACTER
RETURN ; RETURN
.PAGE
.SBTTL ENABLE A DISPLAY FILE
;
; UPON ENTRY R5 CONTAINS DISPLAY FILE
; NUMBER TO BE ENABLED
;
$ENABL: SAVREG ; SAVE THE REGISTERS
CLRB TR$STA ; INDICATE GOOD ENABLE
TST R5 ; IS DISPLAY NUMBER NEGATIVE ?
BLT EN.BN ; YES, ERROR
CMP R5,#77 ; IS DISPLAY NUMBER IN RANGE
BLE EN.GN ; YES, GOOD NUMBER
EN.BN: MOV #ER$BDN,R4 ; R4 IS ERROR POINTER
CALL $ERROR ; WARNING "% BAD DISPLAY NUMBER"
MOVB #3,TR$STA ; INDICATE ERROR CONDITION
BR EN.RET ; RETURN
EN.GN: CLR SE$MOD ; INDICATE DIRECT SEARCH MODE
CALL $SERCH ; GET THIS DISPLAY STATUS
BIT #EX.BIT,4(R4) ; DOES THE DISPLAY EXIST ?
BNE EN.1 ; YES, CONTINUE
MOV #ER$DDE,R4 ; R4 IS ERROR POINTER
CALL $ERROR ; WARNING "%DISPLAY DOES NOT EXIST"
INCB TR$STA ; LET 10 KNOW THE ERROR
BR EN.RET ; AND RETURN
EN.1: BIT #EN.BIT,4(R4) ; IS THE DISPLAY ENABLED ?
BNE EN.RET ; YES, RETURN
MOV R4,R3 ; SAVE POINTER TO THIS ENTRY
INC SE$MOD ; INDICATE INDIRECT SEARCH MODE
CALL $SERCH ; FIND A DISPLAY POINTING PAST
TST R4 ; WAS THE DISPLAY FOUND ?
BGT EN.FND ; YES, CONTINUE
MOV #ER$FNF,R4 ; R4 IS ERROR POINTER
CALL $ERROR ; FATAL "? DISPLAY TABLE CORRUPT"
BR EN.RET ; RETURN
;
EN.FND: CALL $DSTOP ; POLITELY STOP THE DISPLAY
MOV 2(R4),R0 ; GET ADDR. OF LAST WORD OF PREV. DISP.
MOV 2(R3),R1 ; GET ADDR. OF LAST WORD OF THIS DISP.
MOV @R0,@R1 ; NEW DISPLAY DJMPS TO NEXT IN LIST
CLR @R0 ; RESET PREV. DISP. TO POINT
BIS @R3,@R0 ; TO NEW DISPLAY
MOV 4(R4),R0 ; GET STATUS POINTER OF PREV. DISP.
BIC #177700,R0 ; MASK OUT ALL BUT POINTER
BIS R0,4(R3) ; COPY POINTER TO NEW DISP.
BIC #PT.BIT,4(R4) ; CLEAR POINTER OF PREV. DISP.
BIS R5,4(R4) ; INSERT NEW DISPLAY NUMBER
DEC DS$CNT ; DECREMENT THE DISABLED COUNT
FORMAT DS$CNT,ST.DIS,2 ; AND FORMAT INTO STATUS DISPLAY
BIS #EN.BIT,4(R3) ; INDICATE DISPLAY IS ENABLED
MOV #FIRST.,@#DPC ; RESTART THE DISPLAY
EN.RET: RESREG ; RESTORE THE REGISTERS
RETURN ; AND RETURN
.PAGE
.SBTTL DISABLE A DISPLAY FILE
;
; UPON ENTRY R5 CONTAINS DISPLAY NUMBER
; TO BE DISABLED
;
DU$CNT: .WORD 12 ; NUMBER OF DISPLAY FILES USED
DS$CNT: .WORD 3 ; NUMBER OF DISABLED DISPLAY FILES
;
$DSABL: SAVREG ; SAVE THE REGISTERS
CLRB TR$STA ; INDICATE GOOD DISABLE
TST R5 ; IS DISPLAY NUMBER NEGATIVE
BLT DS.BN ; YES, ERROR
CMP R5,#77 ; IS DISPLAY NUMBER IN RANGE ?
BLE DS.GN ; YES, WE HAVE A GOOD NUMBER
DS.BN: MOV #ER$BDN,R4 ; R4 IS ERROR POINTER
CALL $ERROR ; WARNING "% BAD DISPLAY NUMBER"
MOVB #3,TR$STA ; INDICATE ERROR CONDITION
BR DS.RET ; RETURN
DS.GN: CLR SE$MOD ; INDICATE DIRECT SEARCH MODE
CALL $SERCH ; GET THIS DISPLAY STATUS
BIT #EN.BIT,4(R4) ; IS DISPLAY DISABLED ?
BEQ DS.RET ; YES, RETURN
BIT #ND.BIT,4(R4) ; CAN DISPLAY BE DISABLED ?
BEQ DS.1 ; YES, DO SO
MOV #ER$ND,R4 ; R4 IS #ERROR POINTER
CALL $ERROR ; WARNING "% CANNOT DISABLE"
MOVB #2,TR$STA ; INDICATE ERROR CONDITION
BR DS.RET ; RETURN
DS.1: MOV R4,R3 ; SAVE POINTER TO THIS ENTRY
DEC SE$MOD ; INDICATE INDIRECT SEARCH MODE
CALL $SERCH ; FIND THE PREVIOUS DISPLAY
TST R4 ; WAS THE DISPLAY FOUND ?
BGT DS.FND ; YES, CONTINUE
MOV #ER$FNF,R4 ; R4 IS ERROR POINTER
CALL $ERROR ; FATAL "? DISPLAY TABLE CORRUPT"
BR DS.RET ; RETURN
;
DS.FND: CALL $DSTOP ; STOP THE DISPLAY
MOV 2(R4),R0 ; GET ADDR. OF LAST WORD OF PREV. DISP.
MOV 2(R3),R1 ; GET ADDR. OF LAST WORD OF THIS DISP.
CLR @R0 ; RESET PREVIOUS DISPLAY
BIS @R1,@R0 ; TO POINT TO NEXT DISPLAY
MOV 4(R3),R0 ; R0 GETS POINTER WORD
BIC #177700,R0 ; CLEAR ALL EXCEPT POINTER
BIC #PT.BIT,4(R4) ; CLEAR PREV. POINTER
BIS R0,4(R4) ; CHANGE TO NEW POINTER
BIC #PT.BIT,4(R3) ; DISABLE THIS POINTER
BIC #EN.BIT,4(R3) ; TURN OFF ENABLED BIT
INC DS$CNT ; INCREMENT DISABLED COUNT
FORMAT DS$CNT,ST.DIS,2 ; FORMAT INTO STATUS DISPLAY
MOV #FIRST.,@#DPC ; RESTART THE DISPLAY
DS.RET: RESREG ; RESTORE THE REGISTERS
RETURN ; AND RETURN
.PAGE
.SBTTL DISPLAY TABLE SEARCH ROUTINE
;
SE$MOD: .WORD 0 ; SEARCH MODE
;
; 0 = DIRECT SEARCH FOR REQUESTED DISPLAY
; -1 = SEARCH FOR DISPLAY POINTING TO REQUESTED
; 1 = SEARCH FOR DISPLAY POINTING PAST REQUESTED
;
$SERCH: MOV #$$DFT,R4 ; R4 POINTS TO DISPLAY TABLE
TST SE$MOD ; WHAT KIND OF SEARCH ?
BNE SE.IND ; INDIRECT SEARCH
MOV R5,R0 ; DIRECT SEARCH, GET NUMBER
ASL R0 ; MULTIPLY BY TWO
ADD R5,R0 ; ADD (JUST R0 * 3)
ASL R0 ; FORM WORD OFFSET
ADD R0,R4 ; ADD TO BASE ADDRESS
BR SE.RET ; AND RETURN
;
SE.IND: MOV #64.,R1 ; R1 = NUMBER OF DISPLAY FILES
SE.LUP: MOV 4(R4),R0 ; GET STATUS POINTER WORD
BIC #177700,R0 ; CLEAR ALL EXCEPT POINTER
CMP R0,R5 ; COMPARE WITH REQUESTED
BGE SE.FND ; IF >= SEARCH MAY BE OVER
SE.CON: ADD #6,R4 ; ELSE LOOP
SOB R1,SE.LUP ; FOR ALL DISPLAY FILES
CLR R4 ; INDICATE UNSUCCESSFUL
BR SE.RET ; AND RETURN
SE.FND: TST SE$MOD ; WHAT KIND OF SEARCH ?
BGT SE.PST ; LOOK FOR FILE POINTING PAST
CMP R0,R5 ; IS THIS THE ONE ?
BNE SE.CON ; NO, CONTINUE
BR SE.RET ; YES, RETURN
SE.PST: CMP R0,R5 ; IS THIS THE ONE ?
BGT SE.RET ; YES, RETURN
CLR R4 ; NO, BAD SEARCH
SE.RET: RETURN ; RETURN
.PAGE
.SBTTL DELETE ROUTINE
;
; THIS ROUTINE IS USED TO DELETE A SPECIFIED
; DISPLAY FILE, AND COMPRESS THE REMAINING DISPLAY
; FILES IN ORDER TO RECLAIM THE CORE USED
;
DE$LOW: .WORD 0 ; START ADDRESS OF DISPLAY
DE$HGH: .WORD 0 ; END ADDRESS OF DISPLAY
DE$SAV: .WORD 0 ; NUMBER OF BYTES RECLAIMED
;
$DELET: SAVREG ; SAVE THE REGISTERS
TST R5 ; IS THIS A GOOD DISPLAY ?
BLT DE.BDN ; NO, SO ERROR
CMP R5,#77 ; IS THIS A GOOD DISPLAY ?
BLE DE.GDN ; YES, SO CONTINUE
DE.BDN: MOV #ER$BDN,R4 ; R4 IS ERROR POINTER
CALL $ERROR ; WARNING "% BAD DISPLAY NUMBER"
MOVB #3,TR$STA ; LET 10 KNOW THE ERROR
JMP DE.RET ; AND RETURN
;
DE.GDN: CLR SE$MOD ; INDICATE DIRECT SEARCH MODE
CALL $SERCH ; LOOK FOR DISPLAY
BIT #EX.BIT,4(R4) ; DOES THIS DISPLAY EXIST
BNE DE.DE ; YES, SO CONTINUE
MOV #ER$DDE,R4 ; R4 IS ERROR POINTER
CALL $ERROR ; WARNING "% DISPLAY DOES NOT EXIST"
INCB TR$STA ; LET 10 KNOW THE ERROR
JMP DE.RET ; AND RETURN
;
DE.DE: BIT #WP.BIT,4(R4) ; IS THE DISPLAY WRITE-PROTECTED
BEQ DE.WE ; NO, SO CONTINUE
MOV #ER$WP,R4 ; R4 IS ERROR POINTER
CALL $ERROR ; WARNING "% CANNOT DELETE THIS DISPLAY"
MOVB #8.,TR$STA ; LET 10 KNOW THE ERROR
JMP DE.RET ; AND RETURN
;
DE.WE: MOV @R4,R1 ; GET LOW ADDRESS
MOV R1,DE$LOW ; AND SAVE
MOV 2(R4),R2 ; GET HIGH ADDRESS
ADD #2,R2 ; POINT ONE WORD PAST
MOV R2,DE$HGH ; AND SAVE
SUB R1,R2 ; GET BYTE COUNT
MOV R2,DE$SAV ; AND SAVE
BIC #ND.BIT,4(R4) ; IGNORE THE DISABLE BIT
CALL $DSABL ; DISABLE THE DISPLAY
CLR (R4)+ ;
CLR (R4)+ ; REMOVE DISPLAY TABLE ENTRY
CLR (R4)+ ;
.PAGE
; LOOP THROUGH THE DISPLAY TABLE. IF ANY ADDRESS WORDS
; WERE POINTING PAST THE DELETED DISPLAY, THEY SHOULD
; BE UPDATED TO THE NEW ADDRESS (CURRENT - DE$SAV)
; IN ORDER TO MAKE THESE TABLE MODIFICATIONS THE DISPLAY
; WILL HAVE TO BE STOPPED
;
MOV #$$DFT,R4 ; R4 POINTS TO DISPLAY TABLE
MOV #77,R0 ; R0 IS NUMBER OF DISPLAYS
CALL $DSTOP ; STOP THE DISPLAY
DE.TBL: MOV 2(R4),R3 ; SAVE LAST ADDRESS IN R3
BIT #EX.BIT,4(R4) ; DOES THE DISPLAY EXIST
BNE DE.0 ; YES, CONTINUE CHECKING
ADD #4,R4 ; NO, POINT TO NEXT ENTRY
BR DE.3 ; AND CONTINUE THE LOOP
DE.0: CMP (R4)+,DE$HGH ; DOES THIS NEED TO BE CHANGED ?
BLT DE.1 ; NO, SON CONTINUE
SUB DE$SAV,-2(R4) ; YES, UPDATE THE ADDRESS
DE.1: CMP (R4)+,DE$HGH ; DOES THIS NEED A CHANGE ?
BLT DE.2 ; NO, SO CONTINUE
SUB DE$SAV,-2(R4) ; YES, UPDATE THE ADDRESS
DE.2: CMP @R3,DE$HGH ; DOES IT NEED TO BE CHANGED ?
BLT DE.3 ; NO, SO CONTINUE
SUB DE$SAV,@R3 ; UPDATE THE ADDRESS
DE.3: TST (R4)+ ; POINT TO NEXT TABLE ENTRY
SOB R0,DE.TBL ; LOOP FOR ALL DISPLAYS
;
; NOW CORE NEEDS TO BE COMPACTED. THIS IS DONE BY SHIFTING
; EACH WORD ABOVE DE$HGH TO THE CORRESPONDING LOCATION
; ABOVE DE$LOW. WHEN SHIFTING DISPLAYS IN THIS MANNER
; IT WILL BE NECESSARY TO MODIFY ANY DJMP'S THAT
; ORIGINALLY POINTED PAST DE$HGH.
;
MOV DE$LOW,R0 ; GET DESTINATION ADDRESS
MOV DE$HGH,R1 ; GET SOURCE ADDRESS
;
DE.MOV: CMP R1,#STACK ; ARE WE THROUGH YET ?
BGE DE.FIN ; YES, GO FINISH UP
MOV (R1)+,(R0)+ ; MOVE THE WORD
BR DE.MOV ; AND CONTINUE
;
; RESTART THE DISPLAY, AND FIXUP THE STATUS DISPLAY
;
DE.FIN: MOV #FIRST.,@#DPC ; *** RESTART DISPLAY ***
SUB DE$SAV,DF$TOP ; RESET MEMORY POINTER
MOV #STACK,R1 ; GET UPPER MEMORY BOUND
SUB DF$TOP,R1 ; SUBTRACT LOWER BOUND
ASR R1 ; FORM WORD COUNT
FORMAT R1,ST.FRE,5 ; AND FORMAT INTO STATUS DISPLAY
DEC DU$CNT ; THERE IS ONE LESS DISPLAY
DEC DS$CNT ; AND ONE LESS DISABLED
FORMAT DU$CNT,ST.USE,2 ; FORMAT INTO STATUS DISPLAY
FORMAT DS$CNT,ST.DIS,2 ; " " " " " "
DE.RET: RESREG ; RESTORE THE REGISTERS
RETURN ; AND RETURN
.PAGE
.SBTTL RESET ROUTINE
;
; THIS ROUTINE IS USED TO RESET GIDUS BY PERFORMING
; THE FOLLOWING TASKS:
;
; [1] ALL USER DISPLAY FILES ARE DELETED
; [2] A NEW SCROLLING AREA IS LAYED OUT
; [3] THE POINTERS ARE RESET
; [4] THE APPROPRIATE DISPLAYS ARE ENABLED AND DISABLED
;
$RESET: SAVREG ; SAVE THE REGISTERS
MOV #DF$USR + 4,R1 ; R1 POINTS TO DISPLAY TABLE
MOV #54.,R2 ; R2 IS NUMBER OF USER DISPLAYS
MOV #11,R5 ; FIRST USER DISPLAY NUMBER
RE.1: BIT #EX.BIT,@R1 ; DOES THE DISPLAY EXIST ?
BEQ RE.2 ; NO, SO IGNORE IT
BIC #WP.BIT,@R1 ; YES, SO CLEAR W.P. BIT
CALL $DELET ; AND DELETE THE DISPLAY FILE
RE.2: ADD #6,R1 ; POINT TO NEXT DISPLAY
INC R5 ; GET DISPLAY NUMBER
SOB R2,RE.1 ; AND LOOP FOR ALL USER DISPLAYS
;
; LAYOUT A NEW SCROLLING AREA
;
DISABL 1 ; DISABLE CDF. FOR TIME BEING
CALL $DSTOP ; STOP THE DISPLAY
CALL $CDINI ; LAYOUT THE SCROLLING AREA
MOV CD$END,DF$TOP ; RESET LOWER CORE BOUND
MOV #FIRST.,@#DPC ; AND RESTART THE DISPLAY
;
; RESET THE POINTERS AND DISABLE THE LIGHT PEN
;
MOV #760,MP.X ; RESET THE MAIN POINTER
MOV #1320,MP.Y
FORMAT MP.X,ST.MPX,4 ; FORMAT INTO STATUS DISPLAY
FORMAT MP.Y,ST.MPY,4
MOV #1303,AP.X ; RESET THE AUX. POINTER
MOV #1320,AP.Y
FORMAT AP.X,ST.APX,4 ; FORMAT INTO STATUS DISPLAY
FORMAT AP.Y,ST.APY,4
MOV #1,LP$FLG ; DISABLE THE LIGHT PEN
CLR LP$HIT
MOV #"LD,ST.LP ; INDICATE IN STATUS DISPLAY
;
; ENABLE AND DISABLE THE APPROPRIATE GIDUS DISPLAYS
;
CMP CD$NEW,#27. ; IS THERE ROOM FOR STATUS
BGT RE.3 ; NO, SO DISABLE IT
ENABLE 2 ; YES, SO ENABLE
ENABLE 4 ; AND ENABLE THE POINTERS
ENABLE 5
BR RE.4 ; AND CONTINUE
RE.3: DISABL 2 ; DISABLE STATUS
DISABL 4 ; AND THE POINTERS
DISABL 5
RE.4: ENABLE 1 ; ENABLE CDF.
DISABL 6 ; DISABLE OPTION MESSAGE
DISABL 10 ; AND OPTION POINTER
;
; FIXUP THE STATUS DISPLAY AND TURN OFF ANY ERROR MESSAGES
;
MOV #STACK,R1 ; GET UPPER MEMORY BOUND
SUB DF$TOP,R1 ; SUBTRACT LOWER MEMORY BOUND
ASR R1 ; FORM WORD COUNT
FORMAT R1,ST.FRE,5 ; AND FORMAT INTO STATUS DISPLAY
CLR R1 ; LAST DISPLAY ADDED = 0
FORMAT R1,ST.LST,2 ; INDICATE IN STATUS DISPLAY
MOV #ME.END,ME.ON ; TURN OFF ERROR MESSAGES
RESREG ; RESTORE THE REGISTERS
RETURN ; AND RETURN
.PAGE
.SBTTL ERROR DISPLAY ROUTINE
;
; UPON ENTRY R4 POINTS TO ERROR MESSAGE
; WHICH IS AN ASCIZ STRING
;
.NLIST BEX
ER$BDN: .ASCIZ /% BAD DISPLAY FILE NUMBER/
ER$FNF: .ASCIZ /? DISPLAY FILE NOT FOUND (DISPLAY TABLE CORRUPT)/
ER$ND: .ASCIZ /% CANNOT DISABLE A NO-DISABLE DISPLAY FILE/
ER$WP: .ASCIZ /% CANNOT DELETE A WRITE PROTECTED DISPLAY FILE/
ER$ADD: .ASCIZ /? ODD ADDRESS REFERENCE ?/
ER$DDE: .ASCIZ /% DISPLAY DOES NOT EXIST/
.EVEN
.LIST BEX
;
$ERROR: SAVREG ; SAVE THE REGISTERS
MOV #ME.TXT,R0 ; R0 POINTS AT TEXT LINE
MOV #" ,R1 ; R1 USED TO BLANK OUT LINE
MOV #36.,R2 ; NUMBER OF WORDS TO ZAP
ER.1: MOV R1,(R0)+ ; BLANK IT OUT
SOB R2,ER.1
MOV #ME.TXT,R0 ; R0 POINTS AT TEXT LINE
ER.2: MOVB (R4)+,(R0)+ ; MOVE IN CHARACTERS
BNE ER.2 ; UNTIL NULL
MOV #ME.ON,R0 ; NOW TURN ON
MOV #ME.ON+2,@R0 ; THE DISPLAY
RESREG ; RESTORE THE REGISTERS
RETURN ; AND RETURN
.PAGE
.SBTTL UTILITY ROUTINES
;
$SAVRG: PUSH R1 ;
PUSH R2 ;
PUSH R3 ; SAVE ON THE STACK
PUSH R4 ;
PUSH R5 ;
MOV R0,PC ; AND RETURN
;
;
;
$RESRG: TST (SP)+ ; THROW AWAY R0
POP R5 ;
POP R4 ;
POP R3 ; POP ALL REGISTERS
POP R2 ; OFF THE STACK
POP R1 ;
RTS R0 ; RESTORE R0 AND RETURN
.PAGE
.SBTTL DISPLAY STOP ROUTINE
;
; THIS ROUTINE POLITELY STOPS THE DISPLAY
;
$DSTOP: CMP DPC,#LAS.1
BEQ DS.R9
MOV #1,ST$FNC ; STOP FUNCTION
PUSH @#PSW ; SAVE PSW
CLR @#PSW ; ALLOW THE STOP
DS.WA: TST ST$FNC ; HAVE WE STOPPED YET ?
BNE DS.WA ; NO, KEEP WAITING
POP @#PSW ; RESTORE THE OLD PSW
DS.R9: RETURN ; RETURN
.PAGE
; $FRMAT - CONVERT R0 TO OCTAL
;
; R1 POINTS TO OUTPUT AREA
; R2 CONTAINS NUMBER OF DIGITS TO CONVERT
;
$FRMAT: ADD R2,R1 ; SET UP POINTER
FR.NXT: MOV R5,R3 ; USE R3 FOR TEMP. STORAGE
BIC #177770,R3 ; CLEAR ALL EXCEPT BOTTOM DIGIT
ADD #60,R3 ; CONVERT TO ASCII
MOVB R3,-(R1) ; MOVE TO OUTPUT AREA
DEC R2 ; LOOP FOR
BLE FR.RET ; ALL DIGITS
CLC ; CLEAR CARRY BIT FOR ROTATE
BIC #7,R5 ; ZAP BOTTOM DIGIT
ROR R5 ;
ROR R5 ; GET NEXT DIGIT
ROR R5 ;
BR FR.NXT ; AND CONVERT IT
FR.RET: RETURN ; RETURN
.PAGE
.SBTTL GIDUS DISPLAY FILES
; FIRST DISPLAY FILE
;
FIRST.: STATSA ! SINOF ! ITAL0 ! LPDARK ; LOAD STATUS A, NO INTERRUPTS
; NORMAL FONT
; L.P. HITS NOT BRIGHTENED
CHAR ; CHARACTER MODE
.BYTE <SI.CH>,0 ; SHIFT IN
FI.END: DJMP,CDF.
.PAGE
; GIDUS STATUS DISPLAY FILE
;
STATS.: POINT ; SGM - POINT MODE
.WORD 0,1350 ; FIRST LINE OF SCREEN
CHAR ! BLKOFF ; SGM - CHARACTER MODE
ST.ATE: .ASCII /TI / <0> ; GIDUS STATE
ST.DL: .ASCII /CH FR=/ ; DL-11 STATE
ST.FRE: .ASCII /00000 DU=/ ; FREE CORE
ST.USE: .ASCII /12 DD=/ ; DISPLAYS IN USE
ST.DIS: .ASCII /03 LA=/ ; DISABLED DISPLAYS
ST.LST: .ASCII /00 MP=(/ ; LAST DISPLAY ADDED
ST.MPX: .ASCII /0760,/ ; MAIN POINTER X
ST.MPY: .ASCII /1320) AP=(/ ; MAIN POINTER Y
ST.APX: .ASCII /1303,/ ; AUX. POINTER X
ST.APY: .ASCII /1320) / ; AUX. POINTER Y
ST.LP: .ASCII /LD / ; L.P. STATUS
ST.TRC: .ASCII /TRACE / ; TRACE VARIABLE
.BYTE 0 ; .EVEN
ST.END: DJMP,MESAG. ; ONTO NEXT DISPLAY
ST.OLD: .WORD 0 ; OLD STATUS
.PAGE
; MESSAGE DISPLAY FILE
;
MESAG.: POINT ; SGM - POINT MODE
.WORD 0,1321 ; SECOND LINE OF DISPLAY
DJMP ; DISABLE AS A SUB-FILE
ME.ON: ME.END
CHAR ! BLKON ! INT3 ; SGM - CHARACTER MODE
.NLIST BEX
ME.TXT: .ASCII /GIDUS MESSAGE DISPLAY FILE/
.BYTE 0
.ASCII / /
.LIST BEX
ME.END: DJMP,MP. ; ONTO MAIN POINTER
.PAGE
; MAIN POINTER DISPLAY FILE
;
MP.: POINT!LPOFF!INT2!BLKOFF!LINE0 ; SGM - POINT MODE
MP.X: .WORD 760 ; X POSITION
MP.Y: .WORD 1320 ; Y POSITION
SHORTV ; SGM - SHORT VECTOR
SV 30,0 ;
SV -60,0,1 ;
SV 30,30 ; THE POINTER
SV 0,-60,1 ;
SV 5,0
CHAR ! INT2 ! LPOFF ; SGM - CHARACTER MODE
.ASCII /MP/ ; FOR MAIN POINTER
MP.END: DJMP,AP. ; ONTO AUX. POINTER DISPLAY FILE
;
;
;
;
;
;
; AUXILLARY POINTER DISPLAY FILE
;
AP.: POINT!LPOFF!INT2!BLKOFF!LINE0 ; SGM - POINT MODE
AP.X: .WORD 1303 ; X POSITION
AP.Y: .WORD 1320 ; Y POSITION
SHORTV ; SGM - RELATIVE VECTOR
SV 30,0 ;
SV -60,0,1 ;
SV 30,30 ; THE POINTER
SV 0,-60,1 ;
SV 5,0 ;
CHAR ! INT2 ! LPOFF ; SGM - CHARACTER MODE
.ASCII /AP/ ; FOR AUX. POINTER
AP.END: DJMP,LAST. ; ONTO NEXT DISPLAY FILE
.PAGE
; OPTION LIST DISPLAY FILE
;
OMSG.: POINT ! LPOFF ! BLKON ! INT3 ; OPTION MESSAGE FILE
.WORD 810., 655. ; POSITION
STATSA ! ITAL0 ; NORMAL FONT
CHAR ; CHARACTER MODE
.ASCII /SELECT OPTION/
.BYTE 0
OM.END: DJMP,0 ; A DISABLED DISPLAY FILE
.PAGE
; GIDUS COMMAND DISPLAY FILE
;
GCMND.: POINT ! LPOFF ! BLKOFF ! INT2 ; SGM - POINT MODE
.WORD 0 ; X POSITION
.WORD 1246 ; Y POSITION
CHAR ; SGM - CHARACTER MODE
STATSA ! ITAL1 ; ITALICS ON
.ASCII /GIDUS>> /
STATSA ! ITAL0 ; ITALICS OFF
GC.LNE: .ASCII / / <CR.CH> <LF.CH>
GC.ANS: .ASCII / / ; COMMAND ANSWER
DJMP ; A DISABLED SUB-DISPLAY FILE
GC.HLP: GC.END
POINT ; SGM - POINT MODE
.WORD 0 ; X POSITION
.WORD 1170 ; Y POSITION
CHAR ; SGM - CHARACTER MODE
.NLIST BEX
.ASCII /COMMANDS ARE:/ <CR.CH> <LF.CH>
.ASCII <LF.CH> /DISABLE N/ <CR.CH> <LF.CH>
.ASCII /ENABLE N/ <CR.CH> <LF.CH>
.ASCII /(LD) DISABLE LIGHT PEN/ <CR.CH> <LF.CH>
.ASCII /(LE) ENABLE LIGHT PEN/ <CR.CH> <LF.CH>
.ASCII /SPEED N/ <CR.CH> <LF.CH>
.ASCII /DELETE N/ <CR.CH> <LF.CH>
.ASCII /EXAMINE ADDR/ <CR.CH> <LF.CH>
.ASCII /MODIFY VALUE/ <CR.CH> <LF.CH>
.ASCII /TRACE ADDR/ <CR.CH> <LF.CH>
.ASCII /HELP/ <CR.CH> <LF.CH>
.ASCII /RESET NLINES/ <CR.CH> <LF.CH>
.ASCII /OFF/
.EVEN
.LIST BEX
GC.END: DJMP,0 ; A DISABLED DISPLAY FILE
;
;
; OPTION POINTER DISPLAY FILE
;
OPTR.: POINT ! LPOFF ! BLKON ! INT3
OP$X: .WORD 740. ; X POSITION
OP$Y: .WORD 0 ; Y POSITION
STATSA ! ITAL0 ; NORMAL FONT
CHAR ; CHARACTER MODE
.ASCII /==>/
.BYTE 0
OP.END: DJMP,0 ; A DISABLED DISPLAY FILE
.PAGE
; LAST DISPLAY FILE
;
LAST.: DSTOP ; STOP WITH INTERRUPT
LAS.1: DJMP,FIRST. ; RE-DISPLAY
;
;
;
;
;
;
DHALT.: STATSA!SINOF ; FULL STOP, NO INT.
;
CDF.: POINT!INT2!BLKON
CDF.X: .WORD 0,<LST.SC>
CHAR
.BYTE <CRS.CH>,0
STATSA!ITAL0
;
;
;
;
;
.END $START