1
0
mirror of https://github.com/PDP-10/its.git synced 2026-02-11 02:39:49 +00:00
Files
PDP-10.its/src/sysen2/xd.430
2018-07-30 20:35:40 +02:00

1929 lines
41 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.
; -*-MIDAS-*-
TITLE XGP DISPLAY
;FILES MUST END WITH LF OR FF
;NOTE THAT IF I EVER WANT TO ALLOW PAPER TO BE NOT 8.5*11,
;MUST CHANGE CENTER CURSOR COMMAND, AND THE ENDPAG CHECK IN LF.
ZR==0 ;SUPER TEMP
A=1
B=2
C=3
D=4
E=5
F=6
G=7
H=10
T=11
TT=12
PTO=13
PTI=14
CODE=15 ;ASCII CODE FOR THIS CHAR
FONT=16 ;CURRENT FONT
P=17 ;STACK POINTER
BUFSIZ==6000 ;SIZE OF BUFFER
MXSTSZ==200 ;MAX CHARACTER SET SIZE
MXNFNT==20 ;MAX NUMBER OF FONTS
PDLLEN==40 ;LENGTH OF PDL
TTYOCH==1 ;TTY OUTPUT CHANNEL
DSKICH==2 ;DISK FILE INPUT
FNTICH==3 ;FONT INPUT
TTYICH==4 ;TTY OUTPUT
ERRICH==5 ;ERR DEVICE
%TXTOP==4000 ;"TOP" KEY.
%TXSFL==2000 ;"SHIFT-LOCK" KEY.
%TXSFT==1000 ;"SHIFT" KEY.
%TXMTA==400 ;"META" KEY.
%TXCTL==200 ;"CONTROL" KEY.
%TXASC==177 ;THE ASCII PART OF THE CHARACTER.
%TIFUL==400 ;1 => use the full TV character set if possible.
%TJDIS==4000 ;1 => recognize "^P" as an escape for display commands
CIOR==16 ;TV ALU FUNCTION TO DO IORM.
CSET==17 ;TV ALU FUNCTION TO DO MOVEM.
CREGFN==340800 ;BYTE SPEC FOR TV ALU FUNCTIONS
.XCREF A,B,C,P
PJRST==JRST ;FOR PUSHJ P, FOLLOWED BY POPJ P,
DEFINE CONC A,B
A!B!TERMIN
;DECREMENT A 7 BIT BYTE POINTER
DEFINE DBP7 AC
ADD AC,[070000,,0]
TLNE AC,400000
SUB AC,[430000,,1]
TERMIN
LOC 42
JSR TSINT ;INTERRUPT HANDLER ROUTINE FOR TTY INPUT.
LOC 100
SUBTTL INITIALIZATION
GO: MOVE P,[-PDLLEN,,PDB-1]
.CALL [SETZ ;TTY INPUT
SIXBIT /OPEN/
[%TIFUL+.UAI,,TTYICH] ;USE FULL CHAR SET
SETZ [SIXBIT /TTY/]]
.LOSE 1000
.CALL [SETZ ;TTY OUTPUT
SIXBIT /OPEN/
[%TJDIS+.UAO,,TTYOCH] ; USE ^P CURSOR CODES
SETZ [SIXBIT /TTY/]]
.LOSE 1000
.CALL [SETZ ; GET THE TCTYP WORD
SIXBIT /CNSGET/
MOVEI TTYOCH
MOVEM
MOVEM
SETZM A]
.LOSE 1000
CAIE A,%TNTV ; IS THIS A TV?
.VALUE [ASCIZ /:SORRY, XD ONLY WORKS ON TV'SKILL
/]
MOVEI A,ICORE ; SET UP FREE STORAGE LOSSAGE
.CORE (A)
.LOSE 1000
MOVEM A,CORSIZ
LSH A,12
MOVEM A,FSP
SETZM FREE
SETZM CHCNT
SETZI FONT, ; START WITH NO FONTS
.SUSET [.RSNAME,,FILDIR] ; SET UP DEFAULT FILE DIRECTORY
.SUSET [.ROPTION,,A] ; IS THERE IS JCL,
TLNN A,%OPCMD
JRST FI6 ; NO, ACCEPT INPUT FROM THE TTY
; READS INTO JCLBUF AND RETURNS TO FI3.
.BREAK 12,[..RJCL,,FILSPC] ; YES, READ IT IN.
FI3: MOVE A,[FILDEV,,XDEV] ; SET UP DEFAULTS
BLT A,XDIR
MOVE H,[440700,,FILSPC]
MOVE A,[ILDB A,H]
MOVEM A,RXCT ; INSN TO GIVE READER THE JCL.
PUSHJ P,READER
MOVE A,[XDEV,,FILDEV] ; SET UP THE FILE SPEC
BLT A,FILDIR
;OPEN THE FILE AND MAP IT INTO OUR ADDRESS SPACE
FI4: .CALL [ SETZ ;OPEN THE USERS FILE AGAIN
SIXBIT /OPEN/
[.UAI,,DSKICH]
JFFO ERRCOD ;ERROR CODE
FILDEV ;FILE SPEC
FILFN1
FILFN2
SETZ FILDIR]
JRST FI5 ;ERROR IN OPENING FILE.
.CALL [SETZ
SIXBIT /FILLEN/
MOVEI DSKICH ;CHANNEL
SETZM FILLEN]
.LOSE 1000
MOVE A,[-200,,100] ;MAP THE DISK FILE INTO ADDRESS SPACE
; STARTING AT LOCATION 200000
SETZ B,0
.CALL [SETZ ;MAP IT IN
SIXBIT /CORBLK/
MOVEI %CBRED ;TRY FOR READ ACCESS
MOVEI -1 ;HACK MY OWN CORE
A ;BLOCK MODE, GRAB AS MUCH AS POSSIBLE
MOVEI DSKICH ;CHANNEL
SETZ B] ;STARTING AT BEGINNING OF DISK FILE
.LOSE 1000
SETZM IOCNT ; SINCE WE HAVEN'T READ ANYTHING IN YET
MOVE H,[440700,,200000] ; SET UP THE BYTE POINTER FOR COMSCN,
JRST COMSCN ; AND START LOOKING FOR SCRIMP COMMANDS
;HERE FOR ERROR IN OPENING USERS FILE. GIVE HIM ERROR
; MESSAGE ON TTY, AND TRY AGAIN.
FI5: MOVEI A,[ASCIZ /ERROR /]
PUSHJ P,OUTST1
PUSHJ P,ERRDEV ;TYPE OUT ERROR MESSAGE FROM ERR DEVICE.
;GET FILENAME FROM TTY, WITH RUBOUT PROCESSING. RETURN TO FI3.
FI6: MOVEI A,[ASCIZ /INPUT FILE NAME? /]
PUSHJ P,OUTSTR
MOVE H,[440700,,FILSPC]
FI7: .IOT TTYICH,A
PUSHJ P,UCASE
ANDI A,%TXASC
CAIN A,177 ;RUBOUT
JRST FI9
IDPB A,H
CAIn A,15
JRST FI3 ; cariage return
cain a,07
jrst done ; control g
cain a,32
jrst done ; control z
JRST FI7 ; NOT A CR, GO GET MORE
FI9: CAME H,[440700,,FILSPC] ;LEADING RUBOUTS?
CAMN H,[10700,,FILSPC-1]
JRST FI7 ;IGNORE
DBP7 H
FI11: .IOT TTYOCH,[^P]
.IOT TTYOCH,["X] ;RUB IT OUT
JRST FI7
SUBTTL SCRIMP COMMAND SCANNER
;EXPECTS BYTE POINTER IN H.
COMSCN: SETZI B,
ILDB A,H
CAIE A,12 ;IF IT'S A LF
CAIN A,15 ;OR A CR
JRST COMSCN ;THEN IGNORE IT
CAIE A,";
JRST MAIN
CM1: ILDB A,H
PUSHJ P,UCASE ;MAKE IT UPPER CASE
CAIN A,40 ;SPACE, COMMAND WHICH TAKES ARG
JRST CM2
CAIN A,15 ;CR, MUST BE COMMAND WHICH TAKES NO ARG
JRST [ ILDB A,H
JRST COMSCN] ;IGNORE MEANINGLESS COMMAND
LSH B,6
CAIL A,"a ;CONVERT TO SIXBIT (USING HACK THAT
CAILE A,"z ; LOWER CASE IS ALREADY SIXBIT...
SUBI A,40
ANDI A,77
ADD B,A
JRST CM1
CM2: CAMN B,[SIXBIT/ KSET/]
JRST KSET
MOVE C,[-6,,0]
CM3: CAMN B,SCRDS(C)
JRST DECIN
AOBJN C,CM3
COMIGN: ILDB A,H ;SKIP REST OF LINE, AND IGNORE COMMAND
CAIE A,12
JRST COMIGN
JRST COMSCN ;IGNORE MEANINGLESS COMMAND
DECIN: SETZI B, ;READ IN DECIMAL NUMBER
DEC1: ILDB A,H
CAIN A,40 ;SPACE?
JRST DEC1 ;IGNORE.
CAIL A,"0
CAILE A,"9
JRST DEC2
IMULI B,10.
ADDI B,-"0(A)
JRST DEC1
DEC2: CAIE A,". ;DECIMAL POINT?
JRST DEC3
DEC4: ILDB A,H
CAIE A,15
JRST DEC4
DEC3: MOVEM B,TOPMAR(C)
JRST COMSCN
SCRDS: SIXBIT /TOPMAR/
SIXBIT /BOTMAR/
SIXBIT /LFTMAR/
SIXBIT / VSP/
SIXBIT / SKIP/
SIXBIT / SIZE/
; GENERAL PURPOSE ROUTINE TO UPPERCASIFY A LETTER IN A.
UCASE: trne a,%txctl
andi a,37
CAIL A,"a
CAILE A,"z
POPJ P, ;NOT LOWER CASE
SUBI A,40 ;MAKE IT UPPER CASE
CPOPJ: POPJ P,
;ROUTINES USED BY COMSCN
KSET: MOVE A,[KDEFLT,,XDEV] ; SET UP THE KSET DEFAULTS
BLT A,XDIR
MOVE A,[ILDB A,H] ; INSTRUCTION TO FETCH A CHAR
MOVEM A,RXCT
PUSHJ P,READER ; AND READ IN A FILENAME
JUMPL A,[SETZM FONDEV(FONT) ; IF NO FILENAME WAS READ, GO HERE.
JRST KSET1]
MOVE B,XDEV ; STOW AWAY THE RESULTS
MOVEM B,FONDEV(FONT)
MOVE B,XFN1
MOVEM B,FONFN1(FONT)
MOVE B,XFN2
MOVEM B,FONFN2(FONT)
MOVE B,XDIR
MOVEM B,FONDIR(FONT)
KSET1: ADDI FONT,1 ; COUNT ANOTHER FONT
HLLI A, ;CLEAR LEFT HALF
CAIE A,", ; WAS THE LAST CHAR A COMMA?
JRST COMSCN
JRST KSET ; YES, GO BACK FOR MORE
SUBTTL GET FONTS, INITIALIZE
;;; ENTER HERE WITH FONT=0 IF NO FONTS WERE SPECIFIED, OR FONT = <# OF FONTS>
MAIN:
; ****** THIS IS AN INELEGANT KLUDGE, I REALIZE, BUT AT LEAST
; I'M DOCUMENTING IT... IF LUSER HAS SPECIFIED NO FONTS AT ALL, GIVE
; HIM THE DEFAULT AND READ IT IN ANYWAY.
JUMPN FONT,[ SUBI FONT,1
JRST M9]
MOVE B,KDEFLT ;MOVE IN THE DEFAULT
MOVEM B,FONDEV
MOVE B,KDEFLT+1
MOVEM B,FONFN1
MOVE B,KDEFLT+2
MOVEM B,FONFN2
MOVE B,KDEFLT+3
MOVEM B,FONDIR
; ****** END OF INELEGANT KLUDGE.
;NOW FONT=INDEX OF HIGHEST FONT.
M9: MOVEM FONT,NFONTS
SKIPE FONDEV(FONT) ;IF DEVICE=0, THIS FONT WAS NOT SPECIFIED
PUSHJ P,KSTRED
SOJGE FONT,.-2
PUSHJ P,REORG ;GENERATE THE REORGANIZED COPY OF THE FONTS
MOVE A,CORSIZ ;SAVE NEW FREE CORE STATISTICS
MOVEM A,FCRSIZ
LSH A,12
MOVEM A,FCORE
;OPEN THE TV BUFFER AT TVBBAS
MOVE A,[-11,,TVBBAS/2000]
SETZI B,
.CALL [SETZ
SIXBIT /CORBLK/
MOVEI %CBWRT+%CBRED ;TRY FOR READ AND WRITE ACCESS
MOVEI -1 ;HACK MY OWN CORE
A ;BLOCK MODE, GET ALL 10 PAGES OF TV BUFFER
; AND PUT THEM AT TVBBAS
MOVEI %JSTVB ;VIDEO BUFFER PAGES
SETZ B] ;STARTING AT ZERO PAGE OF THE TV BUFFER
.LOSE 1000
;INITIALIZE VARIOUS VARIABLES
PUSHJ P,ICHBP
SETZM XOFF ;START OFF IN HOME POSITION
SETZM YOFF
SETZM GOPAGC
PUSHJ P,DSPLAY ;DISPLAY THE FIRST PAGE
MOVE A,BCHBP
MOVEM A,CHBP
pushj p,port
.SUSET [.SMSK2,,[1_TTYICH]] ;ENABLE INTERRUPT
JRST CURSOR
SUBTTL MAIN DISPATCH ROUTINE
CURSOR: SETZM INTFLG ;WE DON'T WANT INTERRUPTS NOW
.IOT TTYOCH,[^P] ;HOME DOWN CURSOR
.IOT TTYOCH,["Z]
SKIPN FLAG ;THIS IS THE HACK FOR PEOPLE WHO GO OFF THE END
; OF THE FILE WITH THE P COMMAND.
JRST CUR2
MOVEI A,[ASCIZ/SORRY, THAT EXCEEDS THE LENGTH OF THE FILE./]
PUSHJ P,OUTSTR
SETZM FLAG
JRST CURSOR
CUR2: MOVEI A,[ASCIZ/PAGE #/]
PUSHJ P,OUTST1
MOVE A,PAGENO
PUSHJ P,DECTYP ;TYPE OUT PAGE NUMBER
MOVEI A,[ASCIZ/ -->/]
PUSHJ P,OUTST1
.IOT TTYICH,A
SETZI C,
CUR1: TRZ A,%TXSFL+%TXSFT ;COMPUTE THE MULTIPLIER IN B
MOVEI B,1
TRZE A,%TXTOP
LSH B,4 ;TOP
TRZE A,%TXMTA
LSH B,2 ;META
TRZE A,%TXCTL
LSH B,1 ;CONTROL
CAIE A,"[ ;OPEN-BRACKET
CAIN A,"{ ;OR OPEN-BRACE
JRST LEFT
CAIE A,"] ;CLOSE-BRACKET
CAIN A,"} ;OR CLOSE-BRACE
JRST RIGHT
CAIE A,"\ ;BACKSLASH
CAIN A,"| ;OR VERTICAL LINE
JRST UP
CAIE A,"/ ;SLASH
CAIN A,16 ;OR INFINITY-SIGN
JRST DOWN
PUSHJ P,UCASE ;MAKE IT UPPER CASE
CAIN A,"N ;MAIN DISPATCH TABLE
JRST NEXTPG
CAIN A,"Q
JRST DONE
CAIN A,"R
JRST SHOW1
CAIN A,"H
JRST HOME
CAIN A,"C
JRST CENTER
CAIN A,^F ; (TOP C)
JRST TOPCEN
CAIN A,"A
JRST SKIPAG
CAIN A,"P
JRST GOPAG
CAIN A,"?
JRST HELP
CAIN A,"M
JRST [ SETOM MODE
JRST SHOW]
CAIGE A,"0
JRST CURSOR
CAILE A,"9
JRST CURSOR
JRST RD1
RDDEC: .IOT TTYICH,A ;READ IN A DECIMAL #, DIGITS IN A, RETURN IT IN C
ANDI A,%TXASC
CAIL A,"0
CAILE A,"9
JRST CUR1
RD1: IMULI C,10.
ADDI C,-"0(A)
JRST RDDEC
SUBTTL RANDOM COMMANDS
LEFT: MOVEI A,60
IMUL A,B
ADDM A,XOFF
JRST SHOW1
RIGHT: MOVE A,[-60]
IMUL A,B
ADDM A,XOFF
JRST SHOW1
UP: MOVEI A,60
IMUL A,B
ADDM A,YOFF
JRST SHOW1
DOWN: MOVE A,[-60]
IMUL A,B
ADDM A,YOFF
JRST SHOW1
HOME: SETZM XOFF
SETZM YOFF
JRST SHOW1
CENTER: MOVEI A,1100
MOVEM A,XOFF
MOVEI A,1500
MOVEM A,YOFF
JRST SHOW1
TOPCEN: MOVEI A,1100
MOVEM A,XOFF
SETZM YOFF
JRST SHOW1
HELP: MOVEI A,[ASCIZ# XD COMMANDS:
N---NEXT PAGE
H---HOME WINDOW TO TOP LEFT
C---CENTER WINDOW ON PAGE
TOP-C MOVE WINDOW TO TOP CENTER OF PAGE
Q---QUIT
R---REDISPLAY PAGE
M--REDISPLAY PAGE IN MINI-DISPLAY MODE
nA--ADVANCE n PAGES
nP--GO TO nTH PAGE
?---TYPE THIS CRUFT
[---MOVE PAGE LEFT \ / CTRL MULTIPLIES BY 2
]---MOVE PAGE RIGHT |--| META MULTIPLIES BY 4
\---MOVE PAGE UP | | TOP MULTIPLIES BY 8
/---MOVE PAGE DOWN / \ SHIFT IS IGNORED
FOR MORE DETAILED INSTRUCTIONS, SEE .INFO.;XD ORDER.
#]
PUSHJ P,OUTSTR
JRST CURSOR
SUBTTL PAGE MOVING ROUTINES
SHOW1: SETZM MODE ;(ENTRY TO RETURN TO REGULAR MODE)
SHOW: PUSHJ P,DSPLAY ;REDISPLAY THE PAGE
MOVE A,BCHBP
MOVEM A,CHBP
pushj p,port
JRST CURSOR
port: movei a,cset
dpb a,[cregfn,,creg] ; do MOVEMs
movei c,38.
movei a,18.
move b,[400000,,000020]
port1: movem b,tvbbas+17.(a)
addi a,18.
sojg c,port1
hrrei b,-20
movem b,tvbbas+17.
movem b,tvbbas+17.+<18.*39.>
movei a,cior
dpb a,[cregfn,,creg] ; do IORs
move c,[777000,,0]
move d,xoff
idiv d,[-60]
lsh c,(d)
movei d,9.
move a,yoff
idivi a,60
imuli a,18.
port2: movem c,tvbbas+17.(a)
addi a,18.
sojg d,port2
popj p,
DONE: .BREAK 16,160000
NEXTPG: MOVEI C,1
SKIPAG: JUMPLE C,CURSOR ;SKIPS OVER THE NUMBER OF PAGES DESIGNATED IN C
MOVE A,PAGENO
MOVEM A,SPAGEN
SK4: MOVE B,TOPMAR ; MINUS 1
ADD B,BOTMAR
SK1: PUSHJ P,FILEND
JRST SLOSES ;ERROR RETURN, END OF FILE
PUSH P,B
PUSHJ P,SCAN ;CHECK FOR FALLING OFF THE PHYSICAL PAGE
POP P,B
ADD B,MXDP
ADD B,MXBS
CAIL B,2200.
JRST SK3
SK2: ILDB A,CHBP
CAIN A,12 ;LINE FEED
JRST SK1
CAIN A,14 ;FORM FEED
JRST SK3
CAIE A,177 ;XGP ESCAPE
JRST SK2 ;NORMAL CHARACTER, KEEP GOING
ILDB A,CHBP ;INTERPRET ESCAPED CHARACTER
CAILE A,3
JRST SK2 ;NOTHING INTERESTING
JRST @.+1(A) ;DISPATCH ON TYPE OF ESCAPE CODE
SK2
SKESC1
SKESC2
SKESC3
SKESC1: ILDB A,CHBP
CAIGE A,40
JRST SK2 ;LOW NUMBERS ARE FONT CHANGES
CAIL A,40+X1DSPL
.VALUE [ASCIZ /
: Error! This file contains XGP commands not supported here.
Please :BUG XD for help. 
/]
JRST @.+1-40(A)
SKE1T: SKIP2 ;40
SKIP3 ;41
SKIP1 ;42
SKIP1 ;43
[.VALUE] ;44
[.VALUE] ;45
SK2 ;46
SKIP1 ;47
SKIP1 ;50
SKIP2 ;51
SKIP1 ;52
SKIP3 ;53
SKIP3: IBP CHBP
SKESC3:
SKIP2: IBP CHBP
SKESC2:
SKIP1: IBP CHBP
JRST SK2
SK3: AOS PAGENO
SOJLE C,SK5
JRST SK4
SK5: PUSHJ P,FILEND
JRST SLOSES
MOVE A,CHBP
MOVEM A,BCHBP
JRST SHOW
GOPAG: SUB C,PAGENO
JUMPE C,SHOW ;GO TO RIGHT HERE
JUMPG C,SKIPAG ;SKIP UNTIL WE GET THERE
ADD C,PAGENO ;WE MUST GO BACK TO THE BEGINNING
PUSHJ P,ICHBP ;REINITIALIZE CHBP AND PAGENO
SUBI C,1 ;BECAUSE TO GO TO N FROM 1, YOIU SKIP N-1
CAIE C,0
JRST SKIPAG
; PUSHJ P,DSPLAY
; MOVE A,BCHBP
; MOVEM A,CHBP
; JRST CURSOR
jrst show
SLOSES: SETOM FLAG ;SO THAT IT PRINTS THE MESSAGE
PUSHJ P,ICHBP ;REINITIALIZE CHBP AND PAGENO
MOVE C,SPAGEN ;GO BACK TO WHERE HE CAME FROM
JRST GOPAG
SUBTTL DISPLAY THE PAGE
DSPLAY: SETOM INTFLG ;ALLOW INTERRUPTS
.STATUS TTYICH,A
TRNN A,20000 ;PENDING CHARACTERS?
JRST DS5 ;NO, GO AHEAD
POP P, ;IGNORE SAVED RETURN ADDRESS
JRST CURSOR
DS5: .IOT TTYOCH,[^P] ;HOME DOWN CURSOR
.IOT TTYOCH,["Z]
.iot ttyoch,[^P] ; clear to end of line
.iot ttyoch,["L]
MOVEI A,3 ;WAIT 1/10 SEC FOR 11 TO BLINK CURSOR.
.SLEEP A, ; (SUPER-HAIRY PROCESS COORDINATION.)
MOVEI A,CSET ;SET ALU FUNCTION TO DO MOVEMS.
DPB A,[CREGFN,,CREG]
MOVE A,[-17754,,TVBBAS] ;CLEAR THE TV
SETZM (A) ;(CANNOT USE BLT HACK SINCE TV MEMORY IS
AOBJN A,.-1 ; TOO UNRELIABLE, AND IT'S SLOWER)
SETZI FONT,
MOVEI A,CIOR
DPB A,[CREGFN,,CREG] ;SET ALU FUNCTION TO DO IORMS
SKIPL MODE ;IF IN M-MODE, PRINT OUT THE BORDER
JRST DS1
;THE XGP IS 1700 DOTS ACROSS. WE SQUEEZE BY 4, GIVING US 425 TV DOTS
; IN THE TOP AND BOTTOM LINES. WITH 32 BITS PER WORD DISPLAYED, THIS IS
; 13 WORDS PLUS 9 BITS. THE TOP LINE IS ON THE TOP OF THE TV, AND THE
; BOTTOM LINE IS 2200./5.=440. LINES DOWN AND STARTS AT TVBBAS+440.*18.=7920.
MOVE C,[-13.,,0]
HRREI A,-20
DS2: MOVEM A,TVBBAS(C)
MOVEM A,TVBBAS+7920.(C)
AOBJN C,DS2
HRLZI A,-1000
MOVEM A,TVBBAS(C)
MOVEM A,TVBBAS+7920.(C)
;NOW PUT IN THE RIGHT AND LEFT WALLS. THERE ARE 440. TV LINES TO BE
; CHANGED, AND THE BITS TO BE SET ARE THE FIRST BIT AND THE 14TH WORD'S
; 9TH BIT FORM THE LEFT.
MOVEI C,440.
SETZI D,
HRLZI A,400000
HRLZI B,1000
DS3: IORM A,TVBBAS(D)
IORM B,TVBBAS+13.(D)
ADDI D,18.
SOJG C,DS3
DS1: MOVE A,LFTMAR ;INITIALIZE TVXP, TVYP, ETC.
SUB A,XOFF
MOVEM A,TVXP
MOVEM A,ITVXP
MOVE A,TOPMAR
SUB A,YOFF
MOVEM A,TVYP
MOVEM A,ITVYP
IMULI A,18.
ADDI A,TVBBAS
MOVEM A,LTVWD
MOVEI A,576.
MOVEM A,MXTVXP
SETZM STTVYP
;; FOLLOWING PARAGRAPH IS A KLUDGE SO THAT XESC3'S ARE HACKED ON THE FIRST LINE
;; OF A PAGE.
SETZM X3FLAG
PUSHJ P,SCAN
SKIPN X3FLAG
JRST NEWCHR
MOVE A,X3VAL ; THERE WAS AN XGP ESACPE 3.
SUB A,YOFF
MOVEM A,TVYP
MOVEM A,ITVYP
IMULI A,18.
ADDI A,TVBBAS
MOVEM A,LTVWD ; CONVERT INTO AN ADDRESS IN TV MEMORY
NEWCHR: ILDB A,CHBP
CAIN A,0 ;IGNORE NULL BYTE
JRST NEWCHR
CAIG A,7
JRST NORMAL
CAIN A,13
JRST NORMAL
CAIN A,177
JRST ESCAPE
CAILE A,15
JRST NORMAL
JRST @DISTAB-10(A) ;DISPATCH TABLE
;This routine is used for displying characters which are handled
; normally by the xgp. "Normal" decides which version of tvchr to use, and
; also handles the xgp's feature that characters off the end of the paper
; do not get printed. (it may be that the xgp will print part of a char on the
; very edge of the paper, but since this is not ever a desirable feature, etc.,
; xd simply doesn't print such chars at all. This seems like a reasonable short-cut.)
NORMAL: MOVE CODE,A
MOVE A,@CHARDT(FONT)
HRRZ A,(A) ;CHARACTER WIDTH
ADD A,TVXP
ADD A,XOFF ;IGNORE OFFSET
CAIL A,1700. ;IS RIGHT EDGE OF CHAR OFF THE PAPER?
JRST NEWCHR ; YES, FORGET IT.
SKIPGE MODE ;ARE WE IN M-MODE?
JRST [ PUSHJ P,MTVCHR ;YES
JRST NEWCHR]
MOVE A,TVYP ;NO, WE MUST BE IN NORMAL MODE
CAIL A,454. ;ALL OFF BOTTOM?
JRST NEWCHR
ADD A,MXBS
ADD A,MXDP
CAIL A,0 ;ALL OFF TOP?
PUSHJ P,TVCHR
JRST NEWCHR
DISTAB: BS ;BACKSPACE
TAB ;TAB
LF ;LINEFEED
0 ;SHOULDN'T HAPPEN, 13 IS NORMAL
FF ;FORM FEED
CR ;CARRIAGE RETURN
ESCAPE: ILDB A,CHBP
CAIN A,13
JRST RES ;RESERVED
CAIN A,0
JRST NORMAL
CAIG A,7
JRST @EDSTAB-1(A) ;ESCAPE DISPATCH TABLE
CAIL A,40
JRST NORMAL
CAIG A,16
JRST NORMAL
JRST RES
EDSTAB: XESC1
XESC2
XESC3
XESC4
RES ;NEW XGP ESCAPES WOULD GO HERE
RES
RES
BS: MOVEI CODE,40 ;SPACE
MOVE A,@CHARDT(FONT)
HRRZ A,(A) ;CHAR WIDTH
MOVN A,A
ADDM A,TVXP
JRST NEWCHR
TAB: MOVE A,TVXP
ADD A,XOFF ;TO GET XGPXP
SUB A,LFTMAR ;COMPENSATE FOR MARGIN
MOVE CODE,C40
MOVE F,@CHARDT(FONT)
HRRZ C,(F) ;CHARACTER WIDTH OF A SPACE IN THIS FONT
ADD A,C ;TAB ALWAYS GOES AT LEAST ONE SPACE
IMULI C,8.
IDIV A,C
AOJ A,
IMUL A,C ;ROUND UP
SUB A,XOFF ;UNCOMPENSATE FOR OFFSET
ADD A,LFTMAR ;UNCOMPENSATE FOR MARGIN
MOVEM A,TVXP
JRST NEWCHR
FF: POPJ P,
CR: MOVE A,LFTMAR
SUB A,XOFF
MOVEM A,TVXP
JRST NEWCHR
RES: JRST NEWCHR
LF: SETZM ICS ;ICS RESET AT END OF LINE
PUSHJ P,FILEND
POPJ P,
;HACK THE RESETTING OF THE X POSITION.
MOVE A,LFTMAR
SUB A,XOFF
MOVEM A,TVXP
MOVEM A,ITVXP
;SCAN
SETZM X3FLAG
PUSHJ P,SCAN
;NOW FIGURE OUT WHAT HAPPENED TO THE Y POSITION. FIRST LOOKS FOR XESC3'S.
SKIPN X3FLAG
JRST LF1
MOVE A,X3VAL ; THERE WAS AN XGP ESACPE 3.
SUB A,YOFF
JRST LF3
;NO XESC3'S. NOW, WAS THIS AN XESC1 42 RATHER THAN A REAL LF?
LF1: SKIPN LSFLAG ; THIS WANSN'T REALLY A LF, IT WAS AN XESC1 42
JRST LF2
SETZM LSFLAG
MOVE A,MXDP
ADD A,MXBS
CAMGE A,LS
MOVE A,LS
ADD A,ITVYP
JRST LF3
LF2: MOVE A,MXDP ; COMPUTE THE NEW TVYP FROM THE OLD TVYP.
ADD A,MXBS ; (THESE ARE THE SCANNER PARAMETERS OF THE OLD LINE.)
ADD A,VSP ; (FROM THE ";VSP" COMMAND.)
ADD A,ITVYP ; INITIAL TVYP OF THE OLD LINE
;HERE A HAS THE NEW TV Y POSITION.
LF3: MOVEM A,TVYP ; GOT IT, BUT MAY OVERRIDE LATER IN SCANNER.
MOVEM A,ITVYP
IMULI A,18.
ADDI A,TVBBAS
MOVEM A,LTVWD ; CONVERT INTO AN ADDRESS IN TV MEMORY
;NOW CHECK FOR AUTO-EJECT, USING THE RESULTS OF SCAN.
MOVE A,MXBS
ADD A,MXDP
ADD A,TVYP ; (WHICH WE JUST COMPUTED ABOVE)
ADD A,YOFF ; TURN IT INTO AN XGPYP
ADD A,BOTMAR
CAILE A,2200. ; NUMBER OF SCAN LINES ON AN 11 INCH PAGE
POPJ P, ; AUTOMATIC EJECT STRIKES AGAIN.
JRST NEWCHR
XESC1: ILDB A,CHBP
CAIL A,40+X1DSPL
.VALUE [ASCIZ /
: Error! This file contains XGP commands not supported here.
Please :BUG XD for help. 
/]
CAIL A,40
JRST @X1DSP-40(A)
MOVE FONT,A
MOVE A,[BASE,,ABASE]
BLT A,ABASE+MXNFNT-1
JRST NEWCHR
X1DSP: X40
X41
X42
X43
XHUH
XHUH
X46
X47
X50
X51
X52
X53
X1DSPL=.-X1DSP
X40: PUSHJ P,G2CHBP ; XGP COLUMN SELECT, ASCII SPACE
SUB B,XOFF ; NEXT TWO BITS ARE 14-BIT NEW XGPXP
MOVEM B,TVXP
JRST NEWCHR
;GET A 14-BIT NUMBER FROM THE CHBP STREAM INTO B. CLOBBERS A.
G2CHBP: ILDB A,CHBP
MOVE B,A
LSH B,7
ILDB A,CHBP
ADD B,A
POPJ P,
X41: ILDB A,CHBP ;XGP UNDERSCORE, ASCII !
MOVE B,A ; NEXT 7 BITS TWO'S-COMP. SCAN LINE OFFSET
TRNE B,100 ;EXTEND SIGN.
SUBI B,200
ILDB A,CHBP ; (POSITIVE => DOWN) NEXT 14 BITS LENGTH OF
MOVE C,A ; UNDERSCORE
LSH C,7
ILDB A,CHBP
ADD A,C
MOVE C,TVXP
PUSHJ P,UNDRSC ;(THIS ROUTINE DOES THE WORK)
JRST NEWCHR
X42: ILDB A,CHBP ;LINE SPACE, ASCII "
MOVEM A,LS ;DO LF, AND NEXT 7 BITS # OF LINES BETWEEN THIS LINES
SETOM LSFLAG ;BASELINE, AND THE NEW LINE'S.
JRST LF
X43: ILDB A,CHBP ;BASE-LINE ADJUST, ASCII #
CAILE A,77 ;NEXT SEVEN BITS ARE ADDED TO BASELINE TEMPORARILY
SUBI A,200 ;NEGATIVE?
ADD A,BASE(FONT)
MOVEM A,ABASE(FONT)
JRST NEWCHR
X46: MOVE A,TVXP ;START UNDERSCORE, ASCII &
MOVEM A,STAUND
JRST NEWCHR
X47: ILDB A,CHBP ;STOP UNDERSCORE, ASCII '
MOVE B,A ; BYTE IS SCAN LINE INCREMENT, LIKE X41
TRNE B,100 ;EXTEND SIGN.
SUBI B,200
MOVE A,TVXP
MOVE C,STAUND
SUB A,C
PUSHJ P,UNDRSC
JRST NEWCHR
X50: ILDB A,CHBP ;INTERCHARACTER SPACING, ASCII (
MOVEM A,ICS
JRST NEWCHR
X51: ILDB D,CHBP ;THICKNESS OF UNDERLINE
ILDB B,CHBP
TRNE B,100 ;EXTEND SIGN.
SUBI B,200
JUMPLE D,NEWCHR
MOVE A,TVXP
MOVE C,STAUND
SUB A,C
X51A: PUSH P,D
PUSHJ P,UNDRSC
POP P,D
ADDI B,1
SOJG D,X51A
JRST NEWCHR
X52: ILDB A,CHBP ;RELATIVE BASE-LINE ADJUST, ASCII #
CAILE A,77 ;NEXT SEVEN BITS ARE ADDED TO ADJUSTED BASELINE TEMPORARILY
SUBI A,200 ;NEGATIVE?
ADD A,ABASE(FONT)
MOVEM A,ABASE(FONT)
JRST NEWCHR
X53: ILDB A,CHBP ;RELATIVE XGP UNDERSCORE, ASCII !
MOVE B,A ; NEXT 7 BITS TWO'S-COMP. SCAN LINE OFFSET
TRNE B,100 ;EXTEND SIGN.
SUBI B,200
ILDB A,CHBP ; (POSITIVE => DOWN) NEXT 14 BITS LENGTH OF
MOVE C,A ; UNDERSCORE
LSH C,7
ILDB A,CHBP
ADD A,C
MOVE C,TVXP
ADD B,BASE(FONT)
SUB B,ABASE(FONT)
PUSHJ P,UNDRSC ;(THIS ROUTINE DOES THE WORK)
JRST NEWCHR
XESC2: ILDB A,CHBP ;NEXT 7 BITS ARE XGPXP INCREMENT
CAILE A,77
SUBI A,200
ADDM A,TVXP
JRST NEWCHR
XESC3: ILDB A,CHBP ;SCAN LINE OF THIS TEXT LINE
MOVE B,A
LSH B,7
ILDB A,CHBP
ADD B,A
MOVEM B,STTVYP
JRST NEWCHR
XESC4: JRST NEWCHR
XHUH: .VALUE [ASCIZ /:NO SUCH XESC/]
SUBTTL UNDERSCORE ROUTINE
; Arguments passed to this routine
; A / length of underscore
; B / baseline increment
; C / starting tv x-position
UNDRSC: PUSH P,A
PUSH P,B
PUSH P,C
ADD B,TVYP
ADD B,MXBS
; Now, B / the tvyp of the underscore.
JUMPL B,UNDR9
CAIGE B,454.
CAIL C,576.
JRST UNDR9
SKIPE MODE
JRST UNDR9 ;NO UNDERSCORES IN MINI-MODE!!!!
MOVEI D,576.
SUB D,C ;ROOM TO THE RIGHT
CAIL A,(D)
MOVEI A,(D) ;TRUNCATE ON THE RIGHT
JUMPGE C,UNDRS1
ADD A,C ;TRUNCATE ON THE LEFT
SETZI C,
UNDRS1: JUMPLE A,UNDR9
LDB D,[053700,,C] ;WORD-ADDRESS PART OF C.
MOVE E,B
IMULI E,18.
ADDI D,TVBBAS(E)
MOVNI G,20
MOVNI H,1
;NOW ALL ARGUMENTS DESCRIBE A PERFECTLY LEGAL LINE, ALL ON THE SCREEN.
;THE FOLLOWING IS A PER-WORD LOOP. WHEN WE GET HERE THE ACS ARE SET UP TO:
; A / NUMBER OF POINTS REMAINING TO HACK
; B / Y POSITION
; C / X POSITION
; D / CURRENT WORD'S EFFECTIVE ADDRESS
; G / WORD OF ONES TO MOVEM
; H / WORD FULL OF ONES TO DPB
UNDL: LDB E,[000500,,C] ;BIT-POSITION PART.
MOVNS E
ADDI E,32. ;BITS REMAINING IN CURRENT WORD
CAIL E,(A)
MOVE E,A ;E / # OF BITS TO HACK THIS TIME AROUND THE LOOP
; = MIN(BITS_LEFT_IN_WORD,BITS_LEFT_TO_DO)
CAIN E,32.
JRST UNDWRD ;WHOLE WORD, DO QUICKLY
LDB F,[000500,,C] ;BIT POSITION IN WORD
MOVNS F
ADDI F,36.
SUBI F,(E) ;F / 36. - SIZE_OF_BYTE - BIT_POS_IN_WORD
LSH F,36 ;PUT IN PP FIELD
DPB E,[300600,,F] ;PUT IN THE SS FIELD
HRR F,D ;F / BP TO THE BYTE WE WANT TO HACK
DPB H,F ;PUT IN ONES.
JRST UNDXL
UNDWRD: MOVEM G,(D)
UNDXL: SUBI A,(E)
JUMPE A,UNDR9
ADDI C,(E)
AOJA D,UNDL
UNDR9: POP P,C
POP P,B
POP P,A
POPJ P,
SUBTTL READ IN FONT
COMMENT $ XD INTERNAL FORMAT
CHARD(CODE) ;points to character description
FORMAT OF CHARACTER DESCRIPTION
LEFT_KERN,,CHARACTER_WIDTH
;used to be CHARIACTER ID
WORDS_PER_RASTER_LINE,,RASTER_WIDTH
CHARACTER_MATRIX
;THE MATRIX IS STORED ONE COLUMN OF BYTES AT A TIME,
;INVERTED FROM THE KST SO IT GOES THE RIGHT WAY.
$
KSTRED: .CALL [SETZ ;OPEN THE FONT FIE
SIXBIT /OPEN/
JFFO ERRCOD ;ERROR CODE
[.BII,,FNTICH]
FONDEV(FONT) ;FILE SPEC, INDEXED BY FONT
FONFN1(FONT)
FONFN2(FONT)
SETZ FONDIR(FONT)]
JRST NOFONT
SETZM IOCNT
PUSHJ P,WORDIN ;READ KST ID WORD. (UNUSED)
MOVEM A,KSTID(FONT)
PUSHJ P,WORDIN ;READ IN HEIGHT,BASE LINE,CPA
HRRZM A,HEIGHT(FONT)
LDB B,[221100,,A]
MOVEM B,BASE(FONT)
MOVEM B,ABASE(FONT) ;INITIAL BASE LINE ADJUST IS ZERO
LDB B,[331100,,A]
MOVEM B,CPA(FONT)
SETZI CODE, ;ZERO OUT THE CHARDT BLOCK
MOVE A,CHARDT(FONT)
SETZM (A)
MOVEI B,MXSTSZ-1(A)
HRL A,A
ADDI A,1
BLT A,B ;I.E., THE BLT HACK
MOVEI E,MXSTSZ ;FOR EACH CHAR. IN THE FONT...
KST1: PUSHJ P,CHARIN ;CHEW UP A CHAR.
MOVE A,MISSED
JUMPN A,KST2
KST3: SOJG E,KST1 ;LOOP AROUND
KST4: .CLOSE FNTICH, ;LEAVE
POPJ P,
KST2: SKIPE IOCNT ;IF IOCNT=0 AND MISSED0, IT IS THE END OF THE FILE
JRST KST3
JRST KST4
NOFONT: MOVEI A,[ASCIZ /ERROR READING FONT FILE:/]
PUSHJ P,OUTSTR
IRPS XXX,DEL,[DEV: DIR; FN1 FN2 ]
MOVE A,FON!XXX(FONT)
PUSHJ P,SIXTYP
.IOT TTYOCH,["!DEL!]
TERMIN
PUSHJ P,ERRDEV
.VALUE
;READ IN A KST CHARACTER
CHARIN: PUSHJ P,WORDIN ;USER ID, IGNORE
PUSHJ P,WORDIN ;LEFT KERN,,CODE
HRRZ CODE,A
HLLM A,TEMP
CAIN CODE,777777
POPJ P, ; HANDY END-OF-FILE MARKER?
CAILE CODE,177
JRST [ MOVEI A,[ASCIZ/ILLEGAL CODE
/] ; ILLEGAL CODE
JRST TERPRI] ; I.E., PRINT OUT AND RETURN
SKIPE @CHARDT(FONT)
JRST [ MOVEI A,[ASCIZ/DUPLICATE CHARACTER/]
PUSHJ P,TERPRI
JRST .+1]
PUSHJ P,CONS
MOVEM A,@CHARDT(FONT)
MOVE B,A
PUSHJ P,WORDIN ;RASTER WIDTH,,CHARACTER WIDTH
HLL C,TEMP
HRR C,A
MOVEM C,(B) ;LEFT KERN,,CHARACTER WIDTH
HLRZ C,A ;GET RASTER WIDTH
SKIPN C
HRRZ C,(B)
HRRZ B,C ;RASTER WIDTH
ADDI B,7.
LSH B,-3 ; I.E. IDIVI B,8. BYTES PER ROW
CAILE B,72.
.VALUE [ASCIZ/:BPR TOO BIG
/]
HRRZM B,BPR
HRL C,B
PUSHJ P,CONS
MOVEM C,(A)
PUSHJ P,CONS
HRR PTO,A
HRLI PTO,441000
MOVE D,HEIGHT(FONT)
SETZI PTI,
CH1: PUSHJ P,ROWIN ;READ IN A ROW
SOJG D,CH1
POPJ P,
; READ IN A LINE OF KST FONT MATRIX
; FROM DISK INTO FREE STORAGE
ROWIN: MOVE B,BPR
BYTEIN: TLNE PTI,700000
JRST CR1
PUSHJ P,WORDIN
MOVE C,A
MOVE PTI,[441000,,C]
CR1: ILDB T,PTI
CIRC T,-10 ; SECURITY IN OBSCURITY
TLNE PTO,700000
JRST CR3
PUSHJ P,CONS
HRR PTO,A
HRLI PTO,441000
CR3: IDPB TT,PTO
SOJG B,BYTEIN
POPJ P,
SUBTTL REORGANIZE THE CHARACTER MATRICIES
REORG: MOVE FONT,NFONTS ;INDEX OF HIGHEST FONT
RE3: SKIPN FONDEV(FONT) ;SKIP NON-EXISTANT FONTS.
SOJGE FONT,RE3
JUMPL FONT,CPOPJ
MOVE CODE,[-MXSTSZ,,0] ;FOR ALL CHARS
RECHR: MOVE A,@CHARDT(FONT)
JUMPE A,RE1
HLRZ B,1(A)
MOVEM B,BPR ;SAVE NUMBER OF BYTES PER ROW
MOVE B,(A)
MOVEM B,REBUF
MOVE B,1(A)
MOVEM B,REBUF+1
ADDI A,2 ;SET UP THE BYTE POINTERS
MOVEM A,TEMP
HRLI A,341000
MOVEM A,INBP
MOVE A,[441000,,REBUF+2]
MOVEM A,OUTBP
MOVE B,BPR
RECOL: MOVE C,INBP
MOVE D,HEIGHT(FONT)
REBYT: LDB A,C
MOVE E,BPR
IBP C
SOJG E,.-1
IDPB A,OUTBP
SOJG D,REBYT
IBP INBP
SOJG B,RECOL
;NOW COPY THE CONTENTS OF REBUF BACK INTO THE CHARACTER.
HRLI A,REBUF ;POINTER TO REBUF IN LH
HRR A,@CHARDT(FONT) ;POINTER TO CHARDT AREA IN RH
MOVE B,OUTBP
SUBI B,REBUF ;B/ NUMBER OF WORDS IN REBUF-1
ADD B,@CHARDT(FONT) ;LAST LOCATION TO STORE INTO
BLT A,(B) ;AND COPY
RE1: AOBJN CODE,RECHR
SOJGE FONT,RE3
POPJ P,
SUBTTL THE SCANNER
;THIS ROUTINE DOES THE FIRST PASS OVER EACH LINE,
; FINDING THE MAXIMUM BASELINE AND MAXIMUM DEPTH
; (# OF LINES BELOW THE BASELINE) FOR THE LINE.
;THIS IS TO HELP LINE UP CHARS IN DIFFERENT
; FONTS ALONG THEIR BASELINES, AND TO SEE HOW FAR
; DOWN THE TEXT GOES ON THE PAGE, TO SEE IF THE XGP
; DO AN AUTOMATIC EJECT.
SCAN: PUSH P,CHBP
MOVE A,ABASE(FONT)
MOVEM A,MXBS
MOVE A,HEIGHT(FONT)
SUB A,ABASE(FONT)
MOVEM A,MXDP
SCLOOP: ILDB A,CHBP
CAIE A,12 ;LINE FEED
CAIN A,14 ;FORM FEED
JRST SCEND
CAIN A,177
JRST SCESC
JRST SCLOOP
SCEND: POP P,CHBP
POPJ P,
SCESC: ILDB A,CHBP
CAILE A,3
JRST SCLOOP
JRST @SCDT(A)
SCDT: SCLOOP ;0 IS NORMAL
SCESC1 ;XGP ESCAPE 1
SC1 ;XGP ESCAPE 2
SCXE3 ;XGP ESCAPE 3
SCESC1: ILDB A,CHBP
CAIE A,51
CAIN A,40
JRST SC2
CAIN A,41
JRST SC3
CAIE A,52
CAIN A,43
JRST SC1
CAIN A,47
JRST SC1
CAIN A,50
JRST SC1
CAILE A,3
JRST SCLOOP
PUSH P,B
MOVE B,ABASE(A)
CAMLE B,MXBS
MOVEM B,MXBS
MOVE B,HEIGHT(A)
SUB B,ABASE(A)
CAMLE B,MXDP
MOVEM B,MXDP
POP P,B
JRST SCLOOP
SC3: IBP CHBP
SC2: IBP CHBP
SC1: IBP CHBP
JRST SCLOOP
SCXE3: PUSHJ P,G2CHBP
MOVEM B,X3VAL
SETOM X3FLAG
JRST SCLOOP
SUBTTL ROUTINE TO PUT CHARACTERS INTO DISPLAY MEMORY
;CHARS CAN BE OFF SCREEN FOR SEVERAL REASONS:
;ALL OF THE CHAR CAN BE OFF THE RIGHT OR LEFT EDGES
; THIS IS HANDLED BY THE COMPARISONS OF TVXP AND TVXPR AT TVCHR+11, ETC.
;ALL OF THE CHAR CAN BE OFF THE TOP OR BOTTOM EDGES
; THIS IS HANDLED BY THE CALLING ROUTINE (NORMAL:) [WHICH MAY BE A LOSING WAY]
;PART OF THE CHAR CAN BE OFF THE TOP OR BOTTOM EDGES
; THIS IS HANDLED BY TVCNTB AND TVCNTT AT TVCHR+45, ETC.
;PART OF A CHAR CAN BE OFF THE RIGHT OR LEFT EDGES.
; IF THIS HAPPENS IN THE MIDDLE OF A BYTE, TVL12 HANDLES IT. THE
; VARIABLE LINEST IS USED AT TVL12+16 FOR THIS. ALSO, IF WE ARE OFF THE
; RIGHT EDGE, TVCOL SHOULD NOT BE CALLED AGAIN. THIS IS HANDLED BY COMPARING
; THE WOULD-BE NEW TVBP TO SEE IF IT POINTS TO THE NEXT TV LINE, AS
; OPPOSED TO FURTHER OVER IN THE CURRENT LINE, WHERE IT SHOULD BE POINTING.
; THE VARIABLE TVLIN IS USED AT TVCHR+37, ETC.
; ALSO, A WHOLE BYTE COULD BE OFF THE LEFT EDGE, AND IF
; IT IS, THE FURTHER BYTES MUST STILL BE CONSIDERED.
; THIS IS HANDLED BY THE CODE AT TVCOL:.
TVCHR: MOVE F,@CHARDT(FONT)
SKIPG F
POPJ P, ;UNDEFINED CHAR, IGNORE
HLRE B,(F) ;LEFT KERN
SUB B,ICS ;INTERCHARACTER SPACING
ADD B,CPA(FONT)
MOVNS B
PUSHJ P,ADTVXP ;ADD TO TVXP (SETTING TVBP AND TVWD)
MOVE C,TVXP
HRRZ B,1(F) ;RASTER WIDTH
CAML C,MXTVXP
JRST TVCH2 ;ALL OF CHAR OFF RIGHT EDGE (NEVER CALL TVCOL)
ADDI C,-1(B) ;TVXPR
CAMG C,MNTVXP
JRST TVCH2 ;ALL OF CHAR OFF LEFT EDGE (NEVER CALL TVCOL)
MOVEM C,TVXPR ;POS. OF RIGHT HAND SIDE OF BYTE
HLRZ C,1(F) ;BYTES PER ROW
MOVEM C,COLCNT
HRLI C,1000 ;CONSTRUCT TVBP: 8-BIT BYTES
MOVE D,TVBT
DPB D,[360600,,C] ;P=TVBT
HRR C,TVWD
MOVE D,MXBS ;ADJUST FOR BASELINE
SUB D,ABASE(FONT)
IMULI D,18.
ADD C,D
MOVEM C,TVBP ;THAT'S IT
HRRZ C,C
SUBI C,TVBBAS
IDIVI C,18.
AOJ C,
IMULI C,18.
ADDI C,TVBBAS
MOVEM C,TVLIN ;FIRST WORD OF NEXT LINE
MOVE B,[441000,,2]
ADD B,F
MOVEM B,FSBP
MOVEI B,454. ;DON'T FALL OFF BOTTOM OF SCREEN
HRRZ C,TVBP ; THIS IS FOR THE CASE IN WHICH
SUBI C,TVBBAS ; PART OF THE WORD IS OFF EITHER
IDIVI C,18. ; THE TOP OR THE BOTTOM OF THE
MOVEM C,TVCNTT ; SCREEN. ACCUMS. H AND TT ARE
SUB B,C ; USED WITH THIS IN TVCOL.
MOVEM B,TVCNTB
TVCH1: PUSHJ P,TVCOL
SOSLE COLCNT
JRST TVCH1
TVCH2: HLRE C,(F) ;LEFT KERN
ADD C,CPA(FONT) ;PLUS CPA
HRRZ B,(F) ;CHARACTER WIDTH
ADD B,C ;SUBTRACT LEFT KERN AND CPA, ADD CHAR WIDTH
PUSHJ P,ADTVXP
POPJ P,
SUBTTL PUT IN A COLUMN OF BYTES
;DOUBLE SKIPS DURING CERTAIN OFF-RIGHT-EDGE CONDITION
;IF WE ARE HERE AT ALL, AT LEAST SOME OF THE CHAR SHOULD BE DISPLAYED
TVCOL: MOVE A,TVXP
CAMG A,[-10]
JRST TVCOLE
MOVE D,HEIGHT(FONT)
;ARE WE AT THE EDGE OF A TV RASTER LINE?
SETZM LINEST ;INNOCENT UNTIL PROVEN GUILTY
MOVE C,TVXP
CAMGE C,MNTVXP
SOS LINEST ;HANGING OFF LEFT EDGE
MOVE C,TVXPR
CAMLE C,MXTVXP
AOS LINEST ;HANGING OFF RIGHT EDGE
MOVE TT,TVCNTT
MOVE H,TVCNTB
LDB A,[360600,,TVBP]
CAIG A,8+4
JRST TVL12 ;GO TO HARD CASE, WRAPS ACROSS WORDS.
;EASY--DEPOSIT INTO A WORD.
IBP TVBP
MOVE C,TVBP
LDB E,[360600,,TVBP]
TVC1: ILDB B,FSBP
JUMPL TT,TVC3 ;PARTIALLY OFF TOP
LSH B,(E)
MOVEM B,(C) ;DUE TO ALU FUNCTION, THIS IS REALLY AN IORM.
TVC3: ADDI TT,1
ADDI C,18.
SOJLE H,TVCOLE ;PARTIALLY OFF BOTTOM
SOJG D,TVC1
JRST TVCOLE ;FINISHED WITH COLUMN
;HARD--DEPOSIT ACROSS BOUNDARY BETWEEN TWO WORDS.
;THE NEW BYTE IN E MUST BE BROKEN INTO TWO PARTS
;EBP POINTS TO THE FIRST PART.
;BP1 AND BP2 POINT TO THE DESTINATION OF THE TWO
;PARTS, RESPECTIVELY
;NOTE ON ACCUMULATOR USAGE IN THIS ROUTINE:
; A: #OF BITS IN FIRSTR PART OF WORD.
; B: #OF BITS IN LAST PART OF WORD.
; C: WORKING ACCUMULATOR.
; D: COUNTS # OF SCAN LINES NORMALLY IN THIS CHAR.
; E: THE NEW BYTE BEING PUT IN.
; F: POINTS INTO THE CHARACTER MATRIX.
; G: ANOTHER WORKING ACCUMULATOR.
; H: MAKING SURE CHAR DOESN'T FALL OFF THE BOTTOM.
; T: BYTE POINTER INTO TV MEMORY.
; TT: MAKING SURE CHAR ISN'T OFF TOP EDGE.
; CODE, FONT, P: THE USUAL
TVL12: SUBI A,4
MOVEI B,8
SUB B,A
DPB B,[360600,,EBP] ;SET UP E
DPB A,[300600,,EBP]
HRRI C,E
HRRM C,EBP
HRLI C,040000 ;SET UP BP1
HLLZM C,BP1
DPB A,[300600,,BP1]
MOVEI C,36. ;SET UP BP2
SUB C,B
DPB C,[360600,,BP2]
DPB B,[300600,,BP2]
MOVE T,TVBP
TVL121: ILDB E,FSBP
JUMPL TT,TVL122
SKIPGE LINEST
JRST TVL123
LDB C,EBP ;FIRST PART OF BYTE
HRRM T,BP1
DPB C,BP1 ;THIS IS REALLY LIKE AN IORM DUE TO THE ALU FUNCTION.
TVL123: SKIPLE LINEST
JRST TVL122
HRRM T,BP2 ;SECOND PART OF BYTE
AOS BP2
DPB E,BP2 ;THIS IS REALLY LIKE AN IORM DUE TO THE ALU FUNCTION.
TVL122: AOJ TT,
ADDI T,18.
SOSLE H ;DON'T FALL OFF BOTTOM OF SCREEN
SOJN D,TVL121
MOVE A,BP2
MOVEI C,8.
DPB C,[300600,,A]
HRR A,TVBP
ADDI A,1
MOVEM A,TVBP
HRRZ A,A
CAMGE A,TVLIN
JRST TVCOLE
AOS (P)
AOS (P) ;OFF RIGHT EDGE
TVCOLE: SUBI D,1
TVC2: JUMPLE D,CPOPJ
SOJ D,
IBP FSBP
JRST TVC2
;THIS IS LIKE TVCHR FOR MINI-DISPLAY MODE. IT COMPRESSES BY 5 VERTICALLY
;AND BY 4 HORIZONTALLY AND LEAVES BARS OF GLITCHS IN THE MINI DISPLAY.
MTVCHR: MOVE B,XOFF ;IGNORE XOFF AND YOFF
ADDM B,TVXP
MOVE B,YOFF
ADDM B,TVYP
MOVE F,@CHARDT(FONT)
JUMPE F,CPOPJ ;UNDEFINED CHAR, IGNORE
HLRE B,(F) ;LEFT KERN
SUB B,ICS ;INTERCHARACTER SPACING
ADD B,CPA(FONT)
MOVNS B
PUSHJ P,ADTVXP
HLRZ C,1(F) ;BYTES PER ROW
MOVEM C,COLCNT
MOVE B,[441000,,2]
ADD B,F
MOVEM B,FSBP
MOVE A,TVXP
LSH A,-2 ; COMPRESS BY 4
IDIVI A,32. ; 32 BITS IN A WORD. [DO NOT MAKE THIS A LSH,
; WE USE THE REMAINDER.]
ADDI A,TVBBAS
MOVEM A,TVADR1
CAIG B,2 ;HACK TO AVOID HAVING TVBIT1 OR TVBIT2 ZERO
MOVEI B,2
MOVEI C,36.
SUB C,B
MOVEI B,1
LSH B,(C)
MOVEM B,TVBIT2
LSH B,1
MOVEM B,TVBIT1
MOVE G,COLCNT
MTV1: MOVE H,HEIGHT(FONT)
MOVE A,TVYP
MOVEM A,TVADR2
MTV2: MOVE A,TVADR2
IDIVI A,5
IMULI A,18.
ADD A,TVADR1
ILDB B,FSBP ;THE BYTE
LDB C,[040400,,B] ;GET THE FIRST FOUR BITS
JUMPE C,MTV3 ;IF ALL ZEROES, DON'T DO ANYTHING
MOVE D,TVBIT1
IORM D,(A)
MTV3: LDB C,[000400,,B] ;THE SECOND FOUR BITS
JUMPE C,MTV4
MOVE D,TVBIT2
IORM D,(A)
MTV4: AOS TVADR2
SOJG H,MTV2
MOVE A,TVBIT2
LSH A,-2
MOVEM A,TVBIT2
MOVE A,TVBIT1
LSH A,-2
MOVEM A,TVBIT1
AND A,[-16] ;MASK OUT LOWEST 4 BITS
JUMPN A,MTV5 ;IT DIDN'T FALL OFF THE EDGE OF THE WORD
AOS TVADR1
HRLI A,400000
MOVEM A,TVBIT1
HRLI A,200000
MOVEM A,TVBIT2
MTV5: SOJG G,MTV1
HLRE C,(F) ;LEFT KERN
ADD C,CPA(FONT) ;PLUS CPA
HRRZ B,(F) ;CHARACTER WIDTH
ADD B,C ;SUBTRACT LEFT KERN AND CPA, ADD CHAR WIDTH
PUSHJ P,ADTVXP
MOVN B,XOFF ;RESTORE XOFF AND YOFF
ADDM B,TVXP
MOVN B,YOFF
ADDM B,TVYP
POPJ P,
SUBTTL RANDOM ROUTINES
;WORDIN READS IN A WORD FROM DISK
WIBUF: MOVE A,[-BUFSIZ,,BUF];NO,REPLENISH THE BUFFER
.IOT FNTICH,A
HLREM A,MISSED ;SAVE HOW MANY WE NEVER GOT (USUALLY 0)
MOVEI A,BUF
MOVEM A,IOPTR
MOVEI A,BUFSIZ
ADD A,MISSED
MOVEM A,IOCNT
WORDIN: SOSGE IOCNT
JRST WIBUF ;BUFFER EMPTY
MOVE A,@IOPTR
AOS IOPTR
POPJ P,
;PRINT OUT A STRING
OUTSTR: .IOT TTYOCH,[15]
.IOT TTYOCH,[12]
OUTST1: PUSH P,B
MOVE B,A
HRLI B,440700
OUTS1: ILDB A,B
JUMPE A,CPOPBJ
CAIN A,14 ;IT SHOULD STOP ON SEEING FORMFEED, FOR THE ERR DEVICE
JRST CPOPBJ
.IOT TTYOCH,A
JRST OUTS1
TERPRI: PUSHJ P,OUTSTR
.IOT TTYOCH,[15]
.IOT TTYOCH,[12]
POPJ P,
CPOPBJ: POP P,B
POPJ P,
;ADD TO TVXP, ADJUSTING TVBT AND TVWD IF NECESSARY
ADTVXP: ADDB B,TVXP
PUSH P,C
IDIVI B,32.
ADD B,LTVWD
MOVEM B,TVWD
SUBI C,36.
MOVNM C,TVBT
POP P,C
POPJ P,
DECTYP: SETZ C, ;TYPE OUT A POSITIVE DECIMAL INTEGER IN A.
DECT1: IDIVI A,10. ; CLOBBERS B & C & A
ADDI B,60 ;MAKE IT ASCII
PUSH P,B
ADDI C,1
JUMPN A,DECT1
DECT2: POP P,A
.IOT TTYOCH,A
SOJG C,DECT2
POPJ P,
SIXTYP: PUSH P,B
SIXTY1: SETZI B,
ROTC A,6
ADDI B,40
.IOT TTYOCH,B
JUMPN A,SIXTY1
POP P,B
POPJ P,
;;; Print out error message. Expects to find error code in ERRCOD.
ERRDEV: MOVEI A,[ASCIZ /-- /]
PUSHJ P,OUTST1
.CALL [ SETZ
SIXBIT/OPEN/
[.UAI,,ERRICH]
[SIXBIT /ERR/]
MOVEI 4
SETZ ERRCOD]
.LOSE 1400
ERRDE1: .IOT ERRICH,A
CAIGE A,40
JRST CPOPJ
.IOT TTYOCH,A
JRST ERRDE1
;GET NEXT WORD OF FREE STORAGE
;RETURN ITS ADDRESS IN A.
CONS: SOSL FREE
JRST CONS1
.CALL [ SETZ ;CREATE A NEW PAGE
SIXBIT /CORBLK/
MOVEI %CBNDW
MOVEI %JSELF
CORSIZ
SETZI %JSNEW]
.LOSE 1000
AOS CORSIZ
MOVEI A,2000
ADDM A,FREE
CONS1: MOVE A,FSP
AOS FSP
SETZM (A)
POPJ P,
;Skip if CHBP is pointing past the end of the file.
FILEND: PUSH P,A
PUSH P,B
PUSH P,C
HRRZ A,CHBP ; CONVERT INTO CHARACTER ADDRESS
SUBI A,200000-1
IMULI A,5
LDB B,[360600,,CHBP] ; GET PP FIELD
IDIVI B,7
MOVNS B
ADD B,A ; B HAS THE CHARACTER ADDRESS
ADDI B,1
CAMGE B,FILLEN ; SKIP IF CHBP IS TOO BIG
CPOPJ1: AOS -3(P)
POP P,C
POP P,B
POP P,A
POPJ P,
;Interrupt level code.
TSINT: 0
0
EXCH A,TSINT
JUMPGE A,.+2
TRNN A,1_TTYICH
.VALUE [ASCIZ/: INTERRUPT BUG.
/]
MOVEI A,TTYICH
.ITYIC A, ;ITS WANTS TO SEE THIS, THOUGH I DONT CARE
.DISMIS TSINT+1
SKIPE INTFLG ;ENABLED?
JRST TSIN1 ;YES, DO THINGS
MOVE A,TSINT ;NO, PRETEND IT DIDN'T HAPPEN
.DISMIS TSINT+1
TSIN1: MOVE P,[-PDLLEN,,PDB-1] ;REINITIALIZE P
MOVEI A,CSET ;SET ALU FUNCTION TO DO MOVEMS.
DPB A,[CREGFN,,CREG]
SETZM INTFLG ;DISABLE INTERRUPTS
MOVE A,BCHBP
MOVEM A,CHBP ;RESTORE CHBP
.DISMIS [CURSOR] ;GO BACK TO CURSOR ROUTINE
;REINITIALIZE CHBP, BCHBP, AND PAGENO TO THE BEGINNING OF THE FILE
ICHBP: MOVE A,[440700,,200000] ;START POINTER AT BEGINNING OF DISK FILE
MOVEM A,CHBP
MOVEM A,BCHBP
MOVEI A,1 ;START ON PAGE 1
MOVEM A,PAGENO
POPJ P,
SUBTTL FILE NAME READER
; FILE NAME READER. TAKES AN INSN TO XCT IN RXCT TO PUT
; THE NEXT SIXBIT CHAR INTO IN ACCUMULATOR A.
; THE FILE SPEC IS LEFT IN XDEV, XFN1, XFN2, AND XDIR.
; THIS CLOBBERS A,B, AND C. IT IS CALLED WITH PUSHJ P,READER
; IF NO FILE SPEC WAS READ, RETURN -1 IN THE LEFT HALF OF A.
; ALWAYS RETURN THE LAST CHAR READ (THE DELIMITER) IN A.
READER: SETZI ZR,
READE2: SETZI B,
MOVE C,[440600,,B]
REANEX: XCT RXCT ; GET A CHAR INTO AC A
CAIN A,":
JRST READEV
CAIN A,";
JRST READIR
CAIG A,40
JRST READEL ;IF NOT >40, DELIMITER
CAIN A,",
JRST READEL ;COMMA IS A DELIMITER
CAIL A,"a
CAILE A,"z
SUBI A,40 ;IF NOT LOWER CASE, CONVERT TO SIXBIT
; (LOWER CASE IS ALREADY SIXBIT)
TRO ZR,1 ; SET FLAG INDICATING WE HAVE DONE SOMETHING
TLNE C,770000
IDPB A,C
JRST REANEX
READEV: MOVEM B,XDEV ; COLON, THIS IS THE DEVICE NAME
JRST READE2
READIR: MOVEM B,XDIR ; SEMI, THIS IS THE SNAME
JRST READE2
READEL: JUMPE B,READE1 ; DELIMITER, IF NOTHING INPUT THEN DONT CLOBBER ANYTHING
TRNE ZR,2
MOVEM B,XFN2 ; IT IS SET, SO WE ALREADY GOT THE FN1
TRON ZR,2
MOVEM B,XFN1 ; THIS IS THE FIRST TIME, STORE IN FN1 AND SET THE FLAG
READE1: CAIN A,40 ; IF NOT A SPACE, RETURN, LEAVING
JRST READE2 ; WHATEVER IT WAS IN AC A
TRNE ZR,1
POPJ P, ; (IF NOTHIG HAS HAPPENED)
TLO A,-1 ; IF NOTHING WAS EVER READ, SET LEFT HALF OF A TO -1
POPJ P,
SUBTTL DATA AREA
NFONTS: 0 ;INDEX OF HIGHEST KNOWN FONT.
FONDEV: BLOCK MXNFNT ;THE FONT FILES INDEXED BY FONT NUMBER.
FONFN1: BLOCK MXNFNT
FONFN2: BLOCK MXNFNT
FONDIR: BLOCK MXNFNT
KDEFLT: SIXBIT /DSK/ ;THE DEFAULT FONT FILE SPEC
SIXBIT /25FG/
SIXBIT /KST/
SIXBIT /FONTS/
FILDEV: SIXBIT /DSK/ ; THE USER'S FILE FOR INPUT
FILFN1: SIXBIT /@/
FILFN2: SIXBIT />/
FILDIR: 0 ; (GETS INITIALIZED TO THE MSNAME)
XDEV: 0 ; FOR THE READER ROUTINE.
XFN1: 0
XFN2: 0
XDIR: 0
RXCT: 0 ; LOC TO PUT THE INSN NEEDED BY READER FOR INPUT.
MODE: 0 ;0=NORMAL -1=MINI-DISPLAY
INTFLG: 0 ;INTERRUPT FLAG. 0 => DISABLED, 1 => ENABLED
FILLEN: 0 ;LENGTH OF THE FILE, IN WORDS
TVADR1: 0
TVADR2: 0
TVBIT1: 0
TVBIT2: 0
KSTID: BLOCK MXNFNT
HEIGHT: BLOCK MXNFNT
BASE: BLOCK MXNFNT
ABASE: BLOCK MXNFNT
CPA: BLOCK MXNFNT
CHRCNT: 0
MISSED: 0
IOPTR: 0 ;POINTER FOR BUF
IOCNT: 0 ;COUNTER FOR BUF
FILSPC: BLOCK 100 ;FILE SPEC, FROM JCL OR TTY
BPR: 0 ;BYTES PER ROW (I.E. RASTER)
FLAG: 0 ;RANDOM FLAG
EOFFLG: 0 ;END OF FILE FLAG
PTT: 0 ;POINTS AT TT
TEMP: 0 ;TEMP LOCATION
;TVCOL'S VARIABLES
EBP: 0 ;BYTE POINTER TO AC E
BP1: 0 ;BYTE POINTER
BP2: 0 ;BYTE POINTER
TVLIN: 0 ;FIRST WORD OF NEXT LINE IN TV MEMORY
TVXPR: 0 ;POSITION OF RIGHT HAND BIT OF BYTE
LINEST: 0 ;-1 => OFF LEFT EDGE. 0 => OK. 1 => OFF RIGHT EDGE.
;THE NEXT SIX WORDS MUST BE CONTIGUOUS
TOPMAR: 128 ;TOP MARGIN
BOTMAR: 124 ;BOTTOM MARGIN
LFTMAR: 128 ;LEFT MARGIN
VSP: 6 ;VERTICAL SPACEING BETWEEN LINES
SKIPP: 0 ;NUMBER OF PAGES TO SKIP
SIZEE: 0 ;SIZE OF PAGE
TVXP: 0 ;TV'S X-AXIS POSITION
TVYP: 0 ;TV'S Y-AXIS POSITION
ITVXP: 0 ;TVXP AT BEGINNING OF LINE
ITVYP: 0 ;LIKEWISE
STTVYP: 0 ;TVYP SHOULD BE SET TO THIS NEXT LF
PAGENO: 0 ;THE NUMBER OF THE PHYSICAL PAGE WE ARE NOW DISPLAYING
SPAGEN: 0 ;SAVE PAGENO IN CASE HE GOES OFF THE END OF THE FILE
GOPAGC: 0 ; HOLDS C TEMPORARILY FOR THE GOPAG ROUTINE
XOFF: 0 ;X OFFSET
YOFF: 0 ;Y OFFSET
;THAT IS, TVXP = XGP_POSITION - XOFF
MXTVXP: 0 ;MAX TVXP
MNTVXP: 0 ;MIN TVXP
ICS: 0 ;INTERCHARACTER SPACING (XESC1 50)
LS: 0 ;ARGUMENT OF XESC1 42 (LINE SPACE)
LSFLAG: 0 ;FLAG FOR XESC1 42 (LINE SPACE)
STAUND: 0 ;TVXP AT START UNDERSCORE (XESC1 46)
COLCNT: 0 ;COUNTS COLUMNS IN A CHAR
CHCNT: 0 ;CHARACTERS LEFT IN BUFFER
BCHCNT: 0 ;CHCNT AT BEGINNING OF THIS PAGE
CHBP: 0 ;BYTE POINTER TO CHARACTERS IN BUFFER
BCHBP: 0 ;CHBP AT BEGINNING OF THIS PAGE
BCORSZ: 0 ;CORSIZ AT BEGINNING OF THIS PAGE
CHMISS: 0 ;HOW MANY CHARS MISSED WHILE READING IN CHARS
FCORE: 0 ;LOC OF FREE CORE AFTER FONT AREA.
; MUST BE AT THE TOP OF THE PAGE.
FCRSIZ: 0 ;NUMBER OF BLOCKS BEFORE (FCORE)
X3FLAG: 0 ;-1 => AN XGP ESCAPE 3 WAS DONE ON THIS LINE.
X3VAL: 0 ;VALUE OF ANY X-ESC 3 IN THIS LINE.
FSBP: 0
TVBP: 0
INBP: 0
OUTBP: 0
CHWD: 0 ;CHAR WIDTH
TVWD: 0
TVBT: 0
LTVWD: 0 ;TVWD AT BEGINNING OF THE CURRENT LINE
MXDP: 0 ;SCANNER - MAX DEPTH (BELOW BASELINE) SO FAR IN THIS LINE
MXBS: 0 ;SCANNER - MAX BASELINE SO FAR IN THIS LINE (ADJUSTED)
TVCNTT: 0 ;TV LINE COUNTER FOR TOP OF SCREEN
TVCNTB: 0 ;MUST NOT TRY TO PUT IN MORE THAN THIS MANY BYTES
C40: 40 ;CODE FOR SPACE
BITSIN: 0 ;NUMBER OF BITS TO PUT IN PER ROW IN MINI-MODE
ERRCOD: 0 ;CODE OF ERROR COMMITTED, ARGUMENT TO ERRDEV SUBROUTINE
PATCH: BLOCK 100
CHARDT: REPEAT MXNFNT, CONC CHAR,\.RPCNT,(CODE)
REPEAT MXNFNT, CONC CHAR,\.RPCNT,: BLOCK MXSTSZ ;THESE SYMBOLS ARE ONLY REFERENCED FROM
; THE CHARDT TABLE ABOVE.
BUF: BLOCK BUFSIZ ;DISK INPUT BUFFER
REBUF: BLOCK BUFSIZ ;TO REORGNIZE BUF
PDB: BLOCK PDLLEN
FREE: 0
CORSIZ: 0
FSP: 0
CONSTANTS
LOC <.+1777>/2000*2000
TVBBAS: ;TV BUFFER BASE
CREG=TVBBAS+8*2000 ;THE TV CONTROL REGISTER
;FREE STORAGE STARTS HERE.
FS=9*2000+TVBBAS
ICORE==FS_<-12>
END GO