From 3a7bff43c0703d741ee5d7500b3470f1982aa47f Mon Sep 17 00:00:00 2001 From: Elliot Nunn Date: Mon, 25 Sep 2017 00:16:50 +0800 Subject: [PATCH] Add RomLink, a bytecode interpreter The "RomLink" bytecode language can be used to link a tree of binary chunks into a flat file. The bytecode specifying each binary chunk lives in a Resource Manager resource. The RomLink's only purpose is to flatten DeclData.rsrc into a "Slot 0" (motherboard) DeclData, so it seems like overkill. Nonetheless, DeclData.rsrc is very complicated (and so are its antecedents, DeclData.r and the include file RomLink). This implementation is incomplete. It is just enough to build the vestigial DeclROM that TNT and later machines retain for Open Transport. --- DeclData/DeclData.make | 8 - DeclData/DeclData.r | 43 +++- Make/RISC.make | 2 +- Tools/ToolSource/RomLink.c | 380 ++++++++++++++++++++++++++++++++++++ Tools/ToolSource/Tools.make | 7 + 5 files changed, 423 insertions(+), 17 deletions(-) create mode 100644 Tools/ToolSource/RomLink.c diff --git a/DeclData/DeclData.make b/DeclData/DeclData.make index 29e008c..96fdffb 100644 --- a/DeclData/DeclData.make +++ b/DeclData/DeclData.make @@ -30,14 +30,6 @@ PDMMaceDir = {MaceDir}PDMMaceEnet: #include {PDMMaceDir}PDMEnet.Make DeclResources = "{RsrcDir}DeclData.rsrc" ¶ - "{RsrcDir}PrimaryInit.rsrc" ¶ - "{RsrcDir}SecondaryInit.rsrc" ¶ - "{RsrcDir}SuperInit.rsrc" ¶ - "{RsrcDir}DeclDataMace.rsrc" ¶ - "{RsrcDir}DeclDataPDMMace.rsrc" ¶ - "{RsrcDir}DeclDataSonic.rsrc" ¶ - "{RsrcDir}DeclDataVideo.rsrc" ¶ - "{RsrcDir}Gamma.rsrc" DeclHeaders = "{ObjDir}StandardEqu.d" ¶ "{AIncludes}GestaltEqu.a" ¶ diff --git a/DeclData/DeclData.r b/DeclData/DeclData.r index c5b749f..182ce40 100644 --- a/DeclData/DeclData.r +++ b/DeclData/DeclData.r @@ -765,6 +765,24 @@ resource 'sdir' (160, "_sRsrcBFBasedDir") {{ }}; +//------------------------------------------------------------- +// TNT sRsrc Directory +//------------------------------------------------------------- + +resource 'sdir' (170, "_sRsrcTNTDir") {{ + $3E, l{"_sRsrc_TNT"}; // Minimal board sRsrc directory. + $FD, l{"_sRsrc_OpenTxpt"}; // Open Transport functional sRsrc +}}; + + +resource 'boar' (150, "_sRsrc_TNT") {{ + sRsrcType, l{"_BoardType"}; // Minimal board sRsrc. + sRsrcName, c{"Macintosh 4A"}; + BoardId, d{$670}; + VendorInfo, l{"_VendorInfo"}; +}}; + + //------------------------------------------------------------- // // sRsrc_Board Lists @@ -1121,10 +1139,11 @@ resource 'styp' (535, "_BoardType") {CatBoard, TypBoard, 0, 0}; //------------------------------------------------------------- resource 'vend' (540, "_VendorInfo") {{ - VendorId, c{"Copyright © 1986-1993 by Apple Computer, Inc. All Rights Reserved."}; - RevLevel, c{"Macintosh CPU Family 5.1"}; // offset to revision - PartNum, c{"Universal DeclROM"}; // offset to part number descriptor - Date, c{$$Date}; // offset to ROM build date descriptor + VendorId, c{"Copyright © 1986-1998 by Apple Computer, Inc. All Rights Reserved."}; + RevLevel, c{"Macintosh CPU Family 6.0"}; // offset to revision + PartNum, c{"DeclROM for OpenTxpt"}; // offset to part number descriptor + Date, c{"Thursday, April 3, 2003"}; // sorry +// Date, c{$$Date}; // offset to ROM build date descriptor }}; //------------------------------------------------------------- @@ -2899,6 +2918,14 @@ resource 'srsc' (1575, "_sRsrc_Mace") {{ }}; +resource 'srsc' (1576, "_sRsrc_OpenTxpt") {{ + sRsrcType, l{"_NetOpenTxpt"}; // Network type descriptor + sRsrcName, l{"_NetOpenTxptName"}; // offset to name string + sRsrcFlags, d{0}; // don't open this device at start + sRsrcHWDevId, d{2}; // the second of many onboard Ethernet chips +}}; + + //---------------------------------- resource 'srsc' (1580, "_sRsrc_DoubleExposure") {{ @@ -2927,6 +2954,7 @@ resource 'styp' (1605, "_VideoTypeApollo") {CatDisplay, TypVideo, DrSwApple, Dr resource 'styp' (1610, "_VideoTypeGSC") {CatDisplay, TypVideo, DrSwApple, DrHwGSC}; resource 'styp' (1625, "_NetSonic") {CatNetwork, TypEthernet, DrSwApple, DrHwSonic}; resource 'styp' (1630, "_NetMace") {CatNetwork, TypEthernet, DrSwApple, DrHwMace}; +resource 'styp' (1631, "_NetOpenTxpt") {CatNetwork, TypEthernet, DrSwApple, 4}; resource 'styp' (1635, "_CPUDblExp") {CatCPU, TypAppleII, DrSwAppleIIe, DrHwDblExp}; resource 'styp' (1636, "_SCSITransport") {CatIntBus, TypXPT, DrSwApple, sRsrc_BdCyclone}; @@ -2945,6 +2973,7 @@ resource 'cstr' (1660, "_VideoNameApollo") {"Display_Video_Apple_Apollo"}; resource 'cstr' (1665, "_VideoNameGSC") {"Display_Video_Apple_DBLite"}; resource 'cstr' (1680, "_NetSonicName") {"Network_Ethernet_Apple_Sonic"}; resource 'cstr' (1685, "_NetMaceName") {"Network_Ethernet_Apple_Mace"}; +resource 'cstr' (1686, "_NetOpenTxptName") {"Network_Ethernet_Apple_OpenTransport"}; #endif @@ -9483,10 +9512,8 @@ resource 'long' (2657, "_timingApple16") {timingApple16}; // Extended Format/Header Block //------------------------------------------------------------- -resource 'xfrm' (6000, "Root") { - l{"_sSuperInitRec"}, - l{"_sRsrcSuperDir"}, - l{"_sRsrcUnknownDir"}, +resource 'form' (6000, "Root") { + l{"_sRsrcTNTDir"}, 1, // RomRevision appleFormat, 0, diff --git a/Make/RISC.make b/Make/RISC.make index d71d569..ba6094e 100644 --- a/Make/RISC.make +++ b/Make/RISC.make @@ -352,6 +352,6 @@ Clean #include {MakeDir}MainCode.make -##include {DeclDir}DeclData.make +#include {DeclDir}DeclData.make ##include {ResourceDir}Resources.make diff --git a/Tools/ToolSource/RomLink.c b/Tools/ToolSource/RomLink.c new file mode 100644 index 0000000..c9a630f --- /dev/null +++ b/Tools/ToolSource/RomLink.c @@ -0,0 +1,380 @@ +/* I interpret the "RomLink" bytecode. My "programs" are resources. */ + +#include +#include +#include +#include +#include + +// Symbolic constants for ROMLink opcodes. +#define __RL_OP_CSTRING 0x80 +#define __RL_OP_INCLUDE 0x81 +#define __RL_OP_BEGIN 0x82 +#define __RL_OP_END 0x83 +#define __RL_OP_BLOCKSIZE 0x84 +#define __RL_OP_ROMLENGTH 0x86 +#define __RL_OP_ROMCRC 0x87 +#define __RL_OP_TREESIZE 0x88 +#define __RL_OP_ALIGN 0x89 +#define __RL_OP_ANCHOR 0x8a +#define __RL_OP_KEY 0xfe +#define __RL_OP_COMMENT 0xff + +// Symbolic constants for ROMLink resource pattern selectors. +#define __RL_SEL_FILENAME 1 +#define __RL_SEL_NAME 2 +#define __RL_SEL_TYPE 3 +#define __RL_SEL_ID 4 +#define __RL_SEL_LOCAL 5 + + +/* GLOBALS used by get_program and free_program */ + +char blergh[] = "nodeformxfrmcstrlongstypexecpinisinivdevpramvmnalistspdrsdirboarsrscddirgdirvdirvendvmod"; +ResType *global_type_list; +long global_type_count; + + +void to_pas(unsigned char *p, char *c) +{ + int sl = strlen(c); + p[0] = sl; + memcpy(p+1, c, sl); +} + + +void get_program(unsigned char **prog_p, long *len_p, unsigned char *name) +{ + long i; + Handle hdl = NULL; + + for(i=0; i= opcode) + { + memcpy(right, program, opcode); + right += opcode; + program += opcode; + } + + else if(__RL_OP_CSTRING == opcode) + { + long len_with_nul = strlen(program) + 1; + + memcpy(right, program, len_with_nul); + right += len_with_nul; + program += len_with_nul; + + if(len_with_nul & 1) + { + *right++ = 0; + } + } + + else if(__RL_OP_INCLUDE == opcode) + { + unsigned char selector; + unsigned char *res_name_pstr = NULL; + unsigned char *other_prog; + long other_prog_len; + + long used_leftlen, used_rightlen; + + int result; + + while((selector = *program++) != 0) + { + if(selector == __RL_SEL_NAME) + { + res_name_pstr = program; + program += *program + 1; + } + } + + if(!res_name_pstr) { fprintf(stderr, "INCLUDE opcode with unimplemented resource pattern selector\n"); return 1; } + + get_program(&other_prog, &other_prog_len, res_name_pstr); + + if(!other_prog) return 1; + + result = do_program(right, other_prog, other_prog_len, &used_leftlen, &used_rightlen); + free_program(other_prog); + if(result) return result; + + if(left != right && used_leftlen) { fprintf(stderr, "Overwrote to the left!\n"); return 1; } + + left = right - used_leftlen; + right = right + used_rightlen; + } + + else if(__RL_OP_BEGIN == opcode) + { + offset_field_bytes = *program++ / 8; /* how many bytes this is going to use */ + + real_left = left; /* for when we return to our senses */ + real_right = right; + + left = right = fake_middle = left - 0x1000; /* off to lala land, with 4k of room */ + } + + else if(__RL_OP_END == opcode) + { + long newstufflen = right - left; + long offset; + + if(right > real_left) { fprintf(stderr, "Ran out of breathing room!\n"); return 1; } + + real_left -= newstufflen; /* my left including new stuff */ + fake_middle += real_left - left; /* the middle of the new stuff */ + memmove(real_left, left, newstufflen); + + left = real_left; /* get out of lala land */ + right = real_right; + + offset = fake_middle - right; + if((long)right & 1) offset += 1; /* pretend this field is long-aligned */ + + memcpy(right, (char *)(&offset) + 4 - offset_field_bytes, offset_field_bytes); + //printf("%08x\n", offset); + + right += offset_field_bytes; + + offset_field_bytes = 0; + } + + else if(__RL_OP_BLOCKSIZE == opcode) + { + fprintf(stderr, "BLOCKSIZE not implemented\n"); return 1; + } + + else if(__RL_OP_ROMLENGTH == opcode) + { + put_len_here = (unsigned long *)right; + right += 4; + } + + else if(__RL_OP_ROMCRC == opcode) + { + put_crc_here = (unsigned long *)right; + right += 4; + } + + else if(__RL_OP_TREESIZE == opcode) + { + fprintf(stderr, "TREESIZE not implemented\n"); return 1; + } + + else if(__RL_OP_ALIGN == opcode) + { + unsigned char align = *program++; + + while((unsigned long)right % align) + { + *right++ = 0; + } + } + + else if(__RL_OP_ANCHOR == opcode) + { + fprintf(stderr, "ANCHOR not implemented\n"); return 1; + } + + else if(__RL_OP_KEY == opcode) + { + unsigned char key = *program++; /* nop */ + } + + else if(__RL_OP_COMMENT == opcode) + { + fprintf(stderr, "COMMENT not implemented\n"); return 1; + } + + else + { + fprintf(stderr, "Unknown opcode %d\n", opcode); return 1; + } + } + + if(put_len_here) *put_len_here = right - left; + + if(put_crc_here) + { + unsigned char *ptr; + unsigned long sum; + + *put_crc_here = 0; + + sum = 0; + ptr = left; + + for(ptr=left; ptr> 31); + sum += *ptr; + } + + *put_crc_here = sum; + } + + *leftlenp = middle - left; + *rightlenp = right - middle; + + return 0; +} + + +int main(int argc, char **argv) +{ + int print_usage = 0; + + short *refnum_list; + int refnum_count = 0; + short refnum; + Str255 pas; + + char *outfile = NULL; + + unsigned char *buf, *middle; + + unsigned char *prog; + long prog_len; + + int result; + + long used_left, used_right; + + long i; + + short err; + + FInfo fi; + FILE *f; + long writesize, writtensize; + + global_type_list = (ResType *)blergh; + global_type_count = 22; + + refnum_list = (short *)calloc(argc, sizeof *refnum_list); + if(!refnum_list) + { fprintf(stderr, "%s: extreme memory pressure. Quitting.\n", argv[0]); return 1; } + + for(i=1; i