home *** CD-ROM | disk | FTP | other *** search
- PROCEDURE
-
- console (string input with Wordstar editing)
-
- USAGE
-
- To obtain a string of characters from the console in any arbitrary
- length up to a maximum of 80 characters. Provides ability to set
- the maximum length acceptable (for field length control), and to
- return upline, downline, ^Q and escape responses by the operator
- for customized reaction if needed.
-
- FUNCTION
-
- Full line-oriented editing features are supported with Wordstar
- compatible command characters.
-
- The following control characters are recognized:
-
- ^A = backward by words (curser positioned at first
- letter).
- ^S = backspace one character.
- ^D = forespace one character.
- ^F = forward by words (curser positioned at first
- letter).
- ^G = single character delete.
- ^V = single (blank) character inserted. (NOTE: non-
- standard from Wordstar response -- see below.)
- tab = non-destructive forward move of 5 characters.
- left arrow = same as ^S.
- right arrow = same as ^D.
- rub-del = destructive overwriting backspace.
- backspace = backspace.
- <CR> = terminate input. Not echoed to the screen. Curser
- will remain where it was when carriage return made.
- escape = terminate input (quit requested).
- ^Q = terminate input (quit requested, possibly program
- abort requested).
- ^J = terminate input (up arrow requested).
- ^K = terminate input (down arrow requested).
- ^E = terminate input (Wordstar up line requested).
- ^X = terminate input (Wordstar down line requested).
-
- RETURNED VALUES:
- On return from a call to console, your CHAR variable will
- have one of five possible values:
- ^J (CHR(10)) -- down arrow requested.
- ^K (CHR(11)) -- up arrow requested.
- <cr>(CHR(13)) -- normal return
- ^Q (CHR(17)) -- control-Q entered.
- esc (CHR(27)) -- escape entered.
-
- The value of outch on entry to procedure console is ignored.
-
- The integer variable "position" will point to the current
- position in the string array at the time one of the five
- terminating characters was entered (if the curser was at
- the end of the edit line, then "position" will equal
- length(editline)+1). On entry to console, "position" is an
- index into the string and determines where in the string
- console believes itself to be upon entry. Thus you may
- control the starting position, if desired. Naturally,
- you must handle cursor on-screen positioning to conform
- to the position value you are sending to console. If console
- is given a position value which is GREATER than the current
- length of the string it is to edit (as supplied to it in
- the "charcount" parameter), console will move the curser
- back on the line to reach the ending position as defined
- by charcount. For example, if you send it a charcount of
- 10, but a position value of 15, console will assume that
- the cursor is at column 15 and will move back four spaces
- to conform with the defined end of string. The curser will
- be positioned at column 11 (the growing end of the edit
- line), where columns are always counted 1..length(string).
-
- The edited string is returned in your string variable.
-
-
- EXAMPLE
-
-
- PROGRAM demo(INPUT, OUTPUT);
-
- CONST
- maxlength = 80; {max of string} maxbuf = 2;
- lf = $0A; {linefeed}
- bel = 7; {buzzer} nul = 0; {harmless character}
-
-
- VAR
- bufptr, index : INTEGER; {used to access str[bufptr, index]}
- str : ARRAY[0..maxbuf] OF STRING; up, ch : CHAR;
- dummy, upvalue : INTEGER;
-
-
- EXTERNAL PROCEDURE console(VAR outch : CHAR; VAR str : STRING;
- VAR position : INTEGER; charcount, len : INTEGER);
-
-
- EXTERNAL FUNCTION @BDOS(func : INTEGER; parm : WORD) : INTEGER;
-
- {this will be used only to output a linefeed to the terminal, since
- MT+ uses linefeeds for eoln indicators, it can't be written with
- write(chr(lf)) statements. }
-
-
- BEGIN {main}
-
- {*********************** INITIALIZATION *************************}
- index := 1; {we want to start by pointing to first character.}
-
- FOR bufptr := 0 TO maxbuf DO
- str[bufptr] := ''; {initialize all strings to nul lengths}
-
- bufptr := 0; {to start at first field's string}
-
- WRITE('Please enter decimal value of your "up" character:');
- READLN(upvalue);
- up := CHR(upvalue); {up arrow values vary with terminal type}
- {****************************************************************}
-
- WRITELN;
- WRITELN('Type CNTRL-Q to ABORT; ESCAPE when FINISHED.');
- WRITELN;
- WRITELN('First field:');
- WRITELN('Second field:');
- WRITE('Final field: ',up,up); {and wind up on original line}
-
- REPEAT
- IF (ORD(ch)=11) THEN {they asked for up arrow}
-
- IF bufptr > 0 THEN {there's room to rise}
- BEGIN
- WRITE(up);
- bufptr := PRED(bufptr) {and move edit up one, too}
- END
- ELSE WRITE(CHR(bel)) {warn them they've hit the roof}
-
- ELSE IF (ORD(ch)=10) OR (ORD(ch)=13) THEN {down requested}
-
- IF bufptr < maxbuf THEN {there's room to go down}
- BEGIN
- dummy := @BDOS(2, WRD(lf)); {have cp/m put a linefeed}
-
- {The above circuitous call is necessary to defeat MT+'s
- use of linefeeds as end of line indicators which
- makes it impossible to just write(chr(lf)). }
-
- bufptr := SUCC(bufptr)
- END
- ELSE WRITE(CHR(bel)); {we hit the floor!}
-
- {--> } console(ch, str[bufptr], index, LENGTH(str[bufptr]), maxlength);
-
- UNTIL (ORD(ch)=27) OR (ORD(ch)=17); {escape or control-Q}
-
- FOR dummy := bufptr TO maxbuf + 2 DO
- WRITELN; {be sure we're two lines below data fields}
-
- IF (ORD(ch)=17) THEN {they typed a ^Q to bomb out}
- WRITELN('Abort requested via ^Q.')
- ELSE
- WRITELN('Data accepted.');
- END. {main}
-
- A .COM file of this demo program is included in the console
- library for you to try out. Naturally, the code above is considerably
- junked up by the necessity for avoiding direct curser addressing. By
- including in your standard libarary of terminal handlers a function
- such as
- FUNCTION at(row, column : INTEGER) : CHAR;
- things are made much simpler because bufptr can be used in a single
- line-addressing statement to move to the appropriate line, i.e.
- WRITE(at(bufptr, index + offset);
- which will handle all the necessary messy details of being where
- we say we are.
-
-
- QUIRKS
-
- RETURN is non-standard in that
- 1) It may be hit at ANY point in the line and the
- entire line is accepted and returned. This follows
- the Wordstar philosophy of "what you see is what
- you get." Therefore, unwanted characters behind
- the curser must be deleted via ^G before return
- is pressed.
- 2) It is not echoed to the screen, so unless the
- calling program does something about it, you
- remain exactly where you were on the screen when
- return was entered.
-
- ^T is not supported. This is Wordstar's word delete command.
- All deletion must be done one character at a time with ^G
- or the rub-delete key.
-
- ^F is non-standard (in the context of Wordstar). Rather than
- being a toggle on/off, it merely inserts ONE blank space
- at the current curser position. To insert multiple characters,
- ^F must be pressed as many times as needed to create space.
- Following that action, the new material may be typed into the
- "hole" created.
-
- FINAL NOTES
-
- The console.erl file included in the console.lbr file has been
- compiled for 8080 code only, and hence is not optimized for Z-80
- operation (a minimal difference in this case).
-
- I have not tried this, but MT+ claims that such .erl files can be
- invoked from machine language routines. Parameters are passed on the
- stack using a 16-bit word for each parameter. Top of stack is the
- return address.
- In this case you would:
- PUSH (address of outch);
- PUSH (address of str);
- PUSH (address of position);
- PUSH charcount;
- PUSH len;
- PUSH return-address;
- CALL console;
- The only other thing to beware of is that MT+ defines a string
- as str[0] = length byte (0..255), str[1..length] = character array
- so your string would have to match this format.
- I'm pretty sure the stack would be cleaned up upon return since
- a machine language routine called from Pascal has to do its own house-
- cleaning before return, so I assume Pascal returns the favor.
-
- Let me know of any problems, if found.
-
-
- Patrick Wallace
- 628 North Blvd.
- Baton Rouge, La. 70802
-
-