boot3/Patches/PatchPlusROM.a

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