Please login or register.

Login with username, password and session length
Advanced search  

News:

Pages: 1 2 3 4 [5] 6 7 8 9 10
 41 
 on: December 05, 2025, 02:38:22 AM 
Started by nanopico - Last post by Jubadub
Hi everyone,

I have added a new component to the Mac OS ROM: the "Wedge". The Wedge is a chunk of C code inserted into the ROM that runs between the Trampoline and the NanoKernel. It takes the structures prepared by the Trampoline, carefully patches them, spits out some textual debug output, and then hands control to the NanoKernel. The debug output remains hidden in memory while the machine boots up. Once (and if) the machine is booted, it can be read by a small app, WedgeLogReader.

At present the only task of the Wedge is to expand the main segment of Mac OS memory. This allows an extra 128MB of RAM to be used, on top of the 1.5GB limit.

Why go to the trouble of bootstrapping a C runtime? Two reasons:

  • Ease. Patching the PageMap is too complex to accomplish reliably in RISC assembly (see the crash reports above).
  • Portability. The code can be tested on your machine in userspace before risking a crash on boot.

And what cool stuff is in the attached archive?

  • PowerMacInfo, in case you didn't already have a copy. This will crash on a Wedge ROM, because it hardcodes the InfoRecord Page address.
  • WedgeDryRun, a text app to test the Wedge code on your machine. If this crashes, let me know.
  • Mac OS ROM, with all the trimmings. Besides bumping the RAM limit slightly, this should work on all unsupported G4 desktops (including the 9serve, MacOS Plus!). The annoying NanoKernel log window is off by default. If you find it stable and you want the extra RAM, then this is ready for production use!
  • WedgeLogReader, a text app to dump the Wedge log left over from boot. Naturally, it only shows useful information if you booted with the Wedge.
  • NKLogReader, again in case you didn't have a copy.

Those testers who had trouble with the previous patched ROMs, would you please try this out? The best information to post would be: WedgeDryRun output, WedgeLogReader output, NKLogReader output, and before/after screenshots of About This Computer. Please post text inline! That way I can read it on my phone, and it gets indexed by Google.

For the morbidly curious, here is the Wedge C code. The same code runs in both the attached ROM and the WedgeLogReader. I don't suppose that one of the admins feels like changing the tab size to 4?

Code: [Select]
#include <PPCInfoRecordsPriv.h>
#include <MacTypes.h>


#define kFlagNone 0
#define kFlagIRP 1
#define kFlagKDP 2
#define kFlagEDP 3


#define LA_InfoRecord_Orig 0x5fffe000UL
#define LA_UniversalArea_Orig 0x64000000UL
#define LA_RiscRom_Orig 0x68000000UL
#define LA_ConfigInfo_Orig 0x68fef000UL
#define LA_KernelData_Orig 0x68ffe000UL
#define LA_KernelData_Orig 0x68fff000UL


#define kConfigInfoSize 4096
#define kHardwareInfoSize 192


#define kPatchInfoRecord 0x00000001UL
#define kPatchUniversalArea 0x00000010UL
#define kCanPatchEmulator 0x80000000UL


#define kDelta 0x80000000UL


void *memcpy(void *dest, void *src, long n)
{
long i;

char *d = (char *)dest;
char *s = (char *)src;

if(dest < src) /* copy left to right */
{
for(i=0; i<n; i++) d[i] = s[i];
}
else /* copy right to left */
{
for(i=n-1; i>=0; i--) d[i] = s[i];
}

return dest;
}


void *memset(void *dest, int v, long n)
{
char *d = (char *)dest;

while(n) d[--n] = (char)v;

return dest;
}


struct PME
{
unsigned long word1; /* LogicalPageIndexInSegment(16b) || PageCountMinus1(16b) */
unsigned long word2; /* PhysicalPage(20b) || pageAttr(12b) */
};
typedef struct PME PME;


PME *getPageMapPtr(NKConfigurationInfo *ConfigInfo)
{
return (PME *)((long)ConfigInfo + (long)ConfigInfo->PageMapInitOffset);
}


int pmeIsBlank(PME *pme)
{
if(pme->word1 != 0x0000ffffUL) return 0;
if((pme->word2 & 0x00000f00UL) != 0x00000a00UL) return 0;
return 1;
}


int segmentOf(unsigned long LA)
{
return LA >> 28;
}


/*
Create a PageMapEntry (specifying a logical-to-physical mapping within a PowerPC segment)
and insert it into a ConfigInfo struct, taking care not to corrupt the structure.

(Intended to replicate the behaviour of the Trampoline, based on its debug output)
*/

