Initial commit

This commit is contained in:
Elliot Nunn 2018-02-18 02:25:11 +08:00
commit 313177ce2a
48 changed files with 1364 additions and 0 deletions

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
.DS_Store
parcels
tbxi
lzss
__pycache__
*.patch
*.hqx

19
Makefile Normal file
View File

@ -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" $@

20
README.md Normal file
View File

@ -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"

412
lzss.c Normal file
View File

@ -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

144
parcel-layout.txt Normal file
View File

@ -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

BIN
pef/ndrv/BacklightDriver Normal file

Binary file not shown.

Binary file not shown.

BIN
pef/ndrv/PowerMgrPlugin/pmu Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
pef/ndrv/ata/cmd646 Normal file

Binary file not shown.

BIN
pef/ndrv/ata/heathrow Normal file

Binary file not shown.

BIN
pef/ndrv/ata/kauai Normal file

Binary file not shown.

BIN
pef/ndrv/ata/keylargo Normal file

Binary file not shown.

BIN
pef/ndrv/cardbus Normal file

Binary file not shown.

BIN
pef/ndrv/display Normal file

Binary file not shown.

BIN
pef/ndrv/firewire Normal file

Binary file not shown.

BIN
pef/ndrv/i2c Normal file

Binary file not shown.

BIN
pef/ndrv/nvram/flash Normal file

Binary file not shown.

BIN
pef/ndrv/nvram/mac-io Normal file

Binary file not shown.

BIN
pef/ndrv/nvram/via-pmu Normal file

Binary file not shown.

BIN
pef/ndrv/rtc/via-cuda Normal file

Binary file not shown.

BIN
pef/ndrv/rtc/via-pmu Normal file

Binary file not shown.

BIN
pef/nlib/AGPLib Normal file

Binary file not shown.

BIN
pef/nlib/DFMLib Normal file

Binary file not shown.

BIN
pef/nlib/DevNLib Normal file

Binary file not shown.

BIN
pef/nlib/EtherPrintfLib Normal file

Binary file not shown.

BIN
pef/nlib/FWServicesLib Normal file

Binary file not shown.

Binary file not shown.

BIN
pef/nlib/NVRAMServicesLib Normal file

Binary file not shown.

BIN
pef/nlib/NativePowerMgrLib Normal file

Binary file not shown.

BIN
pef/nlib/PCCardLib Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
pef/nlib/PMULib Normal file

Binary file not shown.

BIN
pef/nlib/RTCServicesLib Normal file

Binary file not shown.

BIN
pef/nlib/TimeManagerLib Normal file

Binary file not shown.

BIN
pef/shlb/StartLib Normal file

Binary file not shown.

BIN
pef/shlb/lanLib/apple21143 Normal file

Binary file not shown.

BIN
pef/shlb/lanLib/bmac+ Normal file

Binary file not shown.

BIN
pef/shlb/lanLib/gmac Normal file

Binary file not shown.

BIN
rom Normal file

Binary file not shown.

61
scripts/binhexmake.py Executable file
View File

@ -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()

415
scripts/bootmake.py Executable file
View File

@ -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)

14
scripts/lzss.py Normal file
View File

@ -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)

83
scripts/prclmake.py Executable file
View File

@ -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))

189
scripts/prcltool.py Normal file
View File

@ -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)

BIN
trampoline.elf Normal file

Binary file not shown.