PROGRAM THELP;

{$C-}
{$K-}


{VARIABLE SECTION FOR 'THELP'}

type
  text80          = string[80];
  RegType         = record
                      ax,bx,cx,dx,bp,si,di,ds,es,flags:integer
                    end;
  HalfRegType     = record
                      al,ah,bl,bh,cl,ch,dl,dh:byte
                    end;
  IntrType        = record
                      ip,cs : integer
                    end;

const
  EntryChar       = 19;                { ALT 'R' }
  Escape          = 0;
  FirstRow        = 3;
  FirstCol        = 11;
  WindowWidth     = 60;
  WindowLength    = 18;
  Dr              = 3;
  Mr              = 12;
  Cr              = $0D;
  UserInt         = $66;
  KybdInt         = $16;
  ProgSize : integer = $A000;             { approx. program size }

  Regs    : regtype = (ax:0;bx:0;cx:0;dx:0;bp:0;si:0;di:0;ds:0;es:0;flags:0);
  SaveDS  :integer  = 0;

var
  SaveReg    : RegType;
  SaveHalf   : HalfRegType absolute SaveReg;
  HalfReg    : HalfRegType absolute regs;
  i,j,x,y    : integer;
  CursorPos  : integer;
  Selection  : integer;
  savebuf    : array[1..windowwidth] of array[1..windowlength] of integer;


{ MISC. PROCEDURES AND FUNTIONS FOR THELP }

procedure Bright(line:text80);
begin
  textcolor(15);
  write(line);
  textcolor(7);
end;

procedure PrintHeading;
begin
  bright('T');       write('URBO Pascal ');
  bright('Help   ');  write('Ver 2.0');
end;

procedure PrintMCS;
begin
  bright('M'); write('agnum ');
  bright('C'); write('ustom ');
  bright('S'); write('oftware');
end;

procedure Border;
begin
   GotoXY(1,1);                              {clear the window now}
   Write(chr(218));
   for i:=2 to windowwidth-1 do Write(chr(196));
   Write(chr(191));
   for i:=2 to windowlength-1 do
   begin
      GotoXY(1, i);  Write(chr(179));
      for j := 2 to windowwidth-1 do
         Write(' ');
      GotoXY(windowwidth, i);  Write(chr(179));
   end;
   GotoXY(1, windowlength);
   Write(chr(192));
   for i:=2 to windowwidth-1 do Write(chr(196));
   Write(chr(217));
END;

function GetScreenChar:integer;
begin
   savereg.ax := $0800;                 {9 -> get character/attr @ cursor}
   savereg.bx := 0;
   Intr($10,savereg);
   GetScreenChar := savereg.ax
end;

procedure PutScreenChar(input:integer);
begin
   savereg.ax := $0900 + (input and $FF); {a -> put character/attr @ cursor}
   savereg.bx := input shr 8;          {put the attrib in bl and 0 in bh}
   savereg.cx := 1;
   Intr($10,savereg)
end;

procedure OpenWindow;
begin
  window (firstcol, firstrow, firstcol+windowwidth, firstrow+windowlength);
    for j := 1 to windowlength do
      for i := 1 to windowwidth do
      begin
         GoToXY(i,j);
         savebuf[i][j] := GetScreenChar      {get a attribute/character at the cursor}
      end;
   border;
  window (firstcol+1,firstrow+1,firstcol+windowwidth-2,firstrow+windowlength-2);
  gotoxy(1,1);
end;

procedure closewindow;
begin
  window (firstcol, firstrow, firstcol+windowwidth, firstrow+windowlength);
  for j := 1 to windowlength do
    for i := 1 to windowwidth do
      begin
         GoToXY(i,j);
         PutScreenChar(savebuf[i][j])
      end
end;


{ MENU PRINT PROCEDURES FOR THELP }

