| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- MODULE mkdemo ;
- (* Generates boot.MC4, a single-module MC64 image that prints
- "Hello MC64!" via the SYSTEM write-string service (§9.3). *)
- FROM FileIO IMPORT WriteFile ;
- FROM Console IMPORT Fatal ;
- FROM SYSTEM IMPORT ADR ;
- CONST
- HeaderSize = 64 ;
- DescDeps = 0 ;
- DescLink = 256 ;
- DescName = 264 ;
- DescLoadAddr = 280 ;
- DescChecksum = 288 ;
- DescFlags = 292 ;
- DescVarCount = 293 ;
- DescDepCount = 294 ;
- DescPad = 295 ;
- DescProcs = 296 ;
- ProcTable = 304 ;
- CodeOff = 312 ;
- FileSize = 396 ;
- StrOff = 314 ; (* image offset of the string *)
- StrLen = 14 ; (* 11 chars + CR + LF + NUL *)
- VAR
- buf : ARRAY [0 .. FileSize - 1] OF CHAR ;
- i : CARDINAL ;
- sum : CARDINAL ;
- PROCEDURE Put32 (off, v : CARDINAL) ;
- BEGIN
- buf [off] := CHR (v MOD 256) ;
- buf [off + 1] := CHR ((v DIV 256) MOD 256) ;
- buf [off + 2] := CHR ((v DIV 65536) MOD 256) ;
- buf [off + 3] := CHR (v DIV 16777216) ;
- END Put32 ;
- PROCEDURE Put64 (off : CARDINAL; v : LONGCARD) ;
- VAR j : CARDINAL ;
- BEGIN
- FOR j := 0 TO 7 DO
- buf [off + j] := CHR (VAL (CARDINAL, v MOD 256)) ;
- v := v DIV 256 ;
- END ;
- END Put64 ;
- BEGIN
- FOR i := 0 TO FileSize - 1 DO
- buf [i] := 0C ;
- END ;
- (* file header (64 bytes) : magic *)
- buf [0] := 'M' ;
- buf [1] := 'C' ;
- buf [2] := '6' ;
- buf [3] := '4' ;
- (* descriptor *)
- buf [HeaderSize + DescName] := 'd' ;
- buf [HeaderSize + DescName + 1] := 'e' ;
- buf [HeaderSize + DescName + 2] := 'm' ;
- buf [HeaderSize + DescName + 3] := 'o' ;
- buf [HeaderSize + DescFlags] := CHR (4) ; (* TOINIT *)
- buf [HeaderSize + DescVarCount] := CHR (0) ;
- buf [HeaderSize + DescDepCount] := CHR (0) ;
- Put64 (HeaderSize + DescProcs, 304) ; (* proc table image offset *)
- (* procedure table : proc0 at image offset 312 *)
- Put64 (HeaderSize + ProcTable, 8) ;
- (* code : call_rel 14 ; "Hello MC64!\r\n\0" ; load_imm_byte 1 ; system ; end *)
- buf [HeaderSize + CodeOff] := CHR (8CH) ; (* call_rel *)
- buf [HeaderSize + CodeOff + 1] := CHR (14) ;
- buf [HeaderSize + StrOff] := 'H' ;
- buf [HeaderSize + StrOff + 1] := 'e' ;
- buf [HeaderSize + StrOff + 2] := 'l' ;
- buf [HeaderSize + StrOff + 3] := 'l' ;
- buf [HeaderSize + StrOff + 4] := 'o' ;
- buf [HeaderSize + StrOff + 5] := ' ' ;
- buf [HeaderSize + StrOff + 6] := 'M' ;
- buf [HeaderSize + StrOff + 7] := 'C' ;
- buf [HeaderSize + StrOff + 8] := '6' ;
- buf [HeaderSize + StrOff + 9] := '4' ;
- buf [HeaderSize + StrOff + 10] := '!' ;
- buf [HeaderSize + StrOff + 11] := 13C ; (* CR *)
- buf [HeaderSize + StrOff + 12] := 12C ; (* LF *)
- buf [HeaderSize + StrOff + 13] := 0C ; (* NUL *)
- buf [HeaderSize + CodeOff + 16] := CHR (8DH) ; (* load_imm_byte *)
- buf [HeaderSize + CodeOff + 17] := CHR (1) ;
- buf [HeaderSize + CodeOff + 18] := CHR (0C3H) ; (* system *)
- buf [HeaderSize + CodeOff + 19] := CHR (50H) ; (* end_program *)
- (* checksum over the image, excluding the checksum field itself *)
- sum := 0 ;
- FOR i := HeaderSize TO FileSize - 1 DO
- IF NOT ((i >= 352) AND (i <= 355)) THEN
- sum := sum + ORD (buf [i]) ;
- END ;
- END ;
- Put32 (HeaderSize + DescChecksum, sum) ;
- IF NOT WriteFile ("boot.MC4", buf, FileSize) THEN
- Fatal ("mkdemo: cannot write boot.MC4") ;
- END ;
- END mkdemo.
|