;
                       Help for Turbo Pascal (v3.0)                           

  / Introduction                       C- Logical Devices   
  | Basic data types                   D- Standard file I/O
  | Constants                          E- Pointers
  | Type conversion                    F- Including files
  | Predefined variables               G- Overlays
  | Operators                          H- Chain and Execute
A-| Compiler directives                I- Assembly routines
  | Procedures and Functions           J- Internal representation of basic
  | (including forward declarations)         data types
  | Identifiers and Types              K- The heap and the stacks
  \ String related routines            L- Interrupt Routines in Turbo Pascal
 B- Reserved Words                     M- Run-time and I/O errors
:A :TP
:B :TP3
:C
                            Logical Devices - 1/2                             


     These Devices are used in the Read,  Readln,  Write and Writeln routines. 
Unlike  standard  files,  each  of  these is defined as  EOF  if  the  current 
character is a ^Z, and EOLN if the current character is a ^M or ^Z.  (Standard 
files look one character ahead to determine this.)

     Buffered input editing includes the following commands:
______________________________________________________________________________
<BS>,<DEL>     Remove a character from input stream
<ESC>,<^X>     Remove entire line from input stream
<^D>           Recall a character from last input line (fwd space)
<^R>           Recall (retype) entire last input line
<^M>,<Return>  Process and save entire input line
<^Z>           Simulate end of file.
______________________________________________________________________________

                            Logical Devices - 2/2                             


Name             I/O Notes
______________________________________________________________________________
CON: (console)   I/O Buffered input, echo on, edit facility
TRM: (terminal)	 I/O Unbuffered input, echo on, no edit
KBD: (keyboard)  I   Unbuffered input, echo off, no edit
LST: (list)      O   Output to Aux port (printer)
AUX: (auxillary) I/O Unbuffered, no echo, I/O to Main port (modem)
USR: (user)      I/O User defined handler (see User written I/O drivers)
______________________________________________________________________________
:D
                            Standard File I/O - 1/4                           

     For input and output to logical devices, see Logical Devices, (QQV).
     IOResult  reports  the result of all file transactions.  If IOresult =  0 
then  no error was generated,  otherwize,  the value will indicate the  error. 
IOresult can only be read once, then it is reset.

Predefined files:
     Assign, Reset, Rewrite, Close are illegal on these files.
The  variable BufLen,  may be assigned a value to limit the maximum input line 
length.
Name      device    Notes
Input     CON:      (TRM: if option B- is used; acts like standard pascal)
Output    CON:      (TRM: as with Input)
Con       CON:      (see Logical Devices)
Trm       TRM:           "
Kbd       KBD:           "
Lst       LST:           "    
Aux       AUX:           "
Usr       USR:           "
                            Standard FIle I/O - 2/4                           

User opened files:

Typed files: (files of type something eg:)
VAR
     Fil: File of User_Defined_Array_of_Bannanas;
Seek(Filvar,n)
     Find the Nth block of data in a non text file.
Flush(Filvar)
     Empty  the  file buffer associated with Filvar.  Force next  read  to  be 
     physical.  Filvar cannot be a TEXT
FilePos(Filvar)
     Function  returns  current  position  of the file pointer  for  the  file 
     Filvar.  Filvar cannot be a TEXT
FileSize(Filvar)
     Returns  the  number of records in the file Filvar.  Filvar cannot  be  a 
     TEXT.
Assign(Filvar,Name)
     Assign should never be used with files which are already in  use.  Filvar 
     is associated with a disk file of name Name.
                            Standard File I/O - 3/4                           

Untyped Files: (files of type nothing) 
     These  are  low level files which can only be communicated with  via  128 
byte  records.  Untyped files are simply delared with the reserved  word  file 
eg:
VAR
     Fil : FILE;
     Read,  Write  and  Flush  are not allowed with  untyped  files.  Instead, 
Blockread and BlockWrite are provided:

BlockRead(Filvar, Var, Recs {, Result})
     Read  Recs  records  from file Filvar into the buffer  provided  by  Var. 
Result  will  contain the number of records which were  actually  successfully 
transferred.  This  is  the  only way to read non ascii files which  were  not 
created under Turbo Pascal protocol.
BlockWrite(Filvar, Var, Recs {,Result})
     Similar  in  all  respects  except  direction  of  information  flow   to 
BlockRead.
     FilePos,  EOF, FileSize, and Seek all work as per normal, with the record 
size set to 128 bytes.
                            Standard File I/O - 4/4                           


User written I/O drivers:
     Rewrite  an  input/output driver by assigning one of the pointers  listed 
