Trailing-Edge
-
PDP-10 Archives
-
decuslib20-05
-
decus/20-0139/teco20.mac
There is 1 other file named teco20.mac in the archive. Click here to see a list.
; TECO-20 DEC Standard TECO for TOPS-10 and TOPS-20
;
;Feature tests
;
IFNDEF TOPS20,TOPS20==1 ;[16000] TOPS-20 JSYS's
IFNDEF TOPS10,TOPS10==0 ;[16000] TOPS-10 UUOS
IFNDEF FTXTEC,FTXTEC==1
IFNDEF FTXTCERR,FTXTCERR==TOPS20 ;[21000] No need to swap segs on 20
SEARCH JOBDAT,MACTEN,UUOSYM ;[366] DEFINE SYSTEMY THINGS
IFN TOPS20, SEARCH MONSYM ;[21000] 20-Systemy things too
SALL ; SUPPRESS MACRO EXPANSIONS
;Hiseg origin MOVED to allow lowseg to get bigger
TWOSEGMENTS 640000 ; THIS IS A TWO SEGMENT PROGRAM
.HIGH.=: 640000 ;[15000] Hiseg origin
.DIRECTIVE .XTABM ; TENEXY MACRO'S
DEFINE $TITLE(VTECO)<
IFN FTXTEC&FTXTCERR&TOPS20,<
TITLE. TECO20,VTECO,DEC Standard TECO for TOPS-20
>
IFE FTXTEC&FTXTCERR,<
IFN FTXTEC&TOPS10 ,TITLE. TECO10,VTECO,DEC Standard TECO for TOPS-10
IFN FTXTCERR,TITLE. TECERR,VTECO,ERROR SEGMENT FOR TECO10
>>
;MAKE THE RIGHT TITLE
$TITLE 3(25427) ; EDIT LEVEL 1-Oct-79
SUBTTL J KRUPANSKY/M CRISPIN/A Nourse/JWK/MRC/AWN
SUBTTL Introduction to TECO-10
; TECO-10 is a text editor for the DECsystem-10. It conforms, for
; the most part, with the DEC TECO standard, making it largely
; compatable with TECO-11 and TECO-8. It is also largely upward-compatable
; with the "official" DECsystem-10 TECO.
;
; TECO-10 is adapted from XTEC, and has all of the features of XTEC,
; though some have had their names changed to conform to the standard.
;
; New features (not in XTEC) include:
;
; W and :W Display Window support
; EQ and E% dump mode I/O between qregisters and files
; q-registers can have text and numerics simultaneously
; ET and ED compatable with TECO-11 and TECO-8, including
; read-with-no-wait, control-C intercept,
; read-with-no-echo, cancel ^O, detached flag ...
; [ and ] pass values through unchanged
; m,nUq does nUq and returns m as value
; n:A append n lines from input file
; E* do arbitrary TRMOP. to own terminal
; nEJ commands 0EJ job #, 1EJ TTY #, 2EJ PPN
; EK cancel EB or EW
; q-register () is the text buffer, can be shared with other q-regs
;
; The following XTEC commands have been renamed:
;
; ENfilespec$ to E=filespec$
; EN$ to E=/DELETE$
; EDfilespec$ to E&filespec$
; n^U to nE#
; EAfilespec$ to EWfilespec/APPEND$ (both work for now)
;
; The history of XTEC follows...
;
; XTEC IS BASED ON DIGITAL EQUIPMENT CORPORATION'S TECO WHICH
; WAS WRITTEN BY RC CLEMENTS/PMH/CAM.
; MANY OF THE EXTERNAL CHANGES ARE BASED ON CHANGES MADE TO TECO
; AT STEVENS INSTITUTE OF TECHNOLOGY BY J POTOCHNAK AND G BROWN.
;
; XTEC.MAC WAS WRITTEN BY J KRUPANSKY/JWK, BEGINNING
; 12-AUG-74 AT THE COMPUTER CENTER OF STEVENS INSTITUTE OF TECHNOLOGY,
; HOBOKEN, NJ 07030.
;
; CODE FOR THE ^U, ^Y, EL, FD, <ARGS>M, AND <ARGS>EI COMMANDS, AS
; WELL AS THE /APPEND, /NOIN, /NONSTD, AND /NOOUT I/O SWITCHES
; WAS WRITTEN BY MARK CRISPIN AT THE CHEMISTRY AND CHEMICAL ENGINEERING
; DEPARTMENT OF STEVENS INSTITUTE OF TECHNOLOGY.
SUBTTL TABLE OF CONTENTS
; TABLE OF CONTENTS
;
;
; SECTION PAGE
; 1. Introduction to XTEC.................................. 1
; 2. TABLE OF CONTENTS..................................... 2
; 3. Revision History...................................... 3
; 4. Assembly Parameters................................... 4
; 5. ASSEMBLY INSTRUCTIONS................................. 5
; 6. AC Definitions........................................ 6
; 7. Macro Definitions..................................... 7
; 8. OPDEFs and Symbol Definitions......................... 8
; 9. Flag AC Bit Definitions............................... 11
; 10. Transfer Vector Table for Command Execution........... 12
; 11. Startup Initialization................................ 13
; 12. Compile&Execute XTEC Option Line from DSK:SWITCH.INI.. 16
; 13. COMPILE&EXECUTE DSK:XTEC.INI[,] if it exists.......... 18
; 14. CCL Setup............................................. 19
; 15. Command Input Processor............................... 21
; 16. Read a Command String into the Command Buffer......... 22
; 17. Subroutines for Reading a Command String.............. 24
; 18. Command String is Stored. Process it.................. 25
; 19. Command Decoder Dispatch Table........................ 26
; 20. COMPIL - Command Decoder and Compiler................. 27
; 21. Command Decoding and Compilation Routines............. 31
; 22. Command Decoding and Compilation Subroutines.......... 57
; 23. EXECUT - Execute a Command............................ 63
; 24. $CTM - TRACE MODE TYPE-OUT............................ 65
; 25. $EH AND $EHS.......................................... 66
; 26. $U AND $Q AND $INC.................................... 67
; 27. $PUSH AND $POP........................................ 68
; 28. $DEC AND $OCT AND $CNE AND $CNN AND $FFD.............. 69
; 29. $UP AND $LOW AND CLRCAS AND $CX AND $CXS.............. 70
; 30. $CNZ and $MES and $NA................................. 71
; 31. $CKC and $CHA and $CKD and $CKV and $CKW.............. 72
; 32. $SEMF and $SEMZ and $SEM and $STOP.................... 73
; 33. $R and $C and $J...................................... 74
; 34. $KL and $L and $D..................................... 75
; 35. $TAB and $I and $NI and $L............................ 76
; 36. $BS1 and $BS2......................................... 77
; 37. $TTC.................................................. 78
; 38. $S and $N............................................. 79
; 39. $BAR.................................................. 80
; 40. $BS and $FS........................................... 81
; 41. $TL and $T and $0TT................................... 82
; 42. $A and $P and $PW and $BP............................. 83
; 43. $Y and $CNP AND $CNY AND $CNU......................... 84
; 44. $XL................................................... 85
; 45. $G.................................................... 86
; 46. FAIRET and SUCRET..................................... 87
; 47. $M.................................................... 88
; 48. $EC and $ECS and $TTY................................. 89
; 49. $GTB and $PEK - GETTAB and PEEK....................... 91
; 50. $ER and $EW and $EF and $ED........................... 92
; 51. $EB................................................... 93
; 52. $EA................................................... 94
; 53. $EI................................................... 95
; 54. $EL AND $ELA.......................................... 96
; 55. $EN................................................... 97
; 56. $EP................................................... 98
; 57. $EM and $EZ........................................... 99
; 58. $EE................................................... 100
; 59. $EG and $EX and MONRET................................ 101
; 60. SSTPSC - Prescan a Search String...................... 102
; 61. SSTGSM - Generate a Search Matrix..................... 104
; 62. SERCH and BSERCH - Perform a Search................... 111
; 63. SEARCH - The Actual Search Routine.................... 112
; 64. Command Execution Subroutines......................... 116
; 65. SETFSP - Fill in Defaults for a File Spec............. 122
; 66. SETRAD - Set the Adr of Read-a-Char Routine........... 124
; 67. SETWAD - Set Adr of Punch-a-Char Routine.............. 125
; 68. PUNBUF - Punch part of Input File..................... 126
; 69. PUNCH - Punch part of Text Buffer..................... 127
; 70. ASCPCH - Punch an ASCII Character..................... 128
; 71. SIXPCH - Punch a SIXBIT ASCII Character............... 129
; 72. OCTPCH - Punch an Octal Digit......................... 130
; 73. LSNPCH - Punch a Char and Turn on Bit35 for LSNS...... 131
; 74. GENPCH - Punch a Char and Generate LSNS............... 133
; 75. BAKCLS - Finish "EB" that is in Progress.............. 135
; 76. YANK and APPEND....................................... 137
; 77. ASCAPD - Read an ASCII Char........................... 139
; 78. SUPARD - Read a Char and Suppress LSNS................ 140
; 79. OCTAPD - Read an Octal Digit.......................... 141
; 80. SIXAPD - Read a SIXBIT ASCII Char..................... 142
; 81. MACRO - Compile and Execute a Macro................... 143
; 82. OPENRD - Select a File for Input...................... 145
; 83. OPENWR - Select a File for Output..................... 146
; 84. FILERD - Read a File into a Text Buffer............... 147
; 85. TYPEL and TYPE - Type part of Text Buffer............. 149
; 86. FILOPN - Open a Device and Setup Buffers.............. 150
; 87. FILLKP, FILENT, AND FILRNM - File LOOKUP/ENTER/RENAM.. 152
; 88. ERMT - Error Message Typeout.......................... 155
; 89. ERRTXT - Text of All Error Messages................... 158
; 90. GXXXXX - Character Input Routines..................... 159
; 91. LOGPCH - PUNCH A CHARACTER TO LOG FILE................ 167
; 92. CMDGCH AND CMDBCH - Get char from command buffer...... 168
; 93. TXXXXX - OUTPUT ROUTINES.............................. 169
; 94. MISCELLANEOUS ROUTINES................................ 175
; 95. QSTOR - Store a value/text-buffer in a Q-register..... 179
; 96. QGET - Return a Q-register............................ 181
; 97. QFIND - Find a Q-register in QTAB..................... 182
; 98. MKROOM - Make room for an arbitrary # of chars in ma.. 183
; 99. ADDBLK - Add a block to the Linked-List............... 186
; 100. REFBLK - Add one to the Reference Count for A BLOCK .. 187
; 101. DELBLK - Un-Reference a Block in Linked-List.......... 188
; 102. FNDBLK - Find a Block (given its id) in the Linked-L.. 189
; 103. SAVE AC ROUTINES...................................... 190
; 104. REQM - REQUEST MEMORY (CORE ALLOCATION)............... 191
; 105. RELM - RELEASE MEMORY................................. 192
; 106. GARCOL - GARBAGE COLLECTION ROUTINE................... 193
; 107. FIXREF - RELOCATE THE REFERNECES TO A DYNAMIC BLOCK... 195
; 108. EXPAND - Expand a Block of Core....................... 196
; 109. COMPRS - Compress a Block of Core..................... 198
; 110. SETSTK - INITIALIZE A DYNAMIC STACK................... 199
; 111. ADDPDL - Add a PDL to PDLTAB.......................... 200
; 112. DELPDL - Remove a PDL from PDLTAB..................... 201
; 113. FNDPDL - Find a PDL in PDLTAB......................... 202
; 114. APRTRP - APR Trap handler (POV Recovery).............. 203
; 115. UUOTRP - LUUO Handler................................. 205
; 116. REENTR - Reenter Processing (after ^C^C.REENTER)...... 206
; 117. ERRHAN - Error Handler................................ 207
; 118. ERCTY - TYPE LAST FEW COMMANDS AFTER AN ERROR......... 210
; 119. SAVPCM - SAVE LAST COMMAND STRING IN A Q-REGISTER..... 211
; 120. Phased Pure Low Segment Code.......................... 212
; 121. Impure Low Segment Data............................... 213
SUBTTL Revision History
;[301] 22-FEB-75 /JK - ^C START NO LONGER GETS ILL. MEM. REF.
;[302] 22-FEB-75 /JK - CHANGE EJ CMD TO ^G (FOR GETTABS AND PEEKS)
;[303] 22-FEB-75 /JK - MAKE PW CMD WORK
;[304] 22-FEB-75 /JK - NO ILL UUO IF NO OUTPUT FILE
;[305] 22-FEB-75 /JK - OLD FORM OF = AND == ARE NOW COMPATIBLE
; WITH DEC TECO. N,M= (AND ==) MEAN:
; N.LT.0 - TYPE A CRLF AFTER NUMBER
; N.EQ.0 - TYPE NOTHING AFTER NUMBER
; N.GT.0 - TYPE CHAR WHOSE CODE IS N AFTER NUMBER
;[306] 22-FEB-75 /JK - N^F RETURNS TTY#+^O200000 OF JOB N
;[307] 22-FEB-75 /JK - FIX BUG ABOUT ^R IN INSERTS
;[310] 22-FEB-75 /JK - MAKE ":" AND "@" THROW AWAY PREV. ARGS
;[311] 22-FEB-75 /JK - CHECK VERSION IF EE FILE
;[312] 22-FEB-75 /JK - PREVENT MACROS FROM USING MUCH CORE
;[313] 5-APR-75 /JK - PREVENT ?IO TO UNAS... WHEN "CONTINUE" IS
; TYPED AFTER "EX$$"
;[314] 5-APR-75 /JK - MAKE BOUNDED SEARCHES WORK
;[315] 5-APR-75 /JK - PREVENT <LF><LF> IN SWITCH.INI FROM
; CAUSING INFINITE LOOP
;[316] 5-APR-75 /JK - ADD SOME MORE PORTALS
;[317] 5-APR-75 /JK - MAKE ^C^C.REENTER PRESERVE THINGS
;[320] 10-APR-75 /MC - MAKE [311] WORK PROPERLY
;[321] 10-APR-75 /MC - FIX ^P
;[322] 10-APR-75 /MC - PREVENT MISSING CCL FILE, XTCERR FROM HALTING
;[323] 10-APR-75 /JK(MC) - FIX CRLF IN TRACE MODE
;[324] 10-APR-75 /JK(MC) - FIX SPACE BEFORE COMMAND BUG
;[325] 11-APR-75 /MC - EXTEND [316], CLEAN UP [320] AND [322]
;[326] 11-APR-75 /MC - PREVENT ILLEGAL UUO IF RUN XTCERR
;[327] 12-APR-75 /MC - N^Y YANKS TO PAGE N, ^Y= SAME AS ^P=
;[330] 14-APR-75 /MC - EL FILESPEC MAKES A LOG FILE
;[331] 14-APR-75 /MC - FIX UP ERROR TEXT
;[332] 15-APR-75 /MC - FIX TWO ARGS CARRYING TOO FAR IN ^G, ^T
;[333] 15-APR-75 /MC - N^U USETI'S TO BLOCK N ON INPUT FILE
;[334] 15-APR-75 /MC - /NONSTD OPENS DECTAPE IN NON-STANDARD MODE
;[335] 21-APR-75 /MC - FIX ?IO TO UNAS... WHEN USING EE & LOG FILES
;[336] 26-APR-75 /MC - ^G W/O AN ARGUMENT DOES A PJOB
;[337] 26-APR-75 /MC - FIX UP ERROR MESSAGE ?XTCBAK
;[340] 29-APR-75 /MC - GET DEFAULT PATH BY PATH., NOT GETPPN
;[341] 29-APR-75 /MC - IGNORE .BAK FILE ON OTHERS IN SEARCH LIST
;[342] 30-APR-75 /MC - [-] DOES A PATH., NOT A SETZM
;[343] 10-MAY-75 /MC - FIX HASH AT BEGINNING OF IMMEDIATE LINE TRACE
;[344] 13-MAY-75 /MC - ARGUMENTS CAN BE PASSED TO MACROS BY M
;[345] 13-MAY-75 /MC - EXTEND [344] FOR EI
;[346] 20-MAY-75 /MC - PREVENT ARGUMENTED MACROS FROM GOBBLING CORE
;[347] 6-JUN-75 /MC - USE MACTEN & UUOSYM RATHER THAN C
;[350] 18-JUN-75 /MC - FIX SAVEGET LOCS GETTING CLOBBERED(ST)
;[351] 18-JUN-75 /MC - FIX NNNEDT.TMP NOT BEING READ
;[352] 18-JUN-75 /MC - FIX MACRO RESULT GOING TOO FAR
;[353] 18-JUN-75 /MC - FIX "REENTER" FLAG IN COMMAND STRING
;[354] 18-JUN-75 /MC - FIX DOUBLE PAGES IN BAD ^P ARG
;[355] 18-JUN-75 /MC - FIX EB ON ANOTHER PPN GOING WRONG PLACE
;[356] 18-JUN-75 /MC - FIX EL/APPEND WITH NO LOG FILE
;[357] 18-JUN-75 /MC - FIX .JBCOR POP'ED INTO .JBSA IN "EE"
;[360] 18-JUN-75 /MC - FIX /SIXBIT IN OUTPUT
;[361] 18-JUN-75 /MC - FIX /SUPLSN CAUSING ILL MEM REF
;[362] 18-JUN-75 /MC - FIX ?XTCSRH ERROR TEXT
;[363] 18-JUN-75 /MC - FIX MISSING PORTAL IN "REENTR"
;[364] 18-JUN-75 /MC - FIX ?XTCERR W/ LOWER CASE FLAGGING
;[365] 3-JUL-75 /MC - FIX EB ON OTHERS IN SEARCH LIST
;[366] 3-JUL-75 /MC - USE JOBDAT & MACTEN MORE FULLY
;[367] 3-JUL-75 /MC - PATCH UP CCL CODE
;[370] 3-JUL-75 /MC - MAKE QI= WORK ON ASCII Q-REG
;[371] 3-JUL-75 /MC - MAKE EI LOOK ON TED: IF SPEC NOT OKAY
;[372] 3-JUL-75 /MC - FIX PPN SPEC OVERDEFAULTING ON [,]
;[373] 3-JUL-75 /MC - FIX BUG WITH ^^ AND ^R/^Q IN SEARCHES
;[374] 7-JUL-75 /MC - MAKE [370] WORK
;[375] 7-JUL-75 /MC - MAKE "START" DO A RESTART
;[376] 7-JUL-75 /MC - FIX SPURIOUS %XTCSEF ON OTHERS IN SL
;[377] 7-JUL-75 /MC - ADD FD <-- FIND AND DESTROY(!)
;[400] 4-AUG-75 /MC - FIX ILL MEM REF IN CCL(HOPEFULLY LAST)
;[401] 4-AUG-75 /MC - MAKE ">" THROW AWAY VALUE(TECO COMPATABLE)
;[402] 4-AUG-75 /MC - FIX "0-" BEING = 0 (I.E. :D-LT)
;[403] 4-AUG-75 /MC - FIX "-S" ALWAYS SUCCESSFUL(!)
;[404] 4-AUG-75 /MC - FIX NO "%XTCSEF" ON [-]
;[405] 4-AUG-75 /MC - FIX "?" RETURNING FROM XTCERR TO XTEC
;[406] 4-AUG-75 /MC - IMPLEMENT "EO" PROPERLY
;[407] 6-SEP-75 /MC - USE TITLE., PRETTY UP SOME CODE
;[410] 6-SEP-75 /MC - FIX :8^T ALWAYS FAILING
;[411] 29-OCT-75 /MC - FIX EH= RETURNING WRONG VALUE
;[412] 29-OCT-75 /MC - FIX P AT END OF FILE NOT ZEROING "."
;[413] 29-OCT-75 /MC - FIX EW TO DIRECTORY DEVICE AFTER EW
; TO NON-DIRECTORY DEVICE TRYING TO
; USE PPN 1 GREATER THAN IT SHOULD
;[414] 29-OCT-75 /MC - FIX EW TO NUL: GETTING %XTCSEF
;[415] 29-OCT-75 /MC - FIX [,] MEANING NOTHING!
;[416] 29-OCT-75 /MC - ALLOW "/" FOR % MESSAGES
;[417] 2-DEC-75 /MC - CLEAN UP CODE
;[420] 2-DEC-75 /MC - ADD ILLEGAL MEM REF TRAPPING
;[421] 2-DEC-75 /MC - [415] DID NOT WORK, REMOVE IT AND FIX ORIGINAL PROBLEM
;[422] 3-DEC-75 /MC - MAKE ERROR SEGMENT USE AN INDEX
;[423] 15-DEC-75 /MC - MAKE JWK HAPPY BY REMOVING ALTMODE CONVERSION
;[424] 1-JAN-75 /MC - REMOVE [423] (I WAS RIGHT AFTER ALL)
;[425] 1-JAN-75 /MC - FIX SFD HANDLING
;[426] 5-JAN-75 /MC - FIX MISSING ERROR TEXTS
;[427] 8-JAN-75 /MC MAKE ^U WORK IMMEDIATELY
;TECO10 EDIT HISTORY..
;[1000] ??-NOV-76 /AWN - FIX :EB AND :EL BLOWING UP
;[2000] 13-MAY-77 /AWN - MAKE ^C,REE STOP TYPING
;[3000] 13-MAY-77 /AWN - INSTALL RANDOM-ACCESS Q COMMAND
;[4000] 30-JUN-77 /AWN - FIX ERROR MESSAGES
; AND MAKE :,@ NOT WIPE ARGUMENTS
; AND SAVE BOTH MACRO ARGUMENTS
; AND TYPE ERROR MESSAGES INVOLVING SFD'S BETTER
;[5000] 12-JUL-77 /AWN - MAKE COMPIL NOT CLOBBER FLAGS
; AND MAKE ARG FLAGS GET SHUT OFF WHEN ARGS USED
; IN SEVERAL CASES WHEN THEY WEREN'T
; ALSO FIX UP DPY PROCESSING.
;[6000] 4-AUG-77 /AWN - RANDOM ACCESS Q COMMAND BECOMES ^B
;[7000] 24-AUG-77 /AWN - AUTOMATIC MACRO EXECUTION AFTER COMMAND
;[10000] 14-JAN-78 /AWN - ^Q & ^D command (TRMOPs & Q reg compare)
; And typing of ^L, BLISS symbol constituants
; Plus about 4 months of random patches
;[11000] 9-Feb-78 /AWN - Allow window to supress echoing,
; And Trace & ^A typeout to stop on REEnter
;[12000] 20-Jul-78 /AWN - Simultaneous text & numeric q registers
; & allow text buffer to be accessed as q-register
;[13000] 26-Oct-78 /AWN - Fix numerous bugs that show up when
; buffer size does not fit in 18 bits.
; Put in additional display support,
; ^@,^\, new ED,FB,FZ,FH,FL,FC,FP,FF,:W,V,| commands
;[14000] 26-Jan-79 /AWN Make PDP-11 compatable: ^_ not operator
; "R,^ER,2ED,FD changed to FK,allow non-special controls
; OFO error, == unsigned, scope editing
;[15000] 28-Feb-79 /AWN More PDP-11 compatability stuff:
; nA POP if out of range, nY NYA -nP NPA, EX NFO
; CRLF after $$, 16ED for preserve . after SRH
; Search in <> not always return value,
; Fix passing of values to & from macros
; E% for write q-register out in dump mode
; EN changed to E^, EA to EW/APPEND,
; FB to F0, FC to FX, FL to FY
; Move special :W stuff to 17:W & above
; Implement Harvard FB & FC bounded search
; ::S anchored search ::M compile only
; Fixes to line editing, echoing
; In search: ^A to ^EM, ^B to ^EB
; W runs macro '[W]', :W out of range runs '[:W]'
;[16000] 8-Mar-79 /AWN - Fix PDP-11/PDP-8 compatability stuff:
; Turn off echo when prompt happens
; Fix n@I// m,nPW FR doing autotype if ES.ne.0
; flush NTQ on "M" & "FQ" commands
; make <Sfoo$;> not give error on failure
; Make n^T & ^Atext^A typeout immediate
; fix n^_ remove EN rename
; fix range check on nA command, return -1 not POP
; change remaining YNL error to YCA & fix yank protect
; Make :G pretty print, put in ::G to print literally
; give error on bad "E<char> commands
; Put in ^B, put in n:A, different :A
; make n^T not return value, don't ignore nulls in macro
; put in ::ER,::EB,::EI,::EW,::EE to set defaults
;[17000] Make EO value 3. Put in 1ED mode, take out ^T mode
; Fix truncate mode
;[20000] Make EXPAND validate pointers before using them
; Halt if CORE UUO that can't fail, does.
;[21000] Make TECO-10 runnable on TOPS-20 (not fully JSYSized)
; Swap args if in wrong order.
; Fix ILM on delete from completely full buffer.
; FIX BNF on E? command, and make it echo always
; Also execute q(*EXIT) when EX or ^Z done
; And force echo back on in case of error
;[22000] Make q(*EXIT) execute before checking for NFO on EX
; Teach EE command to write .EXE files
; Make EB work in place by default
; Make EB use same device for .TMP file as input file
;[23000] FT command for setting tabs.
; Escape OK as delimiter for long q-names
; Make it work on TOPS-20
;[24000] Make it work right on TOPS-20
;[25000] Fix rub-outs and ^G's in GETCMD and flakey TABS
; Fix I/O to unassigned ch in FILEWR
SUBTTL Assembly Parameters
SHOW. %%JOBDAT ; VERSION OF JOBDAT
SHOW. %%MACTEN ; VERSION OF MACTEN
SHOW. %%UUOSYM ; VERSION OF UUOSYM
NDS. C$PDLL, 200 ; CONTROL PDL LENGTH
NDS. C$OBFL, 100 ;[12000] Size of terminal output buffer
NDS. C$NREF, 4 ; # REFERNECE WORDS FOR A DYNAMIC MEMORY BLOCK
NDS. C$PATL, ^D16 ; SIZE OF THE PATCHING SPACE
NDS. C$GSIZ, ^D500 ; HOW MUCH TO GROW BEFORE GARBAGE COLLECTING
NDS. C$CMDL, ^D100 ; # WORDS IN INITIAL COMMAND BUFFER
NDS. C$SFDL, 5 ; # NESTED SFDS ALLOWED IN FILESPECS
NDS. C$CODL, ^D100 ; # WORDS TO ADD TO COMMAND BUFFER FOR CODE
NDS. C$NPDL, ^D7 ; # PDLS THAT CAN BE OVERFLOW PROTECTED
NDS. C$TPDL, ^D30 ; SIZE OF APRTRP TEMP CONTROL PDL
NDS. C$LPDL, ^D16 ; SIZE OF TAG PDL
NDS. C$RPDL, ^D16 ; SIZE OF TAG REFERENCE PDL
NDS. C$QRLN, 3*^D30 ; 3 TIMES MIN # Q-REGISTERS
NDS. C$QPLN, 3*^D10 ; 3 TIMES MIN SIZE OF Q-REGISTER PDL
NDS. C$NBUF, 2 ; # BUFFERS FOR A DEVICE
NDS. C$TBLN, ^D1200 ; INITIAL #WORDS IN MAIN TEXT EDITING BUFFER
NDS. C$FILB, ^D10 ; N MEANS FILL BUFFER TILL (N-1)/N FULL
NDS. C$EUVL, -1 ; DEFAULT CASE FLAGGING FLAG VALUE
; -1=NONE
; 0=FLAG LOWER CASE
; +1=FLAG UPPER CASE
NDS. C$BUFL, ^D128 ; # WORDS IN A MONITOR BUFFER
NDS. C$BFHD, 3 ; # WORDS IN A BUFFER HEADER
NDS. C$SRHL, ^D80 ; # CHARS IN SEARCH TEXT
NDS. C$ERRS, 'TECERR' ; NAME OF THE ERROR SEGMENT
NDS. C$3NAM, 'TEC' ; 3 LETTER ABBREVIATION OF OUR NAME
; USED FOR TEMP FILES,ETC.
NDS. C$SEXT,'EXE' ;[21000] Default save file extension
NDS. C$TPRV, <177> ; PROTECTION CODE FOR TEMP FILES
NDS. C$CCNM, '[CCL] ' ; MACRO NAME OF THE CCL COMMAND
; SO WE CAN EXIT ON 'FNF'
NDS. C$EOVL, 3 ;[406] DEFAULT "EO" VALUE OF THIS VERSION
NDS. C$MAXD,^D2000 ;[15000] Larger than this isn't temporary
NDS. FTBSRO,1 ;[16000] Accept backspace as rubout
NDS. FTPRIV,1 ;[12000] Assemble priveleged operations
NDS. C$NTS,24 ;[21000] This many TAB stops
IFN TOPS10&TOPS20,<
PRINTX ?XTEC for TOPS-10 and TOPS-20, can't do both at once
PASS2
END
>
SUBTTL ASSEMBLY INSTRUCTIONS
COMMENT!
TO GENERATE A PRODUCTION VERSION:
.LOAD @XTEC
.SSAVE
.LOAD/COMP @XTCERR
.SSAVE
TO GENERATE A VERSION WITH DDT:
.DEBUG @XTEC
.SAVE
.DEBUG/COMP @XTCERR
.SAVE
!;; END OF COMMENT
SUBTTL AC Definitions
F== 0 ; FLAGS
T1== 1 ; TEMP
T2== T1+1 ; TEMP
T3== T2+1 ; TEMP
T4== T3+1 ; TEMP
T5== T4+1 ; TEMP
X== 6 ; SUPER TEMP (HARDLY EVER SAVED)
C== 7 ; CHARACTER
N== C+1 ; NAME OR NUMBER OR WORD
M== N+1 ; MASK OR NUMBER OR WORD
L== 16 ; ARG OR ARG POINTER
P== 17 ; CONTROL PDP
; ACS USED IN COMMAND COMPILATION
CP== 12 ; CODE GENERATION PDP
TAG== 13 ; TAG STACK
REF== 14 ; TAG REFERENCE STACK
; ACS USED IN COMMAND EXECUTION
PC== TAG ; PC (IE: JSP PC,$$XX)
ARG== REF ; ARGUMENT
VALUE== 15 ; VALUE RETURNED BY A COMMAND
SARG== L ; SECOND ARG
R== CP ; RELOCATION REGISTER TO START
; OF COMMAND BUFFER
SUBTTL Macro Definitions
; FOR - MACRO TO OPEN A CONDITIONAL IF ARG IS TRUE
;
; CALL: FOR FTXXXX,<
; CLOSED BY: >;; END OF FOR FTXXXX
DEFINE FOR (WHO)
<IFE WHO,XLIST
IFN WHO,<LIST
SALL>
IFN WHO,>
; NOTFOR - MACRO TO OPEN A CONDITIONAL IF ARG IS FALSE
;
; CALL IS: NOTFOR FTXXXX,<
; CLOSED BY: >;; END NOTFOR FTXXXX
DEFINE NOTFOR (WHO)
<IFN WHO,XLIST
IFE WHO,<LIST
SALL>
IFE WHO,>
; BIT - MACRO TO DEFINE SUCCESSIVE BIT POSITIONS
;
; BIT(VALUE) DEFINES THE INITAIL BIT POSITION (EG: BIT (1B0) )
; BIT() RETURNS NEXT BIT POSITION BEGINNING WITH INITIAL VALUE (EG: FOO=BIT)
DEFINE BIT (INIVAL)
<IFB <INIVAL>,<<1B<<BIT$$$==BIT$$$+1>-1>>>IFNB <INIVAL>,<BIT$$$==^L<INIVAL>>>
; INT - MACRO TO DEFINE SUCCESSIVE INTEGERS
;
; BIT(VALUE) DEFINES THE INITIAL INTEGER (EG: INT (0) )
; BIT() RETURNS NEXT INTEGER BEGINNING WITH INITIAL VALUE (EG: ONE= INT)
DEFINE INT (INIVAL)
<IFB <INIVAL>,<<<INT$$$==INT$$$+1>-1>>IFNB <INIVAL>,<INT$$$==INIVAL>>
; SKP - MACRO TO GENERATE A JRST OVER THE NEXT N INSTRUCTIONS
;
; SKP() IS EQUIVALENT TO "JRST .+2"
; SKP(N) IS EQUIVALENT TO "JRST .+1+N" AND SKIPS THE NEXT N INSTRUCTIONS
DEFINE SKP (N)
<IFB <N>,<JRST .+2>
IFNB <N>,<JRST .+1+N>>
; GEN - MACRO TO GENERATE A KEYWORD&DISPATCH TABLE
;
; GEN(XXX) GENERATES A TABLE AT ADR 'XXXTBL' WITH LENGTH 'XXXLTH'
; USER MUST DEFINE 'XXX' AS A MACRO:
; DEFINE XXX
;< PAIR NAME,ADR,BITS
; PAIR LASTNM,ADRN,BITS>
; TO GENERATE THE TABLE:
; GEN (XXX); AT ADR 'XXXTBL' WITH LENGTH 'XXXLTH'
DEFINE GEN (TAB)
<DEFINE PAIR (NAME,ADR,BITS)<<SIXBIT/NAME/>>
TAB'TBL:
XLIST
TAB;; ; GENERATE KEYWORDS
TAB'LTH==.-TAB'TBL
DEFINE PAIR (NAME,ADR,BITS)<EXP BITS+ADR>
TAB;; ; GENERATE DISPATCH TABLE
LIST
SALL
>
; STSTK - MACRO TO SETUP AN EXPANDABLE STACK
DEFINE STSTK (AC,LEN,REF)
<IFIDN <AC>,<P>,<MOVE P,[IOWD C$TPDL,TPDL]>
MOVE T1,[<REF,,LEN>]
MOVEI N,AC
PUSHJ P,SETSTK
>
; ECHO - O/S dependent macro to turn echo on or off
DEFINE ECHO (STATE),<
%STATE==0
IFB <STATE>,<%STATE==1>
IFIDN <STATE>,<ON>,<%STATE==1>
FOR TOPS10,<SETSTS TTYC,300-<%STATE*200> >
FOR TOPS20,<IFN %STATE,<PUSHJ P,ECON>
IFE %STATE,<PUSHJ P,ECOFF> >
PURGE %STATE >
;SKPECHO -- O/S-Dependant macro to skip if echo is ON
DEFINE SKPECHO(STATE),<
IFB <STATE>,<...ST==1>
IFNB <STATE>,<IFIDN <STATE>,<ON>,<...ST==1>
IFIDN <STATE>,<OFF>,<...ST==0>>
IFN ...ST,<
FOR TOPS10,<STATZ TTYC,IO.SUP>
FOR TOPS20,<MOVE T1,OURTTY
RFMOD
TXNE T2,TT%ECO>
>
IFE ...ST,<
FOR TOPS10,<STATO TTYC,IO.SUP>
FOR TOPS20,<MOVE T1,OURTTY
RFMOD
TXNN T2,TT%ECO>
>
PURGE ...ST
>
SUBTTL OPDEFs and Symbol Definitions
; ERROR - A MACRO TO GENERATE AN ERROR CALL LUUO
LUUERR==1 ; LUUO OPCODE FOR 'ERROR'
DEFINE ERROR (CODE)
< BYTE (9)LUUERR(4)0(1)0(4)0(18)<E$'CODE==<''CODE''&777777>>>
; CERROR MACRO TO GENERATE ERROR CALL FOR POSSIBLE ":" COMMANDS
LUUCER==2 ; LUUO OPCODE FOR 'CERROR'
DEFINE CERROR (CODE)
< BYTE (9)LUUCER(4)0(1)0(4)0(18)<E$'CODE==<''CODE''&777777>>>
; CERR1 - MACRO FOR LUUO CALL SAME AS 'CERROR' BUT POPS TOP OF STACK
LUUCR1==3 ; LUUO OPCODE FOR 'CERR1'
DEFINE CERR1 (CODE)
< BYTE (9)LUUCR1(4)0(1)0(4)0(18)<E$'CODE==<''CODE''&777777>>>
; WARN - MACRO FOR LUUO TO TYPE A WARNING MESSAGE
LUUWRN==4 ; LUUO OPCODE FOR 'WARN'
DEFINE WARN (CODE)
< BYTE(9)LUUWRN(4)0(1)0(4)0(18)<W$CODE==<''CODE''&777777>>>
; CHKEO - MACRO TO JUMP IF A FEATURE IS DISABLED
LUUCEO==5 ; LUUO OPCODE FOR 'CHKEO'
DEFINE CHKEO(NUM,ADR)
< MOVE X,EOVAL
CAIG X,NUM
JRST ADR
>
;< <LUUCEO>B8+<NUM>B12+<Z ADR>>
; I/O CHANNELS
INP== 1 ; INPUT CHANNEL
OUT== 2 ; OUTPUT CHANNEL
LOG== 3 ;[330] LOG CHANNEL
TTYC== 16 ;[4000] TTY CHANNEL
; MISCELLANEOUS SYMBOLS
.CHSPC==040 ; A SPACE CHAR
.CHLAB=="<" ; LEFT ANGLE BRACKET
.CHRAB==">" ; RIGHT ANGLE BRACKET
; SYMBOLS FOR Q-REGISTER ELEMENTS. INDEX BY ADR OF Q-REGISTER
Q$NAM== 0 ; SIXBIT NAME OF Q-REGISTER
Q$BIT== 1 ; MISCELLANEOUS BITS
QB$REF==1B0 ; RH contains address
QB$BID==1B1 ; RH contains buffer ID
Q$VAL== 2 ; NUMERIC VALUE OF Q-REGISTER
Q$PTR== Q$BIT ; LINKED-LIST ID FOR TEXT BUFFER
; INDICES INTO A DYNAMIC MEMORY BLOCK (RELATIVE TO FIRST DATA WORD)
B$1PTR==-C$NREF ; FIRST POINTER WORD
B$2PTR==B$1PTR+1 ; SECOND POINTER WORD
B$3PTR==B$2PTR+1 ; THIRD POINTER WORD
B$4PTR==B$3PTR+1 ; FOURTH POINTER WORD [12000]
B$DATA==0 ; FIRST DATA WORD
; INDICES INTO A TEXT BUFFER (RELATIVE TO FIRST DATA WORD)
T$PBUF==B$1PTR ; POINTER TO PREVIOUS BUFFER
T$NBUF==B$2PTR ; POINTER TO NEXT BUFFER
T$1REF==B$2PTR ; POINTER TO A STATIC REFERENCE
T$ACRF==B$3PTR ; POINTERS TO TWO AC REFERENCES
T$CCNT==B$DATA ; CHARACTER COUNT FOR BUFFER
T$RCNT==T$CCNT+1 ; REFERENCE COUNT FOR BUFFER
T$BID== T$RCNT+1 ; BUFFER ID
T$BIT== T$BID ;[12000] bits in left half
TB$CMP==400000,,0 ;[12000] compiled
TB$BUF==200000,,0 ;[12000] this is the current text buffer
T$DATA==T$BID+1 ; FIRST DATA WORD FOR TEXT BUFFER
; INDICES INTO A FILE SPEC BLOCK
INT(0) ; INDICES START WITH ZERO
FS$FLG==INT ; FLAGS FOR FILE SPEC
BIT(1B0) ; FLAG BITS START WITH ZERO
FB$OPN==BIT ;[15000] This file is open
FB$DEV==BIT ; DEVICE NAME SEEN
FB$NAM==BIT ; FILE NAME SEEN
FB$EXT==BIT ; FILE EXTENSION SEEN
FB$PRV==BIT ; /PROTECT:<NNN> SEEN
FB$PRJ==BIT ; PROJECT NUMBER SEEN
FB$PRG==BIT ; PROGRAMMER NUMBER SEEN
FB$PTH==BIT ; SOME SORT OF PATH SEEN
FB$DDR==BIT ; DEFAULT DIRECTORY SEEN
FB$SFD==BIT ; SFDS SEEN
FB$EXE==BIT ; /EXECUTE
FB$LSN==BIT ; /LSN - DO LSN PROCESSING
FB$ASC==BIT ; /ASCII - DON'T DO LSN PROCESSING
FB$SIX==BIT ; /SIXBIT - PROCESS A SIXBIT FILE
FB$OCT==BIT ; /OCTAL - PROCESS A BINARY FILE
FB$GEN==BIT ; /GENLSN - GENERATE LSN'S ON OUTPUT
FB$SUP==BIT ; /SUPLSN - SUPPRESS LSN'S ON INPUT
FB$APP==BIT ;[330] /APPEND - APPEND TO LOG FILE
FB$NOO==BIT ;[330] /NOOUT - NO TYPEOUT IN LOG
FB$NOI==BIT ;[330] /NOIN - NO TYPEIN IN LOG
FB$NON==BIT ;[334] /NONSTD - NON STANDARD DECTAPE
FB$DEL==BIT ;[15000] /DELETE for temp files
FB$$IO==FB$LSN!FB$ASC!FB$SIX!FB$OCT!FB$GEN!FB$SUP!FB$PRV!FB$APP!FB$NOO!FB$NOI!FB$NON!FB$DEL
; THE I/O SWITCH BITS
FS$DEV==INT ; SIXBIT DEVICE NAME
FS$NAM==INT ; SIXBIT FILE NAME
FS$EXT==INT ; SIXBIT FILE EXTENSION
FS$PRV==INT ; PROTECTION, ETC.
FS$PTH==INT ; PATH
FS$PPN==FS$PTH+2 ; PPN
FS$SFD==FS$PTH+3 ; FIRST SFD
FS$LTH==FS$SFD+C$SFDL ; LENGTH OF FILE SPEC BLOCK
; FAKE CHARACTERS FOR SEARCH MATRIX
$CHBEG==200 ; SIGNALS MATCH WITH BEGINNING OF BUFFER
$CHEND==201 ; SIGNALS MATCH WITH END OF BUFFER IF NO EOL AT END
$CHSPC==202 ; SIGNALS MATCH WITH MULTIPLE SPACES/TABS
SRHLN==$CHSPC+1 ; # WORDS IN SEARCH MATRIX
SUBTTL Flag AC Bit Definitions
BIT (1B0) ; PRIME THE BIT GENERATOR
F$CCL==BIT ; CCL ENTRY WAS MADE
F$GCN==BIT ; GARBAGE COLLECTION IS NEEDED
F$1RG==BIT ; AN ARGUMENT IS PRESENT (CDC)
F$2RG==BIT ; A SECOND ARG IS PRESENT (CDC)
F$TRC==BIT ; IN TRACE MODE
F$REF==BIT ; T3=ADRREF(NOT ID) FOR QSTOR ROUTINE (TEMP)
F$EOF==BIT ; END OF FILE REACHED
F$FFD==BIT ; FORM FEED AT END OF BUFFER
F$NTI==BIT ; GETCH ROUTINE IS NOT INPUTTING FROM USER'S TERMINAL
F$2CO==BIT ; END OF LINE CHAR SEEN
F$EOL==F$REF ; Last character read was an EOL
F$LSF==BIT ; LAST SEARCH FAILED
F$COL==BIT ; THIS IS A ":" COMMAND (TRAP ON ERRORS)
F$DTM==BIT ; DELIMITED TEXT MODE
F$DNC==BIT ; DOWNCASE ALL INPUT LETTERS
F$UPC==BIT ; UPCASE ALL INPUT LETTERS
F$UAR==BIT ; Up-arrow really is up-arrow
F$CNV==BIT ; DOWNCASE THE NEXT CHAR IF IT IS A LETTER
F$CVV==BIT ; DOWNCASE LETTERS TILL END OF STR OR FURTHER NOTICE
F$CNW==BIT ; UPCASE NEXT CHAR IF A LETTER
F$CWW==BIT ; UPCASE LETTERS TILL END OF STR OR FURTHER NOTICE
F$CNX==BIT ; EXACT SEARCH MODE
F$EXM==BIT ; EXACT SEARCH MODE CAUSED BY ^V OR ^W
F$EMA==BIT ; EXACT SEARCH MODE CAUSED BY ^\
F$CNN==F$REF ; PREVIOUS CHAR WAS ^N(SEARCH MATRIX GENERATION)
F$BPG==F$REF ; FIRST CHAR MATCHED WITH BEGINNING OF PAGE
F$MSR==BIT ; DOING MINUS SEARCH
F$NOF==BIT ; TEMPORARILY SUPPRESS CASE FLAGGING
F$URD==BIT ; A FILE IS OPEN FOR READING
F$UWR==BIT ; A FILE IS OPEN FOR WRITING
F$UBK==BIT ; "EB" IN PROGRESS
F$XXX==BIT ;reserved
F$CMP==BIT ; COMPILE TEXT BUFFER (USED BY "MACRO")
F$STB==BIT ; SUPPRESS NEXT CHAR IF A TAB (FOR LSNS)
F$LSN==BIT ; CURRENT INPUT FILE HAS LSNS
F$REE==BIT ;[317] STOP BEFORE EXECUTING NEXT CMD
F$LOG==BIT ;[330] LOG FILE IN USE
F$$RG==F$1RG!F$2RG!F$COL!F$2CO!F$DTM ; ARGUMENT FLAGS (CDC)
F$$TX==F$UAR!F$CNV!F$CVV!F$CNW!F$CWW!F$EXM!F$EMA!F$CNN ; TEXT MODE FLAGS
; FOR TEXT INSERTION
F$$IO==F$URD!F$UWR!F$UBK!F$LOG ; I/O FLAGS
SUBTTL ET Word (ETVAL) Bit Definitions
ET$EXT==1 ; EXACT TYPEOUT (TRADITIONAL USE OF ET)
ET$DPY==2 ; SCOPE
ET$LC==4 ;[12000] lower case
ET$SUP==10 ;[12000] NO ECHO
ET$CCO==20 ;[12000] cancel ^O
ET$NST==40 ;[12000] Non-blocking TTY input
ET$DET==100 ;[12000] Detach(ed)
ET$ABO==200 ;[12000] Abort on error
;[12000] Teco has not prompted yet
ET$TRN==400 ;[12000] Truncate to TTY width
ET$VTX==1000 ;[12000] VT52/55/61
ET$VT11==2000 ;[12000] VT11 (GT40)
ET$CCT==100000 ;[12000] Trap ^C (reset if ^C typed)
;ED FLAGS...
;[12000]
ED$UAR==1 ;[12000] Uparrow in searches means uparrow
ED$YOK==2 ;[12000] Y & _ always OK
ED$NOV==4 ;[12000] Novice mode
ED$SSF==20 ;[14000] "." stays intact on search fail
ED$BLI==40 ;[12000] Symbol constituants: A-Z,0-9,$,%,_
ED$LLL==100 ;[12000] It's a line if it looks like a line
ED$SKP==200000 ;[12000] ^\ caused a skip
ED$OPT==400000 ;[12000] Optimize compilation
;DMODE bits
DM$ACR==1 ;Terminal does auto CRLF's (Linear addressing)
DM$NL==2 ;Terminal does <CR> also when <LF> typed out
DM$INS==4 ;Terminal is in INSERT mode
SUBTTL Transfer Vector Table for Command Execution
DEFINE TV (CMD)<$$'CMD: IFNDEF $'CMD,<PORTAL BEGIN>
IFDEF $'CMD,<PORTAL $'CMD>>; GEN A TRANSFER VECTOR
; CMDTVT - MACRO TO DEFINE THE COMMAND TRANSFER VECTOR TABLE
; ***** THIS TABLE SHOULD BE GENERATED BEFORE ANYTHING THAT COULD
; POSSIBLY CHANGE (PREFERABLY AT START OF HISEG)
DEFINE CMDTVT<XLIST
TV (CTM) ; TYPE COMMAND IF IN TRACE MODE
TV (ER) ; SELECT FILE FOR INPUT
TV (EM) ; POSITION MAGNETIC TAPE
TV (EW) ; SELECT FILE FOR OUTPUT
TV (EZ) ; ZERO DIRECTORY AND SELECT FILE FOR OUTPUT
TV (EB) ; EDIT BACKUP
TV (RUNP) ; SETUP FILE TO BEW RUN ON EXIT
TV (EI) ; EXECUTE AN INDIRECT COMMAND FILE
TV (EQ) ; READ A FILE INTO Q-REGISTER
TV (EA) ; APPEND TO A FILE
TV (EE) ; SAVE STATE IN A RUNNABLE FILE
TV (EL) ;[330] MAKE A LOG FILE
TV (ELA) ;[330] ALTER LOG FILE PARAMERERS
TV (RENM) ; RENAME CURRENT INPUT FILE
TV (EH) ; RETURN MESSAGE LENGTH
TV (EHS) ; SET MESSAGE LENGTH
TV (GTB) ; GETTAB MUUO (N,M^G)
TV (PEK) ; PEEK MUUO (N^G)
TV (Y) ; CLEAR BUFFER AND INPUT ONE PAGE
TV (CNY) ;[327] YANK IN SPECIFIED PAGE
TV (USI) ;[333] USETI TO SPECIFIED BLOCK
TV (A) ; APPEND A PAGE
TV (J) ; MOVE POINTER TO ABSOLUTE POSITION
TV (C) ; ADVANCE POINTER N POSITIONS
TV (R) ; BACKUP POINTER N POSITIONS
; EQUIVALENT TO -NC
TV (L) ; MOVE TO A LINE RELATIVE TO "."
TV (T) ; TYPE TEXT FROM BUFFER BETWEEN TWO POINTS
TV (TL) ; TYPE N LINES FROM BUFFER
TV (0TT) ; TYPE CURRENT LINE IF LAST SEARCH SUCCEEDED
TV (DEC) ; TYPE THE DECIMAL INTEGER N
TV (OCT) ; TYPE THE OCTAL INTEGER N
TV (MES) ; TYPE A MESSAGE
TV (TTY) ;[306] RETURN TTY#+^O200000 OF JOB N
TV (FFD) ; TYPE A FORMFEED
TV (TTC) ; PERFORM ANY TTCALL
TV (D) ; DELETE CHARACTERS
TV (K) ; DELETE TEXT BETWEEN TWO POINTS
TV (KL) ; DELETE LINES OF TEXT
TV (I) ; INSERT TEXT
TV (NI) ; INSERT CHARACTER WITH THE ASCII VALUE N
TV (TAB) ; TAB INSERT (IE: INSERT <TAB> THEN TEXT
TV (BS1) ; INSERT THE ASCII REPRESENTATION OF DECIMAL N
TV (BS2) ; VALUE OF NUMBER TO RIGHT OF POINTER
TV (UP) ; TRANSLATE TO UPPER CASE
TV (CX) ; ^X - RETURN VALUE OF EXACT SEARCH MODE FLAG
TV (CXS) ; N^X - SET EXACT SEARCH MODE FLAG
TV (LOW) ; TRANSLATE TO LOWER CASE
TV (PW) ; OUTPUT THE CURRENT PAGE AND APPEND
; A FORMFEED TO IT
TV (P) ; OUTPUT CURRENT PAGE
TV (BP) ; OUTPUT PART OF CURRENT PAGE (WITHIN BOUNDS)
TV (CNP) ; POSITION TO A PAGE IN FILE
TV (EF) ; CLOSE THE OUTPUT FILE
TV (CNZ) ; CLOSE THE OUTPUT FILE AND EXIT
TV (EX) ; OUTPUT REMAINDER OF FILE AND EXIT
; EXIT TO THE MONITOR
TV (EG) ; "EX" AND DO LAST COMPILE-CLASS COMMAND
TV (S) ; SEARCH FOR A STRING ON CURRENT PAGE
TV (BS) ; BOUNDED SEARCH
TV (FS) ; CHANGE STR1 TO STR2 ON CURRENT PAGE
TV (N) ; SAME AS "S" BUT USE REST OF FILE
TV (BAR) ;SAME AS "N" BUT DON'T OUTPUT
TV (SEM) ; JUMP OUT OF CURRENT ITERATION
TV (SEMF) ; JUMP OUT OF CURRENT ITERATION IF LAST SEARCH FAILED
TV (SEMZ) ; JUMP OUT OF CURRENT ITERATION IF ARG IS ZERO
TV (CKC) ; CHECK IF ARG IS A SYMBOL CONSTITUENT
TV (CKA) ; CHECK IF ARG IS A LETTER
TV (CKD) ; CHECK IF ARG IS A DIGIT
TV (CKV) ; CHECK IF ARG IS A LOWER CASE LETTER
TV (CKW) ; CHECK IF ARG IS AN UPPER CASE LETTER
TV (U) ; STORE INTEGER IN Q-REGISTER
TV (Q) ; RETURN VALUE STORED IN Q-REGISTER
TV (INC) ; INCREMENT Q-REGISTER BY 1 AND RETURN VALUE
TV (X) ;EXTRACT TEXT FROM TEXT BUFFER
TV (XL) ; STORE LINES FROM BUFFER INTO Q-REGISTER
TV (G) ;GET TEXT FROM A Q-REGISTER
TV (M) ; EXECUTE THE TEXT IN A Q-REGISTER
; AS A COMMAND STRING
TV (PUSH) ; PUSH CONTENTS OF A Q-REGISTER ON QPDL
TV (POP) ; POP QPDL INTO A Q-REGISTER
TV (NA) ;VALUE OF CHAR FOLLOWING POINTER
; POINTER
TV (CNE) ; RETURN VALUE OF THE FORMFEED FLAG.
TV (CNN) ; RETURN VALUE OF THE END-OF-FILE FLAG
TV (STOP) ; <ALT><ALT> (IE: STOP EXECUTION)
TV (EC) ; Maybe output all and RETURN LOWSEG SIZE IN WORDS
TV (ECS) ; SET THE LOWSEGMENT SIZE
TV (QRX) ;[3000] R/A Q REGISTER CMD
TV (QCM) ;[10000] Q-register compare
TV (TRMO) ;[10000] TRMOP.'s
TV (EXE) ;[12000] Execute instruction
TV (EY) ;[12000] EY always , Y only if buffer empty
TV (STQ) ;[12000] store in q-register
TV (CNQ) ;[12000] # of chars in next n lines
TV (E) ;[12000] Go to end of nth line
TV (CNU) ;[12000] Insert to q-register
TV (EK) ;[12000] Flush output file, cancel EB
TV (V) ;[12000] Type n lines either side of .
TV (W) ;[12000] window manipulation
TV (COLW) ;[12000] manipulate window parameters
TV (ETS) ;[12000] Set ET flags
TV (EJ) ;[12000] Set or retrieve system stuff
TV (FOUT) ;[12000] Force all tty output out
TV (TCHR) ;[12000] Type a character on current TTY
TV (FF1) ;[12000] Adjust FL & FC
TV (FF2) ;[12000] Adjust FL & FC
TV (EBAR) ;[14000] E_ (like _ but always legal)
TV (CKR) ;[14000] Check for alphanumeric
TV (EPCT) ;[14000] E% cmd (write out from q-register)
TV (BSL) ;[14000] nFB, nFC line mode bounded search
TV (CW2) ;[15000] m,n:W
TV (GETC) ;[15000] E?q get cmd into q-register
TV (GCHR) ;[16000] ^T Get a character
TV (AL) ;[16000] Append a few lines of text
LIST
SALL>
;THESE INSTRUCTIONS MUST BE THE FIRST DATA WORDS IN HISEG
$EECON:
FOR TOPS10,<
XTCERR:
>
FOR FTXTEC, PORTAL $EECNT ;[325] CALL EE CONTINUE
FOR FTXTCERR,< NOTFOR FTXTEC,<
PORTAL ERMT ;[325] CALL ERROR ROUTINE
>>
FOR FTXTEC!FTXTCERR,SALL ;[410] RESTORE LISTING
; GENERATE THE COMMAND TRANSFER VECTOR TABLE HERE
FOR FTXTEC,<
CMDTVT
SUBTTL Startup Initialization
XTEC: PORTAL .+2 ; ENTRY POINT FOR NORMAL ENTRY
PORTAL .+2 ; ENTRY POINT FOR CCL ENTRY
TDZA T1,T1 ; THIS IS THE NORMAL ENTRY POINT
MOVX T1,F$CCL ; THIS IS THE CCL ENTRY POINT
; CLEAR IMPURE LOW SEGMENT DATA
FOR TOPS10,RESET ;[20000] Make sure .JBFF get set up!
STORE (T2,LOWBEG,LOWEND,0)
; INITIALIZE PURE LOW SEGMENT CODE
FOR TOPS10,<
MOVE T2,[<HICODE,,LOCODE>] ; SETUP BLT POINTER
BLT T2,LOCEND ; BLT CODE TO LOWSEGMENT
; STORE INFORMATION ABOUT WHERE WE CAME FROM
MOVEM .SGNAM,GSGNAM ; STORE OUR NAME
MOVEM .SGNAM,SEGNAM ; (DITTO)
TLNN .SGPPN,777777 ;[15000] Could this be a path block
JRST [JUMPE .SGPPN, [MOVE X, [.PTMAX,,GSGPAT] ;nothing
SETOM GSGPAT+.PTFCN ;so read default
PATH. X, ; if we can
JRST [GETPPN .SGPPN ;do best we can
JFCL ;The useless JACCT skip
JRST .+1] ;back to main code
JRST PTPPPZ] ;We have the path block...
MOVSI X,-.PTMAX ;- # of words to copy
HRLI .SGPPN,(<MOVE T2,0(X)>) ;Make into MOVE T2,75(X)
PTPPPL:! XCT .SGPPN ; Fetch first word
MOVEM T2,GSGPAT(X) ;and store it
AOBJN X,PTPPPL ; Back for more if any left
PTPPPZ:! MOVEI .SGPPN,GSGPAT ;Put addr of path block in PPN place
JRST .+1] ; Back to main code
MOVEM .SGPPN,GSGPPN ; STORE OUR DIRECTORY
MOVEM .SGDEV,GSGDEV ; STORE OUR DEVICE
MOVEM .SGLOW,GSGLOW ; SAVE OUR LOW FILE EXTENSION
>;END IFN TOPS10
; INITIALIZE FLAGS
MOVE F,T1 ; T1 HAS CCL ENTRY FLAG
; RELEASE EXTRA CORE
$XTEC: MOVE X,.JBFF ;[375] FETCH FIRST FREE ADR
MOVEM X,HEAD ; DYNAMIC FREE CORE WILL START THERE
MOVEI T1,(X) ; SAVE THE ADR
CORE X, ; TELL MONITOR EXACTLY HOW MUCH CORE WE NEED
HALT .+1 ;[20000] Shouldn't occur
SETZM (T1) ; FIRST FREE LOC MUST BE ZERO
; (FOR THE CORE MANAGEMENT ROUTINES)
; SETUP APR TRAP ADDRESS
MOVEI X,APRTRP ; FETCH ADR OF APR TRAP HANDLER
MOVEM X,.JBAPR ; AND STORE IN JOBDAT WHERE MONITOR CAN SEE IT
; ENABLE FOR APR POV & ILM TRAPS
MOVX X,AP.REN!AP.POV!AP.ILM ; ENABLE FOR PDL OV AND ILL MEM REF AGAIN AND AGAIN
APRENB X, ; TELL THE MONITOR TO ENABLE THE APR FOR US
; SETUP ADDRESS OF LUUO HANDLER
MOVE X,[PUSHJ P,UUOTRP] ; LUUOS WILL CAUSE PUSHJ TO UUOTRP
MOVEM X,.JB41 ; STORE INSTRUCTION IN JOBDAT
; SETUP ADDRESS OF REENTER HANDLER (FOR ^C^C.REENTER)
MOVEI X,REENTR ; FETCH ADR OF REENTER HANDLER
MOVEM X,.JBREN ; AND STORE IT IN JOBDAT WHERE MONITOR WILL SEE IT
MOVEI X,RESTRT ;[375] LOAD RESTART ADR
HRRM X,.JBSA ;[350] SO SAVEGET DOESN'T GET CLOBBERED
; SETUP TEMPORARY CONTROL PDP
MOVE P,[IOWD C$TPDL,TPDL] ;[301] SETUP TEMP PDP
; INITIALIZE THE MAIN TEXT EDITING BUFFER
MOVEI L,TXTBUF ; FETCH ADR OF REFERENCE TO IT
PUSHJ P,RELM ; deallocate
MOVE L,[<TMPREF,,C$TBLN>] ; ARG FOR ALLOCATING TEXT BUFFER
PUSHJ P,REQM ; ALLOCATE THE TEXT BUFFER
MOVE X,TMPREF ;[12000] Save address of buffer
MOVEM X,TXTBUF ;[12000]
MOVEI L,TXTBUF ;[12000]
HRRM L,B$4PTR(X) ;[12000] Put addr of ref in safer place
HLLZS B$1PTR(X) ;[12000] & zap the old one
MOVEI L,TMPREF ;[12000] Now add to linked list
PUSHJ P,ADDBLK ;[12000]
MOVEI X,NOOF ;[304] FETCH ADR FOR NO OUTPUT FILE ERROR
MOVEM X,PCHADR ;[304] TO PREVENT ILL. UUOS
; Open the TTY so we can control echoing
PUSHJ P,TTOPEN ;[12000]
; Set up prompts so that they will happen
MOVX X,<ASCIZ "*"> ;[12000] This is a "*" to start with
MOVEM X,PROMPT ;[12000] put it in the prompt buffer
; Set up string to type after accepting command (initially CRLF)
MOVSI X,(BYTE (7) 15,12) ;[14000]
MOVEM X,TARCMD ;[14000] Make Stan Rabinowitz happy
; INITIALIZE CASE FLAGGING TO C$EUVL
IFE C$EUVL+1,<SETOM EUVAL> ; -1=FLAG NONE
IFE C$EUVL,<SETZM EUVAL> ; 0=FLAG LOWER CASE
IFE C$EUVL-1,<MOVEI X,1 ; +1=FLAG UPPER CASE
MOVEM X,EUVAL> ; . . .
; SET UP DELIMITERS FOR TEXT AND COMMANDS
MOVEI X,33 ;[12000] ESCAPEs to start with
MOVEM X,DELIM ;[12000] 1 for text
MOVEM X,CDELIM ;[12000] 2 for command delimiter
MOVEM X,CDELIM+1 ;[12000] ...
;[12000] Initialize ET value
MOVX X,ET$ABO ;[12000] Abort flag starts out set
MOVE T1,OURTTY ;[12000] Check LC characteristic of terminal
GETLCH T1 ;[12000] so we can set 4ET
TXNE T1,GL.LCM ;[12000] if it is set
TXO X,ET$LC ;[12000] it was
MOVEM X,ETVAL ;[12000] ET is now initialized
MOVX X,<BYTE (7)40,10> ;[15000] Initialize character wiper-outer
MOVEM X,WIPEC ;[15000] so dpy mode will work, sort of
; INITIALIZE EO VALUE
MOVEI X,C$EOVL ;[3000] SET UP EO VALUE TO CURRENT
MOVEM X,EOVAL ;[3000]
; INITIALIZE "LAST" FILE SPECIFICATIONS
MOVSI X,'DSK' ; DEFAULT DEVICE IS 'DSK'
MOVEM X,LERSPC+FS$DEV ; FOR "ER" FILE-SPEC
MOVEM X,LEWSPC+FS$DEV ; AND LAST "EW" FILE-SPEC
MOVEM X,LEBSPC+FS$DEV ; AND LAST "EB" FILE-SPEC
MOVEM X,LEISPC+FS$DEV ; AND LAST "EI" FILE-SPEC
MOVEM X,LRPSPC+FS$DEV ; AND LAST "ED" FILE-SPEC
MOVEM X,LEESPC+FS$DEV ; AND LAST "EE" FILE-SPEC
MOVEM X,LELSPC+FS$DEV ;[330] AND LAST "EL" FILE-SPEC
MOVE X,SEGNAM ;[330] DEFAULT LOG NAME IS MY NAME
MOVEM X,LELSPC+FS$NAM ;[330] . . .
MOVSI X,'LOG' ;[330] DEFAULT LOG EXTENSION IS 'LOG'
MOVEM X,LELSPC+FS$EXT ;[330] . . .
MOVSI X,'TEC' ; FETCH DEFAULT EXT. FOR "EI"
MOVEM X,LEISPC+FS$EXT ; AND SET DEFAULT FILE EXT. FOR "EI"
MOVSI X,C$SEXT ; FETCH DEFAULT FILE EXT FOR SAVE FILE
MOVEM X,LEESPC+FS$EXT ; AND STORE FOR LATER
; INITIALIZE THE BYTE POINTER FOR MOVING LAST PARTIAL WORD IN 'MKROOM'
MOVE X,[POINT 0,-1(14),34] ; FETCH THE BYTE POINTER
MOVEM X,MKRMBP ; AND STORE FOR USE BY 'MKROOM'
; SETUP THE CONTROL PDL POINTER
STSTK (P,C$PDLL,PDL) ; SETUP THE CONTROL PDL POINTER
; SETUP Q-REGISTER TABLE (QTAB)
STSTK (QR,C$QRLN,QTAB)
; SETUP Q-REGISTER PUSHDOWN LIST (QPDL)
STSTK (QP,C$QPLN,QPDL)
MOVE X,QP ; FETCH THE PDP FOR QPDL
PUSH X,[<0>] ; AND PUSH 3 ZEROS TO MARK BEGINNING
PUSH X,[<0>] ; . . .
PUSH X,[<0>] ; . . .
MOVEM X,QP ; AND STORE THE UPDATED PDP
; SETUP OUR CCL JOB NUMBER (IE: '###XTC')
PUSHJ P,MAKCJN ; MAKE OUR CCL JOB NUMBER
; AND STORE IN "CCJNAM"
; FETCH MESSAGE LENGTH
GTMSG. (X) ; GETTAB MESSAGE LENGTH
MOVEM X,EHVAL ; AND STORE FOR LATER
; STARTUP INITIALIZATION COMPLETE.
SUBTTL Compile&Execute XTEC Option Line from DSK:SWITCH.INI[,]
; SEE IF DSK:SWITCH.INI[-] EXISTS
MOVE N,[Z INP,0] ; SETUP INPUT CHANNEL
MOVEM N,INPCHN ; . . .
MOVEI M,INIBH ; FETCH ADR OF INPUT BUFFER HEADER
MOVEI L,FILSPC ; FETCH ADR OF FILE-SPEC
SETZM FS$FLG(L) ; CLEAR FILE-SPEC FLAGS
MOVSI X,'DSK' ; DEVICE IS 'DSK'
MOVEM X,FS$DEV(L) ; . . .
MOVE X,['SWITCH'] ; NAME IS 'SWITCH'
MOVEM X,FS$NAM(L) ; . . .
MOVSI X,'INI' ; EXTENSION IS 'INI'
MOVEM X,FS$EXT(L) ; . . .
; GETPPN X, ; GET OUR PPN
; JFCL ; (IN CASE OF JACCT)
; MOVEM X,FS$PPN(L) ; AND USE AS PPN FOR FILE
SETZM FS$PPN(L) ;[340] USE DEFAULT PATH FOR PPN
SETZM FS$SFD(L) ; CLEAR SFDS
PUSHJ P,FILOPN ; OPEN DSK:
JRST NOSWI ; NO SWITCH.INI
PUSHJ P,FILLKP ; LOOKUP SWITCH.INI[-]
JRST NOSWI ; NO SWITCH.INI
MOVEI X,[TXO F,F$EOF ; ADR OF WHERE TO GO ON EOF
MOVEI C,.CHESC
POPJ P,]
MOVEM X,INPEOF ; STORE ADR OF EOF PROCESSOR
MOVEI X,[ERROR (IES)] ; FETCH ADR OF WHERE TO GO ON INPUT ERROR
MOVEM X,INPERR ; AND STORE FOR LATER
MOVEI X,INIBH ; FETCH ADR OF BUFFER HEADER
MOVEM X,INPBH ; AND STORE FOR LATER
TXO F,F$NTI ; NOT INPUTTING FROM USER'S TERMINAL
; TRY TO FIND THE XTEC LINE IN SWITCH.INI
INI1: PUSHJ P,GSIX ; PICKUP NAME FROM SWITCH.INI LINE
JUMPE N,INI2 ; NONE. IGNORE THIS LINE
XOR N,SEGNAM ; SEE IF IT IS THE XTEC LINE
JUMPE N,INI3 ; YES
INI2: PUSHJ P,GEOL ; NO, EAT THE LINE
TXZN F,F$EOF ; END OF FILE?
JRST INI1 ; NO, KEEP SEARCHING FOR XTEC LINE
JRST NOSWI ; YES, THEN THERE IS NO XTEC LINE
; COPY THE XTEC LINE TO COMMAND BUFFER AND EXECUTE IT
INI3: MOVEI L,CURCMD ; FETCH ADR OF THE COMMAND BUFFER
PUSHJ P,RELM ; FREE IT
MOVE L,[<CURCMD,,C$CMDL+T$DATA>] ; ALLOCATE NEW COMMAND BUFFER
PUSHJ P,REQM ; . . .
MOVE T3,[POINT 7,T$DATA(T5)] ; SETUP BYTE POINTER TO CMD BUFFER
MOVEI T4,C$CMDL*5-2 ; SETUP COUNT OF CHARS LEFT IN BUFFER
INI4: PUSHJ P,GCHR ; FETCH NEXT CHAR FROM SWITCH.INI
MOVE T5,CURCMD ; FETCH BASE ADR OF COMMAND BUFFER
SOJL T4,INI5 ; BUFFER IS FULL
AOS (T5) ; COUNT THE CHAR
IDPB C,T3 ; AND STORE IT IN THE BUFFER
TXZN F,F$EOL ; WHOLE LINE IN BUFFER?
JRST INI4 ; NO, FETCH ANOTHER CHAR
INI5: MOVEI C,.CHESC ; APPEND TWO ALTMODES TO LINE
IDPB C,T3 ; . . .
IDPB C,T3 ; . . .
AOS (T5) ; AND COUNT THEM
AOS (T5) ; . . .
; NOW COMPILE AND EXECUTE THE LINE
MOVEI L,CURCMD ; FETCH ADR OF COMMAND BUFFER
PUSHJ P,ADDBLK ; ADD THE BUFFER TO THE LINKED LIST
MOVEM N,CMDBID ; SAVE THE BUFFER ID
MOVE L,['[SINI]'] ; GIVE THE BUFFER A NAME
TXO F,F$CMP ; FLAG TO "FORCE COMPILATION"
PUSHJ P,MACRO ; AND COMPILE&EXECUTE THE BUFFER
MOVE N,CMDBID ; RESTORE THE BUFFER ID
PUSHJ P,DELBLK ; AND DELETE THE BUFFER
NOSWI:; JRST INISET ; DO XTEC.INI IF IT EXISTS
SUBTTL COMPILE&EXECUTE DSK:XTEC.INI[,] if it exists
INISET: MOVEI L,FILSPC ; FETCH ADR OF FILE-SPEC
SETZM FS$FLG(L) ; CLEAR THE FILE-SPEC FLAGS
MOVSI X,'DSK' ; DEVICE IS 'DSK'
MOVEM X,FS$DEV(L) ; . . .
MOVE X,SEGNAM ; NAME IS NAME OF THIS SEGMENT
MOVEM X,FS$NAM(L) ; . . .
MOVSI X,'INI' ; EXTENSION IS 'INI'
MOVEM X,FS$EXT(L) ; . . .
; GETPPN X, ; GET OUR PPN
; JFCL ; (IN CASE OF JACCT)
; MOVEM X,FS$PPN(L) ; USE AS FILE PPN
SETZM FS$PPN(L) ;[340] USE DEFAULT PATH FOR PPN
SETZM FS$SFD(L) ; CLEAR SFDS
SETZ N, ; USE CHANNEL ZERO
MOVEI M,INIBH ; FETCH ADR OF INPUT BUFFER HEADER
PUSHJ P,FILOPN ; AND TRY TO FIND FILE
JRST NOINI ; NOT THERE. NO XTEC.INI FILE
PUSHJ P,FILLKP ; TRY TO FIND FILE STILL
JRST NOINI ; NOT THERE. NO XTEC.INI FILE
RELEAS 0, ; RELEASE THE CHANNEL
PUSHJ P,FILERD ; AND READ THE FILE
MOVEM N,CMDBID ; SAVE THE BUFFER ID
MOVE L,['[XINI]'] ; GIVE THE COMMAND A NAME
TXO F,F$CMP ; FORCE COMPILATION
PUSHJ P,MACRO ; AND COMPILE&EXECUTE THE MACRO
MOVE N,CMDBID ; RESTORE THE BUFFER ID
PUSHJ P,DELBLK ; AND DELETE THE BLOCK
NOINI: RELEAS 0, ; RELEASE CHANNEL ZERO
; JRST CCLSET ; DO CCL SETUP IF NECESSARY
SUBTTL CCL Setup
CCLSET: TXNN F,F$CCL ; WAS CCL ENTRY MADE?
JRST NOCCL ; NO
; TRY TO READ TMPCOR CCL FILE
MOVE T1,[<.TCRDF,,[EXP 'EDT ',<IOWD 200,INPBF+3>]>]
; SETUP TMPCOR ARG BLOCK
TMPCOR T1, ; TRY TO READ TMPCOR CCL FILE
JRST CCLST1 ; CAN'T. TRY DSK:###EDT.TMP[-]
; SETUP BYTE POINTER FOR TMPCOR BUFFER
MOVE X,[POINT 7,INPBF+3,6] ; POINT TO 2ND CHAR OF BUFFER
; (TO IGNORE THE LINED "S")
MOVEM X,INPBH+1 ; STORE THE BP IN INPUT BUFFER HEADER
JRST CCLST2 ; AND FIND THE "TECO" COMMAND
; TRY TO READ DSK:###EDT.TMP
CCLST1: INIT INP,.IOASL ; INIT 'DSK'
('DSK') ; . . .
<0,,INPBH> ; . . .
CCLERR: ERROR (CCM) ; ** CCL COMMAND MISSING **
MOVE T1,CCJNAM ; AND LOOKUP ###EDT.TMP
HRRI T1,'EDT' ; . . .
MOVSI T2,'TMP' ; . . .
SETZB T3,T4 ; . . .
LOOKUP INP,T1 ;[351] . . .
ERROR (CCM) ;[322] BALK
MOVEI T1,INPBF ;[400] LOAD ADDR OF INPUT BUFFER
EXCH T1,.JBFF ;[400] SWAP TO FOOL MONITOR
INBUF INP,C$NBUF ;[400] SET UP 1 BUFFER AT INPBF
MOVEM T1,.JBFF ;[400] RESTORE .JBFF
INPUT INP, ; INPUT DISK BUFFER
IBP INPBH+1 ; AND SKIP OVER THE LINED "S"
SETZ T1, ;[367] ZERO FILENAME MEANS DELETE
RENAME INP,T1 ;[367] DELETE IT
JFCL ;[367] SORRY HUN
RELEAS INP, ;[367] FREE CHANNEL
; READ FILE SPEC OF FORM SFILE-SPEC<ALT> OR SFILE-SPEC<CR>
; (<ALT> MEANS DO "EW", <CR> MEANS DO "EB" AND "EY")
CCLST2: MOVEI L,CURCMD ; ALLOCATE COMMAND BUFFER
PUSHJ P,RELM ; . . .
MOVE L,[<CURCMD,,200>] ; . . .
PUSHJ P,REQM ; . . .
MOVE T3,CURCMD ; SETUP BYTE POINTER TO CMD BUFFER
ADD T3,[POINT 7,T$DATA,13] ; . . .
MOVE T5,T3 ; SAVE BP TO THE "B" OF "EB"
MOVSI X,("EB"B13) ; SETUP FOR AN "EB" COMMAND
MOVEM X,(T3) ; . . .
SETZ T4, ; CLEAR THE CHAR COUNT
; PUT THE FILE-SPEC IN THE COMMAND BUFFER
CCLST3: ILDB C,INPBH+1 ; FETCH CCL CHAR
JUMPE C,CCLERR ;[367] NULL IN CCL MEANS SOMETHING FUNNY
CAIE C,.CHALT ; IS CHAR AN OLD ALTMODE?
CAIN C,.CHAL2 ; (TRY ALL FLAVORS!)
MOVEI C,.CHESC ; YES, CONVERT TO NEW STYLE <ALT>
IDPB C,T3 ; AND PUT IN COMMAND BUFFER
CAIN C,.CHCRT ; IS IT A <CR>?
JRST CCLST4 ; YES, FILE-SPEC IS COMPLETE
CAIE C,.CHESC ; IS IT <ALT>?
AOJA T4,CCLST3 ; NO, COUNT AND TRY NEXT CHAR
; SFILE-SPEC$ - COMMAND TO CREATE A FILE
MOVEI C,"W" ; CHANGE "EB" TO "EW"
DPB C,T5 ; . . .
JRST CCLST5 ; AND FINISH UP
; SFILE-SPEC<CR> - COMMAND TO "TECO" A FILE-SPEC
CCLST4: MOVEI C,.CHESC ; ADD AN <ALT> TO COMMAND
DPB C,T3 ;[367] . . .
MOVEI C,"E" ; ADD "EY" TO READ IN FIRST PAGE
IDPB C,T3 ; . . .
MOVEI C,"Y" ; . . .
IDPB C,T3 ; . . .
MOVEI T4,3(T4) ; COUNT THE <ALT>EY
; APPEND <ALT><ALT> TO COMMAND AND EXECUTE IT
CCLST5: MOVEI C,.CHESC ; FETCH AN <ALT>
IDPB C,T3 ; APPEND <ALT> TO COMMAND
IDPB C,T3 ; AND ANOTHER FOR GOOD LUCK
MOVEI T4,3(T4) ; COUNT <ALT><ALT> PLUS TERM CHAR
MOVEM T4,@CURCMD ; STORE CHAR COUNT FOR BUFFER
MOVEI L,CURCMD ; FETCH ADR OF COMMAND BUFFER
PUSHJ P,ADDBLK ; ADD THE BUFFER TO THE LINKED LIST
MOVEM N,CMDBID ; SAVE THE BUFFER ID
MOVX L,C$CCNM ; GIVE THE CCL BUFFER A NAME
TXO F,F$CMP ; FLAG TO "FORCE COMPILATION"
PUSHJ P,MACRO ; AND COMPILE&EXECUTE THE BUFFER
MOVE N,CMDBID ; RESTORE THE BUFFER ID
PUSHJ P,DELBLK ; AND DELETE THE BUFFER
NOCCL: TXZ F,F$NTI ; INPUT FROM USER'S TERMINAL AGAIN
SETZM INPADR ; . . .
SETZM INPCHR ; . . .
; JRST BEGIN ; AND BEGIN NORMAL COMMAND PROCESSING
SUBTTL Command Input Processor
BEGIN:
; SETUP THE CONTROL PDL POINTER
STSTK (P,C$PDLL,PDL) ; SETUP CONTROL PDL
; [12000] Clear the abort flag if it was set
MOVE X,ETVAL ;[21000] Get ET
TXZE X,ET$SUP!ET$ABO ;[14000] Echoing supressed?
ECHO ON ;[21000] turn it back on
MOVEM X,ETVAL ;[21000] Turn off 'supress' and 'abort'
; OUTPUT PROMPT
TXZ F,F$$RG!F$TRC ;[352] CLEAR ARG FLAGS [16000] AND TRACE
SETZM COL ;[23000] This is column 0
SKIPG INPCHR ; ALREADY HAVE FIRST CHAR?
PUSHJ P,TSTAR ; NO, TYPE PROMPT
; CHECK FOR THE "*" COMMAND (IE: SAVE LAST COMMAND IN A Q-REGISTER)
BEGIN0:
PUSHJ P,GETCHL ; READ NEXT INPUT CHAR
CAIN C,"*" ; IS IT A "*"?
JRST SAVPCM ; YES, SAVE PREVIOUS COMMAND IN Q-REGISTER
MOVEM C,INPCHR ; NO, SAVE THE FIRST CHAR OF COMMAND STRING
; RELEASE THE PREVIOUS COMMAND BUFFER
BEGIN1: SKIPE N,PCMBID ; A PREVIOUS COMMAND?
PUSHJ P,DELBLK ; YES, DELETE ITS BUFFER
MOVE N,CMDBID ; NO, FETCH CURRENT BUFFER ID
MOVEM N,PCMBID ; AND SAVE AS BID FOR "PREVIOUS" COMMAND
PUSHJ P,GETCMD ;[12000] Call routine to get a command
JRST BEGIN ;[12000] luser musta typed ^G^G
MOVEI N,TARCMD ;[14000] Type this After Reading CMD
PUSHJ P,TXSTR ;[14000]
PUSHJ P,FOUT ;[16000] Force it out now
MOVX X,ET$SUP ;[16000] See if echo should be supressed
TDNE X,ETVAL ;[16000] ...
ECHO OFF ;[21000] Turn it off
MOVE N,CMDBID ;[14000] Get N back
;Now prepare to execute the command we got (BID is in N)
MOVE L,['[CCMD]'] ; MAKE A NAME FOR THE CMD BUFFER
TXO F,F$CMP ; FLAG THAT BUFFER MUST BE COMPILED
PUSHJ P,MACRO ; AND COMPILE&EXECUTE THE CMD BUFFER
TXZ F,F$COL!F$2CO ;[15000] Clear left over colons
SKIPN N,QREG+<'!'*2> ;[23000] Try to get text of q!
JRST BEGIN ;[7000] NOT TEXT SO GIVE UP
MOVSI L,'! ' ;[7000] AUTOMATIC MACRO NAME
PUSHJ P,MACRO ;[7000] DO THE MACRO
JRST BEGIN ; GO BACK FOR ANOTHER COMMAND
SUBTTL GETCMD -- Get a command string from current input source
; GETCMD - Get a command string from the current input source
; routine allocates its own storage for commands
;
; CALL: PUSHJ P,GETCMD
; <RETURN 1> ;user erased the command, just prompt
; <RETURN 2> ;execute the command. BID is in N
GETCMD:
; ALLOCATE A NEW COMMAND BUFFER
MOVE L,[<CURCMD,,C$CMDL+T$DATA>] ; ARG FOR ALLOCATING BLOCK
PUSHJ P,REQM ; ALLOCATE NEW COMMAND BUFFER
MOVEI L,CURCMD ; FETCH ADR OF REF TO BUFFER
PUSHJ P,ADDBLK ; AND ADD THE BLOCK TO THE LINKED LIST
MOVEM N,CMDBID ; AND SAVE ITS BUFFER ID
PUSHJ P,FNDBLK ; "CURCMD" WILL REFERENCE THE BUFFER
ERROR (BNF) ; CAN'T FIND BLOCK. SHOULDN'T OCCUR!
; SETUP CHAR COUNTS AND BYTE POINTER FOR COMMAND BUFFER
SETZ T5, ; ZAP THE CHAR COUNT
MOVEI T3,C$CMDL*5 ; # CHARS WE CAN PUT IN BUFFER
MOVE T4,[POINT 7,T$DATA(T5)] ; BYTE POINTER
TXO F,F$NOF ; SUPPRESS CASE FLAGGING
; NOW READ COMMAND STRING
RDLOOP: PUSHJ P,GETCHL ; FETCH NEXT INPUT CHAR [12000] in line mode
RDLP0:
TXZE F,F$REE ;[20000] Did we ^C.REE?
JRST RDEMP ;[20000] Yes, start over
FOR FTBSRO,<CAIE C,.CHCNH> ;BACKSPACE OK TOO
CAIN C,.CHDEL ; IS CHAR A RUBOUT?
JRST RDRUB ; YES
CAIN C,.CHLFD ;[10000] Is this a linefeed
JRST [SKPECHO ;[24000] check echoing
JRST .+1 ;[14000] Leave screen position alone!
AOS T1,ROW ;[10000] Increment linefeed count
CAMGE T1,LENGTH ;[12000] Did it cause a scroll
JRST .+1 ;[12000] NO, continue
AOSG SCFWD ;[12000] Yes, say so
SETZM ROW ;[12000] For terminals that go back to top
JRST .+1] ;[12000] Remember that we scrolled
CAIN C,.CHBEL ; IS CHAR A BELL(^G)?
JRST RDBEL ; YES
CAIN C,.CHCNU ; IS CHAR A ^U?
JRST RDCNU ; YES
; STORE THE CHAR IN COMMAND BUFFER BEFORE CHECKING FOR <ALT> OR ^R
PUSHJ P,RDIDPB ; STORE THE CHAR IN COMMAND BUFFER
CAMN C,CDELIM ; IS CHAR A DELIMITER?
JRST RDCDEL ; YES
CAIN C,.CHCNR ; IS CHAR A ^R?
JRST RDCNR ; YES
JRST RDLOOP ; ORDINARY CHAR. GO BACK FOR ANOTHER
; STORE CHAR IN COMMAND BUFFER
RDLP1: PUSHJ P,RDIDPB ; JAM THE CHAR INTO THE COMMAND BUFFER
JRST RDLOOP ; AND GO BACK FOR FOR INPUT
; RDRUB - PROCESS A RUBOUT
RDRUB:
SKPECHO ;[24000] Skip if echo on
JRST RDRB2 ;[14000] Off, so don't type anything
MOVE X,ETVAL ;[16000] Check ET for DPY
TRNN X,ET$DPY ;[5000]
JRST RDRB1 ;[5000] NOT
MOVE N,C ;[24000] Save our "RUBOUT"
PUSHJ P,RDLDB ;[5000] PICK UP THE CHARACTER
JRST RDEMP1 ;[23000] None left
CAIN N,177 ;[5000] REALLY RUBOUT?
JRST [MOVE N,C ;[25000] Remember rubbed-out char
MOVEI C,10 ;[5000] YES SO DO BACKSPACE
PUSHJ P,TCHR ;[5000]
HRRZS COL ;[14000] Un-confuse cursor count
MOVE C,N ;[24000] Put back rubbed-out character
JRST .+1] ;[5000]
CAIN C,12 ;[5000] LINEFEED IS SPECIAL
JRST [MOVEI N,RLF ;[12000] Get sequence for reverse LF
PUSHJ P,T0XSTR ;[5000] UNDO THE LINEFEED
PUSHJ P,RDDLDB ;[5000] LOOK AT PREVIOUS CHARACTER
JRST RDRTYP ;[5000] NONE, SO DON'T WORRY
CAIE C,15 ;[5000] CARRIAGE RETURN?
JRST RDRTYP ;[5000] NO SO RETYPE LINE
PUSHJ P,TCHR ;[5000] TYPE IT
JRST RDLOOP] ;[5000] BACK FOR MORE
CAIGE C," " ;[5000] CONTROL CHAR?
JRST [PUSHJ P,RDDLDB ;[5000] NOW BACK UP
JFCL ;[5000] IGNORE ERROR
JRST RDRTYP]
MOVEI N,WIPEC ;[5000] SPACE,BACKSPACE
PUSHJ P,T0XSTR ;[5000]
SOS COL ;[14000] Tell screen processor we backed up
PUSHJ P,RDDLDB ;[5000] NOW BACK UP
JFCL ;[5000] NOTHING LEFT?
JRST RDLOOP ;[5000] DONE
RDRB1: ;[5000] LABEL ADDED
PUSHJ P,RDLDB ;[5000] GET THE RUBBED OUT CHARACTER
JRST RDEMP ;[5000] NONE THERE
PUSHJ P,TCCHR ; ECHO THE RUBBED OUT CHAR
RDRB2: PUSHJ P,RDDLDB ;[5000] RUB IT OUT
JRST RDEMP1 ;[5000] NOTHING THERE
JRST RDLOOP ; GO BACK FOR MORE INPUT
; RDCNU - PROCESS ^U (KILL CURRENT LINE OF COMMAND BUFFER)
RDCNU: MOVE X,ETVAL ;[5000] SEE IF DPY
TRNE X,ET$DPY ;[5000]
JRST [PUSHJ P,CLRLIN ;[5000] wipe the whole line out
JRST RDCNU1] ;[5000]
;[5000] XXX INSTEAD OF ^U
; PUSHJ P,TCCHR ; ECHO THE ^U
MOVEI N,[ASCIZ / XXX/] ;[5000]
PUSHJ P,TXSTR ;[5000]
PUSHJ P,TCRLF ; GO TO A NEW LINE
RDCNU1: ;[5000] LABEL ADDED
PUSHJ P,RDFLF ; FIND THE PREVIOUS LINEFEED CHAR
JRST RDEMP1 ; NOTHING LEFT
JRST RDLOOP ; FOUND LF. GO BACK FOR SOME MORE INPUT
; RDBEL - PROCESS ^G
RDBEL:
SKPECHO (OFF) ;[25000] Check echoing
PUSHJ P,TCCHR ; ECHO "^G"
PUSHJ P,GETCH ; PICK UP CHAR THAT FOLLOWS THE ^G
CAIN C,.CHSPC ; IS CHAR A SPACE?
JRST RDRTYP ; YES, RETYPE CURRENT LINE
CAIN C,.CHBEL ; IS CHAR ANOTHER ^G?
JRST RDKILL ; YES, KILL ENTIRE COMMAND
CAIN C,"*" ; IS IT A * ??
JRST [MOVE T4,[POINT 7,T$DATA(T5)]
MOVE T1,@CURCMD ;RETYPE ENTIRE COMMAND BUFFER
PUSHJ P,TCRLF ;NEW LINE
PUSHJ P,TSTAR ;[5000] TYPE A STAR TO START
JUMPE T1,RDRTY2 ;[10000] go away if buffer empty
SETZM @CURCMD ;ZERO LENGTH (IT WILL BE RESTORED)
JRST RDRTY1]
; ^G IS JUST ANOTHER TEXT CHAR. STORE IT IN COMMAND BUFFER
MOVEI T1,(C) ; STORE THE CHAR THAT FOLLOWS THE ^G
MOVEI C,.CHBEL ; FETCH A ^G
PUSHJ P,RDIDPB ; STORE THE ^G IN COMMAND BUFFER
MOVEI C,(T1) ; FETCH THE CHAR THAT FOLLOWS THE ^G
JRST RDLP0 ; AND SEE IF IT HAS SOME SPECIAL MEANING
; RDRTYP - ^G<SP> - RETYPE CURRENT LINE FROM COMMAND BUFFER
RDRTYP: MOVE T1,@CURCMD ; FETCH CURRENT CHAR COUNT FOR COMMAND BUFFER
MOVE X,ETVAL ;[5000] SEE IF DPY
TRNE X,ET$DPY ;[5000]
JRST [PUSHJ P,CLRLIN ;[12000] Clear the whole line
JRST .+2]
PUSHJ P,TCRLF ; GO TO A NEW LINE
PUSHJ P,RDFLF ; FIND THE PREVIOUS LINE FEED
PUSHJ P,TSTAR ;[5000] TYPE A STAR
SUB T1,@CURCMD ; MAKE A LOOP COUNT FOR RETYPING LINE
JUMPE T1,RDRTY2 ; DONE IF NOTHING TO RETYPE
RDRTY1: PUSHJ P,RDILDB ; FETCH NEXT CHAR ON LINE
PUSHJ P,TPCHR ; AND TYPE IT [5000] PRETTILY
SOJG T1,RDRTY1 ; LOOP FOR ALL CHARS ON LINE
RDRTY2: JRST RDLOOP ; DONE. GO BACK FOR SOME MORE INPUT
; TSTAR - TYPE A PROMPT
TSTAR: MOVEI N,PROMPT ;[5000] ROUTINE TO TYPE A STAR
PUSHJ P,T0XSTR ;[5000]
MOVE N,PROMSZ ;[14000] # of char positions used by prompt
SOJA N,UPDPRC ;[14000] Update cursor position & return
; RDKILL - ^G^G - KILL ENTIRE COMMAND BUFFER
RDKILL:
PUSHJ P,TCCHR ; ECHO THE SECOND ^G
RDEMP: PUSHJ P,TCRLF ; GO TO A NEW LINE
RDEMP1: MOVE X,CURCMD ; FETCH ADR OF BUFFER
HRRZS X,T$1REF(X) ; AND UNBIND FROM CURCMD
SETZM CURCMD ; UNBIND CURCMD FROM BUFFER
MOVE N,CMDBID ;[30000] Get back Buffer ID
POPJ P, ;[12000] nonskip return (don't execute)
; RDCDEL - SEE IF END OF COMMAND STRING
RDCDEL: SKIPN CDELIM+1 ;[12000] Don't check if only 1 char delimiter
JRST RDFIN ;[12000] it was
PUSHJ P,GETCH ; FETCH NEXT INPUT CHAR
CAME C,CDELIM+1 ;[12000] Other char of delimiter?
JRST RDLP0 ; NO, SEE IF IT HAS ANY SPECIAL MEANING
CAMN C,DELIM ;[12000] Store if also text delim (FS$$)
PUSHJ P,RDIDPB ; YES, STORE IT IN BUFFER
JRST RDFIN ; AND WE'RE DONE READING COMMAND STRING
; RDCNR - ^R - QUOTE THE NEXT CHAR
RDCNR: PUSHJ P,GETCH ; FETCH NEXT INPUT CHAR
CAIE C,.CHDEL ; IS IT A RUBOUT?
CAIN C,.CHCNU ; OR A ^U?
JRST RDLP0 ; YES, CAN'T QUOTE RUBOUT OR ^U
JRST RDLP1 ; NO, STORE THE QUOTED CHAR IN COMMAND BUFFER
SUBTTL Subroutines for Reading a Command String
; RDIDPB - IDPB CHAR INTO THE COMMAND BUFFER
RDIDPB: SOJL T3,RDIDP1 ; JUMP IF NO MORE ROOM IN BUFFER
MOVE T5,CURCMD ; FETCH BASE ADR OF COMMAND BUFFER
IDPB C,T4 ; STORE THE CHAR IN IT
AOS @CURCMD ; COUNT THE CHARS IN COMMAND BUFFER
POPJ P, ; AND RETURN TO CALLER
; EXPAND THE COMMAND BUFFER
RDIDP1: MOVEI N,C$CMDL ; HOW MUCH TO EXPAND BY
MOVEI L,CURCMD ; ADR OF THE BUFFER REFERENCE
PUSHJ P,EXPAND ; EXPAND THE COMMAND BUFFER
MOVEI T3,C$CMDL*5 ; CAN PUT THIS MANY MORE CHARS IN BUFFER
JRST RDIDPB ; CONTINUE WHERE WE LEFT OFF
; RDDLDB - DLDB LAST CHAR FROM COMMAND BUFFER
RDDLDB: SKIPN @CURCMD ; ANYTHING LEFT IN COMMAND BUFFER?
POPJ P, ; NO, GIVE NON-SKIP RETURN
ADD T4,[<7B5>] ; BACK UP A BYTE
JUMPG T4,.+3 ; OK
HRRI T4,-1(T4) ; MUST BACK UP A WORD
HRLI T4,(POINT 7,(T5),34) ; TO LAST BYTE IN PREVIOUS WORD
SOS @CURCMD ; DECREMENT THE CHAR COUNT
MOVE T5,CURCMD ; FETCH BASE ADR OF COMMAND BUFFER
LDB C,T4 ; AND FETCH CHAR FROM BUFFER
JRST CPOPJ1 ; GIVE SKIP RETURN TO CALLER
; RDLDB - LDB CHAR FROM COMMAND BUFFER
RDLDB: SKIPN @CURCMD ; ANYTHING IN BUFFER?
POPJ P, ; NO, GIVE NON-SKIP RETURN TO CALLER
MOVE T5,CURCMD ; YES, FETCH BASE ADR OF COMMAND BUFFER
LDB C,T4 ; FETCH CHAR FROM BUFFER
JRST CPOPJ1 ; AND GIVE SKIP RETURN TO CALLER
; RDILDB - ILDB CHAR FROM COMMAND BUFFER
RDILDB: MOVE T5,CURCMD ; FETCH BASE ADR OF COMMAND BUFFER
ILDB C,T4 ; FETCH NEXT CHAR FROM IT
AOS @CURCMD ; COUNT THE CHAR
POPJ P, ; AND RETURN TO CALLER
; RDFLF - FIND PREVIOUS LINEFEED IN COMMAND BUFFER
RDFLF: PUSHJ P,RDLDB ; FETCH CURRENT CHAR FROM COMMAND BUFFER
POPJ P, ; NONE LEFT. GIVE CALLER NON-SKIP RETURN
CAIN C,.CHLFD ; IS CHAR A LINEFEED?
JRST CPOPJ1 ; YES, GIVE CSKIP RETURN TO CALLER
PUSHJ P,RDDLDB ; NO, BACK UP A CHAR
POPJ P, ; NONE LEFT, GIVE NON-SKIP RETURN TO CALLER
JRST RDFLF ; KEEP LOOKING FOR THE PREVIOUS LF
SUBTTL Command String is Stored. Process it.
RDFIN:
MOVE X,CURCMD ; FETCH ADR OF REF TO BUFFER
HRRZS T$1REF(X) ; AND UNBIND THE REF
SETZM CURCMD ; AND ZERO "CURCMD"
MOVE N,CMDBID ; AND FETCH BUFFER ID FOR COMMAND BUFFER
JRST CPOPJ1 ;[12000] Win return (go execute)
SUBTTL Command Decoder Dispatch Table
;[13000] Changed so that high segment origin can be raised above 400000
; Note that it still cannot be lowered below 400000
DEFINE DSP(D1,C1,D2,C2)<EXP <C1+D1>,<C2+D2>>
D$JR== 1B1 ; SIMPLE JRST DISPATCH
D$EJ== 0 ; EVALUATE PRECEDING ARG AND THEN JRST
DSPTBL: DSP (D$JR,CDBPT,D$JR,CDCNA) ; ^@ ^A
DSP (D$EJ,CDCNB,D$JR,CDCNC) ; ^B ^C
DSP (D$EJ,CDCND,D$JR,CDCNE) ; ^D ^E
DSP (D$EJ,CDCNF,D$EJ,CDCNG) ; ^F ^G
DSP (D$JR,CDCNH,D$EJ,CDTAB) ; ^H TAB
DSP (D$JR,CDCCLR,D$JR,CDCCLR);LF VT [5000] CLEAR FLAGS
DSP (D$JR,CDCNL,D$JR,CDCIGN); FF CR [5000] ON <CR><LF><VT><ESC>
DSP (D$JR,CDCNN,D$JR,CDOCT) ; ^N ^O
DSP (D$EJ,CDCNP,D$EJ,CDCNQ) ; ^P ^Q
DSP (D$JR,CDERR,D$JR,CDCNS) ; ^R ^S
DSP (D$EJ,CDCNT,D$EJ,CDCNU) ; ^T ^U
DSP (D$EJ,CDCNV,D$EJ,CDCNW) ; ^V ^W
DSP (D$EJ,CDCNX,D$EJ,CDCNY) ; ^X ^Y
DSP (D$JR,CDCNZ,D$JR,CDALT) ; ^Z ^[
DSP (D$EJ,CDCBS,D$JR,CDERR) ; ^\ ^]
DSP (D$JR,CDCUA,D$EJ,CDCBA) ; ^^ ^_
DSP (D$JR,CDCIGN,D$JR,CDEXC); SPACE ! !Space no longer does +
DSP (D$EJ,CDQUO,D$EJ,CDOR) ; " #
DSP (D$JR,CDCCLR,D$EJ,CDPCT); $ %
DSP (D$EJ,CDAND,D$JR,CDAPO) ; & '
DSP (D$JR,CDLPA,D$EJ,CDRPA) ; ( )
DSP (D$EJ,CDMUL,D$EJ,CDADD) ; * +
DSP (D$EJ,CDCOM,D$EJ,CDSUB) ; , -
DSP (D$JR,CDPT,D$EJ,CDDIV) ; . /
DSP (D$JR,CDDIG,D$JR,CDDIG) ; 0 1
DSP (D$JR,CDDIG,D$JR,CDDIG) ; 2 3
DSP (D$JR,CDDIG,D$JR,CDDIG) ; 4 5
DSP (D$JR,CDDIG,D$JR,CDDIG) ; 6 7
DSP (D$JR,CDDIG,D$JR,CDDIG) ; 8 9
DSP (D$JR,CDCOL,D$EJ,CDSEM) ; : ;
DSP (D$EJ,CDLAB,D$EJ,CDEQU) ; < =
DSP (D$JR,CDRAB,D$JR,CDQST) ; > ?
DSP (D$JR,CDATS,D$EJ,CDA) ; @ A
DSP (D$JR,CDB,D$EJ,CDC0) ; B C
DSP (D$EJ,CDD,D$EJ,CDE) ; D E
DSP (D$EJ,CDF,D$JR,CDG) ; F G
DSP (D$JR,CDH,D$EJ,CDI) ; H I
DSP (D$EJ,CDJ,D$EJ,CDK) ; J K
DSP (D$EJ,CDL,D$EJ,CDM) ; L M
DSP (D$EJ,CDN,D$JR,CDO) ; N O
DSP (D$EJ,CDP,D$EJ,CDQ) ; P Q
DSP (D$EJ,CDR,D$EJ,CDS) ; R S
DSP (D$EJ,CDT,D$EJ,CDU) ; T U
DSP (D$EJ,CDV,D$EJ,CDW) ; V W
DSP (D$EJ,CDX,D$EJ,CDY) ; X Y
DSP (D$JR,CDZ,D$JR,CDLSB) ; Z [
DSP (D$EJ,CDBKSL,D$JR,CDRSB) ; \ ]
DSP (D$JR,CDUAR,D$EJ,CDBAR) ; ^ _
DSP (D$JR,CDERR,D$JR,CDERR) ; ` {
DSP (D$JR,CDVBAR,D$JR,CDERR) ; | }
DSP (D$JR,CDNOT,D$JR,CDERR) ; ~
CDERR: ERROR (ILL) ; ILLEGAL COMMAND
; PDL FLAGS
P$BEG== 0 ; BEGINNING OF COMMAND STRING
P$PAR== 1 ; LEFT PARENTHESIS
P$ITR== 2 ; LEFT ANGLE BRACKET
P$CON== 3 ; " FOR CONDITIONAL
SUBTTL COMPIL - Command Decoder and Compiler
; CALL: MOVEI L,COMMAND.BUFFER
; PUSHJ P,COMPIL
; (RETURN)
;
; GENERATES CODE AT THE END OF THE COMMAND BUFFER
;
; T4 HOLDS RELATIVE ADDRESS OF LAST CALL TO $$CTM
;
; T5 HOLDS INSTRUCTION TO PERFORM ON TWO ARGUMENTS
;
; USEAS ACS X,T1-T5
COMPIL: MOVEM L,CMDBUF ; SAVE ADR OF REF TO COMMAND BUFFER
; SETUP CHAR COUNT AND BYTE POINTER FOR COMMAND BUFFER
HRRZ X,@(L) ; FETCH CHAR COUNT
MOVEM X,CMDCNT ; AND STORE FOR CMDGCH ROUTINE
MOVE X,[POINT 7,T$DATA(R)] ; FETCH BP
MOVEM X,CMDBP ; AND STORE FOT 'CMDGCH' ROUTINE
; SETUP FOR GENERATING CODE AT END OF COMMAND BUFFER
MOVEI N,C$CODL ; INITIAL SIZE OF CODE SPACE
PUSHJ P,EXPAND ; ADD TO EXISTING SIZE OF COMMAND BUFFER
HRRZ T1,@(L) ; FETCH CHAR COUNT FOR BUFFER
IDIVI T1,5 ; CONVERT TO WORDS
MOVEI CP,T$DATA(T1) ; CP HAS RELATIVE ADR OF WHERE CODE
; WILL START
MOVE N,[<C$CODL,,CP>] ; ADD CURCMD TO THE LIST OF OVERFLOW
PUSHJ P,ADDPDL ; . . .
HRLI CP,-C$CODL+1 ; MAKE CP INTO A PDL POINTER
MOVE T1,(L) ; FETCH ADR OF BUFFER
MOVEI X,CP ; FETCH ADR OF "CP"
MOVEM X,T$ACRF(T1) ; AND BIND "CP" TO BUFFER
ADD CP,T1 ; FIX UP AC CP
; INITIALIZE TAG AND TAG REFERENCE PDLS
STSTK (TAG,C$LPDL,TAGPDL) ; SETUP TAG PDL
STSTK (REF,C$RPDL,REFPDL) ; SETUP TAG REF PDL
PUSH REF,[<0>] ; PUSH TWO ZEROS ON TAG REF PDL
PUSH REF,[<0>] ; . . .
; INITIALIZE PDL FLAG FOR BEGINNING OF COMMAND STRING
PUSH P,[<P$BEG>] ; FLAG BEGINNING OF PDL
; INITIALIZE THE INSTRUCTION IN T5
MOVEI T5,VALUE ; SETUP THE Y FIELD OF INST.
; GEN CODE TO CLEAR THE ":" COMMAND FLAG and [12000] all arg flags
PUSH CP,[TXZ F,F$$RG] ;[12000] Clear all flags at run time
; KLUDGE FOR START OF TRACE MODE
MOVEI T4,T4 ; SO THAT 'GENCT1' WILL BE A NO-OP
SUB T4,@CMDBUF ;[343] (IE: WILL NOT GEN CODE)
; CHECK FOR MACRO CALL, OTHERWISE CLEAR ARGUMENT FLAGS
SKIPN MACFLG ;[344] A MACRO COMPILATION?
JRST CDCRET+2 ;[344] NO, CLEAR FLAGS AND START CD
SETZM MACFLG ;[344] CLEAR THE FLAG FOR LATER
JRST CDCRT1 ;[344] AND CONTINUE CD WITH FLAGS
; HERE FOLLOWS THE MAIN LOOP OF THE COMMAND DECODER AND COMPILER
CDCLF:
CDCCLR: TXZ F,F$COL!F$2CO ;[23000] Clear : and :: flag
PUSH CP,[TXZ F,F$COL!F$2CO] ;[12000] at run time too
CDCRET: TXZE F,F$COL!F$2CO ; A ":" SEEN SINCE LAST COMMAND?
JRST CDCVL1 ; YES
TXZ F,F$$RG ; CLEAR ARG FLAGS
CDCRT1: HRLI T5,(MOVE ARG,) ; SET INST. TO [MOVE ARG,VALUE]
CDCBOP:; TXNN F,F$1RG ; AN ARG SEEN?
; PUSH CP,[SETZ ARG,] ; NO, GEN CODE TO CLEAR ARG
CDCIGN: PUSHJ P,GENCT1 ; TRACE MODE WILL DUMP CMDS TO THIS POINT
PUSHJ P,CMDGCH ; FETCH NEXT COMMAND CHAR
JRST CDCFN1 ; END OF COMMAND STRING
PUSHJ P,GENCTM ; NEXT TRACE DUMP WILL START HERE
; UPCASE CHAR
PUSHJ P,UPCASE ; UPCASE THE CHAR
; FETCH THE COMMAND DISPATCH ADDRESS
CDCCC: MOVEI T1,(C) ; FETCH COPY OF COMMAND CHAR
CAILE T1,"Z"+40 ; In high non-alpha range?
MOVEI T1,-32(T1) ;[12000] Starts after <140>
; ROT T1,-1 ; DIVIDE IT BY 2
MOVE T2,DSPTBL(T1) ; FETCH TWO POSSIBLE DISPATCH ADRS
; JUMPL T1,.+2 ; RH OF T2 HAS RIGHT DSPADR
; HLRZ T2,T2 ; LH OF T2 HAS RIGHT DSPADR
; SEE WHAT KIND OF DISPATCH IT IT
TXNE T2,D$JR ; NON-SIMPLE JRST?
JRST (T2) ; NO, DO A SIMPLE JRST DISPATCH
; MUST "EVAL" PRECEDING ARG BEFORE DISPATCHING
TXNN F,F$1RG ; AN ARG TO BE EVAL'D?
JRST CDCC1 ; [12000] no, save oper till we get one
PUSH CP,T5 ; NO, GEN CODE FOR THE EVALUATION OF ARG
HRLI T5,(MOVE ARG,) ; [12000] remove pending operation, if any
;[13000] Now JRST to the routine
CDCC1: JRST (T2) ; DISPATCH TO SPECIFIC CMD DECODER
CDCPOO: TXZN F,F$1RG ;[12000] Clear argument flag
PUSH CP,[SETZ ARG,] ;[12000] Clear arg if there wasn't one
JRST CDCIGN ;[12000] But leave value alone
; HERE AFTER A ":" COMMAND HAS BEEN SEEN
CDCVL1:
; SKIPA X,.+1 ; FETCH CODE TO CLEAR ":" COMMAND FLAG
; TXZ F,F$COL ; (THIS WAY BECAUSE OF MACRO BUG)
; PUSH CP,X ; GEN INTO CODE
PUSH CP,[TXZ F,F$COL]; FETCH CODE TO CLEAR ":" FLAG
; JRST CDCVAL ; DON'T FORGET: COMMAND RETURNS A VALUE
; HERE WHEN A COMMAND RETURNS A VALUE
CDCVAL: TXO F,F$1RG ; FLAG THAT ARG SEEN
JRST CDCIGN ; AND CONTINUE SCAN
; END OF COMMAND STRING. GENERATE A "POPJ P,"
CDCFIN: PUSHJ P,GENCT1 ; FINISH LAST TRACE DUMP CALL
CDCFN1: TXZ F,F$REE ;[353] CLEAR "REENTER" FLAG
POP P,X ; CLEAR "BEGINNING OF PDL" FLAG
PUSH CP,[POPJ P,] ; GEN CALL TO "RETURN" ROUTINE
JUMPE X,CDCFN2 ; NORMAL, NOW FIXUP TAG REFERENCES
SUBI X,2 ; MANIPULATE PDL FLAGS
JUMPL X,[ERROR (MRP)] ; ** MISSING ")" **
JUMPE X,[ERROR (MRA)] ; ** MISSING RAB **
ERROR (MAP) ; ** MISSING "'" **
; PATCH ALL TAG REFERENCES NOW THAT WE KNOW WHERE ALL TAGS ARE
; MAK AOBJN POINTER TO TAG PDL
CDCFN2: MOVE T5,TAGPDL ; FETCH ADR OF TAG PDL
SUBI T5,(TAG) ; COMPUTE LENGTH OF TAG PDL
MOVSI T5,(T5) ; FORM AOBJN POINTER
HRR T5,TAGPDL ; . . .
; POP TAG REFERENCES ONE AT A TIME AND PATCH THE TAG ADDRESS
CDCFN3: POP REF,N ; POP LAST TAG REF LENGTH
POP REF,M ; POP LAST TAG REF CHAR ADDRESS
JUMPE M,CDCFN8 ; DONE. RELEASE TAG AND REF
HLRZ T1,M ; FETCH CHAR ADDRESS OF TAG REF
SOJ T1, ; 'CAUSE BP WILL BE INCREMENTED FIRST
PUSHJ P,CTOBP ; AND CONVERT TO A BYTE POINTER
ADD T1,@CMDBUF ; MAKE BP ABSOLUTE
MOVE T4,T1 ; AND SAVE BP FOR LATER
; FIND A TAG WITH SAME LENGTH AS TAG REFERENCE
MOVE T3,T5 ; FETCH AOBJN LOOP COUNTER
JUMPG T3,CDCFNE ; IF NO TAGS, ** TAG NOT FOUND **
CDCFN4: MOVE X,1(T3) ; FETCH LENGTH OF NEXT TAG
CAIN X,(N) ; SAME LENGTH AS REFERENCE?
JRST CDCFN6 ; YES, NOW CHECK FOR TAG MATCH
CDCFN5: AOBJN T3,CDCFN4 ; NO, TRY THE NEXT TAG
CDCFNE: ERROR (TAG) ; ** REFERENCE TO UNDEFINED TAG **
; GOT A TAG WITH SAME LENGTH. CHACK IF TEXT MATCHES
CDCFN6: HLRZ T1,(T3) ; FETCH CHAR ADR OF TAG
SOJ T1, ; 'CAUSE BP WILL BE INCREMENTED FIRST
PUSHJ P,CTOBP ; AND CONVERT IT TO A BP
ADD T1,@CMDBUF ; MAKE BP ABSOLUTE
MOVE T2,T4 ; COPY BP FOR REFERENCE
MOVEI 15,(N) ; COPY REFERENCE LENGTH FOR LOOP COUNT
JUMPE 15,CDCFN9 ; IF LEN=0, THEN MATCH SUCCEEDS
CDCFN7: ILDB X,T2 ; FETCH REF CHAR
ILDB C,T1 ; FETCH TAG CHAR
CAIE X,(C) ; STILL MATCH?
JRST CDCFN5 ; NO, TRY NEXT TAG
SOJG 15,CDCFN7 ; YES, LOOP FOR ALL CHARS OF TAG
; FOUND MATCH. PATCH UP THE REFERENCE
CDCFN9: ADD M,@CMDBUF ; COMPUTE ABSOLUTE ADR OF "JRST"
MOVE X,(T3) ; FETCH RELATIVE ADR OF TAG
HRRM X,(M) ; PATCH THE "JRST TAG(R)"
JRST CDCFN3 ; AND PROCESS THE NEXT TAG REFERENCE
; RELEASE TAG,REF, AND CP AS PDLS
CDCFN8: MOVEI N,TAG ; RELEASE TAG
PUSHJ P,DELPDL ; . . .
MOVEI L,TAGPDL ; DELETE THE TAGPDL
PUSHJ P,RELM ; . . .
MOVEI N,REF ; RELEASE REF
PUSHJ P,DELPDL ; . . .
MOVEI L,REFPDL ; RELEASE THE TAG REFERENCE PDL
PUSHJ P,RELM ; . . .
MOVEI N,CP ; RELEASE CP
PJRST DELPDL ; AND RETURN TO CALLER
SUBTTL Command Decoding and Compilation Routines
; CDUAR - "^" - TRANSLATE NEXT CHAR TO A CONTROL CHAR
CDUAR: PUSHJ P,CMDGCH ; FETCH THE NEXT CHAR
ERROR (MEU) ; ** MACRO ENDING WITH ^ **
TRZ C,140 ; TRANSLATE THE CHAR TO CONTROL RANGE
JRST CDCCC ; AND PROCESS THE CONTROL CHAR
; CDALT - ALTMODE
; - SINGLE ALTMODE WILL BE IGNORED
; - TWO ALTMODES GENERATE "JSP PC,$$STOP"
CDALT: PUSHJ P,CMDGCH ; FETCH NEXT COMMAND CHAR
JRST CDCFIN ; END OF COMMAND STRING
CAIE C,.CHESC ; A SECOND ALTMODE?
JRST [PUSHJ P,CMDBCH ; NO, BACKUP OVER THE CHAR
JRST CDCRET] ;[7000] CHANGED BACK. AND CONTINUE CD
PUSH CP,[JSP PC,$$STOP] ; YES, GEN CALL TO "STOP"
JRST CDCCLR ; AND CONTINUE CD
; CDBPT - ^@ - Gen BPT warning for debugging, etc.
;
; GEN: WARN(BPT)
CDBPT: MOVE X,EDVAL ;[12000] Don't do it if ED$OPT
TXNE X,ED$OPT ;[12000] is set in ED
JRST CDCIGN ;[12000]
PUSH CP,[SKIPL BRKFLG] ;[12000] Gen code to check flag
PUSH CP,[WARN(BPT)] ;[12000] gen LUUO into code
JRST CDCIGN ;[12000] don't touch args, etc.
; CDCNA - ^A - GEN COMMAND TO TYPE A STRING ENCLOSED IN ^A'S
; IE: ^ATHIS IS A MESSAGE^A
;
; GEN: JSP PC,$$MES
; <CHAR ADDRESS IN BUFFER,,CHAR COUNT>
CDCNA: PUSH CP,[JSP PC,$$MES] ; GEN CALL TO TYPE MESSAGE
MOVEI C,.CHCNA ; SCAN FOR NEXT ^A
;[21000] Check now so not off by 1
TXNE F,F$DTM ;[12000] Unless delimited text mode
PUSHJ P,CMDGCH ;[12000] It was so do it
JFCL ;[21000] He will lose later
PUSHJ P,CURCHA ; FETCH CURRENT CHAR ADDRESS IN BUFFER
MOVSI T2,(T1) ; AND SAVE FOR LATER
PUSHJ P,FNDCH ; . . .
ERROR (UCA) ; ** UNTERMINATED ^A COMMAND **
HRRI T2,(N) ; FETCH CHAR COUNT FOR MESSAGE
PUSH CP,T2 ; STORE <CHAR ADR,,CHAR COUNT> IN CODE
JRST CDCRET ; AND CONTINUE CD
; CDCNC - ^C - COMMAND TO DO A MONRT.
CDCNC: PUSH CP,[EXIT 1,] ; GEN THE MONRT.
JRST CDCRET ; AND CONTINUE CD
; CDCNE - ^E - COMMAND TO RETURN THE VALUE OF THE FORMFEED FLAG
CDCNE: PUSH CP,[JSP PC,$$CNE] ; GEN CODE TO FETCH VALUE OF FF FLAG
JRST CDCVAL ; AND CONTINUE CD
; CDCNF - ^F RETURNS CONTENTS OF CONSOLE SWITCH REGISTER
; N^F RETURNS TTY#+^O200000 OF JOB N
CDCNF: MOVE X,[JSP PC,$$TTY] ;[306] ASSUME WE WANT TTY#
TXNN F,F$1RG ;[306] WANT TTY#?
MOVE X,[SWITCH VALUE,] ;[306] NO, WANT CONSOLE SWITCHES
PUSH CP,X ;[306] GEN CODE FOR WHATEVER
JRST CDCVAL ; AND CONTINUE SCAN
; CDCNG - N,M^G=GETTAB, N^G=PEEK
CDCNG: MOVE X,[JSP PC,$$GTB] ;[302] ASSUME GETTAB
TXZN F,F$2RG ;[332] 2 ARGS FOR GETTAB?
HRRI X,$$PEK ;[302] NO, ONE ARG FOR PEEK
TXNN F,F$1RG ;[336] WANT PJOB?
MOVE X,[PJOB VALUE,] ;[336] YES, NO GETTAB/PEEK
PUSH CP,X ;[302] GEN THE CALL TO WHATEVER
JRST CDCVAL ;[302] AND CONTINUE WITH SCAN
; CDCNH - ^H - COMMAND TO RETURN TIME OF DAY IN JIFFIES
CDCNH: PUSH CP,[TIMER VALUE,] ; GEN CODE TO FETCH TIME OF DAY IN JIFFIES
JRST CDCVAL ; AND CONTINUE CD
; CDCNL - ^L - COMMAND TO TYPE A FORMFEED
CDCNL: PUSH CP,[JSP PC,$$FFD] ; GEN CODE TO TYPE A FORMFEED
JRST CDCRET
; CDESTAR - E* - TRMOPs [10000]
CDCND:
CDESTA:
TXNE F,F$2RG ;[10000] See if 2 arguments given
PUSH CP,[TXO F,F$2RG] ;[10000] tell the runtime routine
PUSH CP,[JSP PC,$$TRMO] ;[10000]
JRST CDCVAL ;[10000]
CDCNQ: PUSHJ P,ARGK ;[12000] Default arg to 1
PUSH CP,[JSP PC,$$CNQ] ;[12000] # of characters in next n lines
JRST CDCVAL ;[12000]
; CDFQ - FQ - Compare text buffer with Q-register
CDFQ: PUSH CP,[JSP PC,$$QCM] ; [10000]
PUSHJ P,MAKQNM ; [10000]
JRST CDCVAL ; [10000]
; CDCNB - ^B return the date in system-dependant format
CDCNB:
FOR TOPS10!TOPS20,<PUSH CP,[DATE VALUE,]> ;[16000] Get the date from the sys
JRST CDCVAL ;[16000] That is our value
; CDQRX - nQ - Return nth character from a Q-Register
CDQRX: PUSH CP,[JSP PC,$$QRX] ; [10000]
PUSHJ P,MAKQNM ; [10000]
JRST CDCVAL ; [10000]
; CDCNN - ^N - COMMAND TO RETURN THE VALUE OF THE END-OF-FILE FLAG
CDCNN: PUSH CP,[JSP PC,$$CNN] ; GEN CODE TO RETURN VALUE OF EOF FLAG
JRST CDCVAL ; AND CONTINUE CD
; CDCNP - ^P OR N^P - RETURN CURRENT PAGE # OR POSITION TO SPECIFIED PAGE
CDCNP: TXNE F,F$1RG ; AN ARG PRESENT?
JRST CDCNP1 ; YES, POSITION TO SPECIFIED PAGE
; ^P - RETURN THE # OF THE CURRENT PAGE
CDCNP2: PUSH CP,[MOVE VALUE,PAGCNT] ; GEN CODE TO RETURN PAGE #
JRST CDCVAL ; AND CONTINUE CD
; N^P - POSITION TO SPECIFIED PAGE
CDCNP1: PUSH CP,[JSP PC,$$CNP] ; GEN CODE TO CALL $$CNP
JRST CDCRET ; AND CONTINUE CD
;m,n^\ Execute instruction in n with m in AC VALUE
CDCBS: PUSH CP,[JSP PC,$$EXE] ; Gen call to $$EXE
JRST CDCVAL ; and continue
; CDCNS - ^S - Return -SRHLEN (length of last search)
CDCNS: PUSH CP,[MOVN VALUE,SRHLEN] ;[12000] negative length of search
JRST CDCVAL ;[12000] return value
; CDCNT - ^T - COMMAND TO RETURN VALUE OF INPUT CHAR
CDCNT: TXZE F,F$COL ;[16000] :^T (TTCALL) ?
JRST CDCNT0 ;[16000] Yes go there
TXNE F,F$1RG ;[12000] 1 argument given?
JRST [PUSH CP,[JSP PC,$$TCHR] ;[16000] Type this character
JRST CDCRET] ;[16000] Do NOT return a value
PUSH CP,[JSP PC,$$GCHR] ;[16000] Read a character from the terminal
JRST CDCVAL ;[16000] Return that as value
CDCNT0:!TXZN F,F$2RG ;[410] TWO ARGS?
PUSH CP,[SETZ SARG,] ;[410] NO, INSURE SECOND ARG 0!
PUSH CP,[JSP PC,$$TTC] ;[16000] Gen call to TTCALL routine
JRST CDCVAL ; AND CONTINUE CD
; CDCNU - N^U - USETI TO DESIRED BLOCK ON INPUT FILE
CDCNU: SKIPN EOVAL ;[12000] do USETI if EO=0 only
JRST CDCNU1 ;[12000] EO=0
;DO Q-REGISTER STORE FROM TEXT
TXNE F,F$1RG ;[12000] Argument present?
JRST [PUSH CP,[TXO F,F$1RG] ;[12000] need to know at run time
JRST .+1] ;[12000] Also don't want text
PUSH CP,[JSP PC,$$CNU] ;[12000] Gen call
PUSHJ P,MAKQNM ;[12000] get Q-register name
PUSHJ P,CDCINS ;[12000] and text argument
JRST CDCRET ;[12000] RETURN
CDCNU1: PUSHJ P,ARGK ;[333] MAKE SURE IT HAS AN ARG
PUSH CP,[JSP PC,$$USI] ;[333] GEN CALL TO $$USI
JRST CDCRET ;[333] AND CONTINUE CD
; CDCNV - N^V OR ^V - DOWNCASE ALL TEXT
CDCNV: PUSHJ P,ARGK ; MAKE SURE IT HAS AN ARG
PUSH CP,[JSP PC,$$LOW] ; GEN CALL TO $$LOW
JRST CDCRET ; AND CONTINUE CD
; CDCNW - N^W OR ^W - UPCASE ALL TEXT
CDCNW: PUSHJ P,ARGK ; MAKE SURE IT HAS AN ARG
PUSH CP,[JSP PC,$$UP] ; GEN CALL TO $$UP
JRST CDCRET ; AND CONTINUE CD
; CDCNY - ^Y OR N^Y - RETURN CURRENT PAGE # OR YANK TO SPECIFIED PAGE
CDCNY: TXNN F,F$1RG ;[327] AN ARG PRESENT?
JRST CDCNP2 ;[327] YES, TREAT AS ^P
; N^Y - YANK TO SPECIFIED PAGE
PUSH CP,[JSP PC,$$CNY] ;[327] GEN CODE TO CALL $$CNY
JRST CDCRET ;[327] AND CONTINUE CD
; CDCNX - N^X OR ^X - SET OR RETURN EXACT SEARCH MODE FLAG
CDCNX: MOVE X,[JSP PC,$$CX] ; FETCH CALL TO $$CX
TXNE F,F$1RG ; IS IT A SET CMD?
HRRI X,$$CXS ; YES, FETCH ADR OF "SET" ROUTINE
PUSH CP,X ; GEN CALL TO WHATEVER
TXNE F,F$1RG ; WAS IT A "SET" CMD?
JRST CDCRET ; YES, CONTINUE CD
JRST CDCVAL ; NO, IT RETURNS A VALUE
; CDCNZ - ^Z - CLOSE OUTPUT FILE AND RETURN TO MONITOR COMMAND LEVEL
CDCNZ: PUSH CP,[JSP PC,$$CNZ] ; GEN CODE TO CALL $$Z
JRST CDCRET ; AND CONTINUE CD
; CDCUA - ^^X - VALUE OF THE ARBITRARY CHAR "X"
CDCUA: PUSHJ P,CMDGCH ; GET NEXT CHAR
ERROR (MUU) ; NONE LEFT. ** MACRO ENDING WITH ^^ **
HRLI C,(MOVEI VALUE,) ; FORM: MOVEI VALUE,"X"
PUSH CP,C ; AND GEN THE INST. INTO CODE
JRST CDCVAL ; AND CONTINUE CD
; CDQUO - " - BEGINNING OF A CONDITIONAL
;
; FORMAT OF A CONDITIONAL IS:
;
; N"X...COMMANDS...'
;
; WHERE N IS A NUMERIC ARGUMENT, X IS A LETTER, AND
; ...COMMANDS... IS ANY SEQUENCE OF COMMANDS (INCLUDING
; MORE CONDITIONALS. THE COMMANDS ARE EXECUTED IF N.X.0 IS TRUE.
;
; X IS:
;
; L or < EXECUTE COMMANDS IF N.LT.0
; G or > EXECUTE COMMANDS IF N.GT.0
; N EXECUTE COMMANDS IF N.NE.0
; E EXECUTE COMMANDS IF N.EQ.0
; F EXECUTE COMMANDS IF N.EQ.0 (FALSE OF FAILURE)
; U EXECUTE COMMANDS IF N.EQ.0 (UNSUCCESSFUL)
; T EXECUTE COMMANDS IF N.LT.0 (TRUE)
; S EXECUTE COMMANDS IF N.LT.0 (SUCCESS)
; C EXECUTE COMMANDS IF N IS VALUE OF AN ASCII LETTER,
; DIGIT, ".", "%", OR "$".
; A EXECUTE COMMANDS IF N IS VALUE OF AN ASCII LETTER
; D EXECUTE COMMANDS IF N IS VALUE OF AN ASCII DIGIT
; V EXECUTE COMMANDS IF N IS VALUE OF AN ASCII LOWER CASE LETTER
; W EXECUTE COMMANDS IF N IS VALUE OF AN ASCII UPPER CASE LETTER
; R [14000] EXECUTE COMMANDS IF N IS VALUE OF AN ASCII LETTER OR DIGIT
CDQUO: TXNN F,F$1RG ; AN ARG PRESENT?
ERROR (NAQ) ; NO, ** NO ARG BEFORE " **
PUSHJ P,CMDGCH ; FETCH NEXT COMMAND CHAR ("X")
ERROR (MEQ) ; NONE LEFT. ** MACRO ENDING WITH " **
PUSHJ P,UPCASE ; UPCASE THE CHAR
MOVE T1,[IOWD CONLTH,CONTBL] ; AOBJN PTR TO "X" TABLE
PUSHJ P,DISPAT ; DISPATCH TO PROPER CONDITIONAL
ERROR (IQC) ; ** ILLEGAL " COMMAND **
DEFINE QC(CMDS)<IRPC CMDS,<<"CMDS",,CDQ'CMDS>>>
CONTBL: QC (GLNEFUTSCADVWR)
<.CHLAB,,CDQL> ;[14000] Left angle-bracket for less than 0
<.CHRAB,,CDQG> ;[14000] Right ... greater than 0
<"=",,CDQE> ;"= for "E
CONLTH==.-CONTBL
; CDQG - N"G...' - EXECUTE COMMANDS IF N.GT.0
CDQG: PUSH CP,[JUMPLE ARG,0(R)] ; GEN CODE TO SKIP COMMANDS
JRST CDQCJ ; FINISH CONDITIONAL
; CDQT - N"T...' - EXECUTE COMMANDS IF N IS TRUE
CDQT:
; CDQS - N"S...' - EXECUTE COMMANDS IF N IS SUCCESSFUL
CDQS:
; CDQL - N"L...' - EXECUTE COMMANDS IF N.LT.0
CDQL: PUSH CP,[JUMPGE ARG,0(R)] ; GEN CODE TO SKIP COMMANDS
JRST CDQCJ ; FINISH CONDITIONAL
; CDQN - N"N...' - EXECUTE COMMANDS IF N.NE.0
CDQN: PUSH CP,[JUMPE ARG,0(R)] ; GEN CODE TO SKIP COMMANDS
JRST CDQCJ ; FINISH THE CONDITIONAL
; CDQF - N"F...' - EXECUTE COMMANDS IF N IS FALSE
CDQF:
; CDQU - N"U...' - EXECUTE COMMANDS IF N IS UNSUCCESSFUL
CDQU:
; CDQE - N"E...' - EXECUTE COMMANDS IF N.EQ.0
CDQE: PUSH CP,[JUMPN ARG,0(R)] ; GEN CODE TO SKIP COMMANDS
JRST CDQCJ ; FINISH THE CONDITIONAL
; CDQC - N"C...' - EXECUTE COMMANDS IF N IS A SYMBOL CONSTITUENT
CDQC: PUSH CP,[JSP PC,$$CKC] ; GEN CALL TO SEE IF A SYMBOL CONSTITUENT
JRST CDQJA ; FINISH CONDITIONAL
; CDQA - N"A...' - EXECUTE COMMANDS IF N IS A LETTER
CDQA: PUSH CP,[JSP PC,$$CKA] ; GEN CALL TO SEE IF A LETTER
JRST CDQJA ; FINISH CONDITIONAL
CDQR: PUSH CP,[JSP PC,$$CKR] ;[14000] Gen call to see if alphanumeric
JRST CDQJA ;[14000]
; CDQD - N"D...' - EXECUTE COMMANDS IF N IS A DIGIT
CDQD: PUSH CP,[JSP PC,$$CKD] ; GEN CALL TO SEE IF A DIGIT
JRST CDQJA ; FINISH CONDITIONAL
; CDQV - N"V...' - EXECUTE COMMANDS IF N IS A LOWER CASE LETTER
CDQV: PUSH CP,[JSP PC,$$CKV] ; GEN CALL TO SEE IF A LC LETTER
JRST CDQJA ; FINISH CONDITIONAL
; CDQW - N"W...' - EXECUTE COMMANDS IF N IS AN UPPER CASE LETTER
CDQW: PUSH CP,[JSP PC,$$CKW] ; GEN CALL TO SEE IF A UC LETTER
CDQJA: PUSH CP,[JRST 0(R)] ; GEN CODE TO SKIP COMMANDS
CDQCJ: MOVEI X,(R) ; REMEMBER WHERE CONDITIONAL BEGINS
SUB X,@CMDBUF ; . . .
PUSH P,X ; . . .
PUSH P,[<P$CON>] ; FLAG THAT A CONDITIONAL IS ON PDL
JRST CDCRET ; AND CONTINUE CD
; CDAPO - ' - FINISH WAHT " BEGAN (IE: END OF A CONDITIONAL)
CDAPO: POP P,X ; POP THE PDL FLAG
PUSHJ P,CHKCON ;[12000] See that we're in a conditional
POP P,X ; POP THE ADR OF START OF CONDITIONAL
ADD X,@CMDBUF ; MAKE IT AN ABSOLUTE ADR
MOVEI T1,1(CP) ; FETCH ADR OF END OF CONDITIONAL
SUB T1,@CMDBUF ; AND MAKE IT RELATIVE
HRRM T1,(X) ; FINISH THE SKIP OVER COMMANDS
; FOR WHEN CONDITIONAL COMMANDS
; ARE NOT EXECUTED
JRST CDCRET ; AND CONTINUE CD
;[12000] CDVBAR - | - "ELSE" construct
CDVBAR: MOVE X,(P) ;[12000] Check nexting of things
PUSHJ P,CHKCON ;[12000]
MOVE X,-1(P) ;[12000] Get addr of start of conditional
PUSH CP,[JRST 0(R)] ;[12000] Jump past "ELSE" clause
MOVEI T1,1(CP) ;[12000] "ELSE" Will jump past that jump
SUB T1,@CMDBUF ;[12000] relative to buffer
ADD X,@CMDBUF ;[12000] Make X absolute
HRRM T1,(X) ;[12000] The jump instruction is now complete
SOJ T1, ;[12000] Put pointer to that jump on stack
MOVEM T1,-1(P) ;[12000] will fix up on next "'" or "|"
JRST CDCRET ;[12000] Continue
;[12000] CHKCON -- Check that we're in a conditional
;
CHKCON: CAIG X,P$CON ;[12000] Out of range?
JUMPG X,CDAPO1(X) ;[12000] Dispatch unless negative
;[12000] in which case, fall into CDAPO1
CDAPO1:
ERROR (MSC) ; ** MISSING START OF CONDITIONAL **
ERROR (MRP) ; ** MISSING ) **
ERROR (CON) ; ** CONFUSED USE OF CONDITIONALS **
POPJ P, ;[12000] Return
; CDQST - ? - COMMAND TO COMPLEMENT TRACE MODE FLAG
CDQST: SKIPA X,.+1 ; A MACRO BUG FORCES US TO DO THIS
TXC F,F$TRC ; INST. TO COMPLEMENT THE TRACE FLAG
PUSH CP,X ; GEN CODE TO COMPLEMENT TRACE FLAG
JRST CDCRET ; AND CONTINUE CD
; CDCOM - , - DELIMITS FIRST AND SECOND ARGUMENTS
CDCOM: TXZE F,F$1RG ; ARG ALREADY SEEN?
TXOE F,F$2RG ; AND NOT BOTH ARGS?
ERROR (ARG) ; NO. ",ARG" AND "ARG,ARG,ARG" ILLEGAL
PUSH CP,[MOVE SARG,ARG] ; GEN CODE TO SAVE SECOND ARG
JRST CDCRT1 ; AND CONTINUE CD
; CDLPA - ( - PERFORM OPERATIONS INSIDE "()" FIRST
;
; GEN: PUSH P,ARG
; <EVAL INSIDE PARENS>
; MOVE VALUE,ARG
; POP P,ARG
CDLPA: PUSH CP,[PUSH P,ARG] ; GEN CODE TO SAVE ARG
PUSH P,T5 ; SAVE CURRENT OPERATION
PUSH P,[<P$PAR>] ; FLAG THAT A "(" IS ON PDL
JRST CDCRT1 ; AND CONTINUE CD
; CDRPA - ) - FINISH WHAT CDLPA STARTED
CDRPA: POP P,X ; POP PDL FLAG
JUMPE X,CDRPA2 ; ** CONFUSED USE OF () **
SOJG X,CDRPA1 ; ** MISSING LEFT PARENTHESIS **
PUSH CP,[MOVE VALUE,ARG] ; GEN CODE TO SAVE ARG
PUSH CP,[POP P,ARG] ; GEN CODE TO RESTORE OLD ARG
POP P,T5 ; RESTORE PREVIOUS OPERATION
JRST CDCVAL ; AND CONTINUE WITH CD
CDRPA1: ERROR (PAR) ; ** CONFUSED USE OF () **
CDRPA2: ERROR (MLP) ; ** MISSING ( **
; CDEXC - !TAG! - COMMAND TO DEFINE A TAG (IE: LABEL)
CDEXC: TXZ F,F$1RG!F$2RG ;[310] THROW AWAY PREV. CMDS
MOVEI C,"!" ; SCAN FOR CLOSING "!"
TXZE F,F$DTM ;[12000] Check for delimited text mode
PUSHJ P,CMDGCH ;[12000] @!/foo/ or something like that
JFCL ;[12000] If CMDGCH fails, so will FNDCH
PUSHJ P,CURCHA ; FETCH CURRENT CHAR ADR IN BUFFER
MOVSI T1,(T1) ; . . .
HRRI T1,1(CP) ; FETCH CURRENT ADR IN CODE
SUB T1,@CMDBUF ; . . .
PUSH TAG,T1 ; STORE INFO ABOUT TAG DEFINITION
PUSHJ P,FNDCH ; . . .
ERROR (UTG) ; ** UNTERMINATED TAG **
PUSH TAG,N ; STORE LENGTH OF TAG
JRST CDCRET ; AND CONTINUE CD
; CDO - OTAG$ - COMMAND TO BRANCH TO A TAG
CDO: MOVE C,DELIM ;[12000] Scan till delimiter found
TXZE F,F$DTM ;[12000] Special delimiter?
PUSHJ P,CMDGCH ;[12000] Yes
JFCL ;[12000] Will get an error anyway
PUSH CP,[JRST 0(R)] ; GEN CODE TO BRANCH TO TAG
; NOTE THAT Y FIELD MUST BE FILLED
; IN WHEN THE TAG ADR IS KNOWN
PUSHJ P,CURCHA ; FETCH CURRENT CHAR ADR IN BUFFER
MOVSI T1,(T1) ; . . .
HRRI T1,(CP) ; FETCH CURRENT ADR ON CODE
SUB T1,@CMDBUF ; . . .
PUSH REF,T1 ; AND STORE INFO ABOUT THE TAG REFERENCE
PUSHJ P,FNDCH ; . . .
ERROR (MEO) ; ** MACRO ENDING WITH O COMMAND **
PUSH REF,N ; STORE LENGTH OF TAG REFERENCE
JRST CDALT ; AND CONTINUE WITH SCAN
; CDLAB - LAB - AN ITERATION
;
; GEN: PUSH P,ARG
; MOVEI X,%FIN
; PUSH P,X
; %ST: SOSGE -1(P) ; OR "SOSA -2(P)" IF NO ARG
; JSP PC,$$SEM
; ...
; JRST %ST(R)
;%FIN: POP P,X
CDLAB: PUSH CP,[PUSH P,ARG] ; GEN CODE TO STORE REPEAT COUNT
PUSH CP,[MOVEI X,0] ; GEN CODE TO STORE %FIN ADR
PUSH CP,[PUSH P,X] ; . . .
MOVE X,[SOSGE -1(P)] ; FETCH THE CONDITIONAL INST.
TXNN F,F$1RG ; AN ARG PRESENT?
HRLI X,(SOSA 0(P)) ; NO, WILL LOOP FOREVER
PUSH CP,X ; GEN THE CONDITIONAL INST.
PUSH CP,[JSP PC,$$SEM] ; GEN THE "JUMP OUT OF LOOP"
; FOR WHEN REPEAT COUNT RUNS OUT
MOVEI X,-3(CP) ; SAVE THE ADR OF THE "MOVEI"
SUB X,@CMDBUF ; . . .
PUSH P,X ; SO THAT CDRAB CAN PATCH IT
PUSH P,[<P$ITR>] ; SET ITERATION PDL FLAG
JRST CDCRET ; AND CONTINUE CD
; CDRAB - RAB - FINISH WHAT CDLAB STARTED
CDRAB: POP P,X ; POP THE PDL FLAG
JUMPE X,[ERROR (MLA)] ; ** MISSING LAB **
SOJE X,[ERROR (MRP)] ; ** MISSING ) **
SOJG X,[ERROR (MAP)] ; ** MISSING ' **
POP P,X ; POP ADR OF "MOVEI"
MOVEI T1,2(X) ; COMPUTE ADR OF %ST(R)
HRLI T1,(JRST 0(R)) ; MAKE "JRST %ST(R)"
PUSH CP,T1 ; AND GEN IT INTO CODE
PUSH CP,[POP P,X] ; GEN CODE TO CLEAR TEMP REPEAT COUNT
MOVEI T1,(CP) ; COPY CURRENT ADR IN CODE
SUB T1,@CMDBUF ; MAKE IT RELATIVE
ADD X,@CMDBUF ; COMPUTE ABS. ADR. OF "MOVEI"
HRRM T1,(X) ; FINISH "MOVEI X,%FIN"
TXZ F,F$1RG!F$2RG ;[401] CLEAR ARGUMENTS
JRST CDCRT1 ; AND CONTINUE SCAN
; CDADD - + - GEN "ADD ARG,VALUE" FOR AN ADDITION
CDADD: HRLI T5,(ADD ARG,) ; SETUP OPCODE FOR LATER EVAL
JRST CDCPOO ; AND CONTINUE SCAN
; CDSUB - - - GEN "SUB ARG,VALUE" FOR A SUBTRACTION
CDSUB: HRLI T5,(SUB ARG,) ; SETUP OPCODE FOR LATER EVAL
JRST CDCPOO ; AND CONTINUE CD
; CDMUL - * - GEN "IMUL ARG,VALUE" FOR A MULTIPLICATION
CDMUL: HRLI T5,(IMUL ARG,) ; SETUP OPCODE FOR LATER EVAL
JRST CDCPOO ; AND CONTINUE SCAN
; CDDIV - / - GEN "IDIV ARG,VALUE" FOR A DIVISION
CDDIV: HRLI T5,(IDIV ARG,) ; SETUP OPCODE FOR LATER EVAL
JRST CDCPOO ; AND CONTINUE SCAN
; CDAND - & - GEN "AND ARG,VALUE" FOR LOGICAL "AND" OPERATION
CDAND: HRLI T5,(AND ARG,) ; SETUP OPCODE FOR LATER EVAL
JRST CDCPOO ; AND CONTINUE CD
; CDOR - # - GEN "OR ARG,VALUE" FOR LOGICAL "OR" OPERATION
CDOR: HRLI T5,(OR ARG,) ; SETUP OPCODE FOR LATER EVAL
JRST CDCPOO ; AND CONTINUE CD
; CDXOR - ^_ - GEN "XOR ARG,VALUE" FOR LOGICAL "XOR" OPERATION
CDXOR: HRLI T5,(XOR ARG,) ;[12000] SETUP OPCODE FOR LATER EVAL
JRST CDCPOO ;[12000] AND CONTINUE COMMAND
; CDNOT - ~ - GEN "SETC ARG,VALUE" FOR LOGICAL "NOT" OPERATION
CDNOT: HRLI T5,(SETCM ARG,) ;[12000] SETUP OPCODE FOR LATER EVAL
JRST CDCPOO ;[12000] AND CONTINUE
; CDCBA - ^_ - GEN "SETCAM ARG,VALUE" for logical (postfix operator) not
CDCBA: PUSH CP,[SETCAM ARG,VALUE] ;[14000] Generate it [16000] correctly
JRST CDCVAL ;[14000] return value
; CDOCT - ^O - AN OCTAL NUMBER FOLLOWS
CDOCT: SETZ N,
CDOCT1: PUSHJ P,CMDGCH ; FETCH NEXT COMMAND CHAR
JRST CDDIG5 ; NO MORE
CAIG C,"7" ; AN OCTAL DIGIT?
CAIGE C,"0" ; . . . ?
JRST CDDIG4 ; NO, END OF NUMBER
LSH N,3 ; MAKE ROOM FOR THE OCTAL DIGIT
IORI N,-"0"(C) ; AND "OR" IN THE DIGIT
JRST CDOCT1 ; AND GO BACK FOR ANOTHER DIGIT
; CDDIG - A DIGIT - A DECIMAL INTEGER FOLLOWS
CDDIG: SETZ N, ; START WITH N:=0
JRST CDDIG3 ; AND JUMP INTO THE LOOP
CDDIG2: PUSHJ P,CMDGCH ; FETCH NEXT COMMAND CHAR
JRST CDDIG5 ; NO MORE
CDDIG3: CAIG C,"9" ; IS CHAR A DIGIT?
CAIGE C,"0" ; . . . ?
JRST CDDIG4 ; NO. END OF NUMBER
IMULI N,^D10 ; YES, MAKE ROOM FOR DIGIT
ADDI N,-"0"(C) ; AND ADD IN THE DIGIT
JRST CDDIG2 ; AND GO BACK FOR ANOTHER DIGIT
CDDIG4: PUSHJ P,CMDBCH ; REPEAT THE CHAR THAT'S NOT A DIGIT
; GEN: SKIPA VALUE,.+1(R)
; <NUMBER>
; OR
; MOVEI VALUE,<NUMBER>
CDDIG5: TLNN N,-1 ; WILL NUMBER FIT IN 18. BITS?
JRST CDDIG7 ; YES, GEN A "MOVEI"
MOVEI T1,2(CP) ; NO, FETCH ABSOLUTE ".+1"
SUB T1,@CMDBUF ; MAKE RELATIVE ".+1"
HRLI T1,(SKIPA VALUE,0(R)); FORM "SKIPA VALUE,.+1(R)"
PUSH CP,T1 ; STORE "SKIPA" IN CODE
CDDIG6: PUSH CP,N ; STORE <NUMBER> IN CODE
JRST CDCVAL ; AND CONTINUE CD
CDDIG7: HRLI N,(MOVEI VALUE,) ; FORM: MOVEI VALUE,<NUMBER>
JRST CDDIG6 ; AND CONTINUE
; CDEQU - TYPE A NUMERIC QUANTITY
;
; N= (OR N==) - TYPE NUMBER IN DECIMAL (OR OCTAL) FOLLOWED BY CRLF
; N,M= (OR :N,M==) - TYPE NUMBER FOLLOWED BY CRLF IF N.LT.0,
; BY NOTHING IF N.EQ.0, OR
; BY CHAR WHOSE CODE IS N IF N.GT.0
CDEQU: TXNN F,F$1RG!F$2RG ;[305] WAS THERE AN ARG?
ERROR (NAE) ; NO. ** NO ARG BEFORE "=" **
TXNN F,F$2RG ;[305] THE TWO ARG FORM??
PUSH CP,[SETO SARG,] ;[305] NO, GEN CODE TO FORCE CRLF AFTER NUMBER
PUSHJ P,CMDGCH ; FETCH NEXT COMMAND CHAR
JRST CDEQU1 ; NONE LEFT. ASSUME "="
CAIE C,"=" ; A SECOND "="?
JRST CDEQU1 ; NO, IT'S "="
PUSH CP,[JSP PC,$$OCT] ; GEN CALL TO TYPE IN OCTAL
JRST CDCRET ; AND CONTINUE CD
CDEQU1: PUSHJ P,CMDBCH ; BACKUP OVER THE CHAR THAT'S NOT "="
PUSH CP,[JSP PC,$$DEC] ; GEN CALL TO TYPE IN DECIMAL
JRST CDCRET ; AND CONTINUE CD
; CDSEM - ; OR N; - JUMP OUT OF CURRENT ITERATION
; ; - IF LAST SEARCH FAILED
; N; - IF N.EQ.0
CDSEM: PUSHJ P,CHKITR ; CHECK IF WE'RE IN AN ITERATION
ERROR (SNI) ; NO, ** ; NOT IN ITERATION **
CDSEM2: TXNE F,F$1RG ; AN ARG PRESENT?
JRST CDSEM3 ; YES
PUSH CP,[JSP PC,$$SEMF] ; NO, EQN CODE IF POP OUT OF
; CUR. ITERATION IF LAST SEARCH FAILED
JRST CDCRET ; CONTINUE CD
CDSEM3: PUSH CP,[JSP PC,$$SEMZ] ; GEN CODE TO JUMP OUT OF
; CUR. ITERATION IF ARG.GE.0
JRST CDCRET ; CONTINUE CD
; CDCOL - : - NEXT COMMAND WILL RETURN 0 IF IT FAILS, -1 IF IT SUCCEEDS
;[14000] Sets flag for :: if : flag is already set
CDCOL: MOVE X,[TXO F,F$COL] ;[14000] Do this unless set already
TXOE F,F$COL ;[14000] [310] FLAG THAT ":" SEEN
HRRI X,(F$COL!F$2CO) ;[14000] ::, so set that instead
PUSH CP,X ;[14000] set at run time
TXOA F,(X) ;[14000] and now, and skip
;[310] INTO THE COMMON CODE
; CDATS - @ - NEXT TEXT STRING IS IN DELIMITED TEXT MODE
; (EG: @I/TEXT/$ , @FS/STRING/NEWSTR/$)
CDATS: TXO F,F$DTM ; FLAG THAT WE ARE IN DELIMITED TEXT MODE
SKIPN EOVAL ;[3000] [13000] Throw away only if EO=0
TXZ F,F$1RG!F$2RG ;[310] THROW AWAY PREV. ARGS
JRST CDCRT1 ; AND CONTINUE CD
; CDA - A OR NA - APPEND TO BUFFER OR RETURN VALUE OF CHAR
; TO RIGHT OF TEXT POINTER
CDA: TXNE F,F$1RG ; APPEND?
JRST CDNA ; NO, RETURN VALUE OF NEXT CHAR IN BUFFER
; A - APPEND TO TEXT BUFFER
PUSH CP,[JSP PC,$$A] ; GEN CALL TO $$A
JRST CDCRET ; AND CONTINUE CD
; NA - RETURN THE VALUE OF THE CHAR TO THE RIGHT OF THE TEXT POINTER
CDNA: MOVE X,[JSP PC,$$NA] ; GET CALL TO $$NA
TXNE F,F$COL ;[16000] :nA appends n lines
HRRI X,$$AL ;[16000] Get Append line routine
PUSH CP,X ;[16000] Gen whatever...
JRST CDCVAL ; AND CONTINUE CD
; CDB - B - RETURN VALUE OF BEGINNING OF BUFFER; 0
CDB: PUSH CP,[SETZ VALUE,] ; GEN CODE TO RETURN 0
JRST CDCVAL ; AND CONTINUE CD
; CDPT - . - RETURN VALUE OF THE BUFFER POINTER
CDPT: PUSH CP,[MOVE VALUE,PTVAL] ; GEN CODE TO FETCH VALUE OF "."
JRST CDCVAL ; AND CONTINUE CD
; CDH - H - AN ABBREVIATION FOR "B,Z"
CDH: TXOE F,F$2RG ; "ARG,H"?
ERROR (ARG) ; YES. ** ILLEGAL ARG CONSTRUCTION **
PUSH CP,[SETZ SARG,] ; GEN CODE TO RETURN "B" IN SARG
; CDZ - Z - RETURN VALUE OF THE END OF TH BUFFER
CDZ: PUSH CP,[MOVE VALUE,@TXTBUF] ; GEN CODE TO RETURN VALUE OF Z
JRST CDCVAL ; AND CONTINUE CD
; CDTAB - <TAB>TEXT$ - INSERT A TAB CHAR AND TEXT INTO MAIN TEXT BUFFER
CDTAB:
CDSIC: ;Come here to insert any self-inserting character & following text
PUSHJ P,CMDBCH ;[14000] Back up so char inserts itself
JRST CDI0 ;[14000] (tab) is just like i(tab)
; CDI - NI$ OR ITEXT$ - INSERT CHARACTER OR TEXT INTO MAIN TEXT BUFFER
CDI: TXNE F,F$1RG ; IS AN ARG PRESENT?
JRST CDNI ; YES, IT'S "NI$"
; ITEXT$ OR @I/TEXT/$ - INSERT TEXT INTO BUFFER AT CURRENT POSITION
CDI0: PUSH CP,[JSP PC,$$I] ; GEN CODE TO CALL $$I
CDIN1: PUSHJ P,CDCINS ; SCAN THE INSERTION ARGUMENT
JRST CDALT ; AND CONTINUE CD
; CNDI - NI$ - INSERT THE CHAR WHOSE ASCII CODE IS N
CDNI: MOVE C,DELIM ;[12000] use default delimiter
TXNE F,F$DTM ;[12000] check for @I//
PUSHJ P,CMDGCH ;[12000] get another delimiter
JFCL ;[16000] Will lose later anyway
MOVEI T3,(C) ;[12000] Save whatever delimiter it was
PUSHJ P,CMDGCH ; YES, MAKE SURE FOLLOWING CHAR IS SAME
ERROR (NDI) ; NO. ** NO DELIMITER AFTER I **
CAIE C,(T3) ;[12000] is it the delimiter
ERROR (NDI) ; NO. SAME ERROR
PUSH CP,[JSP PC,$$NI] ; GEN CALL TO $$NI
JRST CDCRET ; AND CONTINUE CD
; CDD - D OR ND - DELETE AN ARBITRARY # CHARACTERS FROM TEXT BUFFER
CDD: PUSHJ P,ARGK ; KLUGE ARG IF NECESSARY
PUSH CP,[JSP PC,$$D] ; GEN CALL TO $$D
JRST CDCRET ; AND CONTINUE CD
; CDC0 - C OR -C OR NC - MOVE THE BUFFER POINTER OVER N CHARS
CDC0: PUSHJ P,ARGK ; KLUDGE THE ARG IF THERE WASN'T ANY
PUSH CP,[JSP PC,$$C] ; GEN CODE TO CALL $$C
JRST CDCRET ; AND CONTINUE CD
; CDR - R OR -R OR NR - MOVE THE BUFFER POINTER BACKWARDS N CHARS
CDR: PUSHJ P,ARGK ; KLUDGE THE ARG IF THERE WASN'T ANY
PUSH CP,[JSP PC,$$R] ; GEN CODE TO CALL $$R
JRST CDCRET ; AND CONTINUE CD
; CDJ - J OR NJ - POSITION THE BUFFER POINTER TO A SPECIFIC POSITION
CDJ: TXNN F,F$1RG ;[12000] any argument given?
PUSH CP,[SETZ ARG,] ;[12000] no so make it zero
PUSH CP,[JSP PC,$$J] ; GEN CODE TO CALL $$J
JRST CDCRET ; AND CONTINUE CD
; CDP - P OR NP OR N,MP OR PW OR NPW - PUNCH ALL OR PART OF CURRENT PAGE
; - P - PUNCH ALL OF CURRENT PAGE
; - NP - PUNCH CURRENT PAGE AND NEXT N-1 PAGES
; - N,MP - PUNCH CHARS N+1 THRU M AND LEAVE BUFFER INTACT
; - PW - PUNCH CURRENT PAGE AND APPEND FF CHAR AND LEAVE BUFFER INTACT
; - NPW - PERFORM "PW" N TIMES
CDP: ;[16000] Fix so m,nPW doesn't do W
PUSHJ P,ARGK ; NO, KLUDGE ARG IF NOT PRESENT
PUSHJ P,CMDGCH ; FETCH NEXT COMMAND CHAR
SKP ;[303] NONE, MEANS NOT PW
CAIN C,"W" ; IS COMMAND "PW"?
JRST CDP1 ; Yes, gobble character
PUSHJ P,CMDBCH ; NOT "W", BACK UP OVER THE CHAR
SKIPA X,[JSP PC,$$P] ; AND GEN CALL TO $$P FOR "P" OR "NP"
CDP1: MOVE X,[JSP PC,$$PW] ; YES. FETCH CALL TO $$PW
TXNE F,F$2RG ;[16000] m,nP?
HRRI X,$$BP ;[16000] Gen code for bounded punch
PUSH CP,X ;[16000] Gen it, whatever it was
JRST CDCRET ; AND CONTINUE CD
CDP2: PUSH CP,[JSP PC,$$BP] ; GEN CALL TO $$BP FOR "N,MP"
JRST CDCRET ; AND CONTINUE CD
; CDY - Y OR NY - RENDER THE BUFFER EMPTY AND APPEND A BUFFER
CDY: TXNE F,F$1RG!F$2RG ;[14000] Given an argument?
ERROR (NYA) ;[14000] Yes. He probably blew it
SKIPE MACLVL ;[12000] IN A MACRO?
JRST CDEY ; YES, TREAT SAME AS "EY"
PUSHJ P,ARGK ;[12000] Default to 1
PUSH CP,[JSP PC,$$Y] ;[12000] Allow yank if buffer empty
JRST CDCRET ;[12000] continue compiling
; CDF - FXXX - THE "F" COMMANDS
CDF: PUSHJ P,CMDGCH ; FETCH THE NEXT COMMAND CHARACTER
ERROR (MEF) ; NONE LEFT. ** MACRO ENDING WITH F **
PUSHJ P,UPCASE ; UPCASE THE CHAR
MOVE T1,[IOWD FLTH,FTBL+1] ; FETCH PTR TO DISPATCH TABLE
PUSHJ P,DISPAT ; AND DISPATCH ON THE CHAR
ERROR (IFC) ; ** ILLEGAL F COMMAND **
; DISPATCH TABLE FOR THE "F" COMMANDS
FTBL: <"S",,CDFS>
<"Q",,CDFQ> ;[12000] FQ -- QCM Compare Q-reg w/ text
<"N",,CDFN>
<"D",,CDFD>
<"R",,CDFR> ;[12000] FR command (Replace on last search)
<"Y",,CDFY> ;[14000] Vertical cursor position
<"X",,CDFX> ;[14000] Horizontal cursor position
<"C",,CDFC> ;[14000] Bounded search/replace
<"P",,CDFP> ;[12000] FY,FX
<"0",,CDF0> ;[14000] Start of window
<"B",,CDFB> ;[14000] Bounded search
<"Z",,CDFZ> ;[12000] End of window
<"H",,CDFH> ;[12000] F0,FZ
<"F",,CDFF> ;[12000] Adjust cursor
<"K",,CDFK> ;[14000] FK replaces FD
<"T",,CDFT> ;[21000] Tab stops
FLTH==.-FTBL
; CDFB - FBSTR$ - BOUNDED SEARCH
CDFB: PUSHJ P,ARGK ;[15000] Default arg if none
MOVE T2,[JSP PC,$$BS] ;[14000] Fetch call to 2-arg form
TXNN F,F$2RG ;[14000] Have we 2 argments?
HRRI T2,$$BSL ;[14000] NO. must be line argument
JRST CDS1 ;[14000] Join common search code
; CDFC - FCSTR1$STR2$ - BOUNDED SEARCH/REPLACE
CDFC: PUSHJ P,ARGK ;[15000] Default arg if none
MOVE T2,[JSP PC,$$BS] ;[14000] Fetch call for 2-arg form
TXNN F,F$2RG ;[14000] Have we 2 arguments?
HRRI T2,$$BSL ;[14000] No. must be a line argument
JRST CDFS1 ;[14000] Gen it & fall into common FS code
; CDFN - FNSTR1$STR2$ - FIND "STR1" (USING N-SEARCH) AND SUBSTITUTE "STR2"
CDFN: SKIPA T2,[JSP PC,$$N] ; FETCH CALL FOR N-SEARCH
; CDFS - FSSTR1$STR2$ - FIND "STR1" (USING S-SEARCH) AND SUBSTITUTE "STR2"
;
; GEN: JSP PC,$$S
; <CHAR.ADR,,TEXT.LENGTH>
; JSP PC,$$FS
; <CHAR.ADR,,CHAR.LENGTH>
CDFS: MOVE T2,[JSP PC,$$S] ; FETCH CALL FOR S-SEARCH
PUSHJ P,ARGK ; KLUDGE ARG IF NOT PRESENT
TXNE F,F$2RG ; IS IT A BOUNDED SEARCH?
HRRI T2,$$BS ; YES (SAME FOR FS,FN)
PUSHJ P,CHKITR ; IN AN ITERATION?
JRST CDFS1 ; NO, CONTINUE NORMALLY
TXNN F,F$COL ; ALREADY RETURNING A VALUE?
PUSH CP,[TXO F,F$COL] ; NO, GEN CODE TO SET FLAG
CDFS1: PUSH CP,T2 ; GEN THE SEARCH CALL
PUSH P,T4 ; SAVE AC T4
PUSHJ P,SSTPSC ; PRESCAN THE SEARCH ARG
PUSH P,T2 ;[21000] Save the delimiter
PUSHJ P,SSTGSM ; GEN THE SEARCH MATRIX FOR SYNTAX CHECK
POP P,T3 ;[21000] Get back delimiter
POP P,T4 ; RESTORE AC T4
PUSH CP,[JSP PC,$$FS] ; GEN THE CALL TO THE SUBSTITUTE ROUTINE
PUSHJ P,CDI1 ; SCAN THE INSERTION [21000] knowing the delim
JRST CDS2 ; GEN CODE FOR SEARCH AUTOTYPE
; CDFR Entry for doing replace after already having done search
;
CDFR: PUSH CP,[JSP PC,$$FS] ; GEN THE CALL TO THE SUBSTITUTE ROUTINE
PUSHJ P,CDCINS ; SCAN THE INSERTION
JRST CDCRET ; Continue compilation...
; CDFD -FDSTR$ - Find & destroy "STR" [14000]
; GEN: JSP PC,$$S
; <CHAR.ADR,,TEXT.LENGTH>
; JSP PC,$$FS
; <0> ;Just like FS with null second argument
CDFD: MOVE T2,[JSP PC,$$S] ; FETCH CALL FOR S-SEARCH
PUSHJ P,ARGK ; KLUDGE ARG IF NOT PRESENT
TXNE F,F$2RG ; IS IT A BOUNDED SEARCH?
HRRI T2,$$BS ; YES (SAME FOR FS,FN)
PUSHJ P,CHKITR ; IN AN ITERATION?
JRST CDFD1 ; NO, CONTINUE NORMALLY
MOVE X,[TXO F,F$COL] ;[12000] gen code for setting bit if needed
TXNN F,F$COL ; ALREADY RETURNING A VALUE?
PUSH CP,X ; NO, GEN CODE TO SET FLAG
CDFD1:
PUSH CP,T2 ; GEN THE SEARCH CALL
PUSH P,T4 ; SAVE AC T4
PUSHJ P,SSTPSC ; PRESCAN THE SEARCH ARG
PUSHJ P,SSTGSM ; GEN THE SEARCH MATRIX FOR SYNTAX CHECK
POP P,T4 ; RESTORE AC T4
PUSH CP,[JSP PC,$$FS] ;[14000] Gen call to replace routine
PUSH CP,[0] ;[14000] replace with nothing
JRST CDS2 ;[14000] Gen code for search autotype
; CDFK - FKSTR$ - FIND "STR" (USING S-SEARCH) AND DESTROY ALL UP TO
; AND INCLUDING "STR"
;
; GEN: PUSH P,PTVAL
; JSP PC,$$S
; <CHAR.ADR,,TEXT.LENGTH>
; POP P,ARG
; SUB ARG,PTVAL
; JSP PC,$$D
CDFK: ;[14000] Used to be FD
PUSH CP,[PUSH P,PTVAL] ;[377] GEN CODE TO SAVE VALUE OF "."
MOVE T2,[JSP PC,$$S] ;[377] FETCH CALL FOR S-SEARCH
PUSHJ P,ARGK ;[377] KLUDGE ARG IF NOT PRESENT
TXNE F,F$2RG ;[377] BOUNDED SEARCH?
HRRI T2,$$BS ;[377] YES
PUSHJ P,CHKITR ;[377] IN AN ITERATION?
JRST CDFK1 ;[377] NO, NORMAL FD
TXNN F,F$COL ;[377] ALREADY RETURNING A VALUE?
PUSH CP,[TXO F,F$COL];[377] GEN CODE TO SET FLAG
CDFK1: PUSH CP,T2 ;[377] GEN THE SEARCH CALL
PUSH P,T4 ;[377] SAVE AC T4
PUSHJ P,SSTPSC ;[377] PRESCAN SEARCH ARG
PUSHJ P,SSTGSM ;[377] GEN THE SEARCH MATRIX FOR SYNTAX CHECK
POP P,T4 ;[377] RESTORE AC T4
PUSH CP,[POP P,ARG] ;[377] GEN CODE TO GET OLD VALUE OF "."
PUSH CP,[SUB ARG,PTVAL] ;[377] GEN CODE TO COMPUTE DESTORY #
PUSH CP,[JSP PC,$$D] ;[377] GEN CODE TO DESTROY
JRST CDS2 ;[377] GEN CODE FOR SEARCH AUTOTYPE
; VARIOUS WINDOW PARAMETERS [12000]
CDFH: ;Set or retrieve start & end of window
TXCN F,F$2RG ;[12000] 2 arguments given?
JRST [PUSH CP,[MOVE SARG,WINB] ;[12000] Return both values
PUSH CP,[MOVE VALUE,WINZ] ;[12000] ...
JRST CDCVAL] ;[12000] Return values
PUSH CP,[MOVEM SARG,WINB] ;[12000] Set the Window beginning
;[12000] Fall through to set Window end
CDFZ: ;Set or retrieve End of window
SKIPA X,[MOVE VALUE,WINZ] ;[12000]
CDF0: ;Set or retrieve Start of window
MOVE X,[MOVE VALUE,WINB] ;[12000] Fetch the row the cursor is on
JRST CDRSV ;[12000] Do it to it
CDFP: ;Set or retrieve both row & column of cursor position
TXCN F,F$2RG ;[12000] 2 arguments given?
JRST [PUSH CP,[MOVE SARG,ROW] ;[12000] Return both values
PUSH CP,[MOVE VALUE,COL] ;[12000] ...
JRST CDCVAL] ;[12000] Return values
PUSH CP,[MOVEM SARG,ROW] ;[12000] Set the row
;[12000] Fall through to set column
CDFX: ;Set or retrieve column cursor is in
SKIPA X,[MOVE VALUE,COL] ;[12000] Fetch the column the cursor is on
CDFY: ;Set or retrieve row cursor is in
MOVE X,[MOVE VALUE,ROW] ;[12000] Fetch the row the cursor is on
CDRSV: ;[12000] Entry to generate
; MOVE VALUE,FOO if no arg, or
; MOVEM ARG,FOO if there is an arg
TXNN F,F$1RG ;[12000] Does it have an argument?
JRST CDCFVA ;[12000] Gen it & return value
CDCFNV: HRLI X,(MOVEM ARG,) ;[12000] Change the value
CDCFV2: PUSH CP,X ;[12000] Gen the instruction
JRST CDCRET ;[12000] Return no value
CDCFVA: PUSH CP,X ;[12000] Gen the instruction
JRST CDCVAL ;[12000] Return value
; CDFF - FF - Adjust cursor position
CDFF: MOVE X,[JSP PC,$FF2] ;[12000] Fetch call to 2-arg form
TXZN F,F$2RG ;[12000] 2 args different
HRRI X,$FF1 ;[12000] from 1 arg
PUSH CP,X ;[12000] Put into code
JRST CDCVAL ;[12000] Continue & return value
; CDFT - Get or Set TAB stops ;[21000]
CDFT: MOVE X,EDVAL ;[23000] If optimizing, ...
TXNE X,ED$OPT ;[23000] no range check
JRST CDFT0 ;[23000] ...
PUSH CP,[SKIPL ARG] ;[23000] Negative n.g.
PUSH CP,[CAIL ARG,C$NTS] ;[25000] or too big
PUSH CP,[ERROR (AOR)];[23000] ** ARG OUT OF RANGE **
CDFT0: TXZN F,F$2RG ;[21000] 2 ARGS?
JRST [PUSH CP,[MOVE VALUE,TSTOPS(ARG)] ;[21000] Gen code
JRST CDCVAL] ;[21000] Return value
PUSH CP,[MOVEM SARG,TSTOPS(ARG)] ;[21000] Gen code to set
JRST CDCRET ;[21000] Return no value
; CDK - K OR NK OR N,MK - REMOVE LINES FROM TEXT BUFFER
CDK: PUSHJ P,ARGK ; KLUDGE ARG IF NONE PRESENT
MOVE X,[JSP PC,$$K] ; FETCH CALL TO $$K FOR N,MK
TXNN F,F$2RG ; IS IT "N,MK"?
HRRI X,$$KL ; NO, IT'S "NK"
PUSH CP,X ; GEN THE CALL TO $$K OR $$KL
JRST CDCRET ; AND CONTINUE CD
; CDL - L OR NL - MOVE TO ANOTHER LINE RELATIVE TO "."
CDL: PUSHJ P,ARGK ; IN CASE NO ARG PRESENT
TXNE F,F$2RG ; TWO ARGS PRESENT?
ERROR (TAL) ; YES. ** TWO ARGUMENTS FOR L **
PUSH CP,[JSP PC,$$L] ; GEN CALL TO $$L
JRST CDCRET ; AND CONTINUE CD
; CDS - STEXT$ - SEARCH THE TEXT BUFFER FOR AN OCCURRANCE OF "TEXT"
; NSTEXT$ - NTH OCCURRANCE
; N,MSTEXT$ - WITHIN BOUNDS
; -STEXT$ - BACKWARDS SEARCH
; -NSTEXT$ - NTH OCCURRANCE (SEARCHING BACKWARDS)
; M,NSTEXT$ - WITHIN BOUNDS N,M (SEARCHING BACKWARDS, M.GT.N)
CDS: PUSHJ P,ARGK ; IN CASE THERE IS NO ARG PRESENT
MOVE T2,[JSP PC,$$S] ; FETCH CODE TO CALL $$S
CDS0: TXNE F,F$2RG ; TWO ARGUMENTS PRESENT?
HRRI T2,$$BS ; YES, THEN IT'S A BOUNDED SEARCH
PUSHJ P,CHKITR ; IN AN ITERATION?
JRST CDS1 ; NO
;; SEARCHES INSIDE ITERATIONS ARE THE SAME AS ":" SEARCHES
TXNN F,F$COL ; ALREADY A ":" SEARCH ?
PUSH CP,[TXO F,F$COL]; NO, GEN THE INST. TO SET ":" FLAG
CDS1: PUSH CP,T2 ; GEN THE CALL TO $$S OR $$BS
PUSH P,T4 ; SAVE AC L
PUSHJ P,SSTPSC ; PRESCAN THE SEARCH STRING
PUSHJ P,SSTGSM ; GENERATE DUMMY SEARCH MATRIX
; TO CHECK SYNTAX
POP P,T4 ; RESTORE AC L
CDS2: TXNE F,F$COL ; IS IT A ":" SEARCH?
JRST CDCRET ; YES, DON'T AUTOTYPE AFTER SEARCH
PUSHJ P,CHKITR ; IN AN ITERATION? [16000] removed2 inst
JRST [PUSH CP,[JSP PC,$$0TT] ; GEN CALL TO SEARCH AUTOTYPE ROUTINE
JRST CDCRET] ;[16000] And don't fake a ; in any case
PUSHJ P,CMDGCH ;[16000] See if ; follows
JRST .+3 ;[16000] Don't check the character, then
CAIE C,";" ;[16000] Is this a ; ?
PUSHJ P,CMDBCH ;[16000] Back up over it
PUSH CP,[JSP PC,$$SEMF] ;[16000] Exit if I fail
PUSH CP,[TXZ F,F$COL!F$2CO] ;[16000] Clear colons at runtime
JRST CDCRET ;[16000] Return no value
; CDN - SAME AS THE S COMMAND EXCEPT SEARCH THRU WHOLE FILE
CDN: PUSHJ P,ARGK ; IN CASE NO ARG IS PRESENT
MOVE T2,[JSP PC,$$N] ; FETCH CALL TO $$N
JRST CDS0 ; AND SCAN REST OF "N" COMMAND
; CDBAR - SAME AS "N" SEARCH EXCEPT THAT NOTHING IS OUTPUT
CDBAR: PUSHJ P,ARGK ; IN CASE NO ARG IS PRESENT
MOVE T2,[JSP PC,$$BAR] ; FETCH CALL TO $$BAR
JRST CDS0 ; SCAN SEARCH ARG AND CONTINUE CD
; CDT - T OR NT OR N,MT - TYPE TEXT FROM BUFFER
CDT: PUSHJ P,ARGK ; IN CASE NO ARGS
MOVE X,[JSP PC,$$T] ; FETCH CALL TO $$T
TXNN F,F$2RG ; IS IT "N,MT"?
HRRI X,$$TL ; NO, IT'S "NT"
PUSH CP,X ; GEN THE CALL TO $$T OR $$TL
JRST CDCRET ; AND CONTINUE CD
; CDV - V or nV - (1-n)TnT - TYPE TEXT FROM BUFFER IN WHOLE LINES
CDV: PUSHJ P,ARGK ;[12000] In case of no args do 0TT
PUSH CP,[JSP PC,$$V] ;[12000] Gen call to $$V
JRST CDCRET ;[12000] no value
; CDW - W or nW or n:W or m,n:W - Manipulate screen parameters or window
CDW: TXZE F,F$COL ;[12000] W or :W?
JRST CDCOLW ;[12000] :W
TXNN F,F$1RG ;[15000] Set argument defaults
PUSH CP,[MOVE ARG,DEFARG] ;[15000] no args at all
TXNN F,F$2RG ;[15000] No second argument anyway
PUSH CP,[MOVE SARG,DEFARG] ;[15000] ...
PUSH CP,[JSP PC,$$W] ;[15000] Gen macro call to ([W])
JRST CDCRET ;[12000] no value
CDCOLW:
MOVE X,[JSP PC,$$COLW] ;[15000] Gen macro call to ([:W])
TXZE F,F$2RG ;[15000] 1 or 2 arg form
HRRI X,$$CW2 ;[15000] 2 arg.
PUSH CP,X ;[15000] Gen it
JRST CDCVAL ;[15000] and/or set/read parameter
REPEAT 0,<
TXZE F,F$2RG ;[12000] 2 args?
JRST [PUSH CP,[JSP PC,$$COLW] ;[12000] Gen call to setter
JRST CDCCLR] ;[12000] return no value
MOVE X,EDVAL ;[12000] see if 'optimized'
TXNE X,ED$OPT ;[12000] if so, no range check!!
JRST CDCW1 ;[12000] skip check (hope his macro's debugged!)
PUSH CP,[CAIG ARG,CWMAX] ;[12000] range check
PUSH CP,[SKIPGE ARG] ;[12000] negative n.g too
PUSH CP,[ TDZA VALUE,VALUE] ;[12000] n.g. return 0
CDCW1:! PUSH CP,[MOVE VALUE,CWVEC(ARG)] ;[12000] Get parameter
JRST CDCVL1 ;[12000] Continue (return value)
>
; CDU - NUQ - STORE NUMERIC ARG IN Q-REGISTER
CDU: TXNN F,F$1RG ; AN ARG PRESENT?
ERROR (NAU) ; NO. ** NO ARG BEFORE U **
PUSHJ P,GENQRG ;[22000] Parse the q-register name
JRST [PUSH CP,[JSP PC,$$U] ; GEN CODE TO CALL ROUTINE
PUSH CP,N ;[22000] WHICH STORES Q-REGISTER CONTENTS
JRST CDU1] ; GEN THE Q-REGISTER NAME INTO CODE
ADD N,[MOVEM ARG,QREG+1] ;[22000] Generate instruction
CDU0: PUSH CP,N ;[22000] into code
TXZN F,F$COL ;[23000] :U fudges text also
JRST CDU1 ;[23000] NOT THIS TIME
PUSH CP,[TXZ F,F$COL];[23000] Clear : at run time
SOJA N,CDU0 ;[23000] do the text, too
CDU1: TXZN F,F$2RG ;[14000] Did we get 2 arguments
JRST CDCRET ; AND CONTINUE CD
PUSH CP,[MOVE VALUE,SARG] ;[14000] Second one is our value
JRST CDCVAL ;[14000] So return a value
; CDQ - QQ - RETURN VALUE OF A NUMERIC Q-REGISTER
CDQ:
TXZE F,F$1RG!F$COL ;[12000] Check IF ANY ARGS or ":Q"
JRST [MOVE X,EOVAL ;[12000] See if random access enabled
CAIGE X,3 ;[12000] (i.e. if EO GEQ 3)
JRST .+1 ;[12000] it wasn't
PUSH CP,[JSP PC,$$QRX] ;[12000] get nth char of text
JRST CDQ0] ; [12000] rejoin
MOVE X,EDVAL ;[22000] Do winning thing if optimizing
TXNE X,ED$OPT ;[22000] ...
JRST [PUSHJ P,GENQRG ;[22000] We are, so try to win
JRST [PUSH CP,[JSP PC,$$Q] ;[22000] But we can't win
CDQFZ: PUSH CP,N ;[22000] 'cause it's a long name
JRST CDCVAL] ;[22000] so do the same old thing
ADD N,[MOVE VALUE,QREG+1] ;[22000] Build instruction
JRST CDQFZ] ;[22000] And generate the code
PUSH CP,[JSP PC,$$Q] ; GEN CALL TO RETURN CONTENTS OF Q-REGISTER
CDQ0: PUSHJ P,MAKQNM ; GEN THE Q-REGISTER NAME INTO CODE
JRST CDCVAL ; AND CONTINUE CD
; CDX - NXQ OR N,MXQ OR XQ - STORE TEXT FROM BUFFER INTO Q-REGISTER
CDX: PUSHJ P,ARGK ; KLUDGE THE ARG IF NOT PRESENT
MOVE X,[JSP PC,$$X] ; FETCH THE CALL TO $$X
TXNN F,F$2RG ; IS ARG A # OF LINES?
HRRI X,$$XL ; YES, FETCH CALL TO $$XL
PUSH CP,X ; GEN THE CALL TO $$X OR $$XL
PUSHJ P,MAKQNM ; GEN THE Q-REGISTER NAME
JRST CDCRET ; AND CONTINUE CD
; CDG - GQ - GET THE TEXT CONTAINED IN A Q-REGISTER AND INSERT INTO BUFFER
CDG: PUSH CP,[JSP PC,$$G] ; GEN CALL TO $$G
PUSHJ P,MAKQNM ; GEN THE Q-REGISTER NAME
JRST CDCCLR ; AND CONTINUE CD
; CDCPCT - %Q - INCREMENT Q AND RETURN RESULTING VALUE
CDPCT: PUSHJ P,GENQRG ;[22000] Parse q-register name
JRST [TXNE F,F$1RG ;[12000] Argument present?
PUSH CP,[TXO F,F$1RG] ;[12000] yes
PUSH CP,[JSP PC,$$INC] ; GEN CALL TO $$INC
PUSH CP,N ; GEN Q-REGISTER NAME INTO CODE
JRST CDCVAL] ;[22000] Return value
ADD N,[ADDB ARG,QREG+1] ;[22000] Make instruction
TXNN F,F$1RG ;[23000] Any arguments?
JRST [HRLI N,(AOS VALUE,) ;[23000] Just increment it then
PUSH CP,N ;[23000] gen into code
JRST CDCVAL] ;[23000] Return value
PUSH CP,N ;[22000] and generate code
PUSH CP,[MOVE VALUE,ARG] ;[22000] Make it return the value
JRST CDCVAL ; AND CONTINUE CD
; CDM - MQ - COMPILE AND EXECUTE THE TEXT IN Q-REGISTER Q
CDM: HLR X,F ;[344] COPY FLAGS
ANDI X,(F$$RG) ;[344] AND TO GET ONLY ARG FLAGS
;[344] I REALIZE THIS MEANS ARG FLAGS
;[344] CAN ONLY BE IN LEFT HALF, BUT
;[344] THEY ARE HERE, AND WE CAN'T TXO
;[344] AT RUN TIME!!!
JUMPE X,.+2 ;[344] SKIP NEXT INSTRUCTION IF NO ARGS
PUSH CP,[SETOM MACFLG] ;[344] SET THE MACRO FLAG AT EXECUTION
HRLI X,(TLO F,) ;[344] FINISH MAKING INSTRUCTION
PUSH CP,X ;[344] SAVE THE ARG FLAG SETTING THING
PUSH CP,[JSP PC,$$M] ; GEN CALL TO $$M
PUSHJ P,MAKQNM ; GEN THE Q-REGISTER NAME INTO CODE
JRST CDCVAL ; AND CONTINUE CD
; CDE - EX... - "E" FILENTROL AND FLAG COMMANDS
CDE: PUSHJ P,CMDGCH ; FETCH NEXT COMMAND CHAR
JRST CDEND ;[12000] Go to end of line
PUSHJ P,UPCASE ; UPCASE THE CHAR
MOVE T1,[IOWD ECLTH,ECTBL+1] ; AOBJN PTR TO "E" CMD DISPATCH TABLE
PUSHJ P,DISPAT ; DISPATCH TO SPECIFIC "E" COMMAND
ERROR (IEC) ; ** ILLEGAL E COMMAND **
;[12000] E(space) go to end of that line
CDEND: PUSHJ P,ARGK ;[12000] Default is 1
PUSH CP,[JSP PC,$$E] ;[12000] Do it
JRST CDCRET ;[12000] Back for more (no value)
; DISPATCH TABLE FOR "E" COMMANDS
DEFINE EC(CMDS)<IRPC CMDS,<<"CMDS",,CDE'CMDS>>>
ECTBL:
EC (ABCDEFGHIJKLMNOPQRSTUWXYZ)
<"%",,CDEPCT> ;[14000] E% write out q-register
<"@",,CDEATS> ;[12000] E@ set delimiter
<"#",,CDCNU1> ;[12000] USETI (not standard)
<"&",,CDEAND> ;[14000] E& run program when we exit
<"!",,CDSCD> ;[12000] E! set command delimiter
<"_",,CDEBAR> ;[14000] Unprotectable "_" cmd.
<"*",,CDESTA> ;[14000] TRMOP.
<"=",,CDEEQU> ;[14000] Rename input file
<"?",,CDEQUE> ;[15000] E?q get cmd into q-register
<" ",,CDEND> ;[16000] E<CR> E<LF> E<SPACE> E$ E<ALT>
<15,,CDEND> ;[16000] get the E command
<12,,CDEND> ;[16000]
<.CHESC,,CDEND> ;[16000]
<"$",,CDEND> ;[16000]
<42,,CDEQUE> ;[16000] E"q get cmd into q-register
ECLTH==.-ECTBL
; CDEY - EY - NEW FORM OF THE "YANK" COMMAND
CDEY: PUSHJ P,ARGK ; ASSUME ARG OF "1" IF NONE GIVEN
PUSH CP,[JSP PC,$$EY] ; GEN CALL TO $$Y
JRST CDCRET ; AND CONTINUE CD
; CDEC - EC AND NEC - RETURN AND SET LOWSEGMENT SIZE
;
; GEN: JSP PC,$$EC ; (OR $$ECS TO SET LOWSEG SIZE)
; <RETURN>
CDEC: MOVE X,[JSP PC,$$EC] ; FETCH CALL TO $$EC
TXNE F,F$1RG ; IS IT "NEC"?
HRRI X,$$ECS ; YES, GEN CALL TO $$ECS
PUSH CP,X ; GEN THE CALL TO WHATEVER
TXNE F,F$1RG ; RETURN A VALUE?
JRST CDCRET ; NO, CONTINUE CD
JRST CDCVAL ; YES, CONTINUE CD
; CDEB - EBFILESPEC$ - SETUP FOR EDITTING A FILE
;
; GEN: JSP PC,$$EB
; <FILE.SPEC>
; (RETURN)
CDEB: PUSH CP,[JSP PC,$$EB] ; GEN CALL TO $$EB
CDEXX: PUSHJ P,CDFSPC ; GEN THE FILE SPEC
JRST CDALT ; AND CONTINUE CD
; CDER - ERFILESPEC$ - SETUP FOR READING A FILE
;
; GEN: JSP PC,$$ER
; <FILE.SPEC>
; (RETURN)
CDER: PUSH CP,[JSP PC,$$ER] ; GEN CALL TO $$ER
JRST CDEXX ; GEN FILE SPEC AND CONTINUE CD
; CDEW - EWFILESPEC$ - SETUP FOR WRITING TO A FILE
;
; GEN: JSP PC,$$EW
; <FILE.SPEC>
; (RETURN)
CDEW: PUSH CP,[JSP PC,$$EW] ; GEN CALL TO $$EW
JRST CDEXX ; GEN FILE SPEC AND CONTINUE CD
; CDEZ - EZFILESPEC$ - ZERO DIRECTORY AND SETUP FOR WRITING TO A FILE
;
; GEN: JSP PC,$$EZ
; <FILE.SPEC>
; (RETURN)
CDEZ: PUSH CP,[JSP PC,$$EZ] ; GEN CALL TO $$EZ
JRST CDEXX ; GEN FILE SPEC AND CONTINUE CD
; CDEF - EF - CLOSE OUTPUT FILE
;
; GEN: JSP PC,$$EF
; (RETURN)
CDEF: PUSH CP,[JSP PC,$$EF] ; GEN CALL TO $$EF
JRST CDCRET ; AND CONTINUE CD
; CDEK - EK - FLUSH OUTPUT FILE and Cancel "EB" if any
;
; GEN: JSP PC,$$EK
; (RETURN)
CDEK: PUSH CP,[JSP PC,$$EK] ; GEN CALL TO $$EK
JRST CDCRET ; AND CONTINUE CD
; CDEX - EX - PUNCH REST OF INPUT FILE AND EXIT
;
; GEN: JSP PC,$$EX
; (RETURN) ; IF USER TYPES "CONTINUE" AFTER EXIT
CDEX: PUSH CP,[JSP PC,$$EX] ; GEN CALL TO $$EX
JRST CDCRET ; AND CONTINUE CD
; CDEG - EG - PUNCH REST OF INPUT FILE AND EXIT AND PERFORM LAST
; COMPILE-CLASS COMMAND
CDEG: PUSH CP,[JSP PC,$$EG] ; GEN CALL TO $$EG
JRST CDCRET ; AND CONTINUE CD
; CDEM - NEM - PERFORM MAGTAPE OP N
;
; GEN: JSP PC,$$EM
; (RETURN)
CDEM: PUSH CP,[JSP PC,$$EM] ; GEN CALL TO $$EM
JRST CDCRET ; AND CONTINUE CD
; CDED - EDFILE-SPEC$ - SETUP FILE TO BE RUN ON EXIT
CDED: SKIPN EOVAL ;[12000] 0EO does run with ED
JRST CDEAND ;[12000] same as E&
MOVE X,[MOVE VALUE,EDVAL] ;[12000] Prepare to fetch value
CDCRSB: ;[12000] Enter here to set or get bits
TXNN F,F$2RG ;[12000] 2 arguments?
JRST CDRSV ;[12000] no, just like all the others
HRLI X,(ANDCAM SARG,) ;[12000] Clear these bits first
PUSH CP,X ;[12000] gen into code
HRLI X,(IORM ARG,) ;[12000] now set these bits
JRST CDCFV2 ;[12000] Gen into code & return no value
CDEAND: PUSH CP,[JSP PC,$$RUNP] ; GEN CALL TO $$RUNP
JRST CDEXX ; SCAN FILE SPEC AND CONTINUE CD
; CDEI - EIFILE-SPEC$ - EDIT INDIRECT (EXECUTE AN INDIRECT COMMAND FILE)
CDEI: HLR X,F ;[345] COPY FLAGS
ANDI X,(F$$RG) ;[345] ISOLATE ARGUMENT FLAGS
JUMPE X,.+2 ;[345] SKIP NEXT IF NO ARG
PUSH CP,[SETOM MACFLG] ;[345] SET THE MACRO ARGUMENT FLAG
HRLI X,(TLO F,) ;[345] FINISH RESETTING FLAGS INST.
PUSH CP,X ;[345] SAVE FOR RUN TIME
PUSH CP,[JSP PC,$$EI] ; GEN CALL TO $$EI
JRST CDEXX ; SCAN FILE-SPEC AND CONTINUE CD
CDEBAR: ;[14000] E_ same as _ but always legal
PUSHJ P,ARGK ;[14000] Generate an argument if none
MOVE T2,[JSP PC,$$EBAR] ;[14000] Call to routine
JRST CDS0 ;[14000] Join search code
; CDEP - EPFILE-SPEC$ - READ A FILE INTO Q-REGISTER "*"
CDEP:
PUSH CP,[JSP PC,$$EQ] ; GEN CALL TO $$EQ
PUSH CP,['* '] ;[12000] Q-register name for EP command
JRST CDEXX ; SCAN FILE-SPEC AND CONTINUE CD
; CDEQ - EQ(Q-REG)FILE-SPEC$ - READ A FILE INTO Q-REGISTER
CDEQ: PUSH CP,[JSP PC,$$EQ] ; GEN CALL TO $$EQ
PUSHJ P,MAKQNM ;[12000] Get q-register name
JRST CDEXX ; SCAN FILE-SPEC AND CONTINUE CD
; CDEPCT - E%(Q-REG)FILE-SPEC$ - WRITE A FILE FROM Q-REGISTER
CDEPCT: PUSH CP,[JSP PC,$$EPCT] ; GEN CALL TO $$EPCT
PUSHJ P,MAKQNM ;[12000] Get q-register name
JRST CDEXX ; SCAN FILE-SPEC AND CONTINUE CD
; CDEE - EEFILE-SPEC$ - SAVE STATE IN A FILE (A RUNNABLE FILE)
CDEE: PUSH CP,[JSP PC,$$EE] ; GEN CALL TO $$EE
JRST CDEXX ; SCAN FILE-SPEC AND CONTINUE CD
; CDEA - EAFILE-SPEC$ - SAME AS "EW" BUT APPEND TO EXISTING FILE
CDEA: PUSH CP,[JSP PC,$$EA] ; GEN CALL TO $$EA
JRST CDEXX ; SCAN FILE SPEC AND CONTINUE CD
; CDECAR - E^FILE-SPEC$ - RENAME CURRENT INPUT FILE
CDEN: ERROR (UEN) ;[16000] Unimplemented command
CDEEQU:
PUSH CP,[JSP PC,$$RENM] ; GEN CALL TO $$ECAR
JRST CDEXX ; SCAN FILE-SPEC AND CONTINUE CD
CDEQUE:
PUSH CP,[JSP PC,$$GETC] ;[15000] Gen call
PUSHJ P,MAKQNM ;[15000] And q-register name
JRST CDCVAL ;[15000] Will return -1 unless cmd erased
; CDET - ET OR NET - RETURN OR SET SUBSTITUTION TYPEOUT FLAG
CDET: TXZE F,F$1RG ; IS AN ARG PRESENT?
JRST CDET1 ; YES
PUSH CP,[MOVE VALUE,ETVAL] ; NO, GEN CODE TO RETURN ET FLAGS
JRST CDCVAL ; AND CONTINUE SCAN
CDET1: TXZE F,F$2RG ;[12000] 2 arg form?
PUSH CP,[TXO F,F$2RG] ;[12000] Gen into code
PUSH CP,[JSP PC,$$ETS] ;[12000] Gen call to run-time routine
JRST CDCRET ; AND CONTINUE CD
; CDEO - EO OR NEO - RETURN OR SET EDIT OLD FLAG
CDEO: TXNE F,F$1RG ; IS AN ARG PRESENT?
JRST CDEO1 ; YES
PUSH CP,[MOVE VALUE,EOVAL] ; NO, GEN CODE TO RETURN EO FLAG
JRST CDCVAL ; AND CONTINUE CD
CDEO1: PUSH CP,[CAIL ARG,] ;[406] GEN CODE TO CHECK FOR .LT.0
PUSH CP,[CAILE ARG,C$EOVL] ;[406] GEN CODE TO CHECK FOR .LE.MAXIMUM
PUSH CP,[CERROR (EOA)] ;[406] "EO" ARGUMENT ERROR
PUSH CP,[MOVEM ARG,EOVAL] ; GEN CODE TO SET EO FLAG
JRST CDCRET ; AND CONTINUE CD
; CDEATS -- Set or return current delimiter
CDEATS:
TXNN F,F$1RG ;[12000] Arg?
JRST [PUSH CP,[MOVE VALUE,DELIM] ;[12000] No
JRST CDCVAL] ;[12000]
PUSH CP,[MOVEM ARG,DELIM] ;[12000] Set delimiter at run time also
TXNN F,F$2RG ;[12000] 2 character delimiter?
PUSH CP,[HRLM SARG,DELIM] ;[12000] yes
JRST CDCRET ;[12000] continue (novalue)
; CDSCD -- Set or return current command delimiter
CDSCD:
TXNN F,F$1RG ;[12000] Arg?
JRST [PUSH CP,[MOVE VALUE,CDELIM] ;[12000] No
JRST CDCVAL] ;[12000]
PUSH CP,[MOVEM ARG,CDELIM] ;[12000] Set delimiter at run time also
TXNE F,F$2RG ;[12000] 2 character delimiter?
PUSH CP,[MOVEM SARG,CDELIM+1] ;[12000] yes
JRST CDCRET ;[12000] continue (novalue)
; CDEU - EU OR NEU - SET OR RETURN CASE FLAGING FLAG
CDEU: TXNE F,F$1RG ; IS AN ARG PRESENT?
JRST CDEU1 ; YES
PUSH CP,[MOVE VALUE,EUVAL] ; NO, GEN CODE TO RETURN EU FLAG
JRST CDCVAL ; AND CONTINUE CD
CDEU1: PUSH CP,[MOVEM ARG,EUVAL] ; GEN CODE TO SET EU FLAG
JRST CDCRET ; AND CONTINUE CD
; CDEH - EH OR NEH - RETURN OR SET ERROR MESSAGE LENGTH FLAG
CDEH: MOVE X,[JSP PC,$$EHS] ;[325] FETCH CALL TO EH SET ROUTINE
TXNN F,F$1RG ; "SET" COMMAND?
HRRI X,$$EH ; NO, FETCH ADR OF "RETURN" ROUTINE
PUSH CP,X ; AND GEN THE CALL TO WHATEVER
TXNE F,F$1RG ; "SET"?
JRST CDCRET ; YES, CONTINUE CD
JRST CDCVAL ; NO, CONTINUE CD
; CDEJ - EJ - GET JOB #, TTY #, OR PPN
CDEJ: PUSHJ P,ARGK ;[12000] Fake arg if none
IFN FTPRIV,<
TXNE F,F$2RG ;[12000] Remember 2 args at run time
PUSH CP,[TXO F,F$2RG] ;[12000] if these features are enabled
>
PUSH CP,[JSP PC,$$EJ] ;[12000] Job #,TTY #,PPN
JRST CDCVAL ;[12000] Return value
; CDES - ES OR NES - RETURN OR SET THE AUTOTYPEOUT AFTER SEARCH FLAG
CDES: TXNE F,F$1RG ; IS AN ARG PRESENT?
JRST CDES1 ; YES
PUSH CP,[MOVE VALUE,ESVAL] ; NO, GEN CODE TO RETURN ES FLAG
JRST CDCVAL ; AND CONTINUE CD
CDES1: PUSH CP,[MOVEM ARG,ESVAL] ; GEN CODE TO SET ES FLAG
JRST CDCRET ; AND CONTINUE CD
; CDEL - ELFILESPEC$ - SETUP FOR WRITING OR MODIFYING LOG FILE
;
; GEN: JSP PC,$$EL
; <FILE.SPEC>
; (RETURN)
CDEL: TXNE F,F$1RG ;[330] ARG PRESENT?
JRST CDEL1 ;[330] YES, TO MODIFY
PUSH CP,[JSP PC,$$EL] ;[330] GEN CALL TO $$EL
JRST CDEXX ;[330] GEN FILE SPEC AND CONTINUE CD
CDEL1: PUSH CP,[JSP PC,$$ELA] ;[330] GEN CALL TO $$ELA
JRST CDCRET ;[330] AND CONTINUE CD
; CDBKSL - \ OR N\ - RETURN VALUE OF NUMBER AFTER POINTER IN
; TEXT BUFFER OR INSERT ASCII REPRESENTATION OF N
CDBKSL: MOVE X,[JSP PC,$$BS1] ; FETCH THE CALL TO $$BS1
TXNN F,F$1RG ; IS IT "N\"?
HRRI X,$$BS2 ; NO, ITS "\"
PUSH CP,X ; GEN THE CALL TO $$BS1 OR $$BS2
TXNE F,F$1RG ; RETURN A VALUE?
JRST CDCRET ; NO. CONTINUE CD
JRST CDCVAL ; YES, CONTINUE CD
; CDLSB - [I - PUSH A Q-REGISTER ON THE Q-REGISTER PDL
CDLSB: PUSH CP,[JSP PC,$$PUSH] ; GEN CODE TO CALL $$PUSH
CDLSB1: PUSHJ P,MAKQNM ; GEN THE Q-REGISTER NAME INTO CODE
JRST CDCIGN ; AND CONTINUE CD
; CDRSB - ]I - POP THE Q-REGISTER PDL INTO A Q-REGISTER
CDRSB: TXNE F,F$COL ;[24000] :]q returns value always
TXO F,F$1RG ;[24000] so remember we did so
PUSH CP,[JSP PC,$$POP] ; GEN CODE TO CALL $$POP
JRST CDLSB1 ; FINISH CODE AND CONTINUE CD
SUBTTL Command Decoding and Compilation Subroutines
; GENCTM - GENERATE CALL TO "CHECK FOR TRACE MODE" ROUTINE
; IF IN TRACE MODE, THIS WILL CAUSE TEXT OF COMMAND TO BE TYPED.
;
; CALL: PUSHJ P,GENCTM
; (RETURN)
;
; GEN: JSP PC,$$CTM
; <CHAR POSITION IN BUFFER,,CHAR COUNT>
;
; NOTE: THE CHAR COUNT IS STORED AS ZERO AND THEN FILLED IN
; BY A CALL TO 'GENCT1' AFTER THE COMMAND HAS BEEN SCANNED.
; THE RELATIVE ADR OF THE ZERO WILL BE STORED IN AC CT.
;
; USES ACS X,T1,T4
GENCTM: MOVE X,EDVAL ;[11000] Will we ever want to trace this???
TXNE X,ED$OPT ;[11000]
POPJ P, ;[11000] Hope not
PUSH CP,[JSP PC,$$CTM] ; GEN THE CALL TO "CHECK FOR TRACE MODE"
PUSHJ P,CURCHA ; FETCH CURRENT CHAR ADR IN BUFFER
MOVSI X,-1(T1) ; . . .
PUSH CP,X ; AND GEN INTO CODE
; NOTE THAT CHAR COUNT WILL BE FILLED
; IN BY 'GENCT1'
MOVEI T4,(CP) ; FETCH CURRENT POSITION IN CODE
SUB T4,@CMDBUF ; MAKE IT A RELATIVE ADR
HRL T4,CMDCNT ; ALSO STORE THE CURRENT CHAR COUNT
POPJ P, ; AND RETURN TO CALLER
; GENCT1 - STORE THE CHAR COUNT IN THE LAST CALL TO "CHECK TRACE MODE"
;
; CALL: PUSHJ P,GENCT1
; (RETURN)
;
; USES ACS X,T1,T4
GENCT1: MOVE X,EDVAL ;[11000] Non-trace mode??
TXNE X,ED$OPT ;[11000] Bit on means no trace
POPJ P, ;[11000]
ADD T4,@CMDBUF ; MAKE IT ABSOLUTE POINTER TO DUMMY BP
HLRZ X,T4 ; FETCH THE OLD CHAR COUNT
SUB X,CMDCNT ; SUBTRACT THE CURRENT CHAR COUNT
AOJ X, ; MAKE IT THE ACTUAL CHAR COUNT (NOT -1)
HRRM X,(T4) ; AND STORE THE LENGTH OF TRACE
; MESSAGE IN CALL TO $$CTM
POPJ P, ; AND RETURN TO CALLER
>;; END FOR FTXTEC
FOR FTXTEC!FTXTCERR,<
; CURCHA - RETURN CURRENT CHARACTER ADDRESS IN BUFFER
;
; CALL: PUSHJ P,CURCHA
; (RETURN) ; WITH CHAR ADR IN AC T1
;
; USES AC T1
CURCHA: MOVE T1,@CMDBUF ; FETCH ADR OF COMMAND BUFFER
MOVE T1,(T1) ; FETCH # CHARS IN BUFFER
SUB T1,CMDCNT ; MINUS # LEFT IN BUFFER
MOVEI T1,5*T$DATA(T1) ; REMEMBER OVERHEAD WORDS BEFORE TEXT
POPJ P, ; AND RETURN TO CALLER
>;; END FOR FTXTEC!FTXTCERR
FOR FTXTEC,<
; MAKQNM -SCAN Q-REGISTER NAME AND GENERATE INTO CODE
;
; CALL: PUSHJ P,MAKQNM
; (RETURN)
;
; USES ACS C,N
MAKQNM: PUSHJ P,CMDGCH ; FETCH NEXT COMMAND CHAR
ERROR (MIQ) ; NONE LEFT. ** MISSING Q-REGISTER NAME **
;[15000] Breaks ^U command!
; TXZE F,F$DTM ;[14000] @-FORM?
; JRST MAKQN4 ;[14000] Yes @M'FOO'
CAIN C,"(" ; EXTENDED Q-REGISTER NAME?
AOJA C,MAKQN4 ; YES, PICK UP 6-CHAR NAME
CAIN C,33 ;[22000] Escape?
JRST MAKQN4 ;[22000] Yes, use ITS Teco form
CAIL C," " ;[10000] Too small?
CAILE C,172 ;[10000] Too big?
ERROR (IQN) ;[10000] YES
CAILE C,140 ;[10000] Lower case?
MOVEI C,-40(C) ;[10000] Yes, shift it
MAKQN1: MOVSI N,'A'-"A"(C) ; YES, CONVERT TO SIXBIT
LSH N,^D12 ; AND LEFT JUSTIFY
MAKQN2: PUSH CP,N ; AND GEN INTO CODE
POPJ P, ; RETURN TO CALLER
; PICK UP A 6-CHAR LETTER/DIGIT Q-REGISTER NAME
MAKQN4: PUSH P,[MAKQN2] ;[23000] Save the return address for POPJ
; CSIXT - Get a Q-register name into N. The delimiter is in C.
CSIXT: MOVE T3,C ;[23000] Save away terminator
MOVE T1,[POINT 6,N] ;[14000] Set up byte pointer to N
SETZ N, ;[14000] Start off fresh
CSIXTL: PUSHJ P,CMDGCH ;[14000] Next character
ERROR (UQN) ;[14000] lose
CAIN C,(T3) ;[14000] Is this our delimiter?
POPJ P, ;[14000] Yes, we're done
CAIGE C,40 ;[14000] Not a control, we hope
ERROR (UQN) ;[14000] byte the bag
CAIL C,140 ;[14000] Lower case range?
MOVEI C,-40(C) ;[14000] not any more
MOVEI C,-40(C) ;[14000] Convert to sixbit
TLNE T1,770000 ;[14000] Any room here?
IDPB C,T1 ;[14000] Store it
JRST CSIXTL ;[14000] Back for more
; GENQRG -SCAN Q-REGISTER NAME AND GENERATE INTO CODE
;
; CALL: PUSHJ P,GENQRG
; (RETURN 1) With terminator in C, Q-register-name in N
; (RETURN 2) With q-register name (ASCII) in C, Q-index in N
;
; USES ACS C,N
GENQRG: PUSHJ P,CMDGCH ; FETCH NEXT COMMAND CHAR
ERROR (MIQ) ; NONE LEFT. ** MISSING Q-REGISTER NAME **
CAIN C,"(" ; EXTENDED Q-REGISTER NAME?
AOJA C,.+2 ; YES, PICK UP 6-CHAR NAME
CAIN C,33 ;[22000] Escape?
PJRST CSIXT ;[22000] Yes, use ITS Teco form
CAIL C," " ;[10000] Too small?
CAILE C,172 ;[10000] Too big?
ERROR (IQN) ;[10000] YES
CAILE C,140 ;[10000] Lower case?
MOVEI C,-40(C) ;[10000] Yes, shift it
GENQR1: MOVEI N,'A'-"A"(C) ; YES, CONVERT TO SIXBIT
ASH N,1 ;[23000] 2 words per entry, pleeze
JRST CPOPJ1 ; RETURN TO CALLER
; FNDCH - FIND NEXT OCCURRANCE OF A CHARACTER IN COMMAND STRING
;
; CALL: MOVEI C,CHAR
; PUSHJ P,FNDCH
; (FAIL RETURN)
; (SUCCESS RETURN) ; WITH COUNT IN AC N OF CHARS SCANNED
;
; USES ACS C,T1
FNDCH: MOVEI T1,(C) ; SAVE THE CHAR TO BE SEARCHED FOR
SETZ N, ; CLEAR THE SCANNED CHAR COUNT
FNDCH1: PUSHJ P,CMDGCH ; FETCH NEXT COMMAND CHAR
POPJ P, ; NONE LEFT. GIVE FAIL RETURN TO CALLER
CAIE C,(T1) ; IS IT THE CHAR WE WANT?
AOJA N,FNDCH1 ; NO, COUNT IT AND CONTINUE SCAN
JRST CPOPJ1 ; YES, RETURN TO CALLER WITH SUCCESS RETURN
; UPCASE - UPCASE THE CHAR IN AC C IF IT IS A LOWER CASE LETTER
;
; CALL: MOVEI C,CHAR
; PUSHJ P,UPCASE
; (RETURN) ; WITH UPCASED CHAR IN AC C
;
; USES AC C
UPCASE: CAIG C,"Z"+40 ; IS CHAR LC?
CAIGE C,"A"+40 ; . . . ?
POPJ P, ; NO, JUST RETURN TO CALLER
TRZ C,40 ; YES, UPCASE THE CHAR
POPJ P, ; AND RETURN TO CALLER
; ARGK - IF NO ARG PRESENT GEN "-1" IF LAST OP WAS "SUB" OR "+1" IF NOT
;
; CALL: PUSHJ P,ARGK
; (RETURN) ; WITH CODE GENERATED TO KLUDGE ARG
;
; USES AC X
ARGK: TXNE F,F$1RG ; IS AN ARG PRESENT?
POPJ P, ; YES, NO SPECIAL KLUDGES
; NO ARG. GEN "-1" IF "-" SEEN OR "+1" IF "-" NOT SEEN
MOVE X,[MOVEI ARG,1] ; CODE FOR "+1"
TLNE T5,(4B8) ; WAS LAST OP "SUB"?
TLO X,(MOVNI) ; YES, GEN "MOVNI ARG,1"
PUSH CP,X ; STORE THE ARG KLUDGE CODE
HRLI T5,(MOVE ARG,) ;[402] SET POSSIBLE "SUB" TO "MOVE"
POPJ P, ; AND RETURN TO CALLER
COMMENT \ [14000] Allow control characters
; CHKNCC - GIVE ERROR IF CHARACTER IS A CONTROL CHAR
; (EXCEPT FOR THE COMMON OUTPUT CONTROL CHARACTERS)
;
; CALL: MOVEI C,CHAR
; PUSHJ P,CHKNCC
; (SUCCESS RETURN)
;
; 'ERROR (ICT)' IS GIVEN IF THE CHAR IS AN UN-COMMON CONTROL CHAR
;
; USES AC C
CHKNCC: CAIGE C,.CHSPC ; CHECK FOR CONTROL CHARS
CAIG C,.CHCRT ; . . .
CAIGE C,.CHCNH ; . . .
CAIN C,.CHESC ; . . .
POPJ P, ; NOT A CONTROL CHAR. GIVE SUCCESS RETURN TO CALLER
TXNE F,F$DTM ;[4000] DON'T WORRY IF @ TYPED BEFORE
POPJ P, ;[4000] JUST RETURN QUIETLY
CHKEO 2,CPOPJ ;[4000] ALLOW FOR 1EO ONLY
ERROR (ICT) ; YES, GIVE ERROR
\
; CHKITR - SKIP IF IN AN ITERATION
;
; CALL: PUSHJ P,CHKITR
; (NOT-IN-AN-ITERATION RETURN)
; (IN-AN-ITERATION RETURN)
;
; SMASHES ACS X,T1
CHKITR: MOVE T1,P ; COPY THE CONTROL PDP
; SEE IF AN ITERATION IS ON THE PDL (CONDITIONALS ALLOWED BEFORE IT)
CHKIT1: MOVE X,-1(T1) ; FETCH PDL FLAG
CAIN X,P$ITR ; IS IT AN ITERATION?
JRST CPOPJ1 ; YES, GIVE SUCCESS RETURN TO CALLER
SOJ T1, ; NO, GET READY TO BACKUP ON PDL
CAIN X,P$CON ; IS IT A CONDITIONAL?
SOJA T1,CHKIT1 ; YES, THEY'RE ALLOWED.KEEP LOOKING BACK
POPJ P, ; NO, GIVE FAIL RETURN TO CALLER
; CDCINS - SCAN AN INSERTION ARGUMENT
;
; CALL: PUSHJ P,CDCINS
; (RETURN)
;
; GEN: <CHAR.ADR,,CHAR.LENGTH>
;
; SMASHES ACS X,T1,T3,C
CDCINS: MOVE T3,DELIM ; FETCH THE DELIMITER CHAR
TXZN F,F$DTM ; ARE WE IN DELIMITED TEXT MODE?
JRST CDI1 ; NO
; FETCH THE DELIMITER CHAR FOR DELIMITED TEXT MODE
PUSHJ P,CMDGCH ; FETCH NEXT COMMAND CHAR
ERROR (UIN) ; NONE LEFT. ** UNTERMINATED INSERT **
MOVEI T3,(C) ; SAVE THE TEXT DELIMITER
CDI1: PUSHJ P,CURCHA ; FETCH THE CHAR ADR OF TEXT
MOVSI T2,(T1) ; AND SAVE FOR LATER. ALSO, RH OF T2
; IS CHAR COUNT(NOT SPECIALS) FOR TEXT
;[16000]TXZ F,F$CNT ; CLEAR THE ^T FLAG
; SCAN THE TEXT STRING TO COUNT CHARS AND CHECK VALID USE OF CONTROLS
CDI2: PUSHJ P,CMDGCH ; FETCH THE NEXT COMMAND CHAR
ERROR (UIN) ; NONE LEFT. ** UNTERMINATED INSERT **
CAIN C,(T3) ; IS IT THE DELIMITER CHAR?
JRST CDI4 ; YES. SCAN IS COMPLETE
; DO SPECIAL CHECKING IF THE CHAR IS A CONTROL CHAR
CDI2A:
MOVE T1,[IOWD CDIC1L,CDIC1+1] ; AOBJN POINTER FOR DISPATCH
; TXNE F,F$CNT ; ^T MODE? (IE: ^R AND ^T ARE ONLY SPECIALS)
; MOVE T1,[IOWD CDIC2L,CDIC2+1] ; YES, USE SHORT DISPATCH
PUSHJ P,DISPAT ; DISPATCH ON THE SPECIAL CONTROL CHAR
;[14000] Don't bitch about control characters
; TXNN F,F$CNT ; NOT A SPECIAL CONTROL. IN ^T MODE?
; PUSHJ P,CHKNCC ; NO, MAKE SURE CHAR IS NOT A CONTROL
CDI3: AOJA T2,CDI2 ; COUNT THE TEXT CHAR AND GO BACK FOR MORE
; DONE WITH SCAN OF TEXT STRING. STORE SOME INFO ABOUT IT IN CODE
CDI4: TLNE T3,777 ;[12000] 2-CHARACTER delimiter??
JRST [PUSHJ P,CMDGCH ;[12000] Look at next character
HLRZ T1,T3 ;[12000] and next char of delimiter
CAIN T1,C ;[12000] Are they the same?
JRST .+1 ;[12000] yes
PUSHJ P,CMDBCH ;[12000] no, back up!!
MOVEI C,(T3) ;[12000] first char matched, delimiter
JRST CDI2A] ;[12000] go back to scanning
PUSH CP,T2 ; GEN <CHARADR,,LENGTH> INTO CODE
POPJ P, ; AND RETURN TO CALLER
; DISPATCH TABLES FOR CONTROL CHARS IN INSERT TEXT STRINGS
CDIC1: <"V"-100,,CDI2>
<"W"-100,,CDI2>
<"^"-100,,CDI2>
CDIC2:; <"T"-100,,CDICT>
<"R"-100,,CDICR>
<"Q"-100,,CDICR> ;[16000] Win with ^Q also
CDIC2L==.-CDIC2
CDIC1L==.-CDIC1
; ^T - COMPLEMENT THE ^T MODE FLAG
;CDICT: TXC F,F$CNT ; COMPLEMENT THE ^T FLAG
; JRST CDI2 ; AND CONTINUE SCAN OF TEXT STRING
; ^R - TAKE THE NEXT CHAR AS TEXT
CDICR: PUSHJ P,CMDGCH ; FETCH NEXT COMMAND CHAR
ERROR (UIN) ; NONE LEFT. ** UNTERMINATED INSERT **
JRST CDI3 ; HIDE THE CHAR AND CONTINUE
; CDFSPC - SCAN A FILE SPEC AND GEN INTO CODE
;
; (SEE PARAMETER DEFINITIONS FOR STUCTURE OF A FILESPEC BLOCK)
CDFSPC: MOVEI X,CDFSP2 ; FETCH ADR OF ROUTINE THAT SCNS A CHAR
MOVEM X,INPADR ; AND STORE FOR 'GETCH' ROUTINE
SETZM INPCHR ; IN CASE A CHAR IS WAITING FROM BEFORE
STORE (X,FILSPC,FILSPC+FS$LTH-1,0) ; CLEAR THE FILE.SPEC
MOVEI L,FILSPC ; FETCH ADR OF FILE SPEC BLOCK
TXNN F,F$DTM ;[14000] @-type command
SKIPA C,DELIM ;[14000] No. use default delimiter
PUSHJ P,CMDGCH ;[14000] Yes, get delimiter
JFCL ;[24000] ...
PUSH P,T4 ; SAVE AC T4
PUSH P,C ;[14000] Save whatever delimiter it was
PUSHJ P,GFSPED ; AND SCAN THE FILE SPEC
POP P,X ;[14000] Get back delimiter
POP P,T4 ; RESTORE AC T4
CAME C,X ;[14000] See if that was it
ERROR (IFS) ; NO. ** ILLEGAL FILE SPEC **
; NOW GEN THE FILE SPEC INTO THE CODE
MOVE X,[IOWD FS$LTH,FILSPC+1] ; FETCH AOBJN PTR TO FILESPEC
CDFSP1: PUSH CP,(X) ; GEN A WORD OF THE FILESPEC
AOBJN X,CDFSP1 ; LOOP FOR ALL WORDS OF FILE SPEC
SETZM INPADR ; CLEAR ADR OF INPUT ROUTINE
POPJ P, ; AND RETURN TO CALLER
; ROUTINE TO SCAN A CHAR FOR FILE SPEC
; IGNORES: SPACE,TAB,<LF>,<VT>,<FF>,AND <CR>
CDFSP2: PUSHJ P,CMDGCH ; FETCH NEXT COMMAND CHAR
ERROR (UFS) ; NONE LEFT. ** UNTERMINATED FILE SPEC **
CAIE C,.CHSPC ; IS CHAR A SPACE?
CAIG C,.CHCRT ; OR TAB,<LF>,<VT>,<FF>, OR <CR> ?
CAIGE C,.CHTAB ; . . . ?
POPJ P, ; NO RETURN THE CHAR
JRST CDFSP2 ; YES, IGNORE THE CHAR
SUBTTL EXECUT - Execute a Command
; CALL: MOVEI L,ADRREF ; ADR OF REFERENCE TO COMMAND BUFFER
; PUSHJ P,EXECUT
; (RETURN)
;
; ADRREF: <BUFFER>
;
; BUFFER:
; --------------
; ! CHAR COUNT !
; !------------!
; ! REF. COUNT !
; !------------!
; ! BUFFER ID !
; !------------!
; ! !
; ! ASCII !
; ! !
; ! COMMAND !
; ! !
; !------------!
; ! !
; ! EXECUTABLE !
; ! !
; ! CODE !
; ! !
; --------------
;
; USES ALL ACS
EXECUT: MOVEM L,CMDBUF ; SAVE ADR OF REF TO COMMAND BUFFER
MOVE T1,@(L) ; FETCH # CHARS IN TEXT BUFFER
IDIVI T1,5 ; COMPUTE RELATIVE START ADR OF CODE
MOVEI T1,T$DATA(T1) ; ADD OVERHEAD WORDS FOR TEXT BUFFER
; FORMALIZE THE FACT THAT R AND CP REFERENCE THE BUFFER
MOVE R,(L) ; FETCH ADR OF COMMAND BUFFER
MOVE X,[<PC,,R>] ; FETCH ADRS OF AC REFS
MOVEM X,T$ACRF(R) ; AND BIND THE AC REFS TO BUFFER
; ENABLE FOR CASE FLAGGING (BASED ON EU FLAG)
TXZ F,F$NOF ; CLEAR THE "SUPPRESS CASE FLAGGING" FLAG
; CLEAR "LAST TEN COMMANDS" TABLE
STORE (X,TENIDX,TENIDX+^D10,0) ; CLEAR COMMAND TABLE
; BEGIN EXECUTION
ADDI T1,1(R) ; FIND BEGINNING OF CODE
MOVE SARG,SARGSV ;[3000] RESTORE 2ND ARGUMENT IF ANY
PUSHJ P,(T1) ; BEGIN EXECUTION OF CODE
HRRZS T$1REF(R) ; UNBIND FIXED REF TO BUFFER
SETZM T$ACRF(R) ; UNBIND AC REFS FROM BUFFER
SETZM @CMDBUF ;[14000] Clear pointer to buffer
POPJ P, ; AND RETURN TO CALLER
SUBTTL $CTM - TRACE MODE TYPE-OUT
; $CTM - CHECK FOR TRACE MODE. IF ON, TYPE TEXT
;
; CALL: JSP PC,$$CTM
; <CHAR ADR IN BUFFER,,CHAR COUNT>
; (RETURN)
$CTM: TXZE F,F$REE ;[317] WANT TO STOP NOW?
JRST ERRREC ;[317] YES, STOP!
AOS T1,TENIDX ; INCREMENT AND FETCH INDEX INTO CMD TABLE
IDIVI T1,^D10 ; MAKE ID MODULO 10.
MOVEM T2,TENIDX ; STORE THE NEW INDEX
PUSHJ P,NXTWRD ; FETCH ARG
MOVEM N,TENCMD(T2) ; STORE CMD INFOR IN THE TABLE FOR THE
; "LAST TEN COMMANDS"
TXNN F,F$TRC ; IN TRACE MODE?
JRST (PC) ; NO, RETURN
PUSHJ P,TMSG ; YES, TYPE THE COMMAND
JRST (PC) ; AND RETURN TO CALLER
SUBTTL $EH AND $EHS
; $EH - RETURN CURRENT MESSAGE LENGTH
;
; CALL: JSP PC,$$EH
; (RETURN) ; WITH VALUE IN AC VALUE
$EH: SETZ VALUE, ;[411] ASSUME ZERO
MOVE T1,EHVAL ; FETCH MESSAGE LENGTH
MOVSI X,-3 ; GET READY TO CONVERT TO A NUMBER
TDNE T1,JWTBL(X) ; BIT SET?
AOJ VALUE, ;[411] YES, INCREMENT MESSAGE LENGTH
AOBJN X,.-2 ; AND TRY FOR ALL POSSIBLE LENGTHS
JRST (PC) ; DONE, RETURN TO CALLER
; $EHS - SET THE MESSAGE LENGTH
;
; CALL: JSP PC,$$EHS ; WITH NEW LENGTH IN AC ARG
; (RETURN)
$EHS: CAILE ARG,3 ; ARG TOO LARGE?
MOVEI ARG,3 ; YES, USE LARGEST LEGAL
MOVX X,JW.WPR!JW.WFL ; FETCH DEFAULT LENGTH
JUMPLE ARG,.+2 ; SKIP IF ARG IS NEGATIVE
HRLZ X,JWTBL-1(ARG) ; FETCH LENGTH FROM TABLE
MOVEM X,EHVAL ; STORE THE NEW MESSAGE LENGTH
JRST (PC) ; AND RETURN TO CALLER
; JWTBL - TABLE FOR CONVERTING MESSAGE LENGTHS
JWTBL: <JW.WPR>_-^D18,,<JW.WPR>_-^D18
<JW.WFL>_-^D18,,<JW.WPR!JW.WFL>_-^D18
<JW.WCN>_-^D18,,<JW.WPR!JW.WFL!JW.WCN>_-^D18
SUBTTL $U AND $Q AND $INC
; $U - STORE ARG IN IN SPECIFIED Q-REGISTER
;
; CALL: JSP PC,$$U
; <Q-REGISTER NAME>
; (RETURN)
$U: PUSHJ P,NXTWRD ; FETCH Q-REGISTER NAME
MOVE T1,N ; INTO AC T1
PUSHJ P,QGET ;[12000] Save text in q-register
JRST [TXZN F,F$COL ;[23000] No q register
TDZA T2,T2 ;[23000] No text
MOVE T2,ARG ;[23000] Fabricate it
MOVE T3,ARG ;[23000] Numeric value always
PUSHJ P,QSTOR ;[23000] Store it
JRST (PC)] ;[23000] return
TXZE F,F$COL ;[23000] :U affects text also
MOVEM ARG,Q$PTR(T5) ;[23000] so put it there too
MOVEM ARG,Q$VAL(T5) ; AND STORE THE VALUE IN Q-REGISTER
JRST (PC) ; AND RETURN TO CALLER
; $Q - RETURN THE NUMERIC VALUE OF SPECIFIED Q-REGISTER
;
; CALL: JSP PC,$$Q
; <Q-REGISTER NAME>
; (RETURN) ; WITH NUMERIC VALUE IN VALUE
$Q: PUSHJ P,NXTWRD ; FETCH THE Q-REGISTER NAME
MOVE T1,N ; INTO AC T1
PUSHJ P,QGET ; FETCH THE Q-REGISTER
JRST FAIRET ; DOESN'T EXIST. RETURN ZERO
; TXNN T2,QB$NUM ; IS Q-REGISTER NUMERIC?
; JRST $Q1 ;[370] SEE IF TO TYPE ASCII Q-REG
$Q0: ;[3000] LABEL ADDED
SKIPE VALUE,T3 ; PUT NUMERIC VALUE IN AC VALUE
JRST (PC) ; AND RETURN TO CALLER
$Q1: MOVE X,4(PC) ;[374] FETCH NEXT INSTRUCTION
SKIPE N,T2 ;[23000] Get text if any
CAME X,[JSP PC,$$DEC] ;[370] QI= CONSTRUCTION?
JRST (PC) ;[23000] USE NUMERIC VALUE ANYWAY!
ADDI PC,5 ;[374] BUMP PC SO NOT TO CALL $DEC
MOVEI L,TMPRFG ;[370] TMPRFG WILL REFERENCE THE TEXT BUFFER
PUSHJ P,FNDBLK ;[370] FIND THE BLOCK WITH THE ID
ERROR (BNF) ;[370] EEK!!!!!!!
HRRZ T1,@TMPRFG ;[370] FETCH # OF CHARS
MOVE T3,[POINT 7,T$DATA] ;[370] LOAD BYTE POINTER TO Q-REG
ADD T3,TMPRFG ;[370] JUSTIFY IT TO Q-REG
$Q2: SOJL T1,$G2 ;[370] GO TO UNBIND ROUTINE IN $G WHEN DONE
ILDB C,T3 ;[370] GET A CHARACTER
PUSHJ P,TCCHR ;[370] TYPE THE CHARACTER
JRST $Q2 ;[370] TRY THE NEXT ONE
$QRX: ;[3000] RANDOM ACCESS Q REGISTER HACK
PUSHJ P,NXTWRD ;[3000] Q REGISTER NAME IS NEXT
MOVE T1,N ;[3000] SIXBIT NAME IN N
PUSHJ P,QGET ;[3000] GET IT
JRST FAIRET ;[3000] TREAT LIKE REGULAR FOR COMPATABLILTY
TXNN T2,QB$BID ;[3000] IS IT A TEXT Q REGISTER?
JRST $Q0 ;[12000] No do like numeric
MOVEI N,(T2) ;[3000] GET BID
PUSH P,SARG ;[3000] ALAS L AND SARG ARE 1 AND THE SAME
MOVEI L,TMPRFG ;[3000] TMPRFG WILL REFERENCE IT
PUSHJ P,FNDBLK ;[3000] GET THE TEXT BUFFER ITSELF
ERROR (XXX) ;[3000] ?
POP P,SARG ;[3000] RESTORE 2ND ARGUMENT IF ANY
TXZE F,F$COL ;[12000] :Q? (return # of characters)
JRST [MOVE VALUE,@TMPRFG ;[12000] Get character count
JRST $G2] ;[12000] Un-reference & continue execution
JUMPL ARG,$QRX2 ;[10000] Negative #'s are special case
CAML ARG,@TMPRFG ;[3000] MAKE SURE IT IS IN RANGE
CERROR (ARG) ;[3000] IT WASN'T
MOVE T1,ARG ;[3000] MAKE A BYTE POINTER
IDIVI T1,5 ;[3000] 5 CHARS/WORD
ADD T1,[POINT 7,T$DATA] ;[3000]
ADD T1,TMPRFG ;[3000]
IBP T1 ;[3000] FIND THE PLACE IN THE WORD
SOJGE T2,.-1 ;[3000]
LDB VALUE,T1 ;[3000] GET IT AS OUR VALUE
TXZE F,F$2RG ;[5000] CHECK & CLEAR THE ARG FLAG
;[3000] AND CLOBBER IT IF 2 ARGS GIVEN
DPB SARG,T1 ;[3000]
JRST $G2 ;[3000] DONE unreference & return
$QRX2: MOVMS ARG ;[10000]
CAIL ARG,QXNLEN ;[10000] CHECK RANGE
CERROR(ARG) ;[10000] LOSE
XCT QXNTBL(ARG) ;[10000] DO SOMETHING
QXNTBL: JRST $G2 ;[10000] Return
MOVE VALUE,@TMPRFG ;[10000] Get length of Q-REG text
PUSHJ P,[MOVE VALUE,TMPRFG ;[10000]
ADDI VALUE,3 ;[10000]
POPJ P,] ;[10000]
QXNLEN==.-QXNTBL ;[10000]
; $INC - ADD ARG TO A Q-REGISTER AND RETURN RESULTING VALUE
;
; CALL: JSP PC,$$INC
; (RETURN) ; WITH VALUE IN AC 'VALUE'
$INC: TXNE F,F$1RG ;[12000] Were we passed a value
SKIPA VALUE,ARG ;[12000] Yes, use it
MOVEI VALUE,1 ;[12000] No. default to 1
PUSHJ P,NXTWRD ; FETCH THE Q-REGISTER NAME
MOVE T1,N ; AND COPY INTO AC T1
PUSHJ P,QFIND ; FIND THE Q-REGISTER
JRST $INC0 ;[12000] No Q-register there yet
ADDB VALUE,Q$VAL(T5) ; YES, INCREMENT IT
JRST (PC) ;[12000] and return the value
$INC0: SETZ T2, ;[12000] Set no flags
MOVE T3,VALUE ;[12000] and value for q-register
PUSHJ P,QSTOR ; AND SET THE NEW VALUE OF Q-REGISTER
JRST (PC) ; AND RETURN TO CALLER
SUBTTL $PUSH AND $POP
; $PUSH - PUSH A Q-REGISTER ON THE Q-REGISTER PDL
;
; CALL: JSP PC,$$PUSH
; <Q-REGISTER NAME>
; (RETURN)
$PUSH: PUSHJ P,NXTWRD ; FETCH THE Q-REGISTER NAME
MOVE T1,N ; INTO AC T1
PUSHJ P,QGET ; FETCH THE Q-REGISTER
SETZB T2,T3 ;[23000] Use null q-reg
MOVEI N,(T2) ; FETCH POSSIBLE TEXT BUFFER ID
TXNE T2,QB$BID ; IS Q-REGISTER A TEXT BUFFER?
PUSHJ P,REFBLK ; YES, ADD ONE TO ITS REFERENCE COUNT
MOVE X,QP ; FETCH PQ PDL
AOBJN X,.+1 ; INCREMENT IT
EXCH X,QP ; AND STORE IT
PUSH X,T1 ; PUSH Q-REGISTER NAME
MOVE X,QP ; FETCH QPDL PDP
AOBJN X,.+1 ; INCREMENT Q PDL
EXCH X,QP ; AND STORE IT
PUSH X,T2 ; PUSH Q-REGISTER BITS
MOVE X,QP ; FETCH QPDL PDP
AOBJN X,.+1 ; INCREMENT IT
EXCH X,QP ; AND STORE IT
PUSH X,T3 ; PUSH Q-REGISTER VALUE/ID
JRST (PC) ; RETURN TO CALLER
; $POP - POP THE Q-REGISTER PDL INTO THE SPECIFIED Q-REGISTER
;
; CALL: JSP PC,$$POP
; <Q-REGISTER NAME>
; (RETURN)
$POP: PUSHJ P,NXTWRD ; FETCH THE Q-REGISTER NAME
MOVE T1,N ; INTO AC T1
MOVE X,QP ; FETCH Q PDL
POP X,T3 ; POP THE PUSHED VALUE
POP X,T2 ; POP THE PUSHED BITS
POP X,N ; POP THE PUSHED Q-REGISTER NAME
JUMPN N,.+2 ;[24000] Only empty if both of these are
JUMPE T2,[CERROR (PES)] ; ** POPPED EMPTY STACK **
MOVEM X,QP ; AND STORE THE UPDATED QPDL PDP
TXZ F,F$REF ; T3 DOES NOT CONTAIN TEXT BUFFER REFERENCE
; (IE: IT CONTAINS VALUE/TEXT BUFFER ID)
PUSHJ P,QSTOR ; STORE THE POPPED Q IN SPECIFIED Q-REGISTER
TXZE F,F$COL ;[25000] :]q should return -1 or 0
SETO VALUE, ;[25000] and we won if we got here
JRST (PC) ; AND RETURN TO CALLER
SUBTTL $DEC AND $OCT AND $CNE AND $CNN AND $FFD
; $DEC - TYPE ARG IN DECIMAL
;
; CALL: JSP PC,$$DEC
; (RETURN)
$DEC: MOVE N,ARG ; MOVE ARG INTO PROPER AC
PUSHJ P,TDEC ; AND TYPE IT IN DECIMAL
JRST $OCT1 ;[305] SEE IF MORE TO DO
; $OCT - TYPE ARG IN OCTAL
;
; CALL: JSP PC,$$OCT
; (RETURN)
$OCT: MOVE N,ARG ; MOVE ARG INTO ANOTHER AC
PUSHJ P,TOCT ; AND TYPE IT IN OCTAL
; SEE IF WE MUST SUFFIX NUMBER WITH ANYTHING
$OCT1: JUMPE SARG,(PC) ;[305] N.EQ.0 MEANS NOTHING TO SUFFIX. RETURN
JUMPG SARG,$OCT2 ;[305] N.GT.0 MEANS SUFFIX CHAR
; N.LT.0 MEANS SUFFIX CRLF TO OUTPUT unless ":" used
TXZN F,F$COL ;[12000] Skip CRLF if :=
PUSHJ P,TCRLF ;[305] SUFFIX A CRLF
JRST (PC) ;[305] AND RETURN TO CALLER
; N.GT.0 MEANS SUFFIX CHAR WHOSE CODE IS N TO OUTPUT
$OCT2: MOVEI C,(SARG) ;[305] FETCH THE CHAR TO OUTPUT
PUSHJ P,TCHR ;[305] TYPE THE CHAR
JRST (PC) ;[305] AND RETURN TO CALLER
; $CNE - RETURN VALUE OF THE FORMFEED FLAG (0=OFF,-1=ON)
;
; CALL: JSP PC,$$CNE
; (RETURN) ; WITH RESULT IN AC VALUE
$CNE: SETZ VALUE, ; FORMFEED FLAG IS OFF
TXNE F,F$FFD ; BUT IS IT?
SETO VALUE, ; NO, IT'S ON
JRST (PC) ; RETURN TO CALLER
; $CNN - RETURN THE VALUE OF THE END-OF-FILE FLAG (0=OFF,-1=ON)
;
; CALL: JSP PC,$$CNN
; (RETURN) ; WITH RESULT IN AC VALUE
$CNN: SETZ VALUE, ; THE EOF FLAG IS OFF
TXNE F,F$EOF ; BUT IS IT?
SETO VALUE, ; NO, IT'S ON
JRST (PC) ; RETURN TO CALLER
; $FFD - TYPE A FORMFEED
;
; CALL: JSP PC,$$FFD
; (RETURN)
$FFD: MOVE T1,ETVAL ;[10000] Clear screen & window if display
TXNE T1,ET$DPY ;[10000]
JRST [PUSHJ P,FOUT ;[12000] Force out pending text
OUTSTR HOME ;[12000] Go to top of screen
OUTSTR WIPES ;[12000] and clear it all
MOVSI T1,200000 ;[10000]
IORM T1, SCFWD ;[10000] Indicate window messed up
SETZM ROW ;[12000] Clear row...
SETZM COL ;[12000] ... and column
JRST (PC)] ;[10000]
MOVEI C,.CHFFD ; FETCH A FORMFEED CHAR
PUSHJ P,TCHR ; TYPE IT
JRST (PC) ; AND RETURN TO CALLER
$QCM: MOVE VALUE,ARG ;[10000] Value will be index in qreg
PUSHJ P,NXTWRD ;[10000] Q register name
MOVE T1,N ;[10000]
PUSHJ P,QGET ;[10000] Get the q-register
JRST FAIRET ;[16000] no such q-register
TXNN T2,QB$BID ;[10000] Must contain text
JRST FAIRET ;[16000] no such q-register
MOVEI N,(T2) ;[12000] Buffer ID
MOVEI L,TMPRFG ;[10000] This will reference it
PUSHJ P,FNDBLK ;[10000] Find the text buffer
ERROR (BNF) ;[10000] Ouch
MOVE T1,TMPRFG ;[10000] Addr of buffer
MOVEI T1,3(T1) ;[10000] Skip overhead words
MOVE T3,ARG ;[10000] Adjust the byte pointer
IDIVI T3,5 ;[10000]
ADDI T1,(T3) ;[10000] Add enough words
HLL T1,CBPTBL-1(T4) ;[10000]
MOVE T3,PTVAL ;[10000] Get "."
MOVE T2,@TXTBUF ;[10000] Get length of text buffer
SUB T2,T3 ;[10000] Subtract "." to get chars left
JUMPLE T2,$G2 ;[12000] At end of buffer already
JUMPL ARG,$G2 ;[10000] or too small
MOVE T4,@TMPRFG ;[10000] Get length of q-register
SUB T4,ARG ;[10000] subtract starting place therein
CAML T2,T4 ;[10000] use the lower limit
MOVE T2,T4 ;[10000]
IDIVI T3,5 ;[10000] Turn into a word
MOVEI T3,T$DATA(T3) ;[14000] Skip overhead words here so don't lose
HLL T3,CBPTBL-1(T4) ;[10000] and a byte pointer
ADD T3,TXTBUF ;[10000] to the current character
QCMLP: SOJL T2,$G2 ;[12000] See if we got to the end
ILDB C,T1 ;[10000] Get char from text buffer
ILDB T4,T3 ;[10000] and from q-register
CAIE C,(T4) ;[10000] are they the same?
JRST $G2 ;[10000] no. un-reference & return index to caller
PUSHJ P,UPDCDC ;[12000] Adjust cursor position
AOS PTVAL ;[10000] Move the pointer
AOJA VALUE,QCMLP ;[10000] bump index
; end $QCM
SUBTTL $UP AND $LOW AND CLRCAS AND $CX AND $CXS
; $UP - SET THE "UPCASE ALL TEXT" FLAG (OR CLEAR IF ARG.EQ.0)
;
; CALL: JSP PC,$$UP
; (RETURN)
$UP: JUMPE ARG,CLRCAS ; IF ARG.EQ.0 CLEAR ALL CASE FLAGS
TXZ F,F$DNC ; IF ARG.NE.0 THEN CLEAR "DOWNCASE" FLAG
TXO F,F$UPC ; AND SET THE "UPCASE" FLAG
JRST (PC) ; AND RETURN TO CALLER
; $LOW - SET THE "DOWNCASE ALL TEXT" FLAG (OR CLEAR IF ARG.EQ.0)
;
; CALL: JSP PC,$$LOW
; (RETURN)
$LOW: JUMPE ARG,CLRCAS ; IF ARG.EQ.0, CLEAR ALL CASE FLAGS
TXZ F,F$UPC ; IF ARG.NE.0, CLEAR "UPCASE" FLAG
TXO F,F$DNC ; AND SET THE "DOWNCASE" FLAG
JRST (PC) ; AND RETURN TO CALLER
; CLRCAS - CLEAR "UPCASE" AND "DOWNCASE" FLAGS
CLRCAS: TXZ F,F$UPC!F$DNC ; CLEAR FLAGS
JRST (PC) ; AND RETURN TO CALLER
; $CX - RETURN THE VALUE OF THE "EXACT SEARCH MODE" FLAG
;
; CALL: JSP PC,$$CX
; (RETURN) ; WITH VALUE IN AC VALUE
; ; -1=EXACT SEARCH MODE
; ; 0=BOTH UPPER&LOWER MATCH
$CX: TXNE F,F$CNX ; IN "EXACT SEARCH MODE"?
JRST SUCRET ; YES, RETURN VALUE OF -1
JRST FAIRET ; NO, RETURN VALUE OF 0
; $CXS - SET THE "EXACT SEARCH MODE" FLAG
;
; CALL: JSP PC,$$CXS
; (RETURN)
$CXS: TXZ F,F$CNX ; CLEAR THE "EXACT SEARCH MODE" FLAG
JUMPE ARG,(PC) ; RETURN IF CALLER WANTS IT CLEARED
TXO F,F$CNX ; NO, HE WANTS IT SET
JRST (PC) ; NOW RETURN TO CALLER
SUBTTL $CNZ and $MES and $NA
; $CNZ - CLOSE OUTPUT FILE AND EXEIT TO MONITOR COMMAND LEVEL
;
; CALL: JSP PC,$$CNZ
; (RETURN) ; IF USER TYPES "CONTINUE"
$CNZ: JRST $EX1 ; DO "EF^C"
; $MES - TYPE A MESSAGE (UNLESS IN TRACE MODE)
;
; CALL: JSP PC,$$MES
; <CHAR ADR IN BUFFER,,CHAR COUNT>
; (RETURN)
$MES: PUSHJ P,NXTWRD ; FETCH THE ARG
TXNN F,F$TRC ; IN TRACE MODE?
PUSHJ P,TMSG ; NO, TYPE THE MESSAGE
JRST (PC) ; AND RETURN TO CALLER
; $NA - RETURN THE ASCII VALUE OF THE CHAR FOLLOWING TEXT POINTER
;
; CALL: JSP PC,$$NA
; (RETURN)
$NA: MOVE T1,PTVAL ; FETCH "."
ADD T1,ARG ;[12000] Add the argument to this
JUMPL T1,.+2 ;[12000] error if negative result
CAML T1,@TXTBUF ;[24000] Check for out of bounds correctly
JRST SUCRET ;[16000] it is so return -1
PUSHJ P,GET ; FETCH THE CHAR AFTER "."
MOVE VALUE,C ; COPY THE VALUE
JRST (PC) ; AND RETURN TO CALLER
;[13000] Execute an arbitrary instruction (at your peril!!)
;CALL: JSP PC,$$EXE ;with instruction in ARG
; contents of SARG will be moved to VALUE first
$EXE: MOVE VALUE,SARG ;Most useful for UUO's
MOVEI X,CWVEC ;address of :W vector for TRMOPing
MOVE T5,EDVAL ;[13000] Get ED bits
XCT ARG ;do it
TXZA T5,ED$SKP ;[13000] remember that we didn't skip
TXO T5,ED$SKP ;[13000] or that we did
MOVEM T5,EDVAL ;[13000] save what ever we got
JRST (PC) ;[13000] Continue execution
SUBTTL $CKC and $CHA and $CKD and $CKV and $CKW
; $CKC - SKIP IF ARG IS ASCII CODE FOR A SYMBOL CONSTITUENT
; (IE: A-Z,0-9,%,.,$)
;
; CALL: JSP PC,$CKC
; (FAIL RETURN)
; (SUCCESS RETURN)
$CKC: MOVE C,ARG ; FETCH THE ARG CHARACTER
PUSHJ P,CHKAN ; IS IT CODE FOR A LETTER/DIGIT?
SKP ; NO, TRY AGAIN
JRST 1(PC) ; YES, GIVE SUCCESS RETURN
CAIE C,"%" ; IS CHAR "%"?
CAIN C,"$" ; OR "$"?
JRST 1(PC) ; YES, GIVE SUCCESS RETURN
MOVE X,EDVAL ;[14000] See if BLISS symbol const. set
TXNN X,ED$BLI ;[14000] Check bit (32ED)
JRST CKC0 ;[14000] It wasn't
CAIE C,"&" ;[14000] It was, so check for "&"
CAIN C,"_" ;[14000] Check for "_"
JRST 1(PC) ;[14000] Skip return
JRST (PC) ;[14000] regular return
CKC0: CAIN C,"." ; NO, IS IT "."?
JRST 1(PC) ; YES, GIVE SUCCESS RETURN
JRST (PC) ; NO, GIVE FAIL RETURN
; $CKA - SKIP IF ARG IS ASCII CODE FOR A LETTER (UPPER OR LOWER)
;
; CALL: JSP PC,$CKA
; (FAIL RETURN)
; (SUCCESS RETURN)
$CKA: CAIG ARG,"Z"+40 ; IS ARG WAY OUT OF RANGE?
CAIGE ARG,"A" ; . . . ?
JRST (PC) ; YES. GIVE FAIL RETURN
CAIGE ARG,"A"+40 ; NO, IS CHAR A LETTER?
CAIG ARG,"Z" ; . . . ?
JRST 1(PC) ; YES, GIVE SUCCESS RETURN
JRST (PC) ; NO, GIVE FAIL RETURN
; $CKD - SKIP IF ARG IS ASCII CODE FOR A DIGIT
;
; CALL: JSP PC,$CKD
; (FAIL RETURN)
; (SUCCESS RETURN)
$CKD: CAIG ARG,"9" ; IS ARG CODE FOR DIGIT?
CAIGE ARG,"0" ; . . . ?
JRST (PC) ; NO, GIVE FAIL RETURN
JRST 1(PC) ; YES, GIVE SUCCESS RETURN
; $CKV - SKIP IF ARG IS ASCII CODE FOR A LOWER CASE LETTER
;
; CALL: JSP PC,$CKV
; (FAIL RETURN)
; (SUCCESS RETURN)
$CKV: CAIG ARG,"Z"+40 ; IS ARG CODE FOR A LOWER CASE LETTER?
CAIGE ARG,"A"+40 ; . . . ?
JRST (PC) ; NO, GIVE FAIL RETURN
JRST 1(PC) ; YES, GIVE SUCCESS RETURN
; $CKW - SKIP IF ARG IS ASCII CODE FOR AN UPPER CASE LETTER
;
; CALL: JSP PC,$$CKW
;
; CALL: JSP PC,$$CKW
; (FAIL RETURN)
; (SUCCESS RETURN)
$CKW: CAIG ARG,"Z" ; IS ARG CODE FOR AN UPPER CASE LETTER?
CAIGE ARG,"A" ; . . . ?
JRST (PC) ; NO, GIVE FAIL RETURN
JRST 1(PC) ; YES, GIVE SUCCESS RETURN
; $CKR - Skip if argument is an alphanumeric ascii character
;
; CALL: JSP PC,$$CKR
; (Fail return)
; (Success return)
$CKR: MOVE C,ARG ;[14000] Get into character register
PUSHJ P,CHKAN ;[14000] Check for alphanumeric
JRST (PC) ;[14000] nope
JRST 1(PC) ;[14000] yes
SUBTTL $SEMF and $SEMZ and $SEM and $STOP
; $SEMF - JUMP OUT OF CURRENT ITERATION IF LAST SEARCH FAILED (ELSE CONTINUE)
;
; CALL: JSP PC,$$SEMF
; (RETURN IF LAST SEARCH SUCCEEDED)
$SEMF: TXNN F,F$LSF ; DID LAST SEARCH FAIL?
JRST (PC) ; NO, RETURN TO CALLER
JRST $SEM ; YES, JUMP OF OF CURRENT ITERATION
; $SEMZ - JUMP OUT OF CURRENT ITERATION IF ARG.EQ.0 (ELSE CONTINUE)
;
; CALL: JSP PC,$$SEMZ
; (RETURN IF ARG.LT.0)
$SEMZ: JUMPN ARG,(PC) ; RETURN TO CALLER IF ARG NON-ZERO
; JRST $SEM ; ARG.EQ.0. JUMP OUT OF CURRENT ITERATION
; $SEM - JUMP OUT OF CURRENT ITERATION
;
; CALL: JSP PC,$$SEM
$SEM: POP P,X ; POP "OUT OF ITERATION" ADR
ADDI X,(R) ; MAKE IT AN ABSOLUTE ADR
JRST (X) ; AND POP OUT OF THE ITERATION
; $STOP - STOP MACRO EXECUTION
;
; CALL: JSP PC,$$STOP
;
; DOES A "POPJ P," TO RETURN TO WHOEVER INVOKED THIS MACRO/COMMAND
$STOP: POPJ P, ;[13000] Return to caller
; JRST ERRREC ; SAME AS RECOVERING FROM AN ERROR
SUBTTL $R and $C and $J
; $R - MOVE THE BUFFER POINTER BACKWARDS N CHARS
;
; CALL: JSP PC,$$R
; (RETURN)
$R: MOVN ARG,ARG ; MAKE ARG FOR "R" INTO ARG FOR "C"
; $C - MOVE THE BUFFER POINTER AHEAD N CHARS
;
; CALL: JSP PC,$$C
; (RETURN)
$C: ADD ARG,PTVAL ; MAKE ARG FOR "C" INTO ARG FOR "J"
; $J - MOVE THE BUFFER POINTER TO A SPECIFIC POSITION
;
; CALL: JSP PC,$$J
; (RETURN)
$J: PUSHJ P,CHKARG ; CHECK THE ARG FOR VALIDITY
CERROR (POP) ; ** ATTEMPT TO MOVE POINTER OFF PAGE **
MOVEM ARG,PTVAL ; ARG IS OK. SET NEW "." VALUE
JRST SUCRET ; AND RETURN TO CALLER
SUBTTL $KL and $L and $D
; $KL - REMOVE LINES FROM TEXT BUFFER
;
; CALL: JSP PC,$$KL
; (RETURN)
$KL: PUSHJ P,EVL2RG ; CONVERT LINE ARG TO CHAR ADDRESSES
SKP ; AND FALL INTO $K
; $K - REMOVE TEXT BETWEEN TWO POINTS FROM THE TEXT BUFFER
;
; CALL: JSP PC,$$K
; (RETURN)
$K: PUSHJ P,CHK2RG ; MAKE SURE ARGS ARE IN BOUNDS OF BUFFER
MOVEM SARG,PTVAL ; ".":=N (OF N,M)
SUB ARG,SARG ; COMPUTE # CHARS TO BE DELETED
JUMPE ARG,(PC) ; RETURN TO CALLER IF NOTHING TO DELETE
; ELSE FALL INTO $D
; $D - DELETE SPECIFIED # CHARACTERS FROM MAIN TEXT BUFFER
;
; CALL: JSP PC,$$D
; (RETURN)
$D: MOVM T1,ARG ; SAVE ARG AS ARG FOR 'MKROOM'
ADD ARG,PTVAL ; TURN ARG INTO A BUFFER ADDRESS
PUSHJ P,CHKARG ; AND MAKE SURE IT'S BETWEEN B AND Z
CERROR (POP) ; ** ATTEMPT TO MOVE POINTER OFF PAGE **
CAMGE ARG,PTVAL ; DOING -ND?
MOVEM ARG,PTVAL ; YES, BACKUP THE POINTER
MOVN T1,T1 ; ARG TO MKROOM IS A NEGATIVE # TO DELETE
PUSHJ P,MKROOM ; DELETE THE CHARACTERS
JRST SUCRET ; AND RETURN TO CALLER
SUBTTL $TAB and $I and $NI and $L
; $I - INSERT A TEXT STRING INTO THE TEXT BUFFER AT CURRENT POSITION
;
; CALL: JSP PC,$$I
; <CHAR ADR OF TEXT,# TEXT CHARS>
; (RETURN)
$I: PUSHJ P,NXTWRD ; FETCH <CHARADR,,#CHARS>
HLRZ T1,N ; FETCH THE CHARADR
SOJ T1, ; 'CAUSE BP WILL BE INCREMENTED BEFORE USE
PUSHJ P,CTOBP ; AND CONVERT IT TO A BYTE POINTER
IOR T1,[Z 0(R)] ; BYTE POINTER IS RELATIVE TO CODE
MOVE T3,T1 ; SAVE THE BYTE POINTER FOR LATER
MOVEI N,(N) ; FETCH THE CHAR COUNT
TXZ F,F$$TX ; CLEAR TEXT MODE FLAGS
; MAKE ROOM IN THE TEXT BUFFER FOR THE INSERT TEXT
MOVEI T1,(N) ; FETCH # CHARS TO BE INSERTED
PUSH P,T3 ; SAVE AC T3
PUSH P,N ; SAVE AC N
PUSHJ P,MKROOM ; MAKE ROOM FOR THE INSERT TEXT
POP P,N ; RESTORE AC N
POP P,T3 ; RESTORE AC T3
; INSERT THE TEXT INTO THE BUFFER A CHAR AT A TIME
$I0: JUMPE N,(PC) ; RETURN TO CALLER IF INSERTION IS NULL
$I1: ILDB C,T3 ; FETCH NEXT CHAR FROM TEXT STRING
; CHECK FOR SPECIAL CONTROL CHARACTERS
MOVE T1,[IOWD $IT1L,$IT1+1] ; POINTER TO CTL CHAR DISPATCH TABLE
; TXNE F,F$CNT ; IN ^T MODE?
; MOVE T1,[IOWD $IT2L,$IT2+1] ; YES, USE SHORT DISPATCH TABLE
PUSHJ P,DISPAT ; DISPATCH ON SPECIAL CONTROL CHARS
$I3: PUSHJ P,CASE ; DO ANY REQUIRED CASE CONVERSIONS ON CCHAR
$I4: MOVE T1,PTVAL ; FETCH ADR OF WHERE CHAR WILL GO
PUSHJ P,PUT ; INSERT THE CHAR IN THE TEXT BUFFER AT "."
AOS PTVAL ; ".":="."+1
SOJG N,$I1 ; LOOP FOR ALL CHARS IN TEXT STRING
JRST (PC) ; DONE. RETURN TO CALLER
; DISPATCH TABLES FOR SPECIAL CONTROL CHARS IN INSERT TEXT STRINGS
$IT1: <"V"-100,,$ITV>
<"W"-100,,$ITW>
<"^"-100,,$ITU>
$IT2:; <"T"-100,,$ITT>
<"Q"-100,,$ITR> ;^Q & ^R are both quoting characters
<"R"-100,,$ITR>
$IT2L==.-$IT2
$IT1L==.-$IT1
; ^V - DOWNCASE FOLLOWING LETTER
; ^V^V - DOWNCASE LETTERS UNTIL END OF STRING OR FURTHER NOTICE
$ITV: PUSHJ P,CNV ; SET THE DOWNCASE FLAGS
JRST $I1 ; AND PROCESS NEXT CHAR
; ^W - UPCASE FOLLOWING LETTER
; ^W^W - UPCASE LETTERS UNTIL END OF STRING OR FURTHER NOTICE
$ITW: PUSHJ P,CNW ; SET UPCASE FLAGS
JRST $I1 ; AND PROCESS NEXT CHAR
; ^^ - INSERT LC EQUIVALENT OF FOLLOWING CHAR (@,[,\,],_)
$ITU: ILDB C,T3 ; FETCH THE NEXT CHAR
PUSHJ P,CNUAR ; DOWNCASE IF @,[,\,],OR _
JRST $I4 ; AND COUNT CHAR AND PROCESS NEXT CHAR
; ^R - QUOTE THE NEXT CHAR (IE: TAKE AS TEXT)
$ITR: ILDB C,T3 ; FETCH THE NEXT CHAR
JRST $I3 ; DO CASE CONVERSIONS AND STORE IN BUFFER
; ^T - COMPLEMENT ^T MODE FLAG (IN ^T MODE ONLY ^T AND ^R ARE SPECIAL)
;[16000] ^T mode removed as useless
;$ITT: TXC F,F$CNT ; COMPLEMENT THE ^T MODE FLAG
; JRST $I1 ; AND PROCESS NEXT CHAR
; $NI - INSERT ASCII CHARACTER FOR CODE IN ARG IN TEXT BUFFER AT "."
;
; CALL: JSP PC,$$NI
; (RETURN)
$NI: MOVE C,ARG ; COPY ARG INTO AC C
PUSHJ P,INSCHR ; PUT CHAR INTO BUFFER AT "."
JRST (PC) ; AND RETURN TO CALLER
; $L - MOVE BUFFER POINTER AHEAD AN ARBITRARY NUMBER(-,0,+) OF LINES
;
; CALL: JSP PC,$$L
; (RETURN)
$L: PUSHJ P,EVL2RG ; CONVERT LINE ARG TO STRING ADDRESSES
MOVEM T4,PTVAL ; PTVAL:=ADR OF NTH LINE
JRST (PC) ; RETURN TO CALLER
; $CNQ - return # of characters in next n lines
$CNQ: PUSHJ P,EVL2RG ;[12000] Convert to string addresses
MOVE VALUE,ARG ;[12000] The value to return...
SUB VALUE,SARG ;[12000] is the difference between them
JRST (PC) ;[12000] Return it
; $E - go to END of specified line
;
;CALL: JSP PC,$$E
; (RETURN)
$E: PUSHJ P,EVL2RG ;[12000]
$E1: CAMN T4,@TXTBUF ;[12000] At end of buffer?
JRST $E9 ;[12000] Yes, stay there
PUSHJ P,GETINC ;[12000] Get next character
CAIN C,15 ;[12000] Stop on <CR> or any line terminator
SOJA T4,$E9 ;[12000] do so
PUSHJ P,CHKEOL ;[12000] ...
JRST $E1 ;[12000] try next charcter
SOJ T4, ;[12000] it was a terminator, back over it
$E9: MOVEM T4,PTVAL ;[12000] save result
JRST (PC) ;[12000] Return to caller
SUBTTL $BS1 and $BS2
; $BS1 - N\ - INSERT ASCII REPRESENTATION OF N TO RIGHT OF "."
;
; CALL: JSP PC,$$BS1
; (RETURN)
$BS1: MOVEI X,[AOJA T1,CPOPJ] ; TO COUNT # DIGITS IN NUMBER
MOVEM X,OUTADR ; SAVE ADR OF "OUTPUT" A CHAR ROUTINE
SETZ T1, ; CLEAR THE COUNT OF CHARS IN NUMBER
MOVE N,ARG ; FETCH THE NUMBER
PUSHJ P,TDEC ; COMPUTE # DIGITS IN NUMBER
PUSHJ P,MKROOM ; MAKE ROOM FOR THE NUMBER
MOVEI X,[AOS T1,PTVAL ; TO PUT ASCII CHARS IN THE TEXT BUFFER
SOJA T1,PUT] ; . . .
MOVEM X,OUTADR ; SAVE ADR OF OUTPUT A CHAR ROUTINE
MOVE N,ARG ; FETCH THE NUMBER AGAIN
PUSHJ P,TDEC ; AND STORE THE ASCII REPRESENTATION
; IN THE TEXT BUFFER
SETZM OUTADR ; DO NORMAL OUTPUT NOW
JRST (PC) ; AND RETURN TO CALLER
; $BS2 - \ - RETURN THE VALUE OF THE NUMBER REPRESENTED BY THE DIGITS
; (POSSIBLY +/- SIGN) FOLLOWING ".". "." IS POSITIONED
; AFTER THE LAST DIGIT OR CHAR OF NUMBER
;
; CALL: JSP PC,$$BS2
; (RETURN) ; WITH VALUE IN AC VALUE
$BS2: SETZ VALUE, ; CLEAR THE VALUE
TXZ F,F$1RG ; USED TO REMEMBER THAT "-" SEEN
MOVE T4,PTVAL ; FETCH "."
CAML T4,@TXTBUF ; AT END OF BUFFER?
JRST $BS23 ; YES, RETURN ZERO
$BS20: PUSHJ P,GETINC ; NO. FETCH CHAR FROM BUFFER
CAIN C,"+" ; IS IT "+" SIGN?
JRST $BS20 ; YES, IGNORE "+"
CAIE C,"-" ; IS IT "-" SIGN?
JRST $BS22 ; NO
TXO F,F$1RG ; YES, FLAG THAT "-" SEEN
$BS21: CAML T4,@TXTBUF ; AT END OF BUFFER?
JRST $BS23 ; YES
PUSHJ P,GETINC ; NO, FETCH NEXT CHAR
$BS22: CAIG C,"9" ; IS IT A DIGIT?
CAIGE C,"0" ; . . . ?
SOJA T4,$BS24 ; NO
IMULI VALUE,^D10 ; YES, MAKE ROOM FOR THE DIGIT
ADDI VALUE,-"0"(C) ; AND ADD IN THE DIGIT
JRST $BS21 ; AND TRY FOR ANOTHER DIGIT
$BS23: MOVE T4,@TXTBUF ; FETCH Z
$BS24: TXNE F,F$1RG ; A "-" SIGN SEEN?
MOVN VALUE,VALUE ; YES, NEGATE THE NUMBER
MOVEM T4,PTVAL ; POSITION "." AFTER THE NUMBER
JRST (PC) ; AND RETURN TO CALLER
SUBTTL $TTC
; $TTC - GENERAL PURPOSE TTCALL ROUTINE
;
; CALL: JSP PC,$$TTC ; WITH TTCALL # IN AC ARG
; (RETURN)
$TTC: PUSHJ P,FOUT ;[16000] Force out pending output
TXZ F,F$COL ;[12000] Clear ':' flag
MOVE VALUE,SARG ; SO THAT OUTCHR,SETLCH, AND IONEOU WILL WORK
MOVX T1,1B0 ; INIT POINTER INTO BIT MAP
MOVNI X,(ARG) ; MAKE RIGHT SHIFT COUNT FROM TTCALL #
LSH T1,(X) ; FORM POINTER INTO BIT MAP
CAIG ARG,^D35 ; IS TTCALL # IN RANGE?
TDNN T1,TTLMAP ; . . . ?
ERROR (ITT) ; NO, ** ILLEGAL TTCALL **
TDNE T1,TTXMAP ;[11000] Is this one special
JRST $TTC2 ; YES, DO SPECIAL KLUDGE
LSH ARG,^D23 ; PUT TTCALL # IN AC FIELD
IOR ARG,[TTCALL 0,VALUE] ; AND FROM A TTCALL INSTRUCTION
$TTC0: XCT ARG ; EXECUTE IT
JRST $TTC1 ; IT DIDN'T SKIP
TDNN T1,TTVMAP ; HAVE A VALUE WHEN IT SKIPS?
SETO VALUE, ; YES, SET VALUE:=.TRUE.
JRST (PC) ; NO, HAS ITS OWN VALUE. RETURN TO CALLER
; TTCALL DIDN'T SKIP
$TTC1: TDNE T1,TTSMAP ; WAS TTCALL A "SKIP" TYPE?
JRST FAIRET ; YES, RETURN VALUE OF ZERO FOR NON-SKIP RET
JRST (PC) ; NO, HAS ITS OWN VALUE
;
; Some terminal-related functions that aren't TTCALL's [11000]
;
$TTC2: CAIE ARG,^D8 ;[11000] Is this RESCAN or CCL?
JRST [SKIPN SARG ;[11000] 1 OR 2 ARGS?
SKIPA ARG,TT1VEC-^D16(ARG) ;[11000] 1 ARGUMENT
MOVE ARG,TT2VEC-^D16(ARG) ;[11000] 2 ARGS
JRST $TTC0] ;[11000] and execute it
; SPECIAL KLUDGE FOR RESCAN TTCALL
;
; IF AC SARG.EQ.0 DO A "RESCAN 1", ELSE TAKE ON VALUE ON CCL FLAG
MOVE X,[RESCAN 1] ; FETCH THE "RESCAN" INSTRUCTION
JUMPE SARG,$TTC3 ; WANT TO CHECK CCL FLAG?
MOVE X,[TXNE (F,F$CCL)] ; YES, FETCH PROPER INSTRUCTION
$TTC3: XCT X ; PERFORM THE INSTRUCTION (WHATEVER IT IS)
JRST SUCRET ; SUCCESS RETURN. VALUE:=.TRUE.
JRST FAIRET ; FAIL RETURN. VALUE:=.FALSE.
TT1VEC: MOVE VALUE,INPCHR ;[11000] Get saved character
GETSTS TTYC,VALUE ;[11000] Get status of TTY
TT2VEC: HRRZM SARG,INPCHR ;[11000] Save char for typein
SETSTS TTYC,(SARG) ;[11000] SETSTS for TTY
; BIT MAPS FOR TTCALLS
TTLMAP: <^B111011111111110011,,0> ; MAP OF LEGAL TTCALL #'S
TTXMAP: <^B000000001000000011,,0> ; Map of args that are not TTCALLS
TTSMAP: <^B001001000001100000,,0> ; MAP OF TTCALLS THAT SKIP
TTVMAP: <^B101011100000000000,,0> ; [10000] TTCALLS that return values
$TRMO: ;[10000] Generalized TRMOP. routine
MOVE T3,SARG ;[10000] Second argument is arg to TRMOP.
MOVE T1,ARG ;[10000] Function code is first arg
PUSHJ P,FOUT ;[12000] Force out pending terminal output
MOVE VALUE,[2,,T1] ;[10000] Arg block will be in T1-T3
MOVE T2,OURTTY ;[12000] Get our terminal number
TXZE F,F$2RG ;[11000] if there is any,that is
HRLI VALUE,3 ;[10000] Make length of arglist=3
TRMOP. VALUE, ;[10000] DO IT
JRST FAIRET ;[10000] It didn't work
JRST (PC) ;[10000] Return value, if any
; $GETC: Get command into q-register
; CALL: JSP PC,$$GETC
; <Q.REG.NAME>
; (RETURN)
$GETC:
ECHO ON ;[21000] Always echo this
PUSHJ P,GETCMD ;[15000] Do it
TDZA VALUE,VALUE ;[15000] user typed ^G^G or something
SETO VALUE, ;[15000] Got something ...
MOVX X,ET$SUP ;[21000] See if echo should be off
TDNE X,ETVAL ;[21000] i.e., ET & 8 = 8
ECHO OFF ;[21000] Turn echo back off again
PUSH P,N ;[15000] Save BID of cmd buffer
PUSHJ P,REFBLK ;[21000] Bump the reference count
PUSHJ P,NXTWRD ;[15000] Get q register name
MOVE T1,N ;[15000] into T1 for QGET
POP P,N ;[15000] Get back BID
PUSHJ P,QGET ;[15000] try to get q-register
SETZB T2,T3 ;[15000] no sweat
HRRI T2,(N) ;[15000] New BID
TXO T2,QB$BID ;[15000] text flag now on
TXZ F,F$REF ;[15000] This is a BID not a pointer
PUSHJ P,QSTOR ;[15000] Store away...
JRST (PC) ;[15000] Return
; $TCHR - type (& log) a character
; CALL: MOVX ARG,char
; JSP PC,$$TCHR
; (RETURN)
$TCHR: MOVEI C,(ARG) ;[12000] Character to type
PUSHJ P,TCCHR ;[12000] always type nice
PUSHJ P,FOUT ;[16000] Force it out now
JRST (PC) ;[12000] continue execution
; $GCHR - Input a character from terminal (AND LOG IT!)
; CALL: JSP PC,$$GCHR
; (return with character in VALUE, or -1 if no char and ET$NST set)
$GCHR: PUSHJ P,FOUT ;[16000] Force out output first
$GCHR0: SKIPE VALUE,INPCHR ;[20000] Do we have a character somewhere
JRST [SETZM INPCHR ;[20000] Only once please
JRST (PC)] ;[20000] Yes, use it
MOVX X,ET$NST ;[16000] no stall set?
FOR TOPS10!TOPS20,<
TDNE X,ETVAL ;[16000] no stall set?
JRST [INCHRS VALUE ;[16000] Try to get a character
JRST SUCRET ;[16000] didn't, return -1
JRST (PC)] ;[16000] did, return character
$GCHRW: INCHRW VALUE ;[16000] Wait until the cows come home
>
TXNN F,F$LOG ;[16000] Log this?
JRST (PC) ;[16000] No log file at all
MOVX X,FB$NOO ;[16000] log input?
TDNE X,LELSPC+FS$FLG ;[16000] ...
PUSHJ P,LOGPH1 ;[16000] log it
JRST (PC) ;[16000] continue
; $FF2 - m,nFF - adjust cursor co-ordinates (FX,FY) as if we had done m,nT
$FF2: PUSHJ P,CHK2RG ;[12000] Make sure args in bounds
MOVE T4,SARG ;[12000] Starting point
SUB ARG,SARG ;[12000] # of chars
FF2LP:! SOJL ARG,(PC) ;[12000] exit if done
PUSHJ P,GETINC ;[12000] Get a character
PUSHJ P,UPDCDC ;[12000] Update FX & FY
JRST FF2LP ;[12000] back for more
$FF1: MOVE T5,ARG ;[12000] We will put the row
ADD T5,ROW ;[12000] we want to be in in T5
MOVE T4,PTVAL ;[12000] Start at .
PUSH P,ROW ;[14000] Save current row
PUSH P,COL ;[14000] and column
PUSH P,LENGTH ;[15000] and length of screen
SETZM ROW ;[12000] Initialize row
SETZM COL ;[12000] & col, start at beginning
HRLOI X,377777 ;[15000] Make length very large
MOVEM X,LENGTH ;[15000] indeed
FF1L: CAMLE T4,@TXTBUF ;[12000] Check for end of buffer
JRST FF1Z ;[12000] hit it, finish up
PUSHJ P,GETINC ;[12000] Get a character
PUSHJ P,UPDCDC ;[12000] move cursor position
JUMPL ARG,[CAMLE T5,ROW ;[12000] Got to right row yet?
JRST FF1L ;[12000] No, keep going
JRST FF1Z] ;[12000] yes, finish up
CAML T5,ROW ;[12000] must go past it first
JRST FF1L ;[12000] not yet...
SOJ T4, ;[12000] Yes, back up into it again
FF1Z: SOS VALUE,T4 ;[12000] Undo the INC from GETINC
POP P,LENGTH ;[15000] Put back length of screen
POP P,COL ;[14000] Restore old co-ordinates
POP P,ROW ;[14000] ...
JRST (PC) ;[12000] continue execution
SUBTTL $S and $N
; $S - SEARCH FOR AN OCCURRANCE OF A STRING IN THE TEXT BUFFER
;
; CALL: JSP PC,$$S
; <CHAR.ADR,,<X>B18+TEXT.LENGTH>
; ; CHAR.ADR:=ADR OF SEARCH ARGUMENT
; ; X:=0 IF BOTH LC AND UC LETTERS MATCH
; ; X:=1 IF EXACT SEARCH MODE
; ; TEXT.LENGTH IS LENGTH OF SEARCH ARGUMENT
; (RETURN)
$S: JUMPGE ARG,$S1 ; IF FORWARD SEARCH, THEN DO IT NOW
$S0: MOVE T4,@TXTBUF ; REVERSE BOUNDS FOR MINUS SEARCH
SETZ T5, ; . . .
MOVM ARG,ARG ; AND MAKE REPEAT FACTOR POSITIVE
PUSHJ P,BSERCH ; PERFORM THE SEARCH
JRST $SF ; SEARCH FAILED
JRST (PC) ; SEARCH SUCCEEDED. RETURN TO CALLER
$S1: PUSHJ P,SERCH ; DO THE FORWARD SEARCH
JRST $SF ;[14000] ** SEARCH FAILED **
JRST (PC) ; SEARCH SUCCEEDED. RETURN TO CALLER
$SF: TXNE F,F$2CO ;[14000] ::S never steps on pointer
JRST $SF1 ;[14000] so don't
MOVE X,EDVAL ;[14000] Preserve pointer?
TXNN X,ED$SSF ;[14000] IF SET
$SF0: SETZM PTVAL ;[14000] step on it
$SF1: CERROR (SRH) ;[14000] ** SEARCH FAILED **
JRST (PC) ;[14000] Recover from it?
; $N - NON-STOP SEARCH FOR A STRING
;
; CALL: JSP PC,$$N
; <CHAR.ADR,,<X>B18+TEXT.LENGTH>
; ; CHAR.ADR:=ADR OF SEARCH ARGUMENT
; ; X:=0 IF BOTH LC AND UC LETTERS MATCH
; ; X:=1 IF EXACT SEARCH MODE
; ; TEXT.LENGTH IS LENGTH OF SEARCH ARGUMENT
; (RETURN)
$N: JUMPL ARG,$S0 ; BACKWARDS SEARCH (ONLY IN CURRENT BUFFER)
$N1: PUSHJ P,SERCH ; SEARCH REST OF CURRENT BUFFER
SKP ; SEARCH FAILED
JRST (PC) ; SEARCH SUCCEEDED. RETURN TO CALLER
SETZ T4, ; GET READY TO PUNCH OUT ENTIRE BUFFER
MOVE T5,@TXTBUF ; . . .
PUSHJ P,PUNCH ; PUNCH OUT THE ENTIRE BUFFER
MOVEI C,.CHFFD ; GET READY IN CASE <FF> CHAR NEEDED
TXNE F,F$FFD ; NEED <FF> AT END OF BUFFER?
PUSHJ P,@PCHADR ; YES, PUNCH A <FF> CHAR
TXNE F,F$EOF ; AT END OF FILE?
JRST [PUSHJ P,YANK ; YES, YANK THE BUFFER CLEAR
CERROR (SRH)] ; AND GIVE SEARCH FAIL ERROR
PUSHJ P,YANK ; NO, YANK THE NEXT BUFFER
SOJA PC,$N1 ; BACKUP PC TO <CHAR.ADR,,CHAR.LENGTH>
; AND CONTINUE SEARCH IN NEXT PAGE
SUBTTL $BAR , $EBAR
; $BAR - NON-STOP SEARCH FOR A STRING (NO OUTPUT)
; $BAR & $EBAR are the same except that $EBAR does not check for 2ED
;
; CALL: JSP PC,$$BAR
; <CHAR.ADR,,<X>B18+TEXT.LENGTH>
; ; CHAR.ADR:=ADR OF SEARCH ARGUMENT
; ; X:=0 IF BOTH LC AND UC LETTERS MATCH
; ; X:=1 IF EXACT SEARCH MODE
; ; TEXT.LENGTH IS LENGTH OF SEARCH ARGUMENT
; (RETURN)
$BAR: TXNN F,F$UWR ;[16000] _ OK if no output file
JRST $EBAR ;[16000] ....
MOVE X,EDVAL ;[14000] Check for 2ED
TXNN X,ED$YOK ;[14000] Procede if set
CERROR (YCA) ;[14000] not allowed
$EBAR: JUMPL ARG,$S0 ; BACKWARDS SEARCH (ONLY IN CURRENT BUFFER)
$BAR1: PUSHJ P,SERCH ; SEARCH REST OF CURRENT BUFFER
SKP ; SEARCH FAILED
JRST (PC) ; SEARCH SUCCEEDED. RETURN TO CALLER
TXNE F,F$EOF ; SEARCH FAILED. AT END OF FILE?
JRST $SF0 ; YES, STOP SEARCHING
PUSHJ P,YANK ; READ NEXT BUFFER
SOJA PC,$BAR1 ; POINT PC TO SEARCH ARGUMENT
; AND TRY THE SEARCH AGAIN IN NEXT BUFFER
SUBTTL $BSL, $BS and $FS
; $BSL - Line mode bounded search
;
; CALL: JSP PC,$$BSL
; <CHAR.ADR,,<X>B18+TEXT.LENGTH>
; ; CHAR.ADR:=ADR OF SEARCH ARGUMENT
; ; X:=0 IF BOTH LC AND UC LETTERS MATCH
; ; X:=1 IF EXACT SEARCH MODE
; ; TEXT.LENGTH IS LENGTH OF SEARCH ARGUMENT
; (RETURN)
$BSL: JUMPGE ARG,.+2 ;[15000] Not minus search
TXOA F,F$MSR ;[15000] Is minus search
TXZ F,F$MSR ;[15000] no indeed!
PUSHJ P,EVL2RG ;[14000] Convert line args to char args
TXNE F,F$MSR ;[15000] Reverse args for -nFB
EXCH ARG,SARG ;[15000] so it will be a backwards search
;[14000] and fall into $BS
; $BS - SEARCH FOR AN OCCURRANCE OF A STRING WITHIN SPECIFIED BOUNDS
;
; CALL: JSP PC,$$BS
; <CHAR.ADR,,<X>B18+TEXT.LENGTH>
; ; CHAR.ADR:=ADR OF SEARCH ARGUMENT
; ; X:=0 IF BOTH LC AND UC LETTERS MATCH
; ; X:=1 IF EXACT SEARCH MODE
; ; TEXT.LENGTH IS LENGTH OF SEARCH ARGUMENT
; (RETURN)
$BS: TXO F,F$MSR ; SET THE MINUS SEARCH FLAG
CAML ARG,SARG ;[314] MINUS SEARCH?
TXZA F,F$MSR ; NO, CLEAR FLAG
EXCH SARG,ARG ; Exchange arguments
PUSHJ P,CHK2RG ; CHECK THE ARGS FOR VALIDITY
;[14000]MOVEM SARG,PTVAL ; ".":=LOWER BOUND
TXZE F,F$MSR ; MINUS SEARCH?
EXCH SARG,ARG ; YES, REVERSE THE ARGS
MOVE T4,SARG ; FETCH THE LOWER BOUND
MOVE T5,ARG ; FETCH THE UPPER BOUND
MOVEI ARG,1 ;[314] SEARCH FOR FIRST OCCURRANCE
PUSHJ P,BSERCH ; AND DO THE SEARCH
CERROR (SRH) ;[14000] ** SEARCH FAILED **
JRST (PC) ; SEARCH SUCCEEDED. RETURN TO CALLER
; $FS - SUBSTITUTE A STRING FOR THE LAST SEARCH STRING
;
; CALL: JSP PC,$$FS
; <CHAR.ADR,,CHAR.LENGTH>
; (RETURN)
$FS: PUSHJ P,NXTWRD ; FETCH <ADR,,LEN>
TXNE F,F$LSF ; DID LAST SEARCH FAIL?
JRST (PC) ; YES, DON'T INSERT TEXT STRING
MOVEI T1,(N) ; FETCH INSERTION LENGTH (IN CHARS)
MOVE X,PTVAL ; FETCH VALUE OF "."
SUB X,SRHLEN ; MINUS LENGTH OF LAST SEARCH MATCH
MOVEM X,PTVAL ; POSITION "." BEFORE LAST SEARCH ARG
SUB T1,SRHLEN ; MINUS LENGTH OF LAST SEARCH MATCH
PUSHJ P,MKROOM ; ADJUST BUFFER FOR INSERTION
HLRZ T1,-1(PC) ; FETCH CHAR.ADR
SOJ T1, ; 'CAUSE BP WILL BE INCREMENTED BEFORE USE
PUSHJ P,CTOBP ; CONVERT IT TO A BYTE POINTER
IOR T1,[Z 0(R)] ; BYTE POINTER IS RELATIVE TO CODE
MOVE T3,T1 ; SAVE THE BYTE POINTER FOR LATER
TXZ F,F$$TX ; CLEAR TEXT MODE FLAGS
HRRZ N,-1(PC) ; FETCH # CHARS TO BE INSERTED
JRST $I0 ; AND DO THE INSERT
SUBTTL $TL and $T and $0TT
; $TL - TYPE LINES FROM TEXT BUFFER
;
; CALL: JSP PC,$$TL
; (RETURN)
$TL: PUSHJ P,TYPEL ; CALL THE "TYPE LINES" ROUTINE
JRST (PC) ; AND RETURN TO CALLER
; $T - TYPE TEXT BETWEEN TWO POINTS FROM THE TEXT BUFFER
;
; CALL: JSP PC,$$T
; (RETURN)
$T: PUSHJ P,TYPE ; CALL THE "TYPE" ROUTINE
JRST (PC) ; AND RETURN TO CALLER
; $0TT - TYPE CURRENT LINE IF LAST SEARCH SUCCEEDED AND ES.NE.0
;
; CALL: JSP PC,$$0TT
; (RETURN)
$0TT: TXNN F,F$LSF ; DID LAST SEARCH FAIL?
SKIPN ESVAL ; OR SEARCH AUTOTYPE FLAG OFF?
JRST (PC) ; YES, SKIP THE SEARCH AUTOTYPE
SETZ ARG, ; TYPE UP TO CURRENT POSITION ON LINE (IE: "0T")
PUSHJ P,TYPEL ; . . .
SKIPG C,ESVAL ; FETCH THE SEARCH TYPE CHAR
JRST $0TT1 ; DON'T TYPE SEARCH MARKER
CAIGE C,.CHSPC ; IS SEARCH MARKER A CONTROL CHAR?
MOVEI C,.CHLFD ; YES, SUBSTITUTE A <LF>
PUSHJ P,TCHR ; TYPE THE SEARCH MARKER CHAR
$0TT1: MOVEI ARG,1 ; TYPE REST OF CURRENT LINE (IE: "T")
PUSHJ P,TYPEL ; . . .
JRST (PC) ; AND RETURN TO CALLER
; $V - Type some lines either side of the pointer
;
; CALL: JSP PC,$$V
; (RETURN)
$V: PUSH P,ARG ;[12000] Save argument
MOVN ARG,ARG ;[12000]
AOJ ARG, ;[12000] ARG=(1-ARG)
PUSHJ P,EVL2RG ;[12000] returns start in SARG
MOVE ARG,(P) ;[12000] get back original ARG
MOVEM SARG,(P) ;[12000] Save start of stuff to type
PUSHJ P,EVL2RG ;[12000] This will get end addr
POP P,SARG ;[12000] now we have the correct arguments
PUSHJ P,TYPE0 ;[12000] Type it out
JRST (PC) ;[12000] continue execution
CWOORZ: MOVE SARG,DEFARG ;[15000] Set default 2nd arg
CWOORG: SKIPA T1,['[:W] '] ;[14000] n:W =nM([:W]) if n out of range
; $W - W or nW - Do window stuff
; CALL: JSP PC,$$W
; (RETURN)
$W:
MOVX T1,<'[W] '> ;[14000] W = M([W])
TXO F,F$COL!F$1RG!F$2RG ;[14000] No error if no macro
SETOM MACFLG ;[15000] Don't let COMPIL forget args
PJRST M1 ;[14000] Execute the macro, if any
; $COLW - n:w or m,n:w - manipulate window parameters
; CALL: JSP PC,$$COLW
; (RETURN)
$COLW:
JUMPL ARG,CWOORZ ;[12000] negative n.g.
CAILE ARG,CWMAX ;[12000] Range check
JRST CWOORZ
MOVE VALUE,CWVEC(ARG);[15000] Get the value
TXZ F,F$COL!F$2CO ;[15000] Clear colon flags
JRST (PC) ;[15000] & return it
; $CW2 - M,N:W = set window parameters
; CALL: JSP PC,$$CW2
; (RETURN)
$CW2:
JUMPL ARG,CWOORG ;[15000] No negative entries in table
CAIG ARG,CWMAX ;[15000] Store nothing if out of range
MOVEM SARG,CWVEC(ARG) ;[12000] Store the value
JRST CWOORG ;[15000] Execute the macro
; $EJ - Return some parameter from system
;
; CALL: JSP PC,$$EJ
; (RETURN)
EJMIN==-1 ;[22000] Fix for MACRO bug?
$EJ: CAML ARG,[EJMIN] ;[22000] Return 0 if out of range
CAILE ARG,EJMAX ;[12000] Range check
JRST FAIRET ;[12000] This will return zero always
XCT EJVEC(ARG) ;[12000] Get the parameter
JFCL ;[12000] some skip, some don't
IFN FTPRIV,< ;[12000] Priveleged options
TXZN F,F$2RG ;[12000] Should we try to set one of these?
JRST (PC) ;[12000] Win if we survived this far
XCT EJSVEC(ARG) ;[12000] why not?
JFCL ;[12000] Ignore skip return or lack thereof
>
JRST (PC) ;[12000] We're done
EJMIN==<.-EJVEC>
MOVX VALUE,1000+TOPS20 ;[22000] CPU type=1000, O/S type =0 or 1
EJVEC: ;[12000] Dispatch table
PJOB VALUE, ;[12000] Get our job number
MOVE VALUE,OURTTY ;[12000] Get our terminal number
GETPPN VALUE, ;[12000] Get our PPN
EJMAX==<.-EJVEC> ;[12000] Maximum legal value
SETZ VALUE, ;[12000] EJSVEC[-1] for bad arguments
EJSVEC: JRST FAIRET ;[12000] Can't change job number
MOVEM SARG,OURTTY ;[12000] Make this our output sink
CHGPPN SARG, ;[12000] Change our PPN, return old one
SUBTTL $A and $P and $PW and $BP
; $A - APPEND NEXT PAGE ONTO CURRENT BUFFER
;
; CALL: JSP PC,$$A
; (RETURN)
$A: TXNN F,F$COL ;[16000] :A returns 0 if EOF else -1
JRST A0 ;[16000] not :A
TXNE F,F$EOF ;[16000] So check for EOF
JRST FAIRET ;[16000] It was, so fail
SETO VALUE, ;[16000] Win unless no input file
A0: PUSHJ P,APPEND ; APPEND THE NEXT INPUT PAGE
JRST (PC) ; AND RETURN TO CALLER
; $AL - Append n lines to the buffer from the input file
; CALL: MOVX ARG,<# OF LINES> ;[16000]
; JSP PC,$$AL ;[16000]
; (RETURN) ;[16000]
$AL: TXNE F,F$EOF ;[16000] At EOF already
JRST FAIRET ;[16000] Yes
PUSHJ P,APPENL ;[16000] append lines
JRST SUCRET ;[16000] CONTINUE EXECUTION
; $P - PUNCH CURRENT PAGE AND YANK IN A NEW PAGE
;
; CALL: JSP PC,$$P
; (RETURN)
$P: JUMPGE ARG,.+2 ;[14000] We don't tolerate negative arguments
CERROR (IPA) ;[14000] and this was one
SETZM PTVAL ;[412] INSURE "." IS CLEARED
PUSHJ P,PUNBUF ; PUNCH "ARG" BUFFERS
JRST (PC) ; AND RETURN TO CALLER
; $PW - PUNCH CURRENT PAGE AND ALWAYS APPEND A FORMFEED
; DOES NOT AFFECT THE PAGE IN ANY WAY
;
; CALL: JSP PC,$$PW
; (RETURN)
$PW: JUMPLE ARG,(PC) ; DO NOTHING IF ARG.LE.0
$PW1: SETZ T4, ; T4:=LOWER BOUND (IE: B)
MOVE T5,@TXTBUF ; T5:=UPPER BOUND (IE: Z)
PUSHJ P,PUNCH ; PUNCH OUT THE ENTIRE BUFFER
MOVEI C,.CHFFD ; FETCH A FORM.FEED CHAR
PUSHJ P,@PCHADR ; AND PUNCH IT
SOJG ARG,$PW1 ; KEEP PUNCHING UNTILL ARG RUNS OUT
JRST (PC) ; ARG RAN OUT. RETURN TO CALLER
; $BP - PUNCH PART OF CURRENT PAGE (BETWEEN TWO BOUNDS)
; DOES NOT AFFECT THE PAGE IN ANY WAY
;
; CALL: JSP PC,$$BP
; (RETURN)
$BP: PUSHJ P,CHK2RG ; CHECK ARGS FOR VALIDITY
MOVE T4,SARG ; T4:=LOWER BOUND
MOVE T5,ARG ; T5:=UPPER BOUND
PUSHJ P,PUNCH ; PUNCH PART OF THE BUFFER
JRST (PC) ; AND RETURN TO CALLER
SUBTTL $Y and $CNP AND $CNY AND $CNU
; $Y - RENDER THE BUFFER AND YANK A NEW BUFFER
;
; CALL: JSP PC,$$Y
; (RETURN)
$Y: TXNE F,F$UWR ;[16000] Y is OK if no output file
SKIPN @TXTBUF ;[12000] Naked "Y" legal if buffer empty
JRST $EY ;[14000] ok
MOVE X,EDVAL ;[14000] "Y" legal always if 2ED set
TXNN X,ED$YOK ;[14000]
CERROR (YCA) ;[12000] no good
$EY: MOVE X,PCHFLG ; FETCH FLAGS FOR LAST "EB" OR "EW"
TXNE X,FB$EXE ; /EXECUTE?
JRST SUCRET ; YES, SKIP THE YANK
JUMPLE ARG,SUCRET ; DO NOTHING IF ARG.LE.0
$Y1: PUSHJ P,YANK ; YANK A BUFFER
SOJG ARG,$Y1 ; KEEP YANKING UNTIL ARG RUNS OUT
JRST SUCRET ; ARG RAN OUT. RETURN TO CALLER
; $CNP - PUNCH INPUT FILE TILL SPECIFIED PAGE IS IN BUFFER
;
; CALL: JSP PC,$$CNP ; WITH PAGE # IN "ARG"
; (RETURN)
$CNP: CAMGE ARG,PAGCNT ; ARG BEFORE CURRENT PAGE?
ERROR (PPC) ; YES, ** PAGE PREVIOUS TO CURRENT PAGE **
CAMN ARG,PAGCNT ;[320] CHECK IF ALREADY THERE
JRST (PC) ;[320] YES: RETURN NOW
SOJ ARG, ; ARG:=# FORMFEEDS TO SKIP OVER
$CNP1: CAMG ARG,PAGCNT ; SKIPPED OVER DESIRED # FORMFEEDS?
JRST $CNP2 ; YES, PUNCH THIS BUFFER AND YANK FIRST
SETZ T4, ; PUNCH CURRENT PAGE
MOVE T5,@TXTBUF ; . . .
PUSHJ P,PUNCH ; . . .
MOVEI C,.CHFFD ; FETCH A <FF> CHAR JUST IN CASE
TXNE F,F$FFD ; NEED A <FF>?
PUSHJ P,@PCHADR ; YES, PUNCH THE <FF> AT END OF PAGE
TXNE F,F$EOF ; AT END OF FILE?
JRST $CNP3 ;[354] PAGE NOT FOUND
PUSHJ P,YANK ; NO, READ NEXT PAGE
JRST $CNP1 ; AND SEE IF IT'S THE ONE WE WANT
$CNP2: MOVEI ARG,1 ; PUNCH CURRENT PAGE AND YANK NEXT
JRST $P ; . . .
$CNP3: SETZM PTVAL ;[354] ".":=B (DOES A "J")
SETZM @TXTBUF ;[354] Z:=B (DOES AN "HK")
ERROR (PNF) ;[354] GIVE ERROR MESSAGE
; $CNY - YANK INPUT FILE TILL SPECIFIED PAGE IS IN BUFFER
;
; CALL: JSP PC,$$CNY ; WITH PAGE # IN "ARG"
; (RETURN)
$CNY: CAMGE ARG,PAGCNT ;[327] ARG BEFORE CURRENT PAGE?
ERROR (PPC) ;[327] YES ** PAGE PREVIOUS TO CURRENT PAGE **
CAMN ARG,PAGCNT ;[327] SEE IF ALREADY THERE
JRST (PC) ;[327] YES: RETURN NOW
SOJ ARG, ;[327] ARG:=(PAGE DESIRED-1)
$CNY1: CAMG ARG,PAGCNT ;[327] AT LAST BEFORE?
JRST $CNY2 ;[327] YES: YANK IN LAST
TXNE F,F$EOF ;[327] AT END OF FILE?
ERROR (PNF) ;[327] YES, ** PAGE NOT FOUND **
PUSHJ P,YANK ;[327] YANK IN A PAGE
JRST $CNY1 ;[327] LOOP FOR ANOTHER PAGE
$CNY2: MOVEI ARG,1 ;[327] YANK ONE LAST TIME
JRST $Y1 ;[327] . . .
; $USI - USETI TO DESIRED BLOCK ON INPUT FILE
;
; CALL: JSP PC,$$USI ; WITH BLOCK # IN "ARG"
; (RETURN)
$USI: TXNN F,F$URD ;[333] IS A FILE OPEN FOR INPUT?
CERROR (NFI) ;[333] NO, BALK
USETI INP,(ARG) ;[333] PICK DESIRED BLOCK
MOVEI X,INPBF ;[427] TO BE PLACED IN .JBFF
EXCH X,.JBFF ;[427] GET CURRENT .JBFF AND SAVE TEMP
INBUF INP,C$NBUF ;[427] REND BUFFERS AND MAKE NEW ONES
EXCH X,.JBFF ;[427] RESTORE .JBFF
INPUT INP, ;[427] INPUT A NEW BUFFER
JRST (PC) ;[333] ALL DONE
SUBTTL $CNU,$X,$XL
; $CNU - Store text string in q-register
;
; CALL: JSP PC,$$CNU
; <Q.REGISTER.NAME>
; <CHARADR,,LEN>
; (RETURN)
$CNU:
PUSHJ P,NXTWRD ;[12000] Get Q-register name
MOVE T1,N ;[12000] QGET wants it in T1
PUSHJ P,QGET ;[12000] Get current contents
SETZB T2,T3 ;[12000] Q-register does not exist
PUSH P,T1 ;[12000] Save Q-register stuff on stack
PUSH P,T2 ;[12000]
PUSH P,T3 ;[12000]
PUSHJ P,NXTWRD ;[12000] Text is from cmd buffer (^U cmd)
HLRZ L,N ;[12000] Get character addr in cmd buffer
MOVEI T5,(N) ;[12000] length of insert string
JUMPN T5,$CNU00 ;[12000] rejoin common code
TXNE F,F$1RG ;[12000] if there was an argument
AOJA T5,.+2 ;[15000] Allocate space for 1 char
$CNU00: TXZ F,F$1RG ;[24000] Ignore the argument
PUSH P,L ;[12000] Save L
MOVEI T3,<T$DATA*5>+4 ;[12000]Add in overhead words
ADD T3,T5 ;[13000] and # of characters (36 bits worth)
IDIVI T3,5 ; COMPUTE SIZE IN WORDS
TXNE F,F$COL ;[12000] :^U is append to q-register
JRST [TXNN T2,777777 ;[12000] Any text to append to?
JRST .+1 ;[12000] No (just like X)
MOVEI L,TXREF ;[12000] Get address of text here
MOVEI N,(T2) ;[12000] BID here
PUSHJ P,FNDBLK ;[12000] look for it
ERROR (BNF) ;[12000] OOPS
MOVEI N,-T$DATA(T3) ;[12000] # of words to expand
PUSHJ P,EXPAND ;[12000] Expand it
MOVE T1,TXREF ;[12000] Get start of buffer
MOVX T2,TB$CMP ;[12000] Will have to be recompiled
ANDCAM T2,T$BIT(T1) ;[12000] since we will step on the code
MOVE N,T$CCNT(T1) ;[12000] Find end of buffer
IDIVI N,5 ;[12000] In words, please
ADDM T5,T$CCNT(T1) ;[12000] update size of it
HLL N,CBPTBL-1(M) ;[12000] Find correct byte
ADDI N,T$DATA(T1) ;[12000] Add in addr of start of text
JRST $CNU01] ;[12000] done
MOVEI L,(T3) ;[12000] Get length of block to allocate
HRLI L,TXREF ; TXREF WILL REFERENCE THE TEXT BUFFER
SETZM TXREF ; CLEAR TXREF
PUSHJ P,REQM ; ALLOCATE THE TEXT BUFFER
MOVE N,[POINT 7,T$DATA] ; FORM BYTE POINTER TO BUFFER
ADD N,TXREF ; . . .
ADDM T5,T$CCNT-T$DATA(N) ; SAVE # CHARS TO BE PUT IN Q-REGISTER
$CNU01: POP P,T3 ; RESTORE Char adr into T3
IDIVI T3,5 ; CONVERT TO A BYTE POINTER
HLL T3,CBPTBL-1(T4) ; . . .
TXO T3,<Z (R)> ;[12000] Make relative to cmd buffer
TXZ F,F$$TX ;[15000] Clear all these flags to start
TXZN F,F$1RG ;[15000] Single character numeric insert?
JRST $CNU02 ;[15000] NO
SETZ T5, ;[15000] no more after this one
MOVE C,ARG ;[15000] Get the character
JRST $CNU4 ;[15000] Just insert it, nothing fancy
$CNU02: SOJL T5,$X2 ; JUMPE WHEN FINISHED STORING
$CNU1: ILDB C,T3 ; FETCH NEXT CHAR FROM TEXT STRING
; CHECK FOR SPECIAL CONTROL CHARACTERS
MOVE T1,[IOWD $CNU1L,$CNUT1+1] ; POINTER TO CTL CHAR DISPATCH TABLE
; TXNE F,F$CNT ; IN ^T MODE?
; MOVE T1,[IOWD $CNU2L,$CNUT2+1] ; YES, USE SHORT DISPATCH TABLE
PUSHJ P,DISPAT ; DISPATCH ON SPECIAL CONTROL CHARS
$CNU3: PUSHJ P,CASE ; DO ANY REQUIRED CASE CONVERSIONS ON CCHAR
$CNU4: IDPB C,N ;[14000] Store it
JRST $CNU02 ;[14000] loop
; DISPATCH TABLES FOR SPECIAL CONTROL CHARS IN INSERT TEXT STRINGS
$CNUT1: <"V"-100,,$CNUTV>
<"W"-100,,$CNUTW>
<"^"-100,,$CNUTU>
$CNUT2:; [16000] removed <"T"-100,,$CNUTT>
<"R"-100,,$CNUTR>
<"Q"-100,,$CNUTR>
$CNU2L==.-$CNUT2
$CNU1L==.-$CNUT1
; ^V - DOWNCASE FOLLOWING LETTER
; ^V^V - DOWNCASE LETTERS UNTIL END OF STRING OR FURTHER NOTICE
$CNUTV: PUSHJ P,CNV ; SET THE DOWNCASE FLAGS
JRST $CNU1 ; AND PROCESS NEXT CHAR
; ^W - UPCASE FOLLOWING LETTER
; ^W^W - UPCASE LETTERS UNTIL END OF STRING OR FURTHER NOTICE
$CNUTW: PUSHJ P,CNW ; SET UPCASE FLAGS
JRST $CNU1 ; AND PROCESS NEXT CHAR
; ^^ - INSERT LC EQUIVALENT OF FOLLOWING CHAR (@,[,\,],_)
$CNUTU: ILDB C,T3 ; FETCH THE NEXT CHAR
PUSHJ P,CNUAR ; DOWNCASE IF @,[,\,],OR _
JRST $CNU4 ; AND COUNT CHAR AND PROCESS NEXT CHAR
; ^R - QUOTE THE NEXT CHAR (IE: TAKE AS TEXT)
$CNUTR: ILDB C,T3 ; FETCH THE NEXT CHAR
JRST $CNU3 ; DO CASE CONVERSIONS AND STORE IN BUFFER
; ^T - COMPLEMENT ^T MODE FLAG (IN ^T MODE ONLY ^T AND ^R ARE SPECIAL)
;[16000] ^T mode removed
;$CNUTT: TXC F,F$CNT ; COMPLEMENT THE ^T MODE FLAG
; JRST $CNU1 ; AND PROCESS NEXT CHAR
; $XL - EXTRACT LINES FROM THE TEXT BUFFER AND STORE IN A Q-REGISTER
;
; CALL: JSP PC,$$XL
; <Q.REGISTER.NAME>
; (RETURN)
$XL: PUSHJ P,EVL2RG ; CONVERT LINE ARG TO CHAR ARGS
SKP ; AND FALL INTO $X
; $X - EXTRACT CHARACTERS FROM THE TEXT BUFFER AND STORE IN A Q-REGISTER
;
; CALL: JSP PC,$$X
; <Q.REGISTER.NAME>
; (RETURN)
$X: PUSHJ P,CHK2RG ; MAKE SURE ARGS ARE OKAY
$X0: PUSHJ P,NXTWRD ;[12000] Get Q-register name
MOVE T1,N ;[12000] QGET wants it in T1
PUSHJ P,QGET ;[12000] Get current contents
SETZB T2,T3 ;[12000] Q-register does not exist
PUSH P,T1 ;[12000] Save Q-register stuff on stack
PUSH P,T2 ;[12000]
PUSH P,T3 ;[12000]
JUMPL SARG,[PUSHJ P,NXTWRD ;[12000] Text is from cmd buffer (^U cmd)
HLR SARG,N ;[12000] Get character addr in cmd buffer
MOVEI T5,(N) ;[12000] length of insert string
JUMPN T5,$X00 ;[12000] rejoin common code
TXNN F,F$1RG ;[12000] if there was an argument
JRST $X00 ;[12000] (there wasn't) (null insert)
TLZ SARG,200000 ;[12000] Remember to insert character only
AOJA T5,$X00] ;[12000] then insert it as a character
MOVE T5,ARG ; COMPUTE SIZE OF TEXT BUFFER NEEDED
SUB T5,SARG ; . . .
$X00: PUSH P,SARG ;[12000] Save SARG a.k.a L
MOVEI T3,<T$DATA*5>+4 ;[12000]Add in overhead words
ADD T3,T5 ;[13000] and # of characters (36 bits worth)
IDIVI T3,5 ; COMPUTE SIZE IN WORDS
TXNE F,F$COL ;[12000] :X is append to q-register
JRST [TXNN T2,777777 ;[12000] Any text to append to?
JRST .+1 ;[12000] No (just like X)
MOVEI L,TXREF ;[12000] Get address of text here
MOVEI N,(T2) ;[12000] BID here
PUSHJ P,FNDBLK ;[12000] look for it
ERROR (BNF) ;[12000] OOPS
MOVEI N,-T$DATA(T3) ;[12000] # of words to expand
PUSHJ P,EXPAND ;[12000] Expand it (we already have overhead words)
MOVE T1,TXREF ;[12000] Get start of buffer
MOVX T2,TB$CMP ;[12000] Will have to be recompiled
ANDCAM T2,T$BIT(T1) ;[12000] since we will step on the code
MOVE T3,T$CCNT(T1) ;[12000] Find end of buffer
IDIVI T3,5 ;[12000] In words, please
ADDM T5,T$CCNT(T1) ;[12000] update size of it
HLL T3,CBPTBL-1(T4) ;[12000] Find correct byte
ADDI T3,T$DATA(T1) ;[12000] Add in addr of start of text
JRST $X01] ;[12000] done
MOVEI L,(T3) ;[12000] Get length of block to allocate
HRLI L,TXREF ; TXREF WILL REFERENCE THE TEXT BUFFER
SETZM TXREF ; CLEAR TXREF
PUSHJ P,REQM ; ALLOCATE THE TEXT BUFFER
MOVE T3,[POINT 7,T$DATA] ; FORM BYTE POINTER TO BUFFER
ADD T3,TXREF ; . . .
ADDM T5,-T$DATA(T3) ; SAVE # CHARS TO BE PUT IN Q-REGISTER
$X01: POP P,SARG ; RESTORE AC SARG
LDB T1,[4200,,SARG] ; FETCH START CHAR.ADR [13000] 34 bits worth
IDIVI T1,5 ; CONVERT TO A BYTE POINTER
HLL T1,CBPTBL-1(T2) ; . . .
JUMPL SARG,[TXO T1,<Z (R)> ;[12000] Make relative to cmd buffer
TLNN SARG,200000 ;[12000] inserting character?
MOVE T1,[70700,,ARG] ;[12000] ASCII char in ARG
JRST $X1] ;[12000] Jump into loop
ADD T1,TXTBUF ; . . .
ADDI T1,T$DATA ; Add in overhead words
$X1: SOJL T5,$X2 ; JUMPE WHEN FINISHED STORING
ILDB C,T1 ; FETCH NEXT CHAR FROM MAIN TEXT BUFFER
IDPB C,T3 ; AND STORE IN Q-REGISTER
JRST $X1 ; AND TRY NEXT CHAR
; STORE COMPLETE. BIND THE TEXT BUFFER TO THE Q-REGISTER NAME
$X2:
POP P,T3 ;[12000] Get it off the stack
POP P,T2 ;[12000]
POP P,T1 ;[12000]
TXZE F,F$COL ;[12000] If it was :X... (also clear ":" flag)
TRNN T2,777777 ;[12000] ...and it already had text...
TXOA T2,QB$BID ; FLAG Q-REGISTER AS A TEXT BUFFER
JRST [MOVE T1,TXREF ;[12000] ...then the Q-register is already stored
SETZM TXREF ;[12000] Clear our reference
HRRZS T1,B$2PTR(T1) ;[12000] And the pointer to it
JRST (PC)] ;[12000] And go away
HRRI T2,TXREF ; FETCH ADR OF REFERENCE TO TEXT BUFFER
TXO F,F$REF ; FLAG THAT T3 HAS ADR OF REFERENCE
PUSHJ P,QSTOR ; BIND THE TEXT BUFFER TO THE Q-REGISTER NAME
JRST (PC) ; AND RETURN TO CALLER
SUBTTL $G
; $G - GET THE TEXT CONTAINED IN A Q-REGISTER AND INSERT IN BUFFER
;
; CALL: JSP PC,$$G
; <Q.REGISTER.NAME>
; (RETURN)
$G: PUSHJ P,NXTWRD ; FETCH THE Q-REGISTER NAME
MOVE T1,N ; AND COPY INTO AC T1
PUSHJ P,QGET ; GET THE Q-REGISTER
JRST (PC) ; ** NO TEXT IN Q-REGISTER **
TXNN T2,QB$BID ; IS THERE TEXT IN THE Q-REGISTER?
JRST (PC) ; ** NO TEXT IN Q-REGISTER **
MOVEI N,(T2) ; FETCH THE TEXT BUFFER ID FOR Q-REGISTER
MOVEI L,TMPRFG ; TMPRFG WILL REFERENCE THE TEXT BUFFER
PUSHJ P,FNDBLK ; FIND THE BLOCK WITH THE ID
ERROR (BNF) ; SHOULDN'T OCCUR. ** CAN'T FIND Q-REGISTER **
MOVE T5,@TMPRFG ;[21000](36bits) FETCH THE # CHARS IN Q-REG
MOVE T1,T5 ; T5:=# CHARS IN Q-REGISTER
TXNN F,F$COL ;[12000] don't mung buffer if :G, just type
PUSHJ P,MKROOM ; AND MAKE ROOM FOR THEM
MOVE T3,[POINT 7,T$DATA] ; FORM BYTE POINTER TO Q-REGISTER IN T3
ADD T3,TMPRFG ; . . .
TXZE F,F$COL ;[12000] :G means type it
JRST [COLGLP: SOJL T5,$G2 ;[12000] no more chars
ILDB C,T3 ;[12000] Get character
TXNN F,F$2CO ;[16000] ::G Type literally
JRST [PUSHJ P,TCCHR ;[16000] Type normally
JRST COLGLP] ;[16000] back for more
PUSHJ P,TCHR ;[12000] Type it
JRST COLGLP] ;[12000] back for more
MOVE T1,PTVAL ; FETCH VALUE OF "."
ADDI T1,T$DATA*5 ; SKIP OVER OVERHEAD WORDS
IDIVI T1,5 ; CONVERT TO A BYTE POINTER
HLL T1,CBPTBL-1(T2) ; . . .
ADD T1,TXTBUF ; . . .
ADDM T5,PTVAL ; SET NEW VALUE OF "."
; INSERT THE TEXT FROM THE Q-REGISTER INTO THE MAIN TEXT BUFFER
$G1: SOJL T5,$G2 ; JUMP IF DONE
ILDB C,T3 ; FETCH NEXT CHAR FROM Q-REGISTER
IDPB C,T1 ; AND INSERT INTO TEXT BUFFER
JRST $G1 ; AND TRY FOR NEXT CHAR
; INSERTION COMPLETE. UNBIND THE Q-REG. TEXT BUFFER FROM TMPRFG
$G2: MOVE X,TMPRFG ; FETCH THE ADR OF Q-REG. TEXT BUFFER
HRRZS B$2PTR(X) ; AND UNBIND FROM TMPRFG
TXZ F,F$COL!F$2CO ;[16000] Don't leave : flags on
JRST (PC) ; RETURN TO CALLER
SUBTTL FAIRET and SUCRET
; FAIRET - RETURN ZERO IF COMMAND FAILED
FAIRET: SETZ VALUE, ; SET VALUE:=0
JRST (PC) ; AND RETURN TO CALLER
; SUCRET - RETURN -1 IF COMMAND SUCCEEDED
SUCRET: SETO VALUE, ; SET VALUE:=-1
JRST (PC) ; AND RETURN TO CALLER
SUBTTL $M
; $M - COMPILE AND EXECUTE THE TEXT OF A Q-REGISTER
;
; CALL: JSP PC,$$M
; <Q-REG-NAME>
; (RETURN)
$M: PUSHJ P,NXTWRD ; FETCH THE Q-REG-NAME
MOVE T1,N ; AND COPY INTO AC T1
M1: MOVEM SARG,SARGSV ;[3000] DO NOT LOSE 2ND ARGUMENT TO MACRO
PUSHJ P,QGET ; GET INFO ON THE Q-REGG
JRST (PC) ;[16000] no
TXNN T2,QB$BID ; IS THERE TEXT IN Q-REGISTER?
JRST (PC) ;[16000] no text
MOVE L,T1 ; PUT Q-REG-NAME IN AC L
MOVEI N,(T2) ; PUT BUFFER ID IN AC N
PUSHJ P,MACRO ; NOW COMPILE&EXECUTE THE MACRO
JRST (PC) ;[14000] Leave the returned value alone
SUBTTL $EC and $ECS and $TTY
; $EC - RETURN THE NUMBER OF WORDS IN THE LOWSEGMENT (IE: .JBFF-1)
;
; CALL: JSP PC,$$EC
; (RETURN) ; WITH SIZE IN AC 'VALUE'
$EC: SKIPN EOVAL ;[12000] Don't output all if EO=0
JRST $EC1 ;[12000] EO=0 so just garbage collect
MOVSI ARG,1 ;[12000] Do infinity P commands
TXNE F,F$UWR ;[12000] As long as there is an output file
PUSHJ P,PUNBUF ;[12000]
TXZE F,F$UBK ;[12000] Push everything along for EB
PUSHJ P,BAKCLS ;[12000] INP to .BAK OUT to INP
RELEAS OUT, ;[12000] Close up output file
TXZ F,F$UWR ;[12000] No more output file
MOVEI T1,NOOF ;[12000] Set up error if try to output
MOVEM T1,PCHADR ;[12000] to avoid blowing up
$EC1: PUSHJ P,GARCOL ; GARBAGE COLLECT FIRST
MOVE VALUE,.JBFF ; FETCH SIZE OF LOWSEG+1
SOJA VALUE,(PC) ; COMPUTE LOWSEG SIZE AND RETURN TO CALLER
; $ECS - SET THE LOWSEGMENT SIZE (.JBCOR AND .JBREL)
;
; CALL: JSP PC,$$ECS ; WITH # WORDS IN AC 'ARG'
; (RETURN)
; COMPRESS THE TEXT BUFFER TO MAX(C$TBLN,(C$FILB/(C$FILB-1)*Z+4)/5)
; THEN GARBAGE COLLECT
; AND THEN SET OUR LOWSEG SIZE
$ECS:
FOR TOPS10, PUSHJ P,POSSYM ;[14000] Page out DDT & symbol table
MOVE T1,@TXTBUF ; FETCH Z
IMULI T1,C$FILB ; COMPUTE C$FILB*Z
IDIVI T1,C$FILB-1 ; COMPUTE C$FILB/(C$FILB-1)*Z
ADDI T1,4 ; COMPUTE C$FILB/(C$FILB-1)*Z+4
IDIVI T1,5 ; COMPUTE (C$FILB/(C$FILB-1)*Z+4)/5
CAIGE T1,C$TBLN ; COMPUTE MAX OF ^ AND C$TBLN (ASSUME ^)
MOVEI T1,C$TBLN ; C$TBLN IS THE MAX
MOVE X,TXTBUF ; FETCH ADR OF TEXT BUFFER
HLRZ N,B$1PTR(X) ; FETCH ADR OF END+1 OF TEXT BUFFER
SUBI N,T$DATA(X) ; COMPUTE # WORDS IN TEXT BUFFER
SUBI N,(T1) ; COMPUTE # WORDS TO COMPRESS OUT
MOVEI L,TXTBUF ; FETCH ADR OF TEXT BUFFER REF
PUSHJ P,COMPRS ; AND COMPRESS THE TEXT BUFFER TO MIN SIZE
TXNE F,F$GCN ;[14000] Only if it would do something useful
PUSHJ P,GARCOL ; PERFORM A GARBAGE COLLECTION
; SET OUR CORE SIZE
MOVEI X,(ARG) ; FETCH REQUESTED CORE SIZE
CAMGE X,.JBFF ; NOT TOO SMALL?
MOVE X,.JBFF ;[16000] As small as we can, then
CORE X, ; ASK THE SYSTEM FOR THE CORE
JRST $ECS2 ; FAILED. GET AS MUCH AS WE CAN
; STORE INFO ABOUT OUR SIZE IN JOBDAT
$ECS1: MOVE X,.JBREL ; FETCH OUR NEW SIZE
HRLI X,(X) ; FORM <SIZE,,SIZE>
MOVEM X,.JBCOR ; AND STORE IN .JBCOR
HRLM X,.JBSA ; SET OUR SIZE IN CASE OF A RESET
JRST (PC) ; AND RETURN TO CALLER
; CORE MUUO FAILED. GET AS MUCH CORE AS WE CAN
$ECS2: LSH X,^D10 ; CONVERT # K TO WORDS
SOJ X, ; CONVERT TO A "HIGHEST ADDR"
HRRZ T1,.JBHRL ; FETCH SIZE OF HIGH SEGMENT
IORI T1,1777 ; AND CONVERT TO "HIGHEST ADDR"
SUBI X,(T1) ; COMPUTE MAX LOWSEG SIZE
CORE X, ; AND ASK THE SYSTEM FOR IT
HALT .+1 ;[20000] Should never fail
JRST $ECS1 ; GOT IT. STORE INFO AND RETURN
; $TTY - RETURN TTY#+^O200000 FOR JOB N
;
; CALL: JSP PC,$$TTY
; (RETURN) ; WITH TTY#+^O200000 IN AC VALUE
$TTY: MOVE VALUE,ARG ;[306] FETCH THE ARG
TRMNO. VALUE, ;[306] ASK MONITOR FOR TTY#+^O200000
SETZ VALUE, ;[306] FAILED - RETURN ZERO
JRST (PC) ;[306] AND RETURN TO CALLER
; $ETS - Change ET flags and do appropriate other things
;
; CALL: JSP PC,$ETS
; (RETURN)
$ETS: TXZN F,F$2RG ;[12000] 2 argument form?
JRST $ETS1 ;[12000] NO
IOR ARG,ETVAL ;[12000] ARG is bits to set
ANDCM ARG,SARG ;[12000] SARG is bits to clear
$ETS1: MOVMS T1,ARG ;[12000] Make -1 into 1 for compatability
XOR T1,ETVAL ;[12000] See which ones changed
TXNE ARG,ET$CCT ;[20000] Did he want ^C trapping?
JRST [SETZM INTBLK+2 ;[20000] Make sure it can happen
SETZM INTBLK+3 ;[20000] ....
MOVEI X,INTRPT ;[20000] Address of handler
MOVEM X,INTBLK ;[20000] into block
MOVEI X,ER.ICC ;[20000] Set bit in block for ^C trap
MOVEM X,INTBLK+1 ;[20000]...
MOVEI X,INTBLK ;[20000] Address of block
MOVEM X,.JBINT ;[20000] into .JBINT so monitor will use it
JRST .+1] ;[20000] Continue
TXZE T1,ET$DET ;[12000] Detached flag changed?
JRST [HRLZ T2,OURTTY ;[12000] Assume detaching
TXNN ARG,ET$DET ;[12000] Is he detaching, or attaching?
HRRI T2,777777 ;[12000] Attaching (detached flag turned off)
ATTACH T2, ;[12000] do it, whatever it was
TXC ARG,ET$DET ;[12000] Failed, flip the flag
PUSHJ P,TTOPEN ;[12000] Re-open the terminal
TXNN ARG,ET$DET ;[12000] If attached reset terminal stuff
TXO T1,<ET$SUP!ET$LC> ;[12000] Force setting status
JRST .+1] ;[12000] continue
TXZE T1,ET$SUP ;[12000] Turn echoing on or off?
JRST [TXNN ARG,ET$SUP ;[12000] on or off?
JRST [ECHO ON ;[21000] on (bit was off)
JRST .+1] ;[21000] ...
ECHO OFF ;[21000] Off (bit was on)
JRST .+1] ;[12000] ...
TXZE T1,ET$LC ;[12000] Turn LC input on or off?
FOR TOPS10!TOPS20,<
JRST [MOVE T2,OURTTY ;[12000] Twiddle line characteristics
GETLCH T2 ;[12000] Get them first
TXNN ARG,ET$LC ;[12000] Check our LC bit
TXZA T2,GL.LCM ;[12000] it's off, so clear this one
TXO T2,GL.LCM ;[12000] set it
SETLCH T2 ;[12000] in the monitor
JRST .+1] ;[12000]
>
TXZE ARG,ET$CCO ;[12000] Did he set Cancel-control-O
FOR TOPS10,<
SKPINC ;[12000] Yes, so cancel it
JFCL ;[12000] don't care if it skips
>
FOR TOPS20,<
PUSHJ P,CLRCCO ;[21000]
>
MOVEM ARG,ETVAL ;[12000] Save the bits that are left
JRST (PC) ;[12000] Continue execution
SUBTTL $GTB and $PEK - GETTAB and PEEK
; $GTB - PERFORM A GETTAB MUUO FOR USER
;
; CALL: JSP PC,$$GTB
; (RETURN) ; WITH GETTAB RESULT IN AC 'VALUE'
$GTB: HRLI ARG,(SARG) ; FORM GETTAB MUUO ARGUMENT
GETTAB ARG, ; ASK MONITOR FOR INFORMATION
TDZA VALUE,VALUE ; FAILED, RETURN ZERO
MOVE VALUE,ARG ; PUT RESULT IN AC 'VALUE'
JRST (PC) ; AND RETURN TO CALLER
; $PEK - PERFORM A PEEK MUUO FOR USER
;
; CALL: JSP PC,$$PEK
; (RETURN) ; WITH RESULT IN AC 'VALUE'
$PEK: PEEK ARG, ; ASK MONITOR FOR THE INFORMATION
MOVE VALUE,ARG ; PUT RESULT IN AC 'VALUE'
JRST (PC) ; AND RETURN TO CALLER
SUBTTL $ER and $EW and $EF and $RUNP
; $ER - SETUP A FILE FOR INPUT
;
; CALL: JSP PC,$$ER
; <FILE.SPEC>
; (RETURN)
$ER: MOVE X,FS$FLG(PC) ; FETCH FILE-SPEC FLAGS
TXZE X,FB$EXE ; /EXECUTE?
JRST $EI ; YES DO AN "EI"
MOVEI L,LERSPC ; FETCH ADR OF "ER" FILE-SPEC
TXNE F,F$2CO ;[16000] ::ER just sets defaults
PJRST SFSDEF ;[16000] so go do that instead
PUSHJ P,SETFSP ; FILL IN THE DEFAULTS
PUSHJ P,OPENRD ; AND OPEN THE FILE FOR READING
PUSHJ P,SETRAD ; SET THE ADR OF THE READ-A-CHAR ROUTINE
JRST SUCRET ; AND RETURN TO CALLER
; $EW - SETUP A FILE FOR OUTPUT
;
; CALL: JSP PC,$$EW
; <FILE.SPEC>
; (RETURN)
$EW: MOVE X,FS$FLG(PC) ; FETCH FILE-SPEC FLAGS
TXNE X,FB$EXE ; /EXECUTE?
JRST $EI ; YES, DO AN "EI" INSTEAD OF "EW"
TXNE X,FB$APP ;[14000] EW/APPEND does indeed append
PJRST $APP ;[14000] so append instead
MOVEI L,LEWSPC ; FETCH ADR OF "EW" FILE-SPEC
TXNE X,FB$DEL ;[20000] /SUPERSEDE?
TXO L,1B1 ;[20000] Yes. remember that
TXZE F,F$2CO ;[16000] ::EW just sets defaults
PJRST SFSDEF ;[16000] so go do that instead
TXNE F,F$UBK ; "EB" IN PROGRESS?
CERROR (EBO) ; YES, ** EW WHEN EB IN PROGRESS **
TXNE F,F$UWR ;[14000] Check for open output file
CERROR (OFO) ;[14000] Output file open error
PUSHJ P,SETFSP ; FILL IN THE DAFAULTS
PUSHJ P,OPENWR ; AND OPEN THE FILE FOR WRITING
PUSHJ P,SETWAD ; SET THE ADR OF THE WRITE-A-CHAR ROUTINE
JRST SUCRET ; AND RETURN TO CALLER
; $EF - CLOSE OUTPUT FILE
;
; CALL: JSP PC,$$EF
; (RETURN)
$EF: TXZE F,F$UBK ; "EB" IN PROGRESS?
PUSHJ P,BAKCLS ; YES, FINISH IT
RELEAS OUT, ; RELEASE THE OUTPUT CHANNEL
TXZ F,F$UWR ; NO LONGER WRITING TO A FILE
MOVEI X,NOOF ;[304] FETCH ADR FOR NO OUTPUT FILE
MOVEM X,PCHADR ;[304] TO PREVENT ILL. UUOS
JRST (PC) ; RETURN TO CALLER
; $EK - Cancel EB and flush output file
;
; CALL: JSP PC,$$EK
; (RETURN)
$EK: MOVEI T1,OUT ;[12000] Prepare to do RESDV.
TXZN F,F$UBK ;[12000] Clear EB, skip RESDV. if was set.
RESDV. T1, ;[12000] Output file is no more
RELEAS OUT, ;[12000] Save .TMP file if from EB
TXZ F,F$UWR ;[12000] Not writing output file
MOVEI X,NOOF ;[12000] Cause error if we try
MOVEM X,PCHADR ;[12000] to write to it.
JRST (PC) ;[12000] done
; NOOF - COME HERE WHEN WE WANT TO PUNCH A CHAR BUT NO OUTPUT FILE
NOOF: ERROR (NFO) ;[304] ** NO OUTPUT FILE **
; $RUNP - SETUP FILE TO BE RUN ON EXIT
;
; CALL: JSP PC,$$RUNP
; <FILE.SPEC>
; (RETURN)
$RUNP: MOVEM ARG,RUNOFS ; STORE /RUNOFFSET:N
MOVEI L,LRPSPC ; FETCH ADR OF LAST "E&" FILE-SPEC
PUSHJ P,SETFSP ; AND FILL IN THE DEFAULTS
;[14000]TXO F,F$EDC ; no more FLAG THAT WE MUST RUN A PROG. ON EXIT
JRST SUCRET ; AND RETURN TO CALLER
SUBTTL $EB
; $EB - SETUP A FILE FOR EDITING WITH BACKUP PROTECTION
;
; CALL: JSP PC,$$EB
; <FILE.SPEC>
; (RETURN)
$EB: ;[1000] EBO CHECK MOVED DOWN TO MAKE SURE
;[1000] WE EAT ALL ARGUMENTS (ELSE WE BLOW UP)
MOVE X,FS$FLG(PC) ; FETCH FILE-SPEC FLAGS
TXNE X,FB$EXE ; /EXECUTE?
JRST $EI ; YES, DO AN "EI" INSTEAD OF "EB"
; SETUP THE EB FILESPEC
MOVEI L,LEBSPC ; FETCH ADR OF THE EB FILESPEC
TXZE F,F$2CO ;[16000] ::EB just sets defaults
PJRST SFSDEF ;[16000] so do that, don't open anything
PUSHJ P,SETFSP ; AND FILL IT IN
TXNE F,F$UBK ; "EB" ALREADY IN PROGRESS?
CERROR (EBO) ; YES, ERROR
FOR TOPS10,<
; MAKE SURE DEVICE IS A DSK OR DECTAPE (OR OTHER DIRECTORY DEVICE)
MOVE X,FS$DEV(L) ; FETCH THE DEVICE NAME
DEVCHR X, ; AND FIND ITS CHARACTERISTICS
TXNN X,DV.DIR ; IS IT A DIRECTORY DEVICE?
CERROR (EBD) ; NO, ** EB FOR DEVICE IS ILLEGAL **
; MAKE SURE FILNAME IS NOT ###XTC.TMP OR EXTENSION .BAK
MOVE T5,FS$NAM(L) ; FETCH THE FILE NAME
HLRZ T1,FS$EXT(L) ; FETCH THE FILE EXTENSION
CAMN T5,CCJNAM ; IS FILE NAME '###XTC'?
CAIE T1,'TMP' ; AND EXTENSION .TMP?
CAIN T1,'BAK' ; OR EXTENSION .BAK?
CERROR (EBF) ; YES, ** ILLEGAL EB FILENAME **
; SELECT THE FILE FOR READING
PUSHJ P,OPENRD ; SELECT FILE FOR INPUT
; IF PPN IS NOT OURS, JUST DO ER-EW SEQUENCE
PUSHJ P,GETPTH ;[342] FETCH MY PATH
MOVE T1,RBSPC+.RBPPN ; GET PPN OR ADDRESS THEREOF
JUMPE T1,$EB1 ; DEFAULT PPN IS ALWAYS MINE
TXNN T1,LH.ALF ; A PPN?
MOVE T1,2(T1) ; NO AN ADDRESS--GET THE PPN
MOVE T2,LEBSPC+FS$FLG ;[23000] /INPLACE always does real EB
TXNE T2,FB$DEL ;[23000] ...
JRST $EB1 ;[23000]
CAME X,T1 ; SAME AS THAT OF FILE?
JRST $EB2 ; NO, JUST DO ER-EW SEQUENCE
; SETUP THE FILESPEC FOR THE TEMP FILE
$EB1:
MOVE T1,[<LEBSPC,,FILSPC>] ; COPY INPUT SPEC FOR TEMP FILE
MOVEI T2,FILSPC+FS$PTH-1 ;[23000] Limit of BLT
FOR TOPS10,<
MOVEI X,INP ;[23000] Get the path for the file
MOVEM X,FILSPC+FS$PTH ;[23000] Set up for uuo
MOVE X,[.PTMAX,,FILSPC+FS$PTH] ;[23000] ...
PATH. X, ;[23000]
MOVEI T2,FILSPC+FS$LTH-1 ;[23000] lose.......
>;end TOPS10
BLT T1,(T2) ;[24000] copy rest
; PUT TEMP FILE ON SAME FILE-STRUCTURE AS INPUT FILE
MOVE X,RBSPC+.RBDEV ; FETCH THE FS OF INPUT FILE
ANDCMI X,'__' ; MASK TO FIRST 4 CHARS
MOVEM X,FILSPC+FS$DEV ; AND USE AS DEVICE FOR TEMP FILE
; FILENAME FOR TEMP FILE IS ###XTC
MOVE X,CCJNAM ; FETCH CCL JOB NAME
MOVEM X,FILSPC+FS$NAM ; SET FILENAME FOR TEMP FILE TO ###XTC
; FILE EXTENSION FOR TEMP FILE IS 'TMP'
MOVSI X,'TMP' ; FETCH THE TEMP FILE EXTENSION
MOVEM X,FILSPC+FS$EXT ; AND STORE IT
; USE FILE PROTECTION OF INPUT FILE FOR OUTPUT FILE
; UNLESS PROTECTION WAS SPECIFIED IN FILESPEC
LDB X,[POINT 9,RBSPC+.RBPRV,8] ; FETCH PROT. OF INPUT FILE
MOVE T1,LEBSPC+FS$FLG ; FETCH FILE SPEC FLAGS
TXNN T1,FB$PRV ; /PROTECT:NNN SPECIFIED?
DPB X,[POINT 9,LEBSPC+FS$PRV,8] ; NO, SAVE PROT OF INPUT FILE
; MAKE SURE WE CAN RENAME INPUT FILE
CAIL X,<300> ; CAN WE RENAME THE FILES?
CERROR (EBP) ; NO, ** EB PROTECTED FILES **
DPB X,[POINT 9,LEBSPC+FS$PRV,8] ; SAVE PROTECTION FOR LATER
MOVEI X,C$TPRV ; FETCH THE PROT. FOR TEMP FILE
DPB X,[POINT 9,FILSPC+FS$PRV,8] ; SET PROT. FOR TEMP FILE
; OPEN THE TEMP FILE
MOVSI N,(<Z OUT,>) ; FETCH THE OUTPUT CHANNEL
MOVSI M,OUTBH ; FETCH ADR OF OUTPUT BUFFER HEADER
MOVEI L,FILSPC ; FETCH ADR OF FILE SPEC
PUSHJ P,FILOPN ; OPEN THE TEMP FILE
CERROR (ODV) ; ** OUTPUT OPEN FAILURE **
; SET THE ESTIMATED SIZE OF THE TEMP FILE TO THE SIZE OF INPUT FILE
MOVE M,RBSPC+.RBSIZ ; FETCH SIZE OF INPUT FILE
LSH M,-7 ; CONVERT TO BLOCKSIZE
AOJ M, ; AND ROUND UP
; ENTER THE TEMP FILE
PUSHJ P,FILENT ; ENTER THE TEMP FILE
CERROR (ENT) ; ** ENTER FAILURE **
IFN 0,<; DON'T USE THIS UNLESS DATE75 KLUDGE INSERTED!!!
; SAVE CREATION DATE
LDB X,[POINT 23,RBSPC+.RBPRV,35] ; FETCH CREATION INFO
DPB X,[POINT 27,LEBSPC+FS$PRV,35] ; AND SAVE FOR LATER>
; DONE WITH "EB" SETUP
TXO F,F$UBK!F$UWR!F$URD ; FLAG THAT "EB" IN PROGRESS
; AND THAT WE ARE READING AND WRITING
PUSHJ P,SETRAD ; SET ADR OF READ-A-CHAR ROUTINE
PUSHJ P,SETWAD ; SET ADR OF WRITE-A-CHAR ROUTINE
JRST SUCRET ; AND RETURN TO CALLER
; FILE NOT IN OUR UFD. JUST DO ER-EW SEQUENCE
>;END TOPS10 ONLY
$EB2: MOVE X,[<LEBSPC,,LERSPC>] ; COPY EB SPEC TO ER SPEC
BLT X,LERSPC+FS$LTH-1 ; . . .
MOVE X,[<LEBSPC,,LEWSPC>] ; COPY EB SPEC TO EW SPEC
BLT X,LEWSPC+FS$LTH-1 ; . . .
MOVSI X,'DSK' ;[355] BACK TO DSK:
MOVEM X,LEWSPC+FS$DEV ;[355] . . .
PUSHJ P,GETPTH ;[355] GET MY PATH
MOVEM X,LEWSPC+FS$PPN ;[355] POINT TO ME, NOT TO HIM(HER?)
; SELECT THE INPUT FILE FOR READING
MOVEI L,LERSPC ; FETCH ADR OF ER FILESPEC
PUSHJ P,OPENRD ; AND SELECT IT FOR READING
PUSHJ P,SETRAD ; SET THE ADR OF THE READ-A-CHAR ROUTINE
; SELECT THE OUTPUT FILE FOR WRITING
MOVEI L,LEWSPC ;[355] SELECT ADR OF EW FILESPEC
PUSHJ P,OPENWR ; SELECT OUTPUT FILE FOR READING
PUSHJ P,SETWAD ; AND SET ADR OF PUNCH-A-CHAR ROUTINE
; DONE. RETURN TO CALLER
JRST SUCRET ; GIVE SUCCESS RETURN TO CALLER
SUBTTL $APP - Append to file
; $APP - SETUP FOR APPENDING TO A FILE (OUTPUT)
;
; CALL: JSP PC,$$APP
; <FILE.SPEC>
; (RETURN)
$EA:
$APP:
TXNE F,F$UBK ; "EB" IN PROGRESS?
CERROR (EBO) ; YES, ** EA WHEN EB IN PROGRESS **
TXNE F,F$UWR ;[14000] "EW" or "EA" in progress?
CERROR (OFO) ;[14000] Yes, "OUTPUT FILE OPEN"
MOVEI L,LEWSPC ; FETCH ADR OF LAST "EW" FILE SPEC
PUSHJ P,SETFSP ; AND FILL IN PARTS
TXZ F,F$UWR ; FLAG THAT NO FILE FOR OUTPUT
MOVSI N,(<Z OUT,>) ; SETUP OUTPUT CHANNEL
MOVSI M,OUTBH ; SETUP ADR OF OUTPUT BUFFER HEADER
PUSHJ P,FILOPN ; OPEN THE OUTPUT DEVICE
CERROR (ODV) ; ** OPEN FAILURE FOR OUTPUT DEVICE **
SETZ T5, ; CLEAR "NO USETI NEEDED" FLAG
PUSHJ P,FILLKP ; LOOKUP THE OUTPUT FILE
SETO T5, ; FLAG THAT USETI NOT NEEDED
PUSHJ P,FILENT ; ENTER THE OUTPUT FILE
CERROR (ENT) ; ** ENTER FAILURE **
JUMPN T5,.+2 ; IF LOOKUP FAILED, NO USETI NEEDED
USETI OUT,-1 ; POSITION TO END OF FILE FOR APPENDING
TXO F,F$UWR ; FLAG THAT A FILE IS NOW READY FOR OUTPUT
PUSHJ P,SETWAD ; SET THE ADR OF PUNCH-A-CHAR ROUTINE
JRST SUCRET ; AND GIVE SUCCESS RETURN TO CALLER
SUBTTL $EI
; $EI - EXECUTE AN INDIRECT FILE AS A COMMAND STRING
;
; CALL: JSP PC,$$EI
; <FILE.SPEC>
; (RETURN)
$EI: MOVEI L,LEISPC ; FETCH ADR OF "EI" FILE-SPEC
TXZE F,F$2CO ;[16000] ::EI just sets defaults
PJRST SFSDF0 ;[16000] so go do that instead
PUSHJ P,SETFSP ; AND FILL IN DEFAULTS
SETZ N, ;[371] USE CHANNEL 0
MOVEI M,INIBH ;[371] FETCH ADDR OF BUFFER HEADER
PUSHJ P,FILOPN ;[371] OPEN THE DEVICE
CERROR (IDV) ;[371] ** INPUT DEVICE OPEN FAILURE **
PUSHJ P,FILLKP ;[371] FIND THE FILE
PUSHJ P,$EI1 ;[371] COULDN'T, TRY IT ON TED:
PUSHJ P,FILERD ; AND READ THE FILE INTO A BUFFER
PUSH P,N ; SAVE THE BUFFER ID
MOVE L,['[EICM]'] ; GIVE THE COMMAND A NAME
TXO F,F$CMP ; FORCE COMPILATION
PUSHJ P,MACRO ; AND COMPILE&EXECUTE THE MACRO
POP P,N ; RESTORE THE BUFFER ID
PUSHJ P,DELBLK ; AND DELETE THE BUFFER
JRST SUCRET ; AND GIVE SUCCESS RETURN TO CALLER
$EI1: SETZM LEWSPC+FS$PPN ;[371] IGNORE PPN NOW
MOVSI X,'TED' ;[371] TRY THE TECO MACRO LIBRARY
MOVEM X,LEISPC+FS$DEV ;[371] SET IT FOR TRY
POPJ P, ;[371] RETURN TO TRY IT
SUBTTL $EL AND $ELA
; $EL - MAKE A LOG FILE
;
; CALL: JSP PC,$$EL
; <FILE.SPEC>
; (RETURN)
$EL: MOVEI L,LELSPC ;[330] FETCH ADR OF "EL" FILE-SPEC
TXZE F,F$2CO ;[16000] ::EL just sets defaults
PJRST SFSDF0 ;[16000] so go do that instead
PUSHJ P,SETFSP ;[330] AND FILL IN DEFAULTS
MOVSI N,(<Z LOG,0>) ;[330] FETCH THE LOG CHANNEL
MOVSI M,LOGBH ;[330] SETUP ADR OF LOG BUFFER HEADER
PUSHJ P,FILOPN ;[330] OPEN THE LOG DEVICE
CERROR (LDV) ;[330] ** OPEN FAILURE **
MOVE X,FS$FLG(L) ;[330] LOAD FLAGS
SETZ T5, ;[356] SAY USETI IS COOL
TXNE X,FB$APP ;[330] APPEND?
PUSHJ P,FILLKP ;[330] YES, ENTER UPDATE MODE
SETO T5, ;[330] EITHER NO APPEND OR NO FILE
SETZ M, ;[330] DON'T ESTIMATE ANY SIZE
PUSHJ P,FILENT ;[330] ENTER FILE
CERROR (LFE) ;[330] ** ENTER FAILURE **
MOVE X,FS$FLG(L) ;[330] GET LOG FLAGS
TXNN X,FB$NOO!FB$NOI ;[330] SEE IF ANY ON
TXO X,FB$NOO!FB$NOI ;[330] NO, TURN ALL ON
CAIE T5, ;[356] IS USETI COOL?
TXZ X,FB$APP ;[356] NO, THE NARCS GOT AHOLD OF IT
TXZE X,FB$APP ;[330] APPEND?
USETI LOG,-1 ;[330] YES, APPEND TO PREVIOUS FILE
MOVEM X,FS$FLG(L) ;[330] SAVE LOG FLAGS
TXO F,F$LOG ;[330] INDICATE LOG FILE TO WRITE TO
JRST SUCRET ;[330] SUCESSFUL RETURN
; $ELA - ALTER LOG FILE PARAMETERS
;
; CALL: JSP PC,$$ELA
; <FILE.SPEC>
; (RETURN)
$ELA: CAIL ARG, ;[330] CHECK ARG FOR VALIDITY(0.LE.ARG.LEL3)
CAILE ARG,3 ;[330] . . .
CERROR (ILS) ;[330] ** ILLEGAL EL SPECIFICATION **
TXNN F,F$LOG ;[330] SEE IF LOG FILE OPEN
CERROR (NLF) ;[330] ** NO LOG FILE OPEN **
MOVE X,LELSPC+FS$FLG ;[330] LOAD LOG FILE SPECS
TXZ X,FB$NOO!FB$NOI ;[330] ZERO FLAGS
TXNE ARG,1 ;[330] SEE IF ODD
TXO X,FB$NOI ;[330] YES, /NOIN AT LEAST
TXNE ARG,2 ;[330] SEE IF /NOOUT
TXO X,FB$NOO ;[330] YES
MOVEM X,LELSPC+FS$FLG ;[330] SAVE FLAG SPECS
JRST SUCRET ;[330] GIVE SUCCESS RETURN
SUBTTL $RENM
; $RENM - RENAME CURRENT INPUT FILE
;
; CALL: JSP PC,$$RENM
; <FILE.SPEC>
; (RETURN)
$RENM: MOVEI L,LERSPC ; FETCH ADR OF FILE-SPEC
MOVE X,FS$FLG(PC) ;[15000] Get flags from real filespec
TXNE X,FB$DEL ;[15000] Delete?
TLO L,400000 ;[15000] Yes, remember it
PUSHJ P,SETFSP ; AND FILL IN PARTS
TXNE F,F$UBK ; "EB" IN PROGRESS?
CERROR (EBO) ; YES, ** EB IN PROGRESS **
TXNN F,F$URD ; "ER" IN PROGRESS?
CERROR (ENO) ; NO, ** NO DEVICE OPEN FOR INPUT **
JUMPL L,[SETZ T1, ;[15000] Try to delete it
RENAME INP,T1;[15000] by renaming it to 0
JRST ECARDE ;[15000] failed
JRST ECAR0] ;[15000] it worked
MOVE N,[Z INP,] ; FETCH THE INPUT CHANNEL
PUSHJ P,FILRNM ; AND PERFORM THE RENAME
JRST ECARRE ; RENAME FAILED
ECAR0: RELEAS INP, ; CLOSE THE FILE
TXZ F,F$URD ; AND CLEAR THE "ER" FLAG
JRST SUCRET ; AND GIVE SUCCESS RETURN TO CALLER
ECARDE: MOVEM T2,LREERR ;[16000] Remember last error
ECARRE: RELEAS INP, ; RELEAS THE INPUT CHANNEL
TXZ F,F$URD ; NO LONGER READING A FILE
TXNE F,F$COL ; IS THIS A ":" COMMAND?
JRST FAIRET ; YES, RETURN TO CALLER
CERROR (RNF) ; NO, ** RENAME FAILURE **
SUBTTL $EP, $EQ & E%
; $EQ - READ A FILE INTO Q-REGISTER
;
; CALL: JSP PC,$$EQ
; <Q-REG>
; <FILE.SPEC>
; (RETURN)
$EQ: PUSHJ P,NXTWRD ;[12000] Get Q-register name first
MOVEM N,ACSAVE+N ;[15000] Stash in M
MOVEI L,LERSPC ; FETCH ADR OF LAST "ER" FILE SPEC
MOVE X,FS$FLG(PC) ;[15000] Check flag for /DELETE
TXNE X,FB$DEL ;[15000] Which is NEVER set by SETFSP
TLO L,400000 ;[15000] Set bit in L to do it
PUSHJ P,SETFSP ; AND FILL IN PARTS
PUSHJ P,FILERD ; READ THE FILE INTO A BUFFER
MOVE T1,ACSAVE+N ;[14000] Get back Q-register name
PUSHJ P,QGET ;[12000] Get current contents
SETZB T2,T3 ;[12000] None yet
TXO T2,QB$BID ; SET THE "TEXT" BIT
HRR T2,N ; FETCH THE BUFFER ID
TXZ F,F$REF ; FLAG THAT T3 HAS A BUFFER ID
PUSHJ P,QSTOR ; AND STORE BUFFER IN Q-REGISTER
JRST SUCRET ; AND GIVE SUCCESS RETURN TO CALLER
; $EPCT - WRITE A FILE FROM Q-REGISTER
;
; CALL: JSP PC,$$EPCT
; <Q-REG>
; <FILE.SPEC>
; (RETURN)
$EPCT: PUSHJ P,NXTWRD ;[12000] Get Q-register name first
MOVE T1,N ;[14000] argument to QGET
PUSHJ P,QGET ;[14000] Find the Q-register
CERROR (NTQ) ;[14000] lose
TXNN T2,QB$BID ;[14000] Look for text
CERROR (NTQ) ;[14000] lose
MOVEI N,(T2) ;[14000] BID argument to FILEWR
MOVEI L,LEWSPC ; FETCH ADR OF LAST "EW" FILE SPEC
MOVE X,FS$FLG(PC) ;[15000] Check flag for /SUPERSEDE
TXNE X,FB$DEL ;[24000] Which may be on in default!!
TLO L,200000 ;[15000] Set bit in L to do it
PUSHJ P,SETFSP ; AND FILL IN PARTS
PUSHJ P,FILEWR ; WRITE THE FILE FROM THE BUFFER
JRST SUCRET ; AND GIVE SUCCESS RETURN TO CALLER
SUBTTL $EM and $EZ
; $EM - PERFORM MAGTAPE OPERATIONS
;
; CALL: JSP PC,$$EM
; (RETURN)
$EM: TXNE F,F$UBK ; "EB" IN PROGRESS?
CERROR (EBO) ; YES, ** EB IN PROGRESS **
TXNN F,F$URD ; "ER" IN PROGRESS?
CERROR (EMD) ; NO, ** NO DEVICE SELECTED FOR EM **
CAIGE ARG,1 ; IS OPCODE LEGAL?
CERROR (EMA) ; NO, ** ILLEGAL MAGTAPE OP **
MTAPE INP,(ARG) ; YES, PERFORM THE MAGTAPE OPERATION
MOVEI L,LERSPC ; FETCH THE ADR OF LAST "ER" FILSPC
MOVE N,[Z INP,] ; FETCH THE I/O CHANNEL
MOVEI M,INPBH ; FETCH THE ADR OF THE INPUT BUFFER HEADER
PUSHJ P,FILOPN ; AND OPEN THE INPUT DEVICE AGAIN
CERROR (IEM) ; CAN'T, ** OPEN FAILURE FOR INPUT DEVICE **
JRST SUCRET ; DONE. RETURN TO CALLER
; $EZ - CLEAR DECTAPE DIRECTORY AND DO AN "EW" FOR FILE
;
; CALL: JSP PC,$$EZ
; <FILE.SPEC>
; (RETURN)
$EZ: TXNE F,F$UBK ; "EB" IN PROGRESS?
CERROR (EBO) ; YES, ** EB IN PROGRESS **
TXNE F,F$UWR ;[14000] Check for output file open already
CERROR (OFO) ;[14000] Yes error "OUTPUT FILE OPEN"
MOVEI L,LEWSPC ; FETCH ADR OF LAST "EW" FILE-SPEC
PUSHJ P,SETFSP ; AND FILL IN PARTS
MOVE N,[Z OUT,] ; FETCH OUTPUT CHANNEL
MOVSI M,OUTBH ; FETCH ADR OF OUTPUT BUFFER HEADER
PUSHJ P,FILOPN ; AND OPEN THE OUTPUT DEVICE
CERROR (ODV) ; CAN'T, ** OPEN FAILURE FOR OUTPUT DEVICE **
UTPCLR OUT, ; CLEAR THE DECTAPE DIRECTORY
MTREW. OUT, ; REWIND THE DECTAPE or MAGTAPE
PUSHJ P,OPENWR ; RE-OPEN AND ENTER THE FILE
JRST SUCRET ; AND GIVE SUCCESS RETURN TO CALLER
; SFSDEF - Set filespec defaults, but don't open any file
SFSDEF: SETZM FS$EXT(L) ;[16000] Clear extension also
SFSDF0: SETZM FS$FLG(L) ;[16000] Clear out flags
SETZM FS$NAM(L) ;[16000] and name (leave device alone)
SETZM FS$PRV(L) ;[16000] and protection word...
HRLI X,FS$PRV(L) ;[16000] Set up BLT pointer
HRRI X,FS$PRV+1(L) ;[16000] to zero rest of block
BLT X,FS$LTH-1(L) ;[16000] and zero it
PUSHJ P,SETFSP ;[16000] and fill in from code
JRST SUCRET ;[16000] Return win
SUBTTL $EE
; $EE - WRITE OUT LOWSEG AS A ZERO-COMPRESSED SAVE FILE (RUNNABLE)
;
; CALL: JSP PC,$$EE
; <FILE-SPEC>
; (RETURN)
$EE: MOVEI L,LEESPC ; FETCH ADR OF FILE-SPEC
TXZE F,F$2CO ;[16000] ::EE just sets defaults
PJRST SFSDF0 ;[16000] so go do that instead
PUSHJ P,SETFSP ; AND FILL IN DEFAULTS
PUSH P,.JBSA ; SAVE .JBSA
PUSH P,.JBCOR ; SAVE .JBCOR
PUSH P,X ; MAKE SURE ENOUGH ROOM ON STACK
PUSH P,X ; . . .
PUSH P,X ; . . .
PUSH P,X ; . . .
POP P,X ; . . .
POP P,X ; . . .
POP P,X ; . . .
POP P,X ; . . .
; REDUCE SIZE BY FORCING A GARBAGE COLLECTION
PUSHJ P,GARCOL ; GARBAGE COLLECT
; STORE .JBFF IN .JBSA AND .JBCOR AND CHANGE START ADR TO 'RUNENT'
MOVEI X,RUNENT ; FETCH NEW START ADR
MOVEM X,.JBSA ; AND STORE IN .JBSA
MOVE X,.JBFF ; FETCH .JBFF
HRLM X,.JBSA ; AND STORE IN .JBSA
HRLI X,(X) ; PUT .JBFF IN BOTH HALVES OF .JBCOR
HLRZ T1,.JBCOR ; FETCH .JBCOR
CAIGE T1,(X) ; NEED TO SET .JBCOR?
MOVEM X,.JBCOR ; YES, SET .JBCOR
; SAVE FLAGS AND ACS FOR RESTORATION ON NEXT RUN
MOVE T1,F ; FETCH FLAGS
TXZ T1,F$$IO ; AND CLEAR I/O FLAGS
MOVEM T1,ACSAVE ; AND SAVE FOR NEXT RUN
PUSH P,.JBDDT ; STORE DDT START ADR
PUSH P,[<$EECON>] ; STORE ADR OF WHERE TO GO AFTER RUN&GETSEG
MOVE 1,[<2,,ACSAVE+2>] ; SETUP BLT POINTER
BLT 1,ACSAVE+17 ; AND SAVE ACS FOR NEXT RUN
; INIT DSK:FILE.SAV or .EXE
SETZ N, ; USE CHANNEL 0
MOVSI M,INIBH ; FETCH ADR OF INPUT BUFFER HEADER
PUSHJ P,FILOPN ; OPEN THE DEVICE ('DSK')
CERROR (ODV) ; ** OUTPUT DEVICE OPEN FAILURE **
MOVEI M,^D75 ;[15000] Save file would probably get this big
PUSHJ P,FILENT ; ENTER THE FILE (FILE.SAV[,])
CERROR (ENT) ; ** ENTER ERROR **
SETSTS .IOIBN ; CHANGE TO IMAGE BINARY MODE
MOVEI X,(POINT 36,) ; FETCH PROPER BYTE SIZE
HRLM X,INIBH+1 ; AND SET IT IN BUFFER HEADER
HLRZ X,FS$EXT(L) ;[21000] Make .EXE file if extension is .EXE
CAIN X,'EXE' ;[21000] ...
JRST $EEXE ;[21000] Write an .EXE file
; NOW WRITE OUT THE FILE IN ZERO-COMPRESSED FORMAT
MOVEI N,.JBPFI+1 ; WHEN TO START SAVING
$EE1: SKIPN (N) ; FIND A NON-ZERO?
JSP L,$EE5 ; NO, TRY NEXT WORD
CAML N,.JBFF ; YES, AT END OF CORE?
JRST $EE2 ; YES, DONE
; FOUND A NON-ZERO WORD. COUNT # CONSECUTIVE NON-ZERO AND WRITE OUT
MOVE M,N ; SAVE AC N
SKIPE (N) ; FIND A ZERO?
JSP L,$EE5 ; NO, KEEP LOOKING
SUBM M,N ; YES, COMPUTE # CONSECUTIVE
MOVS N,N ; AND FORM AN IOWD
HRRI N,-1(M) ; FORM: IOWD LEN,,ADR
PUSHJ P,$EE3 ; AND WRITE OUT THE IOWD
MOVE C,N ; SAVE CURRENT ADR
MOVE N,1(C) ; FETCH A NON-ZERO DATA WORD
PUSHJ P,$EE3 ; WRITE OUT A WORD OF DATA
AOBJN C,.-2 ; AND DO FOR ALL CONSECUTIVE NON-ZEROS
MOVEI N,1(C) ; COMPUTE ADR OF WHERE TO START
; SEARCH FOR NEXT NON-ZERO DATA
CAMGE N,.JBFF ; ARE WE DONE?
JRST $EE1 ; NO, KEEP GOING
; DONE. FINISH UP.
$EE2: MOVE N,[JRST RUNENT] ; FETCH INST. TO START PROGRAM
PUSHJ P,$EE3 ; AND WRITE TO
$EEND: POP P,X ; CLEAN UP STACK
POP P,X ;[357] . . .
POP P,.JBCOR ; RESTORE .JBCOR
POP P,.JBSA ; AND RESTORE .JBSA
RELEAS 0, ; RELEAS CHANNEL 0
JRST (PC) ; AND RETURN TO CALLER
; OUTPUT ONE WORD TO FILE
$EE3: SOSGE INIBH+2 ; ANY ROOM LEFT IN BUFFER?
JRST $EE4 ; NO, OUTPUT THE BUFFER
IDPB N,INIBH+1 ; YES, STORE THE CHAR IN BUFFER
POPJ P, ; AND RETURN TO CALLER
; OUTPUT BUFFER TO FILE
$EE4: OUT 0, ; OUTPUT THE BUFFER
JRST $EE3 ; AND CONTINUE
$EERR: GETSTS 0,IOSTS ; FAILED. GET STATUS OF CHANNEL
POP P,X ; CLEAN STACK
POP P,X ; . . .
POP P,.JBCOR ; RESTORE .JBCOR
POP P,.JBSA ; RESTORE .JBSA
ERROR (OUT) ; AND GIVE OUTPUT ERROR MESSAGE
; CHECK IF AC N.GE..JBFF ELSE RETURN .-2
$EE5: CAML N,.JBFF ; .GE..JBFF?
JRST (L) ; YES, JUST NORMAL RETURN
AOJA N,-2(L) ; NO, INCR. N AND RETURN .-2
; $EEXE -- Write an .EXE file
$EEXE:
MOVE N,[1776,,3] ;[21000] Build directory in buffer
PUSHJ P,$EE3 ;[21000] Write start of directory section
MOVE N,[100000,,1] ;[21000] Writable, starting @ file page 1
PUSHJ P,$EE3 ;[21000] ...
HRLZ N,.JBREL ;[21000] Get length of loseg
TLZ N,777 ;[21000] Convert to page # - 1
PUSHJ P,$EE3 ;[21000] # of pages-1 , Process page 0
MOVE N,[1777,,1] ;[21000] Terminating section
PUSHJ P,$EE3 ;[21000] ...
OUTPUT 0, ;[21000] Force it out
SETSTS 0,.IODMP ;[21000] Change to dump mode
MOVE T1,[IOWD 1,INIBF+3] ;[21000] Now zeros for rest of page
SETZB T2,INIBF+3 ;[21000] I/O list is now in T1 & T2
REPEAT <<1000/C$BUFL>-1>,<
OUTPUT 0,T1 ;[21000] ...
>
MOVEI T1,INIBF+3 ;[21000] Prepare to BLT bottom of page 0
BLT T1,INIBF+C$BUFL+2 ;[21000] do it (we can't dump that stuff)
MOVE T1,[IOWD C$BUFL,INIBF+3] ;[21000] Set up I/O list
OUTPUT 0,T1 ;[21000] Write out jobdat & then some
MOVN T1,.JBREL ;[21000] Get back - size of loseg
ADDI T1,C$BUFL-1 ;[21000] Allow for what we already wrote
MOVSI T1,(T1) ;[21000] Build I/O word for rest of core
HRRI T1,C$BUFL-1 ;[21000] ...
OUT 0,T1 ;[21000] And finally catch I/O errors
JRST $EEND ;[21000] We're done
JRST $EERR ;[21000] We lost
; $EECON - COME HERE AFTER RUN&GETSEG IN AN "EE" SAVE FILE
$EECNT: RESET ;[320] CLEAR THE WORLD
POP P,X ; RESTORE THE DDT START ADR
SETDDT X, ; . . . (WHAT? YOU'VE NEVER USED 'SETDDT'???)
POP P,.JBCOR ; RESTORE .JBCOR
POP P,.JBSA ; RESTORE .JBSA
MOVE X,[PUSHJ P,UUOTRP] ;[325] RESTORE LUUO TRAP
MOVEM X,.JB41 ;[325] . . .
MOVX X,AP.REN!AP.POV!AP.ILM ; ENABLE APR FOR PDL OV AND ILL MEM REF
APRENB X, ; . . .
PUSHJ P,MAKCJN ; MAKE OUR CCL JOB NUMBER
PUSHJ P,TTOPEN ;[11000] Open the TTY for echo control
MOVE X,.JBVER ;[325] FETCH LOWSEG VERSION #
XOR X,.HIGH.+.JBHVR ;[12000] [325] COMPARE WITH HISEG VERSION #
TLNE X,777777 ;[12000] Check left half only
ERROR (VAI) ;[311] NO, VERSIONS ARE INCOMPATIBLE
MOVEI X,INTBLK ;[20000] Set up .JBINT for ^C trap if needed
MOVEM X,.JBINT ;[20000] or even if not needed...
JRST (PC) ; AND CONTINUE WITH WHATEVER WAS
; AFTER THE "EE" COMMAND
SUBTTL $EG and $EX and MONRET
; $EG - PERFORM "EX" AND DO PREVIOUS COMPILE-CLASS MONITOR COMMAND
;
; CALL: JSP PC,$$EG
; (CONTROL IS TRANSFERRED TO SYS:COMPIL)
$EG: MOVSI X,'SYS' ; FETCH SYSTEM DEVICE NAME
MOVEM X,LRPSPC+FS$DEV ; AND STORE IN RUN FILE-SPEC
MOVE X,['COMPIL'] ; FETCH COMPIL'S NAME
MOVEM X,LRPSPC+FS$NAM ; AND STORE IN FILE-SPEC
SETZM LRPSPC+FS$EXT ; CLEAR THE FILE EXTENSION
SETZM LRPSPC+FS$PPN ; AND THE PPN
MOVEI X,1 ; /RUNOFFSET:1
MOVEM X,RUNOFS ; . . .
;[14000]TXO F,F$EDC ;No more FLAG THAT A PROGRAM IS TO BE RUN
; JRST $EX ; AND DO THE "EX"
; $EX - PUNCH REST OF INPUT FILE AND EXIT OR RUN A PROGRAM
;
; CALL: JSP PC,$$EX
; (RETURN IF USER TYPES .CONTINUE)
$EX: SKPINL ; PUT USER'S TERMINAL BACK IN .IOASL MODE
JFCL ; . . .
MOVSI ARG,1 ; PUNCH REST OF INPUT FILE
TXNE F,F$UWR ; Is there an output file
PUSHJ P,PUNBUF ; YES, PUNCH THE REST OF THE INPUT FILE
$EX1:
TXNE F,F$UBK ; AN "EB" IN PROGRESS?
PUSHJ P,BAKCLS ; YES, FINISH IT
; [21000] Now execute the *EXIT macro, if there is one.
MOVX T1,'*EXIT ' ;[21000] Get name of macro
PUSHJ P,QGET ;[21000] Try to find one
JRST $EX2 ;[21000] ain't none
TXNN T2,QB$BID ;[21000] Any text in it?
JRST $EX2 ;[21000] NOPE
MOVE N,T2 ;[21000] Get the buffer ID
MOVX L,'*EXIT ' ;[21000] Remember the macro name
PUSHJ P,MACRO ;[21000] Execute it
$EX2: SKIPN @TXTBUF ;[22000] Don't bitch if no text
JRST $EX3 ;[22000] as is the case
TXNN F,F$UWR ;[22000] ANY OUTPUT FILE?
ERROR (NFO) ;[14000] Don't let luser lose his text
$EX3: RELEAS INP, ; RELEAS INPUT AND OUTPUT CHANNELS
RELEAS OUT, ; . . .
RELEAS LOG, ;[330] . . .
TXZ F,F$$IO ;[313] RESET I/O FLAGS
; JRST MONRET ; AND EXIT (OR RUN A PROGRAM)
; MONRET - EXIT TO MONITOR COMMAND LEVEL OR RUN A PROGRAM
MONRET: SKIPN LRPSPC+FS$NAM ;[14000] See if we have a program to run
JRST MONRT1 ; NO, JUST EXIT
; DO A RUN MUUO ON FILE SPECIFIED IN LAST "ED" COMMAND
MOVE T1,LRPSPC+FS$DEV ; FETCH THE DEVICE NAME
MOVE T2,LRPSPC+FS$NAM ; FETCH THE FILE NAME
MOVE T3,LRPSPC+FS$EXT ; FETCH THE FILE EXTENSION
SETZB T4,T5+1 ; ZERO UNUSED WORDS OF RUN BLOCK
MOVE T5,LRPSPC+FS$PPN ; FETCH THE PPN
MOVEI C,T1 ; SETUP ADR OF RUN BLOCK
HRL C,RUNOFS ; PLUS THE RUNOFFSET
RUN C, ; DO THE RUN MUUO
HALT .-1 ; LET MONITOR DO ERROR PROCESSING
; DO A MONRT. AND CONTINUE IF USER TYPES "CONTINUE"
MONRT1: MONRT. ; RETURN TO MONITOR COMMAND LEVEL
JRST (PC) ; RETURN TO CALLER IF USER TYPES COONTINUE
SUBTTL SSTPSC - Prescan a Search String
; SSTPSC - PRESCAN A SEARCH STRING
;
; GEN: <CHAR.ADR,,<X>B18+<Y>B19+TEXT.LENGTH> ; X:=1 IF EXACT MODE
; ; X:=0 IF BOTH UC AND LC MATCH
; ; Y:= (ED & 1)
;
; CALL: PUSHJ P,SSTPSC
; (RETURN)
;
; SMASHES ACS X,T1-T4,C
;
; T2 HOLDS DELIMITER CHAR
; T3 HOLDS <CHAR.ADR,,<X>B18>
; T4 HOLDS <TEXT LENGTH>
SSTPSC: SETZ T4, ; CLEAR THE TEXT LENGTH COUNT
MOVE T2,DELIM ; [12000] Get default delimiter
TXZN F,F$DTM ; IS STRING IN DELIMITED MODE?
JRST SSTPS1 ; NO, ALTMODE IS THE DELIMITER
PUSHJ P,CMDGCH ; YES, FETCH THE DELIMITER CHAR
ERROR (USR) ; NONE LEFT. ** UNTERMINATED SEARCH ARGUMENT **
MOVEI T2,(C) ; COPY THE DELIMITER CHAR
SSTPS1: PUSHJ P,CURCHA ; FETCH ADR OF SEARCH STRING IN COMMAND STRING
MOVSI T3,(T1) ; SAVE THE CHAR.ADR OF STRING
MOVX X,ED$UAR ;[16000] Up-arrow mode??
TDNE X,EDVAL ;[16000] ...
TRO T3,200000 ;[16000] Remember it forever
; SCAN THE COMMAND STRING UNTIL THE DELIMITER CHAR IS SEEN
SSTPS2: PUSHJ P,CMDGCH ; FETCH THE NEXT COMMAND CHAR
ERROR (USR) ; NONE LEFT. ** UNTERMINATED SEARCH ARGUMENT **
CAIN C,(T2) ; IS IT THE DLIMITER CHAR?
JRST SSTPS4 ; YES, SCAN IS COMPLETE
SSTP2X: AOJ T4, ; INCREMENT THE TEXT LENGTH COUNT
CAIN C,"^" ;[16000] Is this an uparrow??
TRNE T3,200000 ;[16000] do we care?
JRST SSTP2Y ;[16000] no
PUSHJ P,CMDGCH ;[16000] Get the next character...
ERROR (USR) ;[16000] Un-terminated search error
ANDI C,37 ;[16000] Make it a control character
JRST SSTP2X ;[16000] And do all our good stuff to it
SSTP2Y: CAIE C,.CHCNR ; IS IT ^R?
CAIN C,.CHCNQ ; OR ^Q?
JRST SSTPS3 ; YES
; CAIN C,.CHCNT ; IS IT ^T?
; TXCA F,F$CNT ; YES, SET THE "^R AND ^T ARE ONLY SPECIALS" FLAG
; TXNE F,F$CNT ; ARE WE IN ^T MODE?
; JRST SSTPS2 ; YES, ^R AND ^T ARE THE ONLY SPECIAL CONTROL CHARS
CAIE C,.CHCNV ; NO, ^V?
CAIN C,.CHCNW ; OR ^W?
TRO T3,1B18 ; YES, SET THE EXACT MODE FLAG
JRST SSTPS2 ; AND CONTINUE SCAN
; ^R AND ^Q - TAKE NEXT CHAR AS TEXT
SSTPS3: PUSHJ P,CMDGCH ; FETCH NEXT COMMAND CHAR
SSTUSR: ERROR (USR) ; NONE LEFT. ** UNTERMINATED SEARCH ARGUMENT **
AOJA T4,SSTPS2 ; AND CONTINUE SCAN
; SCAN COMPLETE. GEN <CHAR.ADR,,<X>B18+TEXT.LENGTH>
SSTPS4: CAILE T4,C$SRHL ; TOO MANY CHARS?
ERROR (STC) ; YES, ** TOO MANY CHARS IN SEARCH STRING **
IOR T3,T4 ; FORM <CHAR.ADR,,<X>B18+TEXT.LENGTH>
PUSH CP,T3 ; AND GEN IT INTO CODE
POPJ P, ; AND RETURN TO CALLER
SUBTTL SSTGSM - Generate a Search Matrix
; SSTGSM - GENERATE SEARCH MATRIX FOR A SEARCH ARGUMENT
; - COPIES SEARCH STRING FROM COMMAND STRING TO 'SRHARG'
; - GENERATE SEARCH MATRIX INTO 'SRHTAB'
; - STORES LENGTH OF SEARCH ARGUMENT IN 'SRHCTR'
; - STORES BIT POINTER FOR SEARCH MATRIX IN 'SRHSMP'
;
; CALL: MOVE T3,[<CHAR.ADR,,<X>B18+TEXT.LENGTH>]
; ; X:=1 IF SEARCH IS TO BE MADE IN EXACT MODE
; ; X:=0 IF SEARCH IS TO MATCH BOTH LC AND UC
; PUSHJ P,SSTGSM
; (RETURN)
;
; IF 'TEXT.LENGTH' IS ZERO, PREVIOUS SEARCH ARGUMENT AND MATRIX ARE USED.
;
; ACS X,T1-T4,N,M ARE SMASHED
;
; T2 HOLDS BYTE POINTER TO SOURCE
; T3 HOLDS COUNT OF CHARS LEFT IN TEXT
; T4 HOLDS BYTE POINTER TO 'SRHARG'
; N HOLDS BIT POSITION FOR SEARCH MATRIX
; M HOLDS ^E NESTING LEVEL
SSTGSM: TXZ F,F$$TX ; CLEAR SOME FLAGS
HLRZ T1,T3 ; FETCH CHAR.ADR OF SEARCH STRING
SOJ T1, ; 'CAUSE BP WILL BE INCREMENTED BEFORE USE
PUSHJ P,CTOBP ; CONVERT CHAR.ADR-1 TO A BYTE POINTER
MOVE T2,T1 ; PUT THE BP IN AC T2
ADD T2,@CMDBUF ; MAKE IT AN ABSOLUTE ADR
TRZE T3,1B18 ; SEARCH IN EXACT MODE?
TXO F,F$EXM ; YES
TRZE T3,1B19 ;[16000] Compiled with uparrow mode?
TXO F,F$UAR ;[16000] Remember it for a while at least
MOVEI T3,(T3) ; COMPUTE TEXT.LENGTH COUNT
JUMPE T3,CPOPJ ; DONE IF SEARCH STRING IS NULL
STORE (X,SRHTAB,SRHTAB+SRHLN-1,0) ; CLEAR THE SEARCH MATRIX
MOVEM T3,SRHCTR ; STORE THE LENGTH OF THE SEARCH STRING
MOVE T4,[POINT 7,SRHARG] ; SETUP BP TO SRHARG
STORE (X,SRHARG,SRHARG+^D<80/5-1>,0) ; CLEAR SEARCH ARG
MOVSI N,(1B0) ; INIT THE SEARCH MATRIX BIT POINTER
SETZ M, ; CLEAR ^E[...] LEVEL COUNT
; SCAN SEARCH STRING AND SET UP SEARCH MATRIX
SSTGS1: ILDB C,T2 ; FETCH CHAR FROM SEARCH STRING
IDPB C,T4 ; AND STORE IN SRHARG
SSTG1X: MOVE T1,[IOWD S2TL,S2T+1] ; SETUP PTR TO SPECIAL CTL CHAR TABLE
; TXNE F,F$CNT ; IN ^T MODE?
; MOVE T1,[IOWD S3TL,S3T+1] ; YES, USE SHORT DISPATCH TABLE
PUSHJ P,DISPAT ; DISPATCH ON SPECIAL CONTROL CHARS
;[14000] Don't bitch about controls
; TXNN F,F$CNT ; NOT SPECIAL. IN ^T MODE?
; PUSHJ P,CHKNCC ; YES, CHECK FOR ILLEGAL CONTROL COMMANDS
SSTGS2: TXNE F,F$EMA ; ACCEPT EITHER LC OR UC?
JRST SSTGS8 ; YES
TXNN F,F$CNX ; EXACT SEARCH MODE?
TXNE F,F$EXM ; . . . ?
JRST SSTGS3 ; YES
; BOTH LC AND UC LETTERS MATCH
SSTGS8: CAIG C,"Z"+40 ; IS CHAR A LC LETTER?
CAIGE C,"A"+40 ; . . . ?
SKP ; NO
TRZ C,40 ; YES, UPCASE IT
CAIG C,"Z" ; IS CHAR UC LETTER?
CAIGE C,"A" ; . . . ?
JRST SSTGS3 ; NO
XORM N,SRHTAB+40(C) ; YES, SET THE LC ENTRY FOR LETTER ALSO
JRST SSTGS4 ; NOW SET THE UC ENTRY FOR LETTER
SSTGS3: PUSHJ P,CASE ; TAKE CARE OF CASE SETTING FOR CHAR
SSTGS4: XORM N,SRHTAB(C) ; SET SEARCH MATRIX ENTRY FOR CHAR
SSTGS5: SOJ T3, ; DECREMENT # CHARS LEFT IN SEARCH STRING
JUMPN M,CPOPJ ; RETURN IF GATHERING DATA FOR ^E[A,B,C]
TXZN F,F$CNN ; WAS PREVIOUS CHAR ^N?
JRST SSTGS6 ; NO
ANDCAM N,SRHTAB+$CHBEG ; CLEAR FAKE CHARACTERS
ANDCAM N,SRHTAB+$CHSPC ; . . .
ANDCAM N,SRHTAB+$CHEND ; . . .
SSTGS6: LSH N,-1 ; ADVANCE SEARCH MATRIX TO NEXT POSITION
SSTGS9: JUMPLE T3,SSTGS7 ; SCAN COMPLETE
JUMPN N,SSTGS1 ; KEEP SCANNING IF .LT.36. CHARS
ERROR (STL) ; NO. ** SEARCH STRING TOO LONG **
; SCAN COMPLETE. STORE BIT POINTER FOR SEARCH MATRIX
SSTGS7: MOVEM N,SRHSMP ; STORE SEARCH MATRIX POINTER
POPJ P, ; AND RETURN TO CALLER
; DISPATCH TABLES FOR SPECIAL CONTROL COMMANDS IN SEARCH STRINGS
; DURING SEARCH MATRIX
S2T: <.CHCNE,,SSGCNE>
<.CHCNX,,SSGCNX>
<.CHCNN,,SSGCNN>
<.CHCNS,,SSGCNS>
<.CHCNV,,SSGCNV>
<.CHCNW,,SSGCNW>
<.CHCBS,,SSGCBS>
<.CHCCF,,SSGCUP>
<"^",,SSGUA> ;[16000] Up-arrow mode
S3T:; <.CHCNT,,SSGCNT>
<.CHCNQ,,SSGCNQ>
<.CHCNR,,SSGCNR>
S3TL==.-S3T
S2TL==.-S2T
; ^X - SET SEARCH MATRIX TO MATCH ANY ARBITRARY CHARACTER
SSGCNX: MOVE X,[<-SRHLN+4,,1>] ; TO SET ALL CHARS
; EXCEPT NULL AND FAKE CHARS
SSGSET: PUSHJ P,SSGSTB ; SET CHARACTER(S) IN SEARCH MATRIX
JRST SSTGS5 ; AND CONTINUE SCAN
; ^N - SET SEARCH MATRIX TO REVERSE SENSE OF SEARCH FOR THE
; ARBITRARY CHARACTER THAT FOLLOWS (MAY BE ^E,^N,ETC.)
SSGCNN: MOVE X,[<-SRHLN+4,,1>] ; SET SEARCH MATRIX FOR ALL CHARS (EXCEPT NULL)
PUSHJ P,SSGSTB ; . . .
TXO F,F$CNN ; FLAG THAT A ^N WAS SEEN
SOJG T3,SSTGS1 ; AND CONTINUE SCAN
ERROR (ICN) ; NO CHARS LEFT. ** ILLEGAL ^N COMMAND **
; ^S - SET SEARCH MATRIX TO MATCH NON-SYMBOL CONSTITUENTS
; (IE: NOT(A-Z,0-9,.,%,$)
; ^B - Same as ^S but easier to type on tubes with PAGE set
SSGEM: XORM N,SRHTAB+$CHSPC ;[10000] Any number of... (^EM)
SOJG T3,SSTGS1 ;[10000]
ERROR(ICA) ;[10000]
SSGEB:
SSGCNS: MOVE X,[<-SRHLN+3,,1>] ; SET SEARCH MATRIX FOR ALL CHARS
PUSHJ P,SSGSTB ; EXCEPT NULL AND FAKE CHARS EXCEPT BEGPAGE
MOVE T1,EDVAL ;[10000] ^O40ED = bliss mode
TXNE T1,ED$BLI ;[10000]
JRST [XORM N,SRHTAB+"_" ;[10000]
XORM N,SRHTAB+"&" ;[10000]
JRST .+2] ;[10000]
XORM N,SRHTAB+"." ; DON'T ALLOW "."
XORM N,SRHTAB+"%" ; DON'T ALLOW "%"
XORM N,SRHTAB+"$" ; DON'T ALLOW "$"
MOVE X,[<-^D10,,"0">] ; DON'T ALLOW DIGITS
PUSHJ P,SSGSTB ; . . .
SSGEA: MOVE X,[<-^D26,,"A">] ; ENTRY POINT FOR ^EA
PUSHJ P,SSGSTB ; SET/CLEAR UC LETTERS
SSGEV: MOVE X,[<-^D26,,"A"+40>] ; ENTRY POINT FOR ^EV
JRST SSGSET ; SET/CLEAR UC LETTERS
; ^V - DOWNCASE FOLLOWING CHAR IF A LETTER
; ^V^V - DOWNCASE FOLLOWING LETTERS TILL END OF STRING OR FURTHER NOTICE
SSGCNV: PUSHJ P,CNV ; SET FLAGS FOR ^V
SOJA T3,SSTGS9 ; AND CONTINUE SCAN
; ^W - UPCASE THE FOLLOWING CHAR IF A LETTER
; ^W^W - UPCASE FOLLOWING LETTERS TILL END OF STRING OR FURTHER NOTICE
SSGCNW: PUSHJ P,CNW ; SET FLAGS FOR ^W
SOJA T3,SSTGS9 ; AND CONTINUE SCAN
; ^\ - COMPLEMENT FORCED EXACT SEARCH MODE
SSGCBS: TXC F,F$EMA ; COMPLEMENT THE FORCED EXACT SEARCH MODE FLAG
SOJA T3,SSTGS9 ; AND CONTINUE SCAN
; ^^ - DOWNCASE THE FOLLOWING CHAR IF @,[,\,],OR _
SSGCUP: SOJLE T3,SSTUSR ;[20000] Un-terminated search error
ILDB C,T2 ; FETCH THE FOLLOWING CHAR
IDPB C,T4 ; AND STORE IN SRHARG
PUSHJ P,CNUAR ;DOWNCASE IT IF @,[,\,],_
SOJA T3,SSTGS2 ; AND CONTINUE SCAN
; ^T - COMPLEMENT THE ^T MODE. DISABLES ALL CONTROL COMMANDS EXCEPT ^R,^Q,^T
;SSGCNT: TXC F,F$CNT ; COMPLEMENT ^T MODE FLAG
; SOJA T3,SSTGS9 ; AND CONTINUE SCAN
; ^R - TAKE THE FOLLOWING CHAR AS TEXT
SSGCNR:
; ^Q - TAKE THE FOLLOWING CHAR AS TEXT
SSGCNQ: ILDB C,T2 ; FETCH THE FOLLOWING CHAR
IDPB C,T4 ; AND STORE IT IN SRHARG
SOJA T3,SSTGS2 ;[373] AND CONTINUE SCAN
; ^ - Take next character as control, if enabled
SSGUA: TXNE F,F$UAR ;[16000] Is up-arrow really up-arrow?
JRST SSTGS4 ;[16000] Yes, treat as ordinary character
ILDB C,T2 ;[16000] Fetch the following character
ANDI C,37 ;[16000] Make it a control
SOJA T3,SSTG1X ;[16000] and process it
; ^E COMMANDS
SSGCNE: ILDB C,T2 ; FETCH THE FOLLOWING CHAR
PUSHJ P,UPCASE ;[12000] Make upper case
IDPB C,T4 ; AND STORE IT IN SRHARG
SOJLE T3,SSGCEE ; NONE LEFT. ** ^E COMMAND ERROR **
MOVE T1,[IOWD S4TL,S4T+1] ; FETCH PTR TO DISPATCH TABLE
PUSHJ P,DISPAT ; DISPATCH ON THE FOLLOWING CHAR
SSGCEE: ERROR (ICE) ; ** ILLEGAL ^E COMMAND **
; DISPATCH TABLE FOR ^E COMMANDS DURING SEARCH MATRIX GENERATION
S4T: <"A",,SSGEA>
<"B",,SSGEB> ;[14000] ^EB = ^S
<"M",,SSGEM> ;[14000] ^EMc any number of c
<"V",,SSGEV>
<"W",,SSGEW>
<"D",,SSGED>
<"L",,SSGEL>
<"S",,SSGES>
<.CHLAB,,SSGEAB>
<"[",,SSGESB>
S4TL==.-S4T
; ^EW - SET SEARCH MATRIX FOR UPPER CASE LETTERS
SSGEW: SKIPA X,[<-^D26,,"A">] ; FETCH AOBJN PTR FOR UC LETTERS
; ^ED - SET SEARCH MATRIX FOR DIGITS
SSGED: MOVE X,[<-^D10,,"0">] ; FETCH AOBJN PTR FOR DIGITS
JRST SSGSET ; SET SEARCH MATRIX AND CONTINUE SCAN
; ^EL - SET SEARCH MATRIX TO MATCH END-OF-LINE DELIMITERS
SSGEL: MOVE X,[<-3,,.CHLFD>] ; FETCH AOBJN POINTER FOR <LF><VT><FF>
JRST SSGSET ; AND SET SEARCH MATRIX AND CONTINUE SCAN
; ^ES - SET SEARCH MATRIX TO MATCH ARBITRARY # SPACES AND/OR TABS
SSGES: XORM N,SRHTAB+.CHSPC ; SET THE SPACE ENTRY IN SEARCH MATRIX
XORM N,SRHTAB+.CHTAB ; SET THE TAB ENTRY
XORM N,SRHTAB+$CHSPC ; SET ENTRY FOR ARBITRARY #
JRST SSTGS5 ; AND CONTINUE SCAN
; ^E<NNN> - SET SEARCH MATRIX TO MATCH ASCII CHAR WHOSE OCTAL CODE IS NNN
SSGEAB: SETZ X, ; SET NUMBER:=0
SSGEA1: ILDB C,T2 ; FETCH NEXT CHAR
IDPB C,T4 ; AND STORE IN SRHARG
SOJL T3,SSGCEE ; ERROR IF NO CHARS LEFT
CAIN C,.CHRAB ; IS CHAR A RIGHT ANGLE BRACKET?
JRST SSGEA2 ; YES, DONE WITH NNN
CAIG C,"7" ; IS CHAR AN OCTAL DIGIT?
CAIGE C,"0" ; . . . ?
ERROR (ICE) ; NO. ** ILLEGAL ^E COMMAND **
LSH X,3 ; YES, MAKE ROOM FOR THE DIGIT
IORI X,-"0"(C) ; AND ADD IN THE DIGIT
JRST SSGEA1 ; AND TRY FOR ANOTHER DIGIT
SSGEA2: ANDI X,177 ; MAKE OCTAL CODE 7 BITS
XORM N,SRHTAB(X) ; AND SET ENTRY IN SEARCH MATRIX
JRST SSTGS5 ; AND CONTINUE SCAN
; ^E[A,B,C] - ACCEPT "A" XOR "B" XOR "C" FOR THIS CHAR POSITION
; A,B,C ARE ANY STRING ELEMENTS INCLUDING ^E COMMANDS
SSGESB: AOJ M, ; COUNT THE LEVELS OF ^E NESTING
SSGES1: PUSHJ P,SSTGS1 ; PROCESS FOLLOWING CHAR
ILDB C,T2 ; FETCH NEXT CHAR
IDPB C,T4 ; AND STORE IN SRHARG
SOJL T3,SSGCEE ; ERROR IF NONE LEFT
CAIN C,"," ; IS CHAR ","?
JRST SSGES1 ; YES, CONTINUE [A,B,...]
CAIE C,"]" ; NO IS CHAR TERMINATING "]"?
ERROR (ICE) ; NO. ** ILLEGAL ^E COMMAND **
SOJA M,SSTGS5 ; YES, DECR ^E NESTING COUNT AND CONTINUE SCAN
; SSGSTB - SET SEARCH MATRIX FOR MULTIPLE CHARACTERS IN SAME POSITION
;
; CALL: MOVE X,[<-LEN,,START.CHAR>]
; PUSHJ P,SSGSTB
; (RETURN)
;
; SMASHES AC X
SSGSTB: XORM N,SRHTAB(X) ; SET ONE CHAR POSITION
AOBJN X,SSGSTB ; LOOP FOR ALL CHARS IN RANGE
POPJ P, ; DONE. RETURN TO CALLER
SUBTTL SERCH and BSERCH - Perform a Search
; SERCH - PERFORM A SEARCH ON THE MAIN TEXT BUFFER FROM "." ON
;
; CALL: PUSHJ P,SERCH
; (FAIL RETURN)
; (SUCCESS RETURN)
;
; SMASHES ACS X,T1-T5,C,N,M
SERCH: MOVE T4,PTVAL ; LOWER BOUND:="."
MOVE T5,@TXTBUF ; UPPER BOUND:=Z
; BSERCH - PERFORM A SEARCH ON THE MAIN TEXT BUFFER WITHIN SPECIFIED BOUNDS
;
; CALL: MOVEI T4,LBOUND ; LOWER BOUND
; MOVEI T5,UBOUND ; UPPER BOUND
; PUSHJ P,BSERCH
; (FAIL RETURN)
; (SUCCESS RETURN)
BSERCH: PUSH P,T4 ; SAVE AC T4
PUSH P,T5 ; SAVE AC T5
PUSHJ P,NXTWRD ; FETCH <CHAR.ADR,,TEXT.LENGTH>
MOVE T3,N ; AND COPY INTO AC T3
PUSHJ P,SSTGSM ; GENERATE THE SEARCH MATRIX
POP P,T5 ; RESTORE AC T5
POP P,T4 ; RESTORE AC T4
EXCH T4,PTVAL ;[14000] Start at this place
MOVEM T4,ACSAVE ;[15000] Save real .
MOVE T4,PTVAL ;[15000] Get back real l.b.
PJRST SEARC0 ; PERFORM THE SEARCH
SUBTTL SEARCH - The Actual Search Routine
; SEARCH - SEARCH THE MAIN TEXT BUFFER (WITHIN BOUNDS) FOR A STRING
;
; CALL: MOVEI ARG,N ; FIND THE NTH OCCURRANCE
; MOVEI T4,LBOUND ; LOWER BOUND CHAR.ADR
; MOVEI T5,UBOUND ; UPPER BOUND. CHAR.ADR
; PUSHJ P,SEARCH
; (FAIL RETURN) ; "." IS B
; (SUCCESS RETURN) ; "." IS AFTER END OF STRING
;
; IT IS ASSUMED THAT SEARCH ARG HAS BEEN COPIED TO 'SRHARG', ITS LENGTH
; STORED IN 'SRHCTR', AND THE SEARCH MATRIX IS IN 'SRHTAB'
;
; SMASHES ACS X,T1,T2,C,N,M
;
; N HOLDS STATIC CHAR.ADR POINTER
; T1 HOLDS STATIC BYTE POINTER
; T2 HOLDS DYNAMIC BYTE POINTER
; M HOLDS BUT POINTER FOR SEARCH MATRIX
SEARCH: MOVE X,PTVAL ; FETCH "."
MOVEM X,ACSAVE ; AND SAVE FOR LATER CHECKING
SEARC0: ;[15000] . already saved
SKIPN SRHCTR ; WAS THERE A PREVIOUS SEARCH ARGUMENT?
ERROR (SNA) ; NO. ** SEARCH WITH NO INITIAL ARGUMENT **
MOVE T3,SRHSMP ; FETCH THE BIT POINTER TO THE LAST
; POSITION IN THE SEARCH MATRIX
TXO F,F$MSR ;TRY NEGATIVE FIRST
CAMG T4,T5 ; IS THIS A MINUS SEARCH?
; (IE: BACKWARDS)
TXZA F,F$MSR ; NO , KEEP ARGS THIS WAY AND ZAP FLAG
EXCH T4,T5 ; EXCHANGE BOUNDS BACK IF NOT MINUS SEARCH
; MAIN SEARCH LOOP
SEARC1: JUMPLE ARG,SEARCS ; SUCCESS IF WE'VE FOUND THE NTH OCCURRANCE
MOVE N,PTVAL ; COPY OF "."
MOVE T1,N ; COPY CURRENT CHAR.ADR
ADDI T1,5*T$DATA-1 ; T1:=CHAR.ADR-1 IN BUFFER
IDIVI T1,5 ; TURN CHAR.ADR INTO A BP
HLL T1,CBPTBL(T2) ; . . .
ADD T1,TXTBUF ; ADD IN THE BASE ADR OF TEXT BUFFER
MOVE T2,T1 ; COPY BP INTO AC T2
JUMPG N,SEARC2 ; JUMP IF NOT AT BEG OF BUFFER
; AT BEGINNING OF BUFFER. SEE IF IT MATCHES FIRST CHAR OF SEARCH
SKIPL SRHTAB+$CHBEG ; DOES BEG OF BUFFER MATCH?
JRST SEARC2 ; NO
MOVX M,1B1 ; YES, START SEARCH AT WITH SECOND CHAR
TXO F,F$BPG ; FLAG THAT BEG OF BUFFER MATCHES
JRST SEARC5 ; AND JUMP INTO THE SEARCH LOOP
; SEE IF SEARCH MATCHES BEGINNING AT CURRENT POSITION
SEARC2: CAML N,T4 ; WITHIN BOUNDS?
CAMLE N,T5 ; . . . ?
JRST SEARC5 ; NO
MOVX M,1B0 ; START WITH FIRST CHAR
MOVE T2,T1 ; DYNAMIC BP:=STATIC BP
JRST SEARC7 ; JUMP INTO THE SEARCH
; CHECK INDIVIDUAL CHARS
SEARC3: TDNE M,SRHTAB+$CHSPC ; MULTIPLE CHARACTERS THIS POSITION?
JRST SERSPC ; YES
AOJ N, ; ADVANCE STATIC POINTER
SEARC4: LSH M,-1 ; ADVANCE SEARCH MATRIX POSITION
SEARC5: CAMN M,T3 ; END OF SEARCH MATRIX?
JRST SEARCS ; YES, FOUND A MATCH
SEARC7: ILDB C,T2 ; FETCH CHAR FROM TEXT BUFFER
TDNE M,SRHTAB(C) ; DOES CHAR MATCH SEARCH MATRIX?
JRST SEARC3 ; YES, TRY NEXT CHAR IN BUFFER
; SEARCH STRING DOES NOT MATCH. ADVANCE STATIC POINTER
TXZE F,F$BPG ; AT BEG OF BUFFER?
JRST SEARC2 ; YES, NOW TRY FIRST CHAR OF SEARCH STRING
TXNE F,F$2CO!F$REE ;[14000] Anchored search?? or aborted?
JRST SRCHF1 ;[14000] Yes. it failed.
TXNE F,F$MSR ; DOING A MINUS SEARCH?
JRST SEARC6 ; YES
AOS N,PTVAL ; ADVANCE THE STATIC CHAR.ADR POINTER
CAMLE N,T5 ; WITHIN BOUNDS?
JRST SRCHF1 ; NO
IBP T1 ; YES, INCREMENT THE STATIC BP
JRST SEARC2 ; AND TRY AGAIN
SEARC6: SOS N,PTVAL ; BACKUP THE STATIC CHAR.ADR POINTER
CAMGE N,T4 ; ABOVE LOWER BOUND?
JRST SRCHF1 ; NO, SEARCH FAILED
ADD T1,[<7B5>] ; YES, DECREMENT STATIC BP
JUMPGE T1,SEARC2 ; AND TRY AGAIN
HRLI T1,(POINT 7,,34) ; . . .
SOJA T1,SEARC2 ; . . .
; SERSPC - SKIP OVER MULTIPLE CHARACTERS
SERSPC: AOJ N, ; ADVANCE TO NEXT CHAR IN BUFFER
CAML N,T4 ; PAST END OF SEARCH BOUNDS?
CAMLE N,T5 ; . . . ?
JRST SEARC4 ; YES, STOP SKIPPING
MOVE X,T2 ; SAVE CURRENT BP
ILDB C,T2 ; GET NEXT CHAR FROM BUFFER
TDNE M,SRHTAB(C) ;[10000] Skip whatever it was
JRST SERSPC ; YES, SKIP IT
MOVE T2,X ; NO, RESTORE BP
JRST SEARC4 ; AND GO BACK FOR MORE OF SEARCH
; SEARCH FAILED
SRCHF1: MOVE X,ACSAVE ; FETCH ORIGINAL "."
MOVEM X,PTVAL ; AND RESTORE IT
TXO F,F$LSF ; "LAST SEARCH FAILED"
SETZ VALUE, ; VALUE:=0
POPJ P, ; GIVE FAIL RETURN TO CALLER
; SEARCH SUCCEEDED
SEARCS: CAML N,T4 ; SUCCEED WITHIN BOUNDS? [16000] boundary
CAMLE N,T5 ; . . . ?
JRST SRCHF1 ; NO, FAILED
TXZ F,F$LSF ; "LAST SEARCH SUCCEEDED"
MOVE X,N ; SAVE CURRENT POINTER
MOVE T2,PTVAL ; SAVE OLD "."
TXNE F,F$MSR ; DO A MINUS SEARCH?
JRST SRCHS2 ; YES
; CHECK IF WE'RE SEARCHING FOR THE NTH OCCURRANCE (N.GT.1)
SRCHS1: MOVEM N,PTVAL ; POSITION "." AFTER SEARCH MATCH-1
SOJG ARG,SEARC1 ; KEEP GOING IF N.GT.1
MOVEM X,PTVAL ; POSITION "." AFTER SEARCH
SUB X,T2 ; COMPUTE THE LENGTH OF THE SEARCH MATCH
MOVEM X,SRHLEN ; AND STORE FOR LATER USE
SETO VALUE, ; SET VALUE TO "SUCCESS"
JRST CPOPJ1 ; AND RETURN TO CALLER
SRCHS2: CAMG N,ACSAVE ; MATCH AFTER "." FOR MINUS SEARCH?
SOSA N,PTVAL ; NO, SEARCH A SUCCESS. DECR "."
SOSA N,PTVAL ; YES, DECR "."
JRST SRCHS1 ; AND SEE IF WE HAVE TO SEARCH AGAIN
JRST SEARC1 ; AND TRY AGAIN
SUBTTL Command Execution Subroutines
; NXTWRD - RETURN WORD AT PC AND INCREMENT PC
;
; CALL: PUSHJ P,NXTWRD
; (RETURN) ; WITH WORD IN AC N
;
; USES ACS X,N. UPDATES PC
NXTWRD: MOVE N,(PC) ; FETCH WORD AT CURRENT PC
AOJA PC,CPOPJ ; INCREMENT PC AND RETURN
; CHKARG - MAKE SURE ARG IS BETWEEN "B" AND "Z"
;
; CALL: PUSHJ P,CHKARG ; WITH ARG IN AC 'ARG'
; (FAIL RETURN) ; ARG IS OUT OF BOUNDS
; (SUCCESS RETURN) ; ARG IS OKAY
CHKARG: JUMPL ARG,.+2 ; ERROR IF ARG IS .LT.0
CAMLE ARG,@TXTBUF ; IS ARG .LE.Z?
POPJ P, ; NO, GIVE FAIL RETURN
JRST CPOPJ1 ; YES, GIVE SUCCESS RETURN TO CALLER
; CHK2RG - MAKE SURE SARG,ARG ARE IN BUFFER AND ERROR IF ARG.LT.SARG
;
; CALL: PUSHJ P,CHK2RG
;
; MODIFIES ACS ARG,SARG
CHK2RG: CAMLE SARG,ARG ; ARE ARGS IN PROPER ORDER
EXCH ARG,SARG ;[21000] Then fix them!
CAMLE SARG,@TXTBUF ; SARG.GT.Z?
MOVE SARG,@TXTBUF ; YES, USE Z AS SARG
JUMPGE SARG,.+2 ; SARG.GE.ZERO?
SETZ SARG, ; NO, USE B AS SARG
CAMLE ARG,@TXTBUF ; ARG.GT.Z?
MOVE ARG,@TXTBUF ; YES, USE Z AS SARG
JUMPGE ARG,.+2 ; ARG.GE.ZERO?
SETZ ARG, ; NO, USE B AS ARG
POPJ P, ; AND RETURN TO CALLER
; EVL2RG - CONVERT SINGLE LINE ARG TO CHARACTER ADRESSES ARGS
;
; CALL: PUSHJ P,EVL2RG
; (RETURN) ; WITH START ADR IN ARG AND END ADR IN SARG
;
; USES ACS T1,T2,T4. MODIFIES ARG,SARG
EVL2RG: MOVE T4,PTVAL ; FETCH CURRENT CHAR ADR
JUMPLE ARG,EVL2R3 ; JUMP IF ARG IS .LE.ZERO
; ARG.GT.ZERO. GO TO THE N-1ST END-OF-LINE
EVL2R1: CAMN T4,@TXTBUF ; AT END OF BUFFER YET?
JRST EVL2R2 ; YES. THAT'S AS FAR AS WE GO
PUSHJ P,GETINC ; FETCH CURRENT CHAR FROM BUFFER AND INCR T4
PUSHJ P,CHKEOL ; IS CHAR END OF LINE?
JRST EVL2R1 ; NO, KEEP GOING
SOJG ARG,EVL2R1 ; YES, KEEP GOING TILL NTH ONE
EVL2R2: MOVE ARG,T4 ; FIRST ARG IS WHERE NTH LINE FROM "." IS
MOVE SARG,PTVAL ; SECOND ARG IS "."
POPJ P, ; RETURN TO CALLER
; ARG.LE.ZERO. GO BACK N END-OF-LINES
EVL2R3: SOJ T4, ; START LOOKING AT "."-1
EVL2R4: MOVE T1,T4 ; FETCH CHAR ADR
JUMPL T1,EVL2R5 ; STOP WHEN BEGINNING OF BUFFER HIT
PUSHJ P,GET ; FETCH CHAR FROM BUFFER
PUSHJ P,CHKEOL ; END OF LINE?
SOJA T4,EVL2R4 ; NO, BACK UP ANOTHER CHAR
AOJLE ARG,.-1 ; YES, KEEP GOING TILL THE NTH ONE
AOSA SARG,T4 ; SECOND ARG IS "." MINUS N LINES
EVL2R5: SETZB SARG,T4 ; IF BEG OF BUFFER HIT, SARG:=0
MOVE ARG,PTVAL ; FIRST ARG IS "."
POPJ P, ; RETURN TO CALLER
; CNV - SET ^V (DOWNCASE NEXT CHAR) FLAG OR LOCK ^V^V FLAG
;
; CALL: PUSHJ P,CNV
; (RETURN)
CNV: TXON F,F$CNV ; SET THE ^V FLAG
POPJ P, ; RETURN TO CALLER IF IT WAR CLEAR
TXZ F,F$CNV!F$CWW ; WAS SET. CLEAR AND SET ^V^V LOCK FLAG
TXO F,F$CVV ; SET ^V^V LOCK FLAG
POPJ P, ; AND RETURN TO CALLER
; CNW - SET ^W (UPCASE NEXT CHAR) FLAG OR LOCK ^W^W FLAG
;
; CALL: PUSHJ P,CNW
; (RETURN)
CNW: TXON F,F$CNW ; SET THE ^W FLAG
POPJ P, ; RETURN TO CALLER IF IT WAS CLEAR
TXZ F,F$CNW!F$CVV ; WAS SET. CLEAR IT
TXO F,F$CWW ; AND SET ^W^W LOCK FLAG
POPJ P, ; AND RETURN TO CALLER
; CNUAR - DOWNCASE CHAR IF IT IS @,[,\,],OR _
;
; CALL: PUSHJ P,CNUAR
; (RETURN)
CNUAR: CAIL C,"[" ; IS IT ONE OF @,[,\,],OR _ ?
CAILE C,"_" ; . . . ?
CAIN C,"@" ; . . . ?
TRO C,40 ; YES, DOWNCASE THE CHAR
POPJ P, ; AND RETURN TO CALLER
; CASE - PUT CHAR IN PROPER CASE (BASED ON FLAGS)
;
; CALL: MOVEI C,CHAR
; PUSHJ P,CASE
; (RETURN)
CASE: CAIL C,"A" ; IS CHAR A LETTER?
CAILE C,"Z" ; . . . ?
CAIL C,"A"+40 ; . . . ?
CAILE C,"Z"+40 ; . . . ?
JRST CASE1 ; NO, CLEAR TEMPORARY CASE FLAGS
; SET THE LETTER TO THE PROPER CASING
TXNE F,F$DNC!F$CNV!F$CVV ; DOWNCASE CHAR?
TRO C,40 ; YES
TXNE F,F$UPC!F$CNW!F$CWW ; UPCASE CHAR?
TRZ C,40 ; YES
; CLEAR TEMPORARY CASE FLAGS
CASE1: TXZ F,F$CNW!F$CNV ; CLEAR TEMP CAPE FLAGS
POPJ P, ; AND RETURN TO CALLER
; GETINC - GET CHAR FROM ADR SPECIFIED IN T4 AND INCREMENT T4
;
; CALL: MOVEI T4,CHAR.ADR
; PUSHJ P,GETINC
; (RETURN) ; WITH CHAR IN AC C AND T4 INCREMENTED
;
; MODIFIES AC T4, SMASHES AC C
GETINC: AOS T1,T4 ; GET ADR INTO T1,INCR T4
SOJA T1,GET ; DECR T1, CALL GET
; GET - FETCH CHAR AT SPECIFIED ADR FROM TEXT BUFFER
;
; CALL: MOVEI T1,CHAR.ADR
; PUSHJ P,GET
; (RETURN) ; WITH CHAR IN AC C
;
; SMASHES ACS T1,T2,C
GET: IDIVI T1,5 ; COMPUTE WORD ADR
ADD T1,TXTBUF ; . . .
MOVEI T1,T$DATA(T1) ; (OVERHEAD WORDS IN BEG OF BUFFER)
HLL T1,CBPTBL(T2) ; MAKE INTO A BYTE POINTER
LDB C,T1 ; AND FETCH CHAR AT SPECIFIED ADR
POPJ P, ; AND RETURN TO CALLER
; INSCHR - INSERT A CHARACTER INTO BUFFER AT "."
;
; CALL: MOVEI C,CHAR
; PUSHJ P,INSCHR
; (RETURN)
INSCHR: MOVEI T1,1 ; WILL MAKE ROOM FOR ONE CHAR
PUSHJ P,MKROOM ; . . .
AOS T1,PTVAL ; ".":="."+1
SOJA T1,PUT ; PUT CHAR AT "."-1
; PUT - PUT CHAR IN BUFFER AT SPECIFIED ADDRESS
;
; CALL: MOVEI T1,CHAR.ADR
; MOVEI C,CHAR
; PUSHJ P,PUT
; (RETURN)
;
; SMASHES ACS T1,T2
PUT: IDIVI T1,5 ; COMPUTE WORD ADDRESS
ADD T1,TXTBUF ; . . .
MOVEI T1,T$DATA(T1) ; (OVERHEAD WORDS AT BEG OF BUFFER)
HLL T1,CBPTBL(T2) ; MAKE INTO A BYTE POINTER
DPB C,T1 ; AND PUT CHAR IN BUFFER
POPJ P, ; RETURN TO CALLER
SUBTTL SETFSP - Fill in Defaults for a File Spec
; SETFSP - Store a File Spec in LFSPC
; USES WHAT IS ALREADY IN LFSPC AS DEFAULTS
;
; CALL: MOVEI PC,FILSPC
; PUSHJ P,SETFSP
; (RETURN)
;
; SMASHES ACS X,T1-T3
SETFSP: MOVE T1,FS$FLG(PC) ; FETCH FILE SPEC FLAGS
TXNE T1,FB$$IO ; ANY I/O SWITCHES?
MOVEM T1,FS$FLG(L) ; YES, USE THEM INSTEAD OF PREVIOUS SWITCHES
MOVE X,FS$DEV(PC) ; FETCH THE DEVICE NAME
TXNE T1,FB$DEV ; FILE SPEC HAVE A DEVICE?
MOVEM X,FS$DEV(L) ; YES, STORE IT
MOVE X,FS$NAM(PC) ; FETCH THE FILE NAME
TXNE T1,FB$NAM ; FILE SPEC HAVE A FILE NAME?
MOVEM X,FS$NAM(L) ; YES, STORE IT
MOVE X,FS$EXT(PC) ; FETCH FILE EXTENSION
TXNE T1,FB$EXT ; FILE SPEC HAVE AN EXTENTION?
MOVEM X,FS$EXT(L) ; YES, STORE IT
;[14000]MOVE X,[%LDSTP] ; FETCH DEFAULT PROTECTION
;[14000]GETTAB X, ; . . .
;[14000] MOVX X,<055B8> ; (IN CASE GETTAB FAILS)
SETZ X, ;[14000] Let system do the defaulting
TXNE T1,FB$PRV ; /PROTECT:NNN SPECIFIED?
MOVE X,FS$PRV(PC) ; YES, FETCH THE PROTECTION CODE
MOVEM X,FS$PRV(L) ; AND STORE IT
TXNN T1,FB$DDR ; DEFAULT DIRECTORY SPECIFIED?
JRST SETFS1 ; NO
; SETZM FS$PPN(L) ; YES, SET DEFAULT DIRECTORY
PUSHJ P,GETPTH ;[342] FETCH MY PATH
MOVEM X,FS$PPN(L) ;[342] SET DEFAULT DIRECTORY
;[3000] JRST SETFS3 ; AND RETURN TO CALLER
MOVE T2,[-C$SFDL,,PATHB+3] ;[3000] COPY SFD IF THAT IS THE DEFAULT
JRST SETF1X ;[3000] JUMP INTO SFD CODE
SETFS1:
TXNN T1,FB$PTH ; PATH SPECIFIED?
JRST SETFS3 ; NO, RETURN TO CALLER
GETPPN X, ; YES, MAKE SURE PPN STORED
JFCL ; (IN CASE OF JACCT)
MOVEM X,FS$PPN(L) ;[421] INITIALIZE DEFAULT
MOVE X,FS$PPN(PC) ; FETCH PPN FROM FILE SPEC
TXNE T1,FB$PRJ ; PROJECT # SPECIFIED IN FILE SPEC?
HLLM X,FS$PPN(L) ; YES, STORE IT
TXNE T1,FB$PRG ; PROGRAMMER # SPECIFIED IN FILE SPEC?
HRRM X,FS$PPN(L) ; YES, STORE IT
IFN C$SFDL,<
;[4000] TXNN T1,FB$SFD ; SFDS IN FILE SPEC?
;[4000] JRST SETFS3 ; NO, RETURN TO CALLER
MOVE T2,[XWD -C$SFDL,FS$SFD] ;[425] SETUP AOBJN LOOP COUNTER
ADDI T2,(PC) ; MAKE IT POINT TO FIRST SFD
SETF1X: ;[3000] LABEL ADDED TO MAKE SFD'S WIN
MOVEI T3,FS$SFD(L) ; FETCH ADR OF WHERE TO STORE SFDS
SETFS2: MOVE X,(T2) ;[3000] FETCH SFD FROM FILE SPEC
;[3000] DON'T SKIP IF NONE
MOVEM X,(T3) ; STORE THE SFD
MOVEI T3,1(T3) ; POINT TO NEXT SFD IN STORED FILE SPEC
AOBJN T2,SETFS2 ; AND LOOP FOR ALL SFDS
>;; END IFN C$SFDL
SETFS3: MOVEI PC,FS$LTH(PC) ; SKIP OVER THE FILE SPEC
POPJ P, ; AND RETURN TO CALLER
SUBTTL SETRAD - Set the Adr of Read-a-Char Routine
; SETRAD - SET ADR OF THE READ-A-CHAR ROUTINE
;
; CALL: MOVEI L,FILSPC
; PUSHJ P,SETRAD
; (RETURN)
;
; SAMSHES ACS X,T1
SETRAD: MOVE T1,FS$FLG(L) ; FETCH FILE-SPEC FLAGS
MOVEM T1,APDFLG ; AND SAVE FOR LATER USE
TXZ F,F$LSN ; CLEAR THE "FILE IS LINE-SEQ." FLAG
TXNN T1,FB$SUP ; /SUPLSN?
TXNN T1,FB$ASC!FB$SIX!FB$OCT ; OR UNSPEC. ASCII?
JRST SETR1 ; YES, CHECK INPUT FILE FOR LSNS
MOVE X,[<ASCAPD,,7>] ; FETCH ADR OF ASCII ROUTINE AND BYTE SIZE
TXNE T1,FB$SIX ; /SIXBIT?
MOVE X,[<SIXAPD,,6>] ; ADR OF SIXBIT ROUTINE AND BYTE SIZE
TXNE T1,FB$OCT ; /OCTAL?
MOVE X,[<OCTAPD,,3>] ; ADR OF OCTAL ROUTINE AND BYTE SIZE
HLRZM X,APDADR ; SAVE ADR OF GET-A-CHAR ROUTINE
DPB X,[POINT 6,INPBH+1,11] ; SET BYTE SIZE IN BUFFER HEADER
POPJ P, ; AND RETURN TO CALLER
; CHECK INPUT FILE FOR LSN'S
SETR1: INPUT INP, ; INPUT THE FIRST BLOCK
MOVE T1,INPBH+1 ; FETCH ADR OF BUFFER
MOVE X,1(T1) ; FETCH FIRST WORD OF FILE
IOR X,2(T1) ; AND THE SECOND WORD ALSO
MOVEI T1,ASCAPD ; PROBABLY NORMAL ASCII
TRNN X,1B35 ; IS IT LINE-SEQUENCE-NUMBERED?
JRST SETR2 ; NO
MOVE T2,FS$FLG(L) ; YES. FETCH I/O SWITCH FLAGS
TXNN T2,FB$SUP ; /SUPLSN?
TXO F,F$LSN ; NO, REMEMBER THAT FILE HAS LINE-SEQ#S
TXNE T2,FB$SUP ; /SUPLSN?
MOVEI T1,SUPAPD ; YES, FETCH ADR OF LSN ROUTINE
SETR2: MOVEM T1,APDADR ; STORE ADR OF GET-A-CHAR ROUTINE
MOVEI X,7 ; FETCH ASCII BYTE SIZE
DPB X,[POINT 6,INPBH+1,11] ; AND STORE IN BUFFER HEADER
POPJ P, ; AND RETURN TO CALLER
SUBTTL SETWAD - Set Adr of Punch-a-Char Routine
; SETWAD - SET ADR OF WRITE-A-CHAR ROUTINE
;
; CALL: MOVEI L,FILSPC
; PUSHJ P,SETWAD
; (RETURN)
;
; SMASHES ACS X,T1
SETWAD: MOVE T1,FS$FLG(L) ; FETCH FILE-SPEC FLAGS
MOVEM T1,PCHFLG ; AND SAVE FOR LATER
MOVE X,[<ASCPCH,,7>] ; FETCH ADR ASCII ROUTINE AND BYTE SIZE
TXNE F,F$LSN ; IS INPUT FILE LINE-NUMBERED?
HRLI X,LSNPCH ; YES, PASS NUMBERS TO OUTPUT
TXNE T1,FB$GEN ; /GENLSN?
HRLI X,GENPCH ; YES, FETCH ADR OF GENLSN ROUTINE
TXNE T1,FB$ASC ; /ASCII?
HRLI X,ASCPCH ; YES, FETCH ADR OF ASCII ROUTINE
TXNE T1,FB$SIX ; /SIXBIT?
MOVE X,[<SIXPCH,,6>] ; YES, FETCH ADR OF SIXBIT ROUTINE
TXNE T1,FB$OCT ; /OCTAL?
MOVE X,[<OCTPCH,,3>] ; YES, FETCH ADR OF OCTQL ROUTINE
HLRZM X,PCHADR ; AND SAVE ADR OF WHATEVER ROUTINE
DPB X,[POINT 6,OUTBH+1,11] ; SET BYTE SIZE IN BUFFER HEADER
MOVE X,["00000"B34] ; INIT THE LSN COUNTER
MOVEM X,LSNCTR ; . . .
SETZM LSNCT1 ; . . .
POPJ P, ; AND RETURN TO CALLER
SUBTTL PUNBUF - Punch part of Input File
; PUNBUF - PUNCH AN ARBITRARY # BUFFERS OF INPUT FILE
;
; CALL: MOVEI ARG,N ; # BUFFERS TO PUNCH (INCLUDING CURRENT)
; PUSHJ P,PUNBUF
; (RETURN)
;
; SMASHES ACS X,T1-T4
PUNBUF: JUMPLE ARG,CPOPJ ; DO NOTHING IF ARG.LE.0
SETZM PTVAL ;[12000] to prevent ?XTCPOP...
PUNB1: SETZ T4, ; T4:=LOWER BOUND (IE: B)
MOVE T5,@TXTBUF ; T5:=UPPER BOUND (IE: Z)
PUSHJ P,PUNCH ; PUNCH OUT THE ENTIRE PAGE
MOVEI C,.CHFFD ; IN CASE FORM FEED NEEDED
TXNE F,F$FFD ; WAS FORM.FEED SEEN ON INPUT?
PUSHJ P,@PCHADR ; YES, PUNCH A FORM.FEED
SETZM @TXTBUF ; CLEAR CHAR COUNT FOR BUFFER
TXNN F,F$EOF ; END OF FILE?
TXNN F,F$URD ; OR NOT READING A FILE?
POPJ P, ; YES, RETURN TO CALLER NOW
PUSHJ P,YANK ; YANK A NEW BUFFER
SOJG ARG,PUNB1 ; KEEP PUNCHING PAGES TILL ARG RUNS OUT
POPJ P, ; ARG RAN OUT. RETURN TO CALLER
SUBTTL PUNCH - Punch part of Text Buffer
; PUNCH - PUNCH OUT PART OF TEXT BUFFER
;
; CALL: MOVEI T4,LBOUND ; LOWER BOUND CHAR.ADR
; MOVEI T5,UBOUND ; UPPER BOUND CHAR.ADR
; PUSHJ P,PUNCH
; (RETURN)
;
; SMASHES ACS T1,T2,T3. USES ACS T4,T5
PUNCH: TXO F,F$STB ; FLAG THAT WE'RE AT BEG OF BUFFER
SETZM LSNCT1 ; CLEAR BYTE COUNTER FOR LSNS
MOVE T3,T5 ; T3:=LOWER BOUND
SUB T3,T4 ; T3:=# CHARS TO PUNCH
JUMPE T3,CPOPJ ; NONE TO PUNCH. RETURN TO CALLER
TXNN F,F$UWR ; ANY FILE FOR OUTPUT?
ERROR (NFO) ; NO, ** NO FILE FOR OUTPUT **
MOVE T1,T4 ; FETCH LOWER BOUND
IDIVI T1,5 ; AND FORM A BYTE POINTER THAT WILL
HLL T1,CBPTBL-1(T2) ; BE INCREMENTED BEFORE USE
ADD T1,TXTBUF ; MAKE BP ABSOLUTE TO TEXT BUFFER
ADDI T1,T$DATA ; SKIP OVER OVERHEAD WORDS OF BUFFER
; MAIN PUNCH LOOP
PUNCH1: ILDB C,T1 ; FETCH NEXT CHAR FROM TEXT BUFFER
PUSHJ P,@PCHADR ; AND PUNCH IT OUT
SOJG T3,PUNCH1 ; AND TRY FOR ANOTHER CHAR
TXZ F,F$STB ; CLEAR TEMP FLAG TO MAKE "YANK" HAPPY
POPJ P, ; ALL DONE. RETURN TO CALLER
SUBTTL ASCPCH - Punch an ASCII Character
; ASCPCH - PUNCH AN ASCII CHAR
ASCPCH: SOSGE OUTBH+2 ; ROOM IN OUTPUT BUFFER?
JRST ASCP1 ; NO
IDPB C,OUTBH+1 ; YES, STORE CHAR IN OUTPUT BUFFER
POPJ P, ; AND RETURN TO CALLER
; ASK MONITOR FOR A NEW OUTPUT BUFFER
ASCP1: OUT OUT, ; ASK MONITOR FOR NEXT BUFFER
JRST ASCPCH ; AND CONTINUE
; OUTERR - OUTPUT ERROR OCCURRED
OUTERR: GETSTS OUT,IOSTS ; GET I/O STATUS FOR OUTPUT CHANNELL
ERROR (OUT) ; AND GIVE AN ERROR MESSAGE
SUBTTL SIXPCH - Punch a SIXBIT ASCII Character
; SIXPCH - PUNCH A SIXBIT CHARACTER AFTER CONVERTING FROM ASCII
SIXPCH: SOSGE OUTBH+2 ; ROOM IN OUTPUT BUFFER?
JRST SIXP1 ; NO
MOVEI X,'A'-"A"(C) ; CONVERT ASCII TO SIXBIT
IDPB X,OUTBH+1 ;[360] AND STORE IN OUTPUT BUFFER
POPJ P, ; AND RETURN TO CALLER
; ASK MONITOR FOR A NEW OUTPUT BUFFER
SIXP1: OUT OUT, ; ASK MONITOR FOR A NEW OUTPUT BUFFER
JRST SIXPCH ; GOT IT. CONTINUE
JRST OUTERR ; FAILED! (SOME RANDOM ERROR)
SUBTTL OCTPCH - Punch an Octal Digit
; OCTPCH - PUNCH AN OCTAL DIGIT AFTER CONVERTING FROM ASCII
OCTPCH: SOSGE OUTBH+2 ; ROOM IN OUTPUT BUFFER?
JRST OCTP1 ; NO
MOVEI C,-"0"(C) ; CONVERT CHAR TO OCTAL
IDPB C,OUTBH+1 ; AND STORE IN OUTPUT BUFFER
POPJ P, ; AND RETURN TO CALLER
; ASK MONITOR FOR A NEW OUTPUT BUFFER
OCTP1: OUT OUT, ; ASK MONITOR FOR A NEW OUTPUT BUFFER
JRST OCTPCH ; GOT IT. CONTINUE
JRST OUTERR ; FAILED! (SOME RANDOM ERROR)
SUBTTL LSNPCH - Punch a Char and Turn on Bit35 for LSNS
; LSNPCH - PUNCH A CHAR AND TURN ON BIT35 FOR LSNS
LSNPCH: TXZN F,F$STB ; AT BEGINNING OF BUFFER?
SKIPE LSNCT1 ; IN AN LSN?
JRST LSNP1 ; YES
PUSHJ P,CHKEOL ; NO, IS CHAR END-OF-LINE?
JRST ASCPCH ; NO, JUST PUNCH IT
MOVEI X,5 ; YES, SET THE LSN FLAG
MOVEM X,LSNCT1 ; . . .
MOVE X,["00000"B34] ; AND GET READY TO JUSTIFY LSN
MOVEM X,LSNCTR ; . . .
PJRST ASCPCH ; AND PUNCH TO <EOL> CHAR
; ADD LEADING ZEROS TO AN EXISTING LSN BEFORE PUNCHING IT
LSNP1: SOSGE LSNCT1 ; DONE WITH LSN?
JRST LSNP2 ; NO, HAVEN'T BEGUN IT YET
CAIG C,"9" ; IS CHAR A DIGIT?
CAIGE C,"0" ; . . . ?
JRST LSNP5 ; NO, PUNCH THE LSN NOW
MOVE X,LSNCTR ; NO, FETCH WHAT WE HAVE ALREADY
LSH X,7 ; SHIFT IT ONE CHAR
DPB C,[POINT 7,X,34] ; AND PUT NEXT DIGIT IN
MOVEM X,LSNCTR ; AND SAVE AGAIN
SKIPN LSNCT1 ; IS THE LSN DONE?
JRST LSNP4 ; YES
POPJ P, ; NO, RETURN TO CALLER
; INIT LSN COUNTER WHEN AT BEGINNING OF BUFFER
LSNP2: MOVEI X,5 ; INIT THE DIGIT COUNTER
MOVEM X,LSNCT1 ; . . .
MOVE X,["00000"B34] ; INIT THE LSN
MOVEM X,LSNCTR ; . . .
JRST LSNP1 ; AND PLACE FIRST DIGIT IN LSN
; NOW PUNCH THE LSN
LSNP4: SETZM LSNCT1 ; CLEAR THE DIGIT COUNTER
MOVE X,OUTBH+2 ; FETCH BYTE COUNT
SUBI X,5 ; ACCOUNT FOR LSN
JUMPG X,.+2 ; SKIP IF ROOM FOR LSN
OUTPUT OUT, ; MAKE ROOM FOR THE LSN
SKIPN OUTBH+2 ; WAS IT A DUMMY OUTPUT?
OUTPUT OUT, ; YES, DO A REAL OUTPUT
AOS X,OUTBH+1 ; POINT TO NEXT WORD
MOVE N,LSNCTR ; FETCH THE LSN
IORI N,1 ; TURN ON THE LSN BIT (BIT35)
MOVEM N,(X) ; AND PUNCH THE LSN
LDB N,[POINT 6,OUTBH+1,5] ; FETCH # BITS LEFT IN WORD
IDIVI N,7 ; CONVERT TO CHARACTERS
MOVEI N,5(N) ; ACCOUNT FOR 5 CHARS OF LSN
; PLUS NULLS TO PAD WORD
MOVNI N,(N) ; . . .
ADDM N,OUTBH+2 ; . . .
MOVEI X,(POINT 7,,34) ; FIX BYTE POINTER TO NEXT WORD
HRLM X,OUTBH+1 ; . . .
POPJ P, ; AND RETURN TO CALLER
; PUNCH LSN AND THE CHAR AFTER IT
LSNP5: PUSH P,C ; SAVE THE CHAR
PUSHJ P,LSNP4 ; PUNCH THE LSN
POP P,C ; RESTORE THE CHAR
PJRST ASCPCH ; AND PUNCH IT AND RETURN TO CALLER
SUBTTL GENPCH - Punch a Char and Generate LSNS
; GENPCH - PUNCH A CHAR GENERATING AN LSN FOR EACH LINE
GENPCH: SKIPN LSNCT1 ; NEED AN LSN?
JRST GENP1 ; YES
PUSHJ P,CHKEOL ; NO, IS THIS CHAR AN END-OF-LINE?
PJRST ASCPCH ; NO, JUST PUNCH IT AND RETURN
SETZM LSNCT1 ; YES, FLAG THAT WE NEED AN LSN SOON
PJRST ASCPCH ; AND PUNCH THE END-OF-LINE CHAR
; GENERATE AN LSN FOR CURRENT LINE
GENP1: PUSH P,C ; SAVE THE CURRENT OUTPUT CHAR
MOVE X,OUTBH+2 ; IS THERE ROOM FOR THE LSN IN BUFFER?
SUBI X,12 ; . . . ?
JUMPG X,.+2 ; SKIP IF ROOM
OUTPUT OUT, ; MAKE ROOM
; PAD OUT CURRENT WORD WITH NULLS
GENP2: LDB X,[POINT 6,OUTBH+1,5] ; FETCH CURRENT BYTE POSITION
CAIG X,1 ; AT END OF WORD?
JRST GENP3 ; YES, READY FOR LSN
IBP OUTBH+1 ; NO, PAD WITH ANOTHER NULL
SOS OUTBH+2 ; DECREMENT BYTE COUNT
JRST GENP2 ; AND TRY AGAIN
; GENERATE A NEW LSN (OLD+10) AND STORE IN OUTPUT BUFFER
GENP3: MOVE X,LSNCTR ; FETCH OLD LSN
; ***** FOLLOWING CODE WORKS BY MAGIC (FROM DEC TECO) *****
ADD X,[BYTE(7)106,106,106,107]
MOVE N,X
AND N,[BYTE(7)60,60,60,60]
LSH N,-3
MOVE T2,X
AND T2,[BYTE(7)160,160,160,160]
IOR N,T2
SUB X,N
ADD X,[BYTE(7)60,60,60,60]
; ***** END OF MAGIC CODE *****
MOVEM X,LSNCTR ; STORE NEW LSN FOR LATER USE
AOS OUTBH+1 ; POINT TO NEXT WORD OF OUTPUT BUFFER
IORI X,1B35 ; SET THE LSN BIT IN LSN
MOVEM X,@OUTBH+1 ; STORE THE LSN IN OUTPUT BUFFER
MOVNI X,5 ; ACCOUNT FOR THE 5 CHARS OF LSN
ADDM X,OUTBH+2 ; . . .
SETOM LSNCT1 ; FLAG THAT LSN IS DONE
MOVEI C,.CHTAB ; AND PUNCH A <TAB> AFTER THE LSN
PUSHJ P,ASCPCH ; . . .
POP P,C ; RESTORE THE LAST OUTPUT CHAR
PJRST ASCPCH ; AND RETURN TO CALLER
SUBTTL BAKCLS - Finish "EB" that is in Progress
; BAKCLS - FINISH "EB" THAT IS IN PROGRESS
;
; 1) DELETE .BAK FILE
; 2) RENAME ORIGINAL FILE TO .BAK
; 3) RENAME .TMP FILE TO ORIGINAL NAME
;
; CALL: PUSHJ P,BAKCLS
; (RETURN)
;
; SMASHES ACS X,T1-T2
BAKCLS:
; DELETE .BAK FILE
MOVE X,[<LEBSPC,,FILSPC>] ; FETCH BLT POINTER
BLT X,FILSPC+FS$LTH-1 ; COPY ORIGINAL FILE-SPEC
MOVSI X,'BAK' ; AND CHANGE FILE EXTENSION
MOVEM X,FILSPC+FS$EXT ; TO .BAK
MOVE N,[Z INP,] ; FETCH INPUT I/O CHANNEL
MOVEI M,INPBH ; FETCH ADR OF INPUT BUFFER HEADER
MOVEI L,FILSPC ; FETCH ADR OF BACKUP FILE SPEC
PUSHJ P,FILOPN ; AND OPEN THE INPUT DEVICE
ERROR (IRN) ; CAN'T. ** INPUT FAILURE FOR RENAME **
PUSHJ P,FILLKP ; LOOKUP THE .BAK FILE
JRST BAKCL2 ; NONE THERE (SAVES US THE TROUBLE OF DELETING IT)
PUSHJ P,GETPTH ;[342] GET MY DEFAULT PATH
MOVE T1,RBSPC+.RBPPN ;[342] GET PPN
TXNN T1,LH.ALF ;[342] AN ADDRESS?
MOVE T1,2(T1) ;[342] YES, GET PPN [4000] FOR REAL
CAME X,T1 ;[342] COMPARE WITH LOOKUP'ED PPN
JRST BAKCL2 ;[341] IT'S ON LIB: PROBABLY
; SAVE PROTECTION OF ORIGINAL .BAK FILE FOR NEW .BAK FILE
LDB X,[POINT 9,RBSPC+.RBPRV,8] ; FETCH .BAK PROTECTION
DPB X,[POINT 9,FILSPC+FS$PRV,8] ; AND STORE FOR NEW .BAK FILE
SETZ T1, ; DELETE THE .BAK FILE
RENAME INP,T1 ; . . .
ERROR (BAK) ; CAN'T . ** CAN'T DELETE .BAK FILE **
; RENAME ORIGINAL FILE TO .BAK
BAKCL2: MOVSI N,(Z INP,) ; FETCH INPUT CHANNEL
MOVEI L,LEBSPC ; FETCH ADR OF ORIGINAL FILE-SPEC
PUSHJ P,FILLKP ; AND LOOK IT UP
ERROR (ILR) ; CAN'T. ** LOOKUP FAILURE FOR INPUT FILE **
; SEE IF ORIGINAL FILE IS PROTECTED <2??>
LDB X,[POINT 9,RBSPC+.RBPRV,8] ; FETCH ORIGINAL FILE PROT
CAIGE X,<200> ; PROTECTED <2??>?
JRST BAKCL3 ; NO, MAKES THINGS EASIER
; ORIGINAL FILE IS PROTECTED <2??>
; RENAME IT TO <1??> SO THAT WE CAN RENAME IT
XORI X,<300> ; CHANGE PROTECTION TO <1??>
PUSH P,LEBSPC+FS$PRV ; SAVE ORIGINAL PROTECTION
DPB X,[POINT 9,LEBSPC+FS$PRV,8] ; SET THE <1??> PROTECTION
PUSHJ P,FILRNM ; AND RENAME THE ORIGINAL FILE TO NEW PROT.
ERROR (IRB) ; CAN'T RENAME IT !?!
POP P,LEBSPC+FS$PRV ; RENAMED IT. RESTORE ORIGINAL PROTECTION
; NOW REANME THE ORIGINAL FILE TO .BAK
BAKCL3: MOVEI L,FILSPC ; FETCH ADR OF .BAK FILE-SPEC
; PROTECTION OF .BAK FILE WILL BE <0NM> (IF WAS PROTECTED <LNM>
; THIS IS SO THAT .BAK FILES CAN BE EASILY DELETED
MOVSI X,(<700>B8) ; CLEAR THE OWNER FIELD IN PROTECTION CODE
ANDCAM X,FILSPC+FS$PRV ; . . .
PUSHJ P,FILRNM ; AND RENAME ORIGINAL TO .BAK
ERROR (IRB) ; CAN'T. ** RENAME FAILURE FOR .BAK FILE **
; RENAME '###XTC.TMP' TO ORIGINAL FILE
MOVSI N,(Z OUT,) ; FETCH OUTPUT CHANNEL
MOVEI L,LEBSPC ; FETCH ADR OF ORIGINAL FILE-SPEC
PUSHJ P,FILRNM ; AND RENAME .TMP FILE TO ORIGINAL
ERROR (RNO) ; CAN'T. ERROR
; DONE WITH "EB"
TXZ F,F$URD!F$UWR!F$UBK ; CLEAR I/O FLAGS
POPJ P, ; AND RETURN TO CALLER
SUBTTL YANK and APPEND
; APPENL Append (ARG) lines to the buffer
APPENL: TXO F,F$EOL ;[16000] Remember it's linewise append
JRST APPEN0 ;[16000] Jump into common APPEND code
; YANK - RENDER THE MAIN TEXT BUFFER EMPTY AND APPEND A NEW BUFFER
;
; CALL: PUSHJ P,YANK
; (RETURN)
YANK: SETZM PTVAL ; ".":=B
SETZM @TXTBUF ; Z:=B MAKES THE BUFFER EMPTY
; PJRST APPEND ; APPEND A NEW BUFFER AND RETURN TO CALLER
; APPEND - READ INPUT CHARACTERS UNTIL:
;
; 1) A FORM.FEED CHARACTER IS ENCOUNTERED, OR
; 2) END.OF.FILE IS ENCOUNTERED, OR
; 3) BUFFER IS WITHIN FI/C$FILB FULL AND A LINE.FEED
; CHARACTER IS ENCOUNTERED, OR
; 4) BUFFER IS WITHIN 128. CHARACTERS OF CAPACITY
;
; T1 HOLDS BYTE POINTER FOR STORING CHARS IN TEXT BUFFER
; T3 HOLDS # CHARS LEFT TILL BUFFER IS (C$FILB-1)/C$FILB FULL
; T4 HOLDS # CHARS LEFT TILL BUFFER IS WITHIN 128. CHARS OF FULL
; T5 HOLDS NEW Z (OLD PLUS #CHARS SEEN)
;
; SMASHES ACS X,T1-T5,C
APPEND: TXZ F,F$EOL ;[16000] Not stop on end-of-line
APPEN0: TXZ F,F$FFD ; CLEAR THE FORMFEED FLAG
TXNN F,F$URD ; IS A FILE OPEN FOR INPUT?
CERR1 (NFI) ; NO, ** NO FILE OPEN FOR INPUT **
; SETUP NEW Z
MOVE T5,@TXTBUF ; NEW Z:=OLD Z
; MAKE SURE THAT THERE IS ROOM FOR AT LEAST 3000. CHARACTERS IN BUFFER
MOVE T4,@TXTBUF ; FETCH Z
EXCH T4,PTVAL ; T4:=. , ".":=Z
MOVEI T1,^D3000 ; FETCH 3000.
ADD T1,PTVAL ; T1:=3000.+Z
SUB T1,T4 ; T1:=3000.+Z-"."
PUSHJ P,MKROOM ; MAKE ROOM FOR CHARS
MOVEM T4,PTVAL ; ".":="."
; COMPUTE # CHARS LEFT TILL BUFFER IS WITH 128. CHARS OF FULL
MOVE X,TXTBUF ; COMPUTE CAPACITY OF BUFFER
HLRZ T1,B$1PTR(X) ; . . .
SUBI T1,(X) ; . . .
IMULI T1,5 ; CONVERT WORDS TO CHARS
SUBI T1,^D128 ; MINUS 128. CHARS
IDIVI T1,^D12 ; MAKE SURE A MULTIPLE OF 12.
IMULI T1,^D12 ; . . .
MOVE T4,T1 ; AND PUT IN AC T4
SUB T4,T5 ; MINUS # CHARS ALREADY IN BUFFER
; COMPUTE # CHARS LEFT TILL BUFFER IS (C$FILB-1)/C$FILB FULL
MOVE T3,T4 ; FETCH # CHARS WE CAN PUT IN BUFFER
ADDI T3,^D128 ; COMPUTE BUFFER CAPACITY
MOVE T1,T3 ; T1:=BUFFER CAPACITY
IDIVI T1,C$FILB ; COMPUTE 1/C$FILB OF BUFFER CAPACITY
SUB T3,T1 ; COMPUTE # CHARS LEFT TILL BUFFER (C$FILB-1)/C$FILB FULL
; SETUP BYTE POINTER FOR STORING CHARS IN TEXT BUFFER
MOVE T1,T5 ; FETCH Z
ADDI T1,5*T$DATA ; TO SKIP OVER OVERHEAD WORDS OF BUFFER
IDIVI T1,5 ; AND FORM A BYTE POINTER THAT WILL
HLL T1,CBPTBL-1(T2) ; BE INCREMENTED BEFORE USE
ADD T1,TXTBUF ; MAKE BP ABSOLUTE
SETZ C, ; CLEAR THE CURRENT CHAR
; MAIN READ LOOP
APPND1: TXNN F,F$EOL ;[16000] Stop on end of line?
SOJGE T3,@APDADR ; NEXT CHAR IF LOTS OF ROOM
JUMPLE T4,APPND2 ; STOP IF WITHIN 128. CHARS OF FULL
CAIE C,.CHLFD ; WAS LAST CHAR A LINE.FEED?
JRST @APDADR ; NO, FETCH NEXT CHAR
TXNE F,F$EOL ;[16000] Stop on end of line?
SOJG ARG,APPND1 ;[16000] Yes, decr count & maybe continue
; APPEND COMPLETE
APPND2: MOVEM T5,@TXTBUF ; STORE NEW VALUE OF "Z"
POPJ P, ; AND RETURN TO CALLER
; "IN" MUUO FAILED. SEE WHAT HAPPENED
APPND3: STATO INP,IO.EOF ; END OF FILE?
JRST APPND4 ; NO, SOME RANDOM I/O ERROR
TXO F,F$EOF ; YES, REMEMBER THAT
JRST APPND2 ; AND FINISH UP
; INPUT ERROR
APPND4: GETSTS INP,IOSTS ; FETCH STATUS OF INPUT CHANNEL
ERROR (INP) ; AND GIVE ERROR MESSAGE
SUBTTL ASCAPD - Read an ASCII Char
; ASCAPD - FETCH NEXT ASCII INPUT CHAR AND STORE IN TEXT BUFFER
ASCAPD: SOSGE INPBH+2 ; ANY MORE CHARS IN INPUT BUFFER?
JRST ASCA1 ; NO, FETCH NEW BUFFER FULL
ILDB C,INPBH+1 ; YES, FETCH NEXT CHAR
CAIN C,.CHFFD ;; IS IT A FORM-FEED?
JRST ASCA2 ; YES
JUMPE C,ASCAPD ; NO, STORE CHAR IN TEXT BUFFER
IDPB C,T1 ; STORE THE CHAR IN TEXT BUFFER
AOJ T5, ; Z:=Z+1
SOJA T4,APPND1 ; AND TRY FOR NEXT CHAR
; INPUT NEW BUFFER
ASCA1: IN INP, ; ASK MONITOR FOR NEXT BUFFER
JRST ASCAPD ; GOT IT. FETCH NEXT CHAR
JRST APPND3 ; FAILED. FIND OUT WHY
; FORM-FEED CHAR ENCOUNTERED. FLAG IT AND STOP THE APPEND
ASCA2: TXO F,F$FFD ; FLAG THAT A <FF> SEEN
AOS PAGCNT ; INCREMENT PAGE COUNTER
JRST APPND2 ; AND STOP THE APPEND
SUBTTL SUPARD - Read a Char and Suppress LSNS
; SUPAPD - IGNORE LSNS ON INPUT(/SUPLSN) AND STORE CHAR IN TEXT BUFFER
SUPAPD: SOSGE INPBH+2 ; ANY MORE CHARS IN INPUT BUFFER?
JRST SUPAP2 ; NO, FETCH NEXT BUFFER
ILDB C,INPBH+1 ; YES, FETCH NEXT CHAR
JUMPE C,SUPAPD ; IGNORING NULLS
CAIN C,.CHFFD ; IS CHAR A FORM-FEED?
JRST ASCA2 ; YES
MOVE X,@INPBH+1 ; FETCH CURRENT INPUT WORD
TRNN X,1B35 ; IS IT A LINE-SEQUENCE-NUMBER?
JRST SUPAP1 ; NO
; SUPPRESS LINE-SEQUENCE-NUMBERS AND THE FOLLOWING <TAB>
AOS INPBH+1 ;[361] IGNORE THE LSN BY MOVING TO NEXT WORD
MOVE X,INPBH+2 ; FETCH THE CHAR COUNT
SUBI X,5 ;[361] AND SUBTRACT 5 CHARS
MOVEM X,INPBH+2 ; . . .
JRST SUPAPD ; AND GO BACK FOR ANOTHER CHAR
; TAB EATEN BY MAGIC IN PREVIOUS ROUTINE. HOW?
; THE BYTE POINTER POINTS TO THE SECOND BYTE IN THE WORD WHEN IT
; HITS THIS ROUTINE. RATHER THAN RESET AND GOBBLE IT AGAIN, I
; LEAVE IT THAT WAY. BECAUSE OF THIS, THE FIRST CHARACTER AFTER THE
; LSN, WHICH IS OF NECESSITY A <TAB>, IS TOTALLY IGNORED!
; THIS MAGIC WAS PART OF [361].
; STORE CHAR IN TEXT BUFFER
SUPAP1: IDPB C,T1 ; STORE CHAR IN TEXT BUFFER
AOJ T5, ; Z:=Z+1
SOJA T4,APPND1 ; AND GO BACK FOR ANOTHER CHAR
; INPUT NEXT BUFFER FROM MONITOR
SUPAP2: IN INP, ;ASK MONITOR FOR NEXT INPUT BUFFER
JRST SUPAPD ; GOT IT
JRST APPND3 ; FAILED. FIND OUT WHY
SUBTTL OCTAPD - Read an Octal Digit
; OCTAPD - FETCH NEXT OCTAL INPUT DIGIT AND STORE CHAR IN TEXT BUFFER
OCTAPD: SOSGE INPBH+2 ; ANY MORE DIGITS IN INPUT BUFFER?
JRST OCTA1 ; NO, FETCH NEXT INPUT BUFFER
ILDB C,INPBH+1 ; YES, FETCH NEXT OCTAL DIGIT
MOVEI C,"0"(C) ; AND CONVERT TO ASCII CHAR
IDPB C,T1 ; AND STORE IN TEXT BUFFER
AOJ T5, ; Z:=Z+1
SOJA T4,APPND1 ; AND TRY FOR NEXT CHAR
; INPUT NEW BUFFER AND GET READY FOR OCTAL PROCESSING
OCTA1: IN INP, ; ASK MONITOR FOR A NEW BUFFER
JRST OCTAPD ; GOT IT. CONTINUE
JRST APPND3 ; FAILED. FIND OUT WHY
SUBTTL SIXAPD - Read a SIXBIT ASCII Char
; SIXAPD - FETCH NEXT SIXBIT INPUT CHAR AND PUT IN TEXT BUFFER
SIXAPD: SOSGE INPBH+2 ; ANY MORE CHARS IN INPUT BUFFER?
JRST SIXA1 ; NO, GET ANOTHER BUFFER
ILDB C,INPBH+1 ; YES, FETCH NEXT CHAR
MOVEI C,"A"-'A'(C) ; AND CONVERT SIXBIT TO ASCII
IDPB C,T1 ; STORE THE ASCII CHAR IN TEXT BUFFER
AOJ T5, ; Z:=Z+1
SOJA T4,APPND1 ; AND GO BACK FOR MORE
; FETCH A NEW INPUT BUFFER
SIXA1: IN INP, ; ASK MONITOR FOR NEXT INPUT BUFFER
JRST SIXAPD ; GOT IT. CONTINUE
JRST APPND3 ; FAILED. FIND OUT WHY
SUBTTL MACRO - Compile and Execute a Macro
; MACRO - COMPILE AND EXECUTE A TEXT BUFFER
;
; CALL: MOVE L,[SIXBIT/Q-REG-NAME/]
; MOVX N,BID
;[12000] will compile if TB$CMP in buffer is off
; TX? F,F$CMP ; ?=O TO COMPILE, ?=Z TO SUPPRESS COMPILE
; PUSHJ P,MACRO
; (RETURN)
MACRO:
; PUSH NAME,BID,REL.PC ON CONTROL PDL
PUSH P,MACNAM ; SAVE NAME OF CURRENT MACRO
PUSH P,MACBID ; SAVE BUFFER ID FOR CURRENT MACRO
MOVEM L,MACNAM ; STORE NEW MACRO NAME
MOVEM N,MACBID ; AND IT'S BUFFER ID
SUB PC,R ; COMPUTE RELATIVE PC
PUSH P,PC ; AND SAVE CURRENT RELATIVE PC
MOVE VALUE,ARG ;[14000] Pass argument to macro
; CLEAR AC AND MACBUF REFERENCES TO CURRENT MACRO TEXT BUFFER
SKIPN MACLVL ; IN A MACRO NOW?
JRST MACRO1 ; NO, NO REFS TO CLEAR
MOVE X,MACBUF ; YES, FETCH BASE ADR OF BUFFER
HRRZS T$1REF(X) ; UNBIND MACBUF FROM BUFFER
SETZM T$ACRF(X) ; UNBIND ACS FROM BUFFER
; FIND THE BUFFER FOR MACRO BUFFER ID
MACRO1: MOVEI L,MACBUF ; FETCH ADR OF BUFFER REF
PUSHJ P,FNDBLK ; FIND THE BUFFER FOR BID
ERROR (BNF) ; CAN'T. ERROR
MOVE X,MACBUF ; FETCH ADR OF BUFFER
AOS T$RCNT(X) ; AND INCREMENT REFERENCE COUNT
; COMPILE BUFFER IF TB$CMP IS OFF
MOVEI L,MACBUF ; FETCH ADR OF REF TO BUFFER
PUSH P,F ;[5000] DON'T LET FLAGS BE CLOBBERED BY COMPIL
TXO F,F$CMP ;[12000] It is now compile-time
MOVE T1,MACBUF ;[12000] Check COMPILED flag for buffer
TXZ F,F$COL ;[23000] Clear colon flag for COMPIL
MOVE T2,T$BIT(T1) ;[12000] Get buffer flags
TXZN F,F$2CO ;[23000] Clear :: too, but if it's on...
JUMPL T2,MACRO2 ;[12000] it is already compiled
MACROY: TXNE T2,TB$BUF ;[12000] if it is the text buffer...
ERROR (XTB) ;[12000] then it should NOT be compiled
PUSH P,SARGSV ;[14000] Save argument to macro
PUSH P,ARG ;[23000] Save other argument
PUSHJ P,COMPIL ; YES
POP P,VALUE ;[23000] Pass value to macro
POP P,SARGSV ;[14000] Restore SARG
MOVE T1,MACBUF ;[12000] now set that bit
MOVX T2,TB$CMP ;[12000]
IORM T2,T$BIT(T1) ;[12000] in the buffer hdr
MACRO2: POP P,F ;[5000] RESTORE FLAGS
TXZ F,F$CMP!F$COL ;[4000] SO ERRORS WILL BE KNOWN TO BE
;[4000] EXECUTION TIME ERRORS
AOS MACLVL ; COUNT THE NESTING OF MACROS
; EXECUTE THE COMPILED BUFFER
MOVEI L,MACBUF ; FETCH ADR OF REF TO BUFFER
TXZN F,F$2CO ;[14000] ::M compile but do not execute
PUSHJ P,EXECUT ; AND EXECUTE THE BUFFER
; POP INFO ABOUT PREVIOUS MACRO OFF CONTROL PDL
TXZ F,F$2CO!F$COL ;[23000] Don't leave colons on
POP P,PC ; RESTORE RELATIVE RETURN PC
POP P,N ; RESTORE BUFFER ID
POP P,MACNAM ; RESTORE NAME OF PREVIOUS MACRO
; RELEASE CURRENT BUFFER
EXCH N,MACBID ; STORE PREVIOUS MACRO BUFFER ID
; AND FETCH CURRENT ONE INTO AC N
PUSHJ P,DELBLK ; AND DELETE THE CURRENT MACRO REF
; RESTORE PREVIOUS MACRO
SOSN MACLVL ; DECREMENT THE MACRO NESTING COUNT
POPJ P, ; AND RETURN TO CALLER IF NO LONGER IN A MACRO
MOVE N,MACBID ; FETCH BUFFER ID FOR PREVIOUS MACRO
MOVEI L,MACBUF ; FETCH ADR OF BUFFER REFERENCE
PUSHJ P,FNDBLK ; AND FIND THE PREVIOUS MACRO BUFFER
ERROR (XXX) ; CAN'T. SHOULDN'T OCCUR!
MOVE R,MACBUF ; FETCH ADR OF BUFFER
ADDI PC,(R) ; MAKE PC ABSOLUTE
MOVE X,[<PC,,R>] ; FETCH AC REFERENCES
MOVEM X,T$ACRF(R) ; AND BIND AC REFS TO BUFFER
POPJ P, ; AND RETURN TO CALLER
SUBTTL OPENRD - Select a File for Input
; OPENRD - SELECT A FILE FOR INPUT
;
; CALL: MOVEI L,FILSPC
; PUSHJ P,OPENRD
; (RETURN)
;
; SMASHES ACS N,M. USES AC L
OPENRD: SETZM PAGCNT ; CLEAR THE PAGE COUNTER
TXZ F,F$URD!F$EOF!F$FFD ; CLEAR SOME FLAGS
MOVSI N,(<Z INP,0>) ; CHANNEL FOR FILOPN
MOVEI M,INPBH ; INPUT BUFFER HEADER FOR FILOPN
PUSHJ P,FILOPN ; OPEN DEVICE FOR INPUT
CERR1 (IDV) ; INPUT DEVICE OPEN FAILURE
PUSHJ P,FILLKP ; LOOKUP THE FILE
CERR1 (FNF) ; FILE NOT FOUND
TXO F,F$URD ; NOW READING FROM A FILE
POPJ P, ; RETURN TO CALLER
SUBTTL OPENWR - Select a File for Output
; OPENWR - SELECT A FILE FOR OUTPUT
;
; CALL: MOVEI L,FILSPC
; PUSHJ P,OPENWR
; (RETURN)
;
; SMASHES ACS M,N. USES AC L
OPENWR: TXZ F,F$UWR ; CLEAR SOME FLAGS
MOVSI N,(<Z OUT,0>) ; CHANNEL FOR FILOPN
MOVE M,[<OUTBH,,INIBH>] ; BUFFER HEADERS FOR OUTPUT CHANNEL
; (INIBH 'CAUSE WE LOOKUP A FILE)
PUSHJ P,FILOPN ; OPEN DEVICE FOR OUTPUT
CERR1 (ODV) ; OUTPUT DEVICE OPEN FAILURE
; SEE IF THE FILE ALREADY EXISTS (IE: ARE WE SUPERCEDING IT?)
JUMPL L,OPENW0 ;[20000] /SUPERCEDE was given so don't care
SKIPN X,FS$PPN(L) ;[404] IS PPN [-] ?
PUSHJ P,GETPTH ;[404] YES, GET PATH(NO WANT 0!)
MOVEM X,FS$PPN(L) ;[404] SAVE UPDATED PPN SPEC
PUSH P,FS$PPN(L) ;[365] THE PPN WILL GET CLOBBERED BY OTHERS
PUSHJ P,FILLKP ; SEE IF THE FILE IS THERE
TDZA T5,T5 ; NO, FLAG THAT IT DOESN'T EXIST
MOVE T5,FS$PPN(L) ;[376] FILE IS THERE. FETCH ITS REAL PPN
POP P,FS$PPN(L) ;[365] THE ONE HE(SHE?) WANTED, NOT OTHERS
; DO THE REAL ENTER
OPENW0: MOVE X,FS$DEV(L) ; FETCH THE DEVICE NAME
DEVCHR X, ; AND GET ITS CHARACTERISTICS
TXNN X,DV.MTA ;[414] NUL: CAN BE MTA AND DIR.(!)
TXNN X,DV.DIR ; IS IT A DIRECTORY DEVICE?
SETZ T5, ;[413] NO, FLAG AS ZERO
CLOSE OUT, ; CLOSE THE OUTPUT CHANNEL
SETZ M, ;[15000] Don't know size now
PUSHJ P,FILENT ; DO THE ENTER
CERR1 (ENT) ; ** ENTER UUO FAILURE **
; SEE IF WE ARE SUPERCEDING THE FILE
JUMPE T5,.+3 ;[376] NOT SUPERCEDING IF FLAG 0
CAMN T5,FS$PPN(L) ;[376] DOES FILE "REALLY" EXIST?
WARN (SEF) ; YES, GIVE MSG ABOUT SUPERCEDE
; DONE. FLAG THAT "EW" IN OPERATION AND RETURN TO CALLER
TXO F,F$UWR ; FLAG THAT "EW" IN OPERATION
POPJ P, ; AND RETURN TO CALLER
SUBTTL FILERD - Read a File into a Text Buffer
; FILERD - READ A FILE INTO A TEXT BUFFER
;
; CALL: MOVX L,<FLAGS,,FILSPC> ;FLAGS: 400000 = delete after read
; PUSHJ P,FILERD
; (RETURN) ; WITH BUFFER ID IN AC N
;
; SMASHES ACS X,T1-T5
FILERD: MOVEI T1,.IODMP ; USE CHANNEL ZERO [13000] Dump mode
MOVE T2,FS$DEV(L) ;Get device name [13000]
SETZB T3,N ;[13000] no b.r.h. for dump mode (& use ch 0)
CAMN T2,['TMP '] ;[15000] Did he really want TMPCOR
JRST [HLLZ T2,FS$NAM(L) ;[15000] Yes, get name
MOVE T1,[.TCRRF,,T2] ;[15000] Set up to read
TMPCOR T1, ;[15000] into null buffer to get length
JRST [SETZM FILSPC ;[15000] Zero FILSPC file block
MOVE X,[FILSPC,,FILSPC+1] ;[15000] so we can
BLT X,FILSPC+FS$LTH-1 ;[15000] use it for the .TMP
MOVE X,CCJNAM ;[15000] Get job # in left half
HLR X,FS$NAM(L) ;[15000] file name in rt half
MOVEM X,FILSPC+FS$NAM ;[15000] i.e. 003EDT
MOVSI X,'TMP' ;[15000] .TMP
MOVEM X,FILSPC+FS$EXT ;[15000] 003EDT.TMP
MOVSI X,'DSK' ;[15000] DSK:
MOVEM X,FILSPC+FS$DEV ;[15000] DSK:003EDT.TMP
HRRI L,FILSPC ;[15000]
PJRST FILERD] ;[15000] And read the file
PUSH P,L ;[15000] Save addr of file block
MOVEI L,T$DATA(T1) ;[15000] Allocate a block that big
HRLI L,FRDREF ;[15000] FRDREF will point to it
PUSHJ P,MAKBUF ;[15000] Get a place to put this thing
MOVEM T5,@FRDREF ;[15000] This many chars in the buffer
MOVNI T3,(L) ;[15000] Negative length
MOVSI T3,(T3) ;[15000] in left half...
HRR T3,FRDREF ;[15000] Address -1 in right half
ADDI T3,T$DATA-1 ;[15000] (include overhead words)
MOVE T1,[.TCRRF,,T2] ;[15000] Assume just read
POP P,L ;[15000] Get back addr of file block
HLLZ T2,FS$NAM(L) ;[15000] Get back file name
TLZE L,400000 ;[15000] Flag is sign bit of L
HRLI T1,.TCRDF ;[15000] Then do read & delete
TMPCOR T1, ;[15000] Read, or read & delete the file
ERROR (XXX) ;[15000] What happened?
JRST FRD5] ;[15000] Go clean up
OPEN 0,T1 ;[13000] Try the open
CERR1 (IDV) ; ** INPUT DEVICE OPEN FAILURE **
PUSHJ P,FILLKP ; LOOKUP THE INPUT FILE
CERR1 (FNF) ; ** FILE NOT FOUND **
PUSH P,L ;[15000] Save addr of file block
MOVSI L,FRDREF ;[13000] Addr of ref in left half
HRR L,RBSPC+.RBSIZ ;[13000] Size of file in words in right half
PUSHJ P,MAKBUF ; AND MAKE A BUFFER FOR TEXT OF FILE
POP P,L ;[15000] Get file block addr back
; READ THE FILE INTO THE BUFFER
;FRD1: SOSGE INIBH+2 ; ANY MORE CHARS IN INPUT BUFFER?
; JRST FRD2 ; NO
; ILDB C,INIBH+1 ; YES, FETCH THE NEXT ONE
; JUMPE C,FRD1 ; IGNORE NULLS
; JRST FRD3 ;PROCESS THE CHAR
;
; INPUT NEXT INPUT BUFFER
;FRD2: IN 0, ; INPUT NEXT BUFFER
; JRST FRD1 ; AND FETCH A CHAR
; STATZ 0,IO.EOF ; FAILED. END-OF-FILE?
;[13000] Use dump mode (Many times faster)
JUMPE T5,FRDZ ;[15000] Zero-length, finish up
MOVEM T5,@FRDREF ;[13000] Store length of buffer
MOVN T1,RBSPC+.RBSIZ ;[13000] Negative length in words
MOVSI T1,(T1) ;[13000] Should be in left half
HRR T1,FRDREF ;[13000] Build address to read in data
ADDI T1,T$DATA-1 ;[13000] Skip over overhead words
SETZ T2, ;[13000] I/O list in T1,T2
IN 0,T1 ;[13000] Read it all in at once
JRST FRD5 ; YES, DONE READING FILE
GETSTS 0,IOSTS ; NO, FETCH I/O STATUS
ERROR (IER) ; AND GIVE AN INPUT ERROR MSG
; STORE THE CHAR IN THE TEXT BUFFER
;FRD3: SOJL T5,FRD4 ; OUT OF ROOM. EXPAND THE TEXT BUFFER
; MOVE T3,FRDREF ; ROOM LEFT. FETCH BASE ADR OF TEXT BUFFER
; IDPB C,T4 ; AND STORE THE CHAR IN BUFFER
; AOS T$CCNT(T3) ; AND INCREMENT THE CHAR COUNT
; JRST FRD1 ; AND FETCH ANOTHER INPUT CHAR
; EXPAND THE TEXT BUFFER WHEN OUT OF ROOM
;FRD4: PUSH P,C ; SAVE AC C
; PUSH P,N ; SAVE AC N
; MOVEI N,C$CMDL ; FETCH #WORDS TO ADD
; MOVEI L,FRDREF ; FETCH ADR OF BUFFER REFERENCE
; PUSHJ P,EXPAND ; AND EXPAND THE BUFFER
; MOVEI T5,C$CMDL*5-2 ; AND RESET THE # CHARS THAT CAN FIT IN BUFFER
; POP P,N ; RESTORE AC N
; POP P,C ; RESTORE AC C
; JRST FRD3 ; AND STORE LAST INPUT CHAR
;[13000] Remove nulls from the end of the file only
FRD5:
MOVE T1,@FRDREF ;[13000] Get # of chars in buffer
FRD5A: SOJLE T1,FRDZ ;[13000] First char is #0
PUSHJ P,CTOBP ;[13000] Make byte pointer
ADD T1,FRDREF ;[13000] Make absolute
ADDI T1,T$DATA ;[13000] Skip overhead words
LDB C,T1 ;[13000] Get the character
JUMPN C,FRDZ ;[13000] not NULL, leave alone
SOSLE T1,@FRDREF ;[13000] 1 less character
JRST FRD5A ;[13000] try again if any left
; DONE READING FILE. CLEAN UP AND RETURN TO CALLER
FRDZ: MOVE X,FRDREF ; FETCH BASE ADR OF BUFFER
HRRZS T$1REF(X) ; AND DELETE THE REF TO BUFFER
SETZM FRDREF ; AND CLEAR 'FRDREF'
JUMPGE L,CPOPJ ;[15000] no /DELETE switch
CAIL T5,C$MAXD ;[15000] If it is fairly long
POPJ P, ;[16000] he probably didn't mean it
SETZ T1, ;[15000] Very short rename block
RENAME 0,T1 ;[15000] STOMP!!!
JRST [MOVEM T2,LREERR ;[16000] Remember error code
CERR1 (RNF)] ;[16000] ** RENAME FAILURE **
POPJ P, ; AND RETURN TO CALLER
; FILEWR - WRITE A FILE FROM A TEXT BUFFER
;
; CALL: MOVEI L,FILSPC
; MOVEI N,BID
; PUSHJ P,FILEWR
; (RETURN)
;
; SMASHES ACS X,T1-T5
FILEWR: MOVE T5,L ;[14000] Save away filespec pointer
MOVEI L,FRDREF ;[14000] FRDREF will reference block
PUSHJ P,FNDBLK ;[14000] Find our block ...
ERROR (BNF) ;[14000] What block???
MOVE L,T5 ;[14000] Get back addr of file block
MOVE T1,FRDREF ;[14000] We will need the length
MOVE T5,T$CCNT(T1) ;[14000] of the block.
ADDI T5,4 ;[14000] Round up so we don't lose anything
IDIVI T5,5 ;[14000] Convert to words
ADDI T1,T$DATA-1(T5) ;[15000] Get addr of last word
MOVE X,[EXP <3777,,777777>,<17,,777777>,77777,377,1](X)
ANDCAM X,(T1) ;[15000] Use bit mask to clear invalid chars
FWR0: MOVEI T1,.IODMP ;[13000] Dump mode
MOVE T2,FS$DEV(L) ;Get device name [13000]
SETZB T3,N ;[13000] no b.r.h. for dump mode & Chn 0
CAMN T2,['TMP '] ;[15000] Is it TMPCOR
JRST [MOVNI T3,(T5) ;[15000] Negative # of words
MOVSI T3,(T3) ;[15000] In left half
HRR T3,FRDREF ;[15000] Addr-1 in right half
ADDI T3,T$DATA-1 ;[15000] (Include overhead words)
HLLZ T2,FS$NAM(L) ;[15000] 3-letters of name
MOVE T1,[.TCRWF,,T2] ;[15000] Write TMPCOR
TMPCOR T1, ;[15000] T2 & T3 are argument block
JRST [SETZM FILSPC ;[15000] Use temp file block
MOVE X,[FILSPC,,FILSPC+1] ;[15000] so we can
BLT X,FILSPC+FS$LTH-1 ;[15000] use it for the .TMP
MOVE X,CCJNAM ;[15000] Get job # in left half
HLR X,FS$NAM(L) ;[15000] file name in rt half
MOVEM X,FILSPC+FS$NAM ;[15000] i.e. 003EDT
MOVSI X,'TMP' ;[15000] .TMP
MOVEM X,FILSPC+FS$EXT ;[15000] 003EDT.TMP
MOVSI X,'DSK' ;[15000] DSK:
MOVEM X,FILSPC+FS$DEV ;[15000] DSK:003EDT.TMP
MOVX L,<1B0+FILSPC> ;[20000] Always supercede
PJRST FWR0] ;[15000] Write it
JRST FWRZ] ;[15000] All done
OPEN 0,T1 ;[13000] Try the open
JRST [MOVE X,FRDREF ;[20000] Clean up reference first
HRRZS X,B$2PTR(X) ;[20000]
CERR1 (ODV)] ;[20000] and then give error
MOVEI M,177(T5) ;[14000] Estimated length of file (round up)
ASH M,-7 ;[15000] Convert to blocks (IDIVI step on R)
PUSHJ P,FILENN ; ENTER THE OUTPUT FILE
JRST [MOVE X,FRDREF ;[20000] Clean up reference first
HRRZS X,B$2PTR(X) ;[20000] to not leave bad pointer around
CERR1 (ENT) ] ;[20000] Then give error
JUMPE T5,FWR9 ;[15000] Zero-length file
MOVNI T1,(T5) ;[13000] Negative length in words
MOVSI T1,(T1) ;[13000] Should be in left half
HRR T1,FRDREF ;[13000] Build address to read in data
ADDI T1,T$DATA-1 ;[13000] Skip over overhead words
SETZ T2, ;[13000] I/O list in T1,T2
OUT 0,T1 ;[13000] Write it all out at once
JRST FWR9 ; YES, DONE WRITING FILE
GETSTS 0,IOSTS ; NO, FETCH I/O STATUS
ERROR (OER) ; AND GIVE AN OUTPUT ERROR MSG
FWR9:
MOVX T1,<17B12> ;[14000] We want to set the mode
ANDCAM T1,RBSPC+.RBPRV ;[14000] back to ASCII
SETZM RBSPC+.RBALC ;[14000] Don't de-allocate any blocks!!!
MOVEI T1,.RBSTS ;[22000] Reset count since RENAME believes
MOVEM T1,RBSPC+.RBCNT ;[22000] that the whole word is the count
RENAME RBSPC ;[14000] Rename it back to ASCII mode
CLOSE 0, ;[14000] Rename failed, try to Close the file
RELEASE 0, ;[14000] and release it.
FWRZ: MOVEI L,(L) ;[24000] Clear supersede/delete bit
PJRST FRDZ ;[14000] and un-reference the block
; MAKBUF - ALLOCATE A TEXT BUFFER AND SETUP CHAR COUNT AND BYTE POINTER
;
; CALL: MOVE L,[<REF,,LEN>]
; PUSHJ P,MAKBUF
; (RETURN)
;
; T4:=BYTE POINTER TO BUFFER (INDEXED BY T3)
; T5:=CHAR COUNT FOR BUFFER(# CHARS THAT'L FIT IN BUFFER)
MAKBUF: PUSH P,L ; SAVE AC L
HLRZ L,L ; FETCH 'REF'
PUSHJ P,RELM ; AND RELEASE ANY EXISTING BLOCK
POP P,L ; RESTORE AC L
HRRI L,T$DATA+10(L) ; DON'T FORGET BUFFER INFO WORDS!
PUSHJ P,REQM ; AND ALLOCATE THE BUFFER
PUSH P,L ; SAVE AC L
HLRZ L,L ; FETCH 'REF'
PUSHJ P,ADDBLK ; PUT BUFFER IN LINKED LIST
HLRZ L,(P) ; FETCH REF FROM AC L<LH>
PUSHJ P,FNDBLK ; AND BIND 'REF' TO BUFFER
ERROR (XXX) ; ? ? ?
POP P,L ; RESTORE AC L
MOVEI T5,(L) ; AND PUT IN AC T5 [13000]
IMULI T5,5 ; COMPUTE # CHARS IN BUFFER
SUBI T5,<T$DATA+10>*5; MINUS #CHARS TAKEN UP BY OVERHEAD
MOVE T4,[POINT 7,T$DATA(T3)] ; FETCH BP TO BUFFER
POPJ P, ; AND RETURN TO CALLER
SUBTTL TYPEL and TYPE - Type part of Text Buffer
; TYPEL - TYPE LINES OF TEXT BUFFER
;
; CALL: MOVEI ARG,N ; "N" OF "NT" COMMAND
; PUSHJ P,TYPEL
; (RETURN)
;
; SMASHES ACS X,T1,T4
TYPEL: PUSHJ P,EVL2RG ; CHANGE LINE ARG TO CHAR ADDRESSES
SKP ; AND FALL INTO "TYPE"
; TYPE - TYPE TEXT FROM TEXT BUFFER (BETWEEN TWO CHAR ADDRESSES)
;
; CALL: MOVEI SARG,CHAR.ADR1 ; LOWER BOUND
; MOVEI ARG,CHAR.ADR2 ; UPPER BOUND
; PUSHJ P,TYPE
; (RETURN)
;
; SMASHES ACS X,T1-T4
TYPE: PUSHJ P,CHK2RG ; MAKE SURE ARGS ARE IN BOUNDS
TYPE0: MOVE T4,ARG ; COPY SECOND ARGUMENT (M OF N,M)
SUB T4,SARG ; COMPUTE # CHARS TO BE TYPED
JUMPE T4,CPOPJ ; NOTHING TO TYPE. JUST RETURN TO CALLER
$T1: MOVE T1,SARG ; FETCH 36 BIT [13000] ADR OF NEXT CHAR
PUSHJ P,GET ; ANF FETCH CHAR FROM BUFFER
CAIN C,177 ;[10000] Rubout forces next character
AOJA SARG,[MOVE T1,SARG ;[10000] [13000] 36 bits
CAML SARG,ARG ;[16000] Still in bounds?
POPJ P, ;[16000] All done
PUSHJ P,GET ;[10000] to print as itself regardless
PUSHJ P,TCHR ;[10000]
SOJA T4,.+2] ;[10000]
PUSHJ P,TCCHR ; AND TYPE IT
AOJ SARG, ; INCREMENT TO NEXT CHAR
TXNN F,F$REE ;[2000] MAKE IT STOP IF WE REENTER
SOJG T4,$T1 ; LOOP FOR ALL CHARS TO BE TYPED
POPJ P, ; DONE. RETURN TO CALLER
SUBTTL FILOPN - Open a Device and Setup Buffers
; CALL: MOVE N,[Z CH,0]
; MOVE M,[<OBUF,,IBUF>]
; MOVEI L,FILSPC
; PUSHJ P,FILOPN
; (OPEN FAILURE RETURN)
; (SUCCESS)
;
; 'CH' IS THE I/O CHANNEL TO BE USED
; 'OBUF' IS THE ADR OF THE OUTPUT BUFFER HEADER
; 'IBUF' IS THE ADR OF THE INPUT BUFFER HEADER
; 'FILSPC' IS THE ADR OF THE FILE SPECIFICATION
;
; USES ACS X,T1-T3
FILOPN: MOVEM L,LASSPC ; SAVE ADR OF FILSPC IN CASE OF ERROR
MOVEI T1,.IOASL ; INIT IN ASCII LINE MODE
MOVE T2,FS$DEV(L) ; FETCH THE SIXBIT DEVICE NAME
; MAKE SURE DEVICE IS NOT A TTY CONTROLLED BY A JOB
MOVE X,T2 ; FETCH DEVICE NAME
DEVCHR X, ; AND ITS CHARACTERISTICS
TXNN X,DV.TTY ; IS DEVICE A TTY?
JRST FILOP2 ; NO, OKAY
TXNE X,DV.AVL ; YES, IS IT AVAILABLE?
TXNE X,DV.TTA ; AND NOT CONTROLLED BY A JOB?
ERROR (TTY) ; NO, ERROR
FILOP2: MOVE T3,M ; FETCH THE ADRS OF THE BUFFER HEADERS
MOVE X,FS$FLG(L) ;[334] GET FLAGS
TXNE X,FB$NON ;[334] SEE IF DECTAPE NON STANDARD
TXO T1,IO.NSD ;[334] NON-STANDARD DECTAPE
MOVE X,[OPEN 0,T1] ; SETUP THE OPEN
IOR X,N ; FILL IN THE CHANNEL
XCT X ; DO THE OPEN
POPJ P, ; OFEN FAILURE
; DO INBUF/OUTBUF
TLNN M,-1 ; OUTPUT HEADER SPECIFIED?
JRST FILOP1 ; NO
; DO OUTBUF TO SETUP OUTPUT BUFFERS
HLRZ T1,M ; FETCH ADR OF OUTPUT BUFFER HEADER
MOVEI T1,3(T1) ; FETCH ADR OF OUTPUT BUFFERS
EXCH T1,.JBFF ; AND PUT WHERE MONITOR CAN SEE IT
MOVE X,[OUTBUF 0,C$NBUF] ; GET READY FOR OUTBUF
IOR X,N ; FILL IN THE CHANNEL
XCT X ; DO THE OUTBUF
MOVEM T1,.JBFF ; RESTORE .JBFF
FILOP1: TRNN M,-1 ; INPUT HEADER SPECIFIED?
JRST CPOPJ1 ; NO, GIVE SUCCESS RETURN
; DO INBUF TO SETUP INPUT BUFFERS
MOVEI T1,3(M) ; FETCH ADR OF WHERE BUFFERS WILL GO
EXCH T1,.JBFF ; AND PUT WHERE MONITOR WILL SEE IT
MOVE X,[INBUF 0,C$NBUF] ; GET READY FOR INBUF
IOR X,N ; FILL IN THE CHANNEL
XCT X ; DO THE INBUF
MOVEM T1,.JBFF ; RESTORE .JBFF
JRST CPOPJ1 ; AND RETURN TO CALLER
SUBTTL FILLKP, FILENT, AND FILRNM - File LOOKUP/ENTER/RENAME
; CALL: MOVE N,[Z CH,0]
; MOVEI M,<ESTSIZ> ; ESTIMATED SIZE OF OUTPUT FILE
; MOVEI L,FILSPC
; PUSHJ P,FILLKP ; OR "PUSHJ P,FILENT"
; ; OR "PUSHJ P,FILRNM"
; (LOOKUP/ENTER ERROR)
; (SUCCESS RETURN)
;
; 'CH' IS THE I/O CHANNEL TO BE USED
; 'FILSPC' IS THE ADR OF THE FILE SPECIFICATION
;
; USES ACS X,T1-T4
FILRNM: MOVE T1,[RENAME 0,RBSPC] ; Set up RENAME opcode
JRST FILL1 ; and jump right in
FILENT: SKIPA T1,[ENTER 0,RBSPC] ; SETUP THE ENTER OPCODE
FILLKP: MOVE T1,[LOOKUP 0,RBSPC] ; SETUP THE LOOKUP OPCODE
FILL1: TLO L,200000 ;[20000] Set the Supersede bit
FILLNS: HRRM L,LASSPC ; SAVE ADR OF FILE SPEC
; CHECK IF DEVICE IS DISK. IF NOT, USE SHORT BLOCK
MOVE X,FS$DEV(L) ; FETCH THE DEVICE NAME
DEVCHR X, ; AND ITS CHARACTERISTICS
TXNN X,DV.DSK ; IS IT A DISK?
JRST FILL5 ; NO, USE SHORT BLOCK
; CLEAR EXTENDED LOOKUP/RENAME/ENTER ARG BLOCK
STORE (X,RBSPC,RBSPC+.RBSTS,0) ; CLEAR ARG BLOCK
; SET ARG COUNT
MOVEI X,.RBSTS ; FETCH COUNT OF ARGS/VALUES
TLNN L,200000 ;[20000] Non-superceding enter??
TRO X,RB.NSE ;[20000] Yes.
MOVEM X,RBSPC+.RBCNT ; AND STORE IN ARG BLOCK
; SET PPN
SKIPE X,FS$PPN(L) ; ANY PPN GIVEN?
MOVEI X,FS$PTH(L) ; YES, FETCH ADR OF PATH SPEC
MOVEM X,RBSPC+.RBPPN ; AND STORE IN ARG BLOCK
; SET FILENAME
MOVE X,FS$NAM(L) ; FETCH FILENAME
MOVEM X,RBSPC+.RBNAM ; AND STORE IN ARG BLOCK
; SET FILE EXTENSION
MOVE X,FS$EXT(L) ; FETCH THE FILE EXTENSION
MOVEM X,RBSPC+.RBEXT ; AND STORE IN ARG BLOCK
; SET FILE PROTECTION
MOVE X,FS$PRV(L) ; FETCH THE FILE PROTECTION
MOVEM X,RBSPC+.RBPRV ; AND STORE IN ARGUMENT BLOCK
; SET ESTIMATED SIZE OF FILE
;[14000] ;If I want it huge I must have a reason
CAXLE M,^D1500 ; INSURE VALUE IS WITHIN REASON
SETZ M, ; WELL, DON'T TRY TO MAKE IT HUGE!!
MOVEM M,RBSPC+.RBEST ; SET ESTIMATED SIZE OF FILE
; CHECK FOR A UFD
HLRZ X,FS$EXT(L) ; FETCH FILE EXTENSION
CAIN X,'UFD' ; IS IT A UFD?
JRST FILL3 ; YES, DO SPECIAL PROCESSING
; DO THE LOOKUP/RENAME/ENTER
FILL2: IOR T1,N ; MAKE THE LOOKUP/RENAME/ENTER INST.
XCT T1 ; AND EXECUTE IT
FILL2A: ;[4000] LABEL MOVED SO ERROR CODE RIGHT
SKIPA T2,RBSPC+.RBEXT ; FAILED. GET ERROR CODE AND SKIP
JRST CPOPJ1 ; SUCCEEDED. GIVE SUCCESS RETURN TO CALLER
FILL2B: HRRZM T2,LREERR ; STORE THE ERROR CODE FOR LATER
POPJ P, ; AND GIVE FAIL RETURN TO CALLER
; FILE IS A UFD
; SET PPN TO [1,1]
FILL3: MOVE X,[<1,,1>] ; FETCH MFD PPN ([1,1])
MOVEM X,RBSPC+.RBPPN ; AND STORE IN ARG BLOCK
; SET FILE NAME TO PPN OF FILESPEC
MOVE X,FS$PPN(L) ; FETCH PPN OF FILE SPEC
MOVEM X,RBSPC+.RBNAM ; AND STORE IN ARG BLOCK
; SET THE "I AM A DIRECTORY BIT" IN .RBSTS WORD
MOVX X,RP.DIR ; FETCH THE "I AM A DIRECTORY" BIT
MOVEM X,RBSPC+.RBSTS ; AND STORE IN ARG BLOCK
JRST FILL2 ; AND DO THE LOOKUP/RENAME/ENTER
; FILENN - FILE ENTER (non-superceding if TLO L,200000)
FILENN: MOVE T1,[ENTER 0,RBSPC] ; SETUP THE ENTER OPCODE
JRST FILLNS ; AND DO Possibly non-superceding ENTER
; FOR NON-DISK, USE SHORT ARG BLOCK
FILL5: MOVE X,T1 ; COPY THE LOOKUP/RENAME/ENTER INST.
MOVE T1,FS$NAM(L) ; FETCH THE FILE NAME
MOVE T2,FS$EXT(L) ; FETCH THE FILE EXTENSION
MOVE T3,FS$PRV(L) ; FETCH THE FILE PROTECTION
SKIPE T4,FS$PPN(L) ; ANY PATH?
MOVEI T4,FS$PTH(L) ; YES, FETCH ADR OF PATH SPEC
; FORM THE LOOKUP/RENAME/ENTER INSTRUCTION
IOR X,N ; FILL IN THE CHANNEL
HRRI X,T1 ; FILL IN ADR OF ARG BLOCK
XCT X ; PERFORM THE LOOKUP/RENAME/ENTER
JRST FILL2B ; FAILED
; SAVE SOME INFO IN EXTENDED ARG BLOCK
MOVEM T3,RBSPC+.RBPRV ; SAVE CREATION INFO
JRST CPOPJ1 ; SUCCEEDED. GIVE SUCCESS RETURN TO CALLER
>;; END FOR FTXTEC
FOR FTXTCERR,<
SUBTTL ERMT - Error Message Typeout
ERMT: MOVE X,.JBREN ; SAVE REENTER ADR FOR OTHER SEGMENT
MOVEM X,RENSAV ; AND SAVE FOR RETURN
MOVEM P,SADSAV ; SAVE THE CONTROL PDP
MOVEI X,[MOVE P,SADSAV ; SET NEW REENTER ADR
JRST ERMT3] ; . . .
MOVEM X,.JBREN ; . . .
; SEARCH FOR THE THREE LETTER ERROR CODE
HRLZ X,.JBUUO ;[422] GET ERROR CODE
; LOAD INDEX AOBJN POINTER
MOVSI N,-ERRLEN ;[422] LOAD LENGTH OF TABLE IN AOBJN FORMAT
; SEARCH FOR THE ERROR
ERMT1: HLLZ C,ERRTAB(N) ;[422] FETCH CODE IN TABLE
CAMN X,C ;[422] FOUND?
JRST ERMT2 ;[422] HOORAY! FOUND IT!!
AOBJN N,ERMT1 ;[422] CONTINUE SEARCHING
JRST ERMTE ;[422] OOPS! FORGOT TO PUT CODE IN TEXT!
; CODE WAS FOUND
ERMT2: MOVX T5,<POINT 7,> ;[422] MAKE T5 A BYTE POINTER TO ERRTAB
HRR T5,ERRTAB(N) ;[422] . . .
PUSHJ P,ERMTL ; TYPE THE LINE
; CHECK IF EXTENDED MESSAGE DESIRED
MOVE X,EHVAL ; FETCH MESSAGE LENGTH
TXNE X,JW.WCN ; WANT MESSAGE CONTINUATION?
JRST ERMT5 ; YES
SETO T4, ; CLEAR FLAG THAT WE TYPE ALL OF MSG
ERMT3: LDB T1,[POINT 9,.JBUUO,8] ; FETCH LUUO OPCODE
CAIN T1,LUUWRN ; A WARNING?
JRST ERMT34 ;[416] YES, NEVER DIE
MOVE X,ETVAL ;[12000] Check abort flag
TXNE X,ET$ABO ;[12000] Go to monitor if set
EXIT 1, ; YES, EXIT FOR FATAL CCL ERROR
; (USER CAN TYPE "CONTINUE" FOR
; MORE INFORMATION)
; PEEK AT NEXT INPUT CHAR TO SEE IF USER WANTS CONTINUATION OF MSG
ERMT34: MOVEI N,PROMPT ; TYPE FAKE PROMPT
PUSHJ P,TXSTR ; . . .
PUSHJ P,GETCH ; AND PEEK AT FIRST CHAR
CAIN C,"/" ; WANT CONTINUATION OF MESSAGE?
AOJLE T4,ERMT5 ; YES, IF WE HAVEN'T TYPED IT YET
CAIN C,"?" ; WANT TO SEE LAST 10 COMMANDS?
JRST ERMT4 ; YES
MOVEM C,INPCHR ; NO, SAVE CHAR FOR LATER
JRST ERMTZ ; AND FINISH UP
; TYPE LAST 10 COMMANDS
ERMT4: PUSH P,T4 ;[405] SAVE MSG FLAG...
PUSHJ P,ERRCTY ; TYPE LAST 10 COMMANDS
POP P,T4 ;[405] BECAUSE "ERRCTY" CLOBBERS IT
JRST ERMT3 ; AND GO BACK FOR MORE
; GIVE EXTENDED MESSAGE
ERMT5: ILDB C,T5 ; FETCH NEXT CHAR FROM TEXT
CAIG C,.CHCNH ; IS CHAR ^@,...,^H?
JRST ERMT3 ; YES, THEN WE'RE DONE
PUSHJ P,TCHR ; NO, TYPE THE CHAR
PUSHJ P,ERMTL ; AND REST OF LINE
JUMPE C,ERMT3 ;[422] IF NULL, QUIT
JRST ERMT5 ; AND TRY FOR ANOTHER LINE
; DONE. RETURN TO CONTROL SEGMENT
ERMTZ: MOVE X,RENSAV ; RESTORE PREVIOUS REENTER ADR
MOVEM X,.JBREN ; . . .
MOVE P,SADSAV ; RESTORE PREVIOUS CONTROL PDP
MOVE X,SEGNAM ; FETCH NAME OF CONTROL SEGMENT
MOVEM X,GSGNAM ; AND STORE IN GETSEG BLOCK
IFN FTXTEC&FTXTCERR, POPJ P, ;[21000] Just return
IFE FTXTEC&FTXTCERR, PJRST GETSG ; AND DO THE GETSEG
; CAN'T FIND THE ERROR CODE IN TEXT
ERMTE: MOVEI N,[ASCIZ/ *** UNDEFINED ERROR CODE ***
/]
PUSHJ P,TSTR ; TYPE THE MESSAGE
JRST ERMTZ
; TYPE A LINE FROM ERROR MESSAGE TEXT
ERMTL: ILDB C,T5 ; FETCH NEXT CHAR OF TEXT
JUMPE C,CPOPJ ;[422] RETURN IF NULL
CAIN C,.CHCNN ; IS IT A CONTROL-N?
JRST ERMTLN ; YES, PROCESS IT
PUSHJ P,TCHR ; NO, TYPE THE CHAR
CAIN C,.CHLFD ; IS IT A <LF>?
POPJ P, ; YES, RETURN TO CALLER
JRST ERMTL ; NO, KEEP TYPING THE LINE
; ERMTLN - PROCESS CONTROL-N IN LINE OF TEXT
ERMTLN: ILDB X,T5 ; FETCH FIRST DIGIT ON ^NDD
MOVEI X,-"0"(X) ; CONVERT CHAR TO A DECIMAL DIGIT
IMULI X,^D10 ; MAKE ROOM FOR SECOND DIGIT
ILDB C,T5 ; FETCH SECOND DIGIT
ADDI X,-"0"(C) ; ADD IN THE SECOND DIGIT
ROT X,-1 ; DIVIDE BY TWO AND KEEP THE REMAINEDER
MOVE T1,CNNTBL(X) ; FETCH TWO ADDR DISPATCH ENTRY
JUMPL X,.+2 ; SKIP IF NUMBER IS ODD
HLRZ T1,T1 ; ODD, FETCH OTHER DISPATCH ADDR
PUSHJ P,(T1) ; AND DISPATCH
JRST ERMTL ; DONE. CONTINUE MESSAGE PROCESSING
; CNNTBL - DISPATCH TABLE FOR ^N ITEMS IN MESSAGES
CNNTBL:
<CNNCCH,,CNNOFL> ; 00 01 Current char, LEBSPC
<CNNFIL,,CNNERC> ; 02 03 LASSPC, Lookup/enter code (#)
<CNNDEV,,CNNPTH> ; 04 05 Output dev, LASSPC path
<CNNARG,,CNNPRO> ; 06 07 ARG, LASSPC PROTECTION
<CNNEBF,,CNNIFL> ; 08 09 LEBSPC name, LEBSPC
<CNNEBN,,CNNIOF> ; 10 11 LEBSPC, IO flags (#)
<CNNTAG,,CNNSKP> ; 12 13 TAG, Lookup/Enter (text)
<CNNISK,,0> ; 14 15 IO error bits (text)
<CNNEOV,,CNNSRH> ; 16 17 EO, Search arg
<CNNTSC,,CNNSWT> ; 18 19 MACNAM, switch
<CNNEWF,,CNNERF> ; 20 21 EW, ER
<CNNCNT,,CNNCND> ; 22 23 ^T, ^D
<CNNSAR,,CNNFLG> ; 24 25 SARG, FLAGS
<CNNVAL,,0> ;26 0 VALUE,
; ^N00 - TYPE CURRENT COMMAND CHAR
CNNCCH: SKIPGE CMDCNT ;[20000] Less than nothing
SETZM CMDCNT ;[20000] Should really be just nothing
PUSHJ P,CMDBCH ; BACKUP 2 CHARS
PUSHJ P,CMDBCH ; . . .
PUSHJ P,CMDGCH ; GET PREVIOUS CHAR
JFCL ; (WHY???)
CAIN C,"^" ; IS THIS AN ^<CHAR> COMMAND?
PUSHJ P,TCHR ; YES, TYPE AN "^" FIRST
PUSHJ P,CMDGCH ; AND FETCH THE CURRENT CHAR
JFCL ; (SHOULDN'T OCCUR)
PJRST TSCHR ; TYPE THE CHAR AND RETURN TO CALLER
; ^N01 - TYPE EB FILE-NAME AND EXTENSION
CNNOFL: MOVEI L,LEBSPC ; FETCH ADR OF LAST OUTPUT FILE-SPEC
PJRST TFSPEC ; AND TYPE FILE-NAME AND RETURN
; ^N02 - TYPE FILE-NAME REFERENCES BY LAST UUO
CNNFIL: MOVE L,LASSPC ; FETCH ADR OF LAST FILE SPEC
PJRST TFSPEC ; AND TYPE THE FILE-NAME AND EXTENSION
; ^N03 - TYPE MONITOR ERROR CODE (L-E-R)
CNNERC: MOVE N,LREERR ; FETCH LAST LOOKUP/RENAME/ENTER CODE
PJRST TOCT ; AND TYPE IT IN OCTAL
; ^N04 - TYPE OUTPUT DEVICE NAME
CNNDEV: MOVEI L,LEBSPC ; FETCH ADDR OF LAST OUTPUT FILE-SPEC
TXNN F,F$UBK ; DOING "EB"?
MOVEI L,LEWSPC ; NO, DOING "EW"
PJRST TDEV ; AND TYPE THE DEVICE NAME
; ^N05 - TYPE LAST FILE-SPEC PATH
CNNPTH: MOVE L,LASSPC ; FETCH ADR OF LAST FILE-SPEC
PJRST TPATH ; AND TYPE PATH AND RETURN
; ^N24 - TYPE SARG VALUE [12000]
CNNSAR: SKIPA N,SARG ;[12000] Fetch 2nd argument
; ^N06 - TYPE ARG VALUE
CNNARG: MOVE N,ARG ; FETCH THE ARG VALUE
PJRST TDEC ; TYPE IT AND RETURN
; ^N07 - TYPE LAST FILE PROTECTION
CNNPRO: MOVE N,LASSPC ; FETCH LAST FILE-SPEC
PJRST TPROT ; TYPE PROTECTION AND RETURN
; ^N08 - TYPE LAST "EB" FILE-NAME
CNNEBF: MOVE N,LEBSPC+FS$NAM ;[337] GET .BAK NAME
PJRST TSIX ;[337] TYPE FILE-NAME AND RETURN
; ^N09 - TYPE LAST INPUT FILE NAME
CNNIFL: MOVEI L,LEBSPC ; FETCH ADR OF LAST INPUT FILE-SPEC
PJRST TFSPEC ; TYPE FILE-NAME AND RETURN
; ^N10 - TYPE ORIGINAL "EB" FILE-NAME
CNNEBN: MOVEI L,LEBSPC ;[12000] FETCH LAST EB SPEC
PJRST TFSPEC ;[237] TYPE ORIGINAL SPEC
; ^N11 - TYPE I/O STATUS FLAGS
CNNIOF: HRRZ N,IOSTS ; FETCH I/O STATUS FLAGS
PJRST TOCT ; AND TYPE IN OCTAL
; ^N12 - TYPR CURRENT TAG
CNNTAG: HLRZ T1,1(REF) ; FETCH CHAR.ADR OF CURRENT TAG
IDIVI T1,5 ; AND FORM A BYTE POINTER
HLL T1,CBPTBL-1(T2) ; . . .
ADD T1,@CMDBUF ; MAKE IT ABSOLUTE
MOVE T2,2(REF) ; FETCH CHAR COUNT FOR TAG
CNNTG1: JUMPE T2,CPOPJ ; RETURN IF DONE
ILDB C,T1 ; FETCH NEXT CHAR FROM TAG
PUSHJ P,TCCHR ; AND TYPE IT
SOJA T2,CNNTG1 ; AND TRY FOR ANOTHER CHAR
; ^N13 - SKIP TO ^ANN WHEN NN IS LRE ERROR CODE IN OCTAL
; (LRE="LOOKUP/RENAME/ENTER")
CNNSKP: LDB T2,[POINT 6,LREERR,35] ; FETCH LRE ERROR CODE
CNNSK1: ILDB C,T5 ; FETCH NEXT TEXT CHAR
CAIN C,.CHCNB ; ^B?
POPJ P, ; YES, PRINT DEFAULT MESSAGE
CAIE C,.CHCNA ; ^A?
JRST CNNSK1 ; NO, TRY AGAIN WITH NEXT CHAR
; FOUND ^A. SEE IF NN MATCHES
ILDB C,T5 ; FETCH FIRST OCTAL DIGIT
MOVEI T1,-"0"(C) ; CONVERT TO A NUMBER
LSH T1,3 ; MAKE ROOM FOR SECOND DIGIT
ILDB C,T5 ; FETCH THE SECOND DIGIT
IORI T1,-"0"(C) ; ADD IN THE SECOND DIGIT
CAIE T1,(T2) ; DOES NN MATCH?
JRST CNNSK1 ; NO, TRY AGAIN
POPJ P, ; YES, TYPE OUT THE LINE
; ^N14 -SKIP TO ^ANN WHERE NN IS OCTAL FOR BITS 18-21 OF I/O STATUS
CNNISK: LDB T2,[POINT 4,IOSTS,21] ; FETCH 4 RELEVANT STATUS BITS
JRST CNNSK1 ; AND FIND THE PROPER MESSAGE
; ^N16 - TYPE "EO" VALUE
CNNEOV: MOVEI N,C$EOVL ;[406] FETCH THE "EO" VALUE
PJRST TDEC ; TYPE IT AND RETURN
; ^N17 - TYPE SEARCH ARG
CNNSRH: MOVEI N,SRHARG ; FETCH ADR OF SEARCH ARG
PJRST TSSTR ; TYPE IT AND RETURN
; ^N18 - TYPE Current MACRO name
CNNTSC: MOVE N,MACNAM ;[12000] current macro name
PJRST TSIX ;[12000] in SIXBIT
; ^N19 - TYPE SWITCH NAME
CNNSWT: MOVE N,SBNAME ; FETCH THE SWITCH NAME
PJRST TSIX ; TYPE IT AND RETURN
; ^N20 - TYPE EW FILE-NAME AND EXTENSION
CNNEWF: MOVEI L,LEWSPC ; FETCH ADR OF LAST OUTPUT FILE-SPEC
PJRST TFSPEC ; AND TYPE FILE-NAME AND RETURN
; ^N21 - TYPE ER FILE-NAME AND EXTENSION
CNNERF: MOVEI L,LERSPC ; FETCH ADR OF LAST INPUT FILE-SPEC
PJRST TFSPEC ; AND TYPE FILE-NAME AND RETURN
; ^N22 - Type current ET value [12000]
CNNCNT: SKIPA N,ETVAL ;[12000] Get the ET value
; ^N23 - Type the currrent ED value [12000]
CNNCND: MOVE N,EDVAL ;[12000] Get the ED value
PJRST TOCT ;[12000] Type in octal
; ^N24 gets CNNSAR, which is just before CNNARG
; ^N25 - Type the global flags [12000]
CNNFLG: MOVE N,F ;[12000] Get the flags
PJRST TOCT ;[12000] Type in octal
; ^N26 - Type the current VALUE [12000]
CNNVAL: MOVE N,VALUE ;[12000] Get VALUE
PJRST TDEC ;[12000] type in decimal
SUBTTL ERRTXT - Text of All Error Messages
CINFO. ; CLEAR THE INFO/REDEF MECHANISM
; MACRO TO DEFINE AN ERROR TEXT
DEFINE ERRGEN(PREFIX,TEXT)<
LSTOF.
E$$'PREFIX': ASCIZ\'TEXT'\
INFO. (REDEF.,<%EGEN ('PREFIX')>)
LSTON.
>
ERRGEN ARG,< Improper Arguments
The following argument combinations are illegal:
1) , (no argument before comma)
2) M,N, (where M and N are numeric terms)
3) H, (because H=B,Z is already two arguments)
4) ,H (H following other arguments)
>
ERRGEN ASN,< Ambiguous Switch Name: /19
The switch "/19" is not uniquely abbreviated, i.e. more than
one switch will match "/19". A longer, unique form of the
switch should be used.
>
ERRGEN BAK,< Cannot Delete Old Backup File
Failure in RENAME process at close of editing job initiated by an EB
command or a TECO command. There exists an old backup file 08.BAK
with a protection 07 such that it cannot be deleted. Hence the
input file 10 cannot be renamed to "08.BAK". The output file
is closed with the filename "01". The RENAME MUUO
error code is 03.
>
ERRGEN BNF,< Block not found
This is an internal error and should be reported. A block of text,
such as a previously-executed command, or q-register text, was not
in the linked list of such blocks.
>
ERRGEN BPT,< Breakpoint in macro "18"
The most recent EB file was: "10"
The most recent ER file was: "21"
The most recent EW file was: "20"
The most recent search argument was: "17"
EO=16, ET=22, ED=23
ARG=06, SARG=24, VALUE=26,
Flags="25"
>
ERRGEN CCM,< CCL Command Missing
TECO10 was run with a run-offset of one (1) and there was no file
'EDT' in TMPCOR or '###EDT.TMP' on the user's disk area.
>
ERRGEN CEF,< Core expansion failure
The current operation requires more memory storage than XTEC now has
and TECO10 is unable to obtain more core from the monitor. This message
can occur as a result of any one of the following things:
1) Command buffer overflow while a long command string is being typed,
2) Q-register buffer overflow caused by an X or [ command.
3) Too many Q-registers in use (.gt.5000),
4) Too much nesting or recursion of the M command.
5) Editing buffer overflow caused by an insert command or
a read command or other causes.
>
ERRGEN CFP,< Can't Find Overflowed PDL
A PDL overflow trap occurred, but TECO10 could not find the PDL
that caused the overflow. This is an internal error and should be
reported, along with a teletype printout showing what the user was
doing.
>
ERRGEN CON,< Confused use of conditionals
Conditionals, parenthesized arguments, and iterations must be properly
nested. The user probably used some construct like: N"E...(...' where
an iteration or parenthesized argument is begun in a conditional
but not terminated in the same conditional.
>
ERRGEN EBD,< EB with Device 04 is Illegal
The EB command and the TECO command may be specified only with
file structured devices (ie: disk and DECtape.)
>
ERRGEN EBF,< EB with Illegal File 02
The EB command and the TECO command may not be used with a file
having the filename extension ".BAK" or a file having the name
"NNNXTC.TMP" where NNN is the user's job number. The user must
either use an ER-EW sequence or rename the file.
>
ERRGEN EBO,< EW Before Current EB Closed
An ER or EW command may not be given while an EB command is in
progress. Give an EF to close the files if you wish
to do an ER or EW, or an EK to cancel the current EB.
>
ERRGEN EBP,< EB Illegal because of file 02 Protection
The file 02 cannot be edited with an EB command or a TECO command
because it has a protection 07 such that it cannot be renamed
at close time.
>
ERRGEN EMA,< EM with Illegal Argument
The argument N in an NEM command must be greater than zero.
>
ERRGEN EMD,< EM with no Input Device Open
EM commands apply only to the input device, and should be preceded
by an ER (or equivalent) command. To position a tape for output, that
unit should be temporarily opened for input while doing the EM commands.
>
ERRGEN END,< EN with a Device is Illegal
Since it is not possible to RENAME across devices. There must be
no device specified in an EN command. The device is specified
in the ER command which selected the file.
>
ERRGEN ENO,< EN REQUIRES AN OPEN INPUT FILE
EN commands apply to the file currently open for input. You must
execute an ER command to select the file to be RENAME'd or deleted
before executing an EN.
>
ERRGEN ENT,< 13
00Illegal Output Filename "02"
ENTER UUO failure 0. The filename "02" specified for the
output file cannot be used. the format is invalid.
01Output UFD for the file "02" not found
ENTER UUO failure 1. The file 02 specified
for output by an EE, EW, EA, EZ, OR MAKE command cannot be created
because there is no user file directory with the project-programmer
number 05 on device 04.
02Output Protection Failure
ENTER UUO failure 2. The file 02 specified
for output by an EE, EA, EZ, EB, MAKE, or TECO command cannot be
created either because it already exists and is write-protected against
the user, or because the UFD it is to be entered into is write-
protected against the user.
03Output File being Modified
ENTER UUO failure 3. The file 02 specified for output
by an EE, EW, EA, EZ, EB, or TECO command cannot be created
because it is currently being created or modified by another job.
04File "02" already exists
ENTER UUO failure 4. Re-issue the command with the /SUPERSEDE switch,
if you really want to supersede the file. Otherwise use a different
name, or (assuming you do not intend to read your current "ER" file
any more, do an "ER" to the file that would be superseded, and
an "E=newname$" to rename it.
06Output UFD or RIB Error
ENTER UUO failure 6. The output file 02 cannot be
created because a bad directory block was encountered by the
monitor while the ENTER was in progress. The user may try
repeating the EE, EW, EA, EB, or TECO COMMAND, BUT IF The ERROR
PERSISTS, IT IS IMPOSSIBLE TO PROCEED. Notify your system manager.
14No Room or Quota Exceeded on 04
ENTER UUO FAILURE 14. The output file 02 cannot be
created because there is no more free space on device 04 or
because the user's quota is already exceeded there.
15Write Lock on 04
ENTER UUO failure 15. The output file 02 cannot be
created because the output file structure is write-locked.
16Monitor Table Space Exhausted
ENTER UUO failure 16. The output file 02 cannot be
created because there is not enough table space left in the
monitor to allow the enter. The user may try repeating the
EE, EW, EA, EB, or TECO command, but if the error persists
he or she will have to wait till conditions improve.
23Output SFD Not Found
ENTER UUO failure 23. The output file 02 cannot be
created because the Sub-File-Directory on which it should be
entered cannot be found.
24Search List Empty
ENTER UUO failure 24. The output file 02 cannot be
created because the user's file structure search list is empty.
25Output SFD Nested Too Deeply
ENTER UUO failure 25. The output file 02 cannot be
created because the specified SFD path for the ENTER
is nested too deeply.
26No Create for Specified SFD Path
ENTER UUO failure 26. The output file 02 cannot be
created because the specified sfd path for the ENTER
is set for no creation.
41Undefined Network Node.
ENTER UUO failure 41. The device 04 cannot be opened
because the node on which it resides is not on line. Try again later.
ENTER FAILURE 03 on Output File 02
The attempted ENTER of the output file 02 has failed and
the monitor has returned an error code of 03. This error
is not expected to occur on an ENTER. Please report it to your
systems manager with the tty printout showing what you were doing.
>
ERRGEN EOA,< 06EO Argument Too Large
The argument 06 given with an EO command is larger than the
standard (maximum) setting of eo=16 for this version of TECO10.
This must be an older version of TECO10 than the user thinks he
is using; the features corresponding to EO=06 do not exist.
>
ERRGEN FNF,< 13
00Input File 02 not Found
LOOKUP UUO failure 0. The file 02 specified for input by an
ER, EB, EI, EP, OR TECO command was not found on the
input device 04.
01Input UFD - not Found
LOOKUP UUO failure 1. The file 02 specified for input by
an ER, EB, EI, EP, OR TECO command cannot be found
because there is no User File Directory with project-programmer
number 05 on device 04.
02Input Protection Failure
LOOKUP UUO failure 2. The file 02 specified for input
by an ER, EB, EI, EP OR TECO command cannot be read
because it is read-protected 07 against the user.
06Input UFD or RIB Error
LOOKUP UUO failure 6. The input file 02 cannot be
read because a bad directory block was encountered by the
monitor while the LOOKUP was in progress. The user may try
repeating the ER, EB, EI, EP OR TECO command, but if the error
persists all is lost. Notify your system manager.
16Monitor Table Space Exhausted
LOOKUP UUO failure 16. The input file 02 cannot be
read because there is not enough table space left in the
monitor to allow the LOOKUP. The user may try repeating the
ER, EB, EI, EP, OR TECO command, but if the error persists
he or she will have to wait until conditions improve.
23Input SFD not Found
LOOKUP UUO failure 23. The input file 02 cannot be found
because the sub-file-directory on which it should be looked up
cannot be found.
24Search List Empty
LOOKUP UUO failure 24. The input file 02 cannot be
found because the user's file structure search list is empty.
25Input SFD Nested Too Deeply
LOOKUP UUO failure 25. The input file 02 cannot be found
because the specified SFD path for the LOOKUP is
nested too deeply.
41Undefined Network Node.
LOOKUP UUO failure 41. The device 04 cannot be opened
because the node on which it resides is not on line. Try again later.
Lookup Failure (03) on Input File 02
The attempted LOOKUP on the input file 02 has failed and
the monitor has returned an error code of 03. This error
is not expected to occur on a LOOKUP. Please give the
terminal prinout showing what you were doing to your system manager.
>
ERRGEN ICE,< Illegal ^E Command in Search Argument
A search argument contains a ^E command that is either not defined
or incomplete. The only valid ^E commands in search arguments are:
^EA, ^ED, ^EV, ^EW, ^EL, ^ES, ^E<NNN>, and ^E[A,B,C,...].
>
ERRGEN ICN,< Illegal ^N Command in Search Argument
When used in a search argument, the ^N command must be followed
by a character.
>
ERRGEN IDV,< Input Device 04 not Available
Open failure. Unable to initialize the device 04
for input. Either the device is being used by someone else right
now, or else it does not exist in the system.
>
ERRGEN IEC,< Illegal Character "00" After E
"E" was interpreted as part of a 2-letter command.
"E00" is not recognized as a command.
>
ERRGEN IEM,< Re-Init Failure on Device 04 After EM
Unable to re-initialize the device 04 after executing an
EM command on it. If this error persists after retrying to
initialize the device with an ER command(or EW command
if output to the device is desired), consult your system manager.
>
ERRGEN IER,< Input Error While Reading a File
While reading an initialization, EI, EP, etc. an i/o error
occurred.
>
ERRGEN IES,< Input Error While Reading SWITCH.INI
An I/O error occurred whilst reading SWITCH.INI.
>
ERRGEN IFC,< Illegal Character "00" After F
"F" was interpreted as part of a 2-letter command.
"F00" is not recognized as a command.
>
ERRGEN IFS,< Illegal Character "00" in File Specification
File specifications must be of the form: DEV:FILE.TXT[PATH]
where DEV, FILE, and EXT are alphanumeric strings. No
characters other than these may appear between the EB, E&, EE, EI,
E=, EQ, E%, EW, or EZ command and the terminator.
>
ERRGEN ILL,< Illegal Command: 00
The character "00" is not defined as a valid TECO10 command.
>
ERRGEN ILM,< Illegal Memory Reference
TECO10 made an illegal memory reference. This is an internal
error and should be reported, along with a teletype printout showing
what the user was doing. The value of the buffer pointer is set to
the beginning of the buffer; the buffer and file should (hopefully)
remain intact.
>
ERRGEN ILR,< Cannot LOOKUP Input File 09 to RENAME it
Failure in rename process at close of editing job initiated by
an EB command or a TECO command. Unable to do a LOOKUP on the
original input file 10 in order to RENAME it to
"08.BAK". The output file is closed with the name "01".
The LOOKUP UUO error code is 03.
>
ERRGEN ILS,< Illegal EL Specification
A numeric specification for the EL command must be greater
than or equal to 0, and less than or equal to 3.
>
ERRGEN INP,< Input Error 11 on File 09
A read error has occurred during input. The input file 09
has been released. The user may try again to read the file, but if
the error persists, the user will have to return to his or her backup file.
The input device error flags (status word right half with bits 22-35
masked out) are 11 (14
01BLOCK TOO LARGE).
02PARITY OR CheCKSUM ERROR).
03BLOCK TOO LARGE AND PARITY ERROR).
04DEVICE ERROR, DATA MISSED).
05BLOCK TOO LARGE AND DEVICE ERROR).
06PARITY ERROR AND DEVICE ERROR).
07BLOCK TOO LARGE, PARITY ERROR, AND DEVICE ERROR).
10IMPROPER MODE).
11BLOCK TOO LARGE AND IMPROPER MODE).
12PARITY ERROR AND IMPROPER MODE).
13BLOCK TOO LARGE, PARITY ERROR, AND IMPROPER MODE).
14DEVICE ERROR AND IMPROPER MODE).
15BLOCK TOO LARGE, DEVICE ERROR, AND IMPROPER MODE).
16PARITY ERROR, DEVICE ERROR, AND IMPROPER MODE).
17BLOCK TOO LARGE, PARITY ERROR, DEVICE ERROR,
AND IMPROPER MODE).
>
ERRGEN IPA,< Illegal argument to "P" command
The "P" command can take a numeric argument, which is the number of
pages to move. A negative argument is illegal.
>
ERRGEN IPP,< Illegal Character "00" in PPN
A PPN IS OF The FORM [PJ,PG,SFD1,...,SFDN]
WheRE "PJ", "PG", AND ",SFD1,...,SFDN" ARE OPTIONAL.
"PJ" AND "PG" MUST BE OCTAL NUMBERS. AN SFD is an alphanumeric
or quoted string.
>
ERRGEN IPR,< Illegal Character 00 in /PROTECT Switch
The format of the /PROTECT switch is: /PROTECT:NNN
Where NNN is an octal number and may optionally be
enclosed in angle brackets (ie: /protect:<nnn>.)
>
ERRGEN IQC,< Illegal Character "00" after " Command
The ONLY VALID " COMMANDS ARE "G, "L, "N, "E, "C,
"<, ">, "=, "R, "A, "D, "V, "W, "T, "F, "S, and "U.
>
ERRGEN IQN,< Illegal Character "00" in Q-Register Name
A Q-register name must be in one 2 formats:
(1) X , where "X" is a printing character (except `,{,|,},~)
(2) (FOO) where "FOO" is up to 6 alphanumerics, or is in quotes.
>
ERRGEN IQR,< Illegal Character "00" in Q-Register Name, please retype
The Q-register name given in the "*" command contains
an illegal character. Re-type the "*" and a legal q-register name.
A Q-register name must be in one 2 formats:
(1) X , where "X" is a printing character (except `,{,|,},~)
(2) (FOO) where "FOO" is up to 6 alphanumerics, or is in quotes.
>
ERRGEN IRB,< Cannot Rename Input File 09 to 08.BAK
Failure in rename process at close of editing job initiated by an
EB command or a TECO command. The attempt to rename the original
input file 10 to the backup filename "08.BAK"
has failed. The output file is closed with the name "01".
The RENAME UUO error code is 03.
>
errgen IRN,< Cannot Re-Init Device 04 for Rename Process
Failure in rename process at close of editing job initiated by
an EB command or a TECO command. Cannot reinitialize
the original input device 04 in order to rename the input file
01 to 08.BAK. The output file is closed with the
name 02.
>
ERRGEN ISW,< Illegal Character "00" in a Switch
AN ARGUMENT WAS EXPECTED AFTER The SWITCH "/19". A
COLON (:) WAS EXPECTED.
>
ERRGEN ITT,< Illegal TTCALL Type Value 06
The EXTENDED TTCALL command must take the form "arg1,arg2:^T"
where arg1 is the (optional) TTCALL argument and arg2 is the
TTCALL type in decimal. The second argument must be a
legitimate TTCALL type, With 0-13 legal except for 3(OUTSTR).
:8^T will do a RESCAN, :1,8^T tests for CCL entry point.
>
ERRGEN IUU,< Illegal LUUO
A local uuo was encountered which is not legal. This error
should not occur. close your files and report this problem
to your system manager.
>
ERRGEN LDV,< Cannot Access Log Device
I can't get that device for a log file, dummy!
>
ERRGEN LFE,< Cannot ENTER Log File
I can't make the file, dummy!
>
ERRGEN LLB,< Linked-list broken
This is an internal error. The linked list of q-register values, etc.
is broken. Try to save your edits and exit. This is an internal error
which should be reported. Save your output.
>
ERRGEN MAP,< Missing '
Every conditional (opened with the " command) must be closed
with the ' command.
>
ERRGEN MCP,< Missing Control PDL
A pdl overflow was trapped and the control pdl was found to be
missing. This error should not occur. Close your files
and report the problem to your system manager.
>
ERRGEN MEE,< Macro Ending with E
A command macro being executed from a Q-register ends with the
character "E". This is an incomplete command. E is the initial
character of an entire set of commands. The other character
of the command begun by E must be in the same macro with the E.
>
ERRGEN MEF,< Macro Ending with F
A command macro being executed from a Q-register ends with the
character "F". This is an incomplete command. F is the initial
character of an entire set of commands. The other character
of the command begun by F must be in the same macro with the F.
>
ERRGEN MEO,< Macro Ending with Unterminated O Command
The last command in macro "18" is an "O" command with no
delimiter to mark the end of the tag-name.
>
ERRGEN MEQ,< Macro Ending with "
The macro "18" ends with a " character. This is an
incomplete command. " must be followed by G, L, N, E, C, A, D,
V, W, T, F, S, or U to indicate the condition under which the
following commands are to be executed. This character must be in
the Q-register with the ".
>
ERRGEN MEU,< Macro Ending with ^
The macro "18" ends with a ^ character. This is an
incomplete command. ^ followed by a character converts the character
into a control character for command parsing. The
character was not there.
>
ERRGEN MIQ,< Macro Ending with "00"
The macro "18" ends with the "00" command.
This command requires a Q-register name of 1 character
or up to 6 characters in parentheses.
>
ERRGEN MLA,< Missing Left Angle Bracket
There is a right angle bracket that has no
matching left angle bracket. An iteration must
be complete within the macro or command.
>
ERRGEN MLP,< Missing (
There is a right parenthesis that is not matched
by a corresponding left parenthesis.
>
ERRGEN MRA,< Missing Right Angle Bracket
There is a left angle bracket that has no
matching right angle bracket. An iteration must
be complete within the macro or command.
>
ERRGEN MRP,< Missing )
There is a right parenthesis that is not matched
by a corresponding left parenthesis.
>
ERRGEN MSC,< Missing Start of Conditional
A ' command (end of conditional) was encountered. Every '
command must be matched by a preceding " (start of conditional)
command.
>
ERRGEN MUU,< Macro Ending with ^^
The macro "18" ends with either a control-^
or ^^. This is an incomplete command. The ^^command takes
a single character text argument that must be in the Q-register
with the ^^.
>
ERRGEN NAE,< No Argument Before =
The command N= or N== causes that value N to be typed. The
= command must be preceded by either a specific numeric
argument or a command that returns a numeric value.
>
ERRGEN NDI,< No Delimiter After I
If the I command has a numeric argument it must be followed
by a null text string i.e.: 33I$ or 33@i//
>
ERRGEN NAQ,< No Argument Before "
The " command must be preceded by a single numeric argument
on which the decision to execute the following commands
or skip to the matching ' is based.
>
ERRGEN NAU,< No Argument Before U
The command NUI stores the value N in Q-register I.
The U command must be preceded by either a specific numeric
argument or a command that returns a numeric value.
>
ERRGEN NFI,< No File for Input
Before issuing an input command (Y, ^Y, or A) it is necessary
to open an input file by use of an ER, EB, or TECO command.
>
ERRGEN NFO,< No File for Output
Before giving an output command (PW, P, ^P, N, EX, or EG) it is
necessary to open an output file by use of an EA, EB, EW, EZ, MAKE,
or TECO command.
>
ERRGEN NLF,< No Log File Open
A command of the form nEL was given, but there is no log file
open to have parameters modified.
>
ERRGEN NSI,< Null Switch Name is Illegal
A switch name must consist of one or more alphanumeric characters.
>
ERRGEN NTQ,< No text in Q-register
The Q-register "19" does not contain text.
>
ERRGEN NYA,< Numeric argument to "Y" or "EY" command
The "Y" command does not take numeric arguments.
Did you type "0YY" instead of "0TT"?
>
ERRGEN ODV,< Output Device 04 Not Available
Initialization failure. Unable to initialize the device 04
for output. Either the device is being used by someone else
right now, or it is write locked, or else it does not exist in
the system.
>
ERRGEN OFO,< EW Before Current Output file Closed
An EB,EW,EA, or EZ command may not be given while an output file is open.
Give an EF to close the file if you wish to save the output file as it is,
or an EK to throw away the current output file.
>
ERRGEN OUT,< Output Error 11. Output File 10 Closed
An error on the output device is fatal.
The output file is closed at the end of the last data that
was successfully output. It has the filename "01".
See the TECO Reference Manual section 4.4 for a recovery
technique. The output device flags (status word right half
with bits 22-35 masked out) are 11 (14
00End of Tape).
01Block Number Too Large, Device Full or Quota Exceeded).
02Parity or Checksum Error).
Block Number Too Large and Parity Error).
04Device Error, Data Missed).
05Block Number Too Large and Device Error).
06Oarity Error and Device Error).
07Block Number Too Large, Parity Error, and Device Error).
10Improper Mode or Device Write Locked).
11Block Number Too Large and Improper Mode).
12Parity Error and Improper mode).
13Block Number Too Large, Parity Error, and Improper Mode).
14Device Error and Improper Mode).
15Block Number Too Large, Device Error, and Improper Mode).
16Parity Error, Device Error, and Improper Mode).
17Block Number Too Large, Parity Error, Device Error,
and Improper Mode).
>
ERRGEN OWL,< OUTPUT ERROR writing LOG FILE
AN OUTPUT ERROR OCCURED, DUMMY!
>
ERRGEN PAR,< Confused Use of Parentheses
An iteration may not be contained within a parenthesized expression.
>
ERRGEN PES,< Attempt to Pop Empty Stack
A ] command (pop off q-register stack into a q-register) was
encountered when there was nothing on the q-register stack.
>
ERRGEN PNF,< Page Number 06 Not Found
An attempt to move to page 06 of the input file 02
was made with the ^P or ^Y command. that page does not exist in the
input file.
>
ERRGEN POP,< Attempt to move Pointer Off Page.
The argument specified with a J, C, R, or D command must point to
a position within the current size of the buffer. (ie: between B
and Z inclusive.) This can also occur on a "]()" command since
the numeric value will be used for ".".
This can also occur with the nA command (A with numeric argument)
if (.+n) attempts to access a character off either end of the buffer.
>
ERRGEN PPC,< Attempt to Move Previous to Current page with ^P or ^Y
The argument to a ^P or ^Y command is an absolute page number in the
file. it must be greater than or equal to the current page number.
>
ERRGEN PTS,< PDL Table Too Small
There are not enough ENTRIES in the pdl table. This error is not
expected to occur. Close your files and report the problem to your
system manager.
>
ERRGEN RNF,< 13
01UFD for 02 Not Found
RENAME UUO failure 1. The new filespec 01 specified
by an EN command cannot be used because there is no directory
05 on device 04.
02Protection Failure for 01
RENAME UUO faulure 2. the filespec 01 specified
by an EN command cannot be used because you are not privileged
to RENAME the input file.
03File Being Modified
RENAME UUO failure 3. The filespec 02 specified
by an EN command cannot be used because the input file is being
modified by someone.
04Rename Filename 02 already exists
RENAME UUO failure 4. The filespec 02 specified
by an EN command could not be used because there is already
a file by that name.
06UFD or RIB Error
RENAME UUO failure 6. The filespec 02 specified
by an EN command could not be used because a bad directory
block was encountered by the monitor. Notify your system manager.
22Cannot Delete a Non-Empty Directory
RENAME UUO failure 22. The filespec 02 specified
by an EN command could not be used because the input file was
a directory which was not empty, and therefore cannot be deleted.
23Output SFD Not Found
RENAME UUO failure 23. The output file 02 specified
by an EN command could not be used because the Sub-File-Directory
on which the file should be placed does not exist.
RENAME failure 03 for 02
The attempted Rename of the Input file has failed and
the monitor has returned an error code of 03. This error should
probably not happen on a RENAME. Please report
the problem to your systems manager.
>
ERRGEN RNO,< Cannot Rename Output File 01
Failure in rename process at close of EDITING job initiated by
an EB command or a TECO command. The attempt to rename the output
file 01 to the name "10" originally specified in the
EB or TECO command has failed. The original input file 10
as been renamed "08.BAK", BUT The OUTPUT FILE IS CLOSED WITH
The NAME "01". The RENAME UUO error code is 03.
>
ERRGEN SEF,< Superceding Existing File: 02
The output file 02 already exists on 04.
This message is warning the user that his or her existing file is
being overwritten.
>
ERRGEN SNA,< Initial Search With No Argument
A search command with null argument has been given, but there
was no preceding search command from which the argument could be
taken.
>
ERRGEN SNI,< ; Not in Iteration
The semicolon command may be used only in an iteration.
>
ERRGEN SRH,< Cannot Find "17"
A search command not preceded by a colon modifier and not
within an iteration has failed to find the specified character
string "17".
If an S, FS, FD, or any negative or bounded search fails, the pointer is
unchanged. After an n or _ search fails, the last page of the
input file has been read and, in the case of N, output, and the
buffer cleared.
>
ERRGEN STC,< Search String Too Long
The maximum length of a search string is 80 characters, including
all string control commands and their arguments.
>
ERRGEN STL,< Search String Too Long
The maximum length of a search string is 36 character positions,
not counting extra characters required to specify a single position.
>
ERRGEN TAG,< Missing Tag !12!
The tag !12! specified by an O command cannot be found.
This tag must be in the same macro level as the O command
referencing it.
>
ERRGEN TAL,< Two Arguments With L
The L command takes at most one numeric argument, namely, the
number of lines over which the buffer pointer is to be moved.
>
ERRGEN TSD,< Too Many Nested SFD'S
The number of Sub-File-Directories specified in
a path exceeds the number allowed by TECO10. If desired, the user
may re-assemble TECO10 with 'C$SFDL' equal to the desired
nesting level of SFD'S.
>
ERRGEN TTY,< Illegal TTY I/O Device
A teletype may be specified as an input/output device in an
ER, EW, EZ, or MAKE command only if it is not being used
to control an attached job, the user's own terminal.
>
ERRGEN UAT,< Unenabled APR Trap
An APR trap occurred which was not enabled. This
error should not occur. Please report it to your systems manager.
>
ERRGEN UCA,< Unterminated ^A Command
A ^A message type-out command has been given,
but there is no corresponding ^A to mark the end
of the message. ^A commands must be complete within a
single macro level.
>
ERRGEN UEN,< Unimplemented "EN" command
The EN command is not implemented, sorry.
>
ERRGEN UFS,< Macro Ending with Unterminated File Selection Command
The last command in the macro "18" is a file selection command
(ER, EW, EB, ED, EL, EI, EN, or EZ) with no delimiter to mark the
end of the file specification.
The file selection command must be complete within the Q-register.
>
ERRGEN UIN,< Unterminated Insert Command
An insert command (possibly an @ insert command) has been given
without terminating the text argument at the same macro level.
>
ERRGEN UQN,< Unterminated Q-Register Name (missing ) )
If a multi-character q-register name is specified, it must be
terminated by a right parenthesis. the format is:
<command>(<q-reg-name>)
>
ERRGEN USN,< Unknown Switch Name: /19
The switch "/19" is not defined with either input or output
file selection commands. The currently implemented switches are:
/PROTECT, /ASCII, /LSN, /NOIN, /NOOUT, /APPEND, /SIXBIT, /OCTAL,
/NONSTD, /GENLSN, and /SUPLSN.
>
ERRGEN USR,< Unterminated Search Command
A search command (possibly an @ search command) has been given
without terminating the text argument at the same macro level.
>
ERRGEN UTG,< Unterminated Tag
A command string tag has been indicated by a ! command,
but there is no corresponding ! to mark the end of the tag.
Tags must be complete within a single command level.
>
ERRGEN VAI,< Version incompatability
The current version of TECO10 may be incompatable with save files
written with the EE command with an old version of TECO10.
Re-compile all your macros and re-issue the EE command if possible.
If this is not possible, it may be possible to continue, but random
errors may occur.
>
ERRGEN XTB,< Attempt to execute the Text editing Buffer.
The Q-register 18 is currently sharing with the blank Q-register,
which is the Text-editing buffer. Do "HX18m18".
>
ERRGEN XXX,< Should Not Occur.
Please report this problem to your systems manager as soon as
possible. sorry for the inconvenience. try to close your files
if possible.
>
ERRGEN YCA,< "Y" or "_" command aborted due to non-empty buffer
The "Y" and "_" commands are only legal if the editing buffer is empty,
or if 2ED is set, or in a macro.
"EY" is the same command as "Y" but without this restriction.
"E_" is the same command as "_" but without this restriction.
>
; NOW, DEFINE THE INDEX TABLE
DEFINE %EGEN(CODE)<''CODE'',,E$$'CODE>
INFO. <DEFINE %TABLE>
ERRTAB: LSTOF.
%TABLE
LSTON.
ERRLEN==.-ERRTAB ; DEFINE LENGTH OF TABLE
>;; END FOR FTXTCERR
FOR FTXTEC,<
SUBTTL GXXXXX - Character Input Routines
; GFSPEC - SCAN A FILE SPECIFICATION AND STORE IN A FILE SPEC BLOCK
;
; SEE PARAMETER DEFINITIONS FOR FORMAT OF A FILE SPEC BLOCK
;
; CALL: MOVEI L,FILE.SPEC.BLOCK
; PUSHJ P,GFSPEC
; (RETURN)
;
; SMASHES ACS X,C,N,T1,T2,T3,T4
;GFSPEC: PUSH P,. ;[23000] No delmiter if entered here
; PUSHJ P,GFSPED ;[24000] So call other one
; POP P,(P) ;[24000] Fix up stack
; POPJ P, ;[24000] And return
; GFSPED - Same as GFSPEC except takes a delimiter on Stack
GFSPED: MOVX T4,FB$$IO ; FETCH IMAGE OF I/O FLAGS FOR FILE-SPEC
AND T4,FS$FLG(L) ; AND KEEP PREVIOUS I/O FLAGS
GFS0: PUSHJ P,GSIX ; PICK UP A SIXBIT NAME
JUMPE N,GFS1 ; NONE THERE
PUSHJ P,GCHR ; PICKUP CHAR AFTER SIXBIT NAME
CAIE C,":" ; IS NAME A DEVICE NAM?
JRST GFSNAM ; NO, IT'S A FILE NAME
; STORE DEVICE NAME
MOVEM N,FS$DEV(L) ; STORE THE DEVICE NAME IN SILE SPEC BLOCK
TXO T4,FB$DEV ; FLAG THAT DEVICE WAS SEEN
JRST GFS0 ; AND TRY FOR MORE OF FILE SPEC
; PICK UP NEXT CHAR
GFS1: PUSHJ P,GCHR ; PICKUP THE NEXT CHAR
; DISPATCH FOR SPECIAL FILESPEC DELIMITERS
GFS2: CAMN C,-1(P) ;[24000] Check delimiter
JRST GFS9 ;[23000] That's it, end of file spec
CAIN C,"." ; "."?
JRST GFSEXT ; YES, FILE EXTENSION FOLLOWS
CAIE C,.CHLAB ; LEFT ANGLE BRACKET?
CAIN C,"[" ; "["?
JRST GFSPTH ; YES, PATH FOLLOWS
CAIN C,"/" ; "/"?
JRST GFSSWI ; YES, SWITCH FOLLOWS
CAIE C,.CHSPC ; IS CHAR A BLANK?
CAIN C,.CHTAB ; OR A TAB?
JRST GFS1 ; YES, IGNORE IT
GFS9: MOVEM T4,FS$FLG(L) ; NO. STORE FILE SPEC FLAGS
POPJ P, ; AND RETURN TO CALLER
; STORE FILE NAME
GFSNAM: MOVEM N,FS$NAM(L) ; STORE THE FILE NAME IN SPEC BLOCK
TXO T4,FB$NAM ; FLAG THAT A FILE NAME WAS SEEN
JRST GFS2 ; AND CHECK THE DELIMITER CHAR
; STORE FILE EXTENSION
GFSEXT: PUSHJ P,GSIX ; SCAN THE FILE EXTENSION
MOVEM N,FS$EXT(L) ; AND STORE IT IN THE SPEC BLOCK
TXO T4,FB$EXT ; FLAG THAT A FILE EXT WAS SEEN
JRST GFS1 ; AND GO BACK FOR MORE
; STORE PATH: [-], [PJ,PG],[PJ,PG,SFD1,...,SFDN] (PJ AND/OR PG MAY BE NULL)
GFSPTH: TXO T4,FB$PTH ; FLAG THAT SOME SORT OF PATH SEEN
PUSHJ P,GCHR ; FETCH NEXT COMMAND CHAR
CAIE C,"-" ; "-"?
JRST GFSP3 ; NO
SETZM FS$PPN(L) ; YES, DEFAULT DIRECTORY IS ZERO PPN
TXO T4,FB$DDR ; FLAG THAT DEFAULT DIRECTORY SEEN
PUSHJ P,GCHR ; FETCH NEXT CHAR
GFSP2: CAIE C,.CHRAB ; NORMAL PATH TERMINATION?
CAIN C,"]" ; . . . ?
JRST GFS0 ; YES,
MOVEM C,INPCHR ; NO, DON'T LOSE THE CHAR
JRST GFS0 ; AND GO BACK FOR MORE OF FILE SPEC
GFSP3: CAIG C,"7" ; IS CHAR AN OCTAL DIGIT?
CAIGE C,"0" ; . . . ?
JRST GFSP4 ; NO
MOVEM C,INPCHR ; YES, REPEAT THE DIGIT
PUSHJ P,GOCT ; AND SCAN THE OCTAL PROJECT NUMBER
HRLM N,FS$PPN(L) ; STORE THE PROJECT NUMBER
TXO T4,FB$PRJ ; FLAG THAT PROJECT NUMBER SEEN
PUSHJ P,GCHR ; AND FETCH NEXT CHAR
GFSP4: CAIE C,"," ; IS IT A COMMA?
JRST [CAIE C,.CHRAB;[23000] Protection?
ERROR (IPP) ; NO, ** ILLEGAL PPN **
JRST SWPRO9] ;[23000] Yes, store it
PUSHJ P,GCHR ; YES, FETCH NEXT CHAR
CAIG C,"7" ; IS IT AN OCTAL DIGIT?
CAIGE C,"0" ; . . . ?
JRST GFSP5 ; NO
MOVEM C,INPCHR ; YES, REPEAT THE CHAR
PUSHJ P,GOCT ; AND SCAN THE PROGRAMMER NUMBER
HRRM N,FS$PPN(L) ; AND STORE THE PROGRAMMER NUMBER
TXO T4,FB$PRG ; FLAG THAT PROGRAMMER NUMBER WAS SEEN
PUSHJ P,GCHR ; FETCH THE NEXT CHAR
GFSP5: CAIE C,"," ; IS IT A ","?
JRST GFSP2 ; NO
; SFD'S
IFE C$SFDL,<ERROR (TSD)> ; SFD'S NOT ALLOWED
IFN C$SFDL,<
TXO T4,FB$SFD ; FLAG THAT SFDS SEEN
MOVE T3,[XWD -C$SFDL,FS$SFD] ; FETCH AOBJN POINTER FOR SFD'S
ADDI T3,(L) ; POINTS INTO FILE.SPEC BLOCK
GFSSFD: PUSHJ P,GSIX ; PICK UP AN SFD NAME
MOVEM N,(T3) ; AND STORE IN FILE SPEC BLOCK
PUSHJ P,GCHR ; FETCH THE DELIMITER
CAIE C,"," ; MORE SFD'S TO COME?
JRST GFSP2 ; NO
AOBJN T3,GFSSFD ; YES
ERROR (TSD) ; ** TOO MANY NESTED SFD'S **
>;; END IFN C$SFDL
; SWITCHES
GFSSWI: PUSHJ P,GSIX ; PICK UP THE SWITCH NAME
JUMPE N,[ERROR (NSI)] ; ** NULL SWITCH ILLEGAL **
PUSH P,L ; SAVE AC L
MOVE L,[IOWD SWILTH,SWITBL+1] ; FETCH PTR TO SWITCH TABLE
PUSHJ P,MATCH ; AND LOOKUP THE SWITCH NAME
ERROR (USN) ; ** UNKNOWN SWITCH NAME **
ERROR (ASN) ; ** AMBIGUOUS SWITCH NAME **
MOVE X,SWILTH(L) ; FETCH DISPATCH ADR
POP P,L ; RESTORE AC L
JRST (X) ; AND DISPATCH TO THE SWITCH HANDLER
DEFINE SWI
< PAIR PROTEC,SWPRO
PAIR EXECUT,SWEXE
PAIR LSN,SWLSN
PAIR ASCII,SWASC
PAIR SIXBIT,SWSIX
PAIR OCTAL,SWOCT
PAIR GENLSN,SWGEN
PAIR SUPLSN,SWSUP
PAIR APPEND,SWAPP ;;[330] /APPEND
PAIR NOOUT,SWNOO ;;[330] /NOOUT
PAIR NOIN,SWNOI ;;[330] /NOIN
PAIR NONSTD,SWNON ;;[334] /NONSTD
PAIR DELETE,SWDEL ;[15000] /DELETE (for temp files & TMPCOR)
PAIR SUPERS,SWDEL ;[20000] /SUPERCEDE for E% & EW
PAIR INPLAC,SWDEL ;[23000] /INPLACE (for EB)
PAIR BINARY,SWOCT ;[23000] /BINARY (no zap nulls)
>
GEN (SWI) ; GENERATE THE SWITCH TABLE
; SWPRO - /PROTECT:<NNN> - FILE PROTECTION
SWPRO: PUSHJ P,GCHR ; MAKE SURE A COLON FOLLOWS
CAIE C,":" ; DOES ONE?
ERROR (ISW) ; NO, ** ILLEGAL SWITCH **
PUSHJ P,GCHR ; YES, FETCH NEXT CHAR
CAIN C,.CHLAB ; LEFT ANGLE BRACKET?
PUSHJ P,GCHR ; YES, IGNORE IT
CAIG C,"7" ; AN OCTAL DIGIT?
CAIGE C,"0" ; . . . ?
ERROR (IPR) ; NO, ** ILLEGAL PROTECTION **
MOVEM C,INPCHR ; YES, REPEAT THE DIGIT
PUSHJ P,GOCT ; AND PICK UP THE WHOLE OCTAL NUMBER
PUSHJ P,GCHR ; FETCH NEXT CHAR
SWPRO9: LSH N,^D27 ; PUT NUMBER IN FILE PROTECTION FIELD
MOVEM N,FS$PRV(L) ; AND STORE IN FILE SPEC
TXO T4,FB$PRV ; FLAG THAT /PROTECT:<NNN> SEEN
CAIE C,.CHRAB ; IS IT RIGH-ANGLE-BRACKET?
MOVEM C,INPCHR ; NO, REPEAT THE CHAR
JRST GFS0 ; AND GO BACK FOR MORE OF FILE SPEC
; SWEXE - /EXECUTE - FORCES AN "EI" ON FILE
SWEXE: TXOA T4,FB$EXE ; SET THE "/EXECUTE" FLAG
; SWLSN - /LSN - KEEP LINE-SEQUENCE NUMBERS IF A FILE HAS THEM
SWLSN: TXO T4,FB$LSN ; SET /LSN
JRST GFS0 ; AND CONTINUE FILE-SPEC SCAN
; SWASC - /ASCII - DON'T CHECK FOR LINE-SEQUENCE-NUMBERS
SWASC: TXOA T4,FB$ASC ; SET /ASCII
; SWSIX - /SIXBIT - FILE IS IN SIXBIT FORMAT
SWSIX: TXO T4,FB$SIX ; SET /SIXBIT
JRST GFS0 ; AND CONTINUE FILE-SPEC SCAN
; SWOCT - /OCTAL - FILE IS A BINARY FILE
SWOCT: TXOA T4,FB$OCT ; SET /OCTAL
; SWGEN - /GENLSN - GENERATE LINE-SEQUENCE NUMBERS ON OUTPUT
SWGEN: TXO T4,FB$GEN ; SET /GENLSN
JRST GFS0 ; AND CONTINUE FILE-SPEC SCAN
; SWSUP - /SUPLSN - SUPPRESS LINE-SEQUENCE-NUMBERS ON INPUT
SWSUP: TXOA T4,FB$SUP ; SET /SUPLSN
; SWAPP - /APPEND - APPEND THIS LOG TO LOG FILE
SWAPP: TXO T4,FB$APP ;[330] SET /APPEND
JRST GFS0 ;[330] AND CONTINUE FILE-SPEC SCAN
; SWNOO - /NOOUT - DO NOT GENERATE OUTPUT
SWNOO: TXOA T4,FB$NOO ;[330] SET /NOOUT
; SWNOI - /NOIN - DO NOT GENERATE INPUT
SWNOI: TXO T4,FB$NOI ;[330] SET /NOIN
JRST GFS0 ;[330] AND CONTINUE FILE-SPEC SCAN
; SWDEL - /DELETE - DELETE (TMPCOR FILE) AFTER READING
SWDEL: TXOA T4,FB$DEL ;[15000]
; SWNON - /NONSTD - OPEN DECTAPE IN NON STANDARD MODE
SWNON: TXO T4,FB$NON ;[334] SET /NONSTD
JRST GFS0 ;[334] AND CONTINUE FILE-SPEC SCAN
; GSIX - GET A SIXBIT NAME
;
; CALL: PUSHJ P,GSIX
; (RETURN) ; WITH NAME IN AC N, MASK IN AC M
;
; USES ACS C,N,M,T1,T2,T3
GSIX: MOVE T1,[POINT 6,N] ; SETUP BP TO NAME
SETZB N,M ; CLEAR NAME AND MASK
MOVSI T2,'_ ' ; SETUP THE MASKING WORD
PUSHJ P,GCHR ; FETCH FIRST CHAR
CAIN C,"*" ; IS IT "*"?
JRST GSIX2 ; YES, HANDLE SPECIALLY
CAIE C,"""" ; A QUOTED SIXBIT NAME?
CAIN C,"'" ; . . . ?
JRST GSIX3 ; YES
SKP ; NO
GSIX1: PUSHJ P,GCHR ; FETCH NEXT CHAR
PUSHJ P,CHKSCB ;[10000] IS IT A LETTER/DIGIT? or &_%$
JRST RPOPJ ; NO, REPEAT IT AND RETURN TO CALLER
MOVEI C,'A'-"A"(C) ; YES, CONVERT THE CHAR TO SIXBIT
TRNN N,'_' ; ROOM FOR ANOTHER CHAR IN NAME?
IDPB C,T1 ; YES, STORE THE CHAR IN NAME
IOR M,T2 ; AND MASK THE CHAR
LSH T2,-6 ; SHIFT THE MASKING WORD
JRST GSIX1 ; AND TRY FOR ANOTHER CHAR
; '*' IS A SPECIAL NAME (IE: 'ALL')
GSIX2: SETZ M, ; CLEAR THE MASK
MOVSI N,'* ' ; SET NAME TO '* '
POPJ P, ; AND RETURN TO CALLER
; SCAN A QUOTED SIXBIT NAME
GSIX3: MOVEI T3,(C) ; SAVE THE DELIMITER CHAR
GSIX4: PUSHJ P,GCHR ; PICK UP THE NEXT CHAR
CAIE C,(T3) ; IS IT THE DELIMITER?
JRST GSIX5 ; NO
PUSHJ P,GCHR ; YES, PICK UP THE NEXT CHAR
CAIE C,(T3) ; TWO OCCURRANCES OF THE DELIMITER?
JRST RPOPJ ; NO, FINISH UP AND RETURN TO CALLER
GSIX5: CAIL C,140 ;[14000] In LC range?
MOVEI C,-40(C) ;[14000] Yes, but not any more
MOVEI C,'A'-"A"(C) ; CONVERT CHAR TO SIXBIT
TRNN N,'_' ; ROOM IN NAME FOR CHAR?
IDPB C,T1 ; YES, STORE CHAR IN NAME
IOR M,T2 ; FILL IN MASK FOR CURRENT POSITION
LSH T2,-6 ; AND SHIFT IT TO NEXT POSITION
JRST GSIX4 ; AND TRY FOR ANOTHER CHAR
RPOPJ: MOVEM C,INPCHR ; STORE THE CHAR SO IT REPEATS NEXT TIME
POPJ P, ; AND RETURN TO CALLER
; GOCT - GET AN OCTAL NUMBER
;
; CALL: PUSHJ P,GOCT
; (RETURN) ; WITH OCTAL NUMBER IN AC N
;
; SMASHES ACS X,C,N
GOCT: SETZ N, ; CLEAR NUMBER
GOCT0: PUSHJ P,GETCH ; FETCH NEXT CHAR
CAIG C,"7" ; IS CHAR AN OCTAL DIGIT?
CAIGE C,"0" ; . . . ?
JRST RPOPJ ; NO, REPEAT THE CHAR AND RETURN TO CALLER
LSH N,3 ; MAKE ROOM FOR THE OCTAL DIGIT
IORI N,-"0"(C) ; AND ADD IN THE OCTAL DIGIT
JRST GOCT0 ; AND CONTINUE
; GEOL - EAT CHARS TILL END OF LINE SEEN
;
; CALL: PUSHJ P,GEOL
; (RETURN)
;
; USES AC C
GEOL: SETZM INPCHR ;[315] CLEAR SAVED CHAR
TXZE F,F$EOL ; END OF LINE YET?
POPJ P, ; YES, CLEAR AND RETURN TO CALLER
PUSHJ P,GCHR ; NO, FETCH NEXT CHAR
JRST GEOL ; AND SEE IF END OF LINE YET
; GCHR - GET NEXT CHAR AND CHECK IF END OF LINE
;
; CALL: PUSHJ P,GCHR
; (RETURN) ; WITH CHAR IN AC C
;
; USES AC C
GCHR: PUSHJ P,GETCH ; FETCH NEXT INPUT CHAR
CAIN C,.CHCNZ ; A CONTROL-Z?
TXO F,F$EOL ; YES, SET END OF LINE
CAIE C,.CHESC ; ALTMODE?
CAIG C,.CHFFD ; <LF>,<VT>,OR <FF>?
CAIGE C,.CHLFD ; . . . ?
POPJ P, ; NO, JUST RETURN TO CALLER
TXO F,F$EOL ; YES, SET EOL
POPJ P, ; AND RETURN TO CALLER
>;; END FOR FTXTEC
FOR FTXTEC!FTXTCERR,<
; GETCHL - GET NEXT INPUT CHARACTER FROM CURRENT INPUT SOURCE
; (IN LINE MODE [12000])
;
; CALL: PUSHJ P,GETCHL
; (RETURN) ; WITH CHAR IN AC C
;
; USES AC C and X
GETCHL:
IFE TOPS20,<
SKIPE C,INPCHR ; REPEAT THE LAST CHAR?
JRST GETCHF ; YES
SKIPE C,INPADR ; ADR OF AN INPUT ROUTINE?
PJRST (C) ; YES, GO TO IT
TXNE F,F$NTI ; INPUT FROM USER'S TERMINAL?
JRST GETCH2 ; NO, FROM SOMEWHERE ELSE
; INPUT A CHAR FROM USER'S TERMINAL IN LINE MODE
SKIPE TTOBUF ;[12000] Check for pending TTY output
PUSHJ P,FOUT ;[12000] Force it out now
GETCLW: INCHWL C ; INPUT A CHAR INTO AC C
JRST CKLOGI ;[12000] See if log file in use
>;END IFE TOPS20
; GETCH - GET NEXT INPUT CHARACTER FROM CURRENT INPUT SOURCE
;
; CALL: PUSHJ P,GETCH
; (RETURN) ; WITH CHAR IN AC C
;
; USES AC C and X
GETCH: SKIPN C,INPCHR ; REPEAT THE LAST CHAR?
JRST GETCH0 ; NO
GETCHF:!SETZM INPCHR ; YES, CLEAR THE SAVED CHAR
POPJ P, ; AND RETURN TO CALLER WITH THE LAST CHAR
GETCH0: SKIPE C,INPADR ; ADR OF AN INPUT ROUTINE?
PJRST (C) ; YES, GO TO IT
TXNE F,F$NTI ; INPUT FROM USER'S TERMINAL?
JRST GETCH2 ; NO, FROM SOMEWHERE ELSE
; INPUT A CHAR FROM USER'S TERMINAL
SKIPE TTOBUF ;[12000] Check for pending TTY output
PUSHJ P,FOUT ;[12000] Force it out
GETCHW: INCHRW C ; INPUT A CHAR INTO AC C
; PUNCH CHAR TO LOG FILE IF I SAID SO
CKLOGI: TXNN F,F$LOG ;[330] DID I SAY SO?
JRST NOLOGI ;[330] NO LOG INPUT
MOVE X,LELSPC+FS$FLG ;[330] GET LOG FLAGS
TXNE X,FB$NOO ;[330] AM I ALLOWED TO RECORD INPUT?
PUSHJ P,LOGPH1 ;[330] RECORD INPUT
; IF CHAR IS ^D, THEN ENTER DDT
NOLOGI: SKIPE .JBDDT ; DO WE HAVE DDT?
CAIE C,.CHCND ; AND IS CHAR A ^D?
POPJ P, ; NO, JUST RETURN WITH THE CHAR
MOVE C,.JBDDT ; FETCH DDT START ADR
GODDT:: PUSHJ P,(C) ; PUSHJ TO DDT
JRST GETCH ; BACK FROM DDT. INPUT ANOTHER CHAR
; INPUT A CHAR. NOT FROM USER'S TERMINAL
GETCH2: MOVE X,INPBH ; FETCH ADR OF INPUT BUFFER HEADER
GETCH3: SOSGE .BFCTR(X) ; ANY CHARS LEFT IN BUFFER?
JRST GETCH4 ; NO
ILDB C,.BFPTR(X) ; YES, FETCH NEXT ONE
JUMPE C,GETCH3 ; IGNORE NULLS
POPJ P, ; RETURN WITH CHAR
; FETCH NEW INPUT BUFFER
GETCH4: MOVSI X,(IN) ; SETUP THE IN OPCODE
IOR X,INPCHN ; "OR" IN THE CHANNEL
XCT X ; DO THE "IN"
JRST GETCH2 ; AND GET CHAR FROM BUFFER
MOVE X,[STATO 0,IO.EOF] ; FAILED. SEE WHAT HAPPENED
IOR X,INPCHN ; FILL IN THE CHANNEL
XCT X ; DO THE "STATO CH,IO.EOF"
JRST @INPERR ; SOME RANDOM INPUT ERROR
PUSHJ P,@INPEOF ; END OF FILE
POPJ P, ; RETURN TO CALLER AFTER EOF
SUBTTL LOGPCH - PUNCH A CHARACTER TO LOG FILE
; LOGPCH - PUNCH A CHARACTER TO LOG FILE
LOGPCH: SOSGE LOGBH+2 ;[330] ROOM IN LOG BUFFER?
JRST LOGP1 ;[330] NO
IDPB C,LOGBH+1 ;[330] YES, STORE CHARACTER IN LOG BUFFER
POPJ P, ;[330] AND RETURN TO CALLER
; ASK MONITOR FOR A NEW LOG BUFFER
LOGP1: OUT LOG, ;[330] OUTPUT TO LOG
JRST LOGPCH ;[330] AND CONTINUE
for ftxtec,ERROR (OWL) ;[330] ** OUTPUT ERROR WRITING LOG **
for ftxtcerr,<
outstr e$$owl ;[326] no endless loops
jrst logpch ;[326] continue
>;; end for ftxtcerr
for ftxtec!ftxtcerr,sall ; restore listing
; LOGPH1 - PUNCH AN INPUT CHARACTER TO LOG FILE
LOGPH1: TXNN X,FB$NOI ;[330] /NOOUT SET?
PJRST LOGPCH ;[330] YES, PUNCH LITERALLY
PUSH P,C ;[330] SAVE CHAR
CAIN C,.CHESC ;[330] ALTMODE?
MOVEI C,"$" ;[330] MAKE "$"
CAIG C,.CHCNH ;[330] .LE.^H ?
JRST LOGPH2 ;[330] YES, ^ FORM
CAIL C,.CHCNN ;[330] .LT.^N ?
CAILE C,.CHCUN ;[330] .LE.^_ ?
JRST LOGPH3 ;[330] NOT AN ^ CHAR
LOGPH2: IORI C,"@" ;[330] MAKE PRINTABLE ASCII
PUSH P,C ;[330] SAVE IT
MOVEI C,"^" ;[330] FETCH UPARROW
PUSHJ P,LOGPCH ;[330] PUNCH IT
POP P,C ;[330] GET CHAR BACK
LOGPH3: PUSHJ P,LOGPCH ;[330] PUNCH WHATEVER
POP P,C ;[330] GET WHAT IT WAS ORIGINALLY
POPJ P, ;[330] RETURN
SUBTTL CMDGCH AND CMDBCH - Get char from command buffer
; CMDGCH - FETCH NEXT CHAR FROM COMMAND BUFFER
;
; CALL: PUSHJ P,CMDGCH
; (FAIL RETURN) ; NO CHARS LEFT IN BUFFER
; (SUCCESS RETURN) ; CHAR IS IN AC C
;
; USES ACS C,X
CMDGCH: SOSGE CMDCNT ; ANY CHARS LEFT?
POPJ P, ; NO, GIVE FAIL RETURN
MOVE X,R ; SAVE AC R
MOVE R,@CMDBUF ; YES, FETCH BASE ADR OF COMMAND BUFFER
ILDB C,CMDBP ; AND FETCH NEXT CHAR FROM BUFFER
MOVE R,X ; RESTORE AC R
;[16000]JUMPE C,CMDGCH ; IGNORING NULLS
JRST CPOPJ1 ; RETURN TO CALLER WITH CHAR IN AC C
; CMDBCH - BACK UP ONE CHAR FOR COMMAND BUFFER
;
; CALL: PUSHJ P,CMDBCH
; (RETURN)
;
; USES AC X
CMDBCH: AOS CMDCNT ; ADD ONE TO THE CHAR COUNT
MOVE X,CMDBP ; FETCH THE BP
ADD X,[<7>B5] ; BACKUP THE BP
JUMPG X,.+3 ; IT'S OK
HRRI X,-1(X) ; GO BACK A FULL WORD
HRLI X,(POINT 7,(CP),34) ; TO LAST BYTE IN PREVIOUS WORD
MOVEM X,CMDBP ; STORE THE UPDATED BP
POPJ P, ; AND RETURN TO CALLER
SUBTTL TXXXXX - OUTPUT ROUTINES
; TSIX - TYPE A SIXBIT WORD (NO TRAILING SPACES)
;
; CALL IS: PUSHJ P,TSIX ; WITH SIXBIT WORD IN AC N
; (RETURN)
;
; ACS C,N ARE SMASHED
TSIX: JUMPE N,CPOPJ ; RETURN IF ONLY BLANKS LEFT
SETZ C, ; CLEAR THE CHAR
LSHC C,6 ; GRAB NEXT CHAR (SIXBIT)
MOVEI C,"A"-'A'(C) ; CONVERT TO ASCII CHAR
PUSHJ P,TCHR ; TYPE THE CHAR
JRST TSIX ; AND LOOP BACK FOR NEXT CHAR
; TOCT AND TDEC - OUTPUT AN OCTAL/DECIMAL NUMBER WITH POSSIBEL "-" SIGN
;
; CALL IS: PUSHJ P,TOCT ; OR PUSHJ P,TDEC
; (ONLY RETURN)
; NUMBER SHOULD BE IN AC N
; ACS C,N,X AND M ARE SMASHED
TOCT:
;[14000] SKIPA X,[^D8] ; FETCH OCTAL RADIX
TOCT0: SETZ C, ;[14000] Start fresh
ROTC C,-3 ;[14000] Get 1 digit worth in reverse order
LSH C,-41 ;[14000] right justify
MOVEI C,"0"(C) ;[14000] Make digit
HRLM C,(P) ;[14000] Save on stack (instead of flags)
JUMPE N,.+2 ;[14000] Supress leading zeroes
PUSHJ P,TOCT0 ;[14000] Call ourself recursively
HLRZ C,(P) ;[14000] Get a digit
JRST TCHR ;[14000] Type it out
TDEC: MOVEI X,^D10 ; FETCH DECIMAL RADIX
JUMPGE N,TDEC0 ; NO "-" SIGN NEEDED
;[1000] FIX LOGFILE CODE BASHING RADIX
MOVE M,X ;[1000]SAVE RADIX
MOVEI C,"-" ; "-" SIGN NEEDED
PUSHJ P,TCHR ; TYPE THE "-" SIGN
MOVM N,N ; AND TAKE ABSOLUTE VALUE OF NUMBER
MOVE X,M ;[1000] RESTORE RADIX
TDEC0: IDIVI N,(X) ; EXTRACT A DIGIT INTO AC M
HRLM M,(P) ; SAVE THE DIGIT
JUMPE N,.+2 ; SKIP IF NO MORE DIGITS
PUSHJ P,TDEC0 ; MORE DIGITS, EXTRACT THEM
; POP DIGITS OFF STACK IN THE ORDER THEY ARE TO BE OUTPUT
HLRZ C,(P) ; POP DIGIT OFF STACK
MOVEI C,"0"(C) ; TURN DIGIT INTO A CHAR
PJRST TCHR ; OUTPUT THE DIGIT AND ALL THAT FOLLOW
; TMSG - TYPE PART THE THE COMMAND BUFFER
;
; CALL: MOVE N,[<CHAR.ADR,,CHAR.LEN>]
; PUSHJ P,TMSG
; (RETURN)
;
; SMASHES ACS N,T1,T2,X
TMSG: HLRZ T1,N ; FETCH CHAR.ADR
MOVEI T1,-1(T1) ; 'CAUSE BYTE POINTER WILL BE INCREMENTED BEFORE USE
PUSHJ P,CTOBP ; CONVERT CHAR.ADR TO BYTE POINTER
IORX T1,<Z (R)> ; EVERYTHING IS INDEXED BY R
MOVEI N,(N) ; KEEP ONLY THE CHAR COUNT
TMSG1: JUMPLE N,FOUT ; IF DONE, RETURN TO CALLER
TXNE F,F$REE ;[10000] REEnter done?
PJRST FOUT ;[16000] yes shaddup & force it out
ILDB C,T1 ; FETCH NEXT CHAR OF MESSAGE
PUSHJ P,TCCHR ; AND TYPE IT
SOJA N,TMSG1 ; AND TRY AGAIN
; TTOPEN - Open the TTY so we can do echo control
TTOPEN:
IFN TOPS10,<
OPEN TTYC,[EXP IO.LEM ;[11000]
SIXBIT 'TTY' ;[11000]
Z] ;[11000]
OPEN TTYC,[EXP 0, ;[12000] to avoid...
SIXBIT 'NUL' ;[12000] I/O to unassigned ...
Z] ;[12000] ...channel
JFCL
SETO X, ;[12000] Get our line #
TRMNO. X, ;[12000] from the system
JRST TTYODT ;[21000] It's detached
>
FOR TOPS20,<
PUSHJ P,SAVE5 ;[21000] Save AC's that will get clobbered
MOVX T1,.FHSLF ;[21000] Our process
GPJFN ;[21000] Make sure primary output is TTY
MOVEI T2,(T2) ;[21000] Output is in right half
CAIE T2,.CTTRM ;[21000] Is it?
JRST [MOVE X,T2 ;[21000] no. leave it alone
JRST TTYOPX] ;[21000] in the right AC
GJINF ;[21000] Yes, so stuff real terminal in
SKIPG X,T4 ;[21000] or -1 if detached
JRST TTYODT ;[21000] remember that we are detached
TXO X,.TTDES ;[21000] Make it a real TTY designator
TTYOPX:>
MOVEM X,OURTTY ;[12000] Remember its number
MOVE X,[POINT 7,TTOBUF] ;[12000] Set up byte pointer
MOVEM X,TTOPTR ;[12000] for terminal output
;Find out terminal width & length
FOR TOPS10,<
MOVEI X,.TOPSZ ;[13000] Length
MOVEM X,TOOFUN ;
MOVE X,[2,,TOOFUN] ;[13000] Addr,,len for UUO
TRMOP. X,
>
MOVEI X,^D24 ;[13000] safe guess
MOVEM X,LENGTH
FOR TOPS10,<
MOVEI X,.TOWID ;[13000] Width
MOVEM X,TOOFUN ;
MOVE X,[2,,TOOFUN] ;[13000] Addr,,len for UUO
TRMOP. X,
>
MOVEI X,^D80
MOVEM X,WIDTH ;[13000] Save it away
MOVEI X,.TOOUS ;[12000] Function code for TRMOP.
MOVEM X,TOOFUN ;[12000] (equivalent to OUTSTR)
MOVEI X,TTOBUF ;[12000] Set up argument also
MOVEM X,TOOADR ;[12000] address of output
POPJ P,
TTYODT: MOVX X,ET$DET ;[12000] Set detached flag
IORM X,ETVAL ;[12000]
POPJ P, ;[12000]
>; END FOR FTXTEC!FTXTCERR
FOR FTXTCERR,<
; TSSTR - TYPE AN ASCIZ STRING WITH SPECIAL CHARS (EG: <TAB>)
;
; CALL: MOVEI N,[ASCIZ/STR/
; PUSHJ P,TSSTR
; (RETURN)
;
; SMASHES AC C. AC N WILL POINT TO LAST WORD OF STRING
TSSTR: HRLI N,(POINT 7,) ; FORM BYTE POINTER TO ASCIZ STRING
TSSTR0: ILDB C,N ; FETCH NEXT CHAR OF STRING
JUMPE C,CPOPJ ; RETURN IF A NULL
PUSHJ P,TSCHR ; TYPE CHAR
JRST TSSTR0 ; AND TRY FOR ANOTHER CHAR
; TSCHR - TYPE A CHAR. IF SPECIAL, TYPE AS <XXX> (EG: <TAB>)
;
; CALL: MOVEI C,"CHAR"
; PUSHJ P,TSCHR
; (RETURN)
;
; SMASHES AC X,C,T1. USES AC N
TSCHR: MOVE T1,[IOWD SCHTL,SCHT+1] ; FETCH POINTER TO SPECIAL CHAR TABLE
TSCHR0: HRRZ X,(T1) ; FETCH A CHAR FROM SPECIAL CHAR TABLE
CAIN C,(X) ; SAME AS OUR CHAR?
JRST TSCHR1 ; YES
AOBJN T1,TSCHR0 ; NO, TRY ANOTHER CHAR IN TABLE
PJRST TCCHR ; NONE LEFT. TYPE AS A NORMAL CHAR
; TYPE A SPECIAL CHAR AS <XXX> (EG: .CHTAB AS <TAB>)
TSCHR1: PUSH P,T1 ; SAVE T1 FOR LATER
MOVEI C,.CHLAB ; TYPE A LEFT WIDGET
PUSHJ P,TCHR ; . . .
POP P,T1 ; RESTORE AC T1
PUSH P,N ; SAVE AC N
HLLZ N,(T1) ; FETCH "XXX" OF <XXX>
PUSHJ P,TSIX ; AND TYPE IT IN SIXBIT
POP P,N ; RESTORE AC N
MOVEI C,.CHRAB ; AND TYPE RIGHT WIDGET
PJRST TCHR ; . . . AND RETURN TO CALLER
; SCHT - SPECIAL CHARACTER TABLE
DEFINE SCH (NAME,CODE)<<<SIXBIT/NAME/>_-^D18,,CODE>>
SCHT:
SCH(TAB,.CHTAB)
SCH(LF,.CHLFD)
SCH(VT,.CHVTB)
SCH(FF,.CHFFD)
SCH(CR,.CHCRT)
SCH(ESC,.CHESC)
SCHTL==.-SCHT
; TFSPEC - TYPE A COMPLETE FILE-SPEC IN FORM: DEV:FILE.EXT[PATH]
;
; CALL: MOVEI L,FILSPC
; PUSHJ P,TFSPEC
; (RETURN)
;
; SMASHES ACS X,C,N,M
TFSPEC: PUSHJ P,TDEV ; TYPE "DEV:"
PUSHJ P,TFILE ; TYPE "FILE.EXT"
PJRST TPATH ; TYPE "[PATH]"
; TDEV - TYPE A DEVICE NAME IN FORM: DEV:
;
; CALL: MOVEI L,FILSPC
; PUSHJ P,TDEV
; (RETURN)
;
; SMASHES ACS C,N
TDEV: MOVE N,FS$DEV(L) ; FETCH THE DEVICE NAME
PUSHJ P,TSIX ; AND TYPE IT
MOVEI C,":" ; FETCHA ":"
PJRST TCHR ; AND TYPE IT
; TFILE - TYPE A FILE-NAME AND EXTENSION IN FORM: FILE.EXT
;
; CALL: MOVEI L,FILSPC
; PUSHJ P,TFILE
; (RETURN)
;
; SMASHES ACS C,N
TFILE: MOVE N,FS$NAM(L) ; FETCH THE FILE-NAME
PUSHJ P,TSIX ; AND TYPE IT
MOVEI C,"." ; TYPE A "."
PUSHJ P,TCHR ; . . .
MOVE N,FS$EXT(L) ; FETCH THE EXTENSION
PJRST TSIX ; TYPE IT AND RETURN TO CALLER
; TPROT - TYPE FILE PROTECTION IN FORMAT: <NNN>
;
; CALL: MOVEI L,FILSPC
; PUSHJ P,TPROT
; (RETURN)
;
; SMASHES ACS C,N,M
TPROT: MOVEI C,.CHLAB ; TYPE LEFT WIDGET
MOVE N,FS$PRV(L) ; FETCH FILE PROTECTION
MOVEI C,"0" ; FETCH A ZERO
CAIL N,^D100 ; A THREE DIGIT NUMBER?
PUSHJ P,TCHR ; NO, ADD A LEADING ZERO
CAIL N,^D10 ; A TWO DIGIT NUMBER?
PUSHJ P,TCHR ; NO, ADD ANOTHER LEADING ZERO
PUSHJ P,TDEC ; TYPE THE FILE-PROTECTION
MOVEI C,.CHRAB ; AND TYPE A RIGHT WIDGET
PJRST TCHR ; AND RETURN TO CALLER
; TPATH - TYPE A PATH IN FORM: [-] OR [N,N] OR [N,N,SFD,...]
;
; CALL: MOVEI L,FILSPC
; PUSHJ P,TPATH
; (RETURN)
;
; SMASHES ACS C,N,M
TPATH: MOVEI C,"[" ; TYPE LEADING DELIMITER
PUSHJ P,TCHR ; . . .
MOVE X,FS$FLG(L) ; FETCH FILE-SPEC FLAGS
TXNN X,FB$DDR ; DEFAULT DIRECTORY?
JRST TPATH2 ; NO
MOVEI C,"-" ; YES, TYPE AS [-]
PUSHJ P,TCHR ; . . .
TPATH1: MOVEI C,"]" ; TYPE CLOSING DELIMITER
PJRST TCHR ; AND RETURN TO CALLER
TPATH2: HLRZ N,FS$PPN(L) ; FETCH PROJECT NUMBER
JUMPE N,.+2 ; DON'T PRINT IF ZERO
PUSHJ P,TOCT ; TYPE PROJECT NUMBER IN OCTAL
MOVEI C,"," ; TYPE A ","
PUSHJ P,TCHR ; . . .
HRRZ N,FS$PPN(L) ; FETCH THE PROGRAMMER NUMBER
JUMPE N,.+2 ; DON'T PRINT IF ZERO
PUSHJ P,TOCT ; TYPE PROGRAMMER NUMBER IN OCTAL
;[3000] ADD CODE TO PRINT SFD
MOVEI T1,FS$SFD(L) ;[3000] T1 POINTS TO START OF SFD'S
TPATH3: SKIPN N,(T1) ;[3000] FETCH NEXT ONE AND SKIP
JRST TPATH1 ;[3000] NO MORE
MOVEI C,"," ;[3000] SEPARATE WITH COMMAS
PUSHJ P,TCHR ;[3000]
PUSHJ P,TSIX ;[3000] TYPE THE SFD NAME
AOJA T1,TPATH3 ;[3000] BACK FOR MORE
>;; END FOR FTXTCERR
FOR FTXTEC!FTXTCERR,<
; TCCHR - OUTPUT A CHAR, ALTMODE AS "$", CONTROL CHARS AS "^"CHAR UNLESS ET.NE.0
; ^I,^J,^K,^L,^M OUTPUT AS THEMSELVES CASE FLAGGING UNLESS F$NOF
;
; CALL IS: PUSHJ P,TCCHR ; WITH CHAR IN AC C
; (ONLY RETURN)
;
; AC C IS SMASHED
TCCHR: MOVE X,ETVAL ;[6000] CHECK ONLY LAST BIT
TRNE X,ET$EXT ;[6000]
PJRST TCHR ; YES, NO SUBSTITUTIONS FOR NON-PRINTING CHARS
TPCHR: ;[5000] ENTER HERE TO ALWAYS PRETTYPRINT
CAIE C,.CHESC ; AN ALTMODE?
JRST TCC0 ; NO
; OUTPUT AN ALTMODE AS "$"
MOVEI C,"$" ; FETCH A "$"
PJRST TCHR ; AND OUTPUT IT
TCC0: TXNE F,F$NOF ; SUPPRESS CASE FLAGGING?
JRST TCC3 ; YES
PUSH P,C ; NO. SAVE CHAR
CAIG C,"_" ; IS IT A UC LETTER?
CAIGE C,"A" ; . . . ?
JRST TCC2 ; NO
; FLAG UC LETTER IF EU:=+
SKIPG EUVAL ; FLAG UC LETTERS?
JRST TCC11 ; NO
TCC1: MOVEI C,"'" ; YES, FLAG WITH "'"
PUSHJ P,TCHR ; TYPE THE "'"
TCC11: POP P,C ; RESTORE THE ORIGINAL CHAR
JRST TCC3 ; TYPE IT AND RETURN TO CALLER
TCC2: CAIG C,"_"+40 ; IS CHAR AN UC LETTER?
CAIGE C,"A"+40 ; . . . ?
JRST TCC11 ; NO
SKIPN EUVAL ; YES, FLAG IT?
JRST TCC1 ; YES
JRST TCC11 ; DON'T FLAG IT
TCC3: CAIN C,14 ;[10000]Form Feed special handling
JRST [;MOVE X,ETVAL ;[10000]
TXNE X,ET$DPY ;[10000] TUBE
JRST TCC4 ;[10000]
JRST TCHR] ;[12000] Type as is (more or less)
SKIPE EOL ;Anything special at end of line?
JRST [CAIN C,15 ;If so,
POPJ P, ; ... then ignore <CR>
CAIE C,12 ;and do special stuff to <LF>
JRST .+1 ; (which this wasn't)
PUSH P,N ; Don't clobber N
MOVEI N,EOL ;Get it,
PUSHJ P,TXSTR ;Type it,
POP P,N ; restore N
SETZM COL ;should be at left margin now
AOS ROW ;of next line
PUSHJ P,UPDCRO ;adjust things if it scrolled
MOVEI C,12 ;get back C (we knew what it was, anyway)
POPJ P,] ;and return
CAIN C,.CHTAB ;[13000] Is this a TAB?
JRST [SKIPN TTAB ;[13000] anything to type in its place?
JRST .+1 ;[13000] no, really type a TAB
PUSH P,N ;[13000]
MOVEI N,TTAB ;[13000] Type this string instead
PUSHJ P,T0XSTR ;[13000] ...
PUSHJ P,TABSTP ;[21000] Find next tab stop
PUSH P,X ;[21000] And save it
TCCT0: AOS N,COL ;[13000] Always increment column by 1 at least
JUMPL N,.+2 ;[25000] Don't screw us if we're lost
CAML N,(P) ;[21000] Did we get there yet?
JRST [MOVEI N,TTABND ;[16000] Sequence for end of tab
PUSHJ P,T0XSTR ;[16000] do it
MOVEI C,.CHTAB ;[13000] Restore C
POP P,X ;[21000] Fix up stack
POP P,N ;[13000] Restore N, check cursor & return
POPJ P,] ;[13000]
MOVEI N,CFWD ;[13000] Advance the physical cursor
PUSHJ P,T0XSTR ;[13000] by typing whatever does that
JRST TCCT0] ;[13000] And check again
JUMPE C,[SKIPN TNULL ;[15000] Do we have anything for NULLs?
JRST .+1 ;[15000] do the usual thing
PUSH P,N ;[15000] Type the specified sequence
MOVEI N,TNULL ;[15000] ...
PUSHJ P,T0XSTR ;[15000] ...
POP P,N ;[15000] Get back old value of N
AOS COL ;[15000] Assume this uses 1 character position
POPJ P,] ;[15000] done
CAIG C,.CHCNH ; ^@-^H?
JRST TCC4 ; YES, SPECIAL OUTPUT
CAIL C,.CHCNN ; ^N-^_?
CAILE C,.CHCUN ; . . . ?
PJRST TCHR ; NO, OUTPUT CHAR AS IS
; OUTPUT CHAR AS "^"CHAR (^@-^H,^N-^_)
TCC4: IORI C,"@" ; MAKE CHAR READABLE
PUSH P,C ; SAVE CHAR
MOVEI C,"^" ; FETCH THE "^" CHAR
PUSHJ P,TCHR ; OUTPUT "^"
POP P,C ; RESTORE READABLE FORM OF CHAR
PJRST TCHR ; AND OUTPUT IT
; TSTR - TYPE AN ASCIZ STRING
;
; CALL: MOVEI N,[ASCIZ/STRING/]
; PUSHJ P,TSTR
; (RETURN)
TSTR: HRLI N,(POINT 7,) ; FORM BYTE POINTER
TSTR0: ILDB C,N ; FETCH NEXT CHAR OF ASCIZ STRING
JUMPE C,CPOPJ ; AND RETURN IF NULL
PUSHJ P,TCCHR ; TYPE THE CHAR
JRST TSTR0 ; AND LOOP FOR ALL CHARS OF STRING
; T0XSTR -- Type an ASCIZ string without disturbing the column setting
; (useful for typing escape sequences & other wierd stuff
; same calling sequence as TXSTR
T0XSTR: PUSH P,COL ;[13000] Type something out
HRROS COL ;[15000] Turn off counting
PUSHJ P,TXSTR ;without disturbing
POP P,COL ;the cursor column
POPJ P, ;[13000]
; TXSTR TYPE AN ASCIZ STRING WITH NO REFORMATTING
;
; CALL: MOVEI N,[ASCIZ/STRING/
; PUSHJ P,TXSTR
; (RETURN)
TXSTR: HRLI N,(POINT 7,) ;[7000] BYTE PTR
TXSTR0: ILDB C,N ;[7000]
JUMPE C,CPOPJ ;[7000]
PUSHJ P,TCHR ;[7000]
JRST TXSTR0 ;[7000]
; CLRLIN -- Clear a whole line from the screen
;
; CALL: PUSHJ P,CLRLIN ;uses text in WIPEL to erase to end of line
;
CLRLIN: MOVEI C,15 ;[12000] naked carriage return first
PUSHJ P,TCHR ;[12000]
MOVEI N,WIPEL ;[12000] erase to end of line
SETZM COL ;[23000] Clear the column count
PJRST T0XSTR ;[12000] type that & return
; TCRLF - OUTPUT A CRLF
;
; CALL IS: PUSHJ P,TCRLF ;
; (ONLY RETURN)
; ACS B AND C ARE SMASHED
TCRLF: SETZM COL ;[23000] Clear column counter
MOVEI C,.CHCRT ; FETCH A CR CHAR
PUSHJ P,TCHR ; AND TYPE IT
MOVEI C,.CHLFD ; FETCH A <LF> CHAR
; PJRST TCHR ; AND TYPE IT AND RETURN
; TCHR - OUTPUT A SINGLE CHAR
;
; CALL IS: PUSHJ P,TCHR
; (ONLY RETURN)
; AC C SHOULD CONTAIN CHAR. AC C IS PRESERVED
TCHR: SKIPE OUTADR ; OUTPUT TO NON-TERMINAL?
PJRST @OUTADR ; YES, GO TO ROUTINE
; PUNCH CHAR TO LOG FILE IF I SAID SO
TXNN F,F$LOG ;[330] DID I SAY SO?
JRST NOLOGO ;[330] NO LOG OUTPUT FOR YOU
MOVE X,LELSPC+FS$FLG ;[330] GET LOG FLAGS
TXNE X,FB$NOI ;[330] RECORD OUTPUT?
PUSHJ P,LOGPCH ;[330] YES, PUNCH IT
; TYPE CHAR ON USER'S TERMINAL
NOLOGO: MOVX X,ET$TRN ;[16000] Check for truncate mode
TDNE X,ETVAL ;[16000] ...
JRST [MOVE X,COL ;[16000] See if we're off the wall yet
CAIE C,10 ;[21000] Always let backspace through
CAMGE X,WIDTH ;[16000] ...
JRST .+1 ;[16000] still OK
CAILE C,15 ;[21000] Always let CR,LF,VT,FF through
CAIGE C,12 ;[21000] ...
JRST .+1 ;[21000] ...
POPJ P,] ;[16000] Don't actually type this character
JUMPE C,[PUSHJ P,FOUT ;[24000] Null is text terminator, so
IFN TOPS10,< PUSH P,TOOFUN;[24000] Save old function code
PUSH P,TOOADR;[24000] Save old address
SETZM TOOADR ;[24000] Prepare to output a null
MOVEI X,.TOOUC;[24000] Just 1 character
MOVEM X,TOOFUN;[24000]
MOVE X,[3,,TOOBLK] ;[24000] Set up to do it
TRMOP. X, ;[24000] We did it
JFCL ;[24000] We didn't, but who cares?
POP P,TOOADR ;[24000] Restore old address
POP P,TOOFUN ;[24000] and old function code
>;End IFN TOPS10 ;[24000]
IFN TOPS20,< PUSHJ P,SAVE2;[24000] Save registers
MOVE T1,OURTTY;[24000] Get our terminal JFN
SETZ T2, ;[24000] And our null character
BOUT ;[24000] Output it
ERJMP .+1 ;[24000] Ignore any error
>;END IFN TOPS20
JRST TCHUPD] ;[24000] return
SKIPE TTOEND ;[12000] See if room in the buffer
PUSHJ P,FOUT ;[12000] There isn't, make some
IDPB C,TTOPTR ;[12000] Store it in the output buffer
SKIPL COL ;[12000] -1FC disables checking
TCHUPD: PUSHJ P,UPDCAD ;[12000] Update cursor address
TLZN C,1 ;[12000] Set by UPDCAD if free CRLF needed
POPJ P, ; AND RETURN TO CALLER
PUSH P,C ;[12000] Save C
PUSHJ P,TCRLF ;[12000] Do the CRLF
POP P,C ;[12000] Get back C
POPJ P, ;[12000]
$FOUT: ;[12000] Entry From user code to force out TTY output
;[12000] Call: JSP PC,$$FOUT ;clobbers X
PUSH P,PC ;[12000] Put return addr where POPJ will see it
;[12000] and fall into FOUT
FOUT: ;[12000] Entry from hiseg to force out TTY output
;[12000] Call: PUSHJ P,FOUT ;clobbers X
FOR TOPS10,<
MOVE X,[3,,TOOBLK] ;[12000] Prepare for TRMOP.
TRMOP. X, ;[12000] Output all of that stuff
JFCL ;[12000] Failed, ignore it
>
FOR TOPS20,<
PUSHJ P,SAVE5 ;[21000] Save the AC's
MOVE T1,OURTTY ;[21000] Destination designator
RFMOD ;[21000] Get the current mode bits
PUSH P,T2 ;[21000] and save them
TRZ T2,300 ;[21000] Put in image mode
SFMOD
HRROI T2,TTOBUF ;[21000] Output buffer pointer
SETZB T3,T4 ;[21000] no count, terminate on null byte
SOUT ;[21000] Do it
ERJMP .+1 ;[24000] Ignore error
POP P,T2 ;[21000] Get back old mode setting
SFMOD ;[21000] and restore terminal to that state
>
SETZM TTOBUF ;[12000] Zero the output buffer
MOVE X,[TTOBUF,,TTOBUF+1] ;[12000]
BLT X,TTOEND ;[12000]
MOVE X,[POINT 7,TTOBUF] ;[12000] Reset byte pointer
MOVEM X,TTOPTR ;[12000]
POPJ P, ;[12000] return
FOR TOPS20,< ;Terminal mode manipulation
CLRCCO: PUSH P,[TT%OSP] ;[21000] Clear "supress output" bit
SKIPA
ECOFF: PUSH P,[TT%ECO] ;[21000] Bit to clear
CLRFMO: PUSH P,T1 ;[21000] Clobber no registers
PUSH P,T2
MOVE T1,OURTTY ;[21000]
RFMOD ;[21000] What do we have now
TDZE T2,-2(P) ;[24000] Set the bits
SFMOD ;[21000] Set it unless already set
JRST SETFMZ ;[21000] Join common restoring code
ECON: PUSH P,[TT%ECO] ;[21000] Bit to set
SETFMO: PUSH P,T1 ;[21000] Clobber no registers
PUSH P,T2
MOVE T1,OURTTY ;[21000]
RFMOD ;[21000] What do we have now
TDON T2,-2(P) ;[21000] Set the bits
SFMOD ;[21000] Set it unless already set
SETFMZ: POP P,T2 ;[21000] Restore registers
POP P,T1 ;[21000] ...
ADJSP P,-1 ;[21000] Throw this away
POPJ P, ;[21000] return
>;end TOPS20
;UPDCDC [12000] Update cursor address, assuming controls get reformatted
;
; CALL: MOVEI C,CHARACTER
; PUSHJ P,UPDCAD
; (return with things updated)
; uses C
;
UPDCDC: CAIL C,177 ;do nothing with rubout or greater
POPJ P, ;
SKIPL EUVAL ;Check for case flagging
JRST [CAIG C,"A"+40 ;check for lower case
CAIGE C,"Z"+40 ;
JRST [CAIG C,"Z" ;check for upper case
CAIGE C,"A" ;
JRST .+1
JUMPE X,UPDPRC
JRST UPDCC2] ;Upper case being flagged
JUMPG X,UPDPRC ;lower case not being flagged
JRST UPDCC2] ;lower case is being flagged
CAIGE C,40 ;Real printing character
CAIN C,.CHESC ;ESCAPE prints as $
JRST UPDPRC ;so treat like printing character
CAIE C,15 ;assume uparrow'ed if not <CR> or <LF>...
CAIN C,12 ;
JRST UPDCAD ;Treat like it is
CAIN C,11 ; ... or <TAB>
JRST UPDCAD ;
UPDCC2: MOVE X,ETVAL ;[21000] See if simulating
TXNE X,ET$EXT ;[21000] Image mode
PJRST UPDCAD ;[21000] Yes, do it like it is
PUSHJ P,UPDPRC ;advance 1 print position,
PJRST UPDPRC ;and another print position
;UPDCAD [12000] Update cursor address (ROW, COL & possibly SCFWD)
; due to having typed a character on the screen
; CALL: MOVEI C,CHARACTER
; PUSHJ P,UPDCAD
; (return with things updated)
UPDCAD: CAIL C,177 ;do nothing with rubout or greater
POPJ P,
CAIL C,40 ;check for control character
JRST UPDPRC ;it was a printing character
CAIN C,15 ;Carriage return?
JRST [SKIPN EOL ;[21000] not if anything to type there
SETZM COL ;go to column 0
POPJ P,] ;and return
CAIN C,12 ;Linefeed?
JRST [SKIPE X,DPYALL ;[21000] do we have to allow for a marker char
JRST [ADDB X,COL ;[21000] Yes, do it
PUSHJ P,UPDPC0 ;[21000] and allow for a stray CRLF
JRST UPDEOL] ;[21000]
UPDEOL: AOS ROW ;next line
MOVE X,DMODE ;Check for NEWLINE mode
SKIPN EOL ;[21000] EOL is assumed to do both
TXNE X,DM$NL ;if set, assume <CR> also
SETZM COL ;IN NEWLINE MODE
JRST UPDCRO] ;check for scroll happening
CAIN C,9 ;TAB?
JRST [PUSHJ P,TABSTP ;[21000] Find next one
MOVEM X,COL ;[21000] We're there
JRST UPDPC0] ;[21000] adjust for it
HRROS COL ;disable checking, we don't know what
POPJ P, ;this character does anyway
UPDPRC: AOS X,COL ;increment column, then check for right margin
UPDPC0: CAMGE X,WIDTH ;if over, do something about it
POPJ P, ;it wasn't so don't worry about it
SETZM COL ;Assume somebody typed a CRLF
AOS ROW ;Go to next row
MOVE X,DMODE ;Check for auto crlf by terminal or something
TXNN X,DM$ACR ;if set, we don't do free CRLFs
TLO C,1 ;Set the bit so somebody might
;
;UPDCRO - enter here with ROW & COL set up to adjust for scrolling
; that might have occurred
UPDCRO: MOVE X,LENGTH ;check the row for scrolling
CAMLE X,ROW ;if greater than length of screen
POPJ P, ;it wasn't
SOJL X,[SETZM ROW ;Terminal does not scroll (goes to top?)
POPJ P,]
MOVEM X,ROW ;say we're at the bottom line
AOS SCFWD ;and just scrolled
POPJ P,
; TABSTP -- Find next TAB stop & return it in X
; CALL: PUSHJ P,TABSTP
; (return) with column of next tab stop in X
TABSTP: PUSH P,N ;[21000] Save this
MOVSI N,1-C$NTS ;[21000] AOBJN for # of tab stops
TABST0: MOVE X,TSTOPS(N) ;[21000] Get one
CAMLE X,COL ;[21000] Is this the one?
JRST TABSTZ ;[21000] Yes, return it
AOBJN N,TABST0 ;[21000] No, try next one
MOVE X,COL ;[21000] no more, stay here
TABSTZ: POP P,N ;[21000] Restore this
POPJ P, ;[21000] & Return
>;; END FOR FTXTEC!FTXTCERR
FOR FTXTEC,<
SUBTTL MISCELLANEOUS ROUTINES
; CHKAN - SEE IF A CHAR IS ALPHA-NUMERIC (LETTER/DIGIT)
;
; CALL IS: PUSHJ P,CHKAN ; WITH CHAR IN AC C
; (NOT A-N)
; (CHAR IS A-N)
;
; AC C SHOULD CONTAIN THE CHAR TO BE CHECKED
CHKSCB: CAIE C,"_" ;[10000] _ and & OK in BLISS
CAIN C,"&" ;[10000]
JRST CPOPJ1 ;[10000]
JRST CHKSC
CHKSCA: CAIN C,"." ;[10000] . OK in MACRO
JRST CPOPJ1 ;[10000] Unless we are in BLISS mode
CHKSC: CAIE C,"%" ;[10000] Percent sign ok
CAIN C,"$" ;[10000] Dollarsign too
JRST CPOPJ1 ;[10000]
CHKAN: CAIG C,"Z"+40 ; IS CHAR LOWER CASE?
CAIGE C,"A"+40 ; . . .
SKP ; NO
MOVEI C,-40(C) ; YES, UPCASE THE LETTER
CAIG C,"Z" ; IS CHAR A LETTER OR DIGIT?
CAIGE C,"0" ; . . . ?
POPJ P, ; NO, GIVE ERROR RETURN
CAIGE C,"A" ; IS IT ?
CAIG C,"9" ; . . . ?
JRST CPOPJ1 ; YES! GIVE SKIP RETURN
POPJ P, ; NO, GIVE ERROR RETURN
; CHKEOL - SKIP IF CHARACTER IN AC C IS AN END-OF-LINE CHARACTER (<LF>,<VT>,<FF>)
;
; CALL: MOVEI C,CHAR
; PUSHJ P,CHKEOL
; (FAIL RETURN)
; (SUCCESS RETURN)
;
; USES AC C
CHKEOL: CAIG C,.CHFFD ; IS CHAR <LF>,<VT>, OR <FF>?
CAIGE C,.CHLFD ; . . . ?
POPJ P, ; NO, GIVE FAIL RETURN TO CALLER
CAIN C,.CHLFD ;[12000] LF always wins
JRST CPOPJ1 ;[12000]
MOVE X,EDVAL ;[11000] Check ED value
TXNE X,ED$LLL ;[11000] If set FF is not line terminator
POPJ P, ;[12000] NO
MOVE X,EOVAL ;[12000] Check EO value too
SOJE X,CPOPJ ;[12000] EO=1 means linefeeds only also
JRST CPOPJ1 ; YES, GIVE SUCCESS RETURN TO CALLER
; MAKCJN - MAKE OUR CCL JOB NUMBER (IE: '###XTC')
;
; CALL: PUSHJ P,MAKCJN
; (RETURN) ; WITH CCL JOB NUMBER IN "CCJNAM"
;
; SMASHES ACS X,T1-T3
MAKCJN: MOVSI T3,C$3NAM ; INITIALIZE TO ' XTC'
PJOB T1, ; FETCH OUR JOB NUMBER
MOVEI X,3 ; FETCH #DIGITS IN '###'
MAKCJ1: IDIVI T1,^D10 ; EXTRACT A DIGIT
MOVEI T2,'0'(T2) ; AND CONVERT TO A SIXBIT DIGIT
LSHC T2,-6 ; AND ADD TO THE CCL JOB NAME
SOJG X,MAKCJ1 ; AND DO SAME FOR NEXT DIGIT
MOVEM T3,CCJNAM ; STORE THE CCL JOB NUMBER (IE: '###XTC')
; IN "CCJNAM"
POPJ P, ; AND RETURN TO CALLER
; GETPTH - GET MY DEFAULT PATH FROM PATH.(SUPERIOR TO SETZM'ING)
;
; CALL: PUSHJ P,GETPTH
; (RETURN) ; WITH PATH IN X
;
; SMASHES AC X (VERY HARD TO COMPREHEND WHY). THE ROUTINE IS USED
; IN GETTING THE DEFAULT PATH, TO ENABLE PEOPLE WHO CHANGE THEIR PATH
; TO HAVE THE RIGHT THING DONE FOR THEM, INCLUDING READING THEIR UFD!
; THIS ROUTINE INITIALLY WAS PART OF $EB, AS MAIN-LINE CODE.
GETPTH: MOVE X,[.PTMAX,,PATHB];[3000][340] LOAD LENGTH AND ADDRESS OF PATH
SETOM PATHB+.PTFCN ;[340] PATHB_-1,,.PTFRD
PATH. X, ;[340] GET MY DEFAULT PATH
CAIA ;[340] SICK MONITOR, USE GETPPN
SKIPA X,PATHB+.PTPPN ;[340] GET PPN FROM PATH BLOCK
GETPPN X, ;[342] GET OUR PPN
JFCL ;[342] (JACCT SKIP)
MOVEM X,PATHB+.PTPPN ;[341] IN CASE OF SICK MONITOR FOR BAKCLS
POPJ P, ;[342] AND RETURN TO CALLER
;[12000] Page out DDT & Symbol table
; Call: PUSHJ P,POSSYM
; (only return)
FOR TOPS10,< ;[21000] Can't do this on TOPS-20 so don't try
POSSYM: SKIPN T1,.JBSYM ;[12000] Symbol table addr & len
POPJ P, ;[12000] no symbols loaded
PUSHJ P,POSSUM ;[12000] put those pages out
SKIPN T1,.JBDDT ;[12000] do DDT
POPJ P, ;[12000] no DDT
HLRZ T2,T1 ;[12000] get # of pages for DDT
SUBM T1,T2 ;[12000] into T2
HRLM T2,T1 ;[12000]
PJRST POSSUM ;[12000] Page it out
;[12000] POSSUM -- Page out some pages
;Call MOVE T1,[-LEN,,ADDR] (in words)
; PUSHJ P,POSSUM
; (only return) ;will not complain if can't page out as requested
POSSUM: TLZ T1,777 ;[12000] convert to pages
ASH T1,-9 ;[12000]
POSPGS: MOVEI T4,(T1) ;[12000] Page it out
MOVEI T2,T3 ;[12000] addr of argument block (in AC's)
MOVEI T3,1 ;[12000] Swap a page in or out
TLO T4,400000 ;[12000] OUT
PAGE. T2, ;[12000] do it
JFCL ;[12000] We tried
AOBJN T1,POSPGS ;[12000] loop back
POPJ P, ;[12000] done
>;END FOR TOPS10
; MATCH - SEE IF A WORD IS IN A TABLE
;
; IF TABLE ENTRY BEGINS WITH '*', THEN ANY ABBREVIATION WINS.
;
; CALL: MOVE N,[SIXBIT/NAME/]
; PUSHJ P,MATCH ; WITH WORD IN AC N, MASK IN AC M
; (NO FIND RETURN)
; (AMBIGUOUS WORD RETURN)
; (SUCCESS RETURN); AC L POINTS TO WORD IN TABLE
;
; ACS X,T1,T2,L ARE SMASHED
MATCH: MOVEM N,SBNAME ; STORE THE SIXBIT NAME
SETO T2, ; USED TO COUNT MATCHES
MAT0: MOVE X,(L) ; FETCH WORD FROM TABLE
TXNE X,3B1 ; IS FIRST CHAR '*' ?
JRST MAT2 ; NO, CHECK THE NORMAL WAY
LSH X,6 ; YES, SHIFT OUT THE '*'
XOR X,N ; SEE IF A MATCH OR ABBREV.
TXZ X,77 ; IGNORE LAST CHAR BECAUSE TABLE ENTRY
; DOESN'T HAVE IT
AND X,M ; DO THE MASKING
JUMPE X,CPOPJ2 ; WIN IF MATCH OR ANY ABBREV. !
JRST MAT1 ; LOSE IF NOT MATCH OR AN ABBREV.
MAT2: XOR X,N ; AN EXACT MATCH?
JUMPE X,CPOPJ2 ; YES, SUCCESS!
AND X,M ; NO, AN ABBREVIATION?
JUMPN X,MAT1 ; NO
AOJG T2,MAT1 ; YES, COUNT IT. FIRST ONE?
MOVEI T1,(L) ; YES, SAVE ADR OF WORD IN TABLE
MAT1: AOBJN L,MAT0 ; TRY NEXT WORD IN TABLE
MOVEI L,(T1) ; ALL DONE. GET ADR OF FIRST MATCH
JUMPL T2,CPOPJ ; THERE WEREN'T ANY MATCHES
JUMPE T2,CPOPJ2 ; SUCCESS, UNIQUE MATCH!
JRST CPOPJ1 ; AMBIGUOUS, MORE THAN ONE MATCH
; DISPAT - LOOKUP A HALFWORD AND DISPATCH IF MATCH
;
; CALL: MOVEI C,XWD ; THE HALFWORD TO BE SEARCHED FOR
; MOVE T1,[IOWD LTH,TAB]
; PUSHJ P,DISPAT
; (NOFIND RETURN)
; IF FOUND, DISPATCH TO ADDRESS IN LH OF TABLE ENTRY
;
; TAB:
; <XWD,,ADR>
; <XWD,,ADR>
; . . .
; LTH==.-TAB
;
; USES ACS X,L,C
DISPAT: HLRZ X,(T1) ; FETCH XWD FROM TABLE ENTRY
CAIN X,(C) ; THE ONE WE'RE LOOKING FOR?
JRST DISPA1 ; YES, DISPATCH
AOBJN T1,DISPAT ; NO, LOOP FOR ALL TABLE ENTRIES
POPJ P, ; NOFIND. GIVE NOFIND RETURN
; FOUND IT! DISPATCH
DISPA1: POP P,X ; IGNORE RETURN ADR TO CALLER
MOVE X,(T1) ; FETCH THE DISPATCH ADDRESS
JRST (X) ; AND DISPATCH
>;; END FOR FTXTEC
FOR FTXTEC!FTXTCERR,<
; CTOBP - CONVERT A CHARACTER ADDRESS TO A BYTE POINTER
;
; CALL: MOVEI T1,CHARADR
; PUSHJ P,CTOBP
; (RETURN) ; WITH BP IN AC T1
;
; USES ACS T1,T2
CTOBP: IDIVI T1,5 ; CONVERT TO WORD ADR + EXTRA
HLL T1,CBPTBL(T2) ; CONVERT EXTRA TO BIT POSITION
POPJ P, ; AND RETURN TO CALLER
; CBPTBL - CONVERSION TABLE FROM CHAR NUMBER(0-5) TO BYTE POINTER
POINT 7,,
CBPTBL: POINT 7,,6
POINT 7,,13
POINT 7,,20
POINT 7,,27
POINT 7,,34
>;; END FOR FTXTEC!FTXTCERR
FOR FTXTEC,<
SUBTTL QSTOR - Store a value/text-buffer in a Q-register
; CALL: MOVE T1,[SIXBIT/NAME/]
; MOVX T2,QB$???+(BID or ADRREF)
; MOVE T3,VALUE
; TX? F,F$REF ; ?=Z IF ADRREF IS REALLY A TEXT-BUFFER ID
; ; ?=O IF ADRREF IS ADR OF REFERENCE TO A TEXT BUFFER
; PUSHJ P,QSTOR
; (RETURN)
;
; PRESERVES ACS (EXCEPT X)
QSTOR: PUSH P,N ; SAVE AC N
PUSH P,L ; SAVE AC L
JUMPE T2,QSTOR1 ;[23000] Any text in q-reg?
TXNN F,F$REF ; IS ADRREF A TEXT BUFFER ID?
JRST QSTOR1 ; NO
; MUST ADD TEXT BUFFER TO THE LINKED LIST AND GET ITS ID
MOVEI L,(T2) ; FETCH THE ADR OF REFERENCE
PUSHJ P,ADDBLK ; ADD THE BLOCK TO THE LINKED-LIST
HRRI T2,(N) ; AND RETURN THE TEXT-BUFFER ID
;[12000] Check for short name, or blank (THE TEXT BUFFER)
QSTOR1:
TDNN T1,[007777,,777777] ;[22000] See if short name
JRST [JUMPE T1,[PUSH P,T3 ;numeric value to .
TXNN T2,QB$BID ;Check for text q-register
JRST QSTR1A ;no text, leave buffer alone
SETZ L,
MOVEI N,(T2) ;Yes, find it
PUSHJ P,FNDBLK
ERROR(BNF) ;OOPS
MOVX T2,TB$BUF ;Set text buffer flag
HLLM T2,T$BIT(T1) ;in buffer header &clr others
EXCH T1,TXTBUF ;Point to text buffer
HLLZS B$4PTR(T1) ;zero old back pointer
HRRZS N,T$BID(T1) ;Get old BID and clear flags
PUSHJ P,DELBLK ;Get rid of it
MOVEI L,TXTBUF ;Save reference
MOVE T1,TXTBUF ;Get back new buffer
HRRM L,B$4PTR(T1)
QSTR1A: POP P,T3 ;[12000] Get numeric val back
CAMLE T3,@TXTBUF ;[12000] Check . value
SETZ T3, ;[15000] out of range
MOVEM T3,PTVAL ;[12000] Store it, it's OK
JRST QSTOR3] ;Restore ACs & return
LDB T5,[350700,,T1] ;[23000] Get q-register index
ADDI T5,QREG-1 ;[23000] Make address
JRST QSTREX] ;[23000] Save in existing q-reg
; NOW SEE IF THE Q-REGISTER ALREADY EXISTS
PUSHJ P,QFIND ; SEE IF THE Q-REGISTER EXISTS
JRST QSTOR2 ; NO, CREATE A NEW Q-REGISTER
; STORE NEW VALUES IN EXISTING Q-REGISTER
QSTREX: MOVE X,Q$BIT(T5) ; SAVE OLD Q-BITS
HRRZ N,Q$PTR(T5) ; SAVE OLD Q-ID
MOVEM T2,Q$BIT(T5) ; SET NEW Q-BITS/Q-ID
MOVEM T3,Q$VAL(T5) ; SET NEW Q-VALUE
TXNE X,QB$BID ; WAS OLD Q-REGISTER A TEXT BUFFER?
PUSHJ P,DELBLK ; YES, DELETE IT
JRST QSTOR3 ; RESTORE ACS AND RETURN TO CALLER
; ADD A NEW Q-REGISTER TO QTAB
QSTOR2: MOVE X,QR ; FETCH QTAB PDP
AOBJN X,.+1 ; INCREMENT IT
EXCH X,QR ; AND STORE IT
PUSH X,T1 ; SET NEW Q-REGISTER NAME
MOVE X,QR ; FETCH QTAB PDP
AOBJN X,.+1 ; INCREMENT QTAB PDP
EXCH X,QR ; AND STORE IT
PUSH X,T2 ; SET NEW Q-REGISTER BITS
MOVE X,QR ; FETCH QTAB PDP
AOBJN X,.+1 ; INCREMENT QTAB PDP
EXCH X,QR ; AND STORE IT
PUSH X,T3 ; SET NEW Q-REGISTER VALUE/TEXT-BUFFER-ID
; RESTORE ACS AND RETURN TO CALLER
QSTOR3: POP P,L ; RESTORE AC L
POP P,N ; RESTORE AC N
POPJ P, ; AND RETURN TO CALLER
SUBTTL QGET - Return a Q-register
; CALL: MOVE T1,[SIXBIT/NAME/]
; PUSHJ P,QGET
; (RETURN) ; T1:= SIXBIT Q-REGISTER NAME
; ; T2:= BITS
; ; T3:= NUMERIC VALUE/TEXT-BUFFER-ID
;
; USES ACS T1-T3
QGET:
MOVEM T1,SBNAME ; SAVE THE Q-REGISTER NAME
TDNN T1,[007777,,777777] ;[22000] Single letter?
JRST [JUMPE T1,[MOVX T2,QB$BID ;[12000] It contains both
HRR T2,TXTBUF ;[12000] Get addr of buffer
HRR T2,T$BID(T2) ;[12000] Get buffer ID
MOVE T3,PTVAL ;[12000] . is numeric value
JRST CPOPJ1] ;[12000] win
LDB T2,[350700,,T1] ;[22000] Get the index
MOVE T3,QREG+<Q$VAL-Q$BIT>(T2) ;[22000] Get the value
MOVE T2,QREG(T2) ;[22000] And the bid/bits
JRST CPOPJ1]
PUSHJ P,QFIND ; FIND THE SPECIFIED Q-REGISTER
POPJ P, ; IT DOESN'T EXIST
MOVE T2,Q$BIT(T5) ; FETCH BITS INTO AC T2
MOVE T3,Q$VAL(T5) ; FETCH VALUE/TEXT-BUFFER-ID INTO AC T3
JRST CPOPJ1 ; AND RETURN TO CALLER
SUBTTL QFIND - Find a Q-register in QTAB
; CALL: MOVE T1,[SIXBIT/NAME/]
; PUSHJ P,QFIND
; (FAIL RETURN)
; (SUCCESS RETURN)
;
; USES ACS T1,T5
;This will not find the text buffer
QFIND:
; MAKE A AOBJN POINTER FOR SEARCHING THROUGH QTAB
MOVE T5,QTAB ; FETCH BASE ADR OF Q-REGISTER TABLE
MOVEI X,(T5) ; COPY OF SAME
SUB X,QR ; COMPUTE MINUS LENGTH OF Q-REGISTER TABLE
HRLI T5,(X) ; <-LEN,,ADR>
; SEARCH FOR THE SPECIFIED Q-REGISTER
QFIND1: CAMN T1,(T5) ; IS THIS THE ONE?
JRST CPOPJ1 ; YES, GIVE SUCCESS RETURN TO CALLER
ADD T5,[<2,,2>] ; NO, POINT TO NEXT Q-REGISTER
AOBJN T5,QFIND1 ; AND LOOP FOR ALL Q-REGISTERS
POPJ P, ; Q-REGISTER NOT FOUND. GIVE FAIL
; RETURN TO CALLER
SUBTTL MKROOM - Make room for an arbitrary # of chars in main text buffer
; CALL: MOVEI T1,#CHARS
; PUSHJ P,MKROOM
; (return)
;
; Uses ACs 1-17 DOES NOT PRESERVE 1-5,N,M
MKROOM: JUMPE T1,CPOPJ ;[14000] Nothing to do
JUMPL T1,MKRM1 ;[13000] need never expand if deleting
MOVE X,TXTBUF ; fetch reference to text buffer
HLRZ T2,B$1PTR(X) ; fetch adr of end of buffer
SUBI T2,T$DATA-B$1PTR(X) ; compute size of text buffer in words
MOVE N,@TXTBUF ; fetch # chars in text buffer
ADDI N,4(T1) ; plus # chars requested
IDIVI N,5 ; CONVERTED TO WORDS
SUB N,T2 ; needed size minus what we have
JUMPLE N,MKRM1 ; we have enough space. just shift buffer
; Add space to main text buffer
MOVEI N,^D10(N) ; fetch # words we need (plus some extra)
PUSH P,L ; Save AC L
MOVEI L,TXTBUF ; Fetch adr of reference to text bufer
PUSHJ P,EXPAND ; Expand text buffer to required size
POP P,L ; restore AC L
; SAVE ACS
MKRM1: MOVE X,[<2,,ACSAVE+2>] ; SETUP BLT POINTER
BLT X,ACSAVE+17 ; STORE ACS 2-17
; See if part of buffer must be shifted
MOVE X,PTVAL ; Fetch buffer pointer
CAMN X,@TXTBUF ; At end of buffer?
JRST MKRM3 ; yes, don't have to shift buffer contents
JUMPL T1,MKRM4 ; NO, HAVE TO SHIFT PART OF BUFFER BACKWARDS
; (IE: FOR THE "D" COMMAND)
; SHIFT FROM "." THROUGH "Z" UP C(T1) CHARACTERS
; GET READY FOR THE UPWARD MOVE
MOVEI 14,(T1) ; AC14:=REQ (REQUESTED # CHARS)
IDIVI 14,5 ; AC14:=Q(REQ/5) , AC15:=REM(REQ/5)
IMULI 15,7 ; AC15:=(REM(REQ/5))*7
MOVN 12,15 ; AC12:=-(REM(REQ/5))*7
MOVEI 15,-43(15) ; AC15:=(REM(REQ/5))*7-43
MOVE 10,PTVAL ; PT (CURRENT BUFFER POSITION)
IDIVI 10,5 ; AC10:=Q(PT/5) , AC12:=REM(PT/5)
ADD 10,TXTBUF ; MAKE AC10 AN ABSOULUTE ADR
MOVEI 10,T$DATA(10) ; . . .
MOVNI 16,-5(11) ; AC11:=-REM(PT/5)-5
IMULI 16,7 ; AC16:=-(REM(PT/5)-5)*7
DPB 16,[POINT 6,MKRMBP,11] ; SIZE OF LAST PARTIAL WORD
ADDI 14,1(10) ; AC14:=Q(REQ/5)+Q(PT/5)+1
MOVE 16,@TXTBUF ; FETCH CHAR ADR OF END OF BUFFER
IDIVI 16,5 ; AC16:=Q(Z/5)
MOVEI T4,T$DATA+1(16) ; COMPUTE # WORDS TO MOVE
ADD T4,TXTBUF ; . . .
SUB T4,10 ; T2:=Q(Z/5)+1-Q(PT/5)=# WORDS TO MOVE
; PUT SHIFT ROUTINE IN FAST ACS
HRLI 10,(MOVE T2,0(T4)) ; AC10:=MOVE T2,[Q(PT/5)](T4)
HRLOI 11,(ROT T2,0) ; AC11:=ROT T2,-1
HRLI 12,(ROTC T2,0) ; AC12:=ROTC T2,-(REM(REQ/5))*7
MOVE 13,[TRZ T3,1] ; AC13:=TRZ T3,1 ;[14000] Clear LSN bit
HRLI 14,(MOVEM T3,0(T4)); AC14:=MOVEM T4,[Q(PT/5)+Q(REQ/5)+1](T4)
HRLI 15,(ROTC 2,0) ; AC15:=ROTC T2,(REM(REQ/5))*7-43
MOVE 16,.+2 ; AC16:=SOJGE T4,11
MOVE 17,[JRST MKRM2] ; AC17:=JRST MKRM2
SOJGE T4,10 ; T2:=T2-1. DONE?
; SHIFT IS ALMOST FINISHED
MKRM2: PORTAL .+1 ;[316] BACK FROM FAST ACS
ROTC T2,43(12) ; STORE LAST PARTIAL WORD
DPB T2,MKRMBP ; . . .
; UPDATE THE # CHARS IN BUFFER
MKRM3: ADDM T1,@TXTBUF ; ADD # CHARS TO BUFFER COUNT
; RESTORE ACS AND RETURN TO CALLER
MOVE 17,[<ACSAVE+2,,2>] ; SETUP BLT POINTER
BLT 17,17 ; ANS RESTORE ACS
POPJ P, ; AND RETURN TO CALLER
; SHIFT FROM "."+ABS(T1) THROUGH "Z" DOWN ABS(T1) CHARACTERS
MKRM4: MOVE 14,PTVAL ; INITIALIZE PARTIAL WORD POINTER
IDIVI 14,5 ; AC14:=Q(PT/5) , AC15:=REM(PT/5)
ADD 14,TXTBUF ; MAKE AC14 AN ABSOLUTE ADR
ADDI 14,T$DATA ; . . .
MOVE T4,14 ; T4:=Q(PT/5)
HRRZM 14,MKRMB1 ; INITIALIZE BP FOR LAST PARTIAL MOVE
IMULI 15,7 ; AC15:=(REM(PT/5))*7
DPB 15,[POINT 6,MKRMB1,11] ; SIZE:=(REM(PT/5))*7
MOVNI 15,-44(15) ; AC15:=44-(REM(PT/5))*7
DPB 15,[POINT 6,MKRMB1,5] ; POSITION:=44-(REM(PT/5))*7
MOVE 11,@TXTBUF ; FETCH "Z"
ADDI 11,<T$DATA*5>+4 ;[21000] Don't shift someone else
IDIVI 11,5 ; AC11:=Q(Z/5) , AC12:=REM(Z/5)
ADD 11,TXTBUF ; MAKE AC11 AN ABSOLUTE ADR
MOVE 13,T1 ; AC13:=REQ (# CHARS TO ADD)
IDIVI 13,5 ; AC13:=Q(REQ/5)
ADDI 13,-1(11) ; AC13:=Q(Z/5)-Q(REQ/5)
MOVNI 12,(14) ; AC12:=(REM(REQ/5))
IMULI 12,7 ; AC12:=(REM(REQ/5))*7
MOVNI 15,-43(12) ; AC15:=43-(REM(REQ/5))*7
SUBI T4,1(13) ; T2:=Q(PT/5)+Q(REQ/5)+Q(REQ/5)-Q(Z/5)-1
; = # WORDS TO SHIFT
; NOW PUT THE BACKWARDS SHIFT ROUTINE IN THE FAST ACS
HRLI 11,(MOVE T3,(T4)) ; AC11:=MOVE T3,[Q(Z/5)+1](T4)
HRLI 12,(ROTC T2,0) ; AC12:=ROTC T2,(REM(REQ/5))*7
HRLI 13,(MOVEM T2,(T4)) ; AC13:=MOVEM T2,[Q(Z/5)-Q(REQ/5)](T4)
MOVE 14,[ADDM T2,@13] ; AC14:=ADDM T2,@13
HRLI 15,(ROTC T2,0) ; AC15:=ROTC T2,43-(REM(REQ/5))*7
MOVE 16,MKRM5 ; AC16:=AOJLE T2,11
MOVE 17,[JRST MKRM6] ; AC17:=JRST KMRM6
LDB T5,MKRMB1 ; FECTH THE LAST PARTIAL WORD
MOVE T2,@11 ; FETCH FIRST WORD
ROT T2,-1 ; T2:=Q(PT/5)+Q(REQ/5) RIGHT JUSTIFIED
MKRM5: AOJLE T4,11 ; T2:=T2+1. DONE?
; DOWNWARD SHIFT IS ALMOST DONE
MKRM6: PORTAL .+1 ;[316] BACK FROM FAST ACS
DPB T5,MKRMB1 ; STORE THE LAST PARTIAL WORD
JRST MKRM3 ; DONE. RESTORE ACS AND RETURN
SUBTTL ADDBLK - Add a block to the Linked-List
; CALL: MOVEI L,ADRREF
; PUSHJ P,ADDBLK
; (RETURN) ; ID IS RETURNED IN AC N
;
; ACS PRESERVED
ADDBLK: PUSHJ P,SAVE2 ; SAVE ACS
MOVE T1,(L) ; FETCH ADR OF BLOCK
SETZM (L) ; CLEAR THE REFERENCE
SKIPN T2,LNKLST+1 ; ANYTHING IN LINKED-LIST?
MOVEI T2,LNKLST ; NO
HRRM T2,B$1PTR(T1) ; LNKLST+1 REFERENCES 2ND WORD OF BLOCK
MOVEI X,B$1PTR(T1) ; FETCH ADR OF FIRST WORD
HRRM X,(T2) ; 2ND WORD OF LAST BLOCK REFERENCES
; FIRST WORD OF NEW BLOCK
MOVEI X,LNKLST+1 ; FETCH ADR OF LNKLST+1
HRRM X,B$2PTR(T1) ; 2ND WORD OF NEW BLOCK REFERENCES
; LNKLST+1
MOVEI X,B$2PTR(T1) ; FETCH ADR OF 2ND WORD OF NEW BLOCK
MOVEM X,LNKLST+1 ; LNKLST+1 REFERENCES 2ND WORD OF NEW BLOCK
; ASSIGN AN ID TO THIS NEW BLOCK
AOS N,LNKID ; GENERATE A NEW ID
; AND RETURN IT IN AC N
MOVEM N,T$BID(T1) ; STORE BID FOR BLOCK
; INITIALIZE THE REFERENCE COUNT FOR THIS BLOCK TO 1
MOVEI X,1 ; INIT REFERENCE COUNT TO 1
MOVEM X,T$RCNT(T1) ; AND STORE IT AS 4TH WORD OF NEW BLLOCK
POPJ P, ; AND RETURN TO CALLER
SUBTTL REFBLK - Add one to the Reference Count for A BLOCK IN LINKED-LIST
; CALL: MOVEI N,ID
; PUSHJ P,REFBLK
; (RETURN)
;
; CLOBBERS AC X
;[12000] Saves AC L. This is the same AC as SARG and we want to allow
; all arguments to pass through $PUSH & $POP
REFBLK: PUSH P,L ;[12000] Save AC L
SETZ L, ; T1 WILL POINT TO BLOCK
PUSHJ P,FNDBLK ; FIND THE BLOCK WITH SPECIFIED ID
SKP ; NONE. RETURN TO CALLER
AOS T$RCNT(T1) ; ADD ONE TO THE REFERENCE COUNT
POP P,L ;[12000] Restore AC L
POPJ P, ; AND RETURN TO CALLER
SUBTTL DELBLK - Un-Reference a Block in Linked-List
; CALL: MOVEI N,ID
; PUSHJ P,DELBLK
; (RETURN)
;
; ACS PRESERVED (EXCEPT X,L)
DELBLK: PUSHJ P,SAVE5 ; SAVE ACS T1-T5
SETZ L, ; T1 WILL POINT TO BLOCK
PUSHJ P,FNDBLK ; FIND THE BLOCK WITH THE SPECIFIED ID
POPJ P, ; DOESN'T EXIST. RETURN TO CALLER
SOSLE T$RCNT(T1) ; DECREMENT THE REFERENCE COUNT
POPJ P, ; OTHERS USING BLOCK. LEAVE IT IN LIST
; REMOVE THE BLOCK FROM THE LIST
HRRZ T2,T$PBUF(T1) ; FETCH POINTER TO PREVIOS BLOCK
HRRZ T3,T$NBUF(T1) ; FETCH POINTER TO NEXT BLOCK
HLLZS T$PBUF(T1) ; DELETE ALL REFERENCES TO BLOCK
HRLI T1,-C$NREF ; MAKE AOBJN POINTER TO DELETE REFS
DELBK0: SETZM T$1REF(T1) ; CLEAR 2 REFS
AOBJN T1,DELBK0 ; AND TRY NEXT 2 REFS
; PATCH THE LINKS AROUND THE BLOCK
DELBK1: HRRM T3,(T2) ; LAST POINTS TO NEXT
HRRM T2,(T3) ; NEXT POINTS TO LAST
GPOPJ: TXO F,F$GCN ; FLAG THAT A GARBAGE COLLECTION NEEDED
POPJ P, ; AND RETURN TO CALLER
POPJ P, ; AND RETURN TO CALLER
SUBTTL FNDBLK - Find a Block (given its id) in the Linked-List
; CALL: MOVEI N,ID
; MOVEI L,ADRREF ; WILL REFERENCE THE BLOCK WHEN FOUND
; ; OR "SETZ L," IF T1 IS TO POINT TO BLOCK
; PUSHJ P,FNDBLK
; (FAIL RETURN)
; (SUCCESS RETURN) ; ADRREF WILL REFERENCE THE BLOCK
; ; IF L=0, THEN T1 POINTS TO BLOCK
;
; SMASHES ACS X,T1,T2
;[12000] Searches LNKLST backwards (most recently created first)
FNDBLK: SKIPN T1,LNKLST+1 ;[12000] ANYTHING IN LINKED LIST?
POPJ P, ; NO, GIVE FAIL RETURN TO CALLER
; FIND THE BLOCK GIVEN ITS ID
FNDBK1: CAIN T1,LNKLST ;[12000] AT END OF LIST?
POPJ P, ; YES, GIVE UP AND GIVE FAIL RETURN TO CALLER
HRRZ X,T$BID-B$2PTR(T1) ;[12000] FETCH ID OF THIS BLOCK
CAIN X,(N) ; IS THIS THE ID WE WANT?
JRST FNDBK2 ; YES
HRRZ T1,-1(T1) ;[12000] NO, FETCH POINTER TO NEXT BLOCK IN LIST
JUMPN T1,FNDBK1 ; [14000] Check for non-zero AND TRY IT
ERROR (LLB) ;[14000] Linked list is broken
; FOUND BLOCK WITH SPECIFIED ID. SET UP REFERENCE TO IT
FNDBK2: MOVEI T1,C$NREF-1(T1) ;[12000] FETCH ADR OF FIRST DATA WORD IN BLOCK
JUMPE L,CPOPJ1 ; RETURN IF T1 SHOULD POINT TO BLOCK
MOVEM T1,(L) ; STORE IT IN REFERENCE
HRLM L,B$2PTR(T1) ; BIND THE REFERENCE TO BLOCK
JRST CPOPJ1 ; AND GIVE SUCCESS RETURN TO CALLER
SUBTTL SAVE AC ROUTINES
SAVE2: POP P,X ; SAVE RETURN ADDRESS
PUSH P,T1 ; SAVE T1
PUSH P,T2 ; SAVE T2
PUSHJ P,(X) ; RETURN
SKP ; CPOPJ RETURN
AOS -2(P) ; CPOPJ1 RETURN
REST2: POP P,T2 ; RESTORE T2
POP P,T1 ; RESTORE T1
POPJ P, ; AND RETURN
SAVE5: POP P,X ; SAVE RETURN ADDRESS
PUSH P,T1 ; SAVE T1
PUSH P,T2 ; SAVE T2
PUSH P,T3 ; SAVE T3
PUSH P,T4 ; SAVE T4
PUSH P,T5 ; SAVE T5
PUSHJ P,(X) ; RETURN
SKP ; CPOPJ RETURN
AOS -5(P) ; CPOPJ1 RETURN
POP P,T5 ; RESTORE T5
POP P,T4 ; RESTORE T4
POP P,T3 ; RESTORE T3
JRST REST2 ; RESTORE T2,T1 AND RETURN
>;; END FOR FTXTEC
FOR FTXTEC!FTXTCERR,<
SUBTTL CPOPJX - Various POPJ Returns
; CPOPJ: NON-SKIP RETURN
; CPOPJ1: SKIP RETURN
; CPOPJ2: DOUBLE-SKIP RETURN
CPOPJ2: AOS (P)
CPOPJ1: AOS (P)
CPOPJ: POPJ P, ; RETURN TO CALLER
>;; END FOR FTXTEC!FTXTCERR
FOR FTXTEC,<
SUBTTL REQM - REQUEST MEMORY (CORE ALLOCATION)
; REQM - CORE ALLOCATION ROUTINE
;
; CALL IS: MOVE L,[XWD ADRREF,LENGTH]
; PUSHJ P,REQM
; (RETURN)
;
; CALLER MUST ALSO SET UP 'ADRREF' (REQM WILL ADD THE ADR OF
; THE FIRST DATA WORD IN THE ALLOCATED BLOCK TO THE RH OF 'ADRREF')
;
; ACS PRESERVED
REQM0: TXNN F,F$GCN ; GARBAGE COLLECTION NEEDED ?
JRST REQM3 ; NO, SIZE OF BLOCK.GT.C$GSIZ
PUSHJ P,GARCOL ; PERFORM A GARBAGE COLLECTION
SKP ; ACS ALREADY SAVED
REQM: PUSHJ P,SAVE2 ; SAVE T1,T2
MOVE X,.JBFF ; FETCH ADR OF FIRST FREE LOCATION
MOVEI T1,(X) ; " IN T1
ADDI T1,C$NREF(L) ; ADD REQUESTED LENGTH PLUS OVERHEAD WORDS
MOVEI T2,(L) ; FETCH REQUESTED LENGTH
ADDB T2,GSIZE ; ACCUMULATE # WORDS ALLOCATED SINCE
; LAST GARBAGE COLLECTION
CAMG T1,.JBREL ; DO WE HAVE THE CORE?
JRST REQM1 ; YES
CAILE T2,C$GSIZ ; NO, TIME FOR A GARBAGE COLLECTION?
JRST REQM0 ; YES, PERFORM ONE
REQM3: MOVEI T2,(T1) ; NO, FETCH ADR OF HIGHEST LOC WE WANT
CORE T2, ; AND ASK MONITOR FOR THE CORE
JRST REQM2 ; NOT ENOUGH CORE!
REQM1: MOVEI T2,1(X) ; FETCH ADR OF START OF NEW BLOCK
HRLI T2,(X) ; SET UP A BLT POINTER ...
BLT T2,(T1) ; AND ZERO OUT THE NEW BLOCK
MOVEM T1,.JBFF ; SAVE POINTER TO FIRST FREE LOCATION
HRLM T1,(X) ; SETUP POINTER TO NEXT BLOCK
HLRM L,(X) ; SETUP POINTER TO FIRST REFERENCE
SETZM (T1) ; ZERO THE FIRST FREE LOCATION
HLRZ T1,L ; FETCH ADR OF REFERENCE
MOVEI X,C$NREF(X) ; FETCH ADR OF FIRST DATA WORD
ADD X,(T1) ; ADD ADR FIRST DATA TO RH OF REFERENCE
HRRM X,(T1) ; AND UPDATE THE REFERENCE
POPJ P, ; AND RETURN
REQM2: TXNE F,F$GCN ; IS A GARBAGE COLLECTION NEEDED?
JRST REQM0 ; YES, PERFORM ONE
ERROR (CEF) ; NO, GIVE AN ERROR :
; "CORE EXPANSION FAILURE"
SUBTTL RELM - RELEASE MEMORY
; RELM - RELEASE A BLOCK OF MEMORY
;
; CALL IS: MOVE L,[XWD OFFSET,ADRREF]
; PUSHJ P,RELM
; (RETURN)
;
; 'OFFSET' IS THE DIFFERENCE BETWEEN THE RH OF 'ADRREF' AND ADR OF FIRST DATA.
;
; ACS PRESERVED
RELM: SKIPN (L) ; IS REFERENCE BOUND TO ANY BLOCK?
POPJ P, ; NO, GIVE IMMEDIATE RETURN
TXO F,F$GCN ; GARBAGE COLLECTION NEEDED
HLRE X,L ; FETCH THE OFFSET
MOVN X,X ; NEGATE THE OFFSET
ADD X,(L) ; ADD THE REFERENCE
HLLZS B$1PTR(X) ; ZAP THE 1ST REFERENCE
HRLI X,-C$NREF+1 ; MAKE AOBJN POINTER FOR REST
RELM0: SETZM B$2PTR(X) ; CLEAR 2 REFS
AOBJN X,RELM0 ; AND TRY NEXT REFS
SETZM (L) ; ZERO THE REFERENCE
POPJ P, ; AND RETURN
SUBTTL GARCOL - GARBAGE COLLECTION ROUTINE
; GARCOL - GARBAGE COLLECTION ROUTINE
;
; CALL IS: PUSHJ P,GARCOL
; (RETURN)
;
; ACS PRESERVED
GARCOL: PUSHJ P,SAVE5 ; SAVE T1,T2,T3,T4,T5
PUSH P,L ; SAVE AC L
SETZ T3, ; ZERO THE RELOCATION FACTOR
MOVE T4,HEAD ; FETCH ADR OF FIRST BLOCK OF CORE
; LOOP FOR EVERY BLOCK OF CORE
GCLOOP: SKIPN X,(T4) ; END OF LIST?
JRST GCDONE ; YES, FINISH UP
HLRZ T5,(T4) ; FETCH ADR OF NEXT BLOCK
MOVE T1,1(T4) ; FETCH 2ND REFERENCE WORD (1ST IS IN Z)
JUMPN T1,GCMOVE ; MOVE BLOCK IF IT IS REFERENCED
TRNE X,-1 ; IS BLOCK REFERENCED?
JRST GCMOVE ;YES, MOVE IT
; THIS IS AN UNBOUND BLOCK
HLRZ X,X ; FETCH ADR OF NEXT BLOCK
SUBI X,(T4) ; COMPUTE LENGTH OF THIS BLOCK
ADDI T3,(X) ; ACCUMULATE THE RELOCATION FACTOR
; TRY NEXT BLOCK
GCNEXT: MOVEI T4,(T5) ; LOAD ADR OF NEXT BLOCK
JRST GCLOOP ; AND TRY NEXT BLOCK
; MOVE THIS BLOCK (IF RELOCATION IS NON-ZERO)
;
; FIRST FIX UP REFERENCES
GCMOVE: JSP L,FIXREF ; RELOCATE THE REFERENCES
; NOW RELOCATE THE BLOCK
GCM3: MOVEI T2,(T4) ; FETCH ADR OF BLOCK
SUBI T2,(T3) ; ADR WHERE BLOCK WILL GO
HRLI T2,(T4) ; ADR WHERE IT IS NOW
HLRZ T1,(T4) ; ADR OF END OF BLOCK+1
SUBI T1,(T3) ; END OF WHERE IT WILL GO
MOVEI X,(T2) ; SAVE ADR OF NEW POSITION OF BLOCK
BLT T2,-1(T1) ; MOVE THE BLOCK
HRLM T1,(X) ; STORE POINTER TO NEXT BLOCK
JRST GCNEXT ; NOW TRY THE NEXT BLOCK
; FINISH UP AFTER THE GARBAGE COLLECTION
GCDONE: MOVNI T1,(T3) ; FETCH NEGATIVE RELOCATION FACTOR
ADDB T1,.JBFF ; UPDATE POINTER TO FIRST FREE
SETZM (T1) ; ZERO THE FIRST FREE LOC
HLRZ X,.JBCOR ; FETCH MIN CORE SIZE
CAIGE T1,(X) ; BELOW MINIMUM SIZE?
MOVEI T1,(X) ; YES, USE MINIMUM SIZE
CORE T1, ; RELEASE UNNEEDED CORE
HALT .+1 ;[20000] Shouldn't happen ever
SETZM GSIZE ; CLEAR "# WORDS ALLOCATED SINCE LAST
; GARBAGE COLLECTION"
TXZ F,F$GCN ; SET "GARBAGE COLLECTION NOT NEEDED"
POP P,L ; RESTORE AC L
POPJ P, ; AND RETURN
SUBTTL FIXREF - RELOCATE THE REFERNECES TO A DYNAMIC BLOCK
; CALL: MOVEI T4,BLOCK
; MOVEI T3,RELOC.CONSTANT
; MOVEI T5,ADDR OF NEXT BLOCK
; JSP L,FIXREF
; (RETURN)
;
; SMASHES ACS X,T1,T2. USES AC T3,T5
FIXREF: JUMPE T3,(L) ; RETURN IF RELOC.CONSTANT=ZERO
MOVEI T2,(T4) ;[14000] Make AOBJN pointer in temp AC
HRLI T2,-C$NREF ; MAKE AOBJN POINTER FOR LOOPING
JRST FIXRF2 ; AND JUMP INTO LOOP FOR FIRST REF
FIXRF1: HLRZ T1,(T2) ; FETCH ADR OF LH REF
JUMPE T1,FIXRF2 ; NONE. TRY RH
HRRZ X,(T1) ; FETCH THE CONTENTS OF REF
CAIGE X,(T5) ;[14000] Check this 'ref'
CAIGE X,(T4) ;[14000] Does it point to this block at all??
JRST [HRRZS (T2) ;[14000] NO!!! It's bogus, get rid of it!
JRST FIXRF2] ;[14000] Try next one.
SUBI X,(T3) ; RELOCATE IT
HRRM X,(T1) ; AND RESTORE IT
FIXRF2: HRRZ T1,(T2) ; FETCH ADR OF RH REF
JUMPE T1,FIXRF3 ; NONE. TRY NEXT WORD
HRRZ X,(T1) ; FETCH CONTENTS OF REF
CAIGE X,(T5) ;[14000] Check this 'ref'
CAIGE X,(T4) ;[14000] Does it point to this block at all??
JRST [HLLZS (T2) ;[14000] NO!!! It's bogus, get rid of it!
JRST FIXRF3] ;[14000] See if any more
SUBI X,(T3) ; RELOCATE IT
HRRM X,(T1) ; AND RESTORE IT
FIXRF3: AOBJN T2,FIXRF1 ; LOOP FOR ALL REFERENCE WORDS
JRST (L) ; DONE. RETURN TO CALLER
SUBTTL EXPAND - Expand a Block of Core
; CALL: MOVEI N,ADDLEN
; MOVE L,[<OFFSET,,ADRREF>]
; PUSHJ P,EXPAND
; (RETURN)
;
; 'ADDLEN' IS THE # WORDS TO ADD AT END OF BLOCK
; 'OFFSET' IS THE DIFFERENCE BETWEEN THE RH OF 'ADRREF' AND ADDRESS
; OF FIRST DATA WORD IN BLOCK.
; 'ADRREF' IS THE ADDRESS OF THE REFERENCE TO BLOCK.
;
; USES AC X. ALL OTHER ACS PRESERVED.
EXPAND: PUSHJ P,SAVE5 ; SAVE T1-T5
; SEE IF BLOCK TO BE EXPANDED IS LAST IN CORE
HLRZ T1,L ; FETCH OFFSET
ADD T1,(L) ; COMPUTE ADR OF BLOCK
HLRZ T2,B$1PTR(T1) ; FETCH POINTER TO NEXT BLOCK
SKIPE (T2) ; A BLOCK AFTER THIS ONE?
JRST EXPAN1 ; YES, MUST RE-ALLOC. AND BLT
; BLOCK IS AT END OF CORE. JUST EXTEND IT.
;
; ALLOCATE A BLOCK OF 'ADDLEN'-C$NREF WORDS (WHICH IS IMMEDIATELY AFTER BLOCK)
PUSH P,L ; SAVE AC L
MOVEI L,-C$NREF(N) ; FETCH LEN OF ANNEX BLOCK
HRLI L,EXPREF ; EXPREF WILL REFERENCE THE ANNEX BLOCK
SETZM EXPREF ; EXPREF WILL POINT TO FIRST DATA WORD
PUSHJ P,REQM ; ALLOCATE THE ANNEX BLOCK
POP P,L ; RESTORE AC L
MOVE T2,EXPREF ; FETCH ADR OF ANNEX BLOCK
HRLI T2,-C$NREF+1 ; MAKE AOBJN PTR FOR CLEARING ALL REFS
EXPAN0: SETZM B$1PTR(T2) ; CLEAR 2 REFS
AOBJN T2,EXPAN0 ; AND TRY FOR NEXT REF WORD
HLRZ T1,L ; FETCH ADR OF MAIN BLOCK
ADD T1,(L) ; . . .
HLRZ T2,B$1PTR(T1) ; FETCH POINTER TO ANNEX BLOCK
ADDI T2,(N) ; MAKE IT POINT PAST ANNEX BLOCK
HRLM T2,B$1PTR(T1) ; PUT IT BACK IN MAIN BLOCK
JRST GPOPJ ; AND RETURN TO CALLER
; (GARBAGE COLLECTION NEEDED)
; ALLOCATE A BIGGER BLOCK AND BLT OLD BLOCK TO IT
EXPAN1: PUSH P,L ; SAVE AC L
MOVEI L,(T2) ; COMPUTE LENGTH OF OLD BLOCK
SUBI L,(T1) ; . . .
MOVEI T3,(L) ; SAVE LENGTH OF OLD BLOCK
ADDI L,(N) ; COMPUTE NEW LENGTH
HRLI L,EXPREF ; ADR OF REF TO NEW BLOCK
SETZM EXPREF ; REF WILL BE TO FIRST DATA WORD
PUSHJ P,REQM ; ALLOCATE A NEW,BIGGER BLOCK
; BLT OLD BLOCK TO NEW BLOCK
POP P,L ; RESTORE AC L
MOVE T4,EXPREF ; FETCH ADR OF NEW BLOCK
MOVEI X,(T4) ; COPY OF "
HLRZ T1,L ; FETCH 'OFFSET'
ADD T1,(L) ; COMPUTE ADR OF OLD BLOCK
HRLI X,(T1) ; MAKE SOURCE OF BLT POINTER
MOVEI T2,(T3) ; FETCH LENGTH OF OLD BLOCK
ADDI T2,(X) ; END OF DEST
BLT X,-1(T2) ;[12000] BLT !!ONLY!! THE OLD BLOCK TO NEW
; FIX UP THE REFERENCES TO NEW BLOCK
MOVE T2,EXPREF ; FETCH ADR OF NEW BLOCK
SUBI T2,(T1) ; COMPUTE REFERENCE RELOCATION CONSTANT
HRLI T1,-C$NREF ; MAKE AOBJN POINTER FOR LOOP
HLRZ T5,B$1PTR(T1) ;[20000] Fetch add of blk after old one
JRST EXPAN3 ; AND JUMP INTO LOOP FOR FIRST REF
EXPAN2: HLRZ X,B$1PTR(T1) ; FETCH ADR OF LH REF
JUMPE X,EXPAN3 ; NONE. TYR RH REF
HRRZS B$1PTR(T1) ; CLEAR THE REF FROM OLD BLOCK
HRRZ T3,(X) ; FETCH CONTENTS OF REF
CAIGE T3,(T5) ;[20000] Is the ref for real??
CAIGE T3,B$1PTR-C$NREF(T1) ;[20000] ... (not a definitive test)
JRST EXPAN3 ;[20000] It's bogus! skip it
ADDI T3,(T2) ; AND RELOCATE IT
HRRM T3,(X) ; AND RESTORE IT
HRLM X,B$1PTR(T4) ; AND REF TO NEW BLOCK
EXPAN3: HRRZ X,B$1PTR(T1) ; FETCH ADR OF RH REF
JUMPE X,EXPAN4 ; NONE. TRY NEXT REF WORD
HLLZS B$1PTR(T1) ; CLEAR THE REF FROM OLD BLOCK
HRRZ T3,(X) ; FETCH CONTENTS OF REF
CAIGE T3,(T5) ;[20000] Is the ref for real??
CAIGE T3,B$1PTR-C$NREF(T1) ;[20000] ... (not a definitive test)
JRST EXPAN4 ;[20000] It's bogus, skip it
ADDI T3,(T2) ; RELOCATE IT
HRRM T3,(X) ; AND RESTORE CONTENTS
HRRM X,B$1PTR(T4) ; ADD REF TO NEW BLOCK
EXPAN4: MOVEI T4,1(T4) ; INCR PTR TO NEXT REF IN NEW BLOCK
AOBJN T1,EXPAN2 ; AND LOOP FOR ALL REFS OF OLD BLOCK
JRST GPOPJ ; AND RETURN TO CALLER
; (AND FLAG THAT GARBAGE COLLECTION NEEDED)
SUBTTL COMPRS - Compress a Block of Core
; CALL: MOVEI N,<#WORDS> ; # WORDS TO REMOVE FROM END OF BLOCK
; MOVX L,<OFFSET,,ADRREF> ; FOR THE BLOCK
; PUSHJ P,COMPRS
; (RETURN)
;
; SMASHES ACS X,T1-T3
COMPRS: CAIG N,-B$1PTR ; CAN WE COMPRESS THE BLOCK?
POPJ P, ; NO, IT WOULDN'T DO ANY GOOD
; COMPUTE THE ADR OF FIRST DATA WORD IN BLOCK
HLRZ T1,L ; FETCH THE OFFSET
ADD T1,(L) ; ADD TO POINTER INTO BLOCK
MOVS T2,B$1PTR(T1) ; FETCH FIRST WORD OF BLOCK
MOVEI T3,(T2) ; SAVE ADR OF END OF BLOCK +1
SUBI T2,(N) ; COMPUTE NEW END OF BLOCK+1
MOVSM T2,B$1PTR(T1) ; PUT THE WORD BACK IN FIRST WORD OF BLOCK
SETZM (T2) ; CLEAR THE UNNEEDED PART OF BLOCK
MOVEI X,1(T2) ; FORM BLT POINTER TO CLEAR
HRLI X,(T2) ; . . .
BLT X,C$NREF(T2) ; CLEAR THE REFERENCES FOR THE "NEW" BLOCK
HRLZM T3,(T2) ; SET POINTER TO NEXT BLOCK FOR "NEW" BLOCK
POPJ P, ; AND RETURN TO CALLER
SUBTTL SETSTK - INITIALIZE A DYNAMIC STACK
; CALL: STSTK (AC,LEN,REF)
; (RETURN)
;
; SMASHES ACS X,T1,T2,T3,N,L
SETSTK: HLRZ T3,T1 ; FETCH REF ADR
MOVEI L,(T3) ; AND COPY INTO AC L
PUSHJ P,RELM ; RELEASE ANY EXISTING STACK
MOVE L,T1 ; FETCH <REF,,LEN>
PUSHJ P,REQM ; AND ALLOCATE THE NEW STACK
MOVNI X,(T1) ; FETCH -LEN
HRLOI X,(X) ; FORM "IOWD LEN,0"
ADD X,(T3) ; FINISH THE PDP
POP P,T2 ; POP OUR RETURN ADR
MOVEM X,(N) ; INITIALIZE THE PDP POINTER
PUSH P,T2 ; PUSH OUR RETURN ADR
HRL N,T1 ; FORM <LEN,,AC>
HRLM N,B$2PTR+1(X) ; BIND AC TO PDL
MOVEI L,(T3) ; FETCH ADR OF REF
PJRST ADDPDL ; AND ADD PDL TO THE PROTECTED PDL LIST
; AND RETURN TO CALLER
SUBTTL ADDPDL - Add a PDL to PDLTAB
; CALL: MOVE N,[<INCREMENTAL LENGTH,,ADR>]
; MOVE L,[<OFFSET,,ADRREF>]
; PUSHJ P,ADDPDL
; (RETURN)
;
; NOTE: ARGUMENTS ARE DESCRIBED IN THE 'FNDPDL' ROUTINE.
;
; USES ACS X,T1,T2
ADDPDL: PUSHJ P,FNDPDL ; SEE IF THE PDL ALREADY EXISTS
JUMPE T1,[ERROR (PTS)] ; NO, AND THERE'S NO MORE ROOM!!
MOVEM N,(T1) ; STORE <INC. LEN.,,ADR> IN PDLTAB
MOVEM L,C$NPDL(T1) ; STORE <OFFSET,,ADRRES> IN PDLTAB
POPJ P, ; AND RETURN TO CALLER
SUBTTL DELPDL - Remove a PDL from PDLTAB
; CALL: MOVEI N,ADR
; PUSHJ P,DELPDL
; (RETURN)
;
; NOTE: ARGUMENTS ARE DESCRIBED IN THE 'FNDPDL' ROUTINE
DELPDL: PUSHJ P,FNDPDL ; FIND THE PDL IN PDLTAB
POPJ P, ; NOT THERE. GOOD, SAVES US THE TROUBLE
SETZM (T1) ; KNOCK THE PDL OUT OF PDLTAB
POPJ P, ; AND RETURN TO CALLER
SUBTTL FNDPDL - Find a PDL in PDLTAB
; CALL: MOVEI N,ADR
; PUSHJ P,FNDPDL
; (FAIL RETURN) ; AC T1 POINTS TO FIRST FREE ENTRY
; OR IS ZERO IF PDLTAB IS FULL
; (SUCCESS RETURN) ; AC T1 POINTS TO PDL ENTRY IN PDLTAB
;
; PDLTAB:
; ----------------------------------------------
; ! INCREMENTAL LENGTH ! ADR !
; !--------------------------------------------!
; / . . . /
; !--------------------------------------------!
; ! OFFSET ! ADRREF !
; !--------------------------------------------!
; / . . . /
; ----------------------------------------------
;
;
; 'INCREMENTAL LENGTH' IS THE # WORDS ADDED TO PDL ON EACH POV.
;
; 'ADR' IS THE ADDRESS OF PDP FOR THE DESIRED PDL.
;
; 'ADRREF' IS THE ADDRESS OF REFERENCE TO THE PDL.
;
; 'OFFSET' IS THE DIFFERENCE BETWEEN THE RH OF ADRREF AND THE
; ADDRESS OF FIRST WORD OF PDL.
;
; USES ACS X,T1,T2
FNDPDL: MOVE T1,[IOWD C$NPDL,PDLTAB+1] ; AOBJN PTR FOR SEARCHING
; THROUGH PDLTAB
SETZ T2, ; IN CASE THERE ARE NO FREE ENTRIES
FNDPD1: HRRZ X,(T1) ; FETCH 'ADR' OF A PDL ENTRY FROM PDLTAB
CAIN X,(N) ; IS IT THE 'ADR' WE WANT?
JRST CPOPJ1 ; YES
SKIPN (T1) ; NO, IS IT A FREE ENTRY?
MOVEI T2,(T1) ; YES, REMEMBER ITS ADDRESS
AOBJN T1,FNDPD1 ; LOOP FOR ALL ENTRIES IN PDLTAB
MOVEI T1,(T2) ; CAN'T FIND DESIRED PDL. RETURN FF ADR.
POPJ P, ; AND GIVE FAIL RETURN TO CALLER
SUBTTL APRTRP - APR Trap handler (POV Recovery)
APRTRP: MOVEM 17,ACSAVE+17 ; SAVE AC 17
MOVEI 17,ACSAVE ;[12000] Build BLT argument
BLT 17,ACSAVE+16 ;[12000] don't save 17 again but save all others
MOVE 17,ACSAVE+17 ;[12000] restore it instead
; Find out what hit us
MOVE X,.JBCNI ; FETCH REASON FOR APR TRAP
TXNE X,AP.ILM ;[420] IS IT BECAUSE OF ILL MEM REF?
ERROR (ILM) ;[420] YES, REPORT IT TO LUSER
TXNN X,AP.POV ; IS IT BECAUSE OF PDL OVERFLOW?
ERROR (UAT) ; NO. ** UNENABLED APR TRAP **
; SETUP TEMP CONTROL PDP
MOVE P,[IOWD C$TPDL,TPDL] ; SETUP TEMP PDL PDP
MOVEI N,P ; CHANGE THE PDL ENTRY IN PDLTAB FOR
PUSHJ P,FNDPDL ; THE CONTROL PDL
ERROR (MCP) ; ** MISSING CONTROL PDL **
MOVEI X,ACSAVE+P ; TO POINT TO ACSAVE+P
HRRM X,(T1) ; WHERE THE REAL P IS HIDDEN
MOVEI T3,(T1) ; SAVE 'P' INDEX INTO PDLTAB TO SAVE TIME
MOVE T5,PDL ; FETCH ADR OF CONTROL PDL
HRLM X,B$2PTR(T5) ; AND REFERENCE ACSAVE+P TO IT
; FIND THE PDP WHICH CAUSED THE OVERFLOW
MOVE T1,[IOWD C$NPDL,PDLTAB+1] ; FOR LOOPING THROUGH PDLTAB
APR1: SKIPN T2,(T1) ; A NULL ENTRY IN PDLTAB?
JRST APR2 ; YES, IGNORE IT
SKIPL (T2) ; NO, IS THIS THE OVERFLOWED PDL?
JRST APR3 ; YES. STOP THE SEARCH
APR2: AOBJN T1,APR1 ; NO, KEEP SEARCHING THROUGH PDLTAB
ERROR (CFP) ; ** CAN'T FIND OVERFLOWED PDL **
; AC T1 POINTS TO PDLTAB ENTRY FOR PDL THAT OVERFLOWED
;
; EXPAND THE PDL THAT OVERFLOWED
APR3: HLRZ N,(T1) ; FETCH THE INCREMENTAL LENGTH FOR PDL
MOVE L,C$NPDL(T1) ; FETCH <OFFSET,,ADRREF> FOR PDL
PUSHJ P,EXPAND ; AND EXPAND THE PDL
; PATCH UP THE PDP (IE: RESTORE -VE COUNT TO LH)
MOVNI N,(N) ; COMPUTE -VE OF INCREMENTAL LENGTH
HRLM N,(T2) ; AND FIX UP THE PDP
MOVEI X,P ; FETCH ADR CONTROL PDP
HRRM X,(T3) ; AND STORE IN ITS PDLTAB ENTRY
MOVE T5,PDL ; FETCH ADR OF CONTROL PDL
HRLM X,B$2PTR(T5) ; AND REFERENCE AC P TO IT
; RESTORE ACS X,T1-T5,N,L,P
MOVE P,ACSAVE+P ; RESTORE AC P
MOVE L,ACSAVE+L ; RESTORE AC L
MOVE N,ACSAVE+N ; RESTORE AC N
MOVE X,[<ACSAVE+T1,,T1>] ; RESTORE ACS T1-T5,X
BLT X,X ; ALL IN TWO INSTRUCTIONS
; RETURN TO POINT OF CALL
JRST @.JBTPC ; RETURN TO POINT OF CALL
SUBTTL UUOTRP - LUUO Handler
UUOTRP: PORTAL .+1 ;[325] IN CASE OF LOWSEG LUUO
LDB X,[POINT 9,.JBUUO,8] ; FETCH THE LUUO OPCODE
CAIN X,LUUERR ; IS IT AN ERROR CALL?
JRST ERRHAN ; YES, GOTO THE ERROR HANDLER
CAIN X,LUUCER ; NO, IS IT A ":" ERROR CALL?
JRST CERR ; YES
CAIN X,LUUCR1 ; IS IT SPECIAL ":" ERROR CALL?
JRST CER1 ; YES
CAIN X,LUUWRN ; IS IT A WARNING CALL?
JRST WARHAN ; YES
CAIN X,LUUCEO ; IS IT A "CHECK EO VALUE" CALL?
JRST CEO ; YES
ERROR (IUU) ; NO, ** ILLEGAL LUUO **
; CER1 - POP TOP OF STACK AND FALL INTO CERR1
CER1: POP P,X ; POP TOP OF STACK
; JRST CERR ; AND FALL INTO CERR
; CERR - GIVE ERROR MSG IF ":" FLAG OFF, ELSE GIVE FAIL RETURN
CERR: TXNN F,F$COL ; IS THIS A ":" MODIFIED COMMAND?
JRST ERRHAN ; NO, GIVE AN ERROR MESSAGE
POP P,X ; YES, CLEAN UP THE STACK
JRST FAIRET ; AND GIVE A "FAIL" RETURN
; WARHAN - GIVE A WARNING MESSAGE
WARHAN: MOVEI C,"%" ; MESSAGE STARTS WITH "%"
JRST ERRH1 ; JUMP INTO MESSAGE HANDLER
; CEO - JUMP TO SPECIFIED ADR IF A FEATURE IS DISABLED
CEO: LDB X,[POINT 4,.JBUUO,12] ; FETCH # FROM LUUO CALL
CAMG X,EOVAL ; IS THAT FEATURE ENABLED?
POPJ P, ; YES, RETURN TO POINT OF CALL PLUS ONE
POP P,X ; NO, CLEAN UP PDL...
JRST @.JBUUO ; AND JUMP TO THE SPECIFIED ADR
SUBTTL REENTR - Reenter Processing (after ^C^C.REENTER)
REENTR: PORTAL .+1 ;[363] KI/KL RE-ENTRY GATEKEEPER
TXO F,F$REE ;[317] WE'LL STOP AFTER THIS CMD IS DONE
JRST @.JBOPC ;[317] BUT CONTINUE LEST WE SCREW UP
; RESTRT - RESTART AFTER ^C
RESTRT: PORTAL .+1 ;[375] KI/KL ENTRY GATEKEEPER
RESET ;[375] RESET THE WORLD
STORE (X,LOWBEG,LOWEND,0) ;[375] CLEAR LOWSEG
;[15000] Loses if run a saved XTEC program & restart & LOSEG name different
; MOVX X,<-1,,.GTPRG> ;[375] GET MY PROGRAM NAME
; GETTAB X, ;[375] ONLY SURE WAY
; MOVX X,'XTEC ' ;[375] ???
; MOVEM X,SEGNAM ;[375] SAVE "SEGMENT NAME"
SETZ F, ;[375] CLEAR ALL FLAGS
JRST $XTEC ;[375] CONTINUE "START"
SUBTTL ERRHAN - Error Handler
ERRHAN:
FOR TOPS10!TOPS20,<
CLRBFI ; CLEAR TYPE-AHEAD
>
ECHO ON ;[21000] Turn echo on, regardless
MOVEI C,"?" ; MESSAGE STARTS WITH A "?"
ERRH1: PUSH P,N ; SAVE AC N
PUSH P,M ; AND AC M
PUSH P,C ;[12000] Save the prefix character
MOVEI N,ERRPRE ;[12000] Error message prefix characters
PUSHJ P,TXSTR ;[12000] with no reformatting
POP P,C ;[12000] Get back the prefix character
SETZM OUTADR ; FORCE OUTPUT TO USER'S TERMINAL
SETZM INPADR ; GO BACK TO TTY FOR INPUT
SETZM INPCHR ; . . .
TXZ F,F$NTI ; . . .
PUSHJ P,TCHR ; TYPE THE LEADING MESSAGE CHAR
MOVE T5,EHVAL ; FETCH MESSAGE LENGTH
TXNN T5,JW.WPR ; TYPE PREFIX?
JRST ERRH3 ; NO, SKIP THE PREFIX
; PREFIX TO MESSAGE (IE: 'TEC???')
HRRZ N,.JBUUO ; FETCH '???' OF THE ERROR CALL
CAIN N,'ILM' ;[420] ILL MEM REF?
SETZM PTVAL ;[420] .:=0
HRLI N,'TEC' ; FETCH THREE CHAR ABBREV. FOR NAME
PUSHJ P,TSIX ; AND TYPE THE PREFIX ('TEC???')
TXNN T5,JW.WFL ; WANT MESSAGE TOO?
JRST ERRH88 ; NO, DONE WITH MESSAGE TYPING
ERRH2: MOVEI N,[ASCIZ/ -/] ; YES, TYPE A DASH BETWEEN PREFIX AND IT
PUSHJ P,TSTR ; . . .
; MUST GETSEG <C$ERRS> TO TYPE LONG MESSAGES
ERRH3: PUSH P,[<ERRH99>] ; SAVE RETURN ADR
IFE FTXTEC&FTXTCERR,<
MOVE X,[ERRSEG:<C$ERRS>] ; FETCH NAME OF ERROR SEGMENT
MOVEM X,GSGNAM ; AND STORE IN GETSEG BLOCK
PUSH P,[<XTCERR>] ; FETCH ADR OF WHERE TO GO IN XTCERR
PJRST GETSG ; AND GO TO THE ERROR SEGMENT
>
IFN FTXTEC&FTXTCERR,<
PJRST ERMT
>
ERRH88: PUSHJ P,TCRLF ; GO TO A NEW LINE
ERRH89: LDB X,[POINT 9,.JBUUO,8] ; FETCH ERROR OPCODE
CAIN X,LUUWRN ; A WARNING?
JRST ERRH94 ;[416] YES, NEVER EXIT
MOVE X,ETVAL ;[12000] Check abort flag (initially set)
TXNE X,ET$ABO ;[12000] Go to monitor if set
JRST [PUSHJ P,FOUT ;[20000] Make sure he sees the message
MONRT. ;[20000] STOP
JRST .+1] ;[20000] he musta typed continue
ERRH94: MOVEI N,PROMPT ; TYPE FAKE PROMPT CHAR
PUSHJ P,TXSTR ; . . .
PUSHJ P,GETCH ; AND PEEK AT FIRST CHAR
CAIN C,"/" ; WANT MORE OF MESSGAE?
JRST ERRH2 ; YES
CAIE C,"?" ; NO, WANT LAST TEN COMMANDS?
JRST ERRH98 ; NO, DONE
; TYPE LAST TEN COMMANDS
PUSHJ P,ERRCTY ; TYPE LAST 10 COMMANDS
JRST ERRH89 ; AND GO BACK FOR MORE
; SAVE THE CHAR WE PEEKED AT
ERRH98: MOVEM C,INPCHR ;SAVE THE CHAR WE PEEKED AT
; FINISH UP WITH MESSAGE TYPING
ERRH99: MOVEI N,ERRPOS ;[12000] Output the error posfix characters
PUSHJ P,TXSTR ;[12000] with no reformatting
LDB X,[POINT 9,.JBUUO,8] ; FETCH OPCODE OF LAST MSG CALL
POP P,M ; RESTORE AC M
POP P,N ; RESTORE AC N
CAIN C,.CHBEL ;[14000] ^G stops us even in a warning
JRST [SETZM INPCHR ;[14000] This is not command input
MOVEI X,OUT ;[20000] Flush output file?
TXNN F,F$UWR ;[20000] Unless there is supposed to be one
RESDV. X, ;[20000] ...
JFCL ;[20000] ....
JRST ERRREC] ;[14000] Go back to command level
CAIN X,4 ; WAS IT A WARNING CALL?
POPJ P, ; YES, RETURN TO CALLER
; ERRREC - RECOVER FROM AN ERROR
ERRREC: SETZM MACLVL ; CLEAR THE MACRO NESTING LEVL COUNT
;[14000] Leave the poor Q-register PDL alone!
; STSTK (QP,C$QPLN,QPDL) ; REINITIALIZE THE
; Q-REGISTER PDL
; MOVE X,QP ; FETCH THE PDP FOR QPDL
; PUSH X,[<0>] ; AND PUSH 3 ZEROS TO MARK BEGINNING
; PUSH X,[<0>] ; . . .
; PUSH X,[<0>] ; . . .
; MOVEM X,QP ; AND STORE THE UPDATED PDP
SETZM INPADR ; CLEAR THE ADR OF GET-A-CHAR ROUTINE
TXZ F,F$NTI ; CLEAR SOME FLAGS
SKIPN X,MACBUF ; MACBUF POINT TO SOMETHING?
JRST ERRR1 ; NO
HRRZS T$1REF(X) ; YES, UNBIND IT
SETZM T$ACRF(X) ; AND UNBIND THE AC REFS
SETZM MACBUF ; CLEAR MACBUF
MOVE N,CMDBID ; AND UNBIND THE CURRENT COMMAND BUFFER
PUSHJ P,DELBLK ; . . .
ERRR1: MOVE T5,@PDL ; FETCH TOP LEVEL RETURN ADR
STSTK (P,C$PDLL,PDL) ; REINITIALIZE THE CONTROL PDL
;;; JRST (T5) ; AND RETURN TO TOP LEVEL
JRST BEGIN ;[13000] Sometimes, you can't trust
;[13000] even the base of the stack
; (WHOEVER THAT IS!)
>;; FOR FTXTEC
FOR FTXTEC!FTXTCERR,<
SUBTTL ERCTY - TYPE LAST FEW COMMANDS AFTER AN ERROR
; LAST 10 (OR SO) CHARS FROM COMPIILATION ERRORS
;
; LAST 10 COMMANDS FOR EXECUTION ERRORS
ERRCTY:
TXNE F,F$CMP ;[4000] WERE WE COMPILING?
;[4000] SKIPN MACLVL ; COMPILATION ERROR?
JRST ERRCTC ; YES
; TYPE LAST 10 COMMANDS FOR EXECUTION ERRORS
MOVE T2,TENIDX ; FETCH POINTER TO LAST COMMAND
MOVEI T4,^D10 ; FETCH LOOP COUNTER
ERRCT1: MOVEI T2,1(T2) ; POINT TO NEXT COMMAND
IDIVI T2,^D10 ; FORM INDEX INTO 'TENCMD'
MOVEI T2,(T3) ; . . .
MOVE N,TENCMD(T3) ; FETCH INFO ABOUT COMMAND
JUMPE N,ERRCT2 ; IGNORE IF NULL
PUSH P,T2 ; SAVE AC T2 FROM 'TMSG'
PUSHJ P,TMSG ; TYPE THE COMMAND
POP P,T2 ; RESTORE AC T2
ERRCT2: SOJG T4,ERRCT1 ; LOOP FOR ALL 10 COMMANDS
; DONE. TYPE ?<CR><LF> AND RETURN TO CALLER
ERRCT3: MOVEI N,[ASCIZ/?
/] ; TYPE ?<CR><LF>
PJRST TSTR ; AND RETURN TO CALLER
;Type text up to error [12000] FOR A COMPILATION ERROR
ERRCTC: PUSHJ P,CURCHA ; FETCH CURRENT POSITION IN COMMAND STRING
MOVEI T4,-T$DATA*5(T1);[12000] Character count is all but ovhd words
MOVE T1,[POINT 7,T$DATA] ;[12000] Pointer to start of buffer
ADD T1,@CMDBUF ;[12000] once we add in the address, that is
ERRCC2: ILDB C,T1 ; FETCH A COMMAND STRING CHAR
PUSHJ P,TCCHR ; AND TYPE IT
SOJG T4,ERRCC2 ; AND TYPE UP TO 10 CHARS
JRST ERRCT3 ; DONE. FINISH UP AND RETURN TO CALLER
>;; END FOR FTXTEC!FTXTCERR
FOR FTXTEC,<
SUBTTL SAVPCM - SAVE LAST COMMAND STRING IN A Q-REGISTER
SAVPCM: PUSHJ P,GETCH ; FETCH THE NEXT CHAR
CAIN C,"(" ; IS IT A LONG Q-REGISTER NAME?
JRST SAVPC3 ; YES
CAIG C,172 ;[12000] Any SIXBITable character will do
CAIGE C,40 ;[12000]
JRST SAVOOPS ;[12000] no good
SAVPC1: CAIL C,140 ;[14000] Make upper case if necessary
MOVEI C,-40(C) ;[14000] it was...
MOVSI N,'A'-"A"(C) ; PUT SIXBIT CHAR IN AC N
LSH N,^D12 ; AND LEFT JUSTIFY IT
SAVPC2: PUSH P,N ; SAVE THE Q-REGISTER NAME
SKIPN N,CMDBID ; FETCH THE BUFFER ID OF LAST COMMAND
JRST BEGIN1 ; OOPS! NO PREVIOUS COMMAND (IGNORE IT)
SETZ L, ; SO THAT AC T1 WILL POINT TO BUFFER
PUSHJ P,FNDBLK ; FIND THE LAST COMMAND BUFFER
JRST BEGIN1 ; GONE. FORGET IT!
AOS T$RCNT(T1) ; INCR. REFERENCE COUNT FOR BUFFER
POP P,T1 ; RESTORE THE Q-REGISTER NAME
PUSHJ P,QGET ;[12000] fetch old one if any
SETZB T2,T3 ;[12000] none there
TXO T2,QB$BID ; SET THE "BID" BIT
HRR T2,CMDBID ;[12000] BID moved ; FETCH THE BUFFER ID
TXZ F,F$REF ; FLAG THAT T3 HAS A BUFFER ID
PUSHJ P,QSTOR ; AND STORE THE BUFFER IN Q-REGISTER
JRST BEGIN1 ; AND CONTINUE WHERE WE LEFT OFF
; SCAN A FANCY Q-REGISTER NAME
SAVPC3: PUSHJ P,GSIX ; PICK UP THE Q-REGISTER NAME
PUSHJ P,GCHR ; SCAN THE NEXT CHAR
CAIE C,")" ; IS IT A ")"?
SAVOOPS: ERROR (IQR) ;[20000] no good, but he can try again
JRST SAVPC2 ; YES, CONTINUE
>;; END FOR FTXTEC
FOR FTXTEC!FTXTCERR,<
SUBTTL Phased (sometimes) Pure Low Segment Code
RELOC 0 ; DOWN TO THE LOW SEGMENT
LOCODE: ; DEFINE WHERE LOW SEGMENT CODE GOES
IFN TOPS10,< ; No Performance Advantage to this on a 20
RELOC ; BACK TO THE HIGH SEGMENT
HICODE: ; DEFINE START OF PHASED CODE
PHASE LOCODE ; KEEP IN PHASE WITH THE LOWSEGMENT
>
; GETSG - ROUTINE TO TRANSFER CONTROL BETWEEN CONTROL AND ERROR SEGMENT
GETSG: MOVEM 17,ACSAVE+17 ; SAVE AC 17
MOVEI 17,ACSAVE ; Set up BLT pointer
BLT 17,ACSAVE+16 ; SAVE ALL ACS
RUNENT: TDZA X,X ;[15000] Not CCL entry
MOVX X,<F$CCL> ;[15000] It is a CCL entry
IORM X,ACSAVE ;[15000] Set it if we entered that way
; it will not be cleared if we didn't
MOVE X,.JBSA ; SAVE START ADR
MOVEM X,SADSAV ; . . .
MOVE X,.JBREN ; SAVE REENTER ADR
MOVEM X,RENSAV ; . . .
MOVSI 1,1 ; RELEASE CURRENT SEGMENT
CORE 1, ; . . .
JFCL ; (WHY SHOULD IT FAIL?)
MOVEI 1,GSGBLK ; LOAD ADR OF GETSEG ARG BLOCK
GETSEG 1, ; GETSEG THE DESIRED SEGMENT
>;; END FOR FTXTEC!FTXTCERR
FOR FTXTEC,<
JRST GTSGF ;[322] GETSEG FAILED
>;; END FOR FTXTEC
FOR FTXTCERR,< NOTFOR FTXTEC&FTXTCERR,<
HALT .-1 ;[325] GETSEG FAILED FOR XTEC
>>;; END FOR FTXTCERR ...
FOR FTXTEC!FTXTCERR,<
MOVE X,SADSAV ; RESTORE START ADR
MOVEM X,.JBSA ; . . .
MOVE X,RENSAV ; RESTORE REENTER ADR
MOVEM X,.JBREN ; . . .
MOVSI 17,ACSAVE ; RESTORE ACS
BLT 17,17 ; . . .
POPJ P, ; AND PROCEED
GTSGF: MOVE X,SEGNAM ;[322] ATTEMPT TO GET XTEC BACK
MOVEM X,GSGNAM ;[322] SET NAME TO XTEC
MOVEI 1,GSGBLK ;[322] LOAD ADDR OF GETSEG ARG BLOCK
GETSEG 1, ;[322] GET XTEC BACK
HALT .-1 ;[322] WE'RE LOST
MOVEI N,SEGERR ;[364] TYPE ERROR MESSAGE
PUSHJ P,TXSTR ;[16000] Type in correct order, please
MOVE X,SADSAV ;[322] RESTORE START ADR
MOVEM X,.JBSA ;[322] . . .
MOVE X,RENSAV ;[322] RESTORE REENTER ADR
MOVEM X,.JBREN ;[322] . . .
MOVSI 17,ACSAVE ;[322] RESTORE ACS
BLT 17,17 ;[322] . . .
POP P,X ;[322] DROP PDP
POP P,X ;[322] . . .
JRST <IFDEF ERRH88,<ERRH88>> ;[325] CONTINUE AS IF NOTHING HAPPENED
SEGERR: ASCIZ/
?XTCERR - CANNOT GETSEG ERROR SEGMENT/
IFNDEF $GCHRW,<$GCHRW==<$GCHR0==0>> ;This is for TECERR
INTRPT: ;[20000] (next 20 lines) .JBINT sent us here
EXCH X,INTBLK+3 ; Look at bits
TLNE X,777775 ; Anything but ^C?
ERROR (XXX) ; CHOKE
MOVE X,ETVAL ; Are we supposed to care about this?
TXZN X,ET$CCT ; ...
JRST INTRPN ; program doesn't want it
MOVEM X,ETVAL ; program does, in fact.
HRRZ X,INTBLK+2 ; See if we are waiting for ^T
CAIN X,$GCHRW ; ...
MOVEI X,$GCHR0 ;[20000] Re-try the held character
HRRM X,INTBLK+2 ;[20000] by backing up a bit...
MOVEI X,3 ; And stuff a ^C in there
MOVEM X,INPCHR ; This way so non-blocking ^T works too.
INTRPZ: EXCH X,INTBLK+3 ; Restore AC
JRST @INTBLK+2 ; Continue execution
INTRPN: MONRT. ; Stop here
JRST INTRPZ ; continue execution
;note that the block is not zeroed, so we won't come here again
;unless he sets 32768ET again
GSGBLK: ; ARG BLK FOR GETSEG MUUO
GSGDEV: FOR TOPS10,0 ; THE DEVICE NAME
FOR TOPS20,'SYS '
GSGNAM: FOR TOPS10,0 ; THE SEGMENT NAME
FOR TOPS20,'TECO20'
GSGLOW: 0 ; FILE EXTENSION FOR LOW FILE
0 ; WE DON'T USE THIS
GSGPPN: 0 ; THE SEGMENT PPN
0 ; WE DON'T USE THIS
GSGPAT: REPEAT .PTMAX,<0> ;[15000] GETSEG path block
; TEMP STORAGE FOR GETSEG ROUTINE
SADSAV: BLOCK 1 ; SAVE AREA FOR .JBSA
RENSAV: BLOCK 1 ; SAVE AREA FOR .JBREN
;Interrupt block for .JBINT
INTBLK: BLOCK 4 ;[20000]
TSTOPS: EXP 10,20,30,40,50,60,70,100,110,120,130,140,150,160,170,200
REPEAT <C$NTS-<.-TSTOPS>>,<Z> ;[21000] Tab stops go here
LOCEND==. ; DEFINE END OF LOWSEGMENT CODE
FOR TOPS10,<
DEPHASE ; BACK TO HISEG RELOCATABLE CODE
>
SUBTTL Impure Low Segment Data
IFN TOPS10,<
RELOC LOCEND-LOCODE ; RELOC TO LOWSEG AFTER CODE
>
LOWBEG: ; DEFINE BEGINNING OF IMPURE LOWSEG DATA
CCJNAM: BLOCK 1 ; OUR CCL JOB NUMBER (IE: '###XTC')
SEGNAM: BLOCK 1 ; NAME OF CONTROL SEGMENT
SBNAME: BLOCK 1 ; HOLDS A SIXBIT NAME
PDL: BLOCK 1 ; CONTROL PUSHDOWN STACK
TPDL: BLOCK C$TPDL ; TEMP PDL FOR APRTRP ROUTINE
ACSAVE: BLOCK ^D16 ; SAVE AREA FOR ACS
TENIDX: BLOCK 1 ; INDEX INTO 'TENCMD'
TENCMD: BLOCK ^D10 ; INFO IN LAST 10 COMMANDS EXECUTED
HEAD: BLOCK 1 ; POINTER TO FIRST BLOCK OF DYNAMIC STORAGE
GSIZE: BLOCK 1 ; #WORDS ALLOCATED SINCE LAST GARBAGE COLLECTION
PDLTAB: BLOCK 2*C$NPDL ; TABLE OF THE PDLS THAT ARE
; OVERFLOW PROTECTED
TMPREF: BLOCK 1 ; USED AS A TEMPORARY REFERNCE
; TO A BLOCK
TMPRFG: BLOCK 1 ; TEMP REF TO TEXT BUFFER FOR $G ROUTINE
EXPREF: BLOCK 1 ;[12000] TEMP REF FOR EXPAND
TXREF: BLOCK 1 ;[12000] TEMP REF FOR $X
TAGPDL: BLOCK 1 ; POINTER TO TAG DEFINITION PDL
FRDREF: BLOCK 1 ; REFERENCE TO FILE-READ BUFFER
REFPDL: BLOCK 1 ; POINTER TO TAG REFERENCE PDL
LNKLST: BLOCK 2 ; POINTERS FOR LINKED LIST
LNKID: BLOCK 1 ; COUNTER FOR ASSIGNING NEW LINKED-LIST IDS
QTAB: BLOCK 1 ; POINTER TO Q-REGISTER TABLE
QPDL: BLOCK 1 ; POINTER TO Q-REGISTER PDL
QR: BLOCK 1 ; Q-REGISTER TABLE PDP
QP: BLOCK 1 ; Q-REGISTER PDL PDP
CMDBID: BLOCK 1 ; BUFFER ID FOR CURRENT COMMAND BUFFER
PCMBID: BLOCK 1 ; BUFFER ID FOR PREVIOUS COMMAND
CURCMD: BLOCK 1 ; POINTER TO CURRENT COMMAND BUFFER
CMDCNT: BLOCK 1 ; COUNT OF CHARS LEFT IN COMMAND BUFFER
; DURING SCAN
CMDBP: BLOCK 1 ; RELATIVE BYTE POINTER TO COMMAND BUFFER
; DURING SCAN
CMDBUF: BLOCK 1 ; ADR OF REF TO COMMAND BUFFER DURING
; DECODE&COMPILE AND EXECUTION
LASSPC: BLOCK 1 ; ADR OF LAST FILE SPEC REFERENCED
RUNOFS: BLOCK 1 ; RUNOFFSET FOR WHEN WE RUN A PROGRAM
RBSPC: BLOCK .RBSTS+1 ; EXTENDED LOOKUP/RENAME/ENTER ARG BLOCK
FILSPC: BLOCK FS$LTH ; FILE SPEC BLOCK FOR CDC
LERSPC: BLOCK FS$LTH ; LAST "ER" FILE-SPEC
LEWSPC: BLOCK FS$LTH ; LAST "EW" OR "EA" FILE-SPEC
LEBSPC: BLOCK FS$LTH ; LAST "EB" FILE-SPEC
LEISPC: BLOCK FS$LTH ; LAST "EI" OR "EP" FILE-SPEC
LEESPC: BLOCK FS$LTH ; LAST "EE" FILE SPEC
LRPSPC: BLOCK FS$LTH ; LAST "E&" FILE-SPEC
LELSPC: BLOCK FS$LTH ;[330] LAST "EL" FILE-SPEC
LREERR: BLOCK 1 ; LAST LOOKUP/RENAME/ENTER ERROR CODE
INIBH: BLOCK C$BFHD ; BUFFER HEADER FOR INI FILES
INIBF: BLOCK C$NBUF*<C$BUFL+3> ; BUFFERS FOR INI FILES
LOGBH: BLOCK C$BFHD ;[330] LOG FILE BUFFER HEADER
LOGBF: BLOCK C$NBUF*<C$BUFL+3> ;[330] LOG FILE BUFFER
OUTADR: BLOCK 1
INPADR: BLOCK 1 ; WHERE TO GO FOR INPUT CHAR
IOSTS: BLOCK 1 ; I/O STATUS FOR LAST I/O ERROR
OUTBH: BLOCK C$BFHD ; BUFFER HEADER FOR OUTPUT
OUTBF: BLOCK C$NBUF*<C$BUFL+3>; OUTPUT BUFFERS
INPBH: BLOCK C$BFHD ; BUFFER HEADER FOR INPUT
INPBF: BLOCK C$NBUF*<C$BUFL+3> ; INPUT BUFFERS
INPCHN: BLOCK 1 ; CURRENT INPUT CHANNEL (Z CH,0)
INPEOF: BLOCK 1 ; ADR OF WHERE TO GO ON INPUT EOF
INPERR: BLOCK 1 ; ADR OF WHERE TO GO ON INPUT ERROR
INPCHR: BLOCK 1 ; LAST INPUT CHAR IF IT IS TO BE REPEATED
PATHB: BLOCK .PTMAX ;[340] BLOCK FOR PATH. UUO
; FLAGS SET/CLEARED BY "E" COMMANDS
EDVAL: BLOCK 1 ;[12000] ED flags
ETVAL: BLOCK 1 ; SUBSTITUTION ON TYPEOUT FLAG
EOVAL: BLOCK 1 ; EDIT OLD FLAG
EUVAL: BLOCK 1 ; CASE FLAGGING ON TYPEOUT FLAG
EHVAL: BLOCK 1 ; ERROR MESSAGE LENGTH FLAG
ESVAL: BLOCK 1 ; AUTOMATIC TYPEOUT AFTER SEARCH FLAG
; SEARCH ARGUMENTS AND MATRIX
SRHARG: BLOCK C$SRHL/5 ; TEXT OF LAST SEARCH ARGUMENT
SRHCTR: BLOCK 1 ; COUNT OF CHARS IN SRHARG
SRHLEN: BLOCK 1 ; THE LENGTH OF THE LAST SEARCH MATCH
SRHSMP: BLOCK 1 ; BIT POINTER TO THE LAST POSITION
; IN THE SEARCH MATRIX
SRHTAB: BLOCK SRHLN ; THE SEARCH MATRIX
;[23000] Permanent Q-register table
QREG: BLOCK <100*2> ;[23000] Single-letter q-registers
; THE MAIN TEXT EDITING BUFFER
TXTBUF: BLOCK 1 ; POINTER TO THE MAIN TEXT EDITING BUFFER
PTVAL==QREG+1 ; CURRENT BUFFER POSITION POINTER
PAGCNT: BLOCK 1 ; CURRENT PAGE NUMBER
MKRMBP: BLOCK 1 ; BYTE POINTER FOR STORING LAST PARTIAL
; WORD IN THE "MAKE ROOM" ROUTINE
MKRMB1: BLOCK 1 ; SAME AS ^ BUT FOR DOWNWARD MOVE
APDADR: BLOCK 1 ; ADR OF READ-A-CHAR ROUTINE
APDFLG: BLOCK 1 ; CURRENT INPUT I/O FLAGS
PCHADR: BLOCK 1 ; ADR OF WRITE-A-CHAR ROUTINE
PCHFLG: BLOCK 1 ; CURRENT OUTPUT I/O FLAGS
LSNCTR: BLOCK 1 ; HOLDS A LINE-SEQUENCE NUMBER
LSNCT1: BLOCK 1 ; COUNTS DIGITS FOR AN LSN
; VARIABLES FOR MACRO CALLS
MACFLG: BLOCK 1 ;[344] FLAG FOR MACRO W/ ARGUMENTS
MACNAM: BLOCK 1 ; Q-REGISTER NAME OF CURRENT MACRO
MACBID: BLOCK 1 ; BUFFER ID FOR CURRENT MACRO
MACLVL: BLOCK 1 ; NESTING LEVEL COUNTER FOR MACROS
MACBUF: BLOCK 1 ; REFERENCE TO TEMP BUFFER
SARGSV==ACSAVE+SARG ;[3000] PLACE TO SAVE SARG SO IT CAN BE PASSED TO A MACRO
DELIM: BLOCK 1 ;[12000] Default text delimiter
CDELIM: BLOCK 2 ;[12000] command delimiter (up to 2 chars, unpacked)
CWVEC: ;[12000] :W stuff starts here
WFLAGS: BLOCK 1 ;[12000] :W flags
WIDTH: BLOCK 1 ;[12000] Width of terminal
LENGTH: BLOCK 1 ;[12000] Length of terminal
DPYALL: BLOCK 1 ;[12000] 'DISPLAY ALL' mode
MARK: BLOCK 1 ;[12000] MARK pointer value
HOLD: BLOCK 1 ;[12000] scroll if within n lines of border
F0:
WINB: BLOCK 1 ;[14000] Start of window
BLOCK 12 ;[14000] Reserved
DMODE: BLOCK 1 ;[12000] Display mode bits
SCFWD: BLOCK 1 ;[10000] # of linefeeds typed at bottom
SCREV: BLOCK 1 ;[12000] # of reverse
PROMSZ: BLOCK 1 ;[14000] # of character positions for prompt
RLF: BLOCK 1 ;[12000] Reverse linefeed character
WIPEC: BLOCK 2 ;[12000] Delete a character
EOL: BLOCK 2 ;[12000] What to type at end of line
TTAB: BLOCK 2 ;[13000] Tab simulation
WIPEL: BLOCK 1 ;[12000] Clear to end of line
WIPES: BLOCK 1 ;[12000] Clear to end of screen
HOME: BLOCK 1 ;[12000] Go to top of screen
CFWD: BLOCK 2 ;[12000] Forward-space
ERRPRE: BLOCK 4 ;[12000] Prefix to error messages
ERRPOS: BLOCK 4 ;[12000] Postfix to error messages
CAD: BLOCK 1 ;[12000] Direct cursor addressing
PROMPT: BLOCK 4 ;[12000] The prompt characters
BRKFLG: BLOCK 1 ;[12000] Enable breakpoints if negative
TARCMD: BLOCK 4 ;[14000] Type after every command
DEFARG: BLOCK 1 ;[15000] Default argument
TNULL: BLOCK 2 ;[15000] Type this for nulls
TTABND: BLOCK 1 ;[16000] Put this at the end of tabs
CWMAX==<.-CWVEC> ;[14000] Maximum legal arg to :W
TOOBLK: ;[12000] TRMOP. output block. DO NOT CHANGE THE ORDER OF THE NEXT 3
TOOFUN: BLOCK 1 ;[12000] TRMOP. block for output
OURTTY: BLOCK 1 ;[12000] Our TTY #
TOOADR: BLOCK 1 ;[12000] Argument to TRMOP. (addr of buffer)
ROW:
FY: BLOCK 1 ;[12000] Row cursor is in
COL:
FX: BLOCK 1 ;[12000] Column...
;WINB was moved into the CWVEC (6:W) for PDP-11 compatability
WINZ:
FZ: BLOCK 1 ;[12000] End of window
TTOPTR: BLOCK 1 ;[12000] Terminal output byte ptr
TTOBUF: BLOCK C$OBFL ;[12000] Terminal output buffer
TTOEND: BLOCK 1 ;[12000] 1 word of overdraw (no count needed)
LOWEND==.-1 ; DEFINE END OF IMPURE LOWSEGMENT DATA
RELOC ; BACK TO HISEG RELOCATABLE
LIT
; PATCHING SPACE
PAT: REPEAT C$PATL,<Z> ; PATCHING SPACE
>;; END FOR FTXTEC!FTXTCERR
FOR FTXTEC, END XTEC ; *** THE END ***
FOR FTXTCERR, NOTFOR FTXTEC, END ; *** THE END ***