int AddPageMapEntry(NKConfigurationInfo *ci, unsigned long LA, unsigned long count, unsigned long PA, unsigned long pageAttr, unsigned long flags)
{
PME *pageMapBase = getPageMapPtr(ci);

PME newEnt;
int entryOffset; /* offset of our new entry within the PageMap (bytes) */

int i;


/* Format string lifted from Trampoline (changed a tiny bit). */

printf("AddPageMapEntry: LA = 0x%08X, count = 0x%05X, PA = 0x%08X, pageAttr = 0x%04X, flags = 0x%02X.\n", LA, count, PA, pageAttr, flags);


/* "Design" the new entry. */

newEnt.word1 = ((LA << 4) & 0xffff0000UL) | (count - 1);
newEnt.word2 = (PA & 0xfffff000UL) | pageAttr;


/* Choose an offset for the entry. */

entryOffset = ci->SegMap32SupInit[segmentOf(LA) * 2];

for(;;)
{
PME *existing;

existing = (PME *)((long)pageMapBase + (long)entryOffset);

if(pmeIsBlank(existing)) break;
if((existing->word1 & 0xffff0000UL) > (newEnt.word1 & 0xffff0000UL)) break;

entryOffset += sizeof(PME);
}


/* Shift the entries above our new entry by 8 bytes. */

for(i=0; i<8; i++)
{
if(*((char *)pageMapBase + ci->PageMapInitSize + i) != 0)
{
printf("PageMap overflow!\n", entryOffset/sizeof(PME));
return 100;
}
}

for(i = ci->PageMapInitSize - 1; i >= entryOffset; i--)
{
*((char *)pageMapBase + i + 8) = *((char *)pageMapBase + i);
}


/* Bump the declared PageMap size by 8 bytes. (ignored by kernel?) */

ci->PageMapInitSize += sizeof(PME);


/* The SegMap (four copies) contains an offset into the PageMap at every second word -- update these. */

for(i=segmentOf(LA)+1; i<16; i++)
{
ci->SegMap32SupInit[i * 2] += sizeof(PME);
ci->SegMap32UsrInit[i * 2] += sizeof(PME);
ci->SegMap32CPUInit[i * 2] += sizeof(PME);
ci->SegMap32OvlInit[i * 2] += sizeof(PME);
}


/* Adjust the pointers to the special PageMap entries. */

if(ci->PageMapIRPOffset >= entryOffset) ci->PageMapIRPOffset += sizeof(PME);
if(ci->PageMapKDPOffset >= entryOffset) ci->PageMapKDPOffset += sizeof(PME);
if(ci->PageMapEDPOffset >= entryOffset) ci->PageMapEDPOffset += sizeof(PME);


/* Set the correct pointer if it is a special one */

if(flags == kFlagIRP)
ci->PageMapIRPOffset = entryOffset;
else if(flags == kFlagKDP)
ci->PageMapKDPOffset = entryOffset;
else if(flags == kFlagEDP)
ci->PageMapEDPOffset = entryOffset;


/* Save our new entry in the gap we have made in the PageMap. */

memcpy((char *)pageMapBase + entryOffset, &newEnt, sizeof(PME));

return 0;
}


/*
Create a blank PageMap inside a pre-existing ConfigInfo structure, with only
those "dummy" entries that the Trampoline would create before calling
AddPageMapEntry.

(Intended to replicate the behaviour of the Trampoline, based on its debug output)
*/

void ErasePageMapTable(NKConfigurationInfo *ci)
{
PME *pageMapBase;
long *pmp;
int seg;


printf("ErasePageMapTable at offset 0x%x\n\n", ci->PageMapInitOffset);

/* Zero out the existing PageMap */

pageMapBase = getPageMapPtr(ci);
memset(pageMapBase, 0, ci->PageMapInitSize);


/* Count up with pmp */

pmp = (long *)pageMapBase;

ci->PageMapInitOffset = (long)pageMapBase - (long)ci;

for(seg=0; seg<16; seg++)
{
ci->SegMap32SupInit[seg * 2] =
ci->SegMap32UsrInit[seg * 2] =
ci->SegMap32CPUInit[seg * 2] =
ci->SegMap32OvlInit[seg * 2] = (long)pmp - (long)pageMapBase;

if(seg <= 5)
{
*pmp++ = 0x0000ffffUL; *pmp++ = 0x00000a00UL;
*pmp++ = 0x0000ffffUL; *pmp++ = 0x00000a00UL;
}
else if(seg >= 6 && seg <= 7)
{
*pmp++ = 0x0000ffffUL; *pmp++ = 0x00000a01UL;
*pmp++ = 0x0000ffffUL; *pmp++ = 0x00000a01UL;
*pmp++ = 0x0000ffffUL; *pmp++ = 0x00000a00UL;
}
else if(seg >= 8)
{
*pmp++ = 0x0000ffffUL; *pmp++ = 0x00000a01UL + (seg << 28);
*pmp++ = 0x0000ffffUL; *pmp++ = 0x00000a00UL;
}
}

ci->PageMapInitSize = (long)pmp - (long)pageMapBase;


/* Zero out the special pointers */

ci->PageMapIRPOffset = 0;
ci->PageMapKDPOffset = 0;
ci->PageMapEDPOffset = 0;
}