procedure PrintMenu(number:integer);
begin
  case number of
    0  : begin
           gotoxy(mr+3,2);   PrintHeading;
           gotoxy(mr+7,3);   PrintMCS;
           gotoxy(mr+12,5);  write('MAIN MENU');
           gotoxy(mr,6);   write('<1> Edit Commands');
           gotoxy(mr,7);   write('<2> Syntax Structure');
           gotoxy(mr,8);   write('<3> Standard Procedures/Functions');
           gotoxy(mr,9);   write('<4> Compiler Directives');
           gotoxy(mr,10);  write('<5> Runtime Errors');
           gotoxy(mr,11);  write('<6> I/O Errors');
           gotoxy(mr,12);  write('<7> Standard Identifiers');
           gotoxy(mr,13);  write('<8> Version 2 Additions Part I');
           gotoxy(mr,14);  write('<9> Version 2 Additions Part II');
         end;
    1  : begin
           gotoxy(mr+3,2);   PrintHeading;
           gotoxy(mr+7,3);   PrintMCS;
           gotoxy(mr+7,5);   write('EDITOR COMMANDS MENU');
           gotoxy(mr,7);   write('<1> Cursor Movements Part I');
           gotoxy(mr,8);   write('<2> Cursor Movements Part II');
           gotoxy(mr,9);   write('<3> Insert and Delete Commands');
           gotoxy(mr,10);  write('<4> Block Commands');
           gotoxy(mr,11);  write('<5> Miscellaneous and Options');
         end;

    2  : begin
           gotoxy(mr+3,2);   PrintHeading;
           gotoxy(mr+7,3);   PrintMCS;
           gotoxy(mr+6,5);   write('SYNTAX STRUCTURE MENU');
           gotoxy(mr,6);   write('<1> TYPE');
           gotoxy(mr,7);   write('<2> CONST');
           gotoxy(mr,8);   write('<3> VAR');
           gotoxy(mr,9);   write('<4> WITH DO and CASE');
           gotoxy(mr,10);  write('<5> REPEAT UNTIL and WHILE DO');
           gotoxy(mr,11);  write('<6> IF THEN ELSE and FOR TO DO');
           gotoxy(mr,12);  write('<7> PROGRAM, PROCEDURE and FUNCTION');
           gotoxy(mr,13);  write('<8> Program Structure');
         end;

    3  : begin
           gotoxy(mr+3,2);   PrintHeading;
           gotoxy(mr+7,3);   PrintMCS;
           gotoxy(mr,5);   write('STANDARD PROCEDURES/FUNCTIONS MENU');
           gotoxy(mr,6);   write('<1> Input/Output Procedures');
           gotoxy(mr,7);   write('<2> Arithmetic Functions');
           gotoxy(mr,8);   write('<3> Scalar Functions/Heap Control');
           gotoxy(mr,9);   write('<4> String Procedures and Functions');
           gotoxy(mr,10);  write('<5> File Handling Procedures');
           gotoxy(mr,11);  write('<6> File Handling Functions');
           gotoxy(mr,12);  write('<7> Transfer/Screen Procs & Funcs');
           gotoxy(mr,13);  write('<8> Miscellaneous Proc/Func Part I');
           gotoxy(mr,14);  write('<9> Miscellaneous Functions Part II');
         end;
  end;
  repeat
    gotoxy(19,15);  write('Enter Selection  ? ');
    savereg.ax := $00;
    Intr(userint,savereg);
    selection := savehalf.ah - 1;
  until ((selection in [0..9]) and (number in [0,3]))
     or ((selection in [0..5]) and (number = 1))
     or ((selection in [0..8]) and (number = 2));
  clrscr;
end;


procedure Wait;
begin
  gotoxy(14,16); write('PRESS <ESC> TO RETURN TO MENU');
  repeat
    savereg.ax := 0;
    Intr(userint,savereg);
  until savehalf.ah = $01;
  clrscr;
end;