below to the address of a newly created routine. (see Addr function)
 
Function        BDOS call Pointer    Use
______________________________________________________________________________
ConSt:boolean   11        ConStPtr   Console status (Keypressed)
ConIn:char      8         ConInPtr   Get console character (CON:,TRM:,KBD:)
ConOut(c:Char)  2         ConOutPtr  Output char to console (CON:,TRM:)
LstOut(c:Char)  5         LstOutPtr  Output char to printer (LST:)
AuxOut(c:Char)  4         AuxOutPtr  Output to modem (AUX:)
AuxIn:char      3         AuxInPtr   Input from modem (AUX:)
UsrOut(c:Char)  2         UsrOutPtr  Same as ConOut unless redefined (USR:)
UsrIn:char      8         UsrInPtr   Same as ConIn unless redefined (USR:)
______________________________________________________________________________
:E
                                 Pointers                                     

     No range checking is ever done on Pointers.  The routines which are
designed  to work together on the Heap,  are:  New & Dispose,  Mark & Release, 
GetMem & FreeMem
     New and Dispose are used with any except variant records
     Mark and Release are primitive, and deallocate the entire heap below
a certain point.
     GetMem  and  FreeMem  are arbitrary versions of  New  and  Dispose.  They 
require  that  the programmer give the size of the chunk to  be  allocated  or 
deallocated from the Heap.  This is neccessary for variant records since Turbo 
will  otherwize  be  unable to determine the correct amount of heap  space  to 
allocate.
:F
                              Including Files                                 


     Use the $I compiler directive to include files.  Include files may not be 
nested, however; the directive does permit the easy use of libraries.
     Include  files can have their own VAR,  TYPE and other  segments  without 
disturbing  the structure of the main turbo program.   In Turbo Pascal,  it is 
possible to duplicate these segments as many times,  and in any order that the 
programmer finds pleasing.  This is very different from the Pascal standard.
:G
                                 Overlays                                     

     Overlays  are defined  automatically  by  grouping  all of the procedures
to  be  in  a  single overlay segment in a group  surrounded  by  non  overlay 
routines and identifying them as overlay routines with the word OVERLAY.  
EG:
     program yaya;
     overlay procedure o1; begin; end;
     overlay procedure o2; begin; end;
     procedure always_in_mem;
     begin; end;
     overlay function of1; begin; end;
Puts  o1 and o2 into the same memory segment.  Only one can be in memory at  a 
time.  Memory  is allocated by the length of the longest of the routines in an 
overlay segment.  "of1" is in an entirely different segment.  Overlays in  the 
same segment must not call one another.
     Overlays  cannot  be forward declared,  or  recursive,  however,  calling 
procedures may be either forward, or recursive or both. 
     Run-time  errors in overlays may be very difficult  to  identify.  Always 
debug overlays thoroughly before making them into overlays.
     Overlays may themselves contain overlays, ad-infinitum. The overlay drive 
default may be changed via the procedure OvrDrive. 
:H
                              Chain and Execute                               

  
     Chain  and Execute,  like overlays,  change the area of control to a  new 
process.  These  however,  are at the mercy of the new program,  and may  well 
never return. All of the old program may well be over-written. Both are called 
with an Assign'ed file variable.
Chain(FilVar)
     Chain transfers control to a special .CHN file compiled from turbo. These 
files  do  not  need to load in the entire Turbo library and therefor  can  be 
faster  and  smaller  than a call to execute.  Both the  chained  and  calling 
program must use the same start address!
Execute(FilVar)
     Like Chain,  control is moved to a new program.  Unlike Chain, the Pascal 
Library is trashed.
     The only possible return is via an I/O error, if the file is not found.
:I
                            Assembly Routines - 1/4                           

     Two methods are available for avoiding using compiled Pascal code.  These 
options are the "inline" command, and the "external" definition.

     External references:
     Use  the reserved word external to declare a routine which will be loaded 
into memory at compile time from an executable file and inserted in the  code. 
The syntax is:
                Function Yaya:Integer; external $EC00;

     The  argument  following the external statement is the memory address  of 
the  external  code.  Parameters for external subprograms must be  dealt  with 
carefully by the program.

     All parameters are transferred via the Z-80 stack.  The top of the  stack 
contains the return address (1 word), followed by the data to be passed.
Var Parameters: The address of the variable is pushed (1 word)
Value Parameters: Data transferred depends on the data type as per below:
Scalars:  Integers,  Booleans, Chars and declared types are transferred to the 
stack as a word. Bytes are stored with the MSB zeroed.
                            Assembly Routines - 2/4                           

