mac-rom/Patches/PatchPlusROM.a
Elliot Nunn 4325cdcc78 Bring in CubeE sources
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included.

The Tools directory, containing mostly junk, is also excluded.
2017-12-26 09:52:23 +08:00

6581 lines
271 KiB
Plaintext

;
; 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 <bbm> 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 <bbm> 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 <dba> 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 <bbm> 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.
; <PMA572> 9/22/88 jwk Added Deferred Task Mgr to the Plus and SE.
; <PM515> 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.
; <PMA542> 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.
; <S497> 6/7/88 med Changed Script Manager to ptch resource
; <PM490> 5/4/88 EMT _SCSIStat breaks Radius Accellerator in MacPlus.
; <s483> 4/29/88 bbm changed hardwired constant to HiIntMask in hardwareEqu (see
; s481).
; <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).
; <PMA418> 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
; <PM400> 2/22/88 ABO Fixed a bug in PMAB301 patch for MacPlus
; <PMA399> 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.
; <PMA361> 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)
; <PMA325> 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.
; <PMA314> 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
; <PMA311> 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
; <PMA299> 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.
; <PM294> 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.
; <PM289> 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.
; <pma287> 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.
; <s263> 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)
; <PM243> 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.
; <PMA218> 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.
; <PMA207> 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.
; <PM184> 6/24/87 EMT PatchPlusROM.a: Fixed FKEYs not working in Excel
; <PM180> 4/30/87 SHF (#37) Fixed scCompare opcode bug in SCSI Manager patch.
; <PM178> 4/16/87 CJB Take out incorrect Timer mgr optimization.
; <PM175> 4/13/87 JTC Insert diagnostic ROM vector call before launch to satisfy
; Radius and other custom hardware folks.
; <PBM164> 4/7/87 JTC&JDT Fix GetStrike utility in FontMgr to avoid doomed GetHandleSize
; after GetResource of FONT sans FOND and with TempResLoad false.
; <PM153> 3/30/87 JTC Fix reg problem in SystemEvent task.
; PABM150> 3/28/87 JTC&JAF New SysEnvirons trap.
; <PM135> 3/24/87 SHF (#37) Removed parity checking from SCSI patch.
; <PM127> 3/23/87 CRC MeasureText fix for new TextEdit and Macintosh Pascal
; <PM119> 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).
; <PM120> 3/19/87 BB Fixed MountPatch (#17) to save ExtFSHook and to call other
; routines in that chain.
; <PM116> 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.
; <PMA100> 3/10/87 DAF Patched InitWindows and FindWindow to use mbdf (PMA097)
; <PMA097> 3/10/87 FJL Back-patch hierarchical menus.
; <PM091> 3/9/87 JTC Patch CompactMem to fix MoveHHi problem that would create tiny
; files.
; <PM090> 3/7/87 bbm (#69) patched _read to fix bug in openresfile.
; <PM076> 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
; <PM075> 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.
; <PM063> 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.
; <PM062> 2/25/87 bbm (#68) added new trap rGetResource.
; <PM057> 2/23/87 MBK All of the new TextEdit is being patched in.
; <PA056> 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.
; <PM049> 2/22/87 RBB (#53 re-revisited) Fixed PrimeTime even more and brought latest
; ROM code in (incl. patch of RmvTime)
; <P044> 2/18/87 DBG Patch DrawPicture,StdGetPic to parse version 2 pictures.
; <P043> 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!
; <PM184/24Jun87>
move.b evtMessage+2(a0),D1 ; Get raw keycode, use A0 not A3 <PM153> <PMAB102/10Mar87>
cmp.b #$3F, D1 ; Keyboard or keypad? <PMAB102/10Mar87>
bhi.s JSEResume ; No keypad FKEYs <PMAB102/10Mar87>
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, <C169/06oct86>
MOVE.L A0,-(SP) ; save for unlock
MOVE.L (A0),A0 ; dereference
JSR (A0)
MOVE.L (SP)+,A0 ; recover handle
_HUnlock ; unlock it <C169/06oct86>
; 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? <PWD 11Mar86>
Bne.s @9 ; Nope - check for GetFCBInfo <PWD 11Mar86>
Swap D1 ; Get access to high word <PWD 11Mar86>
Clr.W D1 ; Clear it (which GetWDCBInfo should have done) <PWD 11Mar86>
Swap D1 ; And return the trap word to the low half <PWD 11Mar86>
Bra.s @99 ; Now all's safe again <PWD 11Mar86>
@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.
;
;
; <s263> 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.
; <pma287> 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.)
; <PMAB301> 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.
; <PM400> bug in above patch if packet type is not ATP. Don't check packet type.
; <s481> 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.
; <s483> 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 <s263>
beq.s @TruVinst ; if not, just do real vinstall <s263>
move.w sr,-(sp) ; Save sr <s481>
ori.w #HiIntMask,sr ; Disable interrupts <s483>
move.l a0,-(sp) ; save new vbl element on stack <s263>
lea SoundVBL,a0 ; point at hertzfeldÕs vbl element <s263>
_VRemove ; remove sound vbl element <s263>
move.l (sp)+,a0 ; get new vbl element back in a0 <s263>
tst.w d0 ; check for error from vremove <pma287>
bne.s @popstatus ; if error then donÕt reinstall sound vbl <s481>
bsr.s @TruVinst ; install new vbl element back in queue <s263>
lea SoundVBL,a0 ; get sound vbl element, and install it <s263>
bsr.s @TruVinst ; install sound vbl element back in queue <s481>
move.w (sp)+,sr ; Restore interrupts <s481>
rts ; <s481>
@popstatus ; <s481>
move.w (sp)+,sr ; Restore interrupts <s481>
@TruVinst ; end of <s263> <s263>
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 <C914>
ADDQ #2,A0 ; adjust SCC addresses for port A
ADDQ #2,A1
@GoLvl2
ADD D0,D0 ; double vector for dispatch <C914>
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) <tj/20oct86>
movem.l D3-D7/A3-A6,SaveRegs(A1) ; save regs first, <tj/20oct86>
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 <A279/28Oct86>
BLT.S L23 ; fall into loop, guaranteed no overflow <A343/03Nov86>
BGT.S @fixover ; was bra.s until now, overflow guaranteed <A343/03Nov86>
CMP.L D1,D2 ; D1 < D2 --> CarrySet -->first bit is zero <A343/03Nov86>
BCS.S L27 ; falls in when 0 quo bits go <A343/03Nov86>
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; <C628>
;
; 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 <C669>
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 <C424/18Nov86> DAF
MOVE.L D3,D1 ; send point as parameter <C424/18Nov86> DAF
BSR CallMBarProc ; call menuBar defproc <C424/18Nov86> DAF
TST.L D0 ; test the result <C424/18Nov86> DAF
BMI.S NotOnMBar ; if +, then not on bar <C424/18Nov86> 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 <EHB 1/23/85>
BSET D0,DSWndUpdate ; cancel pending PaintBehind <EHB 1/23/85>
BSET D0,AlarmState ; reset alarm parity <EHB 1/23/85>
CLR.B WWExist ; say the window world exists <EHB 1/23/85>
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 <C168/17Sep86>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 <DAF 20Aug86>
MOVE.L #-1,D1 ; parameter is -1 for cleared bar only <DAF 20Aug86>
BSR.S CallMBarProc ; execute the defproc <DAF 20Aug86>
JMP IWReEntry ; return to ROM
;-------------------------------------------------------------------------------------------
;
; Utility -- CallMBarProc
;
; On Entry: d0 lo-word=message number, hi-word=parameter1 <FJL 3Feb87>
; 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 <DAF 20Aug86>
MOVE.L MenuList,A0 ; get the menuList head <DAF 20Aug86>
MOVE.L (A0),A0 ; handle->pointer <DAF 20Aug86>
move mbResID(a0), -(sp) ; get resource ID <FJL C428><24Jan87>
andi.w #0007, (sp) ; use low 3 bits only <FJL 24Jan87>
MOVE.W D0,-(SP) ; push the message number <DAF 20Aug86>
swap d0 ; get parameter1 in lo-word
move.w d0, -(sp) ; push parameter1 <FJL 3Feb87>
MOVE.L D1,-(SP) ; push parameter2 <DAF 20Aug86>
;
; get the mbarproc each time we call it instead of counting on low mem to be correct <FJL A/C391>
;
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 <DAF 20Aug86>
_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 <PWD 26Sep85>
MOVEQ #0,D0 ; Clear top word to get remainder as long <PWD 26Sep85>
MOVE.W D3,D0 ; Compute block offset within alloc block <PWD 26Sep85>
LSR.L #8,D0 ; 'divide' by 256 <PWD 26Sep85>
LSR.L #1,D0 ; and again by 2 to get size in phys. blocks <PWD 26Sep85>
SWAP D3 ; Restore D3 for use <PWD 26Sep85>
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' ;<PMAB449>
;____________________________________________________________________________________
; 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 ; <PMAB295>
ROMSCSI EQU $417132
SCRESETDRV EQU $4174E6 ; jsr addr for Reset SCSI bus routine <PMAB466/JWK>
SCRESETEXIT EQU $417184 ; re-entry point into the ROM <PMAB466/JWK>
NOBYTEEX EQU $417184
SCARBDONE EQU $417192 ; <PM075>
SCSELDONE EQU $4171A4 ; <PM075>
SCSENDCMD EQU $41734C ; jsr addr for "SendCMD" ROM routine <PMAB466/JWK>
SCCOMMAND EQU $4171BE ; re-entry point into the ROM <PMAB466/JWK>
ROMDEND EQU $417242
SCGETSTAT EQU $417464 ; jsr addr for "GetStat" ROM routine <PMAB466/JWK>
SCGETMSG EQU $41749A ; jsr addr for "GetMsg" ROM routine <PMAB466/JWK>
SCCYCLEPHASE EQU $417566 ; jsr addr for "CyclePhase" ROM routine <PMAB466/JWK>
SCCOMPLETE EQU $41728C ; re-entry point into the ROM <PMAB466/JWK>
SCSTDENT EQU $417294 ; <PM116>
SCWFBSY EQU $417510 ; <PM075>
SCWFNREQ EQU $41753A ; <PM075>
SCWFREQ EQU $417550 ; <PM075>
zeroReg EQU d7 ; SCSI Mgr convention <25Nov86/SHF>
maxSelector EQU 13 ; <PM075>
scParityErr EQU 11 ; <PM116>
bPERR EQU 5 ; <PM116>
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) <PM116>
cmp.w #maxSelector,d0 ; range check <PM075>
bhi.s DoSCSIUnimp ; adios <PM075>
lsl.w #1,d0 ; calculate word offsets <PMAB466/JWK>
move.w JmpTbl(pc,d0.w),d0 ; get offset to routine <PMAB466/JWK>
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) <PM075>
DC.B 0 ; SCSI Mgr state (G_State) <PMAB466/JWK>
Sel250msCnt EQU 43950 ; 250 msec select timeout <PMAB295>
SCSelectTime ; <PMAB295>
DC.W Sel250msCnt ; <PMAB295>
JmpTbl ; extended table to word offsets for sanity <PMAB466/JWK>
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 <PMAB466/JWK>
lea.l SCSIId,a0 ; point at SCSI ID variable <PMAB466/JWK>
move.b zeroReg,1(a0) ; clear the SCSI Mgr state variable <PMAB466/JWK>
jmp SCRESETEXIT ; exit through the ROM <PMAB466/JWK>
;--------------------------------------------------------------------------
;
; 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 <PMAB466/JWK>
move.w 8(a6),d2 ; get the length <PMAB466/JWK>
jsr SCSENDCMD ; jump directly the ROM "SendCMD" routine <PMAB466/JWK>
beq.s @okExit ; success, let's get out <PMAB466/JWK>
lea.l SCSIId,a0 ; point at SCSI Mgr ID variable <PMAB466/JWK>
move.b zeroReg,1(a0) ; clear the SCSI Mgr global state flag <PMAB466/JWK>
@okExit
jmp SCCOMMAND ; exit through the ROM routine <PMAB466/JWK>
;--------------------------------------------------------------------------
;
; FUNCTION SCSIGet: INTEGER;
; (8)
;
; Arbitrate for the SCSI bus. Returns 0 for success, or error.
;
DoSCSIGet ; <PM075>
lea.l SCSIId,a0 ; point to SCSI Mgr ID variable <PMAB466/JWK>
bset.b #0,1(a0) ; check if Mgr is busy (G_State)(sBusy = 1) <PMAB466/JWK>
beq.s @wasFree ; if zero, SCSI Mgr is free <PMAB466/JWK>
moveq.l #scMgrBusyErr,d0 ; we're busy now <PMAB466/JWK>
bra.s @back2ROM ; let's get out <PMAB466/JWK>
@wasFree
bsr.w Arbitrate ; arbitrate for the bus <PMAB466/JWK>
beq.s @back2ROM ; we were successful, so we're done <PMAB466/JWK>
lea.l SCSIId,a0 ; point at SCSI Mgr ID variable <PMAB466/JWK>
move.b #0,1(a0) ; clear the SCSI Mgr state (G_State) <PMAB466/JWK>
@back2ROM
jmp SCARBDONE ; return d0 and clean up <PMAB466/JWK>
;--------------------------------------------------------------------------
;
; 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 <PM075>
;--------------------------------------------------------------------------
;
; 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 <PMAB466/JWK>
add.l 8(a6),d6 ; add count to start ticks <PMAB466/JWK>
@chkStatus
moveq.l #0,d2 ; <PMAB466/JWK>
jsr SCGETSTAT ; use ROM routine to get status byte <PMAB466/JWK>
beq.s @gotStatus ; success <PMAB466/JWK>
cmp.b #scPhaseErr,d0 ; phase error ? <PMAB466/JWK>
bne.s @chkTime ; no, business as usual <PMAB466/JWK>
jsr SCCYCLEPHASE ; only called for phase errors <PMAB466/JWK>
@chkTime
cmp.l Ticks,d6 ; got the time, pal ? <PMAB466/JWK>
bhi.s @chkStatus ; still time <PMAB466/JWK>
bra.s @completeDone ; report the error <PMAB466/JWK>
@gotStatus
move.l 16(a6),a1 ; get the status byte pointer <PMAB466/JWK>
move.w d2,(a1) ; save the status byte <PMAB466/JWK>
jsr SCGETMSG ; go get the message byte <PMAB466/JWK>
bne.s @completeDone ; communication error <PMAB466/JWK>
move.l 12(a6),a1 ; get the message byte pointer <PMAB466/JWK>
move.w d2,(a1) ; save the message byte <PMAB466/JWK>
@completeDone
lea.l SCSIId,a0 ; point to SCSI Mgr ID variable <PMAB466/JWK>
move.b zeroReg,1(a0) ; clear the SCSI Mgr global state variable <PMAB466/JWK>
jmp SCCOMPLETE ; exit through ROM routine <PMAB466/JWK>
;--------------------------------------------------------------------------
;
; 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 ; <PM075>
moveq.l #iATN,d3 ; prepare for SelAtn
swap d3 ; put iATN bit in upper word
bra.s DoSelContinue ;
DoSCSISelect ; <PM075>
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 <PMAB295>
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 <PMAB466/JWK>
move.b zeroReg,1(a0) ; clear SCSI Mgr global state variable <PMAB466/JWK>
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 ; <PM075>
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 ; <PM075>
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 <PM135>
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 <PM075>
BusDelay ; put here for bsr.s proximity <PM075>
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 <PM075>
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 ; <PM180>
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 <PM116>
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 <PMA211>
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 <PM116>
move.w #DAckRd,a1 ; DMA offset <PM116>
tst.b d4 ; read or write?
bpl.s RdSetup ; <PM116>
add.l a4,a1 ; write offset for 5380 <PM116>
wreq
btst.b #bREQ,sCSR(a3) ; test for *REQ
beq.s wreq
move.b zeroReg,sTCR(a4) ; match Data Out phase <PM116>
move.b #iDMA,sMR(a4) ; set DMA mode <PM116>
move.b #iDB,sICR(a4) ; assert data bus <PM116>
move.b zeroReg,sDMAtx(a4) ; start DMA write <PM116>
bra.s ckphase
RdSetup
add.l a3,a1 ; read offset for 5380 <PM116>
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) ; <PM116>
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? <PM116>
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 <PM116>
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? <PM116>
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? <PM116>
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 <PM116>
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 ; <PM116>
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 <PM116>
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? <PM116>
bne.s DMAOff ; yes, so turn off DMA <25Nov86/SHF>
btst.b #bPM,(a0) ; examine the bus phase <PM116>
bne.s WrDone ; in phase, wait around <25Nov86/SHF>
DMAOff
move.b zeroReg,sMR(a4) ; clear DMA mode <PM116>
move.b zeroReg,sICR(a4) ; disable data bus <PM116>
RdDone
Xfer_done
tst.w d0 ; set the error codes
movem.l (sp)+,a1 ; restore it <25Nov86/SHF>
rts
Arbitrate ; <PMAB466/JWK> 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 <PMAB466/JWK>
move.b (a0),d2 ; get the CPU's SCSI ID <PMAB466/JWK>
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 <PMAB466/JWK>
GetMsg ; <PM075>
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 ; <PM075>
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 <C859>
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 ; <C846>
@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 <A357/06nov86>
SCCBRWOFF equ 0 ; SCC B side R/W offset <A357/06nov86>
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 <A357/06nov86>
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 <A357/06nov86>
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 <A446/20nov86><A357/06nov86><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 <C216/16oct86>
bra.s ToInitSCC ; go init the SCC <A363/07nov86>
;
; 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 <A363/07nov86><14Oct85>
DC.B $7F ; mask for 7-bit data <A363/07nov86><14Oct85>
DC.B $3F ; mask for 6-bit data <A363/07nov86><14Oct85>
DC.B $FF ; mask for 8-bit data <A363/07nov86><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 <C216/14oct86>
and.b #$80,D0 ; from last WR5 written, <C216/14oct86>
or.b D0,WR5AVal(A2) ; apply to new values, <C216/14oct86>
or.b D0,XmitBits(A2) ; <C216/14oct86>
move.b XmitBits(A2),D0 ; make the WR5 value used to <C216/14oct86>
move.b D0,LastWR5(A2) ; remember DTR & other bits, <C216/14oct86>
bclr #7,D0 ; and negate DTR <C216/14oct86>
move.b D0,DTRNegVal(A2) ; <C216/14oct86>
_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) <C216/14oct86><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 ; <C216/16oct86>
bclr #7,XmitBits(A2) ; no, clear the DTR bit <C216/16oct86>
bclr #7,WR5AVal(A2) ; <C216/16oct86>
@1 bclr #3,XmitBits(A2) ; always clear Tx enable <C216/16oct86>
pea @00 ; <patch> 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 ; <A357/06nov86>
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 <PMAB401>
cmpi #16,d1 ; opcode 16? (ctlOptions) <57>
beq CtlSwitchCTSClock ; <57>
CLR.L D0 ; clr D0 incase killio uses D0 as status return <PMAB401>
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) ; <patch> JUMP BACK TO ROM
RTS ; <patch>
;________________________________________________________________________
;
; 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 ; <patch>
MOVE.L #ToContOut,-(SP) ; <patch> BEQ.S ContOut
RTS ; <patch>
@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 ; <patch> BSR.S toStash
MOVE.L JStash,-(SP) ; <patch>
RTS ; <patch>
@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) ; <patch> BRA.S GoodFinish
RTS ; <patch>
PutInOurBuf
PEA @00 ; <patch> BSR GetBufRegs
MOVE.L #ToGetBufRegs,-(SP) ; <patch>
RTS ; <patch>
@00 ; <patch>
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 ; <patch> BSR.S GetBufCnt
MOVE.L #ToGetBufCnt,-(SP) ; <patch>
RTS ; <patch>
@11 ; <patch>
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 ; <patch>
MOVE.L #ToCtlXOff,-(SP) ; <patch> BEQ.S CtlXOff
RTS ; <patch>
@4 BSET #6,FlowOff(A2) ; have we negated DTR? <14Oct85>
BEQ.S @3 ; <patch>
MOVE.L #ToPut,-(SP) ; <patch> HERE'S THE ONE LINE THAT CHANGED - BNE.S @3
RTS ; <patch>
@3 MOVE.L #backToPut,-(SP) ; <patch> JUMP BACK TO ROM
InputRTS RTS ; <patch>
;________________________________________________________________________
;
; 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) ; <patch> JUMP BACK TO ROM
RTS ; <patch>
;________________________________________________________________________
;
; 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) ; <patch>
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) ;<patch> 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 <A363/07nov86>
;_DrvrInstall trap. We need A0 to be returned, not preserved, so lets <A363/07nov86>
;set it specifically. (REGS should be $100) <A363/07nov86>
;
@1 MOVE D3,D0 ; pass D0= refnum (-6, -7, -8, -9)
_DrvrInstall ,SYS,$100 ; returns A0=driver handle <A363/07nov86>
_HLock ; lock it down <A357/06nov86><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 <FJL> -- 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 <PM515>
; MOVE.W #$4E71,(A0) ; <PM515>
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 <PMAB295>
Sel250msCnt EQU 43950 ; 250 msec select timeout <PMAB295>
IMPORT SCSelectTime ; timing value for select timeout <PMAB295>
InstToolTp SCSIPatch,$15 ; install the scsi patch first <11Apr86 ELR?SAB>
BSR.S @ClearBus ; clear up bus problems first <PMAB295>
LEA SCSelectTime,A0
MOVE.W #Sel250msCnt/10,(A0) ; 25 msec select timeout <PMAB295>
PEA @SCSIDone ; fake a return address <PMAB295>
MOVEM.L A0-A6/D0-D7,-(SP) ; save things (ROM restores them) <PMAB295>
JMP ROM75Load ; this avoids the dreaded SCSIReset <PMAB295>
@ClearBus
CLR.W -(SP) ; prepare for return value <PMAB295>
; _SCSIStat ; get current SCSI bus status <PMAB295>
MOVE #scsiStat, -(SP) ; these lines should be <PM490 04May88 EMT>
MOVEQ #$15, D0 ; equivalent to _SCSIStat <PM490 04May88 EMT>
_GetTrapAddress ,newTool ; except that it won't crash <PM490 04May88 EMT>
JSR (A0) ; on a Radius Accellerator <PM490 04May88 EMT>
AND.W #aBSY+aSEL,(SP) ; test BSY&SEL, leave word on stack <PMAB329/10Dec87/JWK>
BEQ.S @ClearRts ; no BSY or SEL, so return <PMAB329/10Dec87/JWK>
@IsBusFloating
AND.W #aSEL,(SP) ; test SEL: floating SCSI bus ? <PMAB329/10Dec87/JWK>
BNE.S @ClearRts ; BSY&SEL true - nothing attached <PMAB329/10Dec87/JWK>
; AND.W #aMSG,(SP) ; test MSG: floating SCSI bus ? <PMAB329/10Dec87/JWK>
; BNE.S @ClearRts ;
PEA Scratch8 ; address for status byte <PMAB295>
PEA Scratch8+2 ; address for message byte <PMAB295>
MOVE.L #OneSecTicks*5,-(SP) ; wait up to five seconds <PMAB295>
_SCSIComplete ; try to get to Bus Free state <PMAB295>
@ClearRts
ADDQ.L #2,SP ; pop off return code <PMAB295>
RTS
@SCSIDone
BSR.S @ClearBus ; clear up remaining bus problems <PMAB295>
LEA SCSelectTime,A0
MOVE.W #Sel250msCnt,(A0) ; restore 250 msec select timeout <PMAB295>
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