; ; 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): ; ; 11/7/93 SAM Roll in from mc900ftjesus. ; 11/7/93 SAM Sync-in this file with CPUBootcode.a from the gibbly sources. ; 7/21/93 RC Changed RegisterROMComponent to selector 42 instead of 27 ; 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. ; 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. ; 6/15/93 SAM Undid change for PDM. We dont need a gibbly to boot ; (we're actually turning the ROM you see...) ; 6/14/93 kc Roll in Ludwig. ; 3/25/93 GS Added GetGibbly and CanthisGibblyBootThisMachine routines to put ; up the proper Alert when booting a 7.1 System without a Gibbly. ; 4/20/93 SAM Removed a call to _InitFonts, cuz _InitGraf calls it. ; 2/12/93 PN Add forROM condition for the previous change ; 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. ; 02/10/93 HY Enable Appletalk on LCR/LC930 again. Revert changes. ; 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. ; 01/11/93 jmp Updated various BoxFlag names. ; 12/16/92 HY Disable Appletalk on LCR/LC930. ; 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. ; 12/1/92 RB Added a call to MakeOverrideMap so that the 'rovm' resource is ; used to override some system resources. ; 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. ; 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. ; 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. ; 11/3/92 fau Corrected a dereference in DetachandExecute. ; 11/01/92 HY Conditionalize changes in for LC930 because we don't have ; VM in ROM. ; 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. ; 10/29/92 SWC Changed ShutdownEqu.a->Shutdown.a. ; 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 : 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 : 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 : 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,: 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,: 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,: 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,: 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,: 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. ; 4/10/87 bbm Save off the A5 world for the inits. (Some inits relied on ; CurrentA5 to be set up.) ; 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. ; 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). ; 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. ; 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’. ; 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. ; 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 ; 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. ; 3/15/88 DBG Prevent invisible INIT files from running ; 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 ; 10/2/87 DAF Added an InitGraf before the InitPalettes so that all gDevices ; will be active. ; 9/21/87 DAF Changed the ROM85 test in s277 to test MacII or greater, rather ; than equal. ; 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. ; 4/10/87 JTC Fix CDEV to be cdev. ; 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. ; 2/14/87 JTC Call InitApplZone after SetApplBase to get initialation ; attendant thereto. ; 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> include 'SonyEqu.a' ; <11> include 'TextServices.a' ; so we have SetTextServiceLanguage <14> include 'UniversalEqu.a' ; <15> MACHINE MC68020 ; _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 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) ; —————————————————————————————————————————————————————————————————————————————————————————————————— 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). 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... MOVEC CACR,D0 ; Get the CAcheControlRegister AND.L #~((1< 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 ; 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> 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> 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 ; 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 ; rb 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 ; rb 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. ; *** 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) . Make Override needs to be called before ; all the System 7 toolbox init code runs, TEInit after, and finally ROM component registration. ; ; 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 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 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 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? ) 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 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 rb move.w #mapTrue,ROMMapInsert ; use the ROM if available rb ENDIF ; 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 rb MOVE.L D1,-(SP) ; save resource type rb MOVE.W D0,-(SP) ; save resource id rb ENDIF ; 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? hy IF forROM THEN ; ADDA.L #6,SP ; clean up stack and get out of here hy ENDIF BRA.S @skip ; we didn’t get it, so just go on hy @GotResource ; found it hy IF forROM THEN ; rb CMP.L #'ptch',2(SP) ; was this lowercase patch ? rb BNE.S @NotROM_VM ; if not, keep on rb CMP.W #42,(SP) ; was it id 42, VM ? rb BNE.S @NotROM_VM ; if not, don't special case rb MOVE.L D1,A0 ; put ROM's VM res handle in a0 rb MOVE.L A0,-(SP) ; save this handle, potential ROM res rb MOVE.L (A0),A0 ; let's get its pointer rb MOVE.L A0,D0 ; copy resource pointer to D0 rb _StripAddress ; if in 24 bit mode, get rid of flags rb MOVE.L (SP)+,A0 ; recover the resource handle rb CMP.L ROMBase,D0 ; is it a ROM resource ? rb rb BLT.S @NotROM_VM ; if not, don't copy to RAM, it's RAM rb _HandToHand ; copy ROM to memory rb MOVE.L A0,D1 ; and set their handle to ptch 42 rb _HLock ; make sure it's locked too rb @NotROM_VM ; rb ADDA.L #6,SP ; recover saved type and id 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... 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. 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> ; —————————————————————————————————————————————————————————————————————————————————————————————————— ;__________________________________________________________________________________ <> thru next <> ; ; 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> 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> rb blt.s @exit ; IF Caboose-Style Keyswitch THEN <5> 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 move.b #PDMTurnOn,pbParam(a0) ; Egret powerdown msg enable 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 ENDWITH EndOfBootCode ; —————————————————————————————————————————————————————————————————————————————————————————————————— end