Bin2Hex.Mod 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. MODULE Bin2Hex; (** AUTHOR "negelef"; PURPOSE "Binary file to Intel Hex-file converter"; *)
  2. IMPORT Streams, Files, Commands;
  3. PROCEDURE Byte (VAR w: Streams.Writer; val: LONGINT);
  4. BEGIN w.Hex (val MOD 100H, -2);
  5. END Byte;
  6. PROCEDURE ExtendedAddressRecord* (VAR w: Streams.Writer; extadr: LONGINT);
  7. BEGIN
  8. w.Char (':'); Byte (w, 2); Byte (w, 0); Byte (w, 0); Byte (w, 4);
  9. Byte (w, extadr DIV 100H); Byte (w, extadr);
  10. Byte (w, 100H - (2 + 0 + 0 + 4 + extadr DIV 100H MOD 100H + extadr MOD 100H) MOD 100H); w.Ln;
  11. END ExtendedAddressRecord;
  12. PROCEDURE DataRecord* (VAR w: Streams.Writer; CONST data: ARRAY OF CHAR; len, offset: LONGINT);
  13. VAR checksum, i: LONGINT;
  14. BEGIN
  15. checksum := len MOD 100H;
  16. INC (checksum, offset DIV 100H MOD 100H + offset MOD 100H);
  17. w.Char (':'); Byte (w, len); Byte (w, offset DIV 100H); Byte (w, offset); Byte (w, 0);
  18. FOR i := 0 TO len - 1 DO Byte (w, ORD (data[i])); INC (checksum, ORD (data[i])) END;
  19. Byte (w, 100H - checksum MOD 100H); w.Ln;
  20. END DataRecord;
  21. PROCEDURE EndOfFileRecord* (VAR w: Streams.Writer);
  22. BEGIN w.Char (':'); Byte (w, 0); Byte (w, 0); Byte (w, 0); Byte (w, 1); Byte (w, 255); w.Ln;
  23. END EndOfFileRecord;
  24. PROCEDURE ConvertFile* (r: Streams.Reader; w: Streams.Writer; offset, maxlen: LONGINT);
  25. VAR len, extadr: LONGINT; c: CHAR; data: POINTER TO ARRAY OF CHAR;
  26. BEGIN
  27. NEW(data,maxlen+1);
  28. extadr := offset DIV 10000H;
  29. IF extadr # 0 THEN ExtendedAddressRecord (w, extadr); END;
  30. REPEAT
  31. len := 0;
  32. LOOP
  33. r.Char (c); IF r.res # Files.Ok THEN EXIT END;
  34. data[len] := c; INC (len); IF len = maxlen THEN EXIT END;
  35. END;
  36. IF len # 0 THEN DataRecord (w, data^, len, offset) END;
  37. INC (offset, len);
  38. IF offset DIV 10000H # extadr THEN
  39. extadr := offset DIV 10000H;
  40. ExtendedAddressRecord (w, extadr);
  41. END;
  42. UNTIL r.res # Files.Ok;
  43. EndOfFileRecord (w);
  44. END ConvertFile;
  45. PROCEDURE Convert* (context: Commands.Context);
  46. VAR
  47. source, dest: ARRAY Files.NameLength OF CHAR;
  48. offset, maxlen: LONGINT;
  49. src, dst: Files.File;
  50. r: Files.Reader; w: Files.Writer;
  51. BEGIN
  52. context.arg.SkipWhitespace; context.arg.String (source);
  53. context.arg.SkipWhitespace; context.arg.String (dest);
  54. IF ~context.arg.GetInteger (offset, TRUE) THEN offset := 0 END;
  55. IF ~context.arg.GetInteger (maxlen, TRUE) THEN maxlen := 255 END;
  56. src := Files.Old (source);
  57. IF src = NIL THEN
  58. context.error.String ("failed to open binary file '"); context.error.String (source); context.error.Char ("'"); context.error.Ln;
  59. context.result := Commands.CommandError; RETURN;
  60. END;
  61. dst := Files.New (dest);
  62. IF src = NIL THEN
  63. context.error.String ("failed to open hex file '"); context.error.String (dest); context.error.Char ("'"); context.error.Ln;
  64. context.result := Commands.CommandError; RETURN;
  65. END;
  66. Files.OpenReader (r, src, 0); Files.OpenWriter (w, dst, 0);
  67. ConvertFile (r, w, offset, maxlen);
  68. w.Update;
  69. Files.Register (dst);
  70. END Convert;
  71. END Bin2Hex.