int PatchMacOSAddressSpace(long patches, unsigned long makeMemAvail, NKConfigurationInfo *ci, NKConfigurationInfo *newci, NKHWInfo *hi, NKHWInfo *newhi)
{
int seg;
PME *pageMapBase;
PME *entryp;

unsigned long LA, newLA, count, PA, pageAttr, flags;

int ret;
int offset;

unsigned long i;


pageMapBase = getPageMapPtr(ci);

ErasePageMapTable(newci);

printf("PatchMacOSAddressSpace: makeMemAvail %08x\n", makeMemAvail);

for(seg=0; seg<16; seg++)
{
for(offset = ci->SegMap32SupInit[seg*2];; offset += sizeof (PME)) /* Iterate over PMEs. */
{
entryp = (PME *)((long)pageMapBase + offset);


/* Misc error conditions */

if(seg < 15 && offset >= ci->SegMap32SupInit[(seg+1) * 2])
{
printf("Overran this segment of the PageMap!\n\n");
return 101;
}
if(offset >= ci->PageMapInitSize)
{
printf("Overran the whole PageMap!\n\n");
return 102;
}

if(pmeIsBlank(entryp)) break;


/* Extract info from PME */

LA = newLA = (seg << 28) | (entryp->word1 >> 4 & 0x0ffff000UL);
count = (entryp->word1 & 0x0000ffffUL) + 1;
PA = entryp->word2 & 0xfffff000UL;
pageAttr = entryp->word2 & 0x00000fffUL;

if(offset == ci->PageMapIRPOffset)
flags = kFlagIRP;
else if(offset == ci->PageMapKDPOffset)
flags = kFlagKDP;
else if(offset == ci->PageMapEDPOffset)
flags = kFlagEDP;
else
flags = kFlagNone;

printf("    nontrivial PME   LA = 0x%08X, count = 0x%05X, PA = 0x%08X, pageAttr = 0x%04X, flags = 0x%02X.\n    ", LA, count, PA, pageAttr, flags);


/* Delete those two annoying PMEs that signal to end the MacOS area */
/* (LA 50000000 count fffe PA 00000000 pageAttr a00) */

if((LA << 4) == 0 && (pageAttr & 0xf00) == 0xa00)
{
printf("MacOS area delimiter: skipping\n\n");
continue;
}


/* Move the InfoRecord page. */

if((patches & kPatchInfoRecord) && LA == LA_InfoRecord_Orig)
{
printf("**IRP**\n    ");

newLA += kDelta;

/* IRP logical address in ConfigInfo */
newci->LA_InfoRecord = newLA;

/* IRP logical address is hardcoded into emulator by lis/ori, so change that. */
if(patches & kCanPatchEmulator)
{
unsigned short hi = LA >> 16;
unsigned short lo = LA & 0xffff;
unsigned short *em = (unsigned short *)0x00f60000UL;

for(i=0; i<0x10000; i+=2)
{
if(em[i+1] == hi && em[i+3] == lo)
{
printf("Patching Emulator lis/ori @ %05x\n    ", i*2);
em[i+1] = newLA >> 16;
em[i+3] = newLA & 0xffff;
break;
}
}
}
}


/* Move the area containing the Universal structures and the Device Tree */

if((patches & kPatchUniversalArea) && LA == LA_UniversalArea_Orig)
{
printf("**Universal/DeviceTree area**\n    ");

newLA += kDelta;

/* Logical address pointers in HardwareInfo */
newhi->DeviceTreeBase = hi->DeviceTreeBase - LA + newLA;
newhi->UniversalInfoTableBase = hi->UniversalInfoTableBase - LA + newLA;
}


if(newLA < makeMemAvail)
{
printf("makeMemAvail is too large with this PME in the way.\n\n");
return 103;
}


/* If this PME was unchanged then newLA will just equal the original LA. */

ret = AddPageMapEntry(newci, newLA, count, PA, pageAttr, flags);
if(ret) return ret;

printf("\n");
}
}


/* Done all meaningful PMEs... put the "MacOS area delimiter" back in */

printf("    Reinserting the MacOS area delimiters:\n");
for(i=0; i<2; i++)
{
printf("    ");
ret = AddPageMapEntry(newci, makeMemAvail & 0xf0000000UL, makeMemAvail >> 12 & 0xffffUL, 0UL, 0xa00, 0);
if(ret) return ret;
}

printf("\n");

return 0;
}


