1
0
mirror of https://github.com/PDP-10/its.git synced 2026-02-27 09:18:58 +00:00
Files
PDP-10.its/src/nova/displa.51
Lars Brinkhoff 44e74a7f2b Nova programs.
NOVCON .008 has an assembler error:
NOROOM+5        17011   0       1       19      TMC     4357

TMC supposedly means Too Many Constants.
2022-04-19 16:51:27 +02:00

1554 lines
26 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.
TITLE NOVA DISPLAYî
A==0 ;ACCUMULATORS
B==1
C==2
D==3
RTC==14 ;IO DEVICES
DSPL==41
PDPI==6
PDPO==7
DRANEW==3 ;CODE MODE SHIFTED RIGHT
ACK==6 ;PDP10 ERROR ACKNOWLEDGE
LEN==7000 ;DISPLAY AREA LENGTH
LLEN==2000 ;LISTS OF LISTS LENGTH
LOADER==17000 ;ADDRESS OF NOVA BLOCK LOADER (HIGHEST LEGAL ADDR +1)
DEFINE ERROR X
LDA A,[X]
JMP @CTENER
TERMIN
LOC 0
0
CINTRP: INTRP
CRESET: RESET
VERS: .FNAM2_-18.
LOC 50
TENCOM: 200 ;PDP10 COMMAND CODES -- MVTO
220 ;PTAT
260 ;PDWN
100 ;SHIP
120 ;ESHIP
140 ;DST
160 ;DREM
300 ;SHOW
320 ;HIDE
360 ;RESET
340 ;WIPE
240 ;NFRM
FDL: 0 ;BADCOM -- USE ALSO AS FAKE DISPLAY LIST
DCOM: MVTO ;COMMAND SUBROUTINES
PTAT
PDWN
SHIP
ESHIP
DST
DREM
SHOW
HIDE
RESET
CWIPE: WIPE
NFRM
CONTIN: CLOCK
CCLOCK=CONTIN
TENCT: 3 ;MVTO
10 ;PTAT
2 ;PDWN
2 ;SHIP
1 ;ESHIP
2 ;DST
2 ;DREM
1 ;SHOW
1 ;HIDE
1 ;RESET
1 ;WIPE
1 ;NFRM
1 ;BADCOM
GETWD: BLOCK 10
CFDL: FDL
CDLT: DLT
CDLB: DLB
CLDL: DLB-DLT+1
CAVAIL: AVAIL
CROV: ROV
CTOP: DLLT
CTOP2: DLLT-4
CBOT: DLLB
PO: 0
N: 0
R: DLLT-4
CBLT: BLT
CDRAW: DRAW
CDRAAD: DRAAD
CDRBM: DRBM
CFRAM: FRAM
CREM: REM
CINST: INST
COUTQ: OUTQ
CINQ: INQ
CPTBUF: PTBUF ;CPTBUF-1 MUST BE NON-0
CTENER: TENERR
CGETEN: GETEN
CSSHIP: SSHIP
CEESHI: EESHIP
CDLIM: DLIM
CTEMP: 0
CTEMP1: 0
STIME: 0
PKPTR: DLLT-4
GETCT: 0
CPX: PX
LISTAD: 0
CPQ: CPQTOP
CDISAD: CPTBUF-1
DISAD: CPTBUF-1
DRARET: 0
DRACNT: 0
DRLEN: 0
DRASV: 0
CDROUT: DROUT
CURX: 0
CURY: 0
XF: 0
YF: 0
XT: 0
YT: 0
HDFLG: 1 ;FLAGS
ERRFL: 0
GETFL: 0
SHIPFL: 0
SBMFL: 0
DBMFL: 0
XDIR: 0
YDIR: 0
;INTERRUPT--
;IF PDP-10 INTERRUPTS INSERT WORD IN 10 QUEUE
ITSVA: 0 ;ACCUMULATORS AND CARRY SAVED HERE
ITSVB: 0
ITSVC: 0
ITSVD: 0
ITSVCY: 0
INTRP: STA A,ITSVA ;SAVE ACCUMULATORS
STA B,ITSVB
STA C,ITSVC
STA D,ITSVD
MOVL D,D ;SAVE CARRY
STA D,ITSVCY
SKPDZ PDPI ;CHECK PDP-10 INPUT
JMP ITPDP
DIBC A,CPU ;CLEAR "PHANTOM INTERRUPT"
HALT ;STOP
JMP ITRES ;RESTORE WORLD
ITPDP: DIAS A,PDPI
LDA B,[ACK]
SUB A,B(SNR)
JMP ITPDP2 ;CHAR IS ERROR ACKNOWLEDGE
LDA D,ERRFL
MOV% D,D(SZR)
JMP ITRES ;WAITING FOR 10 TO ACKNOWLEDGE ERROR
LDA C,[37] ;MASK FOR ALL BUT DATA BITS
ANDZR C,A(SNC)
JMP ITPDP1
ADDZL A,A ;SHIFT LEFT 4
ADDZL A,A
STA A,PWORD
JMP ITRES
ITPDP1: LDA B,PWORD
ADD B,A
JSR @CINQ
JMP ITRES
ITPDP2: STA B,ERRFL ;RESET ERROR FLAG
JMP ITRES
PWORD: 0 ;PDP-10 WORD SAVED HERE
ITRES: LDA A,ITSVCY ;RESTORE INTERRUPTS
MOVR A,A
LDA A,ITSVA ;RESTORE ACCUMULATORS
LDA B,ITSVB
LDA C,ITSVC
LDA D,ITSVD
INTEN ;ENABLE INTERRUPTS
JMP @0 ;RETURN TO ADDRESS INTERRUPTED FROM
;RESET--
;RESTART PROGRAM
;RESET POINTERS AND VARIABLES
;WIPE OUT BUFFERS
RESET: INTDS
LDA B,CDLB
LDA C,CTOP
LDA D,[4]
SUB A,A(SKP) ;A/0 (SKIPA)
RSZDL: ADD D,C
STA A,0(C) ;ZERO DLLT THRU DLB
STA A,1(C)
SUBZ% B,C(SNC)
JMP RSZDL
LDA D,CDLT ;FIX DL
LDA C,CLDL
STA C,0(D)
STA A,1(D)
LDA C,CROV ;FIX AVAIL AND ROV
STA A,0(C)
STA A,1(C)
LDA C,CAVAIL
STA A,0(C)
STA D,1(C)
RSZCN: IRPS X,,[STIME SBMFL DBMFL SHIPFL CURX CURY
GETFL PO N 20 DRASV XDIR YDIR]
STA A,X
TERMIN
LDA C,CPX
IRPS X,,0 1 2 3 4 5
STA A,X(C)
TERMIN
LDA A,CTOP2
STA A,PKPTR
STA A,R
SUBZL A,A
STA A,HDFLG
LDA A,[2]
STA A,@CPTBUF
LDA A,CDISAD
STA A,DISAD
LDA C,CPQ
LDA A,0(C)
STA A,1(C)
STA A,2(C)
;FALLS THROUGH
;FALLS IN
RSIO: IORST ;RESET IO DEVICES
LDA A,[176777] ;MASK OUT ALL BUT PDPI (AND CPU)
MSKO A,
NIOS PDPI ;PDP10 INPUT
NIOC PDPO ;PDP10 OUTPUT
LDA D,CFDL
ADC A,A
DOB D,DSPL ;FAKE DISPLAY LIST (NULL WORD)
DOCS A,DSPL ;LENGTH=1
INTEN
JMP @CGETEN
;DISPLAY OUT--
;GET NEXT ACTIVE DISPLAY LIST FROM DISAD
;GIVE ADDRESS OF START OF DISPLAY INSTRUCTIONS
;AND LENGTH OF DISPLAY INSTRUCTIONS TO DISPLAY
DSO: SKPBZ DSPL
JMP .-1 ;DISPLAY STILL BUSY
LDA C,DISAD
MOV% C,C(SNR)
JMP DSO2 ;NOTHING TO DISPLAY
LDA D,1(C) ;ADDR OF LOAD DISPLAY LIST
LDA A,0(D) ;LOAD LENGTH OF DISPL LIST
NEG A,A
INC A,A ;-(LENGTH-1)
INC D,D ;START OF DISP INSTRUCTIONS
MOVL% A,A(SNC)
JMP DSO3
DOB D,DSPL ;ADDRESS TO B BUFFER
DOCS A,DSPL ;LENGTH TO C BUFFER
DSO2: JMP @CGETEN
DSO3: HALT ;TRAP FOR POSITIVE LENGTH
;FALLS THROUGH
;FALLS IN
;GET 10--
;TRY TO READ PDP10 CODES FROM QUEUE
;JUMP TO APPROPRIATE SUBROUTINE WHEN
;CODE IS RECOGNIZED
GETEN: LDA A,GETFL
MOV% A,A(SZR) ;READY TO READ CODE?
JMP GETEN6 ;NO
JSR @COUTQ ;TRY TO READ CODE
JMP @CCLOCK ;FAIL
STA A,GETWD ;SUCCEED
LDA C,[360] ;MASK ALL BUT CODE BITS
AND C,A
SUB C,C(SKP) ;IDENTIFY CODE (SKIPA)
GETEN1: INC C,C
LDA B,TENCOM(C)
MOV B,B(SNR) ;0=ERROR CANT IDENTIFY
JMP GETEN2
SUB% A,B(SZR)
JMP GETEN1
GETEN2: STA C,GETC ;FOUND CODE
LDA A,TENCT(C) ;NUMBER OF WORDS TO READ
STA A,GETCT
DSZ GETCT
JMP GETEN4
GETEN3: SUB B,B ;ALL WORDS READ
STA B,GETFL
LDA C,GETC
JMP @DCOM(C)
GETEN4: SUBZL C,C
GETEN5: STA C,GETC1 ;NUMBER OF WORDS READ
GETEN6: JSR @COUTQ ;TRY TO READ NEXT WORD
JMP GETEN7 ;FAIL
LDA C,GETC1
STA A,+GETWD(C)
INC C,C
LDA A,GETCT
ADCZ% A,C(SNC) ;GETC1>GETCT?
JMP GETEN5 ;NO--READ NEXT
JMP GETEN3 ;YES--ALL READ
GETEN7: SUBZL B,B
STA B,GETFL ;SET FAIL FLAG AND LEAVE
JMP @CCLOCK
GETC: 0
GETC1: 0
;MOVE TO--
;UNPACK COORDINATES, AND IF PEN IS
;DOWN, DRAW LINE AND INSERT IN LIST
;OF LISTS FOR APPROPRIATE TIME
MVTO: SUB C,C ;UNPACK XY COORDS
JSR NPK1
LDA C,[1777]
AND C,A
AND C,B
STA A,XT
STA B,YT
LDA C,SHIPFL
MOV% C,C(SZR) ;ARE WE SHIPPING?
JMP MVTO2 ;YES
LDA C,CURX
LDA D,CURY
STA A,CURX ;CHANGE CURRENT X,Y
STA B,CURY
STA C,XF
STA D,YF
LDA B,STIME
MOV% B,B(SNR) ;PENUP?
JMP MVTO1
JSR @CDRAW ;NO, DRAW LINE
LDA A,DRLEN
LDA B,CDROUT ;ADDR TO B
SUB C,C ;LISTAD SHOULD BE ZERO
STA C,LISTAD
JSR @CINST ;INSERT IN DISPLAY LIST AREA
MVTO1: JSR @CPTUP ;UPDATE POINTER
JMP @CONTIN
MVTO2: JSR @CDRAAD ;ADD TO LIST
JMP @CONTIN
CPTUP: PTUP
;UNPACK--
;UNPACK COORDINATES FROM TEN FOR MVTO & PTAT
NPK1: LDA A,GETWD(C)
LDA B,[17]
AND B,A
MOVS A,A
LDA B,GETWD+1(C)
ADD B,A
MOVZR A,A
MOVZR A,A
STA A,NPKA
LDA A,GETWD+1(C)
LDA B,[3]
AND B,A
MOVS A,A
LDA B,GETWD+2(C)
ADD A,B
LDA A,NPKA
JMP 0(D)
NPKA: 0
PX: 0
PY: 0
PXP: 0
PYP: 0
PXPP: 0
PYPP: 0
;POINTER AT--
;POINTER LOCATION NAMED BY THREE VERTICES
;UNPACK COORDINATES AND
;COMPILE DISPLAY LIST FOR POINTER
PTAT: SUB C,C ;UNPACK X,Y
JSR NPK1
STA A,PX
STA B,PY
LDA A,GETWD+3 ;UNPACK X',Y'
MOVZL A,A
MOVZL A,A
LDA C,[6]
STA C,CTEMP
LDA B,GETWD+4
MOVZR B,B
DSZ CTEMP
JMP .-2
ADD B,A
STA A,PXP
LDA A,GETWD+4
LDA C,[77]
AND C,A
LDA B,GETWD+5
LDA C,[4]
STA C,CTEMP
MOVZL A,A
MOVZR B,B
DSZ CTEMP
JMP .-3
ADD B,A
STA A,PYP
LDA C,[5] ;UNPACK X'',Y''
JSR NPK1
STA A,PXPP
STA B,PYPP
;FALLS THROUGH
;FALLS IN
PTATA: JSR @CSSHIP ;START APPENDING
LDA A,CURX ;DRAW FROM (CURX, CURY)
LDA B,CURY
STA A,XF
STA B,YF
LDA A,PXP ;TO (PXP, PYP)
LDA B,PYP
JSR ADR
LDA A,PXPP ;TO (PXPP, PYPP)
LDA B,PYPP
JSR ADR
LDA A,PX ;TO (PX, PY)
LDA B,PY
JSR ADR
LDA A,CURX ;TO (CURX, CURY)
LDA B,CURY
JSR ADR
PTAT2: JSR @CEESHI ;TERMINATE LIST
LDA A,DRLEN
LDA B,CDROUT
LDA C,CPTBUF
JSR XFER ;TRANSFER LIST FROM DROUT TO PTBUF
LDA A,CURX ;CHANGE XF AND YF TO CURRENT POS
LDA B,CURY
STA A,XF
STA B,YF
JSR PTUP1
JMP @CONTIN
ADR: STA A,XT ;(CALLED WITH JSR)
STA B,YT
JMP @CDRAAD
;POINTER UP--
;UPDATE POINTER TO (CURX, CURY)
PTUP: LDA A,CURX
LDA B,CURY
PTUP1: SUBZR C,C
ADD C,A ;POINT MODE X
LDA C,[120000]
ADD C,B ;POINT MODE Y
LDA C,CPTBUF
STA A,2(C) ;STORE AT TOP OF POINTER DISPLAY LIST
STA B,3(C)
JMP 0(D)
;TRANSFER--
;BLT LENGTH A FROM B TO C
XFER: STA D,XFERR
STA A,.+4
STA B,.+4
STA C,.+4
JSR @CBLT
0 ;LENGTH
0 ;SOURCE ADDRR
0 ;DEST ADDR
JSR @XFERR
XFERR: 0
;BLOCK TRANSFER--
;TRANFER BLOCK 0(D) OF LENGTH 1(D) TO
;2(D)
BLT: DSZ 1(D)
LDA A,1(D)
STA A,20
DSZ 2(D)
LDA A,2(D)
STA A,21
BLT1: LDA A,@20
STA A,@21
DSZ 0(D)
JMP BLT1
JMP 3(D)
;PENDOWN--
;IF TIME NAMED BY 10 IS 7777 MAKE STIME -1 (INFINITY)
;OTHERWISE MAKE STIME TIME NAMED BY PDP10
PDWN: LDA C,[17]
LDA A,GETWD
AND C,A
MOVS A,A
LDA B,GETWD+1
ADD B,A
LDA B,[7777] ;N=INFINITY?
LDA C,SHIPFL
MOV% C,C(SZR)
JMP PDWN1
SUB% A,B(SNR)
LDA A,[-1]
STA A,STIME
JMP @CONTIN
PDWN1: SUB% A,B(SZR) ;PENDOWN?
SUB C,C ;YES--(IF PDWN SBMFL=1, ELSE =0)
STA C,SBMFL
JMP @CONTIN
;HIDE--
;TURN ON HIDE FLAG
;SHOW--
;TURN OFF HIDE FLAG
SHOW: SUB A,A(SKP)
HIDE: SUBZL A,A
STA A,HDFLG
JMP @CONTIN
;DISPLAY--
;DISPLAY DISPLAY LIST NAMED BY PDP-10 STARTING AT CURRENT LOCATION
;IN CURRENT PENDOWN MODE
DST: LDA A,STIME
MOV% A,A(SNR)
JMP @CONTIN
JSR DLP ;DOES LIST WITH THAT NAME EXIST?
;YES, AC2 POINTS TO NAME (IF NO, NEVER RETURNS)
LDA D,1(C)
STA D,LISTAD
JSR @CINST ;MOVETO CURRENT DISPLAY LIST AREA
JMP @CONTIN
DSTLP: 0 ;LENGTH OF SOURCE LIST SAVE HERE
;THIS SUBROUTINE SEARCHES FOR DISPLAY LIST IN ACTIVE DISPLAY LIST
;AREA, WITH NAME THAT MATCHES NAME IN PDP-10 COMMAND
DLP: STA D,DSTLP ;SAVE RETURN ADDRESS
LDA A,GETWD+1 ;NAME OF DESIRED LIST
SUBZR B,B
ADD B,A ;STORED VERSION OF LIST NAME
LDA B,CBOT ;ADDRESS OF BOTTOM OF DISPLAY LIST BUFFER
LDA C,CTOP ;ADDRESS OF FRAME TIME OR LIST NAME
DLP1: LDA D,0(C) ;TIME OR NAME
SUB% A,D(SNR) ;IS NAME DESIRED ONE?
JMP @DSTLP ;YES, RETURN TO CALLING ROUTINE
LDA D,[4] ;CHECK NEXT LIST
ADD D,C
ADCZ% B,C(SZC) ;HAVE ALL LISTS BEEN CHECKED?
JMP @CONTIN ;YES, IGNORE PDP-10 INSTRUCTION
JMP DLP1 ;NO, CONTINUE SEARCH
;DISPLAY REMOVE--
;REMOVE LIST SHIPPED FROM 10 FROM ACTIVE AREA
;REMOVE ALL REFERENCES TO LIST
DREM: JSR DLP ;SEARCH FOR LIST WITH SAME NAME
;SUCCESS, AC2 IS ADDRESS OF NAME
SUB A,A ;0
STA A,0(C) ;MAKE FRAMES ZERO
LDA D,1(C) ;ADDRESS OF DISPLAY LIST
STA D,PO
STA D,LISTAD
LDA B,0(D)
STA B,N
STA A,1(C) ;ZERO ADDRESS
JSR @CREM ;REMOVES DISPLAY LIST
LDA C,CTOP ;REMOVE ALL REFERENCES TO THIS LIST
LDA B,CBOT
LDA A,LISTAD
DREM3: LDA D,1(C)
SUB% A,D(SZR)
JMP DREM4
SUB D,D
STA D,0(C)
STA D,1(C)
STA D,2(C)
STA D,3(C)
DREM4: LDA D,[4]
ADD D,C
ADCZ% B,C(SZC)
JMP @CONTIN
JMP DREM3
;SHIP--
;GET DISPLAY LIST INSTRUCTIONS FROM PDP10
;TURN ON SHIP FLAG
;SAVE NAME OF LIST, INITIALIZE DRAW PARAMETERS
SHIP: JSR @CSSHIP ;INITIALIZE DRAAD
LDA A,GETWD+1
STA A,LISTN ;NAME OF LIST
LDA A,CURX ;FIX TEMP X AND Y COORDS
LDA B,CURY
STA A,XF
STA B,YF
JMP @CONTIN ;CONTINUE
LISTN: 0
SSHIP: SUBZL A,A
STA A,SHIPFL ;SHIPFL=1
STA A,SBMFL
SUB A,A
STA A,DBMFL ;DBMFL=0
STA A,XDIR
STA A,YDIR
LDA B,CDROUT
STA B,20 ;AUTO-INC
STA A,@20 ;SPACE FOR NULL,X,Y
STA A,@20
STA A,@20
LDA A,[DRANEW] ;CODE MODE
STA A,DRASV ;MAKE DRAW THINK THIS IS LAST WORD COMPILED
JMP 0(D)
;END SHIP--
;TURN OFF SHIP FLAG, STORE COMPILED LIST
;(COMPLEMENT BEAM IF NECESSARY TO LEAVE OFF)
ESHIP: LDA A,SHIPFL
MOV% A,A(SNR)
JMP @CONTIN ;IGNORE IF NOT SHIPPING
JSR @CEESHI ;FINISH UP LIST
ESHIP1: LDA A,DRLEN ;LENGTH TO A
LDA B,CDROUT ;ADDRESS TO B
LDA C,LISTN ;NAME
LDA D,STIME
STA D,LISTN ;SAVE STIME IN LISTN
SUBZR D,D
ADD D,C ;STORED FORM OF NAME
STA C,STIME ;LIST NAME IN STIME
SUB C,C ;BE SURE LISTAD IS ZERO
STA C,LISTAD
JSR @CINST ;INSERT IN DL
LDA A,LISTN
STA A,STIME ;RESTORE CURRENT TIME
JMP @CONTIN
EESHIP: SUB A,A
STA A,SHIPFL
LDA A,DRASV ;LAST WORD COMPILED
STA D,DRARET ;DRAW RETURN ADDRESS
LDA C,DBMFL ;CURRENT STATE OF BEAM
MOV% C,C(SNR) ;COMPLEMENT BEAM?
JMP @ENCOMP ;NO
JMP @ECOMP ;YES
ENCOMP: DRATR0 ;JUMP HERE IF BEAM ALREADY OFF
ECOMP: DRATRA ;JUMP HERE TO COMPLEMENT BEAM
;WIPE--
;REMOVES ALL DISPLAY LISTS
;WITH POSITIVE OR INFINITE (-1) TIME LEFT
WIPE: LDA C,CTOP2
LDA B,CBOT
SUB A,A
WIPE1: LDA A,[4]
ADD A,C
ADCZ% B,C(SZC) ;ARE WE AT BOTTOM OF LIST OF LISTS?
JMP @CONTIN ;YES
LDA A,0(C) ;NO,GET TIME
MOV% A,A(SNR)
JMP WIPE1
INCZL% A,A(SEZ) ;IS TIME -1 OR POSITIVE?
JMP WIPE1 ;NO,GET NEXT LIST
SUB A,A ;YES, WIPE OUT
STA A,0(C) ;MAKE TIME ZERO
LDA D,3(C) ;CHECK TO SEE IF THIS IS A REFERENCE
MOV% D,D(SNR)
JMP WIPE2
STA A,1(C) ;ZERO OUT REFERENCE
STA A,2(C)
STA A,3(C)
JMP WIPE1
WIPE2: LDA D,1(C)
STA D,PO ;ARG FOR REM
LDA B,0(D)
STA B,N
STA C,WPTR ;SAVE POINTER
STA A,1(C) ;ZERO ADDRESS
JSR @CREM ;REMOVE LIST
LDA B,CBOT ;RESTORE CBOT
LDA C,WPTR ;RESTORE POINTER
JMP WIPE1
WPTR: 0
;NEWFRAME--DECREMENT FRAME TIMES AND UPDATE DISPLAY LISTS
NFRM: JSR @CFRAM
JMP @CONTIN
;CLOCK--
;FIND NEXT ACTIVE LIST ANDJUMP TO DSO
CLOCK: LDA A,CTOP2
LDA B,CBOT ;CHECK FOR PKPTR
LDA C,PKPTR
JSR @CDLIM
JSR DPICK
SUB A,A ;FAILî
STA A,DISAD ;SUCCEED
LDA A,CTOP2
LDA B,CBOT ;CHECK FOR PKPTR
LDA C,PKPTR
JSR @CDLIM
JMP @CPKR
CPKR: DSO
;DPICK--
;PICK NEXT ACTIVE DISPLAY LIST
DPICK: SUB A,A ;CLEAR FLAGS
STA A,DPFLG
DPICK1: LDA A,PKPTR
LDA B,[4]
ADD B,A
STA A,PKPTR
LDA B,CBOT
SUBZ% B,A(SNC) ;A>=B?
JMP DPICK2 ;NO
LDA A,CTOP2
STA A,PKPTR
LDA B,DPFLG ;FLAG ON?
MOV% B,B(SZR)
JMP 0(D) ;YES
SUBZL B,B ;SET FLAG
STA B,DPFLG
LDA B,HDFLG ;DISPLAY POINTER?
MOV% B,B(SZR)
JMP DPICK1 ;NO
LDA A,CDISAD ;SUCCEED
JMP 1(D)
DPICK2: MOV A,C
LDA B,0(C)
MOV% B,B(SNR)
JMP DPICK1
INCL% B,B(SZC)
JMP DPICK1 ;NOT A DISPLAY LIST
LDA B,2(C)
MOV% B,B(SNR)
JMP 1(D)
STA D,DPFLG ;SET UP REFERENCE
LDA D,1(C)
STA B,2(D)
LDA B,3(C)
STA B,3(D)
LDA D,DPFLG
JMP 1(D) ;RETURN TO SUCCESS
DPFLG: 0
;INSERT--
;INSERT BLOCK IN DISPLAY LIST
;THIS SUBROUTINE LOOKS FOR
;EMPTY BLOCKS IN DISPLAY LIST AREA
;WHICH ARE LARGE ENOUGH TO ACCOMODATE
;DISPLAY LIST.
;CALLED WITH THE DISPLAY LIST
;LENGTH IN INLEN, AND THE ADDRESS IN
;INADR
INST: STA D,INRET
STA A,INLEN ;A CONTAINS LENGTH
STA B,INADR ;B CONTAINS ADDRESS
SUB B,B ;SWITCH OFF
LDA D,CBOT ;ADDR OF FINAL PSTN
LDA C,R ;PREVIOUS INSERTION
;CHECK LIST OF DISPLAY LISTS (CTOP-CBOT)
;FOR SOME SPOT WE CAN INSERT THE ADDRESS
;AND TIME OF THE CURRENT LIST
INST0: LDA A,[4] ;FIND NEXT POSITION
ADD A,C
ADCZ% C,D(SZC) ;IS THIS FINAL PSTN IN LIST OF DISPLAY LISTS?
JMP INST1 ;NO, SEE IF WE CAN INSERT INFORMATION HERE
MOV% B,B(SNR) ;YES--SWITCH ON?
;HAVE WE BEEEN THROUGH LIST OF LISTS ONCE ALREADY?
JMP INST2 ;NO, SET SWITCH
ERROR 1 ;TOO MANY LISTS!!!
INST1: LDA A,0(C) ;FRAME TIME
MOV% A,A(SNR) ;IS IT ZERO?
JMP INST3 ;YES, USE THIS LOCATION
JMP INST0 ;NO, FIND NEXT POSITION
INST2: INC B,B ;SET SWITCH
LDA C,CTOP ;MOVE BACK TO TOP OF LIST OF LISTS
JMP INST1
;INSERT TIME AND LENGTH IN PROPER
;SPOT IN LIST OF DISPLAY LISTS
;ACC C CONTAINS ADDRESS WHERE TIME
;WILL BE INSERTED
;FIRST, FIND SECOND FREE BLOCK
INST3: STA C,R
LDA A,LISTAD
MOV% A,A(SNR)
JMP INST3A
LDA B,CURX ;CREATE REFERENCE
SUBZR A,A
ADD A,B
STA B,2(C) ;X COORDINATE
MOVZR A,A
MOVOR A,A
LDA B,CURY
ADD A,B
STA B,3(C) ;Y-COORDINATE
LDA B,STIME
STA B,0(C)
LDA B,LISTAD
STA B,1(C) ;ADDRESS REFERENCE
JMP @INRET
INST3A: LDA D,CROV ;ADDR OF ROVING POINTER TO DISPLAY LIST AREA
SUB B,B ;PUT SWITCH OFF (SWITCH WILL NOW BE USED
STA B,INSTS ;TO CHECK HOW MANY TIMES WE HAVE GONE
;OVER DISPLAY LIST AREA)
;IN DISPLAY AREA, ROV IS POINTER TO
;FIRST FREE BLOCK. THE FIRST ADDRESS
;IN EACH BLOCK CONTAINS THE LENGTH OF THE
;BLOCK, THE SECOND ADDRESS POINTS TO THE
;NEXT FREE BLOCK. THE SECOND ADDRESS
;OF THE LAST FREE BLOCK CONTAINS ZERO.
;FALLS THROUGH
INST4: LDA C,1(D) ;ADDR OF NEXT FREE BLOCK
MOV% C,C(SZR) ;END OF DISPLAY AREA?
JMP INST5 ;NO, SEE IF BLOCK IS THE RIGHT LENGTH
LDA B,INSTS
MOV% B,B(SNR) ;YES--SWITCH ALREADY ON?
;HAVE WE BEEEN THROUGH DISPLAY AREA ONCE ALREADY?
JMP INST4A ;NO, PUT SWITCH ON
ERROR 2 ;DISPLAY AREA FULL!!!
;PUT SWITCH ON, GO BACK TO TOP OF DSPL LIST AREA
INST4A: ISZ INSTS ;SWITCH ON
LDA D,CAVAIL ;PTR TO TOP OF LIST AREA
JMP INST4
;FREE BLOCK FOUND
;FIRST, SEE IF IT IS LONG ENOUGH TO ACCOMODATE
;DISPLAY LIST. THEN SEE IF IT IS ONE LONGER THAN DISPLAY LIST.
;IF SO DO NOT USE. IF IT EXACTLY EQUALS
;DISPLAY LIST, FIX POINTER TO NEXT FREE BLOCK (EXCEPT
;IF IT IS FIRST BLOCK.
;IS THIS LEGAL LOCATION?
INST5: STA D,INDST ;(DLB>LEGAL LOCS>DLT)
LDA A,CDLT
LDA B,CDLB
JSR @CDLIM
LDA D,INDST
LDA A,0(C) ;LENGTH OF FREE BLOCK
LDA B,INLEN ;LENGTH TO BE INSERTED
SUBZ B,A(SZC) ;A<B? BLOCK TOO SMALL?
JMP INST6 ;NO, SEE IF ONLY ONE LOCATION LEFT.
INST5A: MOV C,D ;YES--CHECK NEXT FREE BLOCK
JMP INST4
INST6: MOV A,B ;REMAINING LOCATIONS
SUBZL A,A ;ONE IN A
SUB% B,A(SNR) ;ONLY ONE LOCATION LEFT?
JMP INST5A ;YES--DONT USE THIS BLOCK
MOV% B,B(SZR) ;AREA EXACTLY FILLED?
JMP INST7 ;NO, FIX ROV+1 AND TRANSFER LIST TO BLOCK
LDA A,AVAIL+1 ;YES
SUB% A,C(SNR) ;FIRST BLOCK?
JMP INST5A ;YES, DON'T OBLITERATE IT
LDA A,1(C) ;NO--CHANGE POINTERS
STA A,1(D)
;FALLS THROUGH
;FIX POINTER TO LAST BLOCK FILLED
;DO BLOCK TRANSFER OF LIST TO LIST AREA, AND RETURN TO
;CALLING ROUTINE
INST7: LDA A,1(D) ;ROVING PTR PTS TO PREVIOUS BLOCK
STA B,0(C) ;FREE STORAGE LEFT IN BLOCK
STA A,ROV+1 ;PNTR TO PREVIOUS BLOCK
ADD B,C
LDA D,R ;DLIST PTR PTS TO RESERVED BLOCK
STA C,1(D)
LDA B,STIME ;SET FRAME TIME
STA B,0(D)
STA C,INDST
SUB A,A
STA A,2(D)
STA A,3(D)
JSR @CBLT ;DO BLOCK TRANSFER OF DISPLAY LIST
INLEN: 0 ;ARGS FOR BLT--LENGTH
INADR: 0 ;SOURCE BLOCK
INDST: 0 ;DEST BLOCK
JMP @INRET ;BLT RETURNS HERE
INRET: 0
INSTS: 0
AVAIL: 0
DLT
ROV: 0
0
;TEN ERROR--
;SENDS ERROR MESSAGES TO TEN
;CALLED WITH CODE IN ACC A
TENERR: LDA B,[100] ;TURN ON HIGH ORDER BIT TO AVOID MESSING UP ITS
ADD B,A ;ADD TO ERROR MESSAGE
SKPBZ PDPO ;WAIT TILL PDP OUT NOT BUSY
JMP .-1
DOAS A,PDPO ;SEND ERROR CODE TO PDP10
SUB A,A
STA A,SHIPFL ;FIX THIS IN CASE
STA A,GETFL
SUBZL A,A ;SET ERROR FLAG
STA A,ERRFL
LDA C,CPQ ;IGNORE REST OF QUEUE
LDA B,0(C)
STA B,1(C)
STA B,2(C)
LDA A,STIME
INCL% A,A(SNC) ;SEE IF THIS HAS BEEN MESSED UP BY SHIP
JMP @CONTIN ;SNAP NAME HAS HIGH BIT ON AND IS NOT -1
LDA A,@CLISTN ;YES, RESTORE
STA A,STIME
JMP @CONTIN
CLISTN: LISTN
;ERRORS--
;1-TOO MANY LISTS
;2-LISTS TOO LONG
;3-LIST BEING "SHIPPED" TOO LONG
;4-MORE OF THE SAME
;FRAME--
;DECREMENT FRAME TIME OF ALL ACTIVE LISTS
;NOT INFINITELY DISPLAYED
FRAM: STA D,FRAMR ;DECREMENT FRAME TIMES
LDA C,CTOP ;ADDR OF DSPLL
FRAM1: LDA A,0(C) ;NEXT FRAME TIME
MOV% A,A(SNR) ;ZERO?
JMP FRAM2 ;YES
MOVL% A,A(SZC) ;NO--NEGATIVE?
JMP FRAM2 ;YES
DSZ 0(C) ;DECREMENT
JMP FRAM2
LDA A,2(C)
MOV% A,A(SZR)
JMP FRAM1B ;THIS IS A REFERENCE
FRAM1A: LDA D,1(C) ;REMOVE FROM DSPL IF ZERO
STA D,PO ;ADDR OF BLOCK TO BE REMOVED
STA C,CTEMP ;SAVE POSITION IN DSPLL
LDA A,0(D) ;LENGTH OF BLOCK
STA A,N
JSR REM
LDA C,CTEMP
FRAM1B: SUB A,A
STA A,1(C) ;CLEAR OUT ADDRESS
STA A,2(C)
STA A,3(C)
FRAM2: LDA B,[4]
ADD B,C
LDA B,CBOT
SUBZ% B,C(SZC) ;C<=CBOT?
JMP @FRAMR ;NO--RETURN
JMP FRAM1 ;YES TEST NEXT
FRAMR: 0
;REMOVE--
;REMOVE LIST FROM DISPLAY LIST AREA
;AND RESET POINTERS
REM: STA D,REMRET
LDA A,CDLT
LDA B,CDLB
LDA C,PO
JSR @CDLIM
LDA A,PO
LDA C,CAVAIL ;ADDR OF AVAIL
REM2: LDA D,1(C) ;ARRD OF NEXT FREE BLOCK
MOV% D,D(SNR) ;NULL?
JMP REM4
SUBZ% D,A(SNC) ;ARE WE PAST BLOCK TO BE DELETED?
JMP REM3
MOV D,C ;NO--CHUG DOWN LIST
JMP REM2
REM3: STA C,CTEMP1
LDA B,N ;LENGTH OF BLOCK
ADD B,A
SUB% D,A(SZR) ;CHECK UPPER BOUND
JMP REM4
LDA A,ROV+1 ;ARE WE INCREASING LENGTH OF FREE BLOCK ON TOP?
SUB% A,D(SZR)
JMP REM3A ;NO
SUB A,A ;YES
STA A,ROV+1 ;RE-INITIALIZE POINTER
REM3A: LDA A,0(D) ;N_N+LENGTH OF NEXT BLOCK
ADD A,B
STA B,N
LDA D,1(D) ;PTR TO NEXT FREE BLOCK
LDA C,PO ;STORE IN 2ND WD OF FREED BLOCK
STA D,1(C)
JMP REM5
REM4: STA C,CTEMP1
LDA C,PO ;FIX PTR
STA D,1(C)
REM5: LDA C,CTEMP1
LDA D,0(C) ;CHECK LOWER BOUND
LDA B,PO
ADD C,D
SUB% B,D(SZR)
JMP REM6
LDA A,N
LDA D,0(C)
ADD D,A
MOV B,D
STA A,0(C)
LDA A,1(D)
STA A,1(C)
JMP @REMRET
REM6: MOV B,D
STA B,1(C)
LDA A,N
STA A,0(D)
JMP @REMRET
REMRET: 0
;DRAW--
;COMPILE LIST CONSISTING OF STRAIGHT
;LINE FROM XF,YF TO XT,YT
;LIST STARTS AT DROUT, WHICH CONTAINS LENGTH
DRAAD: STA D,DRARET ;CALL HERE TO APPEND LIST
LDA A,DRASV ;GET LAST LIST WORD
LDA B,SBMFL ;WAY BEAM SHOULD BE
LDA C,DBMFL ;WAY BEAM IS
SUB% B,C(SZR) ;COMPLEMENT BEAM?
JSR @CDRBM ;YES
STA B,DBMFL
LDA D,XF
LDA C,YF
JMP DRAW1
DRAW: STA D,DRARET ;STORE RETURN ADDRESS IN PAGE 0
LDA D,CDROUT ;SET UP SELF-INCREMENTING COUNTER
STA D,20
LDA B,[1777]
SUB A,A ;OUTPUT NULL CHARACTER
STA A,@20
STA A,XDIR
STA A,YDIR
LDA D,XF ;XCOORDINATE INSTRUCTION
AND B,D
SUBZR A,A
ADD D,A
STA A,@20
LDA C,YF ;YCOORDINATE INSTRUCTION
AND B,C
LDA A,[120000]
ADD C,A
STA A,@20
LDA A,[DRANEW] ;CODE MODE
MOV D,B
JSR @CDRBM
MOV B,D
;FALLS THROUGH
;FALLS IN
DRAW1: LDA B,XT
MOVL% B,B(SZC) ;SEE IF XT IS NEGATIVE
JMP @CDRAX ;YES
SUBZ D,B(SZC) ;NO,IS .DX NEGATIVE?
JMP DRAW1A ;NO
NEG B,B ;YES
JMP @CDRAX1
DRAW1A: LDA D,XDIR ;GET X DEFLECTION
MOV% D,D(SZR)
JMP @CDRAX2 ;COMPLEMENTED, RESTORE
DRAW2: LDA D,YT ;SAME FOR .DY
MOVL% D,D(SZC)
JMP @CDRAY ;YT IS NEGATIVE
NEGZ C,C
ADD D,C(SNC) ;IS .DY NEGATIVE?
JMP @CDRAY1 ;YES
LDA D,YDIR ;GET Y DEFLECTION
MOV% D,D(SZR)
JMP @CDRAY2 ;COMPLEMENTED, RESTORE
JMP DRAW2A
CDRAX: DRARX
CDRAX1: DRARX1
CDRAX2: DRARX2
CDRAY: DRARY
CDRAY1: DRARY1
CDRAY2: DRARY2
;DX IN B, DY IN C
DRAW2A: MOVZR B,B ;DIVIDE DX AND DY BY 2
MOVZR C,C
ADD% B,C(SNR) ;SEE IF BOTH DX AND DY ARE 0
JMP DRATR
LDA D,SHIPFL
MOV% D,D(SNR) ;SKIP FOLLOWING GOOK IF NOT SHIPPING
JMP DRAW3
STA A,DRASV ;SAVE A
LDA A,XDIR ;MAKE NEW XF 2*((XF/2)+(DX/2))
LDA D,XF ;THIS ROUTINE TO MAKE NOVA THINK
MOVZR D,D ;IT IS WHERE IT IS!!
MOV% A,A(SNR)
ADDZL B,D(SKP) ;DX>0 ADD DX TO XF
SUBZL B,D
STA D,XF
LDA A,YDIR ;SAME FOR YF
LDA D,YF
MOVZR D,D
MOV% A,A(SNR)
ADDZL C,D(SKP)
SUBZL C,D
STA D,YF
LDA A,DRASV ;RECLAIM
;FALLS THROUGH
DRAW3: SUBZ% B,C(SZC) ;CALCULATE DY-DX
JMP DRAHZY ;DY .GE. DX
MOV B,D ;DX>DY, B>D
MOV C,B ;PUT DX=S IN ACC D, DY=R IN ACC B
LDA C,DRAZ ;MAKE HRZ INSTRUCTION COUNT X
STA C,DRAHRZ
LDA C,DRAO
JMP DRAW4
DRAHZY: MOV C,D
LDA C,DRAO ;DY=S IN ACC D, DX=R IN ACC B
STA C,DRAHRZ ;MAKE HRZ INSTRUCTION COUNT Y
LDA C,DRAZ
DRAW4: STA C,DRAHRZ+1
STA D,DRACNT ;SET UP COUNTER
LDA C,SHIPFL
MOV% C,C(SNR) ;SHIPPING?
JMP DRAW5 ;NO
STA A,DRASV
MOV B,D ;SAVE B
LDA B,DRACNT
SUB A,A
LDA C,[7]
DIV ;C/(A_16 +B)=B REM A
LDA A,20
ADD A,B
INC B,B
INC B,B ;HIGHEST POSSIBLE ADDRESS
LDA A,[LOADER] ;ADDRES OF LOADER
SUBZ% A,B(SZC) ;LIST TOO LONG?
JMP DRAW6 ;YES
MOV D,B ;NO, RESTORE B
LDA A,DRASV ;RECLAIM LAST INSTRUCTION OF LAST LIST
LDA D,DRACNT ;D
DRAW5: MOV B,C ;R IN ACC C
JMP DRALP1 ;ENTER BASIC ASSEMBLING LOOP
DRAW6: ERROR 3 ;LIST TOO LONG!!!
DRAT: 0 ;TEMP STORAGE
DRALP: ADD C,B ;BASIC ASSEMBLING LOOP
MOVL% A,A(SNC) ;SEE IF PACKED WORD IS FULL
JMP DRALP1 ;WORD NOT FULL
STA A,@20 ;STORE OLD WORD
LDA A,20
STA B,DRAT
LDA B,[LOADER]
SUBZ% B,A(SNC)
JMP DRALP0
ERROR 4
DRALP0: LDA B,CDROUT ;SEE THAT STUFF IS >DROUT
SUBZ% A,B(SZC)
HALT
LDA B,DRAT
LDA A,[DRANEW] ;START NEW WORD
DRALP1: STA B,DRAT ;SAVE DR, ORIGINAL ENTRY TO LOOP
MOVZL B,B(SZC) ;2*DR
JMP DRAHRZ ;DR IS NEGATIVE
ADCZ% D,B(SNC) ;2*DR-S
JMP DRAHRZ ;2*DR.LE.S
MOVOL A,A ;2*DR>S
MOVOL A,A ;DIAGONAL INSTRUCTION
LDA B,DRAT ;RESTORE DR
SUB D,B ;DR-S
JMP DRALP2
DRAHRZ: 0 ;HRZ INSTRUCTION FROM DRASO GOES HERE
0 ;AND HERE
LDA B,DRAT ;RESTORE DR
DRALP2: DSZ DRACNT ;SEE IF MORE INSTRUCTIONS ARE LEFT
JMP DRALP
;FALLS THROUGH
;FALLS IN
DRATR: LDA C,SHIPFL
MOV% C,C(SZR) ;SHIPPING?
JMP DRATR2 ;YES
DRATRA: JSR DRBM ;BEAM OFF
DRATR0: LDA B,[DRANEW]
SUB% A,B(SNR) ;IS WORD ONLY CODE MODE?
JMP DRATR1
JSR DRALJ ;NO, LEFT JUSTIFY & STORE
DRATR1: LDA B,20 ;CALCULATE LENGTH OF ASSEMBLED PROGRAM
LDA A,CDROUT
SUB A,B
INC B,B
STA B,@CDROUT
STA B,DRLEN ;SAVE LENGTH
JMP @DRARET ;RETURN TO CALLING PROGRAM
DRATR2: JSR DRAFU ;IS WORD FULL?
STA A,DRASV ;SAVE CURRENT WORD
JMP @DRARET ;RETURN
DRARX: NEG B,B
ADD D,B
DRARX1: LDA D,XDIR
MOV% D,D(SZR)
JMP @DRAXR ;ALREADY COMPLEMENTED
DRARX2: JSR DRA4S ;MAKE ROOM FOR 4 BITS
ADDZL A,A ;COMPLEMENT X DEFLECTION COUNTER
MOVZL A,A
MOVOL A,A
LDA D,XDIR
COM D,D
STA D,XDIR
JSR DRAFU ;WORD FULL?
JMP @DRAXR
DRAXR: DRAW2
DRARY: SUB D,C(SKP) ;YT<0, SKIP NEXT INSTRUCTION
DRARY1: NEG C,C
LDA D,YDIR
MOV% D,D(SZR)
JMP @DRARYR ;Y DEFLECTION ALREADY COMPLEMENTED
DRARY2: JSR DRA4S ;MAKE ROOM FOR 4 BITS
ADDZL A,A ;COMPLEMENT Y DEFLECTION COUNTER
DRAO: MOVOL A,A ;INSTRUCTIONS GO TO DRAHRZ FROM HERE
DRAZ: MOVZL A,A ;AND HERE
LDA D,YDIR
COM D,D
STA D,YDIR
JSR DRAFU ;WORD FULL?
JMP @DRARYR
DRARYR: DRAW2A
DRBM: STA D,DRBMR
JSR DRA4S ;SPACE FOR 4 BITS?
ADDZL A,A ;CHANGE BEAM
MOVOL A,A
MOVOL A,A
JSR DRAFU ;WORD FULL?
JMP @DRBMR
DRBMR: 0
DRA4S: STA D,DRALJR ;SEE IF ROOM FOR 4 BITS
LDA D,[17_12.]
AND% D,A(SNR)
JMP @DRALJR ;YES, RETURN
JMP DRALJ1
DRALJ: STA D,DRALJR ;LEFT JUSTIFY
DRALJ1: MOVZL A,A(SNC)
JMP DRALJ1
MOVR A,A
STA A,@20
LDA A,[DRANEW]
JMP @DRALJR
DRALJR: 0
DRAFU: MOVL% A,A(SNC) ;WORD FULL?
JMP 0(D) ;NO
STA A,@20 ;YES, STORE
LDA A,[DRANEW] ;START NEW WORD
JMP 0(D)
;IN QUEUE--
;INSERT 8 BIT WORD INTO PDP10 QUEUE
INQ: LDA C,RPQ ;INSERT IN PDP-10 QUEUE
LDA B,CPQBOT
SUBZ% B,C(SNC) ;IF AT BOTTOM
JMP INQ1
LDA C,CPQTOP ;MOVE TO TOP
JMP .+2
INQ1: INC C,C
LDA B,FPQ
SUB% B,C(SNR)
JMP INQ2 ;QUEUE OVERFLOW
STA A,0(C)
STA C,RPQ
JMP 0(D)
INQ2: HALT
JMP @CRESET
;OUT QUEUE--
;TAKE 8 BIT WORD FROM PDP10 QUEUE TO
;ACC A
OUTQ: INTDS
LDA C,FPQ
LDA B,RPQ
SUB% B,C(SNR) ;IF FRONT = REAR Q EMPTY
JMP OUTQ2+1
SUBZ% B,C(SNC)
JMP OUTQ1
LDA C,CPQTOP
JMP .+2
OUTQ1: INC C,C
LDA A,0(C)
STA C,FPQ
OUTQ2: INC D,D
INTEN
JMP 0(D)
CPQBOT: PQBOT
CPQTOP: PQTOP
RPQ: PQTOP
FPQ: PQTOP
;DELIMIT--
;SUBROUTINE CHECKS THAT
;C IS WITHING LEGAL BOUNDS
DLIM: ADCZ% C,A(SZC) ;IS C<A?
HALT ;YES
ADCZ% B,C(SZC) ;B<C?
HALT ;YES
JMP 0(D)
;IF THIS HALTS:
;A/ LOWEST LEGAL ADDRESS
;B/ HIGHEST LEGAL ADDRESS
;C/ ADDRESS TESTED
;D/ ADDRESS CALLED FROM +1
;BLOCK AND BUFFERS--
;PDP10 QUEUE
PQTOP: LOC .+20
PQBOT: 0
;LIST OF LISTS
DLLT: LOC .+LLEN-1
DLLB: 0
;DISPLAY LIST AREA
DLT: LEN
LOC .+LEN-2
DLB: 0
;POINTER AREA
PTBUF: 2
LOC .+300
;DRAW BUFFER
DROUT: 0
LOC 22
CONSTA
END 0