mkdemo.mod 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. MODULE mkdemo ;
  2. (* Generates boot.MC4, a single-module MC64 image that prints
  3. "Hello MC64!" via the SYSTEM write-string service (§9.3). *)
  4. FROM FileIO IMPORT WriteFile ;
  5. FROM Console IMPORT Fatal ;
  6. FROM SYSTEM IMPORT ADR ;
  7. CONST
  8. HeaderSize = 64 ;
  9. DescDeps = 0 ;
  10. DescLink = 256 ;
  11. DescName = 264 ;
  12. DescLoadAddr = 280 ;
  13. DescChecksum = 288 ;
  14. DescFlags = 292 ;
  15. DescVarCount = 293 ;
  16. DescDepCount = 294 ;
  17. DescPad = 295 ;
  18. DescProcs = 296 ;
  19. ProcTable = 304 ;
  20. CodeOff = 312 ;
  21. FileSize = 396 ;
  22. StrOff = 314 ; (* image offset of the string *)
  23. StrLen = 14 ; (* 11 chars + CR + LF + NUL *)
  24. VAR
  25. buf : ARRAY [0 .. FileSize - 1] OF CHAR ;
  26. i : CARDINAL ;
  27. sum : CARDINAL ;
  28. PROCEDURE Put32 (off, v : CARDINAL) ;
  29. BEGIN
  30. buf [off] := CHR (v MOD 256) ;
  31. buf [off + 1] := CHR ((v DIV 256) MOD 256) ;
  32. buf [off + 2] := CHR ((v DIV 65536) MOD 256) ;
  33. buf [off + 3] := CHR (v DIV 16777216) ;
  34. END Put32 ;
  35. PROCEDURE Put64 (off : CARDINAL; v : LONGCARD) ;
  36. VAR j : CARDINAL ;
  37. BEGIN
  38. FOR j := 0 TO 7 DO
  39. buf [off + j] := CHR (VAL (CARDINAL, v MOD 256)) ;
  40. v := v DIV 256 ;
  41. END ;
  42. END Put64 ;
  43. BEGIN
  44. FOR i := 0 TO FileSize - 1 DO
  45. buf [i] := 0C ;
  46. END ;
  47. (* file header (64 bytes) : magic *)
  48. buf [0] := 'M' ;
  49. buf [1] := 'C' ;
  50. buf [2] := '6' ;
  51. buf [3] := '4' ;
  52. (* descriptor *)
  53. buf [HeaderSize + DescName] := 'd' ;
  54. buf [HeaderSize + DescName + 1] := 'e' ;
  55. buf [HeaderSize + DescName + 2] := 'm' ;
  56. buf [HeaderSize + DescName + 3] := 'o' ;
  57. buf [HeaderSize + DescFlags] := CHR (4) ; (* TOINIT *)
  58. buf [HeaderSize + DescVarCount] := CHR (0) ;
  59. buf [HeaderSize + DescDepCount] := CHR (0) ;
  60. Put64 (HeaderSize + DescProcs, 304) ; (* proc table image offset *)
  61. (* procedure table : proc0 at image offset 312 *)
  62. Put64 (HeaderSize + ProcTable, 8) ;
  63. (* code : call_rel 14 ; "Hello MC64!\r\n\0" ; load_imm_byte 1 ; system ; end *)
  64. buf [HeaderSize + CodeOff] := CHR (8CH) ; (* call_rel *)
  65. buf [HeaderSize + CodeOff + 1] := CHR (14) ;
  66. buf [HeaderSize + StrOff] := 'H' ;
  67. buf [HeaderSize + StrOff + 1] := 'e' ;
  68. buf [HeaderSize + StrOff + 2] := 'l' ;
  69. buf [HeaderSize + StrOff + 3] := 'l' ;
  70. buf [HeaderSize + StrOff + 4] := 'o' ;
  71. buf [HeaderSize + StrOff + 5] := ' ' ;
  72. buf [HeaderSize + StrOff + 6] := 'M' ;
  73. buf [HeaderSize + StrOff + 7] := 'C' ;
  74. buf [HeaderSize + StrOff + 8] := '6' ;
  75. buf [HeaderSize + StrOff + 9] := '4' ;
  76. buf [HeaderSize + StrOff + 10] := '!' ;
  77. buf [HeaderSize + StrOff + 11] := 13C ; (* CR *)
  78. buf [HeaderSize + StrOff + 12] := 12C ; (* LF *)
  79. buf [HeaderSize + StrOff + 13] := 0C ; (* NUL *)
  80. buf [HeaderSize + CodeOff + 16] := CHR (8DH) ; (* load_imm_byte *)
  81. buf [HeaderSize + CodeOff + 17] := CHR (1) ;
  82. buf [HeaderSize + CodeOff + 18] := CHR (0C3H) ; (* system *)
  83. buf [HeaderSize + CodeOff + 19] := CHR (50H) ; (* end_program *)
  84. (* checksum over the image, excluding the checksum field itself *)
  85. sum := 0 ;
  86. FOR i := HeaderSize TO FileSize - 1 DO
  87. IF NOT ((i >= 352) AND (i <= 355)) THEN
  88. sum := sum + ORD (buf [i]) ;
  89. END ;
  90. END ;
  91. Put32 (HeaderSize + DescChecksum, sum) ;
  92. IF NOT WriteFile ("boot.MC4", buf, FileSize) THEN
  93. Fatal ("mkdemo: cannot write boot.MC4") ;
  94. END ;
  95. END mkdemo.