void DebugDumpPageMap(NKConfigurationInfo *ci)
{
PME *pageMapBase, *pme;
int i, j;

pageMapBase = getPageMapPtr(ci);

printf("DebugDumpPageMap\n");

for(i=0; i<ci->PageMapInitSize; i+=sizeof(PME))
{
for(j=0; j<16; j++)
{
if(ci->SegMap32SupInit[j*2] == i)
{
printf("%X ", j);
break;
}
}
if(j == 16) printf("  ");

pme = (PME *)((long)pageMapBase + i);

printf("%03x: %08x %08x", i, pme->word1, pme->word2);

if(i == ci->PageMapIRPOffset)
{
printf(" IRP");
}
else if(i == ci->PageMapEDPOffset)
{
printf(" EDP");
}
else if(i == ci->PageMapKDPOffset)
{
printf(" KDP");
}

printf("\n");
}
printf("\n");
}


/* Main function for Wedge patch */

void wedge(NKConfigurationInfo *ci, NKProcessorInfo *pi, NKSystemInfo *si, NKDiagnosticInfo *di, OSType rtasFour, unsigned long rtasProc, NKHWInfo *hi)
{
char ci_tmp[kConfigInfoSize], hi_tmp[kHardwareInfoSize];
int ret;

printf("Hello from the Wedge.\n");
printf("      ConfigInfo (r3) @ %08x\n", ci);
printf("   ProcessorInfo (r4) @ %08x\n", pi);
printf("      SystemInfo (r5) @ %08x\n", si);
printf("  DiagnosticInfo (r6) @ %08x\n", di);
printf("            RTAS (r7) = %08x\n", rtasFour);
printf("        RTASProc (r8) @ %08x\n", rtasProc);
printf("    HardwareInfo (r9) @ %08x\n", hi);
printf("\n");


/* PatchMacOSAddressSpace */

DebugDumpPageMap((NKConfigurationInfo *)ci);

printf("Rearranging the MacOS address space...\n\n");
memcpy(ci_tmp, ci, sizeof ci_tmp);
memcpy(hi_tmp, hi, sizeof hi_tmp);

ret = PatchMacOSAddressSpace(kPatchInfoRecord | kPatchUniversalArea | kCanPatchEmulator,
                             0x68000000UL,
                             (NKConfigurationInfo *)ci, (NKConfigurationInfo *)ci_tmp,
                             (NKHWInfo *)hi, (NKHWInfo *)hi_tmp);

if(!ret)
{
printf("Copying modified ConfigInfo and HWInfo over the originals.\n\n");
memcpy(ci, ci_tmp, sizeof ci_tmp);
memcpy(hi, hi_tmp, sizeof hi_tmp);

DebugDumpPageMap((NKConfigurationInfo *)ci);
}
else
{
printf("PatchMacOSAddressSpace failed with error %d.\n", ret);
}


/* Insert more clever, interesting patches here. */


/* Uses r3-r9 -- compiler doesn't really need a prototype for this. */
printf("\nHanding over to the NanoKernel.\n");
NanoKernelJump(ci, pi, si, di, rtasFour, rtasProc, hi);
}


/* Main function for MPW Tool */

void main(void)
{
char ci_tmp[kConfigInfoSize], hi_tmp[kHardwareInfoSize];
char *ci, *hi;
long nk_struct_ver, nk_struct_len;
int ret;

printf("Hello from the (dry-run) Wedge.\n");

ci = (char *)0x68fef000UL;
printf("      ConfigInfo @ %08x\n", ci);

NKLocateInfoRecord(6, &hi, &nk_struct_ver, &nk_struct_len);
printf("    HardwareInfo @ %08x\n", hi);

printf("\n");


DebugDumpPageMap((NKConfigurationInfo *)ci);

printf("Copying the system ConfigInfo and HardwareInfo structs.\n\n");
memcpy(ci_tmp, ci, sizeof ci_tmp);
memcpy(hi_tmp, hi, sizeof hi_tmp);

ret = PatchMacOSAddressSpace(kPatchInfoRecord | kPatchUniversalArea,
                             0x68000000UL,
                             (NKConfigurationInfo *)ci, (NKConfigurationInfo *)ci_tmp,
                             (NKHWInfo *)hi, (NKHWInfo *)hi_tmp);

if(!ret)
{
printf("PatchMacOSAddressSpace succeeded (but was forbidden from patching the Emulator).\n\n");

DebugDumpPageMap((NKConfigurationInfo *)ci_tmp);
}
else
{
printf("PatchMacOSAddressSpace failed with error %d.\n", ret);
}
}

And here is some sample output.

Code: [Select]
Hello from the Wedge.
      ConfigInfo (r3) @ 00003000
   ProcessorInfo (r4) @ 0fffff40
      SystemInfo (r5) @ 0ffffe00
  DiagnosticInfo (r6) @ 00000000
            RTAS (r7) = 52544153
        RTASProc (r8) @ 00000000
    HardwareInfo (r9) @ 0ffffd40

DebugDumpPageMap
0 000: 0000ffff 00000a00
  008: 0000ffff 00000a00
1 010: 0000ffff 00000a00
  018: 0000ffff 00000a00
2 020: 0000ffff 00000a00
  028: 0000ffff 00000a00
3 030: 0000ffff 00000a00
  038: 0000ffff 00000a00
