Trailing-Edge
-
PDP-10 Archives
-
cuspbinsrc_2of2_bb-fp63b-sb
-
10,7/lp20/lp20.mac
There are no other files named lp20.mac in the archive.
TITLE LP20 LP20 RAM AND VFU FILE MANIPULATOR
SUBTTL T. LITT /TL
;
;
; COPYRIGHT (c) 1986
; DIGITAL EQUIPMENT CORPORATION
; ALL RIGHTS RESERVED.
;
; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE
; AND WITH THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS
; SOFTWARE OR ANY OTHER COPIES THEREOF MAY NOT BE PROVIDED OR
; OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. NO TITLE TO
; AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED.
;
; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE
; WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT
; BY DIGITAL EQUIPMENT CORPORATION.
;
; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY
; OF ITS SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY
; DIGITAL.
SEARCH GLXMAC,ORNMAC
SALL ;MAKE NICE MACROS
.DIRECT FLBLST
PROLOG (LP20)
.TEXT |/SYMSEG:LOW/LOCALS,REL:OPRPAR/SEGMENT:LOW|
LOC 137
.JBVER::VRSN. LP2
RELOC
TOPS20<
DEFINE COPYRIGHT,<ASCIZ \
COPYRIGHT >
>
COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1986. ALL RIGHTS RESERVED.
\;END COPYRIGHT MACRO
COMMENT $
LP20 is a replacement for MAKVFU, MAKRAM (a -20 only utility), and DMPVFU.
It is intended that LP20 will consolidate all RAM and VFU file manipulation
utilities.
I gratefully note stealing the GLXLIB skeleton interface from DPM...
$
SUBTTL Table of Contents
; TABLE OF CONTENTS FOR LP100/LP20 RAM and VFU file manipulator
;
;
; SECTION PAGE
; 1. Table of Contents..................................... 2
; 2. Revision history...................................... 3
; 3. Assembly parameters................................... 4
; 4. Various control blocks................................ 5
; 5. Command table definitions............................. 6
; 6. Initialization........................................ 7
; 7. Error message processing.............................. 8
; 8. Command tables
; 8.1 Major modes................................... 9
; 8.2 Generic commands.............................. 11
; 8.3 RAM mode...................................... 14
; 8.4 VFU mode...................................... 15
; 9. Parser action routines for field validation........... 16
; 10. Generic commands
; 10.1 Control-Z and EXIT............................ 17
; 10.2 HELP.......................................... 18
; 10.3 MODE.......................................... 19
; 10.4 LIST and SHOW................................. 22
; 10.5 READ and WRITE................................ 25
; 11. RAM commands
; 11.1 ARROW......................................... 35
; 11.2 CLEAR......................................... 36
; 11.3 (CONDITIONALLY-)TRANSLATE..................... 37
; 11.4 LIST and SHOW support......................... 39
; 11.5 LOWER-CASE/UPPER-CASE......................... 42
; 11.6 NUMBER-OF-DATA-BITS........................... 43
; 11.7 Utility routines.............................. 44
; 12. VFU commands
; 12.1 CLEAR......................................... 45
; 12.2 LENGTH........................................ 46
; 12.3 LINES-PER-INCH................................ 47
; 12.4 LIST and SHOW support......................... 48
; 12.5 (UN-)PUNCH.................................... 51
; 12.6 PAGE-SIZE..................................... 53
; 12.7 Utility routines.............................. 54
; 13. Parser interface
; 13.1 Argument fetchers............................. 55
; 14. Default RAM data...................................... 56
; 15. Macros for generating default VFU data................ 58
; 16. Default VFU data buffer............................... 60
; 17. Error routines........................................ 61
; 18. Impure storage........................................ 62
SUBTTL Revision history
REPEAT 0,<
Edit Who Date What
---- --- --------- -------------------------------------------------------
1 TL 27-APR-86 Create from the pure frustration with what came before.
2 TL 27-APR-86 Make the changes for TOPS-20.
3 TL 02-MAY-86 Add RAM mode CLEAR command
4 TL 10-MAY-86 Remove $ABBREV macro. KEYTAB can serve.
>
LP2EDT==4
LP2VER==1 ;VERSION
LP2MIN==0
LP2WHO==0
SUBTTL Assembly parameters
;ACCUMULATORS:
C=10 ;CHARACTER AC
F=11 ;FLAG AC
;RH IS TEMP FOR EACH CMD
;LH IS GLOBAL
F.R8BT==(1B0) ;RAM IS 8-BIT
P=17 ;NORMAL STACK
;VARIOUS PARAMETERS:
PDLSIZ==^D1000 ;PUSH-DOWN STACK SIZE
FILSIZ==16 ;NUMBER OF WORDS NEEDED FOR AN ASCIZ FILESPEC
DEFINE $MSG (TYP,PFX,RET,TXT),<
PUSHJ P,[PUSHJ P,ERRMSG
XWD "TYP",''PFX''
XWD RET,[ITEXT (<'TXT>)]]
>
CR.SAV==CR.SIZ ;FOR ACTION ROUTINES
CHRMSK==177
BYTMSK==377
SUBTTL Various control blocks
; GLXLIB INITIALIZATION BLOCK
IB: $BUILD (IB.SZ) ;SIZE OF BLOCK
$SET (IB.PRG,,%%.MOD) ;PROGRAM NAME
$SET (IB.OUT,,T%TTY) ;TTY OUTPUT
$SET (IB.FLG,IT.OCT,1) ;REQUIRE COMMAND TERMINAL
$EOB ;END OF BLOCK
; PARSER BLOCK
PARBLK: $BUILD PAR.SZ ;SIZE OF BLOCK
$SET (PAR.TB,,CMD010) ;ADDRESS OF TABLES
$SET (PAR.PM,,PROMPT) ;PROMPT STRING
$SET (PAR.CM,,CMDBLK) ;COMMAND RETURN BLOCK
$EOB ;END OF BLOCK
PROMPT: ASCIZ |LP20>| ;PROMPT STRING
; DEFAULT DATA FILE FD
TOPS10<
DEFFIL: $BUILD (FDMSIZ) ;SIZE OF BLOCK
$SET (.FDLEN,FD.LEN,FDMSIZ) ;LENGTH OF FD
$SET (.FDLEN,FD.TYP,.FDNAT) ;FILE SPEC TYPE (NATIVE)
$SET (.FDSTR,,<'DSK '>) ;ERSATZ DEVICE HLP:
$SET (.FDNAM,,<'LP20 '>) ;FILE NAME
$SET (.FDEXT,,<'VFU '>) ;EXTENSION
$EOB
>
TOPS20<
DEFFIL: $BUILD (<.FDLEN+1>) ;SIZE OF BLOCK
$SET (.FDLEN,FD.LEN,FDXSIZ) ;LENGTH OF FD
$SET (.FDLEN,FD.TYP,.FDNAT) ;FILE SPEC TYPE (NATIVE)
$EOB ;END OF BLOCK
DEFFNM: ASCIZ |DSK:LP20.VFU|
BLOCK FDXSIZ-<.-DEFFNM> ;ALLOCATE ENOUGH SPACE FOR ANYTHING
>
SUBTTL Command table definitions
; LIST COMMAND SWITCHES
LS.ALL==1B19 ;/ALL-ENTRIES
LS.BRF==1B20 ;/BRIEF
LS.LIN==1B21 ;/BY-LINE
LS.TTY==1B22 ;LIST ON TTY:
LS.VAL==77 ;RESERVED FOR SWITCHES WITH VALUES
; PUNCH COMMAND MODIFIER
PU.UNP==1B19 ;UN-PUNCH
; WRITE COMMAND SWITCHES
WR.8BT==1B19 ;/8-BIT FORMAT
WR.L10==1B20 ;/LP100-CODES
SUBTTL Initialization
START: JFCL ;NO CCL ENTRY
RESET ;STOP I/O
MOVE P,[IOWD PDLSIZ,PDL] ;SET UP STACK
MOVEI S1,IB.SZ ;LENGTH OF IB
MOVEI S2,IB ;ADDRESS OF IB
PUSHJ P,I%INIT## ;FIREUP GLXLIB
MOVE T1,[Z.BEG,,Z.BEG+1] ;SET UP BLT
SETZM Z.BEG ;CLEAR FIRST WORD
BLT T1,Z.END-1 ;CLEAR ENTIRE LOWSEG
MOVEI T1,MSGTYO ;MESSAGE TYPEOUT ROUTINE
MOVEM T1,TYOADR ;SAVE
SETZB S1,S2 ;CLEAR ACS
PUSHJ P,P$INIT## ;INITIALIZE THE PARSER
GETCMD: MOVE P,[IOWD PDLSIZ,PDL] ;SET UP STACK
TRZ F,-1 ;CLEAR PER-COMMAND FLAGS
MOVE S1,[CMDBLK,,CMDBLK+1] ;SET UP BLT
SETZM CMDBLK ;CLEAR FIRST WORD
BLT S1,CMDBLK+PAGSIZ-1 ;CLEAR OUT COMMAND PARSER PAGE
MOVEI S1,COM.SZ-1
STORE S1,.MSTYP+CMDBLK,MS.CNT ;SET INITIAL SIZE
MOVEI S1,PAR.SZ ;GET SIZE OF PARSER BLOCK
MOVEI S2,PARBLK ;POINT TO IT
PUSHJ P,PARSER## ;PARSE THE COMMAND
JUMPF COMERR ;CHECK FOR PARSER ERRORS
DISPAT: MOVEI S1,COM.SZ+CMDBLK ;POINT TO FIRST ARGUMENT
PUSHJ P,P$SETU## ;GET BASE ADDRESS OF PARSED DATA
PUSHJ P,P$KEYW## ;GET KEYWORD VALUE
SKIPT ;CHECK FOR CONFUSION
$STOP (LIC,<LP20 is confused>)
PUSHJ P,(S1) ;DISPATCH TO PROCESSOR
JRST GETCMD ;GO GET ANOTHER COMMAND
; HERE ON PARSER ERRORS
COMERR: MOVE S1,PRT.FL(S2) ;GET THE FLAGS
SKIPA S2,PRT.EM(S2) ;GET THE ADDRESS OF ERROR TEXT
SYNERR: MOVEI S2,[ASCIZ |Command syntax error|]
$TEXT (,<^M^J? ^T/0(S2)/>)
JRST GETCMD ;GO TRY AGAIN
SUBTTL Error message processing
MSGTYO: $CALL K%TPOS ;RETURN HORRIZONTAL CARRIAGE POSITION
MOVEI S2,[ASCIZ ||] ;ASSUME ALREADY AT LEFT MARGIN
SKIPE S1 ;TEST
MOVEI S2,[BYTE(7) .CHCRT,.CHLFD,0] ;NEED A CRLF
TOPS10<
HRROI T4,.GTWCH ;GETTAB TO
GETTAB T4, ; RETURN WATCH BITS
SETZ T4, ;STRANGE ...
TLNN T4,(JW.WPR!JW.WFL) ;HAVE PREFIX OR FIRST LINE SET?
TLO T4,(JW.WPR!JW.WFL) ;NO--DEFAULT TO THEM
>
; Prefix
HLRZ T1,ERRPFX ;GET SEVERITY CHARACTER
MOVSI T2,'LP2' ;OUR NAME
HRR T2,ERRPFX ;FORM PREFIX
TOPS10<
TXNN T4,JW.WPR ;WANT PREFIX?
SETZ T2, ;NO
; First line
TXNE T4,JW.WFL ;WANT FIRST LINE?
>
SKIPA T3,[ERRSTR] ;YES
MOVEI T3,[ASCIZ ||] ;POINT TO NULL TEXT
; Termination
CAIE T1,"[" ;INFORMATIONAL?
TDZA T4,T4 ;NO
MOVEI T4,"]" ;TERMINATE PROPERLY
$TEXT (,<^T/(S2)/^7/T1/^W/T2/ ^T/(T3)/^7/T4/^M^J>)
POPJ P, ;RETURN
SUBTTL Command tables -- Major modes
;STARTUP TABLE -- USED TO SELECT INITIAL MODE
CMD010: $INIT(CMD020)
CMD020: $KEYDSP (CMD030)
CMD030: $STAB
DSPTAB (,.CTRLZ,<>,CM%INV)
DSPTAB (EXI010,.EXIT,<EXIT>)
DSPTAB (HLP010,.HELP,<HELP>)
DSPTAB (MOD010,.MODE,<MODE>)
DSPTAB (TAK010,.POPJ,<TAKE>)
$ETAB
;RAM MODE COMMANDS
RAM010: $INIT(RAM020)
RAM020: $KEYDSP (RAM030)
RAM030: $STAB
DSPTAB (,.CTRLZ,<>,CM%INV)
DSPTAB (ARR010,.ARROW,<ARROW-MODE>)
DSPTAB (CLR020,.RMCLR,<CLEAR>)
DSPTAB (DEL010,.DELIM,<CONDITIONALLY-TRANSLATE>)
DSPTAB (DEL010,.DELIM,<DELIMITED-TRANSLATE>,CM%INV)
DSPTAB (EXI010,.EXIT,<EXIT>)
DSPTAB (HLP010,.HELP,<HELP>)
DSPTAB (LST010,.LIST,<LIST>)
DSPTAB (LOW010,.LOWER,<LOWER-CASE>)
DSPTAB (MOD010,.MODE,<MODE>)
DSPTAB (NUM010,.DATAB,<NUMBER-OF-DATA-BITS>)
DSPTAB (WRI010,.WRITE,<OUTPUT>,CM%INV)
DSPTAB (REA010,.READ,<READ>)
DSPTAB (SHO010,.SHOW,<SHOW>)
DSPTAB (TAK010,.POPJ,<TAKE>)
DSPTAB (TRA010,.TRANS,<TRANSLATE>)
DSPTAB (UPP010,.UPPER,<UPPER-CASE>)
DSPTAB (WRI010,.WRITE,<WRITE>)
$ETAB
;VFU MODE COMMANDS
VFU010: $INIT(VFU020)
VFU020: $KEYDSP (VFU030)
VFU030: $STAB
DSPTAB (,.CTRLZ,<>,CM%INV)
KEYTAB (VFUCLR,<C>,<CM%ABR!CM%INV>) ;BECAUSE OF INVIS CHANNEL CMD
DSPTAB (CHA010,.CHANN,<CHANNEL>,CM%INV)
VFUCLR: DSPTAB (CLR010,.CLEAR,<CLEAR>)
DSPTAB (EXI010,.EXIT,<EXIT>)
DSPTAB (HLP010,.HELP,<HELP>)
DSPTAB (INF010,.SHOW,<INFORMATION>,CM%INV)
DSPTAB (LEN010,.LENGT,<LENGTH>)
DSPTAB (LIN010,.LINES,<LINES-PER-INCH>)
DSPTAB (LST010,.LIST,<LIST>)
DSPTAB (MOD010,.MODE,<MODE>)
DSPTAB (CLR010,.CLEAR,<NEW>,CM%INV)
DSPTAB (WRI020,.WRITE,<OUTPUT>,CM%INV)
DSPTAB (PAG010,.PAGES,<PAGE-SIZE>)
DSPTAB (PUN010,.CHANN,<PUNCH>)
DSPTAB (REA010,.READ,<READ>)
DSPTAB (SHO010,.SHOW,<SHOW>)
DSPTAB (TAK010,.POPJ,<TAKE>)
DSPTAB (UNP010,.UNPUN,<UN-PUNCH>)
DSPTAB (WRI020,.WRITE,<WRITE>)
$ETAB
SUBTTL Command tables -- Generic commands
EXI010: $NOISE (CONFRM,<to the monitor>)
HLP010: $NOISE (HLPKEY,<with command>)
HLPKEY: $KEY (CONFRM,CMD030,<$ALTERNATE(CONFRM)>)
LST010: $NOISE (LSTSWI,<editing buffer to>)
LSTSWI: $SWITCH (,LSTRAM,<$ACTION (SHRSWT),$ALTER (LST040)>)
LSTRAM: $STAB
DSPTAB (NEXT(LSTSWI),<LS.BRF>,<BRIEF>)
$ETAB
LSTVFU: $STAB
; DSPTAB (NEXT(LSTSWI),<LS.BRF>,<BRIEF>)
DSPTAB (NEXT(LSTSWI),<LS.LIN>,<BY-LINE>)
$ETAB
LST040: $OFILE (CONFRM,<output listing file>,)
;MODE COMMAND
MOD010: $NOISE (MOD020,<of operation is>)
MOD020: $KEY (MOD040,MOD030)
MOD030: $STAB
KEYTAB (-1,<RAM>)
KEYTAB (1,<VFU>)
$ETAB
MOD040: $NOISE (CONFRM,<file mode>)
REA010: $IFILE (CONFRM,<input data file>,<>)
SHO010: $NOISE (SHOSWI,<editing buffer contents>)
SHOSWI: $SWITCH (,SHORAM,<$ACTION (SHRSWT),$ALTERNATE (CONFRM)>)
SHORAM: $STAB
DSPTAB (CONFRM,<LS.ALL>,<ALL-ENTRIES>)
DSPTAB (SHO030,<1>,<BEGIN:>)
DSPTAB (SHO030,<2>,<END:>)
$ETAB
SHOVFU: $STAB
DSPTAB (CONFRM,<LS.ALL>,<ALL-ENTRIES>)
DSPTAB (SHO050,<1>,<BEGIN:>)
DSPTAB (NEXT(SHOSWI),<LS.LIN>,<BY-LINE>)
DSPTAB (SHO050,<2>,<END:>)
$ETAB
SHO030: $QUOTE (NEXT(SHOSWI),<quoted character>,<$ACTION(CHKCHS),$ALTER(SHO040)>)
SHO040: $NUMBER (NEXT(SHOSWI),^D8,<octal character code>,<$ACTION(CHKCHR)>)
SHO050: $NUMBER (NEXT(SHOSWI),^D10,<decimal line or channel number>,<>)
TAK010: $CRLF (<$ALTERNATE(TAKFDB##),$PREFILL(TAKDEF)>)
WRI010: $OFILE (CONFRM,<output data file>,<>)
WRI020: $SWITCH (,WRI025,<$ACTION (SHRSWT),$ALTER (WRI030)>)
WRI025: $STAB
DSPTAB (NEXT(WRI020),<WR.8BT>,<8-BIT-FORMAT>)
DSPTAB (NEXT(WRI020),<WR.L10>,<LP100-CODES>)
$ETAB
WRI030: $OFILE (CONFRM,<output data file>,<>)
CONFRM: $CRLF
;A real kludge to deal with OPRPAR's non-global routines
;Broken by GALAXY 5 Move to more suitable place
TAKDEF: MOVEI S1,TAKFDB## ; Get the TAKE address
AOS S1 ; Bump over the header
STORE S1,CR.PDB(S2),RHMASK ; Save new PDB to use
$RETT ; Return
SUBTTL Command tables -- RAM mode
ARR010: $NOISE (ARR020,<translation for>)
ARR020: $QUOTE (CONFRM,<quoted character>,<$ACTION(CHKCHS),$ALTER(ARR030)>)
ARR030: $NUMBER (CONFRM,^D8,<octal character code>,<$ACTION(CHKCHR)>)
CLR020: $NOISE (CONFRM,<entire RAM>)
TRA010: $NOISE (DEL010,<unconditionally>)
DEL010: $QUOTE (DEL030,<quoted character>,<$ACTION(CHKCHS),$ALTER(DEL020)>)
DEL020: $NUMBER (DEL030,^D8,<octal character code>,<$ACTION(CHKCHR)>)
DEL030: $NOISE (DEL040,<to>)
DEL040: $QUOTE (CONFRM,<quoted character>,<$ACTION(CHKCHS),$ALTER(DEL045)>)
DEL045: $NUMBER (CONFRM,^D8,<octal character code>,<$ACTION(CHKCHR),$ALTERNATE(DEL050)>)
DEL050: $KEYDSP (DEL060)
DEL060: $STAB
DSPTAB (DEL070,0,<DELIMITER-CHARACTER>,CM%INV)
DSPTAB (CONFRM,1,<NO-ACTION>)
DSPTAB (DEL070,0,<PREFIX-CHARACTER>)
DSPTAB (DEL080,2,<SLEW>)
DSPTAB (DEL090,3,<VFU-CHANNEL>)
$ETAB
DEL070: $NOISE (DEL074,<and>)
DEL074: $KEYDSP (DEL075,<$DEFAULT(<NO-ACTION>),$ALTERNATE(DEL076)>)
DEL075: $STAB
DSPTAB (CONFRM,1,<NO-ACTION>)
DSPTAB (DEL080,2,<SLEW>)
DSPTAB (DEL090,3,<VFU-CHANNEL>)
$ETAB
DEL076: $QUOTE (CONFRM,<quoted character>,<$ACTION(CHKCHS),$ALTER(DEL078)>)
DEL078: $NUMBER (CONFRM,^D8,<octal character code>,<$ACTION(CHKCHR)>)
DEL080: $NUMBER (DEL082,^D10,,<$ACTION(CHKSLW)>)
DEL082: $NOISE (CONFRM,<lines>)
DEL090: $NUMBER (CONFRM,^D10,,<$ACTION(CHKVFU)>)
LOW010: $NOISE (CONFRM,<output>)
NUM010: $NOISE (NUM020,<is>)
NUM020: $KEY (CONFRM,NUM030)
NUM030: $STAB
KEYTAB (0,<7-BITS>)
KEYTAB (1,<8-BITS>)
$ETAB
UPP010: $NOISE (CONFRM,<output only>)
SUBTTL Command tables -- VFU mode
UNP010:
PUN010: $NOISE (CHA020,<channel number>)
CHA010: $NOISE (CHA020,<number>)
CHA020: $NUMBER (CHA030,^D10,<VFU channel number>,<$ACTION(CHKVFU)>)
CHA030: $KEYDSP (CHA040)
CHA040: $STAB
DSPTAB (CONFRM,0,<ALL-LINES>)
DSPTAB (CONFRM,1,<BOTTOM-OF-FORM>)
DSPTAB (CHA050,2,<EVERY>)
DSPTAB (CHA055,3,<FORMS-BREAK>)
DSPTAB (CHA060,4,<LINES>)
DSPTAB (CONFRM,5,<TOP-OF-FORM>)
$ETAB
CHA050: $NUMBER (CHA055,^D10,,<$ACTION(CHKLIN)>)
CHA055: $NOISE (CONFRM,<lines>)
CHA060: $NOISE (CHA062,<numbered>)
CHA062: $NUMBER (CHA064,^D10,,<$ACTION(CHKLIN)>)
CHA064: $COMMA (CHA062,<$ALTERNATE(CONFRM)>)
CLR010: $NOISE (CONFRM,<entire VFU>)
INF010: $NOISE (CONFRM,<about current VFU>)
LEN010: $NOISE (LEN020,<of physical page is>)
LEN020: $NUMBER (LEN030,^D10,,<$DEFAULT(<66>)>)
LEN030: $NOISE (CONFRM,<lines>)
LIN010: $NOISE (LIN020,<set by VFU is>)
LIN020: $KEY (CONFRM,LIN030,<$DEFAULT(<PRINTER-CONTROLLED>)>)
LIN030: $STAB
KEYTAB (354,6-LPI)
KEYTAB (355,8-LPI)
KEYTAB (356,LEFT-ALONE,CM%INV)
KEYTAB (356,PRINTER-CONTROLLED)
$ETAB
PAG010: $NOISE (PAG020,<of logical page is>)
PAG020: $NUMBER (PAG030,^D10,,<>)
PAG030: $NOISE (CONFRM,<lines>)
SUBTTL Parser action routines for field validation
;ROUTINE TO VERIFY OCTAL CHARACTER CODES FOR RAM COMMANDS
;STRING
CHKCHS: MOVE S2,CR.SAV(S2) ;GET ADDRESS OF PARSE DATA
LDB S1,[POINT 7,CR.RES(S2),13] ;GET SECOND CHARACTER
JUMPN S1,CHKCER ;IF STRING TOO LONG, ERROR
LDB S1,[POINT 7,CR.RES(S2),6] ;FIRST CHARACTER IS VALUE
CAIA
;NUMBER
CHKCHR: MOVE S1,CR.RES(S2) ;GET DATUM
CAIL S1,0 ;MUST BE IN RANGE 0 THRU
CAILE S1,^D255 ;255
JRST CHKCER ;FOR 8-BIT MODE
TLNN F,F.R8BT ;OK IF 8-BIT MODE
CAIG S1,^D127 ;BUT 7 BIT MODE MUST BE 0 THRU 127
$RETT ;OK
CHKCER: MOVEI S1,ERARG$ ;ERROR CODE
MOVEI S2,[ASCIZ /Invalid character code/]
$RETF ;NG
;ROUTINE TO VERIFY SLEW RANGES FOR RAM COMMANDS
CHKSLW: MOVE S1,CR.RES(S2) ;GET DATUM
CAIL S1,0 ;MUST BE IN RANGE 0 THRU
CAILE S1,^D15 ;15
CAIA ;ERROR
$RETT ;OK
MOVEI S1,ERARG$ ;ERROR CODE
MOVEI S2,[ASCIZ /Invalid slew distance (0 thru 15)/]
$RETF ;NG
;ROUTINE TO VERIFY VFU CHANNEL NUMBERS
CHKVFU: MOVE S1,CR.RES(S2) ;GET DATUM
CAIL S1,1 ;MUST BE IN RANGE 1 THRU
CAILE S1,^D12 ;12
CAIA
$RETT ;OK
MOVEI S1,ERARG$ ;ERROR CODE
MOVEI S2,[ASCIZ /Invalid channel number/]
$RETF ;NG
;ROUTINE TO VERIFY VFU LINE NUMBERS
CHKLIN: MOVE S1,CR.RES(S2) ;GET DATUM
CAIL S1,1 ;MUST BE IN RANGE 1 THRU
CAMLE S1,LINSPP ;PHYSICAL PAGE SIZE
CAIA
$RETT ;OK
MOVEI S1,ERARG$ ;ERROR CODE
MOVEI S2,[ASCIZ /Invalid line number/]
$RETF ;NG
SUBTTL Generic commands -- Control-Z and EXIT
EXP CTLZ.H ;ADDRESS OF HELP TEXT
.CTRLZ: JRST .EXIT ;SAME AS EXIT
CTLZ.H: ASCIZ |
Typing Control-Z will cause the program to
return to monitor level. This is the preferred
method of exiting the program.
|
EXP EXIT.H ;ADDRESS OF HELP TEXT
.EXIT: $HALT ;RETURN TO MONITOR
JRST START ;THE FOOL TYPED CONTINUE
EXIT.H: ASCIZ |
The EXIT command will cause the program to
return to monitor level. This command is
equivalent to typing ^Z.
|
SUBTTL Generic commands -- HELP
EXP HELP.H ;ADDRESS OF HELP TEXT
.HELP: PUSHJ P,P$KEYW## ;GET A KEYWORD
JUMPF HELP.1 ;SHOULDN'T FAIL
MOVE S1,ARG.DA(S2) ;POINT TO RETURNED DATA
HLRZ S1,(S1) ;NOW GET PROCESSOR ADDRESS
MOVE S1,-1(S1) ;AND THE HELP TEXT POINTER
HRROI S1,(S1) ;FINALLY POINT TO THE TEXT
JRST HELP.2 ;ONWARD
HELP.1: HRROI S1,HELP.H ;POINT HELP FOR THIS COMMAND
HELP.2: $CALL K%SOUT ;TYPE IT
HRROI S1,[BYTE(7).CHCRT,.CHLFD,0] ;POINT TO A CRLF
$CALL K%SOUT ;TYPE IT
POPJ P, ;DONE
HELP.H: ASCIZ |
The HELP command will print useful information about
any other command. Typing HELP with no argument will
cause this text to be printed.
|
SUBTTL Generic commands -- MODE
EXP MODE.H
.MODE: $CALL P$KEYW## ;GET KEYWORD
JUMPF SYNERR
HRREM S1,CMDMOD ;SET NEW MODE
MOVE T1,S1 ;SAVE WORD INDEX
ASH S1,1 ;INDEX BY TWOS
MOVE T2,S1 ;SAVE BY-TWOS INDEX
DMOVE S1,[EXP RAM010,[ASCIZ /LP20_RAM>/]
EXP -1,0 ;TOP LEVEL
EXP VFU010,[ASCIZ /LP20_VFU>/]
]+2(T2) ;GET ADDRESS OF NEW PARSE TABLE/PROMPT
STORE S1,PARBLK+PAR.TB ;STORE NEW PARSE TABLE ADDRESS
STORE S2,PARBLK+PAR.PM ;STORE NEW PROMPT ADDRESS
DMOVE S1,[SIXBIT /RAM/ ;DEFAULT FILE EXTENSION
EXP RAM030 ;AND HELP KEYWORDS
SIXBIT /___/
EXP 0
SIXBIT /VFU/
EXP VFU030]+2(T2) ;FOR THIS MODE
TOPS10<
STORE S1,DEFFIL+.FDEXT ;SET IN DEFAULT FILE SPEC
>
TOPS20<
$TEXT (<-1,,DEFFNM>,<DSK:LP20.^W/S1/^0>)
>
STORE S2,HLPKEY+.CMDAT+1 ;STORE CORRECT HELP CHAIN
DMOVE S1,[XWD DEFRAM,RDATA ;DEFAULT RAM
EXP RDATA+DEFRLN
EXP 0,0
XWD DEFVFU,RDATA ;DEFAULT VFU
EXP RDATA+DEFVLN
]+2(T2) ;FOR THIS MODE
BLT S1,-1(S2) ;COPY DEFAULT DATA INTO PLACE
DMOVE S1,[EXP LSTRAM,SHORAM ;SWITCH PARSES FOR LIST AND SHOW
EXP 0,0
EXP LSTVFU,SHOVFU]+2(T2)
MOVEM S1,LSTSWI+.CMDAT+1 ;STORE FOR LIST
MOVEM S2,SHOSWI+.CMDAT+1 ;AND FOR SHOW
DMOVE S1,[POINT 8,RDATA ;ASSUME VFU STYLE DATA
EXP 4]
DMOVEM S1,FILPTR ;POINT TO DEFAULT VFU
MOVEI S1,^D66
MOVEM S1,LINSPP
MOVEI S1,^D60
MOVEM S1,LINSLP
MOVEI S1,377 ;LOWER LIMIT IS 377
MOVEM S1,RAMLIM
SETZM RAMLIM+1 ;UPPER LIMIT IS UNTOUCHED
SKIPL CMDMOD ;IN VFU MODE?
$RET ;YES, DONE
MOVE S1,[XWD RDATA,RDATA+100] ; RAM DATA IS DUPLICATED FOR SECOND
BLT S1,RDATA+177 ;128 CHARACTERS
DMOVE S1,[POINT 18,RDATA ;SETUP RAM STYLE POINTERS
EXP 2]
DMOVEM S1,FILPTR ;TO DEFAULT RAM
$RET
MODE.H: ASCIZ |
The MODE command selects the operating mode of the LP20 program.
RAM mode is used for editing .RAM files, which specify how the ASCII
characters in a user data file are to be interpreted by an LP20 controller.
VFU mode is used for editing .VFU files, which specify the vertical
pitch and physical size of each logical page, and on which line(s) each
VFU channel stops.
|
SUBTTL Generic commands -- LIST and SHOW
EXP SHOW.H
.SHOW: TROA F,LS.TTY!LS.BRF ;MARK LISTING TO TERMINAL
EXP LIST.H
.LIST: DMOVE T1,RAMLIM ;DEFAULT /BEGIN AND /END
CAMLE T1,T2 ;IF OUT OF ORDER
EXCH T1,T2 ;USER HASN'T TOUCHED ANYTHING
LIST0S: PUSHJ P,P$SWIT## ;GET SWITCH
JUMPF LIST.0 ;NONE, TRY FILESPEC
MOVE S1,ARG.DA(S2) ;GET RETURNED CODE
TRNE S1,LS.VAL ;VALUE SWITCH?
JRST LIST0V ;YES, PROCESS VALUE
TRO F,(S1) ;NO - SET ANY BITS FOR THIS COMMAND
JRST LIST0S ;LOOP FOR ALL SWITCHES
LIST0V: MOVE T3,S1 ;SAVE SWITCH CODE
PUSHJ P,PARCHR ;GET VALUE
JUMPF SYNERR
CAIN T3,1 ;/BEGIN?
JRST [MOVEM S1,T1 ;YES, SAVE
MOVEM S1,RAMLIM ;AND RESET LOWER LIMIT FOR DEFAULT
JRST LIST0S] ;LOOP FOR MORE SWITCHES
CAIN T3,2 ;/END?
JRST [MOVEM S1,T2 ;YES, SAVE
MOVEM S1,RAMLIM+1 ;AND RESET UPPER LIMIT FOR DEFAULT
JRST LIST0S] ;LOOP FOR MORE SWITCHES
JRST LIST0S ;LOOP FOR MORE
LIST.0: CAMLE T1,T2 ;MUST BE IN ORDER
$MSG (<?>,BEM,GETCMD,</BEGIN:^O3R0/T1,BYTMSK/ exceeds /END:^O3R0/T2,BYTMSK/>)
DMOVEM T1,RAMLIM ;SAVE NEW DEFAULTS
TRNE F,LS.TTY ;SHOW?
JRST LIST.2 ;YES, SKIP ALL THIS
PUSHJ P,P$OFIL## ;GET FILE
JUMPF SYNERR ;COMMAND SYNTAX ERROR
PUSH P,S1
PUSHJ P,P$CFM## ;MUST BE EOL
POP P,S1
JUMPF SYNERR ;COMMAND SYNTAX ERROR
MOVEM S1,FILEFD+FOB.FD ;SAVE FD ADDRESS
SETZM FILEFD+FOB.US ;NO IYB PPN
SETZM FILEFD+FOB.CD ;NO CONNECTED DIRECTORY
SETZM FILEFD+FOB.AB ;NO ATTRIBUTES BLOCK
MOVEI S1,^D7 ;7 BIT BYTES
MOVEM S1,FILEFD+FOB.CW ;SAVE
MOVEI S1,FOB.SZ ;LENGTH OF FOB
MOVEI S2,FILEFD ;ADDRESS OF FOB
$CALL F%OOPN
JUMPT LIST.1 ;ONWARD IF NO ERRORS
MOVE S2,FILEFD+FOB.FD ;GET OUR FD
$MSG (<?>,CWF,GETCMD,<Cannot write ^F/(S2)/; ^E/S1/>)
LIST.1: MOVEM S1,LSTIFN ;SAVE
MOVNI S2,1 ;WE WANT THE EXACT FD
$CALL F%FD ;GET IT
SKIPT ;ANY ERRORS?
SKIPA S2,FILEFD+FOB.FD ;YES--JUST USE WHAT WE HAVE
MOVEI S2,(S1) ;POINT TO SOURCE
$MSG (<[>,WLF,,<Writing listing to ^F/(S2)/>)
LIST.2: MOVEM F,TXTFLG ;SAVE FLAGS FOR $TEXT OUTPUT
MOVE S1,CMDMOD ;GET COMMAND MODE
PUSHJ P,@[EXP LIST.R,0,LIST.V]+1(S1) ;CALL LISTER
;T1/ BEGIN: T2/ END:
MOVE S1,LSTIFN
TRNN F,LS.TTY ;DON'T CLOSE FILE IF SHOW CMD
$CALL F%REL ;CLOSE DISK FILE
TRNE F,LS.TTY ;TTY LISTING?
$TEXT (LSTCHR,<>) ;YES, ADD A <CR><LF> BEFORE PROMPT
$RET
SHOW.H: ASCIZ |
The SHOW (editing buffer) command lists the contents of the editing buffer
on your terminal. (Use LIST to direct the output to a disk file.)
The following switches may be used to control the output produced:
/ALL-ENTRIES List entire buffer
/BEGIN: Start listing at specified position
/END: End listing with specified position
The default is to show only the part of the buffer of current interest.
In VFU mode, the following additional switch selects the output format:
/BY-LINE Output VFU by line number rather than by channel
The default is to output a listing by channel number.
|
LIST.H: ASCIZ |
The LIST (editing buffer to) filespec command produces a readable listing
of the editing buffer on the specified file.
The output file must be on disk. Use SHOW for listing the buffer to your
terminal.
In RAM mode, the following switch may be used:
/BRIEF Do not include reference data at end of listing
The default is to include about a page of reference data at the end of
the listing.
In VFU mode, the following switche may be used:
/BY-LINE Output VFU by line number rather than by channel
The default is to output a listing by channel number.
|
LSTCHR: MOVE S2,TXTFLG ;GET FLAGS (F IS APPARENTLY CORRUPT)
TRNE S2,LS.TTY ;SHOW?
PJRST K%BOUT## ;YES, LET GLXTXT DO IT
MOVE S2,S1 ;COPY BYTE
MOVE S1,LSTIFN ;GET THE IFN OF THE FILE
PJRST F%OBYT ;GO OUTPUT IT
SUBTTL Generic commands -- READ and WRITE
EXP READ.H
.READ: SETZ T1, ;READ
CAIA WRIT.H
.WRITE: MOVEI T1,1 ;WRITE
FILE: HRRI F,WR.L10 ;DEFAULT TO WRITE/LP100
PUSHJ P,@[EXP P$IFIL## ;GET INPUT FILE
EXP P$OFIL##](T1) ;GET OUTPUT FILE
JUMPT FILE.D ;GOT IT
HLLZS F ;ELSE RESET FLAGS
FILE.A: PUSHJ P,P$SWIT## ;TRY TO GET A SWITCH
JUMPF FILE.C ;CAN'T
MOVE S1,ARG.DA(S2) ;GET RETURNED CODE
IOR F,S1 ;SAVE FLAG
JRST FILE.A ;LOOP FOR ANOTHER
FILE.C: PUSHJ P,@[EXP P$IFIL## ;GET INPUT FILE
EXP P$OFIL##](T1) ;GET OUTPUT FILE
JUMPF SYNERR ;COMMAND SYNTAX ERROR
PUSH P,S1
PUSHJ P,P$CFM## ;MUST BE EOL
POP P,S1
JUMPF SYNERR ;COMMAND SYNTAX ERROR
FILE.D: MOVEM S1,FILEFD+FOB.FD ;SAVE FD ADDRESS
SETZM FILEFD+FOB.US ;NO IYB PPN
SETZM FILEFD+FOB.CD ;NO CONNECTED DIRECTORY
SETZM FILEFD+FOB.AB ;NO ATTRIBUTES BLOCK
PUSHJ P,@[EXP E$READ,E$WRIT](T1) ;DO I/O
POPJ P, ;RETURN
READ.H: ASCIZ |
The READ command reads a pre-existing VFU or RAM file into the editing
buffer.
In VFU mode, the controller type (LP20 or LP100) is determined automatically.
|
WRIT.H: ASCIZ |
The WRITE command writes the editing buffer to a new .VFU or .RAM file.
In VFU mode, the file format may be selected with the following switches:
/8-BIT-FORMAT Writes a (TOPS-20) 8-bit VFU file with LP20 codes.
/LP100-CODES Writes LP100-format VFU codes.
The default is /LP100-CODES in a (TOPS-10) 7-bit VFU file.
If both /8-BIT-FORMAT and /LP100-CODES are specified, the LP100 codes
will be written to a (TOPS-20) 8-bit VFU file.
Note that TOPS-10 normally uses /LP100-CODES in 7-bit VFU files, even with
LP20 controllers. The monitor/LPTSPL provide automatic translation.
|
E$READ::TDZA P2,P2 ;READ
E$WRIT:: MOVEI P2,1 ;WRITE
MOVEI S1,^D36 ;36 BIT BYTES
MOVEM S1,FILEFD+FOB.CW ;SAVE
MOVEI S1,FOB.SZ ;LENGTH OF FOB
MOVEI S2,FILEFD ;ADDRESS OF FOB
XCT FILTAB(P2) ;OPEN FOR INPUT OR OUTPUT
JUMPT FILE.1 ;ONWARD IF NO ERRORS
MOVE S2,FILEFD+FOB.FD ;GET TARGET FD
SKIPN P2 ;READING OR WRITING?
$MSG (<?>,CRF,GETCMD,<Cannot read ^F/(S2)/; ^E/S1/>)
$MSG (<?>,CWF,GETCMD,<Cannot write ^F/(S2)/; ^E/S1/>)
FILE.1: MOVEM S1,IFN ;SAVE
MOVNI S2,1 ;WE WANT THE EXACT FD
$CALL F%FD ;GET IT
SKIPT ;ANY ERRORS?
SKIPA S2,FILEFD+FOB.FD ;YES--JUST USE WHAT WE HAVE
MOVEI S2,(S1) ;POINT TO SOURCE
HRLZS S2 ;BUILD A BLT POINTER
HRRI S2,FD ;GET DESTINATION
LOAD S1,.FDLEN(S1),FD.LEN ;GET LENGTH
BLT S2,FD-1(S1) ;COPY IT AWAY
JUMPN P2,OPEN.4 ;JUMP IF WRITING
MOVE S1,IFN ;GET IFN
PUSHJ P,GETFSZ ;GET FILE SIZE IN WORDS
SKIPLE S1 ;BETTER BE A REAL FILE
CAILE S1,MAXFIL ;MAKE SURE IT'S REASONABLE
$MSG (<?>,NLS,GETCMD,<Not a legal size for ^F/FD/>)
$CALL M%GMEM ;GET MEMORY TO MATCH SIZE OF FILE
ADJSP P,3 ;ALLOCATE SOME SPACE
DMOVEM S1,-2(P) ;STORE RESULT
MOVN P1,S1 ;NEGATE SIZE
MOVSS P1 ;MAKE AOBJN POINTER TO FILE
HRR P1,S2 ;COMPLETE WITH ADDRESS
MOVEM P1,0(P) ;SAVE IT FOR LATER
$MSG (<[>,RDF,,<Reading data from ^F/FD/>)
OPEN.1: MOVE S1,IFN ;GET IFN
$CALL F%IBYT ;GET A WORD
JUMPT OPEN.2 ;JUMP IF NO ERRORS
$MSG (<?>,FIE,OPEN.E,<^E/S1/ reading ^F/FD/>)
OPEN.E: DMOVE S1,-2(P) ;GET FILE MEMORY
$CALL M%RMEM ;GET RID OF IT
ADJSP P,-3 ;FIX STACK
MOVE S1,IFN ;GET IFN
$CALL F%REL ;RELEASE THE FILE
JRST GETCMD ;DONE
OPEN.2: MOVEM S2,(P1) ;PUT A WORD
AOBJN P1,OPEN.1 ;LOOP THROUGH ENTIRE FILE
POP P,P1 ;POINT TO FILE IN MEMORY
DMOVE T1,[POINT 18,RDATA ;ASSUME .RAM FILE
EXP 2] ;BYTES/WORD
MOVE S2,[POINT 18,(P1),17] ;EXTERNAL IS ALSO 18 BIT
PUSH P,[0] ;NORMAL BYTES
SKIPG CMDMOD ;PROCESSING VFU?
JRST OPEN.R ;NO, NOTHING SPECIAL
SETZM VFUSIZ ;VFU IS EMPTY
;FIGURE OUT FILE FORMAT
DMOVE T1,[POINT 8,RDATA ;VFU'S ARE STORED INTERNALLY AS 8 BIT
EXP 5] ;BYTES/WD
MOVE S2,[POINT 7,(P1)] ;ASSUME 7-BIT EXTERNAL REPRESENTATION
ILDB S1,S2 ;GET FIRST BYTE
CAIL S1,25 ;SKIP IF LESS THAN FIRST VALID START
CAILE S1,27 ;SKIP IF IN RANGE
SETOM (P) ;NOT, WIERD 8-BIT BYTES
SKIPE (P) ;WIERD?
MOVE S2,[POINT 16,(P1),15] ;YES, ASSUME 8-BIT VFU IN DTE FORMAT
OPEN.R: DMOVEM T1,FILPTR ;SAVE POINTERS TO INTERNAL DATA
OPEN.3: LDB S1,S2 ;GET THE NEXT BYTE
SKIPN (P) ;DTE FORMAT?
JRST OPN.3A ;NO
IDPB S1,T1 ;YES, DEPOSIT LOW BYTE FIRST
PUSHJ P,CHKSTP ;CHECK FOR STOP CODE
JRST OPN.3S ;GOT ONE, STOP
LSH S1,-8 ;GET HIGH BYTE NEXT
OPN.3A: IDPB S1,T1 ;STORE IN INTERNAL BUFFER
PUSHJ P,CHKSTP ;CHECK FOR STOP CODE
JRST OPN.3S ;GOT ONE, STOP
IBP S2 ;POINT TO NEXT EXTERNAL BYTE
TRNN S2,-1 ;DONE ENTIRE INTERNAL WORD YET?
JRST OPEN.3 ;NO, KEEP GOING
HLLZS S2 ;YES, RECYCLE THE WORD OFFSET
AOBJN P1,OPEN.3 ;AND LOOP FOR ENTIRE FILE
SKIPGE CMDMOD ;VFU MODE?
JRST OPN.3R ;NO, RAM
OPN.3S: SETZ S2, ;ASSUME BAD FILE
MOVE S1,FILPTR ;GET POINTER TO FILE
ILDB S1,S1 ;READ FIRST BYTE
CAIN S1,25 ;GENERIC START?
MOVEI S2,356 ;YES, USE 8-BIT VARIETY
CAIN S1,26 ;6-LPI START?
MOVEI S2,354 ;YES, LIKEWISE
CAIN S1,27 ;8-LPI START?
MOVEI S2,355 ; ...
JUMPN S2,OPN.3B ;JUMP IF VALID START CODE
CAIL S1,354 ;NOT 7-BIT, IS IT 8?
CAILE S1,356 ;...
$MSG (<?>,IVS,OPEN.E,<Invalid VFU start code ^O/S1/>)
JRST OPN.3C ;VALID 8-BIT START, CHECK STOP
OPN.3B: MOVE S1,FILPTR ;GET POINTER TO START BYTE
IDPB S2,S1 ;REPLACE START BYTE WITH 8-BIT CODE
MOVEI S2,1 ;SET INDEX FOR PROPER STOP CODE
OPN.3C: LDB S1,T1 ;GET LAST VFU DATA BYTE
CAME S1,[EXP 357,126](S2) ;MAKE SURE STOP CODE MATCHES START
$MSG (<?>,NVS,OPEN.E,<Invalid VFU stop code ^O/S1/>)
MOVEI S1,357 ;SET TO 8-BIT CODE
DPB S1,T1 ;SO INTERNAL CODES ARE ALWAYS 8-BIT
MOVE S1,VFUSIZ ;GET SIZE OF VFU
CAIGE S1,<143*2>+2 ;MAX OF 143 LINES + START AND STOP
TRNE S1,1 ;BETTER BE EVEN (2-BYTE PAIRS +S +S)
OPN.3D: $MSG (<?>,NVL,OPEN.E,<Invalid VFU length>)
LSH S1,-1 ;TURN INTO LINES
SOJLE S1,OPN.3D ;CORRECT FOR START AND STOP. BE SANE.
MOVEM S1,LINSPP ;SET AS PHYSICAL LENGTH
CAMGE S1,LINSLP ;CHECK LOGICAL LENGTH
MOVEM S1,LINSLP ;LOGICAL WAS PAST NEW PHYSICAL, SHORTEN
JRST OPN.3X ;IT'S OK, EXIT
OPN.3R: MOVE S1,-2(P) ;GET SIZE OF .RAM FILE
CAIE S1,200 ;RAM FILES MUST BE 256 CHARS IN 18 BITS
$MSG (<?>,NRF,OPEN.E,<Not a RAM file>)
OPN.3X: DMOVE S1,-2(P) ;GET FILE MEMORY
$CALL M%RMEM ;GET RID OF IT
ADJSP P,-3 ;FIX STACK
MOVEI S1,377 ;LOWER LIMIT IS 377
MOVEM S1,RAMLIM
SETZM RAMLIM+1 ;UPPER LIMIT IS UNTOUCHED
JRST OPEN.5 ;DONE, RELEASE FILE AND EXIT
;ROUTINE TO TURN AN IFN IN S1 INTO THE FILE SIZE IN WORDS
TOPS10<
;ON TOPS-10, WE CAN TRUST GLXFIL
GETFSZ: MOVX S2,FI.SIZ ;SIZE OF FILE IN BYTES
PJRST F%INFO ;GET SIZE OF FILE
>
TOPS20<
;ON THE OTHER HAND, TOPS-20 GLXFIL JUST DOESN'T
GETFSZ: $SAVE <T1,T2,T3>
MOVX S2,FI.CHN ;GET THE JFN ASSIGNED
$CALL F%INFO ;BY GLXLIB
MOVE S2,[2,,.FBBYV] ;READ 2 WORDS OF FDB INFO
MOVEI T1,T2 ;INTO T2 AND T3
GTFDB% ;READ
ERJMP [$STOP (JSF,<GTFDB% JSYS failed>)]
MOVEI S1,^D36 ;BITS/WORD
LOAD S2,T2,FB%BSZ ;BYTE SIZE OF FILE
IDIVI S1,(S2) ;COMPUTE BYTES/WORD IN FILE
MOVE S2,T3 ;GET BYTES IN FILE
EXCH S1,S2 ;SWITCH
IDIVI S1,(S2) ;COMPUTE WORDS IN FILE
SKIPE S2 ;PARTIAL WORD AT END?
AOJ S1, ;YES, ALLOW FOR IT
$RET ;RETURN S1/ FILE SIZE IN WORDS
>
OPEN.4: $MSG (<[>,WDF,,<Writing data to ^F/FD/>)
SKIPG CMDMOD ;VFU?
JRST OPN.4R ;NO, RAM IS SIMPLE
TRNN F,WR.8BT ;/8-BIT FORMAT?
TRO F,WR.L10 ;NO, MUST BE /LP100 CODES
MOVE T1,FILPTR ;POINT TO DATA
SETZM VFUSIZ ;CLEAR VFU SIZE
OPN.4A: ILDB S1,T1 ;GET VFU CODE
PUSHJ P,CHKSTP ;SEE IF A STOP CODE
CAIA ;YES
JRST OPN.4A ;NO, CONTINUE
MOVE S1,VFUSIZ ;GET SIZE OF VFU IN BYTES
TRNN F,WR.8BT ;/8-BIT FORMAT?
IDIVI S1,5 ;NO, 7. 5/WORD
TRNE F,WR.8BT ;/8-BIT FORMAT?
IDIVI S1,4 ;YES, 4/WORD
SKIPE S2 ;PARTIAL WORD?
AOJ S1, ;YES, ALLOCATE IT
$CALL M%GMEM ;ALLOCATE A SCRATCH BUFFER
ADJSP P,2 ;SAVE SOME SPACE
DMOVEM S1,-1(P) ;TO SAVE THE DESCRIPTOR
HRLI S2,(POINT 8,) ;ASSUME /8-BIT FORMAT
TRNN F,WR.8BT ;IS IT?
HRLI S2,(POINT 7,) ;AH, WELL, 7-BIT
MOVE T2,FILPTR ;POINT TO DATA
ILDB S1,T2 ;GET START CODE
TRNE F,WR.L10 ;/LP100?
MOVE S1,[EXP 26,27,25]-354(S1) ;YES -- TRANSLATE TO 7-BIT START
IDPB S1,S2 ;OUTPUT START CODE
SETZM VFUSIZ ;RECOMPUTE SIZE OF VFU
OPN.4B: ILDB S1,T2 ;GET NEXT DATA BYTE
PUSHJ P,CHKSTP ;SEE IF A STOP BYTE
JRST OPN.4C ;JUMP WHEN AT END
IDPB S1,S2 ;NOT AT END, COPY VFU DATA
JRST OPN.4B ;LOOP TO END OF VFU
;HELPER ROUTINE TO SEE IF WE GOT A STOP CODE
CHKSTP: SKIPG CMDMOD ;MUST BE A VFU
JRST .POPJ1 ;RAM, CAN'T BE A STOP CODE
PUSH P,S1 ;SAVE INPUT
ANDI S1,377 ;IN CASE OF A 16-BIT FILE
CAIE S1,126 ;7-BIT STOP?
CAIN S1,357 ;OR 8-BIT?
SOS -1(P) ;YES TO EITHER, STOP
POP P,S1
AOS VFUSIZ ;COUNT ANOTHER VFU BYTE READ
JRST .POPJ1
OPN.4C: TRNE F,WR.L10 ;/LP100 ?
MOVEI S1,126 ;YES, USE LP100 STOP CODE
IDPB S1,S2 ;STORE STOP CODE
TRNN F,WR.8BT ;8-BIT FORMAT?
JRST OPN.4E ;NO, NO SWAPPING NEEDED
MOVE T1,0(P) ;YES, GET POINTER TO DATA
HRLI T1,(POINT 16,) ;DO IT TWO BYTES AT A TIME
PUSH P,S1 ;SAVE STOP CODE
OPN.4D: ILDB S1,T1 ;GET NEXT BYTE PAIR
MOVE T2,S1 ;COPY NEW BYTES
LSH S1,8 ;SHIFT HIGH BYTE UP
LSH T2,-8 ;SHIFT LOW BYTE DOWN
DPB T2,[POINT 8,S1,35] ;SO
DPB S1,T1 ;STORE SWAPPED BYTES
LDB S1,[POINT 8,S1,35-8] ;GET HIGH BYTE
CAME S1,(P) ;SEE IF A STOP BYTE
JRST OPN.4D ;NO, CONTINUE (STOP CAN'T BE LOW)
ADJSP P,-1 ;TOSS STOP CODE
OPN.4E: MOVS S2,-1(P) ;GET NUMBER OF WORDS IN VFU
HRR S2,0(P) ;ADDRESS OF BUFFER
OPN.WF: MOVE S1,IFN ;GET IFN
$CALL F%OBUF ;WRITE THE BUFFER OUT
JUMPT OPN.WX ;CHECK FOR ERRORS
ADJSP P,1 ;ADJUST STACK
$MSG (<?>,FOE,OPEN.E,<^E/S1/ writing ^F/FD/>)
OPN.4R: MOVSI S2,200 ;WORDS IN A .RAM FILE
HRRI S2,RDATA ;WHERE IT COMES FROM
MOVE S1,IFN ;GET IFN
$CALL F%OBUF ;WRITE THE BUFFER OUT
SKIPT ;CHECK FOR ERRORS
$MSG (<?>,EOR,OPEN.5,<^E/S1/ writing ^F/FD/>)
PUSHJ P,OPEN.5 ;CLOSE THE FILE
TOPS20<
MOVEI S1,400 ;BYTES IN FILE
MOVEI S2,^D18 ;NORMAL BYTE-SIZE FOR TOPS-20
PUSHJ P,SETBSZ ;SET THE BYTE-SIZE
>
$RET ;DONE
OPN.WX: DMOVE S1,-1(P) ;GET FILE MEMORY
$CALL M%RMEM ;GET RID OF IT
ADJSP P,-2 ;FIX STACK
PUSHJ P,OPEN.5 ;CLOSE THE FILE
TOPS20<
AOS S1,VFUSIZ ;DON'T FORGET THE START CODE
TRNE F,WR.8BT ;IF 8-BIT MODE
ASH S1,-1 ;WE WANT 16-BIT BYTES
MOVEI S2,^D7 ;ASSUME 7-BIT FILE
TRNE F,WR.8BT ;BUT, IF 8-BIT MODE
MOVEI S2,^D16 ;USE 16-BIT BYTES
PUSHJ P,SETBSZ ;SET THE BYTE-SIZE
>
$RET ;DONE
OPEN.5: MOVE S1,IFN ;GET IFN
$CALL F%REL ;RELEASE
POPJ P, ;AND RETURN
FILTAB: $CALL F%IOPN ;READ
$CALL F%OOPN ;WRITE
;ROUTINES TO UPDATE FILE BYTE SIZE AND EOF POINTER
;ENTERED WITH S1/ BYTES WRITTEN, S2/ PROPER BYTE SIZE
TOPS20<
SETBSZ: $SAVE <T1,T2,T3,T4>
DMOVE T2,S1 ;SAVE THE LENGTH AND BYTE SIZE
MOVSI S1,(GJ%OLD!GJ%SHT) ;WE MUST FIND THE FILE AGAIN
HRROI S2,FD+.FDSTG ;POINT TO THE EXACT FILENAME
GTJFN% ;GET THE FILE
$STOP (FDP,<Output file ^F/FD/ has disappeared>)
MOVE T4,S1 ;SAVE RESULT
HRLI S1,.FBBYV(CF%NUD) ;DON'T UPDATE DISK, UPDATE BYTE SIZE
MOVX S2,FB%BSZ ;CHANGE JUST THE BYTE SIZE
STORE T3,T1,FB%BSZ ;STORE THE NEW BYTE SIZE FOR CHFDB%
CHFDB% ;UPDATE BYTE SIZE
ERJMP CHFERR ;ERROR
MOVE S1,T4 ;GET JFN AGAIN
HRLI S1,.FBSIZ ;FILE SIZE
SETO S2, ;ALL BITS
MOVE T1,T2 ;CORRECT LENGTH
CHFDB% ;UPDATE
ERJMP CHFERR ;OOPS
MOVE S1,T4 ;ONCE AGAIN, OUR JFN
RLJFN% ;GET RID OF IT
$STOP (JDP,<JFN for ^F/FD/ has disappeared>)
$RET ;DONE
CHFERR: $STOP (CFF,<CHFDB% JSYS failure>)
>
SUBTTL RAM commands -- ARROW
EXP ARRO.H
.ARROW: PUSHJ P,PARCHR ;GET THE CHARACTER CODE
JUMPF SYNERR
MOVEI S2,INTBIT+"^" ;ARROW MODE TRANSLATION
PUSHJ P,SETRAM ;UPDATE THE RAM
$RET
ARRO.H: ASCIZ |
The ARROW ch command causes the character specified by ch to be
printed as ^C, where C is the upper-case character matching ch.
The RAM is loaded with Interrupt and the special code "^", which
causes the monitor to expand the character in up-arrow form.
|
SUBTTL RAM commands -- CLEAR
EXP RCLR.H
.RMCLR: PUSHJ P,P$CFM## ;CONFIRM
JUMPF SYNERR
SETZM RDATA ;MAKE RAM DO NOTHING
MOVE S1,[XWD RDATA,RDATA+1]
BLT S1,RDATA+<^D256/2> ;CLEAR ENTIRE RAM
$RET
RCLR.H: ASCIZ |
The CLEAR command initialized the entire RAM such that no character
will translate.
Note that MODE RAM loads in a default RAM, not a CLEAR RAM.
|
SUBTTL RAM commands -- (CONDITIONALLY-)TRANSLATE
EXP DELM.H
.DELIM: SETZ T1, ;NO TRANSLATE
CAIA TRAN.H
.TRANS: MOVEI T1,TRNBIT ;TRANSLATE
PUSHJ P,PARCHR ;GET THE CHARACTER CODE
JUMPF SYNERR
MOVE T2,S1 ;SAVE CHARACTER
PUSHJ P,TRN0.0 ;CALL PROCESSOR
$RETF
$RETT
TRN0.0: PUSHJ P,PARCHR ;GET THE NEW CHARACTER CODE
JUMPF TRAN.1 ;JUMP IF NONE
TRAN.0: IOR S1,T1 ;SET TRANSLATE/DELIMITER BITS
MOVE S2,T2 ;GET CHAR BEING TRANSLATED
EXCH S1,S2 ;CHAR IN S1
PUSHJ P,SETRAM ;CHANGE RAM
JRST .POPJ1 ;OK
;PROBABLY A KEYWORD
TRAN.1: $CALL P$KEYW## ;GET THE CODE
JUMPF SYNERR
PUSHJ P,@[EXP TRN1.D ;PREFIX-CHARACTER (DELIMITER-CHARACTER)
EXP TRN1.N ;NO-ACTION
EXP TRN1.S ;SLEW
EXP TRN1.V](S1) ;VFU
JRST SYNERR
JRST TRAN.0
TRN1.D: IORI T1,DELBIT ;SET DELIMITER BIT
ADJSP P,-1 ;TOSS RETURN
JRST TRN0.0 ;PROCESS POSSIBILITIES
TRN1.N: SETZ S1, ;NO-ACTION IS ZERO
JRST .POPJ1 ;HAPPY
TRN1.S: $CALL P$NUM## ;GET THE SLEW AMOUNT
$RETIF
IORI S1,PAPBIT+SLWBIT ;SAY PAPER MOTION AND SLEW
JRST .POPJ1 ;OK
TRN1.V: $CALL P$NUM## ;GET THE CHANNEL NUMBER
$RETIF
SOJ S1, ;MAKE CHANNELS START AT 0 FOR HW
IORI S1,PAPBIT ;PAPER MOTION, VFU CHANNEL
JRST .POPJ1 ;OK
DELM.H: ASCIZ |
CONDITIONALLY-TRANSLATE (character code) <octal number> (to) <object>
Causes the specified character to be translated to the specified
object only when preceded by a PREFIX-CHARACTER. See the
TRANSLATE command. When not translated, characters print as themselves.
|
TRAN.H: ASCIZ |
TRANSLATE (character code) <octal number> (to) <object>
Causes the specified character to be translated to the specified object.
For conditional translation, see CONDITIONALLY-TRANSLATE.
Available objects:
PREFIX-CHARACTER (and) <other object>
Specifies that this is a PREFIX-CHARACTER. PREFIX-CHARACTERs
cause the FOLLOWING character to be translated. PREFIX-CHARACTERs
themselves are translated unconditionally. (Possibly to themselves.)
The translation for this character is specified as <other object>.
The default is NO-ACTION.
NO-ACTION
When translated, no action or printing will occur.
SLEW <decimal number> (lines)
When the character is translated, causes the printer to slew the specified
number of lines, which must be in the range 0 to 15.
VFU-CHANNEL <decimal number>
When the character is translated, the printer advances to the next hole in
the specified channel of the vertical format tape. Channel number must be
in the range 1 to 12.
<octal number>
When translated, the character will print as the specified code.
|
SUBTTL RAM commands -- LIST and SHOW support
LIST.R: $TEXT (LSTCHR,<^M^JUser data RAM data RAM Flags>)
$TEXT (LSTCHR,<Oct ASCII Oct ASCII^A>)
TRNN F,LS.BRF ;IF /BRIEF, DON'T MISLEAD
$TEXT (LSTCHR,< (See key below)^A>)
$TEXT (LSTCHR,<^M^J--- ----- --- ----- ----------------->)
MOVE T3,FILPTR ;POINT TO FILE DATA
MOVSI T4,-400 ;ASSUME MAX LENGTH
TRNN F,LS.TTY ;IF FILE LISTING
JRST LSTR.L ;USE MAX
TRNN F,LS.ALL ;IF ONLY PART WANTED
JRST LSTR.P ;DO PARTIAL LISTING
MOVEI S1,377 ;FULL LISTING
MOVEM S1,RAMLIM ;SO RESET WORKING RANGE
SETZM RAMLIM+1 ;AS USER HAS SEEN WHOLE THING
JRST LSTR.L ;NOW GO DO IT
LSTR.P: MOVE T3,T1 ;WHERE TO START
ADJBP T3,FILPTR ;BUMP TO BEGINNING
SUBM T1,T2 ;- (END - BEGIN)
MOVSI T4,-1(T2) ; - ( (END - BEGIN) + 1 )
HRR T4,T1 ;START AT BEGINNING (WHERE ELSE?)
LSTR.L: ILDB S1,T3 ;GET NEXT BYTE
HRRZ S2,T4 ;GET CURRENT BYTE
PUSHJ P,LSTR.C
MOVE S2,S1
PUSHJ P,LSTR.C
TRNE S1,INTBIT
$TEXT (LSTCHR,<Int ^A>)
TRNE S1,DELBIT
$TEXT (LSTCHR,<Del ^A>)
TRNE S1,TRNBIT
$TEXT (LSTCHR,<Trn ^A>)
TRNN S1,PAPBIT
JRST LSTR.1
CHNMSK==17
TRNN S1,SLWBIT
SKIPA T1,[[ITEXT (<VFU chn ^D/S1,CHNMSK/^A>)]]
SKIPA T1,[[ITEXT (<Slew ^D/S1,CHNMSK/^A>)]]
AOJ S1,
$TEXT (LSTCHR,<PI ^I/(T1)/^A>)
LSTR.1: $TEXT (LSTCHR,<>)
AOBJN T4,LSTR.L
TRNN F,LS.BRF ;QUIET IF /BRIEF
$TEXT (LSTCHR,<^T/RAMKEY/^A>)
$RET
;ROUTINE TO LIST A CHARACTER AS OCTAL, ASCII
LSTR.C: ANDI S2,BYTMSK ;PITCH CONTROL BITS
MOVE T2,S2
PUSH P,S2
ANDI S2,CHRMSK
CAIL S2,40
SKIPA T1,[[ITEXT (< ^7/S2,CHRMSK/ ^A>)]]
MOVEI T1,[ITEXT (< ^^^7/S2,CHRMSK/ ^A>)]
CAIN S2,177
MOVEI T1,[ITEXT (< DEL ^A>)]
CAIGE S2,40
JRST [POP P,S2
TRO S2,100
JRST .+2]
POP P,S2
$TEXT (LSTCHR,<^O3R0/T2,BYTMSK/ ^I/(T1)/ ^A>)
$RET
RAMKEY: ASCIZ |
-----------------General information---------------
Characters sent to the printer are looked-up in the RAM to determine how
they are processed. The RAM may specify that a character is to be printed,
translated to another character or action, conditionally translated, or
ignored.
After the RAM processing occurs, a second level of processing is handled
by the controller. <TAB> characters (011) are translated to enough spaces
to reach the next 8-column tab stop. (If past col 127, executes a LF, then
tabs to col 9.) <NUL> characters (000) are not passed to the printer at all.
They may be used to inhibit any action. <CR> (015), <LF> (012), and <FF> (014)
are normally translated by the RAM, but if output will cause paper motion
independent of the VFU. Any other non-printing character will be printed
as a space. Any non-paper motion character received in column 133 causes
a <LF> to be output first.
Character marked as "delimiters" can cause the following character to
be processed differently from the normal case. For example, the RAM can
implement FORTRAN carriage control See examples below.
----------------Key to flags-------------------
Int Processor intervenes before character is printed. If Trn is set,
applys only if DELHLD is st. (Prefixed character) Driver handles
if data is 136 (^), otherwise "Undefined character interrupt".
Del Current and following character are translated, regardless of Trn.
See examples. DELHLD is set for next character.
Trn RAM data or command is sent to printer rather than input character.
Modifies Int, PI. DEL forces Trn action.
PI Paper motion initiated if Trn or DELHLD also set. Motion may
be a slew (absolute physical advance), or VFU channel advance.
Examples:
---------
To make "1" advance to top-of-form when in column 1, but print as "1"
otherwise (eg, FORTRAN carriage control):
<CR> Del no-action
<LF> Del no-action
1 PI VFU chn 1
To make <CR> advance 0 lines:
<CR> Trn PI Slew 0
To print all <ESC> characters as "$":
<ESC> Trn (Data = 044)
To print Control/X as "^X":
^X Int (Data = 136) [Implemented in device driver]
|
SUBTTL RAM commands -- LOWER-CASE/UPPER-CASE
EXP LOWR.H
.LOWER: MOVEI S2,TRNBIT+"@"+40 ;CONVERT TO SELF
PJRST RAMCAS ;DO CASE
EXP UPPR.H
.UPPER: MOVEI S2,TRNBIT+"@" ;CONVERT TO UPPER CASE
;PJRST RAMCAS
RAMCAS: MOVEI S1,"@"+40 ;DO ALL LOWER CASE LETTERS
DMOVE T1,S1 ;SAVE POSITION,CONVERTED VALUE
MOVEI T3,177-140 ;NUMBER OF CODES TO DO (140-176)
RAMCA1: PUSHJ P,SETRAM ;UPDATE RAM WITH NEW DATA
AOS S1,T1 ;ADVANCE TO NEXT CHAR
AOS S2,T2 ;ADVANCE DATA TOO
SOJG T3,RAMCA1 ;CONTINUE FOR ALL ASCII LOWER-CASE
$RET
LOWR.H: ASCIZ |
The LOWER-CASE (output) command sets the ASCII lower case codes (140 thru
176) to translate to themselves. Used with 96 character printers.
|
UPPR.H: ASCIZ |
The UPPER-CASE (output only) command sets the ASCII lower case codes (140
thru 176) to translate to the corresponding upper case characters. Used
with 64 character printers.
|
SUBTTL RAM commands -- NUMBER-OF-DATA-BITS
EXP DATB.H
.DATAB: $CALL P$KEYW ;GET THE KEYWORD
JUMPF SYNERR
SKIPN S1 ;8?
TLZA F,F.R8BT ;NO
TLO F,F.R8BT ;YES
$RET
SUBTTL RAM commands -- Utility routines
SETRAM: CAMGE S1,RAMLIM ;SEE IF NEW LOW
MOVEM S1,RAMLIM ;IT IS
CAMLE S1,RAMLIM+1 ;SEE IF NEW HIGH
MOVEM S1,RAMLIM+1 ;IT IS
ROT S1,-1 ;COMPUTE RAM OFFSET
SKIPL S1 ;ODD BYTE?
HRLM S2,RDATA(S1) ;NO, EVEN
SKIPGE S1 ;EVEN?
HRRM S2,RDATA(S1) ;NO, ODD
ADDI S1,^D128/2 ;POINT TO SECOND HALF
TLNE F,F.R8BT ;8-BIT DATA?
$RET ;YES, DONE
SKIPL S1 ;NO, PUT IN HIGH HALF ALSO
HRLM S2,RDATA(S1)
SKIPGE S1
HRRM S2,RDATA(S1)
$RET
DATB.H: ASCIZ |
The NUMBER-OF-DATA-BITS n command determines whether the input code is
considered to be 7 or 8 bit characters.
When n is 7-BIT, entries made for codes 0-177 are duplicated for 200-377.
When n is 8-BIT, entries made for codes 0-177 are independent of 200-377.
|
SUBTTL VFU commands -- CLEAR
EXP CLR.H
.CLEAR: $CALL P$CFM## ;MAKE SURE
JUMPF SYNERR
TRO F,PU.UNP ;WE UNPUNCH
MOVEI T3,177777 ;CLEARING ALL CHANNELS
MOVE T1,LINSPP ;STARTING FROM THE LAST
CLR.1: SOJL T1,.POPJ ;DONE IF PAST LINE 0
MOVE S1,T1 ;COPY CURRENT LINE
PUSHJ P,SETVFU ;CLEAR ALL CHANNELS
JRST CLR.1 ;AND LOOP FOR ALL LINES ON PAGE
CLR.H: ASCIZ |
The CLEAR command clears the entire VFU so that no line is marked for any
channel.
Note that the MODE VFU command loads a default VFU, not a CLEAR VFU.
|
SUBTTL VFU commands -- LENGTH
EXP LENG.H
.LENGT: $CALL P$NUM## ;GET THE PAGE LENGTH
JUMPF SYNERR ;HUH?
CAMN S1,LINSPP ;ANY CHANGE?
$RET ;NO, DON'T BOTHER
JUMPLE S1,SYNERR ;SANITY
CAILE S1,^D143 ;IN RANGE
$MSG (<?>,LTL,GETCMD,<Length may not exceed 143 lines>)
EXCH S1,LINSPP ;STORE NEW LENGTH, GET OLD
MOVE T1,S1 ;COPY OLD
MOVEI T3,177777 ;BITS TO CLEAR OLD STOP CODE & DATA
TRO F,PU.UNP ;UNPUNCH THEM
PUSHJ P,SETVFU ;SO
LINE.1: AOS S1,T1 ;ADVANCE A LINE
CAMLE S1,LINSPP ;UP TO NEW LENGTH YET?
JRST LINE.2 ;YES, STOP NOW
PUSHJ P,SETVFU ;NO, CLEAR NEWLY ALLOCATED LINE
JRST LINE.1 ;LOOP TILL ALL NEW LINES ARE CLEARED
LINE.2: MOVEI T3,357 ;ADD NEW BITS
MOVE S1,LINSPP ;LOCATION
CAMGE S1,LINSLP ;IS THIS LESS THAN THE LOGICAL PAGE?
MOVEM S1,LINSLP ;YES, SHORTEN LOGICAL PAGE TO LENGTH
TRZ F,PU.UNP ;PUNCH, THIS TIME
PUSHJ P,SETVFU ;SO - THE STOP CODE GETS "PUNCHED"
$RET ;DONE
LENG.H: ASCIZ |
The LENGTH n command resets the page length to n lines.
N must be less than or equal to 143 lines.
If the new length is less than the logical page size, the page size is
reduced to the new length.
If the new length is larger than the previous length, all channels are
cleared for the new lines.
|
SUBTTL VFU commands -- LINES-PER-INCH
EXP LPI.H
.LINES: $CALL P$KEYW## ;GET THE KEYWORD
JUMPF SYNERR
MOVE S2,FILPTR ;POINT TO FILE DATA
IDPB S1,S2 ;REPLACE THE START CODE PER DEMAND
$RET
LPI.H: ASCIZ |
LINES-PER-INCH
Specifys which LPI setting is selected by the VFU. Not all
printers support 6-LPI and 8-LPI selections. If a VFU which selects
an unsupported LPI setting is loaded, VFU errors will result.
PRINTER-CONTROLLED works with all current printers.
6-LPI VFU selects 6 lines per inch
8-LPI VFU selects 8 lines per inch
PRINTER-CONTROLLED VFU accepts printer's switch or lever setting
|
SUBTTL VFU commands -- LIST and SHOW support
;T1/ BEGIN:
;T2/ END:
LIST.V: $TEXT (LSTCHR,<>)
TRNE F,LS.TTY ;FOR TERMINAL, INCLUDE THESE
$TEXT (LSTCHR,<Length: ^D/LINSPP/^M^JPage-size: ^D/LINSLP/>)
MOVE S1,FILPTR ;GET FILE POINTER
ILDB S1,S1 ;GET START CODE
SUBI S1,354 ;MAKE IN RANGE 0-2
$TEXT (LSTCHR,<VFU selects ^T/@LPITAB(S1)/^M^J>)
TRNN F,LS.LIN ;/BY-LINE?
JRST LSTV.C ;NO, DO BY CHANNELS
;LISTING IS /BY-LINES
$TEXT (LSTCHR,<Line Channels>)
$TEXT (LSTCHR,<---- ----------------------------------->)
MOVE T3,FILPTR ;POINT TO FILE DATA
IBP T3 ;SKIP START CODE
MOVN T4,LINSPP ;ASSUME MAX LENGTH
MOVSS T4 ;AOBJN STYLE
HRRI T4,1 ;FROM LINE 1
TRNN F,LS.TTY ;IF FILE LISTING
JRST LSTL.1 ;USE MAX
TRNN F,LS.ALL ;IF ONLY PART WANTED
JRST LSTL.0 ;DO PARTIAL LISTING
MOVEI S1,377 ;FULL LISTING
MOVEM S1,RAMLIM ;SO RESET WORKING RANGE
SETZM RAMLIM+1 ;AS USER HAS SEEN WHOLE THING
JRST LSTL.1 ;NOW GO DO IT
LSTL.0: CAMLE T2,LINSPP ;BIGGER THAN PHYSICAL PAGE?
MOVE T2,LINSPP ;YES, ONLY THAT MUCH
SKIPLE T1 ;SKIP IF TOO SMALL
CAMLE T1,LINSPP ; ALSO BAD IF TOO BIG
MOVEI T1,1 ;USE LINE 1
MOVE T3,T1 ;WHERE TO START
SOJ T3, ;MAKE 0-RELATIVE
ASH T3,1 ;2 BYTES OF DATA PER LINE
AOJ T3, ;SKIP START CODE
ADJBP T3,FILPTR ;BUMP TO BEGINNING
SUBM T1,T2 ;- (END - BEGIN)
MOVSI T4,-1(T2) ; - ( (END - BEGIN) + 1 )
HRR T4,T1 ;START AT BEGINNING (WHERE ELSE?)
;LOOP FOR EACH LINE
LSTL.1: ILDB S1,T3 ;GET NEXT BYTE
ILDB S2,T3 ;GET HIGH BYTE
LSH S2,6 ;SHIFT HIGH CHANNELS OVER
IOR S1,S2 ;MAKE CHANNEL MASK
$TEXT (LSTCHR,< ^D3 /T4,RHMASK/ ^A>)
MOVEI T1,^D12 ;NUMBER OF CHANNELS
MOVEI S2,1_^D12 ;PRE-DECREMENTED CHANNEL MASK
;LOOP FOR EACH CHANNEL
LSTL.2: LSH S2,-1 ;NEXT CHANNEL
TRNE S1,(S2) ;IS MARK SET?
$TEXT (LSTCHR,<^D2 /T1/ ^A>) ;YES, LIST CHANNEL
TRNN S1,(S2) ;CHECK AGAIN
$TEXT (LSTCHR,< ^A>) ;NOT SET, ALLOW SPACE
SOJG T1,LSTL.2 ;LOOP FOR ALL CHANNELS
HRRZ S1,T4 ;GET LINE NUMBER
CAMN S1,LINSLP ;LOGICAL END-OF-PAGE?
$TEXT (LSTCHR,< [End of Page]^A>)
$TEXT (LSTCHR,<>) ;CRLF
AOBJN T4,LSTL.1 ;LOOP FOR ALL LINES
$RET
;LISTING IS /BY-CHANNEL
LSTV.C: $TEXT (LSTCHR,<Chn Lines>)
$TEXT (LSTCHR,<--- ----------------------------------------------------------------------->)
MOVE T4,[XWD -^D12,1] ;DO ALL CHANNELS
LSTC.2: $TEXT (LSTCHR,< ^D2 /T4,RHMASK/ ^A>)
MOVN T3,LINSPP ;LINES/PHYSICAL PAGE
MOVSS T3
HRRI T3,1 ;START AT LINE 1
PUSH P,FILPTR ;SAVE BYTE POINTER
IBP (P) ;SKIP START CODE
LSTC.3: PUSH P,[EXP ^D24] ;MAX LINES TO LIST/LINE
LSTC.4: ILDB S1,-1(P) ;GET LOW BYTE
ILDB S2,-1(P) ;AND HIGH BYTE
LSH S2,6 ;SHIFT INTO POSITION
IOR S1,S2 ;AND MERGE
MOVEI S2,1 ;COMPUTE THIS CHANNEL
LSH S2,-1(T4) ;SLIDE MASK INTO PLACE
TRNN S1,(S2) ;IS THIS CHANNEL MARKED?
AOBJN T3,LSTC.4 ;NO, LOOP FOR ALL LINES
JUMPGE T3,LSTC.6 ;EXIT IF NO MORE
SOSL (P) ;SPACE LEFT ON THIS LINE?
JRST LSTC.5 ;YES, CONTINUE
$TEXT (LSTCHR,<^M^J ^A>) ;NO, START A NEW LINE
ADJSP P,-1 ;TOSS OLD COUNT
XCT LSTC.3 ;START A NEW ONE
SOS (P) ;AND ACCOUNT FOR THIS LINE
LSTC.5: $TEXT (LSTCHR,<^D2 /T3,RHMASK/ ^A>) ;YES, LIST THIS LINE
AOBJN T3,LSTC.4 ;LOOP FOR NEXT LINE
LSTC.6: ADJSP P,-2 ;TOSS STACKED BP
$TEXT (LSTCHR,<>) ;NEW LINE
AOBJN T4,LSTC.2 ;NEXT CHANNEL
$RET
;LPI labels
LPITAB: [ASCIZ /6-LPI/]
[ASCIZ /8-LPI/]
[ASCIZ /Printer-controlled LPI/]
SUBTTL VFU commands -- (UN-)PUNCH
EXP UNPU.H
.UNPUN: TROA F,PU.UNP ;SET UNPUNCH
EXP CHAN.H
.CHANN: $CALL P$NUM## ;PARSE THE CHANNEL NUMBER
JUMPF SYNERR
SOS T4,S1 ;SAVE IT - IN INTERNAL FORM
MOVEI T3,1 ;CHANNEL BIT
CAILE T4,5 ;IF IN A HIGH BYTE
ADDI S1,2 ;SKIP UNUSED BITS
LSH T3,(S1) ;KEEP A BIT MASK FOR THE DATA
$CALL P$KEYW## ;PARSE THE KEYWORD
JUMPF SYNERR
JRST @[EXP CHAN.A ;ALL
EXP CHAN.B ;BOTTOM
EXP CHAN.E ;EVERY
EXP CHAN.F ;FORMS-BREAK (lines)
EXP CHAN.L ;LINES
EXP CHAN.T ;TOP
](S1) ;DISPATCH ON KEYWORD CODE
;CHANNEL N ALL
CHAN.A: MOVE T2,LINSLP ;LINES PER LOGICAL PAGE
CHNA.1: SOJL T2,.POPJ ;NEXT LINE TO SET
MOVE S1,T2 ;LINE TO SET
PUSHJ P,SETVFU ;SET CHANNEL FOR CURRENT LINE
JRST CHNA.1
;BOTTOM
CHAN.B: MOVE S1,LINSLP ;PUT MARK AT BOTTOM
SOJA S1,SETVFU ;MAKE 0-BASED, SET BIT, AND RETURN
;EVERY N
CHAN.E: $CALL P$NUM## ;GET STEP SIZE
JUMPF SYNERR
MOVE T2,S1 ;SAVE STEP SIZE
SETZ T1, ;START ON LINE 0
CHNE.1: MOVE S1,T1 ;GET CURRENT LINE
PUSHJ P,SETVFU ;SET IN VFU
ADD T1,T2 ;ADD STEP SIZE
CAMGE T1,LINSLP ;OFF LOGICAL PAGE?
JRST CHNE.1 ;NOT YET
$RET
;FORMS-BREAK
CHAN.F: MOVE T1,LINSLP ;GET FIRST LINE OF FORMS-BREAK AREA
CHNF.1: CAML T1,LINSPP ;IF AT OR PAST PHYSICAL PAGE
$RET ;DONE
MOVE S1,T1 ;MORE TO DO, COPY CURRENT LINE
PUSHJ P,SETVFU ;SET IN VFU
AOJA T1,CHNF.1 ;NOW CONTINUE WITH NEXT LINE
;LINES N,M,...
CHAN.L: $CALL P$NUM## ;GET LINE NUMBER
JUMPF CHNL.X ;NONE, MUST BE CONFIRM
CHNL.1: SOJ S1, ;MAKE LINES START AT ZERO
PUSHJ P,SETVFU ;SET STOP FOR SPECIFIED LINE
$CALL P$COMM## ;PARSE A POSSIBLE COMMA
JUMPF CHNL.X ;IF NOT, MUST BE CONFIRM
$CALL P$NUM## ;COMMA, LINE NUMBER MUST FOLLOW
JUMPT CHNL.1 ;GO PROCESS THIS NUMBER
$MSG (<%>,TCI,,<Trailing comma ignored>)
CHNL.X: $CALL P$CFM## ;CONFIRM
$RETIT ;RETURN IF OK
$MSG (<%>,JEL,,<Junk at end of line ignored>)
$RET
;TOP-OF-FORM
CHAN.T: SETZ S1, ;LINE TO MARK
PJRST SETVFU ;SET AND RETURN
CHAN.H: ASCIZ |
PUNCH (channel) vfu-channel arg
Specifies line or lines on which a channel will stop.
Arg may be one of:
ALL-LINES Mark all lines on the logical page
BOTTOM-OF-FORM Mark last line on the logical page
EVERY n Mark every nth line on the logical page from line 1
FORMS-BREAK Un-mark the forms-break area
LINES n,m,... Mark the specified lines
TOP-OF-FORM Mark the first line on the page
|
UNPU.H: ASCIZ |
UN-PUNCH (channel) vfu-channel arg
Specifies line or lines on which a channel will no longer stop.
Arg may be one of:
ALL-LINES Un-mark all lines on the logical page
BOTTOM-OF-FORM Un-mark last line on the logical page
EVERY n Un-mark every nth line on the logical page from line 1
FORMS-BREAK Un-mark the forms-break area
LINES n,m,... Un-mark the specified lines
TOP-OF-FORM Un-mark the first line on the page
|
SUBTTL VFU commands -- PAGE-SIZE
EXP PAGS.H
.PAGES: PUSHJ P,P$NUM## ;GET THE PAGESIZE
JUMPF SYNERR ;HUH?
JUMPLE S1,SYNERR ;SILLY PEOPLE GET SILLY MESSAGE
CAMLE S1,LINSPP ;BETTER BE LESS THAN PHYSICAL PAGE
$MSG (<?>,PTB,GETCMD,<Pagesize ^D/S1/ exceeds length ^D/LINSPP/>)
MOVEM S1,LINSLP ;OK, CHANGE IT
$RET
PAGS.H: ASCIZ |
The PAGE-SIZE n command sets the length of a logical page to n lines. N must
be less than or equal to the form length. (See the LENGTH command.)
The logical page size determines how many lines commands such as PUNCH EVERY
and PUNCH ALL will effect.
Lines beyond the logical page size may be punched with PUNCH LINE, or
FORMS-BREAK.
The logical page size is defined for your convenience in entering commands
only; it has no direct meaning to the line-printer controller and is
not recorded in the VFU file.
|
SUBTTL VFU commands -- Utility routines
;ENTER WITH LINE # IN S1, BITS TO TURN ON IN T3
SETVFU: LSH S1,1 ;2 BYTES/VFU LINE
AOJ S1, ;SKIP START BYTE
ADJBP S1,FILPTR ;POINT TO FIRST BYTE OF LINE
ILDB S2,S1 ;GET BYTE
PUSH P,S1
PUSH P,S2 ;SAVE LOW BYTE
ILDB S2,S1 ;HIGH BYTE
LSH S2,8
IOR S2,(P) ;COMBINE
TRNN F,PU.UNP ;PUNCH?
TRO S2,(T3) ;YES, SET USER'S BITS
TRNE F,PU.UNP ;UN-PUNCH?
TRZ S2,(T3) ;YES, CLEAR USER'S BITS
MOVEM S2,(P) ;SAVE A COPY
LSH S2,-8
DPB S2,S1 ;PUT HIGH BYTE BACK
POP P,S2 ;GET LOW BYTE
POP P,S1 ;POINTER
DPB S2,S1 ;STORE THAT
$RET
SUBTTL Parser interface -- Argument fetchers
;RETURN A CHARACTER CODE FROM A QUOTED STRING OR AN INTEGER
PARCHR: PUSHJ P,P$NUM## ;FETCH A NUMBER
$RETIT ;DONE IF GOT ONE
PUSHJ P,P$QSTR## ;NOPE, TRY A QUOTED STRING
$RETIF ;NOPE, WE LOSE
LDB S1,[POINT 7,CR.RES(S1),6] ;OK, GET FIRST CHARACTER
$RETT ;LET THAT BE THE DATA
SUBTTL Default RAM data
DEFINE RAMWRD (TYPE,DATUM) <
IFE TYPE-OTHER,<
..T==TRNBIT+DATUM ;;TRANSLATE TO OTHER
>
IFE TYPE-ARROW,<
..T==INTBIT+"^" ;;FORM DATUM WORD
> ;;END OF ARROW TRANSLATION
IFE TYPE-SELF,<
..T==TRNBIT+BYTE ;;TRANSLATE TO SELF
>
IFE TYPE-PAPER,<
..T==VFUBIT+<DATUM-1> ;;PAPER MOTION
>
IFE TYPE-DEL,<
..T==DELBIT ;;DELIMITER
>
IFE TYPE-IGNORE,<
..T==TRNBIT+0 ;;SEND NON-PRINTING CHARACTER
>
IFE TYPE-IMAGE,<
..T==DATUM ;;PROVIDE BINARY QUANTITY
>
IFE BYTE&1,< .T==..T>
IFN BYTE&1,< XWD .T,..T>;;GENERATE WORD
BYTE==BYTE+1 ;;NEXT BYTE
> ;;END OF MACRO
;DEFINITIONS FOR THE ABOVE MACRO
PAPBIT==1B27 ;PAPER MOTION BIT
TRNBIT==1B26 ;TRANSLATE BIT
DELBIT==1B25 ;DELIMITER BIT
INTBIT==1B24 ;INTERRUPT BIT
VFUBIT==PAPBIT+TRNBIT ;VFU OR SLEW TRANSLATION
SLWBIT==1B31 ;SLEW, NOT VFU CHANNEL
ARROW==0 ;ARROW MODE
SELF==1 ;TRANSLATE TO SELF
PAPER==2 ;PAPER MOTION CHARACTER
DEL==3 ;DELIMITER
OTHER==4 ;TRANSLATE TO A PARTICULAR CODE
IGNORE==5 ;IGNORE THIS CODE
IMAGE==6 ;DATUM IS FULL DESCRIPTION
BYTE==200 ;IT MAY SEEM STRANGE, BUT MAKRAM HAD THIS BUG
;AND WE WANT THE DEFAULT RAM TO BE COMPATIBLE,
;NOT RIGHT. (!)
DEFRAM: RAMWRD SELF ;NULL GOES TO SELF
REPEAT ^D8,<RAMWRD ARROW> ;1-10 IS ARROW MODE
RAMWRD SELF ;TAB GOES TO SELF
RAMWRD PAPER,^D8 ;LF IS VERT MOTION
RAMWRD PAPER,7 ;VT IS CHANNEL 7
RAMWRD PAPER,1 ;FF IS TOP OF FORM
RAMWRD PAPER,SLWBIT+1 ;SPACE 0 LINES
REPEAT 2,<RAMWRD ARROW> ;16-17 ARROW TRANSLATION
RAMWRD PAPER,2 ;20 VFU CH 2
RAMWRD PAPER,3 ;21 VFU CH 3
RAMWRD PAPER,4 ;22 VFU CH 4
RAMWRD PAPER,5 ;23 VFU CH 5
RAMWRD PAPER,6 ;24 VFU CH 6
REPEAT 6,<RAMWRD ARROW> ;25-32 ARROW MODE
RAMWRD OTHER,"$" ;33 PRINTS AS $
REPEAT 4,<RAMWRD ARROW> ;34-37 ARROW MODE
REPEAT 177-40,<
RAMWRD SELF> ;ALL REST GO TO SELF
RAMWRD IGNORE ;EXCEPT DELETE, WHO HAD NONE!!!!
DEFRLN==.-DEFRAM
SUBTTL Macros for generating default VFU data
; THE FOLLOWING MACROS ARE USED TO GENERATE VFUBUF, WHICH CONTAINS
; THE DEFAULT VFU DATA TO BE LOADED.
DEFINE MOD(A,B),<A-<<A/B>*B>> ;TAKE A MODULO B
; MACRO OUTBYT - USED TO GENERATE A STREAM OF 8-BIT BYTES. CALLED EACH TIME
; A BYTE NEEDS OUTPUTING. ASSEMBLES 4 8-BIT BYTES AND THEN OUTPUTS A
; EXP PSEUDO-OP.
DEFINE OUTBYT(B),<
..BP==..BP+8 ;;BUMP THE POSITION POINTER BY BYTE SIZE
B==<B&377>_<^D35-..BP> ;;MAKE SURE ONLY 8 BITS WIDE AND THEN
;;SHIFT TO PROPER POSITION IN CURRENT WORD
..B==..B!B ;;PUT BYTE INTO ACCUMULATOR
IFE ..BP-^D31,< ;;IF WE'RE AT THE LAST BYTE IN CURRENT WORD
..BP==-1 ;;RESET POSITION POINTER TO BEGINNING
EXP ..B ;;ASSEMBLE THE WORD
..B=0 ;;CLEAR OUT THE ACCUMULATOR
>;END IFE
>;END DEFINE
; MACRO LASBYT - MUST BE CALLED AFTER ANY USAGE OF OUTBYT MACRO TO ENSURE
; THAT THE LAST BYTE(S) GET OUTPUT.
DEFINE LASBYT,<
IFN ..BP+1,< ;;IF THERE IS SOMETHING LEFT IN THE ACCUMUALTOR
EXP ..B ;; ASSEMBLE IT
>;END IFN
>;END DEFINE
; MACRO VFUBIT - CALLED TO OUTPUT TWO BYTES OF DATA FOR A PARTICULAR
; LINE NUMBER IN THE VFU. GENERATES CHANNEL BIT SETTINGS FOR
; A STANDARD VFU TAPE.
DEFINE VFUBIT(LINE),<
..BT==0 ;;ZERO THE BIT ACCUMULATOR
;;DO 1ST BYTE - CHANNELS 1-6
IFE LINE,<..BT==..BT!1> ;;LINE 0 GETS CHANNEL 1 (TOP OF FORM)
IFE MOD(LINE,36),<..BT==..BT!2> ;;EVERY 30 LINES GETS CHANNEL 2
IFE MOD(LINE,2),<..BT==..BT!4> ;;EVEN NUMBERED LINES GET CHANNEL 3
IFE MOD(LINE,3),<..BT==..BT!10> ;;EVERY 3RD LINE GETS CHANNEL 4
IFE MOD(LINE,12),<..BT==..BT!40>;;EVERY TEN LINES GETS CHANNEL 6
IFLE LINE-^D59,<..BT==..BT!20> ;;ALL LINES GET CHANNEL 5
IFGE LINE-^D60,<..BT==20> ;;LINES 60-65 GET ONLY CHANNEL 5
OUTBYT(..BT) ;;OUTPUT THIS BYTE
;;DO 2ND BYTE - CHANNELS 7-12
..BT==0 ;;ZERO THE BIT ACCUMULATOR
IFE MOD(LINE,24),<..BT==..BT!1> ;;EVERY 20 LINES GET CHANNEL 7
IFLE LINE-^D59,<..BT==..BT!2> ;;LINES 0-59 GET CHANNEL 8
TOPS10<
IFE LINE-^D59,<..BT==..BT!40> ;;LINE 59 GETS CHANNEL 12
IFGE LINE-^D60,<..BT==0> ;;LINES 60-65 GET NOTHING
>
TOPS20< ;;DON'T ASK WHY, BUT TOPS-20 PUTS BOF ON FIRST LINE OF FORMS BREAK AREA
IFE LINE-^D60,<..BT==40> ;;LINE 60 GETS CHANNEL 12
IFGE LINE-^D61,<..BT==0> ;;LINES 61-65 GET NOTHING
>
OUTBYT(..BT) ;;OUTPUT THIS BYTE
>;END DEFINE
SUBTTL Default VFU data buffer
..BP==-1 ;INITIALIZE POSITION FOR FIRST BYTE
..B==0 ;INITIALIZE BYTE ACCUMULATOR
..L==0 ;INITIALIZE LINE COUNTER
STARTC==356 ;DEFINE START CODE
STOPC==357 ;DEFINE STOP CODE
DEFVFU:
OUTBYT(STARTC) ;OUTPUT THE START CODE
REPEAT ^D66,< ;66 LINES/PAGE
VFUBIT(..L) ;DO BYTES FOR THIS LINE
..L==..L+1 ;BUMP LINE COUNTER
>;END REPEAT
OUTBYT(STOPC) ;OUTPUT THE STOP CODE
LASBYT ;FINISH UP
DEFVLN==.-DEFVFU
SUBTTL Error routines
ERRMSG: MOVEM 0,ERRACS+0 ;SAVE AC 0
MOVE 0,[1,,ERRACS+1] ;SET UP BLT
BLT 0,ERRACS+17 ;SAVE ALL ACS
MOVE S1,[POINT 7,ERRSTR] ;BYTE POINTER TO STORAGE
MOVEM S1,ERRPTR ;SAVE
POP P,S1 ;GET ADDRESS OF ARGUMENTS
POP P,ERRRET ;RETRIEVE RETURN ADDRESS
MOVE S2,0(S1) ;GET SEVERITY,,PREFIX
MOVEM S2,ERRPFX ;STORE
MOVE S2,1(S1) ;GET ADDRESS OF ITEXT BLOCK
HRRZM S2,ERRITX ;SAVE IT
TLNE S2,-1 ;SPECIAL RETURN ADDRESS GIVEN?
HLRZM S2,ERRRET ;YES--OVERWRITE DEFAULT
DMOVE S1,ERRACS+S1 ;RESTORE S1 AND S2
$TEXT (ERROUT,<^I/@ERRITX/^0>) ;STORE TEXT
PUSHJ P,@TYOADR ;CALL TYPEOUT ROUTINE
MOVE 0,[ERRACS+1,,1] ;SET UP BLT
BLT 0,16 ;RESTORE ACS 1-16
MOVE 0,ERRACS+0 ;RESTORE AC 0
PJRST @ERRRET ;RETURN
ERROUT: IDPB S1,ERRPTR ;STORE CHARACTER
POPJ P, ;NO--RETURN
SUBTTL Impure storage
Z.BEG:! ;BEGINING OF DATA STORAGE
PDL: BLOCK PDLSIZ ;SUBROUTINE CALL STACK
ERRACS: BLOCK 20 ;ERROR PROCESSOR - AC STORAGE
ERRRET: BLOCK 1 ;ERROR PROCESSOR - RETURN ADDRESS
ERRITX: BLOCK 1 ;ERROR PROCESSOR - ITEXT BLOCK ADDRESS
ERRPTR: BLOCK 1 ;ERROR PROCESSOR - BYTE POINTER
ERRPFX: BLOCK 1 ;ERROR PROCESSOR - PREFIX
ERRSTR: BLOCK <^D132+5>/5
TYOADR: BLOCK 1
FD: BLOCK FDXSIZ ;READ/WRITE FD
IFN: BLOCK 1 ;READ/WRITE IFN
LSTIFN: BLOCK 1
FILEFD: BLOCK FDXSIZ
CMDBLK: BLOCK PAGSIZ ;COMMAND PARSER PAGE
CMDMOD: BLOCK 1 ;COMMAND MODE: 0 NONE/-1 RAM/1 VFU
RDATA: BLOCK <MAXFIL==<400/2>> ;SPACE FOR 256 CHAR RAM AND MAX VFU
VFUSIZ: BLOCK 1 ;NUMBER OF VFU DATA BYTES READ
LINSLP: BLOCK 1 ;LINES PER LOGICAL PAGE
LINSPP: BLOCK 1 ;LINES PER PHYSICAL PAGE
TXTFLG: BLOCK 1 ;COPY OF F FOR USE IN $TEXT RTNS
;CHANGES MADE TO F MUST APPEAR HERE
;FOR $TEXT ROUTINES TO SEE THEM
RAMLIM: BLOCK 2 ;LIMITS OF USER-TOUCHED RAM
;****
FILPTR: BLOCK 1 ;BYTE POINTER TO FILE
FILCTR: BLOCK 1 ;BYTES/WORD FOR FILE
;****
Z.END:! ;END OF DATA STORAGE
END START