Trailing-Edge
-
PDP-10 Archives
-
decuslib10-06
-
43,50434/book.004
There are no other files named book.004 in the archive.
;PICTURE BOOK, A GRAPHICS SYSTEM FOR THE GT40
;PICTURE BOOK RESPONDS TO TELETYPE I/O IT RECEIVES FROM A HOST
;COMPUTER BY DISPLAYING THE I/O SIMILARLY TO THE WAY A VT05
;DISPLAYS
;IT ALSO RESPONDS TO GRAPHIC COMMANDS SENT IN CODE
;EITHER BY FORTRAN SUBROUTINES RUNNING IN THE HOST MACHINE
;OR DIRECTLY FROM THE HOST MACHINE'S ASSEMBLY LANGUAGE
;
; DEC-11-GPBAA-B-LA
;
; COPYRIGHT (C) 1974
; DIGITAL EQUIPMENT CORPORATION
; MAYNARD, MASSACHUSETTS 01754
; THE INFORMATION IN THIS SOURCE LISTING IS SUBJECT TO
; CHANGE WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED AS A
; COMMITTMENT BY DIGITAL EQUIPMENT CORPORATION.
; DIGITAL EQUIPTMENT CORPORATION ASSUMES NO RESPONSIBILITY
; FOR ANY ERRORS THAT MAY APPEAR IN THIS LISTING.
; THIS SOFTWARE IS FURNISHED TO THE PURCHASER
; UNDER A LICENSE FOR USE ON A SINGLE COMPUTER
; SYSTEM AND CAN BE COPIED (WITH INCLUSION OF DIGITAL'S
; COPYRIGHT NOTICE) ONLY FOR USE IN SUCH SYSTEM, EXCEPT AS
; MAY OTHERWISE BE PROVIDED IN WRITING BY DIGITAL.
; DIGITAL EQUIPMENT CORPORATION ASSUMES NO RESPONSIBILITY
; FOR THE USE OR RELIABILITY OF ITS SOFTWARE ON EQUIPMENT
; THAT IS NOT SUPPLIED BY DIGITAL.
;
;
;
;R. FRIEDENTHAL
;EDIT 2, 4/25/73
;EDIT 3, 10/12/73 D. VELTEN
;EDIT 4, 26/7/74 R. GORDON, GENERAL ELECTRIC CO., BURLINGTON, VT.
.ENABL AMA
.LIST ME
.ENABL ABS
.=0 ;RESTART ADDRESS: 0
JMP START
R0=%0
R1=%1
R2=%2
R3=%3
R4=%4
R5=%5
R6=%6
R7=%7
TEMP=R0
ARG1=R1
ARG2=R2
INPTR=R3 ;POINTS TO NEXT BYTE IN VT05
CHAR=R4 ;HOLDS INPUT CHARACTER
SSP=R5 ;SUBPICTURE STACK POINTER
SP=R6 ;STACK POINTER
PC=R7 ;PROGRAM COUNTER
;DEVICE ADDRESSES
TENIN=175610 ;TEN INPUT
TENOUT=175614 ;TEN OUTPUT
CLKOUT=177546 ;CLOCK ADDRESS
KEYIN=177560 ;KEYBOARD OUTPUT
GTPC=172000 ;GT PROGRAM COUNTER
GTSTAT=GTPC+2 ;GT STATUS WORD
GTX=GTSTAT+2 ;GT X COORDINATE
GTY=GTX+2 ;GT Y COORDINATE
STATUS=177776 ;PDP-11 STATUS REGISTER
;VECTORS
TENVEC=300 ;TEN INPUT VECTOR
STPVEC=320 ;DSTOP
LPVEC=STPVEC+4 ;LITE PEN
TIMVEC=LPVEC+4 ;TIME-OUT
KEYVEC=60 ;KEYBOARD
CLKVEC=100 ;CLOCK
;GT INSTRUCTIONS
DSTP=173400 ;STOP
DNOP=164000 ;NOP
DJMP=160000 ;DISPLAY JUMP
DVEC=110000 ;LONG VECTOR
DPT=114000 ;ABSOLUTE POINT
DCHR=100000 ;CHARACTER
DRELP=130000 ;RELATIVE POINT
DRELV=104000 ;SHORT VECTOR
DGRAX=120000 ;X GRAPH
DGRAY=124000 ;Y GRAPH
BLINK=30 ;BLINK MODE
NOBLI=20 ;STEADY MODE
SOLID=4 ;SOLID LINES
LONGD=5 ;LONGDASH LINES
SHORTD=6 ;SHORTDASH
DOTD=7 ;DOTDASH
INT0=2000 ;INTENSITY 0(LOWEST)
INT1=2200
INT2=2400
INT3=2600
INT4=3000
INT5=3200
INT6=3400
INT7=3600 ;INTENSITY 7(HIGHEST)
ITALIC=60 ;ITALIC MODE
NOITAL=40 ;UPRIGHT MODE
LITE=140 ;LITE PEN SENSITIVE
NOLITE=100 ;NON-LITE PEN SENSITIVE
SYNC=4 ;SYNC(NOT USED)
;MISCELLANEOUS
HGHPRI=340 ;HIGH PRIORITY BITS
GTPRI=200 ;GT40 PRIORITY
TXTSTA=170000 ;STATUSA TO START DFILE
DELTAZ=174100 ;ORIGINAL GRAPH INCREMENT OF 0
SSIZE=40 ;SIZE OF MAIN STACK
SSSIZE=144 ;SIZE, IN BYTES, OF SUBPICTURE STACK
ROLSIZ=200 ;ORIGINAL ROLL SIZE
HEDSIZ=20 ;ADDITIONAL INFORMATION IN DISPLAY FILE
BUFFS=40 ;MAX. AND ORIGINAL NUMBER OF BUFFERS
BUFALL=5500 ;ORIGINAL TOTAL BUFFER AREA (40@132 PER)
LF=12 ;LINE FEED
MINUS=55 ;MINUS SIGN
QUOTE=42 ;QUOTE *2
CR=15 ;CARRIAGE RETURN
CRLF=5015 ;CRLF FOR BUFFER STARTS
CONC=3 ;^C
CONR=222 ;^R(WITH PARITY BIT), RESETS THE BOOK
SHIN=17 ;SHIFT-IN CHARACTER
SHOUT=7017 ;SHIFT-OUT CHARACTER
;SHIFT-IN IN LOW BYTE
;MACROS
.MACRO CALL J
JSR PC,J
.ENDM
;INTERRUPT VECTORS
.=4
NEXM ;NON-EXISTANT MEMORY
HGHPRI
.=24
PWRFAL ;POWER FAIL
HGHPRI
.=KEYVEC
KEYINT ;KEYBOARD INPUT
HGHPRI
.=CLKVEC
CLKINT ;CLOCK
HGHPRI
.=TENVEC
TENINT ;PDP-10 INPUT
HGHPRI
.=STPVEC
STPINT ;DISPLAY STOP
GTPRI
LPINT ;LIGHT PEN
GTPRI
TIMINT ;TIME OUT/SHIFT OUT
GTPRI
.=400 ;START OF PROGRAM
.=.+SSIZE ;START WITH MAIN STACK
STACK=.
START: RESET ;RESET ALL DEVICES
RESET
RESET
MOVB #CONC,@#TENOUT+2 ;STOP LOADER
MOV #16,@#TENIN ;DISABLE INTERRUPTS
CLR @#KEYIN
CLR @#TENOUT
RSET: MOV #STACK,SP ;SET UP STACK
CLR TEMP ;STOP CLOCK BY PUTTING 0,
CALL NOCLK ;INTO DEVICE REGISTER
MOV #40,SCROLL
MOV #110,CHARS ;START WITH 72 CHAR.S PER LINE
;START WITH 40 LINES OF SCROLLING
MOV PAGES,LAYP ;AND A FILL CORE WITH PAGES 100 LONG
CLR LAYT ;AND NO TABLES,
CLR LAYG ;OR GRAPHS
CLR LAYF ;OR FIGURES
CLR LAYT+2 ;LATIN MODE
;MOV KSIZE,ARG1 ;ARG1 CONTAINS ADDR. OF INDEX START **NEW**
CALL SETUP ;NOW SETUP THE SYSTEM THIS WAY
CLR MODE ;INITIALIZE MODE WORD
MOV GSTART,HITADR ;ORIGINAL L.P. HIT AT PICTURE 0,
ADD #14,HITADR ;LINE 0
MOV #117,@#TENIN ;ENABLE INTERRUPTS
MOV #101,@#KEYIN
BIC #HGHPRI,STATUS ;PUT US IN LOW GEAR
MOV #DFILE,GTPC ;AND START THE DISPLAY
TSTB @MESPTR ;IF MESSAGE WAITING,
BNE MAININ ;PRINT IT,
MOV #MES1,MESPTR ;ELSE, PRINT RESET MESSAGE
;MAININ GETS THE NEXT CHARACTER. ON A CONTROL G , IT DISPLATCHES TO GRAPHICS.
;ON A CONTROL CHARACTER IT DISPATCHES TO THE CORRECT SUBROUTINE OR
;IF NO SUBROUTINE, IGNORES THE CHARACTER. AND ON A PRINTING CHARACTER,
;IT ENTERS THE CHARACTER IN THE CORRECT BUFFER AS POINTED TO BY
;CURLIN AND INPTR.
MAININ: CALL GETCAR ;GET A CHAR FROM THE BUFFER
CMPB CHAR,#40
BLT CONTRO ;YES, PROCESS CONTROL CHAR
CMPB CHAR,#177 ;TEST FOR RUBOUT
BEQ MAININ ;AND IGNORE IT
CALL PRINT ;ELSE, INSERT THE CHARACTER IN THE BUFFUR
BR MAININ ;THEN GO GET NEXT CHAR
CONTRO: CLR TEMP ;USE TEMP AS OFFSET IN TABLE OF CHARS
CONLOP: CMPB CHAR,CONTAB(TEMP) ;AND LOOK FOR A MATCH
BEQ CONDUN ;IF FOUND, DISPATCH
TSTB (TEMP)+ ;POINT TO NEXT ENTRY
TSTB CONTAB(TEMP) ;0 TERMINATES TABLE
BNE CONLOP ;WHEN 0 ENCOUNTERED,
BR MAININ ;IGNORE THIS CHARACTER
CONDUN: ASL TEMP ;DOUBLE THE OFFSET INTO THE TABLE
JSR PC,@CONGO(TEMP) ;AND USE AS OFFSET INTO SUBROUTINE TABLE
BR MAININ ;NOW GET NEXT CHARACTER
CONTAB: .BYTE 01,04,07,10,11,12,13,14,15,30,31,32,35,36,37,0
.EVEN
CONGO: .WORD NOLINE,DRAWIT,BELL,BACKSP,TAB,LINEF,LINEF,FORMF
.WORD CARRET,FORWSP,BACKSP,UPSP,HOME,EOL,EOS
;PRINT INSERT THE CHARACTER IN CHAR INTO THE CURRENT BUFFER OR IGNORES IT
PRINT: MOV INPTR,TEMP ;COMPARE IN-POINTER
SUB @CURLIN,TEMP ;WITH START OF LINE
SUB #2,TEMP ;IGNORE CRLF WORD IN LINE
CMP TEMP,CHARS ;IF THIS CHAR. WOULD GO BEYOND LINE,
BGE NOPR ;IGNORE IT
CMP TEMP,#100 ;IF 64TH CHARACTER,
BNE NOBLE
MOV #1,GTSTAT ;RING ZEE BELL
NOBLE: MOVB CHAR,(INPTR)+ ;ENTER THE CHARACTER
PRINT0: ADD #16,CURX ;AND MOVE OVER THE CURSOR
NOPR: RTS PC ;THEN RETURN
;CONTROL CHARACTER ROUTINES
;CARRET HANDLES CARRIAGE RETURNS
CARRET: MOV @CURLIN,INPTR ;RESET IN-PTR TO START OF LINE
TST (INPTR)+ ;BEYOND THE FIRST CRLF
CLR CURX ;SET CURSOR TO START OF LINE
RTS PC
;LINEF HANDLES LINEFEEDS
;WHEN IT RECEIVES A LINE FEED WITH THE BOTTOM LINE CURRENT,
;IT PULLS THE ADDRESS OF THE TOP LINE OUT OF THE ROLL
;MOVES ALL OTHER ADDRESSES UP ONE
;ZEROES OUT THE FORMER TOP LINE AND PLACES ITS ADDRESS
;IN THE BOTTOM LINE OF THE ROLL
LINEF: CMP CURLIN,LASLIN ;ON LAST LINE?
BGE UPIT ;THEN SCROLL
SUB @CURLIN,INPTR ;MAKE INPTR AN OFFSET FROM START OF LINE
ADD #4,CURLIN ;MAKE CURLIN POINT TO NEXT SLOT
CALL PAD ;PAD BLANKS TILL OFFSET;INPTR COMES BACK CORRECT
SUB #30,CURY ;MOVE CURSOR DOWN
RTS PC
UPIT: SUB @CURLIN,INPTR ;MAKE INPTR INTO OFFSET
MOV TTY0+2,TEMP ;SAVE ADDRESS OF TOP LINE FROM ROLL
MOV #TTY0+2,ARG1 ;GET ADDRESSES OF TOP TWO LINES
MOV #TTY0+6,ARG2 ;AND USE THESE AS POINTERS
UPLOOP: CMP ARG2,LASLIN ;LAST LINE?
BGT SCROLD ;YES, STOP SCROLLING
MOV (ARG2)+,(ARG1)+ ;MOVE EACH ADDRESS UP ONE
CMP (ARG2)+,(ARG1)+ ;SKIPPING THE STOP
BR UPLOOP
SCROLD: MOV TEMP,(ARG1) ;THEN MOVE ORIGINAL TOP LINE IN
CALL ZIPLIN ;ZERO IT OUT
CALL PAD ;PAD TILL LAST INPTR OFFSET
RTS PC
;UPSP MOVES THE CURSOR AND THE INPTR TO THE PREVIOUS LINE IF ONE EXISTS.
UPSP: CMP CURLIN,#TTY0+2 ;IF CURRENT LINE THE TOP OF THE ROLL,
BLE DUNUP ;DO NOTHING
SUB @CURLIN,INPTR ;OTHERWISE MAKE INPTR AN OFFSET
SUB #4,CURLIN ;POINT CURLIN TO PREVIOUS LINE
ADD #30,CURY ;MOVE THE CURSOR UP BUT NOT ACROSS
CALL PAD ;AND PAD BLANKS, IF NEEDED, ON THE PREVIOUS LINE
DUNUP: RTS PC ;INPTR NOW POINTS IN PREVIOUS LINE
;FORWSP MOVES THE CURSOR AND THE INPTR FORWARD WITHOUT AFFECTING
;CHARACTERS ON THE LINE
FORWSP: TSTB (INPTR) ;TEST FOR NO CHARACTER IN NEXT SLOT
BLE BLANK ;IF NONE, INSERT A BLANK
INC INPTR ;ELSE MOVE THE INPTR,
CALL PRINT0 ;AND THE CURSOR (NO BELL)
RTS PC
BLANK: MOV #40,CHAR
CALL PRINT ;ENTER CHARACTER-IN CODE
RTS PC
TAB: MOV INPTR,ARG1 ;CALCULATE CURRENT OFFSET
SUB #2,ARG1 ;FROM CRLF WORD
SUB @CURLIN,ARG1
TABS: CALL BLANK ;INSERT A SPACE
INC ARG1 ;INCREMENT COUNTER
BIC #177770,ARG1 ;AND IF COUNTER NOT MOD 8,
BNE TABS ;DO ANOTHER BLANK
RTS PC ;ELSE, QUIT
;HOME SETS THE INPTR AND THE CURSOR TO THE UPPER LEFT OF THE SCREEN
HOME: MOV #TTY0+2,CURLIN ;MAKE TOP LINE CURRENT
MOV @CURLIN,INPTR ;POINT INPTR JUST PAST CRLF
TST (INPTR)+
CLR CURX ;SET THE CURSOR TO UPPER LEFT
MOV #1350,CURY
RTS PC
;BACKSP MOVES THE INPTR AND THE CURSOR BACK ONE CHARACTER
BACKSP: SUB #2,INPTR ;TEST FOR AT START OF LINE
CMP INPTR,@CURLIN
BLE ATLEFT ;IF SO, DO NOTHING
DEC INPTR ;ELSE MOVE BACK THE INPOINTER
SUB #16,CURX ;AND THE CURSOR
ATLEFT: ADD #2,INPTR ;NOW UNDO PREVIOUS SUBTRACTION
RTS PC ;AND RETURN TO MAIN
;EOL ERASES TO THE END OF THE CURRENT LINE
EOL: MOV INPTR,TEMP ;GET CURRENT CHAR. POSITION
EOLLOP: TSTB (TEMP) ;WHEN LOW BYTE OF DSTP REACHED (A 0),
BEQ DUNEOL ;OR 1ST NON-CHARACTER(ALSO 0), QUIT
CLRB (TEMP)+ ;ELSE, CLEAR A BYTE
BR EOLLOP ;AND GO ON
DUNEOL: RTS PC
;EOS CLEARS FROM THE CURRENT CHARACTER POSITION TO THE END OF THE
;SCREEN.
EOS: CALL EOL ;FIRST CLEAR REMAINDER OF CURRENT LINE
MOV CURLIN,ARG1 ;SAVE POSITION OF CURRENT LINE
EOSLOP: ADD #4,CURLIN ;THEN ZIP ONE LINE AFTER ANOTHER
CMP CURLIN,LASLIN
BGT DUNEOS ;UNTIL END OF ROLL
CALL ZIPLIN
BR EOSLOP
DUNEOS: MOV ARG1,CURLIN ;NOW RESOTORE CURRENT LINE POINTER
RTS PC
;FORMF DOES A HOME AND ERASE
FORMF: CALL HOME ;HOME
CALL EOS ;AND ERASE TILL END OF SCREEN
RTS PC
;NOLINE IGNORES ALL CHARACTERS UNTIL IT ENCOUNTERS A LINE FEED
;THE USER MAY, THUS, CAUSE PICTURE BOOK TO IGNORE A LINE BY PRECEEDING
;IT WITH A NULL (0)
NOLINE: CALL GETCAR ;GET NEXT CHARACTER,
CMPB CHAR,#LF ;TILL LF ENCOUNTERED
BNE NOLINE
RTS PC
;BELL RINGS THE BELL ON ^G (07)
BELL: MOV #1,GTSTAT ;WRITING IN STATUS RINGS THE BELL ON ^G
RTS PC
;GENERAL VT05 ROUTINES
;GETCAR GETS THE NEXT INPUT CHARACTER
;!CHAR!
GETCAR: MOVB @MESPTR,CHAR ;SEE IF MESSAGE WAITING
BEQ GETONE ;IF SO,
INC MESPTR ;RETURN MESSAGE CHAR AND BUMP POINTER
RTS PC
.IFDF NOBUF ;THIS CODE USES NO BUFFER
GETONE: MOV INCHAR,CHAR ;ELSE,GET THE CHAR FROM STORAGE
BEQ GETONE ;IF NONE THERE, WAIT
BIC #177600,CHAR ;USE LOW 7 BITS
CLR INCHAR ;CLEAR STORAGE
MESIN: RTS PC ;RETURN WITH CHAR
.ENDC
.IFNDF NOBUF ;THIS CODE USES A BUFFER
GETONE: CMP OUT,IN ;COMPARE POINTERS
BEQ GETONE ;AND WAIT FOR INPUT
MOVB @OUT,CHAR ;GET THE CHAR.
INC OUT ;AND BUMP POINTER
BIC #177600,CHAR ;USE 7 LOW BITS
RTS PC
.ENDC
;PUTCAR TAKES THE CHARACTER IN CHAR AND SEND IT TO THE HOST
;STATUS ON RETURN DENOTES SIGN OF CHAR
PUTCAR: TSTB @#TENOUT ;WHEN XMIT READY,
BGE PUTCAR
MOVB CHAR,@#TENOUT+2 ;SEND THE CHAR
RTS PC
;ZIPLIN ZEROES A TEXT BUFFER
;!TEMP!ARG2!
ZIPLIN: MOV @CURLIN,TEMP ;START AT CURRENT LINE
MOV #CRLF,(TEMP)+ ;START BUFFER WITH CRLF
MOV CHARS,ARG2 ;CHARS CONTAINS BYTES PER BUFFER
ASR ARG2 ;CONVERT TO WORDS
ZIPLOP: CLR (TEMP)+
DEC ARG2
BGT ZIPLOP
MOV #DSTP,(TEMP)+ ;END WITH STOP 0
CLR (TEMP)+
RTS PC
;PAD PADS BLANKS STARTING AT THE INPTR WHICH COMES DOWN AS AN
;OFFSET IN INPTR, BACK TO THE FIRST CHARACTER IN THE CURRENT LINE
;AS POINTED TO BY CURLIN.
;!INPTR!TEMP!
PAD: ADD @CURLIN,INPTR ;INPTR SAME OFFSET BUT NEXT LINE
MOV INPTR,TEMP ;NOW POINT TO CURRENT CHARACTER POS.
PADLOP: TSTB -(TEMP) ;IF PREVIOUS POSITION CONTAINS 0,
BNE DUNPAD
MOVB #40,(TEMP) ;INSERT A BLANK
BR PADLOP ;UNTIL SOME CHARACTER OR THE CRLF PAIR,
DUNPAD: RTS PC ;REACHED
;GRAPHICS ROUTINES
;DRAWIT PICKS UP THE ID CHARACTER THEN DISPLATCHES TO THE PROPER
;ROUTINE
DRAWIT: CALL GETCAR ;GET THE ID CHAR.
MOV CHAR,TEMP ;USE IT AS OFFSET, BUT SAVE FOR ROUTINES
ASLB TEMP ;*2
BPL DRAWIT ;IF LESS THAN ALPHABET, IGNORE IT
NOTLOW: BICB #200,TEMP ;MAKE POS. NOW
CMPB TEMP,#64 ;IF BEYOND ALPHABET,
BGT BADID ;BAD ID
JSR PC,@IDS(TEMP) ;ELSE OK, DISPATCH
BADID: RTS PC
;THE ID TABLE CONTAINS A DESCRIPTION OF THE ROUTINE, THE REASON FOR
;CHOOSING THE PARTICULAR LETTER CODE, AND THE NAME OF THE FORTRAN
;SUBROUTINE THAT CORRESPONDS TO EACH ENTRY
IDS=. ;START OF ID TABLE
IOTA ;@(AT), START, READ OR STOP THE CLOCK: IOTA
OLINE ;A(AXIS) MARK A GRAPH, MARKG
BITS ;B(BITS), SET MODE: BITS
SUBP ;C,(CALL), CALL A PAGE: PICUTURE,FIGURE,TABLE,GRAPH
DOT ;D(DOT), ABSOLUTE POINT: DOT
ERASE ;E(ERASE), ERASE A PAGE: ERASEP,ERASEF,ERASEG,ERASET
OPAGE ;F(FIGURE), OPEN A FIGURE: OPENF
OPAGE ;G(GRAPH), OPEN A GRAPH: OPENG
HIT ;H(HIT), LIGHT PEN HIT: HIT
OLINE ;I(INCH), MARK A FIGURE: MARKF
JOT ;J(JOT), WRITE IN A FIGURE: JOT
OLINE ;K(KARACHTER), MARK A TABLE: MARKT
OLINE ;L(LINE), MARK A PICTURE: MARKP
MOVE ;M(MOVE), INVISIBLE VECTOR: MOVE
NOJOT ;N(NOJOT), WRITE INVISIBLY IN A FIGURE: NOJOT
LAYOUT ;O(OPEN), LAYOUT THE BOOK: LAYOUT
OPAGE ;P(PICTURE), OPEN A PICTURE: OPENP
TEXT ;Q,(QUOTE), INSERT A CHARACTER: TEXT
RSET ;R(RESET), RESET THE BOOK: THEEND
SET ;S(SET), INVISIBLE VECTOR: SET
OPAGE ;T(TABLE), OPEN A TABLE
UNHIT ;U(UNHIT), WAIT FOR L.P. HIT BEFORE RETURNING
VECTOR ;V(VECTOR), VECTOR: VECTOR
PUTNUM ;W(WAIT), WAIT TILL THIS COMMAND EXECUTES: WAIT
READX ;X(X), READ X-COORDINATE: READX
READY ;Y(Y), READ Y-COORDINATE: READY
PLOT ;Z(X OR Y), PLOT A POINT: PLOT
;LAYOUT SETS UP THE BOOK.
;IT SETS THE AMOUNT OF LINE TO SCROLL. THEN
;IT READS PAGE NUMBER AND LINE NUMBER INTO THE LAYOUT TABLE A BYTE
;AT A TIME.
;O+9*N
;LAYOUT: MOV #173000,TTY0 ;INSERT NON-INTERRUPT STOP IN ROLL
;STPLOP: CMP GTPC,#TTY0+2 ;AND WAIT FOR THIS STOP
; BNE STPLOP
LAYOUT: CALL GETCAR ;GET AMOUNT TO SCROLL
MOV CHAR,SCROLL
CALL GETCAR ;GET WORDS PER BUFFER
ASL CHAR ;*2 FOR BYTES
MOV CHAR,CHARS ;AND SAVE
MOV #LAYTAB,TEMP ;NOW ENTER ALL SIZES IN LAYOUT TABLE
LAYLOP: CALL GETCAR ;PAGES IN LO BYTES, LINES IN HI
MOVB CHAR,(TEMP)+ ;PICTURES,FIGURES,GRAPHS,THEN TABLES
CMP TEMP,#LAYT+3 ;INCLUDING GREEK OR LATIN MODE
BLT LAYLOP
CALL SETUP ;NOW SETUP THE BOOK
MOV CHAR,ARG1 ;SAVE CHAR TO TEST SIGN
BIC #160000,CHAR ;MOD 4096
TST ARG1 ;IF IT WAS NEGATIVE, THEN HAVE
BPL LAYPLS ;TO SET BIT 13 FOR INFORM
BIS #20000,CHAR ;SUBROUTINE TO WORK PROPERLY.
LAYPLS: CALL INFORM ;PUT OVERLAP IN COORDINATE FORM
CALL PUTCO ;SEND OUT THE OVERLAP
TST ARG1 ;IF BAD LAYOUT (NEG. RETURN),
BGE LAYDUN
JMP RSET ;RESET THE BOOK
LAYDUN: MOV #DFILE,GTPC ;START THE DISPLAY
CLR STATUS ;ALLOW DISPLAY INTERRUPTS
RTS PC
;OPAGE OPENS A PAGE OF A GIVEN TYPE
;IT DOES SO BY ENTERING ITS ADDRESS IN THE OPEN TABLE.
;IT GETS THIS ADDRESS FROM THE INDEX
;IT IGNORES NON-EXISTANT PAGES
;P,G,T, OR F+N
OPAGE: CALL OFFSET+4 ;GET OFFSET INTO OTABLE
MOV CONTS(ARG1),TEMP ;GET START OF THIS TYPE FROM T.O.C.
CALL GETCAR ;GET PAGE NUMBER
CMPB CHAR,LAYTAB(ARG1) ;IF HIGHER THAN PAGES AVAILABLE
BGT NODO ;IGNORE
ASL CHAR ;*4 FOR OFFSET INTO INDEX
ASL CHAR
SUB CHAR,TEMP ;POINTS TO INDEX ENTRY
MOV TEMP,OTABLE(ARG1) ;NOW ENTER PAGE'S ADDR. INTO OTABLE
NODO: RTS PC ;NOUGHT ELSE
;OLINE OPENS A LINE ON A PAGE.
;IT ENTERS ITS ADDRESS IN THE MARKER TABLE, FINDING THE ADDRESS
;BY ADDING THE LINE OFFSET TO THE ADDRESS IN THE OPEN TABLE.
;LINE OFFSET=LINE*6 FOR PICTURE,LINE*2 FOR GRAPH OR FIGURE,
;LINE*1 FOR TABLE
;IT READS LINE NUMBER MOD 128, IGNORING NEGATIVITY
;A LINE NUMBER BEYOND PAGE TYPE SETS MARKER FOR OPEN PAGE TO 0
;(L,A,K, OR I +N)
OLINE: CALL OFFSET+4 ;ARG1 WILL CONTAIN OFFSET INTO OTAB
CALL LINOFF ;GET LINE OFFSET INTO ARG2
MOV OTABLE(ARG1),TEMP ;GET ADDRESS OF INDEX ENTRY
TOOBAD: MOV (TEMP),-(TEMP) ;MAKE MARKER ENTRY EQUAL TO IT
ADD ARG2,(TEMP) ;THEN OFFSET THE MARKER
CLR ARG2
CMP (TEMP)+,MARGS(ARG1) ;TEST FOR MARKER BEYOND IT,
BGE TOOBAD ;IF SO,SET MARKER TO START OF PAGE
RTS PC
;OFFSET RETURNS 0,2,4,6 IN ARG1 FOR P OR L, F OR I, T OR K, G OR A
;RESPECTIVELY, THE OFFSET INTO THE TABLE OF CONTENTS(T.O.C.) AND
;THE LAYOUT TABLE. ARG1 WILL CONTAIN THIS OFFSET.
;!ARG1!
OFFSET: CALL GETCAR ;GET THE ID
MOV #7,ARG1 ;START THE OFFSET RETURN REGISTER
OFFLOP: CMPB CHAR,OFFIDS(ARG1) ;FIND A MATCH
BEQ OFF
DEC ARG1 ;ELSE GO BACK A BYTE
BGE OFFLOP
NOFF: TST (SP)+ ;IF NO MATCH KLUDGE AN RTS AND RETURN TO FIRST CALLER
OFF: BIC #177771,ARG1 ;NOW MAKE ARG1 EVEN
RTS PC
OFFIDS: .BYTE 'P,'L,'F,'I,'G,'A,'T,'K ;IDS
;PAIR FOR PICTURE, FIGURE, GRAPH, TABLE
;BITS SETS BITS IN MODE CORRESPONDING TO THE VARIOUS MODES AVAILABLE
;ON THE GT40. EACH LINE THAT ENTERS A PICTURE
;USES THESE BITS IN WORD 0, ADDING ON THE BITS THAT DETERMINE
;THE TYPE OF GRAPHIC DATA IN THE LINE.
;(B+4*N)
BITS: CLR MODE ;GET RID OF LAST MODE
CALL GETCAR ;SET BLINK-NESS
ROL CHAR ;TEST FOR BIT 6 SET,
ASRB CHAR ;INDICATING NEGATIVE VALUE
BMI NOB ;IN WHICH CASE, NO-BLINK ENABLE
BEQ STEADY ;IF 0, NO BLINK ENABLED
BIS #10,MODE ;ELSE BLINK
STEADY: BIS #20,MODE ;SET ENABLE BIT
NOB: CALL GETCAR ;GET INTENSITY
ROL CHAR ;ON NEGATIVE ARG,
ASRB CHAR
BMI NOI ;NO ENABLE
SWAB CHAR ;ELSE PUT THE BITS INTO THE MODE WORD
ROR CHAR
BIS #2000,CHAR ;ENABLE THEM
BIC #174177,CHAR ;AND MAKE SURE NO OVERFLOW (MODULO 8)
BIS CHAR,MODE ;NOW ENTER THEM
NOI: CALL GETCAR ;GET LINE TYPE
ROL CHAR
ASRB CHAR
BMI NOT
BIS #4,CHAR ;SET ENABLE BIT IF POSITIVE ARG.
BIC #177770,CHAR ;MODULO 4
BIS CHAR,MODE
NOT: CALL GETCAR ;GET LIGHT PEN SENSITIVITY
ROL CHAR
ASRB CHAR
BMI NOS
BEQ DULL
BIS #40,MODE ;AND SET PROPER BITS
DULL: BIS #100,MODE
NOS: RTS PC
;THESE ROUTINES ENTER LINES AND POINTS INTO
;PICTURES.
;VECTOR ADDS A VISIBLE VECTOR
;SET ADDS AN INVISIBLE VECTOR
;DOT ADDS A VISIBLE POINT
;SET ADDS AN INVISIBLE POINT
;(V,M,D OR S)+4*N
SET: BIS #DPT,MODE ;SET UP MODE WORD
MOVE: BIS #DVEC,MODE ;DITTO
CLR ARG1 ;VISIBLE BIT OFF
BR ENTERP
DOT: BIS #DPT,MODE
VECTOR: BIS #DVEC,MODE
MOV #40000,ARG1 ;ALSO SET VISIBLE, INVISIBLE BIT
ENTERP: CALL GETNUM ;GET A COORDINATE
BIS CHAR,ARG1 ;INTO ARG1(WHICH MAY HAVE A BIT SET)
CALL GETNUM ;AND ANOTHER,
MOV CHAR,ARG2 ;INTO ARG2
PICIN: MOV OPENP,TEMP ;POINT TEMP TO OPEN PICTURE ENTRY IN INDEX
SUBIN: CALL INSERT ;AND INSERT THIS LINE
INFIN: RTS PC
;SUBP INSERTS A SUBROUTINE CALL IN THE CURRENT PICTURE, CURRENT LINE
;WORD 0 OF THE LINE CONTAINS THE MODE OF THE SUBPICTURE.
;FOR A PICTURE, MODE IS NOT NEEDED BUT IS VECTOR MODE
;A FIGURE TAKES EITHER RELATIVE POINT MODE OR SHORT VECTOR MODE.
;A TABLE TAKES CHARACTER MODE.
;A GRAPH TAKES EITHER X GRAPH OR Y GRAPH MODE
;WORD 1 CONTAINS THE STOP INSTRUCTION THAT CAUSES AN INTERRUPT.
;WORD 2 CONTAINS THE ADDRESS OF THE LINE CALLED CALCULATED FROM
;THE INDEX ENTRY FOR THE START OF THE PAGE SPECIFIED IN THE ARGUMENT
;FOLLOWING THE ID LETTERS.
;(C+P,V,D,T,X,OR Y+2*N)
SUBP: CALL GETCAR ;GET THE ID LETTER(TYPE OF PAGE TO CALL)
MOV #5,ARG1 ;ARG1 POINT TO A TABLE
TYPLOP: CMPB CHAR,TYPIDS(ARG1)
BEQ TYPIT ;GET OFFSET INTO ID TABLE,
DEC ARG1
BGE TYPLOP ;TO CALCULATE MODE OF CALL
BR NOFF ;IF NO MATCH, RETURN TO MAIN CALLER
TYPIT: BISB TYPES(ARG1),MODE+1 ;ENTER HIGH BITS IN MODE WORD
INC ARG1 ;NOW CHANGE ARG1 INTO AN OFFSET FOR
BIC #177771,ARG1 ;THE TABLE OF CONTENTS
CALL LINADR ;GET ADDRESS OF LINE INTO ARG2
CMP ARG2,MARGS(ARG1) ;IF ADDRESS BEYOND CHAPTER,
BGE INFIN ;IGNORE CALL
BIC #1,ARG2 ;MAKE SURE EVEN ADDRESS (TABLE SOMETIMES ODD)
MOV #DSTP+ITALIC,ARG1 ;SET UP ARG1 WITH WORD 1 OF LINE
MOV OPENP,TEMP ;COMPARE ADDRESS OF CALL WITH
TST -(TEMP)
CMP ARG2,(TEMP)+ ;ADDRESS OF INSERTION
BLE INFIN ;IF NOT GREATER, IGNORE REQUEST
BR SUBIN ;ELSE INSERT IT
TYPIDS: .BYTE 'P,'V,'D,'X,'Y,'T ;SECOND ID LETTERS
TYPES: .BYTE DVEC/400,DRELV/400,DRELP/400 ;MODE BITS FOR WORD 0
.BYTE DGRAY/400,DGRAX/400,DCHR/400
;ERASE ERASES THE CURRENTLY OPEN PAGE STARTING
;AT THE CURRENT LINE BY ADDING DNOP'S UNTIL IT ENCOUNTERS A STOP 0.
;THIS MAY CAUSE A TIME OUT WHEN DNOP-ING THE ADDRESS OF A SUBROUTINE CALL.
;THE TIME-OUT ROUTINE SIMPLY STARTS THE DISPLAY AT THE TOP
;OF THE DISPLAY FILE MAKING THE ERROR UNNOTICEABLE.
;(E+P,F,G OR T)
ERASE: CALL OFFSET ;GET OFFSET INTO OTABLE
MOV OTABLE(ARG1),ARG2 ;CALCULATE ADDRESS,
MOV -(ARG2),TEMP ;OF OPEN LINE
ERSLOP: CMP (TEMP)+,#DSTP ;WHEN STOP-NOP REACHED,
BNE NOTEND
CMP (TEMP),#DNOP
BNE NOTEND
RTS PC ;QUIT
NOTEND: MOV #DNOP,-(TEMP) ;ELSE, DNOP ANOTHER WORD
TST (TEMP)+
BR ERSLOP
;PLOT INSERTS THE NEXT TWO BYTE VALUE INPUT INTO THE CURRENT GRAPH
;IN THE LINE POINTED TO BY THE MARKER
PLOT: MOV OPENG,ARG1 ;GET POINTER TO INDEX ENTRY
CALL GETNUM ;GET COORDINATE
BIT #20000,CHAR ;TEST FOR NEGATIVE VALUE
BEQ LOT
BICB #300,CHAR ;IF SO, USE LOW 6 BITS A NEW GRAPH INCR.
MOV #DELTAZ,DELTA ;FIRST INSERT 0 INCREMENT WORD IN FILE
BISB CHAR,DELTA ;THEN SET NEW INCREMENT
RTS PC
LOT: CMP -(ARG1),ENDG ;IF MARKER BEYOND END OF GRAPH CHAPTER
HOT: BLT OT
REMARK: TST (ARG1)+ ;GET ADDRESS OF START OF PAGE
MOV (ARG1),-(ARG1) ;AND INSERT IT IN THE MARKER
OT: MOV (ARG1),ARG2 ;GET LINE ADDRESS FROM MARKER
MOV CHAR,(ARG2)+ ;INSERT THE COORDINATE
MOV ARG2,(ARG1) ;INCREASE THE MARKER
RTS PC
;JOT INSERTS THE NEXT TWO BYTE BALUE INPUT INTO THE CURRENT FIGURE
;IN THE LINE POINTED TO BY THE MARKER
;(J+2*N)
;NOJOT INSERTS AN INVISIBLE JOT
;(N+2*N)
NOJOT: CLR -(SP) ;PUSH INVISIBLITY
BR OJOT
JOT: MOV #40000,-(SP) ;PUSH VISIBILITY
OJOT: CALL GETCO ;GET X COORDINATE,7 BITS
SWAB CHAR ;SHIFT THESE BITS LEFT 7
ROR CHAR
MOV CHAR,ARG2 ;AND SAVE
CALL GETCO ;GET Y-COORD
BIS ARG2,CHAR ;AND PUT TOGETHER
BIS (SP)+,CHAR ;SET VIS-INVIS BIT FROM STACK
MOV OPENF,ARG1 ;SET UP ARG1 WITH CURRENT FIGURE
CMP -(ARG1),ENDF ;TEST FOR BEYOND CHAPTER
BR HOT ;AND INSERT THIS WORD IF NOT
;GETCO GETS A 7 BIT COORDINATE MAKING SURE
;IT HAS THE NEGATIVE BIT SET IF NEGATIVE AND PROPER FORMAT
;!CHAR!
GETCO: CALL GETCAR ;GET COORD
ASLB CHAR ;IF NEGATIVE,
ASRB CHAR
BPL NOTMI
NEGB CHAR ;NEGATE TO GET POSITIVE VALUE
BISB #100,CHAR ;AND SET NEG. BIT TO INDICATE DIRECTION
NOTMI: RTS PC
;TEXT ENTERS CHARACTERS IN THE CURRENT TABLE.
;IT WILL ENTER ONE CHARACTER IN THE NEXT AVAILABLE BYTE, EITHER
;A REGULAR OR SPECIAL CHARACTER. IT WILL CLEAR THE ODD BYTE OF
;A CONTROL WORD
TEXT: MOV OPENT,ARG1 ;POINT TO INDEX ENTRY
MOV -(ARG1),ARG2 ;AND TO NEXT FREE BYTE
CALL GETCAR ;GET NUMBER OF CHARACTERS TO FOLLOW
MOV CHAR,TEMP ;SAVE AS COUNTER
TEXLOP: CALL GETCAR ;GET A CHARACTER
CMPB CHAR,#40 ;IGNORE CONTROL CHARACTERS
BLT TEXLOP
TSTB LAYT+2 ;IF IN GREEK MODE,
BEQ INLAT
BICB #340,CHAR ;USE LOW 5 BITS
CMPB CHAR,#SHIN ;IGNORING SHIFT-IN
BEQ NOSEE
INLAT: MOVB CHAR,(ARG2)+ ;NOW ENTER THE CHARACTER
TSTB (ARG2) ;AND IF ODD BYTE,
BGE EVEN ;OF A CONTROL WORD (DNOP OR DSTP)
CLRB (ARG2) ;CLEAR IT TO SHOW CHAR. IN LOW BYTE
EVEN: CMP ARG2,ENDT ;IF POINTER POINTS TO MARGIN
BLT SKIM
MOV @OPENT,ARG2 ;POINT IT TO START OF TABLE
SKIM: MOV ARG2,(ARG1) ;THEN UPDATE THE MARKER
NOSEE: DEC TEMP ;COUNT A CHARACTER
BGT TEXLOP ;AND GET ANOTHER , IF NECESSARY
RTS PC ;AND GO BACK
;READX AND READY RETURN THE X AND Y COORDINATE RESPECTIVELY OF
;THE PICTURE LINE SPECIFIED IN THE NEXT TWO INPUT ARGUMENTS.
READX: MOV #5712,XORY ;ON X-CO, DON'T AUTO-INCREMENT
BR READXY
READY: MOV #5722,XORY ;ON Y-CO, DO AUTO-INCREMENT
READXY: CLR ARG1 ;SET UP OFFSET INTO T.O.C.
CALL LINADR ;GET ADDRESS INTO ARG2
CMP ARG2,@CHAFIG ;TEST FOR ADDRESS BEYOND PICTURES
BGE NONO ;IF SO SEND BACK 0
TST (ARG2)+ ;POINT IT TO WORD 1
XORY: TST (ARG2) ;TEST FOR CONTROL WORD THERE
BGE NOTSUB
NONO: MOV #177777,CHAR ;IF SO, RETURN -4095
BR NOCOS
NOTSUB: MOV (ARG2),CHAR ;ELSE RETURN THE X OR Y CO. DEPENDING,
NOCOS: CALL PUTCO ;ON WHETHER 'XORY' POPPED POINTER OR NOT
RTS PC
.IFDF OLDWAY
;PUTNUM SENDS OUT THE 14 BIT VALUE IN CHAR.
;IT WILL SEND IT OUT AS A 14 BIT VALUE RATHER THAN IN THE
;GT40 FORMAT IT RECEIVES WHICH INCLUDES A NEGATIVE BIT AND A DELTA VALUE
;!CHAR!ARG1!
PUTCO: MOV CHAR,ARG1 ;TEST THE VALUE
BIT #2000,ARG1 ;FOR NEGATIVE
BEQ PUTNUM
NEG CHAR ;IF SO MAKE IT A POSITIVE OFFSET,
BIC #160000,CHAR
BIS ARG1,CHAR ;WITH NEGATIVE BIT SET
PUTNUM: SWAB CHAR
CALL PUTCAR ;THEN OUTPUT IT,
SWAB CHAR ;A BYTE AT A TIME
CALL PUTCAR ;HIGH BYTE FIRST
RTS PC
.ENDC
;PUTCO OUTPUTS A COORDINATE
;PUTNUM OUTPUTS THE VALUE IN CHAR AS A 4 DIGIT OCTAL NUMBER
;!CHAR!ARG2!
PUTCO: BIT #20000,CHAR ;IF NEG. BIT SET IN COORD.,
BEQ PUTNUM
MOVB #MINUS,@#TENOUT+2 ;OUTPUT A MINUS SIGN
PUTNUM: MOV #CR,-(SP) ;PUSH THE FINAL CR ONTO THE STACK
MOV #4,ARG2 ;SET UP COUNTER
STACH: MOV CHAR,-(SP) ;PUSH CHAR,
BIC #177770,(SP) ;AND MAKE LOW 3 BITS INTO ASCII DIGIT
BIS #60,(SP)
ROR CHAR ;ROTATE NEXT DIGIT INTO LOW 3 BITS
ROR CHAR
ROR CHAR
DEC ARG2
BGT STACH ;AND DO 4 DIGITS
MOV #5,ARG2 ;THEN OUTPUT 5 CHARACTERS
POPLOP: MOV (SP)+,CHAR
CALL PUTCAR
DEC ARG2
BGT POPLOP
JSR PC,NOLINE ;NOW IGNORE TILL THE LF ECHO
RTS PC
;HIT RETURNS THE PAGE AND LINE OF THE LAST LIGHT PEN HIT
;IT DOES SO BY CALCULATING THESE VALUES FROM THE CONTENTS OF
;'HITADR' INTO WHICH THE LIGHT PEN INTERRUPT ROUTINE PLACES THE
;ADDRESS+6 OF THE LAST HIT
;(H)
;UNHIT FIRST WAITS FOR A LIGHT PEN HIT BEFORE RETURNING ITS ADDRESS
;(W)
UNHIT: CLR HITADR ;CLEAR ADDR. TO CAUSE WAIT FOR NEXT HIT
NOHIT: TST HITADR ;WAIT TILL HIT ADDR. SET BY LPINT
BEQ NOHIT
HIT: CLR CHAR
MOV CHAPIC,ARG1 ;GET ADDRESS OF 1ST INDEX ENTRY
CMP (ARG1)+,(ARG1)+ ;START POINTER BELOW START OF INDEX
HITLOP: INC CHAR ;AND COUNT PAGES
CMP -(ARG1),-(ARG1) ;POINTER TO PAGE ADDRESS IN INDEX
CMP (ARG1),HITADR ;WHEN ADDRESS EXCEEDED,
BLE HITLOP
SUB #2,CHAR ;SET THE COUNTER TO THE PREVIOUS PAGE
CALL PUTNUM ;AND SEND OUT THIS NUMBER
MOV HITADR,TEMP
CMP (ARG1)+,(ARG1)+ ;POINT TO PREVIOUS INDEX ENTRY
SUB (ARG1),TEMP ;SUBTRACT IT FROM THE HIT ADDRESS
ASR TEMP ;DIVIDE BY 2 TO GET (LINE+1)*3
CLR CHAR ;SET A COUNTER TO 0
TRILOP: MOV CHAR,ARG2 ;MULT. COUNTER BY 3
ASL ARG2
ADD CHAR,ARG2
INC CHAR
CMP ARG2,TEMP ;AND COMPARE IT TO THE HIT OFFSET
BLT TRILOP ;UNTIL IT EXCEEDS THIS OFFSET
SUB #2,CHAR ;THEN SET THE COUNTER BACK 2
CALL PUTNUM ;AND SEND OUT THE LINE NUMBER
RTS PC
;IOTA STARTS THE CLOCK FOR ARG>0, READS THE TIMER FOR ARG=0,
;AND STOPS THE CLOCK FOR ARG<0
;(@)
IOTA: CALL GETCAR ;GET THE ARGUMENT
CLR TEMP
ROLB CHAR ;FOR ARG<0,
BMI NOCLK ;STOP THE CLOCK
BEQ GETIME ;FOR =0, RETURN THE TIME
MOV #300,TEMP ;FOR >0, START THE CLOCK
NOCLK: CLR TIMER ;SET TIMER TO 0
MOV TEMP,@#CLKOUT
RTS PC
GETIME: MOV TIMER,CHAR
CALL PUTNUM ;SEND TIME AS A POSITIVE VALUE, MOD 4096
RTS PC
;INSERT INSERTS LINES INTO PICTURES.
;IT PUTS A NON-INTERRUPT STOP IN WORD 1 OF THE LINE, INSERTS DATA,
;THEN CHECKS FOR GTPC STOPPED. IF STOPPED, IT RESTARTS IT AT WORD 1.
;MODE MUST CONTAIN THE MODE.
;ARG1 AND ARG2 SHOULD CONTAIN WORDS 2 AND 3
;TEMP MUST CONTAIN A POINTER TO THE INDEX ENTRY.
;!TEMP!ARG1!ARG2!CHAR!
INSERT: MOV -(TEMP),CHAR ;GET ADDRESS OF LINE FROM MARKER
MOV #173000,(CHAR)+ ;INSERT NON-INTERRUPT STOP
MOV ARG1,(CHAR)+ ;INSERT X OR DSTP IN WORD 2
MOV ARG2,(CHAR) ;INSERT Y OR ADDRESS IN WORD 3
SUB #4,CHAR
MOV MODE,(CHAR)+ ;INSERT MODE OVER STOP
CLR MODE ;AND CLEAR MODE FOR NEXT USE
;GTGO: CMP GTPC,CHAR ;GTPC POINTING JUST PAST STOP?
; BNE NOSTOP ;NO, NO NEED TO RESTART
; CMP GTPC,CHAR ;YES. STILL THERE NOW?
; BNE NOSTOP ;NO, COINCIDENCE
GTGO: TST GTSTAT ;TEST FOR DISPLAY STOPPED
BGE NOSTOP
CMP GTPC,CHAR ;IF SO, STOPPED HERE?
BNE NOSTOP
SUB #2,GTPC ;YES, START GT AT WORD 0 OF LINE
NOSTOP: ADD #6,(TEMP) ;POINT MARKER TO NEXT LINE
CMP (TEMP)+,ENDP ;TEST FOR BEYOND PICTURES
BLT INPIC
MOV (TEMP),-(TEMP) ;IF SO SET MARKER TO START OF PICTURE
INPIC: RTS PC
;LINADR RETURNS THE ADDRESS OF THE LINE SPECIFIED BY THE NEXT TWO
;INPUT ARGUMENTS, PAGE AND LINE.
;ARG1 MUST CONTAIN THE PAGE TYPE'S OFFSET INTO THE T.O.C.
;ARG2 WILL RETURN WITH THE ADDRESS OF WORD 0 OF THE LINE
;!CHAR!TEMP!ARG1!ARG2!
LINADR: MOV CONTS(ARG1),TEMP ;GET ADDRESS OF INDEX ENTRY OF PAGE 0
CALL GETCAR ;GET PAGE NUMBER
ASL CHAR ;*4 FOR OFFSET INTO INDEX
ASL CHAR
SUB CHAR,TEMP ;ADD IT TO INDEX POINTER
MOV (TEMP),TEMP ;TEMP NOW POINTS TO START OF PAGE
CALL LINOFF ;CALCULATE OFFSET OF THIS LINE FROM START
ADD TEMP,ARG2 ;ADD START OF PAGE TO THIS OFFSET
RTS PC ;RETURN WITH ADDRESS IN ARG2
;LINOFF CALCULATES THE LINE OFFSET DEPENDING UPON THE TYPE OF PAGE
;CALLED. ARG1 MUST CONTAIN THE OFFSET INTO THE T.O.C..
;ARG2 WILL CONTAIN THE LINE OFFSET SPECIFIED IN THE NEXT INPUT ARG.
;!ARG2!CHAR!
LINOFF: CALL GETCAR
MOV CHAR,ARG2 ;SO DOES ARG2
TST ARG1 ;IF IN A PICTURE,
BNE NOTRI
ASL ARG2 ;MULT. LINE*3
ADD CHAR,ARG2
;NOTRI: CMP ARG1,#6 ;IF NOT IN A TABLE,
; BEQ NOBI
NOTRI: ASL ARG2 ;MULT. LINE*2
NOBI: RTS PC ;RETURN OFFSET IN ARG2
;GETNUM INPUTS A VALUE CONSISTING OF TWO BYTES.
;CHAR WILL CONTAIN THIS VALUE
;!TEMP!CHAR!
GETNUM: CALL GETCAR ;GET HIGH BYTE
SWAB CHAR
ASR CHAR ;OVER 1 BIT TO FIT
MOV CHAR,TEMP ;SAVE HI BYTE
CALL GETCAR ;AND GET LOW
ADD TEMP,CHAR ;NOW PUT TOGETHER
INFORM: BIT #20000,CHAR ;IF 14TH BIT SET (BIT 13)
BEQ PLUSB
NEG CHAR ;NEGATE AND,
BIC #176000,CHAR
BIS #20000,CHAR ;SET NEGATIVE BIT
PLUSB: RTS PC
;TABLES
;TABLE OF CONTENTS
;THIS TABLE , ONE ENTRY PER PAGE TYPE, POINTS TO THE FIRST ENTRY OF
;EACH PAGE TYPE IN THE INDEX
CONTS=.
CHAPIC: .WORD 0 ;PICTURES
CHAFIG: .WORD 0 ;FIGURES
CHAGRA: .WORD 0 ;GRAPHS
CHATAB: .WORD 0 ;TABLES
ENDCHA: .WORD 0 ;END OF BOOK ADDRESS
;OPEN TABLE
;THIS TABLE POINTS TO THE PAGE IN THE INDEX CURRENTLY OPEN FOR EACH TYPE
OTABLE=.
OPENP: .WORD 0 ;PICTURE
OPENF: .WORD 0 ;FIGURE
OPENG: .WORD 0 ;GRAPH
OPENT: .WORD 0 ;TABLE
CLOSE: .WORD 0 ;END OF BOOK ADDRESS
;MARGIN TABLE
;THIS TABLE HOLDS THE ADDRESSES OF THE LAST STOP FOR EACH PAGE TYPE
MARGS=.
ENDP: .WORD 0 ;END OF PICTURES
ENDF: .WORD 0 ;END OF FIGURES
ENDG: .WORD 0 ;END OF GRAPHS
ENDT: .WORD 0 ;END OF TABLES(AND OF BOOK)
;LAYOUT TABLE
;THIS TABLE CONTAINS ONE WORD PER PAGE TYPE
;THE LOW BYTE OF EACH WORD CONTAINS THE NUMBER OF PAGES OF THIS TYPE
;THE HIGH BYTE CONTAINS THE NUMBER OF LINES PER PAGE.
;SETUP WILL LOOK IN THIS TABLE TO DETERMINE HOW TO SET UP THE SYSTEM.
;THE ORIGINAL SETUP IS ALL PICTURES
LAYTAB=.
LAYP: .WORD 0 ;PICTURES
LAYF: .WORD 0 ;FIGURES
LAYG: .WORD 0 ;GRAPHS
LAYT: .WORD 0 ;TABLES
.WORD 0 ;0 MEANS LATIN, NON-0 MEANS GREEK
;SETUP
;SETUP SETS UP THE BOOK. IT LOOKS IN THE LAYOUT TABLE TO DETERMINE
;HOW MANY OF EACH PAGE TO CREATE AND HOW LONG TO MAKE EACH. IT LOOKS
;IN THE WORD 'SCROLL' TO DETERMINE HOW MANY LINES OF VT05 TO MAKE.
;ARG1 MUST POINT TO THE END OF THE BOOK
;CHAR WILL RETURN WITH OVERLAP OR UNUSED(POSITIVE MEANS OVERLAP)
SETUP: CLR TIMER ;CLEAR TIMER BUT DON'T STOP CLOCK
BIS #GTPRI,STATUS ;DISALLOW DISPLAY INTERRUPTS WHILE FIXING CORE
MOV KSIZE,ARG1 ;ARG1 PTS TO START OF INDEX AT BASE OF CORE
MOV SCROLL,CHAR ;GET AMT TO SCROLL
ASL CHAR ;*4 TO GET SIZE OF ROLL
ASL CHAR
MOV #TTY0,INPTR ;GET ADDR. OF START OF FILE
ADD CHAR,INPTR ;AND ADD OFFSET TO GET START OF GRAPHICS
MOV #LAYTAB-1,SSP ;GET ADDRESS OF LAYOUT TABLE,
MOV #CONTS,CHAR ;TABLE OF CONTENTS
CLR (INPTR)+ ;LEAVE SPACE FOR SHIFT OUT WORD
CLR (INPTR)+
MOV INPTR,GSTART ;SAVE START OF GRAPHICS FILE
MOV #DPT+NOBLI+NOLITE+INT3,(INPTR)+ ;START FILE WITH ABS POINT (0,0)
CLR (INPTR)+
CLR (INPTR)+
; BR TYPONE ;LEAVE PICTURE LINES AS IS(LINES+1)
;TYPONE: NOP ;*****
NEWTYP: MOV ARG1,(CHAR)+ ;ENTER INDEX LOCATION IN TABLE OF CONTENTS
; INCB 2(SSP) ;IF SUB-PAGES HAVE 2 MORE LINES THAN SPECIFIED
MOV ARG1,10(CHAR) ;AND IN OPEN TABLE THAT FOLLOWS
TSTB (SSP)+ ;POINT TO NEXT ENTRY IN LAYTAB
CMP SSP,#LAYTAB+10 ;DONE ALL TYPES YET?
BGE DUNPAG ;IF SO, QUIT
MOVB (SSP)+,ARG2 ;COUNT PAGES
BR TOPPAG
NEWPAG: MOV INPTR,22(CHAR) ;INSERT EACH END ADDRESS IN MARGIN TABLE
MOV #DSTP,(INPTR)+ ;INSERT MARGIN, A STOP-NOP
MOV #DNOP,(INPTR)+
MOV #DNOP,(INPTR)+
DECB ARG2 ;TEST FOR DONE HERE
BLE NEWTYP ;SO AT LEAST ONE OF EACH TYPE
TOPPAG: MOVB (SSP),TEMP ;COUNT LINES
MOV INPTR,(ARG1) ;ELSE, ENTER THIS PAGE IN THE INDEX
MOV INPTR,-(ARG1) ;AND IN THE MARKER THAT FOLLOWS EACH ENTRY
TST -(ARG1) ;AND LEAVE POINTER TO NEXT ENTRY
NEWLIN: MOV #DNOP,(INPTR)+ ;ELSE, DNOP A WORD
CMP SSP,#LAYTAB+2 ;IF IN A PICTURE,
BGT INCH1
MOV #DNOP,(INPTR)+ ;DNOP TOTAL OF 3 WORD
MOV #DNOP,(INPTR)+
INCH1: DECB TEMP ;TEST FOR END OF PAGE HERE,
BLE NEWPAG ;SO AT LEASE ONE LINE IN EACH PAGE
BR NEWLIN ;GO DO NEXT LINE
DUNPAG: SUB #2,ENDP ;POINT PICTURE MARGIN TO START OF LINE
MOV #TTY0,ARG1 ;GET ADDRESS OF ROLL
MOV SCROLL,CHAR ;AND NUMBER OF BUFFERS
NEWTTY: MOV #DSTP,(ARG1)+ ;IN THE ROLL, INSERT A STOP,
MOV ARG1,CURLIN ;THIS LINE CURRENT
MOV ARG1,LASLIN ;(SAVE AS LAST LINE IN ROLL)
MOV INPTR,(ARG1)+ ;FOLLOWED BY ADDRESS OF BUFFER
CALL ZIPLIN ;CLEAR THIS BUFFER
MOV TEMP,INPTR ;TEMP POINTS TO END OF BUFFER
DEC CHAR ;AND DO,
BGT NEWTTY ;ALL BUFFERS
SUB ENDCHA,INPTR ;DOES BUFFER END OVERLAP INDEX END?
MOV INPTR,CHAR ;SAVE AMOUNT OF OVERLAP OR UNUSED
NEG CHAR ;GET NEGATIVE
ASR CHAR ;GET WORD COUNT
BLE DUNSET ;RETURN TO LAYOUT
TSTB (SSP)+ ;NON-0 MEANS GREEK MODE
BEQ LATIN
MOV #DCHR,(ARG1)+ ;SO INSERT SHIFT OUT
MOV #SHOUT,(ARG1)+
LATIN: MOV #TTY0+2,CURLIN ;CURLIN PTS TO TOP OF ROLL
MOV TTY0+2,INPTR ;INPTR POINTS TO 1ST BUFFER
TST (INPTR)+ ;POINT IT BEYOND MODE WORD
CLR CURX ;CURSOR STARTS AT X=0,
MOV #1350,CURY ;AND Y=1350
MOV #DELTAZ,DELTA ;SET GRAPH INCREMENT 0
MOV #SUBSTK,SSP ;ALL DONE, SET UP S.P. STACK
DUNSET: RTS PC ;AND RETURN, LEAVING DISPLAY STOPPED
;INTERRUPT ROUTINES
;STOP INTERRUPT
;THIS ROUTINE HANDLES TWO TYPES OF STOPS: STOP0 THAT ENDS A PAGE AND
;STOP FOLLOWED BY THE ADDRESS OF A SUBROUTINE.
;ON A SUBROUTINE STOP IT PUSHES THE ADDRESS OF THE CURRENT GTPC ONTO
;THE SUBPICTURE STACK AND PUTS THAT ADDRESS IN THE GTPC. ON A STOP0
;IT LOOKS IN THE STACK. IF IT FINDS IT EMPTY IT RESTARTS THE DISPLAY
;AT THE TOP OF THE DISPLAY FILE. OTHERWISE, IT POPS THE LAST CALLING
;ADDRESS INTO THE GTPC.
STPINT: MOV TEMP,-(SP) ;SAVE REGISTER ON STACK
MOV @GTPC,TEMP ;GET FOLLOWING WORD
BLE STOP0 ;IF AN ADDRESS THERE,
MOV GTPC,-(SSP) ;PUSH GTPC ONTO STACK
ADD #2,(SSP) ;AND MAKE IT POINT TO NEXT WORD
BR GO ;AND START AT CALLED ADDRESS
STOP0: CMP SSP,#SUBSTK ;IF STACK EMPTY ON STOP0,
BEQ GOTOP ;START DISPLAY AT TOP
MOV (SSP)+,TEMP ;ELSE POP STARTING ADDRESS
BR GO
GOTOP: MOV #DFILE,TEMP ;TOP ADDRESS
GO: MOV TEMP,GTPC ;START DISPLAY
MOV (SP)+,TEMP ;RETRIEVE REGISTER
RTI ;AND EXIT
;LIGHT PEN INTERRUPT
;LPINT CHECKS FOR A LONG VECTOR OR ABS. POINT IN PICTURE 0, LINE 0.
;IF SO, IT TAKES THE GTX AND GTY AND MAKES THESE THE X AND Y COORDINATES
;OF THAT LINE, MAKING SURE TO KEEP THE SAME VISIBLITY.
;IT ALSO SAVES THE ADDRESS OF THE GTPC FOR USE BY 'HIT'
LPINT: MOV TEMP,-(SP) ;SAVE TWO REGISTERS
MOV ARG1,-(SP)
MOV GSTART,TEMP ;GET ADDRESS OF START OF GRAPHICS
ADD #10,TEMP ;POINT TO LINE 0, WORD 1
TST (TEMP) ;TEST FOR SUBROUTINE CALL (A STOP)
BLT NOLPCO ;IF SO,DO NOTHING
MOV GTX,ARG1 ;ELSE, GET X -COORD OF HIT
BIC #176000,ARG1 ;GET RID OF GRAPH INCREMENT STORE HERE
BIT #40000,(TEMP) ;TEST FOR VISIBLE
BEQ NOTVIS
BIS #40000,ARG1 ;IF SO SET VISIBLE BIT
NOTVIS: MOV ARG1,(TEMP)+ ;AND INSERT X-COORD
MOV GTY,ARG1 ;NOW GET Y-COORD OF HIT
BIC #176000,ARG1 ;IGNORE OTHER BITS STORED THERE
CMP ARG1,#1400 ;AND KEEP IT ON THE SCREEN
BLT ONPIC
MOV #1377,ARG1
ONPIC: MOV ARG1,(TEMP)
NOLPCO: MOV GTPC,HITADR ;NOW SAVE ADDRESS OF HIT (+6)
CMP HITADR,@CHAFIG ;UNLESS CURRENTLY NOT IN A PICTURE
BLE INAPIC
MOV (SSP),HITADR ;IN WHICH CASE SAVE THE CALLER'S ADDRESS
INAPIC: MOV #1,GTPC ;RESTART THE DISPLAY
MOV (SP)+,ARG1 ;AND RESTORE REGISTERS
MOV (SP)+,TEMP
RTI
;TIME OUT INTERRUPT
;TIMINT JUST RESTARTS THE DISPLAY.
TIMINT: MOV #DFILE,GTPC ;JUST RESTART DISPLAY AT TOP OF FILE
RTI
.IFDF NOBUF ;THIS ROUTINE USES NO BUFFER
;TENINT PICKS UP THE INPUT CHARACCTER FROM THE PDP-10
;IT WILL PUT THIS CHAR IN THE INPUT WORD IF THIS WORD IS CLEAR
;I.E. IF PREVIOUS CHARACTER USED ALREADY
TENINT: MOVB @#TENIN+2,INCHAR ;GET CHAR
INCB INCHAR+1 ;AND SET FLAG FOR GETCAR ROUTINE
RTI
.ENDC
.IFNDF NOBUF ;THIS ROUTINE USES A 5 WORD CATCH UP
;TENINT GETS THE NEXT CHARACTER AND INSERTS IT IN THE BUFFER, IF IT
;FINDS SPACE AVAILABLE.
TENINT: MOV CHAR,-(SP) ;SAVE A REGISTER
CMP OUT,IN ;IF CAUGHT UP,
BLT NOCAUT
MOV #INBUFF,IN ;RESET PTRS TO BASE OF BUFFER
MOV #INBUFF,OUT
NOCAUT: MOV @#TENIN+2,CHAR ;GET THE CHAR.
CMP IN,#ENDBUF ;OVERFLOW?
BLT INOK
CALL BELL ;YES, RING THE BELL
BR POPCH ;AND IGNORE THE CHARACTER
INOK: MOVB CHAR,@IN ;INSERT THE CHAR.
INC IN ;BUMP THE POINTER
POPCH: MOV (SP)+,CHAR ;RESTOR SAVED REGISTER
RTI ;AND EXIT
INBUFF: .WORD 0 ;START OF INPUT BUFFER
.=.+30 ;14 WORDS LONG
ENDBUF=.
.ENDC
;KEYINT TAKES INPUT FROM THE KEYBOARD AND SENDS IT TO THE 10
;IF IT RECEIVES A CONTROL R, IT TRAPS IT AND RESETS
KEYINT: CMPB @#KEYIN+2,#CONR ;ON CONTROL R,
BNE OUTCH
JMP RSET ;RESET
OUTCH: MOV @#KEYIN+2,@#TENOUT+2 ;ELSE, SEND TO 10
RTI
;CLKINT JUST INCREMENTS THE TIMER
CLKINT: INC TIMER ;INCREMENT THE TIMER
RTI
TIMER: .WORD 0 ;TIMER HOLD NUMBER OF TICKS
;ERROR ROUTINES
;NEXM RESTARTS ON NON-EXISTANT MEMORY
NEXM: MOV #MES2,MESPTR ;PRINT NEXM MESSAGE,
GOSET: JMP RSET ;AND GO START
;PWRFAL RESTARTS ON POWER-UP
PWRFAL: MOV #MES3,MESPTR ;SET UP POWER MESSAGE
BR GOSET ;THEN GO START
;VARIABLE STORAGE
CURLIN: .WORD 0 ;POINTER TO CURRENT TTY LINE IN ROLL
LASLIN: .WORD 0 ;POINTER TO LAST LINE IN ROLL
GSTART: .WORD 0 ;POINTER TO LAST LINE IN ROLL
MESPTR: .WORD MES0 ;POINTS TO BYTE OF MESSAGE TO DISPLAY
IN: .WORD INBUFF ;INPUT BUFFER IN POINTER
OUT: .WORD INBUFF ;INPUT BUFFER OUT POINTER
TEMPO: .WORD 0 ;ALL PURPOSE TEMPORARY
PAGES: .WORD 0 ;HOLDS AMT OF ORIGINAL PAGES IN SYSTEM
KSIZE: .WORD 0 ;CORE SIZE, START OF INDEX
SCROLL: .WORD 0 ;HOLDS ORIGINAL NUMBER OF VT05 BUFFERS
CHARS: .WORD 0 ;NUMBER OF CHARS PER BUFFER
MODE: .WORD 0 ;CONTAINS CURRENT MODE
HITADR: .WORD 0 ;CONTAINS ADDRESS +2 OF LAST LIGHT PEN HIT
;MESSAGES
MES1: .WORD CRLF ;EACH MESSAGE STARTS WITH CRLF
.ASCII "**RESET**"
.BYTE CR,LF,7 ;AND ENDS WITH CRLF+BELL
MES0: .BYTE 0
MES2: .BYTE CR,LF ;START MESSAGE WITH CRLF
.ASCII "**NEXM**"
.BYTE CR,LF ;END WITH CRLF
.BYTE 0 ;0 FOR END OF MESSAGE
MES3: .BYTE CR,LF
.ASCII "**POWER**"
.BYTE CR,LF
.BYTE 0
.EVEN
.WORD 0 ;EACH MESSAGE ENDS WITH 0
;INIT CALCULATES THE SIZE OF CORE USING THIS VALUE TO DETERMINE THE
;ORIGINAL NUMBER OF PAGES 300(10) WORDS LONG THAT WILL FIT IN THE
;SYSTEM. IT PUTS THIS VALUE IN 'PAGES' FOR SETUP CODE TO USE AND
;PUTS THE END OF THE BOOK INTO 'INDEX' WHERE THE INDEX STARTS
INIT: RESET
RESET
MOV #STACK,SP ;DSTART MAIN STACK
MOV #IFEND,@#4 ;SET UP NEXM EXIT FROM LOOP
MOV #340,@#6
MOV #INIT+SSIZE,R0 ;GET START OF BOOK
ADD #ROLSIZ,R0 ;DON'T FORGET THE ROLL
ADD #BUFALL,R0 ;OR THE BUFFER AREA
CLR PAGES ;INITIALIZE PAGES
NEXPIC: MOV #460,R2 ;300(10) LENGTH PAGES
NEXWRD: TST (R0)+ ;LOOP TILL NEXM,
TST R0 ;CHECK FOR >16K MEMORY **NEW**
BMI IFEND ;IF TRUE, SIMULATE 16K **NEW**
DEC R2 ;COUNTING OFF LINES,
BGT NEXWRD
INC PAGES ;AND PAGES
BR NEXPIC
IFEND: CMP -(R0),-(R0) ;LEAVE A LITTLE ROOM
MOV R0,KSIZE ;AND MAKE THIS THE CORE SIZE
MOV #NEXM,@#4 ;ON NEXM, RESTORE THE VECTOR
NEG R2 ;CALCULATE REMAINDER
ADD #454,R2
ASR R2 ;AND DIVIDE REMAINDER BY 4
ASR R2
ROOMIN: CMP R2,PAGES ;IF REMAINDER NOT BIG ENUF FOR INDEX
BGT ROOM
DEC PAGES ;TRY ONE LESS PAGE
ADD #145,R2 ;INCREASING INDEX AREA BY ITS SIZE
BR ROOMIN
ROOM: MOVB #144,PAGES+1 ;SET PAGES 100 LINES LONG
JMP START ;NOW GO, SETUP WILL OVERLAY THIS CODE
.=INIT+SSSIZE+4 ;LEAVE ROOM FOR SUBPICTURE STACK **NEW**
SUBSTK=. ;SUBPICTURE STACK BACKS INTO ABOVE CODE
DFILE: .WORD TXTSTA+NOITAL ;DFILE STARTS WITH STATUS,
DELTA: .WORD DELTAZ ;GRAPH INCREMENT OF 1
.WORD DPT ;PT AT TOP OF SCREEN STARTS FILE
CURX: .WORD 0
CURY: .WORD 1350 ;TO LOCATE CURSOR
.WORD DCHR+BLINK+INT3+NOLITE ;BLINKING CURSOR FOLLOWS
CURSOR: .BYTE 17,177 ;SHIFT IN AND CURSOR
.WORD DPT ;THEN ABS POINT
.WORD 0 ;TO TOP OF SCREEN
.WORD 1400
.WORD DCHR+NOBLI+INT3+SOLID+NOLITE ;START BUFFERS IN CHAR. MODE
TTY0: .WORD DSTP ;ROLL STARTS HERE, GRAPHICS FOLLOW
.END INIT