4 040: 0000ffff 00000a00
  048: 0000ffff 00000a00
5 050: 0000fffd 00000a00
  058: 0000fffd 00000a00
  060: fffe0000 00000012 IRP
  068: 0000ffff 00000a00
  070: 0000ffff 00000a00
6 078: 4000017f 0ab00012
  080: 8fef0000 00003013
  088: 8ffe0000 00000011 KDP
  090: 8fff0000 00000012 EDP
  098: 0000ffff 00000a01
  0a0: 0000ffff 00000a01
  0a8: 0000ffff 00000a00
7 0b0: 0000ffff 00000a01
  0b8: 0000ffff 00000a01
  0c0: 0000ffff 00000a00
8 0c8: 0000ffff 8000003a
  0d0: 0000ffff 80000a01
  0d8: 0000ffff 00000a00
9 0e0: 0000000f 9000003a
  0e8: 0020001f 9002003a
  0f0: 80007fff 98000032
  0f8: 0000ffff 90000a01
  100: 0000ffff 00000a00
A 108: 0000ffff a0000a01
  110: 0000ffff 00000a00
B 118: 0000ffff b0000a01
  120: 0000ffff 00000a00
C 128: 0000ffff c0000a01
  130: 0000ffff 00000a00
D 138: 0000ffff d0000a01
  140: 0000ffff 00000a00
E 148: 0000ffff e0000a01
  150: 0000ffff 00000a00
F 158: 0000ffff f000003a
  160: 0000ffff f0000a01
  168: 0000ffff 00000a00

Rearranging the MacOS address space...

ErasePageMapTable at offset 0x3ac

PatchMacOSAddressSpace: makeMemAvail 68000000
    nontrivial PME   LA = 0x50000000, count = 0x0FFFE, PA = 0x00000000, pageAttr = 0x0A00, flags = 0x00.
    MacOS area delimiter: skipping

    nontrivial PME   LA = 0x50000000, count = 0x0FFFE, PA = 0x00000000, pageAttr = 0x0A00, flags = 0x00.
    MacOS area delimiter: skipping

    nontrivial PME   LA = 0x5FFFE000, count = 0x00001, PA = 0x00000000, pageAttr = 0x0012, flags = 0x01.
    **IRP**
    Patching Emulator lis/ori @ 181e8
    AddPageMapEntry: LA = 0xDFFFE000, count = 0x00001, PA = 0x00000000, pageAttr = 0x0012, flags = 0x01.

    nontrivial PME   LA = 0x64000000, count = 0x00180, PA = 0x0AB00000, pageAttr = 0x0012, flags = 0x00.
    **Universal/DeviceTree area**
    AddPageMapEntry: LA = 0xE4000000, count = 0x00180, PA = 0x0AB00000, pageAttr = 0x0012, flags = 0x00.

    nontrivial PME   LA = 0x68FEF000, count = 0x00001, PA = 0x00003000, pageAttr = 0x0013, flags = 0x00.
    AddPageMapEntry: LA = 0x68FEF000, count = 0x00001, PA = 0x00003000, pageAttr = 0x0013, flags = 0x00.

    nontrivial PME   LA = 0x68FFE000, count = 0x00001, PA = 0x00000000, pageAttr = 0x0011, flags = 0x02.
    AddPageMapEntry: LA = 0x68FFE000, count = 0x00001, PA = 0x00000000, pageAttr = 0x0011, flags = 0x02.

    nontrivial PME   LA = 0x68FFF000, count = 0x00001, PA = 0x00000000, pageAttr = 0x0012, flags = 0x03.
    AddPageMapEntry: LA = 0x68FFF000, count = 0x00001, PA = 0x00000000, pageAttr = 0x0012, flags = 0x03.

    nontrivial PME   LA = 0x80000000, count = 0x10000, PA = 0x80000000, pageAttr = 0x003A, flags = 0x00.
    AddPageMapEntry: LA = 0x80000000, count = 0x10000, PA = 0x80000000, pageAttr = 0x003A, flags = 0x00.

    nontrivial PME   LA = 0x90000000, count = 0x00010, PA = 0x90000000, pageAttr = 0x003A, flags = 0x00.
    AddPageMapEntry: LA = 0x90000000, count = 0x00010, PA = 0x90000000, pageAttr = 0x003A, flags = 0x00.

    nontrivial PME   LA = 0x90020000, count = 0x00020, PA = 0x90020000, pageAttr = 0x003A, flags = 0x00.
    AddPageMapEntry: LA = 0x90020000, count = 0x00020, PA = 0x90020000, pageAttr = 0x003A, flags = 0x00.

    nontrivial PME   LA = 0x98000000, count = 0x08000, PA = 0x98000000, pageAttr = 0x0032, flags = 0x00.
    AddPageMapEntry: LA = 0x98000000, count = 0x08000, PA = 0x98000000, pageAttr = 0x0032, flags = 0x00.

    nontrivial PME   LA = 0xF0000000, count = 0x10000, PA = 0xF0000000, pageAttr = 0x003A, flags = 0x00.
    AddPageMapEntry: LA = 0xF0000000, count = 0x10000, PA = 0xF0000000, pageAttr = 0x003A, flags = 0x00.

    Reinserting the MacOS area delimiters:
    AddPageMapEntry: LA = 0x60000000, count = 0x08000, PA = 0x00000000, pageAttr = 0x0A00, flags = 0x00.
    AddPageMapEntry: LA = 0x60000000, count = 0x08000, PA = 0x00000000, pageAttr = 0x0A00, flags = 0x00.

