home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / ASMCODE.ZIP / NEWCRT.PAS < prev    next >
Pascal/Delphi Source File  |  1994-11-02  |  20KB  |  630 lines

  1. { ────────────────────────────────────────────────────────────────────────
  2.  
  3.   This code is Copyright (c) 1994 by Jonathan E. Wright and AmoebaSoft.
  4.  
  5.   To communicate with the author, send internet mail to: NELNO@DELPHI.COM
  6.  
  7.   About this code:
  8.     A replacement for some of the stuff that Borland's CRT unit does, though
  9.     it lacks most of Borland's screen I/O stuff.  But the good part is it
  10.     replaces the BIOS keyboard handler, therefore making the buffer 255
  11.     characters instead of 15 and allowing multiple keys to be pressed and
  12.     _sensed_ at one time.  Perfect for video games.
  13.  
  14.     If you use this code in any of your programs, or as a basis for anything
  15.     else you may write, please give credit to Nelno the Amoeba.  A postcard
  16.     from your country or town would also be nice.  Send it to:
  17.  
  18.     Nelno
  19.     58 1/2 Woodland Rd.
  20.     Asheville, NC 28804-3823
  21.     USA
  22.  
  23.   ──────────────────────────────────────────────────────────────────────── }
  24.  
  25. UNIT NewCrt;
  26.  
  27. {$F+}
  28.  
  29. INTERFACE
  30.  
  31. USES
  32.   DOS, Types;
  33.  
  34. CONST
  35.   { Timer constants }
  36.   IOCount    : WORD = 0;
  37.   IOFlag     : BYTE = 0;
  38.   IOLoops    : WORD = 0;
  39.   TimerMult  : WORD = 1;
  40.   Int08Flag  : WORD = 1;
  41.   OrigRate   : WORD = 1;             { number of int 8's that will occur
  42.                                        before old int 8 vector is called }
  43.  
  44.   { NewCrt constants for KeyFlags array }
  45.  
  46.   KeyPadMinus= $4A;
  47.   LeftArrow  = $4B;
  48.   RightArrow = $4D;
  49.   KeyPadPlus = $4E;
  50.   UpArrow    = $48;
  51.   DownArrow  = $50;
  52.   Space      = $39;
  53.   KeyPad5    = $4C;
  54.   Home       = $47;
  55.   EndKey     = $4F;
  56.   PageUp     = $49;
  57.   PageDown   = $51;
  58.   Insert     = $52;
  59.   Delete     = $53;
  60.   Escape     = $01;
  61.   ScrollLock = $46;
  62.   F1         = $3B;
  63.   F2         = $3C;
  64.   F3         = $3D;
  65.   F4         = $3E;
  66.   F5         = $3F;
  67.   F6         = $40;
  68.   F7         = $41;
  69.   F8         = $42;
  70.   F9         = $43;
  71.   F10        = $44;
  72.  
  73.   Quit      : BOOLEAN = FALSE;          { set if Alt-X is pressed }
  74.  
  75.   { if a corresponding key is pressed the byte indexed by that key's
  76.     scancode will be set to > 0.  When the key is released it will be set
  77.     to 0.  Checking this array allows multiple keys to be pressed at once }
  78.   KeyFlags  : ARRAY [0..127] OF BYTE = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  79.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  80.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  81.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  82.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  83.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  84.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  85.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  86.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  87.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  88.                                         0, 0, 0, 0, 0, 0, 0, 0);
  89.  
  90.   KeyBuff   : ARRAY [0..255] OF BYTE = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  91.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  92.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  93.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  94.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  95.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  96.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  97.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  98.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  99.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  100.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  101.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  102.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  103.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  104.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  105.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  106.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  107.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  108.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  109.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  110.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  111.                                         0, 0, 0, 0);
  112.  
  113.   KeyTran   : ARRAY [0..127] OF BYTE = (000,027,049,050,051,052,053,054,055,
  114.                                         056,057,048,045,061,008,
  115.                                         009,113,119,101,114,116,121,117,105,
  116.                                         111,112,091,093,013,
  117.                                         000,097,115,100,102,103,104,106,107,
  118.                                         108,059,039,096,
  119.                                         000,000,122,120,099,118,098,110,109,
  120.                                         044,046,047,000,
  121. { spacebar row }
  122.                                         042,000,032,000,
  123. { function keys = scan code + 80h }
  124.                                         $BB,$BC,$BD,$BE,$BF,$C0,$C1,$C2,$C3,$C4,
  125. { Keypad = # code + 80 h }
  126.                                         $C5,$C6,$C7,$C8,$C9,045,$CB,$CC,$CD,043,$CF,
  127.                                         $D0,$D1,$D2,127,
  128. { Nothing }
  129.                                         000,000,000,
  130. { F11 & F12 }
  131.                                         197,198,
  132. { more Nothing }
  133.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  134.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  135.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  136.                                         0, 0, 0);
  137.  
  138.   ShiftTran : ARRAY [0..127] OF BYTE = (000,027,033,064,035,036,037,094,038,
  139.                                         042,040,041,095,043,008,
  140.                                         009,081,087,069,082,084,089,085,073,
  141.                                         079,080,123,125,013,
  142.                                         000,065,083,068,070,071,072,074,075,
  143.                                         076,058,034,126,
  144.                                         000,000,090,088,067,086,066,078,077,
  145.                                         060,062,063,000,
  146. { spacebar row }
  147.                                         042,000,032,000,
  148. { function keys = scan code + 80h }
  149.                                         187,188,189,190,191,192,193,194,195,196,
  150. { Keypad = # code + 80 h }
  151.                                         000,000,055,056,057,045,052,053,054,043,049,
  152.                                         050,051,048,046,
  153. { Nothing }
  154.                                         000,000,000,
  155. { F11 & F12 }
  156.                                         197,198,
  157. { more Nothing }
  158.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  159.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  160.                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  161.                                         0, 0, 0);
  162.  
  163.  
  164.   KeyBuffOn : BYTE = 1;              { 0 = no buff, 1 = buffer all
  165.                                        2 = do not buffer function & keypad }
  166.   KeyHead   : WORD = OFS (KeyBuff);
  167.   KeyTail   : WORD = OFS (KeyBuff);
  168.   KeyChange : BYTE = 0;
  169.   KillFlag  : BYTE = 0;
  170.  
  171. TYPE
  172.   RKeyFunc    = FUNCTION : CHAR;
  173.   KeyPrsdFunc = FUNCTION : BOOLEAN;
  174.  
  175. { newCrt variables and procedures }
  176.  
  177. VAR
  178.   Time      : BYTE;
  179.  
  180.   KeyPressed : KeyPrsdFunc;
  181.   ReadKey    : RKeyFunc;
  182.  
  183.  
  184. PROCEDURE ClrScr;
  185. PROCEDURE InitKeyboard;
  186. PROCEDURE RestoreKeyboard;
  187. PROCEDURE Delay (ms:word);
  188. PROCEDURE Sound (n : WORD);
  189. PROCEDURE NoSound;
  190. PROCEDURE StartTimer (ms : WORD);
  191. PROCEDURE StopTimer;
  192. PROCEDURE Beep;
  193. PROCEDURE ClearBuff;
  194.  
  195. { Timer variables and procedures }
  196.  
  197. VAR
  198.   Start      : LONGINT;
  199.   Finish     : LONGINT;
  200.   TotalTime  : LONGINT;
  201.  
  202. PROCEDURE StartTime;
  203. PROCEDURE StopTime;
  204. PROCEDURE SetTimer0Rate (Multiplier : WORD);
  205.  
  206.  
  207. IMPLEMENTATION
  208.  
  209. CONST
  210.   ScanCode : BYTE = 0;
  211.  
  212. VAR
  213.   OldInt9   : POINTER;
  214.   SavedExit : POINTER;
  215.  
  216. {$L KEY.OBJ}
  217.  
  218. FUNCTION  KeyPrsd : BOOLEAN; EXTERNAL;
  219. FUNCTION  RKey : CHAR; EXTERNAL;
  220. PROCEDURE NewInt9; EXTERNAL;
  221.  
  222. (* ********************************************************************** *)
  223.  
  224. PROCEDURE NewExit; FAR;
  225.  
  226. BEGIN
  227.   ExitProc := SavedExit;
  228.   RestoreKeyboard;
  229. END;
  230.  
  231. { ╔═══════════════════════════════════════════════════════════════════════╗
  232.   ║                                                                       ║
  233.   ║                                                                       ║
  234.   ╚═══════════════════════════════════════════════════════════════════════╝ }
  235.  
  236. PROCEDURE ClrScr; ASSEMBLER;
  237.  
  238. ASM
  239.   mov     ah,02
  240.   xor     dx,dx
  241.   xor     bx,bx
  242.  
  243.   int     10h    { set cursor position }
  244.  
  245.   mov     ah,09
  246.   mov     al,20h
  247.   xor     bx,bx
  248.   mov     bl,07
  249.   mov     cx,2000
  250.  
  251.   int     10h
  252. END;
  253.  
  254. { ╔═══════════════════════════════════════════════════════════════════════╗
  255.   ║                                                                       ║
  256.   ║                                                                       ║
  257.   ╚═══════════════════════════════════════════════════════════════════════╝ }
  258.  
  259. FUNCTION BIOS_KeyPressed : BOOLEAN; ASSEMBLER;
  260.  
  261. ASM
  262.   CMP     ScanCode,0
  263.   JNE     @@1
  264.   MOV     AH,1
  265.   INT     16H
  266.   MOV     AL,0
  267.   JE      @@2
  268.  
  269. @@1:
  270.   MOV     AL,1
  271.  
  272. @@2:
  273. END;
  274.  
  275. { ╔═══════════════════════════════════════════════════════════════════════╗
  276.   ║                                                                       ║
  277.   ║                                                                       ║
  278.   ╚═══════════════════════════════════════════════════════════════════════╝ }
  279.  
  280. FUNCTION BIOS_ReadKey : CHAR; ASSEMBLER;
  281.  
  282. ASM
  283.   MOV     AL,ScanCode
  284.   MOV     ScanCode,0
  285.   OR      AL,AL
  286.   JNE     @@1
  287.  
  288.   XOR     AH,AH
  289.   INT     16H
  290.  
  291.   OR      AL,AL
  292.   JNE     @@1
  293.   MOV     ScanCode,AH
  294.   OR      AH,AH
  295.   JNE     @@1
  296.   MOV     AL,'C'-64
  297. @@1:
  298. END;
  299.  
  300. { ╔═══════════════════════════════════════════════════════════════════════╗
  301.   ║                                                                       ║
  302.   ║                                                                       ║
  303.   ╚═══════════════════════════════════════════════════════════════════════╝ }
  304.  
  305. PROCEDURE InitKeyboard;
  306.  
  307. BEGIN
  308.   IF DebugKeys THEN Print ('InitKeyboard: Initializing keyboard...', $0F);
  309.   GetIntVec ($09, OldInt9);
  310.  
  311.   IF DebugKeys THEN Print ('SetInt9 : Depriving BIOS...', $0F);
  312.   SetIntVec ($09, @NewInt9);
  313.  
  314.   KeyPressed := KeyPrsd;
  315.   ReadKey := RKey;
  316. END;
  317.  
  318. { ╔═══════════════════════════════════════════════════════════════════════╗
  319.   ║                                                                       ║
  320.   ║                                                                       ║
  321.   ╚═══════════════════════════════════════════════════════════════════════╝ }
  322.  
  323. PROCEDURE RestoreKeyboard;
  324.  
  325. BEGIN
  326.   KeyPressed := BIOS_KeyPressed;
  327.   ReadKey := BIOS_ReadKey;
  328.  
  329.   IF DebugKeys THEN Print ('RestoreInt9: Re-instating BIOS handler...', $0F);
  330.   SetIntVec ($09, OldInt9);
  331. END;
  332.  
  333. { ╔═══════════════════════════════════════════════════════════════════════╗
  334.   ║                                                                       ║
  335.   ║                                                                       ║
  336.   ╚═══════════════════════════════════════════════════════════════════════╝ }
  337.  
  338. PROCEDURE Sound (n : WORD);
  339.  
  340. VAR
  341.   F  : WORD;
  342.   HF : BYTE;
  343.   LF : BYTE;
  344.  
  345. BEGIN
  346.   IF n >= 37 THEN
  347.   BEGIN
  348.     F := 1193280 DIV n;
  349.  
  350.     HF := Hi (F);
  351.     LF := Lo (F);
  352.  
  353.     Port [$43] := $B6;
  354.  
  355.     Port [$42] := LF;
  356.     Port [$42] := HF;
  357.  
  358.     asm
  359.          in al, 61h
  360.          or al, 3
  361.          out 61h, al
  362.     end;
  363.   END;
  364. END;
  365.  
  366. { ╔═══════════════════════════════════════════════════════════════════════╗
  367.   ║                                                                       ║
  368.   ║                                                                       ║
  369.   ╚═══════════════════════════════════════════════════════════════════════╝ }
  370.  
  371. PROCEDURE NoSound; ASSEMBLER;
  372.  
  373. ASM
  374.   in al, 61h
  375.   and al, 0FCh
  376.   out 61h, al
  377. END;
  378.  
  379. { ╔═══════════════════════════════════════════════════════════════════════╗
  380.   ║                                                                       ║
  381.   ║                                                                       ║
  382.   ╚═══════════════════════════════════════════════════════════════════════╝ }
  383.  
  384. PROCEDURE Delay (ms:word); ASSEMBLER;
  385.  
  386. ASM {machine independent delay function}
  387.   mov     ax,1000
  388.   mul     ms
  389.   mov     cx,dx
  390.   mov     dx,ax
  391.   mov     ah,86h
  392.   int     15h
  393. END;
  394.  
  395. { ╔═══════════════════════════════════════════════════════════════════════╗
  396.   ║                                                                       ║
  397.   ║                                                                       ║
  398.   ╚═══════════════════════════════════════════════════════════════════════╝ }
  399.  
  400. PROCEDURE StartTimer (ms : WORD); ASSEMBLER;
  401.  
  402. ASM
  403.   mov     Time,0
  404.  
  405.   mov     ah,83h
  406.   mov     al,01
  407.   int     15h
  408.  
  409.   mov     ax,1000
  410.   mul     ms
  411.   mov     cx,dx
  412.   mov     dx,ax
  413.  
  414.   mov     ax,ds
  415.   mov     es,ax
  416.   mov     bx,OFFSET Time
  417.  
  418.   xor     al,al
  419.   mov     ah,83h
  420.  
  421.   int     15h
  422. END;
  423.  
  424. { ╔═══════════════════════════════════════════════════════════════════════╗
  425.   ║                                                                       ║
  426.   ║                                                                       ║
  427.   ╚═══════════════════════════════════════════════════════════════════════╝ }
  428.  
  429. PROCEDURE StopTimer; ASSEMBLER;
  430.  
  431. ASM
  432.   mov    ah,83h
  433.   mov    al,01
  434.   int    15h
  435.  
  436.   mov    Time,0
  437. END;
  438.  
  439. { ╔═══════════════════════════════════════════════════════════════════════╗
  440.   ║                                                                       ║
  441.   ║                                                                       ║
  442.   ╚═══════════════════════════════════════════════════════════════════════╝ }
  443.  
  444. PROCEDURE Beep;
  445.  
  446. BEGIN
  447.   Sound (1000);
  448.   Delay (50);
  449.   NoSound;
  450. END;
  451.  
  452. { ╔═══════════════════════════════════════════════════════════════════════╗
  453.   ║                                                                       ║
  454.   ║                                                                       ║
  455.   ╚═══════════════════════════════════════════════════════════════════════╝ }
  456.  
  457. PROCEDURE ClearBuff;
  458.  
  459. VAR
  460.   I    : BYTE;
  461.   Key  : CHAR;
  462.  
  463. BEGIN
  464.   IF KeyPrsd THEN
  465.   REPEAT
  466.     Key := RKey;
  467.   UNTIL NOT (KeyPrsd);
  468.   Key := #0;
  469. END;
  470.  
  471. { ╔═══════════════════════════════════════════════════════════════════════╗
  472.   ║                                                                       ║
  473.   ║                                                                       ║
  474.   ╚═══════════════════════════════════════════════════════════════════════╝ }
  475.  
  476. PROCEDURE StartTime;
  477.  
  478. VAR
  479.   H, M, S, S100 : WORD;
  480.  
  481. BEGIN
  482.   GetTime (H, M, S, S100);
  483.  
  484.   Start := LONGINT (H) * LONGINT (360000) + LONGINT (M) * LONGINT (6000) + LONGINT (S) * LONGINT (100) + LONGINT (S100);
  485. END;
  486.  
  487. { ╔═══════════════════════════════════════════════════════════════════════╗
  488.   ║                                                                       ║
  489.   ║                                                                       ║
  490.   ╚═══════════════════════════════════════════════════════════════════════╝ }
  491.  
  492. PROCEDURE StopTime;
  493.  
  494. VAR
  495.   H, M, S, S100 : WORD;
  496.  
  497. BEGIN
  498.   GetTime (H, M, S, S100);
  499.  
  500.   Finish := LONGINT (H) * LONGINT (360000) + LONGINT (M) * LONGINT (6000) + LONGINT (S) * LONGINT (100) + LONGINT (S100);
  501.  
  502.   TotalTime := Finish - Start;
  503. END;
  504.  
  505. { ╔═══════════════════════════════════════════════════════════════════════╗
  506.   ║                                                                       ║
  507.   ║                                                                       ║
  508.   ╚═══════════════════════════════════════════════════════════════════════╝ }
  509.  
  510. PROCEDURE IODelay; ASSEMBLER;
  511.  
  512. ASM
  513.   mov     cx,IOCount
  514.   jcxz    @IOInit
  515.  
  516. @IODelayLoop:
  517.   loop    @IODelayLoop
  518.  
  519.   mov     sp,bp                         { exit procedure                }
  520.   pop     bp
  521.   ret
  522.  
  523. @IOInit:
  524.   mov     ax,ds                         { put data segment in es        }
  525.   mov     es,ax
  526.   mov     ax,8300h                      { wait interval                 }
  527.   mov     cx,0
  528.   mov     dx,5000                       { delay 5ms                     }
  529.   mov     bx,OFFSET IOFlag
  530.  
  531.   int     15h                           { start delay                   }
  532.  
  533.   jc      @Int15Error
  534.  
  535. @IODelayLoop2:
  536.   test    IOFlag,80h
  537.   jnz     @DelayDone
  538.   jmp     @NextLabel
  539.  
  540. @NextLabel:
  541.   loop    @IODelayLoop2
  542.  
  543.   mov     ax,100
  544.   jmp     @IOExit
  545.  
  546. @DelayDone:
  547.   mov     ax,0FFFFh                     { get number of times looped    }
  548.   sub     ax,cx
  549.   mov     IOLoops,ax
  550.  
  551.   mov     bx,1500                       { adjustment factor             }
  552.   xor     dx,dx
  553.   div     bx
  554.   cmp     ax,0
  555.   je      @IO1Delay                     { set at least 1 delay          }
  556.   jmp     @IOSet
  557.  
  558. @Int15Error:
  559.   or      ah,ah                         { int 15 busy, try again        }
  560.   jz      @IOExit                       { if an old system, set 1 delay }
  561.  
  562. @IO1Delay:
  563.   mov     ax,1
  564.  
  565. @IOSet:
  566.   mov     IOCount,ax
  567.  
  568. @IOExit:
  569. END;
  570.  
  571. { ╔═══════════════════════════════════════════════════════════════════════╗
  572.   ║                                                                       ║
  573.   ║                                                                       ║
  574.   ╚═══════════════════════════════════════════════════════════════════════╝ }
  575.  
  576. PROCEDURE SetTimer0Rate (Multiplier : WORD);
  577.  
  578. BEGIN
  579.   OrigRate := Multiplier;
  580. ASM
  581.   mov     bx,Multiplier
  582.   cmp     bx,0
  583.   ja      @Start
  584.  
  585.   inc     bx
  586.   mov     Multiplier,bx
  587.  
  588. @Start:
  589.   mov     TimerMult,bx
  590.   mov     Int08Flag,bx
  591.  
  592.   cli
  593.  
  594.   mov     al,36h                        { command for 16-bit port mode 3 }
  595.   out     43h,al
  596.  
  597.   mov     cx,IOCount
  598. @IOD1:
  599.   loop    @IOD1
  600.  
  601.   mov     ax,65535
  602.   xor     dx,dx
  603.   div     bx
  604.   out     40h,al                        { load timer 0 MSB              }
  605.  
  606.   mov     cx,IOCount
  607. @IOD2:
  608.   loop    @IOD2
  609.  
  610.   xchg    al,ah
  611.   out     40h,al                        { load timer 0 LSB              }
  612.  
  613.   sti
  614. END;
  615.   IF DebugKeys THEN PRINT ('SetTimer0Rate: ' + ST (TRUNC (Multiplier * 18.2)) + ' per second.', $0F);
  616. END;
  617. { ╔═══════════════════════════════════════════════════════════════════════╗
  618.   ║                                                                       ║
  619.   ║                                                                       ║
  620.   ╚═══════════════════════════════════════════════════════════════════════╝ }
  621. BEGIN
  622.   SavedExit := ExitProc;
  623.   ExitProc := @NewExit;
  624.  
  625.   IODelay;
  626.   IF DebugKeys THEN PRINT ('IODelay: IOCount is ' + ST (IOCount) + ', IOLoops was ' + ST (IOLoops) + '.', $0F);
  627.  
  628.   InitKeyBoard;
  629. END.
  630.