Announcement

After 5 years serving the vintage Apple enthusiast community, ThinkClassic has been marked for closure and is now in caretaker mode. Please see this thread for further information. Please direct any questions, comments and enquiries about the website, management and ownership to this thread.

You are not logged in.

#1 2016-04-15 21:20:22

bigmessowires
Member
Registered: 2014-05-15
Posts: 183

Mac II series ROM hacking testing

I'm experimenting with some custom ROM images for the dougg3 ROM SIMM. I'd like to try doing some icon hacks, changing the startup sound, and other goodies. Is there any good way to test out my modified ROM images under emulation, without having to rewrite a SIMM and stick it in a Mac each time?

I thought I'd read about using MESS to do this, but it only seems to emulate 68000 Macs. Mini vMac is also 68000-only, and Sheepshaver is PPC. Maybe Basilisk II? It emulates a 68040, while the IIsi and most other machines targeted by the dougg3 ROM have a 68030.

Offline

#2 2016-04-15 21:27:47

bigmessowires
Member
Registered: 2014-05-15
Posts: 183

Re: Mac II series ROM hacking testing

I should have tested before posting - Basilisk II doesn't work either. It complains if the ROM image is over 1 MB. If I truncate the image to 1 MB, it complains it's an "unsupported ROM type". So it won't even try to boot from it. Any other bright ideas?

Last edited by bigmessowires (2016-04-15 21:28:05)

Offline

#3 2016-04-15 22:30:40

bigmessowires
Member
Registered: 2014-05-15
Posts: 183

Re: Mac II series ROM hacking testing

Looks like I was wrong about MESS only supporting 68000 Macs. It handles most of the Mac II series too, and this is almost working! I'm able to boot an emulated Mac IIci in MESS, and I can even boot using the modified iisi+romdrv0.9+nomem+nosum+img.bin ROM from http://synack.net/~bbraun/macromboot.html. It warns me that the ROM image is the wrong size and checksum, but it still runs:

C:\Users\chamberlin\Documents\MESS>mess64.exe -skip_gameinfo -window -resolution 640x480 maciici
368cadfe.rom WRONG LENGTH (expected: 00080000 found: 00200000)
368cadfe.rom WRONG CHECKSUMS:
    EXPECTED: CRC(46adbf74) SHA1(b54f9d2ed16b63c49ed55adbe4685ebe73eb6e80)
       FOUND: CRC(c68b9c14) SHA1(440ffecea1779c0f2b4d9076df699ddd4da7444b)
WARNING: the system might not run correctly.

Unfortunately the ROM disk doesn't work. If I hold down the R key to boot the ROM disk, it does nothing for several seconds, and then it shows the flashing disk icon with an X, as if I'd inserted a bad floppy disk. So I'm guessing that MESS isn't mapping the whole ROM image into the Mac's memory space, but is only mapping the first 512K, which is the expected ROM size.

Offline

#4 2016-04-15 22:35:44

bbraun
Member
Registered: 2014-05-29
Posts: 1,064
Website

Re: Mac II series ROM hacking testing

Yeah, you can hack up MESS to make it work, but MESS isn't mapping the whole ROM.  It's only mapping the original size of the ROM, so you have to go and update some hard coded constants for each machine target you want to use...

I have gotten it working on MESS before, and it's definitely a good way to test things like the boot icon.

The ADB emulation has been squirlly though.  I've done a couple different fixes to at least the IIsi's emulation that made things better, but I'm still not convinced it's all the way there yet.  So expect some oddness from time to time, particularly early in the boot sequence and in macsbug.

Offline

#5 2016-04-16 00:08:07

bigmessowires
Member
Registered: 2014-05-15
Posts: 183

Re: Mac II series ROM hacking testing

Cool, and thanks for the warning about ADB. Which Mac model did you emulate with MESS? The IIsi required some additional ROM files that I couldn't find anywhere, so I'm using the IIci. Maybe the ADB implementation is better/worse in one or the other.

It looks I should be able to test icons and other stuff this way, as long as it fits in 512K, so that's great. I'm going to guess that rebuilding MESS from source isn't trivial, so I'll probably skip that until I get really desperate. It's good to know it's possible, though.

Offline

#6 2016-04-16 00:38:25

bbraun
Member
Registered: 2014-05-29
Posts: 1,064
Website

Re: Mac II series ROM hacking testing