procedure CursorMoveI;
begin
  gotoxy(dr,2);   write('CURSOR MOVEMENTS  Part I :');
  gotoxy(dr,4);   write('  Character left         Ctrl-S  ->   ',#$1B);
  gotoxy(dr,5);   write('    Alternative          Ctrl-H  ->  ');
  gotoxy(dr,6);   write('  Character right        Ctrl-D  ->   ',#$1A);
  gotoxy(dr,7);   write('  Word left              Ctrl-A  ->  Ctrl ',#$1B);
  gotoxy(dr,8);   write('  Word right             Ctrl-F  ->  Ctrl ',#$1A);
  gotoxy(dr,9);   write('  Line up                Ctrl-E  ->   ',#$18);
  gotoxy(dr,10);  write('  Line down              Ctrl-X  ->   ',#$19);
  gotoxy(dr,11);  write('  Scroll up              Ctrl-W  ->  ');
  gotoxy(dr,12);  write('  Scroll down            Ctrl-Z  ->  ');
  gotoxy(dr,13);  write('  Page up                Ctrl-R  ->  PgUp');
  gotoxy(dr,14);  write('  Page down              Ctrl-C  ->  PgDn');
  Wait;
end;

procedure CursorMoveII;
begin
  gotoxy(dr,2);   write('CURSOR MOVEMENTS  Part II :');
  gotoxy(dr,4);   write('  To left on line      Ctrl-Q Ctrl-S  ->  Home');
  gotoxy(dr,5);   write('  To right on line     Ctrl-Q Ctrl-D  ->  End');
  gotoxy(dr,6);   write('  To top of page       Ctrl-Q Ctrl-E  ->  Ctrl Home');
  gotoxy(dr,7);   write('  To bottom of page    Ctrl-Q Ctrl-X  ->  Ctrl End');
  gotoxy(dr,8);   write('  To top of file       Ctrl-Q Ctrl-R  ->  Ctrl PgUp');
  gotoxy(dr,9);   write('  To end of file       Ctrl-Q Ctrl-C  ->  Ctrl PgDn');
  gotoxy(dr,10);  write('  To top of block      Ctrl-Q Ctrl-B  ->  ');
  gotoxy(dr,11);  write('  To end of block      Ctrl-Q Ctrl-K  ->  ');
  gotoxy(dr,12);  write('  To last cur.pos.     Ctrl-Q Ctrl-P  ->  ');
  Wait;
end;

procedure InsertDelete;
begin
  gotoxy(dr,2);   write('INSERT and DELETE :');
  gotoxy(dr,4);   write('  Insert mode on/off     Ctrl-V         ->  Ins');
  gotoxy(dr,5);   write('  Insert line            Ctrl-N         ->  ');
  gotoxy(dr,6);   write('  Delete line            Ctrl-Y         ->  ');
  gotoxy(dr,7);   write('  Del to end of line     Ctrl-Q Ctrl-Y  ->  ');
  gotoxy(dr,8);   write('  Delete right word      Ctrl-T         ->  ');
  gotoxy(dr,9);   write('  Del char under cursor  Ctrl-G         ->  Del');
  gotoxy(dr,10);  write('  Delete left character  <DEL>          ->  ');
  gotoxy(dr,11);  write('    Alternative          nothing        ->  ');
  Wait;
end;

procedure BlockCommands;
begin
  gotoxy(dr,2);   write('BLOCK COMMANDS :');
  gotoxy(dr,4);   write('  Mark block begin       Ctrl-K Ctrl-B  ->  F7');
  gotoxy(dr,5);   write('  Mark block end         Ctrl-K Ctrl-K  ->  F8');
  gotoxy(dr,6);   write('  Mark single word       Ctrl-K Ctrl-T  ->  ');
  gotoxy(dr,7);   write('  Hide/display block     Ctrl-K Ctrl-H  ->  ');
  gotoxy(dr,8);   write('  Copy block             Ctrl-K Ctrl-C  ->  ');
  gotoxy(dr,9);   write('  Move block             Ctrl-K Ctrl-V  ->  ');
  gotoxy(dr,10);  write('  Delete block           Ctrl-K Ctrl-Y  ->  ');
  gotoxy(dr,11);  write('  Read block from disk   Ctrl-K Ctrl-R  ->  ');
  gotoxy(dr,12);  write('  Write block to disk    Ctrl-K Ctrl-W  ->  ');
  Wait;
end;

procedure MiscEditing;
begin
  gotoxy(dr,1);   write('MISC. EDITING COMMANDS :');
  gotoxy(dr,2);   write('  End edit               Ctrl-K Ctrl-D  ->  ');
  gotoxy(dr,3);   write('  Tab                    Ctrl-I         ->  Tab');
  gotoxy(dr,4);   write('  Auto tab on/off        Ctrl-Q Ctrl-I  ->  ');
  gotoxy(dr,5);   write('  Restore line           Ctrl-Q Ctrl-L  ->  ');
  gotoxy(dr,6);   write('  Find                   Ctrl-Q Ctrl-F  ->  ');
  gotoxy(dr,7);   write('  Find and Replace       Ctrl-Q Ctrl-A  ->  ');
  gotoxy(dr,8);   write('  Repeat last find       Ctrl-L         ->  ');
  gotoxy(dr,9);   write('  Control char prefix    Ctrl-P         ->  ');
  gotoxy(dr,10);  write('  Abort operation        Ctrl-U         ->  ');
  gotoxy(dr,11);  write('OPTIONS :');
  gotoxy(dr,12);  write('  B - Backwards        U - Ignore upper/lowercase');
  gotoxy(dr,13);  write('  G - Global           W - Whole words only');
  gotoxy(dr,14);  write('  N - No qestions      n - Number of occurences');
  Wait;
end;

procedure PrintType;
begin
  gotoxy(dr,2);   write('{ integer, real, boolean, char, string[xx] }');
  gotoxy(dr,4);   write('TYPE');
  gotoxy(dr,5);   write('  text80   = STRING[80];');
  gotoxy(dr,6);   write('  letter   = ''a''..''z'';');
  gotoxy(dr,7);   write('  tones    = 1..12;');
  gotoxy(dr,8);   write('  row      = SET OF tones;');
  gotoxy(dr,9);   write('  chtype   = char;');
  gotoxy(dr,10);  write('  regtype  = record');
  gotoxy(dr,11);  write('               ax,bx,cx,dx,bp,si,di,ds,es,flags:INTEGER');
  gotoxy(dr,12);  write('             end;');
  gotoxy(dr,13);  write('  day      = (monday,tuesday,wenesday,thursday,');
  gotoxy(dr,14);  write('              friday,saturday,sunday);');
  Wait;
end;

procedure PrintConst;
begin
  gotoxy(dr,2);   write('{ stored in code_segment }');
  gotoxy(dr,3);   write('{ integer, real, boolean, char, string[xx] }');
  gotoxy(dr,5);   write('CONST');
  gotoxy(dr,6);   write('  minus2     = -2;');
  gotoxy(dr,7);   write('  pagesize   = 60;');
  gotoxy(dr,8);   write('  pi         = 3.1415926535;');
  gotoxy(dr,9);   write('  histring   = ''hello'';');
  gotoxy(dr,10);  write('  valid      = TRUE;');
  gotoxy(dr,11);  write('  msb : BYTE = 0;');
  gotoxy(dr,12);  write('  lsb : BYTE = 0;');
  Wait;
end;

procedure PrintVar;
begin
  gotoxy(dr,2);   write('{ stored in data_segment }');
  gotoxy(dr,3);   write('{ integer, real, boolean, char, string[xx] }');
  gotoxy(dr,4);   write('VAR');
  gotoxy(dr,5);   write('  count,index    : INTEGER;');
  gotoxy(dr,6);   write('  result,value   : REAL;');
  gotoxy(dr,7);   write('  eom,character  : CHAR;');
  gotoxy(dr,8);   write('  line           : STRING[80];');
  gotoxy(dr,9);   write('  error          : BOOLEAN;');
  gotoxy(dr,10);  write('  inventory      : FILE OF invtype;');
  gotoxy(dr,11);  write('  matrix         : ARRAY [1..50,1..50] OF INTEGER;');
  gotoxy(dr,12);  write('  cmdlength      : BYTE ABSOLUTE CSEG:$0080;');
  gotoxy(dr,13);  write('  cmdline        : STRING[127] ABSOLUTE CSEG:$0080;');
  gotoxy(dr,14);  write('  intrip         : INTEGER ABSOLUTE $0000:$0040;');
  Wait;
end;

procedure PrintCase;
begin
  gotoxy(dr,2);   write('WITH record_identifier DO');
  gotoxy(dr,3);   write('  statement;');
  gotoxy(dr,6);   write('CASE expression OF');
  gotoxy(dr,7);   write('  constant  :  statement;');
  gotoxy(dr,8);   write('  constant  :  statement');
  gotoxy(dr,9);   write('ELSE');
  gotoxy(dr,10);  write('  statement;');
  gotoxy(dr,11);  write('  statement');
  gotoxy(dr,12);  write('END;');
  Wait;
end;

procedure RepeatWhile;
begin
  gotoxy(dr,4);   write('REPEAT');
  gotoxy(dr,5);   write('  statement;');
  gotoxy(dr,6);   write('  statement ');
  gotoxy(dr,7);   write('UNTIL condition;');
  gotoxy(dr,10);  write('WHILE condition DO');
  gotoxy(dr,11);  write('  statement;');
  Wait;
end;

procedure IfFor;
begin
  gotoxy(dr,2);   write('IF condition');
  gotoxy(dr,3);   write('  THEN statement');
  gotoxy(dr,4);   write('  ELSE statement;');
  gotoxy(dr,7);   write('FOR variable := expression1 TO expression2 DO');
  gotoxy(dr,8);   write('  statement;');
  gotoxy(dr,10);  write('                      or');
  gotoxy(dr,12);  write('FOR variable := expression1 DOWNTO expression2 DO');
  gotoxy(dr,13);  write('  statement;');
  Wait;
end;

procedure ProgProcFunc;
begin
  gotoxy(dr,4);   write('PROGRAM progname;');
  gotoxy(dr,7);   write('PROCEDURE procname(VAR num1,num2 : INTEGER; ch : CHAR);');
  gotoxy(dr,8);   write('PROCEDURE procname(str1 : STRING80; length : REAL);');
  gotoxy(dr,11);  write('FUNCTION funcname(VAR value : REAL) : INTEGER;');
  gotoxy(dr,12);  write('FUNCTION funcname(ch : CHAR; num : INTEGER) : STRING80;');
  Wait;
end;

procedure ProgramStructure;
begin
  gotoxy(dr,1);   write('PROGRAM programname;');
  gotoxy(dr,2);   write('type');
  gotoxy(dr,3);   write('  .....');
  gotoxy(dr,4);   write('const');
  gotoxy(dr,5);   write('  .....');
  gotoxy(dr,6);   write('var');
  gotoxy(dr,7);   write('  .....');
  gotoxy(dr,8);   write('PROCEDURE procedurename(variable_list);');
  gotoxy(dr,9);   write('  .....');
  gotoxy(dr,10);  write('FUNCTION functionname(variable_list):type_identifier;');
  gotoxy(dr,11);  write('  .....');
  gotoxy(dr,12);  write('begin');
  gotoxy(dr,13);  write('  .....');
  gotoxy(dr,14);  write('end.');
  Wait;
end;

procedure InputOutput;
begin
  gotoxy(dr,1);   write('INPUT/OUTPUT PROCEDURES :');
  gotoxy(dr,2);   write('  Read(var F:file of type;var v:type);');
  gotoxy(dr,3);   write('  Read(var F:text;var I:Integer);');
  gotoxy(dr,4);   write('  Read(var F:text;var R:Real);');
  gotoxy(dr,5);   write('  Read(var F:text;var C:Char);');
  gotoxy(dr,6);   write('  Read(var F:text;var S:string);');
  gotoxy(dr,7);   write('  Readln(var F:text);');
  gotoxy(dr,8);   write('  Write(var F:file of type;var v:type);');
  gotoxy(dr,9);   write('  Write(var F:text;I:Integer);');
  gotoxy(dr,10);  write('  Write(var F:text;R:Real);');
  gotoxy(dr,11);  write('  Write(var F:text;B:Boolean);');
  gotoxy(dr,12);  write('  Write(var F:text;C:Char);');
  gotoxy(dr,13);  write('  Write(var F:text;S:string);');
  gotoxy(dr,14);  write('  Writeln(var F:text);');
  Wait;
end;

procedure Arithmetic;
begin
  gotoxy(dr,2);   write('ARITHMETIC FUNCTIONS :');
  gotoxy(dr,3);   write('  Abs(I:Integer):Integer;');
  gotoxy(dr,4);   write('  Abs(R:Real):Real;');
  gotoxy(dr,5);   write('  ArcTan(R:Real):Real;');
  gotoxy(dr,6);   write('  Cos(R:Real):Real;');
  gotoxy(dr,7);   write('  Exp(R:Real):Real;');
  gotoxy(dr,8);   write('  Frac(R:Real):Real;');
  gotoxy(dr,9);   write('  Int(R:Real):Real;');
  gotoxy(dr,10);  write('  Ln(R:Real):Real;');
  gotoxy(dr,11);  write('  Sin(R:Real):Real;');
  gotoxy(dr,12);  write('  Sqr(I:Integer):Integer;');
  gotoxy(dr,13);  write('  Sqr(R:Real):Real;');
  gotoxy(dr,14);  write('  Sqrt(R:Real):Real;');
  Wait;
end;

procedure ScalarHeap;
begin
  gotoxy(dr,2);   write('SCALAR FUNCTIONS :');
  gotoxy(dr,3);   write('  Odd(I:Integer):Boolean;');
  gotoxy(dr,4);   write('  Pred(X:scalar):scalar;');
  gotoxy(dr,5);   write('  Succ(X:scalar):scalar;');
  gotoxy(dr,6);   write('HEAP CONTROL PROCEDURES :');
  gotoxy(dr,7);   write('  GetMem(var P:pointer;I:Integer);');
  gotoxy(dr,8);   write('  Mark(var P:pointer);');
  gotoxy(dr,9);   write('  New(var P:pointer);');
  gotoxy(dr,10);  write('  Release(var P:pointer);');
  gotoxy(dr,11);  write('HEAP CONTROL FUNCTIONS :');
  gotoxy(dr,12);  write('  MemAvail:Integer;');
  gotoxy(dr,13);  write('  Ord(P:pointer):Integer;');
  gotoxy(dr,14);  write('  Ptr(I:Integer):pointer;');
  Wait;
end;

procedure Strings;
begin
  gotoxy(dr,2);   write('STRING PROCEDURES :');
  gotoxy(dr,3);   write('  Delete(var S:string;Pos,Len:Integer);');
  gotoxy(dr,4);   write('  Insert(S:string;var D:string;Pos:Integer);');
  gotoxy(dr,5);   write('  Str(I:Integer;var S:string);');
  gotoxy(dr,6);   write('  Str(R:Real;var S:string);');
  gotoxy(dr,7);   write('  Val(S:string;var R:Real;var p:Integer);');
  gotoxy(dr,8);   write('  Val(S:string;var I,P:Integer);');
  gotoxy(dr,9);   write('STRING FUNCTIONS :');
  gotoxy(dr,10);  write('  Concat(S1,S2,...,Sn:string):string;');
  gotoxy(dr,11);  write('  Copy(S:string;Pos,Len:Integer):string;');
  gotoxy(dr,12);  write('  Length(S:string):Integer;');
  gotoxy(dr,13);  write('  Pos(Pattern,Source:string):Integer;');
  Wait;
end;

procedure FileProc;
begin
  gotoxy(dr,2);   write('FILE PROCEDURES :');
  gotoxy(dr,3);   write('  Assign(var F:file;name:string);');
  gotoxy(dr,4);   write('  BlockRead(var F:file;var Dest:Type;Num:Integer);');
  gotoxy(dr,5);   write('  BlockWrite(var F:file;var Dest:Type;Num:Integer);');
  gotoxy(dr,6);   write('  Chain(var F:file);');
  gotoxy(dr,7);   write('  Close(var F:file);');
  gotoxy(dr,8);   write('  Erase(var F:file);');
  gotoxy(dr,9);   write('  Execute(var F:file);');
  gotoxy(dr,10);  write('  Rename(var F:file;Name:string);');
  gotoxy(dr,11);  write('  Reset(var F:file);');
  gotoxy(dr,12);  write('  Rewrite(var F:file);');
  gotoxy(dr,13);  write('  Seek(var F:file of type;Pos:Integer);');
  Wait;
end;

procedure FileFunc;
begin
  gotoxy(dr,2);   write('FILE FUNCTIONS :');
  gotoxy(dr,3);   write('  Eof(var F:file):Boolean;');
  gotoxy(dr,4);   write('  Eoln(var F:Text):Boolean;');
  gotoxy(dr,5);   write('  FilePos(var F:file of type):Integer;');
  gotoxy(dr,6);   write('  FilePos(var F:file):Integer;');
  gotoxy(dr,7);   write('  FileSize(var F:file of type):Integer;');
  gotoxy(dr,8);   write('  FileSize(var F:file):Integer;');
  Wait;
end;

procedure TransferScreen;
begin
  gotoxy(dr,1);   write('TRANSFER FUNCTIONS :');
  gotoxy(dr,2);   write('  Chr(I:Integer):Char;');
  gotoxy(dr,3);   write('  Ord(X:scalar):Integer;');
  gotoxy(dr,4);   write('  Round(R:Real):Integer;');
  gotoxy(dr,5);   write('  Trunc(R:Real):Integer;');
  gotoxy(dr,6);   write('SCREEN RELATED PROCEDURES :');
  gotoxy(dr,7);   write('  CrtExit;');
  gotoxy(dr,8);   write('  CrtInit;');
  gotoxy(dr,9);   write('  ClrEol;');
  gotoxy(dr,10);  write('  ClrScr;');
  gotoxy(dr,11);  write('  DelLine;');
  gotoxy(dr,12);  write('  GotoXY(X,Y:Integer);');
  gotoxy(dr,13);  write('  InsLine;');
  gotoxy(dr,14);  write('  LowVideo;');
  gotoxy(dr,15);  write('  NormVideo;');
  Wait;
end;

procedure MiscProc;
begin
  gotoxy(dr,1);   write('MISCELLANEOUS PROCEDURES :');
  gotoxy(dr,2);   write('  Bdos(func,param:Integer);');
  gotoxy(dr,3);   write('  Bios(func,param:Integer);');
  gotoxy(dr,4);   write('  Delay(mS:Integer);');
  gotoxy(dr,5);   write('  FillChar(var dest;length:Integer;data:Char);');
  gotoxy(dr,6);   write('  FillChar(var dest;length:Integer;data:Byte);');
  gotoxy(dr,7);   write('  Halt;');
  gotoxy(dr,8);   write('  Move(var source,dest;length:Integer);');
  gotoxy(dr,9);   write('  Randomize;');
  gotoxy(dr,10);  write('  Inline($CD/$10);');
  gotoxy(dr,11);  write('  Intr(intrnum:Integer;regs:Regtype);');
  gotoxy(dr,12);  write('MISCELLANEOUS FUNCTIONS Part I :');
  gotoxy(dr,13);  write('  Addr(var variable):Integer;');
  gotoxy(dr,14);  write('  Addr(<function identifier>):Integer;');
  gotoxy(dr,15);  write('  Addr(<procedure identifier>):Integer;');
  Wait;
end;

procedure MiscFunc;
begin
  gotoxy(dr,1);   write('MISCELLANEOUS FUNCTIONS Part II :');
  gotoxy(dr,2);   write('  Bdos(Func,Param:Integer):Byte;');
  gotoxy(dr,3);   write('  BdosHL(Func,Param:Integer):Integer;');
  gotoxy(dr,4);   write('  Bios(Func,Param:Integer):Byte;');
  gotoxy(dr,5);   write('  BiosHL(Func,Param:Integer):Integer');
  gotoxy(dr,6);   write('  Hi(I:Integer):Integer;');
  gotoxy(dr,7);   write('  IOresult:Boolean;');
  gotoxy(dr,8);   write('  KeyPressed:Boolean;');
  gotoxy(dr,9);   write('  Lo(I:Integer):Integer;');
  gotoxy(dr,10);  write('  Random(Range:Integer):Integer;');
  gotoxy(dr,11);  write('  Random:Real;');
  gotoxy(dr,12);  write('  SizeOf(var variable):Integer;');
  gotoxy(dr,13);  write('  SizeOf(<type identifier>):Integer;');
  gotoxy(dr,14);  write('  Swap(I:Integer):Integer;');
  gotoxy(dr,15);  write('  Upcase(Ch:Char):Char;');
  Wait;
end;

procedure PrintDirectives;
begin
  gotoxy(dr,1);   write('COMPILER DIRECTIVES :');
  gotoxy(dr,2);   write('  B - I/O Mode Selection          [ default B+ ]');
  gotoxy(dr,3);   write('  C - CNTL S and CNTL C           [ default C+ ]');
  gotoxy(dr,4);   write('  I - I/O Error Handling          [ default I+ ]');
  gotoxy(dr,5);   write('  I - Include Files');
  gotoxy(dr,6);   write('  R - Index Range Check           [ default R- ]');
  gotoxy(dr,7);   write('  V - Var-parameter Type Checking [ default V+ ]');
  gotoxy(dr,8);   write('  U - User Interupt               [ default U- ]');
  gotoxy(dr,9);   write('  K - Stack Checking              [ default K+ ]');
  gotoxy(dr,10);  write('  examples  :');
  gotoxy(dr,11);  write('    {$I-}');
  gotoxy(dr,12);  write('    {$I INCLUDE.FIL}');
  gotoxy(dr,13);  write('    {$B-,R+,V-}');
  gotoxy(dr,14);  write('    (*$U+*)');
  Wait;
end;

procedure RuntimeErrors;
begin
  gotoxy(dr,2);   write('RUN-TIME ERROR MESSAGES :');
  gotoxy(dr,3);   write('  01  -  Floating point overflow.');
  gotoxy(dr,4);   write('  02  -  Division by zero attempted.');
  gotoxy(dr,5);   write('  03  -  Sqrt argument error.');
  gotoxy(dr,6);   write('  04  -  Ln argument error.');
  gotoxy(dr,7);   write('  10  -  String length error.');
  gotoxy(dr,8);   write('  11  -  Invalid string index.');
  gotoxy(dr,9);   write('  90  -  Index out of range.');
  gotoxy(dr,10);  write('  91  -  Scalar or subrange out of range.');
  gotoxy(dr,11);  write('  92  -  Out of integer range.');
  gotoxy(dr,12);  write('  FF  -  Heap/stack collision.');
  Wait;
end;

procedure IOErrors;
begin
  gotoxy(dr,1);   write('I/O ERROR MESSAGES :');
  gotoxy(dr,2);   write('  01  -  File does not exist.');
  gotoxy(dr,3);   write('  02  -  File not open for input.');
  gotoxy(dr,4);   write('  03  -  File not open for output.');
  gotoxy(dr,5);   write('  04  -  File not open.');
  gotoxy(dr,6);   write('  10  -  Error in numeric format.');
  gotoxy(dr,7);   write('  20  -  Operation not allowed on a logical device.');
  gotoxy(dr,8);   write('  21  -  Not allowed in direct mode.');
  gotoxy(dr,9);   write('  22  -  Assign to std files not allowed.');
  gotoxy(dr,10);  write('  90  -  Record length mismatch.');
  gotoxy(dr,11);  write('  91  -  Seek beyond end-of-file.');
  gotoxy(dr,12);  write('  99  -  Unexpected end-of-file.');
  gotoxy(dr,13);  write('  F0  -  Disk write error.');
  gotoxy(dr,14);  write('  F1  -  Directory is full.');
  gotoxy(dr,15);  write('  F2  -  File size overflow.   FF  -  File disappeared.');
  Wait;
end;

procedure StdIdentifiers;
begin
  gotoxy(dr,2);   write('STANDARD IDENTIFIERS :');
  gotoxy(dr,3);   write('  DSeg:Integer');
  gotoxy(dr,4);   write('  CSeg:Integer');
  gotoxy(dr,5);   write('  SSeg:Integer');
  gotoxy(dr,6);   write('  Seg(Name):Integer');
  gotoxy(dr,7);   write('  Addr(Name):pointer');
  gotoxy(dr,8);   write('  Ofs(Name):Integer');
  gotoxy(dr,9);   write('  Mem[segment:offset]');
  gotoxy(dr,10);  write('  MemW[segment:offset]');
  gotoxy(dr,11);  write('  Port[portnum]');
  gotoxy(dr,12);  write('  PortW[portnum]');
  gotoxy(dr,13);  write('  LongFilePos       LongFileSize');
  gotoxy(dr,14);  write('  LongSeek          MsDos');
  Wait;
end;

procedure Version2I;
begin
  gotoxy(dr,2);   write('VERSION 2 Part I ');
  gotoxy(dr,3);   write('  Procedures Part I :');
  gotoxy(dr,4);   write('    Dispose(var P:pointer);');
  gotoxy(dr,5);   write('    Draw(X1,Y1,X2,Y2,Color:Integer);');
  gotoxy(dr,6);   write('    FreeMem(var P:pointer,I:Integer);');
  gotoxy(dr,7);   write('    GraphBackground(Color:Integer);');
  gotoxy(dr,8);   write('    GraphColorMode;');
  gotoxy(dr,9);   write('    GraphMode;');
  gotoxy(dr,10);  write('    GraphWindow(X1,Y1,X2,Y2,Color:Integer);');
  gotoxy(dr,11);  write('    HiRes;');
  gotoxy(dr,12);  write('    HiResColor(Color:Integer);');
  gotoxy(dr,13);  write('    NoSound;');
  gotoxy(dr,14);  write('    Palette(Color:Integer);');
  Wait;
end;

procedure Version2II;
begin
  gotoxy(dr,2);   write('VERSION 2 Part II');
  gotoxy(dr,3);   write('  Procedures Part II :');
  gotoxy(dr,4);   write('    Plot(X,Y,Color:Integer);');
  gotoxy(dr,5);   write('    Sound(I:Integer);');
  gotoxy(dr,6);   write('    TextBackground(Color:Integer);');
  gotoxy(dr,7);   write('    TextColor(Color:Integer);');
  gotoxy(dr,8);   write('    TextMode(Color:Integer);');
  gotoxy(dr,9);   write('    Window(X1,Y1,X2,Y2,Color:Integer);');
  gotoxy(dr,10);  write('  Functions :');
  gotoxy(dr,11);  write('    MaxAvail:Integer;');
  gotoxy(dr,12);  write('    WhereX:Integer;');
  gotoxy(dr,13);  write('    WhereY:Integer;');
  Wait;
end;



{ MAIN INTERUPT SERVICE PROCEDURES }


procedure EditCommands;
begin
  repeat
    PrintMenu(1);
    case selection of
      1 : CursorMoveI;
      2 : CursorMoveII;
      3 : InsertDelete;
      4 : BlockCommands;
      5 : MiscEditing;
    end;
    until selection = escape;
    selection := 10;
end;

procedure Syntax;
begin
  repeat
    PrintMenu(2);
    case selection of
      1 : PrintType;
      2 : PrintConst;
      3 : PrintVar;
      4 : PrintCase;
      5 : RepeatWhile;
      6 : IfFor;
      7 : ProgProcFunc;
      8 : ProgramStructure;
    end;
    until selection = escape;
    selection := 10;
end;

procedure ProcFunc;
begin
  repeat
    PrintMenu(3);
    case selection of
      1 : InputOutput;
      2 : Arithmetic;
      3 : ScalarHeap;
      4 : Strings;
      5 : FileProc;
      6 : FileFunc;
      7 : TransferScreen;
      8 : MiscProc;
      9 : MiscFunc;
    end;
    until selection = escape;
    selection := 10;

end;

procedure DOIT;
begin
  textcolor(7);
  repeat
    PrintMenu(0);
    case selection of
      1 : EditCommands;
      2 : Syntax;
      3 : ProcFunc;
      4 : PrintDirectives;
      5 : RuntimeErrors;
      6 : IOErrors;
      7 : StdIdentifiers;
      8 : Version2I;
      9 : Version2II;
    end;
  until selection = escape;
end;


procedure ProcessInt;                  { Start of interupt service }
begin
{when invoked, this procedure saves the registers into the structured constant
 'REGS' and restores the ds from the previously saved integer constant 'saveds'}

    inline(
    $53/                               {PUSH BX}
    $BB/regs/                          {MOV BX,OFFSET REGS}
    $2E/$89/$47/$00/                   {CS:MOV [BX]0,AX}
    $58/                               {POP AX}
    $2E/$89/$47/$02/                   {CS:MOV [BX]2,AX}
    $2E/$89/$4F/$04/                   {CS:MOV [BX]4,CX}
    $2E/$89/$57/$06/                   {CS:MOV [BX]6,DX}
    $2E/$89/$6F/$08/                   {CS:MOV [BX]8,BP}
    $2E/$89/$77/$0A/                   {CS:MOV [BX]A,SI}
    $2E/$89/$7F/$0C/                   {CS:MOV [BX]C,DI}
    $2E/$8C/$5F/$0E/                   {CS:MOV [BX]E,DS}
    $2E/$8C/$47/$10/                   {CS:MOV [BX]10,ES}
    $9C/                               {PUSHF}
    $58/                               {POP AX}
    $2E/$89/$47/$12/                   {CS:MOV [BX]12,AX}
    $2E/$8E/$1E/saveds                 {CS:MOV DS,SAVEDS -- PUT PROPER DS}
    );

  if halfreg.ah <> 0 then Intr(userint,regs) else
  begin
    Intr(userint,regs);
    if (halfreg.ah = EntryChar) and (halfreg.al = $00) then
    begin
      savereg.ax := $0300;
      savereg.bx := $0;
      Intr($10,savereg);               { get cursor position }
      cursorpos := savereg.dx;

      OpenWindow;                      { save text in window }
      DOIT;
      CloseWindow;                     { put back the text in the window }

      savereg.ax := $0200;
      savereg.bx := $0;
      savereg.dx := cursorpos;
      Intr($10,savereg);               { restore cursor position }

      halfreg.ah := 0;
      Intr(userint,regs);
    end;
  end;

{when invoked this routine restores the registers from the structure constant}

    inline(
    $BB/REGS/                          {MOV BX,OFFSET REGS}
    $2E/$8E/$47/$10/                   {CS:MOV ES,[BX]10}
    $2E/$8E/$5F/$0E/                   {CS:MOV DS,[BX]0E}
    $2E/$8B/$7F/$0C/                   {CS:MOV DI,[BX]0C}
    $2E/$8B/$77/$0A/                   {CS:MOV SI,[BX]0A}
    $2E/$8B/$6F/$08/                   {CS:MOV BP,[BX]08}
    $2E/$8B/$57/$06/                   {CS:MOV DX,[BX]06}
    $2E/$8B/$4F/$04/                   {CS:MOV CX,[BX]04}
    $2E/$8B/$47/$00/                   {CS:MOV AX,[BX]00}
    $2E/$FF/$77/$12/                   {CS:PUSH [BX]12}
    $9D/                               {POPF}
    $2E/$8B/$5F/$02/                   {CS:MOV BX,[BX]02}
    $5D/                               {POP BP}  {restore the stack pointer}
    $5D                                {POP BP}
    );

    inline ($CA/$02/$00)               {RETF 02}

end;


{ PROGRAM 'THELP' }                    { Program installation }
begin
  SaveDS := dseg;
  SaveReg.ax := $3500 + UserInt;
  Intr($21,SaveReg);                   { get user interupt }

  if SaveReg.es <> $00 then
    writeln('User Interupt in use -- cant install THELP.')
  else

  begin
    writeln('Installing THELP  --  Press < ALT "R" > to Recall help.');
    writeln('                      Press   < ESC >   to  exit  help.');
    savereg.ax := $3500 + KybdInt;
    Intr($21,savereg);                 { get keyboard interupt }

    savereg.ax := $2500 + UserInt;
    savereg.ds := savereg.es;
    savereg.dx := savereg.bx;
    Intr($21,savereg);                 { put in user interupt }

    savereg.ax := $2500 + KybdInt;
    savereg.ds := cseg;
    savereg.dx := ofs(ProcessInt);
    Intr($21,savereg);                 { install our interupt processor }

    savereg.dx := ProgSize;
    Intr($27,savereg);                 { terminate and stay resident }
  end;
  inline($CD/$20);                     { terminate if interupt in use }
end.
