home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol256 / dialog11.bas < prev    next >
Encoding:
BASIC Source File  |  1986-03-22  |  25.7 KB  |  851 lines

  1. REM PROGRAM DIALOG
  2. REM A PROGRAM TO AUTOMATICALLY LOG IN AND EXTRACT DATA FROM
  3. REM A DATABASE SYSTEM
  4. REM
  5. REM WRITTEN BY E. VERNON BUCK, SAN LORENZO, CA. (415) 276-4607
  6. REM VERSION 1.1, DEC. 31, 1985.
  7. REM
  8. REM DIALOG READS "INSTRUCTIONS" FROM AN "INSTRUCTION FILE". THIS FILE
  9. REM IS PRODUCED BY ANY EDITOR OR WORD PROCESSOR. THE INSTRUCTION
  10. REM FILE TELLS THE PROGRAM HOW TO CONDUCT A "DIALOG" WITH THE
  11. REM REMOTE (OR "HOST") COMPUTER. THE INSTRUCTIONS TELL THE PROGRAM
  12. REM WHAT MESSAGES TO SEND, AND WHAT MESSAGES TO RECEIVE FROM THE
  13. REM HOST. THE PROGRAM CAN ALSO MAKE SOME
  14. REM SIMPLE DECISIONS (BRANCHING) BASED ON THE CONTENT OF MESSAGES
  15. REM RECEIVED FROM THE HOST. THE DIALOG IS DISPLAYED ON THE 
  16. REM TERMINAL AS IT HAPPENS, AND (OPTIONALLY) RECORDED
  17. REM IN A "LOG" FILE.
  18. REM
  19. REM THE INSTRUCTIONS AVAILABLE ARE AS FOLLOWS:
  20. REM    S,ccc...c        SEND THE STRING ccc...c TO THE HOST.
  21. REM                THE SEND COMMAND EXPECTS THE
  22. REM                CHARACTERS TO BE ECHOED BY THE HOST.
  23. REM
  24. REM    T,ccc...c        TRANSMIT THE STRING ccc...c TO THE
  25. REM                HOST. IDENTICAL TO THE S COMMAND,
  26. REM                EXCEPT DOES NOT EXPECT AN ECHO.
  27. REM
  28. REM    R,ttt...t         RECEIVE A STRING OF CHARACTERS FROM
  29. REM                THE HOST UNTIL THE "TERMINATION" STRING
  30. REM                ttt...t IS RECEIVED. ANY NUMBER OF
  31. REM                CHARACTERS CAN BE RECEIVED BEFORE THE
  32. REM                TERMINATION STRING IS ENCOUNTERED, BUT
  33. REM                ONLY THE LAST 2000 (ABOUT 1 SCREENFULL)
  34. REM                WILL BE RETAINED.
  35. REM
  36. REM    I,ddd...d,n        IF THE LAST RECEIVED CHARACTERS
  37. REM                (INCLUDING THE TERMINATION CHARACTERS
  38. REM                FROM THE R INSTRUCTION) WERE ddd...d,
  39. REM                THEN JUMP TO THE INSTRUCTION LINE
  40. REM                LABELED n. n IS A NUMBER FROM
  41. REM                1 TO 9999.
  42. REM
  43. REM    G,n            GO TO (JUMP UNCONDITIONALLY) TO THE
  44. REM                INSTRUCTION LINE LABELED n.
  45. REM
  46. REM    E,i,n            IF AN ERROR CONDITION OF TYPE i IS
  47. REM                DETECTED, THEN GO TO THE
  48. REM                INSTRUCTION LINE LABELED n.
  49. REM                i CAN BE:
  50. REM                 "SE" - SEND INSTRUCTION ECHO ERROR
  51. REM                 "RE" - RECEIVE INSTRUCTION
  52. REM                        PARITY, FRAME OR OVERRUN ERROR
  53. REM                 "TO" - TIME OUT
  54. REM                 "CL" - CARRIER LOST.
  55. REM                n = 0 MEANS IGNORE THE ERROR, AND
  56. REM                CONTINUE. THIS IS THE DEFAULT.
  57. REM                n = -1 ("SE" ONLY) MEANS SEND A
  58. REM                BACKSPACE AND REPEAT THE ERRONEOUS
  59. REM                CHARACTER
  60. REM
  61. REM    L,lll            CONTROL THE AMOUNT OF INFORMATION TO
  62. REM                BE SAVED IN THE LOG FILE:
  63. REM                lll=ON -- SAVE RECEIVED DATA ONLY
  64. REM                lll=OFF-- SAVE NOTHING
  65. REM                lll=ALL-- SAVE BOTH TRANSMITTED AND
  66. REM                      RECEIVED DATA (DEFAULT)
  67. REM
  68. REM    D,ddd            CONTROLS WHETHER THE DIALOG WILL BE
  69. REM                DISPLAYED ON THE TERMINAL AS IT
  70. REM                HAPPENS:
  71. REM                ddd=OFF -- NOT DISPLAYED ON TERMINAL
  72. REM                ddd=ON  -- DISPLAYED ON TERMINAL
  73. REM                       (DEFAULT)
  74. REM
  75. REM    C,p            MAKE p THE CONTROL CHARACTER PREFACE
  76. REM                FOR THE INSTRUCTION LINES THAT FOLLOW.
  77. REM                I.E., ^M WOULD BE TRANSMITTED AS A
  78. REM                CTRL-M    WHEN p="^". DEFAULT IS "^".
  79. REM                THE C INSTRUCTION IS NON-EXECUTABLE.
  80. REM                THAT IS, IT OPERATES ON THE INSTRUC-
  81. REM                TIONS AS THEY ARE COMPILED, BUT NOT
  82. REM                AS EXECUTED (SINCE INSTRUCTIONS
  83. REM                MIGHT BE EXECUTED IN A DIFFERENT
  84. REM                ORDER).
  85. REM
  86. REM    X            EXIT. CLOSE FILES AND RETURN TO CP/M.
  87. REM
  88. REM INSTRUCTIONS CAN BE PRECEEDED BY A "LABEL NUMBER". THIS IS LIKE A
  89. REM LINE NUMBER IN BASIC OR FORTRAN. IT IS OPTIONAL. BUT OF COURSE, IF
  90. REM THERE IS AN I, G OR E INSTRUCTION ANYWHERE IN THE INSTRUCTIONS,
  91. REM THEN THERE MUST BE A LABELED INSTRUCTION WHICH MATCHES THE
  92. REM LABELS GIVEN IN THE I, G OR E INSTRUCTION. EXAMPLE:
  93. REM 100,S,hello^M
  94. REM    ...
  95. REM    G,100
  96. REM
  97. REM NOTES: (1) ALL INSTRUCTION PARAMETERS MUST BE SEPARATED BY COMMAS.
  98. REM       (2) IF A COMMA IS NEEDED IN A CHARACTER STRING, THEN
  99. REM           SURROUND THE STRING WITH QUOTES ("...").
  100. REM       (3) LEADING BLANKS ARE IGNORED, UNLESS THE STRING IS QUOTED.
  101. REM       (4) DO NOT USE TAB CHARACTERS (CTRL-I) TO INDENT.
  102. REM           USE SPACES.
  103. REM
  104. REM TO INVOKE THE PROGRAM, TYPE
  105. REM    DIALOG insfile.dlg logfile.log
  106. REM WHERE insfile.dlg IS THE FILE CONTAINING THE INSTRUCTIONS, AND
  107. REM logfile.log IS THE LOG FILE (TO BE WRITTEN BY DIALOG). THE LOG
  108. REM FILE IS OPTIONAL AND CAN SIMPLY BE OMITTED. THERE ARE NO DEFAULT
  109. REM FILE NAMES OR EXTENSIONS. REPLACING logfile.log WITH A QUESTION
  110. REM MARK WILL CAUSE THE INSTRUCTION FILE TO BE COMPILED, BUT NOT
  111. REM EXECUTED, FOR TESTING PURPOSES.
  112. REM 
  113. REM THE INSTRUCTIONS ARE STORED IN VARIABLES
  114. REM     COMM$ : THE COMMAND
  115. REM     ARG1$ : THE FIRST ARGUMENT (A STRING)
  116. REM     ARG2% : THE SECOND ARGUMENT (A NUMBER)
  117. REM
  118. REM PATCH AREA CONSTANTS:
  119. REM DATA.PORT% = I/O DATA PORT FOR MODEM
  120. REM CTRL.PORT% = I/O PORT TO READ TO TEST FOR TRANSMIT/RECEIVE
  121. REM         READY
  122. REM TRDY.MASK% = THE BIT TO TEST FOR TRANSMIT READY (IS SET TO 1)
  123. REM TRDY.POL% = SET THE SAME BIT AS TRDY.MASK% TO 1 TO REVERSE THE
  124. REM     POLARITY OF THE TEST (I.E. READY WHEN BIT = 0)
  125. REM RRDY.MASK%, RRDY.POL% = SAME FOR RECEIVE READY
  126. REM RERR.PORT% = I/O PORT TO READ TO TEST FOR READ ERRORS
  127. REM RERR.MASK%, RERR.POL% = BITS TO TEST FOR READ ERRORS (I.E.
  128. REM    PARITY, FRAME AND/OR OVERRUN), AND POLARITY OF SAME
  129. REM RES.PORT% = I/O PORT TO RECEIVE THE FOLLOWING RESET BYTE. (SET TO
  130. REM        -1 IF NO RESET BYTE IS REQUIRED)
  131. REM RERR.RES% = BYTE TO SEND TO RESET PORT TO RESET UART AFTER
  132. REM        RECEIPT OF PARITY, FRAME OR OVERRUN ERROR
  133. REM CARRIER.PORT% = I/O PORT TO READ TO TEST FOR CARRIER PRESENT 
  134. REM CARRIER.MASK% = THE BIT(S) TO TEST FOR CARRIER PRESENT (E.G. DSR)
  135. REM CARRIER.POL% = POLARITY OF CARRIER BIT(S)
  136. REM CC.PREF$ = THE CHARACTER THAT PRECEEDS A CHARACTER TO INDICATE
  137. REM        THAT THE 2ND CHARACTER IS A CONTROL CHARACTER.
  138. REM        (I.E. ^M = CTRL-M, WHEN CC.PREF$ = "^")
  139. REM MAX.TIME = APPROX. TIME OUT TIME. FOR 4MHZ CPU, 1100 ~= 1 SECOND
  140. REM
  141. REM HOW TO PATCH THE .COM FILE:
  142. REM USING DDT.COM, OR SOME OTHER PATCHING PROGRAM, FIND THE FOLLOWING
  143. REM DATA STATEMENTS. THEY ARE PREFACED BY THE WORD "PATCH:". CHANGE
  144. REM THE NUMBERS FOLLOWING PATCH: TO SUIT YOUR SYSTEM. THEY ARE IN
  145. REM DECIMAL AND ASCII, AS FOLLOWS:
  146. REM    (1) THE UART DATA I/O PORT NUMBER
  147. REM    (2) THE UART TRANSMIT/RECEIVE READY I/O PORT NUMBER
  148. REM    (3) THE BIT TO TEST FOR TRANSMIT READY
  149. REM    (4) THE BIT TO BE EXCLUSIVE OR'ED BEFORE TESTING FOR TRANSMIT
  150. REM    (5) THE BIT TO TEST FOR RECEIVE READY
  151. REM    (6) THE BIT TO BE EXCLUSIVE OR'ED BEFORE TESTING FOR RECIEVE
  152. REM    (7) THE I/O PORT TO READ FOR RECEIVE ERRORS
  153. REM    (8) THE BIT(S) TO TEST FOR RECEIVE ERRORS (PARITY, FRAME
  154. REM        AND/OR OVERRUN, ETC.)
  155. REM    (9) THE BIT(S) TO BE EXCLUSIVE OR'ED WITH THE ERROR BITS
  156. REM        BEFORE TESTING
  157. REM    (10) THE I/O PORT TO SEND A RESET BYTE TO (-01 IF NONE)
  158. REM    (11) BYTE TO SEND TO THE RESET PORT TO RESET UART FOLLOWING
  159. REM        RECEPTION OF A TRANSMISSION ERROR
  160. REM    (12) THE I/O PORT TO READ FOR CARRIER PRESENT TEST
  161. REM    (13) THE BIT(S) TO TEST FOR CARRIER ON (I.E., THE DSR LINE)
  162. REM    (14) THE BIT(S) TO BE EXCLUSIVE OR'ED WITH THE CARRIER ON BIT
  163. REM        BEFORE TESTING
  164. REM    (15) THE DEFAULT CHARACTER TO BE A PREFACE FOR CONTROL
  165. REM        CHARACTERS
  166. REM    (16) THE TIME OUT COUNTER MAXIMUM
  167. REM
  168.     DATA "PATCH:",000,001,001,000,002,000,001,008,000
  169.     DATA 001,055,001,128,000
  170.     DATA "^",066000
  171. REM
  172.     DIM COMM$(200),ARG1$(200),ARG2%(200),LABEL%(200)
  173.     DIM BUFFER%(2000)
  174. REM
  175. REM SET THE I/O PORT PARAMETERS
  176.     READ GARBAGE$,DATA.PORT%,CTRL.PORT%,TRDY.MASK%,_
  177.         TRDY.POL%,RRDY.MASK%,RRDY.POL%
  178.     READ RERR.PORT%,RERR.MASK%,RERR.POL%,RES.PORT%,RERR.RES%,_
  179.         CARRIER.PORT%,CARRIER.MASK%,CARRIER.POL%
  180. REM
  181. REM SET THE CONTROL CHARACTER PREFACE
  182.     READ CC.PREF$
  183. REM SET THE TIME OUT COUNTER MAXIMUM
  184.     READ MAX.TIME
  185. REM
  186.     TRUE% = (0 = 0)
  187.     FALSE% = (1 = 0)
  188.     CC.PREF% = ASC(CC.PREF$)
  189. REM
  190. REM GET THE FILE NAMES FROM CP/M COMMAND
  191. REM
  192.     INST.FILE$ = ""
  193.     FOR ADDRESS% = 93 TO 100
  194.     INST.FILE$ = INST.FILE$ + CHR$(PEEK(ADDRESS%))
  195.     NEXT ADDRESS%
  196.     IF INST.FILE$ = "        " THEN GO TO 9600
  197.     INST.FILE$ = INST.FILE$ + "."
  198.     DRIVE% = PEEK(92)
  199.     IF DRIVE% > 0 THEN _
  200.         INST.FILE$ = CHR$(DRIVE% + 64) + ":" + INST.FILE$
  201.     FOR ADDRESS% = 101 TO 103
  202.     INST.FILE$ = INST.FILE$ + CHR$(PEEK(ADDRESS%))
  203.     NEXT ADDRESS%
  204. REM
  205.     LOG.FILE$ = ""
  206.     FOR ADDRESS% = 109 TO 116
  207.     LOG.FILE$ = LOG.FILE$ + CHR$(PEEK(ADDRESS%))
  208.     NEXT ADDRESS%
  209.     NO.LOG.FILE% = (LOG.FILE$ = "        " )
  210.     COMPILE.ONLY% = (LOG.FILE$ = "?       " )
  211.     IF NO.LOG.FILE% THEN GO TO 100
  212.     LOG.FILE$ = LOG.FILE$ + "."
  213.     DRIVE% = PEEK(108)
  214.     IF DRIVE% > 0 THEN _
  215.         LOG.FILE$ = CHR$(DRIVE% + 64) + ":" + LOG.FILE$
  216.     FOR ADDRESS% = 117 TO 119
  217.     LOG.FILE$ = LOG.FILE$ + CHR$(PEEK(ADDRESS%))
  218.     NEXT ADDRESS%
  219. REM
  220. 100    REM
  221. REM OPEN THE INSTRUCTION FILE
  222.     OPEN "I",#1,INST.FILE$
  223. REM
  224. REM
  225. REM READ THE INSTRUCTIONS INTO MEMORY AND CHECK FOR OBVIOUS
  226. REM ERRORS
  227.     FOR NO.INSTR% = 1 TO 200
  228. REM    SET TRAP FOR SYNTAX ERROR & INITIALIZE LABEL% ARRAY
  229.     LABEL.PRESENT% = FALSE%
  230.     LABEL%(NO.INSTR%) = 0
  231. REM    EXIT LOOP IF NO MORE COMMANDS
  232.     IF EOF(1) THEN GO TO 500
  233. 200    REM
  234.     INPUT #1, COMMAND$
  235. REM TAKE FIRST CHARACTER AND CONVERT TO UPPER CASE IF NECESSARY
  236.     ASCII.VAL% = ASC(COMMAND$)
  237.     IF ASCII.VAL% > 96 AND ASCII.VAL% <= 122 THEN _
  238.         FIRST.CHAR$ = CHR$(ASCII.VAL% - 32) ELSE _
  239.         FIRST.CHAR$ = CHR$(ASCII.VAL%)
  240. REM GO TO APPROPRIATE SECTION TO INTERPRET DIFFERENT INSTRUCTIONS
  241.     IF FIRST.CHAR$ = "L" THEN GO TO 300
  242.     IF FIRST.CHAR$ = "D" THEN GO TO 320
  243.     IF FIRST.CHAR$ = "S" OR FIRST.CHAR$ = "R" _
  244.         OR FIRST.CHAR$ = "T" THEN GO TO 350
  245.     IF FIRST.CHAR$ = "I" THEN GO TO 400
  246.     IF FIRST.CHAR$ = "E" THEN GO TO 430
  247.     IF FIRST.CHAR$ = "G" THEN GO TO 440
  248.     IF FIRST.CHAR$ = "C" THEN GO TO 450
  249.     IF FIRST.CHAR$ = "X" THEN GO TO 490
  250. REM
  251. REM COMMAND$ IS NONE OF THE INTRINSIC COMMANDS. ASSUME IT IS
  252. REM A STATEMENT LABEL
  253. REM TEST FOR ILLEGAL COMMAND
  254.     IF LABEL.PRESENT% OR ASCII.VAL% < 48 OR _
  255.         ASCII.VAL% > 57 THEN GO TO 9010
  256.     LABEL.VALUE% = VAL(COMMAND$)
  257. REM CHECK RANGE OF LABEL
  258.     IF LABEL.VALUE% < 1 OR LABEL.VALUE% > 9999 THEN GO TO 9015
  259. REM CHECK FOR DUPLICATE LABEL ON A PREVIOUS INSTRUCTION
  260.     IF NO.INSTR% = 1 THEN GO TO 280
  261.     FOR LABEL.NO% = 1 TO NO.INSTR% - 1
  262.     IF LABEL%(LABEL.NO%) = LABEL.VALUE% THEN GO TO 9020
  263.     NEXT LABEL.NO%
  264. 280    REM
  265. REM SAVE THIS LABEL 
  266.     LABEL%(NO.INSTR%) = LABEL.VALUE%
  267.     LABEL.PRESENT% = TRUE%
  268.     GO TO 200
  269. REM
  270. 300    REM
  271. REM COMPILE A LOG INSTRUCTION
  272. REM READ THE ARGUMENT
  273.     IF EOF(1) THEN GO TO 9000
  274.     INPUT #1, ARGUMENT1$
  275. REM TEST FOR LEGALITY OF ARGUMENT
  276.     IF ARGUMENT1$ <> "IN" AND ARGUMENT1$ <> "OFF" AND _
  277.         ARGUMENT1$ <> "ALL" THEN GO TO 9025
  278.     IF ARGUMENT1$ <> "OFF" AND NO.LOG.FILE% THEN GO TO 9005 
  279.     IF ARGUMENT1$ = "OFF" THEN ARG2%(NO.INSTR%) = 0
  280.     IF ARGUMENT1$ = "IN" THEN ARG2%(NO.INSTR%) = 1
  281.     IF ARGUMENT1$ = "ALL" THEN ARG2%(NO.INSTR%) = 2
  282.     ARG1$(NO.INSTR%) = ARGUMENT1$
  283.     GO TO 490
  284. REM
  285. 320    REM
  286. REM COMPILE D (DISPLAY ON/OFF) COMMAND
  287.     IF EOF(1) THEN GO TO 9000
  288.     INPUT #1, ARGUMENT1$
  289.     IF ARGUMENT1$ <> "ON" AND ARGUMENT1$ <> "OFF" _
  290.         THEN GO TO 9025
  291.     ARG2%(NO.INSTR%) = ( ARGUMENT1$ = "ON" )
  292.     ARG1$(NO.INSTR%) = ARGUMENT1$
  293.     GO TO 490
  294. REM
  295. 350    REM
  296. REM COMPILE A SEND OR RECEIVE INSTRUCTION
  297. REM READ THE ARGUMENT
  298.     IF EOF(1) THEN GO TO 9000
  299.     INPUT #1, IN.STRING$
  300. REM TEST FOR LEGALITY
  301.     IF LEN(IN.STRING$) < 1 THEN GO TO 9025
  302. REM CONVERT CONTROL CHARACTERS
  303.     GO SUB 10000
  304.     IF LEN(OUT.STRING$) > 2000 THEN GO TO 9025
  305.     ARG1$(NO.INSTR%) = OUT.STRING$
  306. REM SAVE THE CONTROL CHARACTER PREFACE (NEEDED FOR LOGGING)
  307.     ARG2%(NO.INSTR%) = CC.PREF%
  308.     GO TO 490
  309. REM
  310. 400    REM
  311. REM COMPILE AN IF INSTRUCTION
  312. REM READ THE 1ST ARGUMENT
  313.     IF EOF(1) THEN GO TO 9000
  314.     INPUT #1, IN.STRING$
  315. REM TEST FOR LEGALITY
  316.     IF LEN(IN.STRING$) < 1 THEN GO TO 9025
  317. REM CONVERT CONTROL CHARACTERS
  318.     GO SUB 10000
  319.     ARG1$(NO.INSTR%) = OUT.STRING$
  320. REM READ THE 2ND ARGUMENT
  321.     IF EOF(1) THEN GO TO 9000
  322.     INPUT #1, ARGUMENT2%
  323. REM TEST FOR REASONABLENESS
  324.     IF ARGUMENT2% < 1 OR ARGUMENT2% > 9999 THEN GO TO 9030
  325.     ARG2%(NO.INSTR%) = ARGUMENT2%
  326.     GO TO 490
  327. REM
  328. 430    REM
  329. REM COMPILE AN ON ERROR JUMP
  330.     IF EOF(1) THEN GO TO 9000
  331.     INPUT #1, ARGUMENT1$
  332.     IF ARGUMENT1$ <> "RE" AND ARGUMENT1$ <> "SE" _
  333.         AND ARGUMENT1$ <> "TO" AND ARGUMENT1$ <> "CL" _
  334.         THEN GO TO 9025
  335.     ARG1$(NO.INSTR%) = ARGUMENT1$
  336.     IF EOF(1) THEN GO TO 9000
  337.     INPUT #1, ARGUMENT2%
  338. REM TEST FOR REASONABLENESS
  339.     IF ARGUMENT2% < -1 OR ARGUMENT2% > 9999 THEN GO TO 9030
  340.     ARG2%(NO.INSTR%) = ARGUMENT2%
  341.     GO TO 490
  342. REM
  343. REM
  344. 440    REM
  345. REM COMPILE A JUMP (GOTO) INSTRUCTION
  346.     IF EOF(1) THEN GO TO 9000
  347.     INPUT #1, ARGUMENT2%
  348. REM TEST FOR REASONABLENESS
  349.     IF ARGUMENT2% < 1 OR ARGUMENT2% > 9999 THEN GO TO 9030
  350.     ARG2%(NO.INSTR%) = ARGUMENT2%
  351.     GO TO 490
  352. REM
  353. 450    REM
  354. REM COMPILE A CHANGE CONTROL CHARACTER PREFACE
  355.     IF EOF(1) THEN GO TO 9000
  356.     INPUT #1, ARGUMENT1$
  357.     IF LEN(ARGUMENT1$) <> 1 THEN GO TO 9025
  358.     CC.PREF% = ASC(ARGUMENT1$)
  359.     ARG1$(NO.INSTR%) = ARGUMENT1$
  360.     ARG2%(NO.INSTR%) = CC.PREF%
  361.     GO TO 490
  362. REM
  363. 490    REM
  364. REM STORE THE COMMAND
  365.     COMM$(NO.INSTR%) = FIRST.CHAR$
  366.     NEXT NO.INSTR%
  367. 500    REM
  368.     NO.INSTR% = NO.INSTR% - 1
  369. REM
  370.     CLOSE #1
  371.     IF NO.INSTR% <= 0 THEN GO TO 9040
  372. REM
  373. REM REPLACE THE STATEMENT LABELS IN THE I, E, AND G COMMANDS WITH THE
  374. REM ACTUAL LINE NUMBERS REPRESENTED BY THE LABELS
  375.     FOR I% = 1 TO NO.INSTR%
  376.     COMMAND$ = COMM$(I%)
  377.     IF COMMAND$ <> "I" AND COMMAND$ <> "G" _
  378.         AND COMMAND$ <> "E" THEN GO TO 800
  379.     TARGET.LABEL% = ARG2%(I%)
  380. REM IF TARGET IS <= 0, THEN IT'S NOT A LINE NUMBER, SO SKIP
  381.     IF TARGET.LABEL% <= 0 THEN GO TO 800
  382. REM SEARCH THROUGH THE LIST OF LABELS
  383.     FOR K% = 1 TO NO.INSTR%
  384.     IF LABEL%(K%) = TARGET.LABEL% _
  385.         THEN GO TO 750
  386.     NEXT K%
  387. REM LABEL NOT FOUND IN LABEL LIST
  388.     GO TO 9035
  389. 750    REM
  390. REM SET ARG2% TO THE LINE NUMBER OF THE LABELED INSTRUCTION
  391.     ARG2%(I%) = K%
  392. 800    REM
  393.     NEXT I%
  394. REM
  395. REM
  396. REM EXIT IF THIS WAS A COMPILE ONLY RUN
  397.     IF NOT COMPILE.ONLY% THEN GO TO 900
  398.     PRINT "No instruction errors detected in ";INST.FILE$
  399.     END
  400. REM
  401. 900    REM
  402. REM EXECUTE THE INSTRUCTIONS
  403. REM
  404. REM
  405. REM OPEN THE LOG FILE
  406.     IF NOT NO.LOG.FILE% THEN OPEN "O",#2,LOG.FILE$
  407. REM INITIALIZE INSTRUCTION COUNTER
  408.     INST.LIN% = 0
  409. REM INITIALIZE LOGGING FLAG
  410.     IF NO.LOG.FILE% THEN LOG.FLAG% = 0 ELSE LOG.FLAG% = 2
  411. REM INITIALIZE TERMINAL DISPLAY ON FLAG
  412.     DISPLAY% = TRUE%
  413. REM INITIALIZE ON ERROR TARGET LINE NUMBER
  414.     RERR.LIN% = 0
  415.     SERR.LIN% = 0
  416.     TERR.LIN% = 0
  417.     CERR.LIN% = 0
  418. REM INITIALIZE BUFFER POINTER
  419.     CHAR.NO% = 0
  420. REM
  421. REM
  422. REM TOP OF EXECUTION LOOP
  423. 1000    REM
  424.     INST.LIN% = INST.LIN% + 1
  425.     IF INST.LIN% > NO.INSTR% OR INST.LIN% < 1 _
  426.         THEN GO TO 9550
  427.     COMMAND$ = COMM$(INST.LIN%)
  428.     IF COMMAND$ = "S" OR COMMAND$ = "T" THEN GO TO 2000
  429.     IF COMMAND$ = "R" THEN GO TO 3000
  430.     IF COMMAND$ = "I" THEN GO TO 4000
  431.     IF COMMAND$ = "G" THEN GO TO 4400
  432.     IF COMMAND$ = "E" THEN GO TO 4500
  433.     IF COMMAND$ = "L" THEN GO TO 5000
  434.     IF COMMAND$ = "D" THEN GO TO 5100
  435.     IF COMMAND$ = "C" THEN GO TO 1000
  436.     IF COMMAND$ = "X" THEN GO TO 9550
  437. REM
  438. REM
  439. 2000    REM
  440. REM EXECUTE THE SEND COMMAND
  441. REM
  442. REM GET THE STRING
  443.     CHARS.OUT$ = ARG1$(INST.LIN%)
  444. REM GET THE NUMBER OF CHARACTERS TO SEND
  445.     NO.OUT% = LEN(CHARS.OUT$)
  446. REM COPY THE CHARACTERS INTO THE OUTPUT BUFFER
  447.     FOR CHAR.NO% = 1 TO NO.OUT%
  448.     BUFFER%(CHAR.NO%) = ASC(MID$(CHARS.OUT$,CHAR.NO%,1))
  449.     NEXT CHAR.NO%
  450. REM
  451. REM IF LOG.FLAG% IS 2, WRITE CHARACTERS TO LOG FILE.
  452.     IF NOT DISPLAY% AND LOG.FLAG% < 2 THEN GO TO 2400
  453. REM MUST REINSERT THE CONTROL CHARACTER PREFACE.
  454.     PRNT.PREF$ = CHR$(ARG2%(INST.LIN%))
  455.     FOR CHAR.NO% = 1 TO NO.OUT%
  456.     CHAR% = BUFFER%(CHAR.NO%)
  457.     IF CHAR% < 32 THEN GO TO 2200
  458.     PRNT.CHAR$ = CHR$(CHAR%)
  459.     IF DISPLAY% THEN PRINT PRNT.CHAR$;
  460.     IF LOG.FLAG% = 2 THEN PRINT #2, PRNT.CHAR$;
  461.     GO TO 2300
  462. 2200    REM
  463. REM WRITE PRINTABLE CONTROL CHARACTER
  464.     IF DISPLAY% THEN PRINT PRNT.PREF$;
  465.     PRNT.CHAR$ = CHR$(CHAR% + 64)
  466.     IF DISPLAY% THEN PRINT PRNT.CHAR$;
  467.     IF LOG.FLAG% < 2 THEN GO TO 2300
  468.     PRINT #2, PRNT.PREF$;
  469.     PRINT #2, PRNT.CHAR$;
  470. 2300    REM
  471.     NEXT CHAR.NO%
  472. REM
  473. REM WRITE <CR>,<LF> TO LOG FILE
  474.     IF DISPLAY% THEN PRINT ""
  475.     IF LOG.FLAG% = 2 THEN PRINT #2, ""
  476. 2400    REM 
  477. REM
  478. REM CLEAR THE MODEM RECEIVER REGISTER
  479.     IF COMMAND$ = "S" THEN GARBAGE% = INP(DATA.PORT%)
  480. REM
  481. REM NOW SEND THE CHARACTERS TO THE OUTPUT PORT
  482.     FOR CHAR.NO% = 1 TO NO.OUT%
  483.     CHAR.OUT% = BUFFER%(CHAR.NO%)
  484. 2420    REM
  485. REM
  486. REM WAIT FOR READY SIGNAL FROM CONTROL PORT
  487.     TIME.COUNT = 0.0
  488. 2425    REM
  489. REM IF ENABLED, TEST FOR TIME OUT
  490.     IF TERR.LIN% > 0 AND TIME.COUNT > MAX.TIME THEN _
  491.         GO TO 2440 ELSE TIME.COUNT = TIME.COUNT + 1.0
  492. REM IF ENABLED, TEST FOR CARRIER STILL PRESENT
  493.     IF (CERR.LIN% > 0) AND _
  494.         ((INP(CARRIER.PORT%) XOR CARRIER.POL%) AND _
  495.         CARRIER.MASK%) = 0 THEN GO TO 2445
  496. REM SEE IF TRANSMITTER READY FOR NEW CHARACTER ELSE LOOP
  497.     IF ((INP(CTRL.PORT%) XOR TRDY.POL%) AND TRDY.MASK%) = 0 _
  498.         THEN GO TO 2425
  499. REM
  500. REM SEND CHARACTER
  501.     OUT DATA.PORT%,CHAR.OUT%
  502. REM
  503. REM SKIP ECHO IF T COMMAND
  504.     IF COMMAND$ = "T" THEN GO TO 2500
  505. REM WAIT FOR ECHO IN RECEIVER
  506. REM TIME.COUNT IS NOT REINITIALIZED UNTIL ECHO IS RECEIVED
  507. 2430    REM
  508. REM IF ENABLED, TEST FOR TIME OUT
  509.     IF TERR.LIN% > 0 AND TIME.COUNT > MAX.TIME THEN _
  510.         GO TO 2440 ELSE TIME.COUNT = TIME.COUNT + 1.0
  511. REM IF ENABLED, TEST FOR CARRIER PRESENT
  512.     IF (CERR.LIN% > 0) AND _
  513.         ((INP(CARRIER.PORT%) XOR CARRIER.POL%) AND _
  514.         CARRIER.MASK%) = 0 THEN GO TO 2445
  515. REM SEE IF ECHOED CHARACTER HAS BEEN RECEIVED, ELSE LOOP
  516.     IF ((INP(CTRL.PORT%) XOR RRDY.POL%) AND RRDY.MASK%) = 0 _
  517.         THEN GO TO 2430
  518. REM
  519. REM GET ECHO AND STRIP PARITY BIT
  520.     ECHO% = INP(DATA.PORT%) AND 127
  521. REM
  522. REM TEST ECHO IF ON ERROR TESTING IS ENABLED
  523.     IF SERR.LIN% = 0 OR ECHO% = CHAR.OUT% THEN GO TO 2500
  524.     IF SERR.LIN% = -1 THEN GO TO 2450
  525.     INST.LIN% = SERR.LIN% - 1
  526.     IF DISPLAY% THEN PRINT "<<<-Send echo error"
  527.     IF LOG.FLAG% > 0 THEN PRINT #2, _
  528.         "<<<-Send echo error"
  529.     GO TO 2510
  530. REM
  531. 2440    REM
  532. REM TIME OUT DURING SEND PROCEDURE
  533.     INST.LIN% = TERR.LIN% - 1
  534.     IF DISPLAY% THEN PRINT "<<<-Send time out"
  535.     IF LOG.FLAG% > 0 THEN PRINT #2, "<<<-Send time out"
  536.     GO TO 2510
  537. REM
  538. 2445    REM
  539. REM CARRIER LOST WHILE ATTEMPTING TO SEND A CHARACTER
  540.     INST.LIN% = CERR.LIN% - 1
  541. REM RESET I/O ERROR SO WON'T GIVE FALSE ALARM ON NEXT CHARACTER
  542.     IF RES.PORT% >= 0 THEN OUT RES.PORT%,RERR.RES%
  543. REM CLEAR THE RECEIVER BUFFER
  544.     GARBAGE% = INP(DATA.PORT%)
  545.     IF DISPLAY% THEN PRINT "<<<-Carrier lost"
  546.     IF LOG.FLAG% > 0 THEN PRINT #2, "<<<-Carrier lost"
  547.     GO TO 2510
  548. REM
  549. 2450    REM
  550. REM
  551. REM AUTOMATIC RE-TRY OPTION (E INSTRUCTION E,SE,-1)
  552. REM WAIT FOR READY SIGNAL FROM CONTROL PORT
  553. 2455    REM
  554. REM IF ENABLED, TEST FOR TIME OUT
  555.     IF TERR.LIN% > 0 AND TIME.COUNT > MAX.TIME THEN _
  556.         GO TO 2440 ELSE TIME.COUNT = TIME.COUNT + 1.0
  557. REM IF ENABLED, TEST FOR CARRIER STILL PRESENT
  558.     IF (CERR.LIN% > 0) AND _
  559.         ((INP(CARRIER.PORT%) XOR CARRIER.POL%) AND _
  560.         CARRIER.MASK%) = 0 THEN GO TO 2445
  561. REM SEE IF TRANSMITTER READY FOR NEW CHARACTER ELSE LOOP
  562.     IF ((INP(CTRL.PORT%) XOR TRDY.POL%) AND TRDY.MASK%) = 0 _
  563.         THEN GO TO 2455
  564. REM
  565. REM SEND BACKSPACE CHARACTER
  566.     OUT DATA.PORT%,8
  567. REM
  568. REM GET BACKSPACE ECHO
  569. REM WAIT FOR ECHO IN RECEIVER
  570. 2460    REM
  571. REM IF ENABLED, TEST FOR TIME OUT
  572.     IF TERR.LIN% > 0 AND TIME.COUNT > MAX.TIME THEN _
  573.         GO TO 2440 ELSE TIME.COUNT = TIME.COUNT + 1.0
  574. REM IF ENABLED, TEST FOR CARRIER STILL PRESENT
  575.     IF (CERR.LIN% > 0) AND _
  576.         ((INP(CARRIER.PORT%) XOR CARRIER.POL%) AND _
  577.         CARRIER.MASK%) = 0 THEN GO TO 2445
  578. REM GET I/O STATUS BYTE AND LOOP UNTIL CHARACTER READY
  579.     IF ((INP(CTRL.PORT%) XOR RRDY.POL%) AND RRDY.MASK%) = 0 _
  580.         THEN GO TO 2460
  581. REM
  582. REM GET ECHOED BACKSPACE
  583.     GARBAGE% = INP(DATA.PORT%)
  584. REM GO BACK AND TRY TO SEND CHARACTER AGAIN
  585.     GO TO 2425
  586. REM
  587. 2500    REM
  588. REM
  589.     NEXT CHAR.NO%
  590. 2510    REM
  591. REM
  592. REM SET CHAR.NO% TO 0. USED AS FLAG BY "I" COMMAND.
  593.     CHAR.NO% = 0
  594.     GO TO 1000
  595. REM
  596. 3000    REM
  597. REM RECEIVE A STRING. HALT RECEPTION WHEN A TERMINATION
  598. REM STRING IS FOUND.
  599. REM
  600. REM GET TERMINATION STRING
  601.     TERM.STRING$ = ARG1$(INST.LIN%)
  602. REM GET LENGTH OF TERMINATION STRING MINUS 1.
  603.     NO.TERM.M1% = LEN(TERM.STRING$) - 1
  604. REM INITIALIZE THE TEST STRING AND BUFFER COUNTER
  605.     TEST.STRING$ = ""
  606.     CHAR.NO% = 0
  607.     WRAPPED% = FALSE%
  608. REM
  609. 3010    REM
  610. REM WAIT FOR CHARACTER READY SIGNAL FROM CONTROL PORT
  611.     TIME.COUNT = 0.0
  612. 3020    REM
  613. REM IF ENABLED, TEST FOR TIME OUT
  614.     IF TERR.LIN% > 0 AND TIME.COUNT > MAX.TIME THEN _
  615.         GO TO 3070 ELSE TIME.COUNT = TIME.COUNT + 1.0
  616. REM IF ENABLED, TEST FOR CARRIER STILL PRESENT
  617.     IF (CERR.LIN% > 0) AND _
  618.         ((INP(CARRIER.PORT%) XOR CARRIER.POL%) AND _
  619.         CARRIER.MASK%) = 0 THEN GO TO 3060
  620. REM GET I/O STATUS BYTE AND LOOP UNTIL CHARACTER READY
  621.     IF ((INP(CTRL.PORT%) XOR RRDY.POL%) AND RRDY.MASK%) = 0 _
  622.         THEN GO TO 3020
  623. REM
  624. REM GET CHARACTER FROM DATA PORT AND STRIP OFF PARITY BIT
  625.     CHAR% = INP(DATA.PORT%) AND 127
  626. REM ADD THE CHARACTER TO THE BUFFER
  627.     CHAR.NO% = CHAR.NO% + 1
  628. REM SEE IF BUFFER IS FULL
  629.     IF CHAR.NO% <= 2000 THEN GO TO 3050
  630. REM WRAP THE BUFFER POINTER BACK TO BEGINNING AND SET FLAG
  631.     CHAR.NO% = 1
  632.     WRAPPED% = TRUE%
  633. 3050    REM
  634.     BUFFER%(CHAR.NO%) = CHAR%
  635. REM
  636. REM IF ENABLED, CHECK FOR DATA (PARITY, ETC.) ERROR
  637.     IF (RERR.LIN% <= 0) OR ((INP(RERR.PORT%) XOR RERR.POL%) AND _
  638.         RERR.MASK%) = 0    THEN GO TO 3080
  639. REM ERROR FOUND
  640.     INST.LIN% = RERR.LIN% - 1
  641. REM RESET I/O ERROR SO WONT GIVE FALSE ALARM ON NEXT CHARACTER
  642.     IF RES.PORT% >= 0 THEN OUT RES.PORT%,RERR.RES%
  643. REM PRINT ALERT MESSAGE
  644.     IF DISPLAY% THEN PRINT "Receive data error->>>"
  645.     IF LOG.FLAG% >= 1 THEN PRINT #2, _
  646.         "Receive data error->>>"
  647. REM SKIP THE TERMINATION STRING TEST, BUT LOG AND PRINT THE
  648. REM DATA RECEIVED SO FAR
  649.     GO TO 3090
  650. REM
  651. 3060    REM
  652. REM CARRIER LOST WHILE TRYING TO RECEIVE
  653.     INST.LIN% = CERR.LIN% - 1
  654. REM RESET I/O ERROR SO WON'T GIVE FALSE ALARM ON NEXT CHARACTER
  655.     IF RES.PORT% >= 0 THEN OUT RES.PORT%,RERR.RES%
  656. REM CLEAR THE RECEIVER BUFFER
  657.     GARBAGE% = INP(DATA.PORT%)
  658.     IF DISPLAY% THEN PRINT "Carrier lost->>>"
  659.     IF LOG.FLAG% >= 1 THEN PRINT #2, _
  660.         "Carrier lost->>>"
  661.     GO TO 3090
  662. REM
  663. 3070    REM
  664. REM TIME OUT ERROR EXIT FOR RECEIVE
  665.     INST.LIN% = TERR.LIN% - 1
  666.     IF DISPLAY% THEN PRINT "Receive time out->>>";
  667.     IF LOG.FLAG% >= 1 THEN PRINT #2, _
  668.         "Receive time out->>>";
  669.     GO TO 3090
  670. REM
  671. 3080    REM
  672. REM DELETE THE LEFT MOST CHARACTER FROM TEST STRING AND ADD
  673. REM THE NEW CHARACTER TO THE RIGHT END
  674.     TEST.STRING$ = RIGHT$(TEST.STRING$,NO.TERM.M1%) + CHR$(CHAR%)
  675. REM
  676. REM SEE IF TEST STRING IS TERMINATION STRING
  677. REM ELSE GO BACK FOR NEXT CHARACTER
  678.     IF TEST.STRING$ <> TERM.STRING$ THEN GO TO 3010
  679. REM
  680. REM TERMINATION STRING FOUND. IF LOGGING IS ON, SAVE TO DISK
  681. 3090    REM
  682.     IF NOT WRAPPED% THEN GO TO 3200
  683.     FOR I% = CHAR.NO% + 1 TO 2000
  684.     PRNT.CHAR$ = CHR$(BUFFER%(I%))
  685.     IF DISPLAY% THEN PRINT PRNT.CHAR$;
  686.     IF LOG.FLAG% >= 1 THEN PRINT #2, PRNT.CHAR$;
  687.     NEXT I%
  688. 3200    REM
  689.     FOR I% = 1 TO CHAR.NO%
  690.     PRNT.CHAR$ = CHR$(BUFFER%(I%))
  691.     IF DISPLAY% THEN PRINT PRNT.CHAR$;
  692.     IF LOG.FLAG% >= 1 THEN PRINT #2, PRNT.CHAR$;
  693.     NEXT I%
  694. REM
  695.     GO TO 1000
  696. REM
  697. 4000    REM
  698. REM EXECUTE AN IF MATCH THEN BRANCH INSTRUCTION.
  699. REM RIGHT- MOST CHARACTER OF TEST STRING IS ALIGNED WITH THE
  700. REM MOST RECENTLY RECEIVED CHARACTER (INCLUDING THE TERMINATION
  701. REM CHARACTER(S)) IN THE R COMMAND.
  702. REM VARIABLE CHAR.NO% WILL BE > 0 ONLY IF PRECEEDING INSTRUCTION
  703. REM WAS A RECEIVE. THE I INSTRUCTION CAN ONLY BE EXECUTED IF
  704. REM CHARACTERS HAVE BEEN RECEIVED.
  705.     IF CHAR.NO% <= 0 THEN GO TO 1000
  706. REM GET THE STRING WE ARE LOOKING FOR
  707.     TEST.STRING$ = ARG1$(INST.LIN%)
  708.     NO.TEST% = LEN(TEST.STRING$)
  709. REM SEE IF BUFFER HAS AT LEAST AS MANY CHARACTERS AS STRING
  710.     IF NO.TEST% > CHAR.NO% AND NOT WRAPPED% THEN GO TO 1000
  711. REM VARIABLE TEST.CHAR.NO% POINTS TO A CHARACTER IN TEST STRING
  712.     TEST.CHAR.NO% = NO.TEST% + 1
  713. REM COMPARE THE CHARACTERS, FROM RIGHT TO LEFT
  714.     FOR I% = CHAR.NO% TO 1 STEP -1
  715.     TEST.CHAR.NO% = TEST.CHAR.NO%  - 1
  716. REM IF NO MORE CHARACTERS TO COMPARE IN STRING, THEN IT MATCHED
  717.     IF TEST.CHAR.NO% = 0 THEN GO TO 4100
  718.     TEST.CHAR% = ASC(MID$(TEST.STRING$,TEST.CHAR.NO%,1))
  719. REM END TEST AT FIRST MISMATCH
  720.     IF BUFFER%(I%) <> TEST.CHAR% THEN _
  721.         GO TO 1000
  722.     NEXT I%
  723. REM
  724. REM IN CASE BUFFER WAS WRAPPED, THEN CONTINUE COMPARING CHARS
  725.     IF NOT WRAPPED% THEN GO TO 4100
  726. REM IF WRAPPED, THEN CONTINUE FROM END OF BUFFER%
  727.     FOR I% = 2000 TO CHAR.NO% + 1 STEP -1
  728.     TEST.CHAR.NO% = TEST.CHAR.NO% - 1
  729.     IF TEST.CHAR.NO% = 0 THEN GO TO 4100
  730.     TEST.CHAR% = ASC(MID$(TEST.STRING$,TEST.CHAR.NO%,1))
  731.     IF BUFFER%(I%) <> TEST.CHAR% THEN _
  732.         GO TO 1000
  733.     NEXT I%
  734. 4100    REM
  735. REM IF WE HAVE GOTTEN THIS FAR (I.E. WE HAVE NOT BEEN SENT
  736. REM BACK TO LINE 1000) THEN WE DEFINITELY HAVE A MATCH.    
  737.     INST.LIN% = ARG2%(INST.LIN%) - 1
  738.     GO TO 1000
  739. REM
  740. 4400    REM
  741. REM EXECUTE A JUMP (GO TO) INSTRUCTION
  742.     INST.LIN% = ARG2%(INST.LIN%) - 1
  743.     GO TO 1000
  744. REM
  745. 4500    REM
  746. REM EXECUTE AN ON ERROR GO TO INSTRUCTION
  747.     ARGUMENT1$ = ARG1$(INST.LIN%)
  748.     IF ARGUMENT1$ = "RE" THEN _
  749.         RERR.LIN% = ARG2%(INST.LIN%)
  750.     IF ARGUMENT1$ = "SE" THEN _
  751.         SERR.LIN% = ARG2%(INST.LIN%)
  752.     IF ARGUMENT1$ = "TO" THEN _
  753.         TERR.LIN% = ARG2%(INST.LIN%)
  754.     IF ARGUMENT1$ = "CL" THEN _
  755.         CERR.LIN% = ARG2%(INST.LIN%)
  756.     GO TO 1000
  757. REM
  758. 5000    REM
  759. REM CHANGE THE LOG FLAG
  760.     LOG.FLAG% = ARG2%(INST.LIN%)
  761.     GO TO 1000
  762. REM
  763. 5100    REM
  764. REM CHANGE THE DISPLAY (PRINT TO TERMINAL) FLAG
  765.     DISPLAY% = ARG2%(INST.LIN%)
  766.     GO TO 1000
  767. REM
  768. 6000    REM
  769. REM
  770. REM
  771. REM ERROR MESSAGES
  772. 9000    REM
  773.     PRINT "Error: end of file at line #";NO.INSTR%; _
  774.         ", command = ";FIRST.CHAR$
  775.     GO TO 9500
  776. 9005    REM
  777.     PRINT "Error: L instruction without log file name"; _
  778.         " in CP/M command"
  779.     GO TO 9500
  780. 9010    REM
  781.     PRINT "Error: illegal instruction:";FIRST.CHAR$; _
  782.         ", at line #";NO.INSTR%
  783.     GO TO 9500
  784. 9015    REM
  785.     PRINT "Error: illegal label for line #";NO.INSTR%
  786.     GO TO 9500
  787. 9020    REM
  788.     PRINT "Error: duplicate label ";LABEL.VALUE%; _
  789.         " at line #";NO.INSTR%
  790.     GO TO 9500
  791. 9025    REM
  792.     PRINT "Error: illegal parameter for ";FIRST.CHAR$; _
  793.         " command at line #";NO.INSTR%
  794.     GO TO 9500
  795. 9030    REM
  796.     PRINT "Error: illegal label argument in ";FIRST.CHAR$; _
  797.         " command at line #";NO.INSTR%
  798.     GO TO 9500
  799. 9035    REM
  800.     PRINT "Error: undefined label in line #";I%
  801.     GO TO 9500
  802. 9040    REM
  803.     PRINT "Error: no instructions found."
  804.     GO TO 9500
  805. 9050    REM
  806.     PRINT "Error: too many characters in Send string at line #";_
  807.         INST.LIN%
  808. 9500    REM
  809.     PRINT "Instruction file ";INST.FILE$
  810. 9550    REM
  811.     CLOSE
  812.     END
  813. REM
  814. 9600    REM
  815.     PRINT "To run DIALOG, type"
  816.     PRINT "   DIALOG INSTFILE.DLG LOGFILE.LOG"
  817.     PRINT "where INSTFILE.DLG contains the instructions"; _
  818.         " (the input to DIALOG),"
  819.     PRINT "and LOGFILE.LOG (optional) will receive the log"; _
  820.         " (the output from DIALOG)."
  821.     PRINT "To check for syntax errors only, type"
  822.     PRINT "   DIALOG INSTFILE.DLG ?
  823.     END
  824. REM
  825. 10000    REM
  826. REM THIS SUBROUTINE CONVERTS ANY CHARACTERS PRECEEDED BY THE
  827. REM CONTROL CHARACTER PREFACE TO CONTROL CHARACTERS
  828.     NO.CHARACTERS% = LEN(IN.STRING$)
  829.     OUT.STRING$ = ""
  830.     PREFACE% = FALSE%
  831. REM
  832.     FOR CHAR.NO% = 1 TO NO.CHARACTERS%
  833.     CHAR% = ASC(MID$(IN.STRING$,CHAR.NO%,1))
  834. REM BRANCH IF PREVIOUS CHARACTER WAS THE CONTROL PREFACE
  835.     IF PREFACE% THEN GO TO 10050
  836. REM CHECK EACH CHARACTER FOR THE CONTROL PREFACE
  837.     IF CHAR% <> CC.PREF% THEN GO TO 10100
  838.     PREFACE% = TRUE%
  839.     GO TO 10200
  840. 10050    REM
  841. REM MAKE CHARACTER INTO CORRESPONDING CONTROL CHARACTER
  842.     CHAR% = CHAR% - 64
  843.     PREFACE% = FALSE%
  844. 10100    REM
  845. REM COPY THE CHARACTER INTO THE OUTPUT BUFFER
  846.     OUT.STRING$ = OUT.STRING$ + CHR$(CHAR%)
  847. 10200    REM
  848.     NEXT CHAR.NO%
  849.     RETURN
  850. REM
  851.