Force32: persistent 32-bit addressing without a PRAM battery (updates thread)

It's time to resurrect the Force32 thread!

Force32 is a system extension that makes your Mac always run in 32-bit addressing mode, even without a PRAM battery. It works by, at startup, checking whether 32-bit addressing is turned on in the xPRAM; if it is turned off, it turns it on then restarts. This is essentially the same technique that System 7.6 uses.

Note that this won't magically enable 32-bit addressing on non-32bit clean machines: you still need MODE32 for that. This just keeps the flag in the PRAM turned on.

Attached below is a build of version 1.1: if anyone wants to try it out who isn't me I'd appreciate it. This version adds the following new things over version 1.0:
  • Quietly bails out instead of rebooting on 68000 machines (this feature requested by @superjer2000). This saves a pointless reboot on those machines because they can't do 32-bit addressing at all anyway.
  • Is now an 'scri' file instead of an 'INIT' file. This means it loads before most other extensions automatically, no need to muck about with the name any more. You can use ResEdit or Drop•Attribute or something like that to turn it back into an INIT (you only need to change the file type) if you want more control over where it loads, but most people want it to load first, to speed up the boot process.
  • Selfishly, I've revamped the way I store the source and build it so I (or you!) can now build it straight out of a git working copy, no need to muck about with SIT files for things with resource forks. This should make it a lot easier to work on in future if I can think of any more features.
This does not include the network-interface saving that several people have requested. I think I've worked out a neat way to do that, but it needs a bit of thought and it will likely be a separate extension.

As always, the source code is at https://github.com/cheesestraws/Force32
 

Attachments

Last edited:
Nice and tidy!

Curious, does CW glue up Gestalt so you can call it without the Gestalt Manager? It probably does. Otherwise you will of course crash under early versions of System 6. (THINK and MPW both provide glue to SysEnvirons for the relevant subset of selectors IIRC. It might even be in the universal headers somehow, I am curious now.)
 
I was just thinking that yesterday: I think it does. Perhaps I should more gracefully bail out if I'm running before 7, as it's not like twiddling the 32-bit bit will do anything pre-system 7 (will it?)
 
Hi, I've been using PRAM auto restore for a while now, it's a great utility to avoid keeping a battery inside my macs! The only drawback is that I have to reboot once manually every time I want to use my mac since 32 bits addressing, mouse speed and other things need to be set before system loads.

That's where your great utility came to my mind, it has the ability to automatically reboot the mac whenever 32 bits addressing is not set. But it doesn't really checks for effective 32 bits addressing, it only checks the pram value... So if I load PRAM auto restore first, Force32 thinks 32 bits addressing is enabled and doesn't reboot automatically the mac, if I load PRAM auto restore after Force32, the mac reboots itself in 32 bits mode but all my other parameters aren't set until I make a last reboot manually...

Is it possible for you to modify Force32 to make a real check instead of a simple PRAM check? (Idea: in "about the finder" there is only 8M of RAM usable in 24 bits mode even if 32 bits addressing is already set in PRAM but not from start)

PS: I currently use system 7.1.1 mainly on a LC475.
 
Last edited:
Hmmm, you're right, that's a good idea. Let me have a think about how that should work.
Is there a toolbox function you can check the availability of? Or the address of something in the memory map - does the stack or heap or something I forget work backwards from the top of memory in a way that is globally clear regardless of if you only have 8MB?

Do you get a useful error if you read a byte several gig into the address space 🤣
 
