; ; File: PatchPlusROM.a ; ; Contains: patches for the first ROMs shipped in a Macintosh Plus ($0075) ; ; Copyright: © 1985-1992 by Apple Computer, Inc., all rights reserved. ; ; Change History (most recent first): ; ; <63> 1/19/92 DTY Look at emAppleTalkInactiveOnBoot before getting the AppleTalk ; version. If AppleTalk is inactive, don’t set up the serial port ; for use by AppleTalk. This is part of a large conspiracy to ; convince the universe that AppleTalk really isn’t around if it ; is inactive. ; <62> 8/30/91 DTY Define onMac and has3rdFloppy in this file instead of in ; FeatureList in BBSStartup. onMac is true because this file ; patches the Mac Plus ROM. has3rdFloppy is false because it was ; always false for System builds. ; <61> 6/12/91 LN removed #include 'HardwareEqu.a' ; <60> 3/17/91 eh Serial driver status calls 9 and $8000 now return hardcoded ; driver version instead of getting it from DCE. This obviates the ; need for the linked patch to _Open to patch the version number ; in the DCE, a fix which was causing FileShare to crash. ; <59> 3/4/91 dba dty: get rid of SysVers conditionals ; <58> 2/21/91 eh (djw)Fixed bug in Serial Driver that was preventing use of one ; port when Nike was printing on the other. ; <57> 2/13/91 eh (djw) Re-did async serial driver patch. Combined all previous ; patches into a single patch. Now support the NIKE printer. ; <56> 1/19/91 mbs (jg) Include ATalkPrivateEqu.a to get AGBHandle equates since ; they were moved out of ATalkEQU.a. Add local equate for ; ATPFirst = 249 since it has changed since the Plus ROM was ; created. ; <55> 1/14/91 djw (eh) Fix bug in SCSI Quantum patch which was transferring one ; extra data byte on multi-block writes. ; <54> 12/16/90 dnf (dba) Conditionalize Patch #40 (Volume rename patch) out of 7.0. ; It has been moved into FileMgrPatches.a ; <53> 12/15/90 djw (jwk) Add SCSI Mgr support for Quantum 7.9 ROM problem by adding ; a separate TIB interpreter and replacing blind write ; <52> 12/14/90 bbm (djw) roll in linked comefrompatch from patchplusrom.a into ; resourcemgrpatches.a. ; <51> 12/14/90 dnf (jsm) Turn all patches on ExtFSHook off for 7.0 since they have ; been moved to LaterFileMgrPatches.a ; <50> 12/13/90 BBM (stb) move the patch to compactmem into memorymgrpatches.a. ; <49> 12/11/90 BBM (JSM) moved the superpatch fix to ResourceMgrPatches.a, as this ; comefrom patch is now a linked patch. ; <48> 11/28/90 JSM Move come-from patches on _NewHandle and _DisposeHandle ; inside UpdateResFile to ResourceMgrPatches.a. ; <47> 11/26/90 JSM Fix previous comment. ; <46> 11/26/90 JSM Delete come-from patch on _StackSpace inside RgnOp since ; it never worked (see QuickDrawPatches.a for details), move ; come-from patch on _ValidRect inside SetIText to ; DialogMgrPatches.a. ; <45> 11/20/90 JSM Move come-from patch on _GetResource inside GetNextEvent ; to ToolboxEventMgrPatches.a; don't need come-from patch on ; _GetResource inside the dialog manager for 7.0, which means the ; entire _GetResource patch here is unneeded for 7.0. ; <44> 11/14/90 JSM Move come-from patch on _TEAutoView to fix dialog manager ; bug to DialogManagerPatches.a. ; <43> 11/12/90 CL (reviewed by PKE)onMac is defined to a non-zero value in the ; system builds even though there is non mac plus code being built ; for it. Changing the onMac flag to different name which is not ; used. ; <42> 11/9/90 PKE (really CEL, reviewed by PKE) Define onMac for ColorEqu.a so ; JStdTbTbl is set correctly for MacPlus. ; <41> 11/9/90 dba & gbm; Move LoadResource patch that checks for errors while ; loading WDEFs and CDEFs to WindowMgrPatches.a and ; ControlMgrPatches.a; move SectRect patch that disables the ; Control Manager’s overzealous change to not draw a control to ; ControlMgrPatches.a — more steps towards the obsolescence of ; this file; put patch protection header on patch to ResrvMem for ; the async. driver ; <40> 10/21/90 gbm (with dba) get rid of GetVol patch (GVPatch) for StartBoot in ; 7.0, since StartBoot isn’t used in 7.0 ; <39> 9/25/90 KIP Change Sound Mgr. to a linked patch. ; <38> 9/22/90 dba get rid of Time Mgr. patching here since we now use the real ; TimeMgr.a to make a linked patch ; <37> 9/21/90 KON Move StdBits patch to AllB&WPatch.a and make it a linked patch. ; <36> 8/18/90 dba get rid of ptchInst 7 and 8 (Sony Format and Eject patches) as ; they are now linked patches ; <35> 8/17/90 dba move CloseDialog patch (come-from on DisposeHandle) to ; DialogMgrPatches.a, since it trashes other patches to ; DisposeHandle, and since all come-from patches should become ; linked patches eventually ; <34> 8/14/90 DTY Removed ptchInst 0 since TextEdit is now a linked patch. ; <33> 8/8/90 SAM Changing DispatchHelper & ProcHelper into an old style ptch. ; •••--> Temporary <--••• Remove when the Sound ptch get converted ; into an Lptch. ; <32> 7/30/90 dnf Remove installation of ptch 18 (File Manager) and ptch 6 (Btree ; Manager), now linked patches ; <31> 7/23/90 dba get rid of ptch 1 since Menu Mgr. is now a linked patch ; <30> 7/23/90 dba get rid of ptch 25 for 7.0; it is covered by DialogMgrPatches; ; get rid of extraneous pre-6.0.6 SysVers conditionals; removed ; ptchInst 16 since PrGlue is a linked patch ; <29> 7/20/90 DTY Removed ptchInst 10 & 11 since Bass is finally a linked patch. ; <28> 7/19/90 CCH NEEDED FOR SIXPACK: Removed HwPriv patch. It's now a ; linked-patch. ; <27> 7/2/90 DTY Removed ptchInst 21 since Resource Manager extensions are now in ; a linked patch. ; <26> 6/26/90 DTY Remove ptchInst 2 since Notification Manager is now a linked ; patch. ; <25> 6/25/90 DTY Remove ptchInst 9 since ScrollSpeedFix is now a linked patch. ; <24> 6/19/90 VL Remove PtchInst 29 since MiscPatches is a linked patch now. ; <23> 6/12/90 JSM Remove PtchInst 33 since PPC Toolbox is a linked patch now. ; <22> 6/11/90 EMT Moved alternate trap dispatcher loading to boot blocks. ; <21> 6/7/90 EMT Remove PtchInst 17 since Layer Manager is a linked patch now. ; <20> 6/7/90 VL Remove PtchInst 28 since HelpMgr is a linked patch now. ; <19> 5/29/90 DDG NEEDED FOR SIXPACK: Changed all the sixpack conditionals from ; six-point-oh-seven to six-point-oh-six. ; <18> 5/10/90 JSM AliasMgr now a linked patch, don't install it here anymore. ; <17> 5/2/90 BBM add makesysfree for 6.0 systems ; <16> 4/16/90 SMB Changed 'ptch' 27 conditionals to include it for 6.0.6 builds. ; <15> 4/16/90 csd moved the patch install of ptch 29 (shutdown manager and misc) ; before the install of PPC because PPCLoader calls ; ShutDownInstall. ; <14> 4/11/90 dba get rid of patch to InitApplZone for 7.0; move PPC after B-Tree ; Manager ; <13> 4/4/90 KON Remove ptch 44 and 35 since they are now linked patches. ; <12> 3/29/90 KON Install ptch 44 for all b&w machines. ; <11> 3/27/90 BBM fix a VRemove bug under the new bootblocks. ; <10> 3/23/90 NC Added ptch 43 for System 6.0.6 on up. This is for Sound. ; <9> 2/20/90 DD Changed the pchRead to do a proper come-from patch; it now ; compares the return address first, and calls oldRead instead of ; ROMRead. This makes it compatable with other come-from Read ; patches, like the one for SizeRsrc in compression. ; <8> 2/5/90 DDG Fix SysBeep by including it in the sound manager patch instead ; of the individual patches for each ROM (Neil [NC] actually did ; the fix) ; <7> 2/4/90 dba get rid of SysBeepPatch because it is in the Sound Mgr. patch ; <6> 1/31/90 SMB NEEDED FOR Scripts604 and 6.0.5 - Fixed Dialog Mgr bug that ; didn't get rolled into rom. Have to do a come-from patch in ; TEAutoView to fix a rect for R-to-L text. ; <5> 1/22/90 PKE Used new InstallGestaltEarly symbol to control whether Gestalt's ; ptch 5 installation is done earlier (needed for TextEdit 3.0), ; and made it happen for SysVers>=$605 instead of SysVers>=$700. ; (This is already in the System6Proj sources). ; <4> 1/13/90 EMT Put StripAddress back in. Darin was confused. ; <3> 1/12/90 CCH Added include of “HardwarePrivateEqu.a”. ; <2> 1/4/90 dba conditionalized out WaitNextEvent for 7.0 since we always have ; MultiFinder; install BadTrap patch for DebugStr as well as ; Debugger for 7.0, since we have a large trap table; get rid of ; Launch patch for Radius for 7.0 because Ed Tecot sez, and ; because it just makes some Radius features go away, it doesn’t ; crash (we told Radius this would happen); got rid of pre-HMenus ; Menu Mgr. patches and got rid of the HMenus conditional; got rid ; of StripAddress since it is now installed before patches are ; loaded; got rid of the patch and setup that was used to do the ; override of the MBDF for switch-launching since 7.0 does not ; switch launch (MultiFinder-only); renamed some symbols and got ; rid of some extraneous equates to avoid warnings ; <1> 12/17/89 CCH Adding for the first time into BBS. ; <6.2> 12/11/89 GMR Added ptchInst 8; Sony Format patch is now in it's own patch ; file (FormatPatch.a). ; <6.1> 11/29/89 GGD NEEDED FOR 6.0.5 Enabled the Extended Time Manager (which ; matches the code that is in the IIci/Portable ROMs) ; <6.0> 11/21/89 EMT NEEDED FOR 6.0.5: Added humane scrolling. ; <5.9> 11/16/89 EMT Moved KeyTrans trap as well, since keyboard relies on it. ; <5.8> 11/16/89 EMT Moved keyboard initialization to ROMAllFix for FullWrite and ; MacroMaker. ; <5.7> 11/10/89 rwh NICE FOR 6.0.5: backpatch hwPriv to accelerated Plusses. ; <5.6> 10/31/89 KST relblock patch is not necessary on System 7.0 (patches now load ; after Ramcache, this will break Mac Plus. ; <5.5> 10/30/89 EMT Moved keyboard initialization here from INITs 0 & 1. ; <5.4> 10/16/89 csd Moved the code that installs the expanded trap dispatcher to the ; beginning of the installation section, before all other patches. ; <5.3> 10/15/89 BAL Added support for 32-Bit QuickDraw pictures via ptch 35 ; <5.2> 10/6/89 JSM Removed SnarfMan 'ptch', now PACK 13. ; <5.1> 10/4/89 EMT Added the PPC Toolbox as a 'ptch'. ; <5.0> 9/4/89 PKE Install Script Manager 7.0 extensions, ptch 27. ; <4.9> 8/28/89 SES Removed references to nFiles. ; <4.8> 8/22/89 PKE NEEDED FOR 6.0.4 (SCRIPTS BUILD) & 7.0: Conditionalize 4.7 for ; Scripts604 OR (SysVers >= $700) ; <4.7> 8/19/89 PKE NEEDED FOR 6.0.4 (SCRIPTS BUILD) & 7.0: Moved PtchInst 5 ; (Gestalt) ahead of other PtchInsts so they can use Gestalt. ; <4.6> 8/8/89 GMR Added ptch 29 - BigBang only patches for all ROMs ; <4.5> 8/1/89 BG Modified the conditional for <4.3> to be (SysVers >= $700) to ; make sure it does not appear in any 6.0.x builds. ; <4.4> 7/25/89 GMR Needed for 6.0.4: Added Sony Eject patch (ptch 7) ; <4.3> 7/7/89 BG Added Gary D.'s optimized A-Trap dispatcher to Mac Plus. ; <4.2> 6/30/89 BBM Added resource mgr extensions ('ptch' 21). ; <4.1> 6/29/89 RLC Added HelpMgr PatchInstall macro for patch #28 ; <4.0> 6/21/89 NJC Added a ptchinst 3 to if it wasn't already there and added in a ; commented-out ptchinst 23 for the sound dispatcher,DJ, and S.M. ; enhancements. ; <3.9> 6/13/89 dnf Moved btree ptch install after hfs70 ptch install. ; <•3.8> 6/10/89 CEL Moved Private.a QuickDraw Equates into proper QuickDraw private ; file (colorequ.a), got rid of QuickDraw nFiles dependencies and ; fixed up necessary files… ; <3.7> 5/31/89 CEL Only defined Spline_Font variable if it is undefined - makes it ; easier to build test 6.0.4 systems ; <3.6> 5/31/89 prp Added Alias Manager Support ; <3.5> 5/30/89 dnf Added HFS 7.0 Enhancements (ptch 18) ; <3.4> 5/26/89 CCH Conditionalized out install of 6.0.4 PrGlue. ; <3.3> 5/25/89 CCH Re-added PrGlue patch that was taken out in v2.7 for 6.0.4. ; <3.2> 5/23/89 EVA SysVers conditional is $700 for deferred task patch; DTsk ; globals use DC, not DS ; <3.1> 5/23/89 jaz Change version conditionals to test for $700 and not $604 ; <3.0> 5/19/89 jaz Add code to patch in Gary D's new Extended Time Manager ; <2.9> 5/18/89 ggd (Really EH) added Deferred Task Manager; patched level 1 thru 3 ; int handlers ; <2.8> 5/13/89 EMT Added Window Manager extensions (Layers). ; <2.7> 5/8/89 NMB Replaced PrGlue with Ginsu's PrGlue. ; <2.6> 5/4/89 CCH Moved include of ToolTrapFix so that it would be executed at ; installation time. ; <2.5> 5/3/89 CEL Rolling in Bass for the first time into EASE… ; <2.4> 4/18/89 JSM Install SnarfMan 'ptch'. ; <2.3> 4/17/89 CCH Rolled out Altair changes. ; <2.2> 3/22/89 CCH Now looks for DiskCachePriv.a in Aincludes directory. ; <2.1> 3/21/89 KST Added install code to bring in Btree Manager. ; <2.0> 3/17/89 CCH Fixed install of Cache Control Trap so that it installs under ; 6.0.4. ; <1.9> 2/22/89 CCH Added install code to bring in Gestalt patch. ; <1.8> 2/21/89 JB (DNF, actually) These files seems to work now, so I'm checking ; them back in. ; <1.7> 2/21/89 JB Added include of 'DiskCachePriv.a' and fixed duplicate symbols. ; <1.6> 2/20/89 JB Cleaned up revision history comments. ; <1.5> 2/20/89 JB Added change history comments to previous submission. ; <•1.4> 2/20/89 JB Moved cache control trap and "not a Mac disk" extfspatch from ; BeforePatches.a. Dave & Joe ; <1.3> 2/2/89 CCH Changed a short branch to a long branch in both 6.03 and Big ; Bang. ; <1.2> 1/31/89 CCH Merged changes from 6.0.3. ; <1.1> 1/16/89 CCH Merged 6.0.3 final sources into 7.0. ; <1.0> 11/16/88 CCH Added to EASE. ; PMAB581> 10/16/88 GGD Installed latest version of TimeMgr, which also includes work ; around for bug with Rockwell VIAs (6.0.3 and Altair) Replaces ; PMAB564 ; PMAB574> 9/24/88 jwk Rolled old SCSI Mgr enhancements into the patch files. ; 9/22/88 jwk Added Deferred Task Mgr to the Plus and SE. ; 8/18/88 djw Fix to PMAB372 async DTR patch. The patch is not being cutback ; properly when installed on a Mac 512K. Cleaned up comments for ; PMAB372 ; PMAB564> 8/18/88 ggd Patched in the New Improved Time Manager for all CPUs, ; Completely replaces old Time Manager, and replaces patches on ; MacPlus and MacSE. ; PMAB559> 8/9/88 BAL Altered change to FontMgrPatch.a (PMA542) to continue checking ; fractEnable. ; 7/25/88 DAF Removed some code from FontMgrPatch.a to correct FOND measuring ; bug. Patch visualization and design, courtesy of BAL. ; PMAB528> 7/12/88 CEL/DAF Made width tables non-purgeable. ; 6/7/88 med Changed Script Manager to ptch resource ; 5/4/88 EMT _SCSIStat breaks Radius Accellerator in MacPlus. ; 4/29/88 bbm changed hardwired constant to HiIntMask in hardwareEqu (see ; s481). ; 4/27/88 bbm There was a small window after the vremove where a timer ; interrupt could happen. Since the sound driver services the ; timer in the vbl task, the code to reinstall the vbl task would ; never happen. ; PMAB466> 4/13/88 JWK Fixed SCSIGet to perform cleaner arbitration. ; PMAB457> 4/7/88 RWW Fixed CloseDialog to properly disopse TERecord ; PMAB449> 3/30/88 rwh replace SysEnvirons code w/INCLUDE SysEnvirons.a (Version 2!) ; PMAB442> 3/25/88 EKH Fixed 'PatchInstall' fail bug. (Wasn't calling SysErr ; correctly). ; 3/4/88 EMT Fix bug in PMA314 which left ROMMapInsert set. ; PMAB407> 2/26/88 DAF Removed PMAB370 (UprStr). I didn't know that you could use ; UprStr to just strip diacriticals. My post processing was ; causing AppleShare to get grave accents accidentally when ; stripping names. This can still be fixed, it just requires a ; deeper fix rather than post processing. ; PMAB401> 2/23/88 djw Bug in async driver - killIO did not set reg D0 to good return ; status. Combine with patch #42 ; 2/22/88 ABO Fixed a bug in PMAB301 patch for MacPlus ; 2/21/88 DAF Fixed StdBits to use (corrected) PackBits (for Scanner app). ; PMAB372> 1/26/88 djw Fixed DTR bug in async serial driver - a jump to the wrong ; label. Combined this with old serial patches (#3,#42) in ; ResrvMem. ; PMAB370> 1/25/88 DAF UprStr had an "a" instead of a "`" in it's case table, so I ; added a post-call scan of the string to fix this. ; 1/18/88 AWC Add fast polygon stuff to PatchPlusROM.a, PatchSEROM.a ; PMAB354> 1/7/88 EMT Unimplemented Toolbox versions of 12 bisexual traps ; PMAB340> 12/17/87 EMT Miscellaneous fixes to NMgr + System Alarm uses NMgr. ; PMAB335> 12/15/87 EMT ptchInstall now calls SysError on failure ; PMAB329> 12/10/87 JWK Fixed SCSI patch to avoid 10sec delay if booting with no SCSI ; devices attached. (PMAB295) ; 12/8/87 jw Added new sysbeep, calls sound manager like Mac II ; PMAB318> 11/30/87 jw Added new improved sound manager. ; PMAB317> 11/28/87 EMT Added Notification Manager. ; 11/25/87 EMT Patch GetResource to get MBDF instead of ROM override on Plus, ; SE ; PMAB315> 11/25/87 RWW Err, GetResource doesn't return resNotFound? Fixed ptchInstall ; 11/24/87 EMT Install Menu Manager using 'ptchInstall' method. Undoes PMA097. ; PMAB310> 11/24/87 PYG/EMT Make WaitNextEvent trap for Classic Mac OS. ; PMAB308> 11/24/87 RWW Added ptchInstall, which installs 'ptch' resources. This saves ; keeping duplicate copies of identical code in several patch ; files. ; PMAB309> 11/24/87 RWW Massive, world-shattering change - yank TE patches and do this ; whizzy new installation ; PMAB305> 11/22/87 DAF Fixed buffer calculation bug in RgnOp ; PMAB301> 11/15/87 ABO Fix ATP delayed duplicate response bug ; 10/27/87 NMB Fixed DrText through _StdTxMeas so that QuickDraw properly ; handles fonts larger than 128Kb. ; PMAB295> 10/19/87 SHF Changed the routine that tries one last time to load SCSI ; drivers from SCSI devices. It tries to clear up SCSI bus ; problems before and after loading the drivers, and the selection ; timeout was extended from about 5 msec to 25 msec to increase ; the safety margin. ; 10/8/87 bbm Since the new font manager is now backpatched on the macplus we ; now need to invalidate the new font manager if a CloseResFile ; occurs. ; 9/25/87 BB Modified MountVol patch (#17) to clean up stack before calling ; other patches which are also linked in the "ExtFSHook" chain. ; PMAB284> 9/21/87 JTC Amend patch to CompactMem to fix MoveHHi dinky block creation. ; This patch just adds more code to the patch, nothing more ; exciting. ; 9/18/87 bbm sound manager uses sound manager uses soundactive different than ; sound driver. Thus soundactive could be true with no sound vbl ; task installed. So now we check for an error from vremove, which ; we should have done in the first place. (This is the same patch ; as S278, which got deleted when PMAB284 was checked in.) ; PMAB270> 9/13/87 FJL Fix DrawPicture patch (in DrawPicturePatch.a) to first check for ; valid picture handle and pointer, then do GetState, lock, and ; SetState on return. At the request of Sheila, Phil and Scott. ; 9/7/87 bbm The current sound driver uses low memory as a vbl queue element. ; A bug occurs if sound is active. The low memory queue element is ; zeroed regardless if there is a next element in the queue or ; not. Thus the machine may hang. The fix forces the sound vbl ; queue element to be last in the queue always. ; PMAB271> 9/14/87 BB/JB Modified unmount patch PM243 to unconditionally unmount a volume ; if the HFS bit is set in the ioTrap word. ; PMAB253> 8/27/87 CRC Fixed MaxSizeRsrc in FontMgr for Radius (once again) ; 8/25/87 BB/JB Patch UnmountVol to prevent unmount when files are open. ; PMAB241> 8/26/87 RDC Added patch for BadTrap handler routine to save registers before ; exiting to SysError routine - needed for new MacsBug. ; 7/22/87 JTC Patch InitApplZone to base ApplLimit/HiHeapMark on SP not ; BufPtr. This helps at start time when the stack world is in the ; middle of RAM and some hoggish apps want to do a MaxApplZone on ; the miniheap. ; PMAB226> 7/21/87 GWN Backout PMAB216. ; PMAB216> 7/21/87 GWN Patch Read, Write, Control and Status to fix Async problem. ; PMAB210> 7/20/87 DAF WindowMgr,ControlMgr: Adjusted LoadResource to improve handling ; of WDEFs, CDEFs. ; 7/17/87 EHB QuickDraw: Patched packBits to allow scanlines > 127 bytes ; PABM202> 7/9/87 MBK TextEdit: Fix to recalibration bomb when text length = 32,767 ; PABM203> 7/9/87 MBK TextEdit: Fix to deletion bug (display would get messed up) ; PABM197> 7/9/87 MBK TextEdit: Fix to TEStylInsert call when record is deactivated ; PABM198> 7/9/87 MBK TextEdit: Fix to allow styles to be set at null selection ; PABM201> 7/9/87 MBK TextEdit: Fix to allow fixed line heights to work ; PABM186> 7/1/87 CRC RealFont: Undid PBM164 and put in MaxSizeRsrc call instead of ; GetHandleSize ; PABM187> 7/1/87 CRC FMSwapFont: Fixed mismeasuring underline with fractEnable true. ; 6/24/87 EMT PatchPlusROM.a: Fixed FKEYs not working in Excel ; 4/30/87 SHF (#37) Fixed scCompare opcode bug in SCSI Manager patch. ; 4/16/87 CJB Take out incorrect Timer mgr optimization. ; 4/13/87 JTC Insert diagnostic ROM vector call before launch to satisfy ; Radius and other custom hardware folks. ; 4/7/87 JTC&JDT Fix GetStrike utility in FontMgr to avoid doomed GetHandleSize ; after GetResource of FONT sans FOND and with TempResLoad false. ; 3/30/87 JTC Fix reg problem in SystemEvent task. ; PABM150> 3/28/87 JTC&JAF New SysEnvirons trap. ; 3/24/87 SHF (#37) Removed parity checking from SCSI patch. ; 3/23/87 CRC MeasureText fix for new TextEdit and Macintosh Pascal ; 3/19/87 BB Added patch to MapFBlock to fix error in the calculation of ; physical block numbers (adding a word value rather than a long ; word value). ; 3/19/87 BB Fixed MountPatch (#17) to save ExtFSHook and to call other ; routines in that chain. ; 3/19/87 SHF (#37) SCSI patch changes for SuperMac. ; PMAB117> 3/19/87 CRC additional font mgr fixes for disk switch, FONDstate bugs ; PBAM109> 3/17/87 CRC patched ValidRect to restore register clobbered by DrawItem in ; SetIText ; PMAB102> 3/10/87 EMT Fixed all patches to not use FKEYs when code came from keypad. ; 3/10/87 DAF Patched InitWindows and FindWindow to use mbdf (PMA097) ; 3/10/87 FJL Back-patch hierarchical menus. ; 3/9/87 JTC Patch CompactMem to fix MoveHHi problem that would create tiny ; files. ; 3/7/87 bbm (#69) patched _read to fix bug in openresfile. ; 3/2/87 CRC Removed all Font Manager patches and merged with massive ; patch(es). #2a, #30a, #45, #46, 1/2 of #47, #54, #55 removed ; 3/2/87 SHF (#37 re-revisited) Overhauled SCSI Manager, especially TIB ; interpreter, select timing, and added SCSISelAtn, SCSIMsgIn, and ; SCSIMsgOut for compatibility with MacSE and Mac2. ; 2/27/87 mbk Removed all previous TextEdit patches, and merged the ones still ; needed into TEPatch. #10A, #14, #15, #58, and #59 were removed, ; and #56 and #57 were merged into TEPatch. ; 2/25/87 bbm (#68) added new trap rGetResource. ; 2/23/87 MBK All of the new TextEdit is being patched in. ; 2/23/87 JNP (#51 re-revisited); 1. Restore curMap before jumping into the ; print code. Also, under PrintOpen, Move PrintVars+iPrErr to d0 ; instead of testing it. 2. Under PrintOpen, Move PrintVars+iPrErr ; to d0 instead of testing it. 3. Save curMap in a3 before getting ; the PDEF resource the first time. ; 2/22/87 RBB (#53 re-revisited) Fixed PrimeTime even more and brought latest ; ROM code in (incl. patch of RmvTime) ; 2/18/87 DBG Patch DrawPicture,StdGetPic to parse version 2 pictures. ; 2/18/87 DBG&JTC Broke patch file up into separate PROCs. ; 2/13/87 JNP (#51 revisited) 1). Fixed a BAD bug with stack corruption on ; error exit if the printer resource file does not exist in the ; system folder. - In OpenRF, return _OpenRFPerm error in d0 - ; Removed ResErr check after OpenRF call under OpenPrRF. The error ; is already in d0. - Under OpenPrRF, if we have an error from ; OpenRF, put that error in low memory and branch to GlueAbort. It ; used to bne to LLOut. - Cleaned up GlueOut to eliminate call to ; _BlockMove. 2). Don't close the driver during PrClose. Close the ; resource file only. This is to eliminate the overhead of going ; thru .Print everytime. NOTE: The old PrLink used to leave the ; driver open. It must have been changed when PrLink was changed ; to PrGlue (I think!). - Removed call to _PrDrvrClose from ; PrintClose. ; 1/22/87 JTC (#67) Fix FixDiv/FracDiv, add StripAddress. ; 1/17/87 JTC (#66) Fix FixRound, Fix2Long, Frac2Fix at last. ; 1/15/87 TJ (#65) Added 'figTrkSpd' Timer #2 fix. (Sony driver) FigTrkSpd ; uses T2 to calculate rotation time, and leaves the timer messed ; up. ; 1/7/87 DAF (#64) Added GetCVariant routine to 128K ROMs (from ; PatchSEROM.a). ; 1/7/87 DAF (#63) Added GetWVariant routine to 128K ROMs (from ; PatchSEROM.a). ; 1/5/87 ABO (#62) Patch to VInstall to fix non-atomic test and decrement in ; MPP's VBL task (same as in ROM76PTCH) ; 12/22/86 JNP (#51 revisited) If the GetResource call to get a PDEF fails, ; don't give up. The printer resfile may not be in the resource ; search path. Save and restore the user resource map around the ; GetResource (for PDEF) call. Get the printer resfile refnum from ; the low memory print var ($944+$E) or open the printer resource ; file to get it. After opening the printer resource file, save ; the refnum in low memory. The code to get the printer resfile ; refnum is now in a procedure called OpenRF. Check the print ; error after _PrDrvrOpen call in PrintOpen. ; 12/10/86 TJ (#52) Disabled all interrupts (instead of just VIA) at WakeUp ; patch. Level 2 - 3 is needed for the server, the code is ; straight line and quick so be safe. ; 12/9/86 TJ (#53) PrimeTime fix update: when interrupts are deferred due to ; higher priority interrupts or ints off (Sony diskettes ...) the ; VIA timer goes .LT. 0, and value read cannot be assumed to be ; valid. ; 12/9/86 TJ (#52) Fix to the fix to the fix ... Pat Dirks' original fix of ; raising interrupt level to 1 also prevented a recursion path as ; well as trashed regs ... it goes back in. (Sony WakeUp) ; 12/9/86 ABO (#61) Patch to VInstall to make dummy header for ATP after open. ; Header points to patches to SendRequest, SendResponse and the ; VBL task to call GetDataArea with interrupts off. ; 12/3/86 SHF (#37 revisited) Added a phase change check for polled SCSI ; Manager read, write, and compare. ; 11/25/86 SHF (#37 revisited) Fixed another SCSI Manager bug. ; 11/21/86 jdt (#54) Patch to GetFontName for system font remapping. ; 11/21/86 jdt (#2a revisited,#55) Patched SwapFont in addition to Jerome's ; patch. Now maps international ranges correctly. ; 11/21/86 jdt (#56) Patch to TEAutoView so destRect is correct when teSysJust ; is set. ; 11/21/86 jdt (#57) Patch to TextBox to fix a Dialog Manager problem. The ; Dialog Manager always calls with a left justification, so we ; substitute right justification when teSysJust is set. ; 11/21/86 jdt (#58) Patch the TERecal hook to use a non-zero value for teJust ; when wordRedraw is set. ; 11/21/86 jdt (#59) Patch the TEDoText hook to use the proper teJust value ; when TERecal is set. ; 11/21/86 jdt (#60) Patch KeyTrans so MacPlus can use the new keyboard ; resources. ; 11/7/86 JNP Fixed a bugs in #51. In PrDrvrDCE and PrDrvrVers, put the result ; on the stack at (sp) instead of at 12(a6). Then, jump to GlueOut ; instead of LLOut. Changed Bra.s at PrOCerr to Bra. ; 11/6/86 MED (#16,#36 revisited) Entered JDT's patch. New patch allows only ; the digit keys to be checked by the FKEY code in GetNextEvent, ; and modifies the ascii codes returned by these characters. The ; new keyboard stuff returns codes 30-39 for these characters, ; even when the shift and command keys are down. We substract 30 ; here to bring them into line with the 0-9 codes expected by ; GetNextEvent. ; 10/22/86 TJ (#52 revisited) Fixes to the fixes ... ; 10/20/86 TJ (#52 revisited) Changed patch #52 to fix the real problem with ; the Sony WakeUp call, ie. save the registers first. Raising the ; interrupt level to 1 works as well. Fixed the damn comments. ; 10/14/86 PWD (#52,#53) Patched Sony Driver wake-up routine to raise ; interrupts to level 2 to shut out VIA and patched Time Manager's ; PrimeTime and Reschedule code to take care of multiple-client ; scheduling bug. ; 10/9/86 JNP Fixed bugs in PrPurge and PrNoPurge. Check the low byte of flags ; to see if the driver is RAM based. ; 9/11/86 BB (#50) Patched BasicIO to fix asynch problem and OffLinErr ; problem. ; 9/10/86 BB (#49) Patched FClose to fix refnum problem when called by ; UnMountVol. ; 9/9/86 BB (#48) Patched MountVol to fix rename problem. ; 8/5/86 DLD converted to MPW build style. ; 5/17/86 JTC (#47) Patch GetResource to fix 2 bugs: 1) Font manager can be ; fooled when a fond has been purged but its handle is loaded into ; LastFOND by virtue of a cached width table; when SwapFont is ; called later, the (bogus) 'purge bits' saved in the high byte of ; LastFOND might be blasted on top of a Nil master pointer, ; leading to later disaster. So we watch for this case at the ; critical GetResource. 2) Could/Free-Dialog/Alert call a common ; routine that Get(s)Resource of WDEF #n without blasting MapTrue ; into ROMMapInsert, thus loading the damned WDEF unnecessarily, ; messing up the Finder and others; if GetResource is called from ; one of these common places ROMMapInsert is stuffed before going ; off to the ROM. ; 5/13/86 JTC Moved #45 and #46 above big scsi and async patches. ; 5/12/86 BBM (#11,12,31, revisited) if the compaction gap in updateresfile ; was 1 to 3 bytes long and if the the resource to be moved ; forward in the file was not in memory, the size would write over ; itself. This was the bug that resulted in the random system file ; that was 7 meg in length (or 4 meg, or 8 meg, etc). ; 5/7/86 JTC (#41, revisited) tst.w D0 added to set CCR for direct rts to ; user, as in Switcher 4.4. ; 5/6/86 JTC (#46) Patch FixRatio to catch operand reversal in FontMetrics. ; 5/2/86 JTC (#45) Big patch to SetHandleSize to fix FontMgr problem ; computing height tables. ; 5/2/86 JTC (#44) Appendage to (#41) to handle RecoverHandle as well. ; 4/23/86 JTC (#29a revisited) Fix two problems in DisposHandle side of patch: ; (1) check for return address in correct place in stack; (2) ; bypass memory mgr entirely when bogus stack block is 'disposed'. ; 4/23/86 PWD (#43) Added a patch to BTFlush and BTClose to prevent the ROM ; B*-Tree code from handling user-created B*-Trees when the RAM ; B*-Tree package makes a _FlushFil call from its own FlushCache ; code. ; 4/23/86 LAK (#42) Added another patch for async driver (better control over ; DTR). Only installed for MacPlus. Also made SCSI patch only ; installed for MacPlus. Changed some branches to shorts. ; 4/17/86 JTC Fixed up a misspelled (etc.) reference to Lo3Bytes in ; ReallocHand (etc.) patch. ; 4/16/86 SAB not a patch - just minor cosmetic cleanup ; 4/15/86 BBM (#41) Patch to DisposHandle, ReallocHandle and HandleZone to try ; and get the right zone. ; 4/15/86 PWD (#40) Added patch to Rename to make it handle offline and ; external File System volume renames correctly ; 4/14/86 LAK (#39) Added patch for indexed GetFileInfo. ; 4/11/86 EHB (#38) Replaced duplicate Hlock with a Hunlock ; 4/9/86 JTC (#36) Update SystemEvent patch (watching calls from ; GetNextEvent) to filter command-shift-funny keys, where funny ; maps to ASCII 0-9 and so coinciding with FKeys. ; 4/8/86 JTC (#34) Added patch to InitZone to fix Mem Mgr problem in ; MakePtrSpc <08Apr86> ; 4/8/86 PWD (#35) Added patch to make Sony VBL task run at level 3 (instead ; of level 1) ; 3/13/86 ALR (#33) Updated the version number for new release. ; 3/11/86 PWD (#32) Expanded TFSDPatch to take care of a problem with ; GetWDInfo as well (the top half of D1, expected to be 0 by ; ChkWDRefNum, is never actually cleared, causing the WDRefNum ; check to fail. The patch clears just the top half of D1 on ; GetWDInfo traps before continuing). ; 1/31/86 BBM (#31) Upped the version number by one for this new release. ; Fixed the patch to UpdateResFile (now the pointers work on large ; files, eg the system file). ; 1/9/86 BBM (#29a) fixed UpdateResfile to grab space off the stack when it ; can not find the room for a buffer in the heap. 31 Jan 86 ; JTC&EHB (#30, #30a) RelString -- fix InsertResMenu for adding ; items other than at end. <31jan86> GetFontName -- fix to ; correctly invalidate FONT cache after call. ; 1/2/86 BB (#29) Improved Scavenger patch (now file number must be the file ; number for the catalog or extents file only). Also, the ; CacheFlag is set to force flushing. ; 1/2/86 JTC (#28) Change to HSetFlags to preserve flags across standard ; entry. ; 12/29/85 BB (#27) Added Savenger patch. ; 12/26/85 LAK (#26) Added fix to MoveHHi patch (stack problems). ; 12/20/85 BB (#25) Improved the HD20 driver patch per Larry's instruction. ; 12/19/85 BB (#24) Added patch for HD20 driver (SonyDCD) to fix block count ; problem which occurs during a retry of a read or write ; operation. ; 12/18/85 BBM (#23) Patched MaxBlock to fix a bug in the openresfile superload ; routine. ; 12/17/85 BB (#22) Replaced MountVol patch (dated 10Dec85) with a new patch ; that also patches RenameVol (from Patrick). ; 12/17/85 BB (#21) Added Eric's patch for VIA interrupts. ; 12/13/85 EHB (#20) Added patches for window manager (DragGrayRgn and ; DragTheRgn). ; 12/11/85 BB (#18) Added patch for Control Manager at FileClose (from Ernie). ; Also cleaned up the documentation some. 12 Dec 85 JTC&DLD (#19) ; Patch to InitApplZone to invalidate font cache (setting ; LastSPExtra to -1) so that apps can start up without InitFonts, ; but with a clean slate. ; 12/10/85 LAK (#17) Added patch to MountVol at CmdDone (from Patrick). ; 12/9/85 JTC (#16) Patch to keep FKeys away from ornaments. ; 12/9/85 JTC (#15) Fixed TextEdit patch from previous line to do SIGNED ; multiply! ; 12/8/85 LAK (#14) Added patch to TextEdit to support cursor keys. ; 12/8/85 LAK (#13, 13a) Added sound patch from Mark L., and FileClose patch ; from me. ; 12/6/85 BBM (#12) Changed one equate in the rmgr patch. ; 12/6/85 LAK (#11) Added Brian's resource manager fix for UpdateResFile. ; Fixed patch to GetFCBInfo (sigh). ; 12/4/85 BB (#9 ) Fixed SetEOF patch to also check for calls from ExtBTFile. ; 12/4/85 BB (#10) Fixed FlushMDB patch to use D0 rather than D1. ; EHB (#10A) Patch for Text Editor Standard Entry ; 12/4/85 ELR (#8) Fixed bug in Eric's StartBoot patch. ; 12/4/85 BB (#7) Fixed SetEOF patch to set up condition codes upon exit. ; 12/3/85 BB (#6) Updated some of the patch code documentation. ; 12/2/85 BB (#4) Added Eric's StartBoot patch. JTC&ALR(#5) ; Forced necessary comma in ', SYS' in macro. ; 12/2/85 LAK (#3) Added async driver patch at ResrvMem. ; 11/22/85 BB (#2) Added IODone patch. JTC (#2a) FMSwapFont problem ; patch to fix an invalidation problem ; 11/19/85 PWD (#1) Changed SetEOF patch to check return address directly on A6 ; stack. BB (#1A) Patch for BTDelete (update depth bug) ; BB (#1B) Patch for BTDelete (GetNode bug - trashes the cache) ; 11/18/85 BB New today. BB (#0) Patch for Install Drivers ; STRING ASIS IF (&TYPE('SPLINE_FONT') = 'UNDEFINED') THEN SPLINE_FONT: EQU hasSplineFonts ENDIF IF (&TYPE('USE_MAKESYSFREE') = 'UNDEFINED') THEN USE_MAKESYSFREE: EQU 1 ; need to expand the system heap for 6.0 systems ENDIF IF (&TYPE('Scripts604') = 'UNDEFINED') THEN Scripts604: EQU 0 ENDIF IF (&TYPE('isMacPlus') = 'UNDEFINED') THEN ;<43-CEL,PKE> isMacPlus: EQU 1 ;<42-CEL,PKE> ENDIF ; ; <62> onMac is the MacPlus ; if (&TYPE('onMac') = 'UNDEFINED') then ; <62> onMac: equ 1 ; <62> endif ; <62> ; ; <62> has3rdFloppy is false for System builds. ; if (&type('has3rdFloppy') = 'UNDEFINED') then ; <62> has3rdFloppy: equ 0 ; <62> endif ; <62> load 'StandardEqu.d' include 'HardwarePrivateEqu.a' include 'SonyEqu.a' include 'SCSIEqu.a' include 'PrEqu.a' include 'PrPrivate.a' include 'ATalkEqu.a' include 'ATalkPrivateEqu.a' include 'ColorEqu.a' include 'PrintCallsEqu.a' include 'DiskCachePriv.a' ; P003 <21Feb89><2.2> INCLUDE 'PatchMacros.a' INCLUDE 'ScriptPriv.a' ; <16> ROM75Fix MAIN EXPORT IMPORT RamSysInit EXPORT SysBase,CutBack ; SysBase is the entry point for ROM75Fix. Upon entry D1.L contains our handle. ; ; Once the patches have been installed, this code is cut back to exclude the patch ; installation code. SysBase Bra RamSysInit ; do the patch installation. DC.L ('PTCH') ; resource type <03Dec85> DC.W $0075 ; patch ID $75. DC.W 7 ; current version number. ; cut back the ram-based system code to exclude this initialization code CutBack _SetHandleSize ; adjust our size MOVEQ #$7F,D0 ; a soon to be large number SWAP D0 _CompactMem ,SYS ; optional comma RTS ; all done ;################################ PATCH CODE GOES HERE ####################################### ; Note that keyboard stuff comes first so that debugging is easier… ;_______________________________________________________________________________________ ; (Patch #16, #36, PMAB102, PM184 ; ; Hopefully this is the last time for this patch... ; The previous implementations worked fine, except when the application had ; disabled SystemEvent calls from GNE. This new approach moves the ; responsibility of handling FKEYs from GetNextEvent to SystemEvent. ; ; Function SystemEvent(theEvent: EventRecord): Boolean; ; ; This patch prevents desk accessories from being passed FKey events, which ; they are unable to deal with correctly, and prevents the GetNextEvent ; code from checking for FKEYs unless it really should. ; ; If the event is not a keyUp or keyDown event, it is passed to the regular ; SystemEvent trap immediatly. Likewise, if the trap has not been invoked from ; GetNextEvent, or the modifiers do not specify an FKEY, the patch jumps into ; the regular SystemEvent trap code. ; ; Next, the patch checks the ASCII code for this keyboard event. If it is in ; the range 0..9, we return to the GetNextEvent code, at a point past the FKEY ; check. This is a hack, as these ASCII codes could theoretically be used in ; a menu by an accessory (command-shift-enter and command-shift-backspace). ; ; A second check is then made on the ASCII code; this time to determine wether ; it is a digit. If so, we substract 30 from the ASCII code in the event ; record and return false to the original SystemEvent call. This brings the ; ASCII codes for the digits into line with the 0-9 codes expected by the silly ; GetNextEvent trap code. This should trigger said code into doing the original ; FKEY stuff. ; ; <06nov86> ;_______________________________________________________________________________________ RAMSysEvt PROC EXPORT ROMSysEvt EQU $415BE0 ; start of SystemEvent CheckType move.l 4(sp),a0 ; load eventRecord pointer. cmp.w #keyDwnEvt,evtNum(a0) ; event = keyDown? beq.s CheckMods ; yes => we care about it. cmp.w #keyUpEvt,evtNum(a0) ; event = keyUp? bne.s JSEResume ; no => do normal stuff. ; Also clears other high three bytes of D1 CheckMods MOVEQ #$0B,D1 ; seek cmdKey, shiftKey, not alphaLock, and optionKey AND.B evtMeta(A0),D1 ; high byte of meta word contains modifier bits SUBQ.B #$03,D1 ; want cmdKey AND shiftKey BUT NOT optionKey BNE.S JSEResume ; if not so, no FKey action! ; move.b evtMessage+2(a0),D1 ; Get raw keycode, use A0 not A3 cmp.b #$3F, D1 ; Keyboard or keypad? bhi.s JSEResume ; No keypad FKEYs move.b evtMessage+3(a0),d1 ; load ascii code. sub.b #$30,d1 ; ascii code < $30? blo.s JSEResume ; yes => do normal stuff. cmp.b #$09,d1 ; ascii code > $39? bhi.s JSEResume ; yes => do normal stuff. tst.b ScrDmpEnb ; Are FKEYs enabled? beq.s JSEResume ; no => do normal stuff. ; Do the FKEY. SUBQ #4,SP ; load in appropriate function-key package MOVE.L #'FKEY',-(SP) MOVE.W D1,-(SP) ; types 0-9 _GetResource MOVE.L (SP)+,D0 BNE.S @0 ; br if we got the resource TST.W D1 ; zero? BEQ.S DoneFKey ; exit if so CMP.W #2,D1 ; other than 1 or 2? BGT.S DoneFKey MOVEQ #1,D2 ; 1 means from function key JSR ROMDoEject ; 1 and 2 are eject keys BRA.S DoneFKEY ; then exit... @0 MOVE.L D0,A0 MOVE.L (A0),D0 ; dereference BEQ.S DoneFKey ; exit if purged _HLock ; lock the FKEY code, MOVE.L A0,-(SP) ; save for unlock MOVE.L (A0),A0 ; dereference JSR (A0) MOVE.L (SP)+,A0 ; recover handle _HUnlock ; unlock it ; The system handled the event so return true. DoneFKey MOVE.L (SP)+, (SP) MOVE.W #-1, 4(SP) ; return true. RTS JSEResume jmp ROMSysEvt ; do normal SystemEvent. MeasureText PROC EXPORT IMPORT TextWidth ;-------------------------------------------------------------------- ; PM127 23Mar87 CRC MeasureText fix for new TextEdit and Macintosh Pascal ; ; PROCEDURE MeasureText(count: INTEGER; textAddr,charLocs: Ptr); ; ; Call textMeasProc via TextWidth for the benefit of Think’s Macintosh Pascal. ; (TextEdit used to use TextWidth but changed to MeasureText for efficiency; ; Think added styles to TextEdit inside the bottleneck procs that no longer ; got called. This calls the bottleneck proc only if it is different from ; StdTxMeas, since the speed hit is appreciable.) PARAMSIZE EQU 10 COUNTX EQU PARAMSIZE+8-2 ;WORD TEXTADDR EQU COUNTX-4 ;LONG, Ptr to ASCII CHARLOCS EQU TEXTADDR-4 ;LONG, Ptr to output array INREC EQU -16 ;FMInput record VARSIZE EQU INREC ROMNoScale EQU $408E76 ROMUseSwapFont EQU $408DFE LINK A6,#VARSIZE ;ALLOCATE LOCALS MOVEM.L D3/D4/A2,-(SP) ;SAVE ORIGINAL REGS. MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT ; if there is a txMeasProc not equal to StdTxMeas, call CharWidth instead MOVE.L grafProcs(A0),D0 ;are there overridden graf procs? BEQ.S useSwapFont MOVE.L D0,A1 MOVE.L txMeasProc(A1),D0 CMP.L JStdTxMeas,D0 BEQ.S useSwapFont MOVEM.L D5/D6/A3,-(SP) ;SAVE ADDITIONAL REGS. MOVE.L TextAddr(A6),A2 MOVE.L CharLocs(A6),A3 MOVE CountX(A6),D3 MOVEQ #0,D4 ;INIT WIDTH TO 0.0 MOVEQ #0,D6 ;furthest character right so far MOVEQ #0,D5 ;sum to add in to fix text width SUBQ #2,SP ;make room for the returned width nextChar MOVE.L A2,-(SP) CLR -(SP) MOVE D4,-(SP) _TextWidth MOVE (SP),D0 ;get the width CMP D6,D0 ;is it smaller than the last measurement? BGE.S @notSmaller ;if this is equal to or larger than last, no prob. ADD D6,D5 ;if smaller, add last measurement to sum @notSmaller ADD D5,D0 ;add sum to character position MOVE D0,(A3)+ MOVE (SP),D6 ;make this measure into last measure (for next time) ADDQ #1,D4 CMP D3,D4 BLE.S nextChar ;LOOP FOR COUNT+1 CHARLOCS ADDQ #2,SP ;toss character width MOVEM.L (SP)+,D5/D6/A3 ;restore regs JMP ROMNoScale ;restore regs, pop params, go home useSwapFont JMP ROMUseSwapFont ;use FMSwapFont instead ;_______________________________________________________________________________________ ; (Patch #0) ; ; Patch for InstallRDrivers. ; ; Patched using InstallRDrivers trap. ; ; NOTES: ; (1) This is an OS trap, so we can use regs D0-D1/A0-A1 (saved by dispatcher) ; (2) The intent here is to allow application-heap-based drivers/desk ; accessories to keep some permanent storage in the system heap. ; The bug was introduced in an attempt to allow this, but resulted in ; DCtlStorage NEVER getting cleared for app-heap-based drivers. ; There is still an assumption that ROM-based drivers never have storage ; in the application heap (they are always skipped by InstallRDrivers); ; note that all heaps above ApplZone are assumed to be application zones. ;_______________________________________________________________________________________ InstallRDrivers PROC EXPORT ROMInstallRDrivers EQU $40F72C ; for ROM version $0075 jInstallRDrivers EQU $53C JSR ROMInstallRDrivers ; first do the ROM call MOVE.L UTableBase,A1 ; get pointer to unit table MOVE.W UnitNtryCnt,D1 ; get # of entries in unit table @1 MOVE.L (A1)+,D0 ; get the DCE handle BEQ.S @2 ; if NIL, skip MOVE.L D0,A0 ; get handle in A-reg MOVE.L (A0),D0 ; dereference BEQ.S @2 ; br if DCE purged (shouldn't be) MOVE.L D0,A0 ; get DCE ptr MOVE.L DCtlStorage(A0),D0 ; get its storage handle AND.L Lo3Bytes,D0 ; clear the high byte <20Nov85> CMP.L ApplZone,D0 ; is it in the system zone? BLT.S @2 ; if so, it's cool CLR.L DCtlStorage(A0) ; zero DCtlStorage @2 SUBQ #1,D1 ; more to do? BNE.S @1 ; loop until done MOVEQ #0,D0 ; return the zero result the RTS ; ROM routine should have. ;_______________________________________________________________________________________ ; (Patch #32, #11) ; ; Patch for GetFCBInfo and GetWDInfo. ; ; Patched using Trap $60 - TFSDispatch. ; ; This patch fixes a problem in GetFCBInfo: when a refNum is supplied by the user, the code ; in FndFCB fails to set up A2 to point to the VCB, which GetFCBInfo relies on. The patch ; essentially duplicates the path through GetFCBInfo into FndFCB for those cases where a refNum ; is supplied and sets up A2 properly, after which it re-joins the GetFCBInfo code. ; ; (A1,D1) are always set up by FndFCB to point to the FCB, A2 to point to the VCB. The routine ; CkFileRfn sets D0 and clobbers D2 (which is also clobbered by FndFCB and isn't used in GetFCBInfo). ; ; This patch also fixes a problem in GetWDInfo: the routine GetWDCBInfo doesn't clear the top ; half of D1 before calling ChkWDRefNum, which expects it to be zero (it does a DIVU). The ; patch clears the top half of D1 coming into the trap to avoid this problem; D1 really only ; contains a word coming in (the trap word). ;_______________________________________________________________________________________ TFSDPatch PROC EXPORT FSQueue EQU $4028AA CmdDone EQU $40295E CkFileRfn EQU $40537A retFCBInfo EQU $4053BE GetFCBInfo EQU $4053B2 TFSDispatch EQU $402852 Cmp.W #7,D0 ; GetWDInfo call? Bne.s @9 ; Nope - check for GetFCBInfo Swap D1 ; Get access to high word Clr.W D1 ; Clear it (which GetWDCBInfo should have done) Swap D1 ; And return the trap word to the low half Bra.s @99 ; Now all's safe again @9 Cmp.W #8,D0 ; GetFCBInfo call? Bne.S @99 ; If not, we're all set. Tst.W ioFCBIndx(A0) ; Is it an indexed request? Bne.S @99 ; If so, we're OK after all. Jsr FSQueue ; Wait our turn Moveq #0,D1 ; Clear top half of D1 Move.W ioRefNum(A0),D1 ; Pick up the refNum requested Move.L FCBsPtr,A1 ; Set up A1 for CkFileRfn and @10 code <06Dec85> Jsr CkFileRfn ; Check it for validity Beq.S @10 ; continue if all went well Jmp CmdDone ; Otherwise, punt here & now. @10 Move.L FCBVPtr(A1,D1),A2 ; The REAL fix: set up VCB pointer Jmp retFCBInfo ; re-join the ROM code. @99 Jmp TFSDispatch ; Continue life as we used to know it. ;_______________________________________________________________________________________ ; (Patch #4) ; ; Patch for Create ; ; Patched using FndFilNam vector. ; ; This patch to FndFilNam fixes a bug in Create (both FileCreate and DirCreate) on HFS ; volumes - when the volume is write protected, Create doesn't return an error, causing ; the volume to be unrecognized in disk switches because information on dirty locked ; volumes is never flushed. ; ; This patch basically modifies the patch through FndFilNam from Create to include a call ; to CVFlgs, which will signal an error when the volume is locked. Note that Create expects ; a FNFErr to be returned from FndFilNam: successful completion of FndFilNam is an error in ; Create. If CVFlgs fails, the return patch is forced to CmdDone, which terminates the call ; with the error code in D0. ; ; CVFlgs doesn't modify any registers other than D0. ;_______________________________________________________________________________________ FndFlPatch PROC EXPORT CmdDone EQU $40295E CreateCall EQU $4041F0 FndFilNam EQU $404996 CVFlgs EQU $403A76 MOVE.L (SP)+,-(A6) ;save return address JSR FndFilNam ;do usual thing. BEQ.S @90 ;punt if no error encountered CMP.L #CreateCall,(A6) ;coming from create? BNE.S @90 ;nope - all is fine as is. CMP.W #FNFErr,D0 ;file not found? BNE.S @90 ;nope - some other way out. JSR CVFlgs ;yes - do extra check BNE.S @80 ;punt on errors MOVEQ #FNFErr,D0 ;restore status, OK to let Create continue BRA.S @90 @80 MOVE.L #CmdDone,(A6) ;if NE, change return path. @90 MOVE.L (A6)+,-(SP) ;restore return address TST.W D0 RTS ;_______________________________________________________________________________________ ; (Patch #1) ; ; Patch for SetEOF. ; ; Patched using ExtendFile vector. ; ; This patch fixes a problem with SetEOF on HFS volumes: when there isn't enough free ; space remaining on the volume, SetEOF as is would still allocate as much space as ; possible before failing with a DskFulErr (a la FileAlloc). ; ; This patch changes ExtendFile to check the remaining space on the volume for calls ; other than FileAlloc, and to return DskFulErr without allocating any space if there ; isn't enough space left on the volume to satisfy the complete request. ; ; The patch code uses D0, which is a strict output parameter from ExtendFile. ; ExtendFile is expected to set up D6 with the number of bytes actually allocated, so ; this is cleared when an error return is forced. ;_______________________________________________________________________________________ ExtFPtch PROC EXPORT FAllocCall EQU $4054A8 ExtBTCall EQU $406EF0 ; <04Dec85> ExtendFile EQU $405B82 CMP.L #FAllocCall,4(A6) ; Return address in FileAlloc? <19Nov85> BEQ.S @90 ; Yes - let it pass unmolested CMP.L #ExtBTCall,(SP) ; Return address in ExtBTFile? <04Dec85> BEQ.S @90 ; Yes - let it pass unmolested <04Dec85> MOVE.W VCBFreeBks(A2),D0 ; No - check if sufficient space free first MULU VCBAlBlkSiz+2(A2),D0 ; Compute free space in bytes CMP.L D4,D0 ; Compare against requested space BCC.S @90 ; If enough space free (somewhere), go on MOVEQ #0,D6 ; otherwise, no bytes allocated. <04Dec85> MOVEQ #DskFulErr,D0 ; result = 'disk full' <04Dec85> RTS ; Force return from ExtendFile @90 JMP ExtendFile ; Continue life as we used to know it. ;_______________________________________________________________________________________ ; (Patch #1a) ; ; Patch for BTDelete (update depth bug). ; ; Patched using FreeNode vector. ; ; Notes: ; ; 1) The depth of a BTree is reduced by one level whenever the root index ; node results with only one record following a delete operation. In ; this case, the child node pointed to by the root index node becomes ; the new root node. However, this new root node could also be an ; index node containing only one record, requiring yet another reduction ; in the BTree depth. BTDelete does not check the new root node for this ; condition. This patch fixes the problem by getting the new root node ; and jumping back to the BTDelete code that checks for a depth reduction. ; ; 2) Register A0 is used as a scratch register by BTDelete and FreeNode. ;_______________________________________________________________________________________ BTDelP1 PROC EXPORT EXPORT BTDelP2 GetNode EQU $407408 FreeNode EQU $406FBA BDUpdDepth EQU $406868 BDExit EQU $4068A2 BDExit1 EQU $4068A8 CMP.L #BDExit,(SP) ; comming from right place in BTDelete? BNE.S @1 ; no -> LEA @2,A0 ; yes, force FreeNode to return MOVE.L A0,(SP) ; to patch code @1 JMP FreeNode ; continue with FreeNode @2 MOVE.L BTCRoot(A4),D3 ; D3 = new root node # MOVE.L D3,D2 ; get the new root node MOVEQ #0,D1 ; JSR GetNode ; BEQ.S @3 ; got it -> JMP BDExit1 ; error -> @3 MOVEA.L A0,A3 ; A3 = ptr to node buffer JMP BDUpdDepth ; check # of records in new root -> ;_______________________________________________________________________________________ ; (Patch #1b) ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 01jan1904 #1b (GetNode) (BTDelete) ; ; Patch for BTDelete (GetNode bug - trashes the cache). ; ; Patched using GetNode vector. ; ; Notes: ; ; 1) BTDelete does not check for an error return following a call to ; GetNode when getting a parent node. If an error occurs, A0 is ; returned containing a pointer to a Cache Buffer Header (CBH) ; instead of the normal pointer to the cache buffer. This pointer ; is then used by BTDelete as a node buffer pointer thus, trashing ; the CBH. This patch forces BTDelete to take an error exit if an ; error is returned by GetNode. ;_______________________________________________________________________________________ BTDelP2 BDGetParent EQU $40680A CMP.L #BDGetParent,(SP) ; comming from right place in BTDelete? BNE.S @1 ; no -> LEA @2,A0 ; yes, force GetNode to return MOVE.L A0,(SP) ; to patch code @1 JMP GetNode ; continue with GetNode @2 BEQ.S @3 ; no error from GetNode -> JMP BDExit1 ; take BTDelete error exit @3 JMP BDGetParent ; continue with the delete ;_______________________________________________________________________________________ ; (Patch #2) ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 22Nov85 #2 (IODone) (IODone) ; ; Patch for IODone (preserves D0 accross IODone) ; ; Patched using IODone vector. ;_______________________________________________________________________________________ IODone PROC EXPORT ROMIODone EQU $402082 ; <22Nov85> MOVE.W D0,-(SP) ; preserve D0 across IODone <22Nov85> JSR ROMIODone ; <22Nov85> MOVE.W (SP)+,D0 ; <22Nov85> RTS ; <22Nov85> ;_______________________________________________________________________________________ ; (Patch #11, #12, #31) ; ; <06dec85> BBM ; This patch fixes a bug in UpdateResFile, in the subroutine CmpFrmDsk. There were ; three extra lines that didn't need to be there. These lines blitzed D5. The fix is ; to copy the code from the latest jump table entry and remove these lines. ; ; <31jan86> BBM ; For large files that over flow the update buffer, and that have a lot of gaps, the ; pointer D5 was not being updated correctly. ; ; <12May86> BBM ; If the compaction gap in updateresfile was one to three bytes long and if the the ; resource to be moved forward in the file was not in memory, the size would write over ; itself. This was the bug that resulted in the random system file that was 7 meg. ;_______________________________________________________________________________________ UpdtJmpEntry PROC EXPORT ; ROM routines RCmpDskExit EQU $413B20 RCmpFrmMem EQU $413A3C ROddSize EQU $41357A RPartRead EQU $413B58 RPartWrite EQU $413B8E ; yes that's $413B8E, not $413BAE <06dec85> BBM RPtr1Exit EQU $413A80 RRLocnNew EQU $413A96 RUpdtReturn EQU $4139F2 RWriteZero EQU $413AB2 RZnextRes EQU $413880 ; Offsets into a resource entry: RID EQU 0 ; ID of the resource RNameOff EQU RID+2 ; Name offset of the resource RAttr EQU RNameOff+2 ; Attribute byte (high byte of locn) RLocn EQU RAttr ; Location of the resource in source file RHndl EQU RLocn+4 ; Handle of the resource RefID EQU RHndl ; If reference, ID of ref'd resource RefNameOff EQU RefID+2 ; If reference, NameOff of ref'd resource RESize EQU RHndl+4 ; Resource entry size @3 BTST #ResChanged,RAttr(A2) ; is the rsrc in mem (and needs to be written) BEQ.S @4 ; CC=EQ means ResChanged bit not set JSR RCmpFrmMem ; else get rsrc from memory and compact <06dec85> BBM BPL.S @5 ; go get next resource @4 BSR.S CmpFrmDsk ; read rsrc from disk and compact @5 JSR RZnextRes ; go get the next resource <06dec85> BBM BEQ.S @3 ; if more resources loop back JMP RUpdtReturn ; and continue in the ROM <06dec85> BBM CmpFrmDsk MOVE.L RLocn(A2),D0 ; point to next resource in file AND.L Lo3Bytes,D0 ; make sure high byte cleared for compare SUB.L D5,D0 ; check to see if this RLocn is resonable BGE.S @4 ; CC=GE offset seems good (past stuff written) JSR RPartWrite ; make sure we have some room to work in <06dec85> BBM JSR RRLocnNew ; update rsrc location in map <06dec85> BBM JMP RWriteZero ; write out zero for size of rsrc & return <06dec85> BBM @4 ADD.L A1,D0 ; add offset to end of compact region ADDQ.L #4,D0 ; add in the size of the rsrc size CMP.L D0,D4 ; is all of the size in memory??? BGE.S @1 ; if it is all in memory go read in size JSR RPartWrite ; else get some room to work with <06dec85> BBM MOVE.L RLocn(A2),D0 ; get current position of this resource AND.L Lo3Bytes,D0 ; get rid of the resource attributes MOVE.L D0,D5 ; set up read pointer for next read JSR RPartRead ; and read in the size <06dec85> BBM @1 MOVE.L RLocn(A2),D0 ; point A0 to Size of resouce JSR RRLocnNew ; update new position in the map <06dec85> BBM SUB.L D5,D0 ; ... D0 now has delta from D5 to size AND.L Lo3Bytes,D0 ; ... make sure no garbage in high byte MOVE.L A1,A0 ; ... get pointer into buffer ADD.L D0,A0 ; ... A0 now points to the size in memory ; MOVEQ #4,D0 ; get the length of the size into D0 <12may86> BBM ; BSR.S @9 ; update all pointers etc. <12may86> BBM JSR ROddSize ; D0 gets Size of Rsrc; A0 points to Rsrc <06dec85> BBM ADDQ.L #4,D0 ; add in the length of a resource, and … <12may86> BBM SUBQ.L #4,A0 ; … point A0 back to start of size of rsrc <12may86> BBM MOVE.L D0,D2 ; save size for later ADD.L A0,D2 ; Check to see if all of rsrc is in buffer CMP.L D2,D4 ; is all of rsrc in buffer? BGE.S @9 ; if all in buffer exit by compacting <06dec85> BBM ADD.L A0,D5 ; bump D5 pointer by A0-A1 to … <31jan86> BBM SUB.L A1,D5 ; … keep D5 correct for large files <31jan86> BBM AND.L Lo3Bytes,D5 ; … and make sure no garbage in high byte <31jan86> BBM JMP RCmpDskExit ; Skip three lines and return. <06dec85> BBM @9 JMP RPtr1Exit ; Either JMP or JSR to RPtr1Exit <06dec85> BBM ;_______________________________________________________________________________________ ; (Patch #29a) ;_______________________________________________________________________________________ Patch29A PROC EXPORT EXPORT MyDisHandle ;_______________________________________________________________________________________ ; patched _DisposHandle - moved UpdateResFile come-from stuff to ResourceMgrPatches.a <48> ;_______________________________________________________________________________________ RomDsHand EQU $410170 MyDisHandle move.l #RomDsHand,A1 ; load the vector to go to the real DisposH <15apr86> BBM bra.s FinDisPatch ; Go finish the DisposHandle patch <15apr86> BBM ;------------------------------------------------------------------------------- ; (Patch #41) ; (Patch #44) <02May86> ; ; Patch to DisposHandle, ReallocHandle, and HandleZone ; <15apr86> BBM ; #44 adds RecoverHandle as well. <02May86> ; ; When DisposHandle or ReallocHandle is called with a purged handle, the ; Memory Manager puts the master pointer in the free list of theZone (the ; current zone). If theZone is not set up correctly, then the free list could ; contain master pointers from the wrong zone. We can’t read the minds of ; developers, so if theZone is set to some value other than SysZone or ; ApplZone, then we must blindly put the master pointer back in that zone. ; However, if theZone is set to SysZone or ApplZone we can at least put the ; master pointer back in the free list that is the most reasonable. ; ; Note that if this is called with a nil handle, it may temporarily set up ; theZone to some zone — but the call to RomDisposHandle handles it correctly ; by doing nothing at all. ; ; WARNING! THIS PATCH SHOULD IMMEDIATELY FOLLOW PATCH NUMBER 29a. ;------------------------------------------------------------------------------- EXPORT MyRecovHand,MyHandZone,MyReaHand RomReaHand EQU $4101EC RomHandZon EQU $4101AE ROMRecovHand EQU $4101B6 ; <02May86> MyRecovHand move.l #ROMRecovHand,A1 ; real ReoverHandle <02May86> bra.s FinDisPatch ; <02May86> MyHandZone move.l #RomHandZon,A1 ; load the vector to go to the real HandleZone <15apr86> BBM bra.s FinDisPatch ; and jump to the common code <15apr86> BBM MyReaHand move.l #RomReaHand,A1 ; load the vector to go to the real ReallocH <15apr86> BBM FinDisPatch move.l theZone,D2 ; put theZone in D2 for convenience move.l D2,-(sp) ; save the zone across this call cmp.l ApplZone,D2 ; Is current zone the ApplZone? beq.s @0 ; If so, go check master pointer cmp.l SysZone,D2 ; Is the current Zone the SysZone? bne.s @9 ; If theZone is neither ApplZone or ; … the SysZone, then use theZone move.l ApplZone,theZone ; assume default is ApplZone @0 move.l A0,D2 ; make sure there are no garbage … and.l Lo3Bytes,D2 ; … bits in the high byte for cmp. <17Apr86> cmp.l ApplZone,D2 ; test which zone to put mp in bhi.s @9 ; cc=hi means mp in ApplZone move.l SysZone,theZone ; put back in SysZone, fall into DH @9 jsr (a1) ; go do the actual disposhandle move.l (sp)+,theZone ; restore the zone tst.w d0 ; set CCR in case returning directly to user, as <07may86> ; Switcher 4.4 rts ; return to the dispatcher ;_______________________________________________________________________________________ ; (Patches #13, #61, #62) ; ; (#62) This patch is to fix a bug in lap.a within the MPP driver. ; January 5, 1987 ; Alan Oppenheimer ; ; If we're doing a VInstall to install MPP's VBL task, change the address to ; one in RAM, where we disable interrupts and then call the real VBL task. ; This makes the test-and-decrement atomic, preventing VBLDeferCnt from ever ; going negative. ; ; (#61) Patch to create dummy ATP DCE to fix GetDataArea bug ; December 9th, 1986 ; Alan Oppenheimer ; ; (#13) New Sound Driver Patches ; December 9th, 1985 ; Mark Lentczner ; ; Two things were patched: 1) The test at the begining of the byte ; map VBL task should correctly deal with an empty queue by calling ; DoneVBL. 2) The test at the end of the byte map VBL should NOT ; call DoneVBL, but only GoToIODone instead. ; ; ; The current sound driver uses low memory as a vbl queue element. A bug occurs ; if sound is active. The low memory queue element is zeroed regardless if there is a ; next element in the queue or not. Thus the machine may hang. The fix forces the ; sound vbl queue element to be last in the queue always. ; sound manager uses sound manager uses soundactive different than sound driver. ; Thus soundactive could be true with no sound vbl task installed. So now we check for an ; error from vremove, which we should have done in the first place. (This is the same patch ; as S278, which got deleted when PMAB284 was checked in.) ; if a delayed duplicate response came in to ATP it could overwrite a valid response ; before it was thrown out due to a bad TID. Patch SendRequest to install a new socket ; listener which checks the TID first. ; bug in above patch if packet type is not ATP. Don't check packet type. ; There was a small window after the vremove where a timer interrupt could happen. ; Since the sound driver services the timer in the vbl task, the code to reinstall the ; vbl task would never happen. ; changed hardwired constant to HiIntMask in hardwareEqu (see s481). ;_______________________________________________________________________________________ NewVInstall PROC EXPORT EXPORT NewVRemove ROMVInstall EQU $401C2A DoneVBL EQU $417B50 ROMBMap EQU $417C82 ;SoundVBLAddress .EQU $270 CallFrom EQU $1C ; Offset on stack of caller FromATP EQU $419E04 ; After _VInstall in ATP dATP EQU $28 ; Offset to ATP DCE in unit table ATPOpen EQU $419DB8 ; ATP open code ATPClose EQU $419E8E ; ATP close code ATPDoControl EQU $419E06 ; ATP control code GetDataArea EQU $41A6B8 IntoCheckTime EQU $41A27A IntoDispatch EQU $419E3C IntoSendReq EQU $41A140 ATPExit EQU $419F66 IntoSendRsp EQU $419FD8 NoBuffs EQU $41A018 PastSL EQU $41A146 ROMATPIgnore EQU $41A3A8 ROMReadResp EQU $41A448 VBL60 EQU 60 ; Call us every second (60 ticks) VBLQEl EQU $CC ; VBL queue element offset TCBE EQU 6 ; Number of entries in TCB table TSktNum EQU 0 ; Socket no. request was on (offset) TQElPtr EQU TSktNum+TCBE ; Offset to qEl ptr VBLHnd EQU $41AB1E ; MPP VBL task address in ROM tst.b SoundActive ; sound playing? fixes trashed vbl queue beq.s @TruVinst ; if not, just do real vinstall move.w sr,-(sp) ; Save sr ori.w #HiIntMask,sr ; Disable interrupts move.l a0,-(sp) ; save new vbl element on stack lea SoundVBL,a0 ; point at hertzfeld’s vbl element _VRemove ; remove sound vbl element move.l (sp)+,a0 ; get new vbl element back in a0 tst.w d0 ; check for error from vremove bne.s @popstatus ; if error then don’t reinstall sound vbl bsr.s @TruVinst ; install new vbl element back in queue lea SoundVBL,a0 ; get sound vbl element, and install it bsr.s @TruVinst ; install sound vbl element back in queue move.w (sp)+,sr ; Restore interrupts rts ; @popstatus ; move.w (sp)+,sr ; Restore interrupts @TruVinst ; end of CMP.L #FromATP,CallFrom(SP) ; Called from ATP? BNE.S @20 ; Try the MPP patch if not ; ; Change address of VBL routine to our patch ; @10 LEA CTPatch,A2 ; A2 -> VBL patch MOVE.L A2,VBLAddr(A0) ; Set in queue element ; ; Create dummy DCE in RAM ; MOVE.L UTableBase,A2 ; A2 -> unit table MOVE.L dATP(A2),A2 ; A2 = handle to ATP DCE MOVE.L (A2),A2 ; A2 -> DCE LEA FakeATP,A1 ; A1 -> fake DCE MOVE.L A1,DCtlDriver(A2) ; Set in DCE (pointer since ROM driver) ; ; Check if from MPP VBL task ; @20 CMP.L #VBLHnd,VBLAddr(A0) ; Called to set MPP VBL task? BNE.S @30 ; Branch if not PEA NewVBLHnd ; Push address of patch MOVE.L (SP)+,VBLAddr(A0) ; Set it @30 BRA SoundPatch ; That's it - go do VInstall ; ; New MPP VBL task to effect patch ; NewVBLHnd MOVE SR,-(SP) ; Save interrupt status MOVE #SCCLockout,SR ; Interrupts off (SCCLockout) JSR VBLHnd ; Call VBL task MOVE (SP)+,SR ; Restore interrupts RTS ; That's it FirstATPPlus EQU 249 ; First ATP csCode for the ATP in the Mac Plus Rom ; ; The following is a fake header for ATP. Most calls just jump into the ROM. ; FakeATP DC.W $4400 ; Control, Locked DC.W 0,0 ; No time, no events DC.W 0 ; No menu ; ; Entry points offset table ; DC.W Open-FakeATP DC.W Nothing-FakeATP DC.W PControl-FakeATP DC.W Nothing-FakeATP DC.W Close-FakeATP DC.B 4 ; driver name DC.B '.ATP ' Open JMP ATPOpen Close JMP ATPClose ; ; This is the real patch. We patch out the start of CheckTime (the VBL task) ; to call GetDataArea with interrupts off. We also patch out the Control ; entry point so we can fix some of the routines. ; CTPatch MOVE #VBL60,VBLCount(A0) ; Reset count for next time LEA -VBLQEl(A0),A2 ; A2 -> our variables BSR.S DoGetDA ; *** GetDataArea, ints off *** JMP IntoCheckTime ; Jump into the ROM PControl TST.L AbusVars ; Make sure MPP opened ok BEQ.S GoControl ; Branch if not MOVE.W CSCode(A0),D2 ; D2 = control code LEA RspPatch,A3 ; A3 -> SendResponse patch CMP #SendResponse,D2 ; SendResponse? BEQ.S GoDispatch ; If so, dispatch to it LEA ReqPatch,A3 ; A3 -> SendResponse patch CMP #SendRequest,D2 ; SendRequest? BEQ.S GoDispatch ; If so, dispatch to it GoControl JMP ATPDoControl ; If not, do all control code ; ; Jump into the ROM dispatch code, which will jump to what A3 points to with ; stuff set up right ; GoDispatch SUB #FirstATPPlus,D2 ; Dispatch needs this ADD D2,D2 ; And this (now offset into table) JMP IntoDispatch ; Jump into ROM (will come back) ; ; *** Call GetDataArea in ROM with interrupts off *** ; DoGetDA MOVE SR,-(SP) ; Save SR MOVE #SCCLockout,SR ; Disable interrupts JSR GetDataArea ; Call it MOVE (SP)+,SR ; Restore interrupts TST D0 ; Set CCR to D0 Nothing RTS ; That's it ; ; *** Patch(es) to SendRequest. Include PMAB301 patch *** ; ReqPatch MOVE #TooManyReqs,D0 ; Assume too many concurrent requests MOVEQ #TCBE-1,D2 ; D2 = offset into TCB table @10 TST.B TSktNum(A2,D2) ; Is this entry free? DBEQ D2,@10 ; Keep going until got one BNE.S ToATPExit ; Return error if none MOVEQ #DDPLenErr,D0 ; Assume a length error CMP #ATPMaxData,ReqLength(A0) ; Check length BHI.S ToATPExit ; Return error if too high CLR.B D1 ; Indicate we want a dynamic socket BSR.S DoGetDA ; *** GetDataArea with ints off *** BNE.S @20 ; Just continue if error LEA newATPRead,A1 ; A1 -> new socket listener JMP PastSL ; Jump into ROM @20 JMP IntoSendReq ; Jump into ROM ToATPExit JMP ATPExit ; Jump into ROM ; ; *** Patch to SendResponse *** ; RspPatch MOVE.L BDSPointer(A0),A1 ; A1 -> BDS from request SWAP D1 ; Save socket number in high word MOVE #BadBuffNum,D0 ; Assume invalid number of buffers MOVE.B NumOfBuffs(A0),D1 ; D1 = number of buffers BEQ.S ToNoBuffs ; Branch if none CMP.B #ATPMaxNum,D1 ; Too high? BHI.S ToATPExit ; Return error if so BSR.S DoGetDA ; *** GetDataArea with ints off *** JMP IntoSendRsp ; Jump into ROM ToNoBuffs JMP NoBuffs ; Jump into ROM ; ; This is the PMAB301 real patch. We make sure the TID matches before reading in ; the response ; newATPRead MOVEQ #ATPHdSz,D3 ; D3 = size to read SUBQ #1,A3 ; Make A3 even JSR (A4) ; Read header into RHA BNE.S Nothing ; Just return if error MOVE.L ATPVars(A2),A5 ; A5 -> our local variables MOVE.L A3,-(SP) ; Save A3 SUBQ #ATPHdSz,A3 ; A3 -> start of ATP header MOVE.B DDPDstSkt-DDPType(A3),D0 ; D0 = dest. socket no. MOVE.B (A3)+,D2 ; D2 = control byte BPL.S @20 ; Ignore if not a response (2) ADD.B D2,D2 ; Shift it left one bit BMI.S @20 ; Ignore if not a response (3) ; ; Incoming response - find the TCB for it and read it in ; MOVEQ #TCBE-1,D2 ; D2 = number to search, less one @10 CMP.B TSktNum(A5,D2),D0 ; This it? DBEQ D2,@10 ; Try all we can BNE.S @20 ; Ignore it if no match LSL #2,D2 ; D2 = offset to queue element pointer MOVE.L TQElPtr(A5,D2),A5 ; A5 -> queue element MOVE.B (A3)+,D3 ; D3 (word) = response number (4) ; ; *** The actual fix *** ; MOVE (A3)+,D0 ; D0 = TID from packet CMP ReqTID(A5),D0 ; Is it the one we want? BNE.S @20 ; If not just ignore it JMP ROMReadResp ; Otherwise continue @20 JMP ROMATPIgnore ; Ignore the packet ; ; *** Start sound patch (#13) *** ; SoundPatch ; On each Vert. Task Install... BSR.S PatchSIn ; fix the byte-map VBL task JMP ROMVInstall ; and then get on with the installation BMapPatch ; The New byte-map VBL task MOVE.L SoundDCE,A1 ; check to see if DCE queue is empty MOVE.L DCtlQHead(A1),D0 BNE.S @1 ; if it isn't proceed as normal JSR DoneVBL ; otherwise, first call DoneVBL @1 JSR ROMBMap ; do normal byte-map VBL ; note: falls into patch code since the ; compleation routine may have re-primed ; the driver and pointed task back to ROM PatchSIn ; Fix up the sound VBL task if not already CMP.L #ROMBMap,SoundVBL+vblAddr BNE.S @1 ; go if patch doesn't need fixing PEA BMapPatch ; set to address of patch byte-map VBL MOVE.L (SP)+,SoundVBL+vblAddr @1 RTS ROMVRemove EQU $401C74 FmBMapStart EQU $417C84 FmBMapEnd EQU $417D0E NewBMapEnd EQU $417D10 NewDoneVBLEnd EQU $417B58 NewDeAllocEnd EQU $417A22 FromFlushAppVbls EQU $40F544 NewVRemove ; On each Vert. Task Remove... MOVEQ #-1,D0 ; assume error LEA 40(sp),A1 ; Setup A1 to point into stack (yuck) CMP.L #FmBMapStart,(A1) ; coming from BMap start? BEQ.S @NextCheck ; if so proceed as normal CMP.L #FmBMapEnd,-(A1) ; coming from BMap end? BNE.S @NextCheck ; if not process as normal MOVE.L #NewBMapEnd,(A1) ; bypass condition code setting MOVE.L #NewDoneVBLEnd,-(A1) ; bypass buffer reset MOVE.L #NewDeAllocEnd,-(A1) ; bypass inactive flagging MOVEQ #0,D0 ; BRA.S @LeaveTask ; and DON'T remove the task! @NextCheck LEA $1C(sp),A1 ; Get return address for check, CMP.L #FromFlushAppVbls,(A1) ; to see if we are coming from FlushAppVbls BNE.S @RomVRemove ; if not, go do rom version of VRemove MOVE.L ApplZone,-(sp) ; get two zone ptrs where we can compare them MOVE.L SysZone,-(sp) ; two zones poised for compare CMP.L (sp)+,(sp)+ ; if appl==sys get out with D0!=0 BEQ.S @LeaveTask ; don’t nuke sys zone stuff at start time @RomVRemove JMP ROMVRemove ; @LeaveTask RTS ; and DON'T remove the task! ;_______________________________________________________________________________________ ; FileClose patch #13a ; ; This fixes a bug in the File System with flushing files (either by FlushFile or by FlushVol). ; The manifestation of this bug was that after removing Fonts from a System file with Font/DA ; mover, the space was not freed up on disk. Specifically, after cutting back a file, if a flush ; was done before the close of that file (very common on System files, because you would never ; close the current one), the space was not actually freed up. At FClose, because it was a ; flush, the file would not be truncated; it would, however, be marked non-dirty. Later, when ; the close come along, since the FCB is not dirty, the truncation is not checked for. (SetEOF calls ; TruncateFile with FlushOnly=$FF, causing it to truncate only to the end of the current extent; ; there may be only one extent for the System file, and so no blocks are actually deallocated). ; ; The fix is to truncate even on flushes. ; ; NOTES: ; (1) FClose is not vectored; the interesting callers are FlushFile and FlushVol. ; ; (2) The closest vector is after the truncate code: a call to CMGetCN which calls the ; vectored setup routine CMSetUp. The truncate code is just added here (minus the ; garbage about user-set clump sizes which isn't really supported since SetFileInfo ; no longer supports setting it, and minus the call to TstMod which should be superfluous ; since the dirty bit in the FCB can't be set if the file is not modifiable - TstMod calls ; RfnCall which needs A0 set up to point to user parameter block with a refnum in it which ; FlushVol calls don't have, so it's hard to do anyway: calling TstMod is probably a bug when ; FClose is called by UnmountVol . . .). ; ; (3) The patch to the code would be to leave out these two lines: ; ;ResetAEOF TST.B FlushOnly ; Just flushing? ; BNE.S UpdFlCat ; If so, don't adjust the EOF ; ; AND force FlushOnly=$00 for the TruncateFile call. Perhaps it might be better to ; use a different parameter to TruncateFile: who else calls it? TruncateFile is only ; called by SetEOF and FClose. ; ; (4) There is another minor bug: the FCB is marked clean, then a call to TruncateFile ; is made which may mark the FCB dirty again. This is ok for Close since the FCB ; is cleared at the end, but to avoid a second, unnecessary update of the directory ; entry, the following line should be added after the call to TruncateFile: ; ; BCLR #FCBModBit,FCBMdRByt(A1,D1) ; mark the FCB clean ; ; (5) There is an apparent alternative patch: patch Close to call TruncateFile even if the FCB is not ; marked dirty. One problem: if someone is removing some FONTs from their current System ; File, space will only appear after a shutdown or switch-launch. It might help scavenge ; other truncate problems, though. The killer: the volume may be ejected by the time the ; File is closed. Doing the truncate at Flush time is better; it also protects against resets ; with files open: if these files haven't been truncated, there will be space lost which would ; need a separate scavenger program to recover. Resetting is a common way to shutdown. ; ; Patch: 56 bytes ;_______________________________________________________________________________________ ; GetFileInfo patch #39 ; ; (1) CMGetOff is called from exactly two places: both in GetCatInfo. ; (2) CMGetOff is the only place where VCBDirIDM is validated. ; (3) The first GetCatInfo call to CMGetOff is for an indexed GetFileInfo call ; in which only files are wanted. VCBDirIndex is used here to keep ; a separate index marker for files. If VCBDirIDM is validated ; in this path, it is cool. ; (4) The second GetCatInfo call to CMGetOff is for a real indexed GetCatInfo ; call. If VCBDirIDM is validated in this path, VCBDirIndex should ; be invalidated. ; (5) VCBDirIndex can not be invalidated by setting it to zero: this makes ; it look valid always. By setting it to $FFFF, it will appear that ; any other indexed call is looking for a file before it and will ; thus be invalidated. ; (6) The source patch might be setting VCBDirIndex to $FFFF for the real ; indexed GetCatInfo path. I don't think that clearing VCBDirIndex ; in the GetCatInfo code (done inefficiently anyways) done now (non- ; indexed path) is warranted. ;_______________________________________________________________________________________ ; MountVol patch #48 ; ; As part of the volume consistency check in MountVol, the volume name in the VCB is ; compared with the name of the root directory. If they are different, MountVol calls ; CMReNameCN to rename the root directory. Unfortunately, the pointer passed by ; MountVol specifying the old (previous) root directory name points to that name within ; a cache buffer. Depending on the sorting order of the names involved, the contents ; of that cache buffer is sometimes changed by the BTree Manager before CMRenameCN is ; done with it. This causes the CMRenameCN to fail which in turn causes MountVol to ; fail. ; ; A simple solution to the problem is to pass CMRenameCN the DirID of the root ; directory instead of its ParID and CName. This will cause more BTree activity in ; order to locate the directory record, but who cares since this rename operation is an ; exception. ; ; The patch is via the CMSetUp vector. The patch code simply puts the root DirID in ; D0 and clears A0 indicating no CName. ;_______________________________________________________________________________________ PtchCMSetUp PROC EXPORT FromFlCls1 EQU $4051FC ; ROM 0075 FClose (updFlCat) return address from CMGetCN call ROMTruncateFile EQU $405D98 ; ROM 0075 TruncateFile subroutine address FromGetCInfo EQU $404C48 ; ROM 0075 GetCatInfo subroutine address FromMtRename EQU $4031BE ; ROM 0075 MountVol return address from CNRenameCN call <09Sep86> CMP.L #FromGetCInfo,$10(A6) ; <14Apr86> from indexed GetCatInfo? BNE.S @0 ; <14Apr86> br if not MOVE.W #-1,VCBDirIndex(A2) ; <14Apr86> inval dir index for next GetFileInfo @0 CMP.L #FromFlCls1,$10(A6) ; from FClose? BNE.S @2 ; br if not NOT.B FlushOnly ; just flushing? (also, set FlushOnly to $00 for Truncate call) BNE.S @1 ; br if not (on Close we're ok) MOVE.L (SP)+,-(A6) ; clean up the stack MOVEM.L D0/D2/A0,-(A6) ; save regs we are using for CMGetCN MOVE.L FCBPLen(A1,D1),D3 ; New end of file JSR ROMTruncateFile ; Truncate to this position MOVEM.L (A6)+,D0/D2/A0 ; restore regs for CMGetCN MOVE.L (A6)+,-(SP) ; and continue with node lookup @1 NOT.B FlushOnly ; restore FlushOnly flag to its previous state BCLR #FCBModBit,FCBMdRByt(A1,D1) ; mark FCB clean in case TruncateFile dirtied it @2 CMP.L #FromMtRename,40(A6) ; from MountVol rename? <09Sep86> BNE.S @3 ; br if not <09Sep86> MOVEQ #FSRtDirID,D0 ; set D0 to root DirID <09Sep86> SUBA.L A0,A0 ; indicate no CName <09Sep86> @3 SUB #lenCMVars,A6 ; allocate memory for CM vars MOVEA.L A6,A4 ; A4 = pointer to CM vars RTS ;_______________________________________________________________________________________ ; (Patch #20) ; ; Patch for Window Manager ; ; Patches DragGrayRgn ($105) and DragTheRgn ($126) ; ; This is a repeat of an old patch that I somehow trashed in the new ROM sources. ; It is waiting for ticks to reach a certain value and test if greater or equal rather ; than just equal (in case a couple of ticks have elapsed behind our backs). ; ; added <13Dec85> ;_______________________________________________________________________________________ DragGrayRgn PROC EXPORT EXPORT DragTheRgn ROMDragGrayRgn EQU $411E5A ; DragGrayRgn ROM address ROMDragTheRgn EQU $411E66 ; DragTheRgn ROM address ROMDrag2 EQU $411F18 ; DragTheRgn after dragdelay bug CallDrg1 EQU $411F54 ; Window Mgr ROM routine CallDragHook EQU $411F50 ; Window Mgr ROM routine LEA DragPattern,A0 ; Copy WMgrGray into DragPattern MOVE.L #$AA55AA55,(A0) ; (same thing as ROM does) MOVE.L (A0)+,(A0) DragTheRgn LINK A6,#-24 ; Link 4 extra bytes to save ActionProc LEA ThePatch,A0 ; A0 -> our patch MOVE.L 8(A6),-24(A6) ; first save user's actionProc MOVE.L A0,8(A6) ; install our patch as actionProc JMP ROMDragTheRgn+4 ; Jump into ROM after LINK instruction ThePatch ADDQ #4,SP ; Pop return address (from in CallDrg1) MOVE.L #ROMDrag2,(SP) ; Return after bug (replace CallDrg1's) MOVE.L -24(A6),D0 ; the REAL user drag ook JSR CallDrg1 ; call it if it's valid (same as ROM) JSR CallDragHook ; Call global hook, too (same as ROM) MOVE.L Ticks,D0 ; now do the delay right (same) ADDQ.L #2,D0 ; bump it two ticks (same) DragDelay CMP.L Ticks,D0 ; has ticks caught up yet? (same) BHI.S DragDelay ; Loop till it has (this was the BUG!!) RTS ;_______________________________________________________________________ ;<2.9> Deferred Task Manager _DTInstall Trap, vDisptch ; EH Interrupt Handlers Lvl1Int, Lvl2Int, Lvl3Int ; ; This patch adds the deferred task manager code, which consists of the ; _DTInstall Trap and the vDisptch routine, to the MacPlus. ; ; To add the manager, we must also patch out the interrupt handlers, ; since they are what call the vDisptch routine, which executes the ; deferred tasks. ; ; The code is lifted whole-heartedly from Gary Davidian's inthnd and ; DTCore files. ; ;_______________________________________________________________________ DeferredTaskPatch proc export DTInstall ; Trap for installing deferred tasks export vDisptch ; Deferred task handler export level1Int ; level 1 primary interrupt handler export level2Int ; level 2 primary interrupt handler export level3Int ; level 3 primary interrupt handler ; Private equates for interrupt handlers IntRegs reg a0-a3/d0-d3 ; registers saved by all interrupt handlers IntRegsSize equ 8*4 ; size of IntRegs in bytes, must change if IntRegs changes ; Rename a few historical equates for clarity Via1DT equ Lvl1DT ; Dispatch table for VIA1 interrupts SccDT equ Lvl2DT ; Dispatch table for SCC interrupts ; ; Since the Plus has no low memory globals to deal with the deferred task manager, ; we create them here. ; export plsDTQueue plsDTQueue ; queue label plsDTQFlags dc.w 0 ; queue flags <3.2> plsDTskQHdr dc.l 0 ; pointer to the first entry in queue <3.2> plsDTskQTail dc.l 0 ; pointer to the last entry in the queue <3.2> ;_______________________________________________________________________ ; ; Auto-Vector Interrupts on Mac Plus/SE ; ; The auto-vectors are assigned as below (according to interrupt priority level): ; ; Level 1: VIA1 interrupts, dispatched through Via1Int using Via1DT. ; ; Level 2: SCC interrupts, dispatched through SccDecode using SccDT. ; For HcMac, the Apple Sound Chip Interrupt is OR'ed with this interrupt. If ; the dispatcher determines that the SCC was not responsible, then the sound driver ; interrupt handler is called. ; ; Level 3: Simultaneous VIA1 and SCC interrupts, will revert to a level 2 interrupt. ;_______________________________________________________________________ Level3Int rte ; just return, it will revert to level 2 Level2Int movem.l IntRegs,-(SP) ; preserve registers lea SccDecode,a3 ; use the SCC interrupt dispatcher bra.s ServiceInt ; call primary interrupt dispatcher Level1Int movem.l IntRegs,-(SP) ; preserve registers lea Via1Int,a3 ; use the VIA1 interrupt dispatcher *fall into* bra.s ServiceInt ; call primary interrupt dispatcher ;_______________________________________________________________________ ; ; Routine: ServiceInt - Primary Interrupt Dispatcher ; Inputs: A3 - address of secondary interrupt dispatcher ; Stack contains saved 'IntRegs' with an interrupt stack ; frame below them. ; This routine is branched to (or fallen into), and will restore ; the saved 'IntRegs' and return from the stacked interrupt. ; Outputs: none ; Destroys: A0, A1, A2, D0, D1, D2 ; ; ; Function: Provides a centralized handler for calling a secondary dispatcher. ; Creates a consistent environment for all secondary interrupt dispatchers, ; to allow them to easily decode the interrupt source and pass then on ; to other handlers. The interrupt environment is as follows. Registers ; A0-A3/D0-D3 are preserved. ; The secondary interrupt dispatcher will then be called, with a JSR, and ; may either return with an RTS when done, of JMP to another dispatcher to ; do more decoding of the interrupt, and then it can either RTS or JMP. ; ; When the interrupt processing has been completed, and control returns ; back to this routine, it will call any queued Deferred Tasks (if returning ; to level zero),restore the saved registers A0-A3/D0-D3, and return from the ; primary interrupt with an RTE instruction. ; ;_______________________________________________________________________ ServiceInt jsr (a3) ; call the secondary interrupt dispatcher move.l plsDTskQHdr,d0 ; no convenient lowmem EQUATE to use tst.l d0 ; see if any deferred tasks are queued beq.s @NoDTasks ; if none, don't need to run them ; IMPORTANT!! - following calculation depends on stack setup ; Must be changed if stack usage changed! moveq.l #$07,d0 ; mask for int level in saved SR ($0700) and.b IntRegsSize(sp),d0 ; test upper byte of saved SR bne.s @NoDTasks ; if not returning to level zero, don't run tasks jsr vDisptch ; dispatch the deferred tasks @NoDTasks movem.l (sp)+,IntRegs ; restore registers rte ; and return from the interrupt ;_______________________________________________________________________ ; ; Routines: Via1Int - Secondary Interrupt Dispatcher ; Inputs: none ; Outputs: A1 - base address of the interrupting VIA ; Destroys: A0, A1, D0 ; ; Function: Decodes and prioritizes VIA interrupts, locates a handler ; for the highest priority enable VIA interrupt source in the Via1DT ; or Via2DT as shown below. The handler is jumped to, and it will return ; to the primary interrupt handler when done. ; ; ; Via1DT -> (00) CA2 highest priority ; (04) CA1 | ; (08) shift reg | ; (0C) CB2 | ; (10) CB1 | ; (14) T2 Timer \|/ ; (18) T1 Timer V ; (1C) spurious: no interrupt pending lowest priority ; ;_______________________________________________________________________ Via1Int movea.l VIA,a1 ; get VIA1 base address moveq.l #$7F,d0 ; mask for interrupt pending bits (clr high bit) and.b vIFR(a1),d0 ; get VIA interrupt pending flags and.b vIER(a1),d0 ; only process enabled interrupts add.w d0,d0 ; setup index into table of words movea.w PrioritizeViaInts(d0.w),a0 ; get the dispatch table offset movea.l (a0),a0 ; get routine address from table jmp (a0) ; dispatch to routine PrioritizeViaInts dc.w Via1DT+(4*7) ; 0 0 0 0 0 0 0 no bits set dc.w Via1DT+(4*0) ; 0 0 0 0 0 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 0 0 0 0 0 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 0 0 0 0 0 1 1 bit 0 is highest priority dc.w Via1DT+(4*2) ; 0 0 0 0 1 0 0 bit 2 is highest priority dc.w Via1DT+(4*0) ; 0 0 0 0 1 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 0 0 0 0 1 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 0 0 0 0 1 1 1 bit 0 is highest priority dc.w Via1DT+(4*3) ; 0 0 0 1 0 0 0 bit 3 is highest priority dc.w Via1DT+(4*0) ; 0 0 0 1 0 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 0 0 0 1 0 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 0 0 0 1 0 1 1 bit 0 is highest priority dc.w Via1DT+(4*2) ; 0 0 0 1 1 0 0 bit 2 is highest priority dc.w Via1DT+(4*0) ; 0 0 0 1 1 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 0 0 0 1 1 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 0 0 0 1 1 1 1 bit 0 is highest priority dc.w Via1DT+(4*4) ; 0 0 1 0 0 0 0 bit 4 is highest priority dc.w Via1DT+(4*0) ; 0 0 1 0 0 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 0 0 1 0 0 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 0 0 1 0 0 1 1 bit 0 is highest priority dc.w Via1DT+(4*2) ; 0 0 1 0 1 0 0 bit 2 is highest priority dc.w Via1DT+(4*0) ; 0 0 1 0 1 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 0 0 1 0 1 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 0 0 1 0 1 1 1 bit 0 is highest priority dc.w Via1DT+(4*3) ; 0 0 1 1 0 0 0 bit 3 is highest priority dc.w Via1DT+(4*0) ; 0 0 1 1 0 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 0 0 1 1 0 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 0 0 1 1 0 1 1 bit 0 is highest priority dc.w Via1DT+(4*2) ; 0 0 1 1 1 0 0 bit 2 is highest priority dc.w Via1DT+(4*0) ; 0 0 1 1 1 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 0 0 1 1 1 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 0 0 1 1 1 1 1 bit 0 is highest priority dc.w Via1DT+(4*5) ; 0 1 0 0 0 0 0 bit 5 is highest priority dc.w Via1DT+(4*0) ; 0 1 0 0 0 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 0 1 0 0 0 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 0 1 0 0 0 1 1 bit 0 is highest priority dc.w Via1DT+(4*2) ; 0 1 0 0 1 0 0 bit 2 is highest priority dc.w Via1DT+(4*0) ; 0 1 0 0 1 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 0 1 0 0 1 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 0 1 0 0 1 1 1 bit 0 is highest priority dc.w Via1DT+(4*3) ; 0 1 0 1 0 0 0 bit 3 is highest priority dc.w Via1DT+(4*0) ; 0 1 0 1 0 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 0 1 0 1 0 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 0 1 0 1 0 1 1 bit 0 is highest priority dc.w Via1DT+(4*2) ; 0 1 0 1 1 0 0 bit 2 is highest priority dc.w Via1DT+(4*0) ; 0 1 0 1 1 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 0 1 0 1 1 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 0 1 0 1 1 1 1 bit 0 is highest priority dc.w Via1DT+(4*4) ; 0 1 1 0 0 0 0 bit 4 is highest priority dc.w Via1DT+(4*0) ; 0 1 1 0 0 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 0 1 1 0 0 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 0 1 1 0 0 1 1 bit 0 is highest priority dc.w Via1DT+(4*2) ; 0 1 1 0 1 0 0 bit 2 is highest priority dc.w Via1DT+(4*0) ; 0 1 1 0 1 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 0 1 1 0 1 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 0 1 1 0 1 1 1 bit 0 is highest priority dc.w Via1DT+(4*3) ; 0 1 1 1 0 0 0 bit 3 is highest priority dc.w Via1DT+(4*0) ; 0 1 1 1 0 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 0 1 1 1 0 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 0 1 1 1 0 1 1 bit 0 is highest priority dc.w Via1DT+(4*2) ; 0 1 1 1 1 0 0 bit 2 is highest priority dc.w Via1DT+(4*0) ; 0 1 1 1 1 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 0 1 1 1 1 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 0 1 1 1 1 1 1 bit 0 is highest priority dc.w Via1DT+(4*6) ; 1 0 0 0 0 0 0 bit 6 is highest priority dc.w Via1DT+(4*0) ; 1 0 0 0 0 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 1 0 0 0 0 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 1 0 0 0 0 1 1 bit 0 is highest priority dc.w Via1DT+(4*2) ; 1 0 0 0 1 0 0 bit 2 is highest priority dc.w Via1DT+(4*0) ; 1 0 0 0 1 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 1 0 0 0 1 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 1 0 0 0 1 1 1 bit 0 is highest priority dc.w Via1DT+(4*3) ; 1 0 0 1 0 0 0 bit 3 is highest priority dc.w Via1DT+(4*0) ; 1 0 0 1 0 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 1 0 0 1 0 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 1 0 0 1 0 1 1 bit 0 is highest priority dc.w Via1DT+(4*2) ; 1 0 0 1 1 0 0 bit 2 is highest priority dc.w Via1DT+(4*0) ; 1 0 0 1 1 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 1 0 0 1 1 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 1 0 0 1 1 1 1 bit 0 is highest priority dc.w Via1DT+(4*4) ; 1 0 1 0 0 0 0 bit 4 is highest priority dc.w Via1DT+(4*0) ; 1 0 1 0 0 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 1 0 1 0 0 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 1 0 1 0 0 1 1 bit 0 is highest priority dc.w Via1DT+(4*2) ; 1 0 1 0 1 0 0 bit 2 is highest priority dc.w Via1DT+(4*0) ; 1 0 1 0 1 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 1 0 1 0 1 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 1 0 1 0 1 1 1 bit 0 is highest priority dc.w Via1DT+(4*3) ; 1 0 1 1 0 0 0 bit 3 is highest priority dc.w Via1DT+(4*0) ; 1 0 1 1 0 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 1 0 1 1 0 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 1 0 1 1 0 1 1 bit 0 is highest priority dc.w Via1DT+(4*2) ; 1 0 1 1 1 0 0 bit 2 is highest priority dc.w Via1DT+(4*0) ; 1 0 1 1 1 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 1 0 1 1 1 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 1 0 1 1 1 1 1 bit 0 is highest priority dc.w Via1DT+(4*5) ; 1 1 0 0 0 0 0 bit 5 is highest priority dc.w Via1DT+(4*0) ; 1 1 0 0 0 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 1 1 0 0 0 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 1 1 0 0 0 1 1 bit 0 is highest priority dc.w Via1DT+(4*2) ; 1 1 0 0 1 0 0 bit 2 is highest priority dc.w Via1DT+(4*0) ; 1 1 0 0 1 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 1 1 0 0 1 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 1 1 0 0 1 1 1 bit 0 is highest priority dc.w Via1DT+(4*3) ; 1 1 0 1 0 0 0 bit 3 is highest priority dc.w Via1DT+(4*0) ; 1 1 0 1 0 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 1 1 0 1 0 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 1 1 0 1 0 1 1 bit 0 is highest priority dc.w Via1DT+(4*2) ; 1 1 0 1 1 0 0 bit 2 is highest priority dc.w Via1DT+(4*0) ; 1 1 0 1 1 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 1 1 0 1 1 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 1 1 0 1 1 1 1 bit 0 is highest priority dc.w Via1DT+(4*4) ; 1 1 1 0 0 0 0 bit 4 is highest priority dc.w Via1DT+(4*0) ; 1 1 1 0 0 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 1 1 1 0 0 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 1 1 1 0 0 1 1 bit 0 is highest priority dc.w Via1DT+(4*2) ; 1 1 1 0 1 0 0 bit 2 is highest priority dc.w Via1DT+(4*0) ; 1 1 1 0 1 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 1 1 1 0 1 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 1 1 1 0 1 1 1 bit 0 is highest priority dc.w Via1DT+(4*3) ; 1 1 1 1 0 0 0 bit 3 is highest priority dc.w Via1DT+(4*0) ; 1 1 1 1 0 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 1 1 1 1 0 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 1 1 1 1 0 1 1 bit 0 is highest priority dc.w Via1DT+(4*2) ; 1 1 1 1 1 0 0 bit 2 is highest priority dc.w Via1DT+(4*0) ; 1 1 1 1 1 0 1 bit 0 is highest priority dc.w Via1DT+(4*1) ; 1 1 1 1 1 1 0 bit 1 is highest priority dc.w Via1DT+(4*0) ; 1 1 1 1 1 1 1 bit 0 is highest priority ;_______________________________________________________________________ ; ; Routine: SccDecode 8530 SCC Interrupt Dispatcher ; ; All SCC interrupts: this interrupt dispatcher determines the actual ; interrupting source and dispatches through a table of secondary vectors ; maintained in the SYSCOM area. The table looks like this: ; ; SccDT -> (00) channel B: transmit buffer empty ; (04) channel B: external status (or mouse vertical interrupt) ; (08) channel B: receive character available ; (0C) channel B: special receive condition ; (10) channel A: transmit buffer empty ; (14) channel A: external status (or mouse horizontal interrupt) ; (18) channel A: receive character available ; (1C) channel A: special receive condition ; ; SccDT contains a long entry-point address for each of the eight primary ; interrupt routines corresponding to the eight primary interrupting sources. ; ; The two external status interrupts may be broken down into the following ; sources by the primary receiver: ; ; zero count (when the SCC baud rate generator is used as a timer) ; DCD (or mouse vertical/horizontal) ; sync/hunt (for synchronous serial modes only) ; CTS (external handshake in signal) ; Txunderrun/EOM (for synchronous serial modes only) ; Break/abort (interrupts when break(async)/abort(sync) begins and ends) ; ; A secondary dispatch is made for external/status interrupts through ; the external/status dispatch table: ; ; ExtStsDT -> (00) ext/sts B - non-mouse ; (04) unused (or mouse vertical interrupt) ; (08) ext/sts A - non-mouse ; (0C) unused (or mouse horizontal interrupt) ; ; A check is made to determine whether the mouse input (DCD) has changed ; from the last time: if so, the dispatch is made through the mouse ; vector, if not, thru the non-mouse vector. D0 contains the current ; status (read reg 0) and D1 the changed bits from the previous time ; an extenal/status interrupt was received; a reset ext/sts command is also given. ; ; The two special receive condition interrupts may also be further subdivided, but ; all subdivisions are directly related to serial data transfer and not the mice: ; ; end of frame (synchronous modes) ; CRC/framing error ; receiver overrun ; parity error ; all sent (asynchronous mode only) ; ; Each primary routine is entered with the processor priority masked, and with ; registers D0-D3 and A0-A3 available for use; A0 will point to SCC channel A/B ; control read address and A1 to SCC channel A/B control write address, ; depending upon which channel is interrupting: ; ; (READ ADDRESS) (WRITE ADDRESS) ; ; CHANNEL A/B DATA 4(A0) 4(A1) ; ; CHANNEL A/B CONTROL (A0) (A1) ; ; Each routine (except for external/status secondary routines) is responsible ; for clearing the source of the interrupt in the SCC, and for saving and ; restoring any additional A or D registers used. ; ; Routines must exit with an RTS rather than an RTE. ; ; ; The interrupt routine is selected by reading the SCC modified interrupt vector. ; The SCC selects the particular vector to supply according to a fixed priority: ; ; Receiver channel A (highest) ; Transmit channel A ; Ext/Status channel A ; Receiver channel B ; Transmit channel B ; Ext/Status channel B (lowest) ; ; The highest priority interrupt which is also enabled is selected by the SCC. ; Only processing one request at a time allows SccDecode to be re-entrant and service ; routines may lower the processor priority as soon as possible in order to ; process other pending interrupts. ; ; Written by: Bud Tribble 25-Mar-81 ; SccDecode MOVE.L SCCRd,A0 ; get SCC read address MOVE.B (A0),D0 ; read to sync up SCC (just to be safe) MOVE.L SCCWr,A1 ; get SCC channel B write control address SccDecodeCommon MOVE.B #2,(A1) ; point to SCC register 2, B channel LEA SccDT,A2 ; point to dispatch table and delay MOVEQ #$0E,D0 ; 'and mask' and extra delay AND.B (A0),D0 ; read the modified interrupt vector CMPI.B #8,D0 ; channel A interrupt? BLT.S @GoLvl2 ; branch if for B ADDQ #2,A0 ; adjust SCC addresses for port A ADDQ #2,A1 @GoLvl2 ADD D0,D0 ; double vector for dispatch MOVE.L 0(A2,D0.W),A2 ; get dispatch vector JMP (A2) ; chain to service routine ;_______________________________________________________________________ ; ; Routine: DTINSTALL ; ; Arguments: A0 (input) : address of deferred task queue element ; D0 (output): error code - 0 no error ; -2 invalid queue element ; ; Function: Installs a deferred task queue element into the deferred ; task queue pointed to by the variable plsDTQueue. ; ; Format of the deferred task queue element is: ; ; DTLink Link to next queue element (pointer) ; DTType element ID (word = DTQType) ; DTFlags optional flags (word) ; DTAddr address of deferred task routine (pointer) ; DTParm optional A1 parameter (long) ; DTReservd reserved for future use (long) ; ; Registers Used: D0,A1, A0 ;_______________________________________________________________________ DTINSTALL CMP.W #DTQType,DTType(A0) ; is it the proper type? <1.2> BNE.S TypeErr ; return error if not ; now we jsr to the EnQueue routine to add the element to task queue. ; We jump directly thru trap vector for our specific machine to save time ; and avoid the trap dispatcher, which may be important for interrupt-time code. ; (deferred tasks tend to get installed in secondary interrupt handlers) lowEnqueueByte EQU $16F move.l a2,-(sp) ; save out a2 lea plsDTQueue,a1 ; get ptr to queue (SE--low-mem global) move.l #(ToolTable+(4*lowEnqueueByte)), a2 ; calc vector of Enqueue call move.l (a2),a2 ; get Enqueue addr from vector jsr (a2) ; go Enqueue (on Plus) MOVEQ.L #noErr,D0 ; no errors move.l (sp)+,a2 ; restore a2 RTS ; return to caller TypeErr MOVEQ.L #VTypErr,D0 ; else flag the error RTS ; and return with error code in D0 <1.2> ;______________________________________________________________________ <1.2> ; ; Dispatch routine for deferred tasks. This routine checks the deferred ; task queue and removes and executes all tasks found. Regs D0-D3 ; and A0-A3 are saved prior to call. ; ; Bit test the flags to see if we were already executing a deferred task ; when the interrupt occurs. If so, then we should just return to finish up ; that task; don't start a new one. (Any tasks that have gotten queued ; during the interrupt will be caught when the current DT returns.) ;______________________________________________________________________ vDisptch BTST.B #INVBL,QFLAGS+VBLQUEUE ; doing VBL tasks? BNE.S @Exit ; if so, keep deferring lea plsDTQFlags,a0 ; (no lowmem EQUATE to use on Plus) BSET.b #InDTQ,(a0) ; already in dispatcher? BEQ.S DspStart ; check the queue if not @Exit RTS ; otherwise exit DspLoop MOVEA.L D0,A0 ; else setup ptr for use ; now we jsr to the DeQueue routine to add the element to task queue. ; We jump directly thru trap vectors for our specific machines to save time ; and avoid the trap dispatcher, which may be important for interrupt-time code. lowDeQueuebyte EQU $16E lea plsDTQueue,a1 ; get ptr to queue (Plus--local storage) move.l #(ToolTable+(4*lowDeQueuebyte)),a2 ; calc vector for Dequeue move.l (a2),a2 ; get addr from vector jsr (a2) ; go Dequeue (on Plus) MOVEA.L DTAddr(A0),A2 ; get ptr to first task MOVEA.L DTParm(A0),A1 ; get optional parameter ANDI.W #$F8FF,SR ; enable all ints JSR (A2) ; and go do task DspStart ORI.W #HiIntMask,SR ; disable all ints move.l plsDTskQHdr,D0 ; get queue head (Plus--local) BNE.S DspLoop ; loop if tasks exist lea plsDTQFlags,a0 ; no lowmem EQUATE to use BCLR.b #InDTQ,(a0) ; clear indicator (Plus--local) RTS ; and exit endproc ;_______________________________________________________________________ ; End of Patch code for: ;<2.9> Deferred Task Manager _DTInstall Trap, vDisptch ; EH Interrupt Handlers Lvl1Int, Lvl2Int, Lvl3Int ;_______________________________________________________________________ ;_______________________________________________________________________________________ ; (Patch #24, #25) ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 20Dec85 #24 (SendCmd) (SonyDCD) ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 20Dec85 #25 (SendCmd) (SonyDCD) ; ; Patch for HD20 driver (invalid block count for a read or write retry operation) ; ; Patched using SendCmd vector ; ; This patch fixes the bug present in HD20 driver (SonyDCD). When an error occurs during ; a disk read or write operation, the requested block count is incremented by one, causing ; the subsequent retry operation to read/write an additional block. For a read, this ; results with a trashed cache buffer header. ; ; The patch at SendCmd checks for a retry of a read or write command and decrements the ; requested block count. ; ; Upon entry to SendCmd the registers A1 and D3 are set up as follows: ; ; A1.L (in) -- ptr to drive vars ; D3.W (in) -- number of blocks requested ; ;_______________________________________________________________________________________ SendCmdPtch PROC EXPORT ToSendCmd EQU $4196B2 ; ROM address of SendCmd CMPI.B #dcStatus,DCDCmd(A1) ; read or write command? <20Dec85> BGE.S @1 ; no, return to SendCmd <20Dec85> CMPI.B #maxTries-1,ReCalCnt(A1) ; a retry? BEQ.S @1 ; no, return to SendCmd CMPI.B #NoResp,LastStatus(A1) ; time out? <20Dec85> BEQ.S @1 ; yes, return to SendCmd <20Dec85> SUBQ.W #1,D3 ; adjust the block count MOVE.B D3,SeqNum(A1) ; update in SonyVars <20Dec85> @1 JMP ToSendCmd ; return to SendCmd ;_______________________________________________________________________________________ ; (Patch #28) ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 02Jan86 #28 (HRSRC,HNoRSRC,HGetFlags,HSetFalgs) (HRSRC,HNoRSRC,HGetFlags,HSetFalgs) ; ; Patches for HRSRC, HNoRSRC, HGetFlags, HSetFalgs -- ; new memory mannager routines to deal with the RSRC ; bit of an handle, and to save/restore the lead bits ; of an handle. The Flags routines deal with the entire high byte ; of the handle. The point is to free apps from having to twiddle the ; bits directly, allowing us to move the bits in future (32-bit?) ; architectures. These patches contain mixed-case text in honor of the ; forebear, heap and heapGuts. ;_______________________________________________________________________________________ ; Patch28 PROC EXPORT EXPORT HRSRC EXPORT HNoRsrc EXPORT HGetFlags EXPORT HSetFlags JHStdEntry EQU $410262 ;common entry routine for handle bit twiddlers ; ; PROCEDURE HRSRC(h: Handle); ; - Set the RSRC bit of the block pointed to by the given handle. ; Input: A0 - handle. HRSRC JSr JHStdEntry ;filter out 0 and NIL BEq.S HFail ;handle was NIL BSet #Resource,(A1) ;set the lock bit BrA.S HGood ;return success ; ; PROCEDURE HNoRSRC(h: Handle); ; - Clear the RSRC bit of the block pointed to by the given handle. ; Input: A0 - handle. HNoRSRC JSr JHStdEntry ;filter out 0 and NIL BEq.S HFail ;handle was NIL BClr #Resource,(A1) ;set the lock bit ;fall through to HGood HGood MoveQ #0,D0 BrA.S HExit HFail MoveQ #nilHandleErr,D0 HExit Move.W D0,MemErr ;signal errors globally RtS ;simple return from simple routine! ; ; FUNCTION HGetFlags(h: Handle) : BYTE; ; - Get the high byte of the associated handle. ; Input: A0 - handle. ; Output: D0.B - flag byte. HGetFlags JSr JHStdEntry ;filter out 0 and NIL BEq.S HFail ;handle was NIL -- stuff D0 with error code MoveQ #0,D0 ;clear the high bits Move.B (A1),D0 ;stuff the byte Clr.W MemErr ;no error RTS ; ; PROCEDURE HSetFlags(h: Handle; f: BYTE); ; - Set the high byte of the associated handle. ; Input: A0 - handle; D0.B - flag byte HSetFlags Move.B D0,D1 ;preserve across entry call <02Jan86 JTC> JSr JHStdEntry ;filter out 0 and NIL BEq.S HFail Move.B D1,(A1) ;stuff the byte from preserved slot <02Jan86 JTC> BrA.S HGood ;just return zero... ;_______________________________________________________________________________________ ; (Patch #26) ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 26Dec85 #26 (PMoveHHi) (MoveHHi) ; ; Patch for MoveHHi -- set theZone properly across the call. ; The old Pascal glue rendition of MoveHHi required the caller to set ; theZone properly before the call, even though the zone could be inferred ; from the handle itself. The ROM version does indeed infer theZone, but ; it doesn't in fact set theZone across the call. This is bad news, because ; when _CompactMem called to slide the blocks, it may operate on the ; wrong zone! ;_______________________________________________________________________________________ ; PMoveHHi PROC EXPORT JMMHPrologue EQU $4104C6 ;MMHPrologue J1MoveHHi EQU $410290 ;instruction after JSR MMHPrologue Move.L theZone,-(SP) ;save current value of TheZone <26Dec85> PEA @1 ;throw in an address to intercept return <26Dec85> JSR JMMHPrologue ;the usual start code, leaving zone in A6 Move.L A6,theZone Tst.L D7 ;set CCR as MMHPrologue did before theZone stuff JMP J1MoveHHi ;resume with MoveHHi <26Dec85> @1 Move.L (SP)+,theZone ;restore theZone and clean up the stack <26Dec85> RTS ;_______________________________________________________________________________________ ; (Patch #27, #29) ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 02Jan85 #27 (ExtBTFile) (Scavenger) ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 02Jan85 #29 (ExtBTFile) (Scavenger) ; ; Patch for Scavenger. ; ; Patched using ExtBTFile vector. ; ; This patch updates the extent info retained in the alternate MDB on disk. The updated ; info includes the PEOF and the MDB-resident extent record (1st 3 extents) for the BTree ; file being extended. The last-modified date (DrLsMod) is also updated. ; ; The patch code intercepts the return from ExtBTFile (after the BTree file has been ; extended). At this point the patch code reads the Alternate MDB from disk ( via GetBlock), ; updates the extent info, and writes the block back to disk (via RelBlock). ; ; Note, the Alternate MDB block is left in the cache (not dirty). However, it is re-read ; from disk the next time it is to be updated. ;_______________________________________________________________________________________ ScavPatch PROC EXPORT FindDrive EQU $403414 vExtBTFile EQU $406ED4 GetBlock EQU $4077B0 RelBlock EQU $407A0A MOVE.L (SP)+,-(A6) ; save callers return address PEA spStart ; force ExtBTFile to return to patch code JMP vExtBTFile ; continue with ExtBTFile ; ; At this point we have executed ExtBTFile. ; D0.W = result code ; A4.L = pointer to BTCB ; spStart BNE spExit1 ; error from ExtBTFile, exit -> ST CacheFlag ; really flush cache after extension of B-Tree files since ; associated info in MDB is flushed immediately. MOVEM.L D0-D2/A0-A3/A5,-(A6) ; save regs we need MOVE.W BTCRefNum(A4),D1 ; D1 = file refnum MOVEA.L FCBSPtr,A5 ; A5 = ptr to FCB LEA 0(A5,D1.W),A5 ; MOVEA.L FCBVPtr(A5),A2 ; A2 = ptr to VCB MOVE.W VCBDrvNum(A2),D2 ; drive number JSR FindDrive ; locate drive queue element (A3 = ptr to DQE) BNE.S spExit ; no such drive, exit -> ; ; Determine disk size. D2 is set to the disk size (in blocks). ; MOVEQ #0,D2 ; Vol size in 512-byte blocks if not a Sony MOVE.W DQDRVSZ(A3),D2 ; CMPI.W #2,DQDrive(A3) ; Drive # > 2 ? BGT.S @1 ; yes, not sony, got size -> MOVE.W #800,D2 ; assume single-sided sony TST.B DQDRVSZ(A3) ; TwoSideFmt? BEQ.S @1 ; br if not ASL.L #1,D2 ; two-sided, double size @1 TST.W 4(A3) ; new version element? BEQ.S spGetMDB ; br if not MOVE.L DQDRVSZ(A3),D2 ; it's a long in the new world SWAP D2 ; but swapped for compatibility ; ; Get the alternate MDB from disk. ; spGetMDB SUBQ.W #2,D2 ; block # = disk size - 2 MOVE.W VCBVRefNum(A2),D0 ; volume refnum MOVEQ #kGBRead,D1 ; force read option MOVEA.L BTCCQPtr(A4),A1 ; ptr to cache queue JSR GetBlock ; get the block (A0 = ptr to alt MDB) BNE.S spExit ; error, exit -> MOVEQ #kRBTrash,D1 ; set trash RelBlock option <02Jan85> CMP.W #TSigWord,DrSigWord(A0) ; does it bear the Turbo signature? BNE.S spRelBlk ; no, release the block and exit -> <02Jan85> ; ; Update the extent info. ; spUpdate LEA DrCTFlSize(A0),A3 ; assume update for catalog MOVEQ #FSCTCNID,D0 ; catalog BTree file? <02Jan85> CMP.L FCBFlNm(A5),D0 ; <02Jan85> BEQ.S @1 ; yes -> MOVEQ #FSXTCNID,D0 ; extents BTree file? <02Jan85> CMP.L FCBFlNm(A5),D0 ; <02Jan85> BNE.S spRelBlk ; no, release the block and exit -> <02Jan85> LEA DrXTFlSize(A0),A3 ; point to extent file info @1 MOVE.L FCBPlen(A5),(A3)+ ; update the file size (PEOF) MOVEQ #(lenXDR/4)-1,D0 ; length of XDR (in long words) - 1 LEA FCBExtRec(A5),A1 ; source = FCB extent record @2 MOVE.L (A1)+,(A3)+ ; update DBRA D0,@2 ; ...the extent record info MOVE.L Time,DrLsMod(A0) ; update mod date also ; ; Release the block (with force write option). ; MOVEQ #kRBWrite,D1 ; force write RelBlock option spRelBlk JSR RelBlock ; release the block spExit MOVEM.L (A6)+,D0-D2/A0-A3/A5 ; restore registers spExit1 MOVE.L (A6)+,-(SP) ; restore callers address TST.W D0 ; reset condition codes RTS ; return to caller ************************************************************************ <08Apr86 JTC> ; (Patch #34) ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 08Apr86 #34 (InitZone) (MakePtrSpc) ; ; This patch to InitZone calls the JSRs to the original ROM code and ; then, on return from ROM, replaces the ROM standard grow-zone proc ; (not to be confused with the the USER grow-zone proc) included here. ; The point is to fix a problem in the Memory Manager routine MakePtrSpc ; which incorrectly advances through the heap looking for bases from which ; to call routine MakeSpace. Luckily, a common (and elaborate) sequence ; of routines is always invoked in this troublesome case, so that a simply ; ugly stack test determines whether we're in trouble. When we have been ; called ultimately from MakePtrSpc, we just fudge the return address ; (now very deep within the stack) to get us here to a little patch rotine. ; Embarrassingly, a very similar situation required patching back in ; 64K ROM days. Alas... ; ; MagicMPS is an offset into the stack at which to look for ROMFromMPS. ; In detail, the stack is: ; 410656 return to CallGZProc ; 16 longs ; 4106BE return to BkCompactS ; 2 longs ; 410712 return to AllocBk ; 6 longs ; 410BFA return to RelocRel ; 5 longs ; 410BD6 return to SafeReloc ; 1 long ; 410B7A return to MakeSpace ; 7 longs ; 410B18 return to MakePtrSpc ; etc. ; ************************************************************************ MyInitZone PROC EXPORT ROMInitZone EQU $40FF38 ; InitZone start ROMFromMPS EQU $410B18 ; rts from "BSR.S MakeSpace" MagicMPS EQU 172 ; offset to MakePtrSpc return, if any! ROMStdGZ EQU $410C6C ; StdGZ start ROMBackMPS EQU $410B34 ; resume MakePtrSpc privGZ EQU $2C ; private MM growzone proc move.l (a0),-(sp) ; save ptr to zone jsr ROMInitZone move.l (sp)+,a0 ; ptr to zone lea myStdGZ,a1 move.l a1,privGZ(a0) ; overwrite with our StdGZ rts myStdGZ cmp.l #ROMFromMPS,MagicMPS(sp) ; could it be???? bne.s goROMStdGZ lea PatchMPS,a1 move.l a1,MagicMPS(sp) ; fudge our loop goROMStdGZ jmp ROMStdGZ ************************************************************************ ; When we return from MakeSpace, ; A0 = end of previously searched region ; A1 = junk ; A2 = ptr to found space, or NIL ; A3 = end of zone ; A4 = zone ; A5-A7 = reserved ; D0/D2-D7 = reserved ; D1 = junk ************************************************************************ PatchMPS move.l a2,d2 ; NE --> we got the space bne.s goROMBackMPS lea HeapData(a4),a2 ; start the search for a new region rgnLoop move.l TagBC(a2),d1 ; size of current block and.l Lo3Bytes,d1 ; stripped of flags add.l d1,a2 ; ptr to next block tst.b TagBC(a2) ; status of block at hand beq.s @4 ; free block is bad place bpl.s @3 ; ptr block is good place move.l Handle(a2),a1 ; recover master ptr adda.l a4,a1 ; a1 := master ptr tst.b (a1) ; PL --> unlocked bpl.s @4 ; loose block is bad place @3 cmpa.l a0,a2 ; a0 < a2 is desired, past old rgn bhi.s @5 @4 cmpa.l a3,a2 ; a3 <= a2 means beyond heap end bcs.s rgnLoop ; Carry Set means a3 > a2 @5 move.l a2,a0 ; reset rgn base suba.l a2,a2 ; clear a2 for return to MakePtrSpc goROMBackMPS jmp ROMBackMPS ;-------------------------------------------------------------------------- ; (Patch #35) ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 01Jan1904 #35 (SonyVBL) (SonyVBL) ; ; Patch to Sony VBL task to make it run at interrupt level 3 (instead of 1): ;-------------------------------------------------------------------------- SonyVBL PROC EXPORT MOVE SR,-(SP) ; Save status reg across call ORI.W #$0300,SR ; Lock out all other interrupts JMP $418B46 ; And continue as before ;___________________________________________________________________________ ; ; Patch #43: ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 23Apr86 #43 (BTFlush,BTClose) (BTFlush,BTClose) ; ; A patch in the ROM's BTFlush and BTClose path to keep it ; from acting on requests for user-created B*-Trees. ; ; Symptoms are that the ROM B*-Tree code is invoked for a user-created ; B*-Tree (using the B*-Tree manager package). Since the B*-Tree manager ; sits on top of the actual File System, it makes a _FlushFile call when ; it has written some B*-Tree blocks out to the file. The ROM code, however, ; will look at the FCB for the file, decide that this must be one of its ; B*-Trees, and tries to do its own FlushCache for this B*-Tree, which ; crashes due to differences in the data structures for the BTCB and the ; Cache Block header setups between the ROM B*-Tree manager and the B*-Tree ; manager package. ; ; Written by: Patrick W. Dirks, April 19 1986. ; ; Modification History: ; ; 4/23/86 PWD New today. ;___________________________________________________________________________ Patch43 PROC EXPORT EXPORT BTFlush EXPORT BTClose ; ; Special addresses required: ; ;jBTClose .EQU $730 ; BTClose vector (from NewEqu) ROMBTClose EQU $4066E2 ; ROM BTClose entry ;jBTFlush .EQU $738 ; BTFlush vector (from NewEqu) ROMBTFlush EQU $4068C8 ; ROM BTFlush entry ; ; New BTClose entry: ; BTClose: PEA ROMBTClose ; Set up to jump into ROM BTClose BRA.S CNIDChk ; Go check the CNID ; ; New BTFlush entry: ; BTFlush: PEA ROMBTFlush ; Set up to jump into ROM BTFlush CNIDChk: MOVEM.L A0/D0,-(SP) ; Stash A0 for our check MOVEA.L FCBsPtr,A0 ; Point to the FCB table MOVE.L 0(A0,D0),D0 ; Pick up the File # SUBQ.L #$4,D0 ; Compare to catalog CNID MOVEM.L (SP)+,A0/D0 ; Restore registers BLS.S @10 ; Yes - let 'em go (its catalog, #4 or extents, #3) ADDQ.L #4,SP ; Remove the vector address MOVEQ #0,D0 ; ...and fake successful completion @10 RTS ; And call it a day. ;_______________________________________________________________________________________ ; FClose patch #49 ; ; This bug occurs when FClose is called as the result of an UnmountVol, without ; a preceeding FlushVol call. FClose calls TstMod which in turn calls RFNCall. ; RFNCall needs A0 pointing to an IO parameter block with IORefNum set up. This field ; is zero when FClose is called from UmmountVol, causing D1 (the file refnum) to be ; set to zero by RFNCall. ; ; Since the call to RFNCall is superfluous in this case, the source code can be fixed ; by simply bypassing the call to RFNCall. This can be accomplished by changing the ; "BSR TstMod" in FClose to "BSR TstMod1" as follows: ; ; ResetAEOF TST.B FlushOnly ; BNE.S UpdFlCat ; BSR TstMod1 ; ; and by adding the label "TstMod1" in TstMod as follows: ; ; TstMod ; BSR.S RFNCall ; BNE.S TMExit ; TstMod1 MOVEQ #WrPermErr,D0 ; ; The ROM75 patch for this bug is via the RFNCall vector. The patch code simply ; checks for the return address from the BSR TstMod in FClose and returns immediatly ; from RFNCall with a successful result. ;_______________________________________________________________________________________ FClosePtch PROC EXPORT FromFClose EQU $4051BC ; return address from TstMod call <10Sep86> ToRFNCall EQU $405358 ; entry address for RFNCall <10Sep86> CMP.L #FromFClose,4(SP) ; comming from right place in FClose? <10Sep86> BNE.S @1 ; no -> <10Sep86> CLR.W D0 ; result = 'ok' <10Sep86> RTS ; return to TstMod <10Sep86> @1 JMP ToRFNCall ; continue with RFNCall <10Sep86> ENDPROC ;_______________________________________________________________________________________ ; BasicIO patch #50 ;; ; This patch fixes two bugs in BasicIO. The first one occurs when a async driver ; completes an asynchronous call synchronously. The stack is not cleaned up ; immediately causing a build up of stack frames until the high level FS call ; completes. A stack overflow can occur if the high level FS call involves a lot of ; read/write operations. ; ; The second one occurs when a read or write is issued for an off-line volume. The ; condition codes are left set as if no error occurred, causing the higher level ; caching routines to proceed as if the disk block had been read or written. However, ; this is only a problem for MountVol since in all other cases, the off-line condition ; is detected by the disk switch hook. ; ; The patch is via the BasicIO vector. Due to the position of the bugs and the ; relatively small size of the BasicIO routine, the patch code is simply a copy of ; the BasicIO routine with the two bugs fixed. The code changes are marked with the ; date of this patch, <11Sep86>. ;_______________________________________________________________________________________ BasicIOPtch PROC EXPORT ; read/write the disk block MOVE.L A6,HFSStkPtr ; save stack ptr TST.B FSCallAsync ; was FS call async? <01Oct85> BNE.S rwAsync ; br if so (keep it that way) <01Oct85> TST.B D1 ; 'read' operation? BNE.S @3 ; no, must be a 'write' -> _Read ; read it synchronously <01Oct85> BRA.S RWCont1 ; then continue <01Oct85> @3 _Write ; write it synchronously <01Oct85> BRA.S RWCont1 ; then continue <01Oct85> rwAsync LEA RWIOComp,A1 ; IO completion address MOVE.L A1,IOCompletion(A0) ; BCLR #HFSContd,HFSFlags ; Clear 'premature-continuation' flag TST.B D1 ; 'read' operation? BNE.S @1 ; no, must be a 'write' -> _Read ,ASYNC ; read it asynchronously BRA.S @2 ; @1 _Write ,ASYNC ; write it asynchronously @2 BEQ.S @3 ; br if no immediate error <02Oct85> TST.W IOResult(A0) ; immediate error? for sure? <02Oct85> BLE.S RWCont ; br if so (otherwise, driver just <02Oct85> ; passed back some garbage . . .) @3 BSET #HFSContd,HFSFlags ; We're now returning from the trap BNE.S RWCont1 ; If we already returned, do I/O comp. now <11Sep86> RWRTS RTS ; return to caller (complete asynchronously) ; IO completion routine RWIOComp BSET #HFSContd,HFSFlags ; We're continuing now BEQ.S RWRTS ; If trap didn't really return ,ASYNC ; ... then RTS now (we'll be back) RWCont MOVEM.L D4-D7/A4-A6,-(SP) ; preserve non-interrupt registers PEA RWCont2 ; return to here to restore regs RWCont1 MOVEA.L HFSStkPtr,A6 ; Recover HFS' private stack pointer <01Oct85> MOVEM.L (A6)+,D1-D7/A0-A5 ; Retrieve registers off A6 stack <01Oct85> MOVE.L (A6)+,-(SP) ; pop ret address off HFS stack <01Oct85> TST.W D0 ; any errors? <01Oct85> BEQ.S @1 ; br if not <01Oct85> CMP.W #OffLinErr,D0 ; Offline? <09Sep85> BEQ.S @1 ; br if so <10Sep85> MOVE.W D0,FSIOErr ; save original error for debugging <01Oct85> MOVEQ #IOErr,D0 ; transform it to generic IO error <01Oct85> @1 TST.W D0 ; set up condition codes <11Sep86> RTS ; return to caller with error code <01Oct85> RWCont2 MOVEM.L (SP)+,D4-D7/A4-A6 ; restore the registers <01Oct85> RTS ; we're done with it! <01Oct85> ;___________________________________________________________________________ ; ; Patch #52: ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 10Dec86 #52 (SonyWakeUp) (SonyWakeUp) ; ; A patch to the Sony Driver's wakeup routine to prevent driver re-entry ; AFTER the registers have been saved but BEFORE the wakeup address has ; been set. ; ; Symptoms are that mysterious hangs in the Sony Driver when the old entry ; point is re-entered with the new registers. ; ; Written by: Patrick W. Dirks, June 24 1986. ; ; Modification History: ; ; 6/24/86 PWD New today. ; 10/14/86 PWD Integrated into ROM75Fix sources ; 09Dec86 TJ Added the original patch of raised int level ; 10dec86 TJ No interrupts allowed ;___________________________________________________________________________ SonyWakeUp PROC EXPORT ; ;Special addresses: ; ROMWakeup EQU $4187DA ; ROM wakeup entry point or.w #$0300,SR ; no interrupts <10dec86><09dec86><24jun86> move.l SonyVars,A1 ; ROM expects this (and we need it) movem.l D3-D7/A3-A6,SaveRegs(A1) ; save regs first, jmp ROMWakeup ; And enter normal wakeup routine endp ;___________________________________________________________________________ ; Patch #63 07Jan87 DAF GetWVariant WindowMgr2.a:GetWVariant ; ; This patch is a toolbox enhancement to 128K ROM and greater systems ; ; function GetWVariant ( someWindow : WindowPtr ) : integer; ; ; GetWVariant returns the variant code of the windowRecord pointed at by ; someWindow. The value returned is an integer even though variants ; are currently only 4 bits as word params on the stack are easier to ; handle ; GetWVariant PROC EXPORT MOVE.L (SP)+,A0 ; get the return address MOVE.L (SP)+,A1 ; get windowPtr MOVEQ #$0F,D0 ; trim to 4 bits, word length AND.B WindowDef(A1),D0 ; get the variant code MOVE.W D0,(SP) ; return the result JMP (A0) ; return to caller ;___________________________________________________________________________ ; Patch #64 07Jan87 DAF GetCVariant ControlMgr1.a:GetCVariant ; ; This patch is a toolbox enhancement to 128K ROM and greater systems ; ; function GetCVariant ( whichControl : controlHandle ) : integer; ; ; GetCVariant returns the control variant code of the control whose ; handle is whichControl. Variant codes are 4-bit values returned ; right-justified in the word result. In case you are wondering ; the result is word rather than byte because it's less complicated ; for this stack-based routine, and the variant is passed to the ; defprocs as a word. GetCVariant PROC EXPORT MOVE.L (SP)+,A1 ; get the return address MOVE.L (SP)+,A0 ; get windowPtr MOVE.L (A0),A0 ; get ctl ptr MOVEQ #$0F,D0 ; lo nybble only AND.B ContrlDefHandle(A0),D0 ; get selector parameter MOVE.W D0,(SP) ; return result JMP (A1) ; and return to caller ; ; Patch #65 15Jan87 TJ FigTrkSpd sonyQDUtil.a ; ; This patch fixes lost Time Manager interrupts; the Sony driver, via ; the routine FigTrkSpd, uses T2 to measure rotational time, and hence leaves ; the timer stopped. This is fixed here by setting T2 to be 0001, ie. the ; shortest possible interval. If TimeMgr had an interrupt pending, it ; most certainly would have expired by now (FigTrkSpd takes some time) so ; setting a count of 1 will cause a near-immediate interrupt, if it is ; enabled. If its not enabled, nothing happens and we wasted our time. ; Patch65 PROC EXPORT EXPORT newFigTrkSpd,oldFigTrkSpd oldFigTrkSpd dc.l 0 ; saved orig. vector newFigTrkSpd move.l A2,-(SP) move.l oldFigTrkSpd,A2 ; call the orig. code first, jsr (A2) ; (it wrecks T2) [this is not] move.w SR,-(SP) ; then fix it [as much fun] or #$0700,SR ; ints off while we fiddle, move.l VIA,A2 move.b #1,VT2C(A2) ; set T2 count to 0001, move.l (SP),(SP) ; delay [as skateboarding] move.b #0,VT2CH(A2) move.w (SP)+,SR move.l (SP)+,A2 ; skate & annoy rts ;___________________________________________________________________________ ; Patch #66 17Jan87 JTC FixRound, Fix2Long, Frac2Fix from Munger.a ; ; This patch corrects silly bugs in the Mac+ ROM. It is taken ; essentially verbatim from the Aladdin and later code. Patch66 PROC EXPORT EXPORT MyFixRound,MyFix2Long,MyFrac2Fix ***************************************************************** * Fixround -- get negative case right by adding (1/2 - epsilon) * to negative values (-M + f) and truncating to more negative * integer. This is a la CRC’s ultimate fix for Maui/Becks. * It didn’t work for Mac64 either, but nobody used it there. ***************************************************************** MyFixRound ; added code <17Jan87 JTC> movea.l (sp)+,a0 ; strip return address moveq #1,d1 ; d1 := $00000001 ror.w #1,d1 ; d1 := $00008000 = 1/2 move.l (sp)+,d0 ; fixed-pt argument bpl.s @skipMinusFix ; just add 1/2 if positive not.w d1 ; d1 := $00007FFF = 1/2 - epsilon @skipMinusFix add.l d1,d0 ; add 1/2 (with or without epsilon) bvc.s @skipOflowFix ; oVerflow bit is set for pos oflow only moveq #-2,d0 ; d0 := $FFFFFFFE = -2 ror.l #1,d0 ; d0 := $7FFFFFFF = huge pos value @skipOflowFix swap d0 ; d0.w := truncated integer value move.w d0,(sp) ; stuff integer function result jmp (a0) ; return to caller ***************************************************************** * Fix2Long, Frac2Fix -- convert one fixed-pt type to another by * right-shifting significant bits and rounding. Bug in Mac+ * was that the round up was addq (.w, that is) not addq.l. * Frac = ii.ff ffff ffff ffff ffff ffff ffff ffff * Fix = iiii iiii iiii iiii.ffff ffff ffff ffff * Long = iiii iiii iiii iiii iiii iiii iiii iiii. ***************************************************************** MyFix2Long ; added code <17Jan87 JTC> moveq #16,d1 ; d1 := 16 = right shift count bra.s rtShftCommon ; common code to shift and round MyFrac2Fix ; added code <17Jan87 JTC> moveq #14,d1 ; d1 := 14 = right shift count rtShftCommon movea.l (sp)+,a0 ; return address move.l (sp)+,d0 ; argument to be shifted and rounded bpl.s @posFixArg ; go to easy case of shift and round neg.l d0 ; shift and round as positive value lsr.l d1,d0 ; align bcc.s @negNoInc ; Carry = round bit addq.l #1,d0 ; round up by an ulp <-- BUG WAS HERE @negNoInc neg.l d0 ; restore true sign bra.s @fixFini ; and exit @posFixArg lsr.l d1,d0 ; align binary pt bcc.s @fixFini ; Carry = round bit addq.l #1,d0 ; round by an ulp <-- BUG WAS HERE @fixFini move.l d0,(sp) ; stuff return arg jmp (a0) ;___________________________________________________________________________ ; Patch #67 22Jan87 JTC FixDiv/FracDiv from Munger.a. And new StripAddress. ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 22Jan87 #67 (FixDiv/FracDiv,StripAddress) (FixDiv/FracDiv,StripAddress) ; ; This patch corrects silly bugs in the Mac+ ROM. It is taken ; essentially verbatim from the Aladdin and later code. ; Duck soup StripAddress is added anew. Patch67 PROC EXPORT EXPORT MyFracDiv,MyFixDiv ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; FixDiv: <#66 22Jan87 JTC> ; Dividing xxxx.xxxx by yyyy.yyyy. Must prenormalize y to run division ; algorithm. To minimize number of divide steps, prenormalize x as well. ; Step count = 1-int + 16-frac + 1-round + y-shifts - x-shifts - 1-DBRA. ; Cases: count <= 0 quo := 0 ; 0 < count < 32 quo := as computed ; count >= 32 quo := fixOver ; Note that we can accommodate the "extra" round bit because the signed ; result is really only 31 bits wide in magnitude. ; ; FracDiv: ; Step count = 1-int + 30-frac + 1-round + y-shifts - x-shifts - 1-DBRA. ; ; FixDiv: ; Step count = 1-int + 16-frac + 1-round + y-shifts - x-shifts - 1-DBRA. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ROMFixStdEntry equ $415880 ROMFixArgs equ $41588C ROMFixOver equ $4158A4 ROMFix2ParamEx equ $41585E ROMFixReSign equ $415854 MyFracDiv JSR ROMFixStdEntry ; use rom where we can MOVEQ #31,D3 ; 1 + 30 + 1 - 1 = signature of FixRatio BRA.S comDiv MyFixDiv JSR ROMFixStdEntry ; use rom where we can MOVEQ #17,D3 ; 1 + 16 + 1 - 1 = signature of ... comDiv JSR ROMFixArgs ; use rom where we can ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize quo, have step count in D3; and check for division by zero. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOVEQ #0,D0 ; initialize quo TST.L D1 BNE.S @13 ; entry to next loop, D1 tested @fixOver JMP ROMFixOver ; use rom where we can ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Loop to prenormalize y. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @11 ADDQ.W #1,D3 ADD.L D1,D1 @13 BPL.S @11 TST.L D2 BNE.S @17 ; continue if nonzero denom @TwoParmExit JMP ROMFix2ParamEx ; hasty retreat if 0/0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Loop to prenormalize x. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @15 SUBQ.W #1,D3 ADD.L D2,D2 @17 BPL.S @15 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for cases above, based on step count in D3.W ; The 0-based quotient bit count is in D3, for a DBRA loop below. ; D3 <= 0 means that there are no (nonzero) quotient bits to compute, ; that is, the result is zero. D3 < 32 means that we're computing ; at most 32 real bits, so there can be no overflow. ; Now the subtle part: with normalized dividend and divisor, there is at ; most one leading 0 bit before the nonzero quotient begins. That means ; that when the D3 = 32 (that is, 33 quotients bits coming), we overflow ; precisely when the leading quotient bit is 1; otherwise, we just fall ; into the divide loop where a zero quotient bit would have taken us. ; Finally D3 > 32 gurantees overflow. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TST.W D3 BLE.S @TwoParmExit ; StdExit, 0 is the result CMPI.W #32,D3 ; changed for #31 to # 32 BLT.S L23 ; fall into loop, guaranteed no overflow BGT.S @fixover ; was bra.s until now, overflow guaranteed CMP.L D1,D2 ; D1 < D2 --> CarrySet -->first bit is zero BCS.S L27 ; falls in when 0 quo bits go BRA.S @fixOver ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Divide loop, to divide D2 by D1, developing D3.W quotient bits into D0. ; At each step quotient is left shifted one place; in event of carry-out ; be sure to force subtract. Because of tests above, there's no chance ; of overflow except during round step. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; L21 ADD.L D0,D0 ; make way for next quo bit ADD.L D2,D2 ; shift dividend BCS.S L25 ; force subtract on carry L23 CMP.L D1,D2 ; divisor vs dividend BCS.S L27 ; skip subtract if too small L25 SUB.L D1,D2 ADDQ.W #1,D0 ; no carry here L27 DBRA D3,L21 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Use the low bit of D0 to round the result. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LSR.L #1,D0 BCC.S @reSign ADDQ.L #1,D0 @reSign JMP ROMFixReSign ENDPROC ****************************************************************************** * StripAddress -- remove extraneous bits from an address. * Input: D0 = address to be stripped * Output: D0 = stripped address * Regs trashed: none * Implemented on Aladdin and Milw, backpatched to Mac+. ***************************************************************************** MyStripAddress PROC EXPORT and.l Lo3Bytes,d0 rts ENDPROC ;___________________________________________________________________________ ; PMA207 Cxxx 17Jul87 EHB PackBits ; ; This patch allows scanLines > 127 bytes to be packed using packBits. PatchPMA207 PROC EXPORT ENDPROC ; Important: PackBitsPatch.a contains globals which must be ; outside of any PROC. INCLUDE 'PackBitsPatch.a' ;___________________________________________________________________________ ; PM062 C628 25feb87 bbm added new trap rGetResource. (#68) ; ; Routine: FUNCTION rGetResource(theType: ResType; theID: INTEGER): Handle; ; ; Arguments: 10(A6) (input.L) resource type ; 8(A6),A0(input.W) resource ID ; 14(A6) (output.L) resource handle ; ; Called By: A-trap through dispatcher ; Calls: GetResource ; ; Function: do a normal GetResource without the rom map; if that fails, ; do GetResource with the rom map inserted. ; ; NOTE: _GetResource expects a specific items on the stack when called. ; This routine depends heavily on that stack. Below is a picture ; of the stack just before the _GetResource trap is executed ; (starting in the middle of the stack and ending at the top of stack, ; or starting in high memory and decending down in memory). ; ; handle 4 bytes ; type 4 bytes (E bytes back on stack after < subq #4,sp >) ; ID 2 bytes (C bytes back on stack after < subq #4,sp >) ; rtn addr 4 bytes (8 bytes back on stack after < subq #4,sp >) ; rtn addr 4 bytes (4 bytes back on stack after < subq #4,sp >) ; handle 4 bytes (0 bytes back on stack after < subq #4,sp >) ; type 4 bytes ; ID 2 bytes NewRGetResource PROC EXPORT grStFr equ $0E ; size of the stack frame. (see note above) clr.b ROMMapInsert ; make sure we don’t use rom map bsr.s @getrsrc ; bne.s @exit ; if handle is not zero, then we don’t check rom st.b ROMMapInsert ; else make sure we use rom map bsr.s @getrsrc ; @exit ; std exit to strip the stack move.l (sp)+,a0 ; strip off the return address into a0 addq #6,sp ; strip off type and ID jmp (a0) ; and return through a0 @getrsrc ; go do GetResource move.b resload,ROMMapInsert+1 ; set temp value of resload to current resload subq #4,sp ; save room for another handle (see note above) move.l grStFr(sp),-(sp) ; push type again move.w grStFr+2(sp),-(sp) ; push ID again _GetResource ; move.l (sp)+,grStFr(sp) ; push the handle we got back into the area ; the user saved for the handle and set cc’s rts ; ENDPROC ; NewRGetResource ;------------------------------------------------------------------------------ ; PM090 07mar87 bbm (#69) patched _read to fix bug in openresfile. ; PMAB216 21Jul87 GWN Read,Write,Control,Status ; PMAB226 21Jul87 GWN Backout PMAB216. ; 20Feb90 DD Changed the pchRead to do a proper come-from patch; it now compares ; the return address first, and calls oldRead instead of ROMRead. ; This makes it compatable with other come-from Read patches, like the ; one for SizeRsrc in compression. ; ; ; pchRead ; If the resource file is trashed, OpenResFile should return an error when it ; tries to open the file. There is an obscure bug where the type offset in the ; map is odd, which causes the validity check (in routine CheckMap in RmgrAsm2) ; during openresfile to get an address error. The last trap before the check ; is _Read. This patch to _Read has four parts: first, it executes the rom ; read call; second, it checks if we are coming from the buggy place in ROM; ; third, it checks if the type offset is odd; and fourth, it ‘doctors’ the ; dataoffset and datasize in the map so that the validity check will fail ; before it gets an address error. ; ;------------------------------------------------------------------------------ NewMapStack Record 0 dispatcherReturn DS.L 1 ;return address to the dispatcher dispatcherRegs DS.L 5 ;dispatcher saves five regs. dispatcherResult DS.L 1 ;dispatcher pops this result long. readReturn DS.L 1 ;return address for the _Read trap. RdResgisters DS.L 4 ;four registers saved by RdData. RdDataReturn DS.L 1 ;return address (to NewMap?) EndR rNewMap EQU $004136B4 ; address if coming from NewMap’s call ; ... to RdData, which calls _Read ROMread EQU $004023BE ; address of _Read in ROM MTypOdd EQU $19 ; mtype offset for byte in map odd check badSize EQU $01000000 ; too large size for resource manager pchRead Proc Export ;patch _read to fix bug in openresfile With NewMapStack cmp.l #rNewMap,RdDataReturn(sp) ; check if coming from the bug in rsrcmgr beq.s @comeFromRead ; ... if not, JumpOldRead. @callOldRead BackToTrap oldRead ; just jump to the old read. ; Never returns @comeFromRead Bsr @callOldRead ; go do the read first move.l (A4),A1 ; A4-handle to map, A1-preserved by dispr btst #0,MTypOdd(A1) ; check for an odd value in type offset beq.s @exit ; ... if not odd, just exit move.l #badSize,(A1) ; make sure eof for maxRFEOF is bad move.l (A1),8(A1) ; so maxRFEOF returns value >= $02000000 @exit rts EndWith ;------------------------------------------------------------------------------ ; end of patch ;------------------------------------------------------------------------------ ENDPROC ; pchRead ; PMA100 CXXX 10Mar87 DAF FindWindow {TB}WindowMgr3.a ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 10Mar87 #PMA100 (FindWindow) (FindWindow) ; ; FindWindow Patch: ; ; This patch adjusts FindWindow to call the menuBar defProc to hit test the mouse ; point. It works only with the patched menumgr. ; ; ; FUNCTION FindWindow(thePoint: Point; VAR theWindow: WindowPtr): INTEGER; ; ; FindWindow PROC EXPORT IMPORT CallMBarProc FWEntry1 EQU $412116 FWEntry2 EQU $412112 MOVEM.L D1/D3/A3,-(SP) ;save work registers <23-Oct-85 EHB> LEA 16(SP),A0 ;point to window ptr var <23-Oct-85 EHB> MOVE.L (A0)+,A1 ;get pointer to windowPtr CLR.L (A1) ;make it NIL MOVE.L (A0)+,D3 ;get the mouse point CLR.W (A0) ;set classification code to zero ; ; first check to see if the point is on the menu bar. It returns - for not in menubar, ; 0 for in menubar, but not in title, or + for in menu Title. ; MOVEQ #1,D0 ; put hit message in D0 DAF MOVE.L D3,D1 ; send point as parameter DAF BSR CallMBarProc ; call menuBar defproc DAF TST.L D0 ; test the result DAF BMI.S NotOnMBar ; if +, then not on bar DAF JMP FWEntry2 NotOnMBar JMP FWEntry1 ;____________________________________________________________________________________ ; PMA100 CXXX 10Mar87 DAF InitWindows {TB}WindowMgr2.a ; ; InitWindows Patch: ; ; This patch adjusts InitWindows to call the menuBar defProc when calculating the ; menuBar height and clearing the space. It works only with the patched menumgr. ; ; ; PROCEDURE InitWindows; ; INITWINDOWS PROC EXPORT IMPORT CallMBarProc AllocPort EQU $411570 IWReEntry EQU $4115E6 MOVEM.L D3-D5/A3-A4,-(SP) ; save work registers MOVEQ #7,D0 ; handy bit number BSET D0,DSWndUpdate ; cancel pending PaintBehind BSET D0,AlarmState ; reset alarm parity CLR.B WWExist ; say the window world exists MOVE.L MinusOne,SaveUpdate ;enable update accumulation and erasing ; set up the deskPattern from Sys.resource SUBQ #4,SP ;make room for function result MOVE #deskPatID,-(SP) ;push pattern ID of deskPattern _GetPattern ;tell resource manager to get it MOVE.L (SP)+,A0 ;get the pattern handle MOVE.L (A0),A0 ;get pattern pointer MOVE.L (A0)+,DeskPattern ;init the deskPattern MOVE.L (A0),DeskPattern+4 ;don't forget 2nd half of it ; ; allocate and init the window manager's port ; JSR AllocPort MOVE.L A3,WMGRPORT ;make it the wmgrPort ; ; initialize the screen by blacking out the corners, drawing the menu bar, and then ; filling the rest with the deskPattern. LEA PortRect(A3),A0 ; get the port's rect MOVE.L A0,-(SP) ; a copy for building gray region MOVE.L A0,-(SP) ; and one for painting it gray LEA TempRect,A4 ; get a temp rect MOVE.L A4,A1 ; get a copy to trash MOVE.L (A0)+,(A1)+ ; copy the portRect MOVE.L (A0),(A1) MOVE.L A4,-(SP) ; push the temp rect MOVE.L #$FFFDFFFD,-(SP) ; and make it bigger _InsetRect ; by 3 pixels on each side MOVE.L #$00030003,-(SP) ; get a wider pen _PenSize MOVE.L A4,-(SP) ; push the port rect MOVE.L #$00160016,-(SP) ; and a radius for nice rounding _FrameRoundRect ; and black out the corners _PenNormal ; fix the pen back up ; ; draw the empty menu bar, leaving the clip region set to the menuBar _InitMenus ; init the mbar defproc DAF MOVEQ #6,D0 ; set up for the height message, no params BSR.S CallMBarProc ; execute the defproc,ignoring the result MOVEQ #0,D0 ; set up for the draw message MOVE.L #-1,D1 ; parameter is -1 for cleared bar only BSR.S CallMBarProc ; execute the defproc JMP IWReEntry ; return to ROM ;------------------------------------------------------------------------------------------- ; ; Utility -- CallMBarProc ; ; On Entry: d0 lo-word=message number, hi-word=parameter1 ; d1 parameter2 ; Use: a0 ; On Exit: d0 return value ; ; mbResID: comes from menuList ; mbVariant: the low 3 bits of mbResID are the variant ; ; Note that we store the MBDF's Hndl in low memory location MBDFHndl but this is for ; convenience only. We do not count on its being there between calls to this utility. ; ;------------------------------------------------------------------------------------------- CallMBarProc PROC EXPORT movem.l d4, -(sp) ; save work register CLR.L -(SP) ; make room for defproc return MOVE.L MenuList,A0 ; get the menuList head MOVE.L (A0),A0 ; handle->pointer move mbResID(a0), -(sp) ; get resource ID <24Jan87> andi.w #0007, (sp) ; use low 3 bits only MOVE.W D0,-(SP) ; push the message number swap d0 ; get parameter1 in lo-word move.w d0, -(sp) ; push parameter1 MOVE.L D1,-(SP) ; push parameter2 ; ; get the mbarproc each time we call it instead of counting on low mem to be correct ; subq #4, sp ; space for return result move.l #'MBDF', -(sp) move mbResID(a0), -(sp) ; get resource ID MOVE.W #MapTRUE,ROMMapInsert ; set flag to load from ROM _GetResource move.l (sp)+, MBDFHndl MOVE.L MBDFHndl,A0 ; get the menu bar defproc handle _HGetState ; get the current state move.l d0, d4 ; save state in d4 _HLock ; lock it MOVE.L (A0),A0 ; get a pointer to it JSR (A0) ; jump to it ; returned from defproc, return handle to previous state before exiting MOVE.L MBDFHndl,A0 ; get the handle move.l d4, d0 ; get previous state from d4 _HSetState ; reset previous state MOVE.L (SP)+,D0 ; get the defproc return movem.l (sp)+, d4 ; restore work register RTS ; and return ;____________________________________________________________________________________ ; PM119 MapFBlock patch: ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 19Mar87 #PM119 (jLg2Phys) (MapFBlock) ; ; This patch fixes a problem in MapFBlock which was trashing the extent file. ; MapFBlock was adding a word value rather than a long word value during the ; calculation of starting logical block number. This resulted in a wrap- ; around of the block number (modulo 64K). Since the extent file resides at ; allocation block zero, it was the first file to be trashed. ; ; This patch applies to Mac+ (ROM75) only. A separate patch in ROMAllFix is ; used for ROM76-78). This is due to the addition of vectors for MapFBlock ; and XFSearch in ROM76. ; ; Patched using the "jLg2Phys" vector. NOTE, this patch replaces the ; "jLg2Phys" vector without saving the previous contents of that vector! ; ; The corresponding source code modification for this patch were made to ; FXM.a in the "MapFBlock" routine. The required modification was simply ; changing "ADD.W D0,D3" to "ADD.L D0,D3" when calculating the physical ; start block address. ;____________________________________________________________________________________ MapFBPatch: PROC EXPORT toMFSMap EQU $4055F0 ; ROM75 continuation address in Lg2Phys ; for MFS file mapping toXFSearch EQU $405F04 ; ROM75 entry point for XFSearch toMapFBExit EQU $405D8A ; ROM75 address for MFExit in MapFBlock contMapFBlk EQU $405D78 ; ROM75 continuation address in MapFBlock ; (next instruction following buggy ADD.W) MOVEA.L FCBVPtr(A1,D1.W),A2 CMPI.W #Tsigword,VCBSigWord(A2) ; is sigword that of TFS? <19Mar87> BEQ.S DoMapFBlock ; br for TFS file block mapping. <19Mar87> JMP toMFSMap ; Otherwise, do the MFS file mapping <19Mar87> DoMapFBlock MOVE.L (SP)+,-(A6) ; save return address on A6 stack MOVEM.L D1-D2/D4-D5/D7/A0-A1/A3-A4,-(A6) ; save registers SUB #lenFXVars,A6 ; allocate memory for FXM vars <19Mar87> MOVEA.L A6,A4 ; A4 = pointer to FXM vars <19Mar87> CLR.B FXVFlags(A4) ; clear all flags <19Mar87> LEA 0(A1,D1.W),A3 ; A3 = FCB pointer ; ; locate the extent mapping the desired file position ; MOVE.L D5,D0 ; file position JSR toXFSearch ; call XFSearch <19Mar87> BEQ.S @0 ; ok if zero -> <19Mar87> JMP toMapFBExit ; exit on errors <19Mar87> @0 LEA 0(A1,D1.W),A1 ; A1 = ptr to extent entry MOVE.W D3,D1 ; D1 = beg FABN for extent SUB.W xdrNumABlks(A1),D1 ; MOVE.W D3,D2 ; D2 = end FABN in extent + 1 ; ; determine end of available space (PEOF or end of extent) ; MULU VCBAlBlkSiz+2(A2),D2 ; convert end FABN + 1 to file pos MOVE.L FCBPLen(A3),D0 ; get PEOF CMP.L D0,D2 ; end of extent > PEOF? BLE.S @1 ; no, use end of extent -> MOVE.L D0,D2 ; yes, use PEOF @1 DIVU VCBAlBlkSiz+2(A2),D2 ; D2 = end of avail space ( end FABN + 1) ; ; set up some constants ; MOVE.L VCBAlBlkSiz(A2),D6 ; D6 = # blks per alloc blk DIVU #512,D6 ; MOVEQ #0,D7 ; D7 = start blk # for alloc blks MOVE.W VCBAlBlSt(A2),D7 ; ; ; calculate physical start block ; MOVE.L D5,D3 ; file position / alloc blk size DIVU VCBAlBlkSiz+2(A2),D3 ; = FABN mapping file position SWAP D3 ; Get remainder in low word MOVEQ #0,D0 ; Clear top word to get remainder as long MOVE.W D3,D0 ; Compute block offset within alloc block LSR.L #8,D0 ; 'divide' by 256 LSR.L #1,D0 ; and again by 2 to get size in phys. blocks SWAP D3 ; Restore D3 for use SUB.W D1,D3 ; - beg FABN = alloc blk delta ADD.W xdrStABN(A1),D3 ; + starting ABN = ABN mapping file pos MULU D6,D3 ; convert to physical block # ADD.L D0,D3 ; Offset in physical blocks within alloc. blk <19Mar87> JMP contMapFBlk ; continue with MapFBlock in ROM <19Mar87> ENDPROC ; end MapFBlock patch ;____________________________________________________________________________________ ;----------------------------------------------------------------------------- ; PABM150 28Mar87 JTC&JAF New SysEnvirons call. INCLUDE 'SysEnvirons.a' ; ;____________________________________________________________________________________ ; PM243 Unmount patch: ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 24Aug87 Pm243 (Unmount) (Unmount) ; ; This patch prevents a volume from being unmounted if there are any open files ; on the requested volume. Side effects from letting this happen was typically ; a trashed catalog or extent file due to re-assignment of an FCB (refnum). ; In the MultiFinder environment, one application could unmount a volume out ; from underneath another. ; ; Patched using the "UnmountVol" trap. ; ; PMAB271 14Sep87 BB/JB Modified unmount patch PM243 to unconditionally unmount a ; volume if the HFS bit is set in the ioTrap word. ;____________________________________________________________________________________ UnmountPatch: proc RomFSQSync equ $4028a6 ; Mac Plus FSQueueSync toUnmount equ $403606 ; Mac Plus return from DtrmV3 in UnmountVol RomDtrmV3 equ $403642 ; Mac Plus DtrmV3 address jsr RomFSQSync ; Get in sync... clr.b FlushOnly ; Setup same as UnmountVol jsr RomDtrmV3 ; Call DtrmV3 to do setup stuff bne.s UnmountExit ; error from DTrmV3... ; ; On return from DtrmV3, A2 contains the VCB ptr of the volume ; in question. Search the FCB array for open files that reference ; the volume... ; moveq #0,d0 ; Initialize result code btst #HFSBit,ioTrap(a0) ; Unconditional unmount? <14Sep87> bne.s @6 ; Xfer if so... <14Sep87> movem.l a1/d1/d2,-(sp) move.l FCBsPtr,a1 ; FCB array base address moveq #2,d1 ; Index of 1st FCB @2 move.l fcbFlNm(a1,d1),d2 ; Is the file currently open? beq.s @4 ; Nope, try next FCB... cmp.l fcbVPtr(a1,d1),a2 ; Is the file on the vol in question? bne.s @4 ; No, try next FCB... cmp.w #Tsigword,vcbSigWord(a2) ; is sigword that of TFS? bne.s @3 ; Yes, assert UnmountVol error cmp.l #FSUsrCNID,d2 ; is it an internal file? blo.s @4 ; if so, try next FCB... cmp.l #$47525420,d2 ; is it a fake AppleShare FCB? beq.s @4 ; yes, skip it... @3 moveq #fBsyErr,d0 ; assert UnmountVol error bra.s @5 ; Get out... @4 add.w FSFCBLen,d1 ; Next FCB array entry cmp.w (a1),d1 ; Reached the end yet? blo.s @2 ; Continue search... @5 movem.l (sp)+,a1/d1/d2 @6 ; <14Sep87> tst.w d0 ; Were files open? UnmountExit: jmp toUnmount endproc ; end of UnmountPatch ;____________________________________________________________________________________ ; PMAB241 BadTrap Handler patch ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 26Aug87 PMAB241 (BadTrap) (BadTrap) ; ; This patch is to salvage D0 reg for MacsBug on Debugger traps which use the ROM BadTrap routine. ; Fix is to save regs prior to using D0 reg for error code. ;____________________________________________________________________________________ NewBadTrap PROC EXPORT ROMSysErr3 EQU $40114A ; ROM entry point in SysErr after save of regs MOVEM.L D0-D7/A0-A7,SEVars ; save all regs for debugger MOVEQ #12,D0 ; signal bad trap error JMP ROMSyserr3 ; and go to ROM, don't resave regs ENDPROC ;____________________________________________________________________________________ ; PMAB241 font manager patch ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 08oct87 PM294 (CloseResFile) (fontmanager) ; ; Since the new font manager is now backpatched on the macplus we now need to invalidate ; the new font manager if a CloseResFile occurs. ;____________________________________________________________________________________ ROMCloseResFile EQU $413BD2 ; ROM entry point for CloseResFile PM294 ; PM294 CloseResFile PROC EXPORT ; PM294 MOVE.L MinusOne,LastSPExtra ; invalidate font cache for font manager PM294 jmp ROMCloseResFile ; and go to real font manager PM294 ENDPROC ; PM294 ;____________________________________________________________________________________ ; PP332 Cache control trap ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch BeforePatches.a 14Dec87 n/a ; ; This patch adds a new trap to programatically control parameters of the RAMCache. ; ; ; Function: These traps provide an interface to the file system ; caching mechanism. ; ; Cache Trap ; Routines: ; GetCSize Get cache size ; SetCSize Set cache size ; GetApZnSiz Get minimum application zone size ; SetApZnSiz Set minimum application zone size ; GetMaxCXfr Get maximum cached transfer size ; SetMaxCXfr Set maximum cached transfer size ; GetCStatus Get cache status ; SetCStatus Get cache status ; ; Internal ; Routines: ; GetCacSize Get current size of cache ; ; To do: ; Need to completely redefine way cache uses memory. Should be ; a trap here to feed memory to the cache (called by MultiFinder ; or memory manager), also a way to ask for those blocks back ; if they are needed. ; Need some reasonableness checks for parameters. ; ; Modification History: ; ; <20Nov87> JB New today. ; <25Nov87> JB Added get/set cache status ; <02Dec87> JB Changed for ioParamblock interface ; <20Feb89> JB/DNF Moved from BeforePatches.a ;_____________________________________________________________________________ ;_____________________________________________________________________________ ; Cache trap dispatcher ; ; Supplied: ; D0.W Service selector index ; A0.L New cache parameter value if call is a 'set' call ; ; Returned: ; D0.L Result code ; 'ParamErr' is returned if either the selector ; is invalid or if the value supplied on a 'set' ; call is unreasonable ; A0.L Requested cache parameter value if the ; call was a 'get' call ;_____________________________________________________________________________ CachePatch PROC EXPORT ROMFSQSync equ $4028a6 ; Mac Plus FSQueueSync address ROMCmdDone equ $40295e ; Mac Plus CmdDone address ioMisc equ $1C ; old ioMisc mnemonic--need appropriate new name ;_____________________________________________________________________________ ; Cache trap dispatch table: ;_____________________________________________________________________________ CTrapTbl dc.w GetCSize-CTrapTbl ; 0 - get cache size dc.w SetCSize-CTrapTbl ; 1 - set cache size dc.w GetApZnSiz-CTrapTbl ; 2 - get min application zone size dc.w SetApZnSiz-CTrapTbl ; 3 - set min application zone size dc.w GetMaxCXfr-CTrapTbl ; 4 - get max cached transfer size dc.w SetMaxCXfr-CTrapTbl ; 5 - set max cached transfer size dc.w GetCStatus-CTrapTbl ; 6 - get cache status dc.w SetCStatus-CTrapTbl ; 7 - set cache status maxCacheTrap equ (*-CTrapTbl)/2 ; Number of traps defined EXPORT CacheTrap CacheTrap cmp.w #maxCacheTrap,d0 ; Valid trap index? blo.s @1 ; Xfer if so... moveq #ParamErr,d0 ; Else, indicate parameter error rts @1 lea CTrapTbl,a1 ; Base of dispatch table add.w d0,d0 ; Trap index into WORD index add.w (a1,d0),a1 ; Routine to invoke jmp (a1) ; Go to requested routine... CTExit jmp ROMCmdDone ; Exit via the file system... ;_____________________________________________________________________________ ; 0 -- Get cache size ;_____________________________________________________________________________ GetCSize jsr ROMFSQSync ; Synchronize with the file manager move.l CacheVars,a1 ; Cache vars address move.l OldBufPtr(a1),d0 ; Pre-cache BufPtr sub.l NewBufPtr(a1),d0 ; Size of cache = (Pre-cache BufPtr)-current move.l d0,ioMisc(a0) ; Return in param block moveq #0,d0 ; Result = SUCCESS bra.s CTExit ;_____________________________________________________________________________ ; 1 -- Set cache size ;_____________________________________________________________________________ SetCSize jsr ROMFSQSync ; Synchronize with the file manager move.l ioMisc(a0),d0 ; Get desired cache size moveq #15,d1 ; Divide by 32K lsr.l d1,d0 ; ... move.b d0,CacheConfig ; Set mem config for next launch moveq #0,d0 ; Result = SUCCESS bra.s CTExit ;_____________________________________________________________________________ ; 2 -- Get minimum application zone size ;_____________________________________________________________________________ GetApZnSiz jsr ROMFSQSync ; Synchronize with the file manager move.l CacheVars,a1 ; Cache vars address move.l CacheMinZn(a1),ioMisc(a0) moveq #0,d0 ; Result = SUCCESS bra.s CTExit ;_____________________________________________________________________________ ; 3 -- Set minimum application zone size ; ; This value is examined whenever the cache is grown. Cache size will ; not be allowed to exceed this amount. The default value is enough ; space to load and run an application. The value may be set to a ; smaller value to enable use of memory for cacheing when it is known ; that other applications will not be present (MultiFinder). ;_____________________________________________________________________________ SetApZnSiz jsr ROMFSQSync ; Synchronize with the file manager move.l CacheVars,a1 ; Cache vars address move.l ioMisc(a0),CacheMinZn(a1) ; Set new ApplZone size minimum moveq #0,d0 ; Result = SUCCESS bra.s CTExit ;_____________________________________________________________________________ ; 4 -- Get maximum cached transfer size ;_____________________________________________________________________________ GetMaxCXfr jsr ROMFSQSync ; Synchronize with the file manager move.l CacheVars,a1 ; Cache vars address move.l CacheByteLim(a1),ioMisc(a0) moveq #0,d0 ; Result = SUCCESS bra.s CTExit ;_____________________________________________________________________________ ; 5 -- Set maximum cached transfer size ; ; This value is examined on each "read/write in place" call. These cache ; calls are used by file system to transfer integral blocks from the ; caller's buffer to/from the disk (possibly) without caching. Setting ; this value to a smaller value will tend to keep reading/writing large ; files from effectively causing a flush of the cache. This might ; make an environment where multiple files are typically open behave ; better (i.e., one application won't tend to cause the cache to be ; flushed). ;_____________________________________________________________________________ SetMaxCXfr jsr ROMFSQSync ; Synchronize with the file manager move.l CacheVars,a1 ; Cache vars address move.l OldBufPtr(a1),d0 ; Pre-cache BufPtr sub.l NewBufPtr(a1),d0 ; Size of cache = (Pre-cache BufPtr)-current move.l ioMisc(a0),d1 ; Get caller's parameter cmp.l d1,d0 ; Cache size >= requested max xfer size? bhs.s @1 ; Xfer if so... moveq #ParamErr,d0 ; Else, indicate parameter error bra CTExit @1 move.l d1,CacheByteLim(a1) ; Set new max transfer size moveq #0,d0 ; Result = SUCCESS bra CTExit ;_____________________________________________________________________________ ; 6 -- Get cache status ;_____________________________________________________________________________ GetCStatus jsr ROMFSQSync ; Synchronize with the file manager move.l CacheVars,a1 ; Cache vars address moveq #0,d0 ; Assume cache disabled tst.b CurEnable(a1) ; Cache currently enabled? beq.s @1 ; Xfer if currently disabled (error?) btst #5,CacheEnable ; test enable bit beq.s @1 ; Xfer if disabled moveq #1,d0 ; Else, indicate "enabled" @1 move.l d0,ioMisc(a0) ; Set returned cache status to caller moveq #0,d0 ; Result = SUCCESS bra CTExit ;_____________________________________________________________________________ ; 7 -- Set cache status ;_____________________________________________________________________________ SetCStatus jsr ROMFSQSync ; Synchronize with the file manager tst.l ioMisc(a0) ; Enable or disable? beq.s @1 ; Xfer if disable... bset #5,CacheEnable ; Else, ask for enable on next launch bra.s @2 @1 bclr #5,CacheEnable ; Ask for disable on next launch @2 moveq #0,d0 ; Result = SUCCESS bra CTExit ;_____________________________________________________________________________ ;********************** End of Cache control trap **************************** ;_____________________________________________________________________________ ENDPROC ;____________________________________________________________________________________ ;_______________________________________; ;_______________________________________; ;_______________________________________; ;_______________________________________; ;_______________________________________; ;_______________________________________; ;_______________________________________; ;_______________________________________; ;_______________________________________; ;_______________________________________; ; ; BEWARE, YE WHO CROSS THIS LINE! ;_______________________________________; ;_______________________________________; ;_______________________________________; ;_______________________________________; ;_______________________________________; ;_______________________________________; ;_______________________________________; ;_______________________________________; ;_______________________________________; ;_______________________________________; OldMacEnd PROC EXPORT ; PATCHES AFTER THIS POINT ARE ONLY INSTALLED IF MACPLUS HARDWARE ; IS PRESENT! ;------------------------------------------------------------- ; (Patch #37) ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 25Nov86 #37 (DataXfer) (SCSIDispatch) ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 02Dec86 #37 (DataXfer) (SCSIDispatch) ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 02Mar87 #PM075 (DataXfer) (SCSIDispatch) ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 24Mar87 #PM116 (DataXfer) (SCSIDispatch) ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 30Apr87 #PM135 (MapFBlock) (SCSIDispatch) ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 20Jul87 #PMA211 (SCSIRead,SCSIWrite,SCSIRBlind,SCSIWBlind) (SCSIRead,SCSIWrite,SCSIRBlind,SCSIWBlind) ;AppleSystemPatch PatchPlusROM.a 19Oct87 #PMAB295 (SCSISelect) (SCSIDispatch) ; ; Here is a large patch to the SCSI manager. The functions fixed: <11AprELR&SAB> ; ; 1) Multi-block DMA transfers now work for blind operations in BOTH ; read and write modes... ; ; 2) SCSI Stat function now returns meaningful data. ; ; 25Nov86 SHF Another fix (and tightened up a fair amount of code): ; Fixed premature turning off of pseudo-DMA mode for writes. ; 02Dec86 SHF Added check for phase change in polled data transfers. ; PM075 02Mar87 SHF Fixed more problems, added SelAtn, MsgIn, MsgOut. ; PM116 19Mar87 SHF Made change to DataXfer for SuperMac, parity checking. ; PM135 24Mar87 SHF Removed parity checking for now. (Not all devices ; generate it.) ; PM180 30Apr87 SHF Fixed scCompare opcode bug in SCSI Manager patch. ; PMA211 20Jul87 SHF Fixed scLoop bug in SCSI Manager code. ; PMAB295 19Oct87 SHF Now gets the Select timeout value from a variable (was hard-coded). ; PMAB466 13Apr88 JWK Uses "bset" to arbitrate cleanly for the SCSI bus. ; SCSIPatch PROC EXPORT EXPORT SCSelectTime ; ROMSCSI EQU $417132 SCRESETDRV EQU $4174E6 ; jsr addr for Reset SCSI bus routine SCRESETEXIT EQU $417184 ; re-entry point into the ROM NOBYTEEX EQU $417184 SCARBDONE EQU $417192 ; SCSELDONE EQU $4171A4 ; SCSENDCMD EQU $41734C ; jsr addr for "SendCMD" ROM routine SCCOMMAND EQU $4171BE ; re-entry point into the ROM ROMDEND EQU $417242 SCGETSTAT EQU $417464 ; jsr addr for "GetStat" ROM routine SCGETMSG EQU $41749A ; jsr addr for "GetMsg" ROM routine SCCYCLEPHASE EQU $417566 ; jsr addr for "CyclePhase" ROM routine SCCOMPLETE EQU $41728C ; re-entry point into the ROM SCSTDENT EQU $417294 ; SCWFBSY EQU $417510 ; SCWFNREQ EQU $41753A ; SCWFREQ EQU $417550 ; zeroReg EQU d7 ; SCSI Mgr convention <25Nov86/SHF> maxSelector EQU 13 ; scParityErr EQU 11 ; bPERR EQU 5 ; move.l (sp)+,a0 ; get the retaddr move.w (sp)+,d0 ; function selector move.l a0,-(sp) ; push the return address jsr SCSTDENT ; return via jmp (a0) cmp.w #maxSelector,d0 ; range check bhi.s DoSCSIUnimp ; adios lsl.w #1,d0 ; calculate word offsets move.w JmpTbl(pc,d0.w),d0 ; get offset to routine jmp JmpTbl(pc,d0.w) ; go there (bits 8-15 = 0 from selector) DoSCSIUnimp move.w #dsCoreErr,d0 ; unimplemented core routine error _SysError ; bombs away... <25Nov86/SHF> ;======================================================================================= <53> djw ; WARNING...WARNING...WARNING...WARNING...WARNING...WARNING... ; If this code changes, and the offset of G_State from the beginning of the patch ; moves from $23 bytes, then the linked patch SCSIBusy for the MacPlus will be ; broken. The linked patch's @G_State equate must be adjusted if G_State in this ; code moves. ;======================================================================================= SCSIId DC.B scMacID ; CPU SCSI ID mask (G_ID) DC.B 0 ; SCSI Mgr state (G_State) Sel250msCnt EQU 43950 ; 250 msec select timeout SCSelectTime ; DC.W Sel250msCnt ; JmpTbl ; extended table to word offsets for sanity DC.w DoSCSIReset-JmpTbl ; 0: SCSIReset DC.w DoSCSIGet-JmpTbl ; 1: SCSIGet DC.w DoSCSISelect-JmpTbl ; 2: SCSISelect DC.w DoSCSICmd-JmpTbl ; 3: SCSICmd DC.w DoSCSIComplete-JmpTbl ; 4: SCSIComplete DC.w DoSCSIRead-JmpTbl ; 5: SCSIRead DC.w DoSCSIWrite-JmpTbl ; 6: SCSIWrite DC.w DoSCSIInstall-JmpTbl ; 7: SCSIInstall (unused) DC.w DoSCSIRBlind-JmpTbl ; 8: SCSIRBlind DC.w QuantumWBlindPlus-JmpTbl; 9: SCSIWBlind - quantum 7.9 rom fix <53> djw DC.w DoSCSIStat-JmpTbl ; 10: SCSIStat DC.w DoSCSISelAtn-JmpTbl ; 11: SCSISelAtn DC.w DoSCSIMsgIn-JmpTbl ; 12: SCSIMsgIn DC.w DoSCSIMsgOut-JmpTbl ; 13: SCSIMsgOut ;-------------------------------------------------------------------------- ; ; FUNCTION SCSIReset: INTEGER; ; (8) ; ; Resets the SCSI bus and then delays for a while. ; DoSCSIReset jsr SCRESETDRV ; use the ROM to reset the SCSI bus lea.l SCSIId,a0 ; point at SCSI ID variable move.b zeroReg,1(a0) ; clear the SCSI Mgr state variable jmp SCRESETEXIT ; exit through the ROM ;-------------------------------------------------------------------------- ; ; FUNCTION SCSICmd(Buffer: Ptr, Count: INTEGER): INTEGER; ; (10) (8) (14) ; ; Send the target the given command. Returns 0 for success, or error. ; DoSCSICmd move.l 10(a6),a2 ; get command buffer address move.w 8(a6),d2 ; get the length jsr SCSENDCMD ; jump directly the ROM "SendCMD" routine beq.s @okExit ; success, let's get out lea.l SCSIId,a0 ; point at SCSI Mgr ID variable move.b zeroReg,1(a0) ; clear the SCSI Mgr global state flag @okExit jmp SCCOMMAND ; exit through the ROM routine ;-------------------------------------------------------------------------- ; ; FUNCTION SCSIGet: INTEGER; ; (8) ; ; Arbitrate for the SCSI bus. Returns 0 for success, or error. ; DoSCSIGet ; lea.l SCSIId,a0 ; point to SCSI Mgr ID variable bset.b #0,1(a0) ; check if Mgr is busy (G_State)(sBusy = 1) beq.s @wasFree ; if zero, SCSI Mgr is free moveq.l #scMgrBusyErr,d0 ; we're busy now bra.s @back2ROM ; let's get out @wasFree bsr.w Arbitrate ; arbitrate for the bus beq.s @back2ROM ; we were successful, so we're done lea.l SCSIId,a0 ; point at SCSI Mgr ID variable move.b #0,1(a0) ; clear the SCSI Mgr state (G_State) @back2ROM jmp SCARBDONE ; return d0 and clean up ;-------------------------------------------------------------------------- ; ; FUNCTION SCSIStat: INTEGER; ; (8) ; ; Get the SCSI bus status from the 5380 registers. Fixed a bug with ; storing values off sp rather than a6. ; DoSCSIStat move.b sBSR(a3),8(a6) ; high byte move.b sCSR(a3),9(a6) ; low byte ; Falls through to jmp NOBYTEEX ;-------------------------------------------------------------------------- ; ; FUNCTION SCSIInstall -- Obsolete, no value returned ; DoSCSIInstall jmp NOBYTEEX ; return to ROM ;-------------------------------------------------------------------------- ; ; FUNCTION SCSIComplete(VAR Stat, Msg: INTEGER; wait: LongInt): INTEGER; ; (16) (12) (8) (20) ; ; Complete the SCSI command. Returns 0 for success, or error. ; DoSCSIComplete move.l Ticks,d6 ; get current time add.l 8(a6),d6 ; add count to start ticks @chkStatus moveq.l #0,d2 ; jsr SCGETSTAT ; use ROM routine to get status byte beq.s @gotStatus ; success cmp.b #scPhaseErr,d0 ; phase error ? bne.s @chkTime ; no, business as usual jsr SCCYCLEPHASE ; only called for phase errors @chkTime cmp.l Ticks,d6 ; got the time, pal ? bhi.s @chkStatus ; still time bra.s @completeDone ; report the error @gotStatus move.l 16(a6),a1 ; get the status byte pointer move.w d2,(a1) ; save the status byte jsr SCGETMSG ; go get the message byte bne.s @completeDone ; communication error move.l 12(a6),a1 ; get the message byte pointer move.w d2,(a1) ; save the message byte @completeDone lea.l SCSIId,a0 ; point to SCSI Mgr ID variable move.b zeroReg,1(a0) ; clear the SCSI Mgr global state variable jmp SCCOMPLETE ; exit through ROM routine ;-------------------------------------------------------------------------- ; ; FUNCTION SCSISelect(TargID: INTEGER): INTEGER; ; FUNCTION SCSISelAtn(TargID: INTEGER): INTEGER; ; (8) (10) ; ; Select the target on the bus. Returns 0 for success, or error. ; Selection can be done with (SCSISelAtn) or without (SCSISelect) the ; ATN line. ; DoSCSISelAtn ; moveq.l #iATN,d3 ; prepare for SelAtn swap d3 ; put iATN bit in upper word bra.s DoSelContinue ; DoSCSISelect ; moveq.l #0,d3 ; clear upper word (no ATN) DoSelContinue lea SCSIid,a0 ; address of soft SCSI ID mask move.b (a0),d2 ; get the ID mask move.w 8(a6),d3 ; get target ID moveq.l #1,d0 ; build the select mask lsl.b d3,d0 ; shift to the appropriate position lea sICR(a4),a0 ; avoid later indexing move.b #iSEL,(a0) ; set select line bsr.s BusDelay ; a little bus delay move.b zeroReg,sTCR(a4) ; de-assert *I/O to become an initiator or.b d2,d0 ; merge CPU ID and target ID masks move.b d0,sODR(a4) ; put ID mask value on the bus swap d3 ; get back flag for ATN (if set) or.b #iBSY+iSEL+iDB,d3 ; busy, select, assert data bus move.b d3,(a0) ; assert the signals move.b zeroReg,sMR(a4) ; clear arbitration move.b zeroReg,sSER(a4) ; clear select int. enable register bclr #3,d3 ; reset *BSY move.b d3,(a0) bsr.s BusDelay ; a little bus delay move.w SCSelectTime,d1 ; 250 msec select timeout jsr SCWFBSY ; wait for target to respond beq.s @SelOK ; found a target (d0 cleared) move.b zeroReg,(a0) ; release the lines lea.l SCSIId,a0 ; point at SCSI Mgr global ID variable move.b zeroReg,1(a0) ; clear SCSI Mgr global state variable bra.s @SelDone ; and exit @SelOK bsr.s BusDelay ; a little bus delay and.b #$0A,d3 ; reset *SEL and *DB bits move.b d3,(a0) @SelDone jmp SCSELDONE ; finish up in ROM (errcode in d0) ;-------------------------------------------------------------------------- ; ; FUNCTION SCSIMsgIn(VAR Message: INTEGER): INTEGER; ; (8) (12) ; ; Receive a message byte from the target. Returns 0 for success, or error. ; DoSCSIMsgIn ; bra.w GetMsg ; Have to work around the bra.s table ;-------------------------------------------------------------------------- ; ; FUNCTION SCSIMsgOut(Message: INTEGER): INTEGER; ; (8) (10) ; ; Receive a message byte from the target. Returns 0 for success, or error. ; DoSCSIMsgOut ; bra.w SendMsg ; Have to work around the bra.s table ;-------------------------------------------------------------------------- ; ; FUNCTION SCSIRead(Control:Ptr): INTEGER; (polled read and write) ; FUNCTION SCSIWrite(Control:Ptr): INTEGER; ; FUNCTION SCSIRBlind(Control:Ptr): INTEGER; (blind read and write) ; FUNCTION SCSIWBlind(Control:Ptr): INTEGER; ; (8) (12) ; ; This is the heart of the SCSI data transfer code, which includes the ; Transfer Information Block (TIB) interpreter. ; DoSCSIWBlind bset #15,d4 ; set blind mode flag <25Nov86/SHF> DoSCSIWrite st d4 ; set flag for writes <25Nov86/SHF> bra.s DataCommon ; <25Nov86/SHF> DoSCSIRBlind bset #15,d4 ; set blind mode flag <25Nov86/SHF> DoSCSIRead ; only start for reads <25Nov86/SHF> move.b #iIO,sTCR(a4) ; match Data In phase <25Nov86/SHF> move.b #iDMA,sMR(a4) ; DMA mode move.b zeroReg,sIDMArx(a4) ; start DMA for a read <25Nov86/SHF> ; ; Continuation of Read and Write routines ; DataCommon moveq.l #bDMAR,d3 ; bit for DREQ test used in DataXFER <29Oct85> move.l 8(a6),a1 ; get the control block pointer bra.s exec ; branch into loop to continue BusDelay ; put here for bsr.s proximity moveq.l #StlDelay,d1 ; loop this many times @1 dbra d1,@1 rts c_compare move.b #1,d4 ; this means compare to DataXFER <29Oct85> ; FALL THROUGH to c_inc c_inc ; INC Addr,count bsr.s DataXFER ; move some data <23Apr86 LAK> bne.s data_end add.l d2,scParam1(a1) ; increment the pointer ; FALL THROUGH to next_cmd next_cmd c_nop ; also NOP, just skip the command add.w #SCSIZE,a1 ; move the command pointer exec move.w scOpcode(a1),d0 ; get the function opcode move.l scParam1(a1),a2 ; get the generic address move.l scParam2(a1),d2 ; get the generic count subq.w #5,d0 ; reworked beq.s c_loop ; 5 addq.w #4,d0 beq.s c_inc ; 1 subq.w #1,d0 beq.s c_noinc ; 2 subq.w #5,d0 beq.s c_stop ; 7 addq.w #4,d0 beq.s c_add ; 3 subq.w #1,d0 beq.s c_move ; 4 subq.w #2,d0 beq.s c_nop ; 6 subq.w #2,d0 ; beq.s c_compare ; 8 moveq.l #scBadParmsErr,d0 ; garbage parameters... bra.s data_end c_noinc ; NOINC addr,count bsr.s DataXFER ; move some data <23Apr86 LAK> beq.s next_cmd ; & process next command bra.s data_end c_add ; ADD addr,data add.l d2,(a2) ; the count added to the where bra.s next_cmd c_move ; MOVE addr1,addr2 move.l d2,a0 move.l (a2),(a0) ; simple enough bra.s next_cmd c_loop ; LOOP relative addr,count subq.l #1,d2 ; drop the count beq.s next_cmd ; if count = 0, do next command move.l d2,scParam2(a1) ; put the count back for next time add.l a2,a1 ; modify the command pointer bra.s exec ; and process the next command c_stop moveq.l #0,d0 ; indicate no error data_end move.b zeroReg,sMR(a4) ; clear DMA mode move.b zeroReg,sICR(a4) ; disable data bus jmp ROMDend ;-------------------------------------------------------------------------- ; ; Move some data. d2 bytes into/from a2->. ; d4 contains modifying information: ; bit 15 is the blind bit. ; d4.b = minus = write ; = zero = read ; = plus = compare ; ; d2 contains the byte count on entry. ; DataXFER move.l a1,-(sp) ; save this register <25Nov86/SHF> moveq.l #0,d0 ; clear error register <29Oct85> move.l d2,d6 ; local copy of count <25Nov86/SHF> beq.w Xfer_done ; if it was zero <25Nov86/SHF> subq.l #1,d6 ; adjust count for dbra move.l d6,d5 ; make a copy of the byte count swap d5 ; and get hiword in d5 lea sBSR(a3),a0 ; for quick DRQ polling move.w #DAckRd,a1 ; DMA offset tst.b d4 ; read or write? bpl.s RdSetup ; add.l a4,a1 ; write offset for 5380 wreq btst.b #bREQ,sCSR(a3) ; test for *REQ beq.s wreq move.b zeroReg,sTCR(a4) ; match Data Out phase move.b #iDMA,sMR(a4) ; set DMA mode move.b #iDB,sICR(a4) ; assert data bus move.b zeroReg,sDMAtx(a4) ; start DMA write bra.s ckphase RdSetup add.l a3,a1 ; read offset for 5380 RdCmp btst.b d3,(a0) ; wait for DMA Request <25Nov86/SHF> bne.s Continue ; if there, ready for bytes... btst.b #bREQ,sCSR(a3) ; test for *REQ in case of phase error beq.s RdCmp ; no req either, must be seeking ckphase btst.b #bPM,(a0) ; examine the phase <25Nov86/SHF> beq.s PhaseErr ; it changed... <25Nov86/SHF> Continue tst.w d4 ; if d4.w is <1, these are blinds... bmi.s BlkStart ; go to the blind code ; ; We get here when for polled transfer modes. ; tst.b d4 ; Singles, write/read? beq.s SnRd ; is a read bmi.s SnWr ; is a write. ; ; This is the loop for compares ; SnCmp btst.b d3,(a0) ; beq.s SnCmpChk ; no DRQ; in phase? <03Dec86/SHF> move.b (a1),d1 ; get data byte <29Oct85> cmp.b (a2)+,d1 ; same? <29Oct85> beq.s @0 moveq.l #scCompareErr,d0 ; record compare error <29Oct85> @0 dbra d6,SnCmp ; <25Nov86/SHF> dbra d5,SnCmp bra.w RdDone SnCmpChk ; <03Dec86/SHF> btst.b #bPM,(a0) ; phase still OK? bne.s SnCmp ; continue if it is <03Dec86/SHF> bra.s PhaseErr ; else return error <03Dec86/SHF> ; ; This is the loop for polled reads. Byte count is in d5,d6. ; SnRd btst.b d3,(a0) ; wait for DRQ beq.s SnRdChk ; <03Dec86/SHF> move.b (a1),(a2)+ ; read bytes into user space dbra d6,SnRd ; <25Nov86/SHF> dbra d5,SnRd bra.s RdDone SnRdChk btst.b #bPM,(a0) ; phase still OK? bne.s SnRd ; continue if it is <03Dec86/SHF> bra.s PhaseErr ; else return error <03Dec86/SHF> ; ; This is the loop for polled writes. Byte count is in d5,d6. ; SnWr btst.b d3,(a0) ; wait for DRQ <25Nov86/SHF> beq.s SnWrChk move.b (a2)+,(a1) ; write bytes dbra d6,SnWr ; <25Nov86/SHF> dbra d5,SnWr bra.s WrDone SnWrChk ; <03Dec86/SHF> btst.b #bPM,(a0) ; phase still OK? bne.s SnWr ; continue if it is <03Dec86/SHF> PhaseErr ; <25Nov86/SHF> moveq.l #scPhaseErr,d0 ; <25Nov86/SHF> bra.s xfer_done ; <25Nov86/SHF> ; ; We get here for blind mode operations... ; BlkStart btst d3,(a0) ; wait for DRQ to start beq.s BlkStart tst.b d4 ; then test Direction beq.s @0 ; is a read <29Oct85> bmi.s @1 ; write... <29Oct85> ; ; blind compare <29Oct85> ; @2 move.b (a1),d1 ; cmp.b (a2)+,d1 beq.s @3 moveq #scCompareErr,d0 @3 dbra d6,@2 ; <25Nov86/SHF> dbra d5,@2 bra.s RdDone ; ; blind read ; @0 move.b (a1),(a2)+ ; move the byte dbra d6,@0 ; <25Nov86/SHF> dbra d5,@0 bra.s RdDone ; get here for read done ; ; blind write ; @1 move.b (a2)+,(a1) ; move the byte out dbra d6,@1 ; <25Nov86/SHF> dbra d5,@1 WrDone ; fixed to avoid premature turning off of DMA mode <25Nov86/SHF> btst.b d3,(a0) ; did we get DRQ? bne.s DMAOff ; yes, so turn off DMA <25Nov86/SHF> btst.b #bPM,(a0) ; examine the bus phase bne.s WrDone ; in phase, wait around <25Nov86/SHF> DMAOff move.b zeroReg,sMR(a4) ; clear DMA mode move.b zeroReg,sICR(a4) ; disable data bus RdDone Xfer_done tst.w d0 ; set the error codes movem.l (sp)+,a1 ; restore it <25Nov86/SHF> rts Arbitrate ; Moved out of range of one byte jump table lea SCSIid,a0 ; pointer to SCSI ID move.b (a0),sODR(a4) ; put my ID on bus @ArbRetry move.b zeroReg,sMR(a4) ; clear arbitration bit moveq.l #-1,d1 ; dbra count = 65535 move.b #iARB,sMR(a4) ; start arbitration @0 btst.b #bAIP,sICR(a3) ; are we in arbitration? dbne d1,@0 ; if not, keep trying bne.s @ArbStarted ; arbitration started move.b zeroReg,sMR(a4) ; clear arbitration bit moveq.l #scArbNBErr,d0 ; error code bra.s @ArbDone @ArbStarted moveq.l #StlDelay,d0 ; delay count @1 dbra d0,@1 ; let the bus relax btst.b #bLA,sICR(a3) ; did we lose arbitration? bne.s @ArbRetry ; if at first you don't succeed... moveq.l #0,d0 ; get ready for ID check moveq.l #0,d2 move.b sCDR(a3),d0 ; check bus for higher priority device lea.l SCSIId,a0 ; point to CPU's SCSI ID move.b (a0),d2 ; get the CPU's SCSI ID eor.b d2,d0 ; mask my SCSI id cmp.w d0,d2 blo.s @ArbRetry ; branch if we lost arbitration btst.b #bLA,sICR(a3) ; look if we lost arbitration (again) bne.s @ArbRetry moveq.l #0,d0 @ArbDone rts ; go back and jump into the ROM GetMsg ; move.l 8(a6),a1 ; get the ptr to the message variable move.b #iMSG+iCD+iIO,sTCR(a4) ; set match for MSGIN phase move.l #HalfSec,d3 ; timing constant move.l d3,d1 ; set it up in d1 jsr SCWFREQ ; wait for *REQ bne.s @MsgInDone ; timed out btst.b #bPM,sBSR(a3) ; still in phase? bne.s @MsgInOK ; yes, so continue moveq.l #scPhaseErr,d0 ; phase error bra.s @MsgInDone @MsgInOK moveq.l #0,d2 ; clear upper bytes move.b sCDR(a3),d2 ; load the message byte move.b sICR(a3),d4 ; get current ICR or.b #iACK,d4 ; set *ACK move.b d4,sICR(a4) move.w d2,(a1) ; store the message in the variable move.l d3,d1 ; set up timing constant in d1 again jsr SCWFNREQ ; wait for *REQ to go away bne.s @MsgInDone ; timed out eor.b #iACK,d4 ; clear *ACK move.b d4,sICR(a4) @MsgInDone jmp ROMDend SendMsg ; move.w 8(a6),d2 ; get the message move.b #iMSG+iCD,sTCR(a4) ; set match for MSGOUT phase move.l #HalfSec,d3 ; timing constant move.l d3,d1 ; set it up in d1 jsr SCWFREQ ; wait for *REQ bne.s @MsgOutDone ; timed out btst.b #bPM,sBSR(a3) ; still in phase? bne.s @MsgOutOK ; yes, so continue moveq.l #scPhaseErr,d0 ; phase error bra.s @MsgOutDone @MsgOutOK move.b #iDB,sICR(a4) ; assert data bus, deassert *ATN if set move.b d2,sODR(a4) ; send message byte move.b #iACK+iDB,sICR(a4) ; set *ACK and *DB move.l d3,d1 ; set it up in d1 jsr SCWFNREQ ; wait for *REQ to go away bne.s @MsgOutDone ; timed out move.b zeroReg,sICR(a4) ; deassert *ACK and *DB @MsgOutDone jmp SCSELDONE ; finish up in ROM ;_________________________________________________________________________________________ <48+> djw ; Beginning code for Quantum 7.9 ROM fix ; ; Detailed description of the Quantum problem and solution: ; ; Quantum drives with the firmware version 7.9, has a problem with loosing the last byte ; of a block during a multi-block write. The problem occurs when the time between blocks ; written to the SCSI bus on the CPU side, is greater than 482 microseconds. This may ; occur in situations where there are a lot of interrupts. When conditions are right and ; the problem happens, the last byte of the previous block (in a multi-block transaction), ; is "eaten" by the drive. Any checksum or CRC calculated by the drive is correct, ; because the drive calculates it after the byte has been corrupted. This problem is ; especially frequent when email packages are installed on the Mac, since they generate ; a lot of interrupts which take a long time. This problem only occurs during fast ; writes in the SCSI manager (pseudo-dma mode). ; ; The way the SCSI manager currently works is it gets a TIB packet which contains the ; instructions on how to talk to a particular device. Included in the TIB is when to ; re-synchronize with the drive by waiting for a *REQ. When we see *REQ, the SCSI ; manager then begins the next TIB data transfer instruction and loads a byte of data ; into the 53C80's output register. After the first byte is "manually" sent, the ; hardware handshaking automatically takes care of the *REQ and *ACK handshaking. When ; the TIB write transfer is complete, pseudo-dma is disable, which releases *ACK, ; completing the handshake. This allows the target to assert *REQ when it is ready. ; ; The window of vulnerability is between the last byte of the previous block and the ; first byte of the next block. More correctly, it is between the rising edge of *ACK ; and the falling edge of the next *ACK. Because we release *ACK to synchronize, an ; interrupt may come in and delay the next transfer. ; ; The solution to the problem is to pre-load a data byte into the 53C80's data output ; register before we release *ACK. There are two ways of releasing *ACK: disable pseudo ; dma, and write a byte to the data output register. Leaving pseudo-dma enabled through ; the entire TIB will mean that whenever a *REQ occurs, there will be data available in ; the output register. This means there will be no delay between bytes because the ; hardware is not subject to interrupt delays. ; ; This patch therefore involves patching the TIB interpreter and the fast write routine ; in the SCSI manager. There are five versions of the SCSI manager to patch: Mac Plus, ; SE, Mac II, Portable, and IIci. ; ;_________________________________________________________________________________________ ; QuantumWBlindPlus - patch to NewSCSIWBlind ; ; This code replaces the original SCSIWBlind entry point. The new entry for blind ; writes enables pseudo-dma on a per-transaction basis. Pseudo-dma was previously ; enabled only on a per-TIB-instruction basis. We completely patch out the existing ; ROM and system patch code for blind writes. This includes the TIB interpeter and ; the blind data transfer routine. ; ; Input: reg a3 = base of SCSI read addr ; a4 = base of SCSI write addr ; a6 = SCSI stack frame ; d7 = zero ; Opt noclr ; set optimization to no clr <53> djw QuantumWBlindPlus maxOpcode Equ 8 ; max TIB opCode (from SCSIPriv.a) <53> djw ; This is the entry to the TIB interpeter for blind writes. Enable pseudo-dma mode ; for the duration of the write transaction. move.b d7,sTCR(a4) ; set to match data out phase move.b #iDMA,sMR(a4) ; enable DMA in mode register move.b #iDB,sICR(a4) ; assert data bus in initiator command reg move.b d7,sDMAtx(a4) ; start write DMA ; Start of TIB interpreter @dataCommon move.l 8(a6),a1 ; get the TIB pointer bra.s @exec ; tighten loop by branching first @c_inc bsr.s FastWriteFix ; go to write blind routine bne.s @data_end ; if error, bail out add.l d1,scParam1(a1) ; increment the pointer ; FALL THROUGH to @next_cmd ; continue @next_cmd @c_nop ; also NOP, just skip the command add.w #scSize,a1 ; point to the next TIB instruction ; FALL THROUGH to @exec @exec move.w scOpcode(a1),d1 ; get the function opcode move.l scParam1(a1),a2 ; get the generic address move.l scParam2(a1),d2 ; get the generic count cmp.w #maxOpcode,d1 ; valid opcode ? bhi.s @c_badop ; return err if not add.w d1,d1 ; convert to table index jmp @JmpTable(pc,d1.w) ; jump to routine for opcode @JmpTable bra.s @c_badop ; 0 is not a valid opcode bra.s @c_inc ; 1 bra.s @c_noinc ; 2 bra.s @c_add ; 3 bra.s @c_move ; 4 bra.s @c_loop ; 5 bra.s @c_nop ; 6 bra.s @c_stop ; 7 nop ; 8 not valid ; fall through to @c_badop @c_badop moveq.l #scBadparmsErr,d0 ; bad opcode bra.s @data_end @c_noinc ; NOINC addr,count bsr.s FastWriteFix ; go to write blind routine bne.s @data_end ; if error, exit bra.s @next_cmd ; else process next command @c_add ; ADD addr,data add.l d2,(a2) ; the count added to the where bra.s @next_cmd ; process the next command @c_move ; MOVE addr1,addr2 move.l d2,a0 ; get the destination address move.l (a2),(a0) ; simple enough bra.s @next_cmd ; process the next command @c_loop ; LOOP relative addr,count tst.l d2 ; check for zero loop count beq.s @next_cmd ; if count is already zero, quit loop subq.l #1,d2 ; drop the count move.l d2,scParam2(a1) ; put the count back for next time beq.s @next_cmd ; if count exhausted, don't loop add.l a2,a1 ; modify the command pointer bra.s @exec ; and process the next command @c_stop moveq.l #noErr,d0 ; indicate no error ; FALL THROUGH to @data_end ; @data_end ; Disable DMA mode move.b d7,sMR(a4) ; clear the mode register move.b d7,sICR(a4) ; disable the data bus jmp (ROMDEnd) ; continue in ROM <53> djw ;_________________________________________________________________________________________ ; FastWriteFix - patch to FastWrite ; ; This code replaces the low level data transfer routine for fast writes in the SCSI ; manager. It is rewritten to assume psuedo-dma is always on, and to do the device ; synchronization (looking for *REQ and *DRQ), after loading a data byte into the ; output register of the 5380. We don't have to worry about zero-byte transfers. They ; are weeded out in the calling routine (Transfer). ; ; Entry: d2 = number of bytes to transfer ; a2 = ptr to data buffer to transfer ; a3 = base addr for SCSI reads ; a4 = base addr for SCSI writes ; ; Exit: d1 = number of bytes actually transfered. This value is only good if ; the transfer was good with no errors. It is inaccurate when an ; error aborts the transfer. FastWriteFix @savedregs Reg d2-d3/a0-a1 movem.l @savedregs,-(sp) lea.l sBSR(a3),a1 ; a1 = sBSR(a3) by convention movea.l #DAckRd,a0 ; point to addr for pseudo-dma (hhsk) adda.l a4,a0 ; use a0 moveq.l #noErr,d0 ; assume no error move.l d2,d1 ; make a copy of the count - is it zero ? beq.s @Done ; no bytes to xfer - done ; Pre-load the NCR 53C80's output register with a byte of data. If we are in ; the middle of a multi-block write, *ACK is currently asserted. Writing a byte ; to the output register will release *ACK, completing the handshaking, allowing ; the target to assert *REQ. move.b (a2)+,(a0) ; write data byte to output register sub.l #1,d2 ; dec number of bytes to xfer beq.s @DoneWait ; no more data bytes to xfer <55> djw ; With *ACK released, determine if the target is in sync. We cannot look for ; *REQ to be asserted, because the target may have already accepted the data byte ; and released *REQ at this point. We can sync on DRQ which will signal when ; the NCR 53C80 is ready to accept a data byte, meaning a *REQ from the target ; must have already occurred and our data byte was taken. @syncWait btst.b #bDMAR,(a1) ; check bus & status reg for DRQ bne.s @doWrite ; DRQ present - sync-ed up so proceed btst.b #bREQ,sCSR(a3) ; no DRQ - is *REQ present ? beq.s @syncWait ; no *REQ yet - wait for sync btst.b #bPM,(a1) ; with *REQ, check phase lines bne.s @syncWait ; still in data out phase - wait moveq.l #0,d1 ; out of phase - did not xfer any bytes moveq.l #scPhaseErr,d0 ; return error bra.s @Done ; exit ; Perform the write to the SCSI chip. The transfer code is the same as the original ; MacPlus so the transfer speed does not change. ; Reg d2.l = number of bytes to move @doWrite sub.l #1,d2 ; adjust byte cnt for dbra loop <55> djw move.l d2,d3 ; get number of 64K byte blks to move swap d3 ; count in low word @CopyLoop move.b (a2)+,(a0) dbra d2,@CopyLoop ; up to 64K bytes loop dbra d3,@CopyLoop ; loop in chunks of 64K bytes ; Before exiting this routine, make sure that the peripheral has actually accepted ; the data byte. Wait for a DRQ (meaning the SCSI chip is ready for another byte) ; before exiting. @DoneWait moveq.l #noErr,d0 ; set good return btst.b #bDMAR,(a1) ; check for DRQ (a1 = sBSR(a3)) bne.s @Done ; if DRQ, peripheral got the byte btst.b #bREQ,sCSR(a3) ; no DRQ - is *REQ present ? beq.s @DoneWait ; no *REQ yet - wait for it btst.b #bPM,(a1) ; are we still in phase ? bne.s @DoneWait ; if so, keep waiting @Done movem.l (sp)+,@savedregs tst.w d0 ; set the condition codes rts ; we're done Opt all ; set optimization to preset <53> djw ;================= End SCSI Patches =================== ;_____________________________________________________________________________ <57> eh ; ; Async Serial Driver patch ; ; This is the new Async Serial driver patch for the Mac Plus. We are combining ; the three patches (to ReservMem for _Open, to _Control, and for the interrupt ; handlers) into this one. ; ; We now patch out ALL the driver headers completely by installing them in the ; patchfile install code. ; ; Here is what the OLD fixes do: ; ; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed ;AppleSystemPatch PatchPlusROM.a 14Oct85 #3 (AsynchDrvrs) (ResrvMem) ; NOTES: ; (1) This patches an async driver bug. The old ROM async driver defaulted ; hardware handshake on. The RAM-based driver, which we adapted for ; the new ROM didn't. This breaks a couple of plotter programs which ; never configure the handshake options. ; (2) The patch to the driver is simply ; ; ST HWHS(A2) ; default hardware handshake on ; . . . in the open code, after A2 locals have been allocated. ; (3) The only reasonable place to patch this routine is in NewHandle or ; ResrvMem, the calls used to allocate the space for the driver locals. ; ResrvMem is patched because it is a less frequently used trap. ; ; ;AppleSystemPatch PatchPlusROM.a 23Feb88 #42 PMAB401 (Control) (Control) ; NOTES ; (1) This patches an async driver bug. On a MacPlus, the handshake out ; line is usually connected to DTR. When configuring the SCC, we ; drop DTR for 20-30 usec. This may cause a connected modem to ; disconnect. ; (2) This happens for two control calls: 8 (full reconfig) and 13 (change ; baud rate only). It may also happen on an Open if DTR has been left ; asserted from a previous call but this is of less concern. ; (3) Unfortunately, the only good patch point is at the Control dispatch ; to the driver (patching Control would entail duplication of ; IOCore functions and might not be possible if a call were pending ; already). We currently patch the Open of the output async drivers; ; this patch takes advantage of this, installing new pointers to ; the driver headers for the output drivers at this time. All new ; calls have to be redirected to the ROM, intercepting the two ; pertinent control calls. ; (4) Control calls using the input driver refnums will not benefit from ; this patch. MacTerminal uses the output driver refnum (always?) and ; needs this patch the most, so it should suffice. I think that most ; other apps do too. Patching out the input side of the drivers would ; take much more code and is not possible at the current patch point ; (actually, we could replace the DCE pointers at boot time - but then ; anyone who disconnected them couldn't find them via the ROM resource ; map . . .). ; (5) Test: control call 13 (set baud rate) ; - to same baud rate should skip init (except for under 300) ; - to different baud rate should not glitch DTR ; control call 8 (reinit all xmit, receive values) ; - to 00xxxxxx xxxxxxxx should get control err, no reinit ; - to same baud rate should skip init ; - to different baud rate should not glitch DTR ; test above for both states of DTR ; option to leave DTR asserted should result in DTR asserted at ; close; when reopened there will be a slight glitch on DTR. ; otherwise, DTR should go down at close and back up at open. ; ; Also in Control, clear reg D0 before returning to ROM. This fixes a bug where KillIO returns ; without clearing reg D0 to show a good status. ; ; ;AppleSystemPatch PatchPlusROM.a 26jan88 PMAB372 (AOutOpen,RAIntHnd) (RAIntHnd) ; If hardware handshaking is enabled, and the receiver de-asserts DTR, but the sender ignores ; it and keeps sending, the receiver will go into an infinite loop in the receive interrupt ; routine. This was caused by a jump to the wrong label. The patch is installed in a patch ; vector for the async driver. Needed to include all async driver code which jumped to ; the receive interrupt handler. ; ; ; ; Here is what the NEW fixes do: ; ;AppleSystemPatch PatchPlusROM.a 11Jan91 <57> (all driver entry points,all int handlers) ; We need to add provide nike printer support. This entails: ; -- patch control call 16 to use bit 6 for setting external/internal clocking modes. ; -- Patch to add status call to return version. ; -- Patch InitSCC routine to use this RAM-based table so ; that clocking mode is now variable instead of hard-wired to internal only. ; -- set clock divide to 1 instead of 16 for external clocking ; -- clear HWHS enable since we can't clock and handshake on same line ; -- Patch whole ExtIntHandler so we can set bit 3 of AsyncErr if break rcvd. ; -- We patch all the port A driver headers (port B driver headers already patched) ; so that we can put a signature word before each header that we can use ; to identify ourselves as the Apple async serial driver. We do this ; right now so that that our linked patch on Open (in Serialpatches.a) will ; not stomp the version number of some third party driver that sticks them- ; selves into our spot in the unit table. I think this idea will come in ; handy later as well. I think i'll use the signature word 'wong'. ; ; FOR BAP ; -- Always get the driver storage pointer for port B from extended mem ; -- Call Gestalt 'atkv' in Open and Close to determine version of AppleTalk to see which ; port arbitration scheme we should use, ours or the LAP mgr's. ; ; <58> Fixed bug in external clock stuff that was causing us to disable ; internal clocking on both ports if we were trying to do external ; clocking on just one. So Nike would print but Tabasco would just ; sit there. The fix was to set clocking params at each time we go ; thru InitSCC, rather than just once during the external clocking ; control call. This way even tho the ports share the InitSCCTable, ; we set the Table properly by keying off of the value in CtlOptions ; variable, which they don't share. ; <60> Status calls 9 and $8000 now return static version number instead ; of what's in the DCE. We patch _Open to set the DCE version byte to ; 2 to be backward compatible, but the status call returns vers=5. asyncPatch PROC EXPORT EXPORT AsyncAOut,AsyncAIn,AsyncBOut,AsyncBIn OldVersion equ 2 ; old version of the driver (written to DCE) <60> Version EQU 5 ;current version 2/91 <57> ; ROM addresses we need ROMAOutOpen EQU $41B7C6 ; for documention only (not used- used by old patches) ROMBOutOpen EQU $41B7F4 ROMAOutClose EQU $41B970 ROMBOutClose EQU $41B984 ROMAOutPrime EQU $41BC02 ROMBOutPrime EQU $41BC08 ROMAStatus EQU $41BA06 ROMBStatus EQU $41BA0C ROMCtlDisp EQU $41BA68 ROMCtlExit EQU $41BAA0 ROMInitSCC EQU $41B920 ; bypass driver ROM entrypoint addresses ;port A ROM_AInEntryOpen EQU $41b76c ROM_AInEntryPrime EQU $41bcbc ROM_ChkAConfig EQU $41b784 ROM_AOutEntryPrime EQU $41bc02 ;port B backToBInOpenStart EQU $41b77a ROM_ChkBConfig EQU $41b78a backToBInPrime EQU $41bcc6 backToBOutPrime EQU $41bc0c ; interrupt handler equates backToTXIntHnd EQU $41bc88 backToPollDtain EQU $41BDAA ToContOut EQU $41BCAC ToGoodFinish EQU $41BC46 ToGetBufRegs EQU $41BD24 ToGetBufCnt EQU $41BD34 ToCtlXOff EQU $41BE52 ToPut EQU $41BE4C backToPut EQU $41BE48 ToRdReqDone EQU $41BEB8 ToCtlSet EQU $41bb80 toContOut1 EQU $41bcb0 ; open call patch equates ROM_InitSCC1 EQU $41b926 ROM_TAIntHnd EQU $41bc8a ; interrupt handler we're NOT patching ROM_InstllLBuf EQU $41baf6 ; Control Patch equates backToBypassControl EQU $41BA68 ROM_CtlGood EQU $41ba9e ROM_CtlExit EQU $41baa0 ROMInitDefs EQU $41B8D4 ; Status patch equates backToStatus EQU $41ba28 ; Close patch equates SyncOutput EQU $41b9dc ResetData EQU $41b960 ResetLth EQU $10 freePort EQU $41b9ca ; for BAP -- since these are not in Interfaces or Internals, ; where they should be LUsePortB EQU 17 ; request use of printer port ;<2.0> LFreePortB EQU 18 ; grant use of printer port ;<2.0> LStatPortB EQU 19 ; obtain current printer port status ;<2.0> LAPMgrPtr EQU $B18 ; This points to start of LapMgr ;<2.0> LAPMgrCall EQU 2 ; Offset to make LAP manager calls ;<2.0> ; misc equates BInDCEOffset EQU 28 ; offset in Unit table of the .BIn DCE ; async serial driver equates SCCARWOFF equ 2 ; SCC A side R/W offset SCCBRWOFF equ 0 ; SCC B side R/W offset PortAVars EQU $2D0 ; serial chan A variables and buffer AInDCE EQU PortAVars+4 ; Device Control Entry ptr for input PortBVars EQU AInDCE+4 ; serial port B variables and buffer BInDCE EQU PortBVars+4 ; Device Control Entry ptr for input OutDCE EQU 0 ;(4) long DCE pointer for output driver SCCOffset EQU 4 ;(2) word of SCC offset . . . InBufPtr EQU 6 ;(4) pointer to local input buffer BufSizeX EQU 10 ;(2) size of local input buffer BufLow EQU 12 ;(2) low buf byte count to send XOn BufHigh EQU 14 ;(2) bytes from end of buffer to send XOff SWHS EQU 16 ;(1) software handshake enable HWHS EQU 17 ;(1) hardware handshake enable XONChar EQU 18 ;(1) input char which continues output (SWHS) XOFFChar EQU 19 ;(1) input char which stops output Options EQU 20 ;(1) bit 4 = abort on parity error ; bit 5 = abort on overrun ; bit 6 = abort on framing error PostOptions EQU 21 ;(1) bit 7=1 enables posting break changes ; bit 5=1 enables posting handshake changes InSWHS EQU 22 ;(1) input XOn/XOff flow control enable InHWHS EQU 23 ;(1) input RTS (DTR) flow control enable <14Oct85> AsyncErr EQU 24 ;(1) error indications (cumulative) SoftOR EQU 0 ; bit 0 = soft overrun ; bit 4 = parity error ; bit 5 = overrun error ; bit 6 = framing error FlowOff EQU 25 ;(1) $80 = input flow shut off by XOff, $40 by DTR ReadCmd EQU 26 ;(1) FF = read command pending WriteCmd EQU 27 ;(1) FF = write command pending CTSFlag EQU 28 ;(1) FF = CTS asserted XOFFlag EQU 29 ;(1) FF = XOFF pending LastWR5 EQU 30 ;(1) WR5 value with last DTR state <14Oct85> DTRNegVal EQU 31 ;(1) WR5 value used to negate DTR <14Oct85> SCCReset EQU 32 ;(1) WR9 value for reset StopBits EQU 33 ;(1) stop bits/parity option (WR4 value) WR1AVal EQU 34 ;(1) first WR1 value to write WR3AVal EQU 35 ;(1) first WR3 value to write WR5AVal EQU 36 ;(1) first WR5 value to write BaudLoCnst EQU 37 ;(2) 2 byte baud rate constant (WR12-13) BaudHiCnst EQU 38 RcvrBits EQU 39 ;(1) 1 byte receiver bits/char (WR3 value) XmitBits EQU 40 ;(1) 1 byte xmitter bits/char (WR5 value) WReqPin EQU 41 ;(1) w/req pin state (WR1 value) lastSetup EQU 42 ;(2) last SCC init values . . . BufIndex EQU 44 ;(2) index into local buffer (insert) BufOutdex EQU 46 ;(2) index into local buffer (remove) LocalBuf EQU 48 ;(64) local buffer for input chars LclBufSize EQU 64 ; default input buffer size = 64 bytes HSCount EQU 112 ;(2) count of CTS pulses in VBL time (clk detect) <14Oct85> LastTime EQU 114 ;(4) ticks time of last CTS pulse (clk detect) <14Oct85> SendXOnff EQU 118 ;(1) flag to xmit logic to send XOn/XOff <14Oct85> CharMask EQU 119 ;(1) $1F,$3F,$7F, or $FF mask for input chars PEChar EQU 120 ;(1) char to change incoming parity errors to <14Oct85> AltChar EQU 121 ;(1) char to change incoming PEChars to <14Oct85> InSWHS1 EQU 122 ;(1) saved InSWHS state <14Oct85> CtlOptions EQU 123 ;(1) bits 0-6=0 (reserved). bit 7=1 to leave <14Oct85> ; DTR state unchanged at close. SaveExInt EQU 124 ;(4) saved Ext int vector <14Oct85> SaveTxInt EQU 128 ;(4) saved TxD int vector <14Oct85> SaveRxInt EQU 132 ;(4) saved RxD int vector <14Oct85> SaveSxInt EQU 136 ;(4) saved Special Rx int vector <14Oct85> LclVarSize EQU 140 ; output driver storage size <14Oct85> ;_______________________________________________________________________ <57> ; ; Patched Driver headers (with signature long word before each header) ; DC.b 'wong' ; our personal signature AsyncAIn DC.W $4D00 ; read, control, status, lock DC.W 0,0 ; not an ornament DC.W 0 ; no menu DC.W AInOpen-AsyncAIn ; Initialization routine DC.W AInPrime-AsyncAIn ; input Prime routine DC.W AControl-AsyncAIn ; shared Control routine DC.W AStatus-AsyncAIn ; shared Status routine DC.W AInClose-AsyncAIn ; Close routine DC.B 4 ; channel A input driver DC.B '.AIn ' DC.b 'wong' ; our personal signature AsyncAOut DC.W $4E00 ; write, control, status, lock DC.W 0,0 ; not an ornament DC.W 0 ; no menu DC.W AOutOpen-AsyncAOut ; Initialization routine DC.W AOutPrime-AsyncAOut ; output Prime routine DC.W AControl-AsyncAOut ; shared Control routine DC.W AStatus-AsyncAOut ; shared Status routine DC.W AOutClose-AsyncAOut ; Close routine DC.B 5 ; channel A output driver DC.B '.AOut' DC.b 'wong' ; our personal signature AsyncBIn DC.W $4D00 ; read, control, status, lock DC.W 0,0 ; not an ornament DC.W 0 ; no menu DC.W BInOpen-AsyncBIn ; Initialization routine DC.W BInPrime-AsyncBIn ; input Prime routine DC.W BControl-AsyncBIn ; shared Control routine DC.W BStatus-AsyncBIn ; shared Status routine DC.W BInClose-AsyncBIn ; Close routine DC.B 4 ; channel B input driver DC.B '.BIn ' DC.b 'wong' ; our personal signature AsyncBOut DC.W $4E00 ; write, control, status, lock DC.W 0,0 ; not an ornament DC.W 0 ; no menu DC.W BOutOpen-AsyncBOut ; Initialization routine DC.W BOutPrime-AsyncBOut ; output Prime routine DC.W BControl-AsyncBOut ; shared Control routine DC.W BStatus-AsyncBOut ; shared Status routine DC.W BOutClose-AsyncBOut ; Close routine DC.B 5 ; channel B output driver DC.B '.BOut' ;_______________________________________________________________________ <57> ; ; Patched Entry Points ; Here are the entrypoints to the routines that require little or no ; patching. They just jump back to ROM. Look for the other routines ; in the code following. ; AInPrime jmp ROM_AInEntryPrime BInPrime move.l ExpandMem,a2 ; use ExpandMem instead of PortBVars move.l ExpandMemRec.emSerdVars(a2),a2 jmp backToBInPrime AOutPrime jmp ROM_AOutEntryPrime BOutPrime move.l ExpandMem,a2 ; use ExpandMem instead of PortBVars move.l ExpandMemRec.emSerdVars(a2),a2 jmp backToBOutPrime AInClose BInClose moveq #0,d0 ; shorter to return than to jump to ROM rts ;_______________________________________________________________________ <57> ; ; Open fixes: .In drivers ; ; -- do that nutty BAP stuff to arbitrate for port B. We call gestalt to see ; if we have the required version of appletalk to do the BAP. If so, we ; call the Lap mgr to arbitrate. If not, we use the ROM arbitration routine. ; AInOpen jmp ROM_AInEntryOpen BInOpen bsr.s NewChkBConfig jmp backToBInOpenStart NewChkBConfig move.l ExpandMem,a0 ; <63> tst.w ExpandMemRec.emAppleTalkInactiveOnBoot(a0) ; <63> If AppleTalk is inactive, don’t set up the LAP manager bnz.s @appleTalkInactive ; <63> AppleTalk is not active. move.l #'atkv',d0 ; what version of Appletalk? _Gestalt tst.w d0 ; <63> Check the result code bne.s @appleTalkInactive ; <63> AppleTalk is inactive. move.l a0,d0 ; get high byte (version) into low byte rol.l #8,d0 cmp.b #53,d0 ; is Atalk version 53 or greater? bge.s @useLAP ; yes, than call LAP manager, it exists @appleTalkInactive ; no, use old chkConfig movea.l (sp)+,a2 ; save out return addr pea @00 move.l #ROM_ChkBConfig,-(sp) ; JSR to ROM routine rts @00 move.l a2,-(sp) ; restore return addr bra.s @done @useLAP move.l a1,-(sp) ; save out reg's we might use move.w #LStatPortB,d0 ; request status of the printer port move.l LAPMgrPtr,a0 jsr LAPMgrCall(a0) cmp.b #useAsync,d1 ; do we already own the port? beq.s @rstrReg ; yes move.w #LUsePortB,d0 ; no, request use of the printer port- move.b #useAsync,d1 ; for the serial driver- move.l LAPMgrPtr,a0 ; by calling the LAP Manager jsr LAPMgrCall(a0) @rstrReg move.l (sp)+,a1 ; restore reg's cmp.w #noErr,d0 ; did we get the printer port? beq.s @done ; yes adda.l #4,sp ; no, pop return address and go to IOCore @done rts ; ;_______________________________________________________________________ <57> ; ; Open fixes: .Out drivers ; ; -- get driver storage from ExpandMem for port B. ; -- do that nutty BAP stuff to arbitrate for port B ; -- patch the InitSCC call, which we want to have here in RAM so ; we can muck around with the InitData table for external clocking. ; AOutOpen pea @00 move.l #ROM_ChkAConfig,-(sp) ; jsr to ROM routine rts @00 LEA PortAVars,A2 ; local variables address PEA NewPollDtain ; this proc handles disk poll data <20Oct85> PEA NewSCAIntHnd ; Special RxD int handler <20Oct85> PEA NewRAIntHnd ; RxD int handler <20Oct85> PEA ROM_TAIntHnd ; TxD int handler <20Oct85> PEA Lvl2DT+16 ; SCC interrupt dispatch table, chan A <20Oct85> PEA NewExtAIntHnd ; External int handler <20Oct85> PEA ExtStsDT+8 ; SCC External/Status table, chan A <20Oct85> MOVEQ #SCCARWOFF,D1 ; SCC read/write offsets MOVEQ #-9,D2 ; WR1 value ($F7) - w/req = char in MOVEQ #-$7E, D3 ; reset channel A ($82) MOVE.W SPPortA,D4 ; parameter RAM config value, chan A BRA.S OpenInstall ; use shared open code <20Oct85> BOutOpen ; first check that configuration is ok and port is idle bsr.s NewChkBConfig move.l ExpandMem,a2 ; local variable address in is <2.0> lea ExpandMemRec.emSerdVars(a2),a2 ; expandmem <2.0> CLR.L -(SP) ; no disk poll routine PEA NewSCBIntHnd ; new special RxD int handler PEA NewRBIntHnd ; new RxD int handler pea NewTBIntHnd ; TxD int handler pea Lvl2DT ; SCC interrupt dispatch table, chan A pea NewExtBIntHnd ; External int handler PEA ExtStsDT ; SCC External/Status table, chan B <20Oct85> MOVEQ #SCCBRWOFF,D1 ; SCC read/write offset MOVEQ #$17,D2 ; WR1 value - w/req pin = float MOVEQ #$42,D3 ; reset channel B MOVE.W SPPortB,D4 ; parameter RAM config value, chan B ; A0 = open parameter block ptr (not used) ; D1 = SCC read/write offset A1 = DCE address ; D2 = WR1 value A2 = local variables pointer location ; D3 = channel reset data ; D4 = clk param init values ; D5 = ExtStsDT offset ; (SP) ExtStsDT vector addr ; 4(SP) External/status interrupt handler addr ; 8(SP) Lvl2DT table vector addr for this channel ; 12(SP) Transmit interrupt handler addr ; 16(SP) Receive interrupt handler addr ; 20(SP) Special receive condition interrupt handler addr ; 24(SP) Poll data receiver addr or zero OpenInstall MOVEQ #(LclVarSize+1)/2,D0 ; size of locals in words <14Oct85> ADD.L D0,D0 ; size of locals in bytes <14Oct85> _ResrvMem ,SYS ; make room as low as possible MOVEQ #(LclVarSize+1)/2,D0 ; size of locals in words <14Oct85> ADD.L D0,D0 ; size of locals in bytes <14Oct85> _NewHandle ,SYS,CLEAR ; get local storage on system heap ; clear errors, error options ; read, write, XOFF and CTS flags ; index, outdex, inSWHS, inSWHS1, PEChar ; HWHS, SWHS, XONChar, XOFFChar ; AltChar, CharMask, InHWHS, <14Oct85> ; HSCount, LastTime <14Oct85> BEQ.S @1 ; br if we got the memory <20Oct85> RTS ; memory full exit <20Oct85> @1 MOVE.L A0,DCtlStorage(A1) ; save handle in our storage pointer MOVE.B #oldVersion,DCtlQueue+1(A1) ; note our version <06Feb85> <60> MOVE.L (A0),(A2) ; save pointer in lo-mem MOVE.L (A0),A2 ; and get the pointer _HLock ; AND THEN lock it down <14Oct85> LEA SaveExInt(A2),A3 ; locals address for saved vectors <20Oct85> MOVE.L (SP)+,A0 ; ExtStsDT table entry address <20Oct85> MOVE.L (A0),(A3)+ ; save old Ext/Sts handler address <20Oct85> MOVE.L (SP)+,(A0) ; install the new <20Oct85> MOVE.L (SP)+,A0 ; Lvl2DT table address <20Oct85> MOVE.L (A0),(A3)+ ; save old TxD int handler address <20Oct85> MOVE.L (SP)+,(A0)+ ; install the new <20Oct85> ADDQ #4,A0 ; skip ext/sts primary dispatch <20Oct85> MOVE.L (A0),(A3)+ ; save old RxD int handler address <20Oct85> MOVE.L (SP)+,(A0)+ ; install the new <20Oct85> MOVE.L (A0),(A3)+ ; save old Spec RxD handler address <20Oct85> MOVE.L (SP)+,(A0)+ ; install the new <20Oct85> _AssumeEq SaveExInt+4,SaveTxInt _AssumeEq SaveTxInt+4,SaveRxInt _AssumeEq SaveRxInt+4,SaveSxInt MOVE.L (SP)+,D0 ; poll data handler? (chan A only) <20Oct85> BEQ.S @2 ; br if not <20Oct85> MOVE.L D0,PollProc ; this proc handles disk poll data <20Oct85> @2 MOVE.L A2,A3 ; locals pointer MOVE.L A1,(A3)+ ; output DCE pointer MOVE.W D1,(A3)+ ; SCC channel address offset pea @01 move.l #ROM_InstllLBuf,-(sp) ; jsr to ROM to install our local buffer <57> rts @01 ST Options(A2) ; abort input on errors defaults on ST HWHS(A2) ; default hardware handshake on <13Jan86> MOVE.B D3,SCCReset(A2) ; channel reset data MOVE.B D2,WReqPin(A2) ; WR1 value for SCC initialization or.b #$80,LastWR5(A2) ; "last DTR" at open = assert bra.s ToInitSCC ; go init the SCC ; ; The following code is shared with Control channel initialization calls. ; ;____________________________________________________________________ ; ; ToInitSCC ; This fills in the SCC register image (bytes 'StopBits' to 'XmitBits' ;inclusive) for output to the chip. ; ; A2 = SCC A or B side vars ; D4 = [V][V][W][W][X][X][Y][Y] [Z][Z][Z][Z][Z][Z][Z][Z] ; VV = 1,2,3, for 1,1.5,2 stop bits (00 for AppleBus) ; WW = 0,1,2,3 for no,odd,no,even parity ; XX = 0,1,2,3, for 5,7,6,8 data bits ; YY = high byte of baud rate constant, low 2 bits ; ZZZZZZZZ = low byte of baud rate constant ; ;____________________________________________________________________ ; MaskTbl DC.B $1F ; mask for 5-bit data <14Oct85> DC.B $7F ; mask for 7-bit data <14Oct85> DC.B $3F ; mask for 6-bit data <14Oct85> DC.B $FF ; mask for 8-bit data <14Oct85> ToInitSCC MOVE.W #$C000,D0 ; bit 15-14 mask AND.W D4,D0 ; zero? (probably bad PRAM value) BNE.S @0 ; br if not MOVE.W #$CC0A,D4 ; otherwise, use defaults 9600 baud, 8 data bits @0 MOVE.W #$0C00,D0 ; mask for bits 10-11 (# data bits) <14Oct85> AND.W D4,D0 ; isolate these bits <14Oct85> ROL.W #6,D0 ; convert to 0-3 offset <14Oct85> MOVE.B MaskTbl(D0),CharMask(A2) ; get appropriate data mask <14Oct85> LEA StopBits(A2),A3 LEA InitDefs,A4 ; process clock data MOVEQ #7,D0 ; expand into 8 bytes variable data @1 MOVE.B (A4)+,D1 ; rotate left count MOVE.W D4,D3 ; clock pram data ROL.W D1,D3 ; get appropriate bits into low byte AND.B (A4)+,D3 ; only keep relevant bits OR.B (A4)+,D3 ; add in constant bits MOVE.B D3,(A3)+ ; store processed data DBRA D0,@1 ; do all 8 bytes MOVEQ #$64,D1 ; get WR1A mask AND.B (A3)+,D1 ; form value MOVE.B D1,WR1AVal(A2) ; and store in WReqPin MOVE.W D4,(A3) ; lastSetup - remember this config <20Oct85> move.b LastWR5(A2),D0 ; get current DTR bit and.b #$80,D0 ; from last WR5 written, or.b D0,WR5AVal(A2) ; apply to new values, or.b D0,XmitBits(A2) ; move.b XmitBits(A2),D0 ; make the WR5 value used to move.b D0,LastWR5(A2) ; remember DTR & other bits, bclr #7,D0 ; and negate DTR move.b D0,DTRNegVal(A2) ; _AssumeEq StopBits+1,WR1AVal _AssumeEq WR1AVal+1,WR3AVal _AssumeEq WR3AVal+1,WR5AVal _AssumeEq WR5AVal+1,BaudLoCnst _AssumeEq BaudLoCnst+1,BaudHiCnst _AssumeEq BaudHiCnst+1,RcvrBits _AssumeEq RcvrBits+1,XmitBits _AssumeEq XmitBits+1,WReqPin _AssumeEq WReqPin+1,lastSetup BSR.S InitSCC ; initialize SCC channel MOVEQ #0,D0 ; no errors OpenEnd RTS ; <06Feb85> ;___________________________________________________________; ; ; ; D4 = [V][V][W][W][X][X][Y][Y] [Z][Z][Z][Z][Z][Z][Z][Z] ; ; ; ; VV = 1,2,3, for 1,1.5,2 stop bits (00 for AppleBus) ; ; WW = 0,1,2,3 for no,odd,no,even parity ; ; XX = 0,1,2,3, for 5,7,6,8 data bits ; ; YY = high byte of baud rate constant, low 2 bits ; ; ZZZZZZZZ = low byte of baud rate constant ; ;___________________________________________________________; InitDefs DC.B 4,$0F,$40 ; (WR4) rotate left 4, leave 4 low bits, add $40 DC.B 0,$00,$00 ; (WR4) (dummy entry - WR1AVal will go here) DC.B 12,$C0,$00 ; (WR3) WR3 - first write DC.B 11,$60,$02 ; (WR5) WR5 - first write (no DTR) <14Oct85> DC.B 0,$FF,$00 ; (WR12) baud constant, low byte DC.B 8,$03,$00 ; (WR13) baud constant, hi byte DC.B 12,$C0,$01 ; (WR3) WR3 - final value DC.B 11,$60,$0A ; (WR5) WR5 - final value (no DTR) <14Oct85> ;________________________________________________________________________ ; ; Routine: SCC Initialize Routine ; ; Arguments: A2 (input) -- pointer to local variables for this channel ; ; Function: This routine initializes one channel of the SCC for asynchronous ; communication; the baud rate, data bits, stop bits, and parity ; options are set according to local variable values. The baud-rate generator ; output is used for both transmitter and receiver clocks, and ; interrupts are enabled: CTS, Break, and DCD (for Mac mouse) external ; interrupts are enabled; all transmitter and receiver interrupts ; are enabled. Parity errors are configured to generate special ; condition vectors. ; ; Other: Registers A0-A3 are used. ; ; Initialization data for SCC: RS-232 async communication: ; FORMAT: data,register# - for immediate data ; register#,$FF - for variable data ; ; Initialization order is as suggested in a Zilog applications ; note on SCC initialization. ; ; ; Patch: --We patch this routine to use the InitData table here in RAM ; instead of the one in ROM. We do this so that the values in ; WR11 and WR14 aren't hardcoded, so that we can support external ; clocking. ; --We also fix the value of StopBits (WR4) here to have the clock ; divide bits correspond to the the external/internal clock state ; indicated in CtlOptions. We do this here so that CtlConfig calls ; won't stomp StopBits in the ToSCCInit routine. ; --We also disable HWHS so we don't try to use CTS line for both ; clocking and handshaking. ; ; NOTE: THIS PATCH IS NOT DIRECTLY ROM-ABLE!!!!!!!!!!!!!!!!! ; must revise the table and the varibles such that ; registers 11 and 14 are NOT hardcoded if in ROM. ;___________________________________________________________________; clkBit equ 6 ; bit 6 in CtlOptions controls ext/int SCC clk clkDvdBit equ 6 ; divide clock bit in WR4 clkMask equ %01000000 ; mask for getting at clkBit <58> extClkSrc equ %00101000 ; SCC clk src is TRxC (CTS) pin (WR11) <58> intClkSrc equ %01010000 ; SCC clk src is baud rate generator (WR11) <58> BRGEnbl equ %00000001 ; enable baud rate generator (WR14) <58> BRGDsbl equ %00000000 ; disable baud rate generator (WR14) <58> ; Initialization table the same for all CPU's except classic Mac <2.3> InitData DC.B $02,9 ; status in low bits, MIE disabled DC.B 4,$FF ; x16 clk, stop bits, parity options DC.B 1,$FF ; WR1 reg, first write DC.B 3,$FF ; bits/char option rcvr DC.B 5,$FF ; bits/char option xmitter DC.B $00,2 ; zero interrupt vector DC.B $00,10 ; NRZ encoding clkMode DC.B $50,11 ; br gen clk to rcvr, xmitter,clockMode <57> DC.B 12,$FF ; set baud rate low byte DC.B 13,$FF ; set baud rate high byte DC.B 3,$FF ; enable rcvr DC.B 5,$FF ; enable xmitter BRGEnable DC.B $01,14 ; enb baud rate generator from RTxC pin <57> DC.B $A8,15 ; Break, CTS, and DCD (for mouse) external ints <2.3> DC.B $10,0 ; reset ext/status twice DC.B $10,0 DC.B 1,$FF ; w/req pin configuration DC.B $0A,9 ; enable interrupts, status in low bits InitLth EQU *-InitData ; InitSCC LEA InitData,A3 ; get pointer to init data MOVEQ #InitLth,D1 ; and init length movem.l d1/a0,-(sp) ; save out reg's <58> ; default to internally clocked state <58> bset.b #clkDvdBit,StopBits(a2) ; default to a divide-by-16 clock <58> moveq #intClkSrc,d0 ; internal clocking source <58> moveq #BRGEnbl,d1 ; enable baud rate generator <58> btst.b #clkBit,CtlOptions(a2) ; are we externally clocked? beq.s @load ; not externally clocked, so load ; set to externally clocked state bclr.b #clkDvdBit,StopBits(a2) ; set to a divide-by-one clock <58> moveq #extClkSrc,d0 ; external clock source <58> moveq #BRGDsbl,d1 ; disable baud rate generator <58> clr.b HWHS(a2) ; make sure we're not trying to do HWHS <58> @load lea ClkMode,a0 ; load params into InitSCC data table <58> move.b d0,(a0) ; <58> lea BRGEnable,a0 ; <58> move.b d1,(a0) ; <58> movem.l (sp)+,d1/a0 ; restore reg's <58> InitSCC1 jmp ROM_InitSCC1 ; JMP to finish up in ROM <57> ;_______________________________________________________________________ <57> ; ; Close fixes ; -- get driver storage from ExpandMem for port B. ; -- do that nutty BAP stuff to free port B, which unfortunately is ; at the end of the close call, so we patch the whole thing. ; AOutClose CLR.L PollProc ; no more poll-data process routine LEA Lvl2DT+16,A4 ; get dispatch table address LEA ExtStsDT+8,A5 ; and secondary dispatch table <14Oct85> LEA PortAVars,A6 ; local variables ptr address <14Oct85> MOVEQ #8,D3 ; for PortAUse <01Feb85> BRA.S ABClose ; BOutClose LEA Lvl2DT,A4 ; get dispatch table address LEA ExtStsDT,A5 ; and secondary dispatch table <14Oct85> move.l ExpandMem,a6 ; local vars ptr in expand mem <2.0> lea ExpandMemRec.emSerdVars(a6),a6 ; <2.0> MOVEQ #0,D3 ; for PortBUse <01Feb85> ABClose move.l a1,-(sp) ; save DCE ptr MOVE.L (A6),A2 ; get locals pointer <14Oct85> TST.B CtlOptions(A2) ; leave DTR unchanged? <14Oct85> bmi.s @1 ; bclr #7,XmitBits(A2) ; no, clear the DTR bit bclr #7,WR5AVal(A2) ; @1 bclr #3,XmitBits(A2) ; always clear Tx enable pea @00 ; BSR SyncOutput move.l #SyncOutput,-(sp) ; delay until last char has cleared output buffer<14Oct85> rts @00 movea.l #ResetData,A3 MOVEQ #ResetLth,D1 jsr InitSCC1 ; shut down the channel (call RAM routine) ; for BAP ; we replace ROM's port arbitration stuff with BAP stuff ; too bad the ROM port arbitration code comes at the END of the close call LEA SaveExInt(A2),A3 ; reinstall former int handlers <14Oct85> MOVE.L (A3)+,(A5) ; <14Oct85> MOVE.L (A3)+,(A4)+ ; <14Oct85> ADDQ.L #4,A4 ; <14Oct85> MOVE.L (A3)+,(A4)+ ; <14Oct85> MOVE.L (A3),(A4) ; <14Oct85> move.l (sp)+,a1 ; restore DCE ptr MOVE.L DCtlStorage(A1),A0 ; get storage handle _DisposHandle ; get rid of it CLR.L DCtlStorage(A1) ; without a trace CLR.L (A6) ; get rid of ptr address <14Oct85> tst.w d3 ; what port are we? beq.s @freeB ; port b; do that BAP thing to free port move.l #freePort,-(sp) ; port a; finish up in ROM 2aed6 rts @freeB move.l ExpandMem,a0 ; <63> tst.w ExpandMemRec.emAppleTalkInactiveOnBoot(a0) ; <63> If AppleTalk is inactive, don’t set up the LAP manager bnz.s @freeThePort ; <63> AppleTalk is not active. move.l #'atkv',d0 ; what version of Appletalk? <52> _Gestalt tst.w d0 ; <63> Check result code bne.s @freeThePort ; <63> If an error, AppleTalk is inactive move.l a0,d0 ; get high byte (version) into low byte rol.l #8,d0 cmp.b #53,d0 ; is Atalk version 53 or greater? bge.s @useLAP ; yes, then call LAP manager, it exists @freeThePort move.l #freePort,-(sp) ; no, then finish up in ROM rts @useLAP move.w #LFreePortB,d0 ; call LAP Manager to free port B move.b #useAsync,d1 move.l LAPMgrPtr,a0 jsr LAPMgrCall(a0) move.w #0,d0 ; no error on close rts ;_______________________________________________________________________ <57> ; ; Routine: Status ; Patch: We patch status to add a call to return the driver's version. AStatus MOVE.L PortAVars,A2 ; local variables address BRA.S ABStatus BStatus move.l ExpandMem,a2 ;local variables <2.0> move.l ExpandMemRec.emSerdVars(a2),a2 ; <2.0> ABStatus MOVE.W IOTrap(A0),-(SP) ; save trap to distinguish immed calls<14Oct85> MOVE.L A1,-(SP) ; save passed DCE for in/out <14Oct85> MOVE.W SR,-(SP) ; disable interrupts for ctl call <14Oct85> ORI #HiIntMask,SR ; LEA CSCode(A0),A0 ; get pointer to return parameters MOVEQ #StatusErr,D0 ; assume status error MOVE.L A2,D1 ; have our variables been set up? <14Oct85> Bgt @stat1 ; yes, variables set up, so ok move.l #ROM_CtlExit,-(sp) ; no, vars not set up, so exit rts @stat1 MOVE.W (A0)+,D1 ; get opcode cmpi.w #9,d1 ; do we care? beq.s @version ; yes cmpi.w #$8000,d1 ; largest negative number csCode for Version beq.s @version ; yes move.l #BackToStatus,-(sp) ; no rts @version move.b #Version,(a0) ; return the version <60> move.l #ROM_CtlGood,-(sp) rts ;_______________________________________________________________________ <57> ; ; Routine: Control ; Patch: We patch control for the following reasons: ; 1) to add external clock support in control call 16 ; 2) clear reg D0 in case this call is for KillIO ; 3) fix dtr bug in call 8 ; 4) fix baud rate bugs in call 13 AControl MOVE.L PortAVars,A2 ; local variables address BRA.S Control BControl move.l ExpandMem,a2 ; use ExpandMem instead of PortBVars <57> move.l ExpandMemRec.emSerdVars(a2),a2 ; <57> Control MOVE.W IOTrap(A0),-(SP) ; save trap to distinguish immed calls MOVE.L A1,-(SP) ; save passed DCE for in/out MOVE.W SR,-(SP) ; disable interrupts for control call ORI #HiIntMask,SR LEA CSCode(A0),A0 ; get parameters MOVE.W (A0)+,D1 ; get opcode CMP.W #8,D1 ; SerReset? BEQ.S CtlConfig ; br if so CMP.W #13,D1 ; set baud rate? BEQ CtlSetSpd ; br if so - changed from short branch cmpi #16,d1 ; opcode 16? (ctlOptions) <57> beq CtlSwitchCTSClock ; <57> CLR.L D0 ; clr D0 incase killio uses D0 as status return JMP backToBypassControl ; otherwise, go the ROM route ;_______________________________________; ; ; Reconfigure the SCC according to the ; encoded parameter . . . just skip if ; it's the same as last configured. ; ; Fixes here: ; ; (1) In the reinit, leave DTR in current ; state (don't glitch it). ; (2) Report ControlErr if parameter has ; zeroes in two high bits (used to ; just be ignored). ;_______________________________________; CtlConfig MOVE.W (A0)+,D4 ; get word of configuration data jsr ToInitSCC ; just call what we've already patched <57> bra CtlExit ; and exit _Control thru ROM code ;_______________________________________; ; ; Set new baud rate; actual rate is passed. ; ; Fixes here: ; ; (1) Avoid reinit if baud rate does not ; change (don't disturb SCC). ; (2) Remember setting if it fits in our ; allocated 9 bits of LastSetUp. ; (3) Leave DTR in its current state during ; reinit of SCC. ; ;_______________________________________; CtlSetSpd MOVE.L #MacConst,D2 ; clock constant (with X16 clk figured in) MOVE.L D2,D3 ; Save clock constant MOVEQ #0,D0 ; clear high byte MOVE.W (A0),D0 ; baud rate to set MOVE.L D0,D1 LSR.W #1,D1 ADD.L D1,D2 ; bias dividend by divisor/2 for round DIVU D0,D2 MOVE.W D2,D1 ; save intermediate term SUBQ.W #2,D2 ; new baud constant MOVE.W #$01FF,D0 ; mask for low 9 bits CMP.W D0,D2 ; see if constant fits in setup word BLS.S @1 ; br if so CLR.W lastSetup(A2) ; zero invalidates lastSetup BRA.S @2 @1 AND.W lastSetup(A2),D0 ; get current baud rate CMP.W D0,D2 ; same as the one to set? BEQ.S CtlGood ; just exit if so . . . AND.W #$FE00,lastSetup(A2) ; clear out old baud constant OR.W D2,lastSetup(A2) ; and ring in the new @2 MOVE.B D2,BaudLoCnst(A2) ; set the baud constant LSR.W #8,D2 MOVE.B D2,BaudHiCnst(A2) DIVU D1,D3 ; actual baud rate MOVE.W D3,(A0) ; return for user ; BRA.S toROMInit ; change SCC setting, COMMENT IT OUT <57> ; LastWR5 is valid from Open init and any CtlSetDTR or CtlClrDTR calls. ; We just have to adjust XmitBits and WR5AVal to reflect current state of DTR, ; and set DTRNegVal to XmitBits value with DTR clear . . . toROMInit MOVEQ #-128,D0 ; $80 mask AND.B LastWR5(A2),D0 ; current DTR state in bit 7 LEA XmitBits(A2),A3 ; useful ptr BCLR #7,(A3) ; clear DTR bit (already 0 in WR5AVal) MOVE.B (A3),DTRNegVal(A2) ; save for CtlClrDTR OR.B D0,WR5AVal(A2) ; set DTR bit if currently asserted OR.B D0,(A3) ; for both writes to WR5 JSR InitSCC ; change SCC setting <57> ; Make sure we leave XmitBits set to DTR asserted ; value for CtlSetDTR routine (DTRNegVal wasn't changed), ; and WR5AVal set to DTR negated for Close. MOVEQ #7,D0 BSET D0,XmitBits(A2) ; DTR asserted constant BCLR D0,WR5AVal(A2) ; DTR negated constant CtlGood MOVEQ #0,D0 ; IOResult=0 for success CtlExit JMP ROM_CtlExit ; pop params and call IODone CtrlErr MOVEQ #ControlErr,D0 BRA.S CtlExit ; go to IODone ; then to CtlGood ; Routine: SetCtlOptions -- Opcode 16 <57> ; Patch: We patch this routine so that bit 6 of CtlOptions variable now ; controls a switch to internal/external clocking on the CTS (HSIn) line. ; Inputs: byte number in IOPB value ; (26) [$0010] ; (28) bit 7 = 0 for drop DTR at close ; bit 7 = 1 for leave DTR unchanged at close ; bit 6 = 0 for internal clocking ; bit 6 = 1 for external clocking ; bits 0-5 reserved for future use ; Notes: We will not put control for the GPI internal/external ; clocking switch here, as that requires the control of ; HW external to the SCC (namely, the VIA vSync pin). Control ; of the GPIa line is in _HWPriv. ; CtlSwitchCTSClock move.b (a0),CtlOptions(a2) ; store new value <58> bsr InitSCC ; set up the SCC according to new value <58> move.l #ROM_CtlGood,-(sp) ; <58> rts ;_______________________________________________________________________ ; ; Interrupt Handlers ; ; ;_______________________________________________________________________ ; ; Routine: PollDtaIn ; Arguments: A5.L (input) -- AVBufA pointer ; A6.L (input) -- SCC channel A Data pointer ; PollStack -- start of stack data ; This routine should be jsr'ed to, with polled input data ; on the stack (high-order bytes between current SP+4 and ; PollStack address). ; Function: Processes input data from disk driver polling. ;_______________________________________________________________________ AsyncPRAddr EQU PollRtnAddr ; don't use DskRtnAddr because Sony driver uses it NewPollDtaIn MOVE.L PollStack,A4 ; start of data MOVE.L (SP)+, AsyncPRAddr ; save return address <01Feb85> StorData TST.B (A5) ; SCC data available? BMI.S @1 MOVE.B (A6),-(SP) ; push it on the stack BRA.S StorData ; get it emptied out . . . @1 CMP.L SP,A4 ; processed all data? BEQ.S @2 ; exit if so SUBQ #2,A4 ; skip over garbage byte MOVE.B (A4),D0 ; get next byte LEA PortAVars,A3 ; get appropriate variables (channel A) LEA SCCRBase+ACtl,A0 ; and SCC pointers for RxBF routine LEA SCCWBase+ACtl,A1 BSR.S PollStash ; store it, using our RxBF routines BRA.S StorData @2 MOVE.L #backToPollDtain,-(SP) ; JUMP BACK TO ROM RTS ; ;________________________________________________________________________ ; ; Routine: RXIntHnd ; ; Arguments: A0 (input) -- chan A/B control read address ; A1 (input) -- chan A/B control write address ; ; Function: This routine handles SCC receiver interrupts for ; both channels; the data is read and stashed, IODone called ; if necessary. ;________________________________________________________________________ NewRBIntHnd ; <57> move.l ExpandMem,a2 ; use ExpandMem instead of PortBVars move.l ExpandMemRec.emSerdVars(a2),a2 movea.l UTableBase,a3 ; get .Bin DCE ptr in a3 movea.l BInDCEOffset(a3),a3 movea.l (a3),a3 MOVE.B SCCData(A0),D0 ; get the data byte bra.s PS1 NewRAIntHnd LEA PortAVars,A3 ; get appropriate variables (chan A) RXIntHnd MOVE.B SCCData(A0),D0 ; get the data byte PollStash MOVE.L (A3)+,A2 ; get pointer to local variables MOVE.L (A3),A3 ; and DCE pointer PS1 AND.B CharMask(A2),D0 ; zero unused high bits <57> MOVE.B PEChar(A2),D1 ; Are we translating PE Characters? BEQ.S @1 ; No, just save the char. CMP.B D1,D0 ; Is the new char a PEChar? BNE.S @1 ; No, just do normal stuff MOVE.B AltChar(A2),D0 ; Make sure that a good char <14Oct85> ; doesn't look like PEChar. @1 TST.B SWHS(A2) ; software handshake enabled? BEQ.S StashIt ; branch if not CMP.B XONChar(A2),D0 ; was this an XON? <14Oct85> BNE.S @2 ; MOVE.L #ToContOut,-(SP) ; BEQ.S ContOut RTS ; @2 CMP.B XOFFChar(A2),D0 ; how about an XOFF? <14Oct85> BNE.S StashIt ; if not, then stash the character ST XOFFlag(A2) ; if so, then note it BRA InputRTS ; and exit ; stash byte in the user's buffer if a request is pending, otherwise use our own StashIt TST.B ReadCmd(A2) ; read request pending? BEQ.S PutInOurBuf ; if there isn't one, stash it in ours PutInUserBuf MOVE.L A3,A1 ; get DCE pointer PEA @1 ; BSR.S toStash MOVE.L JStash,-(SP) ; RTS ; @1 BPL.S InputRTS ; if request isn't finished, just RTS CLR.B ReadCmd(A2) ; no longer a read request pending MOVE.L #ToGoodFinish,-(SP) ; BRA.S GoodFinish RTS ; PutInOurBuf PEA @00 ; BSR GetBufRegs MOVE.L #ToGetBufRegs,-(SP) ; RTS ; @00 ; MOVE.B D0,0(A3,D1.W) ; stash the byte ADDQ.W #1,D1 ; update BufIndex CMP.W D3,D1 BNE.S @1 ; br if not at the end MOVEQ #0,D1 ; otherwise, reset to 0 @1 CMP.W D2,D1 ; hit the output index? BNE.S @2 ; br if not BSET #SoftOR,AsyncErr(A2); note the soft overrun BRA.S InputRTS ; and exit without updating index @2 MOVE.W D1,BufIndex(A2) ; update index TST.W InSWHS(A2) ; XON/XOFF or DTR input flow control?<14Oct85> BEQ.S InputRTS ; br if not PEA @11 ; BSR.S GetBufCnt MOVE.L #ToGetBufCnt,-(SP) ; RTS ; @11 ; SUB.W D0,D3 ; bytes to top CMP.W BufHigh(A2),D3 ; past the max limit? BCC.S InputRTS ; exit if not TST.B InHWHS(A2) ; input DTR flow control? <14Oct85> BNE.S @4 ; MOVE.L #ToCtlXOff,-(SP) ; BEQ.S CtlXOff RTS ; @4 BSET #6,FlowOff(A2) ; have we negated DTR? <14Oct85> BEQ.S @3 ; MOVE.L #ToPut,-(SP) ; HERE'S THE ONE LINE THAT CHANGED - BNE.S @3 RTS ; @3 MOVE.L #backToPut,-(SP) ; JUMP BACK TO ROM InputRTS RTS ; ;________________________________________________________________________ ; ; Routine: SCIntHnd ; ; Arguments: A0 (input) -- channel A/B control read address ; A1 (input) -- channel A/B control write address ; ; Function: This routine handles SCC special condition interrupts: ; these occur when an input character is received that has ; a parity error, framing error, or causes an overrun. ; If the option is set to abort on the error, the character ; is discarded and the input request (if any) aborted; otherwise, ; the error is noted and the character buffered as usual. ; Patch: forBAP, get driver storage ptr from expanded mem ; get DCE ptr from UTable ;________________________________________________________________________ NewSCBIntHnd ; <57> move.l ExpandMem,a3 ; use ExpandMem instead of PortBVars move.l ExpandMemRec.emSerdVars(a3),a2 movea.l UTableBase,a3 ; get .Bin DCE ptr in a3 movea.l BInDCEOffset(a3),a3 movea.l (a3),a3 bra.s SC1 ; and branch around port a code code NewSCAIntHnd LEA PortAVars,A3 ; get appropriate variables (chan A) SCIntHnd MOVE.L (A3)+,A2 ; get local variables pointer MOVE.L (A3),A3 ; and DCE pointer (delay, too) SC1 MOVE.B #1,(A1) ; point to error reg <57> MOVE.B (A0),D1 ; read the error condition MOVEQ #$70,D3 ; form $70 mask AND.B D3,D1 ; isolate error bits OR.B D1,AsyncErr(A2) ; accumulate errors (delay, too) MOVE.B SCCData(A0),D0 ; get the data byte AND.B CharMask(A2),D0 ; zero unused high-order bits <14Oct85> MOVE.B Options(A2),D2 ; get abort options AND.B D1,D2 ; should we abort? MOVE.B #$30,(A1) ; reset the error flag AND.B D3,D2 BNE.S @2 ; br if we should abort . . . MOVE.B PEChar(A2),D3 ; alternate char for parity errors? BEQ.S @1 ; br if not CMP.B D0,D3 ; Is the incoming char equal to the PEChar? BNE.S @0 ; No, no substitution needed. MOVE.B AltChar(A2),D0 ; Make sure that a good char <14Oct85> ; doesn't look like PEChar. @0 BTST #4,D1 ; parity error? BEQ.S @1 ; br if not MOVE.B D3,D0 ; replace it @1 BRA StashIt ; go stash it . . . @2 TST.B ReadCmd(A2) ; if we have no pending read command BEQ.S InputRTS ; then just discard the character MOVEQ #RcvrErr,D0 ; otherwise, note the error MOVE.L #ToRdReqDone,-(SP) ; JUMP BACK TO ROM RTS ; ;________________________________________________________________________ ; ; Routine: TBIntHnd ; for BAP ; Get the variables ptr from expand mem for the interrupt handlers ; NewTBIntHnd move.l ExpandMem,a2 ; use ExpandMem instead of PortBVars move.l ExpandMemRec.emSerdVars(a2),a2 Jmp backToTXIntHnd ; back to ROM ;________________________________________________________________________ ; ; Routine: ExtIntHnd ; for BAP ; Get the variables ptr from expand mem for the interrupt handlers ; Get input DCE ptr from the Unit Table ; ; -- patch to set bit 3 in AsyncErr (had to patch in ALL code before). ; -- also fix the RdReqDone problem NewExtBIntHnd move.l ExpandMem,a3 ; use ExpandMem instead of PortBVars move.l ExpandMemRec.emSerdVars(a3),a2 movea.l UTableBase,a3 ; get .BIn DCE ptr in a3 movea.l BInDCEOffset(a3),a3 movea.l (a3),a3 bra.s ExtIntHnd NewExtAIntHnd LEA PortAVars,A3 ; get appropriate variables - chan A MOVE.L (A3)+,A2 ; get pointer to local variables MOVE.L (A3),A3 ; get .AIn DCE ptr in a3 ExtIntHnd MOVE.B D1,D2 ; changed bits AND.B postOptions(A2),D2 ; post this change? BEQ.S @0 ; br if not MOVEM.L D0/A0,-(SP) ; preserve these registers MOVE.W #IODrvrEvt,A0 ASL.W #8,D0 ; make room for 'changed' values MOVE.B D1,D0 SWAP D0 ; make room for input driver refnum MOVE.W DCtlRefnum(A3),D0 _PostEvent ; and post the event MOVEM.L (SP)+,D0/A0 @0 TST.B D1 ; see if it's a change in break status BMI.S extBreak ; branch if it was a break interrupt LSL.B #2,D0 ; must be CTS change SMI CTSFlag(A2) ; set flags according to CTS ; This piece of code is used to detect a clock into the HWHS line ; and shut off the ext/sts interrupt for the handshake line. CMP.W #80,HSCount(A2) ; exceeded 80 transitions in 16 MS? <14Oct85> BCS.S @2 ; br if not <14Oct85> MOVEQ #-120,D0 ; ($88) leave mouse/break ints enabled<14Oct85> MOVEQ #15,D1 ; write register 15 <14Oct85> pea @00 ; bsr CtlSet move.l #ToCtlSet,-(sp) ; rts @00 @2 MOVE.L Ticks,D2 ; get current tick time <14Oct85> CMP.L LastTime(A2),D2 ; same as last? <14Oct85> BEQ.S @3 ; br if so <14Oct85> MOVE.L D2,LastTime(A2) ; new last time <14Oct85> CLR.W HSCount(A2) ; restart count for new time <14Oct85> @3 ADDQ #1,HSCount(A2) ; update count <14Oct85> move.l #toContOut1,-(sp) ; BRA ContOut1--if freshly asserted, continue output<14Oct85> rts extBreak TST.B D0 ; check break level BMI.S @1 ; if it's asserted, terminate any input MOVE.B SCCData(A0),D0 ; otherwise (end of break), discard null @done RTS ; and return <2.5> @1 MOVEQ #BreakRecd,D0 ; note the break bset.b #3,AsyncErr(a2) ; we now note break level in status <57> TST.B ReadCmd(A2) ; read request pending? BEQ.S @done ; no, then just return <2.5> move.l #ToRdReqDone,-(sp) ; a3 has input DCE ptr rts ENDPROC ; End of Async Serial Driver Patch ;_____________________________________________________________________________ <57> eh ;_______________________________________________________________________________________ ; ; beginning of patch installation code ;_______________________________________________________________________________________ MacPlusEnd PROC EXPORT ; <23Apr86 LAK> RAMSysInit PROC EXPORT IMPORT MacPlusEnd,OldMacEnd,SysBase,CutBack Move.L D1,-(SP) ;save our handle ; Note that keyboard stuff comes first so that debugging is easier… InstToolTp RAMSysEvt,$1B2 ; RAM SystemEvent ; PMAB354 07Jan88 EMT Unimplemented Toolbox versions of 12 bisexual traps INCLUDE 'ToolboxCastration.a' InstOSTp InstallRDrivers,$4F ;install the InstallRDrivers patch. <20Nov85> JTFSDispatch EQU $580 Lea TFSDPatch,A0 ;install the TFSDispatch patch. Move.L A0,JTFSDispatch ; Lea FndFlPatch,A0 ;install the FileCreate Patch. Move.L A0,JFNDFilName ; Lea ExtFPtch,A0 ;install the Extend Patch. <18Nov85> Move.L A0,JExtendFile ; <18Nov85> Lea BTDelP1,A0 ;install the BTDelete patch 1 Move.L A0,JFreeNode ; Lea BTDelP2,A0 ;install the BTDelete patch 2 Move.L A0,JGetNode ; LEA BTClose,A0 ; Point to the new BTClose entry (patch #43)<23Apr86> MOVE.L A0,jBTClose ; And set the ROM up to vector through it <23Apr86> LEA BTFlush,A0 ; Point to the new BTClose entry (patch #43)<23Apr86> MOVE.L A0,jBTFlush ; And set the ROM up to vector through it <23Apr86> PEA IODone ; install IODone patch <22Nov85> MOVE.L (SP)+,jIODone ; <22Nov85> ;_____________________________________________________________________________ ; <57> Installation of the Async Serial Driver Patch ; We completely re-install the drivers to use our RAM-based ones ; from here in the patchfile. SERDVersion equ 5 IMPORT AsyncAOut,AsyncAIn,AsyncBOut,AsyncBIn PEA AsyncBOut PEA AsyncBIn PEA AsyncAOut PEA AsyncAIn MOVEQ #-6, D3 ; .AIn refnum ; ;The REGS trap bit doesnt seem to be defined anywhere, nor set in the ;_DrvrInstall trap. We need A0 to be returned, not preserved, so lets ;set it specifically. (REGS should be $100) ; @1 MOVE D3,D0 ; pass D0= refnum (-6, -7, -8, -9) _DrvrInstall ,SYS,$100 ; returns A0=driver handle _HLock ; lock it down <26Apr85> MOVE.L (A0),A0 ; MOVE.L (SP)+,A1 MOVE.L A1, (A0)+ ; (DCtlDriver) shove in driver ptr MOVE.W DrvrFlags(A1),(A0)+ ; (DCtlFlags) clear ram-based flag, set driver flags MOVE.W #SERDVersion,(A0) ; (DCtlQueue) and note new version SUBQ #1,D3 ; next driver CMP.W #-9,D3 ; past the last driver refnum? BGE.S @1 ; loop if not ; <57> End of Async Serial driver patch ;_____________________________________________________________________________ PEA UpdtJmpEntry ;install the UpdateResFile fix <06Dec85> MOVE.L (SP)+,jCmpFrm InstOSTp NewVInstall,$33 ;patch to the sound driver involves patching InstOSTp NewVRemove,$34 ; both VInstall and VRemove. PEA PtchCMSetUp ;patch the FileClose bug at CMSetUp vector MOVE.L (SP)+,jCMSetUp DGRTrap EQU $105 ; value of DragGrayRgn trap DTRTrap EQU $126 ; value of DragTheRgn trap InstToolTp DragGrayRgn,DGRTrap ; install Window manager patch ($105) <13Dec85> InstToolTp DragTheRgn,DTRTrap ; install Window manager patch ($126) <13Dec85> ;______________________________________________________________________ ; Start of Initialization code for: ;<2.9> Deferred Task Manager _DTInstall Trap, vDisptch ; EH Interrupt Handlers Lvl1Int, Lvl2Int, Lvl3Int ; ; InitIntHandler: Initialize exception dispatch tables -- ; VIA (#1) interrupts -- 8 vectors; level 1 interrupts on all Mac, Mac++ ; SCC interrupts -- 8 vectors; level 2 on Mac, Mac++ ; 68xxx exception vectors -- low mem dispatch table ; deferred task vectors -- low mem dispatch table ; ;______________________________________________________________________ import DTInstall import vDisptch import level1Int import level2Int import level3Int import plsDTQueue ; patch in the addr for Deferred Task Handler lea vDisptch ,a0 ; stuff the vector for the handler move.l a0, jDisptch lea DTInstall,A0 ; move to A0 for SetTrapAddress move.w #$A082,D0 ; get trap number _SetTrapAddress NewOS ; install _DTInstall ; ; initialize the queue header, which is up above in our code space ; lea plsDTQueue,a0 ; Plus queue, local to this code clr.w (a0)+ ; Qflags clr.l (a0)+ ; QHead clr.l (a0) ; QTail ; and finally replace the interrupt autovectors (turn of interrupts while ; we muck around with their handler vectors) move.w SR, -(sp) ori.w #HiIntMask,SR ; disable all ints lea AutoInt1,a2 ; point to main vectors in low mem lea Level1Int,a0 ; level 1 interrupt handler move.l a0,(a2)+ ; lea Level2Int,a0 ; level 2 interrupt handler move.l a0,(a2)+ lea Level3Int,a0 ; level 3 interrupt handler move.l a0,(a2)+ ; move.w (sp)+, SR ; re-enable interrupts ;_______________________________________________________________________ ; End of Initialization code for: ;<2.9> Deferred Task Manager _DTInstall Trap, vDisptch ; EH Interrupt Handlers Lvl1Int, Lvl2Int, Lvl3Int ;_______________________________________________________________________ InstOSTp MyDisHandle,$23 ; patched disposhandle <31jan86> BBM <48> InstOSTp MyReaHand,$27 ; patched Reallochandle <15apr86> BBM InstOSTp MyHandZone,$26 ; patched HandleZone <15apr86> BBM InstOSTp MyRecovHand,$28 ; patched recoverhandle <02May86> PEA SendCmdPtch ; install HD20 driver patch at SendCmd <19Dec85> MOVE.L (SP)+,jSendCmd ; <19Dec85> InstOSTp HRSRC,$67 ; set RSRC bit of handle <24Dec85 JTC> InstOSTp HNoRSRC,$68 ; clear RSRC bit of handle <24Dec85 JTC> InstOSTp HGetFlags,$69 ; get handle flags <24Dec85 JTC> InstOSTp HSetFlags,$6A ; set handle flags <24Dec85 JTC> InstOSTp PMoveHHi,$64 ; patch MoveHHi at the start <24Dec85 JTC> Lea ScavPatch,A0 ;install the Scavenger patch. <29Dec85> Move.L A0,jExtBTFile ; <29Dec85> ; ************************************************************************************ ; REMOVED BY P044. <18Feb87 DBG> ; InstOSTp NewHLock,$29 ; replace HLock <11Apr86 EHB> ; ************************************************************************************ InstOSTp MyInitZone,$19 ; <08Apr86 JTC> LEA FClosePtch,A0 ; install the FClose patch #49 <10Sep86> MOVE.L A0,jRFNCall ; <10Sep86> LEA BasicIOPtch,A0 ; install the BasicIO patch #50 <11Sep86> MOVE.L A0,jBasicIO ; <11Sep86> InstToolTp GetWVariant,$0A ; add in GetWVariant (#63) <07Jan87 DAF> InstToolTp GetCVariant,$09 ; add in GetCVariant (#64) <07Jan87 DAF> lea oldFigTrkSpd,A0 ; patch FigTrkSpd (#65) <15Jan87/TJ> move.l jFigTrkSpd,(A0) ;copy of the orig. vector, lea newFigTrkSpd,A0 move.l A0,jFigTrkSpd ; insert ours in series InstToolTp MyFixRound,$6C ; corrected FixRound (#66) <17Jan87 JTC> InstToolTp MyFix2Long,$40 ; corrected Fix2Long (#66) <17Jan87 JTC> InstToolTp MyFrac2Fix,$42 ; corrected Frac2Fix (#66) <17Jan87 JTC> InstToolTp MyFixDiv,$4D ; corrected FixDiv (#67) <22Jan87 JTC> InstToolTp MyFracDiv,$4B ; corrected FracDiv (#67) <22Jan87 JTC> InstOSTp MyStripAddress,$55 ; new StripAddress (#67) <22Jan87 JTC> InstToolTp CloseResFile,$19A ; patch CloseResFile (PM294) <08oct87 bbm> ; <1.9> 2Feb89 CCH Added Gestalt. ; <4.7> <08/19/89 pke> Moved this up here so other 'ptch' files can use Gestalt ; (e.g TextEdit needs this for 6.0.4 scripts builds and for 7.0) PtchInst 5 ; PM062 C628 25feb87 bbm added new trap rGetResource. InstToolTp NewRGetResource,$0C ; install rGetResource ; PMA207 17Jul87 EHB PackBits ; bitmaps.a InstToolTp NewPackBits,$CF ; patch PackBits ;------------------------------------------------------------------------------ ; PMA097 -- Back-patch hierarchical menus ;------------------------------------------------------------------------------ ; PMA311 24Nov87 EMT Install Menu Manager using 'ptchInstall' method. InstToolTp FindWindow,$12C ; (#PMA100) <10Mar87 DAF> InstToolTp InitWindows,$112 ; (#PMA100) <10Mar87 DAF> ; install MapFBlock patch (PM119) LEA MapFBPatch,A0 ; install patch code MOVE.L A0,jLg2Phys ; using jLg2Phys vector ; PABM150 InstOSTp mySysEnvirons,$90 ; PM243 -- PM243 Unmount patch InstOSTp UnmountPatch,$0E ; <24Aug87> ; PMAB241 26Aug87 RDC - install BadTrap patch IMPORT NewBadTrap InstToolTp NewBadTrap,$1FF ; replace Debugger trap $A9FF InstToolTp NewBadTrap,$3FF ; replace Debugger trap $ABFF InstToolTp MeasureText,$37 ; patch MeasureText (PM127) <23Mar87 CRC> ; S497 7June88 med Changed Script Manager to ptch resource PtchInst 4 ; Script Manager 7.0 extensions (must be after PtchInst 4 !!) to be included for 6.0.6 builds. IF installScriptMgrPtch27 THEN ; <5.0> <16> PtchInst 27 ; <5.0> Must load after ptch 4 ! ENDIF ; <5.0> ; ; Install the Sony VBL patch: ; MOVEA.L SonyVars,A0 ; Point back to the Sony driver variables LEA SonyVBL,A1 ; Point to the patched VBL entry point MOVE.L A1,10(A0) ; Re-direct the VBL task LEA SonyWakeUp,A0 ; Point to Sony wakeupentry point <14Oct86> MOVE.L A0,jWakeUp ; Redirect Sony wakeup routine <14Oct86> ;_____________________________________________________________________________ ; PP332 ; Install Cache control trap ;_____________________________________________________________________________ InstOSTp CacheTrap,$74 ; install the HFS RAM disk cache control trap ;_____________________________________________________________________________ ; End of Cache control trap installation ;_____________________________________________________________________________ TST.B ScsiFlag ; SCSI hardware around? <23Apr86 LAK> BMI.S @PatchSCSI ; br if so <23Apr86 LAK> ; LEA instAsync,A0 ; NOP the async driver DTR patch (no DTR on old macs) <23Apr86 LAK> ; MOVE.W #$4E71,(A0) ; <23Apr86 LAK> ; LEA instAsync2,A0 ; NOP async drvr DTR patch PMAB372 ; MOVE.W #$4E71,(A0) ; LEA OldMacEnd,A1 ; cut back to here <23Apr86 LAK> BRA CalcCutBk ; <23Apr86 LAK> <2/2/89 CCH> ; ; PMAB295 19Oct87 SHF Do extra clean up before and after loading SCSI drivers the final time. ; PMAB329 10Dec87 jwk Fixed PMAB295 to avoid 10sec delay booting with no SCSI devices attached. ; PMAB574 24Sep88 jwk Rolled enhancements to old SCSI Mgr to make it new-SCSI-Mgr-friendly. ; @PatchSCSI ROM75Load EQU $407D4E ; Mac-Plus SCSILoad Sel250msCnt EQU 43950 ; 250 msec select timeout IMPORT SCSelectTime ; timing value for select timeout InstToolTp SCSIPatch,$15 ; install the scsi patch first <11Apr86 ELR?SAB> BSR.S @ClearBus ; clear up bus problems first LEA SCSelectTime,A0 MOVE.W #Sel250msCnt/10,(A0) ; 25 msec select timeout PEA @SCSIDone ; fake a return address MOVEM.L A0-A6/D0-D7,-(SP) ; save things (ROM restores them) JMP ROM75Load ; this avoids the dreaded SCSIReset @ClearBus CLR.W -(SP) ; prepare for return value ; _SCSIStat ; get current SCSI bus status MOVE #scsiStat, -(SP) ; these lines should be MOVEQ #$15, D0 ; equivalent to _SCSIStat _GetTrapAddress ,newTool ; except that it won't crash JSR (A0) ; on a Radius Accellerator AND.W #aBSY+aSEL,(SP) ; test BSY&SEL, leave word on stack BEQ.S @ClearRts ; no BSY or SEL, so return @IsBusFloating AND.W #aSEL,(SP) ; test SEL: floating SCSI bus ? BNE.S @ClearRts ; BSY&SEL true - nothing attached ; AND.W #aMSG,(SP) ; test MSG: floating SCSI bus ? ; BNE.S @ClearRts ; PEA Scratch8 ; address for status byte PEA Scratch8+2 ; address for message byte MOVE.L #OneSecTicks*5,-(SP) ; wait up to five seconds _SCSIComplete ; try to get to Bus Free state @ClearRts ADDQ.L #2,SP ; pop off return code RTS @SCSIDone BSR.S @ClearBus ; clear up remaining bus problems LEA SCSelectTime,A0 MOVE.W #Sel250msCnt,(A0) ; restore 250 msec select timeout LEA MacPlusEnd,A1 ; cut back to here . . . <23Apr86 LAK> CalcCutBk LEA SysBase,A0 ; start of patch code <23Apr86 LAK> SUB.L A0,A1 ; size of patch code <23Apr86 LAK> MOVE.L A1,D0 ; <23Apr86 LAK> Move.L (SP)+,A0 ; restore the handle passed by SysPatch <23Apr86 LAK> BRA CutBack ; cut us back -> <23Apr86 LAK> ENDPROC UsesPtchInst ; Patch Install code ;<2.5-4april89-CEL> END