Were you missing just the egret rom?  I put some of the roms at http://synack.net/~bbraun/mess/ but I haven't spent the time to validate that's all that's needed.  The 'nb_image' rom is a declrom w/driver I wrote, and Arbee and I wrote the mess implementation of a card that will map a file into the nubus card's superspace.  That'll let you use a minivmac/basilliskII disk image.  You can boot from it, but like all bootable nubus cards, it'll only boot if you have it set in pram first.  So you'll need to boot from a floppy or something first, then set the startup disk to it, and then should be able to boot it.

At some point I need to spend some time to writeup how to use MESS for mac emulation, it's on the endless todo list.

Offline

#7 2016-04-16 03:35:25

bigmessowires
Member
Registered: 2014-05-15
Posts: 183

Re: Mac II series ROM hacking testing

Yes, egret was all I needed, thanks! I've got the IIsi running now under MESS.

Maybe recompiling MESS from source isn't so bad - there are instructions here: http://www.mess.org/compiling_mess. Then I could edit the expected ROM size for the IIci and IIsi.

Offline

#8 2016-04-16 14:11:57

bbraun
Member
Registered: 2014-05-29
Posts: 1,064
Website

Re: Mac II series ROM hacking testing

Yeah, it's not too bad, just takes a while and some disk space.
In the src/mess/drivers/mac.c file you can change the ROM_START macro for the machine you're looking at, and IIRC, change the first argument to the ROM_REGION32_BE macro and the 3rd argument of ROM_LOAD to be the size of the ROM.

Offline

#9 2016-04-17 03:56:07

bigmessowires
Member
Registered: 2014-05-15
Posts: 183

Re: Mac II series ROM hacking testing

Your memory about the macros was spot on! I got MESS 0.172 built from source, and I think I correctly modified the IIci config to expect a 2 MB ROM, but it won't boot from the iisi+romdrv0.9+nomem+nosum+img.bin ROM image. It just shows a black screen, with no chime or other activity. If I take the original IIci 512K ROM image and dupe it 4x to make a 2 MB image, then the IIci config boots fine with my modified version of MESS. I know you're not the MESS tech support, but since you've been down this path before, can you think of anything I might have forgotten?

All my edits are in mac.c, first in ADDRESS_MAP_START:

static ADDRESS_MAP_START(maciici_map, AS_PROGRAM, 32, mac_state )
    //AM_RANGE(0x40000000, 0x4007ffff) AM_ROM AM_REGION("bootrom", 0) AM_MIRROR(0x0ff80000)
    AM_RANGE(0x40000000, 0x401fffff) AM_ROM AM_REGION("bootrom", 0) AM_MIRROR(0x0fe00000)

Then in ROM_START:

ROM_START( maciici )
    //ROM_REGION32_BE(0x80000, "bootrom", 0)
    ROM_REGION32_BE(0x200000, "bootrom", 0)
   
    //ROM_LOAD32_BYTE( "341-0736.um12", 0x000000, 0x020000, CRC(7a1906e6) SHA1(3e39c80b52f40798502fcbdfc97b315545c4c4d3) )
    //ROM_LOAD32_BYTE( "341-0735.um11", 0x000001, 0x020000, CRC(a8942189) SHA1(be9f653cab04c304d7ee8d4ec312c23ff5d47efc) )
    //ROM_LOAD32_BYTE( "342-0734.um10", 0x000002, 0x020000, CRC(07f56402) SHA1(e11ca97181faf26cd0d05bd639d65998805c7822) )
    //ROM_LOAD32_BYTE( "342-0733.um9",  0x000003, 0x020000, CRC(20c28451) SHA1(fecf849c9ac9717c18c13184e24a471888028e46) )
    ROM_LOAD( "368CADFE.rom", 0x000000, 0x200000, CRC(000000) SHA1(f923de4125aae810796527ff6e25364cf1d54eec) )
ROM_END

BTW, the stock IIsi config in MESS 0.172 seems to be broken. Even without any source code or ROM image changes, the IIsi config plays a boot chime, but then an ascending chord, and dies. So that won't be much help for testing ROM hacks. I also noticed that somebody (you?) recently added the modplus-harp2.bin that we developed last year as an officially supported ROM image for the Mac Plus config.

Offline

#10 2016-04-17 04:18:50

bigmessowires
Member
Registered: 2014-05-15
Posts: 183

Re: Mac II series ROM hacking testing

