TURBO Pascal 3.0 projects



1. Problems on keyboard input using background processing (CP/M)

As is generally known CP/M is a polling system and programmers cannot use interrupt routines. Unless one is programming hardware oriented bypassing the OS. But this is at a disadvantage that it leads to running on a special machine only which is in contrast to the idea using CP/M.

Programming in a standard environment may be performed by an appropriate setting of a request of the keyboard for example. This may be done whenever intensive computing takes place. A very good example for such an appliclation is the Public Domain editor VDO25.

But also the TURBO PASCAL programmer is able to request the state of the keyboard and collect pending characters until they are used by an input routine. One alternative is to write a procedure which will be called from time to time as mentioned by the assembler programming. A better way would be calling such a procedure automatically. A simple trick for that is using a feature of TURBO PASCAL (refering to version 3.0).

A look into the manual tells us that the compiler option {$U+} invokes an keyboard routine looking for Ctrl-C which will be interpreted as aborting the program.

What does this option imply referring to the execution of the Z80 CPU (or 8080)?
The compiler simply stores at the end of each statement the instruction RST 38H (Z80 mnemonic) or rather RST 7 (8080 mnemonic) - hex code FF. This instruction works exactly as a subroutine call, that is the program counter will be pushed onto stack and - in this case - the call of address hex 0038 will be executed. In general this address holds a jump to the actual routine. It looks a bit formal but the advantage over a direct CALL is the shortness of the instruction. A CALL requires three bytes but the RST instruction one byte only.
(By the way: RST instructions are executed if an interrupt takes place on a 8080 CPU).
Executing on the JOYCE this leads into difficulties because this machine handles interrupts via the RST 7 instruction. We have a functional conflict between the JOYCE interrupts and TURBO PASCAL option {$U+}.
In fact JOYCE programmers using this option for interrupting a program may experience a nasty surprise because this option does not work on the JOYCE machine (This statement is valid only for versions of TURBO which were purchased until middle of the year 1986. I don't know if this problem was solved later).
Fortunately the German distributor of TURBO PASCAL, the HEIMSOETH company, send a patch on my request. Find here the patch for changing RST 7 to RST 6 (hex F7) within TURBO.COM. After patching the compiler the option {$U+} works without a problem.

2. TURBO PASCAL 3.0 Patch

To perform the TURBO.COM and SID.COM are required. The the following commands must be typed:
    A>SID TURBO.COM          ( Call the debugger           )
    CP/M 3 SID - Version 3.0 ( Ready message from SID      )
    NEXT MSZE  PC  END
    7980 7980 0100 D2FF      ( State display by SID        )
    #F372,F372,30            ( Change RST 7 to RST 6       )
    #F378,F378,31            (          dtto.              )
    #F595,F595,F7            ( Change opcode               )
    #WTURBOP.COM             ( Write new file TURBOP.COM   )
    00F1h record(s) written  ( SID ready message           )
    #^C                      ( STOP key on JOYCE           )
    A>TURBOP                 ( Call the modified compiler  )

3. The TURBO PASCAL routines

Find introduced here some procedures and functions implemeted as include files to use the compiler option {$U+} to collect characters.

Keep in mind some disadvantages of this project:
  1. Option {$U+} increases the execution time of programs
  2. Collection of characters is meaningful for working with strings only. Of course working with single characters as well as with numbers is possible. Working with numbers requires a conversion into the selected type (integer, real).
The introduced routines are to be handled as basic principle only,

For proper function a type declaration named LINE is required. It presents a string with given length, e.g.:
          TYPE LINE : STRING [80];
to allocate a buffer for collecting up to 80 characters. The include file creates four variables which may not declared within the main part of course. These are:
BUFFER : LINE; This is the internal buffer for collecting the characters
BUFMAX : INTEGER; This is a variable holding the max number of characters to be collected
UOPT   : BOOLEAN; This boolean indicates whether program abortion by Ctrl-C may be allowed or not
DETECT : BOOLEAN; Boolean used for internal purpose

The prozedures and functions:

AHEAD;

Whenever the program executes the RST 6 instruction this procedure - written completely in assembler - will be called. If a Ctrl-C is found program aborts if variable UOPT is set accordingly. Note that procedure INI_AHEAD must be called to enable this function.

INI_AHEAD(BUFF:INTEGER;OPT:BOOLEAN);

This procedure installs the procedure AHEAD. It
  sets the buffer size to the value of BUFF
  initializes the BUFFER
  enters procedure AHEAD in address of RST 6
and sets option BREAK to the value of OPT. If OPT is set to TRUE program aborts on input of Ctrl-C.
(This takes the same effet as the original option {$U+})

GET_AHEAD(VAR XIN:LINE):BOOLEAN;

This function - partially written in assembler - handles the collected characters. Here XIN defines the buffer where characters will be copied into. Besides the returning boolean of this function also the boolean variable DETECT may be set. There are following dependencies on the boolean variables:
Variable: DETECT GET_AHEAD Function
Case 1 FALSE FALSE No character collected
Case 2 FALSE TRUE Characters were collected and transferred to buffer XIN completely. The old buffer is empty now.
Case 3 TRUE TRUE Characters were collected and a RETURN were detected. The new buffer is filled up to RETURN and the new buffer hold still characters.
The last result allows handling of several lines.

READ_LINE(TEXT:LINE):LINE;

This function handles the input of one line out of the buffer. A line will be returned. Compared to the cases above there are the following dependencies:
Case 1 The string TEXT will be displayed on the screen and a complete line will be read from keyboard.
Case 2 The string TEXT as well as the characters collected already will be displayed on the screen and the line will be filled with characters read from keyboard.
Case 3 The content of the buffer will be returned without displaying the string TEXT.

4. Closing advices

  1. Never turn on option {$U+} within the include file. That may result in a crash.
  2. But turn on option {$U+} after the include file to activate the mechanism.
  3. If time-critical routines are used turn off the mechanism at the start of a procedure or function using {$U-}. At the end it should be reactivated by {$U+}. Otherwise characters may be lost.
  4. If the buffer is filled partially (case 2) it is not possible to delete characters with the function READ_LINE.



Published in Klubzeitung No. 54 - Nov. 1998.   Author: Werner Cirsovius