Copying modified ConfigInfo and HWInfo over the originals.

DebugDumpPageMap
0 000: 0000ffff 00000a00
  008: 0000ffff 00000a00
1 010: 0000ffff 00000a00
  018: 0000ffff 00000a00
2 020: 0000ffff 00000a00
  028: 0000ffff 00000a00
3 030: 0000ffff 00000a00
  038: 0000ffff 00000a00
4 040: 0000ffff 00000a00
  048: 0000ffff 00000a00
5 050: 0000ffff 00000a00
  058: 0000ffff 00000a00
6 060: 00007fff 00000a00
  068: 00007fff 00000a00
  070: 8fef0000 00003013
  078: 8ffe0000 00000011 KDP
  080: 8fff0000 00000012 EDP
  088: 0000ffff 00000a01
  090: 0000ffff 00000a01
  098: 0000ffff 00000a00
7 0a0: 0000ffff 00000a01
  0a8: 0000ffff 00000a01
  0b0: 0000ffff 00000a00
8 0b8: 0000ffff 8000003a
  0c0: 0000ffff 80000a01
  0c8: 0000ffff 00000a00
9 0d0: 0000000f 9000003a
  0d8: 0020001f 9002003a
  0e0: 80007fff 98000032
  0e8: 0000ffff 90000a01
  0f0: 0000ffff 00000a00
A 0f8: 0000ffff a0000a01
  100: 0000ffff 00000a00
B 108: 0000ffff b0000a01
  110: 0000ffff 00000a00
C 118: 0000ffff c0000a01
  120: 0000ffff 00000a00
D 128: fffe0000 00000012 IRP
  130: 0000ffff d0000a01
  138: 0000ffff 00000a00
E 140: 4000017f 0ab00012
  148: 0000ffff e0000a01
  150: 0000ffff 00000a00
F 158: 0000ffff f000003a
  160: 0000ffff f0000a01
  168: 0000ffff 00000a00


Handing over to the NanoKernel.

@ELN Are there Python scripts for creating the "Third limit-breaking ROM", or is any other such tooling available?

For example, using your tbxi and tbxi-patches projects like we do for the Mac mini G4 ROM patches, or other similar tooling.

If so, we could apply the 1.628 GB RAM limit patches to Rairii's 10.2.1 CPU Software 5.9 version of the ROM, and get even System 7 to move up from 1.5 GB max RAM to 1.628 GB!

Both the third-limit breaking ROM and Rairii's ROM are based on the same US Mac OS ROM 10.2.1 with CPU Software 5.9, so most likely it will work!

(Nevermind figuring out what to do with so much RAM on System 7. That can wait!)

 42 
 on: December 04, 2025, 10:42:54 PM 
Started by jjuran - Last post by jjuran
Welcome to Mac OS 9 Lives!, @jjuran! -afro- It's great to have you join the fray! Mac OS 9 army grows!

For anyone else wondering about the really cool things @jjuran already brought to Mac OS 9, check out this interesting Garden thread.

Thanks! 

Sorry for any confusion around the Legacynth alpha download.  I've since given up on the MacBinary+ format for general distribution and wrote a SEA shell which is now used for the Legacynth installer:

Legacynth
https://www.macrelics.com/legacynth/

The current version supports Lode Runner's sound effects...

 43 
 on: December 04, 2025, 10:17:57 PM 
Started by jjuran - Last post by Jubadub
Welcome to Mac OS 9 Lives!, @jjuran! -afro- It's great to have you join the fray! Mac OS 9 army grows!

For anyone else wondering about the really cool things @jjuran already brought to Mac OS 9, check out this interesting Garden thread.

 44 
 on: December 04, 2025, 10:14:23 PM 
Started by cluster_fsck - Last post by Jubadub
Guy was not pleased using older CodeWarrior versions in the '90s alongside CVS, apparently:
https://www.metamage.com/text/relix/origins.html

I think he speaks older Code Warriors, because speaks C and Pascal. And last Core Warrior with Pascal was pro 4.
btw. last Code Warrior for Mac, CodeWarrior Development Studio 10 (pro 10) has Metrowerks Standard Library 11.0 and
it has good Posix standard support for Mac OS 9.2.2. Bad points with that Code Warrior is that you have to run it on OSX
and it cannot compile to 68k, what he wanted too.