Hi, I thought of a different way to make the ideal init (for me) but except old Basic computers and Casio calculators my programming skills are close to absolute zero :(

see here
 
I've just been using the Gestalt Manager.
C:
Gestalt('addr', &addressMode);
addressMode32bitbit = addressMode & 1;
if( addressMode32bitbit == 0 ){ // we are not 32bit
    // do some "we're not 32bit" stuff
}
 
Without relocating too many things, isn't it also possible to modify a ROM (the IIsi-derived, "universal" type) so that the default PRAM values prefer 32-bit addressing at cold boot? I've always been interested in trying something like that, for both practicality and fun factor.

(Not meaning to detract from Force32 in any way, I install it on everything!)
 
C:
typedef UInt32 Bool32;

inline
Bool32 In32BitMode()
{
    return StripAddress(0xFF000000);
}

Oops. I recalled that _StripAddress takes its parameter in D0 and returns its result in D0, forgetting that StripAddress() takes a void* and returns Ptr. Adding the appropriate casts is left as an exercise.

Using StripAddress() in this way is only slightly better than calling Gestalt(). It works universally in all System 6.0.x, whereas Gestalt requires 6.0.4 minimum. Instead, I'd write this:

C:
inline
Boolean In32BitMode()
{
    return ! TARGET_CPU_68K  ||  ((UInt16) ROM85 < 0x7fff  &&  GetMMUMode());
}

This works in System 1 on a 64K ROM through System 7, PPC, Carbon, Mach-O, x86, and even 64-bit (which I admit is nonsensical) until whenever Apple drops GetMMUMode() from their headers, and it doesn't require a trap check or any trap dispatches at all.

Alternatively, it could be written in a negated sense:

C:
inline
Boolean In24BitMode()
{
    return TARGET_CPU_68K  &&  ! ((UInt16) ROM85 < 0x7fff  &&  GetMMUMode());
}

which even still makes sense on 64-bit architectures.
 
Oops. I recalled that _StripAddress takes its parameter in D0 and returns its result in D0, forgetting that StripAddress() takes a void* and returns Ptr. Adding the appropriate casts is left as an exercise.

Using StripAddress() in this way is only slightly better than calling Gestalt(). It works universally in all System 6.0.x, whereas Gestalt requires 6.0.4 minimum. Instead, I'd write this:

C:
inline
Boolean In32BitMode()
{
    return ! TARGET_CPU_68K  ||  ((UInt16) ROM85 < 0x7fff  &&  GetMMUMode());
}

This works in System 1 on a 64K ROM through System 7, PPC, Carbon, Mach-O, x86, and even 64-bit (which I admit is nonsensical) until whenever Apple drops GetMMUMode() from their headers, and it doesn't require a trap check or any trap dispatches at all.

Alternatively, it could be written in a negated sense:

C:
inline
Boolean In24BitMode()
{
    return TARGET_CPU_68K  &&  ! ((UInt16) ROM85 < 0x7fff  &&  GetMMUMode());
}

which even still makes sense on 64-bit architectures.
How come MMU calls are in the 64k ROM? Didn't it only ship with 68000 macs that didn't have an MMU or any 32bit addressing? Or do you just mean "works with".

That's why I thought the gestalt manager would be fine - it goes back to 6.0.4, but even 6.0.4 doesn't properly support 32bit addressing. I've been testing for OS version in this sort of thing, again, likely a more convoluted and less elegant solution, but I needed to anyway.

I guess it means you can test for it with a single command, but is it a development environment level code / tool rather than an OS tool? Surely Apple weren't planning for 32bit addressing in the 64k ROM era or perhaps they'd have thought not to use the upper byte as flags! 😄

You have me trying to work out what situations you could be in 32bit mode under these scenarios... You'd need a 68020 or 68030 upgrade and Connectix's Optima, or to have manually switched to 32bit in code. Would that even work in System 1?! Optima specifically seems to require System 6.
 
Last edited:
TARGET_CPU_68K && ! ((UInt16) ROM85 < 0x7fff && GetMMUMode());

I think it might not work on the Mac Plus and SE in Systems prior to 4.1

If I understand the code correctly:
1. Check to see if you are running PowerPC code. If so, you must be in 32-bit or greater.
2. Check to see if you are running on the 128K ROM or newer (excludes Mac 128 and Mac 512) and ...
3. Then check the MMU mode, which is actually stored in a low memory global, not a trap.

For step 2, I think you want less than or equal (UInt16) ROM85 <= 0x7FFF
For step 3, I don't know what value is going to be stored on the Mac Plus and SE in the global prior to when it was implemented for the Mac II in System 4.1.

That's why I thought the gestalt manager would be fine - it goes back to 6.0.4

At least in CodeWarrior 11, the glue code allows it to work back to System 1. So, checking for gestaltAddressingModeAttr gestalt32BitAddressing and that Gestalt returns noErr works fine. I've tested it on a Mac 128 in System 1.
 
Back
Top