I got it working! The problem was the initial PC address stored in bytes 4-7 of the ROM image. In the stock ROM this is 4080002A, but in the iisi+romdrv0.9+nomem+nosum+img.bin it was 0000002A. I changed it to 4080002A, and then I was able to boot the IIci config using the ROM disk by holding the "r" key at startup. This suggests MESS's emulation of the way ROM is mapped to address 0 at initial startup is broken. Or else I somehow broke it with my config changes. Either way, 4080002A seems more correct since 0000002A isn't in the standard ROM area of the memory map.

It took about 6 seconds of holding the "r" key before the ROM disk boot started. Any idea what it's doing during that time? If there's no memory test, and pressing "r" aborts the check for SCSI disks, then I would have thought it would start booting more or less immediately. When I tried it yesterday on a real Mac IIsi, I don't recall it taking that long. But I can't try it again now, since that computer's PSU is dismantled for recapping. :-)

Offline

#11 2016-04-17 17:49:06

bbraun
Member
Registered: 2014-05-29
Posts: 1,064
Website

Re: Mac II series ROM hacking testing

Cool that you got it working!  Yeah, it shouldn't take 6s to boot, but I wouldn't be surprised if there's something going on with MESS there.  MESS does have a very useful debugger (it's actually super useful for debugging ROM changes) if you haven't found it already.  The -debug option should bring up a separate window, but then window focus with the keyboard/mouse gets kind of weird.

I don't think I added any checksums for modded ROMs, so that must have been someone else.

Last edited by bbraun (2016-04-17 17:49:51)

Offline

#12 2016-04-18 20:44:19

bigmessowires
Member
Registered: 2014-05-15
Posts: 183

Re: Mac II series ROM hacking testing

No, I hadn't discovered the debugger option. WOW!!! :-)

Offline

#13 2016-04-19 00:15:03

bigmessowires
Member
Registered: 2014-05-15
Posts: 183

Re: Mac II series ROM hacking testing

OK, I'm starting with back-porting the "press and hold R now" from the the Plus ROM disk driver to the IIsi version. Here's a random pile of questions. I'll keep working on it, but if you have any thoughts on these in the meantime, let me know.

- Is there any fundamental reason the "press and hold R now" can't be added to the IIsi driver? Something about 32-bit addressing or Quickdraw that I'm failing to understand? I guess handling of multiple monitors might be an issue.

- My compiled driver is considerably bigger than yours, which I recall also happened with the Plus driver, and I assumed it was due to using different versions of CodeWarrior. In this case, though, my version is enough bigger that it overflows the space in the .netboot driver and overlaps the beginning of the the .atboot driver. Will that cause a problem? I'm not clear how the resource manager finds those resources, and if there's another reference to .atboot that would need to be patched. Alternatively, I could enable code optimization in the Codewarrior project to shrink the size. Currently it's set to no optimization, which I assume was intentional.

- If I'm following the code correctly, it will check the 'r' key only once, the first time Prime is called, and if 'r' isn't held at that moment then it will remove the ROM disk from the drive queue. When exactly does Prime get called for the first time? Do you have to hold down 'r' as you turn on the power switch? I thought there was a window of a few seconds during which you could press 'r', but I'm probably confusing this with the Plus driver's behavior.

- What exactly is the intent of the math involving MemTop / 2?

if(((unsigned long)*BufPtr - kRomDrvSize) <= (( ((unsigned long)*MemTop) / 2) - (1024*1024)))

I understand it's checking to make sure there's enough RAM available for the RAM disk, but I'm confused about the specifics of this test. It's checking if the base address of the RAM disk would be below the midpoint of physical RAM minus 1 meg?

Offline

#14 2016-04-19 01:14:36

bbraun
Member
Registered: 2014-05-29
Posts: 1,064
Website

Re: Mac II series ROM hacking testing

There should be no reason the message can't be put into the IIsi driver.  That should be fine.

You can probably enable optimization to shrink the size.  I think the only thing I really needed was to make sure constant strings are appended to the end of the function they're used in rather than in another resource or something.  I can't recall the dialog options offhand.
If the driver overflows into the .atboot driver, that'll probably be a problem.  The resource map has a header describing which resources are where, and then there's a little header at the top of each resource describing it.  I suspect that if something tries to walk the map, and the .atboot driver's header isn't where it's expected to be, things will get confused.  I think I experimented with trying to remove the .atboot driver from the resource map entirely in order to have more space, but I don't think I tracked down all the map's references.

