; 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, M, AND 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 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 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 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) IFN WHO,> ; NOTFOR - MACRO TO OPEN A CONDITIONAL IF ARG IS FALSE ; ; CALL IS: NOTFOR FTXXXX,< ; CLOSED BY: >;; END NOTFOR FTXXXX DEFINE NOTFOR (WHO) 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) ,<<1B<-1>>>IFNB ,>> ; 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) ,<<-1>>IFNB ,> ; 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) , IFNB ,> ; 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) > TAB'TBL: XLIST TAB;; ; GENERATE KEYWORDS TAB'LTH==.-TAB'TBL DEFINE PAIR (NAME,ADR,BITS) TAB;; ; GENERATE DISPATCH TABLE LIST SALL > ; STSTK - MACRO TO SETUP AN EXPANDABLE STACK DEFINE STSTK (AC,LEN,REF) ,

, MOVE T1,[] MOVEI N,AC PUSHJ P,SETSTK > ; ECHO - O/S dependent macro to turn echo on or off DEFINE ECHO (STATE),< %STATE==0 IFB ,<%STATE==1> IFIDN ,,<%STATE==1> FOR TOPS10, > FOR TOPS20, IFE %STATE, > PURGE %STATE > ;SKPECHO -- O/S-Dependant macro to skip if echo is ON DEFINE SKPECHO(STATE),< IFB ,<...ST==1> IFNB ,,,<...ST==1> IFIDN ,,<...ST==0>> IFN ...ST,< FOR TOPS10, FOR TOPS20, > IFE ...ST,< FOR TOPS10, FOR TOPS20, > 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)>> ; 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)>> ; 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)>> ; 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)>> ; 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 > ;< B8+B12+> ; 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: 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 also when typed out DM$INS==4 ;Terminal is in INSERT mode SUBTTL Transfer Vector Table for Command Execution DEFINE TV (CMD)<$$'CMD: IFNDEF $'CMD, IFDEF $'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 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) ; (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,[] ; 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,() ;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,[] ; 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, ;[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, ; -1=FLAG NONE IFE C$EUVL, ; 0=FLAG LOWER CASE IFE C$EUVL-1, ; . . . ; 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, ;[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,[] ; 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 ',]>] ; 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 OR SFILE-SPEC ; ( MEANS DO "EW", MEANS DO "EB" AND "EY") CCLST2: MOVEI L,CURCMD ; ALLOCATE COMMAND BUFFER PUSHJ P,RELM ; . . . MOVE L,[] ; . . . 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 IDPB C,T3 ; AND PUT IN COMMAND BUFFER CAIN C,.CHCRT ; IS IT A ? JRST CCLST4 ; YES, FILE-SPEC IS COMPLETE CAIE C,.CHESC ; IS IT ? 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 - COMMAND TO "TECO" A FILE-SPEC CCLST4: MOVEI C,.CHESC ; ADD AN 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 EY ; APPEND TO COMMAND AND EXECUTE IT CCLST5: MOVEI C,.CHESC ; FETCH AN IDPB C,T3 ; APPEND TO COMMAND IDPB C,T3 ; AND ANOTHER FOR GOOD LUCK MOVEI T4,3(T4) ; COUNT 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 ; ;user erased the command, just prompt ; ;execute the command. BID is in N GETCMD: ; ALLOCATE A NEW COMMAND BUFFER MOVE L,[] ; 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, ;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 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 - 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),> 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 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,[] ; 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,[] ; 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 ; 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 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, ;[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)>> 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,[] ; 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 ; ; 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,[] ; 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,[] ; 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) ; ; OR ; MOVEI VALUE, 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 IN CODE JRST CDCVAL ; AND CONTINUE CD CDDIG7: HRLI N,(MOVEI VALUE,) ; FORM: MOVEI VALUE, 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 - 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 ; ; JSP PC,$$FS ; 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 ; ; 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 ; ; 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)>> 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 E E E$ E <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) ; 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 ; ; (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 ; ; (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 ; ; (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 ; ; (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 ; ; (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 ; ; ; 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: ; ; 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 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,,,,AND 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,,,, OR ? 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: ; -------------- ; ! 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,[] ; 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 ; ; (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: _-^D18,,_-^D18 _-^D18,,_-^D18 _-^D18,,_-^D18 SUBTTL $U AND $Q AND $INC ; $U - STORE ARG IN IN SPECIFIED Q-REGISTER ; ; CALL: JSP PC,$$U ; ; (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 ; ; (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 ; ; (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 ; ; (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 ; ; (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 ; ; (RETURN) $I: PUSHJ P,NXTWRD ; FETCH 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 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 ; ; (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 ; 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 ; 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 CHAR NEEDED TXNE F,F$FFD ; NEED AT END OF BUFFER? PUSHJ P,@PCHADR ; YES, PUNCH A 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 ; 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 ; 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 ; 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 ; 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 ; ; (RETURN) $FS: PUSHJ P,NXTWRD ; FETCH 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 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 CHAR JUST IN CASE TXNE F,F$FFD ; NEED A ? PUSHJ P,@PCHADR ; YES, PUNCH THE 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 ; ; ; (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,+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, ;[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 ; ; (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 ; ; (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,+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, ;[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 ; ; (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 ; ; (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 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, ;[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 ; ; (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 ; ; (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 ; ; (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 ; ; (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,[] ; 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,() ; 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,[] ; COPY EB SPEC TO ER SPEC BLT X,LERSPC+FS$LTH-1 ; . . . MOVE X,[] ; 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 ; ; (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,() ; 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 ; ; (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 ; ; (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,() ;[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 ; ; (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 ; ; (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 ; ; ; (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 ; ; ; (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 ; ; (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 ; ; (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: B18+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 B18> ; T4 HOLDS 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 B18+TEXT.LENGTH> SSTPS4: CAILE T4,C$SRHL ; TOO MANY CHARS? ERROR (STC) ; YES, ** TOO MANY CHARS IN SEARCH STRING ** IOR T3,T4 ; FORM 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,[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 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 - 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 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,[] ; FETCH ADR OF ASCII ROUTINE AND BYTE SIZE TXNE T1,FB$SIX ; /SIXBIT? MOVE X,[] ; ADR OF SIXBIT ROUTINE AND BYTE SIZE TXNE T1,FB$OCT ; /OCTAL? MOVE X,[] ; 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,[] ; 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,[] ; YES, FETCH ADR OF SIXBIT ROUTINE TXNE T1,FB$OCT ; /OCTAL? MOVE X,[] ; 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 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 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,[] ; 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 ; 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 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 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 , 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,[] ; 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,() ; 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,() ; CHANNEL FOR FILOPN MOVE M,[] ; 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: 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,[] ; 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 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,*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,[] ; 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, ; 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, ;[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 ? 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: ; 00 01 Current char, LEBSPC ; 02 03 LASSPC, Lookup/enter code (#) ; 04 05 Output dev, LASSPC path ; 06 07 ARG, LASSPC PROTECTION ; 08 09 LEBSPC name, LEBSPC ; 10 11 LEBSPC, IO flags (#) ; 12 13 TAG, Lookup/Enter (text) ; 14 15 IO error bits (text) ; 16 17 EO, Search arg ; 18 19 MACNAM, switch ; 20 21 EW, ER ; 22 23 ^T, ^D ; 24 25 SARG, FLAGS ;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 ^ 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, 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:.) > 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: () > 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. 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, ; 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: - 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: 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 ; ,,OR ? 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,[] ; 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, ; 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: ) ; ; 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 (EG: ) ; ; 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 (EG: .CHTAB AS ) 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 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)<<_-^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: ; ; 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 CAIE C,12 ;and do special stuff to 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 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 or ... CAIN C,12 ; JRST UPDCAD ;Treat like it is CAIN C,11 ; ... or 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 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 (,,) ; ; CALL: MOVEI C,CHAR ; PUSHJ P,CHKEOL ; (FAIL RETURN) ; (SUCCESS RETURN) ; ; USES AC C CHKEOL: CAIG C,.CHFFD ; IS CHAR ,, OR ? 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: ; ; ; . . . ; 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+(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,[] ; 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,+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,[] ; 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, ; 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 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 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,[] ; MOVE L,[] ; 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 IN PDLTAB MOVEM L,C$NPDL(T1) ; STORE 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 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,[] ; 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 TO TYPE LONG MESSAGES ERRH3: PUSH P,[] ; SAVE RETURN ADR IFE FTXTEC&FTXTCERR,< MOVE X,[ERRSEG:] ; FETCH NAME OF ERROR SEGMENT MOVEM X,GSGNAM ; AND STORE IN GETSEG BLOCK PUSH P,[] ; 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 ? AND RETURN TO CALLER ERRCT3: MOVEI N,[ASCIZ/? /] ; TYPE ? 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, ;[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 > ;[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 >, ;[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* ; BUFFERS FOR INI FILES LOGBH: BLOCK C$BFHD ;[330] LOG FILE BUFFER HEADER LOGBF: BLOCK C$NBUF* ;[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*; OUTPUT BUFFERS INPBH: BLOCK C$BFHD ; BUFFER HEADER FOR INPUT INPBF: BLOCK C$NBUF* ; 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, ; PATCHING SPACE >;; END FOR FTXTEC!FTXTCERR FOR FTXTEC, END XTEC ; *** THE END *** FOR FTXTCERR, NOTFOR FTXTEC, END ; *** THE END ***