mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-22 04:31:30 +00:00
3324 lines
146 KiB
Plaintext
3324 lines
146 KiB
Plaintext
;
|
||
; File: Boot3.a (formerly BootCode.a)
|
||
;
|
||
; Contains: boot code for the Macintosh system
|
||
;
|
||
; This code lives in the 'boot' 3 resource in the System file.
|
||
;
|
||
; This code takes over the boot process from Boot2.a, and takes it
|
||
; up to the launch of the Process Manager. This code used to be in
|
||
; Boot2.a itself but was split off during the implementation of the
|
||
; CPU Gibbly mechanism. All code which handles booting should be added to
|
||
; this file; Boot2.a doesn’t do much beyond finding a CPU Gibbly with
|
||
; this code and passing on the boot baton. This code, unlike Boot2.a,
|
||
; can be in ROM if we so choose.
|
||
;
|
||
; This contains all the code necessary to get from boot to the Process Mgr.
|
||
; It also contains the code that was formerly in INIT 31 that loads INIT resources
|
||
; from INIT, RDEV, and cdev files.
|
||
;
|
||
; Written by: Darin Adler, based on old boot blocks and StartBoot.a
|
||
;
|
||
; Copyright: © 1990-1993 by Apple Computer, Inc. All rights reserved.
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <SM30> 11/7/93 SAM Roll in <MC2> from mc900ftjesus.
|
||
; <MC2> 11/7/93 SAM Sync-in this file with CPUBootcode.a from the gibbly sources.
|
||
; <SM29> 7/21/93 RC Changed RegisterROMComponent to selector 42 instead of 27
|
||
; <SM28> 7/20/93 SAM Cleaned up more stuff. Moved the processmgr 'proc' resource
|
||
; loading code *way* forward in the boot. The scod's end up being
|
||
; the very first resources in the heap. The "Welcome dialog is
|
||
; displayed after the scods are loaded. Removed a couple of 24
|
||
; bit routines. Redid the old installmgr code (which is now
|
||
; called InitSys7ToolBox). See the comment block around that
|
||
; change for details. Made QuickTime components not load on
|
||
; 68010s. Added labels to the ROM header references.
|
||
; <SM27> 6/17/93 rab Removed the GetGibbly and CanThisGibblyBootThisMachine routines
|
||
; and the code that calls them. This code was inadvertantly rolled
|
||
; in during the Ludwig sync up.
|
||
; <SM26> 6/15/93 SAM Undid change <LW2> for PDM. We dont need a gibbly to boot
|
||
; (we're actually turning the ROM you see...)
|
||
; <SM25> 6/14/93 kc Roll in Ludwig.
|
||
; <LW2> 3/25/93 GS Added GetGibbly and CanthisGibblyBootThisMachine routines to put
|
||
; up the proper Alert when booting a 7.1 System without a Gibbly.
|
||
; <SM24> 4/20/93 SAM Removed a call to _InitFonts, cuz _InitGraf calls it.
|
||
; <SM23> 2/12/93 PN Add forROM condition for the previous change
|
||
; <SM22> 02/11/93 HY Fix problem in routine DetachAndExecute. If a particular resource
|
||
; is not found in either the ROM or system file then you crash.
|
||
; <SM21> 02/10/93 HY Enable Appletalk on LCR/LC930 again. Revert <SM18> changes.
|
||
; <SM20> 2/5/93 SAM Removed the code that was unimplementing MemoryDispatch based on
|
||
; MMUtype. Removed the CPU/MMU checks before calling VM. VM
|
||
; knows if it can run.
|
||
; <SM19> 01/11/93 jmp Updated various BoxFlag names.
|
||
; <SM18> 12/16/92 HY Disable Appletalk on LCR/LC930.
|
||
; <SM17> 12/7/92 GMA We now call RegisterRomComponents directly from Boot3 instead of
|
||
; through the Manager InstallationVector(in ROM). Rom Components
|
||
; are registered (through ComponentDispatch) after making the
|
||
; Cyclone Gibbly Resident. This allows the Components in ROM to
|
||
; use Localized Strings in the Gibbly without referenceing the
|
||
; gibbly file directly.
|
||
; <SM16> 12/1/92 RB Added a call to MakeOverrideMap so that the 'rovm' resource is
|
||
; used to override some system resources.
|
||
; <SM15> 11/20/92 GS Added the EnablePDMsgs for the Quadra 900/950 . This was
|
||
; originally in a linked patch routine to avoid a problem with the
|
||
; KeySw handler early in the boot process.
|
||
; <SM14> 11/18/92 RB Finally, the Disk Cache code is in ROM so we don't need to
|
||
; install ptch 41 (the only one in SuperMario ROMs) anymore.
|
||
; <SM13> 11/3/92 RB Use ROMBase to check for VM being in ROM or not, and call
|
||
; StripAddress on the resource pointer before checkin it, just in
|
||
; case we are in 24 bit mode.
|
||
; <SM12> 11/3/92 fau Corrected a dereference in DetachandExecute.
|
||
; <SM11> 11/01/92 HY Conditionalize changes in <SM10> for LC930 because we don't have
|
||
; VM in ROM.
|
||
; <SM10> 10/30/92 RB Give VM in ROM a chance to load when this file is being used as
|
||
; a ROM Gibbly. VM in ROM is newer than the one in the system and
|
||
; it behaves correctly in SuperMario based ROMs.
|
||
; <SM9> 10/29/92 SWC Changed ShutdownEqu.a->Shutdown.a.
|
||
; <SM8> 10/22/92 CSS Change short branches to word branches.
|
||
; <41> 8/13/92 JDR Offset to CloseTheFile was out of range in ForTheFuture.
|
||
; <40> 8/13/92 DTY #1039434 <BBM>: Don’t register components from QuickTime if
|
||
; we’re booting on a 68000.
|
||
; <39> 7/22/92 csd #1018711: If script extensions can’t be found in the Extensions
|
||
; folder, change <26> added a check for the System Folder. On
|
||
; Install 1 disks, though, we don’t even have that; everything is
|
||
; at the root. So we’ll also check there. This is required so WSI
|
||
; and WSII systems can have Install 1 disks.
|
||
; <38> 6/27/92 DTY #1033818: We decided to leave the Gibbly the current resource
|
||
; map after all, so CurMap needs to be changed to SysMap before
|
||
; LoadDSAT can be called.
|
||
; <37> 6/24/92 DTY #1033818 <csd>: Undo <17> since 'boot' 2 now puts the Gibbly
|
||
; underneath the system resource map before heading into 'boot' 3
|
||
; so that the system will now always be the top resource map.
|
||
; <36> 6/15/92 csd #1032429 <gbm>: Added the file type 'vbnd' to the list of types
|
||
; from which INITs are run. These are Telephone Tools from the
|
||
; Comm Toolbox Telephone Manager.
|
||
; <35> 5/28/92 DTY #1030972: After 'DSAT' 0 is set up, look at a bit in low memory
|
||
; to see if 'boot' 2 could find a Gibbly or not. If it couldn’t,
|
||
; the bit is set, which means that this code should bring up the
|
||
; error alert saying that the disk is too old.
|
||
; <34> 4/29/92 DTY #1027105: Roll out changes from <27>. The script extensions were
|
||
; being loaded, but seconary inits, like Akiko and
|
||
; InputBackSupport were still being disabled since they’re just
|
||
; normal INITs. Making them work would take a lot of hacking
|
||
; around, and that doesn’t give us a nice general solution anyway,
|
||
; so just don’t try to fix the problem at all.
|
||
; <33> 4/23/92 DTY Fix a bug in the linked patch extension mechanism. (I TOLD you
|
||
; it wasn’t tested.) Set up D5 with a pointer to the linked patch
|
||
; loader so that linked patch extensions will work.
|
||
; <32> 4/20/92 DTY #1024149: Don’t prevent DAL from loading if AppleTalk is off.
|
||
; <31> 4/20/92 JSM Moved this file from BootCode.a to Boot3.a, keeping all
|
||
; revisions.
|
||
; <30> 4/17/92 DTY Add mechanism to load linked patch files from the Extensions
|
||
; folder. Conditionalized for theFuture. No, I didn’t test this
|
||
; change. I don’t have an 'lpch' file to test with. And it’s not
|
||
; theFuture yet.
|
||
; <29> 4/16/92 DTY Always include ResourceMgrPriv.a (in case this file is used for
|
||
; a Gibbly), and don’t include LAPEqu.a any more, since the dummy
|
||
; LAP routine went away.
|
||
; <28> 4/15/92 JSM Roll-in changes from SuperMario to support their ROM gibbly,
|
||
; should not change System build. Take out some leftover revision
|
||
; <28> comments from when part of this file lived in
|
||
; StartSystem.a.
|
||
; <27> 4/13/92 DTY #1027105,<csd>: Script extensions should be considered part of
|
||
; required system software, and should not be disabled when the
|
||
; shift key is held down if Roman is not the primary script.
|
||
; Also, removed changes from revision <12>, AppleTalk does the
|
||
; right thing now.
|
||
; <26> 4/2/92 csd #1018711,<FM>: Change the LoadINITFilesInFolder routine to look
|
||
; in the System Folder if there’s an error trying to get the
|
||
; Extensions Folder when loading script extensions.
|
||
; <25> 4/2/92 DTY #1025555,<BBM>: When this file was part of StartSystem.a,
|
||
; MakeSysHeapGrowable was done way early in the boot process. It
|
||
; even does it twice. My worries about doing this so early in the
|
||
; last change are therefore unfounded. Move the first call to
|
||
; MakeSystemHeapGrowable back to StartSystem.a so that Gibblies do
|
||
; not get closed out. Get rid of the check around the second
|
||
; MakeSystemHeapGrowable.
|
||
; <24> 4/1/92 DTY #1025555,<FM>: Add A/UX support.
|
||
; <23> 3/27/92 DTY #1025567: Call _RsrcZoneInit before growing the system heap for
|
||
; the Process Manager to blow away any resources in the
|
||
; application heap that will get trashed by the call to
|
||
; _SetAppBase.
|
||
; <22> 3/26/92 DTY #1024282,<gbm>: I took the MoveHHi out of LinkedPatchLoader, so
|
||
; we don’t need to keep so much stack space in memory all the
|
||
; time. Go back to the way it was before <19>.
|
||
; <21> 3/25/92 FM last checkin was #1025326
|
||
; <20> 3/25/92 FM Rolled in code from StartSystem.a. Now StartSystem.a only
|
||
; contains code to load a gibbly. BootCode.a (the gibbly) now
|
||
; takes care of all startup initialization.
|
||
; <19> 3/20/92 DTY BLT: Since the linked patch loader now calls _MoveHHi, VM is
|
||
; hanging with a double bus fault because the stack pointer is
|
||
; being moved to a paged out page again. Bump up the stack size
|
||
; needed for boot.
|
||
; <18> 3/16/92 DTY #1024540: Load 'pext' (El Kabong printing extensions) files from
|
||
; our special folders.
|
||
; <17> 3/3/92 DTY #1023670: The system 'boot' 3 needs to call _UseResFile before
|
||
; loading linked patches. This is because MacsBug resets CurMap to
|
||
; be the reference number of TopMapHndl, which could be a Gibbly
|
||
; calling the system’s boot code. This causes the linked patch
|
||
; loader to fail since it might not find any 'lpch' resources in
|
||
; the Gibbly.
|
||
; <16> 2/18/92 DTY Use d5 as a flag meaning that we had to implement StripAddress
|
||
; ourselves. If we had to relocate the boot code, check this flag
|
||
; to determine if we patched StripAddress. This lets Scruffy
|
||
; work.
|
||
; <15> 2/11/92 DTY Release the 'lodr' resource after linked patches have been
|
||
; loaded. This frees up about 2K in the system heap.
|
||
; <14> 2/11/92 DCL Changed the name of include file TSMEqu.[aph] to
|
||
; TextServices.[aph] for better read-ability.
|
||
; <13> 1/23/92 csd Make sure that enough pages are in memory before we move the
|
||
; supervisor stack pointer when relocating the boot world. If a
|
||
; stack operation causes a page fault, it creates a double bus
|
||
; fault, guaranteed.
|
||
; <12> 1/19/92 DTY Add a bunch of skanky code to prevent network code from being
|
||
; loaded if AppleTalk is turned off: Set up a fake LAP manager,
|
||
; and don’t load DAL, AppleShare, or FileShare. (And just think
|
||
; about how 7 Up had to do this without changing the boot code!)
|
||
; Also get rid of NewROMCheck since this is done implicitly by the
|
||
; Gibblies.
|
||
; <11> 1/17/92 DTY Don’t set up StkLowPt when relocating the boot world. Setting it
|
||
; causes the stack sniffer to fire.
|
||
; <10> 1/14/92 csd If VM adds memory the machine, relocate the boot world (code,
|
||
; stack, globals) to the new MemTop/2 area. This is because the VM
|
||
; code costs memory in the System heap, and CubeE no longer has
|
||
; room to boot on a 2 megabyte machine. Also, move the BootGlobals
|
||
; record and other equates to BootEqu.a so we don’t have to keep
|
||
; the StartSystem.a and BootCode.a versions in sync.
|
||
; <9> 12/12/91 csd #1017421: with bal, loading the components from the QuickTime
|
||
; init because it won’t since the Component Manager is implemented
|
||
; already. Load components from the System file before we load
|
||
; init files. This doesn’t work yet because the component manager
|
||
; can’t handle 'thng' resources which come from a resource file
|
||
; with the refnum 0, which is what HomeResFile returns for the
|
||
; System.
|
||
; <8> 12/10/91 JH Oops, forgot to fill out the script language record before
|
||
; sending it to SetTextServiceLanguage.
|
||
; <7> 12/9/91 JH Added a little subroutine called TellTSMScriptAndLanguage. It
|
||
; gets called right after _AddScriptFonts and its purpose is to
|
||
; tell the text service manager what the system script and
|
||
; language is.
|
||
; <6> 11/23/91 YK Removed RegisterComponetFile calls. Added ComponentSearch at the
|
||
; end of LoadINITFiles.
|
||
; <5> 11/15/91 DTY Change the resource ID of the 'lodr' resource to match the ones
|
||
; in the Gibbly ERS.
|
||
; <4> 11/12/91 DTY Pass off a pointer to the 'ptbl' resource to the linked patch
|
||
; loader. Change type of linked patch load resource to 'lodr'.
|
||
; <3> 11/11/91 DTY The linked patch loader has been moved to the 'pldr' 0 resource
|
||
; for CPU Gibblies. Get this resource and jump to it instead of
|
||
; importing the label and jsr’ing.
|
||
; <2> 11/8/91 DTY Adding a comment describing why this file is here.
|
||
; <1> 11/8/91 DTY first checked in
|
||
;
|
||
; Change history from StartSystem.a:
|
||
;
|
||
; <56> 11/4/91 YK Register components in the INIT loading loop.
|
||
; <55> 11/4/91 JSM Take out SysPrivateEqu.a again.
|
||
; <54> 10/28/91 SAM Added a default define of false to has3rdFloppy.
|
||
; <53> 10/28/91 SAM/KSM Rolled in Regatta file:
|
||
; On Spike with caches diabled, we patch the MFM WrData vector of
|
||
; the Sony driver so we can use an updated timing constant in the
|
||
; Write code. The original constant is *barely* within spec and
|
||
; with caches disable it is no longer even close.
|
||
; Changed CheckFor040CacheInhibit to use the hwPriv call to push
|
||
; the caches, added a clock rate calculation to determine the
|
||
; amount of adjustment TimeDBRA will require with the caches off
|
||
; on the differently clocked 040s. Added a Terror2 (ROM minor
|
||
; version 17) check to the Zap PRAM routine so it will work on
|
||
; Zydeco.
|
||
; Updated the kNo040CacheTimeDBRA value.
|
||
; Slam a slower/lower TimeDBRA when the 040 caches are inhibited.
|
||
; (jmp) Make the System cmd-opt-r-p PRAM Reset work on TERROR
|
||
; machines to fix a TERROR bug.
|
||
; Changed HighestSupportedBoxFlag to Eclipse33.
|
||
; Added code to inhibit the 68040 caches if the high bit of the
|
||
; MMFlags byte is set (PRAM 8A).
|
||
; Add back the check for Gestalt after loading VM cuz if VM does
|
||
; not load, Gestalt is not yet implemented on non IIci ROM
|
||
; machines.
|
||
; Adding free memory checks after VM loads.
|
||
; Removed the previous revision -- Macsbug has been fixed to load
|
||
; in copyback!
|
||
; Inhibited all 040 caches while loading Macsbug cuz its too
|
||
; brain-damaged to load in copyback.
|
||
; <52> 9/16/91 JSM Cleanup header, don’t include SysPrivateEqu.a (already in dump
|
||
; file).
|
||
; <51> 7/2/91 JSM Remove obsolete 7.0 related SysVers conditionals.
|
||
; <50> 6/12/91 LN added #include 'InternalOnlyEqu.a'
|
||
; <49> 6/11/91 gbm Take out conditional for Regatta
|
||
; <48> 4/13/91 stb dty, BRC#86692: Replace WhichCPU (borrowed from ROM) with
|
||
; HandleMacIIWith030. Now handle exactly one case where we help
|
||
; accelerators be VM-capable.
|
||
; <47> 4/2/91 SAM Bumping HighestSupportedBoxFlag for Regatta build.
|
||
; <46> 3/31/91 csd dba: Changed the test for 040 in the WhichCPU routine so that it
|
||
; doesn’t jam 0 into the CACR, thereby possibly nuking any data
|
||
; which has not been flushed out of the cache.
|
||
; <45> 3/13/91 stb bbm, #83253: setup and use new ExpandMem global
|
||
; emMinSysHeapFreeSpace which specifies how much elbow room to
|
||
; leave in the system/process mgr heaps.
|
||
; <44> 2/19/91 gbm csd, #Go5 approved: Make sure _MemoryDispatch is NOT implemented
|
||
; on machines without PMMUs. Also fix the related bug in the ci
|
||
; ROM that sets MMUType wrong.
|
||
; <43> 2/15/91 gbm stb & dba, BRC # 82829: Fix the WhichCPU routine so that is
|
||
; stops turning off data cache and data bursting on '030s
|
||
; <42> 2/11/91 stb gbm, WS #stb211: change BSR.S back to BSR so MacsBug won’t die
|
||
; if you bail during install (by holding down the mouse button).
|
||
; Disassembler, too.
|
||
; <41> 2/11/91 stb gbm, BRC # 82423: implement StripAddress early enough to use
|
||
; when installing VM
|
||
; <40> 1/29/91 csd stb, Whiteboard Bug: Moved the SetDefaults code to an earlier
|
||
; position so that it executes before code that uses the
|
||
; variables.
|
||
; <39> 1/23/91 stb TED,81551: test a result code before BCC’ing.
|
||
; <38> 1/19/91 stb & DC (& dfh for some of it) change 'dbex' id; adjust file cache
|
||
; allowance; coordinate upward and downward growth limits.
|
||
; <37> 1/14/91 stb & mda; more net booting stuff; disable extension disabling if
|
||
; desired; do DoWeHaveEnoughRAMToBoot earlier; give file cache a
|
||
; little less BufPtr room. add culprit names for VM, Debugger,
|
||
; Disassembler; jam CPUflag to support 3rd-party processors for
|
||
; VM.
|
||
; <36> 12/18/90 stb & JDR; add error check after _MemoryDispatch.
|
||
; fix infinite loop in MakeSysFree if couldn’t get desired amount.
|
||
; <35> 12/15/90 stb & KSM; move the currently-executing filename to avoid conflict
|
||
; with INITs which check CurApName to see if it’s post-boot time.
|
||
; Replace error 106 with 25. Remove _MemoryDispatch declaration.
|
||
; <34> 12/13/90 stb & gbm; no longer load AppleTalk from a file.
|
||
; Use source to GetDefaultStartup to avoid problem on Plus.
|
||
; Reserve 100K for post-boot allocations by Process Mgr & Finder.
|
||
; <33> 12/12/90 stb & gbm; pass bufPtrLimit to LoadFileSystemCache code
|
||
; & dba; added 'appe' (background app) to the list of boot-executables.
|
||
; & bbm; add Cmd-Option-pr to reset PRAM on Plus, SE, II, Portable
|
||
; & k s; add net booting hooks
|
||
; <32> 11/15/90 stb & JDR; move dsBufPtrTooLow to SysErr.a
|
||
; <31> 11/9/90 dba & JSM; move 8•24 GC loading before script system loading
|
||
; <30> 11/1/90 dba & stb; some misc. cleanup; fix bug where we were checking
|
||
; against the wrong value for the barrier; fix obscure error
|
||
; handling bug in NewPtrStartup; add NewPtrStartup for post-boot
|
||
; that returns an error; add an ellipsis on the end of long file
|
||
; names, instead of relying on smart code in the DSAT; put in the
|
||
; file name for all files opened outside the system file, not just
|
||
; for files with INIT resources
|
||
; <29> 10/31/90 dba & csd; add code to load the 8•24 GC support code
|
||
; <28> 10/30/90 stb & BBM; make booting safer and more predictable in low-memory
|
||
; conditions.
|
||
; <27> 10/22/90 JJ Rex V8: Change all box flag references to use boxMacLC. Get rid
|
||
; of boxElsie and boxElsieV8.
|
||
; <26> 10/1/90 dba add innocuous value for location 0
|
||
; <25> 9/25/90 SAM Bumped highestBoxFlag to ElsieV8.
|
||
; <24> 9/22/90 gbm (with dba) change the routines that could kill ApplZone so that
|
||
; they do InitApplZone to get rid of the old contents
|
||
; <23> 9/16/90 gbm Fix detatching of system INITs. I don't think it ever worked...
|
||
; <22> 9/10/90 dba fix name copy bug
|
||
; <21> 8/27/90 VL (actually dba) set TheZone to SysZone when doing
|
||
; MakeSystemHeapGrowable since the application heap goes away.
|
||
; <20> 8/10/90 dba load A/ROSE and AppleTalk; this obsoletes INIT 18 and prevents
|
||
; the need for INIT 16
|
||
; <19> 8/6/90 stb add test for at least 1.5MB to make sure we can boot 7.0
|
||
; <18> 7/20/90 dba get rid of PTCH -1
|
||
; <17> 6/22/90 dba (with emt) move this code onto the stack to avoid fragmenting
|
||
; the system heap
|
||
; <16> 6/11/90 EMT Moved alternate trap dispatcher loading from patch files.
|
||
; <15> 5/29/90 DDG NEEDED FOR SIXPACK: Changed all the sixpack conditionals from
|
||
; six-point-oh-seven to six-point-oh-six.
|
||
; <14> 5/11/90 PKE NEEDED FOR SIXPACK: if this file is used for 6.0.6:
|
||
; Conditionalized early loading of script systems (see <9> and
|
||
; <13>) on SysVers >= $700. ALSO (for 7.0 only): Added call to new
|
||
; Script Mgr _AddScriptFonts routine after all INITs.
|
||
; <13> 5/5/90 PKE Added call to Script Mgr _InitScripts (new) after script system
|
||
; installation.
|
||
; <12> 4/25/90 dba change MMU check in LoadVM section (also add feature to load
|
||
; MacsBug before VM)
|
||
; <11> 4/20/90 dba check to see that the Shift key is the only key held down for
|
||
; Extensions Disabled
|
||
; <10> 4/20/90 dba close QD port much earlier; it isn’t doing anyone any good; do
|
||
; InitApplZone for each INIT file; rely on patch to SetAppBase to
|
||
; do InitApplZones
|
||
; <9> 4/19/90 dba add support for Script Systems; increase system heap size
|
||
; <8> 4/19/90 dba make StartupScreens and Disable Extensions work
|
||
; <7> 4/18/90 dba change bsr.s to bsr (I will never check in w/o building)
|
||
; <6> 4/18/90 dba change branch from pl to mi to fix MakeSysFree bug (INITs were
|
||
; not being loaded); restuff dirID to make setting of the noINITs
|
||
; bit work right
|
||
; <5> 4/17/90 dba fix bug with InitApplZone stuff
|
||
; <4> 4/16/90 csd save registers around calls to ptch and PTCH resources since
|
||
; they don’t obey the register saving conventions.
|
||
; <3> 4/11/90 dba put dynamic system heap size code for the Plus and SE back here;
|
||
; do InitApplZone before each INIT, instead of after each
|
||
; MakeSysFree; detach ourselves so we can support remote booting
|
||
; closing the System file and opening a new one
|
||
; <2> 4/10/90 dba fix bugs in MakeSysFree (wrong register d2 vs. d0 and possible
|
||
; error where size is odd)
|
||
; <1> 4/9/90 dba new today
|
||
;
|
||
; Change History from data fork of System file:
|
||
;
|
||
; <5> 3/22/90 dba change name of LoadPatch to LoadLinkedPatches
|
||
; <4> 3/21/90 dba take out the lingering Debugger statement
|
||
; <3> 3/21/90 dba change to work with new boot blocks for 7.0
|
||
; <2> 12/28/89 dba use MAIN instead of PROC to get dead code stripping; also get
|
||
; rid of wierd header that was required by a strange build rule in
|
||
; the old Make file; a corresponding change was made in
|
||
; SysObj.Make
|
||
; <1.5> 11/17/89 dba got rid of checks for 64K ROMs
|
||
; <1.4> 10/14/89 EMT Always load in RAM cache in system 7.
|
||
; <1.3> 6/5/89 EMT One more try.
|
||
; <1.2> 6/2/89 EMT Fixed coding errors in 1.1.
|
||
; <1.1> 6/1/89 EMT Removed ROM69 stuff. Bootstrap StripAddress if it doesn’t exist.
|
||
; Use StripAddress before executing 'PTCH's.
|
||
; <1.0> 11/16/88 CCH Added to EASE.
|
||
; <S174> 4/10/87 bbm Save off the A5 world for the inits. (Some inits relied on
|
||
; CurrentA5 to be set up.)
|
||
; <S145> 3/27/87 bbm The algorithm that S115 used to grow the heap was to enlarge the
|
||
; heap by 16k or the size of the patch - whichever was bigger.
|
||
; What you really want is 16k free in addition to the size of the
|
||
; patch.
|
||
; <S128> 3/23/87 JTC On 64K ROMs be sure not to use nonexistent traps (such as
|
||
; SizeRsrc) or resize heap (since boot blocks are loaded at 64K).
|
||
; <S115> 3/19/87 JTC Ensure sufficient sys heap space before loading patches, using
|
||
; SizeResource to figure the local min. Then guarantee MinSysExtra
|
||
; space after loading last one. Code borrowed from INIT=31.
|
||
; <S109> 3/18/87 bbm Added the code for ‘PTCH $FFFF’. This enables general patches
|
||
; for all machines before the patches are read in by ‘PTCH 0’ and
|
||
; general patches after the patches are read in by ‘PTCH $FFFF’.
|
||
; <S108> 3/17/87 bbm For system heaps larger than 58k, rom69patch needed to move the
|
||
; boot code (the boot code is loaded in at $10000). Since the boot
|
||
; code has moved, the return address on the stack should be
|
||
; modified. If you change the nature of the stack — which rom69fix
|
||
; depends on - you must also modify rom69fix.a.
|
||
; <P029> 1/22/87 JTC JTC The above dates should surely be ‘86 and the res type is now
|
||
; 'PTCH', despite the above comments. This change is to
|
||
; accommodate the new PTCH=0 patch file for all systems.
|
||
; 11/20/86 BB Changed resource type for patch files from 'PTCH' to 'ptch'.
|
||
; 11/15/86 BB New today.
|
||
;
|
||
; Change History from INIT 31:
|
||
;
|
||
; <2> 2/19/90 sad <version 5>
|
||
; look into Extensions and Control Panels folders using Folder
|
||
; Mgr; use 1-deep resource calls instead of 64K ROM-compatible
|
||
; hacks; got rid of d7 hack for 64K ROMs; assures MinSysFree after
|
||
; last INIT file instead of before first
|
||
; <1.4> 11/17/89 dba got rid of checks for 64K ROMs
|
||
; <1.3> 6/19/89 CCH Removed check for files of type 'mntr' from version 1.2.
|
||
; <1.2> 2/21/89 CCH Added 'mntr' type to list of files that contain INITs.
|
||
; <1.1> 1/17/89 CCH Merged changes from 6.0.3.
|
||
; <1.0> 11/16/88 CCH Added to EASE.
|
||
; <S424> 3/15/88 DBG Prevent invisible INIT files from running
|
||
; <S393> 2/12/88 JRM Use fndrInfo bit to eliminate extra OpenResFiles. Set the bit if
|
||
; no INIT resources are found for a file. Check the bit before
|
||
; calling OpenResFile
|
||
; <SB293> 10/2/87 DAF Added an InitGraf before the InitPalettes so that all gDevices
|
||
; will be active.
|
||
; <S285> 9/21/87 DAF Changed the ROM85 test in s277 to test MacII or greater, rather
|
||
; than equal.
|
||
; <S277> 9/16/87 DAF Added InitPalettes here before INIT files are loaded. This
|
||
; causes the data structures to be allocated early rather than
|
||
; during the first init that calls _InitWindows.
|
||
; <S173> 4/10/87 JTC Fix CDEV to be cdev.
|
||
; <S114> 3/19/87 JTC Fix to get 16K min in sys heap even if no RDEV,INIT,CDEV files.
|
||
; Also, look for CDEV files too.
|
||
; <S9> 2/14/87 JTC Call InitApplZone after SetApplBase to get initialation
|
||
; attendant thereto.
|
||
; <S6> 1/5/87 JTC Add new resource 'sysz' comprising just one long word to request
|
||
; said amount of system heap space. Put code into inner loop of
|
||
; loading and executing INITs below to guarantee #MinSysExtra
|
||
; (borrowed from start code) free space at every execution.
|
||
; 8/4/86 DLD Converted source to MPW.
|
||
;
|
||
; System 3.1
|
||
;
|
||
; 2/8/86 JTC&LAK Fixed bug in patching return address into boot blocks after the
|
||
; boot blocks have been moved. Also added a BCLR to assure that
|
||
; the half-way point in memory is even after the DIV by 2.
|
||
; 2/5/86 LAK Fixed bug for Shuffle: return address needs to be updated after
|
||
; stack move.
|
||
;
|
||
; for InfoSphere
|
||
;
|
||
; 1/7/86 LAK On old ROMs: if not called from $10000 space or BufPtr has been
|
||
; moved below MemTop/2 + 1K already then punt the normalization.
|
||
; Someone has probably already 'normalized' the world, hopefully
|
||
; correctly.
|
||
;
|
||
; System Tools Disk for Plus
|
||
;
|
||
; 12/10/85 LAK Modified to look for files of both INIT and RDEV types.
|
||
; 12/6/85 ELR New Today
|
||
;
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; equates
|
||
|
||
supportsMFM equ 1
|
||
|
||
If &type('has3rdFloppy') = 'UNDEFINED' Then
|
||
has3rdFloppy: equ 0
|
||
EndIf
|
||
|
||
load 'StandardEqu.d'
|
||
include 'MMUEqu.a'
|
||
include 'BootEqu.a'
|
||
include 'EgretEqu.a' ; <15>
|
||
include 'Folders.a'
|
||
include 'GestaltEqu.a' ; <33>
|
||
include 'HardwarePrivateEqu.a' ; just for hwCbAUX
|
||
include 'LinkedPatchMacros.a' ; For kROMVersion equates <10>
|
||
include 'ReliabilityEqu.a' ; just for RelPRAM <33>
|
||
include 'ResourceMgrPriv.a' ; for SetupResourceFileAttributes & Resource Override traps <28> <29>
|
||
include 'ScriptPriv.a' ; <13>
|
||
include 'ShutDown.a' ; just for _SDRestart <33><SM9>
|
||
include 'SonyEqu.a' ; <11>
|
||
include 'TextServices.a' ; so we have SetTextServiceLanguage <14>
|
||
include 'UniversalEqu.a' ; <15>
|
||
|
||
MACHINE MC68020 ; <SM28>
|
||
|
||
|
||
_AUXDispatch opword $ABF9 ; <24> A/UX’s trap dispatch *** move to Traps.a
|
||
auxSecondaryInit equ 36 ; <24> Parameter for _AUXDispatch
|
||
auxExtraDebuggerSize equ $1c00-debuggerGlobalSize ; <24> Amount of additional storage space required by A/UX for MacsBug
|
||
|
||
bFInvisible equ 7 ; bit in ilFlUsrWds+fdFlags which means an invisible file
|
||
bFNoINIT equ 7 ; bit in ilFlUsrWds+fdFlags+1 which means no INIT resources
|
||
|
||
vmDebugSignature equ 'JB' ; magic number to debug VM
|
||
bbVMDebugSignature equ bbPageFlags ; boot blocks offset of magic word to debug VM
|
||
|
||
kNo040CacheTimeDBRA25MHz equ 1560 ; # of DBRA's per ms with 25MHz 040 caches inhibited <8>
|
||
kNo040CacheTimeDBRA33MHz equ 1513 ; # of DBRA's per ms with 33MHz 040 caches inhibited <9>
|
||
k040CyclesPerDBRA equ 4 ; # of cycles it takes an 040 to execute a DBRA <9>
|
||
kNoCacheWriteAdj equ $30EA ; No Caches Write Delay constant <11>
|
||
kBootStackSizeNeeded equ $2000 ; this many bytes of stack should be in physical memory <12> <19> <22>
|
||
|
||
kNetBootNameID equ -16507 ; name of NetBoot file <33>
|
||
kNetBootProcID equ -16507 ; id of the net boot proc resource <33>
|
||
kNetBootDriverRefNum equ -50 ; refnum if we are to load the net booter <33>
|
||
|
||
kAROSENameID equ -16501 ; name of A/ROSE file
|
||
kAppleTalkNameID equ -16500 ; name of AppleTalk file
|
||
k8Dot24GCNameID equ -16454 ; name of 8•24 GC file <29>
|
||
|
||
kLinkedPatchFileID equ 'lpch' ; <30> File type containing a bunch of 'lpch' resources.
|
||
kPatchLoaderResourceType equ 'lodr' ; Resource type containing linked patch loader
|
||
kPatchLoaderResourceID equ -16385 ; Resource ID of resource containing linked patch loader
|
||
|
||
kPatchTableResourceType equ 'ptbl' ; Resource type containing patch table ranges
|
||
|
||
kFileShareCreator equ 'hhgg' ; <12>
|
||
kAppleShareCreator equ 'afps' ; <12>
|
||
kDALCreator equ 'dald' ; <12>
|
||
|
||
IF forROM THEN ; <28>
|
||
|
||
SysVersForROM equ $0710 ; <28> jam Cube-E system version into SysVersion lowmem for now
|
||
|
||
kROMVersionPlus equ $0075 ; <28>
|
||
kROMVersionSE equ $0276 ; <28>
|
||
kROMVersionII equ $0178 ; <28>
|
||
kROMVersionPortable equ $037A ; <28>
|
||
kROMVersionIIci equ $067C ; <28>
|
||
kROMVersionSuperMario EQU $077D ; <28>
|
||
|
||
ENDIF ; <28>
|
||
|
||
|
||
BootCode MAIN
|
||
|
||
|
||
; Registers passed in from boot blocks:
|
||
; A3 = handle to this resource
|
||
; A4 = dirID of the startup application (for pre-7.0 systems; used by the remote booting INIT)
|
||
; A5 = pointer to globals (SP + 400)
|
||
; A6 = pointer to boot blocks (used by the remote booting INIT)
|
||
|
||
move.l a3,a0 ; get the size of this boot code
|
||
_GetHandleSize
|
||
lea @continue,a0 ; copy from @continue to the end of the boot code
|
||
lea BootCode,a1
|
||
sub.l a0,a1 ; get BootCode-@continue
|
||
add.l a1,d0 ; fix up size
|
||
|
||
sub.l d0,sp ; make room on the stack
|
||
move.l sp,a1 ; copy onto the stack
|
||
_BlockMove ; move it up
|
||
jmp (a1) ; pass control there
|
||
@continue
|
||
move.l a3,-(sp) ; get rid of the resource
|
||
_ReleaseResource ; and continue with booting as normal
|
||
|
||
move.l ROMBase,a0 ; point into a safe place in ROM
|
||
add.l #$10000,a0 ; 64K into the ROM is always safe
|
||
move.l a0,0 ; jam this nice value into location 0
|
||
|
||
move.l sp,CurStackBase ; MacsBug works better if CurStackBase is set up
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
SetUpStartupScreen
|
||
|
||
; Load everything we need for “Welcome to Macintosh” or a startup screen.
|
||
|
||
move.w SysMap,CurMap ; <38> Make the System the current map so the DSAT will load.
|
||
moveq #0,d0 ; load DSAT 0
|
||
bsr LoadDSAT ; get the handle
|
||
move.l d0,d6 ; stash this away to dispose later
|
||
|
||
;____________________________________________________________________________________
|
||
; Process Manager segment tweaks.
|
||
;
|
||
; Load these 'scod' resource as low as possible in the system heap to reduce
|
||
; system heap fragmentation.
|
||
;
|
||
; Moved this code here so the 'scod's are THE first resources in the heap. Reduces
|
||
; fragmentation (7/20/93) SAM <SM28>
|
||
|
||
kProcessManagerSegmentType equ 'scod' ; Process Manager segment resource type <28>
|
||
|
||
subq #2,sp ; make room in stack for old resfile id <28>
|
||
_CurResFile ; Remember the current resource file, in case we’re booting from a gibbly <28>
|
||
clr.w -(sp) ; id zero is always the system file <28>
|
||
_UseResFile ; Work on the System file <28>
|
||
|
||
lea ProcessManagerSegmentTable,a1 ; Table of Process Manager segments to load low <28>
|
||
@loadSegmentLoop ; <28>
|
||
|
||
move.w (a1)+,d1 ; Get a segment number <28>
|
||
bz.s DoneWithSegments ; Been there, done that. <28>
|
||
subq #4,sp ; room for handle result <28>
|
||
move.l #kProcessManagerSegmentType,-(sp) ; push res type <28>
|
||
move.w d1,-(sp) ; push id <28>
|
||
_Get1Resource ; Load it in <28>
|
||
addq #4,sp ; We don’t really care about the resource <28>
|
||
bra.s @loadSegmentLoop ; go for the next one <28>
|
||
|
||
ProcessManagerSegmentTable ; <28>
|
||
|
||
dc.w $BFAC ; MiscSeg <28>
|
||
dc.w $BFB0 ; KernelSeg <28>
|
||
dc.w $BFB2 ; EPPCSeg <28>
|
||
dc.w 0 ; End of table <28>
|
||
|
||
DoneWithSegments ; <28>
|
||
_UseResFile ; The current resource file is on the stack <28>
|
||
|
||
|
||
bsr EraseMyIcon ; Erase the happy Mac a little later (after the processmgr loads) <SM28>
|
||
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
ShowStartupScreen
|
||
|
||
; First, open the resource fork of the startup screen file to look for a 'PICT' (0) resource.
|
||
|
||
moveq #1,d7 ; no startup screen is up yet
|
||
|
||
subq #2,sp ; make room for refNum
|
||
pea BootGlobals.bootBlocks+bbScreenName(a5)
|
||
_OpenResFile ; open the file
|
||
move.w (sp)+,d0 ; get the refnum
|
||
bmi.s @noResourceFork
|
||
move.w d0,-(sp) ; push back the refNum for later closing
|
||
|
||
subq #4,sp ; make room for handle
|
||
clr.w -(sp)
|
||
_GetPicture
|
||
move.l (sp)+,d0 ; check handle
|
||
bz.s @noPICTResource
|
||
|
||
move.l d0,a2 ; save the handle for later
|
||
move.l (a2),a0 ; dereference it
|
||
|
||
move.l picFrame+botRight(a0),-(sp) ; push the picture’s bounds rect
|
||
move.l picFrame+topLeft(a0),-(sp)
|
||
bsr CenterOnMainScreen ; center a rectangle on the screen
|
||
move.l a2,-(sp) ; get the picture handle
|
||
pea 4(sp) ; pass the centered rectangle
|
||
_DrawPicture
|
||
|
||
addq #8,sp ; get rid of the rectangle on the stack
|
||
|
||
moveq #0,d7 ; a startup screen has been displayed
|
||
@noPICTResource
|
||
_CloseResFile ; close the file (refNum left on stack from above)
|
||
@noResourceFork
|
||
|
||
tst.b d7 ; did we put something up there?
|
||
bz.s @done ; yes, we are done
|
||
|
||
; Now, try the data fork of the startup screen file to look for something to display on the screen.
|
||
|
||
lea BootGlobals.bootBlocks+bbScreenName(a5),a1
|
||
bsr LoadBelowBufPtr
|
||
bnz.s @noDataFork
|
||
cmp.l #342*512/8,d2 ; is the whole thing there?
|
||
blo.s @noDataFork
|
||
|
||
move.l #((342<<16)+512),-(sp) ; put a rect the size of the original Mac screen
|
||
clr.l -(sp) ; on the stack (0,0,342,512) as bounds for a bitMap
|
||
bsr CenterOnMainScreen ; center a rectangle on the screen
|
||
move.w #512/8,-(sp) ; now push the rowBytes of the bitMap
|
||
move.l a2,-(sp) ; and push the base address of the bitMap
|
||
|
||
move.l sp,-(sp) ; srcBits is here
|
||
pea BootGlobals.port+portBits(a5) ; dstBits is the screen
|
||
pea 8+bounds(sp) ; srcRect and dstRect is the one we computed
|
||
move.l (sp),-(sp)
|
||
clr.w -(sp) ; srcCopy mode
|
||
clr.l -(sp) ; no maskRgn
|
||
_CopyBits
|
||
|
||
lea bitMapRec(sp),sp ; get rid of our bitMap on the stack
|
||
|
||
moveq #0,d7 ; a startup screen has been displayed
|
||
bra.s @done
|
||
@noDataFork
|
||
|
||
; Now, do the welcome screen.
|
||
|
||
moveq #dsGreeting,d0 ; put up the greeting
|
||
_SysError
|
||
|
||
@done
|
||
|
||
|
||
IF NOT forROM THEN
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
UnimplementedTrap EQU $9F
|
||
MemoryDispatchTrap EQU $5C
|
||
|
||
SetUpCPUFlag
|
||
|
||
; HandleMacIIWith030 decides whether the processor is an 030 with MacII ROMs.
|
||
; We put it here so that 030 accelerator boards can work where the
|
||
; ROM doesn't know how to check for them. We ignore 040's because either the ROM must know about
|
||
; them or the vendor is doing some hardware magic to make it work without our help.
|
||
|
||
bsr HandleMacIIWith030 ; <48>
|
||
|
||
FixMMUTypeAndKillMemoryDispatch
|
||
|
||
; The ci ROM has a bug in 32-bit mode which causes MMUType to be set to $FF. So, if MMUType
|
||
; is $FF, we set it to the right thing. _MemoryDispatch is mistakenly implemented
|
||
; in 32-bit mode on machines where there is no MMU (because of the previous bug....).
|
||
; So, for machines without an MMU, we’ll unimplement the call.
|
||
; NOTE: The MMUType that we set here is a "best guess", since checking for PMMU vs. HMMU at
|
||
; this point is hard to do. We're assuming that accelerator makers will either:
|
||
; have this set up correctly before we get here, or set it up correctly later on.
|
||
|
||
tst.b MMUType ; check if MMUType has been setup
|
||
bpl.s @keepAGoin ; if it's positive, it has been
|
||
|
||
clr.l d0 ; <48>
|
||
move.b CPUFlag,d0 ; <48>
|
||
lea @DefaultMMUTypes, a0 ; point to our table of defaults
|
||
move.b (a0, d0.w), MMUType ; get the default type of MMU
|
||
|
||
cmp.b #cpu68030, d0 ; are we at least on an '030?
|
||
bge.s @keepAGoin ; yes, then assume MemoryDispatch is okay to have around
|
||
|
||
move.w #UnimplementedTrap, d0 ; no, then set MemoryDispatch be the same as
|
||
_GetTrapAddress ; the Unimplemented trap.
|
||
move.w #MemoryDispatchTrap, d0
|
||
_SetTrapAddress newOS
|
||
|
||
bra.s @keepAGoin
|
||
|
||
@DefaultMMUTypes
|
||
dc.b NoMMU ; 68000 - no MMU
|
||
dc.b NoMMU ; 68010 - no MMU
|
||
dc.b HMMU ; 68020 - HMMU (but could be 68851... oh well)
|
||
dc.b PMMU030 ; 68030 - '030 MMU
|
||
dc.b PMMU040 ; 68040 - '040 MMU
|
||
align
|
||
@keepAGoin
|
||
ENDIF ; NOT forROM
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; CheckFor040CacheInhibit - If we're on an 040 machine and bit 7 of MMFlags (PRAM byte 8A) is set
|
||
; then inhibit the caches (can you say sssloooowwww?) and update TimeDBRA
|
||
; according to a calculated Clock rate (25 or 33Mhz currently). <SAM>
|
||
|
||
|
||
CheckFor040CacheInhibit ; <5> SAM
|
||
|
||
CMPI.B #cpu68040,cpuFlag ; Are we on an 040?
|
||
BNE.S @Continue ; -> Nope, do nothing
|
||
BTST.B #7,MMFlags ; Check the inhibit all caches bit in MMFlags
|
||
BEQ.S @Continue ; -> Leave them enabled
|
||
|
||
_FlushInstructionCache ; Push both caches back to RAM (FlushICache will do both caches) <10>
|
||
|
||
MACHINE MC68040 ; Generate 040 MOVEC instructions... <SM28>
|
||
|
||
MOVEC CACR,D0 ; Get the CAcheControlRegister
|
||
AND.L #~((1<<CACR_DE_040)|(1<<CACR_IE_040)),D0 ; Create a mask excluding the DE & IE bits
|
||
MOVEC D0,CACR ; Clear DE & IE in the CACR (caches are now inhibited)
|
||
|
||
MACHINE MC68020
|
||
|
||
MOVEQ #0,D0 ; Clear D0 <10>
|
||
MOVE.W TimeDBRA,D0 ; Get TimeDBRA <10>
|
||
DIVU.W #(1000/k040CyclesPerDBRA),D0 ; Compute the clock rate based on TimeDBRA & k040CyclesPerDBRA <10>
|
||
|
||
CMPI.W #28,D0 ; Pick a value between 25 & 33 <10>
|
||
BLS.S @Slam25 ; -> 25 MHz <10>
|
||
|
||
@Slam33 MOVE.W #kNo040CacheTimeDBRA33MHz,D0 ; Get the 33Mhz constant <10>
|
||
BRA.S @SetIt ; -> Set it
|
||
@Slam25 MOVE.W #kNo040CacheTimeDBRA25MHz,D0 ; Get the 25Mhz constant <10>
|
||
@SetIt MOVE.W D0,TimeDBRA ; Stuff the value
|
||
|
||
IF NOT forROM THEN ; Do not install this patch when this file is being <28>
|
||
; built as a ROM gibbly, the ROM is fixed. <28>
|
||
|
||
CMPI.B #boxQuadra700,boxFlag ; Are we on a Spike? (Quadra 700) <11><61>
|
||
BNE.S @Continue ; -> No. Do not install patch to MFMWrData <11>
|
||
|
||
LEA EndCachesOffMFMPatch,A0 ; Point to the end of the Patch <11>
|
||
LEA CachesOffMFMPatch,A1 ; Load the "Caches are off, fix the floppy MFM write code" patch <11>
|
||
MOVE.L A0,D0 ; Make a copy of the patch's starting address <11>
|
||
SUB.L A1,D0 ; Calc the size of the Floppy patch <11>
|
||
MOVE.L D0,D3 ; Copy the size to D3 <11>
|
||
|
||
_NewPtr ,Sys ; Get a block of Sys Heap memory <11>
|
||
BNE.S @Continue ; -> No mem. Exit <11>
|
||
|
||
EXG.L A0,A1 ; Swap src w/dest
|
||
MOVE.L D3,D0 ; Size
|
||
_BlockMove
|
||
|
||
MOVE.L A1,jMWrData ; Install the patch in the sony Write Data vector <11>
|
||
|
||
ENDIF ; <28>
|
||
|
||
@Continue
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
; Install the new dispatcher for systems that need it.
|
||
|
||
import InstallDispatch
|
||
jsr InstallDispatch
|
||
|
||
;——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
CheckForExtensionsDisabled
|
||
|
||
; If the Shift key is held down, disable loading of all Extensions, including VM and INITs,
|
||
; and background applications, and Finder Startup Folder.
|
||
|
||
; Do not allow disabling if a 'dbex' resource is not present. This allows users to ensure that
|
||
; their INITs will run (e.g. security packages). <37>
|
||
|
||
clr.b ResLoad ; no preloads please
|
||
subq #4,sp ; make room for function result
|
||
move.l #'dbex',-(sp) ; if present, allow user to Disable Extensions
|
||
move.w #-16385,-(sp) ; 'dbex' (-16385)
|
||
_GetResource
|
||
st ResLoad ; restore resLoad to proper state
|
||
move.l (sp)+,d0 ; did we get a handle?
|
||
bz.s @dontDisable ; no, user won’t get to disable
|
||
move.l d0,-(sp) ; get rid of the empty handle
|
||
_ReleaseResource
|
||
|
||
movem.l KeyMap,d0-d3 ; get four words worth of keys
|
||
bclr #7,d3 ; clear off the power key
|
||
bclr #1,d1 ; clear off the Caps Lock key
|
||
bclr #0,d1 ; clear off and test the Shift key
|
||
bz.s @dontDisable ; Shift key not held down, don’t disable extensions
|
||
or.l d1,d0 ; stray keys held down?
|
||
or.l d2,d0
|
||
or.l d3,d0
|
||
bnz.s @dontDisable ; yes, don’t disable extensions
|
||
|
||
bclr #extensionsEnabledBit,ExtensionsEnabledByte ; disable extensions
|
||
moveq #dsExtensionsDisabled,d0
|
||
bsr BootAlert ; put up an alert if we should
|
||
@dontDisable
|
||
|
||
;___________________________________________________________________________
|
||
|
||
ResetPRAM
|
||
|
||
; CheckForResetPRAM: Checks for the Cmd-Option-R-P keys down, and Resets PRAM <33>
|
||
; if they are down.
|
||
;
|
||
; Only do this if we’re on a Plus ($0075), SE ($0276), II ($0178), or Portable ($037A).
|
||
; Reset the extended parameter RAM by invalidating the validity longword.
|
||
;
|
||
; TERROR ROM note: There is a bug in the TERROR ROM where the cmd-opt-r-p sequence <7> jmp
|
||
; sometimes doesn’t work (a register is being trashed). So, to rectify this problem,
|
||
; we go ahead and let the reset fly on TERROR ROM machines even though they are
|
||
; IIci overpatches. This problem seems to be most accute on Spikes, so we may
|
||
; be able to restrict this code to Spikes only. Still investigating.
|
||
;
|
||
; *** TO DO:
|
||
; reset mouse speed in original PRAM to medium speed on all machines
|
||
|
||
; Keymap’s locations for Cmd-Opt-P-R
|
||
; Cmd = $37 => bit .15 of D1
|
||
; Opt = $3A => bit .2 of D1
|
||
; P = $23 => bit .27 of D1
|
||
; R = $F => bit .23 of D0
|
||
|
||
clr.w BootGlobals.resetFlag(a5) ; by default, don’t reboot
|
||
movem.l KeyMap,d0-d3 ; get four words worth of keys
|
||
|
||
; clear off keys which might be down but we don’t care about
|
||
bclr.l #7,d3 ; clear off the power key
|
||
bclr.l #1,d1 ; clear off the Caps Lock key
|
||
|
||
; test for the keys we do care about, clearing them as we test
|
||
; test for only Cmd, Option, and P, taking care of all tests on D1.
|
||
eori.l #(1<<15)+(1<<2)+(1<<27),d1
|
||
bne @noReset
|
||
|
||
; the only bit left set should be the R bit, so we’ll change it,
|
||
; and then OR everything together, and reset PRAM only if
|
||
; everything is clear.
|
||
bchg.l #23,d0 ; change the R key bit
|
||
|
||
or.l d2,d0 ; OR together everything that’s left
|
||
or.l d3,d0
|
||
bnz.s @noReset ; something else is down, don’t reset PRAM
|
||
|
||
; now check to see if we’re on a ROM which needs resetting help
|
||
movea.l ROMBase,a0
|
||
move.w 8(a0),d2
|
||
cmp.w #kROMVersionPlus,d2
|
||
beq.s @resetPRAM
|
||
cmp.w #kROMVersionSE,d2
|
||
beq.s @resetPRAM
|
||
cmp.w #kROMVersionII,d2
|
||
beq.s @resetPRAM
|
||
cmp.w #kROMVersionPortable,d2
|
||
beq.s @resetPRAM ; <7> jmp
|
||
cmp.w #kROMVersionIIci,d2 ; <7> jmp
|
||
beq.s @chkMinorVers ; <7> jmp
|
||
bra.s @noReset ; <7> jmp
|
||
|
||
@chkMinorVers ; <7> jmp
|
||
move.b 18(A0),d2 ; <7> jmp
|
||
cmp.b #kROMMinorTERROR,d2 ; <7> jmp
|
||
beq.s @resetPRAM ; <7> jmp
|
||
cmp.b #kROMMinorTERROR2,d2 ; <9> SAM
|
||
beq.s @resetPRAM ; <9> SAM
|
||
bra.s @noReset ; <7> jmp
|
||
|
||
@resetPRAM ; stolen from StartInit.a
|
||
lea @stuff,a1 ; stuff to write into PRAM
|
||
subq.w #RelPram>>16,sp ; allocate buffer on stack
|
||
movea.l sp,a0 ; get buffer ptr
|
||
move.l #RelPram,d0 ; get #, addr PRAM bytes
|
||
_ReadXPram ; read the reliability MGR info
|
||
movea.l a1,a0 ; point to table data
|
||
move.l (a0)+,d0 ; get PRAM len/addr, point to data
|
||
_WriteXPRam ; kill the extended PRAM signature
|
||
lea SysParam,a0 ; standard PRAM buffer address
|
||
moveq.l #-1,d0 ; mask/data to write
|
||
move.b d0,(a0) ; kill the signature in the buffer
|
||
_WriteParam ; write the buffer to PRAM
|
||
_InitUtil ; Init PRAM
|
||
movea.l sp,a0 ; get buffer ptr
|
||
move.l #RelPram,d0 ; get #, addr PRAM bytes
|
||
_WriteXPram ; restore the reliability MGR info
|
||
|
||
move.w #-1,BootGlobals.resetFlag(a5)
|
||
bra.s @continue
|
||
@stuff
|
||
dc.l $0004000C ; XPRAM signature len/addr
|
||
dc.l 'Gone' ; invalidate XPRam signature with this
|
||
|
||
@noReset
|
||
@continue
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
RememberPhysicalMemTop
|
||
|
||
; Prior to loading VM, MemTop holds the top of physical memory.
|
||
; We’ll use this later for our reality checking.
|
||
|
||
move.l MemTop,BootGlobals.physicalMemTop(a5)
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
DoWeHaveEnoughRAMToBoot
|
||
|
||
; We’ve got to have at least minRAMNeeded to get 7.0 on its feet. minRAMNeeded was chosen
|
||
; for just enough to get Finder up with room for one control panel. Moved earlier in <37> to crash
|
||
; before VM or MacsBug soaks up too much memory.
|
||
|
||
cmpi.l #minRAMNeededToBoot,BootGlobals.physicalMemTop(a5) ; is RAM big enough?
|
||
bhs.s @weHaveEnough
|
||
moveq #dsNotEnoughRAMToBoot,d0
|
||
_SysError
|
||
|
||
@weHaveEnough
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
IF NOT forROM THEN ; <SM28>
|
||
LoadTemporaryStripAddress
|
||
|
||
; Patch loading depends on StripAddress, so install a temporary version for the time before loading.
|
||
; moved earlier in <41>
|
||
; This must get stomped by anyone who installs a _real_ StripAddress later.
|
||
|
||
moveq #0,d5 ; <16> Assume we don’t patch _StripAddress
|
||
moveq #$55,d0 ; check if StripAddress is already implemented
|
||
_GetTrapAddress newOS
|
||
MOVE.L A0,D1 ; save its address
|
||
MOVE.W #$9F,D0 ; get unimplemented trap address
|
||
_GetTrapAddress newTool
|
||
CMP.L A0,D1 ; are they the same?
|
||
BNE.S @done ; yes, it already is implemented
|
||
|
||
moveq #$55,d0
|
||
LEA TemporaryStripAddress,a0
|
||
_SetTrapAddress newOS ; StripAddress doesn’t exist, use mine as a bootstrap
|
||
moveq #1,d5 ; <16> Use D5 to mean we patched _StripAddress. Any number will do…
|
||
@done
|
||
ENDIF
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
LoadVMAndDebugger
|
||
|
||
; Load VM and MacsBug, but do it in a different order if Joe’s debugging signature is found.
|
||
|
||
btst #extensionsEnabledBit,ExtensionsEnabledByte
|
||
bz.s @done ; extensions disabled means VM and MacsBug are disabled
|
||
|
||
cmp.w #vmDebugSignature,BootGlobals.bootBlocks+bbVMDebugSignature(a5)
|
||
beq.s @forDebugging ; if it is set right, do debugging
|
||
|
||
@normal
|
||
|
||
bsr LoadVM ; VM first
|
||
bsr LoadDebugger
|
||
bra.s @done
|
||
|
||
@forDebugging
|
||
|
||
bsr LoadDebugger ; debugger first; we’ll crash for sure (well, not for sure...)
|
||
bsr LoadVM
|
||
|
||
@done
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
ChooseBufPtrLimit ; <33>
|
||
|
||
; If VM loaded, _MemoryDispatch with D0 = -4 will return any limit to BufPtr that VM knows about.
|
||
; This might be NuBus™ slots or ROM in the logical RAM space (as on the IIci in 24bit mode).
|
||
; Put any VM limit to bufPtr’s descent into BootGlobals.bufPtrLimit(a5) (replacing the default).
|
||
|
||
GetBufPtrLimit equ -4 ; MemoryDispatch selector to get any bufPtr limit
|
||
|
||
move.l #gestaltVMAttr,d0 ; is VM on?
|
||
_Gestalt ;
|
||
tst.w d0
|
||
bne.s @noVMLimit ; if there was an error, forget it
|
||
|
||
move.l a0,d0
|
||
btst #gestaltVMPresent,d0
|
||
beq.s @noVMLimit ; if VM isn’t present, then leave
|
||
|
||
move.w #GetBufPtrLimit,d0
|
||
_MemoryDispatch ; if no limit, leave it set to the default
|
||
tst.l d0
|
||
ble.s @noVMLimit ; if error, skip out. if zero, VM knows no limit
|
||
|
||
move.l BootGlobals.bufPtrLimit(a5),d1
|
||
cmp.l d0,d1 ; VM’s limit < default?
|
||
bhi.s @noVMLimit ; if so, stick with the default.
|
||
|
||
move.l d0,BootGlobals.bufPtrLimit(a5)
|
||
|
||
@noVMLimit
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
bsr AdjustBarrier ; go take other things into account <38>
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
RememberLogicalMemTop
|
||
|
||
; After loading VM, MemTop holds the top of logical memory.
|
||
|
||
move.l MemTop,BootGlobals.logicalMemTop(a5)
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
CleanUpBootPort
|
||
|
||
; Clean up the port that QD sets up for booting.
|
||
|
||
pea BootGlobals.port(a5) ; close the port used for booting
|
||
_ClosePort
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
RelocateBootWorld
|
||
|
||
; If VM has added memory to the machine, relocate all the boot stuff to the new MemTop/2 <10>
|
||
; note: we ignore the QuickDraw globals in the BootGlobals record <10>
|
||
|
||
move.l BootGlobals.logicalMemTop(a5), d0 ; starting MemTop <10>
|
||
cmp.l BootGlobals.physicalMemTop(a5), d0 ; did we add memory? <10>
|
||
bls LoadUserAlerts ; if not, don’t bother <10> <SM8> CSS
|
||
|
||
lsr.l #1, d0 ; new MemTop/2 <10>
|
||
move.l d0, a1 ; point to the new stack <10>
|
||
; Make sure that the pages where the stack will be are in physical memory. We want about 12K <12>
|
||
; fo the stack, so use the logical page size to figure out how many pages to bring in. <12>
|
||
move.l #gestaltLogicalPageSize, d0 ; we want the page size <12>
|
||
_Gestalt ; VM implements Gestalt <12>
|
||
bne LoadUserAlerts ; huh? just bail… <12> <SM8> CSS
|
||
move.l #kBootStackSizeNeeded, d1 ; size of stack needed <12>
|
||
move.w a0, d0 ; page size <12>
|
||
divu d0, d1 ; number of pages we need <12>
|
||
move.l a1, a0 ; where the stack will be <12>
|
||
@makePhysicalStackLoop
|
||
tst.b (a0) ; bring a page in <12>
|
||
sub.w d0, a0 ; point to previous page <12>
|
||
dbra d1, @makePhysicalStackLoop ; do enough pages <12>
|
||
|
||
move.l a1, sp ; move the stack <10>
|
||
lea BootGlobals.initialSP(a5), a0 ; old globals <10>
|
||
move.l #BootGlobals.size, d0 ; size of globals <10>
|
||
_BlockMove ; relocate the globals <10>
|
||
lea BootGlobals.initialA5-BootGlobals.initialSP(a1), a5 ; point A5 into the new globals <10>
|
||
lea BootGlobals.initialA6(a5), a6 ; fix A6 <10>
|
||
|
||
lea FinishMovingBootWorld, a0 ; start of code to move <10>
|
||
lea EndOfBootCode, a1 ; end of code to move <10>
|
||
sub.l a0, a1 ; how much code to move <10>
|
||
move.l a1, d0 ; number of bytes to move <10>
|
||
sub.l d0, sp ; move the stack down to make room <10>
|
||
move.l sp, a1 ; destination is above the stack <10>
|
||
_BlockMove ; move the rest of this code <10>
|
||
move.l sp, CurStackBase ; a new beginning for the stack <10>
|
||
|
||
move.l sp, a0 ; current stack <10>
|
||
sub.l DefltStack, a0 ; leave room for the stack <10>
|
||
_SetApplLimit ; give the System Heap room to grow <10>
|
||
|
||
lea BootGlobals.lowestBufPtr(a5), a0 ; new minimum BufPtr default <10>
|
||
cmp.l BootGlobals.bufPtrLimit(a5), a0 ; is the limit already higher than this? <10>
|
||
bls.s @bootCodeMoved ; if so, don’t need to worry <10>
|
||
move.l a0, BootGlobals.bufPtrLimit(a5) ; bump lower limit past new globals <10>
|
||
|
||
@bootCodeMoved ; <10>
|
||
jmp (sp) ; go to new code location <10>
|
||
|
||
FinishMovingBootWorld ; <10>
|
||
IF NOT forROM THEN ; <SM28> SAM
|
||
tst.w d5 ; <16> Check our _StripAddress semaphore
|
||
bz.s @done ; <16> If D5 is not set, we didn’t patch _StripAddress
|
||
|
||
moveq #$55, d0 ; <10>
|
||
lea TemporaryStripAddress, a0 ; <10>
|
||
_SetTrapAddress newOS ; retarget the interim StripAddress code <10>
|
||
ENDIF
|
||
@done ; <10>
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
LoadUserAlerts
|
||
|
||
; Now that we have done all the boot message stuff, go on to the user alerts.
|
||
|
||
moveq #2,d0 ; load DSAT 2
|
||
bsr LoadDSAT ; get the handle
|
||
move.l d0,-(sp) ; now let the Resource Mgr. forget
|
||
_DetachResource
|
||
move.l d6,-(sp) ; and get rid of DSAT 0
|
||
_ReleaseResource
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
LoadTemporaryNewPtrStartup
|
||
|
||
; INITs depend on NewPtrStartup, so install a temporary version for the time before loading.
|
||
|
||
move.w #$9C,d0
|
||
LEA TemporaryNewPtrStartup,a0
|
||
_SetTrapAddress newOS ; NewPtrStartup doesn’t exist, use mine as a bootstrap
|
||
|
||
; Create a block containing the NewPtrStartup that will be used after boot. <30>
|
||
; It will be installed at the end of the boot below, just before starting the Process Mgr.
|
||
|
||
lea JustReturnAnError,a1 ; get the start in a1
|
||
lea JustReturnAnErrorEnd,a2
|
||
sub.l a1,a2 ; calculate the size in a2
|
||
|
||
move.l a2,d0 ; put the size in d0
|
||
_NewPtr sys ; make a block for this code
|
||
bne BadSystem
|
||
exg a0,a1 ; copy from the old block into the new
|
||
move.l a2,d0 ; put the size in d0
|
||
_BlockMove
|
||
move.l a1,BootGlobals.postBootNewPtrStartup(a5)
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
MakeBootDriveWDRefNum
|
||
|
||
; Up until now, BootDrive contained a drive number; make it a WDRefNum (the current volume).
|
||
|
||
lea BootGlobals.paramBlock(a5),a0
|
||
clr.l ioFileName(A0) ; we don’t want the name
|
||
_GetVol ; make BootDrive a VRefNum/WDRefNum
|
||
move.w ioVRefNum(A0),BootDrive
|
||
|
||
ActivateTrackCache
|
||
|
||
; Turn on the track caching of the Sony driver.
|
||
|
||
btst.b #hwCbAUX,HWCfgFlags ; are we under A/UX?
|
||
bnz.s @noSonyDriver
|
||
|
||
MOVE.W #dskRfn,ioRefNum(a0) ; refNum of the Sony driver
|
||
MOVE.W #9,csCode(a0) ; disk cache control code
|
||
MOVE.W #$FF01,csParam(a0) ; install and enable
|
||
_Control ; allocate and install track cache
|
||
|
||
@noSonyDriver
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
IF NOT forROM THEN ; <SM2> rb <SM14> rb
|
||
|
||
LoadFileSystemCache
|
||
|
||
; This makes assumptions about the RAM cache that are not true of the 6.X cache:
|
||
; • The 'ptch' (41) resource must have the system heap and locked bits set.
|
||
; • The cache locals are allocated by the cache code.
|
||
; • The cache code is aware that it is not loaded above BufPtr and allocates its own buffer space.
|
||
; • The cache code is aware that the limit to bufPtr is passed in d2.
|
||
; This reserves 32K for other things which also need BufPtr space to get the machine booted
|
||
; (e.g. AppleShare).
|
||
|
||
bsr AdjustBarrier ; <38>
|
||
btst #extensionsEnabledBit,ExtensionsEnabledByte ; <38>
|
||
bne.s @normal ; extensions disabled means feed him a small limit <38>
|
||
|
||
move.l BufPtr,d2 ; survival-mode, get my machine booted! <38>
|
||
sub.l #$10000,d2 ; give the cache 64K <38>
|
||
bra.s @continue ; <38>
|
||
@normal
|
||
move.l BootGlobals.bufPtrLimit(a5),d2 ; <33>
|
||
add.l #elbowRoomCacheCantHave,d2 ; <38>
|
||
@continue
|
||
moveq #41,d0
|
||
bsr LoadLowerCaseptch
|
||
|
||
ENDIF ; <SM2> rb <SM14> rb
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
IF forROM THEN ; <28>
|
||
|
||
; In the SuperMario based ROMs, we do not run PTCH(0) or any other patches. However, we do
|
||
; need some of the functionality from PTCH(0). So instead we will execute some of the code
|
||
; which is relevant to SuperMario ROMs. The code in here comes from the file BeforePatches.a
|
||
; which gets compiled into PTCH(0), the Universal patch. (Or used to be-Universal). If the code
|
||
; in this section gets too big, copy this file into a ROMBoot3.a file so that we do not bother
|
||
; the system guys.
|
||
|
||
; Make sure that ExpandMem is the latest, we leave this here because when the system changes, we
|
||
; will need to recompile this gibbly resource and ship it with the system disks, therefore the
|
||
; ROM will have an outdated version of ExpandMem. The loading of new vectors from disk will
|
||
; happen around this time, so the code that allocated the ExpandMem has already been executed
|
||
; and there is no point on replacing it with a new vector. So let's update ExpandMem. <28>
|
||
|
||
|
||
with ExpandMemRec ; <28>
|
||
|
||
movea.l ExpandMem,a0 ; Let's see if we have the latest <28>
|
||
move.l emSize(a0),d0 ; current size of ExpandMem record <28>
|
||
cmpi.l #emRecSize,d0 ; already allocated new blocks? <28>
|
||
bge.s @noSpandex ; no change nessesary... <28>
|
||
|
||
; allocate a new block for the newer ExpandMem
|
||
|
||
movea.l a0,a1 ; save original ExpandMem pointer <28>
|
||
move.l #emRecSize,d0 ; allocate correct amount of space <28>
|
||
_NewPtr ,SYS,CLEAR ; make pointer for a bigger and better copy <28>
|
||
bne @ErrorXit ; no memory ? something must be really wrong <28>
|
||
|
||
; a0 = pointer allocated for new expandMem of emRecSize bytes.
|
||
; copy original bytes of expandMem into my local space.
|
||
|
||
move.l emSize(a1),d0 ; current size of ExpandMem record <28>
|
||
exg a0,a1 ; want source in a0 <28>
|
||
_BlockMove ; <29June89smb> copy old data <28>
|
||
move.w #emCurVersion,emVersion(a1) ; version number <28>
|
||
move.l #emRecSize,emSize(a1) ; size <28>
|
||
move.l a1,ExpandMem ; start using new expandMem <28>
|
||
|
||
; dispose of original ExpandMem pointer.
|
||
_DisposPtr ; still in a0 after move <28>
|
||
beq.s @noSpandex ; exit if everything is ok <28>
|
||
|
||
@ErrorXit _SysError ; <24Aug89smb> <28>
|
||
|
||
endWith ; <28>
|
||
|
||
@noSpandex ; skip around when no room
|
||
|
||
;____________________________________________________________________________________
|
||
; Jam system version number. <PP149>
|
||
; *** we may not really want to do this in the ROM gibbly, but it doesn’t hurt
|
||
|
||
move.w #SysVersForROM,SysVersion ; jam sys version number <28>
|
||
|
||
;____________________________________________________________________________________
|
||
|
||
; Check to see if AppleTalk is active. If it is not, set emAppleTalkInactiveOnBoot
|
||
; to true. Various other parts of the System will look at this global later on to
|
||
; determine whether or not network code should be loaded.
|
||
|
||
move.b SPConfig,d0 ; Get serial port configuration <28>
|
||
and.b #$0f,d0 ; Mask off Port B bits <28>
|
||
beq.s @appleTalkIsActive ; Yes. Don’t set emAppleTalkInactiveOnBoot <62>
|
||
cmp.b #useATalk,d0 ; Configured for AppleTalk? <28>
|
||
beq.s @appleTalkIsActive ; Yes. Don’t set emAppleTalkInactiveOnBoot <28>
|
||
|
||
with ExpandMemRec ; Get the system's globals <28>
|
||
move.l ExpandMem,a0 ; <28>
|
||
move.w #-1,emAppleTalkInactiveOnBoot(a0) ; just do it <28>
|
||
EndWith ; <28>
|
||
|
||
@appleTalkIsActive ; <28>
|
||
|
||
; loop through all the open resource files, and clear the alternate attributes byte
|
||
; then, set it for the system file
|
||
|
||
SetupResourceFileAttributes ; <28>
|
||
move.l TopMapHndl,a0 ;start with the first map <28>
|
||
@next ; <28>
|
||
move.l a0,d0 ;are we done? <28>
|
||
bz.s @done ; <28>
|
||
move.l (a0),a0 ;get the map pointer <28>
|
||
bclr #decompressionPasswordBit,mInMemoryAttr(a0) ; clear the flags for this map <28>
|
||
move.l mNext(a0),a0 ;go on to the next map <28>
|
||
bra.s @next ; <28>
|
||
@done ; <28>
|
||
move.l SysMapHndl,a0 ;get the system map <28>
|
||
move.l (a0),a0 ; <28>
|
||
bset #decompressionPasswordBit,mInMemoryAttr(a0) ; allow dcmps here <28>
|
||
bset #dontCountOrIndexDuplicatesBit,mInMemoryAttr(a0) ; Don’t count duplicate resources in the System file <28>
|
||
bset #twoDeepBit,mInMemoryAttr(a0) ; One deep calls on the System file will search two (or more) maps. <28>
|
||
|
||
|
||
ELSE ; not ROM, System version <28>
|
||
|
||
LoadPTCHZero
|
||
|
||
; PTCH(0) does not get executed in SuperMario based ROMs, only in the System. <28>
|
||
|
||
MOVEQ #0,D0 ; load patches for all ROMs
|
||
BSR LoadPTCH
|
||
|
||
ENDIF ; IF forROM <28>
|
||
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
; Set the ExpandMem global emMinSysHeapFreeSpace <45>
|
||
|
||
move.l ExpandMem,a0
|
||
move.l #minSysHeapFreeSpace,d0
|
||
move.l d0,ExpandMemRec.emMinSysHeapFreeSpace(a0)
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
IF NOT forROM THEN ; don’t load ROM specfic patches or linked patches <28>
|
||
; for SuperMario <28>
|
||
|
||
LoadPTCHROMSpecific
|
||
|
||
; *** obsolete, get rid of this eventually
|
||
|
||
MOVEA.L ROMBase,a0 ; ID = ROM version number
|
||
MOVE.W 8(A0),D0 ; load ROM-specific patch
|
||
BSR LoadPTCH
|
||
|
||
LoadLinkedPatches
|
||
lea LinkedPatchName,a0
|
||
move.l a0,CurNamePtr ; Put ptr to the VM string <37>
|
||
|
||
subq #4,sp
|
||
move.l #kPatchTableResourceType,-(sp)
|
||
clr.w -(sp)
|
||
_GetResource
|
||
move.l (sp),d0 ; <15> Keep 'ptbl' on stack to save a call to _RecoverHandle
|
||
bz.s @noPatchTable
|
||
move.l d0,a0
|
||
_HLock ; Lock it down
|
||
move.l (a0),a3 ; Pass the pointer to the patch loader in A3
|
||
|
||
subq #4,sp
|
||
move.l #kPatchLoaderResourceType,-(sp) ; 'lodr'
|
||
move.w #kPatchLoaderResourceID,-(sp)
|
||
_GetResource ; Use the System’s patch loader if the gibbly doesn’t have one.
|
||
move.l (sp),d0 ; <15> Keep handle to 'lodr' on the stack for a release later
|
||
bz.s @noPatchLoader
|
||
move.l d0,a0
|
||
move.l (a0),d0
|
||
_StripAddress
|
||
move.l d0,a0
|
||
if theFuture then
|
||
move.l a0,d5 ; <33> Remember the linked patch loader address so it can be used to load linked patch extensions
|
||
endif
|
||
jsr (a0) ; Call the patch loader
|
||
|
||
if theFuture then
|
||
move.l #kLinkedPatchFileID,a2 ; <30> Get 'lpch' files
|
||
move.l #kExtensionFolderType,d7 ; <30> from the Extensions folder
|
||
bsr LoadINITFilesInFolder ; <30>
|
||
endif
|
||
|
||
_ReleaseResource ; <15> Release the linked patch loader
|
||
_ReleaseResource ; <15> Release the 'ptbl' resource
|
||
bra.s @done ; Load extensions, Process Manager, etc.
|
||
|
||
@noPatchTable
|
||
@noPatchLoader
|
||
moveq #dsBadPatch,d0 ; Couldn’t find the patch loader code
|
||
_SysError
|
||
|
||
@done
|
||
|
||
ENDIF ; IF NOT forROM <28>
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; Initialize all the System 7.0 Toolbox managers and finalize the VM installation
|
||
; if its enabled. Rewrote this (7/20/93) <SM28>. Make Override needs to be called before
|
||
; all the System 7 toolbox init code runs, TEInit after, and finally ROM component registration. <SM28>
|
||
;
|
||
|
||
; In the SuperMario ROM, most of the 7.0 initialization routines have been grouped
|
||
; together so that we can call them trough a 1 vector call. This vector offset from
|
||
; the start of the ROM is guaranteed not to change. Later on we may want to change
|
||
; this code so it can tell the vector routine which 7.0 Managers to initialize and
|
||
; which ones not to initialize. As in: "We totally re-wrote the Sound Manager, so
|
||
; don't bother installing the old one"
|
||
|
||
IF forROM THEN
|
||
; Override sys resources before initing the 7.0 toolbox stuff <SM28>
|
||
|
||
move.l SysMapHndl,-(sp); Push the map to override (the System File map)
|
||
_MakeOverrideMap ; Override resources in the System with those in the 'romv'
|
||
; ROM resource.
|
||
|
||
WITH ROMHeader
|
||
CLR.W CurMap ; Make the System Map the current one
|
||
|
||
MOVE.L ROMBase,A0 ; Get base o ROM
|
||
ADD.L InitSys7ToolboxOff(A0),A0 ; Add in the offset to the routine of Doom
|
||
JSR (A0) ; Call the 7.0 Toolbox initialization code <SM28>
|
||
|
||
DoRegisterROMComponents
|
||
moveq #42,d0 ; Component Search selector for RegisterROMComponents <70><72>
|
||
|
||
_ComponentDispatch ; register the components ('thng' rsrc's) in ROM
|
||
ENDWITH
|
||
|
||
ENDIF
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
; Load and Execute GoNative Loader
|
||
LoadGoNative
|
||
|
||
lea KeyMap,A0 ; Point to keymap <76>
|
||
cmpi.l #$03000000,(A0) ; Are both S & A down?
|
||
beq.s @noLoad ; -> Nope, load as usual
|
||
; cmpi.l #$00200000,4(A0) ; Is N down?
|
||
; beq.s @noLoad ; -> Yes, (NSA) do not load the NTRBs
|
||
|
||
@load move.w #0,d0 ; ID=0
|
||
move.l #'gnld',d1 ; type='gnld'
|
||
bsr DetachAndExecute
|
||
@noLoad
|
||
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
; Load and Execute Emulator Accelerations
|
||
LoadEmulatorAccel
|
||
|
||
move.b #-1,ROMMapInsert
|
||
move.w #1,d0 ; ID=1
|
||
move.l #'GARY',d1 ; type='GARY'
|
||
bsr DetachAndExecute
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
bsr RealityCheck ; check for enough memory to continue
|
||
move.l #-1,CurNamePtr ; no currently-executing file
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
TestForNeedToReset
|
||
|
||
; Earlier we chose whether we need to reboot. On the Plus, we don’t have _SDRestart until
|
||
; linked patches are loaded. Rather than move that code into this file, we simply waited.
|
||
|
||
tst.w BootGlobals.resetFlag(a5)
|
||
beq.s @skipReset
|
||
|
||
_SDRestart
|
||
@skipReset
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
SetupProcessMgrLaunch
|
||
|
||
; So that old code that patches Launch will still work, we point the Launch trap to the code used
|
||
; to start the Process Mgr. Later, we will call Launch, so all patches to Launch will be executed.
|
||
|
||
lea StartProcessMgr,a0 ; point to the code to start the Process Mgr.
|
||
move.w #$A9F2,d0 ; get the Launch trap number
|
||
_SetTrapAddress
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
Load8Dot24GC ; <31><29>
|
||
|
||
; Load 8•24 GC software from separate file in the control panels folder (or from the system file).
|
||
|
||
btst #6,ROM85 ; Color QuickDraw?
|
||
bnz.s @noCQD ; no CQD, no 8•24
|
||
|
||
move.w #k8Dot24GCNameID,d0 ; get 8•24 GC
|
||
move.l #kControlPanelFolderType,d7
|
||
move.l #'gc24',d5 ; resource ('gc24', 32)
|
||
move.w #32,d6
|
||
clr.w d3 ; clear the DontCloseOnError flag
|
||
bsr ExecuteFromSystemOrFileByName
|
||
@noCQD
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
bsr CreateApplicationHeap
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
; Secondary A/UX initializations (Pre-script systems)
|
||
|
||
btst.b #hwCbAUX,HWCfgFlags ; <24>
|
||
beq.s @notAux ; <24>
|
||
move.w #auxSecondaryInit,-(sp) ; <24>
|
||
move.l #1,-(sp) ; <24>
|
||
_AUXDispatch ; <24> Let A/UX do some initialization
|
||
@notAux ; <24>
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
LoadScriptSystems
|
||
|
||
; Load all of the INIT resources in script systems.
|
||
; These must be loaded before anyone puts up any dialogs or such.
|
||
|
||
btst #extensionsEnabledBit,ExtensionsEnabledByte
|
||
bz.s @skipScripts
|
||
|
||
move.l #'scri',a2 ; look for these types of INITs
|
||
move.l #kExtensionFolderType,d7
|
||
bsr LoadINITFilesInFolder
|
||
@skipScripts
|
||
|
||
; Now initialize the script systems that are installed. We have to do this even if INITs
|
||
; are disabled so that Roman gets initialized.
|
||
|
||
subq #2,sp ; make room for OSErr result <13>
|
||
_InitScripts ; <13>
|
||
addq #2,sp ; ignore result for now <13>
|
||
; *** what kind of reality checking/error checking should go here?
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
; Secondary A/UX initializations
|
||
|
||
btst.b #hwCbAUX,HWCfgFlags ; <24>
|
||
beq.s @notAux ; <24>
|
||
move.w #auxSecondaryInit,-(sp) ; <24>
|
||
clr.l -(sp) ; <24>
|
||
_AUXDispatch ; <24> Let A/UX do some more initialization
|
||
@notAux ; <24>
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
LoadINITResourcesInSystemFile
|
||
|
||
; Load all of the INIT resources from the System file.
|
||
;
|
||
; Note that one of these INIT resources may be the INIT 20 resource used for remote booting.
|
||
; This INIT closes the System file and opens a new system file. In addition, it returns the
|
||
; dirID of the folder containing the startup application in A4. To top that, it also clobbers
|
||
; the boot blocks at A6 with the boot blocks
|
||
|
||
moveq #-1,d4 ; refNum -1 means we load from the System file
|
||
bsr LoadINITResources ; call the common routine below
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
bsr MakeSystemHeapGrowable
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
LoadAROSE
|
||
|
||
; Load A/ROSE.
|
||
|
||
btst #extensionsEnabledBit,ExtensionsEnabledByte
|
||
bz.s @skip ; extensions disabled means A/ROSE is disabled
|
||
|
||
move.w #kAROSENameID,d0 ; get A/ROSE
|
||
move.l #kExtensionFolderType,d7
|
||
bsr LoadINITFileByName
|
||
beq.s @foundInExtensionsFolder
|
||
|
||
move.w #kAROSENameID,d0 ; get A/ROSE
|
||
move.l #kSystemFolderType,d7
|
||
bsr LoadINITFileByName
|
||
@foundInExtensionsFolder
|
||
|
||
@skip
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
LoadAppleTalk
|
||
|
||
; Load AppleTalk from System.
|
||
|
||
btst.b #hwCbAUX,HWCfgFlags ; are we under A/UX?
|
||
bnz.s @noALAP
|
||
|
||
move.l #'lmgr',d5 ; call common routine to load and execute resource <29>
|
||
clr.w d6
|
||
clr.w d3 ; clear the DontCloseOnError flag
|
||
bsr ExecuteFromSystem ; <34>
|
||
@noALAP
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
LoadNetBoot ; <33>
|
||
|
||
; Load NetBoot.
|
||
|
||
; SDRefNum must be kNetBootDriverRefNum (-50) to continue
|
||
|
||
subq #4,sp ; Make room for parameters
|
||
move.l sp,a0 ; Point to the parameter block
|
||
|
||
; We’d like to call GetDefaultStartup, but it’s not on the Plus or SE, so we reimplement it. <34>
|
||
MOVE.L #$00040078,D0 ; Read 4 bytes starting at loc $78
|
||
_ReadXPRam ; Get it from PRAM.
|
||
|
||
move.l (sp)+,d0 ; put result into d0
|
||
cmp.w #kNetBootDriverRefNum,d0; refnum in low word
|
||
bne.s @skip
|
||
|
||
move.w #kNetBootNameID,d0 ; get NetBoot
|
||
move.l #kExtensionFolderType,d7
|
||
move.l #'proc',d5 ; call common routine to load and execute resource
|
||
move.w #kNetBootProcID,d6
|
||
moveq #1,d3 ; set the DontCloseOnError flag
|
||
bsr ExecuteFromSystemOrFileByName
|
||
; *** beq.s @skip ; we’re not actually net-booting this time
|
||
|
||
; *** subq #2,sp ; room for OSErr
|
||
; *** _ReInitScripts
|
||
@skip
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
bsr CreateApplicationHeap
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
LoadSystemComponents ; <9>
|
||
|
||
; Register any components lurking in the system file <9>
|
||
|
||
;pascal long RegisterComponentResourceFile(short resRefNum, short global) <9>
|
||
clr.l -(sp) ; return value <9>
|
||
clr.w -(sp) ; system map fref <9>
|
||
move.w #1,-(sp) ; register them globally <9>
|
||
_RegisterComponentResourceFile ; <9>
|
||
addq #4,sp ; ignore result <9>
|
||
|
||
; In the case where a component had a cmpWantsRegisterMessage, it can happen that the component
|
||
; manager will clone the component and open it in the app heap (if the sys heap is full). Unfortunately,
|
||
; it looks like when that component is closed, the Component Manager globals still thinks that the cloned
|
||
; component is around. This will most likely not be true after all the INITs load, since the sys heap
|
||
; will grow pushing the app heap up which makes some handles to the "closed" component now invalid.
|
||
; The following call will make sure to remove any component instances left around in the app heap.
|
||
|
||
_CleanUpApplicationComponents ; clean up any components left in the app heap
|
||
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
LoadINITFiles
|
||
|
||
; This section searches the default volume for files of type cdev, RDEV
|
||
; and INIT. When it finds one, it opens it and attempts to Get1IndResource
|
||
; on type INIT. If successful, it locks down the resource and executes the
|
||
; code within. When the code returns, it closes the file (thus throwing away
|
||
; the code if it didn’t DetachResource itself), and continues with the next
|
||
; cdev/RDEV/INIT file it finds. Note that ResLoad is turned off over the
|
||
; OpenResFile call.
|
||
;
|
||
; Differences between this and the boot blocks’ INIT launcher:
|
||
;
|
||
; • This doesn’t DetachResource before calling the INIT code (if the
|
||
; code wants to be detached, it must RecoverHandle and do it itself).
|
||
; • This assumes that the Locked bit of the INIT is set (so did the
|
||
; boot blocks, but it’s worth restating!).
|
||
;
|
||
; MemTop -> +-------------------+ Top RAM location
|
||
; | I/O, screen RAM |
|
||
; initial BufPtr -> +-------------------+ Top of program-usable memory
|
||
; | static allocation |
|
||
; | |
|
||
; | |
|
||
; | |
|
||
; 1K + MemTop/2 -> +-------------------+
|
||
; | boot blocks |
|
||
; MemTop/2 -> +-------------------+
|
||
; | boot stack |
|
||
; ApplLimit -> +-------------------+
|
||
; | |
|
||
; | application heap |
|
||
; ApplZone -> +-------------------+
|
||
; | |
|
||
; | system heap |
|
||
; SysZone -> +-------------------+
|
||
; | |
|
||
; | system globals |
|
||
; 0 -> +-------------------+
|
||
;
|
||
; With this, an INIT resource may grab BufPtr space down to MemTop/2 + 1K. It
|
||
; may use the application zone for temporary heap memory. It may even grow the
|
||
; system heap (preferably with the 'sysz' mechanism).
|
||
|
||
btst #extensionsEnabledBit,ExtensionsEnabledByte
|
||
bz.s @skipINITs ; extensions disabled means INITs are disabled
|
||
|
||
move.l #0,a2 ; look for all three types of INITs
|
||
move.l #kExtensionFolderType,d7
|
||
bsr LoadINITFilesInFolder
|
||
move.l #kControlPanelFolderType,d7
|
||
bsr LoadINITFilesInFolder
|
||
move.l #kSystemFolderType,d7
|
||
bsr LoadINITFilesInFolder
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
; Register Components from 'thng' files.
|
||
|
||
move.l #minSysHeapFreeForINIT,d5 ; minimum space needed to run an INIT <6>
|
||
bsr MakeSysFree ; resize (Is this OK for 'thng's?) <6>
|
||
|
||
moveq #34,d0 ; ComponentSearch selector <6>
|
||
_ComponentDispatch ; look for 'thng's <6>
|
||
|
||
@skipINITs
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
; Enable PowerDown Messages if Caboose is available <SM15>
|
||
|
||
jsr EnablePDMsgs
|
||
|
||
;——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
; Now that networks are usable, give script systems a chance to install fonts over the network. <14>
|
||
|
||
subq #2,sp ; make room for OSErr result
|
||
_AddScriptFonts
|
||
addq #2,sp ; ignore result for now
|
||
; *** what kind of reality checking/error checking should go here?
|
||
|
||
;------------------------------------------------------------------------------------------------
|
||
|
||
; Go tell text services manager what the system script is and what its default language is
|
||
bsr TellTSMScriptAndLanguage
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
; Switch from the boot-time NewPtrStartup to one that returns an error. <30>
|
||
|
||
move.l BootGlobals.postBootNewPtrStartup(a5),a0
|
||
move.w #$9C,d0
|
||
_SetTrapAddress newOS ; use the NewPtrStartup that just returns an error
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
; We still have two heaps. We are going to get minSysHeapFreeAfterBoot bytes, even if it
|
||
; means growing the system heap again. This time, though, we’ll stop reserving anything,
|
||
; and take as much as we need.
|
||
|
||
_RsrcZoneInit ; <23> Call _RsrcZoneInit to blow away system resources loaded in the application heap
|
||
|
||
; Guarantee some free space after last INIT (or for folks lacking any INIT files at all).
|
||
|
||
clr.l BootGlobals.reservedForAfterBoot(a5) ; stop reserving that big chunk <34>
|
||
move.l #minSysHeapFreeAfterBoot,d5 ; what we want to have free in the system heap <34>
|
||
bsr MakeSysFree ; resize
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
; Now, we call the launch trap. Before INITs, we patched Launch to point here, to the code that
|
||
; is used to start the Process Mgr. Any patches to Launch will be executed, followed by the Process
|
||
; Mgr. itself.
|
||
|
||
clr.w -(sp) ; for the wierdos who look
|
||
clr.l -(sp) ; we pass the parameters like the old launch
|
||
pea #'MultiFinder' ; (rest in peace)
|
||
move.l sp,a0 ; pass those parameters
|
||
_Launch
|
||
|
||
StartProcessMgr
|
||
|
||
; The Process Mgr. is structured like an application (a bunch of code segments), but
|
||
; the code segments are numbered differently so they can be in the System file.
|
||
; First, set up the application heap, and then load the jump table for the Process Mgr.
|
||
|
||
CLR.L StkLowPt ; keep VBL task out
|
||
MOVE.L BufPtr,sp ; start stack out here
|
||
CLR.L ScrapHandle ; no need for this
|
||
_InitApplZone ; cut back the heap
|
||
|
||
SUBQ #4,SP ; make room for function result
|
||
MOVE.L #'scod',-(SP) ; <25> Keep stb happy.
|
||
MOVE.W #processMgrCode0,-(sp)
|
||
_GetResource ; load the jump table resource ('CODE', processMgrCode0)
|
||
MOVE.L (SP)+,d1 ; save away the handle for later release
|
||
bz.s BadSystem ; no, this system is damaged
|
||
|
||
; Set up A5 worlds (above and below) and the stack pointer.
|
||
|
||
MOVE.L d1,A0 ; get the handle in an address register
|
||
MOVE.L (A0),A0 ; dereference so we can get at the jump table
|
||
SUB.L (A0)+,SP ; allocate "above A5" space
|
||
MOVE.L SP,A5 ; set up A5
|
||
SUB.L (A0)+,SP ; allocate "below A5" space
|
||
MOVE.L A5,CurrentA5 ; remember A5 for the Process Mgr.
|
||
MOVE.L SP,CurStackBase ; remember stack for this one, too
|
||
MOVE.L SP,StkLowPt ; for heap-stack crashes
|
||
|
||
; Move jump table from the resource to its place below A5.
|
||
|
||
MOVE.L (A0)+,D0 ; get the jump table size
|
||
MOVE.L (A0)+,A1 ; get the load offset
|
||
MOVE.W A1,CurJTOffset ; remember the offset
|
||
ADD.L A5,A1 ; add in the base address
|
||
pea 2(A1) ; push the starting address onto the stakc
|
||
_BlockMove ; move it in
|
||
|
||
; Now that things are set up, we can release the jump table resource.
|
||
|
||
MOVE.L d1,-(SP) ; push the resource handle
|
||
_ReleaseResource ; de-allocate it
|
||
|
||
; Set up the stack limit based on how much stack the Process Mgr. needs.
|
||
|
||
MOVE.L SP,A0 ; get the stack
|
||
SUB.W #processMgrStackSize,A0 ; make space for stack
|
||
_SetApplLimit ; set the new limit
|
||
|
||
; Start the Process Mgr.
|
||
|
||
rts
|
||
|
||
; ——— THE END ———
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
LoadDSAT
|
||
|
||
; Loads the desired DSAT resource, and install it in low-memory.
|
||
;
|
||
; D0.W -> resource ID of DSAT
|
||
; D0.L <- handle of DSAT
|
||
|
||
subq #4,sp ; room for returned handle
|
||
MOVE.L #'DSAT',-(SP)
|
||
MOVE.W D0,-(SP)
|
||
_GetResource
|
||
MOVE.L (SP)+,D0
|
||
bz.s BadSystem
|
||
move.l d0,a0
|
||
move.l (a0),DSAlertTab
|
||
RTS
|
||
|
||
BadSystem
|
||
|
||
; Come here if a resource that is required is missing.
|
||
|
||
moveq #dsBadPatch,d0
|
||
_SysError
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
ExecuteFromSystem ; <34>
|
||
|
||
; Execute a resource that is gotten from the system.
|
||
;
|
||
; a5 -> globals, including parameter block and file name storage
|
||
; d3.W -> DontCloseOnError flag. If nonzero, don't CloseTheFile on nonzero result
|
||
; d5.L -> resource type
|
||
; d6.W -> resource ID
|
||
|
||
moveq #-1,d4
|
||
bra.s DontOpenAFile
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
ExecuteFromSystemOrFileByName ; <29>
|
||
|
||
; Execute a resource that is gotten either from the system or from a special file.
|
||
;
|
||
; a5 -> globals, including parameter block and file name storage
|
||
; d0.W -> ID of STR resource containing the file name
|
||
; d3.W -> DontCloseOnError flag. If nonzero, don't CloseTheFile on nonzero result <33>
|
||
; d7.L -> folder type to look in
|
||
; d5.L -> resource type
|
||
; d6.W -> resource ID
|
||
|
||
moveq #-1,d4 ; refNum -1 means no file was opened yet
|
||
|
||
btst #extensionsEnabledBit,ExtensionsEnabledByte
|
||
bz.s DontOpenAFile ; extensions disabled means do not open the special file
|
||
|
||
bsr.s SetUpForFileByName
|
||
bne.s DontOpenAFile
|
||
bsr OpenTheFile
|
||
|
||
DontOpenAFile
|
||
move.w #mapTrue,ROMMapInsert ; get ROM as well as System file
|
||
subq #4,sp
|
||
move.l d5,-(sp)
|
||
move.w d6,-(sp)
|
||
_GetResource
|
||
move.l (sp)+,d1 ; get the result
|
||
bz.s @noResource
|
||
|
||
move.l d1,-(sp) ; save for later release
|
||
bsr ExecuteHandle
|
||
tst.w d3 ; do we care about closing the file? <33>
|
||
bz.s @continue ; nope, just release and close <33>
|
||
tst.w d0 ; yes, check for response <33>
|
||
beq.s @continue ; glad we checked, but don’t close it <37>
|
||
addq #4,sp ; pop the (no longer a resource) handle <37>
|
||
rts ; leave without closing <37>
|
||
@continue
|
||
_ReleaseResource
|
||
@noResource
|
||
bsr CloseTheFile
|
||
@DontClose
|
||
rts
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
LoadINITFileByName
|
||
|
||
; If so, open the file, look for a 'sysz', and cycle through the INITs.
|
||
; If the system heap must be resized, then close and reopen the resource file.
|
||
;
|
||
; d0.W -> resource ID of string containing name of file to load
|
||
; a5 -> globals, including parameter block and file name storage
|
||
; d7.L -> folder type to look in, then folder dirID
|
||
;
|
||
; ccr <- Z means success, NZ means error
|
||
;
|
||
; d4.W = refnum of opened file
|
||
; d5.L = requested contiguous free space in system zone
|
||
|
||
bsr.s SetUpForFileByName
|
||
bnz.s @done
|
||
bsr LoadINITFile
|
||
@done
|
||
rts
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
SetUpForFileByName
|
||
|
||
; Get the name of a file from a resource.
|
||
; Set up a parameter block with the appropriate values, find a folder to work in.
|
||
;
|
||
; a5 -> globals, including parameter block and file name storage
|
||
; d7.L -> folder type to look for
|
||
; d0.W -> resource ID of the file’s name
|
||
;
|
||
; d0.W <- error code
|
||
; d7.L <- dirID of found folder
|
||
|
||
subq #4,sp ; make room for handle result
|
||
move.w d0,-(sp) ; get that string
|
||
_GetString
|
||
move.l (sp)+,d0 ; get result
|
||
bz.s @notFound
|
||
|
||
move.l d0,a0 ; get handle
|
||
moveq #0,d0 ; clear out size for BlockMove <22>
|
||
move.l (a0),a0 ; dereference handle
|
||
move.b (a0),d0 ; get length
|
||
addq.b #1,d0 ; add one for the length byte
|
||
lea BootGlobals.fileName(a5),a1
|
||
_BlockMove
|
||
|
||
bsr SetUpForFolder ; prepare for that folder as well
|
||
@done
|
||
rts
|
||
|
||
@notFound
|
||
move.w #resNotFound,d0 ; get error code
|
||
bra.s @done
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
LoadINITFilesInFolder
|
||
|
||
; The major file-loading loop for INITs. For each file in the folder specified by d7,
|
||
; by index, check whether it’s an INIT, RDEV or cdev. If so, open the file, look
|
||
; for an 'sysz', and cycle through the INITs. If the system heap must be resized,
|
||
; then must close and reopen the resource file.
|
||
;
|
||
; a5 -> globals, including parameter block and file name storage
|
||
; d7.L -> folder type to look in, then folder dirID
|
||
; a2 -> 0 means get INIT, RDEV, cdev, anything else means that file type only
|
||
;
|
||
; d3.W = index of current file
|
||
; d4.W = refnum of opened file
|
||
;
|
||
; no return values
|
||
|
||
move.l a4,-(sp) ; save a4 for folder. Used for creator type. <9>
|
||
|
||
bsr SetUpForFolder
|
||
bz.s @foundFolder ; we got it, keep going <26>
|
||
cmp.l #'scri', a2 ; looking for script extensions? <26>
|
||
bne DoneWithFolder ; if not, don’t try System Folder <26>
|
||
move.l #kSystemFolderType, d7 ; try the System Folder <26>
|
||
bsr SetUpForFolder ; <26>
|
||
bz.s @foundFolder ; it worked <39>
|
||
; <39> go ahead and try anyway with 0 as a dirID in case everything is at the root
|
||
moveq #0, D7 ; try the root <39>
|
||
|
||
@foundFolder
|
||
lea BootGlobals.fileName(a5),a0 ; store pointer to file’s name
|
||
move.l a0,BootGlobals.paramBlock+ioFileName(a5)
|
||
clr.w BootGlobals.paramBlock+ioFileType(a5) ; "version" and permissions
|
||
|
||
moveq #0,d3 ; start looping through the files
|
||
|
||
NextFileInFolder
|
||
addq.w #1,d3 ; increment the file index
|
||
|
||
lea BootGlobals.paramBlock(a5),a0 ; point at IO block
|
||
move d3,ioFDirIndex(a0)
|
||
move.l d7,ioDirID(a0)
|
||
_HGetFileInfo ; d3 file in the folder
|
||
bnz DoneWithFolder ; no more files in the folder, stop loading
|
||
|
||
move.l ioFlUsrWds+fdType(a0),d0 ; grab file type for testing
|
||
move.l ioFlUsrWds+fdCreator(A0),a4 ; save file creator type for LoadInitFile <9>
|
||
move.l a2,d1 ; what file type are we looking for
|
||
bz.s @allTypes ; 0, means look for all boot-executable types
|
||
cmp.l d1,d0 ; is this the type we’re looking for?
|
||
bra.s @checkType ; go ask the storm trooper
|
||
@allTypes
|
||
cmp.l #'INIT',d0 ; is it a system extension?
|
||
bne.s @notExtension ; <12> no, keep checking
|
||
cmp.l #kFileShareCreator,a4 ; <12> Is it FileShare?
|
||
bne.s @goodFile ; <12> No, it’s just some extension
|
||
bra @checkAppleTalkState ; <12> See if AppleTalk is active. If not, don’t load FileShare
|
||
|
||
@notExtension
|
||
cmp.l #'pext',d0 ; <18> Is it an El Kabong printing extension?
|
||
beq.s @goodFile ; <18> Yes. Go load it.
|
||
cmp.l #'cdev',d0 ; is it a control panel?
|
||
BEQ.S @goodFile ; yes, use it
|
||
cmp.l #'RDEV',d0 ; is it a Chooser extension?
|
||
bne.s @notRDEV ; <12> no, keep checking
|
||
cmp.l #kAppleShareCreator,a4 ; <12> Is it AppleShare?
|
||
bne.s @goodFile ; <12> No, it’s just some Chooser extension
|
||
bra @checkAppleTalkState ; <12> See if AppleTalk is active. If not, don’t load AppleShare
|
||
|
||
@notRDEV
|
||
cmp.l #'cbnd',d0 ; is it a connection tool?
|
||
BEQ.S @goodFile ; yes, use it
|
||
cmp.l #'fbnd',d0 ; is it a file transfer tool?
|
||
BEQ.S @goodFile ; yes, use it
|
||
cmp.l #'tbnd',d0 ; is it a terminal emulation tool?
|
||
BEQ.S @goodFile ; yes, use it
|
||
cmp.l #'vbnd',d0 ; is it a telephone tool?
|
||
BEQ.S @goodFile ; yes, use it
|
||
|
||
cmp.l #'adev',d0 ; is it a network extension?
|
||
BEQ.S @goodFile ; yes, use it
|
||
cmp.l #'ddev',d0 ; is it a database extension?
|
||
BEQ.S @goodFile ; yes, use it
|
||
cmp.l #'appe',d0 ; is it a background app? <33>
|
||
BEQ.S @goodFile ; yes, use it
|
||
cmp.l #'fext',d0 ; is it a Finder extension?
|
||
@checkType
|
||
bne.s NextFileInFolder ; no, move along
|
||
@goodFile
|
||
|
||
btst #bFNoINIT,ioFlUsrWds+fdFlags+1(a0) ; do we know there are no INIT resources?
|
||
bne.s NextFileInFolder ; yes, skip slow OpenResFile
|
||
btst #bFInvisible,ioFlUsrWds+fdFlags(a0) ; is it invisible?
|
||
bnz.s NextFileInFolder ; yes, skip it, since it may be evil
|
||
|
||
if theFuture then
|
||
cmp.l #kLinkedPatchFileID,d1 ; <30> Is this a file with type 'lpch'?
|
||
bne.s @normalINITFile ; <30> No. Assume it has 'INIT' resources
|
||
bsr.s LoadLinkedPatchFile ; <30> Go load linked patches from this file
|
||
bra.s NextFileInFolder ; <30> Go around for another one.
|
||
endif
|
||
|
||
@normalINITFile ; <30>
|
||
bsr.s LoadINITFile ; load all the INITs from the file
|
||
bnz.s NextFileInFolder
|
||
|
||
; Check to see if we actually found any INITs in this file. If we didn’t, then save this useful
|
||
; information as a fndrInfo bit so we can skip the really slow OpenResFile the next time we start up.
|
||
|
||
cmp.w #1,d6 ; exit on first time through loop?
|
||
bne.s @hadINIT ; no, had an INIT
|
||
|
||
tst.w d1 ; was the problem not finding a resource?
|
||
bz.s @noINITs ; yes, no INITs
|
||
cmp.w #resNotFound,d1 ; was the problem not finding a resource?
|
||
bne.s @hadINIT ; no, perhaps too little memory
|
||
@noINITs
|
||
lea BootGlobals.paramBlock(a5),a0 ; point at param block
|
||
bset #bFNoINIT,ioFlUsrWds+fdFlags+1(a0) ; remember that there are no INIT resources
|
||
move.l d7,ioDirID(a0) ; reset the dirID, since HGetFileInfo trashes it
|
||
_HSetFileInfo ; write out the bit
|
||
; ignore errors, we’re just optimizing
|
||
@hadINIT
|
||
bra NextFileInFolder
|
||
|
||
; See if AppleTalk is active. If not, don’t load the current extension.
|
||
|
||
@checkAppleTalkState
|
||
move.l a0,-(sp) ; <12> Save parameter block
|
||
move.l ExpandMem,a0 ; <12>
|
||
tst.w ExpandMemRec.emAppleTalkInactiveOnBoot(a0) ; <12> Check saved AppleTalk state
|
||
move.l (sp)+,a0 ; <12> Restore parameter block
|
||
bz.s @goodFile ; <12> AppleTalk is on. It’s ok to load this extension.
|
||
bra.s NextFileInFolder ; <12> AppleTalk is off. Don’t load this extension.
|
||
|
||
DoneWithFolder
|
||
move.l (sp)+,a4 ; restore a4 for folder. Used for creator type. <9>
|
||
rts
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
SetUpForFolder
|
||
|
||
; Set up a parameter block with the appropriate values, and find a folder to work in.
|
||
;
|
||
; a5 -> globals, including parameter block and file name storage
|
||
; d7.L -> folder type to look for
|
||
;
|
||
; d0.W <- error code
|
||
; d7.L <- dirID of found folder
|
||
|
||
sub #4,sp ; var foundDirID result
|
||
move.l sp,a0
|
||
sub #2,sp ; _FindFolder result (OSErr)
|
||
move #kOnSystemDisk,-(sp) ; which disk
|
||
move.l d7,-(sp) ; which folder type
|
||
move.b #kDontCreateFolder,-(sp)
|
||
pea BootGlobals.paramBlock+ioVRefNum(a5) ; var foundVRefNum result
|
||
move.l a0,-(sp) ; var foundDirID result
|
||
_FindFolder
|
||
move.w (sp)+,d0
|
||
move.l (sp)+,d7
|
||
tst.w d0
|
||
rts
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
if theFuture then
|
||
|
||
LoadLinkedPatchFile
|
||
|
||
; Open a file, and install linked patches from it, using the linked patch loader in the
|
||
; system file.
|
||
;
|
||
; A3 -> Pointer to system’s 'ptbl' resource that loads every linked patch.
|
||
; D5 -> Pointer to system’s patch loader.
|
||
;
|
||
|
||
bsr.s OpenTheFile ; <30> Open the resource file, making it the current resource file
|
||
bnz.s @skip ; <30> skip file if the file couldn’t be opened.
|
||
|
||
move.l d5,a0 ; <30> Get the linked patch loader into an address register
|
||
jsr (a0) ; <30>Call the linked patch loader.
|
||
|
||
bsr CloseTheFile ; <30> Close the file now that we’re done.
|
||
@skip
|
||
rts ; <30>
|
||
endif
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
LoadINITFile
|
||
|
||
; Open a file, look for a 'sysz', and cycle through the INITs.
|
||
; If the system heap must be resized, then must close and reopen the resource file.
|
||
;
|
||
; a5 -> globals, including parameter block and file name storage
|
||
; d7.L -> folder type to look in, then folder dirID
|
||
; d6.W <- number of resources loaded
|
||
; d1.W <- error result from loading last resource in the file
|
||
; d0.W <- error result
|
||
; ResErr <- error result
|
||
;
|
||
; d4.W = refnum of opened file
|
||
; d5.L = requested contiguous free space in system zone
|
||
;
|
||
; To do:
|
||
; Change the reality check to a preflight which either chooses to not run the init or to
|
||
; skip the allocation and (hopefully) let the init know that the space wasn't allocated.
|
||
|
||
; Make space before getting 'sysz' to speed up booting, since it reduces re-opening of the file.
|
||
|
||
move.l #minSysHeapFreeForINIT,d5 ; minimum space needed to run an INIT
|
||
bsr MakeSysFree ; resize
|
||
|
||
bsr.s OpenTheFile ; go open the resource file
|
||
bnz.s @skip ; skip file if bad open
|
||
|
||
; Now look for an 'sysz' resource to make a system heap request.
|
||
|
||
subq #4,sp ; room for result
|
||
move.l #'sysz',-(sp) ; 'sysz' resource
|
||
clr.w -(sp) ; id 0 always
|
||
_Get1Resource
|
||
move.l (sp)+,d0
|
||
bz.s @noRequest ; no sysz, go on
|
||
|
||
move.l d0,a0 ; sysz handle
|
||
move.l (a0),a0 ; sysz pointer
|
||
move.l (a0),d5 ; requested size
|
||
bsr.s MakeSysFree ; get it in the sys zone
|
||
@noRequest
|
||
cmp.l #'ånd5',A4 ; is this QuickTime™? <9>
|
||
bne.s @skipQuickTimeFix ; if not, we don’t have to load components <9>
|
||
|
||
; <40> QuickTime components should not be registered on 68000 machines, since they all
|
||
; assume the 020.
|
||
|
||
cmp.b #cpu68020,CPUFlag ; <40> Are we on a 68000? (you mean, less than an '020 right? <SM28>)
|
||
blo.s @skipQuickTimeFix ; <40> If so, don’t register QuickTime’s components
|
||
|
||
;pascal long RegisterComponentResourceFile(short resRefNum, short global) <9>
|
||
clr.l -(sp) ; return value <9>
|
||
move.w d4,-(sp) ; fref <9>
|
||
move.w #1,-(sp) ; register them globally <9>
|
||
moveq #20,d0 ; RegisterComponentResourceFile selector <9>
|
||
_ComponentDispatch ; <9>
|
||
addq #4,sp ; ignore result <9>
|
||
|
||
@skipQuickTimeFix
|
||
|
||
bsr LoadINITResources ; now load all the INIT resources
|
||
|
||
bsr.s CloseTheFile
|
||
|
||
_CleanUpApplicationComponents ; clean up any components left in the app heap <9>
|
||
|
||
@skip
|
||
move.w ResErr,d0
|
||
rts
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
OpenTheFile
|
||
|
||
; Open the current resource file with preloading off.
|
||
;
|
||
; a5 -> globals, including file name at BootGlobals.fileName(a5)
|
||
; d7.L -> parent directory id
|
||
; d4.W <- file refnum
|
||
; d0.W <- error result
|
||
; ResErr <- error result
|
||
;
|
||
; Trashes d0/a0
|
||
|
||
move.l a1,-(sp)
|
||
|
||
subq #2,sp ; room for result
|
||
move.w #0,-(sp) ; at boot time def. vol. = boot vol.
|
||
move.l d7,-(sp)
|
||
pea BootGlobals.fileName(a5)
|
||
move.b #fsCurPerm,-(sp)
|
||
clr.b ResLoad ; no preloads please
|
||
_HOpenResFile
|
||
st ResLoad ; restore resLoad to proper state
|
||
move (sp)+,d4 ; save the refnum
|
||
bmi.s @nothingOpened
|
||
|
||
lea BootGlobals.fileName(a5),a0 ; pointer to file’s name <30>
|
||
move.l a0,CurNamePtr ; Put ptr to the filename into CurApName+4 <35>
|
||
|
||
@nothingOpened
|
||
move.l (sp)+,a1
|
||
move.w ResErr,d0
|
||
rts
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
CloseTheFile
|
||
|
||
; Close the current resource file.
|
||
;
|
||
; d4.W -> file refnum
|
||
; d4.W <- -1, indicating no file is open
|
||
; Trashes d0/a0
|
||
|
||
cmp.w #-1,d4
|
||
beq.s @done
|
||
move.l #-1,CurNamePtr ; no currently-executing file <35>
|
||
move d4,-(sp) ; refNum of the open file
|
||
_CloseResFile
|
||
moveq #-1,d4 ; no file is open
|
||
@done
|
||
rts
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
MakeSysFree
|
||
|
||
; Guarantee a contiguous block of free space in the sys. heap.
|
||
; If the heap must be grown, must carefully close and reopen the
|
||
; current resource file since its map, etc. is in the app heap.
|
||
; To avoid purging everything, we use a loop based on _CompactMem
|
||
; and _SetAppBase. In the worst case, the loop should be
|
||
; executed twice.
|
||
;
|
||
; d5.L -> requested space
|
||
; d4.W -> file refnum, or negative if no resource file is open now
|
||
; a5 -> if d4 is positive, name at BootGlobals.fileName(a5)
|
||
; d7.L -> if d4 is positive, parent directory id
|
||
;
|
||
; Trashes d0-d2/a0
|
||
;
|
||
; To Do:
|
||
; Do the CompactMem anyway, even if there is only one zone.
|
||
; Add a result code indicating success or failure.
|
||
;
|
||
; Assertions:
|
||
; d1 doesn’t get trashed by CloseTheFile, PinSysHeapTop, _SetApplBase, _CompactMem
|
||
|
||
bsr ApplZoneExists
|
||
beq.s @exit ; yes, sys. heap is growable; do nothing
|
||
|
||
move.w d4,d1 ; save file refNum for later
|
||
move.l d5,d0 ; amount needed
|
||
_CompactMem sys ; look for it in sys zone
|
||
sub.l d5,d0 ; gotten - needed
|
||
bge.s @done ; gotten ≥ needed --> done
|
||
|
||
; d0 is negative <36>
|
||
move.l d0,d2 ; size for later
|
||
subq.l #1,d2 ; round up and (it’s negative, so subtract) <36>
|
||
and.w #~1,d2 ; make sure it is even
|
||
|
||
tst.w d4 ; is a resource file open?
|
||
bmi.s @noNeedToClose ; no, no need to close the file
|
||
bsr.s CloseTheFile ; close resource file
|
||
@noNeedToClose
|
||
|
||
move.l SysZone,a0
|
||
move.l bkLim(a0),a0 ; end of sys. zone
|
||
sub.l d2,a0 ; end of zone + (needed-gotten)
|
||
adda.w #sysHeapFreeSpaceSlop,a0 ; with slop
|
||
bsr PinSysHeapTop
|
||
_SetApplBase ; free up more space
|
||
move.l d5,d0 ; amount needed <36>
|
||
_CompactMem sys ; look for it in sys zone again <36>
|
||
|
||
@done
|
||
tst.w d1 ; was there a resource file open?
|
||
bmi.s @noNeedToOpen ; no, no need to re-open the file
|
||
tst.w d4 ; is the resource file still open?
|
||
bpl.s @noNeedToOpen ; yes, no need to re-open the file
|
||
bsr OpenTheFile ; assume success here
|
||
@noNeedToOpen
|
||
|
||
bsr RealityCheck ; make sure we have enough memory to continue
|
||
|
||
@exit
|
||
rts
|
||
|
||
;--------------------------------------------------------------------------------------
|
||
;
|
||
; Call GetEnvirons to get the system script and GetScript to get that scripts language code
|
||
; then pass the information onto the Text Services manager
|
||
;
|
||
TellTSMScriptAndLanguage
|
||
movem.l d3,-(sp) ;save d3
|
||
subq #4,sp ;make room for long result from GetScript
|
||
move.w #smSysScript,-(sp) ;push the system script verb onto the stack
|
||
_GetEnvirons ;get the system script
|
||
move.l (sp)+,d3 ;save return value in d3
|
||
subq #4,sp ;space for GetScript return value
|
||
move.w d3,-(sp) ;put the script (in low word) onto the stack
|
||
swap d3 ;now move the script code high
|
||
move.w #smScriptLang,-(sp) ;now tell us the language
|
||
_GetScript
|
||
addq #2,sp ;again we want the low word
|
||
move.w (sp)+,d3 ;save the language
|
||
subq #4,sp ;make a record on the stack
|
||
move.l sp,a0 ;get a pointer to it
|
||
move.l d3,(a0) ;copy the S&L infor from d0 into the record we made on the stack
|
||
clr.w -(sp) ;clear space for the result
|
||
move.l a0,-(sp) ;move the pointer to the stack
|
||
_SetTextServiceLanguage ;set the script and language
|
||
addq #6,sp ;pop and ignore the result and get rid of the record
|
||
movem.l (sp)+,d3 ;restore d3
|
||
rts
|
||
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
LoadINITResources
|
||
|
||
; The resource loading loop.
|
||
;
|
||
; d4.W -> refNum of file we’re loading from, or -1 meaning the system file
|
||
;
|
||
; d6.W <- number of resources loaded
|
||
; d1.W <- error code
|
||
;
|
||
; d6.W = index of resource
|
||
; d5.L = size needed (used to pass to MakeSysFree)
|
||
;
|
||
; To Do: store the INIT index and/or handle along with the filename to make
|
||
; for easier debugging when files have more than one INIT.
|
||
|
||
moveq #1,d6 ; start with resource 1
|
||
@loop
|
||
|
||
; First, do a Get1IndResource or a GetResource, from the file or System file.
|
||
|
||
move.w #mapFalse,ROMMapInsert ; make ResLoad temporarily false, get ROM as well
|
||
bsr.s GetINITResource
|
||
bnz.s @continue ; got one
|
||
|
||
; If we didn’t get a handle and we are working on a file, we are done.
|
||
; If we are working on the System file, we just move on to the next resource by number.
|
||
|
||
tst.w d4 ; in System?
|
||
bpl.s @done ; no, we are done
|
||
bra.s @next ; yes, keep going
|
||
@continue
|
||
|
||
; Now make sure there is enough system heap free for us.
|
||
|
||
subq #4,sp
|
||
MOVE.L d1,-(SP) ; resource handle
|
||
_SizeRsrc
|
||
MOVE.L (SP)+,d5 ; get the size of the INIT
|
||
ADD.L #minSysHeapFreeForINIT,d5 ; add the required free space
|
||
bsr.s MakeSysFree ; get contiguous bytes in sys. heap
|
||
|
||
; Make a fresh heap, and get the resource, for real this time.
|
||
|
||
move.w #mapTrue,ROMMapInsert ; get ROM as well as System file
|
||
bsr.s GetINITResource ; now get it for real
|
||
bz.s @next ; skip this one if we can’t load it
|
||
|
||
; Detach the resource, if it is one of the ones from the System file.
|
||
|
||
tst.w d4 ; in System?
|
||
bpl.s @noDetach ; no, then don’t detach
|
||
move.l d1, -(sp) ; yes, push handle to detach <23>
|
||
_DetachResource ; and cut it off! <23>
|
||
@noDetach
|
||
|
||
; Lock the sucker down, and call him, preserving registers.
|
||
|
||
bsr SetBufPtrLimit ; jam MemTop so they won’t lower BufPtr too far
|
||
bsr.s ExecuteHandle ; execute the stuff in that resource
|
||
move.l BootGlobals.logicalMemTop(a5),MemTop ; set MemTop back <30>
|
||
|
||
@next
|
||
addq.w #1,d6 ; up the resource index
|
||
tst.w d4 ; in System?
|
||
bpl.s @loop ; no, keep going until we can’t get any more INITs
|
||
|
||
cmp.w #36,d6 ; done yet?
|
||
blt.s @loop ; no, keep loading
|
||
@done
|
||
move.w ResErr,d1
|
||
rts
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
ExecuteHandle
|
||
|
||
; Lock and execute the contents of a handle.
|
||
;
|
||
; d1.L -> handle
|
||
;
|
||
; Trashes d0-d2/a0-a1
|
||
|
||
move.l d1,a0 ; resource handle
|
||
_HLock ; lock before executing
|
||
move.l (a0),d0
|
||
_StripAddress
|
||
move.l d0,a1 ; get stripped, dereferenced address
|
||
|
||
move.l (a5),-(sp) ; preserve QD globals pointer
|
||
movem.l d3-d7/a2-a6,-(sp) ; save all regs over call
|
||
jsr (a1) ; pass handle in a0 for disposing, sizing, etc.
|
||
movem.l (sp)+,d3-d7/a2-a6 ; restore regs
|
||
move.l (sp)+,(a5)
|
||
|
||
bsr RealityCheck ; make sure we have enough memory to continue
|
||
|
||
rts
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
GetINITResource
|
||
|
||
; d6.W -> ID of INIT resource in System file, or index of INIT resource in another file
|
||
; d4.W -> -1 to mean System file, or other to mean current resource file
|
||
; d1.L <- handle
|
||
; ccr <- Z if resource not found
|
||
|
||
subq #4,sp ; room for returned handle
|
||
move.l #'INIT',-(sp)
|
||
move.w d6,-(sp)
|
||
tst.w d4 ; from System?
|
||
bmi.s @getFromSys
|
||
_Get1IxResource ; get indexed from file
|
||
bra.s @got
|
||
@getFromSys
|
||
_GetResource ; get by number from System/ROM
|
||
@got
|
||
move.l (sp)+,d1
|
||
rts
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
IF NOT forROM THEN ; We's never gonna be a II <SM28>
|
||
HandleMacIIWith030 ; rewrite to simpler, more informed case <48>
|
||
|
||
; Check for a Mac II ROM with a 68030.
|
||
; This specific case handles getting in early enough to tell VM that we’ve got an 030 (VM-capable).
|
||
; Normally, accelerator manufacturers are responsible for setting up CPUFlag, MMUType, and their cache
|
||
; settings. Out of the kindness of our hearts, we chose to give this extra support in this one case
|
||
; where VM is a new feature, and they can’t get in early enough to let VM know they are capable.
|
||
;
|
||
; MacIIci ROMs and later do all the right setup for CPUFlag, MMUType, and caches.
|
||
; MacII ROMs do not.
|
||
; Pre-MacII ROMs can't take advantage of VM, so don't help or hurt them.
|
||
|
||
; Lessons learned:
|
||
; You can’t turn on CACR_DE_030 even for an instant with some accelerators; they may depend on
|
||
; MMU tables being set up and die if they aren’t.
|
||
;
|
||
; You can’t set MMUType for them. That confuses SwapMMUMode (as evidenced by MacsBug not loading
|
||
; because it couldn’t find a monitor). They’ll have to provide their own rad SwapMMUMode if they
|
||
; want to jam MMUType.
|
||
;
|
||
; We thought about turning off interrupts during the period we’re setting CACR_WA_030, but figured
|
||
; out that it can never hurt. Check the manual if you don’t believe this.
|
||
|
||
; On Exit: IF actual processor is 68030 & ROM is kROMVersionII
|
||
; CPUFlag <- 030
|
||
; MMUType unchanged
|
||
; CACR unchanged
|
||
;
|
||
; Destroys: d0-d1/a0. CACR may be touched (WA set briefly) but exits unchanged.
|
||
|
||
move.l ROMBase,a0 ; point to ROM to get ROM version
|
||
cmp.w #kROMVersionII,8(a0) ; do we have a MacII ROM?
|
||
bne.s @bail ; no? don’t do anything.
|
||
|
||
cmp.b #cpu68020,CPUFlag ; does the ROM think that this is a 68020?
|
||
bne.s @bail ; no? don’t do anything.
|
||
|
||
; we have now decided to second-guess the ROM
|
||
|
||
MACHINE MC68020
|
||
|
||
movec cacr,d1 ; temp storage
|
||
|
||
move.l d1,d0
|
||
bset #CACR_WA_030,d0 ; WA, (enable data cache)
|
||
movec d0,cacr ; enable data cache (temporarily)
|
||
movec cacr,d0 ; IF CACR WA bit != 0 THEN we’re on an 030 because an 020 doesn’t have WA
|
||
btst #CACR_WA_030,d0 ; see if the bit exists in CACR by seeing whether it stays set
|
||
bz.s @bail ; no? don’t do anything.
|
||
; don’t restore CACR because we just set a bit which doesn’t exist
|
||
|
||
movec d1,cacr ; restore CACR (VERY IMPORTANT: some accelerators can’t handle the cache)
|
||
move.b #cpu68030,CPUFlag ; it’s an 030, let everyone know.
|
||
; You might be tempted to add setting MMUType. Don’t.
|
||
|
||
|
||
@bail
|
||
rts
|
||
ENDIF
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
LoadVM
|
||
|
||
; Load the Virtual Memory system, which is contained in the 'ptch' (42) resource (which is locked).
|
||
; Also note that VM code contains the true test for whether a machine is “VM capable”.
|
||
|
||
btst.b #hwCbAUX,HWCfgFlags ; are we under A/UX?
|
||
bnz.s @noVM
|
||
|
||
IF forROM THEN ; we want the newer VM in ROM <SM10> rb
|
||
move.w #mapTrue,ROMMapInsert ; use the ROM if available <SM10> rb
|
||
ENDIF ; <SM10> rb
|
||
lea VMName,a0 ; put name of VM into CurApPtr <37>
|
||
move.l a0,CurNamePtr ; Put ptr to the VM string <37>
|
||
moveq #42,d0
|
||
bsr LoadLowerCaseptch ; let VM decide for itself
|
||
move.l #-1,CurNamePtr ; no currently-executing file <37>
|
||
@noVM
|
||
rts
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
LoadDebugger
|
||
|
||
; Load the MacsBug debugger, and optionally the other debug thing (Disassembler).
|
||
; If there is no MacsBug, no attempt is made to load Disassmbler.
|
||
; Before loading MacsBug (below BufPtr), 1024 bytes of globals are reserved.
|
||
; MacsBug and the Disassembler are responsible for lowering BufPtr themselves after being loaded.
|
||
; If they don’t, they will be overwritten by the stack and globals of the first application.
|
||
|
||
SUB.L #debuggerGlobalSize,BufPtr ; leave space for MacsBug globals
|
||
btst.b #hwCbAUX,HWCfgFlags ; <24> Are we running under A/UX?
|
||
beq.s @loadDebugger ; <24> No
|
||
sub.l #auxExtraDebuggerSize,BufPtr ; <24> MacsBug needs more room under A/UX
|
||
@loadDebugger
|
||
lea BootGlobals.bootBlocks+bbDbg1Name(a5),a1
|
||
bsr.s LoadBelowBufPtrSkip512 ; try loading it
|
||
BEQ.S @install ; if present, install it
|
||
ADD.L #debuggerGlobalSize,BufPtr ; otherwise, dealloc MacsBug globals
|
||
BRA.S @done
|
||
|
||
@install
|
||
lea DebuggerName,a0 ; put name of MacsBug into CurApPtr <37>
|
||
move.l a0,CurNamePtr ; Put ptr to the MacsBug string <37>
|
||
JSR (a2) ; tell it to install itself
|
||
|
||
; NOTE: the following code must not change in length - MacsBug depends upon it (blegh!)
|
||
; If MacsBug punts, it adds the magic offset 6 (bytes, that is) to the return address
|
||
; to skip over this code. Ideally, the interface should allow the debugger to return
|
||
; an error code (in, say, D0?) to allow happy bypassing of this message.
|
||
|
||
MOVEQ #dsMacsBugInstalled,D0 ; alert saying we got MacsBug
|
||
bsr BootAlert ; display it if we should <42>
|
||
|
||
; If we loaded the debugger successfully, get the Disassembler, too.
|
||
|
||
lea BootGlobals.bootBlocks+bbDbg2Name(a5),a1
|
||
bsr.s LoadBelowBufPtrSkip512 ; search for Disassembler
|
||
BNE.S @done ; branch if there’s no disassembler
|
||
|
||
lea DisassemblerName,a0 ; put name of Disassembler into CurApPtr <37>
|
||
move.l a0,CurNamePtr ; Put ptr to the Disassembler string <37>
|
||
JSR (a2) ; tell it to install itself
|
||
|
||
; see above NOTE for MacsBug: the disassembler works the same way
|
||
|
||
MOVEQ #dsDisassemblerInstalled,D0 ; alert saying we got the disassembler
|
||
bsr BootAlert ; display it if we should <42>
|
||
|
||
@done
|
||
move.l #-1,CurNamePtr ; nothing currently executing <37>
|
||
rts
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
BootAlert
|
||
|
||
; BootAlert posts the boot alert specified; it may be disabled if there is a startup screen.
|
||
;
|
||
; d0.W -> the boot alert number (must be negative).
|
||
; d7.B -> 0 to disable boot alerts.
|
||
|
||
tst.b d7 ; did we get a startup screen?
|
||
bz.s @skip ; if we did, skip
|
||
_SysError ; post the alert
|
||
@skip
|
||
rts
|
||
|
||
string pascal ; names used to identify culprits
|
||
VMName dc.b 'Virtual Memory'
|
||
align
|
||
DebuggerName dc.b 'Debugger'
|
||
align
|
||
DisassemblerName dc.b 'Disassembler'
|
||
align
|
||
LinkedPatchName dc.b 'System'
|
||
align
|
||
string asis
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
; Load the data fork of a file into high memory (just below BufPtr).
|
||
|
||
LoadBelowBufPtrSkip512
|
||
|
||
moveq #64,d1
|
||
lsl.w #3,d1 ; 64*8 = 512
|
||
bra.s LoadBelowBufPtrCommon
|
||
|
||
LoadBelowBufPtr
|
||
moveq #0,d1
|
||
|
||
LoadBelowBufPtrCommon
|
||
|
||
; a1 -> name for file to load
|
||
; d1.L -> number of bytes to skip at the start of the file
|
||
; a5 -> boot globals (used to find place for parameter block)
|
||
; a2 <- location loaded
|
||
; d2.L <- size of file loaded 0 means failure
|
||
; d3.B <- 0 = successfully loaded (CCRs set)
|
||
;
|
||
; Trashes d0-d3/a0-a2.
|
||
|
||
lea BootGlobals.paramBlock(a5),a0
|
||
|
||
MOVEQ #-1,d3 ; error code
|
||
|
||
LEA ioFileName(A0),A2 ; point to params we use
|
||
MOVE.L A1,(A2)+ ; ioFileName(A0)
|
||
CLR.L (A2)+ ; ioDrvNum(A0), ioRefNum(A0) use default drive?
|
||
CLR.B (A2)+ ; ioFileType(A0) type 0
|
||
MOVE.B #fsRdPerm,(A2)+ ; read-only permissions
|
||
lea BootGlobals.fileBuffer(a5),a1
|
||
move.l a1,(A2) ; ioOwnBuf(A0) use space after boot blocks
|
||
_Open
|
||
BNE.S @fail
|
||
|
||
_GetEOF
|
||
BNE.S @close
|
||
MOVE.L (A2)+,d2 ; ioLEOF(A0) get physical length in bytes
|
||
SUB.L d1,d2 ; skip first block
|
||
|
||
MOVE.L BufPtr,A2 ; get top of code stack
|
||
SUB.L d2,A2 ; A2 = where to read into
|
||
|
||
LEA ioBuffer(a0),a1
|
||
MOVE.L A2,(a1)+ ; ioBuffer(A0)
|
||
MOVE.L d2,(a1)+ ; ioByteCount(A0)
|
||
ADDQ #ioPosMode-ioNumDone,a1
|
||
MOVE.W #fsFromStart,(a1)+ ; ioPosMode(A0) absolute positioning
|
||
MOVE.L d1,(a1) ; ioPosOffset(A0) start at 512
|
||
_Read
|
||
BNE.S @close
|
||
MOVEQ #0,d3 ; no errors
|
||
@close
|
||
_Close
|
||
@fail
|
||
tst.b d3 ; test result for CCR
|
||
RTS
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
LoadPTCH
|
||
move.l #'PTCH',d1 ; fall through
|
||
bra.s DetachAndExecute
|
||
|
||
LoadLowerCaseptch
|
||
|
||
move.l #'ptch',d1 ; load one of these
|
||
|
||
DetachAndExecute
|
||
|
||
; Loads, detaches, and executes the resource with given type and ID.
|
||
;
|
||
; D0.W -> patch resource id
|
||
; D1.L -> patch resource type
|
||
; D2.L -> bufPtr’s lower limit (added for the file cache) <33>
|
||
;
|
||
; Trashes: d0-d1/a0
|
||
;
|
||
; Patches are called with their handle in D1.L.
|
||
|
||
|
||
IF forROM THEN ; Special case ROM's VM <SM10> rb
|
||
MOVE.L D1,-(SP) ; save resource type <SM10> rb
|
||
MOVE.W D0,-(SP) ; save resource id <SM10> rb
|
||
ENDIF ; <SM10> rb
|
||
|
||
SUBQ #4,SP ; make room on the stack
|
||
MOVE.L d1,-(SP)
|
||
MOVE.W d0,-(SP)
|
||
_GetResource ; get the resource handle
|
||
MOVE.L (SP)+,D1 ; save the resource handle
|
||
BNE.S @GotResource ; did we find the resource? <SM22> hy
|
||
IF forROM THEN ; <SM23>
|
||
ADDA.L #6,SP ; clean up stack and get out of here <SM22> hy
|
||
ENDIF
|
||
BRA.S @skip ; we didn’t get it, so just go on <SM22> hy
|
||
|
||
@GotResource ; found it <SM22> hy
|
||
|
||
IF forROM THEN ; <SM10> rb
|
||
CMP.L #'ptch',2(SP) ; was this lowercase patch ? <SM10> rb
|
||
BNE.S @NotROM_VM ; if not, keep on <SM10> rb
|
||
CMP.W #42,(SP) ; was it id 42, VM ? <SM10> rb
|
||
BNE.S @NotROM_VM ; if not, don't special case <SM10> rb
|
||
|
||
MOVE.L D1,A0 ; put ROM's VM res handle in a0 <SM10> rb
|
||
MOVE.L A0,-(SP) ; save this handle, potential ROM res <SM10> rb
|
||
MOVE.L (A0),A0 ; let's get its pointer <SM12> rb
|
||
MOVE.L A0,D0 ; copy resource pointer to D0 <SM10> rb
|
||
_StripAddress ; if in 24 bit mode, get rid of flags <SM13> rb
|
||
MOVE.L (SP)+,A0 ; recover the resource handle <SM10> rb
|
||
CMP.L ROMBase,D0 ; is it a ROM resource ? <SM10> rb <SM13> rb
|
||
BLT.S @NotROM_VM ; if not, don't copy to RAM, it's RAM <SM10> rb
|
||
_HandToHand ; copy ROM to memory <SM10> rb
|
||
MOVE.L A0,D1 ; and set their handle to ptch 42 <SM10> rb
|
||
_HLock ; make sure it's locked too <SM10> rb
|
||
|
||
@NotROM_VM ; <SM10> rb
|
||
ADDA.L #6,SP ; recover saved type and id <SM10> rb
|
||
|
||
ENDIF
|
||
|
||
MOVE.L D1,-(SP) ; detach it
|
||
_DetachResource
|
||
MOVE.L D1,A0 ; get the handle
|
||
MOVE.L (A0),D0 ; handle -> pointer
|
||
_StripAddress
|
||
MOVEA.L D0,A0
|
||
movem.l A3-A6, -(SP) ; save important registers
|
||
jsr (A0) ; call it (note that the handle must be in D1)
|
||
movem.l (SP)+, A3-A6 ; restore ’cause ptch/PTCH trashes these
|
||
|
||
@skip
|
||
RTS
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
ApplZoneExists
|
||
|
||
move.l ApplZone,d0
|
||
cmp.l SysZone,d0
|
||
rts
|
||
|
||
CreateApplicationHeap
|
||
|
||
bsr.s ApplZoneExists
|
||
bne.s @clobberIt ; if an ApplZone exists, kill it, otherwise …
|
||
move.l BufPtr,ApplZone ; fool InitApplZone into thinking we had no zone before
|
||
@clobberIt
|
||
_InitApplZone ; make the heap and clean up if there was an old one
|
||
move.l sp,a0 ; current stack
|
||
sub.l DefltStack,a0 ; leave room for INITs to work
|
||
_SetApplLimit
|
||
rts
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
MakeSystemHeapGrowable
|
||
|
||
; Set things up so the system heap and the application heap are the same, so the system heap will
|
||
; grow (this is only needed for the Plus and the SE, other ROMs do something like this already).
|
||
|
||
bsr.s ApplZoneExists
|
||
beq.s @noApplZone ; if no ApplZone exists, no need to kill it
|
||
_InitApplZone
|
||
@noApplZone
|
||
move.l SysZone,a0 ; calculate a new minimum size for the heap
|
||
add.l #initialSysHeapSize,a0 ; make it big enough so it won’t need to grow much
|
||
bsr.s PinSysHeapTop ; don’t go farther than we really can
|
||
_SetApplBase ; SetApplBase will never shrink the heap
|
||
|
||
move.l SysZone,a0 ; the one true heap
|
||
move.l a0,ApplZone ; coincident heaps
|
||
move.l a0,TheZone ; make it the current heap too
|
||
move.l bkLim(a0),HeapEnd ; end of dynamic system/application heap
|
||
move.l sp,a0 ; find the stack
|
||
sub.l DefltStack,a0 ; keep room for the stack
|
||
sub.l #minBootAppHeapSize,a0 ; and the application heap
|
||
_SetApplLimit ; this is the highest we should grow
|
||
rts
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
PinSysHeapTop ; <34>
|
||
|
||
; Things above sysZone include the stack (which starts in the middle) and applZone (if any).
|
||
; This is only called when SysZone is being made ApplZone so it can grow, so there is never
|
||
; an ApplZone to worry about. However, we do have to leave room so we can create one later.
|
||
;
|
||
; Other things above that include: this code (on the stack), BufPtr, MemTop.
|
||
;
|
||
; a0 -> where they think they want the top of heap
|
||
; a0 <- where they get to put the top of the system heap
|
||
;
|
||
; Trashes a1
|
||
;
|
||
; To Do:
|
||
; Consider the case where the recommended top of the sysheap/bottom of the app heap is lower
|
||
; than the current top of the system heap. Bad, but what should happen? We can't cut into
|
||
; the stack or app heap sizes, can we? Maybe we just stop trying to load inits because we
|
||
; ran out of room. How would we get into this state, anyway? Would it (could it) ever happen?
|
||
|
||
move.l sp,a1
|
||
sub.l DefltStack,a1 ; leave room for the stack
|
||
sub.l #minBootAppHeapSize,a1 ; leave room for an app heap later <34>
|
||
sub.l BootGlobals.reservedForAfterBoot(a5),a1 ; leave room for post-boot <34>
|
||
|
||
cmp.l a0,a1
|
||
bhi.s @ok
|
||
move.l a1,a0
|
||
@ok
|
||
rts
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
TemporaryNewPtrStartup ; <30>
|
||
|
||
; This is a routine to lower BufPtr. It’s usable only during startup.
|
||
; Another routine is used after startup is through.
|
||
|
||
; -> d0.L logicalSize
|
||
; <- a0 address of allocated block (Nil on failure)
|
||
; <- d0 result code
|
||
; memFullErr
|
||
; Error is also reported in MemErr
|
||
;
|
||
; _NewPtrStartup ,CLEAR will clear the allocated block.
|
||
|
||
movem.l d2-d3,-(sp) ; save params and work registers
|
||
|
||
move.w d1,d3 ; save trap word in d3
|
||
|
||
addq.l #3,d0 ; round up to nearest multiple of 4 <30>
|
||
andi.b #$FC,d0
|
||
move.l d0,d2 ; save amount requested in d2
|
||
|
||
move.l BufPtr,d1
|
||
sub.l d0,d1 ; proposed new BufPtr value
|
||
bcs.s @allocationFailed ; they asked for something bigger than BufPtr
|
||
|
||
bsr.s IsThisBufPtrOK ; see if this d1 will work as a new value of BufPtr
|
||
bne.s @allocationFailed
|
||
|
||
andi.b #$FC,d1 ; drop it to the next longword
|
||
move.l d1,a0 ; address of allocated block
|
||
move.l a0,BufPtr ; make the allocation
|
||
|
||
btst #clearBit,d3 ; is this a NewPtrStartup ,CLEAR?
|
||
beq.s @dontClear
|
||
move.l d2,d1 ; size to clear out
|
||
move.l a0,a1 ; pointer to block
|
||
bsr.s ClearBlock ; clear out the block at BufPtr as requested
|
||
@dontClear
|
||
movem.l (sp)+,d2-d3
|
||
|
||
clr.l d0 ; set the result code
|
||
move.w d0,MemErr ; set MemErr
|
||
rts
|
||
|
||
@allocationFailed
|
||
movem.l (sp)+,d2-d3
|
||
; fall through into JustReturnAnError
|
||
|
||
JustReturnAnError ; <30>
|
||
|
||
; This is used for NewPtrStartup after startup time.
|
||
|
||
move.l #0,a0 ; return nil
|
||
move.w #memFullErr,d0 ; allocation failed
|
||
move.w d0,MemErr ; set MemErr
|
||
rts
|
||
|
||
JustReturnAnErrorEnd
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
ClearBlock
|
||
|
||
; -> d1.L logicalSize (must be multiple of 4)
|
||
; -> a1 start of block to zero
|
||
;
|
||
; Trashes a1
|
||
|
||
lsr #2,d1 ; d1 := d1 / 4
|
||
subq #1,d1 ; make it zero-based
|
||
|
||
@loop clr.l (a1)+
|
||
dbf d1,@loop
|
||
rts
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
SetBufPtrLimit
|
||
|
||
; This sets MemTop to a value which will put a (faked-up) limit on how far BufPtr may be lowered.
|
||
; It’s based on the rule that BufPtr may not be lowered past MemTop / 2 + 1024. We believe that
|
||
; many INITs use this rule, so we also expect that they will stop where we want them to when they
|
||
; use our computed value of MemTop.
|
||
;
|
||
; Things which limit BufPtr’s descent:
|
||
; must have at least 350K + stack space to launch Finder
|
||
; must have at least ???K + stack space to launch some essential control panel
|
||
; NuBus™ cards or ROM in the logical memory space (when VM is in 24 bit mode
|
||
;
|
||
; a5 -> globals
|
||
; MemTop <- 2 * (bufPtrLimit - 1K)
|
||
;
|
||
; Trashes a0/d0
|
||
;
|
||
; fake MemTop -> FakeMemTop will always be ≥ MemTop
|
||
; MemTop -> +_____________
|
||
; |
|
||
; |
|
||
; BufPtr -> |
|
||
; |
|
||
; |………………………………… <- if 24bit VM, then barrier = BootGlobals.bufPtrLimit(a5)
|
||
; |## NuBus™ ## <- may be here if in 24bit VM mode
|
||
; |
|
||
; |### ROM #### <- ditto
|
||
; |
|
||
; |
|
||
; |------------- <- SysZone + minProcessMgrSpace (could be below barrier)
|
||
; |
|
||
; |
|
||
; |————————————— <- barrier = BootGlobals.lowestBufPtr(a5)
|
||
; boot code -> |±±±±±±±±±±±±± BufPtr can’t go lower than this without killing the machine.
|
||
; boot globals-> |≠≠≠≠≠≠≠≠≠≠≠≠≠
|
||
; top of stack-> |\\\\\\\\\\\\\
|
||
; |\\\ stack \\\
|
||
; SP -> |\\\\\\\\\\\\\
|
||
; |
|
||
; ApplZone … … … … … … … …
|
||
; SZ.bkLim -> |
|
||
; |
|
||
; |
|
||
; SysZone -> |_____________
|
||
; | lomem globs
|
||
; +—————————————
|
||
|
||
bsr AdjustBarrier ; <38>
|
||
move.l BootGlobals.bufPtrLimit(a5),a0 ; <38>
|
||
|
||
sub.w #1024,a0 ; minBufPtr - 1024
|
||
add.l a0,a0 ; 2*(minBufPtr - 1024) <30>
|
||
move.l a0,MemTop ; MemTop := 2*(minBufPtr - 1024)
|
||
rts
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
RealityCheck
|
||
|
||
; This boolean routine returns EQ if there is sufficient space in the system heap to accomodate
|
||
; the amount requested in D0.
|
||
;
|
||
; Trashes d0-d1/a0
|
||
|
||
; Actually just fall through to the next routine, but we might eventually want to check other
|
||
; things, like the size of or the amount of free space in the system heap.
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
IsBufPtrOK
|
||
|
||
; Has BufPtr moved too far down?
|
||
;
|
||
; Trashes d0-d1/a0
|
||
|
||
move.l BufPtr,d1
|
||
bsr.s IsThisBufPtrOK
|
||
beq.s @yes
|
||
|
||
move.w #dsMemFullErr,d0
|
||
_SysError
|
||
@yes
|
||
rts
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
IsThisBufPtrOK ; <30>
|
||
|
||
; Would it be OK to lower BufPtr to the place suggested by d1?
|
||
;
|
||
; 1. Moved past the boot-time barrier. This is a test for whether boot globals would be smashed.
|
||
; 2. Consumed so much room we won’t have room to launch Finder.
|
||
;
|
||
; a5 -> globals
|
||
; d1.L -> suggested BufPtr
|
||
; CCRs <- Z if successful
|
||
;
|
||
; Trashes d1/a0
|
||
|
||
; Have we gone past the boot globals or the limit imposed by VM?
|
||
|
||
move.l BootGlobals.bufPtrLimit(a5),a0 ; a0 := top of the barrier <33><30>
|
||
cmp.l a0,d1 ; barrier < suggested BufPtr?
|
||
blo.s @no ; nope, we need our boot globals
|
||
|
||
; Is there enough space to build the Process Mgr. heap?
|
||
|
||
move.l SysZone,a0
|
||
move.l bkLim(a0),a0
|
||
sub.l a0,d1 ; any space above the system heap?
|
||
blo.s @no ; nope, we need our system heap <30>
|
||
cmp.l #minProcessMgrSpace,d1 ; space >= min Process Mgr. size?
|
||
blo.s @no ; nope, not enough to create the heap & stack
|
||
moveq #0,d1 ; set CCR for success (Z)
|
||
@no ; all failure cases set CCR for failure (not Z)
|
||
rts
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
AdjustBarrier ; <38>
|
||
|
||
; Adjust BootGlobals.bufPtrLimit(a5) to have:
|
||
; MAX( sysHeap.bkLim + minProcessMgrSpace, static limits (i.e. boot globals & vm limits) )
|
||
|
||
; Trashes: a0/d0
|
||
|
||
move.l SysZone,a0
|
||
move.l a0,d0 ; copy baseAddr of SysZone
|
||
move.l bkLim(a0),a0
|
||
add.l #initialSysHeapSize,d0
|
||
cmp.l d0,a0 ; if heap is small because we’re on a small RAM machine
|
||
bhs.s @enoughReservedForSysHeap ; pretend heap is at initialSysHeapSize because it will
|
||
; be that big soon anyway.
|
||
move.l d0,a0 ; Set to be the minimum we’d ever consider.
|
||
@enoughReservedForSysHeap
|
||
add.l #minProcessMgrSpace,a0 ; where the process mgr heap would end if we
|
||
; created it right now
|
||
cmp.l BootGlobals.bufPtrLimit(a5),a0 ; processMgrHeap.bkLim > current barrier?
|
||
bls.s @dont ; if not, don’t adjust
|
||
|
||
move.l a0,BootGlobals.bufPtrLimit(a5) ; set new barrier
|
||
@dont
|
||
rts
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
IF NOT forROM THEN ; not for us either... <SM28>
|
||
TemporaryStripAddress
|
||
|
||
; This is a copy of StripAddress used on the Plus and SE during initialization.
|
||
; Another copy in the patches is used after initialization is through.
|
||
|
||
AND.L Lo3Bytes,D0
|
||
RTS
|
||
ENDIF
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
EraseMyIcon
|
||
|
||
IF NOT forROM THEN ; <28>
|
||
|
||
; Get rid of the happy Macintosh icon.
|
||
; The ROMs leave this icon on the screen and now that we have taken part of the
|
||
; boot process away from the ROM we need to erase that icon. For the old ROMs we
|
||
; call the EraseMyIcon routine in ROM wherever that happens to be in each specific
|
||
; ROM.
|
||
|
||
btst.b #hwCbAUX,HWCfgFlags ; are we under A/UX?
|
||
bnz.s @noErase
|
||
|
||
move.l ROMBase,a0 ; point to ROM
|
||
move.w 8(a0),d0 ; get ROM version
|
||
lea EraseMyIconTable,a1 ; point to table of EraseMyIcon routine offsets
|
||
@next
|
||
move.w (a1)+,d1 ; next ROM version
|
||
bz.s @noErase
|
||
move.w (a1)+,d2 ; ROM offset
|
||
cmp.w d0,d1 ; the right ROM?
|
||
bne.s @next ; no, go on to the next one
|
||
jmp 0(a0,d2.w) ; call the routine
|
||
@noErase
|
||
rts
|
||
|
||
EraseMyIconTable
|
||
|
||
; This is a table of the routines used to erase the startup icon on various machines.
|
||
; A better approach would be a trap or vector, for new ROMs.
|
||
|
||
dc.w kROMVersionII,$18A4 ; II
|
||
dc.w kROMVersionPortable,$2B0C ; Portable
|
||
dc.w kROMVersionIIci,$17DA ; IIci
|
||
dc.w 0
|
||
|
||
ELSE ; <28>
|
||
|
||
; SuperMario based ROMs have a vector at the start of the ROM where the <28>
|
||
; address of the EraseMyIcon routine from ROM is stored. So let's call it. <28>
|
||
|
||
WITH ROMHeader
|
||
|
||
MOVE.L ROMBase,A0 ; Get base o ROM
|
||
ADD.L EraseIconOff(A0),A0 ; Add in the offset to the Happy Mac erase code
|
||
JSR (A0) ; Erase it. <SM28>
|
||
|
||
ENDWITH
|
||
|
||
rts
|
||
|
||
ENDIF
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
CenterOnMainScreen
|
||
|
||
; Center a rectangle on the main screen. The rectangle is passed on the stack.
|
||
; The rectangle is modified in place on the stack (a rectangle, not a pointer to it).
|
||
;
|
||
; stack -> rectangle is passed in on top of the stack
|
||
;
|
||
; Trashes d0-d2/a0-a1
|
||
|
||
lea 4(sp),a0 ; get pointer to the rectangle in question
|
||
|
||
move.l a0,-(sp) ; push rectangle pointer
|
||
moveq #2,d0 ; push horizontal offset
|
||
bsr.s @pushOffset
|
||
moveq #0,d0 ; push vertical offset
|
||
bsr.s @pushOffset
|
||
_OffsetRect ; offset the rectangle
|
||
|
||
rts ; and return
|
||
|
||
@pushOffset
|
||
|
||
; Push offset for the rectangle = screenTop - rectTop + screenHeight - rectHeight.
|
||
; Because screenBits.bounds.topLeft is (0, 0) this simplifies to offsetting by
|
||
; (screenBits.bounds.bottom - rect.bottom - rect.top) / 2.
|
||
;
|
||
; This is all described in terms of the Y dimension, but works for the X dimension, too.
|
||
;
|
||
; a5 -> globals
|
||
; a0 -> pointer to rectangle
|
||
; d0.W -> dimension (0 for Y, 2 for X)
|
||
; stack <- routine pushes the offset onto the stack
|
||
;
|
||
; Trashes d1/a1
|
||
|
||
move.l (sp)+,a1 ; get return address
|
||
|
||
move.w BootGlobals.quickDrawGlobals.screenBits+bounds+botRight(a5,d0.W),d1
|
||
sub.w botRight(a0,d0.W),d1
|
||
sub.w topLeft(a0,d0.W),d1
|
||
asr.w #1,d1 ; divide by 2
|
||
|
||
move.w d1,-(sp) ; move this offset onto the stack
|
||
|
||
jmp (a1) ; return
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
IF NOT forROM THEN ; This patch is not needed when building this as <28>
|
||
; a gibbly for SuperMario based ROMs. <28>
|
||
|
||
CachesOffMFMPatch
|
||
|
||
MOVE.L (SP)+,DskRtnAdr ;Save return address
|
||
MOVEA.L IWM,A4
|
||
LEA wData(A4),A3 ;Point to write data and
|
||
LEA rHandshake(A4),A4 ; handshake registers for speed
|
||
|
||
MOVE.B #$F5,wPhase-wData(A3) ;select another drive address (in this case x101)
|
||
; to avoid the drive's index crosstalk problem
|
||
TST.B rError-wData(A3) ;Clear the error register
|
||
MOVE.B #$18,wZeroes-wData(A3) ;Clear the write and action bits
|
||
MOVE.B #$10,wOnes-wData(A3) ;Set the write bit
|
||
MOVE.B #$01,wOnes-wData(A3) ;Toggle the clFIFO bit to clear out
|
||
MOVE.B #$01,wZeroes-wData(A3) ; any data in the FIFO
|
||
TST.B rError-wData(A3) ;Clear the error register again for grins
|
||
|
||
; Delay a bit then write the sync bytes before the data mark to position
|
||
; the sector data in the correct location relative to the address header.
|
||
; We'll poll the SCC while we wait to keep the CompuServe types happy that
|
||
; we're not losing precious bytes of gossip while we're saving stuff to disk...
|
||
|
||
MOVE.W #kNoCacheWriteAdj,D0 ; write splice timing constant
|
||
JMP $4086EFF4 ; Jump back into the ROM WrData code on Quadra 700 (Spike).
|
||
|
||
|
||
EndCachesOffMFMPatch EQU *
|
||
|
||
ENDIF ; IF NOT forROM <28>
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
|
||
;__________________________________________________________________________________ <<SM15>> thru next <<SM15>>
|
||
;
|
||
; EnablePDMsgs - Enable Eclipse PowerDown Messages
|
||
;
|
||
; This causes Caboose PowerDown messages to be sent to Eclipse instead of
|
||
; having Caboose turn the power off FOR you. This way, we can unmount volumes
|
||
; and flush file caches, etc. The code that does this is initialized in the ROM
|
||
; but has problems running before the filesystem is initialized. Hence, it lives
|
||
; here because this is where the ShutdownMgr finally gets itself established.
|
||
;__________________________________________________________________________________
|
||
|
||
|
||
EnablePDMsgs
|
||
; Only perform this initialization on machines that have Caboose-style keyswitches <5>
|
||
; (i.e.: Eclipse + Zydeco) <5>
|
||
; AND now (i.e.: Cyclone and Cyclone LC) <5><SM13> rb
|
||
;
|
||
move.l d0,-(sp) ; save a handy working register <5>
|
||
move.l #KeyswMask,d0 ; get isolation mask ready <5>
|
||
and.l UnivROMFlags,d0 ; grab keyswitch bits in UnivROMFlags <5>
|
||
sub.l #KeyswCaboose,d0 ; and check if we're a Caboose keyswitch <5>
|
||
movem.l (sp)+,d0 ; restore D0 (MOVEM doesn't reset CCR) <5><SM13> rb
|
||
blt.s @exit ; IF Caboose-Style Keyswitch THEN <5><SM13> rb
|
||
;
|
||
; Enable Caboose/Cuda to send Power Down Messages
|
||
;
|
||
WITH EgretPB
|
||
|
||
movem.l d0/a0-a1,-(sp) ; create some work registers
|
||
suba.l #EgretPbSize,sp ; make room for PB
|
||
move.l sp,a0 ; point A0 to parameter block
|
||
move.w #(PseudoPkt << 8) \
|
||
+ EnDisPDM,pbCmdType(a0) ; Enable PowerDown Messages
|
||
clr.l pbParam(a0) ; clr parm <SM6>
|
||
move.b #PDMTurnOn,pbParam(a0) ; Egret powerdown msg enable <SM6>
|
||
clr.l pbCompletion(a0) ; No Completion
|
||
_EgretDispatch
|
||
|
||
adda.l #EgretPbSize,sp ; discard the parameter block
|
||
movem.l (sp)+,d0/a0-a1 ; restore registers
|
||
@exit ; ENDIF
|
||
rts ; Return to Caller <SM15>
|
||
ENDWITH
|
||
|
||
|
||
EndOfBootCode
|
||
|
||
|
||
; ——————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
end
|