The prime call and that equation are actually some of the few things that had some thought put into them.  smile
When the machine goes to look for a bootable disk, it traverses the drive queue reading block 0 from each until it finds one with a valid boot signature.  This is modified a bit by floppy vs. not floppy, and stored startup disk in pram, but more or less the case.  Prime is the combined read/write call for the driver, so the first call will always be to read block 0 as the ROM is trying to figure out whether to boot from the drive.  So the 'r' key check is there, and if we don't want to boot from the drive, we return error and unload the drive from the queue.  We could return error and leave the drive in the queue, and then it will show up in the Finder after booting, but there was a bunch of discussion about that, and ultimately it was decided by consensus that it should be like the Classic's ROM disk, which doesn't show up.  I believe the ROM disk driver can be built as an INIT too (initially for testing purposes), so people who want the disk to show up, but not boot from it, can install the INIT.
Edit: The reason it's in the first Prime call instead of the Open call is because the keyboard may not be initialized at the point Open is called, and we don't get any other chance.  Basically the Prime call should be called sometime around the time the Floppy icon gets displayed at boot time, where as the Open call gets called right around the time the screen is initialized and the stipple pattern comes up (before even the cursor is displayed I think).  The Prime call is our best shot at a 'deferred' check for the key being held down.

Now, going from memory on that equation, I believe it is to deal with copying the ROM disk image to RAM (so it can be writeable, which is required by appletalk - it needs a writeable boot drive) in 24bit mode, and possibly support for machines with less than 8MB of ram in 24bit mode.  When the ROM disk is copied to RAM, the RAM is allocated out of the system heap, which has limits on its size.  IIRC, the way the memory allocation on macos works is the application heap starts low and the system heap starts high, and when they grow into each other, then you get kaboom.  So the system heap grows downwards, which is why it's subtraction, I think.

Last edited by bbraun (2016-04-19 01:18:18)

Offline

#15 2016-04-19 02:18:47

bigmessowires
Member
Registered: 2014-05-15
Posts: 183

Re: Mac II series ROM hacking testing

Thanks, and one more question: do you recall anything special needed to set breakpoints in the MESS debugger inside the ROM disk driver code? I can set breakpoints at other points in ROM with MESS, and they get hit, but breakpoints inside the ROM disk driver don't ever get hit, even when the driver is clearly being called and is working. I thought maybe the driver gets copied to RAM and run from there, but it contains branch instructions to absolute addresses in ROM, so I don't think that can be true. Sorry for asking so many questions! I'm motivated to get this working. smile

Offline

#16 2016-04-19 02:40:48

bbraun
Member
Registered: 2014-05-29
Posts: 1,064
Website

Re: Mac II series ROM hacking testing

No, there shouldn't be anything special about the driver that way.  It doesn't copy its self into RAM, and ROM drivers should be just running from ROM the whole time.  One thing to try is the driver funnels all calls through the same entry point (even before main).  You can take a look at the driver header that codewarrior generates and see the offsets of the various functions into the driver, and basically each should be setting a register to remember a value, and then jumping to the main funnel point.  You could try setting a break point on that, since that would capture all calls to the driver.
Or maybe a watchpoint.

Offline

#17 2016-04-19 21:17:10

bigmessowires
Member
Registered: 2014-05-15
Posts: 183

Re: Mac II series ROM hacking testing

Progress! The breakpoint problem was due to a memory mapping issue. Instead of setting a breakpoint at address 408xxxxx, I had to set it at 008xxxxx. I'm not sure if that's because of the way ROM is mapped to address 0 during the early boot process - I thought the lowest addresses were switched to RAM well before the point where the driver code runs. Or maybe it's some artifact of virtual memory or 32- vs 24-bit addressing? I am very foggy on that stuff.

Anyway, it's working now. I was able to shrink the size of the driver code slightly through some refactoring, without turning on optimizations, so it no longer overlaps .atboot. I made a trivial change to the ROM disk driver source code to alter the enable keys, then recompiled it with Codewarrior 10 under Sheepshaver. I opened the resulting file with ResEdit, opened the driver resource with RedEdit's generic hex editor, and copied the bytes to the clipboard. Then I switched context to Windows, launched the xvi32 hex editor, and pasted the clipboard text as a hex string. I saved that file as netboot.bin. Then I used xvi32 to open the modified IIsi ROM image containing the earlier version of the ROM disk driver, went to address 51d70, and deleted a block of bytes equal in length to my new netboot.bin. Using xvi32's insert function, I then inserted netboot.bin into the larger image, and confirmed the result was still exactly 2 MB. I saved the modified file, and replaced the file in MESS's "roms" directory with the new file. Then I booted my previously-modified version of MESS that's been patched to expect a 2 MB ROM instead of a 512 K ROM. Held down the enable key, which I'd changed from 'r' to 'b', and confirmed that it still worked. Yay! It's not exactly the simplest process. :-)

