> Not just some sort of BIOS but the full MacOS System.

It's not quite the full system. It may be best to think of the original Mac OS as a software library. The application is in primary control, and uses the OS as a library directly - jumping right into the OS code sometimes. Modern ideas about layers of separation and protection did not yet exist.

A significant portion of the ROM is QuickDraw, routines for doing bitmap graphics and text very quickly. There are some other rather generic routines, like string handling, a sort of a standard library. There are also drivers, interrupt and timer handling, etc. The Chicago system font is in ROM too.

Since it was all designed together, it was not too hard to just make it modular, and have some of the modules in the ROM, and the rest loaded from disk. There is a central dispatch table kept in RAM. When a program makes a Mac OS call, the dispatcher looks up the current vector from the table. When the OS loads, any patches to ROM are handled by redirecting the dispatch to the new routines or patches. It's important to remember classic Mac OS had resources (labelled sections). Large blocks of code are referred to with handles, not pointers. The resource manager can transparently load/unload them behind the scenes as needed.

The Mac has gone through a fair bit of setup before it starts reading the disk. The OS memory manager is running, and the device manager is configured, the disk driver service is set up as well. The boot splash (grey background and the happy Mac icon) is drawn using standard graphics API calls. The calls would do the same thing if used in a normal Mac OS app. The boot sector on disk is loaded using the same calls as in a Mac OS app if you wanted to do low-level disk access.

The resource manager is then told about all the resources in the system file, and any patched resources are patched, etc. And then the finder application is loaded and started. When it goes to look for resources, it'll find them mapped to ROM or the system file through the in-RAM resource map. And when it goes to make a system call, it'll find them mapped to ROM, or the routines loaded in RAM from the System file, through the trap table.

Here's a good article (2019) doing a much deeper dive: https://macgui.com/news/article.php?t=496

> became useless because there was no way to update the ROM

The original Mac 128 and 512 were limited, because their ROMs were the original code, and also 64 KB in size. The later Mac software needed at least 128 KB of ROM (new file system, etc.) and so could never run on those machines. But later system software was never going to run on those machines, anyway.

RAM was extremely expensive in the mid-80s. That is really the only reason for this. The original Mac would have needed an extra 64 or 128 KB of RAM otherwise. That would have bumped the price up several hundred dollars. RAM prices imploded shortly after the Mac's release, of course. System 7 loads around 100 KB of patches to the ROM on a Mac Plus. By 1990 it would clearly have been better to just have it all in RAM. But the architecture was already fixed. (Later Macs would just load a complete ROM image off disk.)

There is one more minor factor: the original Mac can execute code from ROM at full speed. The RAM is contended with the video hardware and has slightly slower throughput. So there is a slight plus to having QD in ROM!