home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / asmutl / pload10.lbr / PLOAD10.PQS / PLOAD10.PAS
Encoding:
Pascal/Delphi Source File  |  1986-05-06  |  7.9 KB  |  332 lines

  1. {
  2.   Program name : PLOAD10.PAS
  3.   Author       : James Whorton
  4.   Date written : June 22, 1985
  5.   Environment  : CP/M 2.2, Turbo Pascal 2.0
  6.  
  7.   ########################################################################
  8.   #  This software is Copyright (C) 1985 by James Whorton. All Rights    #
  9.   #  Reserved. Permission is granted to distribute and use this software #
  10.   #  under the following conditions:                                     #
  11.   #                                                                      #
  12.   #   1. Distribution and use must be non-profit. No profit from this    #
  13.   #      software is allowed without the express written permission      #
  14.   #      of the author.                                                  #
  15.   #   2. Any modifications to the code must be cleared with the author   #
  16.   #      before a new release is made.                                   #
  17.   #   3. All copyright notices must be maintained in their present state,#
  18.   #      including display of said notices.                              #
  19.   ########################################################################
  20.  
  21.   See PLOAD10.MAN for information.
  22. }
  23.  
  24. program pload10;
  25.  
  26. {$V-     Turn off parameter length checking }
  27.  
  28. const
  29.  
  30.  {
  31.   The following equate should be set to the maximum size of binary (.COM)
  32.   file that you will need to generate. The limit for this version is 30K.
  33.   Future revisions will alow greater sizes. COMSIZE is the # of K. As released,
  34.   this loader will allow creation of a 20K binary file.
  35.  }
  36.  
  37.  comsize       = 20;           {Binary max. size}
  38.  
  39.  signon        = 'PLOAD vers. 1.0  Copyright (C) 1985 by James Whorton';
  40.  in_ext        = '.HEX';       {Default input file extension}
  41.  out_ext       = '.COM';       {Default output file extension}
  42.  def_base      = $100;         {Default ORG location}
  43.  cr            = #$0D;         {CR}
  44.  hexset        = '0123456789ABCDEF';  {Hex representation string}
  45.  
  46. type
  47.  
  48.  str15         = string[15];
  49.  str80         = string[80];
  50.  
  51. var
  52.  
  53.  in_file       : text;
  54.  out_file      : file;
  55.  endf          : boolean;
  56.  in_fn,
  57.  out_fn        : str15;
  58.  ch            : char;
  59.  i,j,k,l,
  60.  bytes,
  61.  fil_ptr,
  62.  last_wrt,
  63.  org_adr,
  64.  end_adr,
  65.  loaded        : integer;
  66.  out_buffer    : array[1..$7800] of byte;
  67.  cmdline       : string[30] absolute $80;
  68.  wrkstr        : str80;
  69.  
  70.  
  71.  
  72. {
  73.  Function    : HexOf
  74.  Description : Returns a hexidecimal respresentation of the integer passed
  75.                to the function.
  76. }
  77.  
  78. function HexOf(var dec:integer) : str80;
  79.  
  80.  
  81.  function nibble(a:byte) : char;  {convert nibble 'a' into ascii and return a char}
  82.  var  b        :byte;
  83.  begin
  84.    b := a;
  85.    b := b + 48;
  86.    if b > 57 then b := b + 7;
  87.    nibble:=chr(b);
  88.  end; { hexbyte }
  89.  
  90.  function hexbyte(z:byte) : str80;  {convert byte 'z' into two ascii hex digits}
  91.                           { and return }
  92.  var    a,b   :byte;
  93.  begin
  94.   a:=z;
  95.   b:=a and 240;  { mask off msb }
  96.   b:=b shr 4;
  97.   a:=a and 15;   { mask off lsb }
  98.   hexbyte:=nibble(b)+nibble(a);
  99.  end;
  100.  
  101. begin
  102.  hexof:=hexbyte(hi(dec)) + hexbyte(lo(dec)) + 'H';
  103. end;
  104.  
  105. {
  106.  Procedure   : Abort
  107.  Description : Aborts the program, displays error message if avail.
  108. }
  109.  
  110. procedure Abort(ermsg:str80);
  111. begin
  112.  writeln;
  113.  if length(ermsg)>0 then
  114.   writeln('  -->> Error : ',ermsg,' <<--',^G);
  115.  halt;
  116. end;
  117.  
  118.  
  119. {
  120.  Procedure   : Usage
  121.  Description : Display program usage if no parameters given.
  122. }
  123.  
  124. procedure Usage;
  125. begin
  126.  writeln;
  127.  writeln('Usage:');
  128.  writeln;
  129.  writeln('  PLOAD infile.ext outfile.ext');
  130.  writeln;
  131.  writeln('  File extensions are optional. If excluded, input file extension will');
  132.  writeln('  default to .HEX and output file extension will default to .COM.');
  133.  writeln('  If the output filename is not specified, it will default to the input');
  134.  writeln('  filename.');
  135.  writeln;
  136.  halt;
  137. end;
  138.  
  139.  
  140. {
  141.  Procedure   : GetParam
  142.  Description : Fetches a parameter from the specified string.
  143. }
  144.  
  145. procedure GetParam(var l,s:str80);
  146. begin
  147.  s:='';
  148.  while (length(l)>0) and (l[1]=' ') do
  149.    delete (l,1,1);
  150.  while (length(l)>0) and (l[1]<>' ') do
  151.    begin
  152.     s:=s+l[1];
  153.     delete(l,1,1);
  154.    end;
  155. end;
  156.  
  157.  
  158. {
  159.  Function    : Get_Next
  160.  Description : Fetches the next character from the input file.
  161.                Sets ENDF to TRUE on end of file.
  162. }
  163.  
  164. function Get_Next : char;
  165. var ch : char;
  166. begin
  167.  read(in_file,ch);
  168.  if eof(in_file) then
  169.   endf:=true;
  170.  get_next:=ch;
  171. end;
  172.  
  173.  
  174. {
  175.  Procedure   : Skip
  176.  Description : Skip n chars in the input file.
  177. }
  178.  
  179. procedure Skip(n:integer);
  180. var i:integer;
  181. begin
  182.  for i:=1 to n do
  183.   ch:=get_next;
  184. end;
  185.  
  186.  
  187. {
  188.  Function    : MakeByte
  189.  Description : Converts an n char string hexidecimal representation into an
  190.                integer value.
  191. }
  192.  
  193. function MakeByte(wrkstr:str80) : integer;
  194. var i,
  195.     acc,
  196.     mult,
  197.     ps    : integer;
  198. begin
  199.  acc:=0;
  200.  ps:=1;
  201.  mult:=1;
  202.  if length(wrkstr)>1 then
  203.   for i:=1 to length(wrkstr)-1 do
  204.    mult:=mult*16;
  205.  repeat
  206.   acc:=acc+(pos(wrkstr[ps],hexset)-1) * mult;
  207.   ps:=ps+1;
  208.   if mult=1 then
  209.    mult:=0
  210.   else
  211.    mult:=mult div 16;
  212.  until mult=0;
  213.  makebyte:=acc;
  214. end;
  215.  
  216.  
  217. {
  218.  Procedure   : Fix_Addr
  219.  Description : This short procedure checks the beggining and ending addresses
  220.                 against the current line address and adjusts as needed.
  221. }
  222.  
  223. procedure Fix_Addr;
  224. var i : integer;
  225. begin
  226.  if org_adr=0 then
  227.   org_adr:=j;
  228.  i:=j+(bytes-1);
  229.  if end_adr<i then
  230.   end_adr:=i;
  231. end;
  232.  
  233.  
  234. {
  235.  Procedure   : Proc_Line
  236.  Description : This procedure processes a single line of the .HEX file.
  237. }
  238.  
  239. procedure Proc_Line;
  240. begin
  241.  wrkstr:=get_next+get_next;
  242.  bytes:=makebyte(wrkstr);
  243.  if bytes>0 then
  244.   begin
  245.    wrkstr:='';
  246.    for i:=1 to 4 do
  247.     wrkstr:=wrkstr+get_next;
  248.    j:=makebyte(wrkstr);
  249.    fix_addr;
  250.    fil_ptr:=(j-org_adr)+1;
  251.    skip(2);
  252.    for i:=1 to bytes do
  253.     begin
  254.      wrkstr:=get_next+get_next;
  255.      l:=makebyte(wrkstr);
  256.      if fil_ptr>(comsize*1024) then
  257.       abort('output buffer overflow');
  258.      out_buffer[fil_ptr]:=l;
  259.      loaded:=loaded+1;
  260.      if last_wrt<fil_ptr then
  261.       last_wrt:=fil_ptr;
  262.      fil_ptr:=fil_ptr+1;
  263.     end;
  264.   end;
  265. end;
  266.  
  267.  
  268. { Main code starts here. }
  269.  
  270. begin
  271.  
  272.  writeln(signon);
  273.  if comsize>30 then
  274.   abort('maximum binary file size set too high. Must be 1-30.');
  275.  endf:=false;                        { Set up variables }
  276.  fil_ptr:=1;
  277.  last_wrt:=0;
  278.  org_adr:=0;
  279.  end_adr:=0;
  280.  loaded:=0;
  281.  for i:=1 to (comsize*1024) do              { Zero out buffer }
  282.   out_buffer[i]:=0;
  283.  getparam(cmdline,in_fn);            { Fetch input filename }
  284.  if length(in_fn)=0 then
  285.   usage;                             { No filename given, show usage }
  286.  getparam(cmdline,out_fn);           { Fetch second filename }
  287.  if length(out_fn)=0 then            { If second filename not supplied, set to }
  288.   out_fn:=in_fn;                     { first }
  289.  if pos('.',in_fn)=0 then            { Add extensions if not supplied }
  290.   in_fn:=in_fn+in_ext;
  291.  if pos('.',out_fn)=0 then
  292.   out_fn:=out_fn+out_ext;
  293.  
  294.  assign(in_file,in_fn);
  295.  {$I-}
  296.  reset(in_file);
  297.  {$I+}
  298.  if IOResult<>0 then
  299.   abort('input file not found');     { No input file }
  300.  
  301.  while not endf do
  302.   begin
  303.    ch:=get_next;
  304.    if ch=':' then
  305.     proc_line;
  306.   end;
  307.  
  308.  fil_ptr:=last_wrt+1;
  309.  i:=(fil_ptr div 128);
  310.  j:=(fil_ptr mod 128);
  311.  if j<>0 then
  312.   for k:=0 to j-1 do
  313.    out_buffer[fil_ptr+k]:=26;
  314.  if j<>0 then i:=i+1;
  315.  writeln;                            { Report stats }
  316.  writeln('Start address   : ',hexof(org_adr));
  317.  writeln('End address     : ',hexof(end_adr));
  318.  writeln('Records written : ',hexof(i));
  319.  writeln('Bytes loaded    : ',hexof(loaded));
  320.  
  321.  assign(out_file,out_fn);
  322.  {$I-}
  323.  rewrite(out_file);
  324.  {$I+}
  325.  if IOResult<>0 then
  326.   abort('cannot open output file');  { Output file error }
  327.  blockwrite(out_file,out_buffer,i);
  328.  close(out_file);
  329.  
  330. end.
  331.  
  332.