Initial commit
This commit is contained in:
commit
313177ce2a
|
@ -0,0 +1,7 @@
|
|||
.DS_Store
|
||||
parcels
|
||||
tbxi
|
||||
lzss
|
||||
__pycache__
|
||||
*.patch
|
||||
*.hqx
|
|
@ -0,0 +1,19 @@
|
|||
tbxi: scripts/bootmake.py trampoline.elf parcels
|
||||
./scripts/bootmake.py $@ trampoline.elf parcels
|
||||
SetFile -t tbxi -c chrp $@ || true # macOS only
|
||||
|
||||
# Tomfoolery required to be able to put prclmake.py args in another file
|
||||
parcels: scripts/prclmake.py scripts/prcltool.py parcel-layout.txt scripts/lzss rom $(shell find pef -type f -not -path '*/\.*')
|
||||
sh -c "scripts/prclmake.py $@ `sed 's/#.*//' parcel-layout.txt | tr '\n' ' '`"
|
||||
|
||||
scripts/lzss: lzss.c
|
||||
gcc -O2 -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -rf parcels tbxi scripts/lzss scripts/__pycache__ *.hqx
|
||||
find . -type f -name '*.patch' -delete
|
||||
|
||||
# For your convenience (macOS only)
|
||||
|
||||
%.hqx: % scripts/binhexmake.py
|
||||
scripts/binhexmake.py --data=$< --type=tbxi --creator=chrp --name="Mac OS ROM" $@
|
|
@ -0,0 +1,20 @@
|
|||
The NewWorld ROM
|
||||
================
|
||||
|
||||
This repo is part of the *CDG5* project. It builds version 9.6.1 of the *parcels*-based Mac OS ROM file, starting from a 4 MB Power Mac ROM (`rom`) and other PEF binaries (`pef/`). Use https://github.com/elliotnunn/powermac-rom to build your own ROM. A few bytes are different from the original file because (I think) the original Apple build tool failed to zero-initialize a buffer. The build result does not contain the *System Enabler* found in later Mac OS ROM versions.
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
A basic Unix toolchain is required.
|
||||
|
||||
make tbxi
|
||||
|
||||
Patching
|
||||
--------
|
||||
|
||||
Some useful patches to the Open Firmware boot script can be enabled at the top of `bootmake.py`.
|
||||
|
||||
The parcel build script will preferentially load files with `.patch` appended to the name. This is helpful when using https://github.com/elliotnunn/patchpef to edit the PowerPC binaries under `pef/`. For example, to prevent the Power Manager from crashing while trying to load a PMU plugin on the Mac mini:
|
||||
|
||||
patchpef.py pef/nlib/NativePowerMgrLib{,.patch} Initialize+0x94 " li r3,0"
|
|
@ -0,0 +1,412 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define circ(buffer, offset) ((buffer)[(offset) % sizeof(buffer)])
|
||||
|
||||
|
||||
const int lookup_size = 2;
|
||||
const int thresh_n = 3;
|
||||
const int max_n = 18; // Four bits of lookup
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**************************************************************
|
||||
LZSS.C -- A Data Compression Program
|
||||
***************************************************************
|
||||
4/6/1989 Haruhiko Okumura
|
||||
Use, distribute, and modify this program freely.
|
||||
Please send me your improved versions.
|
||||
PC-VAN SCIENCE
|
||||
NIFTY-Serve PAF01022
|
||||
CompuServe 74050,1022
|
||||
**************************************************************/
|
||||
|
||||
#define N 4096 /* size of ring buffer - must be power of 2 */
|
||||
#define F 18 /* upper limit for match_length */
|
||||
#define THRESHOLD 2 /* encode string into position and length
|
||||
if match_length is greater than this */
|
||||
#define NIL N /* index for root of binary search trees */
|
||||
|
||||
struct encode_state {
|
||||
/*
|
||||
* left & right children & parent. These constitute binary search trees.
|
||||
*/
|
||||
int lchild[N + 1], rchild[N + 257], parent[N + 1];
|
||||
|
||||
/* ring buffer of size N, with extra F-1 bytes to aid string comparison */
|
||||
uint8_t text_buf[N + F - 1];
|
||||
|
||||
/*
|
||||
* match_length of longest match.
|
||||
* These are set by the insert_node() procedure.
|
||||
*/
|
||||
int match_position, match_length;
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
decompress_lzss(uint8_t *dst, uint8_t *src, uint32_t srclen)
|
||||
{
|
||||
/* ring buffer of size N, with extra F-1 bytes to aid string comparison */
|
||||
uint8_t text_buf[N + F - 1];
|
||||
uint8_t *dststart = dst;
|
||||
uint8_t *srcend = src + srclen;
|
||||
int i, j, k, r, c;
|
||||
unsigned int flags;
|
||||
|
||||
dst = dststart;
|
||||
srcend = src + srclen;
|
||||
for (i = 0; i < N - F; i++)
|
||||
text_buf[i] = ' ';
|
||||
r = N - F;
|
||||
flags = 0;
|
||||
for ( ; ; ) {
|
||||
if (((flags >>= 1) & 0x100) == 0) {
|
||||
if (src < srcend) c = *src++; else break;
|
||||
flags = c | 0xFF00; /* uses higher byte cleverly */
|
||||
} /* to count eight */
|
||||
if (flags & 1) {
|
||||
if (src < srcend) c = *src++; else break;
|
||||
*dst++ = c;
|
||||
text_buf[r++] = c;
|
||||
r &= (N - 1);
|
||||
} else {
|
||||
if (src < srcend) i = *src++; else break;
|
||||
if (src < srcend) j = *src++; else break;
|
||||
i |= ((j & 0xF0) << 4);
|
||||
j = (j & 0x0F) + THRESHOLD;
|
||||
for (k = 0; k <= j; k++) {
|
||||
c = text_buf[(i + k) & (N - 1)];
|
||||
*dst++ = c;
|
||||
text_buf[r++] = c;
|
||||
r &= (N - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dst - dststart;
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize state, mostly the trees
|
||||
*
|
||||
* For i = 0 to N - 1, rchild[i] and lchild[i] will be the right and left
|
||||
* children of node i. These nodes need not be initialized. Also, parent[i]
|
||||
* is the parent of node i. These are initialized to NIL (= N), which stands
|
||||
* for 'not used.' For i = 0 to 255, rchild[N + i + 1] is the root of the
|
||||
* tree for strings that begin with character i. These are initialized to NIL.
|
||||
* Note there are 256 trees. */
|
||||
static void init_state(struct encode_state *sp)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(sp, 0, sizeof(*sp));
|
||||
|
||||
for (i = 0; i < N - F; i++)
|
||||
sp->text_buf[i] = ' ';
|
||||
for (i = N + 1; i <= N + 256; i++)
|
||||
sp->rchild[i] = NIL;
|
||||
for (i = 0; i < N; i++)
|
||||
sp->parent[i] = NIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Inserts string of length F, text_buf[r..r+F-1], into one of the trees
|
||||
* (text_buf[r]'th tree) and returns the longest-match position and length
|
||||
* via the global variables match_position and match_length.
|
||||
* If match_length = F, then removes the old node in favor of the new one,
|
||||
* because the old one will be deleted sooner. Note r plays double role,
|
||||
* as tree node and position in buffer.
|
||||
*/
|
||||
static void insert_node(struct encode_state *sp, int r)
|
||||
{
|
||||
int i, p, cmp;
|
||||
uint8_t *key;
|
||||
|
||||
cmp = 1;
|
||||
key = &sp->text_buf[r];
|
||||
p = N + 1 + key[0];
|
||||
sp->rchild[r] = sp->lchild[r] = NIL;
|
||||
sp->match_length = 0;
|
||||
for ( ; ; ) {
|
||||
if (cmp >= 0) {
|
||||
if (sp->rchild[p] != NIL)
|
||||
p = sp->rchild[p];
|
||||
else {
|
||||
sp->rchild[p] = r;
|
||||
sp->parent[r] = p;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (sp->lchild[p] != NIL)
|
||||
p = sp->lchild[p];
|
||||
else {
|
||||
sp->lchild[p] = r;
|
||||
sp->parent[r] = p;
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (i = 1; i < F; i++) {
|
||||
if ((cmp = key[i] - sp->text_buf[p + i]) != 0)
|
||||
break;
|
||||
}
|
||||
if (i > sp->match_length) {
|
||||
sp->match_position = p;
|
||||
if ((sp->match_length = i) >= F)
|
||||
break;
|
||||
}
|
||||
}
|
||||
sp->parent[r] = sp->parent[p];
|
||||
sp->lchild[r] = sp->lchild[p];
|
||||
sp->rchild[r] = sp->rchild[p];
|
||||
sp->parent[sp->lchild[p]] = r;
|
||||
sp->parent[sp->rchild[p]] = r;
|
||||
if (sp->rchild[sp->parent[p]] == p)
|
||||
sp->rchild[sp->parent[p]] = r;
|
||||
else
|
||||
sp->lchild[sp->parent[p]] = r;
|
||||
sp->parent[p] = NIL; /* remove p */
|
||||
}
|
||||
|
||||
/* deletes node p from tree */
|
||||
static void delete_node(struct encode_state *sp, int p)
|
||||
{
|
||||
int q;
|
||||
|
||||
if (sp->parent[p] == NIL)
|
||||
return; /* not in tree */
|
||||
if (sp->rchild[p] == NIL)
|
||||
q = sp->lchild[p];
|
||||
else if (sp->lchild[p] == NIL)
|
||||
q = sp->rchild[p];
|
||||
else {
|
||||
q = sp->lchild[p];
|
||||
if (sp->rchild[q] != NIL) {
|
||||
do {
|
||||
q = sp->rchild[q];
|
||||
} while (sp->rchild[q] != NIL);
|
||||
sp->rchild[sp->parent[q]] = sp->lchild[q];
|
||||
sp->parent[sp->lchild[q]] = sp->parent[q];
|
||||
sp->lchild[q] = sp->lchild[p];
|
||||
sp->parent[sp->lchild[p]] = q;
|
||||
}
|
||||
sp->rchild[q] = sp->rchild[p];
|
||||
sp->parent[sp->rchild[p]] = q;
|
||||
}
|
||||
sp->parent[q] = sp->parent[p];
|
||||
if (sp->rchild[sp->parent[p]] == p)
|
||||
sp->rchild[sp->parent[p]] = q;
|
||||
else
|
||||
sp->lchild[sp->parent[p]] = q;
|
||||
sp->parent[p] = NIL;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
compress_lzss(uint8_t *dst, uint32_t dstlen, uint8_t *src, uint32_t srcLen)
|
||||
{
|
||||
/* Encoding state, mostly tree but some current match stuff */
|
||||
struct encode_state *sp;
|
||||
|
||||
int i, c, len, r, s, last_match_length, code_buf_ptr;
|
||||
uint8_t code_buf[17], mask;
|
||||
uint8_t *srcend = src + srcLen;
|
||||
uint8_t *dstend = dst + dstlen;
|
||||
|
||||
/* initialize trees */
|
||||
sp = (struct encode_state *) malloc(sizeof(*sp));
|
||||
init_state(sp);
|
||||
|
||||
/*
|
||||
* code_buf[1..16] saves eight units of code, and code_buf[0] works
|
||||
* as eight flags, "1" representing that the unit is an unencoded
|
||||
* letter (1 byte), "" a position-and-length pair (2 bytes).
|
||||
* Thus, eight units require at most 16 bytes of code.
|
||||
*/
|
||||
code_buf[0] = 0;
|
||||
code_buf_ptr = mask = 1;
|
||||
|
||||
/* Clear the buffer with any character that will appear often. */
|
||||
s = 0; r = N - F;
|
||||
|
||||
/* Read F bytes into the last F bytes of the buffer */
|
||||
for (len = 0; len < F && src < srcend; len++)
|
||||
sp->text_buf[r + len] = *src++;
|
||||
if (!len) {
|
||||
free(sp);
|
||||
return (void *) 0; /* text of size zero */
|
||||
}
|
||||
/*
|
||||
* Insert the F strings, each of which begins with one or more
|
||||
* 'space' characters. Note the order in which these strings are
|
||||
* inserted. This way, degenerate trees will be less likely to occur.
|
||||
*/
|
||||
for (i = 1; i <= F; i++)
|
||||
insert_node(sp, r - i);
|
||||
|
||||
/*
|
||||
* Finally, insert the whole string just read.
|
||||
* The global variables match_length and match_position are set.
|
||||
*/
|
||||
insert_node(sp, r);
|
||||
do {
|
||||
/* match_length may be spuriously long near the end of text. */
|
||||
if (sp->match_length > len)
|
||||
sp->match_length = len;
|
||||
if (sp->match_length <= THRESHOLD) {
|
||||
sp->match_length = 1; /* Not long enough match. Send one byte. */
|
||||
code_buf[0] |= mask; /* 'send one byte' flag */
|
||||
code_buf[code_buf_ptr++] = sp->text_buf[r]; /* Send uncoded. */
|
||||
} else {
|
||||
/* Send position and length pair. Note match_length > THRESHOLD. */
|
||||
code_buf[code_buf_ptr++] = (uint8_t) sp->match_position;
|
||||
code_buf[code_buf_ptr++] = (uint8_t)
|
||||
( ((sp->match_position >> 4) & 0xF0)
|
||||
| (sp->match_length - (THRESHOLD + 1)) );
|
||||
}
|
||||
if ((mask <<= 1) == 0) { /* Shift mask left one bit. */
|
||||
/* Send at most 8 units of code together */
|
||||
for (i = 0; i < code_buf_ptr; i++)
|
||||
if (dst < dstend)
|
||||
*dst++ = code_buf[i];
|
||||
else {
|
||||
free(sp);
|
||||
return (void *) 0;
|
||||
}
|
||||
code_buf[0] = 0;
|
||||
code_buf_ptr = mask = 1;
|
||||
}
|
||||
last_match_length = sp->match_length;
|
||||
for (i = 0; i < last_match_length && src < srcend; i++) {
|
||||
delete_node(sp, s); /* Delete old strings and */
|
||||
c = *src++;
|
||||
sp->text_buf[s] = c; /* read new bytes */
|
||||
|
||||
/*
|
||||
* If the position is near the end of buffer, extend the buffer
|
||||
* to make string comparison easier.
|
||||
*/
|
||||
if (s < F - 1)
|
||||
sp->text_buf[s + N] = c;
|
||||
|
||||
/* Since this is a ring buffer, increment the position modulo N. */
|
||||
s = (s + 1) & (N - 1);
|
||||
r = (r + 1) & (N - 1);
|
||||
|
||||
/* Register the string in text_buf[r..r+F-1] */
|
||||
insert_node(sp, r);
|
||||
}
|
||||
while (i++ < last_match_length) {
|
||||
delete_node(sp, s);
|
||||
|
||||
/* After the end of text, no need to read, */
|
||||
s = (s + 1) & (N - 1);
|
||||
r = (r + 1) & (N - 1);
|
||||
/* but buffer may not be empty. */
|
||||
if (--len)
|
||||
insert_node(sp, r);
|
||||
}
|
||||
} while (len > 0); /* until length of string to be processed is zero */
|
||||
|
||||
if (code_buf_ptr > 1) { /* Send remaining code. */
|
||||
for (i = 0; i < code_buf_ptr; i++)
|
||||
if (dst < dstend)
|
||||
*dst++ = code_buf[i];
|
||||
else {
|
||||
free(sp);
|
||||
return (void *) 0;
|
||||
}
|
||||
}
|
||||
|
||||
free(sp);
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* my nasty stuff */
|
||||
|
||||
// Yes, I know it's a mess. Feel free to clean it up,
|
||||
// but please don't change the command-line interface.
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
freopen(NULL, "rb", stdin);
|
||||
freopen(NULL, "wb", stderr);
|
||||
|
||||
unsigned char dict[0x1000];
|
||||
unsigned int dict_i = 0xFEE;
|
||||
|
||||
if(argc == 2 && strcmp(argv[1], "x") == 0)
|
||||
{
|
||||
int head_char, lit, offset, len;
|
||||
|
||||
while(1)
|
||||
{
|
||||
head_char = getchar();
|
||||
if(head_char == EOF) return 0;
|
||||
|
||||
head_char |= 0xFF00; //neat little hack, this
|
||||
|
||||
while(head_char != 0xFF)
|
||||
{
|
||||
if(head_char & 1)
|
||||
{ // Literal read (1 char)
|
||||
lit = getchar();
|
||||
if(lit == EOF) return 0;
|
||||
|
||||
circ(dict, dict_i++) = lit;
|
||||
putchar(lit);
|
||||
}
|
||||
else
|
||||
{ // Dictionary read (2 bytes, offset and thingo)
|
||||
offset = getchar();
|
||||
len = getchar();
|
||||
if(offset == EOF) return 0;
|
||||
|
||||
offset |= (len & 0xF0) << 4;
|
||||
len &= 0x0F;
|
||||
len += 3;
|
||||
|
||||
for(int i=0; i<len; i++)
|
||||
{
|
||||
int copy = circ(dict, offset + i);
|
||||
circ(dict, dict_i++) = copy;
|
||||
putchar(copy);
|
||||
}
|
||||
}
|
||||
head_char >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(argc == 2 && strcmp(argv[1], "c") == 0)
|
||||
{
|
||||
uint8_t *a, *b, *ret;
|
||||
uint32_t alen;
|
||||
|
||||
a = malloc(0x400000);
|
||||
b = malloc(0x400000);
|
||||
if(!a || !b) return 1;
|
||||
|
||||
alen = fread(a, 1, 0x400000, stdin);
|
||||
|
||||
ret = compress_lzss(b, 0x400000, a, alen);
|
||||
if(!ret) return 1;
|
||||
|
||||
if(fwrite(b, ret-b, 1, stdout) != 1) return 1;
|
||||
if(fclose(stdout)) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "USAGE: lzss [x|c]\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#define BUF_SIZE 512
|
||||
#define BUF_MIN 128
|
|
@ -0,0 +1,144 @@
|
|||
# These are arguments to prclmake.py, which get put through a hacky process in the Makefile.
|
||||
# Basically, from # to EOL gets deleted, and newlines become spaces.
|
||||
|
||||
--prcl -f=00020000 -t=node -n="CodePrepare Node Parcel" -c=
|
||||
--bin -f=00000000 -t=cstr -n=name --data AAPL,CodePrepare
|
||||
--bin -f=00000000 -t=csta -n=AAPL,prepare_order --data Placeholder
|
||||
--bin -f=00020094 -t=nlib -n=TimeManagerLib -l --src=pef/nlib/TimeManagerLib
|
||||
--bin -f=00020094 -t=nlib -n=NVRAMServicesLib -l --src=pef/nlib/NVRAMServicesLib
|
||||
--bin -f=00020094 -t=nlib -n=RTCServicesLib -l --src=pef/nlib/RTCServicesLib
|
||||
|
||||
--prcl -f=00010000 -t=node -n="CodeRegister Node Parcel" -c=
|
||||
--bin -f=00000000 -t=cstr -n=name --data AAPL,CodeRegister
|
||||
--bin -f=00010094 -t=nlib -n=NativePowerMgrLib -l --src=pef/nlib/NativePowerMgrLib
|
||||
--bin -f=00010094 -t=nlib -n=AGPLib -l --src=pef/nlib/AGPLib
|
||||
--bin -f=00010194 -t=nlib -n=EtherPrintfLib -l --src=pef/nlib/EtherPrintfLib
|
||||
--bin -f=00010094 -t=shlb -n=StartLib -l --src=pef/shlb/StartLib
|
||||
|
||||
--prcl -f=00000000 -t="rom " -n="Mac OS ROM Parcel" -c=
|
||||
--bin -f=00000005 -t="rom " -n= -l --src=rom
|
||||
|
||||
--prcl -f=00000000 -t=psum -n="Property Checksum" -c=
|
||||
--bin -f=00000000 -t=csta -n= --data
|
||||
name
|
||||
model
|
||||
compatible
|
||||
device_type
|
||||
reg
|
||||
assigned-addresses
|
||||
slot-names
|
||||
vendor-id
|
||||
device-id
|
||||
class-code
|
||||
devsel-speed
|
||||
fast-back-to-back
|
||||
bootpath
|
||||
mac-address
|
||||
--bin -f=00000000 -t=csta -n= --data
|
||||
boot-rom
|
||||
macos
|
||||
--bin -f=00000000 -t=csta -n= --data
|
||||
Placeholder
|
||||
--bin -f=00000000 -t=csta -n= --data
|
||||
Placeholder
|
||||
--bin -f=00000000 -t=csta -n= --data
|
||||
usb
|
||||
ieee1394
|
||||
|
||||
--prcl -f=0000000c -t=prop -n=apple21143 -c=network
|
||||
--bin -f=00000006 -t=shlb -n=lanLib,AAPL,MacOS,PowerPC -l --src=pef/shlb/lanLib/apple21143
|
||||
|
||||
--prcl -f=00000009 -t=prop -n=backlight -c=backlight
|
||||
--bin -f=00000000 -t=ndrv -n=driver,AAPL,MacOS,PowerPC --src=pef/ndrv/BacklightDriver --nosum
|
||||
--bin -f=00000002 -t=cstr -n=code,AAPL,MacOS,name --data BacklightDriver
|
||||
|
||||
--prcl -f=0000000c -t=prop -n=bmac+ -c=network
|
||||
--bin -f=00000006 -t=shlb -n=lanLib,AAPL,MacOS,PowerPC -l --src=pef/shlb/lanLib/bmac+
|
||||
|
||||
--prcl -f=0000000c -t=prop -n=cmd646-ata -c=ata
|
||||
--bin -f=00000006 -t=ndrv -n=driver,AAPL,MacOS,PowerPC -l --src=pef/ndrv/ata/cmd646
|
||||
|
||||
--prcl -f=00000008 -t=prop -n=cofb -c=display
|
||||
--bin -f=00000024 -t=ndrv -n=driver,AAPL,MacOS,PowerPC -l --src=pef/ndrv/display
|
||||
|
||||
--prcl -f=0000000c -t=prop -n=cuda -c=via-cuda
|
||||
--bin -f=00000000 -t=ndrv -n=pef,AAPL,MacOS,PowerPC,register -l --src=pef/ndrv/PowerMgrPlugin/cuda --nosum
|
||||
--bin -f=00000002 -t=cstr -n=code,AAPL,MacOS,name --data PowerMgrPlugin
|
||||
|
||||
--prcl -f=0000000c -t=prop -n=gmac -c=network
|
||||
--bin -f=00000006 -t=shlb -n=lanLib,AAPL,MacOS,PowerPC -l --src=pef/shlb/lanLib/gmac
|
||||
|
||||
--prcl -f=0000000c -t=prop -n=grackle -c=pci
|
||||
--bin -f=00000016 -t=nlib -n=pef,AAPL,MacOS,PowerPC,prepare -l --src=pef/nlib/PCICyclesLib/Grackle
|
||||
--bin -f=00000000 -t=cstr -n=code,AAPL,MacOS,name --data Grackle_PCICyclesLib
|
||||
|
||||
--prcl -f=0000000c -t=prop -n=heathrow-ata -c=ide
|
||||
--bin -f=00000006 -t=ndrv -n=driver,AAPL,MacOS,PowerPC -l --src=pef/ndrv/ata/heathrow
|
||||
|
||||
--prcl -f=0000000c -t=prop -n=heathrow-ata -c=ata
|
||||
--bin -f=00000002 -t=ndrv -n=driver,AAPL,MacOS,PowerPC -l --src=pef/ndrv/ata/heathrow --backref
|
||||
|
||||
--prcl -f=0000000c -t=prop -n=kauai-ata -c=ata
|
||||
--bin -f=00000006 -t=ndrv -n=driver,AAPL,MacOS,PowerPC -l --src=pef/ndrv/ata/kauai
|
||||
|
||||
--prcl -f=0000000c -t=prop -n=keylargo-ata -c=ata
|
||||
--bin -f=00000006 -t=ndrv -n=driver,AAPL,MacOS,PowerPC -l --src=pef/ndrv/ata/keylargo
|
||||
|
||||
--prcl -f=0000000c -t=prop -n=keywest-i2c -c=i2c
|
||||
--bin -f=00000006 -t=ndrv -n=driver,AAPL,MacOS,PowerPC -l --src=pef/ndrv/i2c
|
||||
|
||||
--prcl -f=0000000a -t=prop -n=mac-io -c=nvram
|
||||
--bin -f=00000004 -t=ndrv -n=driver,AAPL,MacOS,PowerPC -l --src=pef/ndrv/nvram/mac-io
|
||||
|
||||
--prcl -f=00000001 -t=prop -n=macos -c=
|
||||
--bin -f=00000000 -t=cstr -n=MacOSROMFile-version --data 9.6f1
|
||||
|
||||
--prcl -f=0000000c -t=prop -n=nvram,flash -c=nvram
|
||||
--bin -f=00000004 -t=ndrv -n=driver,AAPL,MacOS,PowerPC -l --src=pef/ndrv/nvram/flash
|
||||
|
||||
--prcl -f=0000000c -t=prop -n=pci104c,ac1a -c=cardbus
|
||||
--bin -f=00000016 -t=ndrv -n=driver,AAPL,MacOS,PowerPC -l --src=pef/ndrv/cardbus
|
||||
--bin -f=00010094 -t=nlib -n=PCCard -l --src=pef/nlib/PCCardLib
|
||||
|
||||
--prcl -f=0000000c -t=prop -n=pci104c,ac50 -c=cardbus
|
||||
--bin -f=00000016 -t=ndrv -n=driver,AAPL,MacOS,PowerPC -l --src=pef/ndrv/cardbus --backref
|
||||
--bin -f=00010094 -t=nlib -n=PCCard -l --src=pef/nlib/PCCardLib
|
||||
|
||||
--prcl -f=0000020c -t=prop -n=pciclass,0c0010 -c=ieee1394
|
||||
--bin -f=00000004 -t=ndrv -n=driver,AAPL,MacOS,PowerPC -l --src=pef/ndrv/firewire
|
||||
--bin -f=00010096 -t=nlib -n=FWServicesLib -l --src=pef/nlib/FWServicesLib
|
||||
--bin -f=00010096 -t=nlib -n=DevNLib -l --src=pef/nlib/DevNLib
|
||||
--bin -f=00010096 -t=nlib -n=DFMLib -l --src=pef/nlib/DFMLib
|
||||
--bin -f=00010096 -t=nlib -n=GenericDriverFamily -l --src=pef/nlib/GenericDriverFamily
|
||||
|
||||
--prcl -f=0000000c -t=prop -n=pmu -c=power-mgt
|
||||
--bin -f=00000000 -t=ndrv -n=pef,AAPL,MacOS,PowerPC,register -l --src=pef/ndrv/PowerMgrPlugin/pmu --nosum
|
||||
--bin -f=00000002 -t=cstr -n=code,AAPL,MacOS,name --data PowerMgrPlugin --backref
|
||||
--bin -f=00000002 -t=cstr -n=target-mode-capable --data SCSI
|
||||
--bin -f=00010096 -t=nlib -n=PMULib -l --src=pef/nlib/PMULib
|
||||
|
||||
--prcl -f=0000000c -t=prop -n=uni-n-i2c -c=i2c
|
||||
--bin -f=00000006 -t=ndrv -n=driver,AAPL,MacOS,PowerPC -l --src=pef/ndrv/i2c
|
||||
|
||||
--prcl -f=0000000c -t=prop -n=uni-north -c=pci
|
||||
--bin -f=00000016 -t=nlib -n=pef,AAPL,MacOS,PowerPC,prepare -l --src=pef/nlib/PCICyclesLib/UniNorth
|
||||
--bin -f=00000002 -t=cstr -n=code,AAPL,MacOS,name --data UniNorth_PCICyclesLib
|
||||
|
||||
--prcl -f=0000000a -t=prop -n=via-cuda -c=rtc
|
||||
--bin -f=00000004 -t=ndrv -n=driver,AAPL,MacOS,PowerPC -l --src=pef/ndrv/rtc/via-cuda
|
||||
|
||||
--prcl -f=0000000a -t=prop -n=via-pmu -c=nvram
|
||||
--bin -f=00000004 -t=ndrv -n=driver,AAPL,MacOS,PowerPC -l --src=pef/ndrv/nvram/via-pmu
|
||||
|
||||
--prcl -f=0000000a -t=prop -n=via-pmu -c=rtc
|
||||
--bin -f=00000004 -t=ndrv -n=driver,AAPL,MacOS,PowerPC -l --src=pef/ndrv/rtc/via-pmu
|
||||
|
||||
--prcl -f=0000000c -t=prop -n=via-pmu-2000 -c=power-mgt
|
||||
--bin -f=00000000 -t=ndrv -n=pef,AAPL,MacOS,PowerPC,register -l --src=pef/ndrv/PowerMgrPlugin/pmu-2000 --nosum
|
||||
--bin -f=00000002 -t=cstr -n=code,AAPL,MacOS,name --data PowerMgrPlugin --backref
|
||||
--bin -f=00010096 -t=nlib -n=PMULib -l --src=pef/nlib/PMULib --backref
|
||||
|
||||
--prcl -f=0000000c -t=prop -n=via-pmu-99 -c=power-mgt
|
||||
--bin -f=00000000 -t=ndrv -n=pef,AAPL,MacOS,PowerPC,register -l --src=pef/ndrv/PowerMgrPlugin/pmu-99 --nosum
|
||||
--bin -f=00000002 -t=cstr -n=code,AAPL,MacOS,name --data PowerMgrPlugin --backref
|
||||
--bin -f=00010096 -t=nlib -n=PMULib -l --src=pef/nlib/PMULib --backref
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,61 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
|
||||
import binhex
|
||||
import argparse
|
||||
import os.path
|
||||
|
||||
|
||||
def get_file(filename):
|
||||
with open(filename, 'rb') as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
def fourcc(s):
|
||||
b = s.encode('ascii').ljust(4, b' ')
|
||||
if len(b) != 4:
|
||||
raise ValueError('wrong length')
|
||||
return b
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description = """Blah."""
|
||||
)
|
||||
|
||||
parser.add_argument('--data', action='store', metavar='FILE', help='Data fork')
|
||||
parser.add_argument('--rsrc', action='store', metavar='FILE', help='Resource fork')
|
||||
parser.add_argument('--type', action='store', metavar='FOURCC', type=fourcc, default=' ', help='(space-padded) type code')
|
||||
parser.add_argument('--creator', action='store', metavar='FOURCC', type=fourcc, default=' ', help='(space-padded) creator code')
|
||||
parser.add_argument('--name', action='store', metavar='FILENAME', default='', help='archived name (taken from DEST by default)')
|
||||
parser.add_argument('--has-bundle', action='store_true', help='set Finder flag indicating BNDL resource present')
|
||||
parser.add_argument('dest', metavar='DEST', help='HQX file')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
# make an auto filename
|
||||
if args.name:
|
||||
name = args.name
|
||||
else:
|
||||
name = os.path.basename(args.dest)
|
||||
|
||||
base, ext = os.path.splitext(name)
|
||||
if ext.lower() == '.hqx':
|
||||
name = base
|
||||
|
||||
assert name
|
||||
|
||||
finfo = binhex.FInfo()
|
||||
finfo.Creator = args.creator
|
||||
finfo.Type = args.type
|
||||
finfo.Flags = 0x2000 if args.has_bundle else 0
|
||||
|
||||
rsrc_fork, data_fork = (get_file(f) if f else b'' for f in [args.rsrc, args.data])
|
||||
|
||||
|
||||
bh = binhex.BinHex((name, finfo, len(data_fork), len(rsrc_fork)), args.dest)
|
||||
|
||||
bh.write(data_fork)
|
||||
bh.write_rsrc(rsrc_fork)
|
||||
|
||||
bh.close()
|
|
@ -0,0 +1,415 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from zlib import adler32
|
||||
from sys import argv
|
||||
from html import escape as html_escape
|
||||
import re
|
||||
|
||||
def html_escape_forth(f):
|
||||
return re.sub(r'[<>]+', lambda m: html_escape(m.group()), f)
|
||||
|
||||
|
||||
|
||||
# Set constants.
|
||||
|
||||
# The COMPATIBLE field at the top of the script
|
||||
COMPATIBLE = [
|
||||
"MacRISC",
|
||||
# "MacRISC2",
|
||||
# "MacRISC3",
|
||||
]
|
||||
|
||||
# Changes to the Forth boot script, all off by default
|
||||
DELETE_MODEL_CHECK = False
|
||||
DELETE_CHECKSUM_CHECK = False
|
||||
MAC_MINI_PRETEND_TO_BE_POWERBOOK = False
|
||||
G4_FIX = False
|
||||
|
||||
# Adds code to set the AAPL,debug property early in the boot script
|
||||
DEBUG_PROPERTY = 0
|
||||
# DEBUG_PROPERTY |= 0x00000001 # Print general informative messages.
|
||||
# DEBUG_PROPERTY |= 0x00000002 # Print formatted Mac OS tables (except config/universal info).
|
||||
# DEBUG_PROPERTY |= 0x00000004 # Print formatted config info table.
|
||||
# DEBUG_PROPERTY |= 0x00000008 # Dump Mac OS tables (except config/universal info).
|
||||
# DEBUG_PROPERTY |= 0x00000010 # Print node names while copying the device tree.
|
||||
# DEBUG_PROPERTY |= 0x00000020 # Print property info while copying the device tree.
|
||||
# DEBUG_PROPERTY |= 0x00000040 # Print interrupt-related info.
|
||||
# DEBUG_PROPERTY |= 0x00000080 # Print interrupt tree traversal info.
|
||||
# DEBUG_PROPERTY |= 0x00000100 # Print address resolution info.
|
||||
# DEBUG_PROPERTY |= 0x00000200 # Print NV-RAM info.
|
||||
# DEBUG_PROPERTY |= 0x00000400 # Print Mac OS "universal" info.
|
||||
# DEBUG_PROPERTY |= 0x00000800 # Print "special" node info.
|
||||
# DEBUG_PROPERTY |= 0x00001000 # Load EtherPrintf utility via parcel for post FCode debugging.
|
||||
# DEBUG_PROPERTY |= 0x00002000 # Print BOOTP/DHCP/BSDP information.
|
||||
# DEBUG_PROPERTY |= 0x00004000 # Allocate writable ROM aperture.
|
||||
# DEBUG_PROPERTY |= 0x00008000 # Mark Toolbox image as non-cacheable.
|
||||
# DEBUG_PROPERTY |= 0x00010000 # Print parcel info while copying the device tree.
|
||||
# DEBUG_PROPERTY |= 0x00020000 # Print information on device tree data checksums.
|
||||
# DEBUG_PROPERTY |= 0x01000000 # Enable the Nanokernel debugger.
|
||||
# DEBUG_PROPERTY |= 0x02000000 # Display the Nanokernel log during boot.
|
||||
# DEBUG_PROPERTY |= 0x10000000 # Dont attempt to unhibernate system.
|
||||
# DEBUG_PROPERTY |= 0x40000000 # Halt after end of FCode (useful if outputting to screen).
|
||||
|
||||
# The OF-friendly parts of the file are padded out to 20k with nulls
|
||||
DATA_OFFSET = 0x5000
|
||||
|
||||
|
||||
|
||||
# Load the two binary blobs, and save their offsets and sizes.
|
||||
|
||||
out_path, elf_path, parcels_path = argv[1:]
|
||||
|
||||
|
||||
tbxi = bytearray(DATA_OFFSET)
|
||||
|
||||
for x in ['elf', 'parcels']:
|
||||
locals()[x + '_offset'] = len(tbxi)
|
||||
with open(locals()[x + '_path'], 'rb') as f:
|
||||
data = f.read()
|
||||
while len(data) % 4:
|
||||
data.extend(b'\x00')
|
||||
locals()[x + '_size'] = len(data)
|
||||
|
||||
tbxi.extend(data)
|
||||
|
||||
info_size = len(tbxi)
|
||||
|
||||
|
||||
|
||||
# Assemble the CHRP-BOOT text for Open Firmware to parse.
|
||||
|
||||
BOOT_SCRIPT = ''
|
||||
|
||||
if DEBUG_PROPERTY: BOOT_SCRIPT += """
|
||||
\ DEBUG_PROPERTY
|
||||
dev /
|
||||
%X encode-int " AAPL,debug" property
|
||||
device-end
|
||||
\ END DEBUG_PROPERTY
|
||||
""" % DEBUG_PROPERTY
|
||||
|
||||
if MAC_MINI_PRETEND_TO_BE_POWERBOOK: BOOT_SCRIPT += """
|
||||
\ MAC_MINI_PRETEND_TO_BE_POWERBOOK
|
||||
dev /
|
||||
" PowerBook4,3" encode-string " model" property
|
||||
" PowerBook4,3" encode-string " MacRISC" encode-string encode+ " MacRiSC2" encode-string encode+ " MacRISC3" encode-string encode+ " Power Macintosh" encode-string encode+ " compatible" property
|
||||
device-end
|
||||
\ END MAC_MINI_PRETEND_TO_BE_POWERBOOK
|
||||
"""
|
||||
|
||||
if G4_FIX: BOOT_SCRIPT += """
|
||||
\ G4_FIX:
|
||||
" /cpus/PowerPC,G4@0" find-package if
|
||||
" /cpus/PowerPC,G4@0" select-dev
|
||||
" cpu-version" active-package get-package-property 0= if
|
||||
decode-int
|
||||
2swap
|
||||
2drop
|
||||
80010201 <
|
||||
0= if
|
||||
80010201 encode-int " cpu-version" property
|
||||
then
|
||||
then
|
||||
device-end
|
||||
then
|
||||
\ END G4_FIX
|
||||
"""
|
||||
|
||||
BOOT_SCRIPT += """
|
||||
here >r
|
||||
dev /
|
||||
"""
|
||||
|
||||
if DELETE_MODEL_CHECK: BOOT_SCRIPT += """
|
||||
\ Model check deleted
|
||||
"""
|
||||
else: BOOT_SCRIPT += """
|
||||
" model" active-package get-package-property abort" can't find MODEL"
|
||||
decode-string 2swap 2drop " iMac,1" $= ?dup 0= if
|
||||
" compatible" active-package get-package-property abort" can't find COMPATIBLE"
|
||||
false >r
|
||||
begin
|
||||
dup while
|
||||
decode-string here over 2swap bounds ?do
|
||||
i c@ dup [char] A [char] Z between if h# 20 xor then c,
|
||||
loop
|
||||
%s
|
||||
2drop
|
||||
repeat
|
||||
2drop r>
|
||||
then
|
||||
r> here - allot
|
||||
0= abort" this image is not for this platform"
|
||||
""" % '\n'.join(' 2dup " %s" $= r> or >r' % m.lower() for m in COMPATIBLE)
|
||||
|
||||
if DELETE_CHECKSUM_CHECK: BOOT_SCRIPT += """
|
||||
\ Checksum check deleted
|
||||
"""
|
||||
else: BOOT_SCRIPT += """
|
||||
decimal
|
||||
1 load-base load-size 14 - adler32 load-base load-size + 12 - 12 ['] eval catch if
|
||||
2drop ." , bad checksum value" -1
|
||||
then
|
||||
<> if
|
||||
." , checksum error"
|
||||
abort
|
||||
then
|
||||
hex
|
||||
"""
|
||||
|
||||
BOOT_SCRIPT += """
|
||||
dev /openprom
|
||||
0 0 " supports-bootinfo" property device-end
|
||||
|
||||
" /chosen" find-package 0= abort" can't find '/chosen'" constant /chosen
|
||||
" memory" /chosen get-package-property abort" memory??" decode-int constant xmem 2drop
|
||||
" mmu" /chosen get-package-property abort" mmu??" decode-int constant xmmu 2drop
|
||||
" AAPL,debug" " /" find-package 0= abort" can't find '/'" get-package-property if
|
||||
false
|
||||
else
|
||||
2drop true
|
||||
then
|
||||
constant debug?
|
||||
debug? if cr ." checking for RELEASE-LOAD-AREA" then
|
||||
" release-load-area" $find 0= if 2drop false then constant 'release-load-area
|
||||
debug? if 'release-load-area if ." , found it" else ." , not found" then then
|
||||
: do-translate " translate" xmmu $call-method ;
|
||||
: do-map " map" xmmu $call-method ;
|
||||
: do-unmap " unmap" xmmu $call-method ;
|
||||
: claim-mem " claim" xmem $call-method ;
|
||||
: release-mem " release" xmem $call-method ;
|
||||
: claim-virt " claim" xmmu $call-method ;
|
||||
: release-virt " release" xmmu $call-method ;
|
||||
1000 constant pagesz
|
||||
pagesz 1- constant pagesz-1
|
||||
-1000 constant pagemask
|
||||
h# {elf_offset:06X} constant elf-offset
|
||||
h# {elf_size:06X} constant elf-size
|
||||
elf-size pagesz-1 + pagemask and constant elf-pages
|
||||
h# {parcels_offset:06X} constant parcels-offset
|
||||
h# {parcels_size:06X} constant parcels-size
|
||||
parcels-size pagesz-1 + pagemask and constant parcels-pages
|
||||
h# {info_size:06X} constant info-size
|
||||
info-size pagesz-1 + pagemask and constant info-pages
|
||||
0 value load-base-claim
|
||||
0 value info-base
|
||||
'release-load-area if
|
||||
load-base to info-base
|
||||
else
|
||||
load-base info-pages 0 ['] claim-mem catch if 3drop 0 then to load-base-claim
|
||||
info-pages 1000 claim-virt to info-base
|
||||
load-base info-base info-pages 10 do-map then
|
||||
\ allocate room for both images
|
||||
parcels-pages 400000 claim-mem constant rom-phys parcels-pages 1000 claim-virt constant rom-virt rom-phys rom-virt parcels-pages 10 do-map
|
||||
elf-pages 1000 claim-mem constant elf-phys elf-pages 1000 claim-virt constant elf-virt
|
||||
elf-phys elf-virt elf-pages 10 do-map info-base elf-offset + elf-virt elf-size move debug? if cr ." elf-phys,elf-virt,elf-pages: " elf-phys u. ." , " elf-virt u. ." , " elf-pages u. then
|
||||
\ copy the compressed image
|
||||
debug? if cr ." copying compressed ROM image" then
|
||||
rom-virt parcels-pages 0 fill
|
||||
info-base parcels-offset + rom-virt parcels-size move
|
||||
'release-load-area 0= if
|
||||
info-base info-pages do-unmap load-base-claim ?dup if info-pages release-mem then
|
||||
then
|
||||
debug? if cr ." MacOS-ROM phys,virt,size: " rom-phys u. ." , " rom-virt u. ." , " parcels-size u. then
|
||||
\ create the actual property
|
||||
debug? if cr ." finding/creating '/rom/macos' package" then
|
||||
device-end 0 to my-self
|
||||
" /rom" find-device
|
||||
" macos" ['] find-device catch if 2drop new-device " macos" device-name finish-device then
|
||||
" /rom/macos" find-device
|
||||
debug? if cr ." creating 'AAPL,toolbox-parcels' property" then
|
||||
rom-virt encode-int parcels-size encode-int encode+ " AAPL,toolbox-parcels" property
|
||||
device-end
|
||||
debug? if cr ." copying MacOS.elf to load-base" then
|
||||
'release-load-area if
|
||||
load-base elf-pages + 'release-load-area execute
|
||||
else
|
||||
load-base elf-pages 0 claim-mem
|
||||
load-base dup elf-pages 0 do-map then
|
||||
elf-virt load-base elf-size move
|
||||
elf-virt elf-pages do-unmap elf-virt elf-pages release-virt
|
||||
elf-phys elf-pages release-mem
|
||||
debug? if cr ." init-program" then
|
||||
init-program
|
||||
debug? if cr ." .registers" .registers then
|
||||
debug? if cr ." go" cr then
|
||||
go
|
||||
cr ." end of BOOT-SCRIPT"
|
||||
"""
|
||||
|
||||
BOOT_SCRIPT = BOOT_SCRIPT.format(**locals())
|
||||
BOOT_SCRIPT = html_escape_forth(BOOT_SCRIPT)
|
||||
|
||||
|
||||
BITMAP = """
|
||||
0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4925B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92006EDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB0049B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBBBFBBBFBBBFBBBFBBBFBBBFBBBFBB252577BFDFDFDFDFDFDFDFDFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF772F332F2F2F332F2F2F332F2F2F332F2A055757575757575B57575B57575B579BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF772F2F2F332F2F2F332F2F2F332F2F2F012E57575B575B57575757575757575777FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF97132F0F2F132F0F2F132F0F2F0F2F0A0557575B5757575B57575B57575B575797FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF772F2F330F2F2F2F0F2F0F2F2F332F052A575B5757535357575B57575B57575B97FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF772F2F2F332F0F2B062F332F132F0A00575757575B25255B5757575B5757575797FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF772F132F0F332F0B060F2F0F2F2F0529575B575B572525575B575757575B575777FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF970F2F2F2F0F2F0B262F0F332F0A0053575757575B25255B57575B5757575B5797FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF772F2F132F2F332F0F2F332F2F0501575B575B5757534F57575B57575B57575797FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF772F2F2F132F2F2F2F132F2F0F052A575757575B5757575B57575757575B575797FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF77330F332F0F2F132F2F0F2F2F00535757575B5757575B575757575B57575B5777FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF972F2F2F2F332F2F132F2F132A00575B575B57575B5757575B5757575B57575797FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF770F330F330F2F0F2F2F332F05255B575757575B5757575B57575B575757575797FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF972F2F2F2F332F332F0F2F2F052A575B57575757575B5757575B57575B575B5797FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF772F0F330F2F0F2F0F332F33052A5757575757575B5757575B575757575B575777FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF772F2F2F332F332F2F2F0F2F050000000000002E57575B5757575B575757575B97FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF77332F132F0F2F0F2F0F332F2A0A2A2A2A050053575B5757575B5757575B575797FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF970F2F2F2F332F332F330F2F0F332F0F330600575757575B5757575B57575B5797FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF772F332F132F0F2F0F2F2F332F2F332F0F2504575B575B57575753575B57575777FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF772F2F2F2F0B060A2B0F2F0F332F0F2F33050557575B574F2E2505535757575B97FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF772F0F330F332F2B0A0606060A0B0B2B0B05052A29250005292E575757575B5797FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF970F2F2F2F0F2F132F2F0F2B0A0A060606010025292E53575B57575B575B575797FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF772F330F332F132F2F2F2F2F332F2F2F2F0501575B575757575757575757575777FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF77332F2F2F2F2F2F132F0F2F0F2F2F0F2F050057575B575B57575B575B57575B97FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF772F2F2F0F332F132F2F2F332F332F2F332600535B575757575B5757575B575797FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF970F330F332F0F2F2F132F0F2F0F330F2F0A004F57575B5757575B5757575B5797FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B332F33332F3333332F333333332F33332F002A77777777777777777777777797FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDBDBDBDBDBDBDBDBDBDBDBDBFBDB2025B7DBDBDBDBDBDBDBDBDBDBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E00B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF006EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFDBDBFFFFFFFFFFFFFFDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB57539BFFFFFFFFFFFF775377DFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFF92006EFFFFFFFFFF6E2592FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53B7DBDBBB53DFFFFFDF97DBFBBB33FFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFF2525FFFFFFFFFF2525DBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3397DBFFFFFFDF33DBFF57B7FFFFFF97DBFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFF9225B7FFFFFFB76E25DBFFFFFFFFFFFFFFFFFFFFFFFFFFDBB7FFFFFFFF7733B7FFFFFFFFFF9B53FF3397FFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFF92496EFFFFFFB79225DBFFFFB792496EFFFFFFB7926E49FFFFFFFFFFFF2F73FFFFFFFFFFFFDF0FDB5333FFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFDBB7B725FFFFFF929225DBFF9292FFFF00DBFF6EB7FFFF6E92FFFFFFFFFF0F93FFFFFFFFFFFFFF2F979B2F33DFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFDBB7FF00B7FFDBB7B725DBFF25B7FFFF25B7DB49DBFFFFFFB7FFFFFFFFDF0F97FFFFFFFFFFFFFF3373FFBB330F53FFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFDBDBFF6E49FFB7FFFF00DBFFFFFFFFFF00B74949FFFFFFFFFFFFFFFFFFDF2F97FFFFFFFFFFFFFF3373FFFFFF972F33FFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFDBDBFFB725FF92FFFF00DBFFFFFFDB9225B7256EFFFFFFFFFFFFFFFFFFFF2F97FFFFFFFFFFFFFF2F73FFFFFFFFBB2F97FFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFB7DBFFFF006EB7FFFF00B7FFFFB7DBFF25B7256EFFFFFFFFFFFFFFFFFFFF3373FFFFFFFFFFFFDF2F97FFFFFFFFFF7773FFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFB7DBFFFF4925DBFFFF00B7FF6EB7FFFF25B76E49FFFFFFFFFFFFFFFFFFFF9B33FFFFFFFFFFFF5753B7BBFFFFFFFF7773FFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFF92DBFFFFDB49DBFFFF00B7FF25B7FFB700B7FF25DBFFFFFFFFFFFFFFFFFFFF5377FFFFFFFFBB3397DF53FFFFFFFF57B7FFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFDB2549DBFFFFB7FFDB490049DB254992DB2549DB9225DBFF92FFFFFFFFFFFFFFFF5397FFFFBB53B7FBFF3397FFFF77B7DBFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFB792DBFFFFFFFFFFB7B7B7DBB76EB7FFDB92DBFFB76E6EB7FFFFFFFFFFFFFFFFFFB7737797DBFFFFFFFF977397BBDBFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
|
||||
0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B
|
||||
"""
|
||||
|
||||
|
||||
BADGES = """
|
||||
1010
|
||||
000000000000000000ABFE0000000000
|
||||
0000000000000000ABFF000000000000
|
||||
ABABABABABABABABFFABABABABABABAB
|
||||
AB7F7F7F7F7F7FFF7F2A2A2A2A2A2AAB
|
||||
AB7F7F7FF17F7FFF542A2AFF2A2A2AAB
|
||||
AB7F7F7FF17FABFF2A2A2AFF2A2A2AAB
|
||||
AB7F7F7F7F7FFF7F2A2A2A2A2A2A2AAB
|
||||
AB7F7F7F7F7FFF542A2A2A2A2A2A2AAB
|
||||
AB7F7F7F7F7FFFFFFFFF2A2A2A2A2AAB
|
||||
AB7F7F7F7F7F7F7F7FFF2A2A2A2A2AAB
|
||||
AB7F7FFFF17F7F7F7FFF2A2AFFFF2AAB
|
||||
AB7F7F7F7FF1F1F1F1FFFFFF542A2AAB
|
||||
AB7F7F7F7F7F7F7F7FFF2A2A2A2A2AAB
|
||||
ABABABABABABABABABFFABABABABABAB
|
||||
000000000000000000ABFF0000000000
|
||||
00000000000000000000ABFF00000000
|
||||
000000000000000000F3FF0000000000
|
||||
0000000000000000F3FF000000000000
|
||||
F3F3F3F3F3F3F3F3FFF3F3F3F3F3F3F3
|
||||
F3AAAAAAAAAAAAFFAA555555555555F3
|
||||
F3AAAAAAF4AAAAFF7F5555FF555555F3
|
||||
F3AAAAAAF4AAF3FF555555FF555555F3
|
||||
F3AAAAAAAAAAFFAA55555555555555F3
|
||||
F3AAAAAAAAAAFF7F55555555555555F3
|
||||
F3AAAAAAAAAAFFFFFFFF5555555555F3
|
||||
F3AAAAAAAAAAAAAAAAFF5555555555F3
|
||||
F3AAAAFFF4AAAAAAAAFF5555FFFF55F3
|
||||
F3AAAAAAAAF4F4F4F4FFFFFF7F5555F3
|
||||
F3AAAAAAAAAAAAAAAAFF5555555555F3
|
||||
F3F3F3F3F3F3F3F3F3FFF3F3F3F3F3F3
|
||||
000000000000000000F3FF0000000000
|
||||
00000000000000000000F3FF00000000
|
||||
000000000000000000FFFE0000000000
|
||||
0000000000000000FFFF000000000000
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
000000000000000000FFFF0000000000
|
||||
00000000000000000000FFFF00000000
|
||||
"""
|
||||
|
||||
|
||||
COMPATIBLE_TAG = '\n'.join(COMPATIBLE)
|
||||
|
||||
BOOT_INFO = """
|
||||
<CHRP-BOOT>
|
||||
<COMPATIBLE>
|
||||
{COMPATIBLE_TAG}
|
||||
</COMPATIBLE>
|
||||
<DESCRIPTION>
|
||||
MacROM for NewWorld.
|
||||
</DESCRIPTION>
|
||||
<ICON SIZE=64,64 COLOR-SPACE=3,3,2 >
|
||||
<BITMAP>
|
||||
{BITMAP}
|
||||
</BITMAP>
|
||||
</ICON>
|
||||
<BOOT-SCRIPT>
|
||||
{BOOT_SCRIPT}
|
||||
</BOOT-SCRIPT>
|
||||
<OS-BADGE-ICONS>
|
||||
{BADGES}
|
||||
</OS-BADGE-ICONS>
|
||||
</CHRP-BOOT>
|
||||
""".format(**locals())
|
||||
|
||||
|
||||
BOOT_INFO = '\n'.join(l for l in BOOT_INFO.split('\n') if l)
|
||||
BOOT_INFO = BOOT_INFO.replace('\n', '\r')
|
||||
BOOT_INFO += '\r\x04' # CR, EOT
|
||||
BOOT_INFO = BOOT_INFO.encode('ascii')
|
||||
|
||||
if len(BOOT_INFO) > DATA_OFFSET:
|
||||
raise ValueError
|
||||
|
||||
# Insert the text
|
||||
tbxi[:len(BOOT_INFO)] = BOOT_INFO
|
||||
|
||||
|
||||
|
||||
# Checksum
|
||||
|
||||
cksum = adler32(tbxi)
|
||||
cksum_str = ('\r\\ h# %08X' % cksum).encode('ascii')
|
||||
|
||||
tbxi.extend(cksum_str)
|
||||
|
||||
|
||||
|
||||
# Write out.
|
||||
|
||||
with open(out_path, 'wb') as f:
|
||||
f.write(tbxi)
|
|
@ -0,0 +1,14 @@
|
|||
import os.path
|
||||
import subprocess as sp
|
||||
|
||||
def _run(arg, input):
|
||||
lzbin = os.path.join(os.path.dirname(__file__), 'lzss')
|
||||
p = sp.Popen([lzbin, arg], stdin=sp.PIPE, stdout=sp.PIPE, bufsize=0x400000)
|
||||
output, stderr = p.communicate(input)
|
||||
return output
|
||||
|
||||
def compress(data):
|
||||
return _run('c', data)
|
||||
|
||||
def extract(data):
|
||||
return _run('x', data)
|
|
@ -0,0 +1,83 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from prcltool import ParcelsArea, ParcelStruct, ParcelEntry
|
||||
import argparse
|
||||
from sys import argv
|
||||
|
||||
|
||||
class DataLoader(argparse.Action):
|
||||
def __call__(self, parser, namespace, values, option_string=None):
|
||||
path = values[0]
|
||||
|
||||
try:
|
||||
p2 = path + '.patch'
|
||||
with open(p2, 'rb') as f:
|
||||
namespace.bytes = f.read()
|
||||
print('Using', p2)
|
||||
except FileNotFoundError:
|
||||
with open(path, 'rb') as f:
|
||||
namespace.bytes = f.read()
|
||||
|
||||
class DataReader(argparse.Action):
|
||||
def __call__(self, parser, namespace, values, option_string=None):
|
||||
d = b''.join(s.encode('ascii')+b'\0' for s in values)
|
||||
namespace.bytes = d
|
||||
namespace.should_checksum = False
|
||||
|
||||
def hex(s):
|
||||
return int(s, 16)
|
||||
|
||||
def fourcc(s):
|
||||
b = s.encode('ascii')
|
||||
if len(b) != 4:
|
||||
raise ValueError('type code not four bytes')
|
||||
return b
|
||||
|
||||
p1 = argparse.ArgumentParser()
|
||||
p2 = argparse.ArgumentParser()
|
||||
|
||||
p1.add_argument('--flags', '-f', action='store', type=hex, default=0)
|
||||
p1.add_argument('--fourcc', '-t', action='store', type=fourcc, default=' ')
|
||||
p1.add_argument('--name', '-n', action='store', default='')
|
||||
p1.add_argument('--compat', '-c', action='store', default='')
|
||||
|
||||
p2.add_argument('--fourcc', '-t', action='store', type=fourcc, default=' ')
|
||||
p2.add_argument('--flags', '-f', action='store', type=hex, default=0)
|
||||
p2.add_argument('--lzss', '-l', action='store_true', dest='compress')
|
||||
p2.add_argument('--name', '-n', action='store', default='')
|
||||
p2.add_argument('--backref', action='store_true', dest='backref_allowed')
|
||||
p2.add_argument('--nosum', action='store_false', dest='should_checksum')
|
||||
p2.add_argument('--src', '-s', nargs=1, dest='bytes', action=DataLoader)
|
||||
p2.add_argument('--data', '-d', nargs='+', dest='bytes', action=DataReader)
|
||||
|
||||
|
||||
# Usage: prog.py [ --prcl prcl-opts [ --bin bin-opts ] ... ] ...
|
||||
|
||||
progname, dest, *args = argv
|
||||
|
||||
groups = []
|
||||
|
||||
me = ParcelsArea()
|
||||
|
||||
for a in args:
|
||||
if a in ('--prcl', '--bin'):
|
||||
n = []
|
||||
groups.append(n)
|
||||
n.append(a)
|
||||
|
||||
for g in groups:
|
||||
t, *opts = g
|
||||
|
||||
if t == '--prcl':
|
||||
prcl = ParcelStruct()
|
||||
p1.parse_args(args=opts, namespace=prcl)
|
||||
me.prcls.append(prcl)
|
||||
elif t == '--bin':
|
||||
bn = ParcelEntry()
|
||||
p2.parse_args(args=opts, namespace=bn)
|
||||
prcl.entries.append(bn)
|
||||
else:
|
||||
raise ValueError('bad arg')
|
||||
|
||||
with open(dest, 'wb') as f:
|
||||
f.write(bytes(me))
|
|
@ -0,0 +1,189 @@
|
|||
# Ripped from somewhere else.
|
||||
# Can kind-of rip parcels.
|
||||
# Needs neatening up.
|
||||
|
||||
import struct
|
||||
from binascii import crc32
|
||||
import lzss
|
||||
import struct
|
||||
|
||||
class ParcelsArea:
|
||||
MAGIC = b'prcl \x01\x00\x00\x00 \x00\x00\x00\x14 \x00\x00\x00\x14 \x00\x00\x00\x00'.replace(b' ', b'')
|
||||
|
||||
def __init__(self, bytes=None):
|
||||
if bytes is not None:
|
||||
if not bytes.startswith(self.MAGIC):
|
||||
raise ValueError('Instead of a prcl magic number: %r' % bytes[:len(self.MAGIC)])
|
||||
|
||||
# Read all the structs in the prcl area!
|
||||
prcls = ParcelStruct.scan(bytes=bytes, first_offset=len(self.MAGIC))
|
||||
prcls = list(prcls)
|
||||
self.prcls = prcls
|
||||
|
||||
for prcl in prcls:
|
||||
for entry in prcl.entries:
|
||||
tpl = (entry.load_offset, entry.load_len, entry.compress)
|
||||
|
||||
x = bytes[entry.load_offset : entry.load_offset+entry.load_len]
|
||||
if entry.compress:
|
||||
x = lzss.extract(x)
|
||||
entry.bytes = x
|
||||
|
||||
else:
|
||||
self.prcls = []
|
||||
|
||||
def __bytes__(self):
|
||||
binaries_added = {} # (bytes, compress): (compressed_bytes, offset, cksum)
|
||||
things = bytearray(self.MAGIC)
|
||||
|
||||
for prcl in self.prcls:
|
||||
prcl_offset = len(things)
|
||||
things.extend(bytes(len(prcl)))
|
||||
|
||||
for entry in prcl.entries:
|
||||
dict_lookup = (entry.bytes, entry.compress)
|
||||
|
||||
try:
|
||||
if not entry.backref_allowed: raise ValueError
|
||||
final_bytes, bytes_offset, cksum = binaries_added[dict_lookup]
|
||||
|
||||
except:
|
||||
# Need to use this binary!
|
||||
final_bytes = entry.bytes
|
||||
if entry.compress:
|
||||
final_bytes = lzss.compress(final_bytes)
|
||||
|
||||
bytes_offset = len(things)
|
||||
cksum = crc32(final_bytes)
|
||||
|
||||
things.extend(final_bytes)
|
||||
|
||||
binaries_added[dict_lookup] = final_bytes, bytes_offset, cksum
|
||||
|
||||
# Pad to 4-byte boundary. Apple's build tool left pad bytes uninitialised!
|
||||
while len(things) % 4:
|
||||
things.append(0x99)
|
||||
|
||||
# Tell this structure where it can find its binary data.
|
||||
entry.uncompressed_len = len(entry.bytes)
|
||||
entry.save_cksum = cksum if entry.should_checksum else 0
|
||||
entry.save_offset = bytes_offset
|
||||
entry.save_len = len(final_bytes)
|
||||
|
||||
# Then tell it where it can find the next one, if any
|
||||
if prcl is self.prcls[-1]:
|
||||
prcl.save_nextoffset = 0
|
||||
else:
|
||||
prcl.save_nextoffset = len(things)
|
||||
|
||||
things[prcl_offset:prcl_offset+len(prcl)] = bytes(prcl)
|
||||
|
||||
# So now all structs and all data are placed. Phew.
|
||||
return bytes(things)
|
||||
|
||||
|
||||
class ParcelStruct:
|
||||
HEADER_FMT = '>I4s4I32s32s'
|
||||
|
||||
@classmethod
|
||||
def scan(cls, bytes, first_offset):
|
||||
offset = first_offset
|
||||
|
||||
while offset:
|
||||
parcel = cls(bytes=bytes, offset=offset)
|
||||
yield parcel
|
||||
offset = parcel.load_nextoffset
|
||||
|
||||
def __init__(self, bytes=None, offset=None):
|
||||
if bytes is not None:
|
||||
load_nextoffset, fourcc, my_len, flags, entry_count, entry_len, name, compat = struct.unpack_from(self.HEADER_FMT, bytes, offset)
|
||||
|
||||
# Checks
|
||||
# if entry_len != ParcelEntry.__len__():
|
||||
# raise ValueError('Parcel entry of %d bytes, expected %d' % (entry_len, ParcelEntry.__len__()))
|
||||
|
||||
# if my_len != header_size + entry_count*entry_len:
|
||||
# raise ValueError('Incorrect parcel header size field %d not %d' % (my_len, struct.calcsize(self.HEADER_FMT) + entry_count*entry_len))
|
||||
|
||||
# Semantics
|
||||
self.fourcc = fourcc
|
||||
self.name = name.rstrip(b'\0').decode('ascii')
|
||||
self.compat = compat.rstrip(b'\0').decode('ascii')
|
||||
self.flags = flags
|
||||
|
||||
len_of_entries = entry_count*entry_len
|
||||
entry_offsets = range(offset + my_len - len_of_entries, offset + my_len, entry_len)
|
||||
self.entries = [ParcelEntry(bytes[o : o+entry_len]) for o in entry_offsets]
|
||||
|
||||
# Ephemerides
|
||||
self.load_nextoffset = load_nextoffset
|
||||
|
||||
else:
|
||||
self.fourcc = b' '
|
||||
self.name = ''
|
||||
self.compat = ''
|
||||
self.flags = 0
|
||||
|
||||
self.entries = []
|
||||
|
||||
def __len__(self):
|
||||
return struct.calcsize(self.HEADER_FMT) + sum(len(e) for e in self.entries)
|
||||
|
||||
def __bytes__(self):
|
||||
save_nextoffset = self.save_nextoffset
|
||||
fourcc = self.fourcc
|
||||
my_len = len(self)
|
||||
flags = self.flags
|
||||
entry_count = len(self.entries)
|
||||
entry_len = ParcelEntry.__len__()
|
||||
name = self.name.encode('ascii')
|
||||
compat = self.compat.encode('ascii')
|
||||
|
||||
header = struct.pack(self.HEADER_FMT, save_nextoffset, fourcc, my_len, flags, entry_count, entry_len, name, compat)
|
||||
|
||||
entries = b''.join(bytes(e) for e in self.entries)
|
||||
|
||||
return header + entries
|
||||
|
||||
class ParcelEntry:
|
||||
FMT = '>4sI4s4I32s'
|
||||
|
||||
def __init__(self, bytes=None):
|
||||
if bytes is not None:
|
||||
(fourcc, flags, compress, uncompressed_len, load_cksum, load_len, load_offset, name) = struct.unpack(self.FMT, bytes)
|
||||
|
||||
self.fourcc = fourcc
|
||||
self.flags = flags
|
||||
self.compress = (compress == b'lzss')
|
||||
self.uncompressed_len = uncompressed_len
|
||||
self.name = name.rstrip(b'\0').decode('ascii')
|
||||
self.backref_allowed = False
|
||||
self.should_checksum = True
|
||||
|
||||
# Ephemeral stuff
|
||||
self.load_cksum = load_cksum
|
||||
self.load_len = load_len
|
||||
self.load_offset = load_offset
|
||||
|
||||
#else:
|
||||
# self.fourcc = b' '
|
||||
# self.flags = 0
|
||||
# self.compress = False
|
||||
# self.uncompressed_len = 0
|
||||
# self.name = ''
|
||||
|
||||
def __bytes__(self):
|
||||
fourcc = self.fourcc
|
||||
flags = self.flags
|
||||
compress = b'lzss' if self.compress else b'\0\0\0\0'
|
||||
uncompressed_len = self.uncompressed_len
|
||||
save_cksum = self.save_cksum
|
||||
save_len = self.save_len
|
||||
save_offset = self.save_offset
|
||||
name = self.name.encode('ascii')
|
||||
|
||||
return struct.pack(self.FMT, fourcc, flags, compress, uncompressed_len, save_cksum, save_len, save_offset, name)
|
||||
|
||||
@classmethod
|
||||
def __len__(cls):
|
||||
return struct.calcsize(cls.FMT)
|
Binary file not shown.
Loading…
Reference in New Issue