Reals:     Six  bytes of data are pushed for a real.  Typically they should be 
removed  with  a sequence like POP HL,  POP DE,  POP BC.  L will  contain  the 
exponent,  H  the least significant byte,  E the fourth,  D the third,  C  the 
second and B the MSB.

Strings:   SP will point to the string length.  Following the length will be N 
bytes  which contain the actual string.  The following code will transfer  the 
data on the stack to StrBuf:
     LD   DE,StrBuf
     LD   HL,0
     LD   B,H
     ADD  HL,SP
     LD   C,(HL)
     INC  BC
     LDIR
     LD   SP,HL
                            Assembly Routines - 3/4                           

Sets:      A set always occupies 32 bytes on the stack.  The following routine 
will transfer the set from the stack to SetBuf:
     LD   DE,SetBuf
     LD   HL,0
     ADD  HL,SP
     LD   BC,32
     LDIR
     LD   SP,HL
     Storing the LSB of the set at the lowest address in SetBuf.

Pointers:  The word at the top of the stack will be the value of the  pointer. 
NIL is represented by the value 0.
Arrays  and Records:  The address of the array or record is always transferred 
to the stack,  and it is the duty of the subprogram to copy the array to a new 
location if it is a VAR parameter.
                            Assembly Routines - 4/4                           

Function results: should be returned as follows
     Scalars: return their value in HL
     Reals: return their value in BC, DE, and HL (as per POP)
     Strings: return pushed into the stack (as per POP)
     Pointer: return in the HL pair
