program picprog;                                        {Program INHX into PIC}
uses picunit;                                           {Uses picunit}
var
  f: text;                                              {Text file}
  sum: byte;                                            {Checksum}

type
  hilo =                                                {Convert word/byte}
  record
    lo,hi: byte;
  end;

function rdhex: byte;                                   {Writes hex to file}
var
  i: word;
  x: byte;
  ch: char;
begin
  x:=0;
  for i:=0 to 1 do
  begin
    read(f,ch);
    case ch of
      '0'..'9': x := x shl 4 + ord(ch) - 48;
      'A'..'F': x := x shl 4 + ord(ch) - 55;
      'a'..'f': x := x shl 4 + ord(ch) - 87;
    else
      writeln('Error in HEX file'); halt;
    end;
  end;
  rdhex:=x;
  sum:=sum+x;
end;

var
  pgmmembyte: array[0..$7ff] of byte absolute pgmmem;
  cfgmembyte: array[$4000..$400f] of byte absolute cfgmem;
  datmembyte: array[$4200..$427f] of byte absolute datmem;
  pgmm: pgmmemtype;
  datm: datmemtype;
  cfgm: cfgmemtype;
  ch: char;
  ant: byte;
  x: byte;
  adr: word;
  i: word;
  ok: boolean;

begin
  fillchar(pgmmem,sizeof(pgmmem),255);                          {Clear buffer}
  fillchar(datmem,sizeof(datmem),255);
  fillchar(cfgmem,sizeof(cfgmem),255);
  if paramcount=2 then val(paramstr(2),com,i) else
  begin
    writeln('Use:');
    writeln('   picprog filename.hex comport');
    halt;
  end;

  assign(f,paramstr(1));                                        {Open file}
  reset(f);
  writeln('Reading file ''',paramstr(1),'''');

  repeat                                                        {Read hex file}
    read(f,ch);
    if ch=':' then
    begin
      sum:=0;
      ant:=rdhex;
      hilo(adr).hi:=rdhex;
      hilo(adr).lo:=rdhex;
      case rdhex of
        0:
        for i:=1 to ant do
        begin
          case adr of
            $0000..$07ff: pgmmembyte[adr]:=rdhex;
            $4000..$400F: cfgmembyte[adr]:=rdhex;
            $4200..$427F: datmembyte[adr]:=rdhex;
          end;
          inc(adr);
        end;
        1: i:=0;
      end;
      x:=rdhex;
      if sum<>0 then
      begin
        writeln('Checksum error'); halt;
      end;
    end;
    readln(f);
  until i=0;
  close(f);                                                     {Close file}

  if cfgmem[7]=$ffff then
    writeln('--- Notice: No configuration word in hex-file ---');

  pgmm:=pgmmem;                                                 {Verify copy}
  datm:=datmem;
  cfgm:=cfgmem;

  writeln('Programming PIC16C84 at COM',com);

  if hwerror then                                               {HW-check}
  begin
    writeln('- Programmer not connected');
    halt;
  end;

  readcfg;
  if cfgmem[7] and 16 = 0 then
  begin
    write('- Code Protected. Erase (Y/N)? ');
    repeat
      readln(ch);
      if upcase(ch)='N' then halt;
    until upcase(ch)='Y';
    eraseall;
  end;

  progall;                                                      {Program}
  write('Verify ');                                             {Verify}
  readall;
  ok:=true;
  for i:=0 to $3ff do if pgmmem[i]<>(pgmm[i] and $3fff) then ok:=false;
  for i:=0 to $3f do if lo(datmem[i])<>lo(datm[i]) then ok:=false;
  writeln(ok);

  writeln('Programming configuration word');
  cfgmem:=cfgm;
  progcfg;
  readcfg;
  if cfgmem[7] and 16 = 0 then
    writeln('Device code-protected')
  else
  begin
    write('Verify ');
    for i:=0 to 3 do if cfgmem[i]<>(cfgm[i] and $3fff) then ok:=false;
    if cfgmem[7]<>(cfgm[7] and $3fff) then ok:=false;
    writeln(ok);
  end;
end.