I'm confused by how the ROM disk driver allocates RAM and copies the ROM disk contents into it, for when you also hold down the 'a' key to make a writeable scratch disk. From my look at the code, it may do this during the first call to Prime, right when it checks the 'a' key, if that MemTop / 2 test succeeds. But if that test fails, it won't do anything except set the flag dNeedTimeMask, which will cause the driver to be called again later. Then when it's called later, it will allocate space for the RAM disk, and copy the ROM disk contents into it. There are two different methods of doing the allocation and copy, for 24- and 32-bit addressing modes. Does that sound right so far?

First question is again about that MemTop / 2 equation. I think I understand the general intent and the details about the directions of heap growth. What I don't understand is the significance of the particular value MemTop / 2 - 1024 * 1024. Was that just an arbitrary threshold for "not enough RAM would remain", or is there a special reason for that specific value?

Second question is why that MemTop / 2 check and the associated ROM-to-RAM copying in Prime needs to be there at all, instead of relying entirely on the delayed allocation method using the dNeedTimeMask flag. As I see it, even if the "not enough RAM test" fails, it will just allocate the RAM anyway later via that second method. Might as well unify everything into a single code path using the delayed allocation method, and add a "not enough RAM" check there if needed.

Third question is about the delayed allocation method when in 24-bit mode. The code to allocate the RAM disk and copy the ROM disk contents into RAM does this:

ctx->disk = (unsigned char *)(8*1048576);
ctx->copyfunc((unsigned char *)kRomDrvLocation, ctx->disk, kRomDrvSize);

It looks like it's blindly copying the ROM disk contents to an absolute address at the 8 MB point in the address space, which we hope is RAM. But it doesn't actually allocate that memory with the OS, using any method that I can see. So there could be other stuff already in that area of RAM that gets overwritten by the copy, or the copied data could get overwritten later by other OS activity, since the OS doesn't know the driver is using that area of memory. Nor does it check to see if there actually exists enough RAM for the RAM disk. I think I must be overlooking something basic here.

Offline

#18 2016-04-19 23:18:58

bbraun
Member
Registered: 2014-05-29
Posts: 1,064
Website

Re: Mac II series ROM hacking testing

Cool that it works!  Yeah, when I was doing this regularly, I was using netatalk as a file share on the mac that compiled it, and netatalk stores the resource information in AppleDouble format inside a .AppleDouble directory on the file server.  I then used dd to grab the right range of the file and dump it into the ROM.  The only hiccup is trying to find the start of the driver within the appledouble file, since that'll change with every recompile it seems.

Yeah, there's 2 places where it does the allocation and copy, for a couple reasons.  The first time the Control function gets called when dNeedTimeMask is set isn't until the Finder launches.  If an INIT (like AppleTalk, I think) needs to write to the boot volume, it'll fail (or silently ignored, I can't remember which) because the volume isn't writeable until the allocation/copy, which isn't until much later in the boot process.  The other reason is the time to copy is noticeable, and people kinda freaked out when the machine boots then hangs right before Finder.  Maybe adding some progress bar or something would improve the user experience.
This ties into the blind copy you found, which is a super sneaky trick added by dougg3.  The driver always operates in 32bit mode because the space where the ROM disk lives isn't entirely addressable in 24bit mode.  The ROM should be at $80000 in 24bit mode, and only has 1MB until $90000 which is for Slot 9, and used by the builtin video of some machines (SE/30 or IIsi, I can't remember which).  So, when Prime is called, it'll switch to 32bit mode to do the copy from ROM into the passed in buffer, and then switch back.  In 24bit mode, the system can obviously only address 8MB, from $0 to $7FFFFF before it hits ROM.  BUT!  If the machine actually has more than 8MB, we can use it because we're always in 32bit mode!  So if you've got the RAM and you're in 24bit mode, you can get the RAM disk for "free".  Meaning, it won't take RAM away from the system or the apps because they're not able to address it anyway.  I believe in this case, if you don't have the physical RAM to back it, bad things might happen because there's not really a good way to check other than to setup a bus error handler and try to do the copy.
That's also why there's a pointer to the copy function, since we want to make sure we've got the right addressing mode when we're referring to the code to run.
One bad part about flipping back and forth between the addressing modes is flipping causes a cache flush.  If people are running in 32bit mode it's a nop.  But for 24bit modes, they get a cache flush kinda often.  It's still a net win though I think, since running from ROM/RAM is still going to be way faster, and if you're in 24bit addressing mode, you're probably running on a processor without enough cache to notice that much difference.