I think there is so many ways to program Mac OS 9 that every body have to find his/her own way.

I use Metrowerks C++ 2.4.1 from CodeWarrior Pro 6.3, by way of MPW's ToolServer, driven by Apple event from MacRelix.  Some of my code also builds with CW Pro 4 (the last version hosted on 68K).  I've written my own post-linkers (which run in MacRelix) to remove the dependency on StripAddress() in Metrowerks' runtime code.

The last time I spoke Pascal was 2002, and that time I was getting paid for it. :-)

Git 2.2.2 indeed ships with MacRelix.  I wouldn't recommend using it with massive repositories like metamage_1.git (except natively in Mac OS X), but it should be fine with small repos.  It still needs integration with a pager and an editor, though.  (I mainly use it as a read-only client for Jaguar.)

Hey, great to have you here as well, @jjuran! Thanks for porting Git to Mac OS 9 one way or another. :)

Just an idea, but do you think you could record a short video capture of this whole process? I would love to see it in action! I think it'd also encourage people to use Git and your other ideas on Mac OS more, that's an excellent workflow.

 45 
 on: December 04, 2025, 07:04:36 PM 
Started by cluster_fsck - Last post by jjuran
I'm starting to develop some new projects and attempting to do all the coding on my old 7100/80.

Obviously, git is out of the question but I had been hoping for a Subversion client but can't seem to locate one -- does anyone know of one? If I have to use old-school CVS, I'll do that, but hate it. Any ideas? Thanks!

In case you missed it, Git *is* an option, in MacRelix:

https://www.macrelix.org/

 46 
 on: December 04, 2025, 07:00:23 PM 
Started by cluster_fsck - Last post by jjuran
Guy was not pleased using older CodeWarrior versions in the '90s alongside CVS, apparently:
https://www.metamage.com/text/relix/origins.html

I think he speaks older Code Warriors, because speaks C and Pascal. And last Core Warrior with Pascal was pro 4.
btw. last Code Warrior for Mac, CodeWarrior Development Studio 10 (pro 10) has Metrowerks Standard Library 11.0 and
it has good Posix standard support for Mac OS 9.2.2. Bad points with that Code Warrior is that you have to run it on OSX
and it cannot compile to 68k, what he wanted too.

I think there is so many ways to program Mac OS 9 that every body have to find his/her own way.

I use Metrowerks C++ 2.4.1 from CodeWarrior Pro 6.3, by way of MPW's ToolServer, driven by Apple event from MacRelix.  Some of my code also builds with CW Pro 4 (the last version hosted on 68K).  I've written my own post-linkers (which run in MacRelix) to remove the dependency on StripAddress() in Metrowerks' runtime code.

The last time I spoke Pascal was 2002, and that time I was getting paid for it. :-)

Git 2.2.2 indeed ships with MacRelix.  I wouldn't recommend using it with massive repositories like metamage_1.git (except natively in Mac OS X), but it should be fine with small repos.  It still needs integration with a pager and an editor, though.  (I mainly use it as a read-only client for Jaguar.)

 47 
 on: December 04, 2025, 05:56:43 PM 
Started by jjuran - Last post by jjuran
Hi,

I'm the developer of Advanced Mac Substitute, MacRelix, and most recently Legacynth.  I target pretty much all versions of Mac OS (as well as POSIX generally), and I write tools to make this more practical.  I primarily write in C++, Perl, and Varyx, though I just started learning Objective-C.  I use Git.

I tend to work mostly on 201x-era Macs, using SheepShaver with Mac OS 8.1 or 9 to run Metrowerks C++ through MPW's ToolServer for building classic programs.

This year I started replaying TaskMaker. :-)

 48 
 on: December 04, 2025, 11:51:11 AM 
Started by Jubadub - Last post by Jubadub
OK, this came out sooner than expected... Or should I say, this was never truly expected.

I'm posting this on all 3 Mac communities I put the original post in, because it's that much of a big deal.

Many of us know System 7.1.2 was the first ever version of Mac OS to support PowerPC-based Macintoshes...

... Yet we couldn't go below System 7.5. Until a day ago:



Rairii just released not only an update to his System Enabler for System 7.5 ~ Mac OS 7.6.1, but also a separate patching effort of the same System Enabler to get System 7.1.x booting.

So this achievement alone is BEYOND newsworthy...

... But it doesn't stop there. No.

You'd think a PURE 68k OS wouldn't boot in PowerPC in bare-metal:



System 7.1.1...



... And System 7.1.

"To boldly go where no PowerMac has ever gone before."

This is precisely what we theorized earlier, and the thoughts we entertained: with Apple's 68k emulator residing in the Mac OS ROM file, we now have the LATEST version of said 68k-to-PPC CPU instruction converter, making ALL OF 68k run as if it was no different than a Java runtime, with "68k bytecode", if you will. :) A whole OS done that way.

