TOPS-20 Monitor Calls User's Guide
Chapter 2 Input and output using the terminal
One of the main reasons for using monitor calls is to transfer data from one location to another. This chapter discusses moving data to and from the user's terminal.
Data transfers to and from the terminal are in the form of either individual bytes or text strings. The bytes are 7-bit bytes. The strings are ASCII strings ending with a 0 byte. These strings are called ASCIZ strings.
To designate the desired string, the user's program must include a statement that points to the beginning of the string being read or written. The MACRO pseudo-op, POINT, can be used to set up this pointer, as shown in the following sequence of statements:
MOVE AC1,PTR . . . PTR: POINT 7,MSG MSG: ASCIZ/TEXT MESSAGE/
Accumulator 1 contains the symbolic address (PTR) of the pointer. At the address specified by PTR is the pointer to the beginning of the string. The pointer is set up by the POINT pseudo-op. The general format of the POINT pseudo-op is:
(Refer to the TOPS-20 MACRO Assembler Reference Manual for more information on the POINT pseudo-op.) In the example above, the POINT pseudo-op has been written to indicate 7-bit bytes starting before the left-most bit in the address specified by MSG.
Another way of setting up an accumulator to contain the address of the pointer is with the following statement:
HRROI AC1,[ASCIZ/TEXT MESSAGE/]
The instruction mnemonic HRROI causes a -1 to be placed in the left half of accumulator 1 and the address of the string to be placed in the right half. However, in the above statement, a literal (enclosed in square brackets) has been used instead of a symbolic address. The literal causes the MACRO assembler to:
- store data within brackets (the string) in a table.
- assign an address to the first word of the data.
- insert that address as the operand to the HRROI instruction.
Literals have the advantage of showing the data at the point in the program where it will be used, instead of showing it at the end of the program.
As far as the I/O monitor calls are concerned, a word in this format (-1 in the left half and an address in the right half) designates the system's standard pointer (that is, a pointer to a 7-bit ASCIZ string beginning before the leftmost byte of the string). The result of the HRROI statement is interpreted by the monitor as functionally equivalent to the word assembled by the POINT 7, address pseudo-op and is the recommended statement to use in preparation for a monitor call. However, byte manipulation instructions (for example, ILDB, IBP, ADJBP) will not operate properly with this type of pointer.
After a string is read, the pointer is advanced to the character following the terminating character of the string. After a string is written, the pointer is advanced to the character following the last non-null character written.
Most TOPS-20 monitor calls accept one-word global byte pointers when executed from a nonzero section (see Section 8.3). Global byte pointers are used with extended addressing and are fully explained in Chapter 8 of this document. Unless specifically stated, TOPS-20 monitor calls do not accept two-word global byte pointers.
2.2 Primary I/O designators
To transfer data from one location to another, the user's program must indicate the source from which the data is to be obtained and the destination where the data is to be placed. By default, the user's terminal is defined as the source and destination. The default can be overridden by using the SPJFN% monitor call (refer to the TOPS-20 Monitor Calls Reference Manual). Examples in this book assume the user's terminal to be the source (input) and destination (output) device. Two designators are used to represent the user's terminal:
- The symbol .PRIIN to represent the user's terminal as the source (input) device.
- The symbol .PRIOU to represent the user's terminal as the destination (output) device.
These symbols are called the primary input and output designators and by default are used to represent the terminal running the program. They are defined in the system file MONSYM.MAC and do not have to be defined in the user's program as long as the program contains the statement
2.3 Printing a string
Many times a program may need to print an error message or some other string, such as a prompt to request input from the user at the terminal. The PSOUT% (Primary String Output) monitor call is used to print such a string on the terminal. This call copies the designated string from the program's address space. Thus, the source of the data is the program's address space, and the destination for the data is the terminal. The program need only supply the pointer to the string being printed.
Accumulator 1 (AC1) is used to contain the address of the pointer. After AC1 is set up with the pointer to the string, the next line of code is the PSOUT% call. Thus, an example of the PSOUT% call is:
HRROI AC1,[ASCIZ/TEXT MESSAGE/] ;string to print PSOUT% ;print TEXT MESSAGE
The PSOUT% call prints on the terminal all the characters in the string until it encounters a null byte. Note that the string is printed exactly as it is stored in the program, starting at the current position of the terminal's print head or cursor and ending with the last character in the string. If a carriage return and line feed are to be output, either before or after the string, these characters should be inserted as part of the string. For example, to print TEXT MESSAGE on one line and to output a carriage return-line feed after it, the user's program includes the call
HRROI AC1,[ASCIZ/TEXT MESSAGE /] PSOUT%
After the string is printed, the instruction following the PSOUT% call in the user's program is executed. Also, the pointer in AC1 is updated to point to the character following the last non-null character written.
The macro TMSG, found in the system file MACSYM, does the same thing as the example above. This macro offers the programmer a convenient way for printing messages on the terminal. For example
TMSG <TEXT MESSAGE >
caused the text message contained between the angle brackets, including the carriage return and line feed, to print on the terminal. The TMSG macro, along with others previously mentioned, will be used consistently in examples throughout this document. Refer to the system file MACSYM.MAC for further information on MACSYM macros.
Refer to Section 1.2.2 for information concerning error returns.
2.4 READING A NUMBER
The NIN% (Number Input) monitor call is used to read an integer. This call does not assume the terminal as the source designator; therefore, the user's program must specify this. The NIN% call accepts the number from any valid source designator, including a string in memory. This section discusses reading a number directly from the terminal. Refer to Section 2.9 for an example of using the NIN% call to read the number from a string in memory. The destination for the number is AC2, and the NIN% call places the binary value of the number read into this accumulator. The user's program also specifies a number in AC3 that represents the radix of the number being input. The radix given can be in the range 2-36.
Thus, the setup for the NIN% monitor call is the following:
MOVEI AC1,.PRIIN ;AC1 contains the primary input designator ;(the user's terminal) MOVEI AC3,^D10 ;AC3 contains the radix of the number being ;input (in this case a decimal number) NIN% ;The call to input the number
After completion of the NIN% call, control returns to the program at one of two places (refer to Section 1.2.2). If an error occurs during the execution of the call, control returns to the instruction following the call. This instruction should be a jump-type instruction to an error processing routine (see Section 1.2.2). Also, an error code is placed in AC3 (refer to Appendix B of the TOPS-20 Monitor Calls Reference Manual for the error codes). If the execution of the NIN% call is successful, control returns to the second instruction following the call. The number input from the terminal is placed in AC2.
The NIN% call terminates when it encounters a nondigit character (for example, a letter, a punctuation character, or a control character). This means that if 32X1 were typed on the terminal, on return AC2 contains a 40 (octal) because the NIN% call terminated when it read the X.
The following program prints a message and then accepts a decimal number from the user at the terminal. Note that the NIN% call terminates reading on any nondigit character; therefore, the user cannot edit his input with any of the editing characters (for example, DELETE, CTRL/W). The RDTTY% call (refer to Section 2.9) should be used in programs that read from the terminal because it allows the user to edit his input as he is typing it.
SEARCH MONSYM HRROI AC1,[ASCIZ/ Enter # of seconds: /] PSOUT% ;output a prompt message MOVEI AC1,.PRIIN ;input from the terminal MOVEI AC3,^D10 ;use the decimal radix NIN% ;input a decimal number ERJMP NINERR ;error-go to error routine MOVEM AC2, NUMSEC ;save number entered . . . NUMSEC:BLOCK 1 . . .
2.5 Writing a number
The NOUT% (Number Output) monitor call is used to output an integer. The user's program moves the number to be output into AC2. The program must specify the destination for the number in AC1 and the radix in which the number is to be output in AC3. The radix given cannot be greater than base 36. In addition, the user's program can specify certain formatting options to be used when printing the number.
Thus, the general setup for the NOUT% monitor call is as follows:
AC1: output designator AC2: number being output AC3: format options in left half and radix in right half
The format options that can be specified in the left half of AC3 are described in Table 2-1.
|0||NO%MAG||Print the number as a positive 36-bit number. For example, -1 would be printed as 777777 777777 if radix=8).|
|1||NO%SGN||Print the appropriate sign (+ or -) before the number. If bits NO%MAG and NO%SGN are both on, a plus sign is always printed.|
|2||NO%LFL||Print leading filler. If this bit is not set, trailing filler is printed and bit NO%ZRO is ignored.|
|3||NO%ZRO||Use 0's as the leading filler if the specified number of columns allows filling. If this bit is not set, blanks are used as the leading filler if the number of columns allows filling.|
|4||NO%OOV||Output on column overflow and return an error. If this bit is not set, column overflow is not output.|
|5||NO%AST||Print asterisks when the column overflows. If this bit is not set, and bit 4 (NO%OOV) is set, all necessary digits are printed when the columns overflow.|
|6-10||Reserved for Digital (must be 0).|
|11-17||NO%COL||Print the number of columns indicated. This value includes the sign column. If this field is 0, as many columns as necessary are printed.|
The following instruction sequence is an example of the NOUT% monitor call. This sequence prints a number, stored in location NUMB, on the user's terminal. The number can be positive, negative or zero, with no special formatting.
MOVX AC1,.PRIOU ;use primary output MOVE AC2,NUMB ;get number from location NUMB MOVX AC3,^D10 ;no special format ;decimal radix NOUT% ;print number EJSHLT ;unexpected fatal error. Halt ;and print message.
Refer to Section 1.2.2 for information concerning error returns. The following example illustrates the use of the three monitor calls described so far, as well as the TMSG macro. The RESET% and HALTF% monitor calls are described in Section 2.6.
SEARCH MONSYM SEARCH MACSYM .REQUIRE SYS:MACREL AC1==1 AC2==2 AC3==3 START: RESET% ;prepare program environment HRROI AC1,[ASCIZ/PLEASE TYPE A DECIMAL NUMBER: /] PSOUT% MOVEI AC1,.PRIIN ;source designator MOVEI AC3,^D10 ;decimal radix NIN% ERJMPS ERROR ;if input error print message ;halt. TMSG <THE OCTAL EQUIVALENT IS > MOVEI AC1,.PRIOU ;destination designator MOVEI AC3,^D8 ;octal radix NOUT% EJSHLT ;fatal error. ;Same as ERJMPS ERROR. HALTF% ;return to command language JRST START ;begin again, if continued ERROR: TMSG< ?ERROR-TYPE START TO BEGIN AGAIN> HALTF% JRST START ;user types continue-start ;again END START
2.6 Initializing and terminating the program
Two monitor calls that have not yet been described were used in the above program - RESET% and HALTF%.
2.6.1 RESET% Monitor Call
A good programming practice is to include the RESET% monitor call at the beginning of every assembly language program. This call closes any existing open files and releases their JFNs, kills any inferior processes, clears the software interrupt system (see Chapter 4), and performs various other process initilization functions. For a complete list of the functions provided by the RESET% monitor call, refer to the description of the call in the TOPS-20 Monitor Calls Reference Manual. The format of the call is
and control always returns to the next instruction following the call.
2.6.2 HALTF% Monitor Call
To stop the execution of a program and return control to the TOPS-20 Command Language, the user must include the HALTF% monitor call as the last instruction performed in the program. The user can then resume execution of the program at the instruction following the HALTF% call by typing the CONTINUE command after control has returned to command level.
2.7 Reading a byte
The PBIN% (Primary Byte Input) monitor call is used to read a single byte (that is, one character) from the terminal. The user's program does not have to specify the source and destination for the byte because this call uses the primary input designator (that is, the user's terminal) as the source and accumulator 1 as the destination. After execution of the PBIN% call, control returns to the instruction following the PBIN%. If execution of the call is successful, the byte read from the terminal is right-justified in AC1. If execution of the call is not successful, an illegal instruction trap is generated, as explained in Section 1.2.2.
2.8 Writing a byte
The PBOUT% (Primary Byte Output) monitor call is used to write a single byte to the terminal. This call uses the primary output designator (that is, the user's terminal) as the destination for the byte; thus, the user's program does not have to specify the destination. The source of the byte being written is accumulator 1; therefore, the user's program must place the byte right-justified in AC1 before the call.
After execution of the PBOUT% call, control returns to the instruction following the PBOUT%. If execution of the call is successful, the byte is written to the user's terminal. If execution of the call is not successful, an illegal instruction trap is generated, as explained in Section 1.2.2.
2.9 Reading a string
Up to this point, monitor calls have been presented for printing a string, reading and writing an integer, and reading and writing a byte. The next call to be discussed obtains a string from the terminal and, in addition, allows the user at the terminal to edit his input as he is typing it.
The RDTTY% (Read from Terminal) monitor call reads input from the user's terminal (that is, from .PRIIN) into the program's address space. Input is read until the user either types an appropriate terminating (break) character or inputs the maximum number of characters allowed in the string, whichever occurs first. Output generated as a result of character editing is printed on the user's terminal (that is, output to .PRIOU).
The RDTTY% call handles the following editing functions:
- Delete the last character in the string if the user presses the DELETE key while typing his input.
- Delete back to the last punctuation character in the string if the user types CTRL/W while typing his input.
- Delete the current line if the user types CTRL/U while typing his input.
- Retype the current line if the user types CTRL/R while typing his input.
Because the RDTTY% call can handle these editing functions, a program can accept input from the terminal and allow this input to be corrected by the user as he is typing it. For this reason, the RDTTY call should be used to read input from the terminal before processing that input with calls such as NIN%.
The RDTTY% call accepts three words of arguments in AC1 through AC3.
|AC1:||pointer to area in program's address space where input is to be placed. This area is called the text input buffer.|
|AC2:||control bits in the left half, and maximum number of bytes in the text input buffer in the right half.|
|AC3:||pointer to buffer for text to be output before the user's input if the user types a CTRL/R, or 0 if only the user's input is to be output on a CTRL/R.|
The control bits in the left half of AC2 specify the characters on which to terminate the input. These bits are described in Table 2-2.
|0||RD%BRK||Terminate input when user types a CTRL/Z or presses the ESC key.|
|1||RD%TOP||Terminate input when user types one of the following:
|2||RD%PUN||Terminate input when user types one of the following:
The ASCII codes listed above represent the punctuation characters in the ASCII character set. Refer to the ASCII character set table in Appendix A of the TOPS-20 Monitor Calls Reference Manual for these characters.
|3||RD%BEL||Terminate input when user types the RETURN or line feed key (that is, end of line).|
|4||RD%CRF||Store only the line feed in the input buffer when the user presses the RETURN key. A carriage return will still be output to the terminal but will not be stored in the buffer. If this bit is not set and the user presses the RETURN key, both the carriage return and the line feed will be stored as part of the input.|
|5||RD%RND||Return to program if the user attempts to delete past the beginning of his input. This allows the program to take control if the user tries to delete all of his input. If this bit is not set, the program waits for more input.|
|6||Reserved for Digital (must be 0).|
|7||RD%RIE||Return to program when there is no input (that is, the text input buffer is empty). If this bit is not set, the program waits for more input.|
|8||Reserved for Digital (must be 0).|
|9||RD%BEG||Return to user program if the user attempts to edit beyond the beginning of the input buffer.|
|10||RD%RAI||Convert lower case input to upper case.|
|11||RD%SUI||Suppress the CTRL/U indication on the terminal when a CTRL/U is typed by the user. This means that if the user types a CTRL/U, XXX will not be printed and, on display terminals, the characters will not be deleted from the screen. If this bit is not set and the user types a CTRL/U, XXX will be printed and, if appropriate, the characters will be deleted from the screen. In neither case is the CTRL/U stored in the input buffer.|
|15||RD%NED||Disable editing characters in user break mask. If this bit is set, then any editing character (^R, ^U, ^V, ^W, and DELETE) in the user supplied break mask does not have its editing function.|
If no control bits are set in the left half of AC2, the input will be terminated when the user presses the RETURN or line feed key (that is, terminated on an end-of-line condition only).
The count in the right half of AC2 specifies the number of bytes available for storing the string in the program's address space. The input is terminated when this count is exhausted, even if a specified break character has not yet been typed.
The pointer in AC3 is to the beginning of a buffer containing the text to be output if the user types a CTRL/R. When this happens, the text in this separate buffer is output, followed by any text that has been typed by the user. The text in this buffer cannot be edited with any of the editing characters (that is, DELETE, CTRL/W, or CTRL/U). If the contents of AC3 is zero, then no such buffer exists, and if the user types CTRL/R, only the text in the input buffer will be output.
If execution of the RDTTY% call is successful, the input is in the specified area in the program's address space. The character that terminated the input is also stored. (If the terminating character is a carriage return followed by a line feed, the line feed is also stored.) Control returns to the user's program at the second location following the call. The pointer in AC1 is advanced to the character following the last character stored. The count in the right half of AC2 is updated to reflect the remaining bytes in the buffer, and appropriate bits are set in the left half of AC2. The bits that can be set on a successful return are:
|Bit 12||RD%BTM||The input was terminated because one of the specified break characters was typed. This break character is placed in the input buffer. If this bit is not set, the input was terminated because the byte count was exhausted.|
|Bit 13||RD%BFE||Control was returned to the program because there is no more input and|
|Bit 14||RD%BLR||The limit to which the user can backup for editing his input was reached.|
For consistent handling of error returns refer to Section 1.2.2.
The following example illustrates the recommended method for reading data from the terminal. This example is essentially the same as the one in Section 2.5; however, the RDTTY% call is used to read the number before the NIN% call processes it. This program stores the last error encountered in location LASTER and therefore uses the ERJMPR pseudo-op.
SEARCH MONSYM SEARCH MACSYM .REQUIRE SYS:MACREL AC1==1 AC2==2 AC3==3 START: RESET% ;prepare program environment HRROI AC1,PROMPT PSOUT% ;type prompt HRROI AC1,BUFFER ;location to store number MOVEI AC2,BUFLEN*5 ;size of buffer HRROI AC3,PROMPT ;pointer to prompt RDTTY% ;read number from term. with editing ERJMPR ERROR ;save error code, print message HRROI AC1,BUFFER ;and halt source designator MOVEI AC3,^D10 ;decimal radix NIN% ERJMPR ERROR ;if input error, print message TMSG <THE OCTAL EQUIVALENT IS > MOVEI AC1,.PRIOU ;and halt destination designator MOVEI AC3,^D8 ;octal radix NOUT% ERJMPR ERROR ;save error code, print message HALTF% ;and halt return to command JRST START ;language begin again, if continued PROMPT: ASCIZ/PLEASE TYPE A DECIMAL NUMBER: / BUFLEN==10 BUFFER: BLOCK BUFLEN LASTER: BLOCK 1 ERROR: MOVEM AC1,LASTER ;save error code TMSG < ?ERROR-TYPE START TO BEGIN AGAIN>;print general error message HALTF% ;halt JRST START ;start over if continued END START
Data transfers of sequential bytes or text strings can be made to and from the terminal. The monitor calls for transferring bytes are PBIN% and PBOUT% and for transferring strings are PSOUT% and RDTTY%. The NIN% and NOUT% monitor calls can be used for reading and writing a number. In general, the user's program must specify a source from which the data is to be obtained and a destination where the data is to be placed. In the case of terminal I/O, the symbol .PRIIN represents the user's terminal as the source, and the symbol .PRIOU represents the user's terminal as the destination.