I believe MemTop / 2 - 1024 * 1024 is actually where the system heap ends and there's other data following it on machines with more than some amount of memory.  I'd need to dig up the reference, but I believe machines with <4MB have a different allocation scheme, and then it was consolidated to the above equation for all other memory sizes.

It is a bit convoluted to handle all these different cases.  It does suffer a bit from organic growth, and I don't know how many people actually care about all the different cases and cleverness, but it's probably there because someone somewhere said "hey, it should do $X!"  smile

Offline

#19 2016-04-20 18:20:43

bigmessowires
Member
Registered: 2014-05-15
Posts: 183

Re: Mac II series ROM hacking testing

OK, then I'll ask the opposite question: why does the delayed allocation method using the dNeedTimeMask flag need to be there at all? Since as you said it causes a hiccup right before the Finder, and anyway it looks like the first RAM disk allocation method will always be used instead of the delayed one, unless there's insufficient RAM. Is it solely a fallback for the case of "free" RAM in 24-bit mode? Or if not, under what condition would the code path be exercised for a delayed dNeedTimeMask allocation in 32-bit mode?

I added the "press and hold r now" feature to the IIsi ROM disk driver and rebuilt it, but even with code size optimizations it's too big to fit inside the .netBOOT driver area. The .ATBOOT driver area is much larger and is also unused, so I tried to use that, but something unknown is preventing the driver code from ever running. Following the instructions on the wiki (http://synack.net/~bbraun/macromboot.html), I set the first bytes of .ATBOOT's resource header at $52530 to $78 to enable it, and the first byte of .netBOOT's resource header to $18 to disable it. Then I splatted my new ROM disk driver code into the ROM image beginning at $52560, overwriting the rest of the .ATBOOT area, using the same technique I previously used successfully with .netBOOT. But when running under MESS, it never even tries to call the new driver code.

There's some ROM startup code at $1AB74 that appears to scan the resources available in ROM, so I spent some time analyzing it. I never found any documentation of of the ROM resource header, but it's clearly a 48 byte structure with some fields that can be inferred. Offset $0 in the header should be $78 in order for the resource to be loaded. It looks like the ROM resources are organized as a linked list, with offset $8 in the resource header being a pointer to the next ROM resource. .ATBOOT is the second to last resource in the list, and .netBOOT is the last one. Offset $c in the resource header points to the actual start of the driver. The name of the driver is at $17 in the header, which seems strange since it's an odd address. (The driver name is also repeated in the driver itself, after the resource header. I have them both set to ".ATBOOT".) Offset $10 is "DRVR".

There are some fields in the resource header I don't understand. The three bytes at offset $14 through $16 are either $000458, $003158, or $003258 in the examples I've looked at. I tried changing this field in .ATBOOT to be the same as for .netBOOT, thinking that might explain why the code in .ATBOOT wasn't getting called, but it didn't make a difference. At offset $20 are eight bytes whose purpose I don't know. Maybe they are the explanation. Four bytes at $28 appears to be the resource size. Four more bytes at $2C have an unknown purpose.

I used the MESS debugger to step through the startup code that walks the resource list, to see what it does when it encounters .ATBOOT. It seems to do what I'd expect: it checks the flags at the start of the resource header, sees that they're set, and then branches to some other code. This code does a bunch of other work that involves the low-memory globals ROMMapHndl and RomMapInsert, which looks like the right thing, though it's too complex for me to follow completely. But once all the ROM-walking is done, none of the entry points in the driver hiding inside .ATBOOT ever get called.

Offline

#20 2016-04-20 18:35:09

bigmessowires
Member
Registered: 2014-05-15
Posts: 183

Re: Mac II series ROM hacking testing

