mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-25 09:30:50 +00:00
6581 lines
271 KiB
Plaintext
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
|