home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / 4415 / MISC.SWG < prev    next >
Text File  |  1993-10-07  |  200KB  |  1 lines

  1. SWAGOLX.EXE (c) 1993 GDSOFT  ALL RIGHTS RESERVED 00036         ANYTHING NOT OTHERWISE CLASSIFIED                                 1      05-28-9313:51ALL                      SWAG SUPPORT TEAM        BOOKISBN.PAS             IMPORT              14          {π For you Programming librarians: the following Turbo Pascal Programπ will verify any ISBN (International Standard Book Number).π}π(*******************************************************************)π Program VerifyISBN;    { Verify any ISBN number. Turbo Pascal      }π                        { 1992, 1993 Greg Vigneault                 }ππ Var    ISBNstr                     : String[16];π        loopc, ISBNlen, M, chksm    : Byte;π beginπ    WriteLn; WriteLn( 'ISBN Verification v0.1, Greg Vigneault',#10);ππ    if ( ParamCount <> 1 ) then begin   { we want just 1 input parm }π        WriteLn( 'Syntax: ISBN <ISBN#>',#7 );π        Halt(1);π    end;π    ISBNstr := ParamStr(1);                     { get ISBN# String  }π    Write( 'Checking ISBN# ', ISBNstr );π    { eliminate any non-digit Characters from the ISBN String...    }π    ISBNlen := 0;π    For loopc := 1 to orD( ISBNstr[0] ) doπ        if ( ISBNstr[ loopc ] in ['0'..'9'] ) then beginπ            inC( ISBNlen );π            ISBNstr[ ISBNlen ] := ISBNstr[ loopc ];π        end;π    { an 'X' at the end of the ISBN affects the result              }π    if ( ISBNstr[ orD( ISBNstr[0] ) ] in ['X','x'] )π        then M := 10π        else M := orD( ISBNstr[ ISBNlen ] ) - 48;π    ISBNstr[0] := CHR( ISBNlen );           { new ISBN str length   }π    chksm := 0;π    For loopc := 1 to ISBNlen-1 doπ        inC( chksm, ( orD( ISBNstr[ loopc ] ) - 48 ) * loopc );π    Write( ' <--- ' );π    if ( ( chksm MOD 11 ) = M )π        then WriteLn( 'Okay' )π        else WriteLn( 'ERRor!',#7 );π end {VerifyISBN}.π(********************************************************************)π                        2      05-28-9313:51ALL                      SWAG SUPPORT TEAM        CPAS-OBJ.PAS             IMPORT              5           REYNIR STEFANSSONππ> Does anyone know of any way to convert a .TPU to a .BIN File toπ> use BIN2OBJ.EXE and then load it as an external? Any helpπ> appreciated...ππIt's a bit round-the-block, but you might get some exercise out of it,πassuming you have the source code:ππ1) Smash the source into C With a code converter.ππ2) Declare the Procedures as `void far PASCAL' and the Functions asπ   `appropriate_Type far PASCAL'.ππ3) Compile it With Turbo C or similar.ππ                                                3      05-28-9313:51ALL                      SWAG SUPPORT TEAM        DBASE4.PRG               IMPORT              39          {πHello every one... Guys and gals is there any such a thing that you canπuse turbp pascal 6 with Dbase IV.. what I heard is I can.πif yes tell me how you export or whatever to use two of thewmπtogether,,,ππYes there is! I have been using it for some time now in dBase as I useπan XT and dBase's editor is too slow when the program has quite a fewπlines (some are 5,000) and the system just kind of dies. When I use TP'sπIDE the editor is FAST!!!! So after reading the books I designed aπprogram in order to use TP as using it in the TEDIT CONFIG.DB commandπwouldn't work as it needed more memory (I only have 640k).π}πππIn dBase's setup program, under the FILES MENU enter in eitherπPRGAPPLIC (overrides Application Control in the ASSIST menu only!) orπ Entry  - C:\DBASEIV\EDIT2.PRGπ Exit   - emptyπ Layout - emptyπPRGCC (allows you to use OPEN CUSTOM UTILIY option under Catalog Menu).π Entry  - emptyπ Exit   - emptyπ Layout - C:\DBASEIV\EDIT2.PRGππI am currently using PRGAPPLIC as I do most of my work in the ControlπCenter anyhow and don't need the Application Generator. Note - PRGCCπwill not pull in a PRG file unless you change the source code to ask forπone.ππHere is the dBase program that calls Turbo Pascal:ππ* <T>Program ----> EDIT2.PRGπ* <D>Language ---> dBase IV 1.5π* <P>Author -----> P.A.T. Systems° C.1993π* <T>Creation date -> 07/22/1992π* <L>Last update ---> 01/06/1993ππ* <G>From-> Control Centerπ* <N>To---> Noneπ* <T>Subs-> Noneππ* This program invokes an External Editor such as Turbo Pascal 6.0'sπ* (TP) Desktop Editor by using the PRGAPPLIC setup in the Config.dbπ* file. Even though it is only for Entry Programs, with some trickyπ* commands we can get it to invoke an External Editor such as TP.ππ* Although I can't do any Compiling or Help Lookup (another use for theπ* Manuals), it still is a great and FAST!!!! Editor to work with.ππ* This program will work with any editor that will accept a filenameπ* as a parameter.ππ* Example  TURBO filename.prg  (Turbo Pascal) ORπ* WP filename.prg     (Word Perfect)ππ* As I am used to TP's Editor, I wished I could use it when I wanted toπ* edit a program.  Especially a long program that when loaded intoπ* dBase's editor is extremely slow, but in TP, editing is FAST!!! Andπ* with dBase IV 1.5's NEW Open Architecture, I now have a way to do it.ππ* This program uses the RUN() function to swap out memory to disk soπ* that the editor can load in.  With the TEDIT command in the Config.dbπ* setup, there wasn't enough memory (on an XT) to load in the editor.π* So I read the manuals (Yes, I do read them occasionally!) and figuredπ* out a way to use an External Editor by utilizing the Control Center'sπ* NEW Open Architecture.ππ* First, copy this program into dBase's Startup Directory.ππ* You next have to change dBase's setup using DBSETUP at the DOS promptπ* and load in the current configuration and then on the Files Menuπ* change the option of PRGAPPLIC so that it readsπ* "C:\DBASEIV\EDIT2.PRG". Once done, save the new configuration andπ* exit to DOS.  Then enter dBase in your usual way.  Next, create orπ* edit an existing program through the Control Center's Applicationπ* Menu.  The Control Center will execute this .PRG file (it willπ* automatically compile it) and load up your Editor with the programπ* ready to edit!ππ* ***Note***π*  This program will only work through the Control Center.  If you typeπ*  "MODI COMM filename" at the DOT PROMPT, the original editor will beπ*  loaded as the Open Architecture only works with the Control Centerπ*  applications.ππ* Hope you enjoy this program!!!!ππ* Parameters passed from Control Center to Application Designerπ* Panel Name, Filename (Programming in dBase IV - Chapter 17, pg 4)ππPARAMETERS cPanelName, cFileNameππ* Clear screen and turn on cursorπ* (MODI COMM turns off cursor when loading and then turns it backπ* on when editing - Why? I don't know. When I invoked my editor, Iπ* found that the cursor had disappeared, so I included this Commandπ* and my cursor came back!)ππCLEARπSET CURSOR ONππ* Store Editor's filename and dBase .PRG Filename to variable forπ* Macro Executionππ* (You can enter your own Editor's file name here if you wish, justπ* include the FULL PATH NAME just in case, and don't forget the SPACE!)ππ* uncomment this line for PRGCC or it will load CATALOG FILEπ* STORE "" TO cFileNameπSTORE "D:\TP\TURBO " + cFileName TO cExecEditππ* Invoke RUN() function to swap out memoryππSTORE RUN("&cExecEdit",.T.) TO nRunππ* Change filename so we can erase .DBO file for proper compilingπ* If creating a new file, no need to erase .DBO fileππIF .NOT. ISBLANK(cFileName)π   STORE SUBSTR(cFileName, 1, AT(".PRG", cFileName)) + "DBO" TO ;π    cExecEditππ* Erase the .DBO fileππ   ERASE &cExecEditπENDIFππ* Return directly to Control Center instead of invoking Command EditorππRETURN TO MASTERππ* Endπ          4      05-28-9313:51ALL                      SWAG SUPPORT TEAM        FLIPLAY.PAS              IMPORT              255         {$G+}ππProgram FliPlayer;ππ{  v1.1 made by Thaco   }π{ (c) EPOS, August 1992 }πππConstπ  CLOCK_HZ              =4608;                   { Frequency of clock }π  MONItoR_HZ            =70;                     { Frequency of monitor }π  CLOCK_SCALE           =CLOCK_HZ div MONItoR_HZ;ππ  BUFFERSIZE            =$FFFE;                  { Size of the framebuffer, must be an even number }π  CDATA                 =$040;                   { Port number of timer 0 }π  CMODE                 =$043;                   { Port number of timers control Word }π  CO80                  =$3;                     { Number For standard Text mode }π  KEYBOARD              =28;                     { Numbers returned by PorT[$64] indicating what hardware caused inT 09/the - }π  MOUSE                 =60;                     { - number on PorT[$60] }π  MCGA                  =$13;                    { Number For MCGA mode }π  MCGACheck:Boolean     =True;                   { Variable For MCGA checking }π  UseXMS:Boolean        =True;                   { Variable For XMS usage }π  XMSError:Byte         =0;                      { Variable indicating the errornumber returned from the last XMS operation }ππTypeπ  EMMStructure          =Recordπ                           BytestoMoveLo,              { Low Word of Bytes to move. NB: Must be even! }π                           BytestoMoveHi,              { High Word of Bytes to move }π                           SourceHandle,               { Handle number of source (SH=0 => conventional memory) }π                           SourceoffsetLo,             { Low Word of source offset, or ofS if SH=0 }π                           SourceoffsetHi,             { High Word of source offset, or SEG if SH=0 }π                           DestinationHandle,          { Handle number of destination (DH=0 => conventional memory) }π                           DestinationoffsetLo,        { Low Word of destination offset, or ofS if DH=0 }π                           DestinationoffsetHi  :Word; { High Word of destination offset, or SEG if DH=0 }π                         end;π  HeaderType            =Array[0..128] of Byte;  { A bufferType used to read all kinds of headers }πππVarπ  Key,                                           { Variable used to check if a key has been pressed }π  OldKey                :Byte;                   { Variable used to check if a key has been pressed }π  XMSRecord             :EMMStructure;           { Variable For passing values to the XMS routine }π  InputFile             :File;                   { Variable For the incomming .FLI File }π  Header                :HeaderType;             { Buffer used to read all kinds of headers }π  Counter,                                       { General purpose counter }π  Speed                 :Integer;                { Timedifference in video tics from one frame to the next }π  FileCounter,                                   { Variable telling the point to read from in the File stored in XMS }π  FileSize,                                      { Size of the .FLI-File }π  FrameSize,                                     { Variable indicating the datasize of current frame }π  NextTime,                                      { Variable saying when it is time to move on to the next frame }π  TimeCounter,                                   { Holding the current time in video tics }π  SecondPos             :LongInt;                { Number of Bytes to skip from the start of the .FLI File when starting - }π                                                 { - from the beginning again }π  Buffer,                                        { Pointer to the Framebuffer }π  XMSEntryPoint         :Pointer;                { Entry point of the XMS routine in memory }π  SpeedString           :String[2];              { String used to parse the -sNN command }π  FileName              :String[13];             { String holding the name of the .FLI-File }π  BufferHandle,                                  { Handle number returned from the XMS routine }π  BytesRead,                                     { Variable telling the numbers of Bytes read from the .FLI File }π  FrameNumber,                                   { Number of the current frame }π  Frames,                                        { total number of frames }π  Chunks                :Word;                   { total number of chunks in a frame }πππFunction UpCaseString(Streng:String):String;π{ takes a String and convert all letters to upperCase }πVarπ  DummyString           :String;π  Counter               :Integer;πbeginπ  DummyString:='';π  For Counter:=1 to Length(Streng) doπ    DummyString:=DummyString+UpCase(Streng[Counter]);π  UpCaseString:=DummyString;πend;πππProcedure InitMode(Mode:Word); Assembler;π{ Uses BIOS interrupts to set a videomode }πAsmπ  mov  ax,Modeπ  int  10hπend;πππFunction ModeSupport(Mode:Word):Boolean; Assembler;π{ Uses BIOS interrupts to check if a videomode is supported }πLabel Exit, Last_Modes, No_Support, Supported;πVarπ  DisplayInfo           :Array[1..64] of Byte;   { Array For storing Functionality/state inFormation }πAsmπ  push esππ  mov  ah,1Bh                                    { the Functionality/state inFormation request at int 10h }π  mov  bx,0                                      { 0 = return Functionality/state inFormation }π  push ds                                        { push DS on the stack and pop it into ES so ES:DI could be used to - }π  pop  es                                        { - address DisplayInfo, as demanded of the interrupt Function }π  mov  di,offset DisplayInfoπ  int  10hππ  les  di,[dWord ptr es:di]                      { The first dWord in the buffer For state inFormation is the address - }π                                                 { - of static funtionality table }π  mov  cx,Mode                                   { Can only check For the 0h-13h modes }π  cmp  cx,13hπ  ja   No_Support                                { Return 'no support' For modes > 13h }ππ  mov  ax,1                                      { Shift the right Byte the right - }π                                                 { - times and test For the right - }π  cmp  cx,10h                                    { - bit For knowing if the       - }π  jae  Last_Modes                                { - videomode is supported       - }π                                                 { -                                }π  shl  ax,cl                                     { -                                }π  test ax,[Word ptr es:di+0]                     { -                                }π  jz   No_Support                                { -                                }π  jmp  Supported                                 { -                                }π                                                 { -                                }πLast_Modes:                                      { -                                }π  sub  cx,10h                                    { -                                }π  shl  ax,cl                                     { -                                }π  test al,[Byte ptr es:di+2]                     { -                                }π  jz   No_Support                                { -                                }ππSupported:π  mov  al,1                                      { AL=1 makes the Function return True }π  jmp  ExitππNo_Support:π  mov  al,0                                      { AL=0 makes the Function return True }ππExit:π  pop  esπend;πππFunction NoXMS:Boolean; Assembler;π{ checks out if there is a XMS driver installed, and in Case it initialize theπ  XMSEntryPoint Variable }πLabel JumpOver;πAsmπ  push esππ  mov  ax,4300h                                  { AX = 4300h => inSTALLATION CHECK }π  int  2Fh                                       { use int 2Fh Extended MEMorY SPECifICATION (XMS) }π  mov  bl,1                                      { use BL as a flag to indicate success }π  cmp  al,80h                                    { is a XMS driver installed? }π  jne  JumpOverπ  mov  ax,4310h                                  { AX = 4310h => GET DRIVER ADDRESS }π  int  2Fhπ  mov  [Word ptr XMSEntryPoint+0],BX             { initialize low Word of XMSEntryPoint }π  mov  [Word ptr XMSEntryPoint+2],ES             { initialize high Word of XMSEntryPoint }π  mov  bl,0                                      { indicate success }πJumpOver:π  mov  al,bl                                     { make the Function return True (AH=1) or False (AH=0) }ππ  pop  esπend;πππFunction XMSMaxAvail:Word; Assembler;π{ returns size of largest contiguous block of XMS in kilo (1024) Bytes }πLabel JumpOver;πAsmπ  mov  ah,08h                                    { 'Query free Extended memory' Function }π  mov  XMSError,0                                { clear error Variable }π  call [dWord ptr XMSEntryPoint]π  or   ax,ax                                     { check For error }π  jnz  JumpOverπ  mov  XMSError,bl                               { errornumber stored in BL }πJumpOver:                                        { AX=largest contiguous block of XMS }πend;πππFunction XMSGetMem(SizeInKB:Word):Word; Assembler;π{ allocates specified numbers of kilo (1024) Bytes of XMS and return a handleπ  to this XMS block }πLabel JumpOver;πAsmπ  mov  ah,09h                                    { 'Allocate Extended memory block' Function }π  mov  dx,SizeInKB                               { number of KB requested }π  mov  XMSError,0                                { clear error Variable }π  call [dWord ptr XMSEntryPoint]π  or   ax,ax                                     { check For error }π  jnz  JumpOverπ  mov  XMSError,bl                               { errornumber stored in BL }πJumpOver:π  mov  ax,dx                                     { return handle number to XMS block }πend;πππProcedure XMSFreeMem(Handle:Word); Assembler;πLabel JumpOver;πAsmπ  mov  ah,0Ah                                    { 'Free Extended memory block' Function }π  mov  dx,Handle                                 { XMS's handle number to free }π  mov  XMSError,0                                { clear error Variable }π  call [dWord ptr XMSEntryPoint]π  or   ax,ax                                     { check For error }π  jnz  JumpOverπ  mov  XMSError,bl                               { errornumber stored in BL }πJumpOver:πend;πππProcedure XMSMove(Var EMMParamBlock:EMMStructure); Assembler;πLabel JumpOver;πAsmπ  push dsπ  push esπ  push dsπ  pop  esπ  mov  ah,0Bh                                    { 'Move Extended memory block' Function }π  mov  XMSError,0                                { clear error Variable }π  lds  si,EMMParamBlock                          { DS:SI -> data to pass to the XMS routine }π  call [dWord ptr es:XMSEntryPoint]π  or   ax,ax                                     { check For error }π  jnz  JumpOverπ  mov  XMSError,bl                               { errornumber stored in BL }πJumpOver:π  pop  esπ  pop  dsπend;πππProcedure ExitDuetoXMSError;πbeginπ  InitMode(CO80);π  WriteLn('ERRor! XMS routine has reported error ',XMSError);π  XMSFreeMem(BufferHandle);π  Halt(0);πend;πππProcedure GetBlock(Var Buffer; Size:Word);π{ reads a specified numbers of data from a diskFile or XMS into a buffer }πVarπ  XMSRecord             :EMMStructure;π  NumberofBytes         :Word;πbeginπ  if UseXMS thenπ  beginπ    NumberofBytes:=Size;π    if Size MOD 2=1 thenπ      Inc(NumberofBytes);  { one must allways ask For a EQUAL number of Bytes }π    With XMSRecord doπ    beginπ      BytestoMoveLo      :=NumberofBytes;π      BytestoMoveHi      :=0;π      SourceHandle       :=BufferHandle;π      SourceoffsetLo     :=FileCounter MOD 65536;π      SourceoffsetHi     :=FileCounter div 65536;π      DestinationHandle  :=0;π      DestinationoffsetLo:=ofs(Buffer);π      DestinationoffsetHi:=Seg(Buffer);π    end;π    XMSMove(XMSRecord);π    if XMSError<>0 thenπ      ExitDuetoXMSError;π    Inc(FileCounter,Size);π  endπ  elseπ    BlockRead(InputFile,Buffer,Size);πend;πππProcedure InitClock; Assembler; {Taken from the FLILIB source}πAsmπ  mov  al,00110100b                             { put it into liNear count instead of divide by 2 }π  out  CMODE,alπ  xor  al,alπ  out  CDATA,alπ  out  CDATA,alπend;πππFunction GetClock:LongInt; Assembler; {Taken from the FLILIB source}π{ this routine returns a clock With occassional spikes where timeπ  will look like its running backwards 1/18th of a second.  The resolutionπ  of the clock is 1/(18*256) = 1/4608 second.  66 ticks of this clockπ  are supposed to be equal to a monitor 1/70 second tick.}πAsmπ  mov  ah,0                                     { get tick count from Dos and use For hi 3 Bytes }π  int  01ah                                     { lo order count in DX, hi order in CX }π  mov  ah,dlπ  mov  dl,dhπ  mov  dh,clππ  mov  al,0                                 { read lo Byte straight from timer chip }π  out  CMODE,al                                     { latch count }π  mov  al,1π  out  CMODE,al                                     { set up to read count }π  in   al,CDATA                                     { read in lo Byte (and discard) }π  in   al,CDATA                                     { hi Byte into al }π  neg  al                                     { make it so counting up instead of down }πend;πππProcedure TreatFrame(Buffer:Pointer;Chunks:Word); Assembler;π{ this is the 'workhorse' routine that takes a frame and put it on the screen }π{ chunk by chunk }πLabelπ  Color_Loop, Copy_Bytes, Copy_Bytes2, Exit, Fli_Black, Fli_Brun, Fli_Color,π  Fli_Copy, Fli_Lc, Fli_Loop, Jump_Over, Line_Loop, Line_Loop2, Next_Line,π  Next_Line2, Pack_Loop, Pack_Loop2;πAsmπ  cli                                            { disable interrupts }π  push dsπ  push es                                        π  lds  si,Buffer                                 { let DS:SI point at the frame to be drawn }ππFli_Loop:                                        { main loop that goes through all the chunks in a frame }π  cmp  Chunks,0                                  { are there any more chunks to draw? }π  je   Exitπ  dec  Chunks                                    { decrement Chunks For the chunk to process now }ππ  mov  ax,[Word ptr ds:si+4]                     { let AX have the ChunkType }π  add  si,6                                      { skip the ChunkHeader }ππ  cmp  ax,0Bh                                    { is it a FLI_COLor chunk? }π  je   Fli_Colorπ  cmp  ax,0Ch                                    { is it a FLI_LC chunk? }π  je   Fli_Lcπ  cmp  ax,0Dh                                    { is it a FLI_BLACK chunk? }π  je   Fli_Blackπ  cmp  ax,0Fh                                    { is it a FLI_BRUN chunk? }π  je   Fli_Brunπ  cmp  ax,10h                                    { is it a FLI_COPY chunk? }π  je   Fli_Copyπ  jmp  Fli_Loop                                  { This command should not be necessary since the Program should make one - }π                                                 { - of the other jumps }ππFli_Color:π  mov  bx,[Word ptr ds:si]                       { number of packets in this chunk (allways 1?) }π  add  si,2                                      { skip the NumberofPackets }π  mov  al,0                                      { start at color 0 }π  xor  cx,cx                                     { reset CX }ππColor_Loop:π  or   bx,bx                                     { set flags }π  jz   Fli_Loop                                  { Exit if no more packages }π  dec  bx                                        { decrement NumberofPackages For the package to process now }ππ  mov  cl,[Byte ptr ds:si+0]                     { first Byte in packet tells how many colors to skip }π  add  al,cl                                     { add the skiped colors to the start to get the new start }π  mov  dx,$3C8                                   { PEL Address Write Mode Register }π  out  dx,al                                     { tell the VGA card what color we start changing }ππ  inc  dx                                        { at the port abow the PEL_A_W_M_R is the PEL Data Register }π  mov  cl,[Byte ptr ds:si+1]                     { next Byte in packet tells how many colors to change }π  or   cl,cl                                     { set the flags }π  jnz  Jump_Over                                 { if NumberstoChange=0 then NumberstoChange=256 }π  inc  ch                                        { CH=1 and CL=0 => CX=256 }πJump_Over:π  add  al,cl                                     { update the color to start at }π  mov  di,cx                                     { since each color is made of 3 Bytes (Red, Green & Blue) we have to - }π  shl  cx,1                                      { - multiply CX (the data counter) With 3 }π  add  cx,di                                     { - CX = old_CX shl 1 + old_CX   (the fastest way to multiply With 3) }π  add  si,2                                      { skip the NumberstoSkip and NumberstoChange Bytes }π  rep  outsb                                     { put the color data to the VGA card FAST! }ππ  jmp  Color_Loop                                { finish With this packet - jump back }πππFli_Lc:π  mov  ax,0A000hπ  mov  es,ax                                     { let ES point at the screen segment }π  mov  di,[Word ptr ds:si+0]                     { put LinestoSkip into DI - }π  mov  ax,di                                     { - to get the offset address to this line we have to multiply With 320 - }π  shl  ax,8                                      { - DI = old_DI shl 8 + old_DI shl 6 - }π  shl  di,6                                      { - it is the same as DI = old_DI*256 + old_DI*64 = old_DI*320 - }π  add  di,ax                                     { - but this way is faster than a plain mul }π  mov  bx,[Word ptr ds:si+2]                     { put LinestoChange into BX }π  add  si,4                                      { skip the LinestoSkip and LinestoChange Words }π  xor  cx,cx                                     { reset cx }ππLine_Loop:π  or   bx,bx                                     { set flags }π  jz  Fli_Loop                                   { Exit if no more lines to change }π  dec  bxππ  mov  dl,[Byte ptr ds:si]                       { put PacketsInLine into DL }π  inc  si                                        { skip the PacketsInLine Byte }π  push di                                        { save the offset address of this line }ππPack_Loop:π  or   dl,dl                                     { set flags }π  jz   Next_Line                                 { Exit if no more packets in this line }π  dec  dlπ  mov  cl,[Byte ptr ds:si+0]                     { put BytestoSkip into CL }π  add  di,cx                                     { update the offset address }π  mov  cl,[Byte ptr ds:si+1]                     { put BytesofDatatoCome into CL }π  or   cl,cl                                     { set flags }π  jns  Copy_Bytes                                { no SIGN means that CL number of data is to come - }π                                                 { - else the next data should be put -CL number of times }π  mov  al,[Byte ptr ds:si+2]                     { put the Byte to be Repeated into AL }π  add  si,3                                      { skip the packet }π  neg  cl                                        { Repeat -CL times }π  rep  stosbπ  jmp  Pack_Loop                                 { finish With this packet }ππCopy_Bytes:                                      π  add  si,2                                      { skip the two count Bytes at the start of the packet }π  rep  movsbπ  jmp  Pack_Loop                                 { finish With this packet }ππNext_Line:π  pop  di                                        { restore the old offset address of the current line }π  add  di,320                                    { offset address to the next line }π  jmp  Line_LoopπππFli_Black:π  mov  ax,0A000hπ  mov  es,ax                                     { let ES:DI point to the start of the screen }π  xor  di,diπ  mov  cx,32000                                  { number of Words in a screen }π  xor  ax,ax                                     { color 0 is to be put on the screen }π  rep  stoswπ  jmp  Fli_Loop                                  { jump back to main loop }πππFli_Brun:π  mov  ax,0A000hπ  mov  es,ax                                     { let ES:DI point at the start of the screen }π  xor  di,diπ  mov  bx,200                                    { numbers of lines in a screen }π  xor  cx,cxππLine_Loop2:π  mov  dl,[Byte ptr ds:si]                       { put PacketsInLine into DL }π  inc  si                                        { skip the PacketsInLine Byte }π  push di                                        { save the offset address of this line }ππPack_Loop2:π  or   dl,dl                                     { set flags }π  jz   Next_Line2                                { Exit if no more packets in this line }π  dec  dlπ  mov  cl,[Byte ptr ds:si]                       { put BytesofDatatoCome into CL }π  or   cl,cl                                     { set flags }π  js   Copy_Bytes2                               { SIGN meens that CL number of data is to come - }π                                                 { - else the next data should be put -CL number of times }π  mov  al,[Byte ptr ds:si+1]                     { put the Byte to be Repeated into AL }π  add  si,2                                      { skip the packet }π  rep  stosbπ  jmp  Pack_Loop2                                { finish With this packet }ππCopy_Bytes2:π  inc  si                                        { skip the count Byte at the start of the packet }π  neg  cl                                        { Repeat -CL times }π  rep  movsbπ  jmp  Pack_Loop2                                { finish With this packet }ππNext_Line2:π  pop  di                                        { restore the old offset address of the current line }π  add  di,320                                    { offset address to the next line }π  dec  bx                                        { any more lines to draw? }π  jnz  Line_Loop2π  jmp  Fli_Loop                                  { jump back to main loop }πππFli_Copy:π  mov  ax,0A000hπ  mov  es,ax                                     { let ES:DI point to the start of the screen }π  xor  di,diπ  mov  cx,32000                                  { number of Words in a screen }π  rep  movswπ  jmp  Fli_Loop                                  { jump back to main loop }πππExit:π  sti                                            { enable interrupts }π  pop  esπ  pop  dsπend;ππππbeginπ  WriteLn;π  WriteLn('.FLI-Player v1.1 by Thaco');π  WriteLn('  (c) EPOS, August 1992');π  WriteLn;π  if ParamCount=0 then                           { if no input parameters then Write the 'usage Text' }π  beginπ    WriteLn('USAGE: FLIPLAY <options> <Filename>');π    WriteLn('                   '+#24+'         '+#24);π    WriteLn('                   │         └──  Filename of .FLI File');π    WriteLn('                   └────────────  -d   = Do not use XMS');π    WriteLn('                                  -i   = InFormation about the Program');π    WriteLn('                                  -n   = No checking of MCGA mode support');π    WriteLn('                                  -sNN = Set playspeed to NN video ticks (0-99)');π    WriteLn('                                         ( NN=70 ≈ frame Delay of 1 second )');π    Halt(0);π  end;ππ  For Counter:=1 to ParamCount do                { search through the input parameters For a -Info option }π    if Pos('-I',UpCaseString(ParamStr(Counter)))<>0 thenπ    beginπ      WriteLn('Program inFormation:');π      WriteLn('This Program plays animations (sequences of pictures) made by Programs like',#10#13,π              'Autodesk Animator (so called .FLI-Files). The Program decodes the .FLI File,',#10#13,π              'frame by frame, and Uses the systemclock For mesuring the time-Delay between',#10#13,π              'each frame.');π      WriteLn('Basis For the Program was the FliLib package made by Jim Kent, but since the',#10#13,π              'original source was written in C, and I am not a good C-Writer, I decided',#10#13,π              'to Write my own .FLI-player in Turbo Pascal v6.0.');π      WriteLn('This Program was made by Eirik Milch Pedersen (thaco@solan.Unit.no).');π      WriteLn('Copyright Eirik Pedersens Own SoftwareCompany (EPOS), August 1992');π      WriteLn;π      WriteLn('Autodesk Animator is (c) Autodesk Inc');π      WriteLn('FliLib is (c) Dancing Flame');π      WriteLn('Turbo Pascal is (c) Borland International Inc');π      Halt(0);π    end;ππ  Speed:=-1;π  Counter:=1;π  While (Copy(ParamStr(Counter),1,1)='-') and (ParamCount>=Counter) do { search through the input parameters to assemble them }π  beginπ   if Pos('-D',UpCaseString(ParamStr(Counter)))<>0 then  { do not use XMS For storing the File into memory }π     UseXMS:=Falseπ   elseπ     if Pos('-N',UpCaseString(ParamStr(Counter)))<>0 then  { do not check For a vga card present }π       MCGACheck:=Falseπ     elseπ       if Pos('-S',UpCaseString(ParamStr(Counter)))<>0 then { speed override has been specified }π       beginπ         SpeedString:=Copy(ParamStr(Counter),3,2);  { cut out the NN parameter }π         if not(SpeedString[1] in ['0'..'9']) or    { check if the NN parameter is legal }π            (not(SpeedString[2] in ['0'..'9',' ']) and (Length(SpeedString)=2)) thenπ         beginπ           WriteLn('ERRor! Can not parse speed ''',SpeedString,'''.');π           Halt(0);π         end;π         Speed:=Byte(SpeedString[1])-48;  { take the first number, in ASCII, and convert it to a standard number }π         if Length(SpeedString)=2 then    { if there is two numbers then multiply the first With 10 and add the next }π           Speed:=Speed*10+Byte(SpeedString[2])-48;π         Speed:=Speed*CLOCK_SCALE;        { convert the speed to number of clock tics }π       end;π   Inc(Counter);π  end;ππ  if ParamCount<Counter thenπ  beginπ    WriteLn('ERRor! No Filename specified.');π    Halt(0);π  end;ππ  FileName:=UpCaseString(ParamStr(Counter));π  if Pos('.',FileName)=0 then  { find out if there exist a . in the Filename }π    FileName:=FileName+'.FLI'; { if not then add the .FLI extension on the Filename }ππ  if MaxAvail<BUFFERSIZE then   { check if there is enough memory to the frame buffer }π  beginπ    WriteLn('ERRor! Can not allocate enough memory to a frame buffer.');π    Halt(0);π  end;ππ  GetMem(Buffer,BUFFERSIZE);π  Assign(InputFile,FileName);π  Reset(InputFile,1);π  if Ioresult<>0 then  { has an error occured during opening the File? }π  beginπ    WriteLn('ERRor! Can not open File ''',FileName,'''.');π    Halt(0);π  end;ππ  if not(MCGACheck) or ModeSupport(MCGA) thenπ    InitMode(MCGA)π  elseπ  beginπ    WriteLn('ERRor! Video mode 013h - 320x200x256 colors - is not supported.');π    Halt(0);π  end;ππ  BlockRead(InputFile,Header,128);  { read the .FLI main header }ππ  if not((Header[4]=$11) and (Header[5]=$AF)) then  { check if the File has got the magic number }π  beginπ    InitMode(CO80);π    WriteLn('ERRor! File ''',FileName,''' is of a wrong File Type.');π    Halt(0);π  end;ππ  if NoXMS then  { if no XMS driver present then do not use XMS }π    UseXMS:=False;ππ  if UseXMS thenπ  beginπ    FileSize:=Header[0]+256*(LongInt(Header[1])+256*(LongInt(Header[2])+256*LongInt(Header[3])));π    if XMSMaxAvail<=(FileSize+1023) SHR 10 then  { is there enough XMS (rounded up to Nearest KB) availible? }π    beginπ      WriteLn('ERRor! not enough XMS For the File');π      Halt(0);π    endπ    elseπ    beginπ      Seek(InputFile,0);  { skip back to start of .FLI-File to put it all into XMS }π      BufferHandle:=XMSGetMem((FileSize+1023) SHR 10);  { allocate XMS For the whole .FLI File }π      FileCounter:=0;π      Repeatπ        BlockRead(InputFile,Buffer^,BUFFERSIZE,BytesRead);  { read a part from the .FLI File }π        if BytesRead MOD 2=1 then  { since BUFFERSIZE shoud be an even number, the only time this triggers is the last part }π          Inc(BytesRead);          { must be done because the XMS routine demands an even number of Bytes to be moved }π        if BytesRead<>0 thenπ        beginπ          With XMSRecord do  { put data into the XMSRecord }π          beginπ            BytestoMoveLo      :=BytesRead;π            BytestoMoveHi      :=0;π            SourceHandle       :=0;π            SourceoffsetLo     :=ofs(Buffer^);π            SourceoffsetHi     :=Seg(Buffer^);π            DestinationHandle  :=BufferHandle;π            DestinationoffsetLo:=FileCounter MOD 65536;π            DestinationoffsetHi:=FileCounter div 65536;π          end;π          XMSMove(XMSRecord);   { move Bytes to XMS }π          if XMSError<>0 then   { have any XMS errors occured? }π            ExitDuetoXMSError;π          Inc(FileCounter,BytesRead);  { update the offset into XMS where to put the next Bytes }π        end;π      Until BytesRead<>BUFFERSIZE;  { Repeat Until Bytes read <> Bytes tried to read => end of File }π    end;π    FileCounter:=128;  { we continue (after reading the .FLI File into XMS) right after the .FLI main header }π  end;ππ  Frames:=Header[6]+Header[7]*256;  { get the number of frames from the .FLI-header }π  if Speed=-1 then                  { if speed is not set by a speed override then get it from the .FLI-header }π    Speed:=(Header[16]+Integer(Header[17])*256)*CLOCK_SCALE;π  InitClock;  { initialize the System Clock }π  OldKey:=PorT[$60];  { get the current value from the keyboard }π  Key:=OldKey;        { and set the 'current key' Variable to the same value }ππ  GetBlock(Header,16);  { read the first frame-header }π  FrameSize:=Header[0]+256*(LongInt(Header[1])+256*(LongInt(Header[2])+256*LongInt(Header[3])))-16;  { calculate framesize }π  SecondPos:=128+16+FrameSize;  { calculate what position to skip to when the .FLI is finished and is going to start again - }π                                { the position = .FLI-header + first_frame-header + first_framesize }π  Chunks:=Header[6]+Header[7]*256;  { calculate number of chunks in frame }π  GetBlock(Buffer^,FrameSize);  { read the frame into the framebuffer }π  TreatFrame(Buffer,Chunks);  { treat the first frame }ππ  TimeCounter:=GetClock;  { get the current time }ππ  {π    The first frame must be handeled separatly from the rest. This is because the rest of the frames are updates/changes of theπ    first frame.π    At the end of the .FLI-File there is one extra frame who handles the changes from the last frame to the first frame.π  }ππ  Repeatπ    FrameNumber:=1;  { we start at the first frame (after the initial frame) }π    Repeatπ      GetBlock(Header,16);  { read frame-header }π      FrameSize:=Header[0]+256*(LongInt(Header[1])+256*(LongInt(Header[2])+256*LongInt(Header[3])))-16;  { size of frame }π      if FrameSize<>0 then  { sometimes there are no changes from one frame to the next (used For extra Delays). In such - }π                            { - Cases the size of the frame is 0 and we don't have to process them }π      beginπ        Chunks:=Header[6]+Header[7]*256;  { calculate number of chunks in the frame }π        GetBlock(Buffer^,FrameSize);  { read the frame into the framebuffer }π        TreatFrame(Buffer,Chunks);  { treat the frame }π      end;ππ      NextTime:=TimeCounter+Speed;   { calculate the Delay to the next frame }π      While TimeCounter<NextTime do  { wait For this long }π        TimeCounter:=GetClock;ππ      if PorT[$64]=KEYBOARD then   { check if the value at the keyboard port is caused by a key pressed }π        Key:=PorT[$60];            { get the current value from the keyboard }π      Inc(FrameNumber);  { one frame finished, over to the next one }π    Until (FrameNumber>Frames) or (Key<>OldKey);  { Repeated Until we come to the last frame or a key is pressed }ππ    if UseXMS thenπ      FileCounter:=SecondPosπ    elseπ      Seek(InputFile,SecondPos);  { set current position in the File to the second frame }ππ  Until Key<>OldKey;  { Exit the loop if a key has been pressed }ππ  InitMode(CO80);  { get back to Text mode }ππ  Close(InputFile);            { be a kind boy and close the File beFore we end the Program }π  FreeMem(Buffer,BUFFERSIZE);  { and free the framebuffer }ππ  if UseXMS thenπ    XMSFreeMem(BufferHandle);πEND.                                                                                                                          5      05-28-9313:51ALL                      SWAG SUPPORT TEAM        GLOBALS.PAS              IMPORT              146         Unit globals;ππ{ Use this Unit For Procedures, Functions and Variables that every Program youπ  Write will share.π}ππInterfaceππUses π  Dos;π  πTypeπ  str1 = String[1]; str2 = String[2]; str3 = String[3];π  str4 = String[4]; str5 = String[5]; str6 = String[6];π  str7 = String[7]; str8 = String[8]; str9 = String[9];π  str10 = String[10]; str11 = String[11]; str12 = String[12];π  str13 = String[13]; str14 = String[14]; str15 = String[15];π  str16 = String[16]; str17 = String[17]; str18 = String[18];π  str19 = String[19]; str20 = String[20]; str21 = String[21];π  str22 = String[22]; str23 = String[23]; str24 = String[24];π  str25 = String[25]; str26 = String[26]; str27 = String[27];π  str28 = String[28]; str29 = String[29]; str30 = String[30];π  str31 = String[31]; str32 = String[32]; str33 = String[33];π  str34 = String[34]; str35 = String[35]; str36 = String[36];π  str37 = String[37]; str38 = String[38]; str39 = String[39];π  str40 = String[40]; str41 = String[41]; str42 = String[42];π  str43 = String[43]; str44 = String[44]; str45 = String[45];π  str46 = String[46]; str47 = String[47]; str48 = String[48];π  str49 = String[49]; str50 = String[50]; str51 = String[51];π  str52 = String[52]; str53 = String[53]; str54 = String[54];π  str55 = String[55]; str56 = String[56]; str57 = String[57];π  str58 = String[58]; str59 = String[59]; str60 = String[60];π  str61 = String[61]; str62 = String[62]; str63 = String[63];π  str64 = String[64]; str65 = String[65]; str66 = String[66];π  str67 = String[67]; str68 = String[68]; str69 = String[69];π  str70 = String[70]; str71 = String[71]; str72 = String[72];π  str73 = String[73]; str74 = String[74]; str75 = String[75];π  str76 = String[76]; str77 = String[77]; str78 = String[78];π  str79 = String[79]; str80 = String[80]; str81 = String[81];π  str82 = String[82]; str83 = String[83]; str84 = String[84];π  str85 = String[85]; str86 = String[86]; str87 = String[87];π  str88 = String[88]; str89 = String[89]; str90 = String[90];π  str91 = String[91]; str92 = String[92]; str93 = String[93];π  str94 = String[94]; str95 = String[95]; str96 = String[96];π  str97 = String[97]; str98 = String[98]; str99 = String[99];π  str100 = String[100]; str101 = String[101]; str102 = String[102];π  str103 = String[103]; str104 = String[104]; str105 = String[105];π  str106 = String[106]; str107 = String[107]; str108 = String[108];π  str109 = String[109]; str110 = String[110]; str111 = String[111];π  str112 = String[112]; str113 = String[113]; str114 = String[114];π  str115 = String[115]; str116 = String[116]; str117 = String[117];π  str118 = String[118]; str119 = String[119]; str120 = String[120];π  str121 = String[121]; str122 = String[122]; str123 = String[123];π  str124 = String[124]; str125 = String[125]; str126 = String[126];π  str127 = String[127]; str128 = String[128]; str129 = String[129];π  str130 = String[130]; str131 = String[131]; str132 = String[132];π  str133 = String[133]; str134 = String[134]; str135 = String[135];π  str136 = String[136]; str137 = String[137]; str138 = String[138];π  str139 = String[139]; str140 = String[140]; str141 = String[141];π  str142 = String[142]; str143 = String[143]; str144 = String[144];π  str145 = String[145]; str146 = String[146]; str147 = String[147];π  str148 = String[148]; str149 = String[149]; str150 = String[150];π  str151 = String[151]; str152 = String[152]; str153 = String[153];π  str154 = String[154]; str155 = String[155]; str156 = String[156];π  str157 = String[157]; str158 = String[158]; str159 = String[159];π  str160 = String[160]; str161 = String[161]; str162 = String[162];π  str163 = String[163]; str164 = String[164]; str165 = String[165];π  str166 = String[166]; str167 = String[167]; str168 = String[168];π  str169 = String[169]; str170 = String[170]; str171 = String[171];π  str172 = String[172]; str173 = String[173]; str174 = String[174];π  str175 = String[175]; str176 = String[176]; str177 = String[177];π  str178 = String[178]; str179 = String[179]; str180 = String[180];π  str181 = String[181]; str182 = String[182]; str183 = String[183];π  str184 = String[184]; str185 = String[185]; str186 = String[186];π  str187 = String[187]; str188 = String[188]; str189 = String[189];π  str190 = String[190]; str191 = String[191]; str192 = String[192];π  str193 = String[193]; str194 = String[194]; str195 = String[195];π  str196 = String[196]; str197 = String[197]; str198 = String[198];π  str199 = String[199]; str200 = String[200]; str201 = String[201];π  str202 = String[202]; str203 = String[203]; str204 = String[204];π  str205 = String[205]; str206 = String[206]; str207 = String[207];π  str208 = String[208]; str209 = String[209]; str210 = String[210];π  str211 = String[211]; str212 = String[212]; str213 = String[213];π  str214 = String[214]; str215 = String[215]; str216 = String[216];π  str217 = String[217]; str218 = String[218]; str219 = String[219];π  str220 = String[220]; str221 = String[221]; str222 = String[222];π  str223 = String[223]; str224 = String[224]; str225 = String[225];π  str226 = String[226]; str227 = String[227]; str228 = String[228];π  str229 = String[229]; str230 = String[230]; str231 = String[231];π  str232 = String[232]; str233 = String[233]; str234 = String[234];π  str235 = String[235]; str236 = String[236]; str237 = String[237];π  str238 = String[238]; str239 = String[239]; str240 = String[240];π  str241 = String[241]; str242 = String[242]; str243 = String[243];π  str244 = String[244]; str245 = String[245]; str246 = String[246];π  str247 = String[247]; str248 = String[248]; str249 = String[249];π  str250 = String[250]; str251 = String[251]; str252 = String[252];π  str253 = String[253]; str254 = String[254]; str255 = String[255];ππConstπ  MaxWord    = $ffff;π  MinWord    = 0;π  MinInt     = Integer($8000);π  MinLongInt = $80000000;π  UseCfg     = True;ππ  {Color Constants:π   Black     = 0; Blue   = 1; Green   = 2; Cyan   = 3; Red   = 4;π   Magenta   = 5; Brown  = 6; LtGray  = 7;π   DkGray    = 8; LtBlue = 9; LtGreen = A; LtCyan = B; LtRed = C;π   LtMagenta = D; Yellow = E; White   = Fπ   }ππConst  Blink               = $80;ππ  {Screen color Constants}πConst   BlackOnBlack       = $00;          BlueOnBlack        = $01;πConst   BlackOnBlue        = $10;          BlueOnBlue         = $11;πConst   BlackOnGreen       = $20;          BlueOnGreen        = $21;πConst   BlackOnCyan        = $30;          BlueOnCyan         = $31;πConst   BlackOnRed         = $40;          BlueOnRed          = $41;πConst   BlackOnMagenta     = $50;          BlueOnMagenta      = $51;πConst   BlackOnBrown       = $60;          BlueOnBrown        = $61;πConst   BlackOnLtGray      = $70;          BlueOnLtGray       = $71;πConst   GreenOnBlack       = $02;          CyanOnBlack        = $03;πConst   GreenOnBlue        = $12;          CyanOnBlue         = $13;πConst   GreenOnGreen       = $22;          CyanOnGreen        = $23;πConst   GreenOnCyan        = $32;          CyanOnCyan         = $33;πConst   GreenOnRed         = $42;          CyanOnRed          = $43;πConst   GreenOnMagenta     = $52;          CyanOnMagenta      = $53;πConst   GreenOnBrown       = $62;          CyanOnBrown        = $63;πConst   GreenOnLtGray      = $72;          CyanOnLtGray       = $73;πConst   RedOnBlue          = $14;          MagentaOnBlue      = $15;πConst   RedOnGreen         = $24;          MagentaOnGreen     = $25;πConst   RedOnCyan          = $34;          MagentaOnCyan      = $35;πConst   RedOnRed           = $44;          MagentaOnRed       = $45;πConst   RedOnMagenta       = $54;          MagentaOnMagenta   = $55;πConst   RedOnBrown         = $64;          MagentaOnBrown     = $65;πConst   RedOnLtGray        = $74;          MagentaOnLtGray    = $75;πConst   BrownOnBlack       = $06;          LtGrayOnBlack      = $07;πConst   BrownOnBlue        = $16;          LtGrayOnBlue       = $17;πConst   BrownOnGreen       = $26;          LtGrayOnGreen      = $27;πConst   BrownOnCyan        = $36;          LtGrayOnCyan       = $37;πConst   BrownOnRed         = $46;          LtGrayOnRed        = $47;πConst   BrownOnMagenta     = $56;          LtGrayOnMagenta    = $57;πConst   BrownOnBrown       = $66;          LtGrayOnBrown      = $67;πConst   BrownOnLtGray      = $76;          LtGrayOnLtGray     = $77;πConst   DkGrayOnBlack      = $08;          LtBlueOnBlack      = $09;πConst   DkGrayOnBlue       = $18;          LtBlueOnBlue       = $19;πConst   DkGrayOnGreen      = $28;          LtBlueOnGreen      = $29;πConst   DkGrayOnCyan       = $38;          LtBlueOnCyan       = $39;πConst   DkGrayOnRed        = $48;          LtBlueOnRed        = $49;πConst   DkGrayOnMagenta    = $58;          LtBlueOnMagenta    = $59;πConst   DkGrayOnBrown      = $68;          LtBlueOnBrown      = $69;πConst   DkGrayOnLtGray     = $78;          LtBlueOnLtGray     = $79;πConst   LtGreenOnBlack     = $0A;          LtCyanOnBlack      = $0B;πConst   LtGreenOnBlue      = $1A;          LtCyanOnBlue       = $1B;πConst   LtGreenOnGreen     = $2A;          LtCyanOnGreen      = $2B;πConst   LtGreenOnCyan      = $3A;          LtCyanOnCyan       = $3B;πConst   LtGreenOnRed       = $4A;          LtCyanOnRed        = $4B;πConst   LtGreenOnMagenta   = $5A;          LtCyanOnMagenta    = $5B;πConst   LtGreenOnBrown     = $6A;          LtCyanOnBrown      = $6B;πConst   LtGreenOnLtGray    = $7A;          LtCyanOnLtGray     = $7B;πConst   LtRedOnBlue        = $1C;          LtMagentaOnBlue    = $1D;πConst   LtRedOnGreen       = $2C;          LtMagentaOnGreen   = $2D;πConst   LtRedOnCyan        = $3C;          LtMagentaOnCyan    = $3D;πConst   LtRedOnRed         = $4C;          LtMagentaOnRed     = $4D;πConst   LtRedOnMagenta     = $5C;          LtMagentaOnMagenta = $5D;πConst   LtRedOnBrown       = $6C;          LtMagentaOnBrown   = $6D;πConst   LtRedOnLtGray      = $7C;          LtMagentaOnLtGray  = $7D;πConst   YellowOnBlack      = $0E;          WhiteOnBlack       = $0F;πConst   YellowOnBlue       = $1E;          WhiteOnBlue        = $1F;πConst   YellowOnGreen      = $2E;          WhiteOnGreen       = $2F;πConst   YellowOnCyan       = $3E;          WhiteOnCyan        = $3F;πConst   YellowOnRed        = $4E;          WhiteOnRed         = $4F;πConst   YellowOnMagenta    = $5E;          WhiteOnMagenta     = $5F;πConst   YellowOnBrown      = $6E;          WhiteOnBrown       = $6F;πConst   YellowOnLtGray     = $7E;          WhiteOnLtGray      = $7F;πConst   BlackOnDkGray     = Blink + $00;   BlueOnDkGray      = Blink + $01;πConst   BlackOnLtBlue     = Blink + $10;   BlueOnLtBlue      = Blink + $11;πConst   BlackOnLtGreen    = Blink + $20;   BlueOnLtGreen     = Blink + $21;πConst   BlackOnLtCyan     = Blink + $30;   BlueOnLtCyan      = Blink + $31;πConst   BlackOnLtRed      = Blink + $40;   BlueOnLtRed       = Blink + $41;πConst   BlackOnLtMagenta  = Blink + $50;   BlueOnLtMagenta   = Blink + $51;πConst   BlackOnYellow     = Blink + $60;   BlueOnYellow      = Blink + $61;πConst   BlackOnWhite      = Blink + $70;   BlueOnWhite       = Blink + $71;πConst   GreenOnDkGray     = Blink + $02;   CyanOnDkGray      = Blink + $03;πConst   GreenOnLtBlue     = Blink + $12;   CyanOnLtBlue      = Blink + $13;πConst   GreenOnLtGreen    = Blink + $22;   CyanOnLtGreen     = Blink + $23;πConst   GreenOnLtCyan     = Blink + $32;   CyanOnLtCyan      = Blink + $33;πConst   GreenOnLtRed      = Blink + $42;   CyanOnLtRed       = Blink + $43;πConst   GreenOnLtMagenta  = Blink + $52;   CyanOnLtMagenta   = Blink + $53;πConst   GreenOnYellow     = Blink + $62;   CyanOnYellow      = Blink + $63;πConst   GreenOnWhite      = Blink + $72;   CyanOnWhite       = Blink + $73;πConst   RedOnDkGray       = Blink + $04;   MagentaOnDkGray   = Blink + $05;πConst   RedOnLtBlue       = Blink + $14;   MagentaOnLtBlue   = Blink + $15;πConst   RedOnLtGreen      = Blink + $24;   MagentaOnLtGreen  = Blink + $25;πConst   RedOnLtCyan       = Blink + $34;   MagentaOnLtCyan   = Blink + $35;πConst   RedOnLtRed        = Blink + $44;   MagentaOnLtRed    = Blink + $45;πConst   RedOnLtMagenta    = Blink + $54;   MagentaOnLtMagenta= Blink + $55;πConst   RedOnYellow       = Blink + $64;   MagentaOnYellow   = Blink + $65;πConst   RedOnWhite        = Blink + $74;   MagentaOnWhite    = Blink + $75;πConst   BrownOnDkGray     = Blink + $06;   LtGrayOnDkGray    = Blink + $07;πConst   BrownOnLtBlue     = Blink + $16;   LtGrayOnLtBlue    = Blink + $17;πConst   BrownOnLtGreen    = Blink + $26;   LtGrayOnLtGreen   = Blink + $27;πConst   BrownOnLtCyan     = Blink + $36;   LtGrayOnLtCyan    = Blink + $37;πConst   BrownOnLtRed      = Blink + $46;   LtGrayOnLtRed     = Blink + $47;πConst   BrownOnLtMagenta  = Blink + $56;   LtGrayOnLtMagenta = Blink + $57;πConst   BrownOnYellow     = Blink + $66;   LtGrayOnYellow    = Blink + $67;πConst   BrownOnWhite      = Blink + $76;   LtGrayOnWhite     = Blink + $77;πConst   DkGrayOnDkGray    = Blink + $08;   LtBlueOnDkGray    = Blink + $09;πConst   DkGrayOnLtBlue    = Blink + $18;   LtBlueOnLtBlue    = Blink + $19;πConst   DkGrayOnLtGreen   = Blink + $28;   LtBlueOnLtGreen   = Blink + $29;πConst   DkGrayOnLtCyan    = Blink + $38;   LtBlueOnLtCyan    = Blink + $39;πConst   DkGrayOnLtRed     = Blink + $48;   LtBlueOnLtRed     = Blink + $49;πConst   DkGrayOnLtMagenta = Blink + $58;   LtBlueOnLtMagenta = Blink + $59;πConst   DkGrayOnYellow    = Blink + $68;   LtBlueOnYellow    = Blink + $69;πConst   DkGrayOnWhite     = Blink + $78;   LtBlueOnWhite     = Blink + $79;πConst   LtGreenOnDkGray   = Blink + $0A;   LtCyanOnDkGray    = Blink + $0B;πConst   LtGreenOnLtBlue   = Blink + $1A;   LtCyanOnLtBlue    = Blink + $1B;πConst   LtGreenOnLtGreen  = Blink + $2A;   LtCyanOnLtGreen   = Blink + $2B;πConst   LtGreenOnLtCyan   = Blink + $3A;   LtCyanOnLtCyan    = Blink + $3B;πConst   LtGreenOnLtRed    = Blink + $4A;   LtCyanOnLtRed     = Blink + $4B;πConst   LtGreenOnLtMagenta= Blink + $5A;   LtCyanOnLtMagenta = Blink + $5B;πConst   LtGreenOnYellow   = Blink + $6A;   LtCyanOnYellow    = Blink + $6B;πConst   LtGreenOnWhite    = Blink + $7A;   LtCyanOnWhite     = Blink + $7B;πConst   LtRedOnDkGray     = Blink + $0C;   LtMagentaOnDkGray = Blink + $0D;πConst   LtRedOnLtBlue     = Blink + $1C;   LtMagentaOnLtBlue = Blink + $1D;πConst   LtRedOnLtGreen    = Blink + $2C;   LtMagentaOnLtGreen= Blink + $2D;πConst   LtRedOnLtCyan     = Blink + $3C;   LtMagentaOnLtCyan = Blink + $3D;πConst   LtRedOnLtRed      = Blink + $4C;   LtMagentaOnLtRed  = Blink + $4D;πConst   LtRedOnLtMagenta  = Blink + $5C;   LtMagentaOnLtMagenta= Blink + $5D;πConst   LtRedOnYellow     = Blink + $6C;   LtMagentaOnYellow = Blink + $6D;πConst   LtRedOnWhite      = Blink + $7C;   LtMagentaOnWhite  = Blink + $7D;πConst   YellowOnDkGray    = Blink + $0E;   WhiteOnDkGray     = Blink + $0F;πConst   YellowOnLtBlue    = Blink + $1E;   WhiteOnLtBlue     = Blink + $1F;πConst   YellowOnLtGreen   = Blink + $2E;   WhiteOnLtGreen    = Blink + $2F;πConst   YellowOnLtCyan    = Blink + $3E;   WhiteOnLtCyan     = Blink + $3F;πConst   YellowOnLtRed     = Blink + $4E;   WhiteOnLtRed      = Blink + $4F;πConst   YellowOnLtMagenta = Blink + $5E;   WhiteOnLtMagenta  = Blink + $5F;πConst   YellowOnYellow    = Blink + $6E;   WhiteOnYellow     = Blink + $6F;πConst   YellowOnWhite     = Blink + $7E;   WhiteOnWhite      = Blink + $7F;ππVarπ  TempStr    : String;π  TempStrLen : Byte Absolute TempStr;π  πFunction Exist(fn: str80): Boolean;π{ Returns True if File fn exists in the current directory                    }ππFunction ExistsOnPath(Var fn: str80): Boolean;π{ Returns True if File fn exists in any directory specified in the current   }π{ path and changes fn to a fully qualified path/File.                        }ππFunction StrUpCase(s : String): String;π{ Returns an upper Case String from s. Applicable to the English language.   }ππFunction StrLowCase(s : String): String;π{ Returns a String = to s With all upper Case Characters converted to lower  }ππFunction Asc2Str(Var s; max: Byte): String;π{ Converts an ASCIIZ String to a Turbo Pascal String With a maximum length   }π{ of max Characters.                                                         }ππProcedure Str2Asc(s: String; Var ascStr; max: Word);π{ Converts a TP String to an ASCIIZ String of no more than max length.       }π{ WARNinG:  No checks are made that there is sufficient room in destination  }π{           Variable.                                                        }ππFunction LastPos(ch: Char; s: String): Byte;π{ Returns the last position of ch in s                                       }ππProcedure CheckIO(a: Byte);ππImplementationππFunction Exist(fn: str80): Boolean;π  beginπ    TempStrLen := 0;π    TempStr    := FSearch(fn,'');π    Exist      := TempStrLen <> 0;π  end; { Exist }ππFunction ExistsOnPath(Var fn: str80): Boolean;π  beginπ    TempStrLen   := 0;π    TempStr      := FSearch(fn,GetEnv('PATH'));π    ExistsOnPath := TempStrLen <> 0;π    fn           := FExpand(TempStr);π  end; { ExistsOnPath }ππFunction StrUpCase(s : String): String;π  Var x : Byte;π  beginπ    StrUpCase[0] := s[0];π    For x := 1 to length(s) doπ      StrUpCase[x] := UpCase(s[x]);π  end; { StrUpCase }ππFunction StrLowCase(s : String): String;π  Var x : Byte;π  beginπ    StrLowCase[0] := s[0];π    For x := 1 to length(s) doπ      Case s[x] ofπ      'a'..'z': StrLowCase[x] := chr(ord(s[x]) and $df);π      else StrLowCase[x] := s[x];π      end; { Case }π  end; { StrLowCase }ππFunction Asc2Str(Var s; max: Byte): String;π  Var stArray  : Array[1..255] of Char Absolute s;π      len      : Integer;π  beginπ    len        := pos(#0,stArray)-1;                       { Get the length }π    if (len > max) or (len < 0) then               { length exceeds maximum }π      len      := max;                                  { so set to maximum }π    Asc2Str    := stArray;π    Asc2Str[0] := chr(len);                                    { Set length }π  end;  { Asc2Str }ππProcedure Str2Asc(s: String; Var ascStr; max: Word);π  beginπ    FillChar(AscStr,max,0);π    if length(s) < max thenπ      move(s[1],AscStr,length(s))π    elseπ      move(s[1],AscStr,max);π  end; { Str2Asc }πππFunction LastPos(ch: Char; s: String): Byte;π  Var x : Word;π  beginπ    x := succ(length(s));π    Repeatπ      dec(x);π    Until (s[x] = ch) or (x = 0);π  end; { LastPos }ππProcedure CheckIO(a: Byte);π  Var e : Integer;π  beginπ    e := Ioresult;π    if e <> 0 then beginπ      Writeln('I/O error ',e,' section ',a);π      halt(e);π    end;π  end; { CheckIO }ππend. { Globals }π  π                                                              6      05-28-9313:51ALL                      SWAG SUPPORT TEAM        HEBREW.PAS               IMPORT              118         {πDAVID SOLLYππFrom Israel Moshe Harel was heard to say to David SollyππThank you For taking the time to answer my many questions.  I have toπtell you, though, that I was lucky to have received your letter becauseπit was addressed to David SALLY and not David SOLLY.ππ>    Are you familiar With a Hebrew Text processor Program called QText?π> I have been able to obtain version 2.10 as public domain software but Iπ> am wondering if there has been an update.  Have you ever heard of aππMH>Current version of QText is 5.0 and it is commercial :-(π  >It comes now With a full set of utilities, including FAX support.ππDid you know that Q-Text version 2.10 was written in Turbo Pascal 3?  Iπwonder if Itschak Maynts (Isaac Mainz?) has continued to use it in hisπlater versions.  Anyway, I would be interested in obtaining the latestπversion of Q-Text.  Can you give me the distributor's address and theπapproximate price?  Thank you.ππ>Most Israeli Printers have a special ROM. You may use downloadable Characterπ>sets or even Graphic printing if needed. I once used LETTRIX For this purposπ>on a Hebrew-less Printer, and it worked fine (but S L O W . . .).πππI have Letrix 3.6.  This was what I was trying to use to print theπQ-Text Files I was writing.  I wrote a Program in Turbo Pascal toπconvert the Q-Text Files into Letrix Files.  The printing is slow butπthe results are favourable. Another advantage to Letrix Hebrew Files isπthat they are written completely in low-ASCII and almost readableπwithout transliteration if one is at all familiar With Hebrew. It is aπgood format For posting Hebrew Text on the Multi-Lingual echo not onlyπbecause it is low-ASCII but also because the method of transliterationπis consistent.ππBelow is my Q-Text File to Letrix File conversion Program.  I hope youπwill find it useful.π}ππProgram QTextLetrix;ππ{$D-}ππUsesπ  Crt, Dos;πππVarπ  InFile,π  TransFile   : Text;π  InFilenm,π  TransFilenm : PathStr;π  Letter, Ans : Char;π  Printable,π  Hebrew,π  Niqud,π  Roman       : Set of Char;π  Nkdm, Rom   : Boolean;ππ{π   "UpItsCase" is a Function that takes a sting of any length andπ   sets all of the Characters in the String to upper case.  It is handyπ   For comparing Strings.π}ππFunction UpItsCase (SourceStr : PathStr) : PathStr;πVarπ  i  : Integer;πbeginπ  For i := 1 to length(SourceStr) doπ    SourceStr[i] := UpCase(SourceStr[i]);π  UpItsCase := SourceStrπend; {Function UpItsCase}πππFunction Exist(fname : PathStr) : Boolean;πVarπ  f : File;πbeginπ{$F-,I-}π  Assign(f, fname);π  Reset(f);π  Close(f);π{$I+}π  Exist := (IOResult = 0) and (fname <> '')πend; {Function exist}ππProcedure Help;πbeginπ  Writeln;π  Writeln ('QTLT (Version 1.0)');π  Writeln ('Hebrew Text File Conversion');π  Writeln ('Q-Text 2.10 File to Letrix(R) 3.6 Hebrew File');π  Writeln;π  Writeln;π  Writeln ('QTLT converts Q-Text Files to Letrix Hebrew format Files.');π  Writeln;π  Writeln ('QTLT expects two parameters on the command line.');π  Writeln ('The first parameter is the name of the File to convert,');π  Writeln ('the second is the name of the new File.');π  Writeln;π  Writeln ('Example:  QTLT  HKVTL.HEB HKVTL.TXT');π  Writeln;π  Writeln ('If no parameters are found, QTLT will display this message.');π  Writeln;π  Halt;πend; {Procedure Help}ππ{π  "ParseCommandLine" is a Procedure that checks if any data was inputπ  at the Dos command line.  If no data is there, then the "Help"π  Procedure is executed and the Program is halted.  Otherwise, theπ  Mode strig Variable is set equal to the Text on the command line.π}ππProcedure ParseCommandLine;πbeginπ  if (ParamCount = 0) or (ParamCount <> 2) thenπ    Helpπ  elseπ  beginπ    InFilenm    := ParamStr(1);π    InFilenm    := UpItsCase(InFilenm);π    TransFilenm := ParamStr(2);π    TransFilenm := UpItsCase(TransFilenm);π  end;πend; {Procedure ParseCommandLine}ππProcedure OpenFiles;πbeginπ  {Open input/output Files}π  If not exist(InFilenm) thenπ  beginπ    Writeln;π    Writeln (InFilenm, ' not found');π    Halt;π  endπ  Elseπ  beginπ    Assign (InFile, InFilenm);π    Reset (InFile);π  end;ππ  If exist (TransFilenm) thenπ  beginπ    Writeln;π    Writeln (TransFilenm, ' already exists!');π    Write ('OverWrite it?  (Y/N) > ');π    Repeatπ      Ans := ReadKey;π      Ans := Upcase(Ans);π      If Ans = 'N' then Halt;π    Until Ans = 'Y';π  end;ππ  Assign (TransFile, TransFilenm);π  ReWrite (TransFile);π  Writeln;πend; {Procedure OpenFiles}ππππProcedure UseOfRoman;πbeginπ  Writeln ('QTLT has detected Roman letters in the source Text.');π  Writeln;π  Writeln ('Letrix expects access to a Roman font to print these Characters');π  Writeln ('otherwise Letrix will report an error condition of fail to perform.');π  Writeln;π  Writeln ('Sample Letrix load instruction:  LX Hebrew Roman');π  Writeln;π  Writeln ('Be sure that these instances are enclosed within the proper');π  Writeln ('Letrix font switch codes so they are not printed as Hebrew Character');π  Writeln;πend; {Procedure UseOfRoman}ππProcedure Niqudim (Var Letter : Char);π{π   Letrix Uses some standard Characters to represent niqudimπ   While Q-Text does not.ππ   This table ensures that certain Characters do not becomeπ   niqudim when translated to Letrix by inserting the tokensπ   which instruct the Letrix Program to use the alternateπ   alphabet -- which by default is number 2.π}πbeginπ  If Not Nkdm thenπ  beginπ    Writeln;π    Writeln ('QTLT has detected Q-Text Characters which Letrix normaly Uses for');π    Writeln ('has transcribed them to print as normal Characters.');π    Writeln;π    Writeln ('Letrix expects access a Roman font to print these Characters');π    Writeln ('otherwise Letrix will report an error condition of fail to perfect');π    Writeln;π    Writeln ('Sample Letrix load instruction:  LX Hebrew Roman');π    Writeln;π    Nkdm := True;π  end; {if not Nkdm}ππ  Case Letter ofππ    '!' : Write (TransFile, '\2!\1');π    '@' : Write (TransFile, '\2@\1');π    '#' : Write (TransFile, '\2#\1');π    '$' : Write (TransFile, '\2$\1');π    '%' : Write (TransFile, '\2%\1');π    '^' : Write (TransFile, '\2^\1');π    '&' : Write (TransFile, '\2&\1');π    '*' : Write (TransFile, '\2*\1');π    '(' : Write (TransFile, '\2(\1');π    ')' : Write (TransFile, '\2)\1');π    '+' : Write (TransFile, '\2+\1');π    '=' : Write (TransFile, '\2=\1');ππ  end; {Case}ππend; {Procedure Nikudim}ππππProcedure QT_Table (Var Letter : Char);π{π  This section reviews each QText letter and matches it With aπ  Letrix equivalent where possibleπ}πbeginπ  Case Letter ofππ    #128 : Write (TransFile, 'a');  {Alef}π    #129 : Write (TransFile, 'b');  {Bet }π    #130 : Write (TransFile, 'g');  {Gimmel etc. }π    #131 : Write (TransFile, 'd');π    #132 : Write (TransFile, 'h');π    #133 : Write (TransFile, 'w');π    #134 : Write (TransFile, 'z');π    #135 : Write (TransFile, 'H');π    #136 : Write (TransFile, 'T');π    #137 : Write (TransFile, 'y');π    #138 : Write (TransFile, 'C');π    #139 : Write (TransFile, 'c');π    #140 : Write (TransFile, 'l');π    #141 : Write (TransFile, 'M');π    #142 : Write (TransFile, 'm');π    #143 : Write (TransFile, 'N');π    #144 : Write (TransFile, 'n');π    #145 : Write (TransFile, 'S');π    #146 : Write (TransFile, 'i');π    #147 : Write (TransFile, 'F');π    #148 : Write (TransFile, 'p');π    #149 : Write (TransFile, 'X');π    #150 : Write (TransFile, 'x');π    #151 : Write (TransFile, 'k');π    #152 : Write (TransFile, 'r');π    #153 : Write (TransFile, 's');π    #154 : Write (TransFile, 't');ππ  end; {Case of}ππend; {Procedure QT_Table}πππProcedure DoIt;π{π  Special commands requred by Letrix.π  Proportional spacing off, line justification off,π  double-strike on, pitch set to 12 Characters per inch.π}πbeginππ  Writeln(transFile,'\p\j\D\#12');π  {Transcription loop}π  While not eof(InFile) doπ  beginπ    Read(InFile, Letter);ππ    If (Letter in Printable) thenπ      Write(TransFile, Letter);ππ    If (Letter in Niqud) thenπ      Niqudim(Letter);ππ    If (Letter in Hebrew) thenπ      QT_Table(Letter);ππ    If (Letter in Roman) and (Rom = False) thenπ    beginπ      UseOfRoman;π      Rom := True;π    end; {Roman Detection}ππ  end; {while}ππ  {Close Files}ππ  Close (TransFile);π  Close (InFile);ππ  {Final message}ππ  Writeln;π  Writeln;π  Writeln('QTLT (Version 1.0)');π  Writeln('Hebrew Text File Conversion');π  Writeln('Q-Text 2.10 Files to Letrix(R) 3.6 Hebrew File');π  Writeln;π  Writeln ('Task Complete');π  Writeln;π  Writeln ('QTLT was written and released to the public domain by David Solly');π  Writeln ('Bibliotheca Sagittarii, Ottawa, Canada (2 December 1992).');π  Writeln;ππend; {Procedure DoIt}πππbeginππ  {Initialize Variables}π  Printable := [#10,#12,#13,#32..#127];π  Roman     := ['A'..'Z','a'..'z'];π  Niqud     := ['!','@','#','$','%','^','&','*','(',')','+','='];π  Printable := Printable - Niqud;π  Hebrew    := [#128..#154];π  Rom       := False;π  Nkdm      := False;ππParseCommandLine;πOpenFiles;πDoIt;ππend.ππ{ππ   Please find below the Turbo Pascal source code For the conversionπProgram For making Letrix Hebrew Files into Q-Text 2.10 Files.  I couldπnot find a way to make this conversion Program convert embedded RomanπText without making it into a monster.  If you have any suggestions, Iπwould be thankful to the input.ππ========================= Cut Here ========================π}ππProgram LetrixQText;ππ{$D-}ππUsesπ  Crt, Dos;ππVarπ  InFile,π  TransFile   : Text;π  InFilenm,π  TransFilenm : PathStr;π  Letter, Ans : Char;π  Printable,π  HiASCII     : Set of Char;ππ{π  "UpItsCase" is a Function that takes a sting of any length andπ  sets all of the Characters in the String to upper case.  It is handyπ  For comparing Strings.π}ππFunction UpItsCase (SourceStr : PathStr): PathStr;πVarπ  i  : Integer;πbeginπ  For i := 1 to length(SourceStr) doπ    SourceStr[i] := UpCase(SourceStr[i]);π  UpItsCase := SourceStrπend; {Function UpItsCase}πππFunction Exist(fname : PathStr) : Boolean;πVarπ  f : File;πbeginπ  {$F-,I-}π  Assign(f, fname);π  Reset(f);π  Close(f);π  {$I+}π  Exist := (IOResult = 0) and (fname <> '')πend; {Function exist}ππProcedure Help;πbeginπ  Writeln;π  Writeln ('LTQT (Version 1.0)');π  Writeln ('Hebrew Text File Conversion');π  Writeln ('Letrix(R) 3.6 File to Q-Text 2.10 File');π  Writeln;π  Writeln;π  Writeln ('LTQT converts Letrix Hebrew format Files to  Q-Text format Files.')π  Writeln;π  Writeln ('LTQT expects two parameters on the command line.');π  Writeln ('The first parameter is the name of the File to convert,');π  Writeln ('the second is the name of the new File.');π  Writeln;π  Writeln ('Example:  LTQT  HKVTL.TXT HKVTL.HEB');π  Writeln;π  Writeln ('If no parameters are found, LTQT will display this message.');π  Writeln;π  Halt;πend; {Procedure Help}ππ{π  "ParseCommandLine" is a Procedure that checks if any data was inputπ  at the Dos command line.  If no data is there, then the "Help"π  Procedure is executed and the Program is halted.  Otherwise, theπ  Mode strig Variable is set equal to the Text on the command line.π}πProcedure ParseCommandLine;πbeginπ  if (ParamCount = 0) or (ParamCount <> 2) thenπ    Helpπ  elseπ  beginπ    InFilenm := ParamStr(1);π    InFilenm := UpItsCase(InFilenm);π    TransFilenm := ParamStr(2);π    TransFilenm := UpItsCase(TransFilenm);π  end;πend; {Procedure ParseCommandLine}ππProcedure OpenFiles;πbeginπ  {Open input/output Files}π  If not exist(InFilenm) thenπ  beginπ    Writeln;π    Writeln (InFilenm, ' not found');π    Halt;π  endπ  Elseπ  beginπ    Assign (InFile, InFilenm);π    Reset (InFile);π  end;ππ  If exist (TransFilenm) thenπ  beginπ    Writeln;π    Writeln (TransFilenm, ' already exists!');π    Write ('OverWrite it?  (Y/N) > ');π    Repeatπ      Ans := ReadKey;π      Ans := Upcase(Ans);π      If Ans = 'N' then Halt;π    Until Ans = 'Y';π  end;ππ  Assign (TransFile, TransFilenm);π  ReWrite (TransFile);π  Writeln;ππend; {Procedure OpenFiles}ππππProcedure LT_Table (Var Letter : Char);π{π  This section reviews each Letrix letter and matches it With aπ  Q-Text equivalent where possibleπ}πbeginπ  Case Letter ofππ    'a' : Write (TransFile, #128);π    'b', 'B','v' : Write (TransFile, #129);  {Vet, Bet}π    'g' : Write (TransFile, #130);π    'd' : Write (TransFile, #131);π    'h' : Write (TransFile, #132);π    'V', 'o', 'u', 'w' : Write (TransFile, #133); {Vav, Holem male, Shuruq}π    'z' : Write (TransFile, #134);π    'H' : Write (TransFile, #135);π    'T' : Write (TransFile, #136);π    'y', 'e' : Write (TransFile, #137); {Yod}π    'C', 'Q', 'W' : Write (TransFile, #138); {Khaf-Sofit}π    'c', 'K' : Write (TransFile, #139); {Khaf, Kaf}π    'l' : Write (TransFile, #140);π    'M' : Write (TransFile, #141);π    'm' : Write (TransFile, #142);π    'N' : Write (TransFile, #143);π    'n' : Write (TransFile, #144);π    'S' : Write (TransFile, #145);π    'i' : Write (TransFile, #146);π    'F' : Write (TransFile, #147);π    'p', 'P', 'f' : Write (TransFile, #148); {Fe, Pe}π    'X' : Write (TransFile, #149);π    'x' : Write (TransFile, #150);π    'k' : Write (TransFile, #151);π    'r' : Write (TransFile, #152);π    's' : Write (TransFile, #153);π    't' : Write (TransFile, #154);π    'A' : Write (TransFile, '-');ππ    {Niqudim and unused letters}ππ    'D','E', 'G', 'I', 'J', 'j', 'O', 'q', 'R', 'U', 'Y', 'Z' :π       Write(TransFile, '');π  elseπ    Write(TransFile, Letter);ππ  end; {Case of}ππend; {Procedure LT_Table}πππProcedure DoIt;πbeginπ  {Transcription loop}π  While not eof(InFile) doπ  beginπ    Read(InFile, Letter);ππ    If (Letter in Printable) thenπ      LT_Table(Letter);ππ    If (Letter in HiASCII) thenπ      Write(TransFile, Letter);π  end; {while}ππ  {Close Files}ππ  Close (TransFile);π  Close (InFile);ππ  {Final message}ππ  Writeln;π  Writeln;π  Writeln('LTQT Version 1.0');π  Writeln('Hebrew Text File Conversion');π  Writeln('Letrix(R) 3.6 File to Q-Text 2.10 File');π  Writeln;π  Writeln;π  Writeln ('Letrix Hebrew File to Q-Text File conversion complete.');π  Writeln;π  Writeln('Special Note:');π  Writeln;π  Writeln ('Q-Text does not support either dagesh or niqudim (vowels).');π  Writeln ('Letters containing a dagesh-qol are reduced to their simple form.');π  Writeln ('Holam male and shuruq are transcribed as vav.  Roman letters used');π  Writeln ('to represent niqudim are ignored.  All other symbols are transcribed'π  Writeln ('without change.');π  Writeln;π  Writeln ('There is no foreign language check -- Anything that can be transcribeπ  Writeln ('into Hebrew Characters will be.');π  Writeln;π  Writeln ('LTQT was written and released to the public domain by David Solly');π  Writeln ('Bibliotheca Sagittarii, Ottawa, Canada (8 December 1992).');π  Writeln;ππend; {Procedure DoIt}πππbeginπ  {Initialize Variables}π  Printable := [#10,#12,#13,#32..#127];π  HiASCII   := [#128..#154];ππ  ParseCommandLine;π  OpenFiles;π  DoIt;πend.ππ                                                                                                                            7      05-28-9313:51ALL                      SWAG SUPPORT TEAM        LONGJUMP.PAS             IMPORT              22          Unit LongJump;ππ{ This Unit permits a long jump from deeply nested Procedures/Functions back }π{ to a predetermined starting point.                                         }ππ{ Whilst the purists may shudder at such a practice there are times when such}π{ an ability can be exceedingly useful.  An example of such a time is in a   }π{ BBS Program when the carrier may be lost unexpectedly whilst a user is on  }π{ line and the requirement is to "back out" to the initialisation reoutines  }π{ at the start of the Program.                                               }ππ{ to use the facility, it is required that a call be made to the SetJump     }π{ Function at the point to where you wish the execution to resume after a    }π{ long jump. When the time comes to return to that point call FarJump.       }ππ{ if you are an inexperienced Programmer, I do not recommend that this Unit  }π{ be used For other than experimentation.  Usually there are better ways to  }π{ achieve what you want to do by proper planning and structuring.  It is     }π{ rare to find a well written Program that will need such and ability.       }ππInterfaceππConstπ  normal = -1;                         { return was not from a LongJump call }πTypeπ  jumpType = Record                        { the data need For a return jump }π                bp,sp,cs,ip : Word;π             end;ππFunction  SetJump(Var JumpData : jumpType): Integer;πProcedure FarJump(JumpData : jumpType; IDInfo : Integer);ππImplementationππTypeπ  WordPtr = ^Word;ππFunction SetJump(Var JumpData : jumpType): Integer;π  begin                     { store the return address (the old bp register) }π    JumpData.bp := WordPtr(ptr(SSeg,SPtr+2))^;π    JumpData.ip := WordPtr(ptr(SSeg,SPtr+4))^;π    JumpData.cs := WordPtr(ptr(SSeg,SPtr+6))^;π    JumpData.SP := SPtr;π    SetJump := normal;                { show that this is not a FarJump call }π  end;  { SetJump }ππProcedure FarJump(JumpData : jumpType; IDInfo : Integer );π  beginπ    { change the return address of the calling routine of the stack so that  }π    { a return can be made to the caller of SetJump                          }π    { Use IDInfo as an identifier of the routine the jump occurred from      }π    WordPtr(ptr(SSeg,JumpData.SP))^   := JumpData.bp;π    WordPtr(ptr(SSeg,JumpData.SP+2))^ := JumpData.ip;π    WordPtr(ptr(SSeg,JumpData.SP+4))^ := JumpData.cs;π    Inline($8b/$46/$06);                                     { mov ax,[bp+6] }π    Inline($8b/$ae/$fa/$ff);                                 { mov bp,[bp-6] }π  end;  { FarJump }ππend.  { LongJump }πππ                                                                                                               8      05-28-9313:51ALL                      SWAG SUPPORT TEAM        MAKEDATA.PAS             IMPORT              7           {> I need about 10 megs of raw data and am looking For info-pascal archives.π> Do they exist? ...and if so could someone please direct me to where I canπI wish everyone made such easy requests to fulfil. Try the followingπProgram. With minor changes, it will supply you With almost any amountπof data For which you could ask.π}πProgram GenerateData;πUsesπ  Crt;πConstπ  DataWanted = 3.0E5;πVarπ  Data    : File of Byte;π  Count   : LongInt;π  Garbage : Byte;πbeginπ  Assign(Data, 'Data.1MB');π  ReWrite(Data);π  Count   := 0;π  Garbage := 1;π  For Count := 1 to Round(DataWanted) doπ  beginπ    Write(Data, garbage); (* smile *)π    GotoXY(1,1);π    Write(Count);π    Inc(Count);π  end;π  Close(Data)πend.π                                                              9      05-28-9313:51ALL                      SWAG SUPPORT TEAM        MAZE.PAS                 IMPORT              14          {πSEAN PALMERππ> Hello there.. I was just wondering.. Since I am completely 'C'π> illiterate, could someone please make an effort and convert theπ> following code in Pascal For me? (Its supposedly makes a solveableπ> maze every time, Cool)ππ{originally by jallen@ic.sunysb.edu}π{Turbo Pascal conversion by Sean Palmer from original C}ππConstπ  h = 23; {height}π  w = 79; {width}ππConstπ  b : Array [0..3] of Integer = (-w, w, 1, -1);π  { incs For up, down, right, left }ππVarπ  a : Array [0..w * h - 1] of Boolean;  { the maze (False = wall) }ππProcedure m(p : Integer);πVarπ  i, d : Byte;πbeginπ  a[p] := True;           {make a path}π  Repeatπ    d := 0;               {check For allowable directions}π    if (p > 2 * w) and not (a[p - w - w]) thenπ      inc(d, 1);          {up}π    if (p < w * (h - 2)) and not (a[p + w + w]) thenπ      inc(d, 2);          {down}π    if (p mod w <> w - 2) and not (a[p + 2]) thenπ      inc(d, 4);          {right}π    if (p mod w <> 1) and not (a[p - 2]) thenπ      inc(d, 8);          {left}π    if d <> 0 thenπ    beginπ      Repeat              {choose a direction that's legal}π        i := random(4);π      Until Boolean(d and(1 shl i));ππ     a[p + b[i]] := True; {make a path}π     m(p + 2 * b[i]);     {recurse}π    end;π  Until d = 0;            {Until stuck}πend;ππVarπ  i : Integer;ππbeginπ  randomize;π  fillChar(a, sizeof(a), False);π  m(succ(w));  {start at upper left}π  For i := 0 to pred(w * h) doπ  begin {draw}π    if i mod w = 0 thenπ      Writeln;π    if a[i] thenπ      Write(' ')π    elseπ      Write('█');π  end;πend.π                                                                                    10     05-28-9313:51ALL                      SWAG SUPPORT TEAM        MISCFUNC.PAS             IMPORT              52          Unit MiscFunc;ππ{ MiscFunc version 1.0 Scott D. Ramsay }ππ{   This is my misc. Function Unit.  Some of the Functions have      }π{ nothing to do With games design but, my Units use it so ...        }π{   MiscFunc.pas is free.  Go crazy.                                 }π{   I've been writing comments to these Units all night.  Since you  }π{ have the source to this, I'll let you figure out what each one     }π{ does.   }ππInterfaceππFunction strint(s:String):LongInt;πFunction intstr(l:LongInt):String;πFunction ups(s:String):String;πFunction st(h:LongInt):String;πFunction Compare(s1,s2:String):Boolean;πFunction dtcmp(Var s1,s2;size:Word):Boolean;πFunction lz(i,w:LongInt):String;πFunction vl(h:String):LongInt;πFunction spaces(h:Integer):String;πFunction repstr(h:Integer;ch:Char):String;πFunction anything(s:String):Boolean;πFunction exist(f:String):Boolean;πFunction errmsg(n:Integer):String;πFunction turboerror(errorcode:Integer) : String;πProcedure funpad(Var s:String);πProcedure unpad(Var s:String);πProcedure munpad(Var s:String;b:Byte);πFunction fpad(s:String;h:Integer):String;πProcedure pad(Var s:String;h:Integer);πProcedure fix(Var s:String;h:String);πProcedure fixh(Var s:String);πFunction range(x,y,x1,y1,x2,y2:Integer) : Boolean;πFunction between(x,x1,x2:Integer):Boolean;ππImplementationπππFunction range(x,y,x1,y1,x2,y2:Integer) : Boolean;π{ returns True if (x,y) is in the rectangular region (x1,y1,x2,y2) }πbeginπ  range := ((x>=x1) and (x<=x2) and (y>=y1) and (y<=y2));πend;πππProcedure fix(Var s:String;h:String);πbeginπ  if pos('.',s)=0π    then s := s+h;πend;πππProcedure fixh(Var s:String);πVarπ  d : Integer;πbeginπ  For d := 1 to length(s) doπ    if s[d]<#32π      then s[d] := ' ';π  For d := length(s)+1 to 255 doπ    s[d] := ' ';πend;πππFunction strint(s:String):LongInt;πVarπ  l : LongInt;πbeginπ  move(s[1],l,sizeof(l));π  strint := l;πend;πππFunction intstr(l:LongInt):String;πVarπ  s : String;πbeginπ  move(l,s[1],sizeof(l));π  s[0] := #4;π  intstr := s;πend;πππFunction ups(s:String):String;πVarπ  d : Integer;πbeginπ  For d := 1 to length(s) doπ    s[d] := upCase(s[d]);π  ups := s;πend;πππFunction st(h:LongInt):String;πVarπ  s : String;πbeginπ  str(h,s);π  st := s;πend;πππFunction Compare(s1,s2:String):Boolean;πVarπ  d : Byte;π  e : Boolean;πbeginπ  e := True;π  For d := 1 to length(s1) doπ    if upCase(s1[d])<>upCase(s2[d])π      then e := False;π  Compare := e;πend;πππFunction dtcmp(Var s1,s2;size:Word):Boolean;πVarπ  d : Word;π  e : Boolean;πbeginπ  e := True;π  d := size;π  While (d>0) and e doπ    beginπ      dec(d);π      e := (mem[seg(s1):ofs(s1)+d]=mem[seg(s2):ofs(s2)+d]);π    end;π  dtcmp := e;πend;πππFunction lz(i,w:LongInt):String;πVarπ  d : LongInt;π  s : String;πbeginπ  str(i,s);π  For d := length(s) to w-1 doπ    s := concat('0',s);π  lz := s;πend;πππFunction vl(h:String):LongInt;πVarπ  d : LongInt;π  e : Integer;πbeginπ  val(h,d,e);π  vl := d;πend;πππFunction spaces(h:Integer):String;πVarπ  s : String;πbeginπ  s := '';π  While h>0 doπ    beginπ      dec(h);π      s := concat(s,' ');π    end;π  spaces := s;πend;πππFunction repstr(h:Integer;ch:Char):String;πVarπ  s : String;πbeginπ  s := '';π  While h>0 doπ    beginπ      dec(h);π      s := s+ch;π    end;π  repstr := s;πend;πππFunction anything(s:String):Boolean;πVarπ  d : Integer;π  h : Boolean;πbeginπ  if length(s)=0π    thenπ      beginπ        anything := False;π        Exit;π      end;π  h := False;π  For d := 1 to length(s) doπ    if s[d]>#32π      then h := True;π  anything := h;πend;πππFunction exist(f:String):Boolean;πVarπ  fil : File;πbeginπ  if f=''π    thenπ      beginπ        exist := False;π        Exit;π      end;π  assign(fil,f);π {$i- }π  reset(fil);π  close(fil);π {$i+ }π  exist := (ioresult=0);πend;πππFunction errmsg(n:Integer):String;πbeginπ   Case n ofπ      -1 : errmsg := '';π      -2 : errmsg := 'Error reading data File';π      -3 : errmsg := '';π      -4 : errmsg := 'equal current data File name';π     150 : errmsg := 'Disk is Write protected';π     152 : errmsg := 'Drive is not ready';π     156 : errmsg := 'Disk seek error';π     158 : errmsg := 'Sector not found';π     159 : errmsg := 'Out of Paper';π     160 : errmsg := 'Error writing to Printer';π    1000 : errmsg := 'Record too large';π    1001 : errmsg := 'Record too small';π    1002 : errmsg := 'Key too large';π    1003 : errmsg := 'Record size mismatch';π    1004 : errmsg := 'Key size mismatch';π    1005 : errmsg := 'Memory overflow';π     else errmsg := 'Error result #'+st(n);π   end;πend;πππFunction turboerror(errorcode:Integer) : String;πbeginπ  Case errorcode ofπ      1: turboerror := 'Invalid Dos Function code';π      2: turboerror := 'File not found';π      3: turboerror := 'Path not found';π      4: turboerror := 'too many open Files';π      5: turboerror := 'File access denied';π      6: turboerror := 'Invalid File handle';π      8: turboerror := 'not enough memory';π     12: turboerror := 'Invalid File access code';π     15: turboerror := 'Invalid drive number';π     16: turboerror := 'Cannot remove current directory';π     17: turboerror := 'Cannot rename across drives';π    100: turboerror := 'Disk read error';π    101: turboerror := 'Disk Write error';π    102: turboerror := 'File not assigned';π    103: turboerror := 'File not open';π    104: turboerror := 'File not open For input';π    105: turboerror := 'File not open For output';π    106: turboerror := 'Invalid numeric Format';π    200: turboerror := 'division by zero';π    201: turboerror := 'Range check error';π    202: turboerror := 'Stack overflow error';π    203: turboerror := 'Heap overflow error';π    204: turboerror := 'Invalid Pointer operation';π    else turboerror := errmsg(errorcode);π  end;πend;πππProcedure funpad(Var s:String);πbeginπ   While s[1]=' ' doπ      delete(s,1,1);πend;πππProcedure unpad(Var s:String);πbeginπ   While (length(s)>0) and (s[length(s)]<=' ') doπ      delete(s,length(s),1);πend;πππProcedure munpad(Var s:String;b:Byte);πbeginπ   s[0] := Char(b);π   While (length(s)>0) and (s[length(s)]<=' ') doπ      delete(s,length(s),1);πend;πππFunction fpad(s:String;h:Integer):String;πbeginπ   While length(s)<h doπ      s := concat(s,' ');π   fpad := s;πend;πππProcedure pad(Var s:String;h:Integer);πbeginπ   While length(s)<h doπ      s := concat(s,' ');πend;πππFunction between(x,x1,x2:Integer):Boolean;πbeginπ  between := ((x>=x1) and (x<=x2));πend;πππend.                                                                                                                   11     05-28-9313:51ALL                      SWAG SUPPORT TEAM        PATCHEXE.PAS             IMPORT              22          {π>If this cannot be done, then hhow can one include a pcx directly insideπ>the compiled File???ππ  There's a trick to do that :π  Suppose your Program is called PROG.EXE and your PCX File IMAGE.PCXππ  After each compile of PROG.EXE, do :π  COPY /B PROG.EXE+IMAGE.PCXππ  Then, when you want to display the PCX, open the EXE File, read it'sπ  header :π}ππFunction GetExeSize(ExeName:String; Var TotSize,Expect:LongInt):Boolean;π{ returns True if EXE is already bind }πTypeπ  ExeHeaderRec = Record {Information describing EXE File}π    Signature         : Word; {EXE File signature}π    LengthRem         : Word; {Number of Bytes in last page of EXE imageπ    LengthPages       : Word; {Number of 512 Byte pages in EXE image}π    NumReloc          : Word; {Number of relocation items}π    HeaderSize        : Word; {Number of paraGraphs in EXE header}π    MinHeap,MaxHeap   : Word; {ParaGraphs to keep beyond end of image}π    StackSeg,StackPtr : Word; {Initial SS:SP, StackSeg relative to imageπ    CheckSum          : Word; {EXE File check sum, not used}π    IpInit, CodeSeg   : Word; {Initial CS:IP, CodeSeg relative to imageπ    RelocOfs          : Word; {Bytes into EXE For first relocation item}π    OverlayNum        : Word; {Overlay number, not used here}π  end;ππVarπ  ExeF : File;π  ExeHeader : ExeHeaderRec;π  ExeValue : LongInt;π  count : Word;ππbeginπ  TotSize:=0; Expect:=0;π  Assign(ExeF,ExeName); Reset(ExeF,1);π  if IoResult=0 thenπ  beginπ    TotSize:=FileSize(ExeF);π    BlockRead(ExeF,ExeHeader,SizeOf(ExeHeaderRec),Count);π    With ExeHeader doπ    if Signature=$5A4D thenπ    beginπ      if LengthRem=0 thenπ        ExeValue:=LongInt(LengthPages) shl 9π      elseπ        ExeValue:=(LongInt(Pred(LengthPages)) shl 9)π      Expect:=ExeValue;π    end;π  end;π  Close(ExeF);π  GetExeSize:=(TotSize<>Expect);πend;ππ{π  If GetExeSize returns True, your PCX has been placed at the end of theπ  EXE (you did not forget :)) and all you have to do next is skip theπ  Program itself : Seek(ExeF,Expect);ππ  Then starts your PCX. If you know in advance the sizes of the PCXπ  File, you can place any data you want (including lots of PCX) at theπ  end of your EXE.ππ  This example is taken from a Unit I wrote a long time ago (was calledπ  Caravane) and it worked very well. I accessed the end of my exe Fileπ  like a normal Typed File. Quite funny but I do not use this anymore.π  Note that you can LzExe or Pklite the EXE part (not the PCX one). Youπ  can DIET both parts With the resident version.ππ  I hope the Function GetExeSize is not copyrighted since it is much tooπ  commented to be one of my work :)π                                                                     12     05-28-9313:51ALL                      SWAG SUPPORT TEAM        REBOOT1.PAS              IMPORT              9           { Subject: How to reboot With TP7.0 ??? }πVarπ  hook : Word Absolute $0040:$0072;ππProcedure Reboot(Cold : Boolean); Far;πbeginπ  if (Cold = True) thenπ    hook := $0000π  elseπ    hook := $1234;ππ  ExitProc := ptr($FFFF,$0000);πend;πππ{πP.S.  Note that it does not require any Units to compile.  Thoughπdepending on your Implementation, you may need to call HALT toπtrip the Exit code (which caUses a reboot).π}ππProgram reset;πUsesπ  Dos;πVarπ  regs : Registers;πbeginπ  intr(25,regs);πend.ππ{ Yeah but it is easier to do it in Inline Asmπeg:π}πProgram reset;πbeginπ  Asmπ    INT 19h; {19h = 25 decimal}π    end;πend.ππ{πOne Word about this interupt is that it is the fastest rebootπI know of but some memory managers, eg QEMM 6.03 don't like it,πIt will seriously hang Windows if called from a Dos Shell,πMicrosoft Mouse Driver 8.20 doesn't seem to like being runπafter you call int 19h and it was resident.πOther than that it works like a gem!π}π                                                                             13     05-28-9313:51ALL                      SWAG SUPPORT TEAM        REBOOT2.PAS              IMPORT              7           {πKARIM SULTANππBelieve it or not,  Int 19h is not he way to go.  It will stimulate a warmπboot, but it is not very safe.  It doesn't do some of the shutdown workπnecessary For some applications, and the preferred method is to set the Wordπat location 40:72 and to jump to $FFFF:0.πHere are my Procedures For doing reboots from a Program:π}πProcedure ColdBoot;  Assembler;πAsmπ  Xor  AX, AXπ  Mov  ES, AXπ  Mov  Word PTR ES:[472h],0000h   {This is not a WARM boot}π  Mov  AX, 0F000hπ  Push AXπ  Mov  AX, 0FFF0hπ  Push AXπ  Retfπend;ππProcedure WarmBoot;  Assembler;πAsmπ  Xor  AX, AXπ  Mov  ES, AXπ  Mov  Word PTR ES:[472h],1234h   {This is not a COLD boot}π  Mov  AX, 0F000hπ  Push AXπ  Mov  AX, 0FFF0hπ  Push AXπ  Retfπend;π                                          14     05-28-9313:51ALL                      SWAG SUPPORT TEAM        REBOOT3.PAS              IMPORT              4           {πREYNIR STEFANSSONππFor anyone wondering how to reboot a PClone from Within Turbo Pascal:πThe Inline code is a far jump to the restart vector at $FFFF:0.π}ππProcedure ColdStart;πbeginπ   MemW[$40:$72] := 0;π   Inline($EA/0/0/$FF/$FF);πend;ππProcedure WarmStart;πbeginπ   MemW[$40:$72] := $1234;π   Inline($EA/0/0/$FF/$FF);πend;ππ                                                      15     05-28-9313:51ALL                      SWAG SUPPORT TEAM        SUNDRY.PAS               IMPORT              99          Unit sundry;ππInterfaceππUsesπ  Dos,π  sCrt,π  Strings;ππTypeπ  LongWds = Recordπ              loWord,π              hiWord : Word;π            end;π  ica_rec = Recordπ              Case Integer ofπ                0: (Bytes   : Array[0..15] of Byte);π                1: (Words   : Array[0..7] of Word);π                2: (Integers: Array[0..7] of Integer);π                3: (strg    : String[15]);π                4: (longs   : Array[0..3] of LongInt);π                5: (dummy   : String[13]; chksum: Integer);π                6: (mix     : Byte; wds : Word; lng : LongInt);π            end;π{-This simply creates a Variant Record which is mapped to 0000:04F0π  which is the intra-applications communications area in the bios areaπ  of memory. A Program may make use of any of the 16 Bytes in this areaπ  and be assured that Dos and the bios will not interfere With it. Thisπ  means that it can be effectively used to pass values/inFormationπ  between different Programs. It can conceivably be used to storeπ  inFormation from an application, then terminate from that application,π  run several other Programs, and then have another Program use theπ  stored inFormation. As the area can be used by any Program, it is wiseπ  to incorporate a checksum to ensure that the intermediate applicationsπ  have not altered any values. It is of most use when executing childπ  processes or passing values between related Programs that are runπ  consecutively.}ππ  IOproc = Procedure(derror:Byte; msg : String);ππConstπ  ValidChars : String[40] = ' ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-'+#39;π  HexChars : Array[0..15] of Char = '0123456789ABCDEF';ππVarπ  ica : ica_rec Absolute $0000:$04f0;π  FilePosition : LongInt;π(*  OldRecSize   : Word; *)π  TempStr      : String;ππProcedure CheckIO(Error_action : IOproc; msg : String);ππFunction CompressStr(Var n): String;π  {-Will Compress 3 alpha-numeric Bytes into 2 Bytes}ππFunction DeCompress(Var s): String;π  {-DeCompresses a String Compressed by CompressStr}ππFunction NumbofElements(Var s; size : Word): Word;π  {-returns the number of active elements in a set}ππFunction PrinterStatus : Byte;π  {-Gets the Printer status}ππFunction PrinterReady(Var b : Byte): Boolean;ππFunction TestBbit(n,b: Byte): Boolean;πFunction TestWbit(Var n; b: Byte): Boolean;πFunction TestLbit(n: LongInt; b: Byte): Boolean;ππProcedure SetBbit(Var n: Byte; b: Byte);πProcedure SetWbit(Var n; b: Byte);πProcedure SetLbit(Var n: LongInt; b: Byte);ππProcedure ResetBbit(Var n: Byte; b: Byte);πProcedure ResetWbit(Var n; b: Byte);πProcedure ResetLbit(Var n: LongInt; b: Byte);ππFunction right(Var s; n : Byte): String;πFunction left(Var s; n : Byte): String;πFunction shleft(Var s; n : Byte): String;πFunction nExtStr(Var s1; s2 : String; n : Byte): String;πProcedure WriteAtCr(st: String; col,row: Byte);πProcedure WriteLnAtCr(st: String; col,row: Byte);πProcedure WriteLNCenter(st: String; width: Byte);πProcedure WriteCenter(st: String; width: Byte);πProcedure GotoCR(col,row: Byte);ππ  {-These Functions and Procedures Unit provides the means to do randomπ    access reads on Text Files.  }ππFunction Exist(fn : String) : Boolean;ππFunction Asc2Str(Var s; max: Byte): String;ππProcedure DisableBlink(State:Boolean);ππFunction Byte2Hex(numb : Byte) : String;ππFunction Numb2Hex(Var numb) : String;ππFunction Long2Hex(long : LongInt): String;ππFunction Hex2Byte(HexStr : String) : Byte;ππFunction Hex2Word(HexStr : String) : Word;ππFunction Hex2Integer(HexStr : String) : Integer;ππFunction Hex2Long(HexStr : String) : LongInt;ππ{======================================================================}πππImplementationππProcedure CheckIO(error_action : IOproc;msg : String);π  Var c : Word;π  beginπ    c := Ioresult;π    if c <> 0 then error_action(c,msg);π  end;πππ{$F+}πProcedure ReportError(c : Byte; st : String);π  beginπ    Writeln('I/O Error ',c);π    Writeln(st);π    halt(c);π  end;π{$F-}ππFunction StUpCase(Str : String) : String;πVarπ  Count : Integer;πbeginπ  For Count := 1 to Length(Str) doπ    Str[Count] := UpCase(Str[Count]);π  StUpCase := Str;πend;ππππFunction CompressStr(Var n): String;π  Varπ    S      : String Absolute n;π    InStr  : String;π    len    : Byte Absolute InStr;π    Compstr: Recordπ              Case Byte ofπ                0: (Outlen  : Byte;π                    OutArray: Array[0..84] of Word);π                1: (Out     : String[170]);π             end;π    temp,π    x,π    count : Word;π  beginπ    FillChar(InStr,256,32);π    InStr := S;π    len   := (len + 2) div 3 * 3;π    FillChar(CompStr.Out,171,0);π    InStr := StUpCase(InStr);π    x := 1; count := 0;π    While x <= len do beginπ      temp  := pos(InStr[x+2],ValidChars);π      inc(temp,pos(InStr[x+1],ValidChars) * 40);π      inc(temp,pos(InStr[x],ValidChars) * 1600);π      inc(x,3);π      CompStr.OutArray[count] := temp;π      inc(count);π    end;π    CompStr.Outlen := count shl 1;π    CompressStr := CompStr.Out;π  end;  {-CompressStr}ππFunction DeCompress(Var s): String;π  Varπ    CompStr : Recordπ                clen : Byte;π                arry : Array[0..84] of Word;π              end Absolute s;π    x,π    count,π    temp    : Word;π  beginπ    With CompStr do beginπ      DeCompress[0] := Char((clen shr 1) * 3);π      x := 0; count := 1;π      While x <= clen shr 1 do beginπ        temp := arry[x] div 1600;π        dec(arry[x],temp*1600);π        DeCompress[count] := ValidChars[temp];π        temp := arry[x] div 40;π        dec(arry[x],temp*40);π        DeCompress[count+1] := ValidChars[temp];π        temp := arry[x];π        DeCompress[count+2] := ValidChars[temp];π        inc(count,3);π        inc(x);π      end;π    end;π  end;ππFunction NumbofElements(Var s; size : Word): Word;π {-The Variable s can be any set Type and size is the Sizeof(s)}π  Varπ    TheSet : Array[1..32] of Byte Absolute s;π    count,x,y : Word;π  beginπ    count := 0;π    For x := 1 to size doπ      For y := 0 to 7 doπ        inc(count, 1 and (TheSet[x] shr y));π    NumbofElements := count;π  end;ππFunction PrinterStatus : Byte;π   Var regs   : Registers; {-from the Dos Unit                         }π   beginπ     With regs do beginπ       dx := 0;            {-The Printer number   LPT2 = 1             }π       ax := $0200;        {-The Function code For service wanted      }π       intr($17,regs);     {-$17= ROM bios int to return Printer status}π       PrinterStatus := ah;{-Bit 0 set = timed out                     }π     end;                  {     1     = unused                        }π   end;                    {     2     = unused                        }π                           {     3     = I/O error                     }π                           {     4     = Printer selected              }π                           {     5     = out of paper                  }π                           {     6     = acknowledge                   }π                           {     7     = Printer not busy              }ππFunction PrinterReady(Var b : Byte): Boolean;π  beginπ    b := PrinterStatus;π    PrinterReady := (b = $90) {-This may Vary between Printers}π  end;ππFunction TestBbit(n,b: Byte): Boolean;π  beginπ    TestBbit := odd(n shr b);π  end;ππFunction TestWbit(Var n; b: Byte): Boolean;π  Var t: Word Absolute n;π  beginπ    if b < 16 thenπ      TestWbit := odd(t shr b);π  end;ππFunction TestLbit(n: LongInt; b: Byte): Boolean;π  beginπ    if b < 32 thenπ      TestLbit := odd(n shr b);π  end;ππProcedure SetBbit(Var n: Byte; b: Byte);π  beginπ    if b < 8 thenπ      n := n or (1 shl b);π  end;ππProcedure SetWbit(Var n; b: Byte);π  Var t : Word Absolute n; {-this allows either a Word or Integer}π  beginπ    if b < 16 thenπ      t := t or (1 shl b);π  end;ππProcedure SetLbit(Var n: LongInt; b: Byte);π  beginπ    if b < 32 thenπ      n := n or (LongInt(1) shl b);π  end;ππProcedure ResetBbit(Var n: Byte; b: Byte);π  beginπ    if b < 8 thenπ      n := n and not (1 shl b);π  end;ππProcedure ResetWbit(Var n; b: Byte);π  Var t: Word Absolute n;π  beginπ    if b < 16 thenπ      t := t and not (1 shl b);π  end;ππProcedure ResetLbit(Var n: LongInt; b: Byte);π  beginπ    if b < 32 thenπ      n := n and not (LongInt(1) shl b);π  end;ππFunction right(Var s; n : Byte): String;π  Varπ    st : String Absolute s;π    len: Byte Absolute s;π  beginπ    if n >= len then right := st elseπ    right := copy(st,len+1-n,n);π  end;ππFunction shleft(Var s; n : Byte): String;π  Varπ    st   : String Absolute s;π    stlen: Byte Absolute s;π    temp : String;π    len  : Byte Absolute temp;π  beginπ    if n < stlen then beginπ      move(st[n+1],temp[1],255);π      len := stlen - n;π      shleft := temp;π    end;π  end;ππFunction left(Var s; n : Byte): String;π  Varπ    st  : String Absolute s;π    temp: String;π    len : Byte Absolute temp;π  beginπ    temp := st;π    if n < len then len := n;π    left := temp;π  end;ππFunction nExtStr(Var s1;s2 : String; n : Byte): String;π  Varπ    main   : String Absolute s1;π    second : String Absolute s2;π    len    : Byte Absolute s2;π  beginπ    nExtStr := copy(main,pos(second,main)+len,n);π  end;ππProcedure WriteAtCr(st: String; col,row: Byte);π  beginπ    GotoXY(col,row);π    Write(st);π  end;πππProcedure WriteLnAtCr(st: String; col,row: Byte);π  beginπ    GotoXY(col,row);π    Writeln(st);π  end;ππFunction Charstr(ch : Char; by : Byte) : String;πVarπ  Str : String;π  Count : Integer;πbeginπ  Str := '';π  For Count := 1 to by doπ    Str := Str + ch;π  CharStr := Str;πend;πππProcedure WriteLnCenter(st: String; width: Byte);π  beginπ    TempStr := CharStr(' ',(width div 2) - succ((length(st) div 2)));π    st      := TempStr + st;π    Writeln(st);π  end;ππProcedure WriteCenter(st: String; width: Byte);π  beginπ    TempStr := CharStr(' ',(width div 2)-succ((length(st) div 2)));π    st      := TempStr + st;π    Write(st);π  end;ππProcedure GotoCR(col,row: Byte);π  beginπ    GotoXY(col,row);π  end;ππFunction Exist(fn : String): Boolean;π  Varπ    f         : File;π    OldMode   : Byte;π  beginπ    OldMode := FileMode;π    FileMode:= 0;π    assign(f,fn);π    {$I-}  reset(f,1); {$I+}π    if Ioresult = 0 then beginπ      close(f);π      Exist := True;π    endπ    elseπ      Exist := False;π    FileMode:= OldMode;π  end; {-Exist}ππFunction Asc2Str(Var s; max: Byte): String;π  Var stArray : Array[0..255] of Byte Absolute s;π      st      : String;π      len     : Byte Absolute st;π  beginπ    move(stArray[0],st[1],255);π    len := max;π    len := (max + Word(1)) * ord(pos(#0,st) = 0) + pos(#0,st)-1;π    Asc2Str := st;π  end;πππProcedure DisableBlink(state : Boolean);π   { DisableBlink(True) allows use of upper eight colors as background }π   { colours. DisableBlink(False) restores the normal mode and should  }π   { be called beFore Program Exit                                     }πVarπ   regs : Registers;πbeginπ  With regs doπ  beginπ    ax := $1003;π    bl := ord(not(state));π  end;π  intr($10,regs);πend;  { DisableBlink }ππFunction Byte2Hex(numb : Byte) : String;π  beginπ    Byte2Hex[0] := #2;π    Byte2Hex[1] := HexChars[numb shr  4];π    Byte2Hex[2] := HexChars[numb and 15];π  end;ππFunction Numb2Hex(Var numb) : String;π  { converts an Integer or a Word to a String. Using an unTypedπ    argument makes this possible. }π  Var n : Word Absolute numb;π  beginπ    Numb2Hex := Byte2Hex(hi(n))+Byte2Hex(lo(n));π  end;ππFunction Long2Hex(long : LongInt): String;π  beginπ    With LongWds(long) do { Type casting makes the split up easy}π      Long2Hex := Numb2Hex(hiWord) + Numb2Hex(loWord);π  end;ππFunction Hex2Byte(HexStr : String) : Byte;π  beginπ    Hex2Byte := pos(UpCase(HexStr[2]),HexChars)-1  +π               ((pos(UpCase(HexStr[1]),HexChars))-1) shl  4 { *  16}π  end;ππFunction Hex2Word(HexStr : String) : Word;π  { This requires that the String passed is a True hex String  of 4π    Chars and not in a Format like $FDE0 }π  beginπ    Hex2Word := pos(UpCase(HexStr[4]),HexChars)-1  +π               ((pos(UpCase(HexStr[3]),HexChars))-1) shl  4 + { *  16}π               ((pos(UpCase(HexStr[2]),HexChars))-1) shl  8 + { * 256}π               ((pos(UpCase(HexStr[1]),HexChars))-1) shl 12;  { *4096}π  end;ππFunction Hex2Integer(HexStr : String) : Integer;π  beginπ    Hex2Integer := Integer(Hex2Word(HexStr));π  end;ππFunction Hex2Long(HexStr : String) : LongInt;π  Var Long : LongWds;π  beginπ    Long.hiWord := Hex2Word(copy(HexStr,1,4));π    Long.loWord := Hex2Word(copy(HexStr,5,4));π    Hex2Long := LongInt(Long);π  end;ππbeginπ  FilePosition := 0;πend.π                                      16     05-28-9313:51ALL                      SWAG SUPPORT TEAM        TPASM.PAS                IMPORT              79          {  Ok here it is..   I have disasembled the following TP Program toπshow you the inner workings of TP (well at least 6.0).  TheπFolloing Program was Compiled in the IDE With RANGE, I/O, STACKπchecking turned off.  Look at the code close and see if you canπfind a nasty little bug in it beFore I show you the Asm that TPπCreated on disk.π}ππProgram TstFiles;ππType MyRec = Recordπ               LInt : LongInt;π               Hi   : Word;π               Lo   : Word;π               B1   : Byte;π               B2   : Byte;π               B3   : Byte;π               B4   : Byte;π             end;            {Record Size 12 Bytes}ππConst MaxRecs = 100;πππVar MyTypedFile   : File of MyRec;π    MyUnTypedFile : File;ππ    Rec           : MyRec;π    RecCnt        : Word;πππProcedure FillRec (RecSeed : LongInt);ππ  beginπ  Rec.Lint := RecSeed;π  Rec.Hi   := Hi (Rec.Lint);π  Rec.Lo   := Lo (Rec.Lint);π  Rec.B1   := Lo (Rec.Lo);π  Rec.B2   := Hi (Rec.Lo);π  Rec.B3   := Lo (Rec.Hi);π  Rec.B4   := Hi (Rec.Hi);π  end;πππππbeginπAssign  (MyTypedFile,   'Type.Dat');πAssign  (MyUnTypedFile, 'UnTyped.Dat');πReWrite (MyTypedFile);πReWrite (MyUnTypedFile);ππFor RecCnt := 1 to MaxRecs doπ  beginπ  FillRec (RecCnt);ππ  Write (MyTypedFile  , Rec);π{ Write (MyUnTypedFile, Rec);} {Illegal can't do this}ππ  FillRec (RecCnt + $FFFF);ππ{ BlockWrite (MyTypedFile, Rec, 1);} {Illegal Can't do this eather}ππ  BlockWrite (MyUnTypedFile, Rec, Sizeof (MyRec));π  end;πππend.πππThe Asm Break down is in the next two messages...ππTSTFileS.38: beginπ  cs:0051 9A0000262D     call   2D26:0000 <-------TP Start Up Codeπ  cs:0056 55             push   bpπ  cs:0057 89E5           mov    bp,spπTSTFileS.39: Assign (MyTypedFile, 'Type.Dat');π  cs:0059 BF4400         mov    di,0044π  cs:005C 1E             push   dsπ  cs:005D 57             push   diπ  cs:005E BF3C00         mov    di,003Cπ  cs:0061 0E             push   csπ  cs:0062 57             push   diπ  cs:0063 9AC004262D     call   2D26:04C0 <-------TP's Routine to setπ                                                  up File Records.πTSTFileS.40: Assign (MyUnTypedFile, 'UnTyped.Dat');π  cs:0068 BFC400         mov    di,00C4π  cs:006B 1E             push   dsπ  cs:006C 57             push   diπ  cs:006D BF4500         mov    di,0045π  cs:0070 0E             push   csπ  cs:0071 57             push   diπ  cs:0072 9AC004262D     call   2D26:04C0 <-------TP's Routine to setπ                                                  up File Records.πTSTFileS.41: ReWrite (MyTypedFile);π  cs:0077 BF4400         mov    di,0044π  cs:007A 1E             push   dsπ  cs:007B 57             push   diπ  cs:007C B80C00         mov    ax,000Cπ  cs:007F 50             push   axπ  cs:0080 9AF704262D     call   2D26:04F7 <-------TP's Routine toπ                                                  Create File.πTSTFileS.42: ReWrite (MyUnTypedFile);π  cs:0085 BFC400         mov    di,00C4π  cs:0088 1E             push   dsπ  cs:0089 57             push   diπ  cs:008A B88000         mov    ax,0080π  cs:008D 50             push   axπ  cs:008E 9AF704262D     call   2D26:04F7 <-------TP's Routine toπ                                                  Create File.πTSTFileS.44: For RecCnt := 1 to MaxRecs doπ  cs:0093 C70650010100   mov    Word ptr [TSTFileS.RECCNT],00π    ***  Clear the loop counter For first loopπ  cs:0099 EB04           jmp    TSTFileS.46 (009F)π    ***  Jump to the start of the Loopπ  cs:009B FF065001       inc    Word ptr [TSTFileS.RECCNT]π    ***  The Loop returns to here to inC the loop counterπTSTFileS.46:  FillRec (RecCnt);π  cs:009F A15001         mov    ax,[TSTFileS.RECCNT]π    ***  Move our RecCnt Var into AX registerπ  cs:00A2 31D2           xor    dx,dxπ    ***  Clear the DX Registerπ  cs:00A4 52             push   dxπ  cs:00A5 50             push   axπ    ***  Push the DX and AX Registers on the stack.  Remember ourπ         FillRec Routine expects a LongInt to be passed and RecCntπ         is only a Word.  So it Pushes the DX as the 0 Upper Wordπ         of the LongInt.π  cs:00A6 0E             push   csπ    ***  Push the code segment For some reasion.π  cs:00A7 E856FF         call   TSTFileS.FILLRECπ    ***  Call our FillRec RoutineπTSTFileS.48:  Write (MyTypedFile , Rec);π  cs:00AA BF4400         mov    di,0044π  cs:00AD 1E             push   dsπ  cs:00AE 57             push   diπ    ***  These instructions push the address of MyTypedFile Recordπ         on the stack.  The first paramiterπ  cs:00AF BF4401         mov    di,0144π  cs:00B2 1E             push   dsπ  cs:00B3 57             push   diπ    ***  These instructions push the address of Rec Recordπ         on the stack.  The second paramiterπ  cs:00B4 9AAA05262D     call   2D26:05AAπ    ***  Call the System Function to Write a Typed File.  (In next msg)π  cs:00B9 83C404         add    sp,0004π    ***  Remove our passed parameters from the stackπTSTFileS.51:  FillRec (RecCnt + $FFFF);π  cs:00BC A15001         mov    ax,[TSTFileS.RECCNT]π  cs:00BF 05FFFF         add    ax,FFFFπ  cs:00C2 31D2           xor    dx,dxπ  cs:00C4 52             push   dxπ  cs:00C5 50             push   axπ  cs:00C6 0E             push   csπ  cs:00C7 E836FF         call   TSTFileS.FILLRECπ    ***  Now heres a NASTY littel bug With the code!!!  Look at theπ         above routine.  We wanted to pass a LongInt $FFFF + rec cntπ         But we wound up adding the $FFFF to a Word then passing aπ         LongInt.  if you Compile the sample pas File you'll be ableπ         to see this bug in action..  Good reasion to use a Debugger.πTSTFileS.55:  BlockWrite (MyUnTypedFile, Rec, Sizeof (MyRec))π  cs:00CA BFC400         mov    di,00C4π  cs:00CD 1E             push   dsπ  cs:00CE 57             push   diπ    ***  These instructions push the address of MyUnTypeFile Recordπ         on the stack.  The First paramiterπ  cs:00CF BF4401         mov    di,0144π  cs:00D2 1E             push   dsπ  cs:00D3 57             push   diπ  cs:0594 26817D02B3D7   cmp    es:Word ptr [di+02],D7B3π    *** Armed With the address of the File Record in ES:DIπ        Check the File mode For a In/Out operation.  See Dosπ        Unit Constant definitions.π  cs:059A 7406           je     05A2π    *** if that Compare was equal then jump to returnπ  cs:059C C7063C006700   mov    Word ptr [SYSTEM.inOUTRES],0069π    *** if we didn't jump then put File not oopen For output inπ        Ioresult.π  cs:05A2 C3             retπ    *** Go back to where we were calledπ  cs:05A3 B43F           mov    ah,3Fπ  cs:05A5 BA6400         mov    dx,0064π  cs:05A8 EB05           jmp    05AFππ    *** The Write instruction entered the system Unit hereπ  cs:05AA B440           mov    ah,40π    *** Load Dos Function in AHπ  cs:05AC BA6500         mov    dx,0065π    *** Default error code 101 disk Write error load in DXπ  cs:05AF 55             push   bpπ    ***  Save the BP registerπ  cs:05B0 8BEC           mov    bp,spπ    *** Load the BP Register With the stack Pointerπ  cs:05B2 C47E0A         les    di,[bp+0A]π    *** Load Address of MyTypeFile Rec in ES:SIπ  cs:05B5 E8DCFF         call   0594π    *** Call check For File mode.  See top of messageπ  cs:05B8 751B           jne    05D5π    *** if error jump out of thisπ  cs:05BA 1E             push   dsπ  cs:05BB 52             push   dxπ    *** Save These Registers as we'er going to use themπ  cs:05BC C55606         lds    dx,[bp+06]π    *** Load the address of our Rec in DS:DX Registersπ  cs:05BF 268B4D04       mov    cx,es:[di+04]π    *** Look up Record structure For a File Rec and you'll seeπ        that RecSize is Byte # 4.  Move that value to CXπ  cs:05C3 268B1D         mov    bx,es:[di]π    *** First Byte of a File Rec is the Handel.  Move into BXπ  cs:05C6 CD21           int    21π    *** Make the Dos CALL to Write.  AH = 40π                                     BX = File Handelπ                                     CX = # of Bytes to Write.π                                     DS:DX = Address of Bufferπ        Returns Error In AX if Carry flag set orπ        if good CF = 0 number of Bytes written in AXπ  cs:05C8 5A             pop    dxπ  cs:05C9 1F             pop    dsπ    *** Restore the Registersπ  cs:05CA 7206           jb     05D2π    *** Jump if there was an error (if Carry flag Set)π  cs:05CC 3BC1           cmp    ax,cxπ    *** Comp Bytes requested to what was writtenπ  cs:05CE 7405           je     05D5π    *** if equal then jump out we'r just about doneπ  cs:05D0 8BC2           mov    ax,dxπ    *** Move default errorcode 101 to AXπ  cs:05D2 A33C00         mov    [SYSTEM.inOUTRES],ax <--Set Ioresultπ    *** Store 101 to Ioresultπ  cs:05D5 5D             pop    bpπ    *** Restore BP registerπ  cs:05D6 CA0400         retf   0004π    *** We'r out of hereππ  cs:05D9 B33F           mov    bl,3Fπ  cs:05DB B96400         mov    cx,0064π  cs:05DE EB05           jmp    05E5πππ    *** The BlockWrite instruction entered the system Unit hereπ  cs:05E0 B340           mov    bl,40π    *** Move Dos Function in BLπ  cs:05E2 B96500         mov    cx,0065π    *** Default error 101 Write error in CXπ  cs:05E5 55             push   bpπ    *** Save BP Registerπ  cs:05E6 8BEC           mov    bp,spπ    *** Move Stack Pointer to BPπ  cs:05E8 C47E10         les    di,[bp+10]π    *** Load Address of MyUnTypedFile Record in ES:DIπ  cs:05EB E8A6FF         call   0594π    *** Check For Open in Write Mode See top of messageπ  cs:05EE 753F           jne    062Fπ    *** Jump if not in Write modeπ  cs:05F0 8B460A         mov    ax,[bp+0A] ]π    *** Move File Record cnt in to axπ  cs:05F3 0BC0           or     ax,axπ    *** Check For 0 Record requestπ  cs:05F5 741C           je     0613π    *** Jump if 0 rec requestedπ  cs:05F7 1E             push   dsπ  cs:05F8 51             push   cxπ    *** Save them we'er going to use themπ  cs:05F9 26F76504       mul    es:Word ptr [di+04]π    *** Multiply Record size With RecCnt in AX result in DX & AXπ  cs:05FD 8BC8           mov    cx,axπ               17     05-28-9313:51ALL                      SWAG SUPPORT TEAM        ZTRAS.PAS                IMPORT              33          Unit Globals;ππInterfaceππUses Crt{, Dos?};ππ{ Special keyboard Characters: }π{ I've squeezed them into a couple of lines so that they'd fit in aπmessage.. might be an idea to expand them back to ~20 lines or so..}ππ      NULL = #0;    BS = #8;    ForMFEED = #12;    CR = #13;    ESC = #27;ππ      HOMEKEY = #199;    {Values apply if only used With the 'Getkey' Function}π      endKEY = #207;      UPKEY = #200;      doWNKEY = #208;π      PGUPKEY = #201;     PGDNKEY = #209;    LEFTKEY = #203;π      inSKEY = #210;      RIGHTKEY = #205;   DELKEY = #211;π      CTRLLEFTKEY = #243; CTRLRIGHTKEY = #244;π      F1 = #187;    F2 = #188;    F3 = #189;    F4 = #190;    F5  = #191;π      F6 = #192;    F7 = #193;    F8 = #194;    F9 = #195;    F10 = #196;ππType  CurType       = ( off, Big, Small );ππVar   Ins           : Boolean;  { Global Var containing status of Insert key}ππ{-----------------------------------------------------------------------------}πFunction  GetKey : Char;πProcedure EdReadln(Var S : String);ππProcedure Cursor( Size : CurType ); { Either off, Big or Small }πProcedure ChangeCursor( Ins : Boolean );ππ{-----------------------------------------------------------------------------}πImplementationππFunction GetKey; { : Char; }ππVar C : Char;ππbeginπ  C := ReadKey;π  Repeatπ    if C = NULL thenπ    beginπ      C := ReadKey;π      if ord(C) > 127 thenπ        C := NULLπ      elseπ        GetKey := Chr(ord(C) + 128);π    end else GetKey := C;π  Until C <> NULL;πend; { GetKey }ππ{-----------------------------------------------------------------------------}πProcedure EdReadln; { (Var S : String); }ππ{ Legal : IString; MaxLength : Word; Var ESCPressed : Boolean); }ππVar CPos : Word;π    Ch   : Char;π    OldY : Byte;ππ    Legal      : String[1];π    MaxLength  : Byte;π    EscPressed : Boolean;ππbeginπ  OldY := WhereY - 1;π  ChangeCursor(Ins);π  CPos := 1;                {Place cursor at START of line}π{ CPos := Succ(Length(S));} {Whereas this places cursor at end of line}π  Legal := '';              {Legal and Maxlength originally passed as params}π  MaxLength := Lo( WindMax ) - Lo( WindMin );ππ  Repeatπ    Cursor( off );π    GotoXY(1, WhereY);π    Write(S, '':(MaxLength - Length(S)));π    GotoXY(CPos, WhereY);π    ChangeCursor(Ins);π    Ch := GetKey;π    Case Ch ofπ      HOMEKEY  : CPos := 1;π      endKEY   : CPos := Succ(Length(S));π      inSKEY   : beginπ                    Ins := not Ins;π                    ChangeCursor(Ins);π                 end;π      LEFTKEY  : if CPos > 1 then Dec(CPos);π      RIGHTKEY : if CPos <= Length(S) then Inc(CPos);π      BS       : if CPos > 1 thenπ                 beginπ                    Delete(S, Pred(CPos), 1);π                    Dec(CPos);π                 end;π      DELKEY   : if CPos <= Length(S) then Delete(S, CPos, 1);π      CR       : ;π      ESC      : beginπ                    S := '';π                    CPos := 1;π                 end;π      elseπ      beginπ        if ((Legal = '') or (Pos(Ch, Legal) <> 0)) andπ           ((Ch >= ' ') and (Ch <= '~')) andπ            (Length(S) < MaxLength) thenπ        beginπ          if Ins then Insert(Ch, S, CPos) elseπ          if CPos > Length(S) then S := S + Ch elseπ             S[CPos] := Ch;π          Inc(CPos);π        end;π      end;π    end; { Case }π  Until (Ch = CR);π  Cursor( Small );π  ESCPressed := Ch <> ESC;π  Writeln;πend; { EditString }ππ{-----------------------------------------------------------------------------}πProcedure Cursor; { ( Size : CurType ); { Either off, Big or Small }ππVar Regs : Registers;ππbeginπ   With Regs Do beginπ      Ax := $100;π      Case Size ofπ         off   : Cx := $3030;π         Big   : Cx := $0F;π         Small : Cx := $607;π      end;π      Intr ( $10, Regs );π   end;πend;ππ{-----------------------------------------------------------------------------}πProcedure ChangeCursor; { ( Ins : Boolean ); }π{Changes cursor size depending on status of insert key}ππbeginπ   if Ins then Cursor( Small ) else Cursor( Big );πend;ππbeginπend.π                                                                18     05-10-9314:24ALL                      COLIN BUCKLEY            Compiler Directives      (232)T_Pascal_R     32          So I'm using a common include file, which I'll add to the end of this message,πand I've noticed something very strange.  I used the Object browser to findπall the units, and I have triple checked to ensure they all include theπinclude file and this is what I've found:ππWith DEBUGGING set my file compiles to 115KπWithout DEBUGGING set 81KππWhen I look at the file there is still loads of symbol information there.πAfter TDStrip of the above file, it's down to 55K (81-55=26).  That's a 26Kπdifference.  Where is it coming from?  Sure I'm using CRT and DOS, andπobviously the include file doesn't work for them, but after looking at theπremaining symbol information, it's alot of stuff from my various unitsπaswell as CRT and DOS.ππWhat's the deal with the symbols coming from my units when I tell themπnot to?  I say symbols as it's all declarations from my interfaceπsections like variables and procedure names, etc.ππAnyways, I wasn't interested in using multiple configuration files, butπI guess I'll have to as I forgot about Borland units, and I guess everyoneπelse did aswell.ππ----------------------------- OPTIONS.INC --------------------------------π{πTurbo Pascal Compiler Directivesπ}ππ{$DEFINE i286}π{$DEFINE DEBUGGING}ππ{$A+}                   { Data Alignment........Word                  }π{$I-}                   { I/O Checking..........Off                   }π{$X-}                   { Enhanced Syntax.......Off                   }π{$V-}                   { String Type Checking..Relaxed               }π{$P-}                   { Open Strings..........Off                   }π{$T-}                   { @ Pointers............UnTyped               }ππ{$IFDEF i286}π{$G+}                   { 286 OpCodes...........On                    }π{$ELSE}π{$G-}                   { 286 OpCodes...........Off                   }π{$ENDIF}ππ{$IFDEF OVERLAYS}π{$F+}                   { Far Calls.............On                    }π{$O+}                   { Overlays Allowed......Yes                   }π{$ELSE}π{$F-}                   { Far Calls.............Off                   }π{$O-}                   { Overlays Allowed......No                    }π{$ENDIF}ππ{$IFDEF DEBUGGING}π{$B+}                   { Boolean Evaluation....Complete              }π{$D+}                   { Debugging Info........On                    }π{$L+}                   { Line Numbers..........On                    }π{$Y+}                   { Symbol Information....On                    }π{$R+}                   { Range Checking........On                    }π{$S+}                   { Stack Checking........On                    }π{$Q+}                   { Overflow Checking.....On                    }π{$ELSE}π{$B-}                   { Boolean Evaluation....Short Circuit         }π{$D-}                   { Debugging Info........Off                   }π{$L-}                   { Line Numbers..........Off                   }π{$Y-}                   { Symbol Information....Off                   }π{$R-}                   { Range Checking........Off                   }π{$S-}                   { Stack Checking........Off                   }π{$Q-}                   { Overflow Checking.....On                    }π{$ENDIF}ππ{πProgram Memory Requirementsπ}π{$M 32000,0,0}          { Stack Size............32000   Heap.....0     }ππ.----------------------------------------------------.π| Colin Buckley                                      |π| Toronto, Ontario, Canada                           |π| InterNet: colin.buckley@rose.com                   |π|                                                    |π| So Eager to Play, So Relunctant to Admit it...     |π`----------------------------------------------------'ππ---π ■ RoseReader 2.10ß P003288 Entered at [ROSE]π * Rose Media, Toronto, Canada : 416-733-2285π * PostLink(tm) v1.04  ROSE (#1047) : RelayNet(tm)ππ                                                                                                                    19     05-31-9308:05ALL                      FLOOR NAAIJKENS          RANDOM NUMBER GENERATOR  IMPORT              21          ==============================================================================π BBS: The Sand Box BBS - SourceNet Central HUBπ  To: JUD MCCRANIE                 Date: 12-17─92 (16:42)πFrom: TREVOR CARLSEN             Number: 531    [87] FD-PascalπSubj: BP 7 DIFFERENCE            Status: Publicπ------------------------------------------------------------------------------π JM> The behavior of RANDOM (with RandSeed set) is different inπ JM> BP7 (and presumably TP7) from that in TP 5.5.  (I don't knowπ JM> how TP 6 compares since I burned it off my disk).ππ JM> RandSeed := 123;π JM> for i := 1 to 8 do writeln( random( 1000));ππ JM> TP 5.5: 343 282 986 996 781 855 343  32π JM> BP 7.0: 859  80 869 854 317 257  20  46ππ JM> ...both are consistant, but they are different sequences.π JM> This can have some dire consequences.  ...ππIt certainly could if you did not know about it and unfortunately I canπfind no reference to the changes in the documentation. (Richard Nelson?)ππHere is a fix (supplied to me via Netmail courtesy Joe Lamoine - thanks Joe).ππ>Quote........ππI posted a message on Compuserve last nite and got the followingπunit in a response.  It seems to work fine!πππ{ *  Turbo Pascal Runtime Library Version 6.0     * ;π  *  Random Number Generator                      * ;π  *                                               * ;π  *  Copyright (C) 1988,92 Borland International  * }ππ unit TP6Rand;ππ interfaceππ function Random(Max: Integer): Integer;ππ implementationππ constπ  { Scaling constant}π  ConstM31 = Longint(-31);π  { Multiplication factor}π  Factor: Word = $8405;πππ function NextRand: Longint; assembler;π { Compute next random numberπ  New := 8088405H * Old + 1π  Out  DX:AX = Next random numberπ }π asmπ  MOV  AX,RandSeed.Word[0]π  MOV  BX,RandSeed.Word[2]π  MOV  CX,AXπ  MUL  Factor.Word[0]     { New = Old.w0 * 8405H }π  SHL  CX,1               { New.w2 += Old.w0 * 808H }π  SHL  CX,1π  SHL  CX,1π  ADD  CH,CLπ  ADD  DX,CXπ  ADD  DX,BX              { New.w2 += Old.w2 * 8405H }π  SHL  BX,1π  SHL  BX,1π  ADD  DX,BXπ  ADD  DH,BLπ  MOV  CL,5π  SHL  BX,CLπ  ADD  DH,BLπ  ADD  AX,1      { New += 1 }π  ADC  DX,0π  MOV  RandSeed.Word[0],AXπ  MOV  RandSeed.Word[2],DXπ end;ππfunction Random(Max: Integer): Integer; assembler;π asmπ  CALL  NextRandπ  XOR   AX,AXπ  MOV   BX,Max.Word[0]π  OR    BX,BXπ  JE    @@1π  XCHG  AX,DXπ  DIV   BXπ  XCHG  AX,DXπ @@1:π end;ππend.ππ>End of quote.πππTeeCeeπππ--- TC-ED   v2.01π * Origin: The Pilbara's Pascal Centre (+61 91 732930) (3:690/644)π                                               20     06-22-9309:24ALL                      SWAG SUPPORT TEAM        Hi Resolution Timer      IMPORT              20          UNIT Timer;ππ{ TIMER - Fine resolution timer functions          }ππINTERFACEπUSES Crt,Dos;πCONSTπ   TixSec  = 18.20648193;π   TixMin  = TixSec * 60.0;π   TixHour = TixMin * 60.0;π   TixDay  = TixHour * 24.0;πTYPEπ   DiffType = String[16];πVARπ   tGet       : Longint ABSOLUTE $0040:$006C;πFUNCTION tStart: Longint;πFUNCTION tDiff(StartTime,EndTime: Longint) : Real;πFUNCTION tFormat(T1,T2:Longint): DiffType;πPROCEDURE GetTime(H,M,S,S100:Word);ππIMPLEMENTATIONππVARπ   TimeDiff   : DiffType;ππ{ tStart - wait for a new tick, and return theπ  tick number to the caller.  The wait allowsπ  us to be sure the user gets a start at theπ  beginning of the second.                         }ππFUNCTION tStart: Longint;πVARπ   StartTime : Longint;πBEGINπ      StartTime := tGet;π   WHILE StartTime = tGet DO;π      tStart := tGetπEND;ππ{ tDiff - compute the difference between twoπ  timepoints (in seconds). }ππFUNCTION tDiff(StartTime,EndTime: Longint) : Real;πBEGINπ   tDiff := (EndTime-StartTime)/TixSec;πEND;ππPROCEDURE GetTime(H,M,S,S100:Word);πVARπ   Regs : Registers;πBEGINπ   Regs.AH := $2C;π   MsDos(Regs);π   H := Regs.CH;π   M := Regs.CL;π   S := Regs.DH;π   S100 := Regs.DLπEND;ππ{ tFormat - given two times, return a pointerπ  to a (static) string that is the differenceπ  in the times, formatted HH:MM:SS }ππFUNCTION tFormat(T1,T2:Longint): DiffType;ππFUNCTION rMod(P1,P2: Real): Real;πBEGINπ   rMod := Frac(P1/P2) * P2πEND;ππVARπ    Temp : Real;π   tStr : String;π   TempStr : String[2];π   TimeValue : ARRAY [1..4] OF Longint;π   I : Integer;πBEGINπ   Temp := t2-t1;           { Time diff. }π   {Adj midnight crossover}π   IF Temp < 0 THENπ          Temp := Temp + TixDay;π      TimeValue[1] := Trunc(Temp/TixHour);  {hours}π      Temp := rMod(Temp,TixHour);π   TimeValue[2] := Trunc(Temp/TixMin); {minutes}π   Temp := rMod(Temp,TixMin);π   TimeValue[3] := Trunc(Temp/TixSec); {seconds}π   Temp := rMod(Temp,TixSec);     {milliseconds}π   TimeValue[4] := Trunc(Temp*100.0/TixSec+0.5);π   STR(TimeValue[1]:2,tStr);π   IF tStr[1] = ' ' THEN tStr[1] := '0';π   FOR I := 2 TO 3 DOπ      BEGINπ         STR(TimeValue[I]:2,TempStr);π         IF TempStr[1]=' ' THENπ                            TempStr[1]:='0';π         tStr := tStr + ':'+ TempStrπ      END;π   STR(TimeValue[4]:2,TempStr);π   IF TempStr[1]=' ' THEN TempStr[1]:='0';π   tStr := tStr + '.' + TempStr;π   tFormat := tStrπEND;ππEND.π                                                        21     07-16-9306:11ALL                      SWAG SUPPORT TEAM        A source code mangler    IMPORT              43     èo   {πHere is a VERY simple source-code mangler that I just made. It simply:ππ1) Removes whitespace,π2) Removes comments (but not Compiler-directives!),π3) Makes everything upper-Case.π4) Make lines max. 127 Chars wide (max. For Turbo Pascal),π5) Doesn't mess up literal Strings :-)ππI don't imagine that this is anything Near perfect - but it's better thanπnothing...ππ}ππProgram Mangler;ππConstπ  Alpha : Set of Char = ['a'..'z', 'A'..'Z', '0'..'9'];ππVarπ  F, F2 : Text;π  R, S : String;π  X : Byte;π  InString : Boolean;ππFunction NumChar(C : Char; S : String; Max : Byte) : Byte;πVarπ  N, Y : Byte;πbeginπ  N := 0;π  For Y := 1 to Max doπ    if S[Y] = C then Inc(N);π  NumChar := N;πend;ππFunction TrimF(T : String) : String;πVarπ  T2 : String;πbeginπ  T2 := T;π  While (Length(T2) > 0) and (T2[1] = ' ') doπ    Delete(T2, 1, 1);π  TrimF := T2;πend;ππFunction Trim(T : String) : String;πVarπ  T2 : String;πbeginπ  T2 := TrimF(T);π  While (Length(T2) > 0) and (T2[Length(T2)] = ' ') doπ    Delete(T2, Length(T2), 1);π  Trim := T2;πend;ππProcedure StripComments(Var T : String);πVarπ  Y : Byte;π  Rem : Boolean;πbeginπ  Rem := True;π  if Pos('(*', T) > 0 thenπ  beginπ    For Y := Pos('(*', T) to Pos('*)', T) doπ      if (T[Y] = '$') or (T[Y] = '''') thenπ        Rem := False;π    if (Rem) and (not Odd(NumChar('''', T, Pos('(*', T)))) thenπ      Delete(T, Pos('(*', T), Pos('*)', T)+2-Pos('(*', T));π  end;π  if Pos('{', T) > 0 thenπ  beginπ    For Y := Pos('{', T) to Pos('}', T) doπ      if (T[Y] = '$') or (T[Y] = '''') thenπ        Rem := False;π    if (Rem) and (not Odd(NumChar('''', T, Pos('(*', T)))) thenπ      Delete(T, Pos('{', T), Pos('}', T)+1-Pos('{', T));π  end;πend;ππbeginπ  ReadLn(S);π  Assign(F, S);π  Reset(F);π  ReadLn(S);π  Assign(F2, S);π  ReWrite(F2);π  R := '';π  S := '';ππ  While not EoF(F) doπ  beginπ    ReadLn(F, R);π    StripComments(R);π    R := Trim(R);π    X := 1;π    While X <= Length(R) doπ    beginπ      InString := (R[X] = '''') xor InString;π      if not InString thenπ      beginπ        if R[X] = #9 thenπ          R[X] := ' ';π        if ((R[X] = ' ') and (R[X+1] = ' ')) thenπ        beginπ          Delete(R, X, 1);π          if X > 1 thenπ            Dec(X);π        end;π        if ((R[X] = ' ') and not(R[X+1] in Alpha)) thenπ          Delete(R, X, 1);π        if ((R[X+1] = ' ') and not(R[X] in Alpha)) thenπ          Delete(R, X+1, 1);π        R[X] := UpCase(R[X]);π      end;π      Inc(X);π    end;π    if (Length(R) > 0) and (R[Length(R)] <> ';') thenπ      R := R+' ';π    if Length(R)+Length(S) <= 127 thenπ      S := TrimF(S+R)π    elseπ    beginπ      WriteLn(F2, Trim(S));π      S := TrimF(R);π    end;π  end;ππ  WriteLn(F2, S);π  Close(F);π  Close(F2);πend.π{π > 1) Remove whitespace.πJust removes indentation now.π > 2) Put lines together (max. length approx. 120 Chars).πThis is going to be one of the harder parts.π > 3) Make everything lower-Case (or upper-Case).πNo need.. see 4.π4.  Convert all Types, Consts, and VarS to an encypted name, like so:π     IIl0lll1O0lI1π5.  Convert all Procedures, and Functions like #4π6.  On Objects, Convert all "data" fields.  Leave alone all others except Forπthe "ConstRUCtoR" and on that, only check to see if any Types are being used.πConstructors are the only ones that can change from the ancestor.π7.  on Records, When Typed like this:πaRec.Name:='Rob Green';  check to see if arec is in the list, if not, skip.πif like this:π   With arec doπ     name:='Rob Green';  do the same as above, but check For begin and end.π8.  Leave externals alone.π9.  Also mangle the Includes.π10. Leave Any Interface part alone, and only work With the Implementation.πThis is what my mangler currently does.(all except For #7 and #10, havent gotπthat Far yet.)  Any ways it works pretty good.  im happy With the results iπam getting With it.  It makes it "VERY" hard to read.  The only thing i seeπhaving trouble With down the line, is the "Compressing" of mulitiple lines.ππAnyways, heres a small Program, and then what PAM(Pascal automatic mangler)πdid to it:π}ππProgram test;ππTypeπ   pstr30 = ^str30;π   str30  = String[30];ππVarπ   b : Byte;π   s : pstr30;ππFunction hex(b : Byte) : String;πConstπ   Digits : Array [0..15] of Char = '0123456789ABCDEF';πVarπ   s:String;πbeginπ   s:='';π   s[0] := #2;π   s[1] := Digits [b shr 4];π   s[2] := Digits [b and $F];π   hex:=s;πend;ππbeginπ   new(s);π   s^:='Hello world';π   Writeln(s^);π   Writeln('Enter a Byte to convert to hex:');π   readln(b);π   s^:=hex(b);π   Writeln('Byte :',b,' = $',s^);π   dispose(s);πend.πππProgram test;πTypeπ  IO1II0IO00O = ^II0lOl1011I;π  II0lOl1011I = String[30];πVarπ  III0O1ll10l:Byte;π  I11110I11Il0:IO1II0IO00O;ππFunction Il00O011IO0I(III0O1ll10l:Byte):String;πConstπ  Illl1OOOO0I : Array [0..15] of Char = '0123456789ABCDEF';πVarπ  I11110I11Il0:String;πbeginπ  I11110I11Il0:='';π  I11110I11Il0[0] := #2;π  I11110I11Il0[1] := Illl1OOOO0I [III0O1ll10l shr 4];π  I11110I11Il0[2] := Illl1OOOO0I [III0O1ll10l and $F];π  Il00O011IO0I:=I11110I11Il0;πend;πbeginπ  new(I11110I11Il0);π  I11110I11Il0^:='Hello world';π  Writeln(I11110I11Il0^);π  Writeln('Enter a Byte to convert to hex:');π  readln(III0O1ll10l);π  I11110I11Il0^:=Il00O011IO0I(III0O1ll10l);π  Writeln('Byte :',III0O1ll10l,' = $',I11110I11Il0^);π  dispose(I11110I11Il0);πend.ππ                                                                   22     07-16-9306:13ALL                      KENT BRIGGS              Randmom Number Function  IMPORT              16     èo   ===========================================================================π BBS: Canada Remote SystemsπDate: 06-18-93 (23:27)             Number: 26893πFrom: KENT BRIGGS                  Refer#: NONEπ  To: BRIAN PAPE                    Recvd: NO  πSubj: RANDOM NUMBERS                 Conf: (1221) F-PASCALπ---------------------------------------------------------------------------π -=> Quoting Brian Pape to Erik Johnson <=-ππ BP> Please- I *am* looking for the source code to a decent random numberπ BP> generator so that I'm not dependant on Borland.ππ Brian, Borland did change their random:word function when they releasedπ 7.0.  However the random:real function, the randomize procedure, and theirπ method of updating randseed remain the same as ver 6.0.  Using DJ Murdoch'sπ CycleRandseed procedure and reverse engineering TP6's and TP7's Randomπ functions, I came up with the following routines:ππconst rseed: longint = 0;ππprocedure randomize67;      {TP 6.0 & 7.0 seed generator}πbeginπ  reg.ah:=$2c;π  msdos(reg);    {get time: ch=hour,cl=min,dh=sec,dl=sec/100}π  rseed:=reg.dx;π  rseed:=(rseed shl 16) or reg.cx;πend;ππfunction rand_word6(x: word): word;    {TP 6.0 RNG: word}πbeginπ  rseed:=rseed*134775813+1;π  rand_word6:=(rseed shr 16) mod x;πend;ππfunction rand_word7(x: word): word;    {TP 7.0 RNG: word}πbeginπ  rseed:=rseed*134775813+1;π  rand_word7:=((rseed shr 16)*x+((rseed and $ffff)*x shr 16)) shr 16;πend;ππfunction rand_real67: real;    {TP 6.0 & 7.0 RNG: real}πbeginπ  rseed:=rseed*134775813+1;π  if rseed<0 then rand_real67:=rseed/4294967296.0+1.0 elseπ  rand_real67:=rseed/4294967296.0;πend;ππIf anyone can improve on these please post some code here, thanks.ππ___ Blue Wave/QWK v2.12π--- Renegade v06-11 Betaππ * Origin: Snipe's Castle BBS, Waco TX   (817)-757-0169 (1:388/26)π                                                                                                              23     08-18-9312:20ALL                      JOSE ALMEIDA             Get the active code page IMPORT              20     èo   { Gets the active (set by user) and system (at boot byte) code page.π  Part of the Heartware Toolkit v2.00 (HTelse.PAS) for Turbo Pascal.π  Author: Jose Almeida. P.O.Box 4185. 1504 Lisboa Codex. Portugal.π          I can also be reached at RIME network, site ->TIB or #5314.π  Feel completely free to use this source code in any way you want, and, ifπ  you do, please don't forget to mention my name, and, give me and Swag theπ  proper credits. }ππPROCEDURE Get_Code_Page(var Active_CP : word;π                       var System_CP : word;π                       var Error_Code : byte);π{ DESCRIPTION:π    Gets the active (set by user) and system (at boot byte) code page.π  SAMPLE CALL:π    Get_Code_Page(Active_CP,Default_CP,Error_Code);π  RETURNS:π    Active : active code page set by userπ    System : system code page at boot timeπ    Error_Codeπ      0 : no errorπ      else : see The Programmers PC Source Book 3.191π  NOTES:π    Applies to all versions beginning with v3.3.π    See Get_Code_Page_Text() in order to get string text. }ππvarπ  HTregs : registers;ππBEGIN { Get_Code_Page }π  HTregs.AX := $6601;π  MsDos(HTregs);π  if HTregs.Flags and FCarry <> 0 thenπ    beginπ      Active_CP := $FFFF;           { on error set to $FFFF }π      System_CP := $FFFF;           { on error set to $FFFF }π      Error_Code := HTregs.AL;π    endπ  elseπ    beginπ      Active_CP := HTregs.BX;π      System_CP := HTregs.DX;π      Error_Code := 0;π    end;πEND; { Get_Code_Page }ππππFUNCTION Get_Code_Page_Text(CP : word) : String14;ππ{ DESCRIPTION:π    Gets the current active code page in string form.π  SAMPLE CALL:π    St := Get_Code_Page_Text(860);π  RETURNS:π    e.g.: 'Portugal'π  NOTES:π    None. }ππBEGIN { Get_Code_Page_Text }π  case CP ofπ    437 : Get_Code_Page_Text := 'USA English';π    850 : Get_Code_Page_Text := 'Multilingual';π    852 : Get_Code_Page_Text := 'CZ/SL/HU/PL/YU';π          { CZ and SL = Czechoslovakia (Czech & Slovak) }π          { HU        = Hungary                         }π          { PL        = Poland                          }π          { YU        = Yugoslavia                      }π    854 : Get_Code_Page_Text := 'Spain';π    860 : Get_Code_Page_Text := 'Portugal';π    863 : Get_Code_Page_Text := 'Canada-French';π    865 : Get_Code_Page_Text := 'Norway/Denmark';π  elseπ    Get_Code_Page_Text := 'Unknown';π  end;πEND; { Get_Code_Page_Text }π                                              24     08-18-9312:27ALL                      JOSE ALMEIDA             Intra-App Comm Area      IMPORT              15     èo   { Gets or puts information in the Intra-Application Communications Area (ICA).π  Part of the Heartware Toolkit v2.00 (HTmemory.PAS) for Turbo Pascal.π  Author: Jose Almeida. P.O.Box 4185. 1504 Lisboa Codex. Portugal.π          I can also be reached at RIME network, site ->TIB or #5314.π  Feel completely free to use this source code in any way you want, and, ifπ  you do, please don't forget to mention my name, and, give me and Swag theπ  proper credits. }ππPROCEDURE ICA(GetPut : boolean;π      var SourceDest);π{ DESCRIPTION:π    Gets or puts information in the Intra-Application Communications Area (ICA).π  SAMPLE CALL:π    ICA(True,MyVar);π    orπ    ICA(False,MyVar);π  RETURNS:π    See notes (bellow).π  NOTES:π    These sixteen bytes, called the Intra-Application Communications Areaπ      (ICA) can be used by any program for any purpose, Usually it is usedπ      to pass data betwenn two or more programs. Not many programs use thisπ      area. If you wish to use this area, make sure checksums and signaturesπ      are used to insure the reliability of your data, since another programπ      may also decide to use this area.π           [in The Assembly Language Database, Peter Norton]π    The incomming SourceDir variable may be of any type.π    Nevertheless, the size of that variable MUST be at least 16 bytes long,π      or unpredictable results may occur...π    The programer before changing this area contents, should keep itsπ      contents in a variable for later restore. It is not a very good ideiaπ      to not restore the contents before the program end, because thatπ      area may being used by another program. }ππBEGIN { ICA }π  if GetPut thenπ    Move(Mem[$0000:$04F0],SourceDest,16)π  elseπ    Move(SourceDest,Mem[$0000:$04F0],16)πEND; { ICA }π                25     08-18-9312:28ALL                      JOSE ALMEIDA             Get Print Screen Status  IMPORT              8      èo   { Gets the status of the last or current Print Screen operation.π  Part of the Heartware Toolkit v2.00 (HTparal.PAS) for Turbo Pascal.π  Author: Jose Almeida. P.O.Box 4185. 1504 Lisboa Codex. Portugal.π          I can also be reached at RIME network, site ->TIB or #5314.π  Feel completely free to use this source code in any way you want, and, ifπ  you do, please don't forget to mention my name, and, give me and Swag theπ  proper credits. }ππFUNCTION PrtSc_Status : byte;π{ DESCRIPTION:π    Gets the status of the last or current Print Screen operation.π  SAMPLE CALL:π    NB := PrtSc_Status;π  RETURNS:π    00h : Print Screen completeπ    01h : Print Screen currently in progressπ    FFh : Error occurred during Print Screen }ππBEGIN { PrtSc_Status }π  PrtSc_Status := Mem[$0000:$0500];πEND; { PrtSc_Status }π                                                                                   26     08-27-9320:00ALL                      SWAG SUPPORT TEAM        Finding Anagrams         IMPORT              47     èo   {$A+,B+,D+,E-,F+,G+,I+,L+,N-,O+,P+,Q+,R+,S+,T+,V-,X+,Y+}π{$M 65520,100000,655360}π{πProgram compiled and tested With BP 7.0ππWARNING since this Program is not using the fastest algorithm toπfind it's Anagrams, long Delays can be expected For largeπinput-Strings.ππTest have shown the following results:ππ  Length of Input       Number of anagrams foundππ        2                         2π        3                         6π        4                        24π        5                       120π        6                       720π        7                      5040ππAs can plainly be seen from this, the number of Anagrams For aπString of length N is a direct Function of the number of AnagramsπFor a String of N-1. In fact the result is f(N) = N * f(N-1).ππYou might have recognised the infamous FACTORIAL Function!!!ππTypeπ  MyType = LongInt;ππFunction NumberOfAnagrams(Var InputLen : MyType) : MyType;ππ  Varπ    Temp : MyType;ππ  beginπ    Temp := InputLen;π    if Temp >1 thenπ    beginπ      Temp := Temp - 1;π      NumberOfAnagrams := InputLen * NumberOfAnagrams(Temp);π    end elseπ      NumberOfAnagrams := InputLen;π  end;ππThe above Function has been tested and found to work up to an inputπlength of 12. After that, Real numbers must be used. As a side noteπthe Maximum value computable was 1754 With MyType defined asπExtended and Numeric-Coprocessor enabled of course. Oh and BTW, theπparameter is passed as a Var so that the Stack doesn't blow up whenπyou use Extended Type!!!! As a result, you can't pass N-1 to theπFunction. You have to STORE N-1 in a Var and pass that as parameter.πThe net effect is that With Numeric Copro enabled, at 1754 it blowsπup because of a MATH OVERFLOW, not a STACK OVERFLOW!!!ππBased on these findings, I assume the possible anagrams can beπcomputed a lot faster simply by Realising that the possible AnagramsπFor an input length of (N) can be found by finding all anagrams forπan input Length of (N-1) and inserting the additional letter in eachπ(N) positions in those Strings. Since this can not be doneπrecursively in memory, the obvious solution would be to to outputπthe anagrams strating With the first 4 or 5 caracters to a File,πbecause those can be found quickly enough, and then to read in eachπString and apply the following caracters to each and Repeat thisπprocess Until the final File is produced.ππHere is an example:ππ      Anagrams For ABCDππ      Output Anagrams For AB to Fileππ        Giving      AB and BAππ      read that in and apply the next letter in all possible positionsππ        Givingπ                  abCπ                  aCbπ                  Cabπ                &π                  baCπ                  bCaπ                  Cbaππ      Now Apply the D to this and getππ                  abcDπ                  abDcπ                  aDbcπ                  Dabcπ                &ππ                  acbDπ                  acDbπ                  aDcbπ                  Dacbππ      Etc... YOU GET THE POINT!!!ππBTW Expect LARGE Files if you become too enthousiastic With this!!!ππ  An Input of just 20 caracters long will generate a File ofππ        2,432,902,008,176,640,000 Anagramsπ        That'sπ          2.4 Quintillion Anagramsππ  Remember that each of those are 20 caracters long,π  add Carriage-return and line-feeds and you've got yourself aπ  HUGE File ;-)ππ  In fact just a 10 Caracter input length will generate 3.6 Millionπ  Anagrams from a 10 Caracter input-String. Again add Cr-LFs andπ  you've got yourself a 43.5 MEGAByte File!!!!!! but consider youπ  are generating it from the previous File which comes to 3.5 MEGπ  For an Input Length of 9 and you've got yourself 45 MEG of DISK inπ  use For this job.ππ}πUsesπ  Strings, Crt;ππConstπ  MaxAnagram = 1000;ππTypeπ  AnagramArray = Array[0..MaxAnagram] of Word;π  AnagramStr   = Array[0..MaxAnagram] of Char;ππVarπ  Target       : AnagramStr;π  Size         : Word;π  Specimen     : AnagramArray;π  Index        : Word;π  AnagramCount : LongInt;ππProcedure working;πConstπ  CurrentCursor : Byte = 0;π  CursorArray   : Array[0..3] of Char = '|/-\';πbeginπ  CurrentCursor := Succ(CurrentCursor) mod 4;π  Write(CursorArray[CurrentCursor], #13);πend;ππProcedure OutPutAnagram(Target : AnagramStr;π                        Var Specimen : AnagramArray; Size : Word);πVarπ  Index : Word;πbeginπ  For Index := 0 to (Size - 1) doπ    Write(Target[Specimen[Index]]);π  Writeln;πend;ππFunction IsAnagram(Var Specimen : AnagramArray; Size : Word) : Boolean;πVarπ  Index1,π  Index2 : Word;π  Valid  : Boolean;πbeginπ  Valid  := True;π  Index1 := 0;π  While (Index1<Pred(Size)) and Valid doπ  beginπ    Index2 := Index1 + 1;π    While (Index2 < Size) and Valid doπ    beginπ      if Specimen[Index1] = Specimen[Index2] thenπ        Valid := False;π      inc(Index2);π    end;π    inc(Index1);π  end;π  IsAnagram := Valid;πend;ππProcedure FindAnagrams(Target : AnagramStr;π                       Var Specimen : AnagramArray; Size : Word);πVarπ  Index : Word;π  Carry : Boolean;πbeginπ  Repeatπ    working;π    if IsAnagram(Specimen, Size) thenπ    beginπ      OutputAnagram(Target, Specimen, Size);π      inc(AnagramCount);π    end;π    Index := 0;π    Repeatπ      Specimen[Index] := (Specimen[Index] + 1) mod Size;π      Carry := not Boolean(Specimen[Index]);π      Inc(Index);π    Until (not Carry) or (Index >= Size);π  Until Carry and (Index >= Size);πend;ππbeginπ  ClrScr;π  Write('Enter anagram Target: ');π  readln(Target);π  Writeln;π  AnagramCount := 0;π  Size := Strlen(Target);π  For Index := 0 to MaxAnagram doπ    Specimen[Index] := 0;π  For Index := 0 to Size - 1 doπ    Specimen[Index] := Size - Index - 1;π  FindAnagrams(Target, Specimen, Size);π  Writeln;π  Writeln(AnagramCount, ' Anagrams found With Source ', Target);πend.π                                                                                                             27     08-27-9320:01ALL                      MARK OUELLET             Fast Anagrams            IMPORT              20     èo   {$A+,B+,D+,E-,F+,G+,I+,L+,N-,O+,P+,Q+,R+,S+,T+,V-,X+,Y+}π{$M 65520,100000,655360}π{π  Copyright 1993 Mark Ouellet. All rights reserved.ππ  May be freely distributed and incorporated in your own code, in partπ  or in it's entirety as long as due credit is given to it's authorππ  All I ask is that you state my name if you use ALL or PART of it inπ  your own code.π}ππProgram FastAnagrams;ππUsesπ  Crt;ππTypeπ  StrPointer = ^String;π  NodePtr = ^Node;π  Node    = Recordπ    Anagram : StrPointer;π    Next    : NodePtr;π  end;ππVarπ  OldAnagrams : NodePtr;π  NewAnagrams : NodePtr;π  OldCursor : NodePtr;π  NewCursor : NodePtr;π  InputStr : String;ππProcedure GetInput;πbeginπ  ClrScr;π  Write('Input your String: ');π  readln(InputStr);πend;ππProcedure FindAnagrams;ππVarπ  OldIndex : Word;π  NewIndex : Word;ππbeginπ  OldAnagrams := NIL;π  OldCursor   := NIL;π  NewAnagrams := NIL;π  NewCursor   := NIL;ππ  New(OldCursor);π  OldCursor^.Next := OldAnagrams;π  GetMem(OldCursor^.Anagram, 2);π  OldCursor^.Anagram^ := Copy(InputStr, 1, 1);π  OldAnagrams := OldCursor;ππ  For OldIndex := 2 to Ord(InputStr[0]) doπ  beginπ    OldCursor := OldAnagrams;π    While OldCursor <> NIL doπ    beginπ      For NewIndex := 1 to Ord(OldCursor^.Anagram^[0])+1 doπ      beginπ        New(NewCursor);π        NewCursor^.Next := NewAnagrams;π        getmem(NewCursor^.Anagram, sizeof(OldCursor^.Anagram^)+1);π        NewCursor^.Anagram^ := OldCursor^.Anagram^;π        Insert(Copy(InputStr, OldIndex, 1),π          NewCursor^.Anagram^, NewIndex);π        NewAnagrams := NewCursor;π      end;π      OldCursor := OldCursor^.Next;π      FreeMem(OldAnagrams^.Anagram, Ord(OldAnagrams^.Anagram^[0])+1);π      OldAnagrams^.Anagram := nil;π      Dispose(OldAnagrams);π      OldAnagrams := OldCursor;π    end;π    OldAnagrams := NewAnagrams;π    OldCursor   := OldAnagrams;π    NewAnagrams := NIL;π    NewCursor   := NIL;π  end;πend;ππProcedure OutputAnagrams;πVarπ  Count : Word;πbeginπ  Count := 0;π  OldCursor := OldAnagrams;π  While OldCursor <> NIL doπ  beginπ    OldCursor := OldCursor^.Next;π    Writeln(OldAnagrams^.Anagram^);π    FreeMem(OldAnagrams^.Anagram, sizeof(OldAnagrams^.Anagram^));π    dispose(OldAnagrams);π    OldAnagrams := OldCursor;π    Inc(Count);π  end;π  Writeln;π  Writeln(Count, ' Anagrams found.');πend;ππbeginπ  GetInput;π  Writeln;π  Writeln(MaxAvail, ' Available memory.');π  Writeln;π  FindAnagrams;π  OutputAnagrams;πend.π 28     08-27-9320:35ALL                      DAVID JURGENS            dBase II File Structure  IMPORT              17     èo    HelpPC 2.0        PC Programmers Referenceπ Copyright (c) 1990 David Jurgensππ               dBASE - File Header Structure (dBASE II)ππ Offset Size          Descriptionππ   00   byte    dBASE version number 02h=dBASE IIπ   01   word    number of data records in fileπ   03   byte    month of last updateπ   04   byte    day of last updateπ   05   byte    year of last updateπ   06   word    size of each data recordπ   08 512bytes  field descriptors  (see below)π  520   byte    0Dh if all 32 field descriptors used; otherwise 00hππ - dBASE II file header has a fixed size of 521 bytesπππ              DBASE - File header structure (DBASE III)ππ Offset Size           Descriptionππ   00   byte      dBASE vers num 03h=dBASE III w/o .DBTπ                  83h=dBASE III w .DBTπ   01   byte      year of last updateπ   02   byte      month of last updateπ   03   byte      day of last updateπ   04   dword     long int number of data records in fileπ   08   word      header structure lengthπ   10   word      data record lengthπ   12 20bytes     version 1.0 reserved data spaceπ 32-n 32bytes ea. field descriptors  (see below)π  n+1   byte      0dH field terminator.πππ - unlike dBASE II, dBASE III has a variable length headerπππ                      dBASE - Field Descriptorsππ dBASE II Field Descriptors (header contains 32 FDs)ππ Offset Size              Descriptionππ   00  11bytes    null terminated field name string, 0Dh as firstπ                  byte indicates end of FDsπ   11   byte      data type, Char/Num/Logical (C,N,L)π   12   byte      field lengthπ   13   word      field data address, (set in memory)π   15   byte      number of decimal placesπππ dBASE III Field Descriptors (FD count varies):ππ Offset Size           Descriptionππ   00  11bytes   null terminated field name stringπ   11   byte     data type, Char/Num/Logical/Date/Memoπ   12   dword    long int field data address, (set in memory)π   16   byte     field lengthπ   17   byte     number of decimal placesπ   18  14bytes   version 1.00 reserved data areaππ       29     08-27-9320:38ALL                      GORDON TACKETT           Device Driver in TP      IMPORT              8      èo   {πGORDON TACKETTππIn version 7 of TP/BP you can write a device driver But it is tricky! Theπfollowing code is not fully tested but seems to work. After looking at someπdisassembly listings I added the patch file section. Use or abuse at your ownπrisk :-)π}ππProgram TestDriver;ππProcedure Dev_Strategy; Forward;πProcedure Dev_Int; Forward;ππProcedure DeviceDriverHeader;πbeginπ  Inline(π    $FFFF/π    $FFFF/π    $2000/π    $0000/π    $0000/π    $FFFF/$FFFF/$FFFF/$FFFF/0);πEnd;ππProcedure Dev_Strategy;πBeginπEnd;ππProcedure Dev_Int;πBeginπEnd;ππVarπ  F : File;ππBeginπ  If ParamCount = 999 Thenπ    DeviceDriverHeaderπ  elseπ  Beginπ    {patch driver}π    movemem(devicedriverheader, DeviceDriverHeader + 3, 20);π    Assign(F, ParamStr(0));π    Reset(F, 1);π    BlockWrite(F, DeviceDriverHeader, 20);π    Close(F);π  End;πEnd.ππ                                                                  30     08-27-9320:38ALL                      D.J. MURDOCK             Another Device in TP     IMPORT              42     èo   {πI've written a simple device driver in TP, and it works.  From some things I'veπheard, it won't work in all versions of DOS (it's an .EXE format device driver,πnot a .BIN format one).  There are tons of restrictions on what you can do inπit - DOS isn't reentrant, and the TP system library isn't designed to do thingsπwhile DOS is active, so I don't even let it get initialized, etc., etc.ππIt's still a bit of a mess, but here it is, for your enjoyment and edification:π a character device driver that keeps a buffer of 255 characters, calledπTPDEVICE.ππTo try it out, compile it (you'll need OPro or TPro; sorry, but stack swappingπis essential, and I wouldn't want to try to write code to do it myself), put itπinto your CONFIG.SYS (on a floppy disk, please!) asππ  device=tpdev.exeππand then reboot.   Hopefully you won't crash, but if you do, you'll have toπreboot from a different disk and remove it from CONFIG.SYS.ππThen you can tryππ  COPY TPDEVICE CONππto see the initialization message, andππ  ECHO This is a line for the buffer >TPDEVICEππto replace it with a new one.π}π{ DOS character device driver written entirely in TP 6 }ππ{ Written by D.J. Murdoch for the public domain, May 1991 }ππ{$S-,F-}       { Stack checking wouldn't work here, and we assume near calls }π{$M $1000,0,0} { We can't use the heap and don't use the stack.  Thisπ                 setting doesn't really matter though, since you normallyπ                 won't run TPDEV }ππprogram tpdev;ππusesπ  opint;  { OPro interrupt services, needed for stack switching }ππprocedure strategy_routine(bp:word); interrupt; forward;πprocedure interrupt_routine(bp:word); interrupt; forward;ππprocedure header; assembler;π{ Here's the trick:  an assembler routine in the main program, guaranteed toπ  be linked first in the .EXE file!!}πasmπ  dd $FFFFFFFF    { next driver }π  dw $8000        { attributes of simple character device }π  dw offset strategy_routineπ  dw offset interrupt_routineπ  db 'TPDEVICE'πend;ππconstπ  stDone = $100;π  stBusy = $200;ππ  cmInit  = 0;π  cmInput = 4;π  cmInput_no_wait = 5;π  cmInput_status  = 6;π  cmInput_flush   = 7;π  cmOutput        = 8;π  cmOutput_Verify = 9;π  cmOutput_status = 10;π  cmOutput_flush  = 11;ππtypeπ  request_header = recordπ    request_length : byte;π    subunit        : byte;π    command_code   : byte;π    status         : word;π    reserved       : array[1..8] of byte;π    case byte ofπ      cmInit : (num_units  : byte;π                first_free : pointer;π                args       : ^char;π                drive_num  : byte;);π      cmInput :  { also used for output }π               (media_descriptor : byte;π               buffer            : pointer;π               byte_count        : word);π      cmInput_no_wait : (next_char : char);π  end;ππvarπ  local_stack  : array[1..4000] of byte;π  end_of_stack : byte;π  request      : ^request_header;π  line         : string;ππprocedure handler(var regs : intregisters);π{ This routine is called by the strategy routine, and handles all requests.π  The data segment is okay, and we're running on the local_stack so we've gotπ plenty of space, but remember:π   ****** The initialization code for SYSTEM and all other units hasn'tπ          ever been called!!  ******** }πbeginπ  with request^ doπ  beginπ    case command_code ofππ      cmInit :π      beginπ        { Last thing in the data segment in TP6 - No heap!!}π        first_free := ptr(dseg, ofs(saveint75) + 4);π        status     := stDone;π        line       := 'TPDRIVER successfully initialized.';π      end;ππ      cmInput :π      beginπ        if byte_count > length(line) thenπ          byte_count := length(line);π        move(line[1], buffer^, byte_count);π        line := copy(line, byte_count + 1, 255);π        status := stDone;π      end;ππ      cmInput_no_wait :π      beginπ        if length(line) > 0 thenπ        beginπ          next_char := line[1];π          status := stDone;π        endπ        elseπ          status := stBusy;π      end;ππ      cmInput_Status,π      cmOutput_Status,π      cmInput_Flush,π      cmOutput_Flush : status := stDone;ππ      cmOutput,π      cmOutput_Verify :π      beginπ        if byte_count + length(line) > 255 thenπ          byte_count := 255 - length(line);π        move(buffer^, line[length(line) + 1], byte_count);π        line[0] := char(byte(byte_count + length(line)));π        status := stDone;π      end;π    end;π  end;πend;ππprocedure RetFar; assembler;π{ Replacement for the IRET code that ends the interrupt routines below }πasmπ  mov sp,bpπ  pop bpπ  pop esπ  pop dsπ  pop diπ  pop siπ  pop dxπ  pop cxπ  pop bxπ  pop axπ  retfπend;ππprocedure strategy_routine(bp : word);πvarπ  regs : intregisters absolute bp;πbeginπ  with regs doπ    request := ptr(es, bx);π  RetFar;πend;ππprocedure interrupt_routine(bp : word);πvarπ  regs : intregisters absolute bp;πbeginπ  SwapStackandCallNear(Ofs(handler), @end_of_stack, regs);π  RetFar;πend;ππbeginπ  writeln('TPDEVICE - DOS device driver written *entirely* in Turbo Pascal.');π  writeln('Install using DEVICE=TPDEV.EXE in CONFIG.SYS.');π  request := @header;  { Need a reference to pull in the header. }πend.π                                                                              31     08-27-9320:55ALL                      JACK MOFFITT             File at end of EXE       IMPORT              25     èo   {πJACK MOFFITTππ>Okay, how about this: If I wanted to attach it to the back of an EXE, Iπ>COPY /B it. Now, in the source code, how do I find the picture and setπ>everything up? I mean do you LoadGif (Ofs,Seg) or something? That's whatπ>I mean, and I'm sorry to put you through this.ππOk..  here we go..  everyone seems to be asking this, so i'll just postπsome source.  Granted this is not a COMPLETE program, just an example onπhow to read the header, and get a pointer to the GIF.π}ππ(* This code originally by Scott Johnson, I revised it later *)ππfunction GetSize(N : byte) : word;πfunction GetData(N : byte) : pointer;πfunction GetDataCount : byte;ππimplementationππusesπ  Dos;ππtypeπ  DataRec = recordπ    Size : word;π    Loc  : longint;π  end;π  DataArray    = array [1..255] of DataRec;π  DataArrayPtr = ^DataArray;ππ  ExeDataRec = recordπ    ActSize : word;π  end;πππvarπ  ExeFile   : file;π  DataCount : byte;         { count of data records }π  Data      : DataArrayPtr;ππprocedure OpenExe;πbeginπ  assign(ExeFile, ParamStr(0));π  reset(ExeFile, 1);πend;ππprocedure CloseExe;πbeginπ  Close(ExeFile);πend;ππprocedure InitExe;πvarπ  ExeHdr : recordπ    M, Z  : char;π    Len   : word;π    Pages : word;π  end;π  ExeLoc  : longint;π  I       : byte;π  ExeData : ExeDataRec;πbeginπ  OpenExe;π  BlockRead(ExeFile, ExeHdr, SizeOf(ExeHdr));π  if ExeHdr.Len = 0 thenπ    ExeHdr.Len := $200;π  ExeLoc := (longint(ExeHdr.Pages) - 1) shl 9 + longint(ExeHdr.Len);π  Seek(ExeFile, ExeLoc);π  BlockRead(ExeFile, DataCount, 1);      { read data count byte }π  Inc(ExeLoc);π  GetMem(Data, SizeOf(DataRec) * DataCount);π  for I := 1 to DataCount doπ  beginπ    Seek(ExeFile, ExeLoc);π    BlockRead(ExeFile, ExeData, SizeOf(ExeData));π    Data^[I].Loc  := ExeLoc;π    Data^[I].Size := ExeData.ActSize;π    Inc(ExeLoc, ExeData.ActSize + 2);π  end;π  CloseExe;πend;ππfunction GetSize(N : byte) : word;πbeginπ  if N > DataCount thenπ    RunError(201);π  GetSize := Data^[N].Size;πend;ππfunction GetData(N : byte) : pointer;πvarπ  P, D    : pointer;π  DataLoc : longint;π  E       : ExeDataRec;πbeginπ  if N > DataCount thenπ    RunError(201);π  GetMem(P, Data^[N].Size);π  OpenExe;π  Seek(ExeFile, Data^[N].Loc + 2);   { +2 is to get past info record }π  BlockRead(ExeFile, P^, Data^[N].Size);π  CloseExe;π  GetData := P;πend;ππfunction GetDataCount : byte;πbeginπ  GetDataCount := DataCount;πend;ππbeginπ  InitExe;πend.ππ{πOk.. that's it.  Call GetData(x) to get the location of the firstπelement.  Datacount is the number of GIFs or whatever you have in thereπand the first two bytes are the actual size..  So to add a file, justπmake a temp file called ADDED.DAT, write a byte value for the datacount,πand a word value for the filesize of the data you're adding, and thenπthe data.  Hope this help all of you who wanted to be able to add ANSis,πGIFs, and whatnot onto exes.  Also, with little modification, you canπmake it read from .DAT files with multiple gifs and stuff in them.π}π                                                                                              32     08-27-9320:55ALL                      GABE KRUPA               Modify EXE constants     IMPORT              65     èo   (*πGABE KRUPAππ> I need to add some information to the end of an EXE file and be ableπ> Say a PCX image for example.  I'm concerned about the EXE file alreadπ> open due to being executed.  Does info tacked to the end of an EXE geπ> into memory automatically, etc.  I haven't tried this yet but am abouπ> hoping someone who has tried it can assist me to avoid some of the piπ> they may have encountered.  Thanks.  (BTW, I am experienced in Pas &ππ  Well, I made a unit for that purpose, but my unit only tacks on 1K ofπstorage space... You can make it as large as you want it, but it'll be aπREAL time consumer and it might push your text editor to the limits (I'mπnot sure if the IDE has a file size limit).ππ  Here it is (in a VERY shortened version )π}πunit inject1k;ππinterfaceπimplementationπconst doesnt_matter_what_this_is_called : boolean = false;ππprocedure never_really_call_this_procedure;πbeginπ  if doesnt_matter_what_this_is_called thenπ    inline( 228/229/230/231/231/233/234/  { this I use for a ID string }π            234/234/234/234/234/234/234/π            234/234/234/234/243/234/234/π{ repeat as many times until you get enough .. each '234/' is 1 byte }π            234/234/234/234/234/234/234/π            234/234/234/234/234/234/234/  { this is the actual 'junk' }π           ); { inline }πend; { procedure }ππend. { unit }π{π  I only inject 1024 into my EXE file... If you want, you can makeπidentical units like that, but the DATA area will NOT be in one longπstring unless all the bytes are in one unit.π  I use the ID string to correctly place the file pointer. Just open theπEXE, read in bytes until you get a 228. Read another, if it's a 229πetc.. Keep looping until you get a 228-229-230-231-232-233-234 and thenπyou can start reading/writing. It's by no means the easiest way, but Iπprefer it over trying to append to the end. I tried that, but I keptπgetting errors and such. As long as the PCX file is fairly small, youπwon't have too much of a problem.π  I'm not sure what the chances are, they must be pretty slim to find aπstring (228-234) one after the other in an EXE. If you think they areπhigher, or whatever, just put your own in. You could probably even putπtext in like this:π}πinline('D'/'A'/'T'/'A'/' '/'S'/'T'/'A'/'R'/'T'/'S'/' '/'H'/'E'/'R'/'E'/π111/111/111/111  { etc... } );π{π         I hope this helps, or gives you some ideas. Note, the unit willπbe about TWICE as large as the number of bytes you inject (maybe 1000πmore), but the EXE will only increse by the number you add. I'm prettyπsure that the extra bytes are just data/debug info in the TPU file.π*)ππ{πMARK LEWISππ> I need to add some information to the end of an EXE file and be ableπ> Say a PCX image for example.  I'm concerned about the EXE file alreadππ[... trim ...]ππ> Well, I made a unit for that purpose, but my unit only tacks onπ> 1K of storage space... You can make it as large as you want it,π> but it'll be a REAL time consumer and it might push your textπ> editor to the limits (I'm not sure if the IDE has a file sizeπ> limit). Here it is (in a VERY shortened version )π> unit inject1k;ππ[... trim ...]ππinteresting<<smile>>... i never thought of doing it like that.. hehe.. here'sπa unit i got from this echo or the other PASCAL echo several years ago.. i'veπused it in self-limiting programs (ones that only run a certain number ofπtimes) and other programs that may be subject to hacking of various forms...πi've modified it slightly for my purposes...π}πunit selfmod;ππ{ Allows a program to self modify a typed constant in the .exe file.  It     }π{ also performs an automatic checksum type .exe file integrity check.        }π{ A longint value is added to the end of the exe file.  This can be read by  }π{ a separate configuration program to enable it to determine the start of    }π{ the programs configuration data area.  To use this the configuration       }π{ typed constant should be added immediately following the declaration of    }π{ ExeData.                                                                   }π{ Where this unit is used, it should always be the FIRST unit listed in the  }π{ uses declaration area of the main program.                                 }π{ Requires DOS 3.3 or later.  Program must not be used with PKLite or LZExe  }π{ or any similar exe file compression programs.                              }π{ The stack size needed is at least 9,000 bytes.                             }ππinterfaceππtypeπ  ExeDatatype    = recordπ                     IDStr      : string[8];π                     FirstTime  : boolean;π                     Hsize      : word;π                     ExeSize    : longint;π                     CheckSum   : longint;π                     StartConst : longint;π                   end;ππconstπ  ExeData : ExeDatatype = (IDStr     : 'IDSTRING';π                           FirstTime : true;π                           Hsize     : 0;π                           ExeSize   : 0;π                           CheckSum  : 0;π                           StartConst: 0);ππ{ IMPORTANT: Put any config data typed constants here }ππprocedure Write2Exec(var data; size: word);ππ{============================================================================}ππimplementationππprocedure InitConstants;π  varπ    f           : file;π    tbuff       : array[0..1] of word;ππ  function GetCheckSum : longint;π    { Performs a checksum calculation on the exe file }π    varπ      finished  : boolean;π      x,π      CSum      : longint;π      BytesRead : word;π      buffer    : array[0..4095] of word;π    beginπ      {$I-}π      seek(f,0);π      finished := false;  CSum := 0;  x := 0;π      BlockRead(f,buffer,sizeof(buffer),BytesRead);π      while not finished do begin             { do the checksum calculations }π        repeat         { until file has been read up to start of config area }π          inc(CSum,buffer[x mod 4096]);π          inc(x);π          finished := ((x shl 1) >= ExeData.StartConst);π        until ((x mod 4096) = 0) or finished;π        if not finished then                { data area has not been reached }π          BlockRead(f,buffer,sizeof(buffer),BytesRead);π      end;π      GetCheckSum := CSum;π    end;ππ  beginπ    assign(f, ParamStr(0));π    {$I-} Reset(f,1);π    with ExeData do beginπ      if FirstTime and (IOResult = 0) then beginπ        Seek(f,2);                  { this location has the executable size }π        BlockRead(f,tbuff,4);π        ExeSize := tbuff[0]+(pred(tbuff[1]) shl 9);π        seek(f,8);                                   {  get the header size }π        BlockRead(f,hsize,2);π        FirstTime := false;π        StartConst := longint(hsize+Seg(ExeData)-PrefixSeg) shl 4 +π                      Ofs(ExeData) - 256;π        CheckSum := GetCheckSum;π        Seek(f,StartConst);π        BlockWrite(f,ExeData,sizeof(ExeData));π        seek(f,FileSize(f));π        BlockWrite(f,StartConst,4);π      endπ      elseπ        if GetCheckSum <> CheckSum then beginπ          writeln;π          writeln(#7,#7,'Program file has been UNLAWFULLY modified!',#7,#7);π          writeln;π          writeln('It may have a Virus attached or someone may have made');π          writeln('an attempt to HACK it. You should check your system for');π          writeln('virus'' before continuing....');π          writeln;π          writeln('Please reinstall the .EXE file from the original archive.');π          writeln('Aborting....');π          halt(255);π        endπ        elseπ          beginπ            writeln;π            writeln('Integrity Validated.');π          end;π    end;  { with }π    Close(f); {$I+}π    if IOResult <> 0 then beginπ      writeln('Unable to initialise program');π      halt;π    end;π  end; { InitConstants }ππprocedure Write2Exec(var data; size: word);π { writes a new typed constant into the executable file. }π  varπ     f          : file;π  beginπ    assign(f, ParamStr(0));π    {$I-} Reset(f,1);π    Seek(f,longint(ExeData.Hsize+Seg(data)-PrefixSeg) shl 4 + Ofs(data)- 256);π    BlockWrite(f,data,size);π    Close(f); {$I+}π    if IOResult <> 0 then;π  end; { Write2Exec }ππbeginπ  writeln('Please Standby...');π  InitConstants;πend.ππ              33     08-27-9321:01ALL                      STEVE ROGERS             True EXE Size            IMPORT              12     èo   {πSTEVE ROGERSππ> Also, does anyone know how PKware wrote the ZIP2EXE Program? I'm alsoπ>writing an encryption Program, and I thought a 'self-decrypting' Fileπ>would be neat, so I had some ideas on how to do it. Could you justπ>append the encrypted data to the end of a short 'stub' Program, whichπ>just seeks in how ever many Bytes and  reads from there? Or would Iπ>have to somehow assign all the data to a few Typed Constants?ππJust so happens I have been dealing With the same problem. I haveπwritten a Procedure to show the "True" size of an EXE File. Knowing thisπyou can easily get to your "data area" by seeking past the "True" size.ππ( Acknowledgements to Andy McFarland and Ray Duncan )π}ππFunction exesize(fname : String) : LongInt;πTypeπ  t_size = Recordπ    mz : Array [1..2] of Char;π    remainder,π    pages : Word;π  end;ππVarπ  f  : File of t_size;π  sz : t_size;ππbeginπ  assign(f,fname);π  {$i-}π  reset(f);π  {$i+}   { io checking should be off }π  if (ioresult <> 0) thenπ    exesize:= 0π  elseπ  beginπ    read(f,sz);π    close(f);π    With sz doπ      exesize := remainder + (pred(pages) * 512);π  end;πend;πππ{πThis thing reads the header of an EXE File and gets the info there. Iπwas amazed when I ran this on a bunch of progs and found how many haveπdata appended. Hope it helps. :)π}                                                                                                  34     08-27-9321:23ALL                      GERD KORTEMEYER          Detect Float Error       IMPORT              132    èo   {πGERD KORTEMEYERππhere are two Units For trapping float-exceptions. In your Program youπwill have to addππ  Uses err387ππand at the beginning of your main Program say For exampleππbeginπ   exception(overflow, masked);π   exception(underflow, dumpask);π   exception(invalid, dumpexit);π   autocorrect(zerodiv, 1.0);π   exception(precision, masked);ππIn this way you can choose For any kind of exception in which way it isπto be handeled. After the lines above the result of a division by zeroπwill be '1.0', in Case of an underflow there will be a dump of the coproπand the user will be asked For the result he wants the operation to have,πin Case of an overflow the largest available number will be chosen andπso on ...ππHere are the Unitsππ    err387 and dis387π}ππ{ ---------------------------------------------------------- }π{ Fehlerbehandlungsroutinen fuer den Intel 80387 bzw. 486 DX }π{ Geschrieben in Turbo Pascal 6.0                            }π{ von Gerd Kortemeyer, Hannover                              }π{ ---------------------------------------------------------- }ππUnit err387;ππInterfaceππUsesπ  dis387, Dos, Crt;ππConstπ  invalid   = 1;π  denormal  = 2;π  zero_div  = 4;π  overflow  = 8;π  underflow = 16;π  precision = 32;π  stackfault= 64;π  con1      = 512;ππ  masked    = 0;π  runtime   = 1;π  dump      = 2;π  dumpexit  = 3;π  dumpask   = 4;π  autocorr  = 5;πππProcedure exception(which, what : Word);πProcedure autocorrect(which : Word; by : Extended);ππProcedure handle_off;πProcedure handle_on;ππProcedure restore_masks;ππProcedure clear_copro;πFunction  status_Word : Word;ππVarπ  do_again : Word;ππImplementationππConstπ  valid = 0;π  zero  = 1;π  spec  = 2;π  empty = 3;ππ  topmask : Word = 14336;π  topdiv  = 2048;ππ  anyerrors : Word = 63;ππ  zweipot : Array [0..15] of Word =π    (1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024,π     2048, 4096, 8192, 16384, 32768);ππ  ex_nam : Array[0..5] of String=π    ('Invalid   ',π     'Denormal  ',π     'Zero-Div  ',π     'Overflow  ',π     'Underflow ',π     'Precision ');ππVarπ  setmasks : Byte;π  normal   : Recordπ    Case Boolean OFπ      True : (adr : Pointer);π      False: (pro : Procedure);π    end;ππ  Exit_on,π  dump_on,π  ask_on,π  auto_on,π  standard : Word;ππ  auto_val : Array [0..5] of Extended;ππProcedure Mask(which : Word);πVarπ  cw : Word;πbeginπ  Asmπ    fstcw cwπ  end;π  cw := cw or which;π  setmasks := Lo(cw);π  Asmπ    fldcw cwπ  end;πend;ππProcedure Unmask(which : Word);πVarπ  cw : Word;πbeginπ  Asmπ    fclexπ    fstcw cwπ  end;π  cw := cw and not (which);π  setmasks := Lo(cw);π  Asmπ    fldcw cwπ  end;πend;ππProcedure restore_masks;πVarπ  setm : Word;π  i    :Integer;πbeginπ  setm:=setmasks;π  For i := 0 to 5 doπ    if (setm and zweipot[i]) <> 0 thenπ      Mask  (zweipot[i])π    elseπ      Unmask(zweipot[i]);πend;ππProcedure clear_copro;πVarπ  cw : Word;πbeginπ  Asmπ    fstcw cwπ  end;π  setmasks := Lo(cw);π  Asmπ    finitπ  end;πend;ππFunction status_Word;πbeginπ  Asmπ    fstsw @resultπ  end;πend;ππ{ Bei welcher Exception soll was passieren? }πProcedure exception;πbeginπ  Case what OFππ    masked  : Mask(which);ππ    runtime :π      beginπ        Unmask(which);π        standard := standard or which;π      end;ππ    dump :π      beginπ        Unmask(which);π        standard := standard and NOT(which);π        dump_on  := dump_on  or  which;π        Exit_on  := Exit_on  and NOT(which);π        ask_on   := ask_on   and NOT(which);π        auto_on  := auto_on  and NOT(which);π      end;ππ    dumpexit :π      beginπ        Unmask(which);π        standard := standard and NOT(which);π        dump_on  := dump_on  or  which;π        Exit_on  := Exit_on  or  which;π        ask_on   := ask_on   and NOT(which);π        auto_on  := auto_on  and NOT(which);π      end;ππ    dumpask :π      beginπ        Unmask(which);π        standard := standard and NOT(which);π        dump_on  := dump_on  or  which;π        Exit_on  := Exit_on  and NOT(which);π        ask_on   := ask_on   or  which;π        auto_on  := auto_on  and NOT(which);π      end;π   end;πend;ππ{ zum Setzen von Auto-Korrekt-Werten }ππProcedure autocorrect;πVarπ  i : Integer;πbeginπ   Unmask(which);π   standard := standard and NOT(which);π   dump_on  := dump_on  and NOT(which);π   Exit_on  := Exit_on  and NOT(which);π   ask_on   := ask_on   and NOT(which);π   auto_on  := auto_on  or  which;π   For i := 0 to 5 doπ     if (which and zweipot[i]) <> 0 thenπ       auto_val[i] := by;πend;ππ{ ------------- Die Interrupt-Routine selbst ------------- }ππProcedure errorcon; Interrupt;πVarπ  copro : Recordπ    control_Word,π    status_Word,π    tag_Word, op,π    instruction_Pointer,π    ip, operand_Pointer, : Word;π    st                   : Array [0..7] of Extended;π  end;ππ  top : Integer; { welches Register ist Stacktop? }ππ  masked,            { welche Exceptions maskiert? }π  occured : Byte;    { welche Exceptions aufgetreten? }ππ  opcode  : Word;ππ  inst_seg,       { Instruction-Pointer, Segment }π  inst_off,       { "                  , Offset  }π  oper_seg,       { Operand-Pointer    , Segment }π  oper_off: Word; { "                  , Offset  }ππ  inst_point : ^Word;                 { zum Adressieren des Opcodes }ππ  oper_point : Recordπ    Case Integer of { zum Adressieren des Operanden }π      1 : (ex : ^Extended);π      2 : (db : ^Double);π      3 : (si : ^Single);π      4 : (co : ^Comp);π    end;ππ  marker: Array [0..7] of Word; { Register-Marker nach Tag-Word }ππ  opt_dump,               { soll ausgeben werden? }π  opt_exit,               { soll aufgehoert werden? }π  opt_ask,                { soll Ergebnis abgefragt werden? }π  opt_auto  : Boolean;    { soll Ergebnis automatisch korrigiert werden? }ππ  i         : Integer;ππ  mem_access: Boolean;    { gibt es Speicherzugriff? }ππ  op_name   : String;     { Mnemonik des Befehls }ππ{ Ersetze Stacktop durch abgefragten Wert }πProcedure ask_correct;πVarπ  res  : Extended;π  ch   : Char;π  t    : String;π  code : Integer;πbeginπ   Asmπ     fstp resπ   end;π   WriteLN;π   Write('The result would be ', res, '. Change? (y/n) ' );π   Repeatπ     Repeat Until KeyPressed;π     ch := ReadKey;;π   Until ch in ['Y','y','N','n'];π   Writeln;π   if ch in ['Y','y'] thenπ   Repeatπ     Write('New value : ');π     READLN(t);π     VAL(t, res, code);π   Until code = 0;π   Asmπ     fld resπ   end;πend;ππFunction hex(w : Word) : String; { Ausgabe als HeX-Zahl }πConstπ  zif : Array [0..15] of Char = ('0','1','2','3','4','5','6','7','8','9',π                                    'a','b','c','d','e','f');πbeginπ  hex := zif[w div zweipot[12]] +π         zif[(w MOD zweipot[12]) div zweipot[8]] +π         zif[(w MOD zweipot[8]) div zweipot[4]] +π         zif[w MOD zweipot[4]];πend;ππProcedure choice;πVarπ  ch : Char;πbeginπ  WriteLN;π  Write('C)ontinue, A)bort ');π  Repeatπ    Repeat Until KeyPressed;π    ch:=ReadKey;;π    if ch in ['A','a'] thenπ      Halt(0);π  Until ch in ['C','c'];π  WriteLN;πend;ππProcedure showcopro; { Ausgeben des FSAVE - Records }πVarπ  i : Integer;πbeginπ  TextMode(LastMode);π  HighVideo;π  WriteLN('Floating point exception, last opcode: ',hex(opcode),π                                               ' (',op_name,')');π  NormVideo;π  WriteLN('Instruction Pointer : ',hex(inst_seg),':',hex(inst_off),π          ' (',hex(inst_point^),')');π  if mem_access thenπ  beginπ    WriteLN('Operand Pointer     : ',hex(oper_seg),':',hex(oper_off));π    WriteLN('( Extended: ',oper_point.ex^,', Double: ',oper_point.db^);π    WriteLN('  Single  : ',oper_point.si^,', Comp  : ',oper_point.co^,' )');π  endπ  elseπ  beginπ    WriteLN;π    WriteLN ('No memory access');π    WriteLN;π  end;π  HighVideo;π  if (occured and stackfault) = 0 thenπ  beginπ    WriteLN('Exception ','Masked':8,'Occured':8,'Should be masked':18);π    NormVideo;π    For i:=0 to 5 doπ      WriteLN(ex_nam[i], (masked   and zweipot[i]) <> 0 : 8,π                         (occured  and zweipot[i]) <> 0 : 8,π                         (setmasks and zweipot[i]) <> 0 : 18);π    HighVideo;π  endπ  elseπ  beginπ    WriteLN('Invalid Operation:');π    if (copro.status_Word and con1) <> 0 thenπ      WriteLN('                       -- Stack Overflow --')π    elseπ      WriteLN('                       -- Stack Underflow --');π    WriteLN;π  end;ππ  WriteLN('Reg  ','Value':29,'Marked':10);π  Normvideo;π  For i := 0 to 7 doπ  beginπ    Write('st(',i,')', copro.st[i] : 29);π    Case marker[i] OFπ       valid : WriteLN('Valid'   : 10);π       spec  : WriteLN('Special' : 10);π       empty : WriteLN('Empty'   : 10);π       zero  : WriteLN('Zero'    : 10);π    end;π  end;πend;ππ{ Ersetze Stacktop durch Auto-Korrekt-Wert }ππProcedure auto_corr;πVarπ  res : Extended;π  i   : Integer;πbeginπ  Asmπ    fstp resπ  end;π  For i := 0 to 5 doπ    if ((occured and zweipot[i]) <> 0) andπ       ((auto_on and zweipot[i]) <> 0) thenπ      res := auto_val[i];π  Asmπ    fld resπ  end;πend;πππProcedure do_it_again;πTypeπ  codearr = Array[0..4] of Byte;πVarπ  sam : Recordπ    Case Boolean OFπ      True : (b: ^codearr );π      False: (p: Procedure);π    end;ππ  op_point : Pointer;π  x        : extended;πbeginπ  New(sam.b);π  sam.b^[0]:=Hi(opcode);π  sam.b^[1]:=Lo(opcode);π  if mem_access thenπ  beginπ  { --- mod r/m auf ds:[di] stellen (00ttt101) --- }π    sam.b^[1] := sam.b^[1] and not (zweipot[7] + zweipot[6] + zweipot[1]);π    sam.b^[1] := sam.b^[1] or (zweipot[2] + zweipot[0]);π  end;π  sam.b^[2] := $ca; { retf 0000 }π  sam.b^[3] := $00;π  sam.b^[4] := $00;π  op_point  := oper_point.ex;π  Asmπ    push dsπ    lds di, op_pointπ  end;ππ  sam.p;ππ  Asmπ    pop dsπ  end;π  Dispose(sam.b);πend;ππbeginπ  Asmπ    push   axπ    xor    al,alπ    out    0f0h,alπ    mov    al,020hπ    out    0a0h,alπ    out    020h,alπ    pop    axπ    fsave  coproπ  end;ππ  { === Pruefen, ob Bearbeitung durch ERRORCON erwuenscht === }π  if (copro.status_Word and standard) <> 0 thenπ  beginπ    Asmπ      frstor coproπ    end;π    normal.pro; { Bye, bye ... }π  end;π  { === Auswerten des FSAVE-Records ========================= }π  { --- Opcode wie im Copro gespeichert     --- }π  opcode := zweipot[15] + zweipot[14] + zweipot[12] + zweipot[11] +π            (copro.ip MOD zweipot[11]);π  op_name := dis(opcode);π  mem_access := op_name='...';π  { --- Was war maskiert, was ist passiert? --- }π  masked  := Lo(copro.control_Word);π  occured := Lo(copro.status_Word );π  { --- Der Instruction-Pointer             --- }π  inst_seg := copro.ip and (zweipot[15] + zweipot[14] + zweipot[13] +π                           zweipot[12]);π  inst_off := copro.instruction_Pointer;π  inst_point := Ptr(inst_seg,inst_off);π  { --- Der Operand-Pointer                 --- }π  oper_seg := copro.op and (zweipot[15] + zweipot[14] + zweipot[13] +π                            zweipot[12]);π  oper_off := copro.operand_Pointer;π  oper_point.ex := Ptr(oper_seg,oper_off);π  { --- Wer ist gerade Stacktop? --- }π  top := (copro.status_Word and topmask) div topdiv;π  { --- Einlesen der Marker aus Tag-Word --- }π  For i := 0 to 7 doπ  beginπ    marker[(8 + i - top) MOD 8] := (copro.tag_Word and (zweipot[i * 2] +π                                    zweipot[i * 2 + 1])) div zweipot[i * 2];π  end;ππ  { --- Welche Aktionen sollen ausgefuehrt werden? --- }π  opt_dump := (copro.status_Word and dump_on) <> 0;π  opt_exit := (copro.status_Word and Exit_on) <> 0;π  opt_ask  := (copro.status_Word and ask_on ) <> 0;π  opt_auto := (copro.status_Word and auto_on) <> 0;ππ  { === Aktionen ============================================ }π  if opt_dump thenπ    showcopro;π  if opt_exit thenπ  beginπ    WriteLN;π    WriteLN('Exit Program due to Programmers request');π    HALT; { Bye, bye ... }π  end;π  if opt_dump and not (opt_ask) thenπ    choice;ππ  copro.control_Word := copro.control_Word or anyerrors;π  Asmπ    frstor coproπ    fclexπ  end;π  { --- Befehl nochmals ausfuehren --- }π  if (occured and do_again) <> 0 thenπ    do_it_again;π  { --- Noch was? --- }π  if opt_auto thenπ    auto_corr;π  if opt_ask  thenπ    ask_correct;π  restore_masks;πend;ππ{ ------------- Ein- und Ausschalten ------------- }ππProcedure handle_on;πbeginπ  Getintvec($75, normal.adr);π  Setintvec($75, @errorcon);πend;ππProcedure handle_off;πbeginπ  Setintvec($75, normal.adr);πend;ππbeginπ  handle_on;π  dump_on :=0;π  Exit_on :=0;π  ask_on  :=0;π  auto_on :=0;π  standard:=0;π  do_again:=invalid+zero_div+denormal;π  clear_copro;πend.πππππππUnit dis387;ππInterfaceππFunction dis(opco : Word) : String;ππImplementationππFunction dis;πVarπ  d, op : String;ππ  Procedure opcr(st : Word);π  Varπ    t : String;π  beginπ    str(st, t);π    op := ' st,st(' + t + ')';π  end;ππ  Procedure opc(st : Word);π  Varπ    t : String;π  beginπ    str(st, t);π    op := ' st(' + t + '),st';π  end;ππ  Procedure op1(st : Word);π  Varπ    t : String;π  beginπ    str(st, t);π    op := ' st(' + t + ')';π  end;ππbeginπ  d  := '...';π  op := '';ππ  Case Hi(opco) OFπ    $d8 :π      Case Lo(opco) div 16 OFπ        $c :π          if opco MOD 16 >= 8 thenπ          beginπ            d := 'fmul';π            opcr(opco MOD 16 - 8);π          endπ          elseπ          beginπ            d := 'fadd';π            opcr(opco MOD 16);π          end;ππ        $e :π          if opco MOD 16 >= 8 thenπ          beginπ            d := 'fsubr';π            opcr(opco MOD 16 - 8);π          endπ          elseπ          beginπ            d := 'fsub';π            opcr(opco MOD 16);π          end;ππ        $f :π          if opco MOD 16 >= 8 thenπ          beginπ            d := 'fdivr';π            opcr(opco MOD 16 - 8);π          endπ          elseπ          beginπ            d := 'fdiv';π            opcr(opco MOD 16);π          end;π      end;ππ   $d9 :π     Case Lo(opco) OFπ       $d0 : d := 'fnop';π       $e0 : d := 'fchs';π       $e1 : d := 'fabs';π       $e4 : d := 'ftst';π       $e5 : d := 'fxam';π       $e8 : d := 'fld1';π       $e9 : d := 'fld2t';π       $ea : d := 'fld2e';π       $eb : d := 'fldpi';π       $ec : d := 'fldlg2';π       $ed : d := 'fldln2';π       $ee : d := 'fldz';π       $f0 : d := 'f2xm1';π       $f1 : d := 'fyl2x';π       $f2 : d := 'fptan';π       $f3 : d := 'fpatan';π       $f4 : d := 'fxtract';π       $f5 : d := 'fprem1';π       $f6 : d := 'fdecstp';π       $f7 : d := 'fincstp';π       $f8 : d := 'fprem';π       $f9 : d := 'fyl2xp1';π       $fa : d := 'fsqrt';π       $fb : d := 'fsincos';π       $fc : d := 'frndint';π       $fd : d := 'fscale';π       $fe : d := 'fsin';π       $ff : d := 'fcos';π     end;ππ   $db :π     Case Lo(opco) OFπ       $e2 : d := 'fclex';π       $e3 : d := 'finit';π     end;π   $dc :π     Case Lo(opco) div 16 OFπ       $c :π         if opco MOD 16 >= 8 thenπ         beginπ           d := 'fmul';π           opc(opco MOD 16-8);π         endπ         elseπ         beginπ           d := 'fadd';π           opc(opco MOD 16);π         end;ππ       $e : if opco MOD 16 >= 8 thenπ         beginπ           d := 'fsub';π           opc(opco MOD 16 - 8);π         endπ         elseπ         beginπ           d := 'fsubr';π           opc(opco MOD 16);π         end;ππ       $f :π         if opco MOD 16 >= 8 thenπ         beginπ           d := 'fdiv';π           opc(opco MOD 16 - 8);π         endπ         elseπ         beginπ           d := 'fdivr';π           opc(opco MOD 16);π         end;π     end;ππ   $dd :π     Case Lo(opco) div 16 OFπ       $c :π         beginπ           d := 'ffree';π           op1(opco MOD 16);π         end;π       $d :π         if opco MOD 16 >= 8 thenπ         beginπ           d := 'fstp';π           op1(opco MOD 16 - 8);π         endπ         elseπ         beginπ           d := 'fst';π           op1(opco MOD 16);π         end;π       $e :π         if opco MOD 16 >= 8 thenπ         beginπ           d := 'fucomp';π           op1(opco MOD 16 - 8);π         endπ         elseπ         beginπ           d := 'fucom';π           op1(opco MOD 16);π         end;π     end;ππ   $de :π     Case Lo(opco) div 16 OFπ       $c :π         if opco MOD 16 >= 8 thenπ         beginπ           d := 'fmulp';π           opc(opco MOD 16 - 8);π         endπ         elseπ         beginπ           d := 'faddp';π           opc(opco MOD 16);π         end;ππ       $d : d := 'fcompp';ππ       $e :π         if opco MOD 16 >= 8 thenπ         beginπ           d := 'fsubp';π           opc(opco MOD 16 - 8);π         endπ         elseπ         beginπ           d := 'fsubrp';π           opc(opco MOD 16);π         end;ππ       $f :π         if opco MOD 16 >= 8 thenπ         beginπ           d := 'fdivp';π           opc(opco MOD 16 - 8);π         endπ         elseπ         beginπ           d := 'fdivrp';π           opc(opco MOD 16);π         end;π     end;π   end;ππ   dis := d + op;πend;ππbeginπend.π                           35     08-27-9321:40ALL                      SEAN PALMER              Simple Multi-Tasker      IMPORT              22     èo   {π by Sean L. Palmerπ Public Domainππ This is a 'multitasking' Program in the sense that it hooks intoπ the timer interrupt, but what that interrupt ends up actuallyπ doing is controlled by the current value in SaveAdr, whichπ changes With each interrupt as the routine passes control backπ to the tick handler not by Exiting normally, but by an explicitπ transfer of control.π The end result of this is that you can Write a state-drivenπ interrupt handlerπ The included example is RealLY simplistic, and barely tested.π I intend to use this to Write a comm port driver thatπ parses the incoming data as it receives it which wouldπ be nice in a communications Program that shells to Dos, asπ the incoming Chars could be saved to disk in the backgroundπ With buffered ZModem or something...π}ππProgram intTest;ππUsesπ  Dos;ππVarπ  saveAdr : Word;  {offset in this code segment of where we are now}π  active  : Boolean;  {to avoid re-entrancy}ππProcedure intHandler; Far; Assembler;πAsmπ  pushaπ  mov  ax, seg @DATAπ  mov  ds, axππ  {anything you need to do before continuing (reading port data?), do here}ππ  in   al, $61  {click speaker as an example}π  xor  al, 2π  out  $61, alππ  test active, $FF  {exit now if interrupted ourselves}π  jz   @OKπ  popaπ  iretππ @OK:π  inc Byte ptr activeπ  stiπ  jmp [saveAdr]  {near jump to continue where handler last left off}πend;ππ{call this Procedure from StateHandler to suspend execution Until next time}ππProcedure wait; near; Assembler;πAsm {wait For next interrupt}π  pop Word ptr saveAdr  {save where to continue next time}π  dec Byte ptr activeπ  popa                  {restore caller regs}π  iretπend;ππConstπ  c : Char = '.';ππProcedure stateHandler;πbeginπ{π a stateHandler Procedure should never ever Exit (only by calling 'wait'),π shouldn't have any local Variables or parameters, and shouldn't callπ 'wait' With anything on the stack (like from a subroutine).π This routine is using the caller's (interrupted Program's) stack, so beπ very very careful}ππ Asmπ   pop bp  {clean up stack mess left by Turbo's Procedure header}π end;π {^ alternative method here is to init saveAdr to offset(proc)+3 and skipπ  the push bp; mov bp,sp altogether}ππ  Repeat  {this is an example only}π    c := '@';π    wait;π    c := '.';π    wait;π  Until False;                {don't let it return normally!!}πend;ππVarπ  oldHook : Procedure;π  i       : Integer;ππbeginπ  saveAdr := ofs(stateHandler);π  getIntVec($1C, @oldHook);π  setIntVec($1C, @intHandler);π  For i := 1 to 1500 doπ    Write(c);π  setIntVec($1C, @oldHook);πend.πππ                                                                                                                     36     08-27-9322:12ALL                      DAVID DOTY               Writing To EXE File      IMPORT              73     èo   {π> How are you saaving the CFG into the .EXE?? Mind posting some code that wilπ> save the CFG to the EXE?(When you get all your bugs fixed!)ππI use these routines in my self-modifying .EXE's. They work pretty good.π}ππUnit WritExec;ππ  { ==================================================================ππ                               Unit: WritExecπ                             Author: David Dotyπ                                     Skipjack Softwareπ                                     Columbia, Marylandπ               CompuServe User I.D.: 76244,1043ππ    This Unit is based on a previously published Program:ππ                            Program: AutoInst v2.0π                             Author: David Duboisπ                                     Zelkop Softwareπ                                     Halifax, Nova Scotiaπ               CompuServe User I.D.: 71401,747π                  Date last revised: 1988.04.24ππ    ==================================================================ππ    This source code is released to the public domain.  if further changesπ    are made, please include the above credits in the distributed code.ππ    This Unit allows a Program to change the value of a Typed Constant in itsπ    own .EXE File.  When the Program is run again, the data will be initializedπ    to the new value.  No external configuration Files are necessary.ππ    Usesππ    Examples of the usefulness of this technique would be:ππ    o   A Program that allows the user to change default display colors.ππ    o   A Program that keeps track of a passWord that the user can change.ππ    HOW IT WORKSππ    You don't have to understand all the details in order to use thisπ    technique, but here they are.ππ    The data to be changed must be stored in a TurboPascal Typedπ    Constant.  In all effect, a Typed Constant is actually a pre-π    initialized Variable.  It is always stored in the Program's Dataπ    Segment.  The data can be of any Type.ππ    First, the Procedure finds the .EXE File by examining the Dos commandπ    line, stored With the copy of the Dos environment For the Program.  Thisπ    allows the Program to find itself no matter where is resides on disk andπ    no matter how its name is changed by the user.ππ    The unTyped File is opened With a Record size of 1. This allows usπ    to read or Write a String of Bytes using BlockRead and BlockWrite.ππ    As documented in the Dos Technical Reference, the size of the .EXEπ    header, in paraGraphs (a paraGraph is 16 Bytes), is stored as aπ    two-Byte Word at position 8 of the File.  This is read into theπ    Variable HeaderSize.ππ    The next step is to find the position of the Typed Constant in theπ    .EXE File. This requires an understanding of the Turbo Pascal 4.0π    memory map, documented on the first and second pages of the Insideπ    Turbo Pascal chapter. (That's chapter 26, pages 335 and 336 in myπ    manual.)ππ    First, find the address in memory where the Typed Constant isπ    stored. This can be done in Turbo Pascal by using the Seg and Ofsπ    Functions. Next find the segment of the PSP (Program segmentπ    prefix). This should always be the value returned by PrefixSeg.π    That will mark the beginning of the Program in memory. Theπ    position of the Typed Constant in the .EXE image should be theπ    number of Bytes between these two places in memory. But ...ππ    But, two corrections must be made. First, the PSP is not stored inπ    the .EXE File. As mentioned on page 335, the PSP is always 256π    Bytes. We must subtract that out. Secondly, there is the .EXE Fileπ    header. The size of this has already been read in and must beπ    added in to our calculations.ππ    Once the position has been determined, the data stored in theπ    Typed Constant is written in one fell swoop using a BlockWrite.π    This replaces the original data, so that the next time the Programπ    is run, the new values will used.ππ    LIMITATIONSππ    You cannot use MicroSoft's EXEPACK on the .EXE File, or any otherπ    packing method I know of. This may change the position, or evenπ    the size of the Typed Constant in the File image.ππ    NOTESππ    Since Typed Constants are always stored in the data segment, theπ    Function call to Seg( ObjectToWrite ) can be replaced With DSeg. Iπ    prefer using Seg since it is more descriptive.ππ    One might think that Cseg can used as an alternative to usingπ    PrefixSeg and subtracting 256. This will work only if the codeπ    resides in the main Program. If, on the other hand, the code isπ    used in a Unit, PrefixSeg must be used as described here. Youπ    might as well use PrefixSeg and save yourself some headaches.ππ    if you have any comments or questions we would be glad to hearπ    them. if you're on CompuServe, you can EasyPlex a letter toπ    76244,1043 or 71401,747. Or leave a message on the Borland Programmer's Aπ    Forum (GO BPROGA). Or, you can Write toππ                         Skipjack Softwareπ                         P. O. Box 61π                         Simpsonville Maryland 21150ππ                            orππ                         Zelkop Softwareπ                         P.O. Box 5177π                         Armdale, N.S.π                         Canadaπ                         B3L 4M7ππ    ==================================================================}πππInterfaceππFunction GetExecutableName : String;π{  This Function returns the full drive, path, and File name of the applicationπ   Program that is running.  This Function is of more general interest thanπ   just For writing into the EXE File.ππ   NOTE: THIS Function WILL ONLY WORK UNDER Dos 3.X + !!! }ππFunction WriteToExecutable(Var ObjectToWrite; ObjectSize : Word) : Integer;π{  This Procedure modifies the EXE File on disk to contain changes to Typedπ   Constants.  NOTE - the Object MUST be a Typed Constant.  It may be foundπ   in any part of the Program (i.e., main Program or any Unit).  The call isπ   made by unTyped address, to allow any kind of Object to be written.  Theπ   Function returns the Dos error code from the I/O operation that failedπ   (if any did); if all operations were successful, the Function returns 0. }ππImplementationππFunction GetExecutableName : String;πTypeπ  Environment = Array[0..32766] of Char;πConstπ  NullChar : Char = #0;π  SearchFailed = $FFFF;πVarπ  MyEnviron   : ^Environment;π  Loop        : Word;π  TempWord    : Word;π  EnvironPos  : Word;π  FilenamePos : Word;π  TempString  : String;πbegin { Function GetExecutableName }π  { Get Pointer to Dos environment }π  MyEnviron := Ptr(MemW[PrefixSeg : $2C], 0);ππ  { Look For end of environment }π  EnvironPos := SearchFailed;π  Loop := 0;ππ  While Loop <= 32767 DOπ  beginπ    if MyEnviron^[ Loop ] = NullChar thenπ      if MyEnviron^[ Loop + 1 ] = NullChar thenπ      begin { found two nulls - this is end of environment }π        EnvironPos := Loop;π        Loop := 32767π      end; { found two nulls }π    Inc(Loop);π  end; { While Loop }ππ  if EnvironPos = SearchFailed thenπ    GetExecutableName := ''π  elseπ  begin { found end of environment - now look For path/File of exec }π    EnvironPos  := EnvironPos + 4;π    FilenamePos := SearchFailed;π    TempWord    := EnvironPos;π    Loop := 0;ππ    While Loop <= 127 DOπ    beginπ      if MyEnviron^[TempWord] = NullChar thenπ      begin { found a null - this is end of path/File of exec }π        FilenamePos := Loop;π        Loop := 127π      end; { found a null }π      Inc(Loop);π      Inc(TempWord);π    end; { While Loop }ππ    if FilenamePos = SearchFailed thenπ      GetExecutableName := ''π    elseπ    begin { found executable name - move into return String }π      TempString[0] := Chr(FilenamePos);π      Move(MyEnviron^[EnvironPos], TempString[1], FilenamePos);π      GetExecutableName := TempString;π    end; { found executable name }π  end; { found environment end }πend; { Function GetExecutableName }πππFunction WriteToExecutable(Var ObjectToWrite; ObjectSize : Word ) : Integer;πConstπ  PrefixSize = 256; { number of Bytes in the Program Segment Prefix }πVarπ  Executable : File;π  HeaderSize : Word;π  ErrorCode  : Integer;πbeginπ  Assign(Executable, GetExecutableName);π  {$I-}π  Reset(Executable, 1);π  ErrorCode := IOResult;ππ  if ErrorCode = 0 thenπ  begin { seek position of header size in EXE File }π    Seek(Executable, 8);π    ErrorCode := IOResult;π  end; { seek header }ππ  if ErrorCode = 0 thenπ  begin { read header size in EXE File }π    BlockRead(Executable, HeaderSize, SizeOf(HeaderSize));π    ErrorCode := IOResult;π  end; { read header }ππ  if ErrorCode = 0 thenπ  begin { seek position of Object in EXE File }π    Seek(Executable,π         LongInt(16) * (HeaderSize + Seg(ObjectToWrite) - PrefixSeg) +π         Ofs(ObjectToWrite) - PrefixSize);π    ErrorCode := IOResult;π  end; { Seek Object position in File }ππ  if ErrorCode = 0 thenπ  begin { Write new passWord in EXE File }π    BlockWrite(Executable, ObjectToWrite, ObjectSize);π    ErrorCode := IOResult;π  end; { Write new passWord }ππ  Close(Executable);π  WriteToExecutable := ErrorCode;ππend; { Function WriteToExecutable }ππend. { Unit WritExec }π