*** For more information see Internal Representation of Data Types ***
Inline:   Inline code should be relocatable. However, an operator is available 
for  writing  fixed code based on the current PC.  The operator  is  "*".  "*" 
procedure   identifiers,   function  identifiers,   variable  identifiers  and 
constants  can  be  added or subtracted.   Identifiers are all  addresses  (or 
offsets) of the identifier in question. "*" is the address of the next byte of 
code to be generated.  Bytes are only created and stored if they are  composed 
entirely  of constants and results in a value in 0..255.  Otherwize a word  is 
stored  in  normal  byte  reversed order.  Byte selection  can  be  forced  by 
surrounding the expression in angle brackets.   Expressions are separated with 
slashes. Eg:
               inline(<$4321/>23/*+2/count+99);

Severe errors may result if SP is changed and not restored in the routine.
:J
              Internal Representation of Basic Data Types - 1/5               

Scalars: 
     One byte iff ;
          Integer subrange within 0..255
          Char
          Booleans
          User Defined Types with fewer than 256 members
     Two bytes iff (2's complement LSB first);
          Integer
          Integer subrange outside 0..255;
          User Defined Types with more than 256 members
Reals:
     6 bytes;
          Exponent (binary offset $80; 0 => REAL IS ZERO)
          LSB
          ...
          MSB mantissa (normalized, radix 2, unsigned, MSBit represents 
                    sign, actual MSBit is always 1 (ie normalized))
              Internal Representation of Basic Data Types - 2/5               

Strings:
     Max+1 bytes;
          Current Length
          First used char
          ...
          Last used char
          ... (unused)
Sets:
     (Max div 8) - (Min div 8) +1 bytes (Max, Min= upper and lower bounds of 
     base type of set);
          Addr_of_byte_of_E = @+(E div 8)-(Min div 8)
          Addr_of_bit_of_E = E mod 8
              Internal Representation of Basic Data Types - 3/5               

File interface Blocks:
     176 Bytes;
     @        Flags (
                 Bit 0..3 : file type 0:disk; 1:Con; 2:Kbd; 3:Lst; 4:Aux; 5:Usr)
                 Bit 4 : read semaphore (set if buffer undefined)
                 Bit 5 : write semaphore (set if data is in data buffer)
                 Bit 6 : Output flag (output allowed)
                 Bit 7 : Input flag (input allowed)
                 )
     @+1      Character buffer
     @+2      Sector buffer pointer LSB; MSB
     @+4      Number of records LSB; MSB
     @+6      Record length LSB;MSB
     @+8      Current record LSB;MSB
     @+10     Unused
              Unused
     @+12     CP/M FCB byte 1
              ...
     @+47     Last CP/M FCB byte
              Internal Representation of Basic Data Types - 4/5               

     @+48     First sector buffer byte
              ...
     @+175    Last sector buffer byte

Pointers:
     2 bytes (unsigned);
     @       LSB
     @+1     MSB
Arrays:
     eg:
     Table: array [1..10,1..10] of type;
          @                   Board[1,1]
          @+sizeof(type)      Board[1,2]
               ...
          @+9*sizeof(type)    Board[1,8]
          @+10*sizeof(type)   Board[2,1]
               ...
          @+99*sizeof(type)   Board[10,10]
              Internal Representation of Basic Data Types - 5/5               

Records:
     Memory is allocated field by field, starting at the lowest address.
     Variants occupy the length of the longest variant. Each variant starts at 
the same address.

Disk Files:
     Random access files:
          Sec 0 Byte 0: No of records (LSB)
          Sec 0 Byte 1:               (MSB)
          Sec 0 Byte 2: Record length (LSB)
          Sec 0 Byte 3:               (MSB)
          Sec 0 Byte 4: First byte of data
          ...
     Text files:
          Lines of characters delimited by ^Z or ^M^J sequences.
:K
                           The Heap and the Stacks                            

     The  Heap  is used to store dynamic variables and is controlled  by  New, 
Mark and Release. Initially, the Heap is set to the first free byte of memory.
     The  recursion stack is only used by recursive routines {$A-}.  Typically 
it is located at $400 below the CPU stack pointer (1k). Upon a recursive call, 
the  process copies its workspace onto the Recursion  stack.  On  exiting,  it 
releases  the allocated memory.  Because of the method,  variables local to  a 
subprogram must never be used as VAR parameters in a recursive call.  (Ie: all 
parameters in a recursive call must be global)
     The  CPU stack is used to store intermediate results during evaluation of 
expressions and to transfer parameters to procedures and functions.  An active 
for  statement  also uses the stack and occupies one word.  The CPU  stack  is 
normally set to the top of free memory.
     The  values  of  each  may be  controlled  with  the  variables  HeapPtr, 
RecurPtr, and StackPtr.  It is neccessary that HeapPtr < RecurPtr < StackPtr.
     A  runtime  error  will  be produced if the  Heap  and  Recursion  Stacks 
overlap. The CPU stack is not checked for overflow, but is relatively unlikely 
since  there  would need to be in excess of 300 active calls on the  stack  to 
cause such problems.   In any event, the Recursion pointer can be relocated if 
such dangers become emminent.
:L
                       Interrupt Routines in Turbo Pascal                     

     All  registers  should  be  saved by the routine.  PUSH and  POP  can  be 
performed  at the beginning and end of the routine through inline  statements. 
Also  the routine should end with EI (enable further interrupts).  It  may  be 
neccessary if interrupts are daisy chained, to use an RETI instruction (inline 
again) rather than the normal RET statment created by the compiler.
     General rules of registers are that Integer ops only use AF,  BC,  DE and 
HL.  Others  may use IX and IY,  and real ops will use the alternate  register 
pairs.
     Standard  I/O procedures must not be called since they are not reentrant. 
All interrupt routines must be compiled with the $A option active {$A+}.  Many 
BDOS and occasionally BIOS calls may be non-reentrant as well.
     All interrupt proccessing is the responsibility of the programmer.
:M
                          Run-Time and I/O Errors - 1/3                       

Runtime:

     01   Floating overflow
     02   Division by zero
     03   Sqrt argument negative
     04   Ln argument negative or zero
     10   String length error
          1.   Concat results in more than 255 character string
          2.   Only strings of length 1 can be converted to char
     11   Invalid string index (param of Copy, Delete, Insert not in [1..255]
     90   Index out of range of array
     91   Scalar or subrange out of range
     92   Out of integer range (trunc, round not in [-32768,32767]
     F0   Overlay file not found
     FF   Heap/Stack collision
                          Run-Time and I/O Errors - 2/3                       

I/O errors:
     01   File does not exist
     02   File not open for input
     03   File not open for output
     04   File not open (BlockRead, BlockWrite)
     10   Error in numeric format (non convertible number)
     20   Operation not allowed on a logical device
     21   Not allowed in direct mode (Chain, Execute not allowed when run from 
          memory)
     22   Assign to std files not allowed
     90   Record length mismatch
     91   Seek past end-of-file
     99   Unexpected end-of-file
          1.   Physical EOF found before ^Z
          2.   Read beyond EOF
          3    Read or BlockRead unable to read next sector
                          Run-Time and I/O Errors - 3/3                       

     F0   Disk write error (disk full, can also be caused by a read, since
          these flush the write buffer before continuing)
     F1   Directory is full
     F2   File size overflow (write beyond record 65535)
     F3   Too many open files
     FF   File disappeared (close attempted on non-existant file)