And guess what? System 7.1 is so light, so fast, I cannot even SEE the "Welcome to Power Macintosh" screen or any of the Extensions loading, because they all just load INSTANTLY. If you blink for even a moment, you WILL miss all of it.

It got to the point that the OS is so light, what takes the "longest" to load is the Mac OS ROM itself! You know that finished loading after you are past the Happy Mac part.

Anyway... There some points about these achievements I'd like to clarify:

- The OSes seem to pair with the Finder as follows: System 7.1 Finder 7.1, System 7.1.1 Finder 7.1.3, System 7.1.2 (and 7.1.2P) Finder 7.1.4. Note that System 7.5 is also paired with Finder 7.1.4;

- Systems 7.1.1 ~ 7.1.2P aren't able to run their Finders (crash+reopen Finder eternal loop), but if we swap them in with Finder 7.1, it all works, which is how I took those screenshots (Rairii figured this out first, as well);

- Systems 7.1.1 comes with its various own "System Enablers". You must delete them first so they don't intervene with Rairii's Enabler, as it's all System 7.1.1 needs. If you don't, you will see this instead. If you do, and please correct me if I'm mistaken, it seems like Rairii's Enabler gets its Resource Fork updated to also error out like this even after you got rid of the other, pesky enablers (I did an MD5 check for both forks to confirm). So if that happens, unpack Rairii's Enabler anew and discard the old one;

- System 7.1.2 (7.1.2P untested) is just like 7.1.1 in that it comes with its own Enabler that you need to get rid of first, in order not to face the same issue. In this case, it's called the "PowerPC Enabler";

- I could boot all these OSes with all Extensions on. I did get this and this as warning messages, though, after boot, at least with System 7.1.2;

- Funnily enough, System 7.5 has the same Finder 7.1.4 as System 7.1.2(P), but there are no issues with it there. Likewise, System 7.1.2(P) is fine with a different Finder. The problem only materializes when both are present simultaneously, but not individually. Incidentally, Finder 7.1.3 on System 7.1.2(P) will also have the same issue, as will the Finder that came with System 7.5, hence why we settle for Finder 7.1 (there are no Finder version 7.1.1 and 7.1.2 that I could find).

I think that's about it. So to highlight one of the interesting features of e.g. System 7.1.2P, it is the latest version of the OS that is still able to format disks as MFS. Nearly all of the later System 7 versions can both read from and write to existing MFS disks, but not format one anew. (So a Mac mini G4 CD for 7.1.2P could, one day, be theoretically cool to have. It is also a relatively popular System 7 version choice by many.)

There's also one more thing: Personally, I never really coexisted much with Mac OS before the System 7.5.x era. So I can't say what should be or should not be working at this point anymore... And I could use more people exploring this together with me. But what I can say is that System 7.1.x was almost as stable as the 7.5 and later counterparts on the Mac mini G4 1.5 GHz model (this hardware is so overkill). Most apps ran, but some, such as "The Teleporting Inchworm" (my personal choice of basic System features benchmark in this project) no longer runs (and freezes the OS). But maybe it was never meant to run on System 7.1 to begin with?

Some might now be wondering, "What about System 7.0 and 7.0.1?". From what I understood, System 7.1.x used a different "format" for its System Enablers compared to 7.5.x and 7.6.x, which is why we now have 2 different Enablers, but it seems no version of Mac OS before 7.1 is even aware of System Enabler files at all! (So-called "gibblies" or "gbly" type.)

So... yeah. Only time can tell what happens or not after this!

As always, many thanks to Rairii for yet another groundbreaking update! The latest enablers can be found in his GitHub project page, as per usual, which are also mirrored here in the Garden for both archival and easier access from Mac OS itself. Make sure to check the release notes for details. This time around, the Mac OS ROMs are the same as the previous release, so nothing new there to think about.

 49 
 on: December 04, 2025, 11:47:39 AM 
Started by Jubadub - Last post by Jubadub
Awesome, @RossDarker! :) Just like with Mac OS 9.2.2, now it feels like the mini has officially stepped into Mac OS 7.6.1 territory!

Many thanks for getting this ready and set up!

 50 
 on: December 04, 2025, 02:04:40 AM 
Started by Jubadub - Last post by RossDarker
Thanks Jubadub, Mac OS 7.6.1 it is!

I’ve put together an experimental Mac OS 7.6.1 Restore CD for the Mac mini if anyone would like to try this out.

See my post (#25) at https://system7today.com/forums/index.php?topic=4125.msg19998;topicseen#msg19996 for more info.

0.1 iso: https://drive.google.com/file/d/1u936FucCak17UsFCR_CYd-CQonXUyRcI

In short, burn this to a CD, then hold C at start-up to boot the disc. After installation, eject the disc with the mouse button when restarting.

Thanks to everyone who has made this possible!  :)

Pages: 1 2 3 4 [5] 6 7 8 9 10