home *** CD-ROM | disk | FTP | other *** search
- REM PROGRAM DIALOG
- REM A PROGRAM TO AUTOMATICALLY LOG IN AND EXTRACT DATA FROM
- REM A DATABASE SYSTEM
- REM
- REM WRITTEN BY E. VERNON BUCK, SAN LORENZO, CA. (415) 276-4607
- REM VERSION 1.1, DEC. 31, 1985.
- REM
- REM DIALOG READS "INSTRUCTIONS" FROM AN "INSTRUCTION FILE". THIS FILE
- REM IS PRODUCED BY ANY EDITOR OR WORD PROCESSOR. THE INSTRUCTION
- REM FILE TELLS THE PROGRAM HOW TO CONDUCT A "DIALOG" WITH THE
- REM REMOTE (OR "HOST") COMPUTER. THE INSTRUCTIONS TELL THE PROGRAM
- REM WHAT MESSAGES TO SEND, AND WHAT MESSAGES TO RECEIVE FROM THE
- REM HOST. THE PROGRAM CAN ALSO MAKE SOME
- REM SIMPLE DECISIONS (BRANCHING) BASED ON THE CONTENT OF MESSAGES
- REM RECEIVED FROM THE HOST. THE DIALOG IS DISPLAYED ON THE
- REM TERMINAL AS IT HAPPENS, AND (OPTIONALLY) RECORDED
- REM IN A "LOG" FILE.
- REM
- REM THE INSTRUCTIONS AVAILABLE ARE AS FOLLOWS:
- REM S,ccc...c SEND THE STRING ccc...c TO THE HOST.
- REM THE SEND COMMAND EXPECTS THE
- REM CHARACTERS TO BE ECHOED BY THE HOST.
- REM
- REM T,ccc...c TRANSMIT THE STRING ccc...c TO THE
- REM HOST. IDENTICAL TO THE S COMMAND,
- REM EXCEPT DOES NOT EXPECT AN ECHO.
- REM
- REM R,ttt...t RECEIVE A STRING OF CHARACTERS FROM
- REM THE HOST UNTIL THE "TERMINATION" STRING
- REM ttt...t IS RECEIVED. ANY NUMBER OF
- REM CHARACTERS CAN BE RECEIVED BEFORE THE
- REM TERMINATION STRING IS ENCOUNTERED, BUT
- REM ONLY THE LAST 2000 (ABOUT 1 SCREENFULL)
- REM WILL BE RETAINED.
- REM
- REM I,ddd...d,n IF THE LAST RECEIVED CHARACTERS
- REM (INCLUDING THE TERMINATION CHARACTERS
- REM FROM THE R INSTRUCTION) WERE ddd...d,
- REM THEN JUMP TO THE INSTRUCTION LINE
- REM LABELED n. n IS A NUMBER FROM
- REM 1 TO 9999.
- REM
- REM G,n GO TO (JUMP UNCONDITIONALLY) TO THE
- REM INSTRUCTION LINE LABELED n.
- REM
- REM E,i,n IF AN ERROR CONDITION OF TYPE i IS
- REM DETECTED, THEN GO TO THE
- REM INSTRUCTION LINE LABELED n.
- REM i CAN BE:
- REM "SE" - SEND INSTRUCTION ECHO ERROR
- REM "RE" - RECEIVE INSTRUCTION
- REM PARITY, FRAME OR OVERRUN ERROR
- REM "TO" - TIME OUT
- REM "CL" - CARRIER LOST.
- REM n = 0 MEANS IGNORE THE ERROR, AND
- REM CONTINUE. THIS IS THE DEFAULT.
- REM n = -1 ("SE" ONLY) MEANS SEND A
- REM BACKSPACE AND REPEAT THE ERRONEOUS
- REM CHARACTER
- REM
- REM L,lll CONTROL THE AMOUNT OF INFORMATION TO
- REM BE SAVED IN THE LOG FILE:
- REM lll=ON -- SAVE RECEIVED DATA ONLY
- REM lll=OFF-- SAVE NOTHING
- REM lll=ALL-- SAVE BOTH TRANSMITTED AND
- REM RECEIVED DATA (DEFAULT)
- REM
- REM D,ddd CONTROLS WHETHER THE DIALOG WILL BE
- REM DISPLAYED ON THE TERMINAL AS IT
- REM HAPPENS:
- REM ddd=OFF -- NOT DISPLAYED ON TERMINAL
- REM ddd=ON -- DISPLAYED ON TERMINAL
- REM (DEFAULT)
- REM
- REM C,p MAKE p THE CONTROL CHARACTER PREFACE
- REM FOR THE INSTRUCTION LINES THAT FOLLOW.
- REM I.E., ^M WOULD BE TRANSMITTED AS A
- REM CTRL-M WHEN p="^". DEFAULT IS "^".
- REM THE C INSTRUCTION IS NON-EXECUTABLE.
- REM THAT IS, IT OPERATES ON THE INSTRUC-
- REM TIONS AS THEY ARE COMPILED, BUT NOT
- REM AS EXECUTED (SINCE INSTRUCTIONS
- REM MIGHT BE EXECUTED IN A DIFFERENT
- REM ORDER).
- REM
- REM X EXIT. CLOSE FILES AND RETURN TO CP/M.
- REM
- REM INSTRUCTIONS CAN BE PRECEEDED BY A "LABEL NUMBER". THIS IS LIKE A
- REM LINE NUMBER IN BASIC OR FORTRAN. IT IS OPTIONAL. BUT OF COURSE, IF
- REM THERE IS AN I, G OR E INSTRUCTION ANYWHERE IN THE INSTRUCTIONS,
- REM THEN THERE MUST BE A LABELED INSTRUCTION WHICH MATCHES THE
- REM LABELS GIVEN IN THE I, G OR E INSTRUCTION. EXAMPLE:
- REM 100,S,hello^M
- REM ...
- REM G,100
- REM
- REM NOTES: (1) ALL INSTRUCTION PARAMETERS MUST BE SEPARATED BY COMMAS.
- REM (2) IF A COMMA IS NEEDED IN A CHARACTER STRING, THEN
- REM SURROUND THE STRING WITH QUOTES ("...").
- REM (3) LEADING BLANKS ARE IGNORED, UNLESS THE STRING IS QUOTED.
- REM (4) DO NOT USE TAB CHARACTERS (CTRL-I) TO INDENT.
- REM USE SPACES.
- REM
- REM TO INVOKE THE PROGRAM, TYPE
- REM DIALOG insfile.dlg logfile.log
- REM WHERE insfile.dlg IS THE FILE CONTAINING THE INSTRUCTIONS, AND
- REM logfile.log IS THE LOG FILE (TO BE WRITTEN BY DIALOG). THE LOG
- REM FILE IS OPTIONAL AND CAN SIMPLY BE OMITTED. THERE ARE NO DEFAULT
- REM FILE NAMES OR EXTENSIONS. REPLACING logfile.log WITH A QUESTION
- REM MARK WILL CAUSE THE INSTRUCTION FILE TO BE COMPILED, BUT NOT
- REM EXECUTED, FOR TESTING PURPOSES.
- REM
- REM THE INSTRUCTIONS ARE STORED IN VARIABLES
- REM COMM$ : THE COMMAND
- REM ARG1$ : THE FIRST ARGUMENT (A STRING)
- REM ARG2% : THE SECOND ARGUMENT (A NUMBER)
- REM
- REM PATCH AREA CONSTANTS:
- REM DATA.PORT% = I/O DATA PORT FOR MODEM
- REM CTRL.PORT% = I/O PORT TO READ TO TEST FOR TRANSMIT/RECEIVE
- REM READY
- REM TRDY.MASK% = THE BIT TO TEST FOR TRANSMIT READY (IS SET TO 1)
- REM TRDY.POL% = SET THE SAME BIT AS TRDY.MASK% TO 1 TO REVERSE THE
- REM POLARITY OF THE TEST (I.E. READY WHEN BIT = 0)
- REM RRDY.MASK%, RRDY.POL% = SAME FOR RECEIVE READY
- REM RERR.PORT% = I/O PORT TO READ TO TEST FOR READ ERRORS
- REM RERR.MASK%, RERR.POL% = BITS TO TEST FOR READ ERRORS (I.E.
- REM PARITY, FRAME AND/OR OVERRUN), AND POLARITY OF SAME
- REM RES.PORT% = I/O PORT TO RECEIVE THE FOLLOWING RESET BYTE. (SET TO
- REM -1 IF NO RESET BYTE IS REQUIRED)
- REM RERR.RES% = BYTE TO SEND TO RESET PORT TO RESET UART AFTER
- REM RECEIPT OF PARITY, FRAME OR OVERRUN ERROR
- REM CARRIER.PORT% = I/O PORT TO READ TO TEST FOR CARRIER PRESENT
- REM CARRIER.MASK% = THE BIT(S) TO TEST FOR CARRIER PRESENT (E.G. DSR)
- REM CARRIER.POL% = POLARITY OF CARRIER BIT(S)
- REM CC.PREF$ = THE CHARACTER THAT PRECEEDS A CHARACTER TO INDICATE
- REM THAT THE 2ND CHARACTER IS A CONTROL CHARACTER.
- REM (I.E. ^M = CTRL-M, WHEN CC.PREF$ = "^")
- REM MAX.TIME = APPROX. TIME OUT TIME. FOR 4MHZ CPU, 1100 ~= 1 SECOND
- REM
- REM HOW TO PATCH THE .COM FILE:
- REM USING DDT.COM, OR SOME OTHER PATCHING PROGRAM, FIND THE FOLLOWING
- REM DATA STATEMENTS. THEY ARE PREFACED BY THE WORD "PATCH:". CHANGE
- REM THE NUMBERS FOLLOWING PATCH: TO SUIT YOUR SYSTEM. THEY ARE IN
- REM DECIMAL AND ASCII, AS FOLLOWS:
- REM (1) THE UART DATA I/O PORT NUMBER
- REM (2) THE UART TRANSMIT/RECEIVE READY I/O PORT NUMBER
- REM (3) THE BIT TO TEST FOR TRANSMIT READY
- REM (4) THE BIT TO BE EXCLUSIVE OR'ED BEFORE TESTING FOR TRANSMIT
- REM (5) THE BIT TO TEST FOR RECEIVE READY
- REM (6) THE BIT TO BE EXCLUSIVE OR'ED BEFORE TESTING FOR RECIEVE
- REM (7) THE I/O PORT TO READ FOR RECEIVE ERRORS
- REM (8) THE BIT(S) TO TEST FOR RECEIVE ERRORS (PARITY, FRAME
- REM AND/OR OVERRUN, ETC.)
- REM (9) THE BIT(S) TO BE EXCLUSIVE OR'ED WITH THE ERROR BITS
- REM BEFORE TESTING
- REM (10) THE I/O PORT TO SEND A RESET BYTE TO (-01 IF NONE)
- REM (11) BYTE TO SEND TO THE RESET PORT TO RESET UART FOLLOWING
- REM RECEPTION OF A TRANSMISSION ERROR
- REM (12) THE I/O PORT TO READ FOR CARRIER PRESENT TEST
- REM (13) THE BIT(S) TO TEST FOR CARRIER ON (I.E., THE DSR LINE)
- REM (14) THE BIT(S) TO BE EXCLUSIVE OR'ED WITH THE CARRIER ON BIT
- REM BEFORE TESTING
- REM (15) THE DEFAULT CHARACTER TO BE A PREFACE FOR CONTROL
- REM CHARACTERS
- REM (16) THE TIME OUT COUNTER MAXIMUM
- REM
- DATA "PATCH:",000,001,001,000,002,000,001,008,000
- DATA 001,055,001,128,000
- DATA "^",066000
- REM
- DIM COMM$(200),ARG1$(200),ARG2%(200),LABEL%(200)
- DIM BUFFER%(2000)
- REM
- REM SET THE I/O PORT PARAMETERS
- READ GARBAGE$,DATA.PORT%,CTRL.PORT%,TRDY.MASK%,_
- TRDY.POL%,RRDY.MASK%,RRDY.POL%
- READ RERR.PORT%,RERR.MASK%,RERR.POL%,RES.PORT%,RERR.RES%,_
- CARRIER.PORT%,CARRIER.MASK%,CARRIER.POL%
- REM
- REM SET THE CONTROL CHARACTER PREFACE
- READ CC.PREF$
- REM SET THE TIME OUT COUNTER MAXIMUM
- READ MAX.TIME
- REM
- TRUE% = (0 = 0)
- FALSE% = (1 = 0)
- CC.PREF% = ASC(CC.PREF$)
- REM
- REM GET THE FILE NAMES FROM CP/M COMMAND
- REM
- INST.FILE$ = ""
- FOR ADDRESS% = 93 TO 100
- INST.FILE$ = INST.FILE$ + CHR$(PEEK(ADDRESS%))
- NEXT ADDRESS%
- IF INST.FILE$ = " " THEN GO TO 9600
- INST.FILE$ = INST.FILE$ + "."
- DRIVE% = PEEK(92)
- IF DRIVE% > 0 THEN _
- INST.FILE$ = CHR$(DRIVE% + 64) + ":" + INST.FILE$
- FOR ADDRESS% = 101 TO 103
- INST.FILE$ = INST.FILE$ + CHR$(PEEK(ADDRESS%))
- NEXT ADDRESS%
- REM
- LOG.FILE$ = ""
- FOR ADDRESS% = 109 TO 116
- LOG.FILE$ = LOG.FILE$ + CHR$(PEEK(ADDRESS%))
- NEXT ADDRESS%
- NO.LOG.FILE% = (LOG.FILE$ = " " )
- COMPILE.ONLY% = (LOG.FILE$ = "? " )
- IF NO.LOG.FILE% THEN GO TO 100
- LOG.FILE$ = LOG.FILE$ + "."
- DRIVE% = PEEK(108)
- IF DRIVE% > 0 THEN _
- LOG.FILE$ = CHR$(DRIVE% + 64) + ":" + LOG.FILE$
- FOR ADDRESS% = 117 TO 119
- LOG.FILE$ = LOG.FILE$ + CHR$(PEEK(ADDRESS%))
- NEXT ADDRESS%
- REM
- 100 REM
- REM OPEN THE INSTRUCTION FILE
- OPEN "I",#1,INST.FILE$
- REM
- REM
- REM READ THE INSTRUCTIONS INTO MEMORY AND CHECK FOR OBVIOUS
- REM ERRORS
- FOR NO.INSTR% = 1 TO 200
- REM SET TRAP FOR SYNTAX ERROR & INITIALIZE LABEL% ARRAY
- LABEL.PRESENT% = FALSE%
- LABEL%(NO.INSTR%) = 0
- REM EXIT LOOP IF NO MORE COMMANDS
- IF EOF(1) THEN GO TO 500
- 200 REM
- INPUT #1, COMMAND$
- REM TAKE FIRST CHARACTER AND CONVERT TO UPPER CASE IF NECESSARY
- ASCII.VAL% = ASC(COMMAND$)
- IF ASCII.VAL% > 96 AND ASCII.VAL% <= 122 THEN _
- FIRST.CHAR$ = CHR$(ASCII.VAL% - 32) ELSE _
- FIRST.CHAR$ = CHR$(ASCII.VAL%)
- REM GO TO APPROPRIATE SECTION TO INTERPRET DIFFERENT INSTRUCTIONS
- IF FIRST.CHAR$ = "L" THEN GO TO 300
- IF FIRST.CHAR$ = "D" THEN GO TO 320
- IF FIRST.CHAR$ = "S" OR FIRST.CHAR$ = "R" _
- OR FIRST.CHAR$ = "T" THEN GO TO 350
- IF FIRST.CHAR$ = "I" THEN GO TO 400
- IF FIRST.CHAR$ = "E" THEN GO TO 430
- IF FIRST.CHAR$ = "G" THEN GO TO 440
- IF FIRST.CHAR$ = "C" THEN GO TO 450
- IF FIRST.CHAR$ = "X" THEN GO TO 490
- REM
- REM COMMAND$ IS NONE OF THE INTRINSIC COMMANDS. ASSUME IT IS
- REM A STATEMENT LABEL
- REM TEST FOR ILLEGAL COMMAND
- IF LABEL.PRESENT% OR ASCII.VAL% < 48 OR _
- ASCII.VAL% > 57 THEN GO TO 9010
- LABEL.VALUE% = VAL(COMMAND$)
- REM CHECK RANGE OF LABEL
- IF LABEL.VALUE% < 1 OR LABEL.VALUE% > 9999 THEN GO TO 9015
- REM CHECK FOR DUPLICATE LABEL ON A PREVIOUS INSTRUCTION
- IF NO.INSTR% = 1 THEN GO TO 280
- FOR LABEL.NO% = 1 TO NO.INSTR% - 1
- IF LABEL%(LABEL.NO%) = LABEL.VALUE% THEN GO TO 9020
- NEXT LABEL.NO%
- 280 REM
- REM SAVE THIS LABEL
- LABEL%(NO.INSTR%) = LABEL.VALUE%
- LABEL.PRESENT% = TRUE%
- GO TO 200
- REM
- 300 REM
- REM COMPILE A LOG INSTRUCTION
- REM READ THE ARGUMENT
- IF EOF(1) THEN GO TO 9000
- INPUT #1, ARGUMENT1$
- REM TEST FOR LEGALITY OF ARGUMENT
- IF ARGUMENT1$ <> "IN" AND ARGUMENT1$ <> "OFF" AND _
- ARGUMENT1$ <> "ALL" THEN GO TO 9025
- IF ARGUMENT1$ <> "OFF" AND NO.LOG.FILE% THEN GO TO 9005
- IF ARGUMENT1$ = "OFF" THEN ARG2%(NO.INSTR%) = 0
- IF ARGUMENT1$ = "IN" THEN ARG2%(NO.INSTR%) = 1
- IF ARGUMENT1$ = "ALL" THEN ARG2%(NO.INSTR%) = 2
- ARG1$(NO.INSTR%) = ARGUMENT1$
- GO TO 490
- REM
- 320 REM
- REM COMPILE D (DISPLAY ON/OFF) COMMAND
- IF EOF(1) THEN GO TO 9000
- INPUT #1, ARGUMENT1$
- IF ARGUMENT1$ <> "ON" AND ARGUMENT1$ <> "OFF" _
- THEN GO TO 9025
- ARG2%(NO.INSTR%) = ( ARGUMENT1$ = "ON" )
- ARG1$(NO.INSTR%) = ARGUMENT1$
- GO TO 490
- REM
- 350 REM
- REM COMPILE A SEND OR RECEIVE INSTRUCTION
- REM READ THE ARGUMENT
- IF EOF(1) THEN GO TO 9000
- INPUT #1, IN.STRING$
- REM TEST FOR LEGALITY
- IF LEN(IN.STRING$) < 1 THEN GO TO 9025
- REM CONVERT CONTROL CHARACTERS
- GO SUB 10000
- IF LEN(OUT.STRING$) > 2000 THEN GO TO 9025
- ARG1$(NO.INSTR%) = OUT.STRING$
- REM SAVE THE CONTROL CHARACTER PREFACE (NEEDED FOR LOGGING)
- ARG2%(NO.INSTR%) = CC.PREF%
- GO TO 490
- REM
- 400 REM
- REM COMPILE AN IF INSTRUCTION
- REM READ THE 1ST ARGUMENT
- IF EOF(1) THEN GO TO 9000
- INPUT #1, IN.STRING$
- REM TEST FOR LEGALITY
- IF LEN(IN.STRING$) < 1 THEN GO TO 9025
- REM CONVERT CONTROL CHARACTERS
- GO SUB 10000
- ARG1$(NO.INSTR%) = OUT.STRING$
- REM READ THE 2ND ARGUMENT
- IF EOF(1) THEN GO TO 9000
- INPUT #1, ARGUMENT2%
- REM TEST FOR REASONABLENESS
- IF ARGUMENT2% < 1 OR ARGUMENT2% > 9999 THEN GO TO 9030
- ARG2%(NO.INSTR%) = ARGUMENT2%
- GO TO 490
- REM
- 430 REM
- REM COMPILE AN ON ERROR JUMP
- IF EOF(1) THEN GO TO 9000
- INPUT #1, ARGUMENT1$
- IF ARGUMENT1$ <> "RE" AND ARGUMENT1$ <> "SE" _
- AND ARGUMENT1$ <> "TO" AND ARGUMENT1$ <> "CL" _
- THEN GO TO 9025
- ARG1$(NO.INSTR%) = ARGUMENT1$
- IF EOF(1) THEN GO TO 9000
- INPUT #1, ARGUMENT2%
- REM TEST FOR REASONABLENESS
- IF ARGUMENT2% < -1 OR ARGUMENT2% > 9999 THEN GO TO 9030
- ARG2%(NO.INSTR%) = ARGUMENT2%
- GO TO 490
- REM
- REM
- 440 REM
- REM COMPILE A JUMP (GOTO) INSTRUCTION
- IF EOF(1) THEN GO TO 9000
- INPUT #1, ARGUMENT2%
- REM TEST FOR REASONABLENESS
- IF ARGUMENT2% < 1 OR ARGUMENT2% > 9999 THEN GO TO 9030
- ARG2%(NO.INSTR%) = ARGUMENT2%
- GO TO 490
- REM
- 450 REM
- REM COMPILE A CHANGE CONTROL CHARACTER PREFACE
- IF EOF(1) THEN GO TO 9000
- INPUT #1, ARGUMENT1$
- IF LEN(ARGUMENT1$) <> 1 THEN GO TO 9025
- CC.PREF% = ASC(ARGUMENT1$)
- ARG1$(NO.INSTR%) = ARGUMENT1$
- ARG2%(NO.INSTR%) = CC.PREF%
- GO TO 490
- REM
- 490 REM
- REM STORE THE COMMAND
- COMM$(NO.INSTR%) = FIRST.CHAR$
- NEXT NO.INSTR%
- 500 REM
- NO.INSTR% = NO.INSTR% - 1
- REM
- CLOSE #1
- IF NO.INSTR% <= 0 THEN GO TO 9040
- REM
- REM REPLACE THE STATEMENT LABELS IN THE I, E, AND G COMMANDS WITH THE
- REM ACTUAL LINE NUMBERS REPRESENTED BY THE LABELS
- FOR I% = 1 TO NO.INSTR%
- COMMAND$ = COMM$(I%)
- IF COMMAND$ <> "I" AND COMMAND$ <> "G" _
- AND COMMAND$ <> "E" THEN GO TO 800
- TARGET.LABEL% = ARG2%(I%)
- REM IF TARGET IS <= 0, THEN IT'S NOT A LINE NUMBER, SO SKIP
- IF TARGET.LABEL% <= 0 THEN GO TO 800
- REM SEARCH THROUGH THE LIST OF LABELS
- FOR K% = 1 TO NO.INSTR%
- IF LABEL%(K%) = TARGET.LABEL% _
- THEN GO TO 750
- NEXT K%
- REM LABEL NOT FOUND IN LABEL LIST
- GO TO 9035
- 750 REM
- REM SET ARG2% TO THE LINE NUMBER OF THE LABELED INSTRUCTION
- ARG2%(I%) = K%
- 800 REM
- NEXT I%
- REM
- REM
- REM EXIT IF THIS WAS A COMPILE ONLY RUN
- IF NOT COMPILE.ONLY% THEN GO TO 900
- PRINT "No instruction errors detected in ";INST.FILE$
- END
- REM
- 900 REM
- REM EXECUTE THE INSTRUCTIONS
- REM
- REM
- REM OPEN THE LOG FILE
- IF NOT NO.LOG.FILE% THEN OPEN "O",#2,LOG.FILE$
- REM INITIALIZE INSTRUCTION COUNTER
- INST.LIN% = 0
- REM INITIALIZE LOGGING FLAG
- IF NO.LOG.FILE% THEN LOG.FLAG% = 0 ELSE LOG.FLAG% = 2
- REM INITIALIZE TERMINAL DISPLAY ON FLAG
- DISPLAY% = TRUE%
- REM INITIALIZE ON ERROR TARGET LINE NUMBER
- RERR.LIN% = 0
- SERR.LIN% = 0
- TERR.LIN% = 0
- CERR.LIN% = 0
- REM INITIALIZE BUFFER POINTER
- CHAR.NO% = 0
- REM
- REM
- REM TOP OF EXECUTION LOOP
- 1000 REM
- INST.LIN% = INST.LIN% + 1
- IF INST.LIN% > NO.INSTR% OR INST.LIN% < 1 _
- THEN GO TO 9550
- COMMAND$ = COMM$(INST.LIN%)
- IF COMMAND$ = "S" OR COMMAND$ = "T" THEN GO TO 2000
- IF COMMAND$ = "R" THEN GO TO 3000
- IF COMMAND$ = "I" THEN GO TO 4000
- IF COMMAND$ = "G" THEN GO TO 4400
- IF COMMAND$ = "E" THEN GO TO 4500
- IF COMMAND$ = "L" THEN GO TO 5000
- IF COMMAND$ = "D" THEN GO TO 5100
- IF COMMAND$ = "C" THEN GO TO 1000
- IF COMMAND$ = "X" THEN GO TO 9550
- REM
- REM
- 2000 REM
- REM EXECUTE THE SEND COMMAND
- REM
- REM GET THE STRING
- CHARS.OUT$ = ARG1$(INST.LIN%)
- REM GET THE NUMBER OF CHARACTERS TO SEND
- NO.OUT% = LEN(CHARS.OUT$)
- REM COPY THE CHARACTERS INTO THE OUTPUT BUFFER
- FOR CHAR.NO% = 1 TO NO.OUT%
- BUFFER%(CHAR.NO%) = ASC(MID$(CHARS.OUT$,CHAR.NO%,1))
- NEXT CHAR.NO%
- REM
- REM IF LOG.FLAG% IS 2, WRITE CHARACTERS TO LOG FILE.
- IF NOT DISPLAY% AND LOG.FLAG% < 2 THEN GO TO 2400
- REM MUST REINSERT THE CONTROL CHARACTER PREFACE.
- PRNT.PREF$ = CHR$(ARG2%(INST.LIN%))
- FOR CHAR.NO% = 1 TO NO.OUT%
- CHAR% = BUFFER%(CHAR.NO%)
- IF CHAR% < 32 THEN GO TO 2200
- PRNT.CHAR$ = CHR$(CHAR%)
- IF DISPLAY% THEN PRINT PRNT.CHAR$;
- IF LOG.FLAG% = 2 THEN PRINT #2, PRNT.CHAR$;
- GO TO 2300
- 2200 REM
- REM WRITE PRINTABLE CONTROL CHARACTER
- IF DISPLAY% THEN PRINT PRNT.PREF$;
- PRNT.CHAR$ = CHR$(CHAR% + 64)
- IF DISPLAY% THEN PRINT PRNT.CHAR$;
- IF LOG.FLAG% < 2 THEN GO TO 2300
- PRINT #2, PRNT.PREF$;
- PRINT #2, PRNT.CHAR$;
- 2300 REM
- NEXT CHAR.NO%
- REM
- REM WRITE <CR>,<LF> TO LOG FILE
- IF DISPLAY% THEN PRINT ""
- IF LOG.FLAG% = 2 THEN PRINT #2, ""
- 2400 REM
- REM
- REM CLEAR THE MODEM RECEIVER REGISTER
- IF COMMAND$ = "S" THEN GARBAGE% = INP(DATA.PORT%)
- REM
- REM NOW SEND THE CHARACTERS TO THE OUTPUT PORT
- FOR CHAR.NO% = 1 TO NO.OUT%
- CHAR.OUT% = BUFFER%(CHAR.NO%)
- 2420 REM
- REM
- REM WAIT FOR READY SIGNAL FROM CONTROL PORT
- TIME.COUNT = 0.0
- 2425 REM
- REM IF ENABLED, TEST FOR TIME OUT
- IF TERR.LIN% > 0 AND TIME.COUNT > MAX.TIME THEN _
- GO TO 2440 ELSE TIME.COUNT = TIME.COUNT + 1.0
- REM IF ENABLED, TEST FOR CARRIER STILL PRESENT
- IF (CERR.LIN% > 0) AND _
- ((INP(CARRIER.PORT%) XOR CARRIER.POL%) AND _
- CARRIER.MASK%) = 0 THEN GO TO 2445
- REM SEE IF TRANSMITTER READY FOR NEW CHARACTER ELSE LOOP
- IF ((INP(CTRL.PORT%) XOR TRDY.POL%) AND TRDY.MASK%) = 0 _
- THEN GO TO 2425
- REM
- REM SEND CHARACTER
- OUT DATA.PORT%,CHAR.OUT%
- REM
- REM SKIP ECHO IF T COMMAND
- IF COMMAND$ = "T" THEN GO TO 2500
- REM WAIT FOR ECHO IN RECEIVER
- REM TIME.COUNT IS NOT REINITIALIZED UNTIL ECHO IS RECEIVED
- 2430 REM
- REM IF ENABLED, TEST FOR TIME OUT
- IF TERR.LIN% > 0 AND TIME.COUNT > MAX.TIME THEN _
- GO TO 2440 ELSE TIME.COUNT = TIME.COUNT + 1.0
- REM IF ENABLED, TEST FOR CARRIER PRESENT
- IF (CERR.LIN% > 0) AND _
- ((INP(CARRIER.PORT%) XOR CARRIER.POL%) AND _
- CARRIER.MASK%) = 0 THEN GO TO 2445
- REM SEE IF ECHOED CHARACTER HAS BEEN RECEIVED, ELSE LOOP
- IF ((INP(CTRL.PORT%) XOR RRDY.POL%) AND RRDY.MASK%) = 0 _
- THEN GO TO 2430
- REM
- REM GET ECHO AND STRIP PARITY BIT
- ECHO% = INP(DATA.PORT%) AND 127
- REM
- REM TEST ECHO IF ON ERROR TESTING IS ENABLED
- IF SERR.LIN% = 0 OR ECHO% = CHAR.OUT% THEN GO TO 2500
- IF SERR.LIN% = -1 THEN GO TO 2450
- INST.LIN% = SERR.LIN% - 1
- IF DISPLAY% THEN PRINT "<<<-Send echo error"
- IF LOG.FLAG% > 0 THEN PRINT #2, _
- "<<<-Send echo error"
- GO TO 2510
- REM
- 2440 REM
- REM TIME OUT DURING SEND PROCEDURE
- INST.LIN% = TERR.LIN% - 1
- IF DISPLAY% THEN PRINT "<<<-Send time out"
- IF LOG.FLAG% > 0 THEN PRINT #2, "<<<-Send time out"
- GO TO 2510
- REM
- 2445 REM
- REM CARRIER LOST WHILE ATTEMPTING TO SEND A CHARACTER
- INST.LIN% = CERR.LIN% - 1
- REM RESET I/O ERROR SO WON'T GIVE FALSE ALARM ON NEXT CHARACTER
- IF RES.PORT% >= 0 THEN OUT RES.PORT%,RERR.RES%
- REM CLEAR THE RECEIVER BUFFER
- GARBAGE% = INP(DATA.PORT%)
- IF DISPLAY% THEN PRINT "<<<-Carrier lost"
- IF LOG.FLAG% > 0 THEN PRINT #2, "<<<-Carrier lost"
- GO TO 2510
- REM
- 2450 REM
- REM
- REM AUTOMATIC RE-TRY OPTION (E INSTRUCTION E,SE,-1)
- REM WAIT FOR READY SIGNAL FROM CONTROL PORT
- 2455 REM
- REM IF ENABLED, TEST FOR TIME OUT
- IF TERR.LIN% > 0 AND TIME.COUNT > MAX.TIME THEN _
- GO TO 2440 ELSE TIME.COUNT = TIME.COUNT + 1.0
- REM IF ENABLED, TEST FOR CARRIER STILL PRESENT
- IF (CERR.LIN% > 0) AND _
- ((INP(CARRIER.PORT%) XOR CARRIER.POL%) AND _
- CARRIER.MASK%) = 0 THEN GO TO 2445
- REM SEE IF TRANSMITTER READY FOR NEW CHARACTER ELSE LOOP
- IF ((INP(CTRL.PORT%) XOR TRDY.POL%) AND TRDY.MASK%) = 0 _
- THEN GO TO 2455
- REM
- REM SEND BACKSPACE CHARACTER
- OUT DATA.PORT%,8
- REM
- REM GET BACKSPACE ECHO
- REM WAIT FOR ECHO IN RECEIVER
- 2460 REM
- REM IF ENABLED, TEST FOR TIME OUT
- IF TERR.LIN% > 0 AND TIME.COUNT > MAX.TIME THEN _
- GO TO 2440 ELSE TIME.COUNT = TIME.COUNT + 1.0
- REM IF ENABLED, TEST FOR CARRIER STILL PRESENT
- IF (CERR.LIN% > 0) AND _
- ((INP(CARRIER.PORT%) XOR CARRIER.POL%) AND _
- CARRIER.MASK%) = 0 THEN GO TO 2445
- REM GET I/O STATUS BYTE AND LOOP UNTIL CHARACTER READY
- IF ((INP(CTRL.PORT%) XOR RRDY.POL%) AND RRDY.MASK%) = 0 _
- THEN GO TO 2460
- REM
- REM GET ECHOED BACKSPACE
- GARBAGE% = INP(DATA.PORT%)
- REM GO BACK AND TRY TO SEND CHARACTER AGAIN
- GO TO 2425
- REM
- 2500 REM
- REM
- NEXT CHAR.NO%
- 2510 REM
- REM
- REM SET CHAR.NO% TO 0. USED AS FLAG BY "I" COMMAND.
- CHAR.NO% = 0
- GO TO 1000
- REM
- 3000 REM
- REM RECEIVE A STRING. HALT RECEPTION WHEN A TERMINATION
- REM STRING IS FOUND.
- REM
- REM GET TERMINATION STRING
- TERM.STRING$ = ARG1$(INST.LIN%)
- REM GET LENGTH OF TERMINATION STRING MINUS 1.
- NO.TERM.M1% = LEN(TERM.STRING$) - 1
- REM INITIALIZE THE TEST STRING AND BUFFER COUNTER
- TEST.STRING$ = ""
- CHAR.NO% = 0
- WRAPPED% = FALSE%
- REM
- 3010 REM
- REM WAIT FOR CHARACTER READY SIGNAL FROM CONTROL PORT
- TIME.COUNT = 0.0
- 3020 REM
- REM IF ENABLED, TEST FOR TIME OUT
- IF TERR.LIN% > 0 AND TIME.COUNT > MAX.TIME THEN _
- GO TO 3070 ELSE TIME.COUNT = TIME.COUNT + 1.0
- REM IF ENABLED, TEST FOR CARRIER STILL PRESENT
- IF (CERR.LIN% > 0) AND _
- ((INP(CARRIER.PORT%) XOR CARRIER.POL%) AND _
- CARRIER.MASK%) = 0 THEN GO TO 3060
- REM GET I/O STATUS BYTE AND LOOP UNTIL CHARACTER READY
- IF ((INP(CTRL.PORT%) XOR RRDY.POL%) AND RRDY.MASK%) = 0 _
- THEN GO TO 3020
- REM
- REM GET CHARACTER FROM DATA PORT AND STRIP OFF PARITY BIT
- CHAR% = INP(DATA.PORT%) AND 127
- REM ADD THE CHARACTER TO THE BUFFER
- CHAR.NO% = CHAR.NO% + 1
- REM SEE IF BUFFER IS FULL
- IF CHAR.NO% <= 2000 THEN GO TO 3050
- REM WRAP THE BUFFER POINTER BACK TO BEGINNING AND SET FLAG
- CHAR.NO% = 1
- WRAPPED% = TRUE%
- 3050 REM
- BUFFER%(CHAR.NO%) = CHAR%
- REM
- REM IF ENABLED, CHECK FOR DATA (PARITY, ETC.) ERROR
- IF (RERR.LIN% <= 0) OR ((INP(RERR.PORT%) XOR RERR.POL%) AND _
- RERR.MASK%) = 0 THEN GO TO 3080
- REM ERROR FOUND
- INST.LIN% = RERR.LIN% - 1
- REM RESET I/O ERROR SO WONT GIVE FALSE ALARM ON NEXT CHARACTER
- IF RES.PORT% >= 0 THEN OUT RES.PORT%,RERR.RES%
- REM PRINT ALERT MESSAGE
- IF DISPLAY% THEN PRINT "Receive data error->>>"
- IF LOG.FLAG% >= 1 THEN PRINT #2, _
- "Receive data error->>>"
- REM SKIP THE TERMINATION STRING TEST, BUT LOG AND PRINT THE
- REM DATA RECEIVED SO FAR
- GO TO 3090
- REM
- 3060 REM
- REM CARRIER LOST WHILE TRYING TO RECEIVE
- INST.LIN% = CERR.LIN% - 1
- REM RESET I/O ERROR SO WON'T GIVE FALSE ALARM ON NEXT CHARACTER
- IF RES.PORT% >= 0 THEN OUT RES.PORT%,RERR.RES%
- REM CLEAR THE RECEIVER BUFFER
- GARBAGE% = INP(DATA.PORT%)
- IF DISPLAY% THEN PRINT "Carrier lost->>>"
- IF LOG.FLAG% >= 1 THEN PRINT #2, _
- "Carrier lost->>>"
- GO TO 3090
- REM
- 3070 REM
- REM TIME OUT ERROR EXIT FOR RECEIVE
- INST.LIN% = TERR.LIN% - 1
- IF DISPLAY% THEN PRINT "Receive time out->>>";
- IF LOG.FLAG% >= 1 THEN PRINT #2, _
- "Receive time out->>>";
- GO TO 3090
- REM
- 3080 REM
- REM DELETE THE LEFT MOST CHARACTER FROM TEST STRING AND ADD
- REM THE NEW CHARACTER TO THE RIGHT END
- TEST.STRING$ = RIGHT$(TEST.STRING$,NO.TERM.M1%) + CHR$(CHAR%)
- REM
- REM SEE IF TEST STRING IS TERMINATION STRING
- REM ELSE GO BACK FOR NEXT CHARACTER
- IF TEST.STRING$ <> TERM.STRING$ THEN GO TO 3010
- REM
- REM TERMINATION STRING FOUND. IF LOGGING IS ON, SAVE TO DISK
- 3090 REM
- IF NOT WRAPPED% THEN GO TO 3200
- FOR I% = CHAR.NO% + 1 TO 2000
- PRNT.CHAR$ = CHR$(BUFFER%(I%))
- IF DISPLAY% THEN PRINT PRNT.CHAR$;
- IF LOG.FLAG% >= 1 THEN PRINT #2, PRNT.CHAR$;
- NEXT I%
- 3200 REM
- FOR I% = 1 TO CHAR.NO%
- PRNT.CHAR$ = CHR$(BUFFER%(I%))
- IF DISPLAY% THEN PRINT PRNT.CHAR$;
- IF LOG.FLAG% >= 1 THEN PRINT #2, PRNT.CHAR$;
- NEXT I%
- REM
- GO TO 1000
- REM
- 4000 REM
- REM EXECUTE AN IF MATCH THEN BRANCH INSTRUCTION.
- REM RIGHT- MOST CHARACTER OF TEST STRING IS ALIGNED WITH THE
- REM MOST RECENTLY RECEIVED CHARACTER (INCLUDING THE TERMINATION
- REM CHARACTER(S)) IN THE R COMMAND.
- REM VARIABLE CHAR.NO% WILL BE > 0 ONLY IF PRECEEDING INSTRUCTION
- REM WAS A RECEIVE. THE I INSTRUCTION CAN ONLY BE EXECUTED IF
- REM CHARACTERS HAVE BEEN RECEIVED.
- IF CHAR.NO% <= 0 THEN GO TO 1000
- REM GET THE STRING WE ARE LOOKING FOR
- TEST.STRING$ = ARG1$(INST.LIN%)
- NO.TEST% = LEN(TEST.STRING$)
- REM SEE IF BUFFER HAS AT LEAST AS MANY CHARACTERS AS STRING
- IF NO.TEST% > CHAR.NO% AND NOT WRAPPED% THEN GO TO 1000
- REM VARIABLE TEST.CHAR.NO% POINTS TO A CHARACTER IN TEST STRING
- TEST.CHAR.NO% = NO.TEST% + 1
- REM COMPARE THE CHARACTERS, FROM RIGHT TO LEFT
- FOR I% = CHAR.NO% TO 1 STEP -1
- TEST.CHAR.NO% = TEST.CHAR.NO% - 1
- REM IF NO MORE CHARACTERS TO COMPARE IN STRING, THEN IT MATCHED
- IF TEST.CHAR.NO% = 0 THEN GO TO 4100
- TEST.CHAR% = ASC(MID$(TEST.STRING$,TEST.CHAR.NO%,1))
- REM END TEST AT FIRST MISMATCH
- IF BUFFER%(I%) <> TEST.CHAR% THEN _
- GO TO 1000
- NEXT I%
- REM
- REM IN CASE BUFFER WAS WRAPPED, THEN CONTINUE COMPARING CHARS
- IF NOT WRAPPED% THEN GO TO 4100
- REM IF WRAPPED, THEN CONTINUE FROM END OF BUFFER%
- FOR I% = 2000 TO CHAR.NO% + 1 STEP -1
- TEST.CHAR.NO% = TEST.CHAR.NO% - 1
- IF TEST.CHAR.NO% = 0 THEN GO TO 4100
- TEST.CHAR% = ASC(MID$(TEST.STRING$,TEST.CHAR.NO%,1))
- IF BUFFER%(I%) <> TEST.CHAR% THEN _
- GO TO 1000
- NEXT I%
- 4100 REM
- REM IF WE HAVE GOTTEN THIS FAR (I.E. WE HAVE NOT BEEN SENT
- REM BACK TO LINE 1000) THEN WE DEFINITELY HAVE A MATCH.
- INST.LIN% = ARG2%(INST.LIN%) - 1
- GO TO 1000
- REM
- 4400 REM
- REM EXECUTE A JUMP (GO TO) INSTRUCTION
- INST.LIN% = ARG2%(INST.LIN%) - 1
- GO TO 1000
- REM
- 4500 REM
- REM EXECUTE AN ON ERROR GO TO INSTRUCTION
- ARGUMENT1$ = ARG1$(INST.LIN%)
- IF ARGUMENT1$ = "RE" THEN _
- RERR.LIN% = ARG2%(INST.LIN%)
- IF ARGUMENT1$ = "SE" THEN _
- SERR.LIN% = ARG2%(INST.LIN%)
- IF ARGUMENT1$ = "TO" THEN _
- TERR.LIN% = ARG2%(INST.LIN%)
- IF ARGUMENT1$ = "CL" THEN _
- CERR.LIN% = ARG2%(INST.LIN%)
- GO TO 1000
- REM
- 5000 REM
- REM CHANGE THE LOG FLAG
- LOG.FLAG% = ARG2%(INST.LIN%)
- GO TO 1000
- REM
- 5100 REM
- REM CHANGE THE DISPLAY (PRINT TO TERMINAL) FLAG
- DISPLAY% = ARG2%(INST.LIN%)
- GO TO 1000
- REM
- 6000 REM
- REM
- REM
- REM ERROR MESSAGES
- 9000 REM
- PRINT "Error: end of file at line #";NO.INSTR%; _
- ", command = ";FIRST.CHAR$
- GO TO 9500
- 9005 REM
- PRINT "Error: L instruction without log file name"; _
- " in CP/M command"
- GO TO 9500
- 9010 REM
- PRINT "Error: illegal instruction:";FIRST.CHAR$; _
- ", at line #";NO.INSTR%
- GO TO 9500
- 9015 REM
- PRINT "Error: illegal label for line #";NO.INSTR%
- GO TO 9500
- 9020 REM
- PRINT "Error: duplicate label ";LABEL.VALUE%; _
- " at line #";NO.INSTR%
- GO TO 9500
- 9025 REM
- PRINT "Error: illegal parameter for ";FIRST.CHAR$; _
- " command at line #";NO.INSTR%
- GO TO 9500
- 9030 REM
- PRINT "Error: illegal label argument in ";FIRST.CHAR$; _
- " command at line #";NO.INSTR%
- GO TO 9500
- 9035 REM
- PRINT "Error: undefined label in line #";I%
- GO TO 9500
- 9040 REM
- PRINT "Error: no instructions found."
- GO TO 9500
- 9050 REM
- PRINT "Error: too many characters in Send string at line #";_
- INST.LIN%
- 9500 REM
- PRINT "Instruction file ";INST.FILE$
- 9550 REM
- CLOSE
- END
- REM
- 9600 REM
- PRINT "To run DIALOG, type"
- PRINT " DIALOG INSTFILE.DLG LOGFILE.LOG"
- PRINT "where INSTFILE.DLG contains the instructions"; _
- " (the input to DIALOG),"
- PRINT "and LOGFILE.LOG (optional) will receive the log"; _
- " (the output from DIALOG)."
- PRINT "To check for syntax errors only, type"
- PRINT " DIALOG INSTFILE.DLG ?
- END
- REM
- 10000 REM
- REM THIS SUBROUTINE CONVERTS ANY CHARACTERS PRECEEDED BY THE
- REM CONTROL CHARACTER PREFACE TO CONTROL CHARACTERS
- NO.CHARACTERS% = LEN(IN.STRING$)
- OUT.STRING$ = ""
- PREFACE% = FALSE%
- REM
- FOR CHAR.NO% = 1 TO NO.CHARACTERS%
- CHAR% = ASC(MID$(IN.STRING$,CHAR.NO%,1))
- REM BRANCH IF PREVIOUS CHARACTER WAS THE CONTROL PREFACE
- IF PREFACE% THEN GO TO 10050
- REM CHECK EACH CHARACTER FOR THE CONTROL PREFACE
- IF CHAR% <> CC.PREF% THEN GO TO 10100
- PREFACE% = TRUE%
- GO TO 10200
- 10050 REM
- REM MAKE CHARACTER INTO CORRESPONDING CONTROL CHARACTER
- CHAR% = CHAR% - 64
- PREFACE% = FALSE%
- 10100 REM
- REM COPY THE CHARACTER INTO THE OUTPUT BUFFER
- OUT.STRING$ = OUT.STRING$ + CHR$(CHAR%)
- 10200 REM
- NEXT CHAR.NO%
- RETURN
- REM
-