Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to the forum
Board view  Mix view

TP5_2COM - an example of how to generate a COM file from TP5 (Announce)

posted by Arjay, 27.06.2010, 13:30
(edited by Arjay on 27.06.2010, 15:42)

> My main issue is that so much code is TP7 only, which hampers using TP55
> freeware. Or other code is too big and complex to use for simple projects.
Ok, let's help fix some of that :) Just for you I have back ported to TP5 some TP7 code I wrote a while ago to generate COM files from TP. The TP5 version appears below and I quickly rewrote it for you this morning under TP5. It isn't as well tested as the TP7 version but "appears" fine, feel free to test as to be honest although it seems fine I haven't had a chance to fully review but thought I would share now "as is" to allow people to have a play with it.

Program TP5_2COM;  {This is an example of how to generate COM files from TP5}

{Freeware code example by Richard L. James http://www.wimborne.org/richard/ }
{VERY IMPORTANT: Always REVIEW generated code created with method shown here}
{This code example uses TP5 to generate EXE code from which we generate a COM}
{Mostly released as a technical curosity for interested people to play with!}
{Use of the following code is entirely at your own risk without any warranty}
{It is *NOT* recommend using this code as is with other versions of TP pascal}


Const
  ExitCodeLength=4;

  NewCode:Array[1..5] of byte =    {We need to ensure BP points after our PSP}
    ($BD, $10, $01, {mov  BP, 110h}  {TP code generated by "subtracks" off BP}
     $EB, $0C);     {jmp short 111}  {Jump to the start of TP generated code}


Var                {Note: We do NOT save the following variables to our .COM}
  COMFile:File;    {Define a binary COM file}
  NumWritten:Word; {BlockWrite needs this variable in this demo we ignore it}



Procedure SaveMe; {We setup code/data we want to save out in single procedure}

Var
  XCounter, YCounter:Word;   {These values are NOT saved but redefined below}


Begin
  {Note: NewCode is SAVED as the start of our .COM file starting org 100h}
  {Then we define some variable space using 00h bytes for 2 variables}

  {IMPORTANT: If adding variables you will NEED to increase this area and
              you will ALSO need to change NewCode appropriately.  Always
              (I repeat ALWAYS) view/check any generated code in a hex editor
              before attempting to run it and keep "everything" in one proc!}

  inline($00/$00/   {BP -A} {Unused variable in this example}
         $00/$00/   {BP -8} {Unused variable in this example}
         $00/$00/   {BP -6} {Unused variable in this example}
         $00/$00/   {BP -4} {In this example our redefined YCounter variable}
         $00/$00/   {BP -2} {In this example our redefined XCounter variable}
         $00/$00);  {BP   } {org 0110h - we point BP here via "newcode" above}

  {In this example the following code starts at org 111h "newcode" jumps here}
  inline($B8/$13/$00/  {mov ax, 0013}  {Change to 320x200 graphics mode}
         $CD/$10);     {int 10h}       {Call Int 10h}

  For XCounter:=0 to 319 do            {Generate a simple 320x200 picture}
    For YCounter:=0 to 199 do
      Mem[$A000:(YCounter*320)+XCounter]:=YCounter xor XCounter;

  inline($31/$C0/      {xor ax,ax}     {AX = 0}
         $CD/$16);     {int 16h}       {Call BIOS to wait for a keypress}

  inline($B8/$03/$00/  {mov ax, 0003h} {Change to 80x25 colour text mode}
         $CD/$10);     {int 10h}

  inline($B8/$00/$4C/  {mov ax, 4C00h} {Terminate with an error code of 0}
         $CD/$21);     {int 21h}       {End program}

  {TP5 generates proc exit code here - we avoid saving it with ExitCodeLength}
End;


Procedure UpToMe;  {Dummy "up to marker" marker to help save our TP code out}

Begin
  {do nothing}
End;


{Our main program does NOT call the above code but simply copies it to a COM}

Begin
  Writeln;
  Writeln('TP5_2com - example program of how to create a COM file with TP5');
  Writeln('Attempting to create tinytp5.com');

  Assign(COMFile, 'tinytp5.com');    { Assign output name to our TP5 .COM file}
  ReWrite(COMFile, 1);               { Create new file with record size = 1 }

  BlockWrite(COMFile, NewCode, SizeOf(NewCode), NumWritten); {Save COM header}
  BlockWrite(COMFile, Mem[Seg(SaveMe):Ofs(SaveMe)+14], {Save out TP proc code}
                     (Ofs(UpToMe)-14)-ExitCodeLength, NumWritten);
                     {note the above -14/+14 avoids saving TP entry/exit code}

  {Normally in a program some error checking would be good here but due to
   the nature of this example I would recommend manually checking any code !!}

  Close(COMFile);    {Close our new file}

  Writeln('tinytp5.com created - "review" with a hex editor before running!');
  Writeln;
  Halt;              {end our TP5 .COM after saving out our example COM file}
End.

 

Complete thread:

Back to the forum
Board view  Mix view
22760 Postings in 2121 Threads, 402 registered users (2 online)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum