• Hello MLAers! We've re-enabled auto-approval for accounts. If you are still waiting on account approval, please check this thread for more information.

Skipping the Startup Memory Test

jmacz

68020
My Power Macintosh 8500 came with 1GB of memory. Do I really need that much? No. But nonetheless, the massive delay on power up due to the memory check is painful. There are a lot of references to using the hidden option in the Memory control panel to disable this check. I decided to try it and here are the results. Again, the instructions are to hold down the command and option keys while double clicking and opening the Memory control panel.

System 7.x - this hidden functionality is not present.

MacOS 8.0/8.1 - this hidden functionality is not present.

MacOS 8.6+ - this hidden functionality exists.

Upon disabling the startup memory check, I can shutdown my Power Macintosh and the next time I boot, it skips the memory check and boots quickly. Just to be sure, I let it sit for minutes after shutdown just to ensure it's actually working as reboots clearly skip the check and I have found that if you shutdown but start the system soon afterwards, the check is also sometimes skipped.

This is well known so why this thread? Because I am actually running System 7.6.1 on my Power Macintosh (I prefer it) and thus am looking for a way to get this functionality to work under System 7.6.1. Apple didn't provide it so the question is whether we can work around it.

How does it work? Searched around and didn't find anything conclusive. But my guess (the same as a few others) is that disabling the check in Mac OS 8.6+ sets a flag either in the PRAM or XPRAM. This flag is read by the ROM during boot and a decision is made whether to preserve or skip the memory check.

To test this theory, I booted into MacOS 8.6 and turned off the memory check. I then tested it a few times to ensure the memory check is indeed being skipped. Then I removed my MacOS 8.6 SD Card, replaced it with my System 7.6.1 SD Card and booted after waiting for a few minutes. The memory check was skipped. Yay! I then shutdown, waited a few minutes. Boot up again. Ugh. Memory check was back in place. I repeated this experiment a few times and found that the very first boot into System 7.6.1 after configuring it in MacOS 8.6 skips the memory check but subsequent boots do not. Hmm...

My guess was then that something in System 7.6.1 overwrites this flag after boot. But this theory seems faulty. Although on the next subsequent boot to MacOS 8.6, it again performs the memory check, if I then hold down the command+option keys, launch the Memory control panel, it shows that the memory check is still disabled. What?? And then if I power down, wait a few minutes, boot back into MacOS 8.6, it skips the memory check again. Hmm... It's possible opening the Memory control panel rewrote something to wherever it's being saved, but I'm curious why the display showed it was still disabled. It needs to read that from somewhere, right? Well anyhow, I then went through the sequence again:
  • Boot into MacOS 8.6.
  • Set setting to skip the memory check.
  • Shutdown and power back up. Confirmed memory check is skipped a few times.
  • Boot into System 7.6.1.
  • Confirmed memory was skipped the first time.
  • Shutdown and power back up. Confirmed memory check was again in place the second time and subsequent times.
  • Boot into MacOS 8.6.
  • Confirmed memory was again in place.
  • Shutdown and power back up without opening the Memory control panel.
  • Confirmed memory check was again being skipped.
Hmm.

I dumped the XPRAM while toggling this setting under MacOS 8.6 and I don't see any changes to the 256 bytes in the XPRAM so it does not seem to be stored there. I have not checked the standard PRAM yet but will do so. If I don't see anything changing in the PRAM, then I will move on to disassembling the Memory control panel to see what it is doing.

My intent is to understand the mechanism in order to attempt to recreate it somehow under System 7.6.1.

I didn't find much about this while searching online and on the forums but if this is already solved and there's a write up somewhere (or software that can configure it within System 7.x) then I'd appreciate a pointer. Otherwise, I guess I'll keep poking at this.
 
You can use my DumpNameRegistry app to capture all of NVRAM. XPRAM should be 256 bytes at offset 0x1300. PRAM is bytes inside XPRAM.
https://68kmla.org/bb/index.php?thr...ng-easier-way-using-flashrom.7013/post-472471
https://forums.macrumors.com/thread...kansas-powermac-rebuild.2459064/post-33962257

My XPRAM notes are attached to these posts:
https://68kmla.org/bb/index.php?threads/read-write-pram-and-xpram.47196/post-568929
https://68kmla.org/bb/index.php?threads/fast-compactflash-for-macintosh-pds-nubus.49328/post-555644

I suppose you can do a compare of the DumpNameRegistry output to see if anything interesting changes in NVRAM/XPRAM/PRAM. Are changes made to NVRAM immediately by the Memory control panel? Or when the control panel quits? Or when the computer shuts down?

NVRAM for Old World Macs is described by IONVRAM.cpp in xnu-124.13 (10.0.4) to xnu-2422.115.4 (10.9.5)

The memory check might be a preference saved to both XPRAM and/or to disk. I suppose if it was saved to both, then they could have different values depending on which OS made the change to XPRAM.
 
Thanks as usual @joevt. For the DumpNameRegistry, is that something that will run in MacOS 8.6 or ? If it's a built binary, I can unzip it fine on my Mac OS X machine but lose any resource forks. I can't for some reason uncompress it on my OS 8.6 PowerMacintosh.

Could be something written on disk although that's not what is detected when booting into System 7.6.1 (when the memory check is disabled) since that's an entirely different disk. I did not detect any diffs in my own dump of the 256 bytes of XPRAM while toggling the setting. I don't know when it's saved so I dumped the XPRAM after a subsequent boot where it demonstrated check/noncheck behavior and still no differences. It must be elsewhere in NVRAM.
 
Thanks as usual @joevt. For the DumpNameRegistry, is that something that will run in MacOS 8.6 or ? If it's a built binary, I can unzip it fine on my Mac OS X machine but lose any resource forks. I can't for some reason uncompress it on my OS 8.6 PowerMacintosh.
The zip files were created on Mac OS X so they preserve the resource forks (I'm currently using Monterey but other versions should also work).

Decompress the zip files on Mac OS X before transferring the app to classic Mac OS.

It has the built binary and the source code files (.z is a resource file). Probably CodeWarrior Pro 4.

I don't remember if I ran the apps in Mac OS 8 or Mac OS 9. I think either should work.
 
Just have to say that my dream scenario for pre-G4 PPC is exactly this: System 7.6.1 (with Speed Doubler) is a fantastic experience - 8 and up feels baggy and I personally don't like the look for beige-era power macs. But that RAM check sure takes time! Fingers crossed you can figure this out 😄
 
Interestingly the PPC upgrade cards for Quadras also have this option in their card control panel, even in 7.1.2. I wonder if it controls the same nvram settings.
 
The easy, quick and dirty method:

1. Start your machine and listen for the startup chime.

2. Press Command-control-power key to restart the machine.

The memory test will be bypassed.
 
The easy, quick and dirty method:

1. Start your machine and listen for the startup chime.

2. Press Command-control-power key to restart the machine.

The memory test will be bypassed.

Haha, fair enough. :)

I did use @joevt tool (btw, your library of tools are awesome!) across 6 different power up cycles (3 with memory check enabled and 3 with memory checked disabled). I see various bytes that changed across these reboots. Will be looking at them to see if I see a pattern.
 
After 6 cycles, I only saw changes in the NVRAM section of DumpNameRegistry, and in that NVRAM section, there were roughly two dozen bytes changing. Looking at the actual bits and comparing it to whether it was a fast boot or a slow boot, I was able to narrow it down to around a dozen candidate bits.

It took around 20 cycles for me to get it down to 1 bit -- ie. after 20 power cycles (around half of them slow, and randomizing it -- ie. not just flipping back and forth sequentially), there was only 1 bit in all of the NVRAM that changed matching the configured slow/fast boot.

This particular bit is located in the byte at offset 0x1258. @joevt mentioned earlier that the 256 bytes of PRAM start at offset 0x1300. That means this is before the PRAM block. Next step is to put together something to read/write just this one bit and see if it does anything, and rule out this bit being coincidentally the right value after 20 power cycles.
 
This particular bit is located in the byte at offset 0x1258. @joevt mentioned earlier that the 256 bytes of PRAM start at offset 0x1300. That means this is before the PRAM block. Next step is to put together something to read/write just this one bit and see if it does anything, and rule out this bit being coincidentally the right value after 20 power cycles.
I modified DingusPPC to log every nvram access.

During startup of an emulated Power Mac 7500:
- it reads nvram byte 0x1308 (speaker volume?)
- inits all 26 ram banks.
- scans all 26 ram banks.
- it writes to 0x1048..0x1117 (8 bytes for each hammerhead bank 0 to 25 0x1048+8*26 = 0x1118). 4 bytes for RAM offset of bank. 4 bytes for size of bank.
- writes to 0x1044..0x1047 (total RAM)
- finalizes 26 ram banks.
- writes to 0x1250..0x1253
- writes to 0x1270..0x1273

- writes to 0x11d0..0x1257

- reads from 0x1180..0x1183
- writes to 0x1180..0x1183

- reads from 0x117c..0x117f
- reads from 0x1256..0x1257

- reads from 0x1040..0x1043
- writes to 0x1040..0x1043

- writes to 0x1168..0x116b
- reads from 0x11d0..0x124f
- reads from 0x1270..0x1273
- reads from 0x1250..0x1253
- reads from 0x1168..0x116b
- reads from 0x1048..0x104f
- reads from 0x1048..0x1117
- reads from 0x1044..0x1047

- reads from 0x1800..0x1ffff (Open Firmware partition)
- reads from 0x1800..0x1fe6 (Open Firmware partition but not unused bytes at the end)

I don't know if any of that includes a RAM test.

So I tried running Memory Control Panel. The only NVRAM byte I could see that it changes is the RAM disk size (XPRAM offset 0xAF = 0x13AF in NVRAM):
Code:
    AF		Memory Control Panel RAM disk size = 0x00=None, 0x01=6656K, 0x27=259584K
It changes the NVRAM byte immediately. But none of the other settings in the Memory Control Panel appear to affect XPRAM.

Maybe there's a problem with the emulation, or else the Memory control panel does not store Memory Test setting to NVRAM.

After more testing, it appears that 0x1043 gets a 0x09 at shutdown after turning Ram Test On.

The RAM test slows boot down, such that you can see a pause between each bank being tested. For each bank, the RAM test reads the bank address and size from NVRAM 0x1048..0x1117.

I can force the RAM test to always happen by make offset 0x1043 always return 9. Before beginning the RAM test, 0x1040..0x1043 is set to zero so that a RAM test never happens twice in a row. I suppose Mac OS will set the value back to 9 if it is able to boot and shutdown again.

Why is this a 32 bit value? What does 9 mean? Is it a number of iterations to perform for the RAM test? I could change DingusPPC to enter the debugger when it is accessing 0x1040..0x1043 to see where the code is and what the code does with the 32 bit value.
 
Interesting.. the OS changing the value was what I suspected given it works on System 7 the first time. I also didn't see anything outside of the normal changes to XPRAM from the memory control panel which is why I was looking at the greater NVRAM after your first note. The write on shutdown might explain why I didn't see a change at offset 0x1043 as after boot it sounds like it would potentially be the same value regardless? It's possible there's something being written out to preferences on what value to write during shutdown, I did see a change to a couple preferences files write after using the memory control panel. The change I saw at 0x1258 might be a consistent value remaining after the memory test is run or perhaps I calculated the offset wrong (I just counted based on the output of your tool inside the NVRAM section). Interesting.
 
Interesting.. the OS changing the value was what I suspected given it works on System 7 the first time.
Before System 7 has started.