I just realized that most of that information is ALREADY IN THE WIKI. My reading comprehension skills are not good. :-(

Offline

#21 2016-04-20 19:06:27

bigmessowires
Member
Registered: 2014-05-15
Posts: 183

Re: Mac II series ROM hacking testing

Aha! I got it to work by renaming the driver back to .netBOOT, even though it now lives in the ROM area for the .ATBOOT driver. There's some ROM code at $1250 which explicitly loads the .netBOOT driver by name and opens it. No such codes exists for .ATBOOT, so the driver resource was getting loaded but never opened.

Offline

#22 2016-04-20 19:33:24

bigmessowires
Member
Registered: 2014-05-15
Posts: 183

Re: Mac II series ROM hacking testing

The Plus version of the ROM disk driver calls a function named IODone() before all the return paths in Prime:

void asm IODone(DCtlPtr d:__A1, short result:__D0) {
    move.l    0x08FC,-(sp)
    rts
}

It looks like this causes the 68000 to "return" to address 0x08FC, which is a low-memory global that points to the IODone routine for drivers. The IIsi version of the ROM disk driver doesn't have this, and just uses a regular return statement to exit from Prime. Maybe it should be using IODone as well?

Offline

#23 2016-04-20 22:04:34

bbraun
Member
Registered: 2014-05-29
Posts: 1,064
Website

Re: Mac II series ROM hacking testing

Cool!  I'm glad you figured out the .netBOOT vs. .ATBOOT thing.  Yeah, early in the boot process, the ROM opens the .Sony and .Sound drivers I think, and I changed that to open .netBOOT and then I think the rom disk driver chains the open to whatever driver it replaced.  If you're moving to .ATBOOT, I think there's also the driver name in the resource map somewhere, and it'd probably be good to keep that in sync.
An alternative that I used in the Plus driver is to move either a section or the whole driver somewhere else in rom and just have the .netBOOT entry point jump to it.

The delayed allocation in 24bit should just be a fallback.  It shouldn't be the primary case I don't think.  Assuming the machine has enough RAM, which I would assume would be the majority of users of this, it shouldn't be hit AFAIK.

For IODone, it probably should be jumping through there explicitly.  I think I added that to the Plus driver as I came to understand the driver interface a bit more.  The part I'm unsure about is whether the CodeWarrior glue code does that jump implicitly.  That jump through iodone won't ever return, it's a way to let the device manager dequeue any other pending requests.  It probably doesn't matter in the case of the rom disk driver because everything is handled synchronously, being just memory operations and all.  For most device drivers, the request would tell the hardware to do something, then the driver would return asynchronously, and then it would service the request via an interrupt or something.  I remember it taking a long time for me to wrap my head around iodone, and it's kind of faded a bit.  The things I remember are: it never returns, it probably doesn't matter for the romdisk driver, it's probably technically more correct to call it.

Cool that you found the wiki!  I had forgotten about it, and I'm glad I documented something back when this was fresh in my mind.

Offline

#24 2016-04-21 02:16:10

bigmessowires
Member
Registered: 2014-05-15
Posts: 183

Re: Mac II series ROM hacking testing

From peeking at the disassembly, I see the scaffolding code added by Codewarrior already handles the IODone stuff. Whatever value is returned by main() gets routed through IODone if needed, so it shouldn't be necessary to do it manually in the ROM driver code.

Unfortunately, it looks like some change between driver versions 0.9 and 0.9.6 broke the RAM disk, at least under MESS while emulating an 8MB IIci. Do you have the older versions under source control? The problem seems related to the amount of installed RAM.

With the emulated 8MB IIci, the RAM disk works fine in the prebuilt iisi+romdrv0.9+nomem+nosum+img.bin, with a 1.5 MB ROM disk. But when I build the ROM disk driver from the 0.9.6 source, it always freezes while rebuilding the desktop if I try to use the RAM disk. As a control, I tried the prebuilt iisi+romdrv0.9.6+nomem+nosum-8mb+chm.bin image, manually editing the 4 bytes for the ROM disk size to make it 1.5MB instead of 8, and appending the same 1.5MB disk image that's used with iisi+romdrv0.9+nomem+nosum+img.bin. It fails in the same way as my locally-built image from the 0.9.6 source. The progress bar for rebuilding the desktop appears, but then the machine freezes, and sometimes it also fills the screen with garbage.

I'm not sure if this emulated IIci is booting in 24 or 32 bit mode. The disk image doesn't have any control panels in the System folder, so I can't easily tell. But from peeking at the low-memory global MMU32Bit at 0xCB2, the value is 0. So I assume it's in 24-bit mode.

If I increase the amount of emulated RAM from 8 to 16MB, then the 0.9.6 RAM disk works. But that shouldn't be necessary, because 8 MB RAM should be enough for a 1.5MB RAM disk and the System RAM. Even 4 MB should be enough. Maybe it's falling back to that hard-coded "free" RAM we discussed earlier, that it expects to find beyond 8MB, but isn't present. But I'm not sure why it would do that, instead of allocating the RAM the normal way during the first call to Prime.

Offline

#25 2016-04-21 03:28:30

bbraun
Member
Registered: 2014-05-29
Posts: 1,064
Website

Re: Mac II series ROM hacking testing

I might have some of the older versions around, but I was just thinking about revision control again.  Everytime I think about revision control for macos projects I end up with no good answer because of resource forks.  MPW used Projector, which was basically a local database of versions.  The way Apple handled shared repositories was to have the Projector database on an AppleShare, and everyone who wanted to access it would mount the share.  We could potentially do something similar using the mac68k.info appletalk vpn, although that's kind of slow and requires a 68k/ppc macos machine with network access to get to it.
There was also MacCVS which would wrap up the resource forks when checking in (I forget the exact encoding), but that wasn't terribly desireable because it would essentially result in binary blobs being checked in, and diffing/annotating/anything wasn't very useful.  But, at least you could check out the different versions.  Early OSX's cvs maintained that wrapping/unwrapping.
So, if you've got any suggestions, let me know.  smile  I've just been asked to help out with the Classic II's ROM, and was thinking it would be good to have some kind of central repository.  mac68k.info has subversion repositories available, which is where some of the disassembly stuff I've done is located, along with the ps2 keyboard/mouse code.

It looks like I've got several old versions at http://synack.net/~bbraun/macsrc/ all named romdrv*

I suspect the problem you're hitting is like you suggest, trying to access >8mb of RAM using 32bit mode.

Ok, you've finally made me open the source.  I was trying to go based on memory, but you've stumped me.  tongue
So BufPtr should be the low memory global pointing to the current part of the system heap.  For my own reference, here's the code that decides whether/how to do the RAM allocation with some added comments inline:

			if (*((unsigned char *)0x0CB2)) {
                                // 32bit mode
				if(((unsigned long)*BufPtr - kRomDrvSize) <= (( ((unsigned long)*MemTop) / 2) - (1024*1024))) {
                                        // If there's not enough space left in the system heap
					d->dCtlFlags |= dNeedTimeMask;
					d->dCtlDelay = 0x10;
				} else {
                                        // There's enough space on the heap, carve out a chunk for the ramdisk
					*BufPtr -= kRomDrvSize;
					ctx->origdisk = *BufPtr;
					ctx->alreadyalloced = 1;
					ctx->disk = (unsigned char *)ctx->origdisk;
					BlockMoveData((unsigned char *)kRomDrvLocation, ctx->disk, kRomDrvSize);
				}
			} else {
                                // 24bit mode
				d->dCtlFlags |= dNeedTimeMask;
				d->dCtlDelay = 0x10;
			}

Then this is the deferred allocation & copy case:

				if (*((unsigned char *)0x0CB2)) { /* if we're already in 32-bit mode, allocate like this */
                                        // 32bit, and memory manager is up and running, do the allocation using NewPtrSys
					ctx->origdisk = NewPtrSys(kRomDrvSize);
					if(ctx->origdisk) {
						ctx->disk = (unsigned char *)RomDrvStripAddress((Ptr)ctx->origdisk);
						ctx->copyfunc((unsigned char *)kRomDrvLocation, ctx->disk, kRomDrvSize);
					}
				} else {
                                        // 24 bit mode
					ctx->ram24 = 1;
					ctx->origdisk = NewPtrSys(1); /* just a dummy pointer to make rest of code work */
					ctx->disk = (unsigned char *)(8*1048576);
					ctx->copyfunc((unsigned char *)kRomDrvLocation, ctx->disk, kRomDrvSize);
				}		

Ok, so I'm remembering a bit more.  I suspect that your mess system is in 24bit mode, since that's the default for the IIci when PRAM is empty, which is probably is with your emulated environment.  It looks like in 24bit mode, it will always try to do the >8MB trick, which would explain why your 8MB system is failing.

The obvious question here is if there wasn't enough memory when we did the 32bit check in Prime, why are we trying to do the allocation again in the 32bit deferred case.  I believe the reason for that is 7.5.something and higher will really really want 32bit mode.  If you boot in 24bit mode, it'll come up with a dialog when it tries to boot telling you to switch to 32bit mode and reboot, which it'll do for you right there.  I think that's the case being handled.  I know there was some weirdness around all that.  I don't regularly use 7.5+ on 030 machines, but I know dougg3 did and he added some of this (which I mis-merged in 0.9.5 I think, sigh version control).

Offline

Board footer

About ThinkClassic

ThinkClassic specialises in the use, maintenance, repair, restoration and modification of vintage computers and peripherals.