Trailing-Edge
-
PDP-10 Archives
-
BB-M081Z-SM
-
monitor-sources/comnd.mac
There are 52 other files named comnd.mac in the archive. Click here to see a list.
; Edit= 9148 to COMND.MAC on 21-Feb-90 by GSCOTT
;Update copyright date.
; Edit= 9112 to COMND.MAC on 30-Jun-89 by GSCOTT
;Handle OWGBPs properly in COMND arguments, handle decrementing a OWGBP in
;STCMP if SC%SUB, and stir in a few ERJMPs here and there.
; UPD ID= 8494, RIP:<7.MONITOR>COMND.MAC.9, 9-Feb-88 12:18:22 by GSCOTT
;TCO 7.1218 - Update copyright notice.
; UPD ID= 8350, RIP:<7.MONITOR>COMND.MAC.8, 19-Jan-88 13:52:05 by GSCOTT
;TCO 7.1183 - DATIME in XCDSEC now, change the IMCALLs.
; UPD ID= 320, RIP:<7.MONITOR>COMND.MAC.7, 10-Dec-87 14:51:23 by RASPUZZI
;TCO 7.1159 - Partial recognition broke beeping if invisible keywords. If
; we have no suffix (norec or inv) then don't attempt partial
; or any recognition.
; UPD ID= 315, RIP:<7.MONITOR>COMND.MAC.6, 1-Dec-87 14:58:28 by RASPUZZI
;TCO 7.1151 - Remove code that spits the recognition character back into
; the input buffer. It causes a beep unnecessarily.
; UPD ID= 95, RIP:<7.MONITOR>COMND.MAC.4, 1-Sep-87 14:50:55 by RASPUZZI
;TCO 7.1047 - Fix stupidity in edit 7413 by not allowing ^Vs for .CMUSR
;and .CMDIR but not breaking the world.
; UPD ID= 31, RIP:<7.MONITOR>COMND.MAC.3, 29-Jun-87 16:38:59 by RASPUZZI
;TCO 7.1014 - Implement partial recognition (keywords and files).
; *** Edit 7413 to COMND.MAC by RASPUZZI on 24-Jan-87, for SPR #18873
; Don't allow ^V's in usernames or directory names. Return an error if some
; bozo tries to use it.
; *** Edit 7404 to COMND.MAC by RASPUZZI on 16-Dec-86, for SPR #21491
; Prevent ILMNRFs by making GETFUN validate the function it is getting from the
; user's address space
; *** Edit 7394 to COMND.MAC by RASPUZZI on 18-Nov-86
; Add ERJMPs after monitor calls to prevent MONNEJ BUGCHKs
; *** Edit 7325 to COMND.MAC by RASPUZZI on 24-Jun-86, for SPR #18086
; Fix problems with help in .CMTAD function
; *** Edit 7309 to COMND.MAC by RASPUZZI on 2-Jun-86
; Now install edit 7299 correctly. Sigh.
; *** Edit 7306 to COMND.MAC by RASPUZZI on 30-May-86
; Remove edit 7299 until it works right
; *** Edit 7305 to COMND.MAC by RASPUZZI on 30-May-86
; Fix edit 7299 so that we don't eat ESC
; *** Edit 7301 to COMND.MAC by RASPUZZI on 27-May-86
; Fix typo in edit 7299. Argh!
; *** Edit 7299 to COMND.MAC by RASPUZZI on 23-May-86, for SPR #17812
; Check for EOL after .CMNUM or .CMNUX and set CM%EOC if there is an EOL
; *** Edit 7292 to COMND.MAC by RASPUZZI on 7-May-86, for SPR #20832
; Fix ^V, ^W, ^U, ^H weirdness by reapplying edit 1989
; *** Edit 7260 to COMND.MAC by MRASPUZZI on 11-Mar-86, for SPR #20948
; Return correct error when a null string is passed to function .CMDEV with
; flags CM%NSF and CM%PO set
; *** Edit 7241 to COMND.MAC by WAGNER on 13-Feb-86
; Edit 7235 was installed incorrectly, breaking SET HOSTING entirely from 20 to
; 20 re-do correctly to not trash login of SKIPN.
; *** Edit 7235 to COMND.MAC by WAGNER on 31-Jan-86
; Edit 7225 caused ?Invalid Source or Destination Designator errors when SET
; HOSTed to another system and attempting a REMARK command. Fix oversight.
; *** Edit 7225 to COMND.MAC by WAGNER on 10-Jan-86, for SPR #21069
; Prevent ILMNRFs by restoring JFN in MOTXT
; UPD ID= 2326, SNARK:<6.1.MONITOR>COMND.MAC.42, 6-Sep-85 12:08:57 by LOMARTIRE
;More TCO 6.1.1464 - Avoid MONPDL from long ^R buffer (CTERM)
; Edit 7116 to COMND.MAC by PRATT on 6-Aug-85, for SPR #611505 (TCO 611505)
; Change a few routines to allow Datatrieve to use OWGBPs and to allow a 30 bit
; address for the command state block address.
; Edit 7115 to COMND.MAC by PRATT on 6-Aug-85, for SPR #15397 (TCO 611506)
; Fix parsing problems if 1st field supplies a default, the 2nd field does not
; supply a default, and the user types <ret>.
; UPD ID= 2249, SNARK:<6.1.MONITOR>COMND.MAC.41, 19-Jun-85 20:48:30 by MELOHN
;TCO 6.1.1464 - add ^R pointer to .MOTXT MTOPR% (CTERM)
; UPD ID= 2057, SNARK:<6.1.MONITOR>COMND.MAC.38, 3-Jun-85 14:22:13 by MCCOLLUM
;TCO 6.1.1406 - Update copyright notice.
; UPD ID= 1977, SNARK:<6.1.MONITOR>COMND.MAC.37, 14-May-85 14:55:04 by MCCOLLUM
;Add ERJMP after SOUT in RDSOUT
; UPD ID= 1237, SNARK:<6.1.MONITOR>COMND.MAC.36, 26-Dec-84 11:15:39 by MCCOLLUM
; More of 6.1.1076 - ERJMPs
; UPD ID= 1166, SNARK:<6.1.MONITOR>COMND.MAC.35, 7-Dec-84 16:42:27 by MCCOLLUM
;TCO 6.1.1076 - Add ERJMPs after some MTOPR jsys'.
; UPD ID= 1094, SNARK:<6.1.MONITOR>COMND.MAC.34, 18-Nov-84 13:32:15 by PRATT
;TCO 6.1.1056 - Handle "/<esc>" when multiple fdb's, should just beep
; UPD ID= 1065, SNARK:<6.1.MONITOR>COMND.MAC.33, 13-Nov-84 11:38:57 by PRATT
;Remove TCO 6.1.1026 - Causes grief in too many places
; UPD ID= 984, SNARK:<6.1.MONITOR>COMND.MAC.32, 7-Nov-84 08:18:28 by PRATT
;More TCO 6.1.1026 - Too much code is under IFN FTNSPSRV
; UPD ID= 4972, SNARK:<6.MONITOR>COMND.MAC.31, 22-Oct-84 12:51:01 by PRATT
;TCO 6.1.1026 - Make ^H retrieve the last command (under IFE FTNSPSRV)
; UPD ID= 4902, SNARK:<6.MONITOR>COMND.MAC.30, 8-Oct-84 13:38:17 by PRATT
;TCO 6.2215 - Make "-<esc>" work again
; UPD ID= 4747, SNARK:<6.MONITOR>COMND.MAC.29, 24-Aug-84 12:21:19 by HAUDEL
;TCO 6.2194 - Add ERJMPRs after several JSYSes.
; UPD ID= 4728, SNARK:<6.MONITOR>COMND.MAC.28, 22-Aug-84 14:27:34 by PRATT
;TCO 6.2189 - Don't put default filespec in the command buffer if crlf typed
; UPD ID= 4712, SNARK:<6.MONITOR>COMND.MAC.27, 20-Aug-84 13:23:23 by PRATT
;TCO 6.2182 - Make .CMQST handle defaults
; UPD ID= 4710, SNARK:<6.MONITOR>COMND.MAC.26, 20-Aug-84 10:50:12 by PRATT
;TCO 6.2180 - Make sure user's T4 is not trashed by CMTADH
; UPD ID= 4641, SNARK:<6.MONITOR>COMND.MAC.25, 31-Jul-84 15:41:43 by PURRETTA
;Update copyright notice
; UPD ID= 4633, SNARK:<6.MONITOR>COMND.MAC.24, 30-Jul-84 17:40:35 by MURPHY
;More 6.2020 - Make TEXTI wakeup correctly again.
; UPD ID= 4448, SNARK:<6.MONITOR>COMND.MAC.23, 11-Jul-84 09:08:57 by MCINTEE
;Add hooks for CTERM.
;UPD ID= 4339, SNARK:<6.MONITOR>COMND.MAC.22, 13-Jun-84 22:11:43 by MOSER
;MORE TCO 6.2060 - DO IT BETTER FIX GE2 - ALWAYS SET FIELD WIDTH IE .LE. 1
; UPD ID= 4271, SNARK:<6.MONITOR>COMND.MAC.21, 30-May-84 21:20:50 by MOSER
;TCO 6.2060 - SPEED UP COMND
; UPD ID= 3745, SNARK:<6.MONITOR>COMND.MAC.20, 24-Feb-84 11:53:38 by MURPHY
;TCO 6.1525 - Fix bugs re. global stack pointer.
; UPD ID= 3497, SNARK:<6.MONITOR>COMND.MAC.19, 20-Jan-84 11:22:28 by MCINTEE
;Typeo in previous
; UPD ID= 3496, SNARK:<6.MONITOR>COMND.MAC.18, 20-Jan-84 11:17:09 by MCINTEE
;TCO 6.1935 - Implement TEXTI% bit RD%NED.
; UPD ID= 3281, SNARK:<6.MONITOR>COMND.MAC.17, 9-Dec-83 18:32:52 by MCCOLLUM
;TCO 6.1901 - Fix incorrect help text for linked .CMKEY FDBs around CMQ1
; UPD ID= 3209, SNARK:<6.MONITOR>COMND.MAC.16, 22-Nov-83 11:31:52 by PRATT
;More TCO 6.1846 - Fix .CMTOK not being returned as function performed.
; UPD ID= 3154, SNARK:<6.MONITOR>COMND.MAC.15, 15-Nov-83 10:16:23 by PRATT
;TCO 6.1846 - Make XCMTOK handle defaults
; UPD ID= 3088, SNARK:<6.MONITOR>COMND.MAC.14, 31-Oct-83 17:43:39 by PRATT
;More of TCO 6.1472 - ERJMPR after DVCHR jsys in RCNM
; UPD ID= 3065, SNARK:<6.MONITOR>COMND.MAC.13, 24-Oct-83 15:55:21 by PRATT
;TCO 6.1838 - Make ^F work in unquoted string if it's a break character
; UPD ID= 2969, SNARK:<6.MONITOR>COMND.MAC.12, 3-Oct-83 10:03:16 by PRATT
;TCO 6.1812 - Make XCMUQS to check CMQUES flag before CMUQS1 code
; UPD ID= 2931, SNARK:<6.MONITOR>COMND.MAC.11, 23-Sep-83 16:07:14 by TSANG
;TCO 6.1802 - Release extraneous JFNs which exist if an error occurs
; in an indirect file command.
; UPD ID= 2870, SNARK:<6.MONITOR>COMND.MAC.10, 29-Aug-83 15:24:26 by PRATT
;TCO 6.1779 - Make TBADD and TBDEL understand abbreviations
; UPD ID= 2769, SNARK:<6.MONITOR>COMND.MAC.9, 26-Jul-83 11:55:26 by PRATT
;TCO 6.1753 - Allow user break masks for switches
; UPD ID= 2395, SNARK:<6.MONITOR>COMND.MAC.8, 2-May-83 15:40:17 by LEACHE
; UPD ID= 2096, SNARK:<6.MONITOR>COMND.MAC.7, 28-Mar-83 17:36:35 by MURPHY
;TCO 6.1472 - Put ERJMP after some JSYSes.
; UPD ID= 1848, SNARK:<6.MONITOR>COMND.MAC.6, 21-Feb-83 16:32:25 by LEACHE
;TCO 6.1518 - Fix "section greater than 37" error for .CMNUX
; UPD ID= 1459, SNARK:<6.MONITOR>COMND.MAC.5, 18-Nov-82 12:04:34 by DONAHUE
;Sigh... Pull last edit till its right
; UPD ID= 1438, SNARK:<6.MONITOR>COMND.MAC.4, 12-Nov-82 16:03:54 by DONAHUE
;Fix previous edit
; UPD ID= 1392, SNARK:<6.MONITOR>COMND.MAC.3, 1-Nov-82 09:22:44 by DONAHUE
;TCO 6.1340 - Change code at XCMTOK to handle defaulting
; UPD ID= 1164, SNARK:<6.MONITOR>COMND.MAC.2, 11-Sep-82 09:47:03 by CHALL
;TCO 6.1167 XCMTOK- CHANGE NPXNMD ERROR TO NPXNMT (TO CORRECT A TYPO)
; UPD ID= 334, SNARK:<6.MONITOR>COMND.MAC.50, 21-Jan-82 10:48:54 by PAETZOLD
;More TCO 5.1687
; UPD ID= 322, SNARK:<6.MONITOR>COMND.MAC.49, 19-Jan-82 08:25:27 by PAETZOLD
;TCO 5.1687 - Fix RDCBP to accept OWGBPs from non-zero section
; UPD ID= 248, SNARK:<6.MONITOR>COMND.MAC.48, 11-Dec-81 15:49:43 by CHALL
;TCO 5.1631 XCMTAD- DON'T COUNT TERMINATOR AS PART OF DATE-TIME
; UPD ID= 190, SNARK:<6.MONITOR>COMND.MAC.47, 6-Nov-81 12:50:22 by CHALL
;TCO 6.1036 ADD FDB FLAG CM%NSF (NO SUFFIX NEEDED)
; TEACH XCMNOD AND XCMDEV TO USE CM%NSF
; UPD ID= 184, SNARK:<6.MONITOR>COMND.MAC.46, 5-Nov-81 09:09:52 by MCINTEE
;Make PARNOD global, for use in module FILNFT
; UPD ID= 246, SNARK:<5.MONITOR>COMND.MAC.45, 6-Oct-81 13:42:43 by MOSER
;TCO 5.1526 MAKE .CMNOI WORK WHEN FIRST IN LIST.
; UPD ID= 156, SNARK:<5.MONITOR>COMND.MAC.44, 9-Sep-81 09:18:52 by CHALL
;TCO 5.1491 XCOM5A- REMOVE TCO 5.1475 UNTIL I GET IT RIGHT (SIGH)
; UPD ID= 136, SNARK:<5.MONITOR>COMND.MAC.43, 1-Sep-81 22:25:25 by DONAHUE
;TCO 5.1484 - Let CTRL/V be seen as a break character
; UPD ID= 120, SNARK:<5.MONITOR>COMND.MAC.40, 25-Aug-81 14:44:44 by CHALL
;TCO 5.1475 XCOM5A- IF THERE'S ONLY ONE KEYWORD (ETC.) OUTPUT IT
; UPD ID= 101, SNARK:<5.MONITOR>COMND.MAC.39, 14-Aug-81 10:28:51 by ZIMA
;TCO 5.1453 - Remove unneeded instructions at RTYP33.
; UPD ID= 53, SNARK:<5.MONITOR>COMND.MAC.38, 20-Jul-81 15:53:52 by MOSER
;TCO 5.1423 LOOK AT TT%LCA AS WELL AS TT%UOC TO DECIDE HOW FAR TO BACK UP.
; UPD ID= 2201, SNARK:<5.MONITOR>COMND.MAC.37, 16-Jun-81 08:22:15 by SCHMITT
;More of TCO 5.1361 - Remove checks for break in default string
; UPD ID= 2193, SNARK:<5.MONITOR>COMND.MAC.36, 12-Jun-81 12:12:13 by SCHMITT
;More of TCO 5.1361 - Make good check for break set supplied at GETBRK
; UPD ID= 2166, SNARK:<5.MONITOR>COMND.MAC.35, 10-Jun-81 15:17:33 by PAETZOLD
;TCO 5.1293 Fix breaks on <CR> for TEXTI
; UPD ID= 2163, SNARK:<5.MONITOR>COMND.MAC.34, 10-Jun-81 09:36:28 by DONAHUE
;TCO 5.1366 - Check if parsing a noise word at NLINE
; UPD ID= 2145, SNARK:<5.MONITOR>COMND.MAC.33, 8-Jun-81 11:52:06 by SCHMITT
;TCO 5.1361 - Check for break characters in default string.
; UPD ID= 2144, SNARK:<5.MONITOR>COMND.MAC.32, 8-Jun-81 10:12:06 by SCHMITT
;TCO 5.1360 - Make .CMCMA terminated with ESC function correctly
; UPD ID= 2114, SNARK:<5.MONITOR>COMND.MAC.31, 1-Jun-81 14:40:58 by SCHMITT
;TCO 5.1357 - in CHKDEF, jump back to XCOMB0 to reset pass 1
; UPD ID= 1940, SNARK:<5.MONITOR>COMND.MAC.30, 5-May-81 16:54:31 by MOSER
;TCO 5.1311 - Make help work as documented if parsing keyword or switch and
; nothing can match.
; UPD ID= 1782, SNARK:<5.MONITOR>COMND.MAC.29, 3-Apr-81 14:03:34 by MURPHY
;Make ^O act like ^R if ever seen in input stream.
; UPD ID= 1742, SNARK:<5.MONITOR>COMND.MAC.28, 19-Mar-81 21:44:18 by MURPHY
;Undo preceding edit. Put COMNX9 back in.
; UPD ID= 1641, SNARK:<5.MONITOR>COMND.MAC.27, 4-Mar-81 10:38:37 by OSMAN
;tco 6.1004 - Don't fail in .CMINI if end of file encountered in lieu of ^H.
; Note: As part of this, remove COMNX9 check so that IOX4 is all that need
; be checked for by user's error handler.
; UPD ID= 1532, SNARK:<5.MONITOR>COMND.MAC.26, 7-Feb-81 21:34:22 by GRANT
;REPLACE NTMX4 ERROR CODE WITH COMX21
; UPD ID= 1449, SNARK:<5.MONITOR>COMND.MAC.25, 16-Jan-81 08:50:10 by GRANT
;Initialize T4 at PARNOD
; UPD ID= 1353, SNARK:<5.MONITOR>COMND.MAC.22, 15-Dec-80 14:15:23 by DONAHUE
;TCO 5.1215 - Add routine ECOCHK to check if echoes are on or off (called
;when a '?' is seen)
; UPD ID= 1122, SNARK:<5.MONITOR>COMND.MAC.21, 3-Oct-80 14:17:24 by SCHMITT
;TCO 5.1166 - Fix parsing when .CMTXT is alternate to other functions
; Create new bit CMNP1 which will say not to perform pass 1
; for certain functions, (.CMTXT) is one.
; UPD ID= 988, SNARK:<5.MONITOR>COMND.MAC.20, 4-Sep-80 15:13:22 by GRANT
;Rewrite PARNOD - add a special entry point for non-ASCIZ strings and
;add DECnet Phase III restriction of at least 1 alphabetic character
; UPD ID= 780, SNARK:<5.MONITOR>COMND.MAC.19, 23-Jul-80 10:56:15 by MURPHY
; ^R after deleting one character after wraparound bug...
; UPD ID= 767, SNARK:<5.MONITOR>COMND.MAC.18, 18-Jul-80 21:19:50 by ZIMA
;TCO 5.1104 - fix typo in RETERR at RDTXT1:+12L
; UPD ID= 748, SNARK:<5.MONITOR>COMND.MAC.17, 9-Jul-80 09:41:23 by OSMAN
;tco 5.1101 - Make "MOU TAP FOO:/VOLID:ABC/WE" give correct error
; UPD ID= 742, SNARK:<5.MONITOR>COMND.MAC.15, 8-Jul-80 10:24:56 by MURPHY
;Fix bug: character left on line when deleting over wraparound
; UPD ID= 740, SNARK:<5.MONITOR>COMND.MAC.13, 7-Jul-80 09:05:22 by OSMAN
;tco 5.1094 - Fix "?" in time/date fields
; UPD ID= 714, SNARK:<5.MONITOR>COMND.MAC.12, 30-Jun-80 16:27:10 by MURPHY
;Fix RD%SUI
; UPD ID= 693, SNARK:<5.MONITOR>COMND.MAC.11, 25-Jun-80 08:46:47 by OSMAN
;tco 5.1076 - Make "SYS ABC^V$^V$<cr>" not beep
; UPD ID= 690, SNARK:<5.MONITOR>COMND.MAC.10, 24-Jun-80 13:33:41 by OSMAN
;tco 5.1075 - Make "SET LOC" do "2102" instead of "L2102"
; UPD ID= 674, SNARK:<5.MONITOR>COMND.MAC.9, 18-Jun-80 17:58:45 by OSMAN
;tco 5.1069 - Prevent "?Device is not a terminal"
; UPD ID= 585, SNARK:<5.MONITOR>COMND.MAC.8, 2-Jun-80 13:52:15 by MURPHY
;MAKE ^U HANDLE MULTIPLE WRAPAROUNDS BETTER
; UPD ID= 584, SNARK:<5.MONITOR>COMND.MAC.7, 2-Jun-80 13:03:22 by MURPHY
;Use clear EOL function instead of clear EOS for speed
; UPD ID= 572, SNARK:<5.MONITOR>COMND.MAC.6, 30-May-80 16:36:30 by MURPHY
;Fix cases where initial <esc> would ding instead of using GTJFN defaults
; UPD ID= 506, SNARK:<5.MONITOR>COMND.MAC.5, 5-May-80 10:52:51 by OSMAN
;tco 5.1032 - Don't return <Cr> after date/time in atom buffer
;Make CMRFLN work as its comment says (rather than nth character being
;break character)
;Make COMND jsys faster by using ADJBP instead of calling DBP
; UPD ID= 491, SNARK:<5.MONITOR>COMND.MAC.4, 30-Apr-80 09:33:52 by OSMAN
;<4.1.EXEC>COMND.MAC.9, 30-Apr-80 09:24:10, EDIT BY OSMAN
;tco 5.1027 - Don't say "ambiguous" when keyword or switch omitted entirely
; UPD ID= 474, SNARK:<5.MONITOR>COMND.MAC.3, 24-Apr-80 15:38:41 by OSMAN
;tco 5.1024 - Don't say "?Ambiguous" if switch input is "/A:" and table
;contains "A:" and "AB:"
;<4.1.MONITOR>COMND.MAC.119, 21-Mar-80 14:55:31, EDIT BY OSMAN
;More 4.2463, 4.2382 - Clear atom buffer if slash not seen for switch, so
;"PRINT XYZ" says "file not found" instead of "not a switch..."
; UPD ID= 340, SNARK:<4.1.MONITOR>COMND.MAC.118, 18-Mar-80 09:21:35 by OSMAN
;tco 4.1.1116 - Don't put in space for last linefeed in indirect file
; UPD ID= 326, SNARK:<4.1.MONITOR>COMND.MAC.117, 12-Mar-80 15:10:34 by OSMAN
;More 4.1.1016 - remove code after ITEXTI that checks for break character
; UPD ID= 206, SNARK:<4.1.MONITOR>COMND.MAC.116, 16-Jan-80 16:47:43 by SCHMITT
; Tco 4.1.1069 - Let '+' & '-' char be valid terminators to .CMNUX
; UPD ID= 96, SNARK:<4.1.MONITOR>COMND.MAC.115, 5-Dec-79 11:31:31 by OSMAN
;tco 4.1.1046 - Prevent double beep on "COPY <esc>"
; UPD ID= 42, SNARK:<4.1.MONITOR>COMND.MAC.114, 28-Nov-79 15:15:20 by OSMAN
;Tco 4.1.1034 - Allow "?" in text lines (like MS subject lines and
;^ESEND commands)
;<4.1.MONITOR>COMND.MAC.113, 14-Nov-79 16:17:50, EDIT BY OSMAN
;more 4.2500 - If chain is .CMNUM, .CMKEY with default string "0",
;and input is "b" which matches a keyword, give keyword return instead
;of trying to put in the default number
;<4.1.MONITOR>COMND.MAC.111, 14-Nov-79 10:28:00, EDIT BY OSMAN
;tco 4.1.1019 - Save and restore user's AC4 correctly in .CMTAD
;<4.1.MONITOR>COMND.MAC.110, 13-Nov-79 10:57:49, EDIT BY OSMAN
;TCO 4.1.1016 - Allow formfeed as end-of-line character
;<4.1.MONITOR>COMND.MAC.109, 12-Nov-79 15:50:32, EDIT BY OSMAN
;tco 4.1.1015 - give "does not begin with slash" error appropriately
;more 4.2463 - Give correct error for switch/filespec choice
;<4.MONITOR>COMND.MAC.107, 29-Oct-79 13:44:17, EDIT BY OSMAN
;more 4.2500
;<4.MONITOR>COMND.MAC.106, 22-Oct-79 18:23:02, EDIT BY OSMAN
;more 4.2500 - fix "build<osman>" (without the space!)
;<4.MONITOR>COMND.MAC.105, 18-Oct-79 15:19:53, EDIT BY OSMAN
;TCO 4.2500 - IF .CMUSR FOLLOWED BY .CMDIR IN CHAIN, AND INPUT IS "ME:"
;AND "ME" IS A USER AND "ME:" IS A LOGICAL NAME, RETURN THE LOGICAL NAME
;tco 4.2514 - Turn off ^O before reprompting after help messages
;<4.MONITOR>COMND.MAC.103, 3-Oct-79 12:57:45, EDIT BY ZIMA
;More 4.2493 - move .CMCFM list check to last to allow .CMFIL test to
; occur first for those who depend on it.
;<4.MONITOR>COMND.MAC.102, 27-Sep-79 16:44:23, EDIT BY ZIMA
;More 4.2161 - make ^V-<crlf> not a continuation line
;<4.MONITOR>COMND.MAC.101, 27-Sep-79 15:28:17, EDIT BY ZIMA
;TCO 4.2495 - assure correct error code returned if NOUT fails in CMNUMH.
;<4.MONITOR>COMND.MAC.100, 27-Sep-79 15:10:43, EDIT BY ZIMA
;TCO 4.2494 - Avoid incorrect leading "or" text from DOHLP by setting
; the CMQUE2 flag properly in CMRTYP.
;<4.MONITOR>COMND.MAC.99, 27-Sep-79 15:01:27, EDIT BY ZIMA
;TCO 4.2493 - recognize .CMCFM in the list on initial CRLF at NLINE
;<4.MONITOR>COMND.MAC.98, 13-Sep-79 09:51:09, EDIT BY OSMAN
;tco 4.2463 - Give correct error on "DISMOUNT CURDS:"
;<4.MONITOR>COMND.MAC.97, 13-Aug-79 16:24:30, EDIT BY OSMAN
;More of 4.2382 - First try broke "REWIND" command!!!
;<4.MONITOR>COMND.MAC.96, 10-Aug-79 13:41:10, EDIT BY OSMAN
;tco 4.2382 - Give better error on "TERMINAL TYPE VT06" error
;Say "not a switch or keyword" instead of "First non-space is not a digit"
;<4.MONITOR>COMND.MAC.95, 10-Aug-79 12:41:18, EDIT BY OSMAN
;MAKE THE SOURCE FILE SHORTER
;<4.MONITOR>COMND.MAC.94, 1-Aug-79 16:07:05, EDIT BY OSMAN
;tco 4.2365 - Don't clobber user's AC4 on .CMTAD function
;<4.MONITOR>COMND.MAC.93, 1-Aug-79 15:24:44, EDIT BY OSMAN
;tco 4.2364 - Close indirect file if bombout due to space exhaustion in CMDIBQ
;<4.MONITOR>COMND.MAC.92, 26-Jul-79 08:49:35, EDIT BY OSMAN
;MORE OF 4.2299 - UPDATE FLAG WORD WITH QUOTEF
;<4.MONITOR>COMND.MAC.91, 25-Jul-79 15:24:59, EDIT BY R.ACE
;FIX SETZM IN XCMIFI THAT FAILS IF USER NOT IN SECTION 0
;<4.MONITOR>COMND.MAC.90, 25-Jul-79 08:57:23, EDIT BY SCHMITT
;TCO 4.2341-call long form GTJFN all the time
;<4.MONITOR>COMND.MAC.89, 25-Jul-79 08:55:56, EDIT BY SCHMITT
;TCO 4.2340-allow parse if default name in GTJFN block present
;<4.MONITOR>COMND.MAC.88, 20-Jul-79 09:36:32, EDIT BY OSMAN
;MORE TCO 4.2299 - Use FLG2, DDT was doing ^U wrong
;<4.MONITOR>COMND.MAC.87, 20-Jun-79 16:08:23, EDIT BY OSMAN
;tco 4.2299 - Don't reject CTRL/V if char count is 1
;<4.MONITOR>COMND.MAC.86, 14-Jun-79 15:40:34, EDIT BY OSMAN
;tco 4.2288 Strip ESC after parse-only user name
;<4.MONITOR>COMND.MAC.85, 12-May-79 12:59:38, EDIT BY MILLER
;MORE FIXES
;<4.MONITOR>COMND.MAC.84, 11-May-79 14:34:53, EDIT BY MILLER
;<4.MONITOR>COMND.MAC.83, 11-May-79 14:25:56, EDIT BY MILLER
;MAKE DPCTL APPLY PARITY BIT IF NECESSARY
;<4.MONITOR>COMND.MAC.82, 27-Apr-79 17:05:12, EDIT BY OSMAN
;MAKE QUOTED CHARACTER (CTRL/V PRECEDES IT) NEVER BE A BREAK CHARACTER
;<4.MONITOR>COMND.MAC.81, 13-Apr-79 10:26:12, EDIT BY OSMAN
;USE SPECIAL MASK FOR ACCOUNT STRINGS
;<4.MONITOR>COMND.MAC.80, 13-Apr-79 10:06:44, EDIT BY OSMAN
;HONOR CM%BRK FOR .CMTXT AND NOT FOR .CMNOD
;<4.MONITOR>COMND.MAC.79, 4-Apr-79 09:51:44, EDIT BY OSMAN
;more of 4.2227
;<4.MONITOR>COMND.MAC.77, 30-Mar-79 15:36:27, EDIT BY OSMAN
;tco 4.2230 - Fix "!!OPR" to exec. (Comments on filespecs failed)
;<4.MONITOR>COMND.MAC.76, 29-Mar-79 13:25:01, EDIT BY OSMAN
;tco 4.2228 - Make CTRL/H work after "SUBMIT /DEP:-15<esc>" (it was causing a second error!)
;<4.MONITOR>COMND.MAC.75, 28-Mar-79 16:50:59, EDIT BY OSMAN
;tco 4.2227 - reparse more often
;<4.MONITOR>COMND.MAC.74, 27-Mar-79 17:23:11, EDIT BY OSMAN
;FIX "OPR SHOW STATUS P?" WHICH WAS GIVING ERROR
;<4.MONITOR>COMND.MAC.73, 21-Mar-79 11:05:37, EDIT BY OSMAN
;tco 4.2221 - Prevent cr after filespec in atom buffer
;<4.MONITOR>COMND.MAC.72, 16-Mar-79 16:56:09, EDIT BY OSMAN
;CLEAR ATOM BUFFER IF .CMCFM FAILS, SO BETTER ERROR CHOICE RESULTS
;<4.MONITOR>COMND.MAC.71, 12-Mar-79 09:48:39, EDIT BY OSMAN
;TCO 4.2213 - CHeck for null device name and return DEVX7
;<4.MONITOR>COMND.MAC.69, 4-Mar-79 14:46:31, Edit by KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<4.MONITOR>COMND.MAC.68, 1-Mar-79 09:14:27, EDIT BY OSMAN
;Before reading next character in TEXTI, deposit a null at end of buffer
;<4.MONITOR>COMND.MAC.67, 21-Feb-79 10:36:54, EDIT BY OSMAN
;FIX SUFFIX CODE IN CMRFL0 (BROKE WHILE PUTTING IN COLON STUFF)
;<4.MONITOR>COMND.MAC.66, 20-Feb-79 13:39:26, EDIT BY OSMAN
;turn on colons after node names
;FIX SWITCH DEFAULTING
;<4.MONITOR>COMND.MAC.64, 14-Feb-79 16:32:35, EDIT BY OSMAN
;CALL CHKBLP AT DELIN3 INSTEAD OF WITHIN DELIN LOOP (SO ^U CAUSES RD%BEG TO
;WIN EVEN IF NO INPUT BEFORE THE ^U
;<4.MONITOR>COMND.MAC.63, 14-Feb-79 09:55:08, EDIT BY OSMAN
;TCO 4.2188 - REQUIRE DOUBLE COLONS ON NODE NAMES
;<4.MONITOR>COMND.MAC.62, 29-Jan-79 09:19:13, EDIT BY OSMAN
;demand that node exist for .CMNOD unless CM%PO on
;<4.MONITOR>COMND.MAC.61, 16-Jan-79 17:07:16, EDIT BY OSMAN
;tco 4.2165 - Give VACCX1 if account string too long
;<4.MONITOR>COMND.MAC.60, 13-Jan-79 18:14:39, EDIT BY ZIMA
;TCO 4.2161 - IMPROVE HANDLING OF CONTINUATION LINES AT CMCIN
;<4.MONITOR>COMND.MAC.59, 9-Jan-79 17:23:27, EDIT BY DBELL
;TCO 4.2158 - MAKE .CMUQS FUNCTION WORK PROPERLY IF BREAK MASK INCLUDES
;THE SPECIAL EDITING CHARACTERS ("?", ALTMODE, CONTROL-F).
;<4.MONITOR>COMND.MAC.58, 3-Jan-79 17:53:55, EDIT BY DBELL
;TCO 4.2147 - MAKE ALTMODES AND ^F'S WORK PROPERLY IN QUOTED STRINGS
;<4.MONITOR>COMND.MAC.57, 27-Dec-78 15:14:47, EDIT BY BERKOWITZ
;TCO 4.2134 - Do not Type "one of the following" on help if only 1 element
; in the switch or keyord table
;<4.MONITOR>COMND.MAC.55, 20-Dec-78 16:56:29, EDIT BY OSMAN
;tco 4.2128 - Get rid of escape and put in space if ESC typed on indirect filespec
;<4.MONITOR>COMND.MAC.54, 20-Dec-78 16:03:39, EDIT BY OSMAN
;tco 4.2126 - indirect files, indirect file errors, best error code
;<4.MONITOR>COMND.MAC.53, 15-Dec-78 16:52:28, EDIT BY OSMAN
;tco 4.2122 - Guarantee that the BIN reading the CTRL/H wakes up on it.
;MAKE ^R CAUSE RETURN IF RD%BEG IS ON (CALL CHKBLP AT RTYPE)
;<4.MONITOR>COMND.MAC.52, 7-Dec-78 16:18:58, EDIT BY OSMAN
;tco 4.2112 - Make comments before guidewords work right.
;<4.MONITOR>COMND.MAC.51, 16-Nov-78 10:45:02, EDIT BY DBELL
;TCO 4.2089 - FIX FNDLIN SO ^G^G^U DOESN'T MOVE CURSOR UP A LINE
;<4.MONITOR>COMND.MAC.50, 4-Nov-78 02:09:47, EDIT BY OSMAN
;tcO 4.2078 - make TBADD understand flags in table entry
;<4.MONITOR>COMND.MAC.49, 30-Oct-78 16:57:47, EDIT BY OSMAN
;TCO 4.2074 - ALLOW $ AND _ IN DEVICE NAMES
;<4.MONITOR>COMND.MAC.47, 27-Oct-78 17:33:17, EDIT BY OSMAN
;MAKE PARNDU RETURN LENGTH IN A
;<4.MONITOR>COMND.MAC.37, 24-Oct-78 17:41:45, EDIT BY OSMAN
;ADD PARNDU
;<4.MONITOR>COMND.MAC.36, 18-Oct-78 13:09:51, EDIT BY OSMAN
;<4.MONITOR>COMND.MAC.35, 17-Oct-78 11:27:45, EDIT BY OSMAN
;<4.MONITOR>COMND.MAC.34, 16-Oct-78 17:47:17, EDIT BY OSMAN
;TCO 4.2046 - ADD RD%BEG
;<4.MONITOR>COMND.MAC.33, 30-Sep-78 20:55:38, EDIT BY DBELL
;TCO 4.2027 - CHECK FOR ^Z ON INDIRECT FILES FOR TERMINALS
;<4.MONITOR>COMND.MAC.32, 28-Sep-78 15:07:43, EDIT BY DBELL
;TCO 4.2026 - IGNORE NULLS READ FROM AN INDIRECT FILE
;<4.MONITOR>COMND.MAC.31, 22-Sep-78 13:18:27, EDIT BY OSMAN
;tco 4.2019 - Beep instead of error if ESC typed at beginning of quoted string
;<4.MONITOR>COMND.MAC.30, 21-Sep-78 11:04:26, EDIT BY KIRSCHEN
;<4.MONITOR>COMND.MAC.29, 21-Sep-78 11:03:32, EDIT BY KIRSCHEN
;<4.MONITOR>COMND.MAC.28, 19-Sep-78 15:40:02, EDIT BY KIRSCHEN
;DISALLOW NULL NODE NAMES
;<4.MONITOR>COMND.MAC.27, 12-Sep-78 17:07:29, EDIT BY OSMAN
;FIX BREAK SET LOOKUP CODE
;<4.MONITOR>COMND.MAC.25, 6-Sep-78 17:17:00, EDIT BY OSMAN
;CHANGED NAMES OF BREAK MASKS IN MONSYM (TO HAVE DOTS IN NAMES)
;<4.MONITOR>NCOMND.MAC.1, 3-Sep-78 12:01:21, EDIT BY OSMAN
;ALLOW CUSTOM BREAK MASKS
;<4.MONITOR>COMND.MAC.23, 18-Aug-78 13:14:37, EDIT BY OSMAN
;PUT SQUARE BRACKETS BACK INTO FILESPEC BREAK SET
;<4.MONITOR>COMND.MAC.22, 11-Aug-78 09:11:26, EDIT BY OSMAN
;WHEN MOVING CURSOR UP ON SCREENS, DECREMENT LINE COUNTER (.MOSLC)
;<HEMPHILL.EXEC>COMND.MAC.3, 7-Aug-78 12:53:49, Edit by HEMPHILL
;TCO 1975 -- MAKE ESCAPE AFTER TOKEN WORK
;<HEMPHILL.EXEC>COMND.MAC.2, 7-Aug-78 12:48:19, Edit by HEMPHILL
;TCO 1974 -- MAKE ESCAPE AFTER COLON IN DEVICE NAMES WORK
;<OSMAN>COMND.MAC.4, 7-Aug-78 09:30:24, EDIT BY OSMAN
;MAKE SO ^R DOESN'T GO UP SCREENS MORE THAN IT SHOULD.
;<OSMAN>COMND.MAC.2, 7-Aug-78 08:59:17, EDIT BY OSMAN
;RESTORE TEXTI TO ALWAYS PERFORM ^U ^R ETC. REGARDLESS OF USER'S BREAK MASK
;<4.EXEC>COMND.MAC.4, 4-Aug-78 15:11:32, EDIT BY OSMAN
;MAKE TEXTI ONLY WAKE ON ITS EDITING CHARACTERS, RATHER THAN ALL CONTROL CHARACTERS
;<4.EXEC>1COMND.MAC.3, 4-Aug-78 14:49:44, EDIT BY OSMAN
;PREVENT TEXTI FROM WAKING ON EVERYTHING AFTER EXECUTING ^W ON SCREENS
;<OSMAN>COMND.MAC.1, 3-Aug-78 20:42:05, EDIT BY OSMAN
;MAKE COMND ONLY WAKE ON ^F $ ? LF
;<4.MONITOR>COMND.MAC.18, 3-Aug-78 11:01:08, EDIT BY R.ACE
;TCO #1966 - FIX BUG IF NODE NAME FIELD TERMINATED WITH ALTMODE
;<4.MONITOR>COMND.MAC.17, 27-Jul-78 15:31:20, EDIT BY OSMAN
;TCO #1960 - ALLOW CM%PO ON .CMDEV FUNCTION
;FIX INPUT OF NEGATIVE NUMBERS (BROKE IN CONJUNCTION WITH "-" STUFF
;WHEN CRLF LOGIC FIXED)
;<3A.MONITOR>COMND.MAC.11, 20-Jun-78 16:29:47, EDIT BY OSMAN
;FIX THE CRLF LOGIC
;<4.MONITOR>COMND.MAC.13, 2-Jun-78 15:26:10, EDIT BY R.ACE
;TCO #1918 - MAKE CTRL/W TREAT CRLF AS A PUNCTUATION CHARACTER
;TCO #1917 - CHANGE ERROR CODE RETURNED BY TEXTI WHEN ARG BLK TOO SHORT
;<OSMAN>COMND.MAC.1, 30-May-78 13:29:59, EDIT BY OSMAN
;PUT CRLF IN COMND BUFFER INSTEAD OF JUST LF
;<OSMAN>3ANEW.MAC.7, 12-Apr-78 17:16:19, Edit by OSMAN
;<4.MONITOR>COMND.MAC.11, 25-Apr-78 10:47:29, EDIT BY OSMAN
;IN .CMFIL FUNCTION, MAKE SURE GJ%CFM IS OFF IN GTJFN BLOCK
;<OSMAN>4MNEW.MAC.5, 12-Apr-78 17:17:07, Edit by OSMAN
;<OSMAN>NEWCOM.MAC.3, 12-Apr-78 11:33:21, EDIT BY OSMAN
;IF LINE WRAPS AND USER TYPES EOL AND RUBS IT OUT, MAKE REPAINT OVERPRINT ORIGINAL LINE
;<4.MONITOR>COMND.MAC.9, 10-Apr-78 15:27:33, EDIT BY OSMAN
;MAKE SURE NULL AT END OF COMMAND IN CMGJ1 LOOP
;<4.MONITOR>COMND.MAC.8, 28-Mar-78 16:39:16, EDIT BY OSMAN
;ON SCREEN, PREVENT REPAINT OF LINE WHEN DELETING TAB AS FIRST CHAR OF SUBSEQUENT LINE
;<OSMAN>NEW4M.MAC.3, 17-Mar-78 16:18:42, Edit by OSMAN
;<OSMAN>NEW4M.MAC.2, 17-Mar-78 15:55:01, Edit by OSMAN
;<OSMAN>COMND.MAC.18, 17-Mar-78 15:22:59, Edit by OSMAN
;<OSMAN>COMND.MAC.17, 17-Mar-78 15:21:08, Edit by OSMAN
;<OSMAN>COMND.MAC.16, 17-Mar-78 15:05:03, Edit by OSMAN
;<OSMAN>COMND.MAC.15, 17-Mar-78 14:57:31, Edit by OSMAN
;<OSMAN>COMND.MAC.14, 17-Mar-78 14:52:05, Edit by OSMAN
;make so no repainting happens on deleting tabs
;<OSMAN>COMND.MAC.13, 17-Mar-78 11:28:35, Edit by OSMAN
;<OSMAN>COMND.MAC.12, 17-Mar-78 10:56:46, Edit by OSMAN
;<OSMAN>COMND.MAC.11, 17-Mar-78 10:47:58, Edit by OSMAN
;DON'T REPAINT WHEN ERASING LAST CHAR ON LINE
;<OSMAN>COMND.MAC.10, 16-Mar-78 17:02:22, Edit by OSMAN
;DON'T CLEAR TO END OF PAGE AFTER ^W, ONLY DURING IF NECESSARY
;<OSMAN>COMND.MAC.4, 16-Mar-78 11:19:57, Edit by OSMAN
;<OSMAN>COMND.MAC.3, 16-Mar-78 10:59:32, Edit by OSMAN
;<OSMAN>COMND.MAC.2, 15-Mar-78 16:24:29, Edit by OSMAN
;CAUSE LESS REPAINTING BY NOT DOING SO ON $ FOR ALTMODE OR FLAGGED CHARACTERS OR UPARROWED CONTROLS
;<OSMAN>COMND.MAC.1, 15-Mar-78 15:22:08, Edit by OSMAN
;<4.MONITOR>COMND.MAC.6, 9-Mar-78 09:35:42, Edit by ENGEL
;ADD SUPPORT FOR THE FULL 128-CHARACTER WAKE UP MASK
;<4.MONITOR>COMND.MAC.5, 31-Jan-78 11:20:43, Edit by ENGEL
;TCO #1881 - CHANGE VERTICAL TAB FROM PUNCTUATION TO TOPS-10 WAKE-UP CLASS
;<4.MONITOR>COMND.MAC.4, 10-Jan-78 10:46:00, EDIT BY HELLIWELL
;CHECK FOR NULL OR MISSING DEFAULT POINTER WHEN CM%DPP SET AND IGNORE
;<4.MONITOR>COMND.MAC.3, 9-Jan-78 15:57:57, EDIT BY OSMAN
;DON'T WRITE NULL IN CMDIB (TOO INEFFICIENT). INSTEAD, CALLER SHOULD DO IT AT END OF STRING
;<4.MONITOR>COMND.MAC.2, 4-Jan-78 14:40:27, EDIT BY OSMAN
;<3.SM10-RELEASE-3>COMND.MAC.2, 4-Jan-78 14:40:09, EDIT BY OSMAN
;REPREVENT TRAILING SPACE FROM APPEARING ON EXEC COMMANDS LIKE "PRINT /LIM$" AFTER THE ":" (DON'T ASSUME CMDIB PRESERVES T1!)
;<4.MONITOR>COMND.MAC.1, 18-Dec-77 16:46:35, EDIT BY OSMAN
;PREVENT UNEXPECTED "?GENERATION NUMBER IS NOT NUMERIC" WHEN
;LPT: HAS BEEN DEFINED AS DSK: AND THEN "LIST SNARK:[HALL]FOO.BAR<CR>
;LIST $" IS TYPED TO THE DUMPER PROGRAM (DEPOSIT NULL AFTER CHAR IN CMDIBQ)
; COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1976, 1990.
; ALL RIGHTS RESERVED.
;
; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
; ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
; INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
; COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
; OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
; TRANSFERRED.
;
; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
; AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
; CORPORATION.
;
; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
; SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL.
SEARCH PROLOG
TTITLE COMND
SWAPCD
;THIS FILE CONTAINS THE COMMAND AND TEXT INPUT SYSTEM, I.E.
;COMND, TBLUK, AND TEXTI. THESE ARE EFFECTIVELY LIBRARY
;ROUTINES BUT ARE IN THE MONITOR FOR CONVENIENT ACCESS.
;NO SPECIAL AC DEFINITIONS ARE USED HEREIN.
;THE COMMAND SCANNER JSYS. THIS ATTEMPTS TO PARSE THE NEXT FIELD
;OF AN INPUT COMMAND LINE. IT READS ADDITIONAL INPUT IF NECESSARY,
;AND ATTEMPTS TO RECOGNIZE THE FIELD SPECIFIED BY 'FN'.
; T1/ PTR TO COMND STATE BLOCK
; T2/ PTR TO LIST OF FUNCTION DESCRIPTOR BLOCKS
; COMND
; RETURNS +1 ALWAYS,
; T1/ FLAGS,,BLK PTR
; T2/ FUNCTION-SPECIFIC RESULT
; T3/ PTR TO FN BLOCK USED IF SUCCESSFUL PARSE
; QUANTITIES UPDATED IN STATE BLOCK. IF INPUT COULD NOT BE PARSED,
; CM%NOP IS SET AND THE CURRENT POINTER POINTS TO THE UNPARSED INPUT.
;FORMAT OF COMND STATE BLOCK:
.CMFLG==:0 ;USER FLAGS,,REPARSE DISPATCH ADDRESS
.CMIOJ==:1 ;INJFN,,OUTJFN
.CMRTY==:2 ;^R BUFFER POINTER
.CMBFP==:3 ;PTR TO TOP OF BUFFER
.CMPTR==:4 ;PTR TO NEXT INPUT TO BE PARSED
.CMCNT==:5 ;COUNT OF SPACE LEFT IN BUFFER AFTER PTR
.CMINC==:6 ;COUNT OF CHARACTERS FOLLOWING PTR
.CMABP==:7 ;ATOM BUFFER POINTER
.CMABC==:10 ;ATOM BUFFER SIZE
.CMGJB==:11 ;ADR OF GTJFN ARG BLOCK
CM%GJB==:777777 ;ADR OF GTJFN ARG BLOCK
;FUNCTION DESCRIPTOR BLOCK
.CMFNP==:0 ;FUNCTION AND POINTER
CM%FNC==:777B8 ;FUNCTION CODE
CM%FFL==:777B17 ;FUNCTION-SPECIFIC FLAGS
CM%LST==:777777 ;LIST POINTER
.CMDAT==:1 ;DATA FOR FUNCTION
.CMHLP==:2 ;HELP TEXT POINTER
.CMDEF==:3 ;DEFAULT STRING POINTER
;FLAGS
CM%ESC==:1B0 ;ESC SEEN
CM%NOP==:1B1 ;NO PARSE
CM%EOC==:1B2 ;END OF COMMAND SEEN
CM%RPT==:1B3 ;REPEAT PARSE NEEDED
CM%SWT==:1B4 ;SWITCH TERMINATED WITH ":"
CM%PFE==:1B5 ;PREVIOUS FIELD ENDED WITH ESC
CM%RAI==:1B6 ;RAISE INPUT
CM%XIF==:1B7 ;NO INDIRECT FILES
CM%WKF==:1B8 ;WAKEUP AFTER EACH FIELD
CM%NOC==:1B11 ;SEMI COLON DOES NOT START COMMENT
;CM%NSF==:1B12 ;THE SUFFIX IS NOT NEEDED (BUT LEGAL IF THERE)
;CM%BRK==:1B13 ;BREAK SET IS SUPPLIED
;CM%PO ==:1B14 ;PARSE-ONLY - DON'T VERIFY
CM%HPP==:1B15 ;HELP PTR PRESENT
CM%DPP==:1B16 ;DEFAULT PTR PRESENT
CM%SDH==:1B17 ;SUPPRESS DEFAULT HELP MESSAGE
;FLAGS FOR CMTAD FUNCTION
CM%IDA==:1B0 ;INPUT DATE
CM%ITM==:1B1 ;INPUT TIME
CM%NCI==:1B2 ;NO CONVERT TO INTERNAL FORMAT
;FLAGS IN KEYWORD TABLE (FIRST WORD OF STRING IF B0-6 = 0)
CM%INV==:1B35 ;INVISIBLE
CM%NOR==:1B34 ;NO-RECOGNIZE (PLACE HOLDER)
CM%ABR==:1B33 ;ABBREVIATION
CM%FW==:1B7 ;FLAG WORD (ALWAYS SET)
;LOCAL MACRO FOR NOPARSE RETURNS
DEFINE NOPARS (CODE)<
MOVEI T1,CODE
CALL XCOMNE ;;"CALL" INSTEAD OF "JRST" TO HELP DEBUGGING
>
;BIT DEFENITIONS FOR THE TEXTI BREAK SETS
CM%CZE==0,,001400 ;CTRL/Z ESC
CM%TOP==2360,,001400 ;TOPS-10 CODES
CM%PU0==375417,,306360 ;TEXTI PUNCTUATION WORD 0
CM%PU1==777774,,001760 ; WORD 1
CM%PU2==400000,,000760 ; WORD 2
CM%PU3==400000,,00740 ; WORD 3
CM%BEL==220,,0 ;CARRIAGE RETURN, LINE FEED
;LOCAL FLAGS (RH OF F)
CMQUES==1B18 ;? TYPED
CMSWF==1B19 ;BEG OF SWITCH SEEN
CMUSRF==1B20 ;USER NAME REQUIRED
CMDEFF==1B21 ;DEFAULT FIELD GIVEN
CMCFF==1B22 ;^F RECOGNIZED FIELD
CMQUE2==1B23 ;IN SECOND OR SUBSEQUENT HELP POSSIBILITY
CMBOL==1B24 ;FIELD IS AT BEG OF LINE
CMTF1==1B25 ;INTERNAL TEMP FLAG
CMINDF==1B26 ;DOING GTJFN ON INDIRECT FILE
CMINDT==1B27 ;INDIRECT FILE IS A TERMINAL
CMCLCV==1B28 ;LAST CHARACTER WAS ^V (UNLESS ^V^V) FOR CMCIN
CMPS1F==1B29 ;PASS1 (FIND LONGEST STRING)
CMPS2F==1B30 ;PASS2 (REJECT FUNCTIONS NOT YIELDING LONGEST STRING)
CMQCAN==1B31 ;HELP CANDIDATE
CMILLF==1B32 ;LINEFEED LAST FLAG DURING INDIRECT
CMEEOC==1B33 ;[7115] COMND ENTERED WITH CM%EOC SET
;FLAGS IN FUNCTION DISPATCH TABLE
;NOTE: ONLY THE LEFT HALF IS AVAILABLE
CMNOD==1B0 ;NO DEFAULT POSSIBLE
CMSBF==1B1 ;SPECIAL BREAK MASK ALLOWED
CMNP1==1B2 ;NO PASS ONE FOR THIS FUNCTION FLAG
NOIBCH=="(" ;NOISE WORD BEG CHARACTER
NOIECH==")" ;NOISE WORD END CHARACTER
CMSWCH=="/" ;SWITCH CHARACTER
CMSWTM==":" ;SWITCH TERMINATOR
CMHLPC=="?" ;HELP CHARACTER
CMCOM1=="!" ;COMMENT CHARACTER
CMCOM2==";" ;FULL LINE COMMENT CHARACTER
CMDEFC=="#" ;DEFAULT FIELD CHARACTER
CMFREC=="F"-100 ;FIELD RECOGNITION CHARACTER
CMINDC=="@" ;INDIRECT FILE CHARACTER
CMRDOC=="H"-100 ;REDO COMMAND CHARACTER
CMQTCH=="""" ;CHARACTER FOR QUOTED STRINGS
CMCONC=="-" ;LINE CONTINUATION CHARACTER
CMQUOT=="V"-100 ;CHARACTER TO QUOTE NEXT CHARACTER
;LOCAL AC USAGE
; F/ FLAGS
; P1/ ORIGINAL,,CURRENT POINTER TO FUNCTION DESCRIPTOR BLOCK
; P2/ POINTER TO STATE BLOCK (T1 OF CALL)
; P3/ REMAINING FREE SPACE COUNT OF USER'S BUFFER
; P4/ CURRENT POINTER
; P5/ COUNT OF VALID CHARACTERS FOLLOWING CURRENT POINTER
; P6/ TRVAR
.COMND::MCENT
CALL XCOMND ;DO THE WORK
XCTU [HRRZ T4,.CMFLG(P2)] ;GET REPARSE DISPATCH ADDRESS IF ANY
JUMPE T4,COMN1
TXNE F,CM%RPT ;REPARSE NEEDED?
HRRM T4,-1(P) ;YES, EFFECT TRANSFER
COMN1: MRETNG
XCOMND::TRVAR <TDSAV4,TMPSTS,EXPLEN,XTRALN,PRECHR,PREERR,FSLEN,BSTLEN,BSTERR,<CNODE,WPN>,<SPCMSK,4>,ATBPTR,ATBSIZ,STKFEN,FNARG,<CMCCM,2>,<OCMCCM,2>,PWIDTH,TABSIZ,DATPT,TABDON,CURSOR,CURPOS,KEYSIZ,BIGSIZ,RCFLGS,CMRBRK,SUFPTR,SUFPT0,ATBSUF,INDFLG,TADCNT,CHAR> ; [7292][7325][7.1047]
;...
;NOTE: THE REASON THIS LIST IS SO LONG IS THAT MANY OF THESE VARIABLES COULD
;APPROPRIATELY BE STKVARED IN LOCAL ROUTINES USED WITHIN XCOMND. HOWEVER, EACH
;STKVAR CALL TAKES TWO EXTRA MEMORY WORDS, SO THIS SINGLE TRVAR SEEMS
;LIKE A GOOD WAY TO DO IT.
;TDSAV4 - SAVED USER'S AC4 DURING TIME/DATE PARSING
;EXPLEN - EXPECTED LENGTH OF INPUT
;XTRALN - EXTRA LENGTH, LIKE 1 FOR COLON IN DEVICES
; OR 2 FOR DOUBLE COLON ON NODE NAMES
;PRECHR - PREFIX CHARACTER FOR CMRFLD
;PREERR - ERROR CODE FOR CMRFLD
;FSLEN - FILESPEC LENGTH
;BSTLEN - LONGEST ATOM BUFFER THAT HAS FAILED
;BSTERR - ERROR CODE ASSOCIATED WITH BSTLEN
;CNODE - NODE NAME IN ASCII
;SPCMSK - CUSTOM USER BREAK MASK FOR FIELD
;ATBPTR - ATOM BUFFER POINTER
;ATBSIZ - ATOM BUFFER SIZE
;STKFEN - STACK FENCE
;FNARG - DATA FOR FUNCTION
;CMCCM - SAVED CC MODE WORDS
;PWIDTH - TERMINAL WIDTH
;TABSIZ - TAB SIZE LARGER THAN LARGEST KEYWORD
;DATPT - POINTER USED DURING CMTAD
;TABDON - END OF TAB FOR "?" ON KEYWORD
;CURSOR - LINE POSITION (KEYWORD "?")
;CURPOS - " " "
;KEYSIZ - KEYWORD LENGTH ("?")
;BIGSIZ - LENGTH OF LONGEST KEYWORD
;RCFLGS - RCDIR/RCUSR RETURNED FLAGS
;CMRBRK - BREAK CONTROL FOR FIELD ROUTINE
;SUFPTR - POINTER TO SUFFIX STRING
;SUFPT0 - POINTER TO BEGINNING OF SUFFIX STRING
;ATBSUF - POINTER TO WHERE SUFFIX BEGINS IN
; ATOM BUFFER
;[7325] OCMCCM - Old CCOC words for ^V, ^W, ^U, ^H weirdness
;[7325] TADCNT - Counter/Flag for help when in .CMTAD so
;[7325] that we are not overly helpful
;[7.1047] CHAR - Temp spot for character
SETZM INDFLG
SETOM TADCNT ;[7325] Init .CMTAD help count
MOVEM T1,P2 ;SAVE BLOCK PTR
HRL P1,T2 ;KEEP BEGINNING OF FUNCTION CHAIN IN P1
MOVEM P,STKFEN ;SAVE CURRENT STACK AS FENCE
MOVEI T1,[COMX11,,.CMRTY ;LIST OF BYTE POINTERS TO CHECK
COMX12,,.CMBFP
COMX13,,.CMPTR
COMX14,,.CMABP
0] ;MARK OF END OF LIST
CALL CHKABP ;CHECK ALL BYTE PTRS
UMOVE P3,.CMCNT(P2) ;SET UP ACTIVE VARIABLES
UMOVE P4,.CMPTR(P2)
UMOVE P5,.CMINC(P2)
XCTU [HLLZ F,.CMFLG(P2)] ;GET 'GIVEN' FLAGS
TXZ F,CM%PFE!CMPS2F!CMEEOC ;[7115] CLEAR VARIOUS FLAGS
TXNE F,CM%EOC ;[7115] WAS END OF COMMAND ALREADY DETECTED ?
TXO F,CMEEOC ;[7115] YES - REMEMBER FOR LATER
TXZE F,CM%ESC ;PREVIOUS FIELD HAD ESC?
TXO F,CM%PFE ;YES
XCTU [HRRZ T1,.CMIOJ(P2)] ;GET OUTPUT JFN
RFCOC ;GET CC MODES
ERJMPR [ITERR()] ;Here is where a bad output designator
;will get detected. Pass error back to caller.
DMOVEM T2,CMCCM ;SAVE THEM
TXZ T2,3B<CMFREC*2+1> ;NO ECHO ^F
TXO T2,3B<.CHLFD*2+1> ;PROPER HANDLING OF NL
ANDCM T3,[3B1+3B7+3B9+3B11+3B19] ;[7292] No echo for ^R, ^U, ^V, ^W, & escape
CAMN T2,CMCCM ;[7292] Change only if necessary
CAME T3,1+CMCCM ;[7292]
SFCOC
ERJMPR [ITERR()] ;Only if changed during execution.
DMOVEM T2,OCMCCM ;[7292] Save ours for later
XCOMB0: SETZM EXPLEN ;CLEAR EXPECTED LENGTH OF FIELD
TXO F,CMPS1F ;MARK THAT WE'RE IN PASS 1
XCOMB: SETOM BSTLEN ;-1 IS SMALLER THAN ANY ATOM BUFFER SIZE
SETZM BSTERR ;SAY ONLY LENGTH ERRORS SEEN SO FAR
HLR P1,P1 ;START AT BEGINNING OF FUNCTION CHAIN
; ..
; ..
XCOMN0: MOVE P,STKFEN ;NORMALIZE STACK IN CASE ABORTED ROUTINES
SETZM XTRALN ;NO EXTRA LENGTH YET
TXZ F,CM%ESC+CM%NOP+CM%EOC+CM%RPT+CM%SWT+CMBOL+CMCFF+CMDEFF+CMINDF+CMCLCV ;INIT FLAGS
TXNE F,CMEEOC ;[7115] GET IN HERE WITH END OF COMMAND SET ?
JRST XCOM5 ;[7115] YES - DON'T CHECK FOR BOL
XCTU [CAMN P4,.CMBFP(P2)] ;AT BEG OF LINE?
TXO F,CMBOL ;YES
XCOM5: HRRZ T1,P1 ;GET ADDRESS ONLY
ULOAD T1,CM%FFL,.CMFNP(T1) ;GET FUNCTION FLAGS
STOR T1,CM%FFL,F ;KEEP WITH OTHER FLAGS
HLRZ Q1,P1 ;GET CM%DPP FLAG FROM FIRST BLOCK ONLY
XCTU [XOR F,.CMFNP(Q1)]
TXZ F,CM%DPP
XCTU [XOR F,.CMFNP(Q1)]
TXNN F,CM%BRK ;IS THERE SPECIAL BREAK MASK?
JRST XCOM6 ;NO
HRRZ T1,P1 ;GET ADDRESS OF CURRENT FUNCTION BLOCK
XCTU [MOVE T4,.CMBRK(T1)] ;YES, GET USER ADDRESS OF IT
XCTU [DMOVE T1,(T4)] ;GET FIRST TWO WORDS
XCTU [DMOVE T3,2(T4)] ;GET REST
DMOVEM T1,SPCMSK ;SAVE FIRST TWO WORDS
DMOVEM T3,2+SPCMSK ;AND REST
XCOM6: TXNN F,CM%DPP ;IS HE SUPPLYING DEFAULT STRING?
JRST XCOM5A ;NO, NO CHECK
UMOVE T1,.CMDEF(Q1) ;GET DEFAULT POINTER
CALL CHKBP ;[9112] (T1/T1) Check it for legality
CAIA ;ILLEGAL, SKIP ILDB (0 POINTER = NULL STRING)
XCTBU [ILDB T1,T1] ;GET FIRST BYTE OF STRING
SKIPN T1 ;NON-ZERO?
TXZ F,CM%DPP ;NO, MAKE BELIEVE NO DEFAULT GIVEN
XCOM5A: HRRZ T1,P1
UMOVE T1,.CMDAT(T1) ;GET FUNCTION DATA IF ANY
MOVEM T1,FNARG ;KEEP LOCALLY
CALL GETFUN ;GET FUNCTION CODE
HLRZ T1,CFNTAB(T1) ;GET TABLE POINTER FOR IT
MOVE T1,COBFGS(T1) ;GET FLAG WORD
JXN T1,CMNOD,XCOM0 ;DISPATCH NOW IF NO DEFAULT POSSIBLE
TXNE F,CM%PFE ;PREVIOUS FIELD ENDED WITH ESCAPE?
JRST [ CALL GETFUN ;YES, SEE IF GUIDEWORD FUNCTION
CAIN T1,.CMNOI ;IS IT?
JRST XCOM8 ;YES, SO GO TYPE GUIDE WORDS, NO POSSIBLE COMMENT, LINE CONTINUATION ETC.
JRST .+1] ;NOT GUIDE WORD FUNCTION
CALL INILCH ;SKIP SPACES AND INIT ATOM BUFFER
NLINE: CALL RDCRLF ;END-OF-LINE FIRST THING ON IT?
CAIA ;NO
JRST [ TXNE F,CMPS1F ;JUST SCANNING?
JRST .+1 ;YES, SO CR NOT SPECIAL
CALL UNCRLF ;YES, PUT IT BACK
CALL GETFUN ;OBTAIN THE FUNCTION CODE
CAIN T1,.CMCFM ;CONFIRM FIRST? (TEST REST BEFORE REPROMPT)
JRST XCOM0 ;YES, DO IT
TXNN F,CM%DPP ;IF DEFAULT GIVEN, USE IT ON CR
TXNN F,CMBOL ;AT BGN OF BFR?
JRST XCOM0 ;NO, TRY NULL FIELD
CAIN T1,.CMFIL ;PARSE ARBITRARY FILE?
JRST CHKDEF ;YES, CHECK GTJFN BLOCK FOR DEFAULT NAME
CAIN T1,.CMNOI ;NO, PARSING A NOISE WORD?
JRST XCOM0 ;YES, DO IT
CALL CHKCFM ;NO, SEE IF THERE IS A CONFIRM IN THE LIST
JRST CHKDF1 ;NONE, REISSUE PROMPT
JRST XCOM0] ;YES, PROCESS IT
CAIN T1,CMINDC ;INDIRECT INDICATOR?
JRST [ TXNN F,CM%XIF ;YES, INDIRECT FILES ALLOWED?
JRST CMIND ;YES, DO IT
JRST .+1] ;NO, KEEP CHARACTER AS ORDINARY INPUT
CAIE T1,.CHESC ;ESC AT BEG OF FIELD?
CAIN T1,CMFREC
JRST XCOM2 ;^F AT BEG OF FIELD
; CAIN T1,CMDEFC ;OR DEFAULT REQUEST?
; JRST XCOM2 ;YES
XCOM3: CALL CMDIP ;PUT CHAR BACK
XCOM0: CALL GETFUN ;GET FUNCTION CODE
XCOM7: TXNN F,CMPS1F ;ARE WE ON PASS1?
JRST XCOM8 ;NO
HLRZ T2,CFNTAB(T1) ;YES, GET ADDRESS OF CONTROL WORD
MOVE T1,COBFGS(T2) ;GET SPECIAL FUNCTION FLAGS
TXNE T1,CMNP1 ;SHOULD WE PERFORM A PASS 1?
;*NOTE* Some functions should not be included
;in pass 1 because they will end up reading
;the whole line and as a result, will be the
;the only function which will get parsed due
;to the number of characters it has read.
;The check that used to be here tested whether
;the function had a break mask and would not
;perform pass1 if it did not. We don't want
;pass 1 performed on .CMTXT but it does have
;a break mask so previous check was inadequate.
JRST XC1 ;NO, FORGET THIS FUNCTION
CALL CMRFLD ;SEE HOW MUCH INPUT THIS FUNCTION WOULD READ
XCOM9: CAML T1,EXPLEN ;BETTER THAN ANY EXPECTED LENGTH SEEN SO FAR?
MOVEM T1,EXPLEN ;YES, REMEMBER NEW LONG LENGTH
JRST XC1 ;SIZE UP REST OF FUNCTIONS
XCOM8: HRRZ T1,CFNTAB(T1) ;DO IT
JRST 0(T1)
CHKDEF: UMOVE T3,.CMGJB(P2) ;GET GTJFN BLOCK ADDRESS
UMOVE T3,.GJNAM(T3) ;GET DEFAULT NAME STRING POINTER
JUMPN T3,XCOM0 ;IF ONE THERE, PARSE IT
CHKDF1: CALL CMRSET ;NO,
SETZ P5, ;EMPTY LINE, IGNORE
CALL CMRTY0 ;REDO PROMPT
JRST XCOMB0 ;RESET PASS1 AND TRY NEXT LINE
;ROUTINE TO GET FUNCTION CODE INTO T1.
GETFUN: HRRZ T1,P1
ULOAD T1,CM%FNC,.CMFNP(T1) ;GET FUNCTION CODE
CAIL T1,0 ;[7404] Function negative?
CAIL T1,MAXCFN ;[7404] Or out of range?
ITERR COMNX1 ;[7404] Yes, return so
RET
;CHKCFM - ROUTINE TO SEE IF A .CMCFM FUNCTION APPEARS ON THE USER'S LIST.
;ACCEPTS P1/ POINTER TO USERS FUNCTION BLOCK
; CALL CHKCFM
;RETURNS +1: IF THERE IS NO .CMCFM ON THE LIST, P1 UNCHANGED
; +2: IF A .CMCFM IS ON THE LIST, P1 IS UPDATED FOR THAT BLOCK
;USES T1.
CHKCFM: STKVAR <LSTPTR> ;TO SAVE P1
MOVEM P1,LSTPTR ;SAVE P1 IN CASE WE NEED TO RESTORE IT
CHKCFL: CALL GETFUN ;GET FUNCTION CODE FROM BLOCK
CAIN T1,.CMCFM ;CONFIRM?
RETSKP ;YES, RETURN SKIP, P1 POINTS TO ITS BLOCK
HRRZ T1,P1 ;POINT TO THE CURRENT BLOCK
ULOAD T1,CM%LST,.CMFNP(T1) ;AND GET THE POINTER TO THE NEXT
HRRM T1,P1 ;UPDATE P1 TO THE NEXT BLOCK
JUMPN T1,CHKCFL ;LOOP AND CHECK BLOCK IF IT EXISTS
MOVE P1,LSTPTR ;BUT IF AT END, RESTORE OLD VALUE OF P1
RET ;AND RETURN NONSKIP
;ESC OR ^F AT BEG OF FIELD
XCOM2: TXNN F,CM%DPP ;YES, HAVE DEFAULT STRING?
JRST XCOM3 ;NO
CALL CMDCH ;FLUSH RECOG CHAR
CALL CMGDP ;GET DEFAULT POINTER
TXO F,CMDEFF ;NOTE FIELD ALREADY IN ATOM BFR
XCOM1: XCTBU [ILDB T1,Q1]
JUMPE T1,[CALL CHKLCH ;CHECK FOR NULL DEFAULT STRING
CAIG T1,0
ITERR COMX10
CALL TIELCH ;END OF STRING, TIE OFF ATOM BUFFER
TXNE F,CMCFF ;^F RECOG?
JRST XCOMRF ;YES, GO GET MORE INPUT
MOVEI T1,.CHESC
CALL CMDIBQ ;YES, APPEND ESC TO BUFFER
CALL TIECMD ;MAKE SURE NULL AT END OF COMMAND
CALL CMRSET ;RESET LINE VARIABLES
JRST XCOMN0] ;TREAT AS ORDINARY INPUT
CALL STOLCH ;STORE CHAR IN ATOM BUFFER
CALL CMDIB ;YES, CHAR TO MAIN BUFFER ALSO
JRST XCOM1
;ROUTINE TO YIELD DEFAULT POINTER IN Q1
CMGDP: HLRZ Q1,P1 ;GET PTR TO FIRST FLD BLOCK
UMOVE T1,.CMDEF(Q1) ;GET DEFAULT STRING PTR
CALL CHKBP ;[9112] (T1/T1) Check pointer
ITERR COMX15 ;BAD
MOVEM T1,Q1
RET
;TABLE OF COMND FUNCTIONS
; RH: ADDRESS OF CODE THAT IMPLEMENTS THAT FUNCTION
; LH: ADDRESS OF CONTROL BLOCK
;
;FORMAT OF CONTROL BLOCK:
;
COBLEN==0 ;LENGTH OF BLOCK INCLUDING THIS WORD
COBBRK==1 ;0 OR ADDRESS OF BREAK MASK FOR FIELD
COBFGS==2 ;FLAG WORD
COBPRE==3 ;0 OR <XWD PREFIX CHARACTER ,, ERROR CODE>
COBSUF==4 ;ADDRESS OF SUFFIX STRING OR 0
;NOTE: IF YOU CHANGE THIS FORMAT, IT'S NICE TO LEAVE THE DISPATCH
; IN THE RIGHT HALF SO THAT CREF LISTINGS SHOW WHERE
; TO FIND THE CODE
DEFINE MNX (FCODE,DISP,BRK,BTS,PRE,SUF)
< DEFARG BRK..,BRK
DEFARG BTS..,BTS
..PRE==PRE ;MIGHT HAVE COMMAS IN IT
DEFARG PRE..,..PRE
DEFARG SUF..,SUF
IFN .-FCODE,<PRINTX ?CFNTAB item FCODE is out of order
>
XWD [EXP 5,BRK..,BTS..,PRE..,SUF..],DISP
>
;MACRO TO ASSIGN THE SECOND ARG TO THE FIRST, UNLESS THE SECOND IS BLANK,
;IN WHICH CASE 0 IS ASSIGNED
DEFINE DEFARG (VARG,VALUE)
< VARG==0 ;;FIRST ASSUME DEFAULTING TO 0
IFNB <VALUE>,<VARG==VALUE>
>
CFNTAB: PHASE 0
MNX .CMKEY,XCMKEY,KEYBRK,CMSBF ;KEYWORD
MNX .CMNUM,XCMNUM,NUMBRK ;INTEGER
MNX .CMNOI,XCMNOI,0,CMNP1 ;NOISE WORD
MNX .CMSWI,XCMSWI,SWIBRK,CMSBF,<XWD "/",NPXNSW> ;SWITCH
MNX .CMIFI,XCMIFI,FILBRK ;INPUT FILE
MNX .CMOFI,XCMOFI,FILBRK ;OUTPUT FILE
MNX .CMFIL,XCMFIL,FILBRK ;GENERAL FILESPEC
MNX .CMFLD,XCMFLD,FLDBRK,CMSBF ;ARBITRARY FIELD
MNX .CMCFM,XCMCFM,0,CMNP1 ;CONFIRM
MNX .CMDIR,XCMDIR,DIRBRK ;DIRECTORY NAME
MNX .CMUSR,XCMUSR,USRBRK ;USER NAME
MNX .CMCMA,XCMCMA,0,CMNP1 ;COMMA
MNX .CMINI,XCMINI,0,CMNOD+CMNP1 ;INITIALIZE COMMAND
MNX .CMFLT,XCMFLT,FLTBRK ;FLOATING POINT NUMBER
MNX .CMDEV,XCMDEV,DEVBRK,CMSBF,0,[ASCIZ /:/] ;DEVICE NAME
MNX .CMTXT,XCMTXT,TXTBRK,CMSBF+CMNP1 ;TEXT
MNX .CMTAD,XCMTAD,0,CMNP1 ;TIME AND DATE
MNX .CMQST,XCMQST,0,CMNP1 ;QUOTED STRING
MNX .CMUQS,XCMUQS,0,CMNOD+CMNP1 ;UNQUOTED STRING
MNX .CMTOK,XCMTOK,0,CMNP1 ;TOKEN
MNX .CMNUX,XCMNUM,NUXBRK ;NUMBER DELIMITED BY NON-DIGIT
MNX .CMACT,XCMACT,ACTBRK ;ACCOUNT
MNX .CMNOD,XCMNOD,NODBRK,0,0,[ASCIZ /::/] ;NODE NAME
DEPHASE
MAXCFN==.-CFNTAB
;RESET EVERYTHING SUCH THAT FIELD CAN BE REREAD.
;THIS ROUTINE IS USEFUL IF FIELD IS READ, AND THEN WE DECIDE WE WANT
;TO REREAD IT WITH A DIFFERENT LENGTH OR BREAK SET SPECIFIED.
CMFSET: CALL CMRSET ;PUT MAIN POINTER TO BEGINNING OF FIELD
CALL INILCH ;RESET POINTER TO ATOM BUFFER
TXZ F,CM%ESC+CM%EOC+CMCFF+CMQUES ;RESET PARSER
RET
;RESET VARIABLES TO BEGINNING OF CURRENT FIELD
CMRSET: SUB P5,P3 ;RESET VARIABLES TO BGN OF FIELD
XCTU [ADD P5,.CMCNT(P2)] ;KEEP ALL CURRENT INPUT
UMOVE P3,.CMCNT(P2)
UMOVE P4,.CMPTR(P2)
RET
;STANDARD EXITS
;RETURN AND REPEAT PARSE BECAUSE USER DELETED BACK INTO ALREADY
;PARSED TEXT
;THIS ALSO HAPPENS ON CASES LIKE "COPY <ESC>" WHICH BEEPS. IF REPARSE WEREN'T
;DONE IN THIS CASE, THEN USER CAN'T CONTINUE WITH "(FROM)". REPARSE ALSO
;HAPPENS ON "EDIT FOO.XX<ESC>" IF IT BEEPS. THIS IS NECESSARY FOR PROGRAMS THAT
;CALL COMND ONCE FOR EACH FUNCTION CODE INSTEAD OF WITH A CHAIN, SINCE THE
;MODIFIED FIELD MAY BECOME VALID FOR A PREVIOUS FUNCTION. FOR INSTANCE, EXEC
;CALLS COMND IN THE "EDIT" COMMAND FOR OLD FILE, AND THEN IF THAT FAILS, IT
;CALLS COMND FOR ANY FILE. IF BOGUS FILESPEC PROVOKES THE "ANY FILE" CASE,
;AND THE USER EDITS THE FILESPEC INTO AN EXISTING FILE, WE WANT THE OLD FILE
;RETURN TO BE TAKEN.
XCOMRF: TXO F,CM%RPT ;REQUEST REPEAT
MOVE T1,P4 ;COMPUTE NUMBER CHARS IN BUFFER
UMOVE T2,.CMBFP(P2)
MOVEM T2,P4 ;RESET PTR TO TOP OF BUFFER
CALL SUBBP ;COMPUTE PTR-TOP
MOVEM T1,P5 ;SET AS NUMBER CHARS FOLLOWING PTR
ADDM T1,P3 ;RESET COUNT TO TOP OF BUFFER
JRST XCOMX2 ;OTHERWISE UPDATE VARIABLES AND EXIT
;GOOD RETURNS
;RETURN TO FIXESC TO CHECK FOR TRAILING ESCAPE.
FIXESC: CALL CMCIN ;READ CHARACTER AFTER FIELD
FIXES1: TXNN F,CM%ESC ;ESCAPE AFTER FIELD?
CALL CMDIP ;NO, PUT IT BACK
XCOMXR: TXNE F,CM%ESC ;RECOG CHARACTER TERMINATED?
CALL CMDCH ;YES, FLUSH IT
XCOMXI: CALL ESCSPC ;TYPE SPACE IF FIELD ENDED WITH ESCAPE
XCOMX2: UMOVEM P3,.CMCNT(P2) ;UPDATE VARIABLES
UMOVEM P4,.CMPTR(P2)
UMOVEM P5,.CMINC(P2)
XCOMX1: MOVE P,STKFEN ;RESET STACK
XCTU [HRRZ T1,.CMIOJ(P2)] ;GET OUTPUT JFN
DMOVE T2,CMCCM ;GET SAVED CC MODES
MOVE Q3,LSTERR ;DON'T LOSE REAL ERROR CODE IF SFCOC "FAILS"
SFCOC ;RESTORE THEM
ERJMPS .+1
MOVEM Q3,LSTERR ;RESTORE CORRECT ERROR
UMOVEM P2,T1 ;ENSURE BLK ADR UNCHANGED
UMOVEM P1,T3 ;RETURN PTR TO FUNCTION BLOCK USED
TXZ F,CM%FFL ;FLUSH FUNCTION FLAGS
XCTU [HLLM F,.CMFLG(P2)] ;RETURN FLAGS
XCTU [HLLM F,T1] ;RETURN IN T1 ALSO
RET
;ROUTINE TO PUT SPACE IN BUFFER IF ESCAPE ENDED FIELD.
ESCSPC: TXZN F,CM%ESC ;FIELD TERMINATED WITH RECOG?
RET ;NO, NOTHING TO DO
TXNE F,CMCFF ;^F RECOG?
JRST XCOMRF ;YES, GET MORE INPUT BEFORE RETURNING
TXO F,CM%ESC ;SET FLAG
MOVEI T1," " ;TERMINATE TYPESCRIPT WITH SPACE
CALL CMDIB
CALLRET CMDIP ;DON'T REALLY PARSE THE SPACE UNTIL NEXT FIELD!
;FAILURE RETURNS - FAILED TO PARSE
XCOMNE: MOVEM T1,LSTERR ;SAVE ERROR CODE
CALL TIELCH ;FIX ATOM BUFFER SO "/BLECCH" ON 'SWITCH OR
;CONFIRM' GIVES "?INVALID SWITCH" INSTEAD OF
;"?NOT CONFIRMED"
XCOMNP: JXN F,CMQUES,CMRTYP ;IF IN HELP, DON'T RETURN NOW
CALL ATMLEN ;GET LENGTH OF ATOM BUFFER
ADD A,XTRALN ;ADD IN POSSIBLE EXTRA LENGTH
CAMG A,BSTLEN ;DID THIS FUNCTION GET FURTHER BEFORE ERROR?
JRST XC1 ;NO
MOVEM A,BSTLEN ;YES, REMEMBER NEW BEST
MOVE A,LSTERR ;GET BEST ERROR SO FAR
MOVEM A,BSTERR ;REMEMBER IT
XC1: CALL CMRSET ;RESET FIELD VARIABLES
UMOVEM P5,.CMINC(P2) ;FIX USER BLOCK
HRRZ T1,P1
ULOAD T1,CM%LST,.CMFNP(T1) ;GET PTR TO NEXT FN BLOCK
HRRM T1,P1 ;SAVE IT
JUMPN T1,XCOMN0 ;DISPATCH IF THERE IS ANOTHER FUNCTION
TXZE F,CMPS1F ;WERE WE ON PASS 1?
JRST [ TXO F,CMPS2F ;SAY WE'RE ON PASS 2
JRST XCOMB] ;GO PARSE ANYTHING THAT'S LONG ENOUGH
TXZE F,CMPS2F ;WERE WE ON PASS2?
JRST [ TXNE F,CMQUES ;WERE WE GIVING HELP?
JRST CMRT1 ;YES, SO NOW HELP IS OVER
SETZM EXPLEN ;LENGTH PROBLEMS, ALLOW ANY LENGTH THIS TIME
JRST XCOMB] ;TRY AGAIN
TXO F,CM%NOP ;NO OTHER POSSIBILITIES, SAY NO PARSE
MOVE T2,BSTERR ;RETURN BEST ERROR CODE
MOVEM T2,LSTERR
UMOVEM T2,T2 ;RETURN IT IN 2 ALWAYS
JRST XCOMX1
;ROUTINE TO MEASURE CURRENT LENGTH OF ATOM BUFFER. IT RETURNS NUMBER
;OF CHARACTERS IN T1.
ATMLEN: MOVEI T1,0 ;START WITH NO CHARACTERS
UMOVE T2,.CMABP(P2) ;GET POINTER TO ATOM BUFFER
ATML1: XCTBU [ILDB T3,T2] ;GET NEXT CHARACTER FROM ATOM BUFFER
JUMPE T3,R ;NULL MEANS END
AOJA T1,ATML1 ;NOT END, COUNT CHARACTER AND LOOP
;HERE AFTER EACH HELP OUTPUT
CMRTYP: CALL CMRSET ;RESET FIELD VARIABLES
HRRZ T1,P1
ULOAD T1,CM%LST,.CMFNP(T1) ;GET NEXT FUNCTION IN LIST
HRRM T1,P1
TXNE F,CMQUE2 ;[7325] Are we done giving all help?
SETOM TADCNT ;[7325] Yes, set this back to normal
TXO F,CMQUES ;MARK IN HELP SEQUENCE
TXNE F,CM%SDH ;MAKE CHECKS TO SET CMQUE2 ONLY AFTER
TXNE F,CM%HPP ; WE HAVE ALREADY TYPED SOMETHING
TXO F,CMQUE2 ;NOTE SECOND OR SUBSEQUENT POSSIBILITY
JUMPN T1,XCOMN0 ;DO SUBSEQUENT HELPS
CMRT1: CALL OSYNCH ;CAUSE ^O IN HELP TO FLUSH HELP BUT NOT FLUSH REPROMPT
SOS P5 ;FLUSH QMARK FROM INPUT
TXZ F,CMQUES+CMQUE2 ;NOTE NOT IN HELP
CALL CMRTY0 ;RETYPE LINE
JRST XCOMB0 ;RESTART PARSE OF CURRENT FIELD
;OSYNCH WAITS FOR ALL OUTPUT TO FINISH AND THEN UNDOES ANY POSSIBLE ^O.
;THE UNDOING IS SO THAT IF THE TYPIST TYPES ^O TO FLUSH THE OUTPUT OF THE
;PREVIOUS COMMAND, SHE'LL SEE THE PROMPT FOR THE NEXT COMMAND. THE PURPOSE
;OF WAITING (SOBE) BEFORE UNDOING ^O IS SO THAT SHE DOESN'T SEE ANY OF THE
;OUTPUT SHE EXPECTED TO FLUSH WITH THE ^O.
;
;OSYNCH THEN GETS TO THE LEFT MARGIN. THIS IS USED FOR PROMPTING FOR NEW
;COMMANDS, AND FOR RETYPING THE COMMAND AFTER HELP MESSAGES. (TYPISTS MAY
;TYPE ^O DURING LENGTHY HELP MESSAGES)
OSYNCH: XCTU [HRRZ T1,.CMIOJ(P2)] ;WAIT FOR ANY CURRENT OUTPUT
SOBE
DOBE
RFMOD ;GET MODES
ERJMP .+1 ;[7394]
TXZE T2,TT%OSP ;OUTPUT SUPPRESS WAS ON?
SFMOD ;YES, CLEAR IT
ERJMP .+1 ;[7394]
XCTU [HRRZ T1,.CMIOJ(P2)] ;GET HANDLE ON OUTPUT CHANNEL
RFPOS
ERJMP .+1 ;[7394]
HRRZ T2,T2
JUMPE T2,R ;DONE IF ALREADY AT LEFT MARGIN
MOVEI T1,.CHLFD ;DO CR TO GET TO LEFT MARGIN
CALLRET CMCOUT
;RETYPE LINE INCLUDING ADVANCE INPUT IF ANY
CMRTY0: XCTU [SKIPE Q1,.CMRTY(P2)] ;GET ^R PTR IF ANY
CMRTY3: XCTU [CAMN Q1,.CMBFP(P2)] ;UP TO TOP OF BFR?
JRST CMRTY2 ;DONE WITH ^R PTR
XCTBU [ILDB T1,Q1] ;TYPE ^R BFR
JUMPN T1,[CALL CMCOUT
JRST CMRTY3]
CMRTY2: UMOVE Q1,.CMBFP(P2) ;GET MAIN BFR PTR
CMRTY4: CAMN Q1,P4 ;UP TO CURRENT PTR?
JRST CMRTY5 ;YES, GO DO ADVANCE INPUT
XCTBU [ILDB T1,Q1] ;TYPE OUT COMMAND BFR
CALL CMCOUT
JRST CMRTY4
CMRTY5: MOVE Q2,P5 ;GET INPUT COUNT
CMRTY6: SOJL Q2,[SETZ T1, ;ALL INPUT PRINTED, TIE OFF BFR
XCTBU [IDPB T1,Q1]
RET]
XCTBU [ILDB T1,Q1]
CALL CMCOUT
JRST CMRTY6
;INDIRECT FILE HANDLING
CMIND: SETOM INDFLG
JXO F,CMQUE2,XCOMNP ;NO SECOND HELP POSSIBILITIES
CALL CMATFI ;GET A JFN ON THE INDIRECT FILE
JRST CMINDE ;FAILED
CALL CMCFM0 ;DO A CONFIRM
JRST [CALL INDRLJ
NOPARS NPXNC] ;NOT CONFIRMED
UMOVE T1,T1 ;GET JFN
DVCHR ;READ CHARACTERISTICS OF DEVICE
ERJMP CMIND0 ;FAIL, ASSUME NOT A TERMINAL
LDB T1,[POINTR T1,DV%TYP] ;GET DEVICE TYPE
CAIN T1,.DVTTY ;IS IT A TTY?
TXOA F,CMINDT ;YES, REMEMBER THAT
CMIND0: TXZ F,CMINDT ;NO, CLEAR FLAG
UMOVE T1,T1 ;THE JFN
MOVX T2,<FLD(7,OF%BSZ)+OF%RD>
OPENF ;OPEN IND FILE
JRST CMINDE ;LOSS
CALL CMFSET ;FLUSH INDIRECT FILESPEC FROM BUFFER BUT LEAVE SPACES IN
CMIND1: UMOVE T1,T1 ;THE JFN
BIN ;READ CHAR FROM IND FILE
ERJMP CMIND2 ;FAILED, PROBABLY END OF FILE
JUMPE T2,CMIND1 ;IGNORE NULLS
TXZ F,CMILLF ;FIRST ASSUME THIS ISN'T EOL
CAIN T2,.CHCRT ;IGNORE CR
JRST CMIND1
CAIN T2,.CHCNZ ;IS THIS A CONTROL-Z?
TXNN F,CMINDT ;AND FROM A TERMINAL?
SKIPA ;NO
JRST CMIND3 ;YES, TREAT AS END OF FILE
CAIE T2,.CHLFD ;CONVERT EOL TO SPACE
CAIN T2,.CHESC ;DITTO ESC (BUT THERE SHOULDN'T BE ANY)
JRST [ MOVEI T2," "
TXO F,CMILLF ;REMEMBER THAT TRAILING SPACE MAY HAVE TO BE REMOVED
JRST .+1]
MOVE T1,T2
CALL CMDIBQ ;PUT CHAR IN BUFFER WITHOUT TYPEOUT
JRST CMIND1
CMIND2: GTSTS ;GET FILE STATUS
TXNN T2,GS%EOF ;EOF?
JRST CMINDE ;NO, SOME KIND OF ERROR
CMIND3: CLOSF ;YES, CLOSE IT
JFCL
TXNE F,CMILLF ;TRAILING SPACE DUE TO EOL?
CALL CMDIP ;YES, REMOVE IT SINCE SOMEONE MAY BE STRICT
MOVEI T1,.CHLFD ;TIE OFF LINE
CALL CMDIBQ
JRST XCOMRF ;REPARSE LINE AS NOW CONSTITUTED
CMINDE: CALL CME0
JRST XCOMNP ;SAY PARSE FAILURE
CME0: UMOVE T1,T1 ;GET INDIRECT JFN AGAIN
MOVE T3,LSTERR ;DON'T LET CLOSF CLOBBER ERROR CODE
CLOSF ;CLOSE IT
ERJMPS .+1 ;COULDN'T, IGNORE
MOVEM T3,LSTERR
RET
INDRLJ: UMOVE T1,T1 ;GET INDIRECT JFN AGAIN
MOVE T3,LSTERR ;DON'T LET RLJFN CLOBBER ERROR CODE
RLJFN ;RELEASE IT
ERJMPS .+1 ;COULDN'T, IGNORE
MOVEM T3,LSTERR
RET
;****************************************
;COMND - LOCAL SUBROUTINES
;****************************************
;TEXTI BREAK SET. NORMALLY ONLY COMND ACTION CHARACTERS, BUT IF
;CM%WKF ON (WAKE ON EVERY FIELD), MUST WAKE ON ALL FIELD TERMINATORS TOO
BRINI. ;INITIALIZE
BRKCH. .CHLFD ;BREAK ON LINEFEED
BRKCH. .CHFFD ;FORMFEED WORKS TO GET TO START COMMAND ON NEW PAGE
BRKCH. .CHESC ;BREAK ON RECOGNITION
BRKCH. CMHLPC ;BREAK ON HELP REQUEST
BRKCH. CMFREC ;BREAK ON FIELD COMPLETION CHARACTER
REGBRK: EXP W0.,W1.,W2.,W3. ;REGULAR TEXTI BREAK MASK
ALLBRK: W0.!FLDB0.
W1.!FLDB1. ;SPECIAL BREAK MASK FOR WAKING ON ALL FIELDS
W2.!FLDB2.
W3.!FLDB3.
KEYBRK: EXP KEYB0.,KEYB1.,KEYB2.,KEYB3. ;KEYWORD BREAK MASK
SWIBRK: EXP KEYB0.,KEYB1.,KEYB2.,KEYB3. ;SWITCH BREAK SAME AS KEYWORD
USRBRK: EXP USRB0.,USRB1.,USRB2.,USRB3. ;USER NAME BREAK MASK
ACTBRK: EXP ACTB0.,ACTB1.,ACTB2.,ACTB3.
FLDBRK: EXP FLDB0.,FLDB1.,FLDB2.,FLDB3. ;STANDARD FIELD BREAK SET
EOLBRK: EXP EOLB0.,EOLB1.,EOLB2.,EOLB3. ;BREAK SET FOR READING TO END OF LINE
TXTBRK: EXP EOLB0.,EOLB1.,EOLB2.,EOLB3. ;TEXT BREAK SET, READ TO END OF LINE
FILBRK: EXP FILB0.,FILB1.,FILB2.,FILB3. ;FILE BREAK SET
DIRBRK: EXP DIRB0.,DIRB1.,DIRB2.,DIRB3. ;DIRECTORY BREAK SET
NODBRK: EXP FLDB0.,FLDB1.,FLDB2.,FLDB3. ;NODE BREAK SET
;SAME AS FIELD RIGHT NOW
DEVBRK: EXP DEVB0.,DEVB1.,DEVB2.,DEVB3. ;DEVICE BREAK SET
;CMRFLD READS INPUT FOR THE CURRENT FUNCTION.
;
;ACCEPTS: P1/ RIGHT HALF TELLS WHAT FUNCTION
; F/ CM%BRK TELLS WHETHER USER HAS SUPPLIED SPECIAL BREAK
; MASK
; CFNTAB/ CMSBF TELLS WHETHER SPECIAL BREAK MASKS ARE ALLOWED FOR
; THIS FUNCTION
;
; WORD COBBRK TELLS ADDRESS OF STANDARD BREAK MASK
;
; WORD COBPRE HAS 0 OR CHAR,,ERROR
;
; WORD COBSUF HAS 0 OR ADDRESS OF SUFFIX STRING
;
;RETURNS +1: T1/ LENGTH OF FIELD INCLUDING PREFIX AND SUFFIX
CMRFLD: CALL GETBRK ;GET BREAK MASK FOR FUNCTION
MOVEM T2,CMRBRK ;SAVE BREAK SET ADDRESS
JUMPE T2,R ;IF NO BREAK MASK, RETURN
CALL GETFUN ;GET FUNCTION CODE
HLRZ T4,CFNTAB(T1) ;GET ADDRESS OF CONTROL BLOCK
SKIPE T1,COBSUF(T4) ;SKIP IF SPECIAL SUFFIX STRING
HRLI T1,440700 ;MAKE BYTE POINTER
MOVEM T1,SUFPTR ;REMEMBER SUFFIX POINTER
MOVEM T1,SUFPT0 ;REMEMBER INITIAL SUFFIX POINTER
HLR T1,COBPRE(T4) ;GET POSSIBLE PREFIX CHARACTER
HRRZM T1,PRECHR ;REMEMBER IT
HRRZ T1,COBPRE(T4) ;GET POSSIBLE ERROR CODE FOR WHEN PREFIX NOT TYPED
MOVEM T1,PREERR ;SAVE POSSIBLE ERROR CODE
CALLRET CMRFL0 ;JOIN COMMON CODE
;CMRFLN READS EXACTLY N CHARACTERS. IN OTHER WORDS, THE N + 1ST CHARACTER
;IS A BREAK CHARACTER, NO MATTER WHAT IT IS.
;
;ACCEPTS: T1/ -N
CMRFLN: MOVEM T1,CMRBRK ;SET UP SPECIAL COUNT AS BREAK MASK
CALLRET CMRFL0 ;JOIN COMMON CODE
;CMRFLX READS FIELD WITH SPECIFIED BREAK MASK. THIS IS USUALLY UNNECESSARY
;BECAUSE THE FUNCTION CODE HAS A STANDARD BREAK MASK WHICH CMRFLD CORRECTLY
;COMPUTES
CMRFLX: MOVEM T1,CMRBRK ;SAVE SPECIFIC BREAK MASK
SETZM SUFPTR ;NO SUFFIX
SETZM SUFPT0
SETZM PRECHR ;NO PREFIX CHARACTER
CMRFL0: MOVNI T1,1
ADJBP T1,ATBPTR
MOVEM T1,ATBSUF ;INITIALLY ASSUME NO SUFFIX IN ATOM BUFFER
TXNE F,CMDEFF ;DEFAULT GIVEN?
JRST CMRATT ;YES, ALREADY IN BUFFER
CMRAT1: CALL CMROOM ;MAKE SURE ROOM FOR ANOTHER CHARACTER
CALL CMCIN ;GET NEXT CHARACTER
CAIN T1,CMQUOT ;THE QUOTING CHARACTER?
JRST CMRQUT ;YES, READ NEXT CHARACTER REGARDLESS
CAIE T1,CMFREC ;^F RECOGNITION?
CAIN T1,.CHESC ;ESC?
JRST [ TXNN F,CMPS1F ;IF SCANNING, ESCAPE ISN'T SPECIAL
;WITHOUT THIS CHECK, "COPY FOO.BAR$$"
;BEEPS INSTEAD OF DEFAULTING!
CALL CHKLCH ;YES, NOT SPECIAL IF ANYTHING NOW IN ATOM BFR
JUMPG T1,CMRATT
CALL CMAMBT] ;NOTHING THERE, DING
CAIE T1," " ;SPACE OR TAB?
CAIN T1,.CHTAB
JRST [ CALL CHKLCH ;YES, RETURN IF ANYTHING IN ATOM BFR
JUMPG T1,.+1
JRST CMRAT1] ;OTHERWISE IGNORE
XCTBU [LDB T1,P4] ;CHKLCH CLOBBERED CHARACTER, GET IT BACK
CAIE T1,CMHLPC ;HELP REQUEST?
IFSKP. ;[7.1014] Yes
CALL CHKFIL ;[7.1014] (/) Parsing a file?
IFSKP. ;[7.1014] Yes, just scanning?
TXNE F,CMPS1F ;[7.1014] Check for scan
IFSKP. ;[7.1014] Not scanning
TXO F,CMQUES ;[7.1014] Flag that we are doing help
CALL DOHLP ;[7.1014] (/) Now give provided help, if any
ENDIF. ;[7.1014]
JRST CMRATR ;[7.1014] Now pass the ? to GTJFN%
ENDIF. ;[7.1014]
CALL ECOCHK ;[7.1014] (/) Yes - echoes on?
IFNSK. ;[7.1014]
MOVEI T1,.TICCG ;[7.1014] No - send a "ding"
CALL CMCOUT ;[7.1014] (T1/) This does the "ding"
CALL CMDCH ;[7.1014] (P3,P4,P5/) Delete '?' from buffer
JRST XCOMRF ;[7.1014] Reparse
ENDIF. ;[7.1014]
TXO F,CMQCAN ;[7.1014] Yes, flag help request
JRST CMRTIE ;[7.1014]
ENDIF. ;[7.1014]
SKIPG CMRBRK ;BREAK SET GIVEN?
JRST CMRAT3 ;NO, KEEP READING REGARDLESS OF CHARACTER
SKIPN SUFPTR ;IS THERE A SUFFIX POINTER?
JRST CMRNS ;NO
ILDB T2,SUFPTR ;GET NEXT CHARACTER OF SUFFIX
CAMN T1,T2 ;DOES CURRENT CHARACTER MATCH SUFFIX CHARACTER?
JRST [ MOVE T3,SUFPTR ;YES, SEE IF SUFFIX ENTIRELY MATCHED NOW
ILDB T3,T3 ;PEEK AT NEXT CHARACTER IN SUFFIX
JUMPN T3,CMRAT3 ;IF NOT OVER, NOTHING TO DO YET
SETZM SUFPTR ;SUFFIX MATCHED, REMEMBER THAT.
CALL SUFLEN ;GIVE LENGTH CREDIT TO SUFFIX
XMOVEI T1,[EXP -1,-1,-1,-1] ;FORCE BREAK ON EVERYTHING SINCE SUFFIX HAS BEEN SEEN
MOVEM T1,CMRBRK
JRST CMRAT1] ;CHECK FOR ESCAPE OR QUESTION MARK AFTER SUFFIX
CAME T1,T2 ;WAS CHARACTER PART OF SUFFIX?
JRST [ MOVE T3,SUFPT0 ;NO, SO RESTART THE SUFFIX SCAN
MOVEM T3,SUFPTR
JRST .+1]
CMRNS: CALL SKPNB ;SKIP IF CHARACTER IS NOT A BREAK CHARACTER
JRST CMRAT1 ;PREFIX SEEN, SKIP IT
JRST CMRATR ;CHAR IS A BREAK.
MOVE T3,ATBPTR ;NOT A BREAK, REMEMBER CURRENT ATOM POINTER,
MOVEM T3,ATBSUF ;SO WE'LL KNOW WHERE SUFFIX BEGINS
CMRAT3: CALL STOLCH ;BUILD KEYWORD STRING
JRST CMRAT1
;[7.1014]
;CHKFIL - Routine to check to see if parsing a filespec
;
; Call with:
; no arguments
; CALL CHKFIL
;
; Returns:
; +1 - Not parsing a file (some other function)
; +2 - COMND function code was .CMIFI, .CMOFI, or .CMFIL
;
; Clobbers no ACs.
CHKFIL: SAVEAC <T1> ;Preserve character in T1
CALL GETFUN ;(/T1) Get functions code
CAIE T1,.CMIFI ;Parsing input file?
CAIN T1,.CMOFI ; or maybe an output file?
RETSKP ;One or the other
CAIE T1,.CMFIL ;Parsing a file?
RET ;Not parsing any file functions
RETSKP ;Yes, let caller know
;ROUTINE TO CHECK IF ECHOES ARE TURNED ON
;CALL ECOCHK
;
;ACCEPTS: P2/ POINTER TO STATE BLOCK IN USER'S ADDRESS SPACE
;
;RETURNS: +1 ECHOES ARE OFF
; +2 ECHOES ARE ON
; CLOBBERS T1,T2
ECOCHK: XCTU [HLRZ T1,1(P2)] ;GET INPUT JFN
RFMOD ;GET MODE WORD
ERJMP .+1 ;[7394]
TRNN T2,TT%ECO ;ECHOES ON?
RET ;NOPE
RETSKP ;YEP
;Routine to return the break mask for a function
;
;CALL GETBRK
;
;Returns +1 Always
;
; T2/ Address of break mask
;
;Preserves T1, Trashes T4
GETBRK: SAVEAC <T1> ;SAVE T1
CALL GETFUN ;GET THE FUNCTION
HLRZ T4,CFNTAB(T1) ;GET THE ADDRESS OF CONTROL BLOCK
SKIPN T2,COBBRK(T4) ;GET ADDRESS OF STANDARD BREAK MASK
RET ;NONE, SO RETURN 0
MOVE T1,COBFGS(T4) ;GET SPECIAL FIELD FLAGS
TXNE F,CM%BRK ;DOES USER HAVE SPECIAL BREAK MASK
TXNN T1,CMSBF ;IS ONE ALLOWED?
RET ;NOT GIVEN OR NOT ALLOWED, RETURN
XMOVEI T2,SPCMSK ;USE SPECIAL MASK
RET ;AND RETURN
;Routine to check if a character is a break character or not.
;This routine allows one to specify a break set on the call
;
;CALL CHKBRK
;
;Accepts T1/ Character to check
; T2/ Address of break set mask
;
;Returns +1/ Character is a break character
; +2/ Character is not a break character
;
; T1/ Character
; Preserves T1, T2, T3 and T4 ;[7413]
;
CHKBRK: SAVET ;[7413]
JUMPE T2,RSKP ;IF NO BREAK SET, RETURN
CHKBR1: MOVE T4,T2 ;PUT BREAK SET ADDRESS IN T4
MOVE T2,T1 ;GET COPY OF CHAR
IDIVI T2,40 ;COMPUT INDEX INTO BIT MASK
MOVE T3,BITS(T3) ;GET BIT FOR CHARACTER
ADD T2,T4 ;GET WORD OFFSET INTO BREAK SET
TDNE T3,0(T2) ;BREAK CHARACTER?
RET ;YES
RETSKP ;NO
;ROUTINE USED WITHIN CMRFLD TO SKIP IF CHARACTER IN T1 IS NOT A BREAK
;CHARACTER.
;IF A PREFIX IS EXPECTED, AND THE CURRENT CHARACTER IS NOT THE CORRECT
;PREFIX CHARACTER, A PARSE ERROR OCCURS.
;
;ACCEPTS: T1/ CHARACTER
;
;RETURNS: +1 CHARACTER WAS PREFIX
; +2 CHARACTER IS A BREAK CHARACTER
; +3 CHARACTER NOT A BREAK CHARACTER
; T1/ CHARACTER
SKPNB: SKIPLE PRECHR ;SPECIAL PREFIX CHARACTER WANTED?
JRST SKHPRE ;HANDLE PREFIX
MOVE T2,CMRBRK ;GET ADDRESS OF BREAK SET
CALL CHKBR1 ;CHECK IF ITS A BREAK CHARACTER
RETSKP ;YES
JRST SK2RET ;NO, GIVE DOUBLE SKIP
SKHPRE: CAME T1,PRECHR ;MAKE SURE PREFIX CHARACTER IS SUPPLIED
JRST [ CALL TIELCH ;MAKE SURE 0-LENGTH ATOM SEEN FOR ERROR EVALUATION
RETSKP]
SETOM PRECHR ;IT'S BEEN SEEN, REMEMBER
RET ;RETURN TO SAY PREFIX SEEN
;ROUTINE USED TO COMPUTE LENGTH OF SUFFIX. THIS LENGTH IS USED AS CREDIT
;TOWARDS THE LENGTH OF ATOMS WHEN COMPUTING ERRORS. THIS CALCULATION ENABLES
;THE TYPIST TO BE TOLD THAT "ABC:" IS AN INCORRECT DEVICE, BUT "ABC" IS AN
;INCORRECT KEYWORD, WHEN THE CHOICES ARE DEVICE OR KEYWORD, AND "ABC" IS NOT
;EITHER.
;NOTE THAT IF WE EVER AGREE TO PUT THE COLON IN THE ATOM BUFFER, WHICH
;WOULD BE A CONSISTENT THING TO DO, THIS SPECIAL CODE WOULD BE UNNECESSARY,
;SINCE THE COLON WOULD BE IN THE ATOM BUFFER AS A REGULAR CHARACTER TO
;CONTRIBUTE TO THE LENGTH.
SUFLEN: MOVEI A,0 ;A WILL HOLD LENGTH
MOVE B,SUFPT0 ;GET POINTER TO BEGINNING OF SUFFIX
SUFL1: ILDB C,B ;GET NEXT CHARACTER FROM SUFFIX
CAIE C,.CHNUL ;LEAVE LOOP IF NULL FOUND
AOJA A,SUFL1
MOVEM A,XTRALN ;REMEMBER LENGTH OF SUFFIX
RET
;GET HERE WHEN QUOTING CHARACTER HAS BEEN SEEN. QUOTING CHARACTER
;MEANS NEXT CHARACTER SHOULD NEVER BE CONSIDERED A BREAK CHARACTER NO
;MATTER WHAT IT IS.
;[7.1047] Unless the quoting character is being used for directory names
;[7.1047] or usernames.
CMRQUT: MOVEM T1,CHAR ;[7.1047] Save quoting character
CALL GETFUN ;[7.1047] (/T1) Get current function
CAIE T1,.CMUSR ;[7.1047] Is function username?
CAIN T1,.CMDIR ;[7.1047] Or directory?
IFNSK. < ;[7.1047] Yes to either
NOPARS COMNX4> ;[7.1047] Say illegal character
MOVE T1,CHAR ;[7.1047] Get character back
CALL STOLCH ;STORE THE QUOTING CHARACTER
CALL CMCINX ;READ CHARACTER BEING QUOTED (BUT DON'T SET FLAGS!)
JRST CMRAT3 ;STORE CHARACTER AND CONTINUE
;CMROOM DECIDES IF WE CAN READ ANOTHER CHARACTER
CMROOM: SKIPLE CMRBRK ;BREAK SET GIVEN?
RET ;YES, SO KEEP READING
AOSG CMRBRK ;NO, COUNT. HAVE WE READ ENOUGH?
RET ;COUNT NOT EXHAUSTED, KEEP READING.
XMOVEI T1,[EXP -1,-1,-1,-1]
MOVEM T1,CMRBRK ;COUNT EXHAUSTED, FOR BREAK ON ANYTHING
RET ;GO READ NEXT CHARACTER IN CASE IT'S "?".
CMRATR: CALL CMDIP ;PUT CHARACTER BACK IN BUFFER
CMRATT: SKIPN SUFPT0 ;IS THERE A SUFFIX?
JRST CMRNS2 ;NO
MOVEI T1,1 ;ATBSUF GOT SAVED BEFORE THE LAST IDPB
ADJBP T1,ATBSUF ;GET POSITION WHERE SUFFIX BEGAN IN ATOM BUFFER
MOVEM T1,ATBPTR ;RESET ATOM POINTER TO GET RID OF SUFFIX
CALL TIELCH ;REALLY GET RID OF IT BY PUTTING NULL AFTER IT
CMRNS2: TXNE F,CM%ESC ;DON'T TYPE SUFFIX IF GUY DIDN'T TYPE ESCAPE
SKIPN SUFPT0 ;IS THERE A SUFFIX?
JRST CMRNS1 ;NO SUFFIX, OR GUY DIDN'T TYPE ESCAPE BEFORE TYPING SUFFIX
TXNN F,CMPS1F ;DON'T REMOVE ESCAPE IF JUST SCANNING
CALL CMDCH ;REMOVE ESCAPE BEFORE APPENDING SUFFIX
SKIPN SUFPTR ;DID USER TYPE ENTIRE SUFFIX?
JRST CMRNS1 ;NO
TXNE F,CMPS1F ;ARE WE ONLY MEASURING LENGTHS?
JRST CMRNS1 ;YES, SO DON'T TYPE THE SUFFIX NOW
CALL SUFLEN ;NO, COMPUTE LENGTH
CMRS: ILDB T1,SUFPTR ;THERE'S A SUFFIX, GET THE NEXT CHARACTER OF IT
JUMPE T1,CMRNS1 ;LEAVE LOOP IF END OF SUFFIX
CALL CMDIB ;SHOW SUFFIX TO USER
JRST CMRS
;END OF FIELD, CHECK TO SEE IF DEFAULT SHOULD BE USED...
CMRNS1: CALL CHKLCH ;SEE HOW LARGE THE FIELD IS
JUMPN T1,CMRTIE ;DON'T USE DEFAULT IF SOMETHING TYPED
TXNN F,CM%DPP ;DID USER SUPPLY A DEFAULT?
JRST [ TXNN F,CMPS1F ;DON'T COMPLAIN IF MERELY MEASURING
SKIPG PRECHR ;NO DEFAULT. WAS PREFIX CHARACTER EXPECTED?
JRST CMRTIE ;NO
MOVE T1,PREERR ;YES, GET ERROR CODE (SUCH AS "SLASH NOT SEEN")
CALL XCOMNE] ;GIVE ERROR. "CALL" IS FOR DEBUGGING PURPOSES
SAVEQ ;ONLY BECAUSE CMGDP CLOBBERS Q1
TXO F,CMDEFF ;MARK THAT DEFAULT BEING USED
CALL CMGDP ;GET POINTER TO DEFAULT STRING
CMRDF1: XCTBU [ILDB T1,Q1] ;GET NEXT CHARACTER OF DEFAULT STRING
JUMPE T1,CMRTIE ;DONE IF NULL
CALL SKPNB ;STRIP ILLEGAL CHARS, SO CORRECT ERROR CODE GOES TO USER
JRST CMRDF1 ;PREFIX SEEN, GET NEXT CHARACTER
JRST CMRTIE ;BREAK CHARACTER, STOP COPYING
CALL STOLCH ;NON-NULL, STORE IN ATOM BUFFER
JRST CMRDF1 ;CONTINUE COPYING
CMRTIE: CALL TIELCH ;MAKE SURE NULL AT END OF ATOM BUFFER
CALL ATMLEN ;YES, GET LENGTH OF ATOM WE JUST READ
ADD T1,XTRALN ;INCLUDE POSSIBLE SUFFIX
SKIPGE PRECHR ;PREFIX CHARACTER SEEN?
AOJ T1, ;YES, COUNT IT
TXNE F,CMDEFF ;ARE WE USING THE DEFAULT STRING?
MOVEI T1,0 ;YES, SO USE 0 SINCE USER DIDN'T REALLY TYPE ANYTHING
TXNE F,CMPS1F ;PASS 1?
JRST XCOM9 ;YES, UPDATE BEST LENGTH SEEN SO FAR
CAMGE T1,EXPLEN ;IS IT LONG ENOUGH?
JRST XC1 ;NO, SO GIVE UP ON THIS FUNCTION
TXZE F,CMQCAN ;FIELD IS LONG ENOUGH. HELP CANDIDATE?
TXO F,CMQUES ;YES, IT'S ELECTED!
RET
;READ QUOTED STRING INTO ATOM BUFFER
;STRING DELIMITED BY ", "" MEANS LITERAL "
CMRQST: TXNE F,CMDEFF ;HAVE DEFAULT?
RETSKP ;YES
CALL RDCRLF ;SEE IF CRLF FOR DEFAULTING ?
IFSKP.
TXNN F,CM%DPP ;YES - GOT A DEFAULT ?
RET ;NO - FAIL
CALL UNCRLF ;BACK UP SO OTHER FIELDS GET CRLF
MOVE Q2,Q1 ;SAVE ARG POINTER, CMGDP CLOBBERS Q1
CALL CMGDP ;GET DEFAULT STRING POINTER
TXO F,CMDEFF ;NOTE DEFAULT SHOULD BE TAKEN
XCTBU [ILDB T1,Q1] ;GET 1ST CHARACTER OF DEFAULT STRING
ELSE.
CAIN T1,CMHLPC ;FIRST CHAR IS HELP?
JRST [ TXO F,CMQUES ;YES
RETSKP]
CAIE T1,.CHESC
CAIN T1,CMFREC ;RECOGNITION ATTEMPTED?
CALL CMAMBT ;YES, AMBIGUOUS
ENDIF.
CAIE T1,CMQTCH ;START OF STRING?
RET ;NO, FAIL
CMRQS1: TXNE F,CMDEFF ;GOT DEFAULT ?
IFSKP.
CALL RDCRLF ;END OF LINE?
CAIA ;NO
CALLRET UNCRLF ;YES, UNREAD IT AND GIVE FAILURE RETURN
ELSE.
XCTBU [ILDB T1,Q1] ;GET NEXT CHARACTER OF DEFAULT STRING
JUMPE T1,R ;FAILURE IF NOT TERMINATED BY QUOTE
ENDIF.
CAIE T1,CMQTCH ;ANOTHER QUOTE?
JRST CMRQS2 ;NO, GO STORE CHARACTER
TXNE F,CMDEFF ;YES - GOT DEFAULT ?
IFSKP.
CALL CMCIN ;NO, PEEK AT ONE AFTER
ELSE.
XCTBU [ILDB T1,Q1] ;GET NEXT CHARACTER OF DEFAULT STRING
JUMPE T1,CMRQS3 ;IF NULL, END OF DEFAULT REACHED
ENDIF.
CAIN T1,CMQTCH ;PAIR OF QUOTES?
JRST CMRQS2 ;YES, STORE ONE
TXNN F,CMDEFF ;TAKING DEFAULT ?
CALL CMDIP ;NO, PUT BACK NEXT CHAR
CMRQS3: CALL TIELCH ;TIE OFF ATOM BUFFER
RETSKP ;GOOD
CMRQS2: CALL STOLCH ;STORE CHAR IN ATOM BUFFER
JRST CMRQS1 ;KEEP LOOKING
;INIT ATOM BUFFER
INILCH: CALL INILC1
CALLRET CMSKSP ;FLUSH INITIAL SPACES
INILC1: UMOVE T1,.CMABP(P2) ;GET PTR
MOVEM T1,ATBPTR
UMOVE T1,.CMABC(P2) ;GET SIZE
MOVEM T1,ATBSIZ
RET
;SHRINK removes characters from the end of the atom buffer.
;
;Accepts: T1/ number of characters to remove
SHRINK: MOVN T2,T1 ;GET NEGATIVE NUMBER OF CHARACTERS TO REMOVE
ADJBP T2,ATBPTR ;ADJUST ATOM POINTER TO SHRUNKEN END
MOVEM T2,ATBPTR ;REMEMBER NEW END
ADDM T1,ATBSIZ ;SHOW THAT THERE'S MORE ROOM NOW IN ATOM BUFFER
MOVEI T1,.CHNUL ;GET NULL TO MARK END OF ATOM BUFFER
XCTBU [IDPB T1,T2] ;PUT NULL IN
RET
;STORE CHARACTER IN ATOM BUFFER
STOLCH: SOSGE ATBSIZ ;ROOM?
ITERR (COMNX2) ;NO
XCTBU [IDPB T1,ATBPTR]
RET
;CHECK NUMBER OF CHARACTERS IN ATOM BUFFER
CHKLCH: UMOVE T1,.CMABC(P2) ;GET ORIG COUNT
SUB T1,ATBSIZ ;COMPUTE DIFFERENCE
RET
;TIE OFF ATOM BUFFER
TIELCH: SKIPG ATBSIZ ;ROOM FOR NULL?
ITERR COMNX2 ;NO, LOSE
SETZ T1,
MOVE T3,ATBPTR ;GET POINTER
XCTBU [IDPB T1,T3] ;DEPOSIT WITHOUT CHANGING PTR
RET
;GET NEXT INPUT CHARACTER FOR PROCESSING
;HANDLES CONTINUATION LINES
;APPEND TEXT TO BUFFER IF NECESSARY WITH INTERNAL TEXTI
; CALL CMCIN
; RETURNS +1 ALWAYS, T1/ CHARACTER
CMCIN: CALL CMCINX ;GET NEXT CHARACTER
CAIE T1,CMCONC ;POSSIBLE CONTINUATION LINE?
JRST [ CAIE T1,CMQUOT ;NO, CONTROL-V?
TXZA F,CMCLCV ;NO, CLEAR THE FLAG
TXC F,CMCLCV ;YES, TOGGLE FLAG TO HANDLE ^V^V
JRST CMCINT] ;RETURN
TXZE F,CMCLCV ;QUOTED DASH? (AND CLEAR FLAG)
JRST CMCINT ;YES--RETURN THE DASH
CALL CMCINX ;NO, POSSIBLE CONTINUATION, CHECK NEXT
CAIN T1,.CHLFD ;LINEFEED?
JRST CMCIN ;YES. CONTINUATION LINE
CAIE T1,.CHCRT ;NOT LF, MAYBE CR,LF?
JRST [ CALL CMDIP ;NOT CR EITHER, PUT BACK
MOVEI T1,CMCONC ;GET BACK HYPHEN
CALLRET CMCINT] ;LIGHT FLAGS AND RETURN
CALL CMCINX ;WAS CR, DOES LF FOLLOW?
CAIN T1,.CHLFD ;LINEFEED?
JRST CMCIN ;YES. CONTINUATION LINE
CALL CMDIP ;NO. PUT CHARACTER BACK
MOVEI T1,.CHCRT ;AND ALSO PUT
CALL CMDIP ;BACK THE CARRIAGE RETURN
MOVEI T1,CMCONC ;AND GET BACK THE HYPHEN TO
CALLRET CMCINT ;RETURN TO THE CALLER, SETTING FLAGS
;CMCINX READS THE CHARACTER BUT DOESN'T LIGHT ANY FLAGS.
CMCINX: SOJL P5,[SETZ P5, ;MAKE INPUT EXACTLY EMPTY
CALL CMCIN1 ;NONE LEFT, GO GET MORE
JRST CMCINX]
XCTBU [ILDB T1,P4] ;GET NEXT ONE
SOS P3 ;UPDATE FREE COUNT
RET
;ROUTINE TO SKIP IFF NEW-LINE IS NEXT IN BUFFER. IF NOT, THE
;CHARACTER SEEN IN LIEU OF NEW-LINE IS IN T1. NOTE: USE UNCRLF
;TO BACK UP OVER NEW-LINE, INSTEAD OF CMDIP.
RDCRLF: CALL CMCIN ;GET NEXT CHARACTER
CAIE T1,.CHFFD ;FORMFEED COUNTS AS END OF LINE
CAIN T1,.CHLFD ;LINEFEED?
RETSKP ;YES, NEW-LINE
CAIE T1,.CHCRT ;CARRIAGE RETURN?
RET ;NEITHER, SO NOT NEW-LINE
CALL CMCIN ;GET CHARACTER AFTER CARRIAGE RETURN
CAIN T1,.CHLFD ;CARRIAGE RETURN LINEFEED TOGETHER?
RETSKP ;YES, NEW-LINE
CALL CMDIP ;NO, PUT NON-LINEFEED BACK
MOVEI T1,.CHCRT ;SAY CARRIAGE RETURN SEEN
RET
;LIGHT SPECIAL FLAGS ROUTINE. TAKES CHARACTER IN T1.
CMCINT: CAIN T1,CMFREC ;^F?
JRST [ TXO F,CM%ESC+CMCFF ;YES
RET]
CAIN T1,.CHESC ;ESC?
JRST [ TXO F,CM%ESC ;YES
RET]
CAIN T1,.CHLFD ;END OF LINE?
TXO F,CM%EOC ;YES, MEANS END OF COMMAND
RET
CMCIN1: STKVAR <CMCSF,<CMCSAC,7>,CMCSC,CMCBLF>
MOVEM F,CMCSF ;PRESERVE ACS USED BY TEXTI
SETZM CMCBLF ;INIT ACCUMULATED FLAGS
MOVEI T1,CMCSAC
HRLI T1,Q1
BLT T1,P4-Q1+CMCSAC ;SAVE Q1-P4
MOVX T1,RD%JFN+RD%BBG ;SET UP FLAGS
TXNE F,CM%RAI ;RAISE INPUT REQUESTED?
TXO T1,RD%RAI ;YES, PASS IT
TXNE F,CM%WKF ;WAKING ON EVERY FIELD?
TXO T1,RD%BEG ;YES, SO WE WANT REPARSE ON ^U
MOVEI Q3,REGBRK ;FIRST ASSUME REGULAR BREAK SET
TXNE F,CM%WKF ;WAKING ON EVERY FIELD?
MOVEI Q3,ALLBRK ;YES, SO BREAK ON ALL PUNCTUATION TOO
MOVE F,T1 ;PASS FLAGS TO TEXTI
UMOVE Q1,.CMRTY(P2) ;SET UP ^R BUFFER
UMOVE Q2,.CMBFP(P2) ;SET UP TOP OF BUFFER
UMOVE P1,.CMIOJ(P2) ;SET UP JFNS
MOVE P2,P4 ;SET BACKUP LIMIT AS CURRENT PTR
MOVEM P3,CMCSC ;SAVE CURRENT COUNT
SUB P3,P5 ;ADJUST COUNT FOR ADVANCE INPUT
ADJBP P5,P4 ;PUSH POINTER PAST CURRENT INPUT
MOVEM P5,P4
CMCIN2: MOVE T1,P2-Q1+CMCSAC ;RESTORE P2 TO T1
XCTU [HLRZ T1,.CMIOJ(T1)] ;GET INPUT JFN
GTSTS
ERJMPR [ITERR()] ;Only if changed during execution.
TXNE T2,GS%EOF ;AT EOF?
ITERR COMNX9 ;YES, BOMB
SKIPG P3 ;ROOM IN BUFFER FOR MORE INPUT?
ITERR COMNX3 ;NO
CALL ITEXTI ;DO INTERNAL TEXTI
ITERR ;FAIL, POSSIBLY BAD INPUT JFN
TXNE F,RD%BFE ;BUFFER EMPTY?
JRST CMCIN4 ;YES
IORB F,CMCBLF ;ACCUMULATE FLAGS (RD%BLR)
TXNE F,RD%BLR ;BACKUP LIMIT REACHED?
JRST CMCIN4 ;YES, CLEANUP AND REPARSE
MOVE P5,CMCSC ;RECOVER PREVIOUS COUNT
SUB P5,P3 ;COMPUTE CHARACTERS JUST APPENDED
MOVSI T1,CMCSAC ;RESTORE ACS Q1-P4, F
HRRI T1,Q1
BLT T1,P4
MOVE F,CMCSF
RET
;HERE ON RETURN FROM TEXTI WHICH REACHED BACKUP LIMIT OR WHICH RETURNED
;BECAUSE BUFFER EMPTY. MUST REPARSE LINE. RESTORE ACS, BUT LEAVE
;MAIN POINTER AS RETURNED BY TEXTI.
CMCIN4: DMOVE Q1,Q1-Q1+CMCSAC ;RESTORE Q1-P2
DMOVE Q3,Q3-Q1+CMCSAC
MOVE P2,P2-Q1+CMCSAC
MOVE F,CMCSF ;RESTORE F
JRST XCOMRF ;RETURN REPEAT PARSE
;SKIP LEADING TABS OR SPACES
CMSKSP: CALL CMCIN ;GET A CHAR
CAIE T1," " ;SPACE OR TAB?
CAIN T1,.CHTAB
JRST CMSKSP ;YES, KEEP LOOKING
TXNN F,CM%NOC ;CAN SEMI COLON CAUSE A COMMENT?
CAIE T1,CMCOM2 ;YES, IS THIS A SEMI COLON?
SKIPA ;SEMI COLON WILL NOT CAUSE A COMMENT
JRST CMCMT2 ;YES
CAIN T1,CMCOM1
JRST CMCMT1 ;YES
CALLRET CMDIP ;NO, PUT IT BACK AND RETURN
;COMMENT
CMCMT2: SETO T1, ;SAY NO TERMINATOR OTHER THAN EOL
CMCMT1: MOVEM T1,Q2 ;REMEMBER MATCHING TERMINATOR
CMCOM: CALL RDCRLF ;NL?
CAIA ;NO
JRST [ CALL UNCRLF ;YES, PUT IT BACK
JRST CMSKSP] ;DO WHATEVER
CAIE T1,CMFREC ;RECOG REQUEST?
CAIN T1,.CHESC
CALL CMAMB ;YES, DING
CAMN T1,Q2 ;MATCHING CHARACTER?
JRST CMSKSP ;YES, END OF COMMENT
JRST CMCOM ;NO, KEEP LOOKING
;LOCAL ROUTINE - SUBTRACT ASCII BYTE PTRS
; T1, T2/ ASCII BYTE PTRS
; CALL SUBBP
; RETURNS +1 ALWAYS,
; T1/ T1-T2 COMPUTED AS 5*(A1-A2)+(P2-P1)/7
SUBBP: LDB T3,[POINT 6,T1,5] ;[7116] GET POSITION OF FIRST BYTE POINTER
LDB T4,[POINT 6,T2,5] ;[7116] GET POSITION OF SECOND BYTE POINTER
TLZ T1,770000 ;[7116] CLEAR POSITION FIELDS
TLZ T2,770000 ;[7116]
CAILE T3,44 ;[7116] CONVERT GLOBAL P&S TO P
MOVE T3,[EXP ^D36,^D29,^D22,^D15,^D8,^D1]-61(T3) ;[7116]
CAILE T4,44 ;[7116] CONVERT GLOBAL P&S TO P
MOVE T4,[EXP ^D36,^D29,^D22,^D15,^D8,^D1]-61(T4) ;[7116]
SUB T1,T2 ;[7116] SUBTRACT ADDRESSES (SIZES FALL OUT)
IMULI T1,5 ;[7116] COMPUTE NUMBER CHARS IN THOSE WORDS
SUBM T4,T3 ;[7116] COMPUTE P2-P1
IDIVI T3,7 ;[7116] COMPUTE NUMBER CHARS IN THOSE BITS
ADD T1,T3 ;[7116] COMPUTE FINAL VALUE
RET ;[7116]
;LOCAL ROUTINE - DELETE LAST CHAR INPUT
CMDCH: MOVNI T1,1 ;BACK UP BYTE POINTER
ADJBP T1,P4
MOVE P4,T1
AOS P3 ;ADJUST SPACE COUNT
SETZ P5, ;CAN'T BE ANY WAITING INPUT
RET
;LOCAL ROUTINE - DECREMENT INPUT POINTER
CMDIP: XCTBU [LDB T1,P4] ;CHECK THE CHARACTER
CAIE T1,CMFREC ;A RECOG REQUEST CHAR?
CAIN T1,.CHESC
TXZ F,CM%ESC+CMCFF ;YES, RESET FLAGS
MOVNI T1,1 ;BACK UP THE COMMAND POINTER ONE BYTE
ADJBP T1,P4
MOVE P4,T1
AOS P5 ;ADJUST COUNTS
AOS P3
RET
;ROUTINE TO UNREAD END-OF-LINE.
UNCRLF: CALL CMDIP ;PUT THE LINEFEED BACK
XCTBU [LDB T1,P4] ;GET CHARACTER BEFORE LINEFEED
CAIE T1,.CHCRT ;CARRIAGE RETURN?
RET ;NO, DON'T UNREAD IT
CALLRET CMDIP ;YES, UNREAD IT TOO
;ROUTINE TO CALL TO GUARANTEE NULL AT END OF COMMAND SO FAR.
TIECMD: MOVEI T1,.CHNUL ;GET A NULL
CALL CMDIBQ ;PUT IT IN COMMAND, CHECKING FOR ROOM
AOJ P3, ;DON'T REALLY COUNT IT HOWEVER
MOVNI T1,1
ADJBP T1,P4 ;LEAVE BYTE POINTER SO NEXT IDPB OVERWRITES NULL
MOVE P4,T1
RET
;LOCAL ROUTINE - DEPOSIT INTO INPUT BUFFER
CMDIB: CALL CMCOUT ;TYPE THE CHAR
CMDIBQ: SETZ P5, ;CLEAR ADVANCE COUNT
SOSGE P3 ;ROOM?
JRST [ TXNE F,CMINDF ;READING INDIRECT FILE?
CALL CME0 ;YES, CLOSE IT
ITERR COMNX3] ;SAY OUT OF ROOM
XCTBU [IDPB T1,P4] ;APPEND BYTE TO USER'S BUFFER
RET
;APPEND CHARACTER TO INPUT BUFFER
; T1/ CHARACTER
CMAPC: MOVEM T1,T4 ;SAVE CHAR
MOVE T2,P5 ;ADVANCE COUNT
ADJBP T2,P4 ;COMPUTE POINTER TO END OF INPUT
XCTBU [IDPB T4,T2] ;APPEND THE CHAR
AOS P5 ;UPDATE ADVANCE COUNT
RET
;DO CALLER-SUPPLIED HELP TEXT IF ANY
DOHLP: TXNN F,CM%HPP ;USER SPECIFING HELP MESSAGE?
TXNN F,CM%SDH ;NO, ALSO SUPPRESSING DEFAULT HELP?
SKIPA ;PRINTING AT LEAST ONE MESSAGE
RET ;NOT PRINTING ANYTHING
HRROI T1,[ASCIZ /
or/]
TXNE F,CMQUE2 ;IN ALTERNATE HELP POSSIBILITIES?
CALL CMSOUT ;YES, NOT ALTERNATIVE
TXNN F,CM%HPP ;HAVE HELP POINTER?
RET ;NO
MOVEI T1," "
CALL CMCOUT ;SPACE BEFORE USER TEXT
HRRZ T1,P1
UMOVE T1,.CMHLP(T1) ;YES, GET IT
CALL CMUSOU ;YES, TYPE IT
RET
;HANDLE AMBIGUOUS TYPE-IN
;DOESN'T RETURN, BUT "CALL CMAMB" IS OFTEN MORE USEFUL THAN "JRST CMAMB"
;SO DURING DEBUGGING YOU CAN TELL HOW YOU GOT HERE
;CMAMBT GIVES NOPARSE IF NOT LAST ITEM IN LIST
CMAMBT: HRRZ T1,P1
ULOAD T1,CM%LST,.CMFNP(T1) ;GET PTR TO NEXT FN BLOCK
SKIPL PRECHR ;SKIP IF HAVE PREFIX (LIKE "/" FOR SWITCH)
JUMPN T1,[NOPARS NPXAMB] ;NO PARSE IF ANOTHER FN AVAILABLE
CMAMB: TXZN F,CM%ESC ;ESC SEEN?
JRST [ NOPARS NPXAMB] ;NO, SAME AS UNREC
XCTBU [LDB T1,P4] ;GET LAST CHARACTER
CAIE T1,CMFREC ;CHECK FOR ^F
CAIN T1,.CHESC ;DON'T FLUSH IT UNLESS RECOGNITION CHARACTER
;CHECK NECESSARY BECAUSE IF PARTIAL RECOGNITION
;DONE, ESCAPE WAS ALREADY REMOVED FROM
;BUFFER BEFORE APPENDING THE RECOGNITION STUFF
CALL CMDCH ;FLUSH RECOG CHAR FROM BUFFER
MOVEI T1,.CHBEL ;INDICATE AMBIGUOUS
CALL CMCOUT
JRST XCOMRF ;GET MORE INPUT AND RESTART
;OUTPUT CHARACTER TO SPECIFIED DESTINATION
; T1/ CHAR
; CALL CMCOUT
; RETURNS +1 ALWAYS
CMCOUT: MOVE T2,T1
XCTU [HRRZ T1,.CMIOJ(P2)] ;GET OUTPUT JFN
BOUT
ERJMPR [ITERX]
MOVE T1,T2 ;RESTORE CHARACTER
RET
;OUTPUT STRING FROM CURRENT CONTEXT
; T1/ STRING PTR
; CALL CMSOUT
; RETURN +1 ALWAYS
CMSOUT: MOVE T2,T1
XCTU [HRRZ T1,.CMIOJ(P2)] ;GET OUTPUT JFN
SETZ T3,
SOUT
RET
;OUTPUT STRING FROM PREVIOUS CONTEXT
; T1/ STRING PTR
; CALL CMUSOU
; RETURNS +1 ALWAYS
CMUSOU: CALL CHKBP ;[9112] (T1/T1) Check byte pointer
ITERR COMX16 ;BAD
MOVEM T1,T4
XCTU [HRRZ T1,.CMIOJ(P2)] ;GET OUTPUT JFN
CMUSO1: XCTBU [ILDB T2,T4] ;GET BYTE FROM PREVIOUS
JUMPE T2,R ;DONE ON NULL
BOUT
ERJMPR [ITERX]
JRST CMUSO1
;CHECK ALL BYTE PTRS
; T1/ PTR TO LIST OF ADDRESSES, TERMINATED BY 0
CHKABP: SAVEQ
MOVEM T1,Q1 ;SAVE LIST PTR
CHKAB1: HRRZ Q2,0(Q1) ;GET NEXT ADDRESS
JUMPE Q2,R ;DONE ON 0
ADD Q2,P2 ;[7116] MAKE PTR TO BLOCK
UMOVE T1,0(Q2) ;[7116] GET BYTE PTR
CALL CHKBP ;[9112] (T1/T1) Check and normalize pointer
JRST [ HLRZ T1,0(Q1) ;BAD, GET ERROR CODE
ITERR ()] ;RETURN
UMOVEM T1,0(Q2) ;PUT IT BACK
AOJA Q1,CHKAB1 ;DO NEXT
;[9112] Routine to check a byte pointer and increment it.
;Accepts normal byte pointers, -1,,address, and one word global byte pointers.
;Call with T1/ pointer to check
;Returns +1 if illegal pointer
;Returns +2 if legal pointer, T1/ new pointer
CHKBP: LDB T2,[POINT 6,T1,5] ;[9112] Get P or P&S field
CAIL T2,61 ;[9112] Is this a legal seven bit
CAILE T2,66 ;[9112] one word global byte pointer?
IFNSK. ;[9112] Nope, not a one word global byte ptr
HLRZ T2,T1 ;[9112] Get the left half of the word
CAIN T2,-1 ;[9112] User furnished -1,,address?
HRLI T1,(POINT 7,0) ;[9112] Yes, make a real byte pointer
LDB T2,[POINT 6,T1,11] ;[9112] Get byte size of pointer
CAIE T2,7 ;[9112] Is this a proper pointer for us?
RET ;[9112] No, give +1 return
ENDIF. ;[9112] It is a legal pointer
IBP T1 ;INCREMENT AND DECREMENT TO NORMALIZE
CALL DBP
RETSKP ;RETURN GOOD
;************************
;FUNCTIONS
;************************
;INITIALIZE LINE AND CHECK FOR REDO REQUEST
XCMINI: CALL OSYNCH ;SYNCHRONIZE OUTPUT DUE TO POSSIBLE ^O
XCTU [SKIPE Q1,.CMRTY(P2)] ;DO PROMPT IF ANY
CMINI2: XCTU [CAMN Q1,.CMBFP(P2)] ;STOP AT TOP OF BUFFER
JRST CMINI1
XCTBU [ILDB T1,Q1]
JUMPN T1,[CALL CMCOUT
JRST CMINI2]
CMINI1: XCTU [CAMN P4,.CMBFP(P2)] ;BUFFER EMPTY?
JRST CMINI4 ;YES, NO REDO POSSIBLE
XCTBU [LDB T1,P4] ;CHECK LAST CHAR
CAIN T1,.CHLFD ;END OF LINE?
JRST CMINI4 ;YES, LAST COMMAND OK, NO REDO
XCTU [HLRZ T1,.CMIOJ(P2)] ;GET IN JFN
RFMOD ;GET CURRENT WAKEUP CLASS
ERJMP .+1 ;[7394]
MOVE T4,T2 ;SAVE IN T4
TXO T2,TT%WAK ;MAKE SURE WE WAKE AFTER FIRST CHARACTER
SFMOD
ERJMP .+1 ;[7394]
DMOVE T2,OCMCCM ;[7292] Move in our CCOC words
TXZE T2,3B17 ;[7292] Turn off CTRL/H if necessary
IFNSK. ;[7394]
SFCOC ;[7292][7394] It was necessary
ERJMP .+1 ;[7394]
ENDIF. ;[7394]
BIN ;READ FIRST CHAR
ERJMP .+1 ;[7394]
EXCH T2,T4 ;PUT CHARACTER IN T4, ORIGINAL WAKEUP CLASS IN T2
SFMOD ;RESTORE WAKEUP BITS (APPROXIMATELY!)
ERJMP .+1 ;[7394]
DMOVE T2,OCMCCM ;[7292] Move in our former CCOC words
TXNE T2,3B17 ;[7292] Do we need to restore CTRL/H?
SFCOC ;[7292] Yes, then do so.
ERJMP .+1 ;[7394]
CAIN T4,CMRDOC ;THE REDO CHARACTER?
JRST CMINI3 ;YES
BKJFN ;NO, PUT IT BACK
JFCL
CMINI4: MOVE T1,P4 ;RESET LINE VARIABLES
UMOVE T2,.CMBFP(P2)
MOVEM T2,P4
CALL SUBBP ;COMPUTE CHARACTERS IN LINE
ADDM T1,P3 ;UPDATE SPACE COUNT
SETZ P5, ;RESET ADVANCE COUNT
JRST XCOMXI ;RETURN GOOD
CMINI3: UMOVE P3,.CMCNT(P2) ;RESET VARIABLES TO CURR FIELD
UMOVE P4,.CMPTR(P2)
SETZ P5, ;NO INPUT
CALL CMRTY2 ;[7292] Retype with no prompt
JRST XCOMRF ;RETURN TO REPARSE
;SWITCH - LIKE KEYWORD BUT PRECEDED BY SLASH
XCMSWI: TXO F,CMSWF ;NOTE DOING SWITCH
CALL CMRFLD ;READ SWITCH FIELD
JRST KEYW0 ;FINISH LIKE KEYWORD
;KEYWORD LOOKUP FUNCTION
XCMKEY: TXZ F,CMSWF ;NOT SWITCH
CALL CMRFLD ;GET INPUT
KEYW0: CALL DOLOOK ;PERFORM THE LOOKUP
MOVEM T1,SUFPTR ;[7.1014] Save entry into table
MOVEM T3,SUFPT0 ;[7.1014] Save recognize string
TXNE F,CMQUES ;HAD "?"
JRST CMQ1 ;YES, GO TYPE ALTERNATIVES
MOVE Q1,T2 ;RETURN FLAGS
TXNE Q1,TL%AMB ;IF NOT AMBIGUOUS OR
TXNN F,CMSWF ;IF NOT DOING SWITCH,
JRST KEYW1 ;SKIP FOLLOWING CODE
JUMPE P5,KMAMB ;IF NOTHING ELSE IN BUFFER, CAN'T PEEK AHEAD
CALL CMCIN ;SWITCH AND AMBIGUOUS, SEE IF COLON NEXT
CAIE T1,CMSWTM ;DID USER TYPE COLON AFTER SWITCH?
JRST [ CALL CMDIP ;NO, UNREAD THE NONCOLON
CALL KMAMB] ;GO DING, IT'S A REAL AMBIGUOUS SWITCH
CALL STOLCH ;THERE'S A COLON, SO TRY PUTTING IT ON ATOM
CALL CMDIP ;UNREAD THE COLON
CALL TIELCH ;GUARANTEE NULL AFTER COLON IN ATOM BUFFER
CALL DOLOOK ;TRY THE LOOKUP WITH THE COLON THERE
MOVEI T1,1 ;PREPARE TO REMOVE COLON
CALL SHRINK ;NOW WE KNOW THERE'S SOMETHING LIKE "/A:" AND
;"/AB:" IN TABLE AND USER TYPED "/A:"
JXN Q1,TL%NOM,KMAMB ;IF WAS AMB AND COL MAKES IT NOM, THEN USE ORIGINAL DIAGNOSIS
KEYW1: JXN Q1,TL%NOM,[NOPARS NPXNOM] ;NO MATCH
JXN Q1,TL%AMB,KMAMB ;DING
TXNN Q1,TL%ABR ;AN ABBREVIATION?
SETZ T3, ;NO, REMAINDER OF STRING IS NULL
MOVEM T1,Q1 ;SAVE TABLE INDEX
XCTU [HLRZ T2,0(Q1)]
CALL CHKTBS ;GET TABLE ENTRY FLAGS
JXE T1,CM%ABR,KEYW3 ;JUMP IF NOT ABBREVIATION
CALL CHKLCH ;GET NUMBER OF CHARACTERS TYPED
MOVEM T1,Q2 ;SAVE IT
XCTU [HRRZ Q1,0(Q1)] ;GET ENTRY FOR WHICH THIS IS AN ABBREVIATION
XCTU [HLRZ T2,0(Q1)]
CALL CHKTBS ;GET STRING PTR FOR IT
MOVE T3,Q2 ;SKIP OVER PART OF STRING ALREADY TYPED
ADJBP T3,T2
KEYW3: UMOVEM Q1,T2 ;RETURN TABLE INDEX
JXE F,CM%ESC,KEYW4 ;DONE IF NO REC WANTED
MOVEM T3,Q1 ;SAVE PTR TO REMAINDER OF STRING
CALL CMDCH ;FLUSH RECOG CHARACTER
KEYW2: XCTBU [ILDB T1,Q1] ;TYPE REMAINDER OF KEYWORD
JUMPE T1,XCOMXI ;DONE
CALL CMDIB ;APPEND COMPLETION TO BUFFER
CAIN T1,CMSWTM ;A SWITCH TERMINATOR?
JRST [ TXZ F,CM%ESC ;YES, OVERRIDES ESC
TXO F,CM%SWT ;NOTE SWITCH TERMINAOTR
TXNN F,CMSWF ;IN SWITCH?
CALL CMDIP ;NO, PUT TERMINATOR BACK
JRST XCOMXI] ;DONE
JRST KEYW2
KEYW4: CALL CHKLCH ;SEE IF ATOM NON-NULL
JUMPE T1,[NOPARS NPXNUL] ;FAIL IF NULL
JXE F,CMSWF,XCOMXI ;DONE IF NOT SWITCH
CALL CMSKSP ;SKIP SPACES
CALL CMCIN ;GET NON-BLANK CHAR
CAIN T1,CMSWTM ;SWITCH TERMINATOR?
JRST [ TXO F,CM%SWT ;YES, NOTE
JRST XCOMXI] ;DONE
CALL CMDIP ;NO, PUT IT BACK
JRST XCOMXI ;OTHERWISE OK
DOLOOK: UMOVE T2,.CMABP(P2) ;POINT TO KEYWORD BUFFER
MOVE T1,FNARG ;GET TABLE HEADER ADDRESS
CALL XTLOOK ;LOOKUP
ITERR () ;BAD TABLE
RET
;COME HERE WHEN SWITCH OR KEYWORD IS AMBIGUOUS. IF THE USER TYPED ESCAPE,
;THEN WE'LL NOW TRANSFER TO CMAMB TO BEEP. IF ESCAPE WAS NOT TYPED AND THE
;ATOM BUFFER IS EMPTY MEANING THE USER TYPED NOTHING (SUCH AS CONFIRMING WHEN
;A SWITCH OR KEYWORD WAS REQUIRED), WE'LL GIVE THE NPXNUL ERROR.
KMAMB: JXN F,CM%ESC,KMAM01 ;[7.1014] If ESC, then recognize what we can before beep
CALL CHKLCH ;GET LENGTH OF ATOM BUFFER
JUMPN T1,CMAMB ;DO STANDARD AMBIGUOUS STUFF IF SOMETHING IN ATOM BUFFER
NOPARS NPXNUL ;OTHERWISE SAY KEYWORD OR SWITCH MISSING
KMAM01: MOVE Q2,FNARG ;[7.1014] Get table header address
XCTU [HLRZ Q1,(Q2)] ;[7.1014] Get length of table
ADDI Q1,1(Q2) ;[7.1014] Make this last table entry address
MOVE Q2,SUFPTR ;[7.1014] Restore saved table entry
CALL CMNXTE ;[7.1014] (Q1,Q2/T1,Q2) Get next entry
IFSKP. ;[7.1014] Next entry exists
MOVE Q3,T1 ;[7.1014] Save current table entry
DO. ;[7.1014]
CALL CMNXTE ;[7.1014] (Q1,Q2/T1,Q2) Find next entry
EXIT. ;[7.1014] That's all of them
MOVE Q3,T1 ;[7.1014] Save current entry in table
LOOP. ;[7.1014] Look for next entry
ENDDO. ;[7.1014]
CALL CMDCH ;[7.1014] (P3,P4,P5/) Delete last char (ESC)
MOVE T2,SUFPTR ;[7.1014] Get entry address
XCTU [HLRZ T2,(T2)] ;[7.1014] Convert to pointer from string
CALL CHKTBS ;[7.1014] (T2/T1,T2) Make it a byte pointer
MOVE T1,Q3 ;[7.1014] Restore last good lookup
CALL USTCMP ;[7.1014] (T1,T2/T1,T2) Compare the 2 strings
MOVE Q3,T2 ;[7.1014] Save best match byte pointer
DO. ;[7.1014]
SKIPN SUFPT0 ;[7.1159] Have a suffix to work with?
EXIT. ;[7.1159] No, must have been a norec
XCTBU [ILDB T1,SUFPT0] ;[7.1014] Get character
CAMN Q3,SUFPT0 ;[7.1014] Best match yet?
JRST CMAMB ;[7.1014] Yes, indicate so
CALL CMDIB ;[7.1014] (T1/) Deposit character and type it
LOOP. ;[7.1014] Do next character
ENDDO. ;[7.1014]
ENDIF. ;[7.1014]
MOVE Q2,SUFPTR ;[7.1014] Restore saved table entry
XCTU [HLRZ T2,0(Q2)] ;[7.1014] Get string pointer for it
CALL CHKTBS ;[7.1014] (T2/T1,T2) Get flags from string
JXN T1,<CM%INV!CM%NOR>,CMAMB ;[7.1014] Don't do completion on norec's and inv's
XCTBU [LDB Q3,P4] ;[7.1014] Get completion character before we step on it
CALL CMDCH ;[7.1014] (P3,P4,P5/) Remove completion character from buffer
DO. ;[7.1014]
XCTBU [ILDB T1,SUFPT0] ;[7.1014] Get next character
JUMPE T1,ENDLP. ;[7.1014] If null character, then we are done
CALL CMDIB ;[7.1014] (T1/) Insert character and type it
LOOP. ;[7.1014] Do all
ENDDO. ;[7.1014]
JRST XCOMRF ;[7.1014] Restart the process
;"?" TYPED, FIRST PARTIAL MATCH FOUND. TYPE ALL PARTIAL MATCHES
CMQ1: JXN T2,TL%NOM,[
JXN F,CMQUE2,CMRTYP ;DO NOTHING IF NOT FIRST ALTERNATIVE
CALL DOHLP ;DO USER HELP IF ANY
TXNE F,CM%SDH ;DEFAULT HELP SUPPRESSED?
JRST CMRTYP ;YES, DONE
HRROI T1,[ASCIZ / keyword (no defined keywords match this input)/]
CALL CMSOUT ;TYPE MESSAGE
JRST CMRTYP] ;RETYPE LINE AND CONTINUE
CMQ3: MOVEM T1,Q2 ;SAVE TABLE INDEX
CALL DOHLP ;DO USER HELP IF ANY
TXNE F,CM%SDH ;DEFAULT HELP SUPPRESSED?
JRST CMRTYP ;YES, DONE
MOVE Q3,FNARG ;GET TABLE PTR
XCTU [HLRZ Q1,0(Q3)] ;GET TABLE SIZE
MOVE T1,Q1 ;SAVE THE LENGTH OF THE TABLE
ADDI Q1,1(Q3) ;COMPUTE TABLE END ADDRESS FOR BELOW
CAIN T1,1 ;ONLY ONE ELEMENT IN THE TABLE
JRST CMQ6 ;YES.. BYPASS "ONE OF THE FOLLOWING"
HRROI T1,[ASCIZ / one of the following:
/]
CALL CMSOUT
CMTAB0: SOS Q2,SUFPTR ;[7.1014] Gets incremented before each application
MOVE Q3,Q2 ;SAVE IN Q3 SO IT CAN BE REINITIALIZED
SETZM TABSIZ ;START WITH TAB SIZE OF 0
SETOM PWIDTH ;MARK THAT WE DON'T KNOW WIDTH YET
CMTAB1: CALL CMNXTE ;GET TO NEXT VALID KEYWORD IN TABLE
JRST CMTAB2 ;NO MORE IN TABLE
CALL CMGTLN ;CALCULATE LENGTH OF KEYWORD
CAML T1,TABSIZ ;LONGEST SEEN SO FAR?
MOVEM T1,TABSIZ ;YES, REMEMBER IT
JRST CMTAB1 ;LOOK AT REST
CMTAB2: MOVE T1,TABSIZ
MOVEM T1,BIGSIZ ;REMEMBER LENGTH OF LONGEST KEYWORD
MOVEI T1,1+3 ;1 SPACES AFTER CRLF AND LEAVE AT LEAST 3 SPACE BETWEEN ITEMS
ADDM T1,TABSIZ
MOVE Q2,Q3 ;RESTART TABLE POINTER FOR ACTUAL LISTING
CMQ5: CALL CMNXTE ;GET TO NEXT KEYWORD
JRST CMRTYP ;NO MORE, REPEAT COMMAND SO FAR AND CONTINUE
CALL KEYTAB ;JUSTIFY "TYPEBALL" FOR KEYWORD TYPEOUT
CALL CMUSOU ;TYPE IT
JRST CMQ5 ;TRY NEXT
CMQ6: MOVEI T1," " ;GET A BLANK
CALL CMCOUT ;OUTPUT THE CHARACTER
JRST CMTAB0 ;CONTINUE TABLE PROCESSING
;ROUTINE WHICH TAKES POINTER TO TABLE IN Q2, POINTER TO END OF TABLE
;IN Q1, AND RETURNS POINTER TO KEYWORD NAME IN T1. SKIPS UNLESS TABLE
;IS EXHAUSTED. ONLY CONSIDERS PRINTABLE KEYWORDS, AND UPDATES Q2.
CMNXTE: AOS Q2 ;LOOK AT NEXT TABLE ENTRY
CMQ2: CAML Q2,Q1 ;BEYOND END OF TABLE?
RET ;YES, FINISHED LIST
XCTU [HLRZ T2,0(Q2)] ;GET STRING PTR FOR IT
CALL CHKTBS ;GET FLAGS FROM STRING
JXN T1,CM%INV+CM%NOR,CMNXTE ;SKIP ENTRY IF INVISIBLE OR NOREC
UMOVE T1,.CMABP(P2) ;POINT TO KEYWORD BUFFER
CALL USTCMP ;COMPARE
JUMPE T1,CMQ4 ;OK IF EXACT MATCH
JXE T1,SC%SUB,R ;DONE IF NOT SUBSTRING
CMQ4: XCTU [HLRZ T2,0(Q2)] ;GET PTR TO STRING FOR THIS ENTRY
CALL CHKTBS
MOVE T1,T2
RETSKP
;ROUTINE TO CALL BEFORE TYPING KEYWORD IN RESPONSE TO "?". GIVE
;IT USER'S BYTE POINTER IN T1. IT DECIDES WHETHER KEYWORD WILL FIT
;ON THIS LINE, AND STARTS NEW LINE IF NOT. IT THEN OUTPUTS A TAB,
;FOLLOWED BY SWITCH DELIMITER (IF KEYWORD IS A SWITCH).
KEYTAB: SAVET ;DON'T CLOBBER USER'S BYTE POINTER
CALL CMGTLN ;COMPUTE LENGTH OF KEYWORD
MOVEM T1,KEYSIZ ;REMEMBER LENGTH
XCTU [HRRZ T1,.CMIOJ(P2)] ;GET OUTPUT CHANNEL
SKIPL PWIDTH ;DO WE ALREADY KNOW HOW WIDE PAPER IS?
JRST KEY2 ;YES, SO DON'T DO SYSTEM CALL
RFMOD ;ASK SYSTEM WHERE RIGHT MARGIN IS
ERJMP .+1 ;[7394]
LDB T3,[220700,,T2] ;ISOLATE RIGHT MARGIN VALUE
CAIE T3,1 ;RIGHT MARGIN TOO LARGE FOR RFMOD?
JRST KEY3 ;NO, WE'VE GOT IT
MOVEI T2,.MORLW ;YES, ASSUME TERMINAL AND READ IT WITH MTOPR
MTOPR
ERJMP .+1 ;[7394]
KEY3: MOVEM T3,PWIDTH ;SAVE WIDTH, SO NO JSYS CALL NEXT TIME
JRST KEY5 ;FIRST TIME THROUGH, ASSUME NO TAB NEEDED
KEY2: CALL GETPOS ;FIND OUT WHERE ON LINE WE ARE
MOVEM T2,CURPOS ;REMEMBER WHERE WE ARE
CALL CMTAB ;SEE WHERE TAB BRINGS US
ADD T2,BIGSIZ ;MAKE SURE WE HAVE ROOM FOR ANOTHER COLUMN
HRROI T1,[ASCIZ /
/]
CAMG T2,PWIDTH ;ROOM FOR ANOTHER KEYWORD ON THIS LINE?
JRST KEY4 ;YES, SO DON'T START NEW LINE
CALL CMSOUT ;GET TO NEXT LINE
CALL GETPOS ;FIGURE OUT WHERE WE ARE NOW
MOVEM T2,CURPOS
CAIA ;NO TAB NECESSARY AT BEGINNING OF LINE
KEY4: CALL TYPTAB ;TYPE A TAB
KEY5: MOVX T1,CMSWCH
TXNE F,CMSWF ;IN SWITCH FIELD?
CALL CMCOUT ;YES, TYPE SWITCH INDICATOR
RET ;READY TO TYPE KEYWORD ALL ON SAME LINE NOW
CMTAB: ADD T2,TABSIZ ;FIGURE OUT MAXIMUM PLACE TAB CAN MOVE US TO
IDIV T2,TABSIZ ;SCALE DOWN TO REALLY WHERE
IMUL T2,TABSIZ ;TAB WILL BRING US TO
RET
;ROUTINE TO TYPE TAB OF SIZE TABSIZ. IT ASSUMES HARDWARE TABS ARE OF
;SIZE 8 AND TRIES TO TYPE AS MANY REAL TABS AS IT CAN, AND THEN SPACES
;OVER REST OF THE WAY.
TYPTAB: MOVE T2,CURPOS ;SEE WHERE WE'RE STARTING ON LINE
MOVEM T2,CURSOR ;REMEMBER WHERE WE ARE
CALL CMTAB ;SEE WHERE WE WANT TO GET TO
MOVEM T2,TABDON ;REMEMBER WHERE WE WANT TO GET TO
TYPTB2: MOVE T1,CURSOR ;GET WHERE WE ARE
ADDI T1,8 ;HARDWARE TAB MIGHT GO THIS FAR
TRZ T1,7 ;BUT MAYBE NOT QUITE
CAMLE T1,TABDON ;WILL HARDWARE TAB GO TOO FAR?
JRST TYPTB1 ;YES
MOVEM T1,CURSOR ;NO, SO REMEMBER WHERE IT BRINGS US
MOVEI T1,.CHTAB
CALL CMCOUT ;AND TYPE IT
JRST TYPTB2 ;LOOP FOR AS MANY HARDWARE TABS AS WE CAN GET AWAY WITH
TYPTB1: AOS T1,CURSOR ;START SINGLE SPACING
CAMLE T1,TABDON ;ARE WE THERE YET?
RET ;YES, SO TAB IS TYPED
MOVEI T1," " ;NO, SO SPACE OVER
CALL CMCOUT
JRST TYPTB1 ;AND LOOP FOR REST OF SPACES
;ROUTINE TO FIND OUT WHERE ON LINE WE ARE. IF NOT A TERMINAL, ASSUMES
;WE'RE AT RIGHT MARGIN (COLUMN 72)
GETPOS: RFPOS ;FIND WHERE ON LINE WE ARE
ERJMP .+1 ;[7394]
CAIN T2,0 ;NOT A TERMINAL?
MOVEI T2,^D72 ;RIGHT, SO ASSUME WE'RE AT COLUMN 72
HRRZ T2,T2 ;ISOLATE COLUMN POSITION
RET
;ROUTINE TAKING POINTER TO KEYWORD IN T1. RETURNS KEYWORD LENGTH IN
;T1. GIVES EXTRA 1 FOR SWITCH, ASSUMING A SLASH WILL PREFIX ITS
;PRINTOUT.
CMGTLN: MOVEI T4,0 ;COUNT OF NUMBER OF CHARACTERS NEEDED FOR THIS KEYWORD
KEY1: XCTBU [ILDB T2,T1] ;PICK UP NEXT CHARACTER FROM KEYWORD
CAIE T2,0 ;ASSUME KEYWORD ENDS ON NULL
AOJA T4,KEY1 ;NOT OVER YET, ACCUMULATE ITS LENGTH
TXNE F,CMSWF ;IS THIS A SWITCH?
AOJ T4, ;YES, DELIMITER TAKES UP ANOTHER SPACE
MOVE T1,T4 ;RETURN LENGTH IN T1
RET
;READ REST OF LINE AS ATOM
XCMTXT: CALL CMRFLD ;READ TEXT
JXN F,CMQUES,[
TXNN F,CMQUE2 ;IF IN MIDDLE OF HELP LIST, THEN "?" ALWAYS DOES HELP
JUMPN T1,XCMTQ ;USUALLY "?" IS JUST PART OF TEXT
CALL DOHLP ;DO USER HELP
HRROI T1,[ASCIZ / text string/]
TXNN F,CM%SDH
CALL CMSOUT ;TYPE HELP UNLESS SUPPRESSED
JRST CMRTYP] ;NO DEFAULT MESSAGE
JXN F,CM%ESC,CMAMB ;JUST DING IF HE TRIES TO DO RECOGNITION
JRST XCOMXI ;DONE
XCMTQ: MOVEI T1,CMHLPC ;PUT QUESTION MARK IN TEXT
CALL STOLCH
CALL TIELCH ;TIE OFF ATOM BUFFER IN CASE IT IS LAST CHARACTER
TXZ F,CMQUES ;FORGET THAT WE'RE IN HELP STATE
JRST XCMTXT ;READ REST OF TEXT
;NOISE WORD FUNCTION
XCMNOI: MOVE T1,FNARG ;GET STRING PTR
CALL CHKBP ;[9112] (T1/T1) Check and normalize pointer
ITERR COMX17 ;BAD
MOVEM T1,Q3
TXNN F,CM%PFE ;PREVIOUS FIELD ENDED WITH ESC?
JRST CMNOI1 ;NO
CMNOI4: TXO F,CM%ESC ;YES, MEANS THIS ONE DID TOO
CMN1: JUMPN P5,[CALL CMCIN ;PASS OVER SPACE PROVOKED BY ESC ON PREVIOUS COMMAND
JRST CMN1]
MOVEI T1,NOIBCH ;TYPE NOISE BEG CHAR
CALL CMDIB ; AND PUT IT IN BUFFER
CMNOI3: XCTBU [ILDB T1,Q3] ;GET NEXT NOISE CHAR
JUMPN T1,[CALL CMDIB ;PUT IT IN BUFFER IF NOT END OF STRING
JRST CMNOI3]
MOVEI T1,NOIECH ;END OF STRING, TYPE END CHAR
CALL CMDIB
JRST XCOMXI ;EXIT
;PREVIOUS FIELD NOT TERMINATED WITH ESC - PASS NOISE WORD IF TYPED
CMNOI1: CALL CMSKSP ;BYPASS SPACES
CALL CMCIN ;GET FIRST CHAR
CAIE T1,NOIBCH ;NOISE BEG CHAR?
JRST [ CALL CMDIP ;NO, NOT A NOISE WORD, PUT IT BACK
JRST XCOMXI] ;RETURN OK
CMNOI2: CALL CMCIN ;GET NEXT NOISE CHAR
CAIE T1,CMFREC ;^F?
CAIN T1,.CHESC ;ESC?
JRST [ CALL CMDCH ;YES, FLUSH IT
JRST CMNOI3] ;COMPLETE NOISE WORD FOR USER
XCTBU [ILDB T2,Q3] ;COMPARE WITH GIVEN STRING
CAIL T1,"A"+40 ;CONVERT TO UC
CAILE T1,"Z"+40
SKIPA
SUBI T1,40
CAIL T2,"A"+40
CAILE T2,"Z"+40
SKIPA
SUBI T2,40
CAMN T1,T2
JRST CMNOI2 ;STILL SAME AS EXPECTED
CAIN T1,NOIECH ;NOT SAME, STRING ENDED TOGETHER?
JUMPE T2,XCOMXI ;YES, EXIT OK
NOPARS NPXINW ;NO, PROBABLY BAD NOISE WORD
;CONFIRM
XCMCFM: CALL CMCFM0 ;DO THE WORK
CAIA ;FAILED
JRST XCOMXI ;OK
NOPARS NPXNC
CMCFM0: CALL RDCRLF ;CRLF SEEN?
CAIA ;NO
RETSKP ;YES, DONE
CAIE T1,.CHTAB ;BLANK?
CAIN T1," "
JRST CMCFM0 ;YES, IGNORE
CAIN T1,CMHLPC ;HELP?
JRST [ CALL DOHLP ;DO USER HELP
HRROI T1,[ASCIZ / confirm with carriage return/]
TXNN F,CM%SDH
CALL CMSOUT ;GIVE HELP MESSAGE
SKIPE INDFLG
CALL INDRLJ
JRST CMRTYP] ;RETYPE AND TRY AGAIN
CAIE T1,CMFREC ;^F?
CAIN T1,.CHESC ;ESC?
JRST [SKIPE INDFLG
CALL INDRLJ
CALL CMAMBT] ;AMBIGUOUS
RET ;NO, FAIL
;FLOATING POINT NUMBER
XCMFLT: CALL CMRFLD ;READ FIELD
JXN F,CMQUES,[CALL DOHLP
HRROI T1,[ASCIZ / number/]
TXNN F,CM%SDH ;SUPPRESS DEFAULT?
CALL CMSOUT ;NO, DO IT
JRST CMRTYP]
UMOVE T1,.CMABP(P2) ;NUMBER NOW IN ATOM BUFFER, GET PTR
UMOVEM T1,T1
IMCALL .FLIN,MSEC1
JRST XCOMNP ;FAILED
JRST CMNUMR ;DO NUMBER CLEANUP AND RETURN
;FLOATING POINT BREAK SET MASK, ALLOWS +, -, ., E, NUMBERS
FLTBRK: 777777,,777760
777644,,001760
400000,,000760
400000,,000760
;NUMBER
XCMNUM: CALL CMRFLD ;READ FIELD
TXNE F,CMQUES ;SAW "?"
JRST CMNUMH ;YES
XCMNX1: UMOVE T1,.CMABP(P2) ;SET UP NIN
UMOVEM T1,T1
MOVE T3,FNARG ;GET RADIX
UMOVEM T3,T3
IMCALL .NIN,MSEC1
JRST XCOMNP ;FAILS
CMNUMR: MOVE T2,ATBPTR
IBP T2 ;BUMP PTR PAST TERMINATOR
CAMN T1,T2 ;NIN SAW WHOLE FIELD?
JRST CMNMR1 ;[7299] Yes, but check for EOL
HRRZ T4,P1 ;GET ADDRESS OF USER FUNCTION BLOCK
ULOAD T3,CM%FNC,.CMFNP(T4) ;GET FUNCTION CODE
CAIE T3,.CMNUX ;A .CMNUX FUNCTION?
JRST [ NOPARS NPXICN] ;NO, INVALID CHARACTER IN NUMBER
MOVE T2,T1 ;GET PNTR FROM NIN IN T2
UMOVE T1,.CMABP(P2) ;AND GET ATOM BUFFER POINTER IN T1
CALL SUBBP ;FIND NEG NUMBER OF BYTES ACTUALLY READ
AOJ T1, ;DON'T INCLUDE THE TERMINATOR
PUSH P,T1 ;AND SAVE IT
CALL CMFSET ;RESET ALL POINTERS
POP P,T1 ;AND GET BACK NUMBER OF BYTES READ BY NIN
CALL CMRFLN ;AND REREAD THE FIELD UP TO TERM NIN SAW
JRST XCMNX1 ;NOW TRY NIN AGAIN.
CMNMR1: TXNE F,CM%ESC ;[7309] Did ESC terminate field?
JRST XCOMXR ;[7309] Yes, don't worry about CM%EOC
CALL RDCRLF ;[7299] (/) Is this EOL?
IFNSK. ;[7299][7301] No
CALL CMDIP ;[7299] Replace character just read
JRST XCOMXR ;[7299] And return number in T2
ENDIF. ;[7299]
CALL UNCRLF ;[7299] (/) Reached EOL, CM%EOC lit, now unread CRLF
JRST XCOMXR ;[7299] Continue with number in T2
;NUMBER BREAK SET, ALLOWS +, -, NUMBERS
NUMBRK: BRMSK. -1,-1,-1,-1,<0123456789+-> ;START WITH ALL, REMOVE DIGITS, PLUS, AND MINUS
NUXBRK: 777777,,777760
777654,,001760
777777,,777760
777777,,777760
CMNUMH: CALL DOHLP ;DO USER SUPPLIED MESSAGE
JXN F,CM%SDH,CMRTYP ;SUPPRESS DEFAULT HELP IF REQUESTED
HRRZ T2,FNARG ;GET BASE
CAIL T2,^D2 ;LEGAL?
CAILE T2,^D10
ITERR COMNX8 ;NO
CAIN T2,^D10 ;DECIMAL?
JRST CMNH10 ;YES
CAIN T2,^D8 ;OCTAL?
JRST CMNH8 ;YES
HRROI T1,[ASCIZ / a number in base /]
CALL CMSOUT ;ARBITRARY BASE
XCTU [HRRZ T1,.CMIOJ(P2)]
HRRZ T2,FNARG
MOVEI T3,^D10
NOUT ;TYPE BASE
ERJMPR [ITERR ()] ;RETURN WITH SAME ERROR CODE
JRST CMRTYP ;RETYPE LINE AND CONTINUE
CMNH8: HRROI T1,[ASCIZ / octal number/]
JRST CMNH
CMNH10: HRROI T1,[ASCIZ / decimal number/]
CMNH: CALL CMSOUT
JRST CMRTYP
;DATE AND/OR TIME
;FLAGS IN ARG SPECIFY WHICH
XCMTAD: MOVE Q1,FNARG ;GET ARG
AOS TADCNT ;[7325] Count how many trips through here
MOVEI T1,EOLBRK ;READ TO END OF LINE
CALL CMRFLX ;SINCE WE REALLY DON'T KNOW HOW MUCH TIME AND DATE JSYS WILL READ
UMOVE T1,T4 ;GET USER'S AC4 WHICH JSYS'S WILL CLOBBER
MOVEM T1,TDSAV4 ;REMEMBER IT
CALL CMTSET ;SET UP FOR AND DO DATE/TIME PARSING
JFCL ;FIRST PASS WE DON'T CARE WHETHER IT SUCCEEDS OR NOT
UMOVE T1,T1
MOVEM T1,DATPT ;REMEMBER HOW FAR WE READ
UMOVE T2,.CMABP(P2) ;GET BEGINNING
CALL SUBBP ;CALCULATE NUMBER OF CHARACTERS READ
SOJ T1, ;DON'T INCLUDE THE TERMINATOR
MOVEM T1,DATPT ;REMEMBER HOW MANY CHARACTERS TO READ
CALL CMFSET ;RESET TO BEGINNING OF FIELD
MOVN T1,DATPT ;CMRFLN NEEDS NEGATIVE NUMBER OF CHARACTERS TO READ
CALL CMRFLN ;READ EXACT NUMBER OF CHARACTERS COMPRISING TIME AND DATE FIELD
JXN F,CMQUES+CMQUE2,CMTADH ;[7325] Do help if needed (secondary help too)
CALL CMTSET ;NO HELP REQUESTED, PARSE FOR REAL
JRST TDBAD ;FAILED
TXNE Q1,CM%NCI ;CONVERT TO INTERNAL FORMAT?
JRST [ MOVSI T1,T2 ;NO, STORE DATA IN USER BLOCK
HRR T1,Q1
XBLTUU [BLT T1,2(Q1)]
JRST TDGOOD]
TXNN Q1,CM%IDA ;HAVE DATE?
JRST [ SETO T2, ;NO, DEFAULT TO TODAY
SETZ T4,
ODCNV ;GET TODAY
UMOVEM T2,T2 ;SET UP FOR IDCNV
UMOVEM T3,T3
JRST .+1]
IMCALL .IDCNV,XCDSEC ;[7.1183] Convert to internal format
JRST TDBAD ;FAILED
TDGOOD: MOVE T1,TDSAV4 ;GET USER'S ORIGINAL AC4
UMOVEM T1,T4 ;RESTORE IT
JRST XCOMXR ;GIVE GOOD RETURN
TDBAD: MOVE T1,TDSAV4 ;RESTORE USER;S AC4
UMOVEM T1,T4
JRST XCOMNP ;GIVE FAILURE RETURN
;ROUTINE THAT DOES DATE/TIME PARSING. SKIPS IFF SUCCESFUL PARSE.
CMTSET: UMOVE T1,.CMABP(P2) ;POINT TO ATOM BUFFER
UMOVEM T1,T1
MOVX T2,1B0+1B6 ;SET UP FLAGS FOR IDTNC
TXNE Q1,CM%IDA ;DATE WANTED?
TXZ T2,1B0 ;YES
TXNE Q1,CM%ITM ;TIME WANTED?
TXZ T2,1B6 ;YES
UMOVEM T2,T2
IMCALL .IDTNC,XCDSEC ;[7.1183] Parse date/time in section XCDSEC now
RET ;IDTNC FAILED
RETSKP ;SUCCEEDED
;TIME/DATE HELP
CMTADH: MOVE T1,TDSAV4 ;RESTORE USER'S AC4
UMOVEM T1,T4
SKIPLE TADCNT ;[7325] Is this our first time through?
JRST CMRTYP ;[7325] No, then don't give another help msg
CALL DOHLP ;DO USER TEXT
JXN F,CM%SDH,CMRTYP ;CHECK SUPPRESS DEFAULT
LOAD T1,<CM%IDA+CM%ITM>,Q1 ;GET FLAGS
HRRO T1,[[ASCIZ //]
[ASCIZ / time/]
[ASCIZ / date/]
[ASCIZ / date and time/]](T1)
CALL CMSOUT ;PRINT APPROPRIATE MESSAGE
JRST CMRTYP
;DEVICE
XCMDEV: CALL CMRFLD ;READ FIELD
TXNE F,CMQUES!CMDEFF ;WANT SOMETHING SPECIAL? [7260] remove CM%NSF
;[7260] to return correct error when a 0 length
;[7260] device or logical appears.
JRST CMDEVS ;YES - CHECK FOR HELP
CALL ATMLEN ;GET LENGTH OF ATOM BUFFER
JUMPE A,[NOPARS DEVX7] ;CATCH NULL DEVICE
TXNE F,CM%NSF ;[7260] Now check for no-suffix
JRST CMDEV1 ;[7260] Continue processing (no : present)
XCTBU [LDB T1,P4] ;MAKE SURE DEVICE ENDED WITH COLON
CAIE T1,":" ;DEVICE?
JRST [ NOPARS NPXIDT] ;NO, FAIL
CMDEV1: TXNE F,CM%PO ;PARSE-ONLY REQUESTED?
JRST CMDEV2 ;YES, DON'T CHECK FOR EXISTENCE
UMOVE T1,.CMABP(P2) ;SET UP STDEV ARGS
UMOVEM T1,T1
IMCALL .STDEV,MSEC1
JRST XCOMNP ;FAILED
CMDEV2: JRST XCOMXI
CMDEVS: TXNN F,CMQUES ;REALLY WANT HELP?
JRST CMDEV1 ;NO - FINISH OFF, IGNORING THE SUFFIX
CALL DOHLP ;YES - DO USER HELP
HRROI T1,[ASCIZ / device name/]
TXNN F,CM%SDH ;SUPPRESS DEFAULT?
CALL CMSOUT ;NO, DO IT
JRST CMRTYP
;QUOTED STRING
XCMQST: CALL CMRQST ;READ THE STRING
JRST [ NOPARS NPXNQS] ;FAILED
JXN F,CMQUES,[CALL DOHLP ;DO USER HELP
HRROI T1,[ASCIZ / quoted string/]
TXNN F,CM%SDH ;DEFAULT HELP?
CALL CMSOUT ;YES
JRST CMRTYP]
TXZ F,CM%ESC+CMCFF ;CLEAR IN CASE USED INSIDE STRING
JRST FIXESC ;CHECK FOR ESCAPE AND RETURN
;UNQUOTED STRING - TAKES BIT MASK (4 WORDS * 32 BITS) TO SPECIFY BREAKS.
XCMUQS: JXE F,CMQUES,CMUQS1 ;? BEEN TYPED ALREADY?
CALL DOHLP ;YES - DO USER HELP
HRROI T1,[ASCIZ / unquoted string/]
TXNN F,CM%SDH ;SUPPRESS DEFAULT?
CALL CMSOUT ;NO, DO IT
JRST CMRTYP
CMUQS1: CALL CMCIN ;GET A CHAR
MOVE T2,T1 ;COPY CHAR
IDIVI T2,^D32 ;COMPUTE INDEX TO BIT ARRAY
MOVE T3,BITS(T3)
ADD T2,FNARG
XCTU [TDNN T3,0(T2)] ;BIT ON (GOT BREAK CHAR) ?
JRST CMUQS1 ;NO, KEEP GOING
CAIN T1,CMHLPC ;TERMINATED WITH HELP CHAR?
JRST [ CALL DOHLP ;YES, DO USER HELP
JRST CMRTYP] ;AND RETYPE LINE
TXZ F,CM%ESC+CMCFF ;CLEAR FLAGS
CALL CMCINT ;SEE IF ESCAPE OR ^F TYPED
TXNN F,CMCFF ;GOT ^F ?
JRST FIXES1 ;NO - TERMINATE NORMALLY
CALL CMDCH ;YES, FLUSH IT
TXO F,CM%ESC ;SET FLAG
MOVEI T1," " ;TERMINATE TYPESCRIPT WITH SPACE
CALL CMDIB
CALL CMDIP ;DON'T REALLY PARSE THE SPACE UNTIL NEXT FIELD!
JRST XCOMX2
;ARBITRARY FIELD
XCMFLD: CALL CMRFLD ;READ FIELD
TXNE F,CMQUES ;"?" SEEN?
JRST [ CALL DOHLP ;YES, DO USER MESSAGE
JRST CMRTYP]
JRST XCOMXR ;LEAVE FIELD IN ATOM BUFFER
;ACCOUNT
XCMACT: CALL CMRFLD ;READ FIELD
TXNE F,CMQUES ;"?" SEEN?
JRST [ CALL DOHLP ;YES, DO USER MESSAGE
JRST CMRTYP]
CALL ATMLEN ;MEASURE LENGTH OF ACCOUNT STRING
CAILE A,MAXLC ;SHORT ENOUGH?
JRST [NOPARS VACCX1] ;NO "ACCOUNT MORE THAN 39 CHARACTERS"
JRST XCOMXR ;YES, SUCCESS
;NODE NAME
XCMNOD: CALL CMRFLD ;READ INPUT
TXNE F,CMQUES!CMDEFF!CM%NSF ;WANT SOMETHING SPECIAL?
JRST NODSPC ;YES - CHECK FOR HELP OR NO-SUFFIX
MOVNI T1,1 ;BACK UP POINTER TO CHECK FOR COLONS
ADJBP T1,P4
XCTBU [LDB T2,T1] ;READ FIRST COLON
XCTBU [ILDB T1,T1] ;READ SECOND COLON
CAIN T1,":" ;ERROR IF EITHER CHARACTER ISN'T COLON
CAIE T2,":"
JRST [ NOPARS NPX2CL] ;NO, ERROR
NOD1: UMOVE A,.CMABP(P2) ;POINT AT THE ATOM BUFFER
MOVE B,A ;GET A COPY
XCTBU [ILDB D,B] ;GET FIRST CHARACTER
JUMPE D,[NOPARS COMX20] ;FAIL IF NULL NAME
MOVEI B,CNODE ;GET PARSED NODE NAME IN CNODE
CALL PARNDU ;CHECK NODE NAME IN ATOM BUFFER
JRST XCOMNE ;FAILED, REASON IN A
TXNE F,CM%PO ;PARSE ONLY?
JRST NOD2 ;YES, GIVE GOOD RETURN NOW
DMOVE A,[.NDVFY
C] ;PREPARE TO VALIDATE NODE NAME
HRROI C,CNODE ;POINT TO NAME BEING VALIDATED
NODE ;VERIFY THE NAME
ERJMPS [NOPARS DCNX13] ;[9112] If NODE JSYS fails node not accessible
TXNN D,ND%EXM ;EXACT MATCH?
JRST [NOPARS DCNX13] ;NODE NOT ACCESSIBLE
NOD2: JRST XCOMXI ;CHECK FOR TRAILING ESCAPE AND RETURN
NODSPC: TXNN F,CMQUES ;REALLY WANT HELP?
JRST NOD1 ;NO - FINISH OFF, IGNORING THE SUFFIX
CALL DOHLP ;YES - DO USER'S SPECIAL HELP
HRROI T1,[ASCIZ/ Node Name/] ;SET UP DEFAULT HELP
TXNN F,CM%SDH ;DOES USER NOT WANT IT
CALL CMSOUT ;NO, TYPE IT
JRST CMRTYP ;AND RETYPE COMMAND
;ROUTINE TO PARSE A NODE NAME IN USER SPACE. IN ORDER TO PREVENT SLY
;PROGRAMS FROM MANAGING TO CHANGE THE STRING AFTER PARNOD HAS BEEN CALLED BUT
;BEFORE THE STRING IS COPIED INTO MONITOR SPACE, CALLERS MUST SUPPLY THIS
;ROUTINE WITH A MONITOR SPACE ADDRESS INTO WHICH TO WRITE THE PARSED STRING
;YOU MUST BE SURE THAT YOUR BUFFER AS SPECIFIED IN B IS LARGE ENOUGH FOR THE
;LONGEST LEGAL NODE NAME
;ACCEPTS: A/ POINTER TO ASCIZ NODE NAME IN USER SPACE
; B/ BUFFER ADDRESS FOR RECEIVING PARSED NAME
;RETURNS: +1 PARSE ERROR, ERROR CODE IN A
; +2 SUCCESSFUL PARSE, NODE NAME COPIED TO BUFFER
; A/ UPDATED USER BYTE POINTER
; B/ LENGTH OF NAME
PARNDU::STKVAR <UUP,MB>
MOVEM B,MB ;REMEMBER ADDRESS OF MONITOR BUFFER
EXCH A,B ;USER POINTER IN B, BUFFER ADDRESS IN A
SOJ A, ;CPYFU2 WANTS ADDRESS BEFORE THE STRING
MOVEI C,1+CPN ;LEAVE ROOM FOR LONG NODE NAME PLUS A NULL
CALL CPYFU2 ;COPY NODE NAME TO BUFFER, RAISE LOWER CASE
NOP ;CPYFU2 ALWAYS RETURNS +2
MOVEM C,UUP ;REMEMBER UPDATED USER POINTER
MOVE A,MB ;GET POINTER TO MONITOR BUFFER
HRLI A,440700 ;MAKE REAL BYTE POINTER
CALL PARNOD ;PARSE THE NODE NAME IN MONITOR SPACE
RET ;FAILED, REASON IN A
MOVE B,A ;RETURN LENGTH IN B
MOVE A,UUP ;SUCCEEDED, SKIP WITH UPDATED USER POINTER IN A
RETSKP ;SUCCESSFUL
;PARSE A NODE NAME IN MONITOR SPACE. TAKES ASCIZ POINTER IN A, SKIPS IF
;SUCCESSFUL, NON-SKIP WITH ERROR IN A IF FAILS. IF SUCCESSFUL, RETURNS LENGTH
;IN A. THE NODE NAME MUST CONSIST OF 6 OR LESS ALPHANUMERIC CHARACTERS,
;AT LEAST ONE OF WHICH MUST BE ALPHABETIC.
;
;PARNO1 IS A SPECIAL ENTRY POINT IF YOU ALREADY KNOW THE NUMBER OF CHARACTERS
;IN THE NAME BEING PARSED AND THE STRING DOES NOT END IN A NULL. 2/ THE COUNT
PARNOD::SKIPA T4,[0] ;"ASCIZ" ENTRY POINT
PARNO1::SKIPA T4,[-1] ;"NOT ASCIZ" ENTRY POINT
MOVEI T2,CPN ;GET MAXIMUM NUMBER OF CHARACTERS IN NAME
SAVEAC <P6>
SETZM P6 ;INIT THE "FOUND ALPHA CHAR" FLAG
XNOD0: ILDB C,A ;GET NEXT CHARACTER FROM NODE NAME
JUMPE C,XNOD1 ;IF NULL, DONE
CALL XNODAL ;IS IT ALPHABETIC?
JRST [CALL XNODNM ;NO, HOW ABOUT NUMERIC?
RETBAD (COMX18) ;NO, ERROR - INVALID CHAR IN NODE NAME
JRST .+1] ;YES, IS GOOD
SOJG T2,XNOD0 ;DECR CHAR. COUNT - IF MORE, GET THE NEXT
JUMPL T2,[RETBAD (COMX19)] ;IF NEGATIVE, ERROR - TOO MANY CHARS.
JUMPGE T4,XNOD0 ;CHAR. COUNT IS 0 - IF ASCIZ, LOOP FOR THE NULL
;HERE WHEN PARSING IS DONE
XNOD1: SKIPN P6 ;DID WE FIND AN ALPHA CHAR?
RETBAD (COMX21) ;NO, GIVE ERROR
MOVEI A,CPN ;GET MAX LENGTH OF A NODE NAME
SUB A,B ;SUBTRACT COUNTDOWN TO GET REAL LENGTH
RETSKP ;RETURN SUCCESS
;LOCAL ROUTINE TO TEST FOR ALPHABETIC CHARACTER
XNODAL: CAIL T3,"A" ;IS IT
CAILE T3,"Z" ; ALPHABETIC?
RET ;NO
SETOM P6 ;YES, SET THE "FOUND ALPHA" FLAG
RETSKP ;IS ALPHA
;LOCAL ROUTINE TO TEST FOR NUMERIC CHARACTER
XNODNM: CAIL T3,"0" ;IS IT
CAILE T3,"9" ; NUMERIC?
RET ;NO
RETSKP ;YES
;INDIRECT FILESPEC (INTERNAL CALL)
CMATFI: TXO F,CMINDF ;NOTE GETTING INDIRECT FILE
JRST XCMIFI ;OTHERWISE, LIKE INPUT FILE
;FILESPEC
XCMFIL: XCTU [HRRZ Q1,.CMGJB(P2)] ;GENERAL - GET GTJFN ARG BLOCK ADR
UMOVE T1,.GJGEN(Q1) ;GET FLAGS FROM IT
JRST CMFIL0 ;DO COMMON CODE
XCMOFI: SKIPA T1,[GJ%FOU+GJ%MSG] ;OUTPUT FILE
XCMIFI: MOVX T1,GJ%OLD ;INPUT FILE
XCTU [HRRZ Q1,.CMGJB(P2)] ;GET GTJFN ARG BLOCK ADR
MOVEI T2,.GJDEV+1(Q1) ;CLEAR DEFAULT POINTERS
XCTU [SETZM -1(T2)]
HRLI T2,.GJDEV(Q1)
XBLTUU [BLT T2,.GJJFN(Q1)]
CMFIL0: TXZ T1,GJ%CFM ;DON'T LET GTJFN DO ITS OWN CONFIRMATION
TXO T1,GJ%XTN ;NOTE EXTENDED GTJFN ARG BLOCK
UMOVEM T1,.GJGEN(Q1) ;PUT FLAGS IN ARG BLOCK
CALL CMCIN ;READ FIRST CHARACTER
CAIE T1,.CHESC
CAIN T1,CMFREC ;RECOGNITION REQUESTED AT BEG OF FIELD?
JRST CMFIL1 ;YES, DON'T CALL CMRFLD BECAUSE IT WOULD DING AND WAIT
CAIN T1,CMHLPC ;[7.1014] Check for ? as first character
JRST CMFHLP ;[7.1014] It was, give general help
CALL CMDIP ;PUT THE PREREAD CHARACTER BACK
TXNE F,CMINDF ;READING INDIRECT SPEC?
JRST [ MOVEI T1,FILBRK ;YES, FORCE FILE SPEC BREAK MASK
CALL CMRFLX
JRST CMFIL3]
CALL CMRFLD ;READ FILESPEC
CMFIL3: CALL ATMLEN ;GET LENGTH OF FILESPEC SO FAR
MOVEM T1,FSLEN
CALL CMRSET ;BACKUP POINTERS TO LET GTJFN READ FILESPEC
MOVEM F,TMPSTS ;PRESERVE FLAGS OVER INILCH CALL
CALL INILCH ;SKIP LEADING SPACES (CAN'T CALL CMFSET BECAUSE WE NEED CM%ESC)
MOVE F,TMPSTS
TXNE F,CMINDF ;READING INDIRECT FILESPEC ?
CALL CMCIN ;YES, READ THE "@"
JRST CMFIL2 ;SKIP OVER THE OTHER "PUTTING BACK"
CMFIL1: CALL CMDIP ;PUT BACK THE ESCAPE OR ^F
TXO Z,CM%ESC ;BUT REMEMBER THAT USER DOING RECOGNITION
CMFIL2: TXNE F,CMDEFF ;DEFAULT STRING?
JRST [ UMOVE T2,.CMABP(P2) ;YES, GET ATM BUF PNTR
UMOVEM T2,T2 ;GIVE TO USER
CALL ATMLEN ;FIND LENGTH OF ATOM BUFFER
MOVE T2,ATBSIZ
SUB T2,T1 ;SUBTRACT WHAT'S THERE ALREADY
MOVEM T2,ATBSIZ ;UPDATE BUFFER SIZE LEFT
ADJBP T1,ATBPTR ;ADJUST POINTER TO PNT TO END OF BUFFER
MOVEM T1,ATBPTR
MOVEI T1,.CHCRT ;SET UP TO PUT <CR> IN BUFFER
CALL STOLCH ;DO IT
MOVEI T1,.CHLFD ;SET UP TO PUT <LF> IN BUFFER
CALL STOLCH
CALL INILC1 ;REINITIALIZE PNTR & COUNT
JRST .+2]
UMOVEM P4,T2 ;NO DEFAULT, PUT MAIN PNTR IN T2
UMOVE T1,.CMIOJ(P2) ;SET UP IO JFNS (INPUT NOT USED)
UMOVEM T1,.GJSRC(Q1)
UMOVE T1,.GJF2(Q1) ;DON'T WIPE OUT OTHER EXTENDED FLAGS
TXO T1,<G1%RND+G1%RBF+G1%RCM+G1%RIE+3> ;SET UP SECOND FLAG AND COUNT WORD
UMOVEM T1,.GJF2(Q1)
UMOVE T1,.CMABP(P2) ;SET ATOM BUFFER TO GET COPY
UMOVEM T1,.GJCPP(Q1) ; OF FILESPEC
UMOVE T1,.CMABC(P2)
UMOVEM T1,.GJCPC(Q1)
UMOVE T1,.CMBFP(P2) ;SET UP ^R PTR
UMOVEM T1,.GJRTY(Q1)
UMOVEM Q1,T1 ;SET UP T1, T2 ARGS
; ..
;ALL DATA NOW SETUP FOR GTJFN - DATA IS IN BLOCK IN PREVIOUS CONTEXT.
;WILL DO INTERNAL CALL TO GTJFN SO PREVIOUS CONTEXT IS NOT CHANGED.
;IF MORE INPUT IS NEEDED, GTJFN WILL RETURN WITH GJFX48.
;ON ANY RETURN, STRING PROCESSED BY GTJFN (WHICH MAY INCLUDE SOME
;RECOGNITION OUTPUT) IS IN ATOM BUFFER AND WILL BE COPIED TO
;MAIN BUFFER.
; ..
MOVEI Q2,0 ;NO GTJFN ERROR YET
IMCALL .GTJFN,MSEC1 ;DO INTERNAL CALL TO GTJFN
ERJMP CMGJE ;[9112] Failed, avoid MONNEJ
UMOVEM T1,T2 ;RETURN JFN TO CALLER
TXNE F,CMDEFF ;GOT FIELD BY DEFAULT ?
TXNE F,CM%ESC ;YES - GOT IT BY RECOGNITION ?
CALL CMGJC ;YES - COPY INPUT TO MAIN BUFFER
TXNE F,CM%ESC ;RECOG CHARACTER TERMINATED?
CALL CMDCH ;YES, FLUSH IT
CALL ESCSPC ;TYPE SPACE IF FILESPEC RECOGNIZED WITH ESCAPE
JXO F,CMINDF,RSKP ;RETURN NOW IF INDIRECT FILESPEC
JRST XCOMX2 ;EXIT GOOD
CMGJE: MOVEM T1,Q2 ;SAVE ERROR CODE
TXNE F,CMQUES ;[7.1014] Doing "?" help from GTJFN%?
JRST CMRTYP ;[7.1014] Yes, retype and continue
CALL CMGJC ;GET USER INPUT
CAIN Q2,GJFX48 ;MORE INPUT NEEDED?
JRST [ TXNE F,CM%ESC ;YES, FLUSH ESC IF NECESSARY
CALL CMDCH
JRST XCOMRF] ;GET MORE INPUT AND TRY AGAIN
JXO F,CMINDF,R ;RETURN FAIL IF INDIRECT FILESPEC
JRST XCOMNP ;YES, RETURN FAILURE
CMGJC: UMOVE T4,.CMABP(P2) ;SUCCESS, GET PTR TO FILESPEC
CMGJ1: XCTBU [ILDB T1,T4] ;COPY FILESPEC TO MAIN BUFFER
JUMPN T1,[SOSGE P3
ITERR COMNX3
XCTBU [IDPB T1,P4]
SOS P5 ;COUNT DOWN ADVANCE BYTES
CALL STOLCH ;PUT CHAR IN ATOM BFR & UPDATE VARIABLES
JRST CMGJ1]
CAIE Q2,GJFX48 ;THIS ERROR MEANS NO TERMINATOR IN ATOM BUFFER
TXNE Z,CM%ESC ;ESCAPE MEANS USER DIDN'T TYPE TERMINATOR
CAIA ;USER DIDN'T TYPE TERMINATOR
JRST [ CALL ATMLEN ;GET LENGTH OF ATOM BUFFER
SUB T1,FSLEN ;CALCULATE LENGTH OF TERMINATOR (MIGHT BE 2 FOR CRLF!)
MOVE Q3,T1 ;REMEMBER IN Q2
JRST CMGJ2] ;GO REMOVE TERMINATOR FROM ATOM BUFFER
MOVEI Q3,1 ;NOTE THAT ONE CHARACTER TO REMOVE
CMGJ2: SKIPGE P5 ;ANYTHING LEFT IN INPUT?
SETZ P5, ;NO, MAKE EXACTLY EMPTY
CAIN P5,0 ;ANY UNPARSED INPUT LEFT AFTER FILESPEC?
CALL TIECMD ;NO, END COMMAND STRING WITH NULL
MOVE T1,Q3 ;GET NUMBER OF CHARACTERS TO REMOVE
CALL SHRINK ;SHRINK THE ATOM BUFFER TO REMOVE TERMINATOR
CMGJ3: CALL CMDIP ;DONE, PUT TERMINATOR BACK
SOJG Q3,CMGJ3 ;LOOP FOR ALL OF TERMINATOR
CAIN Q2,GJFX48 ;IS THERE A TERMINATOR TO REMOVE?
RET ;NO, SO AVOID SECOND BEEP
MOVEI T1,FLDBRK
CALLRET CMRFLX ;READ NULL ATOM TO HANDLE TERMINATOR
;FILESPEC HELP
CMFHLP: JXO F,CMINDF,[HRROI T1,[ASCIZ / filespec of indirect file/]
JRST CMFH1] ;SPECIAL HELP IF INDIRECT FILESPEC
CALL DOHLP ;DO USER MESSAGE
JXN F,CM%SDH,CMRTYP ;SUPPRESS DEFAULT HELP IF REQUESTED
UMOVE T2,.GJGEN(Q1) ;GET GTJFN FLAGS
HRROI T1,[ASCIZ / output filespec/]
TXNN T2,GJ%OLD
TXNN T2,GJ%FOU
HRROI T1,[ASCIZ / input filespec/]
CMFH1: CALL CMSOUT
JRST CMRTYP
;TOKEN - ARBITRARY SYMBOL AS SPECIFIED BY FN DATA
XCMTOK: MOVE T1,FNARG ;GET STRING ADDRESS
CALL CHKBP ;[9112] (T1/T1) Check and normalize it
ITERR COMX17 ;BAD
MOVEM T1,Q1
TXNN F,CM%DPP ;GOT A DEFAULT ?
JRST CMTOK1 ;NO
CALL RDCRLF ;SEE IF CRLF FOR DEFAULTING ?
JRST [CALL CMDIP ;NO - PUT CHAR BACK
JRST CMTOK1] ;CONTINUE NORMAL PROCESSING
CALL UNCRLF ;BACK UP
MOVE Q2,Q1 ;SAVE ARG POINTER, CMGDP CLOBBERS Q1
CALL CMGDP ;GET DEFAULT STRING POINTER
TXO F,CMDEFF ;NOTE DEFAULT SHOULD BE TAKEN
XCMTK1: XCTBU [ILDB T1,Q2] ;GET NEXT CHARACTER FROM TOKEN
JUMPE T1,[CALL TIELCH ;DONE ON NULL. TIE IT OFF
JRST XCOMX2] ;FINISH UP
XCTBU [ILDB T2,Q1] ;GET CHAR FROM DEFAULT STRING
CAME T2,T1 ;MATCH ?
JRST [NOPARS NPXNMT] ;NO. NO MATCH TOKEN
CALL STOLCH ;STORE IN ATOM BUFFER ONLY
JRST XCMTK1 ;NEXT CHAR
CMTOK1: XCTBU [ILDB Q2,Q1] ;GET NEXT CHAR IN STRING
JUMPE Q2,[CALL TIELCH ;SUCCESS IF END OF STRING
JRST FIXESC] ;CHECK FOR TRAILING ESCAPE AND RETURN
CMTOK2: CALL CMCIN ;NO, GET NEXT CHAR OF INPUT
CAMN T1,Q2 ;MATCH?
JRST [ CALL STOLCH ;YES, APPEND TO ATOM BUFFER
JRST CMTOK1] ;CONTINUE
CAIE T1,CMFREC ;RECOG REQUEST?
CAIN T1,.CHESC
CALL CMAMBT ;AMBIGUOUS
CAIE T1,CMHLPC ;HELP REQUEST?
JRST [ NOPARS NPXNMT] ;NO - NO MATCH OF TOKEN
CALL DOHLP ;YES - GIVE THE HELP
JXN F,CM%SDH,CMRTYP
HRROI T1,[ASCIZ/ "/]
CALL CMSOUT
MOVE T1,FNARG
CALL CMUSOU
MOVEI T1,""""
CALL CMCOUT
JRST CMRTYP
;DIRECTORY OR USER NAME
XCMUSR: TXOA F,CMUSRF ;NOTE USER REQUIRED
XCMDIR: TXZ F,CMUSRF
CMDIR1: CALL CMRFLD ;READ FIELD
CAIE T1,COMNX4 ;[7413] Illegal character seen?
IFSKP. ;[7413] Yes
MOVE T1,COMX22 ;[7413] Say illegal character in directory
TXNE F,CMUSRF ;[7413] User or directory?
MOVE T1,COMX23 ;[7413] User, change the error
MOVEM T1,LSTERR ;[7413] Note last error and...
JRST XCOMNP ;[7413] ...back to caller
ENDIF. ;[7413]
TXNE F,CMQUES!CM%ESC ;[7413] Help or recognition wanted?
JRST CMDIRS ;YES - SEE WHICH ONE AND HANDLE IT
CALL CMDEMO ;NO RECOGNITION - SET FOR EXACT MATCH
CMDIR0: TXNE F,CMUSRF ;WANT A USER NAME?
IFNSK. ;[7413]
IMCALL .RCUSR,MSEC1 ;[7413] Yes, get a username
ERJMP XCOMNP ;[7413] Illegal syntax
ELSE. ;[7413]
IMCALL .RCDIR,MSEC1 ;[7413] No, get a directory name
ERJMP XCOMNP ;[7413] Illegal syntax
ENDIF. ;[7413]
MOVEM T1,RCFLGS ;[7413] Remember flags. We might have to ding later
TXNE T1,RC%NOM ;FOUND A MATCH?
JRST CMDIR5 ;NO MATCH, BUT MAYBE PARSE-ONLY REQUESTED
UMOVEM T3,2 ;RETURN THE NUMBER TO THE USER
CMDIR9: TXNE F,CM%ESC ;DID USER END INPUT WITH ESCAPE?
CALL CMDCH ;YES, REMOVE IT FROM BUFFER
CMDIR2: XCTBU [ILDB T1,ATBPTR] ;TYPE AND APPEND REMAINDER OF NAME
JUMPE T1,CMDIR7 ;DONE WHEN NULL CHAR
CALL CMDIB
JRST CMDIR2
CMDIR7: MOVE T1,RCFLGS ;GET RESULT FLAGS FROM RCDIR
TXNN T1,RC%AMB ;WAS INPUT AMBIGUOUS?
JRST XCOMXI ;NO, GIVE SUCCESSFUL RETURN
JRST CMAMB ;YES, RING BELL
;DIRECTORY/USER HELP
CMDIRS: TXNN F,CMQUES ;HELP?
JRST CMDIRR ;NO - CM%ESC IS SET - ALLOW RECOGNITION
CALL DOHLP ;DO USER HELP
JXN F,CM%SDH,CMRTYP ;SUPPRESS DEFAULT HELP IF REQUESTED
HRROI T1,[ASCIZ / user name/]
TXNN F,CMUSRF ;USER?
HRROI T1,[ASCIZ / directory name/]
CALL CMSOUT
JRST CMRTYP ;RETYPE AND CONTINUE
CMDIRR: CALL CMDREC ;SET UP TO ALLOW RECOGNITION
JRST CMDIR0 ;BACK TO THE FLOW
;WE GOT A NO-MATCH RETURN ON TRYING TO PARSE USER OR DIRECTORY
;NAME. THIS MAY BE FOR ONE OF TWO REASONS: EITHER THE USER TYPED
;A PARTIAL NAME AND TRYED TO DO RECOGNITION, OR THE USER TYPED A
;COMPLETE NONEXISTENT NAME. IF CALL REQUESTED PARSE-ONLY, COMPLETE
;NONEXISTENT NAME IS ACCEPTABLE AND WE WANT TO GIVE GOOD RETURN TO
;COMND CALL. IF CALL REQUESTED NOT PARSE-ONLY, NONEXISTENT NAME IS
;UNACCEPTABLE, AND WE WANT TO GIVE NO-PARSE RETURN. IF CALL WAS FOR
;NOT PARSE-ONLY, PARTIAL NAME IS NO GOOD AND WE WANT TO
;GIVE NO-PARSE RETURN. IF CALL WAS FOR PARSE-ONLY, THEN PARTIAL NAME
;WARRANTS AMBIGUOUS RETURN, I.E. DING AND WAIT FOR MORE.
;THE FOLLOWING CODE DECIDES WHICH OF THE ABOVE CASES WE'RE DEALING
;WITH...
CMDIR5: TXNN F,CM%PO ;PARSE-ONLY REQUESTED?
JRST [ NOPARS NPXNMD] ;NO, SO GIVE NO-PARSE NOW
CALL CMDEMO ;EXACT MATCH ONLY SET UP THIS TIME
TXNE F,CMUSRF ;USER NAME FUNCTION?
JRST CMDIR8 ;YES, GO DO RCUSR
IMCALL .RCDIR,MSEC1 ;DIRECTORY FUNCTION
ERJMP CMDIR6 ;USER ATTEMPTED RECOGNITION ON PARTIAL STRING
JRST CMDIR9 ;STRING IS GOOD SYNTAX
CMDIR8: IMCALL .RCUSR,MSEC1
ERJMP CMDIR6
JRST CMDIR9
;GET TO HERE WHEN PARSE-ONLY REQUESTED, AND USER TYPED PARTIAL NAME
;FOLLOWED BY ALTMODE. WE'LL REGARD THIS AS AMBIGUOUS.
CMDIR6: MOVX A,RC%AMB ;PRETEND AMBIGUOUS
IORM A,RCFLGS
JRST CMDIR9 ;GO BACK AND JOIN COMMON CODE
;ROUTINE TO SET UP ARGS FOR IMCALL TO RCDIR/RCUSR. ENTRIES ARE CMDREC
;FOR RECOGNITION, AND CMDEMO FOR NO RECOGNITION.
CMDEMO: MOVX T1,RC%EMO+RC%PAR ;EXACT MATCH ONLY
CAIA ;SKIP SET UP FOR RECOGNITION
CMDREC: MOVX T1,RC%PAR ;RECOGNITION REQUESTED
MOVE T2,FNARG ;GET ARGUMENT WORD
TXNE T2,CM%DWC ;DIRECTORY WILDCARDING ALLOWED?
TXO T1,RC%AWL ;YES (ASSUMES RCUSR DOESN'T CARE!)
UMOVE T2,.CMABP(P2) ;PTR TO TYPE-IN
UMOVEM T1,T1
UMOVEM T2,T2
RET
;COMMA, ARBITRARY CHARACTER
XCMCMA: MOVEI T1,"," ;SET UP COMMA AS CHARACTER TO FIND
MOVEM T1,FNARG
CMCHR: CALL CMCIN ;GET A CHAR
CAIE T1,.CHTAB ;BLANK?
CAIN T1," "
JRST CMCHR ;YES, IGNORE
HRRZ T2,FNARG ;GET SPECIFIED CHAR
CAMN T1,T2 ;THE RIGHT ONE?
JRST CMCHR1 ;YES, WIN
CAIE T1,CMFREC ;^F?
CAIN T1,.CHESC ;ESC?
CALL CMAMBT ;AMBIGUOUS
CAIN T1,CMHLPC ;HELP?
JRST [ CALL DOHLP
JXN F,CM%SDH,CMRTYP ;JUMP IF SUPPRESSING HELP
MOVEI T1," " ;TYPE SPACE
CALL CMCOUT
MOVEI T1,"""" ;TYPE "char"
CALL CMCOUT
HRRZ T1,FNARG
CALL CMCOUT
MOVEI T1,""""
CALL CMCOUT
JRST CMRTYP]
NOPARS NPXCMA ;FAIL
CMCHR1: CALL CMCIN ;GET NEXT CHARACTER
CAIE T1,.CHESC ;CHECK FOR ESCAPE
JRST [ CALL CMDIP ;NOT AN ESCAPE, PLACE IT BACK
JRST XCOMXI] ;AND GIVE SUCCESSFUL RETURN
CALL CMDCH ;IS AN ESCAPE, REMOVE IT
JRST XCOMXI ;AND GIVE SUCCESS RETURN
;LOCAL ROUTINE TO SET UP BYTE PTR TO TABLE STRING AND GET FLAGS
; T2/ ADDRESS OF STRING
; CALL CHKTBS
; T1/ FLAGS
; T2/ BYTE POINTER TO STRING
CHKTBS: XCTU [SKIPE T1,0(T2)] ;CHECK FIRST WORD OF STRING
TXNE T1,177B6 ;FIRST CHAR 0 AND WORD NOT ALL-0?
TDZA T1,T1 ;NO, MAKE FLAGS ALL 0
AOS T2 ;YES, HAVE FLAGS, ADJUST BYTE PTR
HRLI T2,(POINT 7,0) ;SET UP P AND S FIELDS
RET
;STRING COMPARE JSYS
; T1/ TEST STRING POINTER
; T2/ BASE STRING POINTER
; STCMP
; RETURNS +1 ALWAYS,
; T1/ COMPARE CODE:
; 1B0 (SC%LSS) - TEST STRING LESS THAN BASE STRING
; 1B1 (SC%SUB) - TEST STRING SUBSET OF BASE STRING
; 1B2 (SC%GTR) - TEST STRING GREATER THAN BASE STRING
; N.O.T.A. MEANS EXACT MATCH
; T2/ UPDATED BASE STRING POINTER, USEFUL IN CASE TEST STRING
; WAS SUBSET
.STCMP::MCENT
HLRZ T3,T1
CAIN T3,-1
HRLI T1,(POINT 7,0)
HLRZ T3,T2
CAIN T3,-1
HRLI T2,(POINT 7,0)
CALL USTCMP ;DO THE WORK
UMOVEM T1,T1 ;RETURN THE RESULT
UMOVEM T2,T2
MRETNG
;STRING COMPARE ROUTINE - REFERENCES PREVIOUS CONTEXT.
; T1/ TEST STRING POINTER
; T2/ BASE STRING POINTER
; CALL USTCMP
;RETURN AS FOR .STCMP
USTCMP::XCTBU [ILDB T3,T1] ;GET NEXT BYTE FROM EACH STRING
CAIL T3,"A"+40 ;LC LETTER?
JRST [ CAIG T3,"Z"+40
SUBI T3,40 ;YES, CONVERT TO UC
JRST .+1]
XCTBU [ILDB T4,T2]
CAIL T4,"A"+40 ;LC LETTER?
JRST [ CAIG T4,"Z"+40
SUBI T4,40 ;YES, CONVERT TO UC
JRST .+1]
CAME T3,T4 ;STILL EQUAL?
JRST STRC2 ;NO, GO SEE WHY
JUMPN T3,USTCMP ;KEEP GOING IF NOT END OF STRING
SETZ T1, ;STRINGS ENDED TOGETHER, EXACT MATCH.
RET ;RETURN 0
STRC2: IFE. T3 ;[9112] Test string ended, it is a subset
MOVE T1,T2 ;[9112] Yes, prepare to decrement base pointer
SETO T2, ;[9112] by one byte only today
ADJBP T2,T1 ;[9112] This works for all byte pointer types
MOVX T1,SC%SUB ;[9112] Indicate test string is a subset
RET ;[9112] and return
ENDIF. ;[9112] Test string not a subset
CAMG T3,T4 ;STRINGS UNEQUAL
SKIPA T1,[SC%LSS] ;TEST STRING LESS
MOVX T1,SC%GTR ;TEST STRING GREATER
RET
;KEYWORD TABLE ROUTINES.
;THESE ROUTINES PERFORM FUNCTIONS ON KEYWORD TABLES IN STANDARD
;FORMAT. A KEYWORD TABLE IS ONE DESIGNED TO ALLOW ABBREVIATION
;RECOGNITION AND COMPLETION FOLLOWING THE USUAL CONVENTIONS.
;THE TABLE FORMAT IS:
; TABLE: # OF ENTRIES IN USE, MAX SIZE OF TABLE
; XWD ADR OF STRING, ANYTHING
; ..
; ..
;THE TABLE MUST BE SORTED BY STRINGS SO THAT BINARY SEARCHING
;AND AMBIGUITY DETERMINATION MAY BE DONE EFFICIENTLY.
;THE RIGHT HALF OF EACH ENTRY CAN BE THE DATA FOR THE ENTRY OR
;A POINTER TO ADDITIONAL INFORMATION. THESE ROUTINES IGNORE IT.
;**************************************************************
;TBDEL - DELETE AN ENTRY FROM STANDARD KEYWORD TABLE
; T1/ ADDRESS OF TABLE HEADER WORD
; T2/ ADDRESS OF ENTRY TO BE DELETED (AS RETURNED BY LOOKUP)
; TDEL
; RETURN +1 ALWAYS, ITRAP IF TABLE EMPTY
.TBDEL::MCENT
CALL XTDEL ;DO THE WORK
ITERR ()
MRETNG
;THIS IS THE WORKER ROUTINE. IT MAY BE CALLED INTERNALLY, AND
;IT REFERENCES PREVIOUS CONTEXT FOR ALL ARGUMENT DATA.
; RETURNS +1 FAILURE, ERROR CODE IN T1
; RETURNS +2 SUCCESS
XTDEL:: TXNN T1,TB%ABR ;GOT ABRV'S IN TABLE ?
JRST XTDEL1 ;NO. REAL SIMPLE THEN. SKIP ABRV CHECKING.
CALL CHKABR ;IS THIS ENTRY AN ABRV? CHKABR SKIPS IF YES
CALL REMABR ;NO. "KEY" KEYWORD HERE. REMOVE ABRV'S FOR IT.
;... ;FALL THRU
;XTDEL1 - Alternate entry point called from REMABR to remove any abbreviations
;of the keyword were going to delete.
XTDEL1: SAVEAC <T3,T4> ;PRESERVE THESE
ASUBR <TBA,ENT>
XCTU [HLRZ T4,0(T1)] ;GET USED COUNT
MOVE T3,T4
TXZ T1,TB%ABR ;DON'T NEED FLAGS NOW
SOSGE T3 ;REDUCE COUNT, TABLE ALREADY EMPTY?
RETBAD TDELX1 ;YES
ADD T4,T1 ;COMPUTE END OF TABLE
CAILE T2,(T1)
CAMLE T2,T4 ;DELETED ENTRY WITHIN TABLE?
RETBAD TDELX2 ;NO
XCTU [HRLM T3,0(T1)] ;YES, STORE DECREMENTED COUNT
JUMPE T3,TDELZ ;JUMP IF TABLE NOW EMPTY
HRLI T2,1(T2) ;COMPACT TABLE, FROM DELETED ENTRY +1
XBLTUU [BLT T2,-1(T4)] ;TO DELETED ENTRY UNTIL END
TDELZ: XCTU [SETZM 0(T4)] ;CLEAR EMPTY WORD AT END OF TABLE
MOVE T1,ENT ;ENTRY WE'RE DELETING
MOVE T2,TBA ;START OF TABLE
TXNE T2,TB%ABR ;GOT ABBREVIATIONS ?
CALL TDADJ ;YES. ADJUST OLD POINTERS.
XTDEL2: RETSKP
;REMABR - Remove any abbreviations for this keyword.
; T1/ Address of table header word
; T2/ Address of entry we deleted
; Returns + 1 always
; T2/ New address of entry after it's abreviations were removed.
REMABR: SASUBR <TBA,TBSLOT,TB3,TB4> ;SAVE AND NAME AC'S 1-4
XCTU [HLRZ T3,0(T1)] ;GET NUMBER OF ENTRIES IN USE
TXZ T1,TB%ABR
ADD T3,T1 ;COMPUTE END OF USED TABLE SPACE
MOVEI T4,1(T1) ;GET ADR AFTER HEADER WORD
REMADJ: MOVE T2,T4
CALL CHKABR ;DOUBLE CHECK ENTRY. IS IT AN ABRV ?
JRST REMAD1 ;NO. DO NOTHING WITH IT.
CAMLE T4,T3 ;END OF TABLE ?
RET ;YES - DONE
XCTU [HRRZ T2,0(T4)] ;GET DATA PORTION OF THIS ENTRY
CAME T2,TBSLOT ;MATCH ADR OF ENTRY WE'RE CHECKING ?
JRST REMAD1
MOVE T1,TBA ;AC1/ TM%ABR+TBA. AC2/ THIS ENTRY TO DELETE
MOVE T2,T4
CALL XTDEL1 ;DELETE THIS ABBREVIATION
SOS T3 ;SINCE WE REMOVED IT, THE END OF TABLE
SOS TBSLOT ; AND THE SLOT HAS MOVED.
JRST REMADJ ;TRY SAME LOCATION NOW
REMAD1: AOJA T4,REMADJ
;CHKABR - Checks current entry to see if it's an abbrevation
; Call with T2/ Address of keyword we're checking
; Returns + 1 if not an abbreviation.
; + 2 if it is an abbrevation.
CHKABR: SAVEAC <T1>
XCTU [HLRZ T1,0(T2)] ;GET ADR OF ENTRY
XCTU [SKIPE T1,0(T1)] ;CHECK FIRST WORD OF STRING
TXNE T1,177B6 ;FIRST CHAR 0 AND WORD NOT ALL-0?
RET ;NOT AN ABBREVIATION.
TXNN T1,CM%ABR ;ABBREVIATION ?
RET ;NO
RETSKP ;YES
;TBADD - ADD ENTRY TO STANDARD KEYWORD TABLE
; T1/ ADDRESS OF TABLE HEADER WORD
; T2/ ENTRY TO BE ADDED
; TADD
; RETURN +1 ALWAYS, ITRAP IF TABLE FULL OR BAD FORMAT
; T1/ ADDRESS OF NEW ENTRY
.TBADD::MCENT
CALL XTADD ;DO THE WORK
ITERR ()
UMOVEM T1,T1
MRETNG
;WORKER ROUTINE - MAY BE CALLED INTERNALLY. REFERENCES PREVIOUS CONTEXT.
; RETURN +1 FAILURE, TABLE FULL OR BAD FORMAT
; RETURN +2 SUCCESS
XTADD: ASUBR <TBA,ENT>
HLRZ T2,T2 ;CONSTRUCT STRING PTR TO NEW STRING
CALL CHKTBS ;GET POINTER TO ACTUAL STRING
HRRZ T1,TBA ;GET TABLE ADDRESS
CALL XTLOOK ;FIND PLACE FOR NEW ENTRY
RETBAD() ;BAD FORMAT TABLE
TXNE T2,TL%EXM ;EXACT MATCH?
RETBAD TADDX2 ;YES, ENTRY ALREADY IN TABLE
;T1/ ADDRESS WHERE ENTRY SHOULD BE PUT
HRRZ T2,TBA ;GET TABLE ADDRESS
XCTU [HLRZ T4,0(T2)] ;INCREMENT NUMBER ENTRIES IN USE
AOS T4
XCTU [HRRZ T3,0(T2)] ;GET TABLE SIZE
CAMLE T4,T3
RETBAD TADDX1 ;TABLE FULL
XCTU [HRLM T4,0(T2)] ;UPDATE ENTRY COUNT
ADD T4,T2 ;COMPUTE NEW END OF TABLE
XTADD2: CAML T1,T4 ;NOW AT 'HOLE'?
JRST [ MOVE T3,ENT ;YES, INSERT ENTRY
UMOVEM T3,0(T1)
MOVE T2,TBA ;GET ADR OF TABLE (AND FLAGS)
TXNE T2,TB%ABR ;ABRV'S PRESENT ?
CALL TAADJ ;YES, ADJUST THE TABLE
RETSKP]
XCTU [MOVE T3,-1(T4)] ;MOVE TABLE TO CREATE HOLE
XCTU [MOVEM T3,0(T4)]
SOJA T4,XTADD2
;TABLE ADJUSTMENT routines.
;Handles incrementing (TBADD) or decrementing (TBDEL) pointers to
;keywords for abbreviated keywords.
;
;Call with T1/ Address of slot in table being processed
; T2/ Start of table address
;
; CALL TDADJ ;TBDEL adjustment
; CALL TAADJ ;TBADD adjustment
;
;Returns + 1 always
TAADJ: TDZA T3,T3 ;MARK AS ADDING
TDADJ: SETO T3, ;MARK AS DELETING
SASUBR <TBSLOT,TBA,TBFLAG>
TXZ T2,TB%ABR
XCTU [HLRZ T4,0(T2)] ;GET NUMBER OF ENTRIES IN USE
ADD T4,T2 ;COMPUTE END OF USED TABLE SPACE
TBADJ1: AOS T2 ;POINT AT NEXT ENTRY
CAMLE T2,T4 ;END OF TABLE
RET ;YES - DONE
XCTU [HLRZ T1,0(T2)] ;GET ADR OF ENTRY
XCTU [SKIPE T3,0(T1)] ;CHECK FIRST WORD OF STRING
TXNE T3,177B6 ;FIRST CHAR 0 AND WORD NOT ALL-0?
JRST TBADJ1 ;NOT AN ABBREVIATION. TRY NEXT ENTRY
TXNN T3,CM%ABR ;CHECK SOME MORE. ABBREVIATION FLAG ON ?
JRST TBADJ1 ;NO
XCTU [HRRZ T1,0(T2)] ;OKAY GOT ABRV. NOW GET DATA OF ENTRY (RH)
CAMGE T1,TBSLOT ;AFFECTED BY CHANGED ENTRY ?
JRST TBADJ1 ;NO
SKIPE TBFLAG ;ADDING TO TABLE OR DELETING ?
JRST [XCTU [SOS 0(T2)] ;DELETING. DECREMENT THE POINTER
JRST TBADJ1] ;YES. SO GO UPDATE POINTER
XCTU [AOS 0(T2)] ;INCREMENT THE POINTER
JRST TBADJ1 ;TRY NEXT ENTRY
;TBLUK - LOOKUP ENTRY IN STANDARD KEYWORD TABLE
; T1/ ADDRESS OF TABLE HEADER WORD
; T2/ STRING POINTER TO STRING TO BE FOUND
; TLOOK
; RETURNS +1 ALWAYS, ITERR IF BAD TABLE FORMAT
; T1/ ADDRESS OF ENTRY WHICH MATCHED OR WHERE ENTRY WOULD BE
; IF IT WERE IN TABLE
; T2/ RECOGNITION CODE:
; 1B0 (TL%NOM) - NO MATCH
; 1B1 (TL%AMB) - AMBIGUOUS
; 1B2 (TL%ABR) - UNIQUE ABBREVIATION
; 1B3 (TL%EXM) - EXACT MATCH
; T3/ POINTER TO REMAINDER OF STRING IN TABLE IF MATCH
; WAS AN ABBREVIATION. THIS STRING MAY BE TYPED OUT TO
; COMPLETE THE KEYWORD.
.TBLUK::MCENT
CALL XTLOK0 ;DO THE WORK
ITERR ()
UMOVEM T1,T1 ;STORE RESULTS
UMOVEM T2,T2
UMOVEM T3,T3
MRETNG
;WORKER ROUTINE - MAY BE CALLED INTERNALLY. REFERENCES PREVIOUS CONTEXT.
; RETURNS +1 FAILURE, BAD TABLE FORMAT
; RETURNS +2 SUCCESS, ACS AS ABOVE
;INTERNAL AC USAGE:
; T1/ TEST STRING FROM CALL
; T2/ STRING FROM TABLE
; T3/ CLOBBERED BY USTCMP
; T4/ " "
; P1/ CURRENT TABLE INDEX
; P2/ ADDRESS OF TABLE INDEXED BY P1 - USED FOR INDIRECTION
; P3/ INDEX INCREMENT FOR LOG SEARCH
; P4/ SIZE OF TABLE
XTLOOK::SAVEP ;PRESERVE ACS
XTLOK0: ASUBR <TBA,STRG,REMSTR> ;JSYS ENTRY, NO NEED TO PRESERVE ACS
HLRZ T3,T2 ;CHECK STRING POINTER
CAIE T3,-1 ;LH 0 OR -1?
CAIN T3,0
HRLI T2,(POINT 7,0) ;YES, FILL IN
MOVEM T2,STRG
MOVEI P2,1(T1) ;CONSTRUCT ADDRESS OF FIRST ENTRY
HRLI P2,P1!(IFIW) ;MAKE IT INDEXED BY P1
XCTU [HLRZ P4,0(T1)] ;GET PRESENT SIZE
MOVE P3,P4 ;INITIAL INCREMENT IS SIZE
MOVE P1,P4 ;SET INITIAL INDEX TO SIZE/2
ASH P1,-1
JUMPE P4,TABLKX ;IF TABLE EMPTY THEN NO MATCH
TABLK0: XCTU [HLRZ T2,@P2] ;GET STRING ADR FROM TABLE
CALL CHKTBS ;CONSTRUCT POINTER
MOVE T1,STRG ;GET TEST STRING
CALL USTCMP ;COMPARE
JUMPN T1,TABLK1 ;JUMP IF NOT EXACTLY EQUAL
TABLKF: XCTU [HLRZ T2,@P2] ;GET STRING ADDRESS
CALL CHKTBS ;GET FLAGS
JXN T1,CM%NOR,TABLKM ;MAKE IT AMBIG IF NOREC ENTRY
MOVX T2,TL%EXM ;EXACTLY EQUAL, RETURN CODE
JRST TABLKA
TABLKM: SKIPA T2,[TL%AMB] ;AMBIGUOUS RETURN
TABLKX: MOVX T2,TL%NOM ;NO MATCH RETURN
TABLKA: MOVEI T1,@P2 ;RETURN ADR WHERE ENTRY IS OR SHOULD BE
RETSKP
;STRING MAY BE UNEQUAL OR A SUBSET, SEE WHICH
TABLK1: JXE T1,SC%SUB,TABLKN ;UNEQUAL, GO SET UP NEXT PROBE
TABLK3: MOVEM T2,REMSTR ;SUBSTRING, SAVE REMAINDER
JUMPE P1,TABLK2 ;JUMP IF THIS FIRST ENTRY IN TABLE
MOVEI T1,@P2 ;CHECK NEXT HIGHER ENTRY IN TABLE
XCTU [HLRZ T2,-1(T1)] ;GET ITS STRING ADDRESS
CALL CHKTBS ;BUILD BYTE PTR
MOVE T1,STRG ;GET TEST STRING
CALL USTCMP ;TEST PREVIOUS ENTRY
JUMPE T1,[SOJA P1,TABLKF] ;EXACTLY EQUAL, DONE. FIX INDEX.
JXN T1,SC%GTR,TABLK2 ;IF LESS THEN HAVE FOUND HIGHEST SUBSTR
SOJA P1,TABLK3 ;STILL A SUBSTR, CHECK HIGHER
;NOW POINT AT HIGHEST ENTRY WHICH IS A SUBSTR. IF THERE IS AN EXACT
;MATCH, IT IS BEFORE ALL SUBSETS AND HAS ALREADY BEEN FOUND
TABLK2: MOVEI T1,@P2 ;CHECK NEXT ENTRY FOR AMBIGUOUS
CAIL P1,-1(P4) ;NOW AT LAST ENTRY IN TABLE?
JRST TBLK2A ;YES, THIS ENTRY IS DISTINCT
XCTU [HLRZ T2,1(T1)] ;GET STRING ADR OF NEXT ENTRY
CALL CHKTBS ;BUILD BYTE PTR
MOVE T1,STRG ;GET TEST STRING
CALL USTCMP ;COMPARE NEXT LOWER ENTRY
JUMPE T1,[RETBAD TLUKX1] ;EXACT MATCH, TABLE MUST BE BAD
JXN T1,SC%SUB,[MOVE T3,REMSTR ;[7.1014] Get remainder of string if ambiguous
JRST TABLKM] ;[7.1014] Next entry not distinct, do ambiguous return
TBLK2A: XCTU [HLRZ T2,@P2] ;CHECK FLAGS FOR THIS ENTRY
CALL CHKTBS
JXN T1,CM%NOR,TABLKM ;FAIL IF NOREC BIT SET
MOVX T2,TL%ABR ;GIVE LEGAL ABBREVIATION RETURN
MOVE T3,REMSTR ;RETURN PTR TO REMAINDER OF STRING
JRST TABLKA
;HERE WHEN PROBE NOT EQUAL
TABLKN: CAIG P3,1 ;INCREMENT NOW 1?
JRST [ JXN T1,SC%LSS,TABLKX ;YES, NO MATCH FOUND
AOJA P1,TABLKX] ;IF STRING GREATER, BUMP ADR FOR INSERT
AOS P3 ;NEXT INC = <INC+1>/2
ASH P3,-1
TXNE T1,SC%GTR ;IF LAST PROBE LOW, ADD INCREMENT
ADD P1,P3
TXNE T1,SC%LSS
SUB P1,P3 ;LAST PROBE HIGH, SUBTRACT INCR
TBLKN1: CAIL P1,0(P4) ;AFTER END OF TABLE?
JRST [ MOVX T1,SC%LSS ;YES, FAKE PROBE TOO HIGH
JRST TABLKN]
JUMPGE P1,TABLK0 ;IF STILL WITHIN TABLE RANGE, GO PROBE
MOVX T1,SC%GTR ;BEFORE START OF TABLE, FAKE LOW PROBE
JRST TABLKN
;RDTTY, TEXTI -- INPUT WITH EDITING JSYSES. GENERAL DEFINITIONS:
REPEAT 0,<
;THE FOLLOWING DEFINITIONS ARE GIVEN IN MONSYM. THEY ARE DUPLICATED
;HERE FOR INFORMATION ONLY.
; CONTROL BITS:
RD%BRK==1B0 ;BREAK ON REGULAR BREAK SET
RD%TOP==1B1 ;BREAK ON TOPS10 BREAK SET
RD%PUN==1B2 ;BREAK ON PUNCTUATION
RD%BEL==1B3 ;BREAK ON EOL
RD%CRF==1B4 ;SUPPRESS CR IF 1
RD%RND==1B5 ;RETURN ON NULL BUFFER
RD%JFN==1B6 ;1= AC1 IS JFN,,JFN, 0= AC1 IS STRING PTR
RD%RIE==1B7 ;RETURN (RATHER THAN BLOCK) IF INPUT BFR EMPTY
RD%BBG==1B8 ;PTR TO BEGINNING OF DEST BUFFER GIVEN IN AC4
;RD%BEG
RD%RAI==1B10 ;RAISE LOWERCASE INPUT
RD%SUI==1B11 ;SUPPRESS ^U INDICATION
RD%NED==1B15 ;TURN OFF EDITING CHARACTERS IN BREAK MASK
;BITS RETURNED TO USER
RD%BTM==1B12 ;A BREAK CHARACTER WAS SEEN.
RD%BFE==1B13 ;RETURNED BECAUSE BUFFER EMPTY
RD%BLR==1B14 ;BACKUP LIMIT REACHED
> ;END OF MONSYM DEFINITIONS
;DEFINED CHARACTER CLASSES:
;N.B. - MUST MATCH DISPTC TABLE BELOW
TOP==0 ;TOPS10 BREAK
BRK==1 ;REGULAR BREAK SET
ZER==2 ;NULL
EOLC==3 ;EOL
PUN==4 ;PUNCTUATION
SAFE==5 ;ALL OTHERS
RUBO==6 ;DELETE A CHARACTER
RTYP==7 ;RETYPE THE LINE
KLL==10 ;DELETE THE LINE
KWRD==11 ;DELETE A WORD
RDCRC==12 ;CARRIAGE RETURN
RDQTC==13 ;QUOTE CHARACTER
;AC USAGE HEREIN:
;Q1 ^R BUFFER
;Q2 TOP OF BUFFER
;Q3 POINTER TO BREAK CHAR MASK
;P1 SOURCE
;P2 BACKUP LIMIT
;P3 COUNT
;P4 DEST POINTER
;P5 INTERNAL CALLING FLAGS
;F - FLAGS FROM USER (LH)
BRFLGS==RD%TOP+RD%BRK+RD%PUN+RD%BEL ;ALL POSSIBLE BREAK SETS
;LOCAL FLAGS IN P5
CTMTTY==1B17 ;CTERM TTY
DSPMF==1B16 ;IN DISPLAY MODE
RTTY==1B15 ;IN RDTTY
RTXT==1B14 ;IN RDTXT
TXTI==1B13 ;IN TEXTI
INTT==1B12 ;IN INTERNAL TEXTI
;NOTE: YOU CAN'T USE BITS TO "THE LEFT" OF 1B12 IN THIS WORD
;FOR LOCAL FLAGS, SINCE THE USER'S FLAGS ARE THERE.
;HOWEVER, THERE'S PLENTY OF ROOM IN FLG2...
;LOCAL FLAGS IN FLG2
QUOTEF==1B0 ;NEXT CHARACTER IS TO BE QUOTED
NDELC==1B1 ;DELETE DOES NOT MEAN DELETE CHAR
NDELW==1B2 ;CTRL/W DOES NOT MEAN DELETE WORD
NDELL==1B3 ;CTRL/U DOES NOT MEAN DELETE LINE
NRTYPE==1B4 ;CTRL/R DOES NOT MEAN RETYPE
NQUOTE==1B5 ;CTRL/V DOES NOT MEAN QUOTE NEXT CHARACTER
;RDTTY - READ TEXT WITH EDITING
; A/ DESTINATION STRING POINTER
; B/ CONTROL BITS ,, BYTE COUNT
; C/ ^R ECHO BUFFER IF NON -ZERO
; RDTTY
; RETURN +1: FAILURE
; RETURN +2: SUCCESS, 1 AND 2 UPDATED AS APPROPRIATE
.RDTTY::MCENT ;SET UP CONTEXT
UMOVE F,B ;GET FLAGS
TLNN F,(BRFLGS) ;ANY BREAK SETS SELECTED?
TXO F,RD%BEL ;NO. SET BREAK ON EOL THEN
TXO F,RD%JFN ;MUST GET INPUT FROM FILE
MOVE P1,[.PRIIN,,.PRIOU] ;FROM THE PRIMARIES
SETZ Q3, ;NO SPECIAL BREAK MASK
XCTU [HRRZ P3,B] ;BYTE COUNT
UMOVE P4,A ;DESTINATION POINTER
UMOVE Q1,C ;POSSIBLE ^R BUFFER
MOVE Q2,P4 ;TOP OF BUFFER
MOVE P2,Q2 ;BACKUP LIMIT IS TOP OF BUFFER
MOVX P5,RTTY ;NOTE IN RDTTY
JRST RCOMN ;GO DO COMMON CODE
;RDTXT
;INCLUDED FOR COMPATIBILITY ONLY, MAY BE REMOVED.
; A/ SOURCE
; B/ DESTINATION
; C/ FLAGS,,COUNT
; D/ OPTIONAL INITIAL DESTINATION PTR
; RDTXT
; RETURN +1: FAILURE
; RETURN +2: SUCCESS
.RDTXT::MCENT
UMOVE F,C ;GET CONTROL FLAGS
UMOVE P4,B ;GET DESTINATION BYTE POINTER
TXNN F,RD%BBG ;DID USER GIVE EXPLICIT BBUF PTR?
JRST [ MOVEM P4,Q2 ; NO, USE INITIAL DEST STRING PTR
JRST RDTXT2]
UMOVE Q2,D ;YES GET IT
RDTXT2: MOVE P2,Q2 ;BACKUP LIMIT IS TOP OF BUFFER
SETZB Q3,Q1 ;CANT HAVE THESE
MOVX P5,RTXT ;NOTE IN RDTXT
UMOVE P1,A ;SOURCE
XCTU [HRRZ P3,C] ;GET COUNT
JRST RCOMN ;GO DO COMMON CODE
;TEXTI - LONG FORM CALL OF RDTTY
; A/ POINTER TO ARGUMENT BLOCK (E)
;E+0 COUNT OF WORDS IN BLOCK
;E+1 FLAGS
;E+2 INJFN,,OUTJFN OR SOURCE PTR
;E+3 DESTINATION STRING POINTER
;E+4 COUNT OF BYTES IN DESTINATION STRING
;E+5 START OF BUFFER
;E+6 ^R ECHO BUFFER START
;E+7 POINTER TO BREAK CHARACTER MASK
;E+10 BACKUP LIMIT PTR
.TEXTI::MCENT ;ESTABLISH CONTEXT
MOVX P5,TXTI ;NOTE IN TEXTI
UMOVE A,A ;BLOCK POINTER
UMOVE B,.RDCWB(A) ;COUNT OF ARGS
CAIGE B,.RDDBC ;ENOUGH ARGS?
RETERR(ARGX17) ;NO, INVALID ARGUMENT BLOCK LENGTH
UMOVE F,.RDFLG(A) ;FLAGS
UMOVE P1,.RDIOJ(A) ;P1
UMOVE P4,.RDDBP(A) ;DESTINATION
UMOVE P3,.RDDBC(A) ;COUNT OF BYTES IN DESTINATION
SETZB Q1,Q3 ;ASSUME THESE ARENT PRESENT
MOVE Q2,P4 ;ASSUME NO BEGINNING OF BUFFER
CAIL B,.RDBFP ;Q2 GIVEN?
UMOVE Q2,.RDBFP(A) ;YES. GET IT
SKIPN Q2 ;WAS IT NON-ZERO?
MOVE Q2,P4 ;NO. USE DEFAULT
CAIL B,.RDRTY ;^R BUFFER GIVEN?
UMOVE Q1,.RDRTY(A) ;YES. GET IT
CAIL B,.RDBRK ;BREAK MASK GIVEN?
UMOVE Q3,.RDBRK(A) ;YES. GET IT
SETZ P2, ;ASSUME NO BACKUP LIMIT
CAIL B,.RDBKL ;BACKUP LIMIT GIVEN?
UMOVE P2,.RDBKL(A) ;YES, GET IT
SKIPN P2 ;HAVE ONE?
MOVE P2,Q2 ;NO, USE TOP OF BUFFER
JRST RCOMN ;CONTINUE WITH COMMON SETUP
;INTERNAL ENTRY, DOES NOT CHANGE PREVIOUS CONTEXT
;ASSUMES ACS PREVIOUSLY SET UP: Q1,Q2,Q3,P1,P2,P3,P4
;ENTERING HERE ASSUMES THE 4-WORD BREAK MASK AS POINTED TO BY Q3 IS
;IN CURRENT CONTEXT INSTEAD OF PREVIOUS
ITEXTI: MOVX P5,INTT ;NOTE INTERNAL CALL
; .. ;FALL INTO COMMON SETUP
;COMMON ENTRY/SETUP FOR RDTTY, TEXTI
RCOMN: TRVAR <FLG2,<UMSK,4>,CCNT,CCPTR,CRPTR,<COC,2>,<OURCOC,2>,MOD,STKP,<MASK,5>,FWTH,TTYIND,ADDPAR,LSTWID>
SETZM FLG2 ;INITIALIZE FLAGS
JUMPE Q3,RCNM ;SKIP FOLLOWING CODE IF NO CUSTOM BREAK MASK
TXNN P5,INTT ;BREAK MASK, SKIP IF IN CURRENT CONTEXT
JRST [ XCTU [DMOVE A,(Q3)] ;PREVIOUS, GET FIRST TWO WORDS
XCTU [DMOVE C,2(Q3)] ;GET SECOND TWO
JRST RCNM1]
DMOVE A,(Q3) ;CURRENT CONTEXT, GET BREAK MASK
DMOVE C,2(Q3)
RCNM1: DMOVEM A,UMSK ;REMEMBER BREAK MASK
DMOVEM C,2+UMSK
RCNM: SETZM TTYIND ;ASSUME NOT A TERMINAL
MOVEM P,STKP ;SAVE STACK PTR FOR FAIL RETURN
TXZ F,RD%BTM+RD%BFE+RD%BLR ;INIT RETURN FLAGS
TXNN F,RD%JFN ;HAVE JFNS IN 1?
JRST [ MOVE A,P1 ;NO. GET STRING POINTER
CALL RDCBP ;CHECK IT
RETERR(RDTX1) ;NO GOOD
MOVEM A,P1 ;PUT IT BACK IN P1
JRST RDTXT1]
HLRZ A,P1 ;GET INPUT JFN
RFCOC ;GET CURRENT CC STATES
ERJMPR [RETERR()]
DMOVEM B,COC ;SAVE THEM
TXNE P5,INTT ;[7292] Internal TEXTI?
JRST RCNM2 ;[7292] Yes, chars already off
ANDCM C,[3B1+3B7+3B9+3B11] ;NO ECHO OF ^R, ^U, ^V, ^W
SFCOC ;SET OUR MODES
ERJMPR [RETERR()]
RCNM2: DMOVEM B,OURCOC ;[7292] Remember ours
MOVEM C,MOD ;SAVE C
DVCHR ;MTOPR WORKS ON TTY ONLY
ERJMPR [RETERR()]
HLRZ A,P1 ;GET INPUT JFN
LDB T2,[POINTR T2,DV%TYP] ;GET DEVICE TYPE CODE
CAIE T2,.DVTTY ;SKIP IF IT'S A TERMINAL
JRST NOTTY ;NO - NOT A TTY
SETOM TTYIND ;INDICATE IT'S A TERMINAL
GDSTS ;GET DEVICE BITS
ANDX B,GD%PAR ;ISOLATE PARITY ADD BIT
MOVEM B,ADDPAR ;SAVE PARITY BIT
MOVEI B,4 ;SET THE LENGTH IN THE BLOCK
MOVEM B,MASK ;SET INTO THE BLOCK
MOVEI B,.MORBM ;GET WAKE-UP MASK FOR SAVING
XMOVEI C,MASK ;WHERE IT'S GOING
MTOPR
ERJMPR [RETERR()]
MOVEI B,.MORFW ;SAVE THE FIELD WIDTH
MTOPR
ERJMPR [RETERR()]
MOVEM C,FWTH
NOTTY: MOVE C,MOD ;RESTORE C
RFMOD ;GET CURRENT WAKEUP MODES
TXZ B,TT%OSP ;FORGET OUTPUT SUPPRESS
MOVEM B,MOD ;SAVE AND RESTORE WHEN DONE
TRZ B,TT%WAK+TT%DAM ;WILL SET THESE FIELDS
TRO B,<FLD(.TTASC,TT%DAM)> ;ASCII IN
CALL RTSETW ;COMPUTE AND SET WAKEUPS FROM MASK
TXO B,TT%IGN ;IGNORE TT%WAK IN THE SFMOD
SFMOD ;SET NEW MODES
GTTYP ;GET TERMINAL TYPE
HRRZ A,B
HRR P5,TTYPE1(A) ;GET ADDRESS OF CURSOR CONTROL TAALE
TRNE P5,-1 ;HAVE A TABLE?
TXO P5,DSPMF ;YES, SET DISPLAY MODE
; ..
;VERIFY ALL OF THE STRING POINTERS
RDTXT1: SKIPN A,P4 ;HAVE A DEST POINTER?
RETERR (RDTX1) ;NO. THAT IS AN ERROR
CALL RDCBP ;YES. CHECK IT OUT
RETERR(RDTX1) ;BAD
MOVE P4,A ;GET CONVERTED POINTER BACK
SKIPN A,Q1 ;HAVE A ^R BUFFER?
JRST RDTOPM ;NO. GO AROUND THEN
CALL RDCBP ;YES. VERIFY IT
RETERR (RDTX1) ;BAD
MOVE Q1,A ;GET VERIFIED POINTER
RDTOPM: MOVE A,P2 ;VERIFY BACKUP LIMIT PTR
CALL RDCBP
RETERR (RDTX1) ;RETURN ERROR
MOVEM A,P2 ;OK
MOVE A,Q2 ;GET TOP OF BUFFER
CALL RDCBP ;VERIFY IT
RETERR (RDTX1) ;BAD
MOVE Q2,A ;ALL VERIFIED NOW
JUMPLE P3,WRAP0 ;MAKE SURE COUNT HAS ROOM IN IT
MOVEI A,0 ;A WILL COUNT CONSECUTIVE QUOTERS
MOVE C,FLG2 ;BUT ARE QUOTERS
TXNE C,NQUOTE ; FOR REAL ?
JRST RDT2 ;NO, SO DON'T NEED TO COUNT THEM
MOVE B,P4 ;WE'LL START SCANNING BACKWARDS FROM CURRENT END OF DESTINATION STRING
RDT1: CAMN B,P2 ;ANY MORE EDITABLE DATA?
JRST RDT2 ;NO
XCTBU [LDB C,B] ;YES, LOOK AT PREVIOUS CHARACTER
CAIE C,CMQUOT ;A QUOTER?
JRST RDT2 ;NO, SO WE'RE DONE SCANNING
MOVNI C,1 ;YES, BACK UP TO CONTINUE THE SCAN
ADJBP C,B
MOVE B,C
AOJA A,RDT1 ;KEEP TRACK OF HOW MANY QUOTES HAVE BEEN SEEN
RDT2: STOR A,QUOTEF,FLG2 ;NOTE WHETHER FIRST CHARACTER SEEN SHOULD BE QUOTED
IFE FTNSPSRV,<
TXNN F,RD%JFN ;HAVE JFNs ?
IFSKP.
HLRZ A,P1 ;YES. GET INJFN
MOVEI B,.MOCTM ;CHECK FOR CTERM TTY
SETZ C, ;INITIALIZE RESULT (IN CASE OF ERROR)
MTOPR
ERJMP .+1
CAIN C,1 ;IS IT A REAL CTERM TTY ?
TXO P5,CTMTTY ;YES. REMEMBER.
ENDIF.
>;END IFE FTNSPSRV
;...
;MAIN LOOP - DOES INPUT OF BYTE AND DISPATCH ON CHARACTER CLASS
;ACTION ROUTINES EXIT TO:
; INSRT - APPEND CHARACTER AND CONTINUE
; NINSRT - CONTINUE WITHOUT APPENDING CHARACTER
; DING - BUFFER NOW EMPTY, POSSIBLE RETURN TO USER
; WRAP, WRAP0 - RETURNS TO USER
NINSRT: SETOM LSTWID ;NOTE FIELD WIDTH NOT SET YET
INSRT0: TXNE F,RD%BEG ;USER REQUEST INSTANT RETURN WHEN LIMIT REACHED?
TXNN F,RD%BLR ;YES, HAS LIMIT BEEN REACHED
CAIA ;NOT ALL OF THE ABOVE
JRST WRAP0 ;TIME TO RETURN (TYPIST EDITED BACK FAR ENOUGH)
TXNN F,RD%RIE ;USER WANTS RETURN ON NO INPUT?
IFSKP.
TXNN F,RD%JFN ;YES, HAVE A JFN FOR INPUT?
ANSKP. ;NO, PROCESS UNTIL STRING RUNS OUT
HLRZ A,P1 ;GET INPUT JFN
SIBE ;STILL HAVE INPUT?
ANSKP. ;YES
JRST WRAP0 ;NO, RETURN
ENDIF.
; **** ATTENTION ****
; THE FOLLOWING CODE AND THE LOCATION LSTWID ARE DESIGNED TO MINIMIZE THE
; NUMBER OF NEEDLESS MTOPRS DONE BY THIS CODE. THIS SEEMS TRICKY TO GET CORRECT
; AND MAY NEED TO BE RIPPED OUT.
; Fixes, 30-Jul-84 DLM.
SKIPN TTYIND ;A TERMINAL?
IFSKP. ;YES
SKIPLE LSTWID ;WIDTH SET YET?
IFSKP.
MOVEI B,.MOSFW ;SET FIELD WIDTH - MAY WAKEUP AND ECHO
MOVE C,P3 ;GET THE BYTE COUNT
HLRZ A,P1 ;GET INPUT JFN
MTOPR ;SET IT
ERJMPR [RETERR()]
MOVEM P3,LSTWID ;REMEMBER CURRENT WIDTH
ENDIF.
ENDIF.
CALL STP6 ;STORE DEST POINTER
CALL STP3 ;STORE COUNT
CALL WNULL ;GUARANTEE THAT BUFFER ENDS WITH NULL, IN CASE INTERRUPT
CALL RDBIN ;DO BIN
SOS LSTWID ;COUNTDOWN FIELD WIDTH FOR NEXT MTOPR
MOVE A,B ;SAVE CHARACTER IN A
IDIVI B,CHRWRD ;SET UP TO GET CHAR CLASS
LDB B,CCBTAB(C) ;GET IT FROM BYTE TABLE
IDIVI B,2 ;SET UP TO REF DISPATCH TABLE
JUMPE C,[HLRZ D,DISPTC(B) ;GET LH ENTRY
JRST .+2]
HRRZ D,DISPTC(B) ;GET RH ENTRY
MOVE B,A ;ROUTINES WANT CHARACTER IN B
MOVE C,FLG2
TXZN C,QUOTEF ;ARE WE SUPPOSED TO QUOTE THE NEXT CHARACTER?
JRST 0(D) ;DISPATCH TO ACTION ROUTINE
MOVEM C,FLG2 ;TURN OFF QUOTEF IN FLAG WORD
JRST INSRT ;YES, DON'T PERFORM SPECIAL ACTION
;RETURN FROM ACTION ROUTINE TO APPEND CHARACTER AND CONTINUE.
; B/ CHARACTER
INSRT: SETOM LSTWID ;MUST RESET FIELD WIDTH
INSRTC: SKIPN Q3 ;USER SPECIFYING BREAKS?
IFSKP.
MOVE A,B ;YES. GET BYTE
IDIVI B,^D32 ;GET WORD AND OFFSET FOR TESTING
MOVE C,BITS(C) ;TEST MASK
EXCH A,B ;CHAR TO B
XMOVEI D,UMSK ;GET ADDRESS OF USER MASK
ADD A,D ;COMPUTE ADR OF WORD TO TEST
TDNE C,0(A) ;IS THE BIT SET?
JRST WRAP ;YES. WRAP IT UP THEN
ENDIF.
XCTBU [IDPB B,P4] ;APPEND BYTE TO USER STRING
SOJG P3,INSRT0 ;CONTINUE IF STILL HAVE COUNT
JRST WRAP0 ;COUNT EXHAUSTED, RETURN
;BUFFER EMPTY, RING BELL OR RETURN TO USER
BNULL: TXNE F,RD%RND ;USER WANTS RETURN?
JRST WRAPE ;YES
DING: MOVEI B,"G"-100 ;NO, DO BELL
CALL RDBOUT
CALL CHKBLP ;UPDATE BACKUP DATABASE
JRST NINSRT ;AND WAIT FOR FOR INPUT
;RETURNS TO USER.
;HERE IF RETURNING BECAUSE BUFFER BECAME EMPTY AND RD%RND SET
WRAPE: TXO F,RD%BFE ;TELL USER
JRST WRAP0
;APPEND LAST CHARACTER AND RETURN
WRAP: XCTBU [IDPB B,P4] ;APPEND BYTE
SUBI P3,1 ;UPDATE COUNT
TXO F,RD%BTM ;SAY BREAK CHARACTER TERMINATED INPUT
;STORE NULL ON STRING AND RETURN
WRAP0: CALL WNULL ;PUT IN A NULL
CALL WRAPX ;UPDATE USER VARIABLES, ETC.
JXN P5,INTT,RSKP ;DO RET IF INTERNAL CALL
SMRETN
;ROUTINE TO WRITE A NULL AFTER LAST CHARACTER IN BUFFER IF ROOM.
WNULL: JUMPLE P3,R ;DON'T STORE NULL IF COUNT EXHAUSTED
MOVE D,P4 ;GET COPY OF DEST PTR
SETZ B,
XCTBU [IDPB B,D] ;STORE NULL WITHOUT CHANGING USER PTR
RET
;UPDATE USER VARIABLES AND RESTORE USER MODES ON RETURN
WRAPX: CALL STP3 ;UPDATE BYTE COUNT
TXNN F,RD%JFN ;HAVE JFNS?
JRST WRAPX1 ;NO
HLRZ A,P1 ;YES, GET INPUT JFN
MOVE B,MOD ;RESTORE MODES
SKIPE TTYIND ;SKIP IF NOT A TTY
TXO B,TT%IGN ;TTY - IGNORE THE TT%WAK FIELD
SFMOD
ERJMPS WRAPX1 ;GIVE UP IF TTY WENT AWAY
SKIPN TTYIND ;IF IT'S NOT TTY DON'T SKIP
JRST NOTTY2
MOVEI B,.MOSBM ; TO RESTORE THE MASK
XMOVEI C,MASK
MTOPR
ERJMPS WRAPX1 ;GIVE UP IF TTY WENT AWAY
MOVEI B,.MOSFW ;RESTORE FIELD WIDTH
MOVE C,FWTH
MTOPR
ERJMPS WRAPX1 ;GIVE UP IF TTY WENT AWAY
NOTTY2: DMOVE B,COC ;RESTORE CC
CAMN B,OURCOC ;[7292] But only if necessary
CAME C,1+OURCOC ;[7292]
SFCOC
WRAPX1: CALL STP6 ;UPDATE POINTER
CALL STFLG ;UPDATE FLAGS
RET
;RETURN IF FAILURE DETECTED DURING TEXTI
TXIBAD: MOVE P,STKP ;RESET STACK
MOVE Q3,LSTERR ;SAVE ERROR CODE
CALL WRAPX ;UPDATE, ETC.
MOVE A,Q3 ;RETURN ERROR CODE
JXN P5,INTT,R ;LOCAL RETURN
RETERR
;PARAMETERS FOR CLASS TABLE
CCBITS==4 ;BITS/BYTE
CHRWRD==^D36/CCBITS ;BYTES/WORD
;TABLE OF BYTE PTRS TO REFERENCE CLASS TABLE
XX==CCBITS-1
CCBTAB: REPEAT CHRWRD,<
POINT CCBITS,CTBL(B),XX
XX=XX+CCBITS>
;CLASS DISPATCH TABLE
;N.B. - MUST MATCH DEFINITIONS OF CLASS TYPES ABOVE
DISPTC: TOPS10,,BREAKS
ZERO,,EOL1
PUNC,,INSRTC
DELC,,RTYPE
DELIN,,KLWORD
RDCR,,RDQT
;CHARACTER CLASS TABLE
DEFINE CCN (A,B)<
REPEAT B,<
CC1 (A)>>
DEFINE CC1 (C)<
WCHAR==WCHAR+1 ;;KEEP TRACK OF WHICH CHARACTER WE'RE ON
QQ=QQ+CCBITS
IFG QQ-^D35,<
QW
QW=0
QQ=CCBITS-1>
QW=QW+<C>B<QQ>>
;MACRO WHICH DECLARES A CHARACTER TO BE A SPECIAL TEXTI EDITING CHARACTER
DEFINE CCED (C)<
CC1 (C) ;;DO SAME AS CC1
BRKCH. (WCHAR) ;;SAY WE HAVE TO BREAK ON IT
>
WCHAR==-1
QW==0
QQ==-1
BRINI. ;;INITIALIZE BREAK MASKS
CTBL: CC1(ZER) ;0
CCN(PUN,6) ;1-6
CC1(TOP) ;7
CCN(PUN,2) ;10-11
CC1(EOLC) ;12
CC1(TOP) ;VT
CC1(TOP) ;FF
CC1(RDCRC) ;CR
CC1(PUN) ;^N
CC1(RTYP) ;^O - ACTS LIKE ^R IF SEEN IN INPUT STREAM
CCN(PUN,2) ;^P, ^Q
CCED(RTYP) ;^R
CCN(PUN,2) ;^S,^T
CCED(KLL) ;^U
CC1(RDQTC) ;^V
CCED(KWRD) ;^W
CCN(PUN,2) ;^X,^Y
CCN(BRK,2) ;^Z,$
CCN(PUN,4) ;34-37
CCN(PUN,^D16) ;40-/
CCN(SAFE,^D10) ;0-9
CCN(PUN,7) ;:-@
CCN(SAFE,^D26) ;A-Z
CCN(PUN,6) ;]-140
CCN(SAFE,^D26) ;A-Z
CCN(PUN,4) ;173-176
CCED(RUBO) ;177
QW ;GET LAST WORD IN
EDC0==W0. ;REMEMBER BREAK MASKS (SEE "DEFINE BRKCH.")
EDC1==W1.
EDC2==W2.
EDC3==W3.
;LOCAL ROUTINES TO DO LOGICAL BIN AND BOUT. DO ILDB/IDPB IF
;HAVE STRING PTR
;RDBIN
; CALL RDBIN
; RETURN +1 ALWAYS, B/ BYTE READ FROM P1
RDBIN: TXNN F,RD%JFN ;HAVE JFN FOR SOURCE?
JRST [ XCTBU [ILDB B,P1] ;GET A BYTE
CALL STSRC ;STORE NEW POINTER
JRST RDBIN1]
RDBIN2: HLRZ A,P1 ;GET INJFN
IFE FTNSPSRV,<
TXNE P5,CTMTTY ;CTERM TTY ?
CALL MOTXT ;[7235] () Yes, do CTERM remote TEXTI%
>;END IFE FTNSPSRV
BIN ;GET BYTE
ERJMP TXIBAD ;FAILS
JUMPE B,[GTSTS ;NULL ENCOUNTERED, SEE IF EOF
TXNN B,GS%EOF
JRST RDBIN2 ;NOT EOF, FLUSH NULL
JRST TXIBAD] ;EOF, CAUSE FAIL RETURN
RDBIN1: ANDI B,177 ;FLUSH POSSIBLE EXTRANEOUS BITS
TXNN F,RD%RAI ;RAISE INPUT?
RET ;NO, RETURN
CAIL B,"A"+40 ;YES, HAVE LC CHARACTER?
CAILE B,"Z"+40
SKIPA ;NO
SUBI B,40 ;YES, CONVERT TO UPPER
RET
;MOTXT
; CALL MOTXT - set up for CTERM remote TEXTI%
; RETURN +1 ALWAYS
; PRESERVES T1
MAXPMP==^D80 ;Max Prompt Length, bytes
MOTXT: STKVAR <SAVA,<RBUF,<<MAXPMP/5>+1>>> ;Allocate ^R buffer on stack
MOVEM A,SAVA ;[7241] Save A for all cases of MOTXT
SKIPN T2,Q1 ;[7241] Is there an ^R buffer?
IFSKP.
MOTLIN: MOVEI T3,MAXPMP ;Max length of string
MOVE T1,[POINT 7,RBUF];PTR to ^R buffer destination
DO.
XCTBU [ILDB T4,T2] ;Get a character from his string.
JUMPE T4,ENDLP. ;Exit loop if this is null at end of ASCIZ
CAIN T4,.CHLFD ;Was the character <LF>?
JRST MOTLIN ;Yes - forget buffer so far
IDPB T4,T1 ;Deposit character in ^R buffer storage
SOJG T3,TOP. ;Increment string count
ENDDO.
SETZ T4, ;Pick up a null
IDPB T4,T1 ;Deposit null at end ASCIZ string
MOVE A,SAVA ;Restore A from former
ELSE.
SETZM RBUF ;No buffer
ENDIF.
MOVEI B,.MOTXT ;DO CTERM STYLE READ.
HRR C,P3 ;LENGTH
HLL C,F ;FLAGS
HRROI D,RBUF ;PTR TO ^R BUFFER
MTOPR
ERJMP .+1
MOVE A,SAVA ;[7225] RESTORE A FROM FORMER
RET
ENDSV.
;RDBOUT
; B/ BYTE
; CALL RDBOUT
; RETURN +1 ALWAYS, FLUSHES CHARACTER IF NO OUTPUT JFN
RDBOUT: TXNN F,RD%JFN ;HAVE OUTPUT JFN?
RET ;NO, DO NOTHING
HRRZ A,P1 ;YES. GET IT
BOUT ;OUTPUT THE BYTE
ERJMP TXIBAD ;FAILS
RET
;RDSOUT - OUTPUT STRING ALA RDBOUT
; B/ STRING PTR
; CALL RDSOUT
; RETURN +1 ALWAYS, LOSES CHARACTERS IF NO OUTPUT JFN
RDSOUT: TXNN F,RD%JFN ;HAVE OUTPUT JFN?
RET ;NO, DO NOTHING
HRRZ A,P1 ;YES, GET IT
SETZ C,
SOUT ;OUTPUT THE STRING
ERJMP TXIBAD ;FAILED
RET
;CHECK BYTE POINTER GIVEN AS ARGUMENT
;OWGBP FROM NON-ZERO SECTION IS ALLOWED
; A/ BYTE POINTER
; CALL RDCBP
; RETURN +1: NO GOOD, SIZE INVALID
; RETURN +2: OK, LH INITIALIZED IF NECESSARY
RDCBP:
HLRZ B,A ;GET LH
CAIN B,-1 ;IS DEFAULT?
HRLI A,(<POINT 7,0>) ;YES, FILL IN 7-BIT
CALL SPCSNZ ;CALLER FROM NON-ZERO SECTION?
JRST RDCBP2 ;NO
LDB B,[POINT 6,A,5] ;YES...GET THE P FIELD
CAIGE B,45 ;IS THIS A OWGBP?
JRST RDCBP2 ;NO
CAIL B,54 ;YES...IS IT 7,8,9, OR 18 BIT BYTES
CAIN B,77 ;AND NOT 77
RET ;NOT CORRECT SIZE OR 77 SO RETURN BAD
JRST RDCBP3 ;OK...RETURN GOOD
RDCBP2: LDB B,[POINT 6,A,11] ;CHECK BYTE SIZE
CAIGE B,7 ;7 OR GREATER?
RET ;NO, RETURN BAD
RDCBP3: IBP A ;INCR IT AND DECR IT ONCE SO WILL
CALL DBP ; BE IN KNOWN STATE FOR COMPARES
RETSKP
;ROUTINE TO SET WAKEUP SET FROM CHARACTER BIT MASK
; Q3/ 0 IFF NO CUSTOM MASK SUPPLIED
; B/ CURRENT TERMINAL MODE WORD
; CALL RTSETW
; RETURN +1, ALWAYS
RTSETW: SKIPN TTYIND ;SKIP IF IT'S A TERMINAL
RET
SAVEP
SAVET
SETZB P2,P3 ;ZERO AREA USED FOR MASK HOLDING
SETZB P4,P5
JUMPE Q3,RSET1 ;DID USER PROVIDE A MASK
DMOVE P2,UMSK ;YES, GET FIRST PART
DMOVE P4,2+UMSK ;AND REST
RSET1: TXNN P2,<1B<.CHCRT>> ;BREAK ON CR?
TXNE F,RD%BEL ;WANT END OF LINE WAKING?
TXO P2,CM%BEL ;YES - SET BITS
TXNE F,RD%TOP ;TOPS10 WAKE SET?
TXO P2,CM%TOP
TXNE F,RD%PUN ;PUNCTUATION?
JRST [ TXO P2,CM%PU0 ;YES - SET FOUR WORDS
TXO P3,CM%PU1
TXO P4,CM%PU2
TXO P5,CM%PU3
JRST .+1]
TXNE F,RD%BRK ;WAKE ON CTRL/Z OR ESC?
TXO P2,CM%CZE ;YES
TXNE F,RD%NED ;TURN OFF EDITING CHARACTERS ?
JRST [ SETZ B, ;YES. INITIALIZE FLAG.
TXNE P2,1B<.CHCNR> ;IS CTRL/R IN BREAK MASK ?
TXO B,NRTYPE ;YES. CTRL/R IS NOT AN EDITING CHARACTER
TXNE P2,1B<.CHCNU> ;IS CTRL/U IN BREAK MASK ?
TXO B,NDELL ;YES. CTRL/U IS NOT AN EDITING CHARACTER
TXNE P2,1B<.CHCNV> ;IS CTRL/V IN BREAK MASK ?
TXO B,NQUOTE ;YES. CTRL/V IS NOT THE QUOTING CHARACTER
TXNE P2,1B<.CHCNW> ;IS CTRL/W IN BREAK MASK ?
TXO B,NDELW ;YES. CTRL/W IS NOT AN EDITING CHARACTER
TXNE P5,1B<.CHDEL-3*^D32> ;IS DEL IN BREAK MASK ?
TXO B,NDELC ;YES. DEL IS NOT AN EDITING CHARACTER
IORM B,FLG2 ;REMEMBER IT.
JRST .+1]
TXO P2,EDC0 ;ALWAYS BREAK ON EDITING CHARACTERS
TXO P3,EDC1
TXO P4,EDC2
TXO P5,EDC3
MOVEI B,.MOSBM ;NOW TO SET THE MASK
MOVEI C,P1 ;POINT TO MASK
MOVEI P1,4 ;LENGTH OF BLOCK
MTOPR ;SET IT
ERJMPR [RETERR()]
RET
;LOCAL ROUTINES FOR EDITING FUNCTIONS
;DELETE CHARACTER FROM DESTINATION - BACK UP PTR AND CHECK
;FOR TOP OF BUFFER
; CALL BACK
; RETURN +1: AT TOP OF BUFFER, NO CHARACTER TO DELETE
; RETURN +2: CHARACTER DELETED
BACK: CAMN P4,Q2 ;AT TOP OF BUFFER?
RET ;YES
MOVE A,P4 ;GET DEST PTR
CALL DBP ;DECREMENT IT
MOVEM A,P4 ;PUT IT BACK
CALL CHKBLP ;CHECK BACKUP LIMIT
AOJA P3,RSKP ;UPDATE COUNT AND RETURN
;PUT BYTE BACK INTO SOURCE
; B/ BYTE
; CALL RDBKIN
; RETURN +1 ALWAYS
RDBKIN: TXNN F,RD%JFN ;HAVE JFN FOR SOURCE?
JRST [ MOVE A,P1 ;NO, BACK UP P1 STRING
CALL DBP
MOVEM A,P1
RET]
HLRZ A,P1 ;BACK UP THE JFN
BKJFN
JFCL
RET
;CHECK FOR POINTER AT OR BEFORE BACKUP LIMIT
CHKBLP: MOVE T1,P4 ;[7116] GET MAIN PTR
MOVE T2,P2 ;[7116] GET LIMIT PTR
CALL SUBBP ;[7116] COMPUTE DIFFERENCE IN BYTES
CAIG T1,0 ;[7116] IS MAIN PTR ON SAME OR EARLIER BYTE?
TXO F,RD%BLR ;[7116] YES, FLAG LIMIT REACHED
RET
;FIND BEGINNING OF CURRENT LINE.
; CALL FNDLIN
; RETURN +1: AT TOP OF BUFFER
; RETURN +2: A/ BACKED-UP BYTE PTR TO BEGINNING OF LINE
; B/ BYTE COUNT CONSISTENT WITH P4 IN A
; C/ # OF NON-PRINTING CONTROLS IN THE LINE
FNDLIN: CAMN P4,Q2 ;AT TOP OF BUFFER?
RET ;YES
STKVAR <NOPRNT,SAVP3,SAVP4> ;WORK CELLS
SETZM NOPRNT ;NO NO PRINTING CHARACTERS YET
MOVEM P3,SAVP3
MOVEM P4,SAVP4 ;SAVE CURRENT LINE VARIABLES
XCTBU [LDB B,P4] ;GET FIRST CHARACTER TO DELETE
FNDLN1: CAIL B,40 ;A CONTROL?
JRST FNDLN3 ;NO, KEEP LOOKING
DMOVE C,OURCOC ;YES. SEE IF IT IS PRINITNG
ROTC C,0(B)
ROTC C,0(B)
TLNN C,(1B1) ;IS IT?
AOS NOPRNT ;NO. COUNT IT THEN
FNDLN3: MOVE A,P4 ;BACK UP ONE CHARACTER
CALL DBP
MOVEM A,P4
ADDI P3,1
CAMN P4,Q2 ;NOW AT TOP OF BUFFER?
JRST FNDLN2 ;YES, RETURN
XCTBU [LDB B,P4] ;GET NEXT CHARACTER TO DELETE
CAIE B,.CHLFD ;EOL OR LF?
JRST FNDLN1 ;NO, GO LOOK AT SOME MORE
FNDLN2: MOVE A,P4 ;RETURN NEW LINE VARIABLES
MOVE B,P3
MOVE P3,SAVP3 ;RESORE OLD LINE VARIABLES
MOVE P4,SAVP4 ;""
MOVE C,NOPRNT ;AND RETURN # OF NON-PRINTING CONTROLS
RETSKP
;ACTION ROUTINES
;ZERO BYTE
ZERO: SKIPE Q3 ;USER HAVE A MASK?
JRST INSRT ;YES. GO SEE ABOUT IT THEN
JRST WRAP0 ;NO. ALWAYS BREAK THEN
;REGULAR BREAKS
BREAKS: TXNE F,RD%BRK+RD%TOP ;REGULAR INCLUDES TOPS10 - BREAK?
JRST WRAP ;YES
JRST INSRT ;NO, STORE BYTE AND RETURN
;PUNCTUATION AND TOPS10 BYTES
TOPS10: TXNN F,RD%TOP ;BREAK?
PUNC: TXNE F,RD%PUN ;BREAK?
JRST WRAP ;YES
JRST INSRT ;NO
;CARRIAGE RETURN - IF LINE FEED FOLLOWS, TREAT LIKE EOL
RDCR: ;HERE ON A CR
SKIPN Q3 ;USER SPECIFYING BREAKS?
JRST RDCR0 ;NO
MOVE A,UMSK ;YES, GET FIRST WORD OF MASK
TXNE A,<1B<.CHCRT>> ;BREAK ON CARRIAGE RETURN?
JRST INSRT ;YES SO GO DO IT
RDCR0: ;HERE ON CR AND NOT BREAKING ON CR
CALL RDBIN ;GET THE NEXT CHAR
CAIN B,.CHLFD ;LF?
JRST RDCR1 ;YES, NORMAL NEWLINE
CALL RDBKIN ;NO, PUT BACK THE SECOND BYTE
MOVEI B,.CHCRT ;APPEND A REAL CR
JRST TOPS10
RDCR1: TXNE F,RD%CRF ;USER WANTS CR RETURNED?
JRST RDCR2 ;NO, SUPPRESS IT
MOVEI B,.CHCRT
XCTBU [IDPB B,P4] ;APPEND CR
SOJLE P3,[CALL RDBKIN ;NO MORE ROOM
JRST WRAP0] ;PUT LF BACK
RDCR2: MOVEI B,.CHLFD
EOL1: TXNE F,RD%BEL+RD%TOP+RD%PUN ;BREAK ON END OF LINE?
JRST WRAP ;YES
JRST INSRT ;NO
;QUOTE CHARACTER (^V) - INHIBITS EDITING ACTION OF FOLLOWING CHARACTER
; C/ flags from FLG2
RDQT: TXNE C,NQUOTE ;IS CTRL/V NOT THE QUOTING CHARACTER ?
JRST INSRT ;YES.
MOVX C,QUOTEF
IORM C,FLG2 ;REMEMBER TO QUOTE NEXT CHARACTER
JRST INSRT ;GO INSERT THE QUOTER
;DELETE CHARACTER (RUBOUT)
; C/ flags from FLG2
DELC: TXNE C,NDELC ;IS DELETE NOT AN EDITING CHARACTER ?
JRST INSRT ;YES.
CALL BACK ;BACK UP PTR
JRST BNULL ;NOTHING LEFT IN BUFFER
MOVE D,P4
XCTBU [ILDB A,D] ;GET CHAR JUST DELETED
CAIN A,.CHLFD ;WAS IT LF?
JRST [ CALL DELCR ;YES, DELETE C/R AND UPDATE DISPLAY
JRST NINSRT]
MOVE B,MOD
TXNN B,TT%ECO ;ECHOS ON?
JRST NINSRT ;NO, SKIP DISPLAY UPDATE
TXNE P5,DSPMF ;WHAT KIND OF TERMINAL?
JRST [ CALL CURBK ;IF DISPLAY, BACK UP CURSOR
JRST NINSRT]
MOVE B,A ;NOT A DISPLAY TERMINAL
CALL RDBOUT ;ECHO DELETED CHARACTER
MOVEI B,"\"
CALL RDBOUT ;FOLLOW IT WITH A BACKSLASH
JRST NINSRT
;DELETE LAST CHARACTER TYPED IF IT'S A CARRIAGE RETURN
;AND UPDATE TERMINAL DISPLAY TO REFLECT DELETION OF CR/LF
DELCR: CAME P4,Q2 ;AT START OF BUFFER NOW?
JRST [ XCTBU [LDB B,P4] ;NO, GET CHARACTER BEFORE LINEFEED
CAIE B,.CHCRT ;IS IT CARRIAGE-RETURN?
JRST .+1 ;NO
CALL BACK ;YES, KILL IT TOO
JFCL ;(NEVER RETURNS +1)
JRST .+1]
MOVX B,TT%ECO
TDNN B,MOD ;ECHO ON?
RET ;NO, DON'T OUTPUT TO TERMINAL
TXNN P5,DSPMF ;WHAT KIND OF TERMINAL?
JRST [ HRROI B,[ASCIZ/
/] ;NON-VIDEO TERMINAL,
CALLRET RDSOUT] ; SO ACKNOWLEDGE WITH CRLF
CALL CURUP ;MOVE CURSOR UP 1 LINE
CALLRET RTYPES ;RETYPE LINE AND RETURN TO CALLER
;DELETE LINE (CONTROL-U)
; C/ flags from FLG2
DELIN: TXNE C,NDELL ;IS CTRL/U NOT AN EDITING CHARACTER ?
JRST INSRT ;YES.
CALL DELIN0 ;DO THE WORK
CAME P4,Q2 ;BUFFER NOW EMPTY?
JRST NINSRT ;NO, CONTINUE
TXNE F,RD%RND ;YES, USER WANTS RETURN?
JRST WRAPE ;YES, RETURN
CALL RTYPP ;NO, RETYPE PROMPT
JRST NINSRT ;CONTINUE
DELIN0: TXNN F,RD%SUI ;IF NOT SUPPRESSING CTRL-U INDICATION,
CALL CURCR ;PUT CURSOR AT BEGINNING OF LINE
CALL FNDLIN ;FIND BEGINNING OF LINE
JRST DELIN1 ;NOTHING IN BUFFER
MOVEM A,P4 ;SET LINE VARIABLES TO BEGINNING
MOVEM B,P3
CAME P4,Q2 ;BUFFER NOW EMPTY?
JRST DELIN2 ;NO, GO TYPE DELETE INDICATION
DELIN1: TXNE F,RD%SUI ;BUFFER EMPTY, USER SUPPRESSING INDICATION?
JRST DELIN3 ;YES
DELIN2: JXO P5,DSPMF,DELIN3 ;IF DPY, LINE ALEADX CLEAN
HRROI B,[ASCIZ / XXX
/]
CALL RDSOUT ;NON-DPY, NOTE DELETION
DELIN3: CALLRET CHKBLP ;UPDATE BOUNDARY BITS AND RETURN
;DELETE WORD (CONTROL-W)
;C/ flags from FLG2
KLWORD: TXNE C,NDELW ;IS CTRL/W NOT AN EDITING CHARACTER ?
JRST INSRT ;YES.
CALL BACK ;DELETE AT LEAST ONE CHARACTER
JRST BNULL ;WASN'T ONE
MOVE D,P4
XCTBU [ILDB B,D] ;GET CHAR JUST DELETED
CAIN B,.CHLFD ;LF OR EOL?
JRST [ CALL DELCR ;YES, DELETE CR AND UPDATE DISPLAY
JRST BWRD1] ;ENTER BACKWARDS-SCAN LOOP
BWRD4: MOVE C,MOD ;CHECK ECHOS
JXE C,TT%ECO,BWRD1 ;NO OUTPUT IF ECHOS OFF
JXE P5,DSPMF,BWRD1 ;JUMP IF NOT DISPLAY
XCTBU [LDB A,D] ;GET CHAR
CALL CURBKW ;BACK UP CURSOR BUT DON'T CLEAR SCREEN YET
BWRD1: CALL BACK ;DELETE NEXT CHARACTER
JRST BWRD2 ;NO MORE LEFT
MOVE D,P4 ;LOOK AT CHARACTER JUST DELETED
XCTBU [ILDB B,D]
IDIVI B,CHRWRD ;GET ITS CHARACTER CLASS
LDB B,CCBTAB(C)
CAIN B,SAFE ;IS IT A WORD SEPARATOR?
JRST BWRD4 ;NO, KEEP DELETING
IBP P4 ;YES, KEEP THAT CHARACTER
SUBI P3,1
BWRD2: CALL CHKBLP ;CHECK BACKUP LIMIT POINTER
MOVEI B,"_" ;INDICATE WORD DELETION
TXNN P5,DSPMF ;BUT ONLY IF NONDISPLAY
CALL RDBOUT
TXNE P5,DSPMF ;DISPLAY?
CALL CLRLNQ ;YES, THEN CLEAR TO END OF LINE
JRST NINSRT ;CONTINUE INPUT UNLESS BUFFER EMPTY ETC.
;RETYPE LINE (CONTROL-R)
;C/ flags from FLG2
RTYPE: TXNE C,NRTYPE ;IS CTRL/R NOT AN EDITING CHARACTER ?
JRST INSRT ;YES.
MOVE B,MOD ;CHECK ECHOS
JXE B,TT%ECO,DING ;DING IF ECHOS OFF
CALL RTYPES ;DO THE WORK
CALL CHKBLP ;CHECK FOR BACKUP LIMIT SO ^R CAUSES RETURN ON RD%BEG
JRST NINSRT
;RETYPE PROMPT ONLY, ASSUMING CURSER ALREADY POSITIONED AT BEGINNING
;OF LINE
RTYPP: JRST RTYP33 ;ENTER AFTER ALL POSITIONING STUFF
;SUBROUTINE TO RETYPE LINE
RTYPES: JXE P5,DSPMF,[HRROI B,[ASCIZ /
/]
CALL RDSOUT ;NON-DISPLAY, GET CLEAN LINE
JRST RTYP33]
CALL CURCR ;PUT CURSOR TO BEGINNING OF LINE
RTYP33: CALL FNDLIN ;FIND BEGINNING OF LINE
MOVE A,Q2 ;AT TOP OF BUFFER - USE IT
MOVE D,A ;SAVE PTR TO BEGINNING OF LINE
CAME D,Q2 ;BEG OF LINE IS TOP OF BUFFER?
JRST RTYP1 ;NO, DON'T TYPE ^R BFR
SKIPE D,Q1 ;GET ^R BFR IF ANY
RTYP3: CAMN D,Q2 ;UP TO TOP OF BFR?
JRST RTYP4 ;YES, DONE WITH ^R BFR
XCTBU [ILDB B,D] ;GET CHAR FROM ^R BFR
JUMPN B,[CALL RDBOUT ;TYPE IT
JRST RTYP3]
RTYP4: MOVE D,Q2 ;DONE WITH ^R BFR, NOW DO MAIN BFR
RTYP1: CAMN D,P4 ;BACK TO END OF LINE?
RET ;YES
XCTBU [ILDB B,D] ;NO, GET NEXT BYTE
CALL RDBOUT ;TYPE IT
JRST RTYP1 ;LOOP UNTIL AT END OF BUFFER
;ROUTINE TO PUT CURSOR AT BEGINNING OF LOGICAL LINE. WILL DO CURUP'S
;IF NECESSARY.
CURCR: STKVAR <TWID,NUPS>
JXE P5,DSPMF,CURCRX ;NON-DPY, DO NOTHING
MOVEI B,.CHCRT ;DISPLAY, GET TO LEFT MARGIN
CALL RDBOUT
CAMN P4,Q2 ;BEGINNING OF BUFFER?
JRST RTYP2 ;YES, SO DEFINITELY NOT END OF LINE
XCTBU [LDB B,P4] ;NO, GET LAST CHAR
CAIN B,.CHLFD ;END OF LINE?
CALL CURUP ;YES, CURSOR UP FIRST
RTYP2: CALL CLRLIN ;CLEAR THE LINE
CALL GETWTH ;GET WIDTH OF LINE
JUMPE A,RTYP0 ;NO CURSOR UPS NECESSARY IF INFINITE WIDTH LINE
MOVEM A,TWID ;REMEMBER IT
CALL MEASUR ;GET PHYSICAL LENGTH OF LINE
MOVEI A,1 ;CAN'T, SO DON'T TRY TO BACK CURSOR UP
SOJ A,
IDIV A,TWID ;NOW A HAS NUMBER OF CURSOR UPS NEEDED TO GET TO BEGINNING OF LINE
MOVEM A,NUPS ;REMEMBER NUMBER OF UPS NEEDED
RTYP20: SOSGE NUPS ;MORE UPS NEEDED?
JRST RTYP0 ;NO, PROCEED WITH RETYPING LINE
CALL CURUP ;YES, DO ANOTHER
JRST RTYP20 ;AND LOOP FOR REST
RTYP0: CALL CLRLIN ;CLEAR THE LINE
CURCRX: RET
;ROUTINES TO RETURN DATA TO USER FOR RDTXT ROUTINES
STSRC: TXNE P5,RTTY+INTT ;RDTTY OR INTERNAL?
RET ;NOTHING TO DO
TXNE P5,RTXT ;RDTXT?
UMOVEM P1,T1 ;RETURN UPDATED SOURCE
UMOVE T1,T1 ;GET TEXTI BLK PTR
TXNE P5,TXTI ;TEXTI?
UMOVEM P1,.RDIOJ(T1) ;YES
RET ;AND DONE
STFLG: TXNE P5,INTT ;INTERNAL?
RET ;NOTHING TO DO
TXNE P5,RTTY ;RDTTY?
XCTU [HLLM F,T2] ;FLAGS TO T2
TXNE P5,RTXT ;RDTXT?
XCTU [HLLM F,T3] ;FLAGS TO T3
UMOVE T1,T1 ;GET TEXTI BLK PTR
TXNE P5,TXTI ;TEXTI?
XCTU [HLLM F,.RDFLG(T1)] ;FLAGS TO BLOCK
RET ;AND DONE
STP6: TXNE P5,INTT ;INTERNAL?
RET ;NOTHING TO DO
TXNE P5,RTTY ;RDTTY?
UMOVEM P4,T1 ;YES, POINTER TO T1
TXNE P5,RTXT ;RDTXT?
UMOVEM P4,T2 ;YES, POINTER TO T2
UMOVE T1,T1 ;GET TEXTI BLK PTR
TXNE P5,TXTI ;TEXTI
UMOVEM P4,.RDDBP(T1) ;YES, POINTER TO BLK
RET ;AND DONE
STP3: TXNE P5,INTT ;INTERNAL?
RET ;NOTHING TO DO
TXNE P5,RTTY ;RDTTY?
XCTU [HRRM P3,T2] ;YES, COUNT TO T2
TXNE P5,RTXT ;RDTXT?
XCTU [HRRM P3,T3] ;YES, COUNT TO T3
UMOVE T1,T1 ;GET TEXTI BLK PTR
TXNE P5,TXTI ;TEXTI?
UMOVEM P3,.RDDBC(T1) ;YES, COUNT TO BLK
RET ;AND DONE
;CURSOR CONTROL FUNCTIONS FOR DISPLAY TERMINALS
;CURSOR UP ONE LINE
CURUP: HRRZ A,P1 ;GET OUT JFN
RFPOS ;GET POSITION
TLNE 2,-1 ;A NON-ZERO POSITION?
SUB 2,[1,,0] ;YES. DECREMENT LINE NUMBER
SFPOS ;SET NEW POSITION
MOVEI B,.MORLC ;READ LINE COUNTER
MTOPR
ERJMPR [ITERX]
SOJ C, ;DECREASE IT
MOVEI B,.MOSLC
MTOPR ;TELL SYSTEM DECREASED VALUE
ERJMPR [ITERX]
CALL CLRLIN ;CLEAR LINE BEFORE UPPING CURSOR
HRRZ A,P5 ;GET ADDRESS ONLY
MOVE A,.CURUP(A) ;GET APPROPRIATE STRING FOR TERM TYPE
CALLRET DPCTL ;SEND IT
;ROUTINE TO BACK UP CURSOR OVER CHARACTER BEING DELETED, BUT DON'T
;NECESSARILY CLEAR THE CHARACTER. THIS ROUTINE IS PROVIDED FOR EFFICIENCY DURING
;WORD DELETE, IN WHICH IT IS FASTER TO NOT DELETE TO END OF PAGE FOR
;EVERY CHAR OF WORD BEING DELETED. SUPPLY CHARACTER BEING DELETED IN A.
CURBKW: MOVNI B,1 ;-1 IN B TO MARK THAT PAGE CLEARS SHOULDN'T HAPPEN
JRST CURBK0
;ROUTINE TO BACK UP THE CURSOR OVER A CHARACTER BEING DELETED.
;CALL IT WITH CHARACTER IN A.
CURBK: MOVEI B,0 ;MARK NOT DOING WORD DELETE
CURBK0: STKVAR <CLMS,CTRLWF,ARMF>
SETZM ARMF ;FIRST ASSUME NOT AT RIGHT MARGIN
MOVEM B,CTRLWF ;REMEMBER WHETHER DOING PAGE CLEARS OR NOT
CALL COLUMS ;SEE HOW MANY COLUMNS THIS CHARACTER TAKES UP
JRST RTYPES ;RETYPE LINE IF WE DON'T KNOW HOW MANY COLUMNS CHARACTER TAKES UP
MOVEM A,CLMS ;REMEMBER HOW MANY
CALL GETWTH ;GET WIDTH OF TERMINAL
MOVE C,A ;REMEMBER IN C
HRRZ A,P1 ;GET OUT JFN
RFPOS ;GET CURRENT POSITION
HRRZ D,B ;MAKE SIGNED INTEGER
JUMPE C,CURNRM ;COULDN'T BE AT RIGHT MARGIN IF ISN'T ONE
CAML D,C ;ARE WE AT RIGHT MARGIN
SETOM ARMF ;YES, REMEMBER
CURNRM: SUB D,CLMS ;SEE WHAT EFFECT CHARACTER WILL HAVE
JUMPL D,CURSPT ;JUMP IF BACKING UP REQUIRES GOING TO PREVIOUS LINE
CAIN D,0 ;SKIP IF THIS DELETION DOESN'T HIT LEFT MARGIN
JRST [ CAMN P4,Q2 ;YES. AT TOP OF BUFFER
JRST .+1 ;YES. DON'T DELETE ANY MORE
XCTBU [LDB C,P4] ;NO. GET PREVIOUS BYTE
CAIN C,.CHLFD ;AN EOL?
JRST .+1 ;YES. DON'T WRAP
JRST CURSPT] ;NO, GO BACK TO END OF PREV LINE
HRR B,D ;GET NEW LINE POSITION
SFPOS ;SET NEW LINE POSITION
SKIPE ARMF ;AT PHYSICAL RIGHT MARGIN?
SOS CLMS ;YES, SO ONE LESS COLUMN TO BACK UP
CURBK1: SOSGE CLMS ;DONE ENOUGH BACKING UP YET?
JRST CURBK2 ;YES
HRRZ A,P5 ;GET ADDRESS ONLY
MOVE A,.CURBK(A)
CALL DPCTL ;BACK UP ONE COLUMN
JRST CURBK1 ;LOOP FOR NUMBER OF BACKUPS NEEDED
CURBK2: SKIPE CTRLWF ;DOING WORD DELETE?
RET ;YES, SO DON'T CLEAR PAGE HERE
CALLRET CLRLNQ ;NO, SO CLEAR LINE HERE (UNLESS RIGHT ON MARGIN!)
CURSPT: MOVEI B,.CHCRT ;UNDOING LINE, SO CLEAR LINE WE'RE LEAVING
CALL RDBOUT
CALL CURUP ;GO BACK TO PREVIOUS LINE
CALL RTYPES ;RETYPE THE LINE
CALLRET CLRLNQ ;RETURN, MAYBE CLEARING LINE
;ROUTINE TO CAUTIOUSLY CLEAR TO END OF LINE ON SCREEN. ROUTINE CLEARS
;LINE IF AND ONLY IF CURSOR ISN'T AT RIGHT MARGIN, FOR WHICH CASE
;CLEARING LINE MIGHT ERRONEOUSLY CLEAR VALID CHARACTER AT END OF LINE.
CLRLNQ: CALL GETWTH ;GET WIDTH OF LINE
JUMPE A,CLRLIN ;COULDN'T BE AT RIGHT MARGIN IF ISN'T ONE
MOVE C,A ;SAVE WIDTH IN C
HRRZ A,P1
RFPOS ;GET CURRENT POSITION
CAILE C,(B) ;MIGHT WE BE AT RIGHT MARGIN?
CALL CLRLIN ;NO, SO IT'S SAFE TO CLEAR REST OF LINE WITHOUT LOSING CHARACTERS
RET
;CLEAR FROM CURSOR TO END OF LINE
CLRLIN: HRRZ A,P5 ;GET ADDRESS ONLY
MOVE A,.CUREL(A) ;GET ERASE LINE CODE
CALL DPCTL ;GO ERASE IT
RET ;ALL DONE
;ROUTINE TO SEND CONTROL SEQUENCES TO TERMINAL. PUTS TERMINAL
;IN BINARY MODE WHILE SENDING
; A/ BYTE (8)C,C,.. OR Z [BYTE (8)C,C,..]
; CALL DPCTL
; RETURN +1 ALWAYS, TERMINAL MODES PRESERVED
DPCTL: TXNN F,RD%JFN ;HAVE JFNS?
RET ;NO, DO NOTHING
STKVAR <WRD,PWRD,MD>
MOVEM A,WRD ;SAVE WORD
TLNE A,-1 ;HAVE WORD OR POINTER?
MOVEI A,WRD ;WORD, MAKE POINTER TO WORD
HRLI A,(POINT 8,0) ;CONSTRUCT POINTER TO STRING
MOVEM A,PWRD ;SAVE IT
HRRZ A,P1 ;GET OUT JFN
RFMOD ;GET CURRENT TERM MODES
TXO B,TT%IGN ;DON'T CHANGE WAKEUP BITS
MOVEM B,MD ;SAVE
TXZ B,TT%DAM ;SET TO BINARY
SFMOD
DPCTL1: ILDB B,PWRD ;GET BYTE
CAIE B,.STP ;STOP CODE?
JRST [ SKIPE ADDPAR ;ADDING PARITY TO THIS LINE?
CALL TTCMPP ;COMPUTE PARITY FOR THIS CHARACTER
BOUT ;NO, SEND IT
JRST DPCTL1]
MOVE B,MD ;RESTORE TERM MODES
SFMOD
RET
;ROUTINE WHICH TAKES CHAR IN A, AND RETURNS IN A THE NUMBER OF COLUMNS
;USED TO PRINT THAT CHARACTER ON THE PAPER. SKIPS IF KNOWS.
COLUMS: STKVAR <CCHRX>
MOVEM A,CCHRX ;REMEMBER THE CHARACTER
CAIL A,40 ;CONTROL CHARACTER?
JRST COLNC ;NO
CALL GETCOC ;GET CONTROL BITS FOR CHARACTER
MOVE B,CCHRX ;GET THE CHARACTER
JUMPE A,COL0 ;IF NOT BEING DISPLAYED, CHAR TAKES NO COLUMNS
CAIN A,1 ;BEING SHOWN AS UPARROW-CHARACTER?
JRST COLUP ;YES, UPARROW-CHARACTER
CAIN B,.CHTAB ;IS CHARACTER A REAL OR SIMULATED TAB?
JRST COLTAB ;YES, GO FIGURE IT OUT
CAIN A,2 ;SENDING ACTUAL CODE?
JRST COLDN ;YES, SO WE DON'T KNOW HOW MANY COLUMNS IT TAKES
CAIN B,.CHESC ;IS CHARACTER ALTMODE?
JRST COL1 ;YES, SO SIMULATE WITH ONE POSITION
COLDN: RET
COL1: MOVEI A,1 ;FOR CHARS TAKING ONE COLUMN
RETSKP
COL2: MOVEI A,2 ;TWO COLUMNS
RETSKP
COL0: MOVEI A,0 ;CHARACTERS THAT TAKE NO COLUMNS
RETSKP
COLNC: CAIN A,.CHDEL ;RUBOUT?
JRST COL0 ;YES, TAKES NO COLUMNS
CAIL A,101 ;UPPERCASE LETTER?
CAILE A,132
JRST COL1 ;NO, ASSUME 1 COLUMN FOR EVERYTHING ELSE
HRRZ A,P1
RFMOD ;GET MODE WORD
ERJMPR [ITERX]
TXNE B,TT%UOC ;FLAGGING UPPERCASE LETTERS?
TXNE B,TT%LCA ;AND NO LOWERCASE?
JRST COL1 ;NO TO EITHER, ONLY TAKES ONE COLUMN
JRST COL2 ;YES TO BOTH, CHARACTER TAKES 2 COLUMNS
COLUP: MOVE A,CCHRX ;GET CONTROL CHARACTER
ADDI A,100 ;SEE WHICH CHARACTER BEING "CONTROL"ED
CALL COLUMS ;SEE HOW MANY COLUMNS THAT CHARACTER TAKES
JRST COLDN ;CAN'T COMPUTE IF DON'T KNOW HOW TO PRINT THING BEING CONTROLED
AOJ A, ;ADD 1 FOR THE UPARROW (CONTROL-B WHEN
RETSKP ;FLAGGING ON TAKES 3 COLUMNS!!)
;CHARACTER IS TAB. FIGURE OUT HOW MANY COLUMNS IT TAKES BY COUNTING
;COLUMNS FROM BEGINNING OF LINE.
COLTAB: CAMN Q2,P4 ;IS THERE AT LEAST ONE CHAR LEFT IN BUFFER?
JRST COLT2 ;NO
XCTBU [LDB A,P4] ;YES, GET CHARACTER BEFORE THE TAB
CAIE A,.CHLFD ;IS TAB FIRST CHAR ON LINE?
JRST COLT2 ;NO
MOVEI A,8 ;YES, SO TAB TAKES 8 COLUMNS
RETSKP
COLT2: CALL MEASUR ;MEASURE LENGTH OF LINE IN PHYSICAL COLUMNS
JRST COLDN ;CAN'T, SO GIVE UP
MOVE B,A
ADDI A,8
TRZ A,7 ;SEE WHAT COLUMN TAB BROUGHT US TOO
SUB A,B ;CALCULATE COLUMNS TAKEN BY TAB
RETSKP ;DONE!
;ROUTINE TAKING CONTROL CHARACTER IN A AND RETURNING 2-BIT COC FIELD
;FOR THAT CHARACTER IN A.
GETCOC: DMOVE B,OURCOC ;GET BITS
LSH A,1 ;GET NUMBER OF PLACES TO SHIFT
LSHC B,(A) ;LEFT-JUSTIFY BITS IN B
LDB A,[420200,,B] ;GET CORRECT BITS
RET
;ROUTINE TO GET WIDTH OF LINE. SUBROUTINIZED SO THAT WHEN SOMEONE
;DECIDES TO FIX PROBLEMS ASSOCIATED WITH GETTING WIDTHS OF NONTERMINALS,
;THE FIX WILL ONLY NEED TO BE MADE IN ONE SPOT. THIS ROUTINE RETURNS
;WIDTH IN A.
GETWTH: MOVEI A,0(P1) ;NO
MOVEI B,.MORLW ;GET WIDTH OF LINE
MTOPR ;GO GET IT
ERJMPR [ITERX]
MOVE A,C ;RETURN WIDTH IN A
RET
;ROUTINE TO MEASUR PHYSICAL COLUMNS TAKEN UP BY LINE. RETURNS VALUE
;IN A.
;SKIPS IFF SUCCESSFUL IN MEASURING LENGTH OF LINE
;CR AND LF ARE IGNORED DURING THE CALCULATION. (THAT IS SO THAT WHEN
;DOING ^R TO REPRINT PREVIOUS LINE AFTER CR HAS BEEN TYPED, LENGTH OF
;PREVIOUS LINE GETS RETURNED BY THIS ROUTINE REGARDLESS OF THE TERMINAT-
;ING CR)
MEASUR: SETZM CCNT ;INITIALIZE THE COLUMN COUNTER
CALL FNDLIN ;FIND BEGINNING OF LINE
MOVE A,Q2 ;USE BEGINNING OF BUFFER IF THAT'S WHERE WE ARE
MOVEM A,CCPTR ;SAVE POINTER TO LINE TO BE SCANNED
CAMN A,Q2 ;IS THIS LINE FIRST ONE OF BUFFER?
JRST COLTR ;YES, MUST SCAN ^R BUFFER TOO
COLT1: MOVE A,CCPTR
CAMN A,P4 ;HAVE WE SCANNED ENTIRE LINE YET?
JRST COLTE ;YES
XCTBU [ILDB A,CCPTR] ;NO, GET NEXT CHARACTER FROM BUFFER
CALL COLACC ;ACCOUNT FOR THIS CHARACTER
JRST COLDN ;DO THE "DON'T KNOW" CASE
JRST COLT1 ;LOOP FOR REST OF LINE
COLTE: MOVE A,CCNT ;RETURN COLUMN VALUE IN A
RETSKP
COLTR: SKIPN A,Q1 ;FIRST LINE OF BUFFER. IS THERE A ^R BUFFER?
JRST COLT1 ;NO
MOVEM A,CRPTR ;YES, REMEMBER POINTER TO IT
COLR1: MOVE A,CRPTR ;GET POINTER TO ^R BUFFER SO FAR
CAMN A,Q2 ;HAVE WE HIT BEG OF BUFFER?
JRST COLT1 ;YES
XCTBU [ILDB A,CRPTR] ;GET NEXT CHARACTER FROM ^R BUFFER
JUMPE A,COLT1 ;LEAVE LOOP IF DONE
CALL COLACC ;ACCOUNT FOR CHARACTER
JRST COLDN ;DO THE DON'T KNOW CASE
JRST COLR1 ;DO REST OF CHARACTERS IN ^R BUFFER
;SUBROUTINE USED FROM ABOVE TO ACCOUNT FOR A CHARACTER SCANNED IN THE
;LINE
;GIVE IT CHARACTER IN A.
;SKIPS IFF KNOWS HOW TO ACCOUNT FOR CHARACTER.
COLACC: CAIN A,.CHTAB ;A TAB?
JRST COLTI ;YES
CAIE A,.CHCRT ;END OF LINE?
CAIN A,.CHLFD
RETSKP ;YES, IGNORE IT
CALL COLUMS ;NO, SEE HOW MANY COLUMNS IT TAKES
RET ;NON-SKIP IF FUNNY CHARACTER
ADDB A,CCNT ;ADD NUMBER OF COLUMNS IT TAKES
RETSKP
COLTI: MOVE A,CCNT ;TAB SEEN DURING SCAN, GET CURRENT COUNT
ADDI A,8 ;SEE WHERE TAB BRINGS IT
TRZ A,7
MOVEM A,CCNT
; IDIVI A,^D72
; CAIL B,^D60 ;NEAR RIGHT MARGIN?
; RET ;YES, SO GIVE UP, SINCE STRANGE THINGS
;HAPPEN LIKE LINEWRAPPING, OR VT05S WHICH
;TYPE ONLY ONE SPACE ON TABS NEAR RIGHT MARGIN
RETSKP
TNXEND
END