I also didn't see anything outside of the normal changes to XPRAM from the memory control panel which is why I was looking at the greater NVRAM after your first note. The write on shutdown might explain why I didn't see a change at offset 0x1043 as after boot it sounds like it would potentially be the same value regardless?
0x1043 is definitely outside XPRAM in the grater NVRAM. The value is read after chime and reset to zero before the memory test so you never see the non-zero value during the OS. The memory test is called after calling .SerialTestManager. The Serial Test Manager returns immediately if whatever hardware condition (I don't know what) is not satisfied to trigger the Serial Test Manager console. I think the Serial Test Manager has commands to do the same memory tests.

It's possible there's something being written out to preferences on what value to write during shutdown, I did see a change to a couple preferences files write after using the memory control panel.
Yes, there's a couple blocks updated on disk. I didn't try using fsck_hfs to lookup what file the blocks belong to. I think the lookup only works on HFS+ disks.

The change I saw at 0x1258 might be a consistent value remaining after the memory test is run or perhaps I calculated the offset wrong (I just counted based on the output of your tool inside the NVRAM section). Interesting.
I would take the hex output, convert it to binary with xxd -p -r and output to text with xxd like this (replace the zeros with the hex from the hex output):
Code:
xxd -p -r <<< '
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
' \
| xxd > /tmp/nvram.txt
 
DingusPPC Discord channel has the startup source code .Diagnostics.s that does the memory test.
0x1040 is called MemoryTestFlag.
The "EMMO" pin of the BoardReg determines if .SerialTestManager should be executed.
 
I counted right.. used xxd and the value I was looking at is indeed at 0x1258. Given it was in sync with the ram test configuration, and based on what you found, I'm guessing what I saw was left over data from the test and it was just holding a 0 or 1 depending on whether the test was run or not.

I'm not a discord user. Can you share that source code snippet? So it's a 32 bit value beginning at 0x1040 and the value is set to 0x00000009 (meaning it's the byte at 0x1043 that is set) when a ram test should be done on the next boot... Since it's cleared (0x00000000) on boot, unless the shutdown code runs to set it to 0x00000009, it will skip the ram test on the next boot if that code doesn't execute (lost power, etc)? And sounds like that shutdown code determines whether it needs to write the 0x00000009 or not based on something in the file system?

Just to test this out... I configured the ram test to run in Mac OS 8.6 and shutdown. So the sequence should be:
  • Check something on the file system to see if the ram test should be run on next boot (in this case, yes).
  • Write a 0x00000009 into 0x1040...0x1043 (so the test is run on next boot).
  • Power off.
  • Wait...
  • Power on.
  • Check 0x1040...0x1043. If it sees a 0x00000009, run the ram test (in this case, yes, it will run a ram test).
  • Clears 0x1040..0x1043.
  • Ram test is run and boot is slow.
  • OS loads.
At this point, if I pull the plug (basically preventing the code from running at shutdown) I should get NO ram test on next boot even though it's configured to run the ram test.

Ok so I pulled the plug. And then waited for a bit. Plugged power back in and booted. No ram test.

Hmm... so what's interesting is that a 0x00000009 needs to be written for the ram test to be run. When that 0x00000009 isn't written and I boot into System 7, it skips the ram test as expected. But on the next shutdown and boot in System 7 (assuming System 7 does NOT have this config and doesn't write the 0x00000009) then there should be no ram test on the next power cycle... but there is a ram test. Which then suggests even System 7 is writing a 0x00000009 on shutdown. It's just not configurable in System 7? Is this behavior potentially not specific to PPC and also the same on 68K? Is this code present in the supermario code base? If so, is a System 7 patch sufficient to disable memory tests instead of having to resort to custom ROMs for 68K machines?
 
Hmm... so what's interesting is that a 0x00000009 needs to be written for the ram test to be run. When that 0x00000009 isn't written and I boot into System 7, it skips the ram test as expected. But on the next shutdown and boot in System 7 (assuming System 7 does NOT have this config and doesn't write the 0x00000009) then there should be no ram test on the next power cycle... but there is a ram test. Which then suggests even System 7 is writing a 0x00000009 on shutdown. It's just not configurable in System 7? Is this behavior potentially not specific to PPC and also the same on 68K? Is this code present in the supermario code base? If so, is a System 7 patch sufficient to disable memory tests instead of having to resort to custom ROMs for 68K machines?

I ran a quick little test, for what it’s worth. Test machine is a 600/IIvx-based unit with the 601 PPC card (my ”Centris 600”).

For the test I disabled the PPC card via the control panel and booted into 7.5.3. The PPC card control panel (which works fine under System 7) also has the “Disable memory test on startup” option, so I checked it and did a normal shutdown. After leaving the machine off for a while, I powered back up and it did do the memory check, which would seem to indicate System 7 sets the 0x09 flag regardless of how the actual control panel is set. I did verify after the power up that the control panel still showed the option being checked.

EDIT: What puzzles me about this particular test is the 601 card and associated control panel (to my knowledge) predate OS 8 and are System 7-era, so if the option doesn’t work under 7.5.3, what OS version was it supposed to work under? Or maybe it only works if the 601 is enabled? Another test for tomorrow.
 
Last edited:
I counted right.. used xxd and the value I was looking at is indeed at 0x1258. Given it was in sync with the ram test configuration, and based on what you found, I'm guessing what I saw was left over data from the test and it was just holding a 0 or 1 depending on whether the test was run or not.
I didn't see anything get written to 0x1258. I wonder if 8500 is different than 7500 somewhere. I could retry using pm8500 in DingusPPC.

I'm not a discord user. Can you share that source code snippet?
Sure. Attached. I consider Discord like just another forum. Pick a username/password and you're done, just like any other forum.

Hmm... so what's interesting is that a 0x00000009 needs to be written for the ram test to be run. When that 0x00000009 isn't written and I boot into System 7, it skips the ram test as expected. But on the next shutdown and boot in System 7 (assuming System 7 does NOT have this config and doesn't write the 0x00000009) then there should be no ram test on the next power cycle... but there is a ram test. Which then suggests even System 7 is writing a 0x00000009 on shutdown. It's just not configurable in System 7?
I guess so. Could run System 7 in DingusPPC to track NVRAM changes at shutdown to be sure.

Is this behavior potentially not specific to PPC and also the same on 68K?
Probably not. I don't think 68K has an 8K NVRAM. You would have to use a different method to investigate this. Maybe try a different emulator (MAME) to track XPRAM changes if it's doing the set on shutdown/reset on startup thing.

Is this code present in the supermario code base? If so, is a System 7 patch sufficient to disable memory tests instead of having to resort to custom ROMs for 68K machines?
This is Old World PCI Power Mac specific code. Supermario doesn't include it (though it does mention TNT in several places)

There's a file in supermario called StartInit.a that mentions "Start test", "StartTest", "RAM test".
USTStartUp.a has a label @testRam. At @NonEmulatedMachine, it checks a flag sgWarmStart to see if it was a cold start. If so, then it does a RAM test.

PowerPC Macs include this 68K code in their ROMs but they use a 68K emulator that skips over redundant 68K parts?
 

Attachments

I didn't see anything get written to 0x1258. I wonder if 8500 is different than 7500 somewhere. I could retry using pm8500 in DingusPPC.

Your earlier note had 0x1258 being written to and read during startup - that's why I was mentioning that what I saw was maybe just some of that IO which may be deterministically setting that bit based on whether it ran a ram test or not - and that it wasn't the flag.

Probably not. I don't think 68K has an 8K NVRAM. You would have to use a different method to investigate this. Maybe try a different emulator (MAME) to track XPRAM changes if it's doing the set on shutdown/reset on startup thing.

This is Old World PCI Power Mac specific code. Supermario doesn't include it (though it does mention TNT in several places)

There's a file in supermario called StartInit.a that mentions "Start test", "StartTest", "RAM test".

Yeah, I had patched out the memory test for the IIci, SE/30, IIfx, Quadra 700 stock ROMs previously. I went back to take a quick glance at the ram test last night in those ROMs and did see a check but nothing like what was shown in this thread above. Will revisit that later as I'm just curious about the PPC right now.
 
Your earlier note had 0x1258 being written to and read during startup - that's why I was mentioning that what I saw was maybe just some of that IO which may be deterministically setting that bit based on whether it ran a ram test or not - and that it wasn't the flag.
I don't see where I said 0x1258 was being written to.

Here's the list of events I see (DingusPPC pm7500, forcing 0x1043 to be = 9):
Code:
- it reads nvram byte 0x1308 (speaker volume?)
- inits all 26 ram banks.
- scans all 26 ram banks.
- writes  to 0x1048..0x1117 (8 bytes for each hammerhead bank 0 to 25 0x1048+8*26 = 0x1118). 4 bytes for RAM offset of bank. 4 bytes for size of bank.
- writes  to 0x1044..0x1047 (total RAM)
- finalizes 26 ram banks.

- .POST begins in Diagnostics.s
- writes  to 0x1250..0x1253 = Link0
- writes  to 0x1270..0x1273 = CountReg
- writes  to 0x11d0..0x124F = CPURegisterR0..CPURegisterR31

- calls CheckForInitialzation
- writes  to 0x1254..0x1257 = Link1
- reads from 0x1180..0x1183 = ResetCount
- writes  to 0x1180..0x1183  = ResetCount (incremented by 1)
- reads from 0x117c..0x117f = DiagInitSignature
- reads from 0x1254..0x1257 = Link1

- returns to .POST
- reads from 0x1040..0x1043 = MemoryTestFlag (test bits = 9 = ROMChecksumMask + RAMFwdModTestMask)
- writes  to 0x1040..0x1043 = MemoryTestFlag (reset to 0)
- reads from 0x1118..0x111b = TestResults

- calls RunTests
- writes  to 0x1254..0x1257 = Link1

- calls ChecksumROM:
- writes  to 0x1264..0x1267 = Link5
- reads from 0x124c..0x124f = CPURegisterR31
- reads from 0x1264..0x1267 = Link5

- returns to RunTests, begins MemTestLoop
- reads from 0x1048..0x1117 = Bank0Offset..Bank25Size
- reads from 0x1254..0x1257 = Link1

- returns to .POST
- calls HandleTheFailures
- reads from 0x1118..0x111b = TestResults
- writes  to 0x115c..0x115f = TotalFailures
- writes  to 0x1118..0x111b = TestResults

- returns to .POST
- writes  to 0x1168..0x116b = DiagPOSTResult2
- reads from 0x11d0..0x124f = CPURegisterR0..CPURegisterR31
- reads from 0x1270..0x1273 = CountReg
- reads from 0x1250..0x1253 = Link0
- reads from 0x1168..0x116b = DiagPOSTResult2

- returns to whatever called .POST
- reads from 0x1048..0x104f = Bank0Offset..Bank0Size
- reads from 0x1048..0x1117 = Bank0Offset..Bank25Size
- reads from 0x1044..0x1047 = TotalMemorySize

- reads from 0x1800..0x1fff = Open Firmware partition
- reads from 0x1800..0x1fff = Open Firmware partition
- reads from 0x1800..0x1fe6 = Open Firmware partition but not unused bytes at the end
- reads from 0x0f00..0x0fff = ??
- writes  to 0x0f00..0x0f01 = ??
 

Attachments

Code:
- calls CheckForInitialzation
- reads from 0x1254..0x1257 = Link1

Code:
- calls RunTests
- writes  to 0x1254..0x1257 = Link1

Misread the 0x1257 above for 0x1258. My mistake. So then I'm not sure why I'm seeing that bit in 0x1258 toggling in sync with the skip/non-skip of ram tests across 20 power cycles. Could be coincidence. Could be different for this 8500 but I wouldn't expect that.
 
Back
Top