mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-26 01:49:19 +00:00
5397 lines
212 KiB
Plaintext
5397 lines
212 KiB
Plaintext
;
|
||
; File: PatchSEROM.a
|
||
;
|
||
; Contains: patches for the first ROMs shipped in a Macintosh SE ($0276)
|
||
;
|
||
; Copyright: © 1985-1992 by Apple Computer, Inc., all rights reserved.
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <60> 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.
|
||
; <59> 8/30/91 DTY Define onMacPP & has3rdFloppy in this file now that they’re no
|
||
; longer available features in BBSStartup. onMacPP is 1 because
|
||
; this patch files applies to the SE ROM. has3rdFloppy is true
|
||
; because this file used to use {DefsPP}. If this file is ever
|
||
; used in a ROM build (which it probably won’t), has3rdFloppy is
|
||
; false because our new ROMs don’t do that kind of thing any more.
|
||
; <58> 6/12/91 LN removed #include 'HardwareEqu.a'
|
||
; <57> 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.
|
||
; <56> 3/4/91 dba dty: get rid of SysVers conditionals
|
||
; <55> 2/21/91 eh (djw) Fixed bug in serial driver that was preventing use of one
|
||
; port when Nike was printing on the other.
|
||
; <54> 1/30/91 dnf csd/dba, #dnf003: For 7.0, remove the patch that ensured that
|
||
; BTCBs for the catalog and extents files were deallocated on
|
||
; _Eject and _Offline. We no longer close the b*tree control
|
||
; files on _Eject and _Offline, so we no longer need to
|
||
; deallocate their BTCBs.
|
||
; <53> 1/19/91 mbs (jg) Include new ATalkPrivateEQU.a to get AGBHandle equates
|
||
; since they were removed from ATalkEQU.a
|
||
; <52> 1/19/91 eh (djw) Patch portA async serial driver headers to insert
|
||
; signature long word for use in serial driver linked patch.
|
||
; Insert signature before already patched port B driver headers.
|
||
; Change port arbitration code to call new 'atkv' Gestalt call
|
||
; instead of old 'atlk' call.
|
||
; <51> 1/14/91 eh (djw) Added external clocking support for Nike Printer to the
|
||
; Async Serial Driver.
|
||
; <50> 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
|
||
; <49> 12/14/90 dnf (jsm) Turn all patches on the ExtFSHook off for 7.0. They are
|
||
; now linked patches in LaterFileMgrPatches.a
|
||
; <48> 12/13/90 BBM (stb) move the patch to compactmem into memorymgrpatches.a.
|
||
; <47> 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 patches on _DisposeHandle inside CloseDialog and
|
||
; _ValidRect inside SetIText to DialogMgrPatches.a.
|
||
; <46> 11/20/90 JSM <dba> Move come-from patch on _GetResource inside GetNextEvent
|
||
; to disable FKEYs from the keypad to ToolboxEventMgrPatches.a,
|
||
; which means the entire _GetResource patch here is unneeded for
|
||
; 7.0.
|
||
; <45> 11/14/90 JSM <bbm> Move come-from patch on _TEAutoView to fix dialog manager
|
||
; bug to DialogManagerPatches.a.
|
||
; <44> 11/9/90 dba & gbm; Move LoadResource patch that checks for errors while
|
||
; loading WDEFs and CDEFs to WindowMgrPatches.a and
|
||
; ControlMgrPatches.a — one more step towards the obsolescence of
|
||
; this file
|
||
; <43> 9/25/90 KIP Change Sound Mgr. to a linked patch.
|
||
; <42> 9/22/90 dba get rid of Time Mgr. patching here since we now use the real
|
||
; TimeMgr.a to make a linked patch; get rid of obsolete ADB
|
||
; patches
|
||
; <41> 9/21/90 KON Make stdBits patch a linked patch and moved it to
|
||
; AllB&WPatches.a
|
||
; <40> 8/18/90 dba get rid of ptchInst 7 and 8 (Sony Format and Eject patches) as
|
||
; they are now linked patches
|
||
; <39> 8/14/90 DTY Removed PtchInst 0 since TextEdit is now a linked patch.
|
||
; <38> 8/8/90 SAM Changing DispatchHelper & ProcHelper into an old style ptch.
|
||
; •••--> Temporary <--••• Remove when the Sound ptch get converted
|
||
; into an Lptch.
|
||
; <37> 8/7/90 DTY ADBMgrPatch (ptch 34) is a linked patch now.
|
||
; <36> 7/30/90 dnf Remove installation of ptch 18 (File Manager) and ptch 6 (Btree
|
||
; Manager), now linked patches
|
||
; <35> 7/23/90 dba get rid of ptch 1 since Menu Mgr. is now a linked patch
|
||
; <34> 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
|
||
; <33> 7/20/90 DTY Remove ptchInst 10 & 11 since Bass is a linked patch now.
|
||
; <32> 7/20/90 CCH NEEDED FOR SIXPACK: Removed HwPriv patch since it is now a
|
||
; linked patch.
|
||
; <31> 7/20/90 GMR Install ptch 7 on SuperDrive ROMS as well now.
|
||
; <30> 7/16/90 gbm Kill a few warnings
|
||
; <29> 7/16/90 DDG NEEDED FOR SIXPACK: I disabled the patch I made to fix the
|
||
; button CDEF, since it causes much more problems than it fixes.
|
||
; At some point (when I have more time) I may come back and fix
|
||
; this patch for real.
|
||
; <28> 7/2/90 DTY Removed ptchInst 21 since Resource Manager extensions are now a
|
||
; linked patch.
|
||
; <27> 6/29/90 DDG NEEDED FOR SIXPACK: Added patches to SectRgn and DrawText in
|
||
; order to fix a bug in the button CDEF.
|
||
; <26> 6/26/90 DTY Removed ptchInst 2 since Notification Manager is now a linked
|
||
; patch.
|
||
; <25> 6/25/90 DTY Removed ptchInst 9 since ScrollSpeedFix now in a linked patch.
|
||
; <24> 6/19/90 VL Get rid of ptchinst 29 since MiscPatches is a linked patch.
|
||
; <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 Help Mgr is now a linked patch. Get rid of ptch 28.
|
||
; <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 ptch 29 (misc including Shutdown Manager) before ptch 33
|
||
; (PPC) because the PPC loader calls ShutdownInstall.
|
||
; <14> 4/16/90 DDG Rolled over some bug fixes from the system 6 split off sources
|
||
; back into the main ones: we now install patch 25 (generic
|
||
; patches for all systems) and we added a hwPriv patch. Helpers:
|
||
; BBM, djw
|
||
; <13> 4/11/90 dba get rid of patch to InitApplZone for 7.0; move PPC after B-Tree
|
||
; Manager
|
||
; <12> 4/4/90 KON get rid of ptch 44 and ptch 35 since they are now linked ptches.
|
||
; <11> 3/29/90 KON Added ptch 44, a QD patch for all B&W machines.
|
||
; <10> 3/23/90 NC Added ptch 43 for System 6.0.6 on up. This is for Sound.
|
||
; <9> 3/20/90 PWD Changed install of ATP SendRequest patch to check to see if
|
||
; AGBHandle is already allocated.
|
||
; <8> 3/7/90 dba change MyDisposHandle to use BackToTrap
|
||
; <7> 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)
|
||
; <6> 2/4/90 dba get rid of SysBeepPatch because it is in the Sound Mgr. patch
|
||
; <5> 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.
|
||
; <4> 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).
|
||
; <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 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.0> 12/11/89 GMR Added ptchInst 8; Sony Format patch is now in it's own patch
|
||
; file (FormatPatch.a).
|
||
; <5.9> 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) Enabled the
|
||
; New ADB Manager (which matches the code that is in the IIci ROM)
|
||
; Initialized the new LowMem TimeViaDB which was introduced with
|
||
; the IIci ROM
|
||
; <5.8> 11/21/89 EMT NEEDED FOR 6.0.5: Added humane scrolling.
|
||
; <5.7> 11/10/89 rwh NICE FOR 6.0.5: for ptch38, remove check for hwPriv already
|
||
; <5.6> 10/25/89 rwh NICE FOR 6.0.5: add ptch38, backpatch hwPriv for accelerated
|
||
; SE's.
|
||
; <5.5> 10/16/89 csd Moved the code that installs the expanded trap dispatcher to the
|
||
; start of the install section, above all other patches.
|
||
; <5.4> 10/15/89 BAL Added support for 32-Bit QuickDraw pictures via ptch 35
|
||
; <5.3> 10/14/89 GMR Re-added ptch34 - ADB manager patch, for system 7.0
|
||
; <5.2> 10/10/89 GMR Backed out ptch 34, until it can be cleaned up
|
||
; <5.1> 10/6/89 JSM Removed SnarfMan 'ptch', now PACK 13.
|
||
; <5.0> 10/3/89 GMR Added ptch 34, Gary D's new ADB manager, for 7.0.
|
||
; <4.9> 9/26/89 CVC Added the PPC Toolbox as a 'ptch'.
|
||
; <4.8> 9/4/89 PKE Install Script Manager 7.0 extensions, ptch 27.
|
||
; <4.7> 8/28/89 SES Removed references to nFiles.
|
||
; <4.6> 8/22/89 PKE NEEDED FOR 6.0.4 (SCRIPTS BUILD) & 7.0: Conditionalize 4.5 for
|
||
; Scripts604 OR (SysVers >= $700)
|
||
; <4.5> 8/19/89 PKE NEEDED FOR 6.0.4 (SCRIPTS BUILD) & 7.0: Moved PtchInst 5
|
||
; (Gestalt) ahead of (most) other PtchInsts so they can use
|
||
; Gestalt.
|
||
; <4.4> 8/9/89 GMR Added ptch 29 - BigBang only patches for all ROMs
|
||
; <4.3> 8/1/89 BG Modified the conditional in <4.1> to be (SysVers >= $700) to
|
||
; make sure that this patch never appears in a 6.0.x build.
|
||
; <4.2> 7/25/89 GMR Needed for 6.0.4: Added Sony Eject patch (ptch 7)
|
||
; <4.1> 7/7/89 BG Added Gary D.'s optimized A-Trap dispatcher (which adds an
|
||
; extended Toolbox trap table) to the Mac SE.
|
||
; <4.0> 6/30/89 BBM Added resource mgr extensions ('ptch' 21)
|
||
; <3.9> 6/29/89 RLC Added HelpMgr PtchInst #28
|
||
; <3.8> 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.7> 6/13/89 dnf Moved btree ptch install after hfs70 ptch install.
|
||
; <•3.6> 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.5> 5/31/89 CEL Only defined Spline_Font variable if it is undefined - makes it
|
||
; easier to build test 6.0.4 systems
|
||
; <3.4> 5/31/89 prp Added Alias Manager Support
|
||
; <3.3> 5/30/89 dnf Added HFS 7.0 Enhancements (ptch 18)
|
||
; <3.2> 5/26/89 CCH Conditionalized out install of 6.0.4 PrGlue.
|
||
; <3.1> 5/25/89 CCH Re-added PrGlue patch taken out in v2.4 for 6.0.4.
|
||
; <3.0> 5/23/89 EVA SysVers conditional is $700 for deferred task patch
|
||
; <2.9> 5/23/89 jaz Change version conditionals to check for $700 instead of $604
|
||
; <2.8> 5/19/89 jaz Add code to patch in Gary D's new Extended Time Manager
|
||
; <2.7> 5/18/89 ggd (Really EH) Add Deferred Task Manager and patched Level 1 thru 3
|
||
; interrupt handlers.
|
||
; <2.6> 5/16/89 EMT Moved include of ToolTrapFix so that it would be executed at
|
||
; installation time.
|
||
; <2.5> 5/13/89 EMT Added Window Manager extensions (Layers).
|
||
; <2.4> 5/8/89 NMB Replaced PrGlue with Ginsu's PrGlue.
|
||
; <2.3> 5/3/89 CEL Rolling in Bass for the first time into EASE…
|
||
; <2.2> 4/18/89 JSM Install SnarfMan 'ptch'.
|
||
; <2.1> 4/17/89 CCH Rolled out Altair changes.
|
||
; <2.0> 3/22/89 CCH Now looks for DiskCachePriv.a in {AIncludes}.
|
||
; <1.9> 3/21/89 KST Added install code to bring in Btree Manager.
|
||
; <1.8> 3/17/89 CCH Fixed install of Cache Control Trap so that it installs on
|
||
; 6.0.4.
|
||
; <1.7> 2/22/89 CCH Added install code to bring in Gestalt patch.
|
||
; <1.6> 2/21/89 JB (DNF, actually) These files seems to work, so I'm checking them
|
||
; back in.
|
||
; <1.5> 2/20/89 JB Cleaned up revision history comments.
|
||
; <1.4> 2/20/89 JB Moved MapFBlock and "not a Mac disk" ExtFSHook patches from
|
||
; BeforePatches.a
|
||
; <•1.3> 2/20/89 JB Moved cache control trap from BeforePatches.a
|
||
; <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/25/88 jwk Rolled enhancements to old SCSI Mgr to support new SCSI Mgr
|
||
; trap.
|
||
; <PMA572> 9/22/88 jwk Added Deferred Task Mgr to the Plus and SE.
|
||
; 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.
|
||
; <PA511> 6/24/88 JB Added patch to fix UpdAltMDB to use correct disk address on
|
||
; 1440k disks
|
||
; <S497> 6/7/88 med Changed Script Manager to ptch resource
|
||
; <PA489> 5/4/88 EMT Addition to PA419 - Remove Radius SetTrapAddress patch.
|
||
; <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 dispose 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).
|
||
; <PA419> 3/4/88 EMT Radius FPD SE disables PMA314 - patch PA176 to reassert.
|
||
; <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 PMAB372
|
||
; <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
|
||
; 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
|
||
; PMAB344> 12/22/87 JSP Modified to not install sony driver patches if version number of
|
||
; driver is greater than one.
|
||
; 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 PMAB295 to avoid 10 sec delay when booting with no SCSI
|
||
; devices attached.
|
||
; <PMA325> 12/8/87 jw new SysBeep, calls SndPlay like on Mac II
|
||
; PMAB318> 11/30/87 jw Added new improved sound manager.
|
||
; PMAB317> 11/28/87 EMT Added Notification Manager.
|
||
; PMAB315> 11/25/87 RWW Err, GetResource doesn't return resNotFound? Fixed ptchInstall
|
||
; <PMA314> 11/25/87 EMT Patch GetResource to get MBDF instead of ROM override on Plus,
|
||
; SE
|
||
; PMAB308> 11/24/87 RWW Added ptchInstall, which installs 'ptch' resources. This saves
|
||
; keeping duplicate copies of identical code in several patch
|
||
; files.
|
||
; <PMA311> 11/24/87 EMT Install Menu Manager using 'ptchInstall' method. Undoes PMA097.
|
||
; PMAB309> 11/24/87 RWW Massive, world-shattering change - yank TE patches and do this
|
||
; whizzy new installation. This one patch, in one fell swoop,
|
||
; replaces the following old, sometimes ugly patches: P001, P002,
|
||
; P003, P004, P013, P016, P017, P018, P024, P025, P026, PO31,
|
||
; P032, P033, P034, P035, P036, P037, P038, P039, P040, P041,
|
||
; PA064, PA065, PA066, PA070, PA085, PABM139, PABM197, PABM198,
|
||
; PA199, PA200, PABM201, PABM202, PABM203, PABM250
|
||
; PMAB305> 11/22/87 DAF Fixed RgnOp buffer calculation bug.
|
||
; PMAB301> 11/15/87 ABO Fix ATP delayed duplicate response bug
|
||
; <PMA299> 10/27/87 NMB Fixed DrText using _StdTxMeas so that QuickDraw could cope with
|
||
; fonts >128Kb.
|
||
; <PM298> 10/27/87 NMB Replaced FMSwapFont since the Font Manager couldn't cope with
|
||
; fonts >128Kb. That has been fixed.
|
||
; PMAB295> 10/20/87 SHF Modified last call to SCSILoad -- increased patched select
|
||
; timeout to 25 msec (was 5); made more robust for CD ROM.
|
||
; <PAB291> 9/26/87 DBG Changed mouse button debounce time back to 20 msec, and changed
|
||
; code so that mouse downs always get noticed. The code will now
|
||
; never discard a down/up pair, only up/down pairs.
|
||
; <PAB288> 9/24/87 CSL Reduced the mouse button delayed time from 20 msec. to 10 msec.
|
||
; PMAB284> 9/21/87 JTC Fix patch to MoveHHi to prevent dinky free blocks from being
|
||
; created. Patch involves just adding to the part of the loop
|
||
; already patched.
|
||
; <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.
|
||
; <PA267> 9/8/87 CRC Fixed silly bug in GetMaskTab (FMSwapFont) patch.
|
||
; <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.
|
||
; PMAB253> 8/27/87 CRC Fixed MaxSizeRsrc in FontMgr for Radius (once again)
|
||
; PABM250> 8/25/87 MBK TextEdit: Patched DisposPtr and StackSpace to fix Pixel2Char
|
||
; dispose bug
|
||
; PMAB241> 8/25/87 RDC Added patch for BadTrap handler routine to save registers before
|
||
; exiting to SysError routine - needed for new MacsBug.
|
||
; <PAB229> 7/23/87 WRL MouseDrvr MouseDrvr New, improved mouse button debouncing code
|
||
; for ADB machines.
|
||
; <PMA218> 7/22/87 JTC InitApplZone InitApplZone 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.
|
||
; <PMA211> 7/20/87 SHF SCSIRead,SCSIWrite,SCSIRBlind,SCSIWBlind SCSIMgr.a SCSI Mgr:
|
||
; fixed scLoop bug in TIB interpreter.
|
||
; PMAB210> 7/20/87 DAF LoadResource CallWindow,CallControl Improved handling of CDEFs
|
||
; and WDEFs for Juggler
|
||
; <PMA207> 7/17/87 EHB PackBits PackBits Patched packBits to allow scanlines > 127
|
||
; bytes
|
||
; <PA199> 7/9/87 MBK GetFontInfo TESetStyle TextEdit: Fix to SE patch that set point
|
||
; size of 0 to 1 (should leave it)
|
||
; PABM203> 7/9/87 MBK FindLine RecalLines TextEdit: Fix to deletion bug (display would
|
||
; get messed up)
|
||
; PABM202> 7/9/87 MBK FindLine RecalLines TextEdit: Fix to recalibration bomb when
|
||
; text length = 32,767
|
||
; PABM201> 7/9/87 MBK FindLine SetLineHite TextEdit: Fix to allow fixed line heights
|
||
; to work
|
||
; <PA200> 7/9/87 MBK TextWidth Char2Pixel TextEdit: Fix to check if style record
|
||
; before accessing style handle
|
||
; PABM197> 7/9/87 MBK HLock TEStylInsert TextEdit: Fix to TEStylInsert call when
|
||
; record is deactivated
|
||
; PABM198> 7/9/87 MBK HLock,HUnlock,TEDispose,TESetSelect,TEClick,TEDispatch,TEKey
|
||
; TextEdit: Fix to allow styles to be set at null selection
|
||
; <PAB191> 7/2/87 CSL ADBReInit Kbd.a Added pre- and post- processing routine hook for
|
||
; ADBReinit.
|
||
; <PAB192> 7/2/87 EMT ADBProc KbdDrvr Use JADBProc to clean up on ADBReInit
|
||
; PABM186> 7/1/87 CRC GetResource RealFont Took out PA165 and replaced GetHandleSize
|
||
; with MaxSizeRsrc. also added part of underline fractEnable bug
|
||
; fix below.
|
||
; PABM187> 7/1/87 CRC GetMaskTable FMSwapFont two bugs: if fractEnable is false, do
|
||
; not use style widths w/o strike underline measures wrong with
|
||
; fractEnable true: pesky BEQ should have been a BMI
|
||
; <PAB185> 6/29/87 ABO Fix NBP write-to-zero on lookup bug.
|
||
; <PA182> 5/21/87 CSL DiskSelect DiskSelect Fixed the performance problem of the upper
|
||
; internal floppy drive.
|
||
; <s483> 4/27/87 bbm changed a hardwired number to HiIntMask (see s481).
|
||
; <PA176> 4/13/87 JTC Launch Launch Add diagnostic vector for last-chance patching
|
||
; before Finder launch.
|
||
; PABM139> 3/26/87 MBK FindLine TextEdit.a: RecalLines Fixed recal deletion bug.
|
||
; <PAB117> 3/19/87 CRC LoadResource FMSwapFont if fast path fails because of disk
|
||
; switch, recover with panache.
|
||
; PBAM109> 3/17/87 CRC ValidRect GetIText patched ValidRect to restore register
|
||
; clobbered by DrawItem in SetIText
|
||
; <PMA100> 3/10/87 DAF FindWindow wmgr InitWindows wmgr Patched InitWindows and
|
||
; FindWindow to use mbdf (PMA097)
|
||
; PMAB102> 3/10/87 EMT GetResource GetNextEvent Fixed all patches to not use FKEYs when
|
||
; code came from keypad.
|
||
; <PMA097> 3/10/87 FJL Back-patch hierarchical menus.
|
||
; <PA088> 3/9/87 JTC CompactMem mem mgr: MoveHHi Stop creating bogus tiny blocks.
|
||
; <PAB87> 3/6/87 CSL Patch JcrsrTask to support absolute cursor position.
|
||
; <PA085> 3/5/87 MBK HUnlock TextEdit.a:InsertRecal fixed obscure recal bug
|
||
; <PA077> 3/3/87 CRC FreeMem font manager changed to MaxBlock (better call)
|
||
; <PA077> 3/3/87 CRC FixMul font manager fix rounding bug in scaling
|
||
; <PA077> 3/3/87 CRC FixRound font manager allow font sizes greater than 127
|
||
; <PA077> 3/3/87 CRC GetResource font manager look for empty FONDs, too small fonts,
|
||
; etc.
|
||
; <PA081> 3/3/87 SHF SCSICmd SCSIMgr.a:SCSICmd fix too short a timeout waiting for
|
||
; cmd phase
|
||
; <P023> 1/13/87 JNP Print trap ($A8FD) patch. A bug was fixed after the Maui ROMs
|
||
; were frozen. Hence this patch. The bugfix was as follows: 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. Added includes for PrEqu.a and PrPrivate.a
|
||
; <P015> 12/12/86 EMT GetOSEvent OSEventMgr.a:GetOSEvent OSEventAvail
|
||
; OSEventMgr.a:OSEventAvail KbdDrvr kbd.a:KbdDrvr Keyboard global
|
||
; shuffle for Excel
|
||
; <P014> 12/10/86 TJ WakeUp SonyQDUtil.a Recursion path via PrimeTime PrimeTime
|
||
; TimeMgr.a inconsistencies at some boundary conditions
|
||
; <C480> 12/1/86 Fixed FOutExtra set up for Laserwriter fonts in cache
|
||
;
|
||
|
||
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('onMacPP') = 'UNDEFINED') then
|
||
onMacPP: equ 1
|
||
endif
|
||
|
||
;
|
||
; has3rdFloppy was defined for {DefsPP}. Make it so for System builds.
|
||
;
|
||
|
||
if (&type('has3rdFloppy') = 'UNDEFINED') then
|
||
if forROM then
|
||
has3rdFloppy: equ 0
|
||
else
|
||
has3rdFloppy: equ 1
|
||
endif
|
||
endif
|
||
|
||
STRING ASIS
|
||
|
||
LOAD 'StandardEqu.d'
|
||
include 'ATalkEqu.a' ; <PABM150>
|
||
include 'ATalkPrivateEqu.a' ; <53>
|
||
include 'ApplDeskBus.a'
|
||
include 'AppleDeskBusPriv.a'
|
||
include 'HardwarePrivateEqu.a'
|
||
include 'PrEqu.a'
|
||
include 'PrPrivate.a'
|
||
include 'ColorEqu.a'
|
||
include 'SCSIEqu.a'
|
||
include 'SonyEqu.a'
|
||
include 'PrintCallsEqu.a'
|
||
include 'DiskCachePriv.a' ; P003 <21Feb89><2.0>
|
||
INCLUDE 'PatchMacros.a'
|
||
INCLUDE 'ScriptPriv.a' ; <16>
|
||
INCLUDE 'GestaltEqu.a'
|
||
|
||
SONYVERLOC EQU $434709 ; location for checking sony version number
|
||
|
||
ROM76Fix MAIN EXPORT
|
||
IMPORT RamSysInit
|
||
EXPORT SysBase,CutBack
|
||
|
||
; Cut back Code:
|
||
;
|
||
; SysBase is the entry point for ROM76Fix. 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
|
||
DC.W $0276 ; patch ID $76 machine $02.
|
||
DC.W 0 ; 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 #######################################
|
||
|
||
|
||
;___________________________________________________________________________
|
||
;
|
||
; P014 TJ 09dec86 TJ WakeUp SonyQDUtil.a
|
||
; Raised int level to prevent recursion through PrimeTime.
|
||
;
|
||
; A patch to the Sony Driver's wakeup routine to prevent driver re-entry.
|
||
; Symptoms are that the file server crashes or hangs randomly when accessing
|
||
; the HD-20, every few weeks.
|
||
;
|
||
; Derived from ROM75FIX patch #52.
|
||
;
|
||
;___________________________________________________________________________
|
||
|
||
SonyWakeUp PROC EXPORT
|
||
|
||
;
|
||
;Special addresses:
|
||
;
|
||
ROMWakeup EQU $4351a0 ; ROM wakeup entry point
|
||
|
||
or.w #$0300,sr ; lock out VIA interrupts,
|
||
jmp ROMWakeup ; And enter normal wakeup routine
|
||
|
||
ENDPROC
|
||
|
||
;___________________________________________________________________________
|
||
; P015 12Dec86 EMT GetOSEvent OSEventMgr.a:GetOSEvent
|
||
; OSEventAvail OSEventMgr.a:OSEventAvail
|
||
; KbdDrvr kbd.a:KbdDrvr
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchSEROM.a 12Dec86 #P015 (GetOSEvent) (GetOSEvent)
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchSEROM.a 12Dec86 #P015 (OSEventAvail) (OSEventAvail)
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchSEROM.a 12Dec86 #P015 (KbdDrvr) (KbdDrvr)
|
||
;
|
||
; This patch is to shuffle around some globals used for autokey events.
|
||
;
|
||
; Microsoft Excel expects KeyLast to be 0 if no auto key events are pending.
|
||
; When ADB was introduced, it became necessary to use the entire event message,
|
||
; not just the low word. KeyLast was thus too small to contain the repeat
|
||
; event message. KeyLast was relocated to KbdVars and given the name NewKeyLast.
|
||
; KeyLast became KbdLast and held the ADB address of the last keyboard typed on.
|
||
; This caused Excel to thrash when calculating. Thus, KeyLast has been restored
|
||
; to its original meaning; NewKeyLast becomes HiKeyLast and contains the high
|
||
; word of the repeating event message. KbdLast is relocated to KbdVars+2
|
||
; (HiKeyLast+2). All these changes have been reflected in nSysEqu.a.
|
||
;_______________________________________________________________________
|
||
|
||
GetOSEvent PROC EXPORT
|
||
EXPORT OSEventAvail,KbdDrvr
|
||
|
||
PostEvent EQU $403EE6
|
||
OsEventTail EQU $403FEA ; Address of rest of GetOSEvent
|
||
|
||
PEA OsEventTail
|
||
;_______________________________________________________________________
|
||
;
|
||
; Routine: OSEventavail
|
||
;
|
||
; Arguments: A0 (input) -- pointer to user event record (32-bit)
|
||
; D0 (input) -- set of events desired (event mask)
|
||
; D0 (output) -- 0=non-null event returned, -1=null event
|
||
; returned
|
||
; A0 (output) -- pointer to user event record
|
||
; A1 (output) -- pointer to event queue element when D0=0
|
||
; (used internally by GetNextEvent)
|
||
;
|
||
; Function: This routine polls for availability of certain types of events.
|
||
; The user-specified event record format is identical to that of
|
||
; the queue element, except for the queue header fields. If no
|
||
; events are available, the null event is returned along with
|
||
; a -1 result code in D0.
|
||
;
|
||
; EventAvail is also called by GetNextEvent.
|
||
;
|
||
; Calling sequence: MOVE.W #EventMask,D0
|
||
; LEA EventBuffer,A0
|
||
; _EventAvail
|
||
;
|
||
; Other: uses D0,D1,D2,A0,A1
|
||
;_______________________________________________________________________
|
||
NoEvtAvail EQU -1 ; (moved from SysErr.Text)
|
||
EvtOffset EQU 6 ; event record offset from start of
|
||
; event queue element
|
||
|
||
OSEventAvail LEA EventQueue,A1 ; get address of event queue
|
||
|
||
; Since PostEvent could dequeue the first element at any time, the event you
|
||
; are on may suddenly be recycled and you may end up dequeueing a different event
|
||
; or suddenly find yourself at the end of the queue when you were just at the
|
||
; beginning. By disabling interrupts during the search, this is avoided.
|
||
|
||
MOVE SR,-(SP) ; save interrupt state
|
||
ORI #HiIntMask,SR ; no event-generating interrupts <C173 24Sep86>
|
||
MOVE.L QHead(A1),D1 ; get address of 1st element
|
||
BEQ.S TstAutoEvent ; if nil, check for auto events
|
||
|
||
EventALoop MOVE.L D1,A1 ; get pointer into A-reg
|
||
MOVE EvtNum+EvtOffset(A1),D1 ; get its event number
|
||
BTST D1,D0 ; is it one we want?
|
||
BNE.S GotEventAvail ; if so, we got one!
|
||
MOVE.L QLink(A1),D1 ; follow the link to the next one
|
||
BNE.S EventALoop ; if we got one, check it out
|
||
|
||
; there wasn't an event in the queue for us, so check for auto events
|
||
|
||
TstAutoEvent AND.W SysEvtMask,D0 ; figure in system mask for pseudo-evts
|
||
BTST #AutoKeyEvt,D0 ; do we want this kind?
|
||
BEQ.S NoEventAvail ; go on if not
|
||
MOVE.W HiKeyLast, D0
|
||
SWAP D0
|
||
MOVE.W KeyLast, D0
|
||
TST.L D0 ; Key down to auto-repeat?
|
||
BEQ.S NoEventAvail ; if not, return null event
|
||
|
||
MOVE.L Ticks,D1 ; check first threshold
|
||
MOVE.L D1,D2
|
||
SUB.L KeyTime,D1
|
||
CMP KeyThresh,D1
|
||
BLT.S NoEventAvail ; br if not time yet
|
||
|
||
SUB.L KeyRepTime,D2 ; check second threshold
|
||
CMP KeyRepThresh,D2
|
||
BLT.S NoEventAvail ; br if not time yet
|
||
|
||
MOVE.L Ticks,KeyRepTime ; repeat it: first note the time
|
||
MOVE.L A0,-(SP) ; save pointer to user's buffer
|
||
MOVE #AutoKeyEvt,A0 ; get event number
|
||
JSR PostEvent ; go post it (event message already in D0)
|
||
MOVE.L A0,A1 ; get pointer to event queue element
|
||
MOVE.L (SP)+,A0 ; restore pointer to user's buffer
|
||
; and return the event
|
||
|
||
GotEventAvail MOVE (SP)+,SR ; restore interrupt state
|
||
MOVEQ #(EvtBlkSize/4),D0 ; get size of evt record in longwords
|
||
MOVEM.L A0-A1,-(SP) ; preserve regs
|
||
ADD.L #EvtOffset,A1 ; bump to record part of event element
|
||
|
||
@1 MOVE.L (A1)+,(A0)+ ; move it into user's buffer
|
||
SUBQ #1,D0
|
||
BNE.S @1 ; loop till done
|
||
|
||
MOVEM.L (SP)+,A0-A1 ; get regs back
|
||
RTS ; D0 is zero
|
||
|
||
; there wasn't any event available so return the null event in the users event
|
||
; record and a flag in D0
|
||
|
||
NoEventAvail BSR.S FillRecord ; fill in record for null events
|
||
MOVE (SP)+,SR ; restore interrupt state
|
||
CLR.W EvtNum(A0) ; return the null event
|
||
CLR.L EvtMessage(A0) ; zero message for null events
|
||
MOVEQ #NoEvtAvail,D0 ; and D0 non-zero
|
||
RTS
|
||
|
||
; FillRecord fills out the standard fields in an event record pointed to by A0
|
||
|
||
FillRecord MOVE.L Ticks,EvtTicks(A0) ; fill in the current time
|
||
MOVE.L Mouse,EvtMouse(A0) ; and the current mouse point
|
||
|
||
MOVE KeyMap+6,D1 ; get meta-key states
|
||
ROL.W #1,D1 ; rotate around
|
||
MOVE.B D1,EvtMeta(A0) ; update metakey field
|
||
|
||
MOVE.B MBState,EvtMBut(A0) ; get mouse button state
|
||
RTS
|
||
|
||
;______________________________________________________________________
|
||
;
|
||
; Routine: KbdDrvr
|
||
; Arguments: D0.B ADB Command
|
||
; A0 ADB Buffer address
|
||
; A1 ADB Completion Routine Address (= KbdServ)
|
||
; A2 ADB Data Address
|
||
; Output: None
|
||
; Function: Reads buffer and posts keyboard events as appropriate.
|
||
; Side Effects: Trashes A0, A1, D0, D1, D2, D3
|
||
;
|
||
; Modification History:
|
||
; 26 Jun 86 EMT Created
|
||
; 15 Jul 86 EMT Updated to use KCHR resource
|
||
; 21 Jul 86 EMT Complete rewrite - to use new _KeyTrans
|
||
; 3 Oct 86 EMT Added LED bells & whistles
|
||
;<A230/17Oct86> EMT D1 is no longer a parameter to this routine. Must get ADB Address from D0
|
||
;______________________________________________________________________
|
||
|
||
; Keyboard driver data
|
||
KBufCount EQU 2 ; <C201/07Oct86>
|
||
KBufLen EQU 10 ; 8 bytes + length + inuse <C201/07Oct86>
|
||
|
||
KMAPPtr EQU $00
|
||
KeyBits EQU KMAPPtr+4
|
||
KCHRPtr EQU KeyBits+(128/8)
|
||
DeadKey EQU KCHRPtr+4
|
||
KNoADBOp EQU DeadKey+4 ; <C201/07Oct86>
|
||
KNumBufs EQU KNoADBOp+1 ; <C201/07Oct86>
|
||
KFirstBuf EQU KNumBufs+1 ; <C201/07Oct86>
|
||
KbdDSize EQU KFirstBuf+(KBufCount*KBufLen) ; <C201/07Oct86>
|
||
|
||
; KMAP offsets
|
||
KMid EQU $00
|
||
KMtype EQU $01
|
||
KMvers EQU KMid+2
|
||
KMstart EQU KMvers+2
|
||
KMnumEx EQU KMstart+128
|
||
KMstEx EQU KMnumEx+2
|
||
|
||
KbdDrvr ; <C93/29Jul86>
|
||
MOVE.L A2, D3 ; See if A2 actually contains a pointer
|
||
BEQ KbdDone ; If not, can't go on.
|
||
|
||
MOVE.L A0, A1 ; Save A0 in A1 <A230/17Oct86>
|
||
LSR.W #4, D0 ; Shift ADB Address down to low nibble <A230/17Oct86>
|
||
MOVEQ #$F, D1 ; Mask for ADB Address <A230/17Oct86>
|
||
AND.L D1, D0 ; D0 now contains ADB Address <A230/17Oct86>
|
||
MOVE.L D0, D3 ; Save it in D3 <A274/27Oct86>
|
||
LEA -10(SP), SP ; Build parameter block on stack <A230/17Oct86>
|
||
MOVE.L SP, A0 ; Point to it <A230/17Oct86>
|
||
_GetADBInfo ; <A230/17Oct86>
|
||
|
||
ROR.L #8, D3 ; Rotate ADB Address to high byte <A230/17Oct86>
|
||
MOVE.W (SP)+, D3 ; Put Device Type, Orig Addr in low word<A230/17Oct86>
|
||
ADDQ.L #8, SP ; Clear off the rest of the stack <A230/17Oct86>
|
||
SWAP D3 ; D3 is now Device Type, Orig Addr, ADB Addr, Unused <A230/17Oct86>
|
||
|
||
MOVE.B 1(A1), D0 ; Get first stroke <A230/17Oct86>
|
||
MOVE.B 2(A1), -(SP) ; Save second one on stack <A230/17Oct86>
|
||
BSR.S KeyIn
|
||
MOVE.B (SP)+, D0 ; Get second stroke
|
||
|
||
;______________________________________________________________________
|
||
;
|
||
; Routine: KeyIn
|
||
; Arguments: D0.B Raw Keycode
|
||
; D3.L Device Type, Orig Addr, ADB Addr, Unused
|
||
; A2 Private data area
|
||
; Output: None
|
||
; Function Translates keycode and posts event as appropriate.
|
||
; Side Effects: Trashes A0, A1, D0, D1, D2, D3
|
||
; Called From: KbdDrvr twice, (1 BSR, 1 fall-through)
|
||
;______________________________________________________________________
|
||
KeyIn
|
||
CMP.B #$FF, D0 ; Is it not a key?
|
||
BEQ KbdDone ; Skip if so
|
||
|
||
CLR.W KeyLast ; Stop repeating <***>
|
||
CLR.W HiKeyLast ; Stop repeating <***>
|
||
|
||
MOVEQ #$7F, D1 ; Mask = 01111111 binary
|
||
AND.B D0, D1 ; Clear all but low 7 bits
|
||
|
||
MOVE.L KMAPPtr(A2), A1 ; Get KMAP table address
|
||
MOVE.B KMstart(A1, D1), D3 ; Get device independent keycode <C201/07Oct86>
|
||
BPL.S NoExcept ; Handle normally if high bit clear <C201/07Oct86>
|
||
|
||
; An exception has been indicated. Find the correct entry in the exception
|
||
; table and handle as appropriate.
|
||
BCLR #7, D3 ; Clear the high bit <C201/07Oct86>
|
||
LEA KMnumEx(A1), A0 ; Get to the beginning of the exceptions<C201/07Oct86>
|
||
MOVE.W (A0)+, D2 ; Number of entries in table <C201/07Oct86>
|
||
BEQ.S NoExcept ; Skip if none <C201/07Oct86>
|
||
SUBQ.W #1, D2 ; Turn it into a zero-based count <C201/07Oct86>
|
||
|
||
ExLoop
|
||
CMP.B (A0)+, D0 ; See if this is the one <C201/07Oct86>
|
||
BEQ FoundEx ; Skip if so <C201/07Oct86>
|
||
MOVE.B 1(A0), D1 ; Get the string length <C201/07Oct86>
|
||
LEA 2(A0, D1), A0 ; Point to the next entry <C201/07Oct86>
|
||
DBRA D2, ExLoop ; Go around again <C201/07Oct86>
|
||
|
||
NoExcept
|
||
MOVEQ #0, D2 ; Clear out D2 <C201/07Oct86>
|
||
MOVE.B D3, D2 ; Copy virtual keycode to D2 <C201/07Oct86>
|
||
LSR.W #3, D2 ; Divide by 8 for byte offset
|
||
|
||
TST.B D0 ; Up or down key?
|
||
BMI.S KeyUp ; Skip around if key up
|
||
BSET D3, KeyBits(A2, D2) ; Set it for key down
|
||
BRA.S Hammer
|
||
KeyUp
|
||
BCLR D3, KeyBits(A2, D2) ; Clear it for key up
|
||
BSET #7, D3 ; Remember key up for raw key.
|
||
|
||
Hammer
|
||
MOVEM.L KeyBits(A2), D0-D2/A0
|
||
MOVEM.L D0-D2/A0, KeyMap ; Hammer in the correct keymap
|
||
MOVE.L D3, D0 ; Bits 15-8 contain ADB address
|
||
LSR.L #8, D0 ; Put it in the low byte <C219/14Oct86>
|
||
MOVE.B D0, KbdLast ; Stuff it down
|
||
SWAP D0 ; Now get DeviceType
|
||
MOVE.B D0, KbdType ; Update KbdType to show last one used
|
||
|
||
; The next two instructions build the byte of modifier flags from the
|
||
; global key state information. This works because the modifier flags
|
||
; exist in bits $37 to $3E, which appear in the following manner:
|
||
; Byte | 6 | 7 |
|
||
; Bit |37 36 35 34 33 32 31 30|3F 3E 3D 3C 3B 3A 39 38|
|
||
; |^^ | ^^ ^^ ^^ ^^ ^^ ^^ ^^|
|
||
MOVE.W KeyBits+6(A2), D0 ; Get modifier word
|
||
ROL.W #1, D0 ; Rotate in command key
|
||
|
||
SUBQ.L #4, SP ; Make room for result
|
||
MOVE.L KCHRPtr(A2), -(SP) ; Push address of KCHR resource
|
||
MOVE.W D3, -(SP) ; Push keycode (w/o modifiers)
|
||
MOVE.B D0, (SP) ; Put modifiers where they belong
|
||
PEA DeadKey(A2) ; Push address of dead key state
|
||
_KeyTrans
|
||
|
||
MOVE.W (SP)+, D0 ; Get the high word first
|
||
BEQ.S NextWord ; Skip if null
|
||
BSR.S PostIt ; Otherwise post the event
|
||
NextWord
|
||
MOVE.W (SP)+, D0 ; Get the other word
|
||
BEQ.S KbdDone ; If null, we're done
|
||
|
||
;______________________________________________________________________
|
||
;
|
||
; Routine: PostIt
|
||
; Arguments: D0.W ASCII Code
|
||
; D3.W ADB Address in high byte and raw keycode in low byte
|
||
; Output: None
|
||
; Function Posts the keyboard event as appropriate.
|
||
; Side Effects: Trashes A0, D0, D1
|
||
; Called From: KeyIn twice, (1 BSR, 1 fall-through)
|
||
;
|
||
; Modification History:
|
||
; 25 Jun 86 EMT Created
|
||
; 22 Jul 86 EMT Changed order of event data (FHRL -> HFRL)
|
||
;<A230/17Oct86> EMT Clear the up/down bit in the event message
|
||
;______________________________________________________________________
|
||
PostIt
|
||
ROR.W #8, D0 ; Swap ASCII high and low byte (xxLH)
|
||
SWAP D0 ; Move to high word (LHxx)
|
||
MOVE.W D3, D0 ; Move in ADB address and raw keycode (LHFR)
|
||
ROL.L #8, D0 ; Rotate around (HFRL)
|
||
|
||
TST.B D3 ; Key up or down?
|
||
BMI.S PostKeyUp ; Skip if key up
|
||
MOVE.L Ticks, D1
|
||
MOVE.L D1, KeyTime ; Mark the time for auto repeat
|
||
MOVE.L D1, KeyRepTime
|
||
MOVE.W D0, KeyLast ; Save event message <***>
|
||
SWAP D0
|
||
MOVE.W D0, HiKeyLast ; Save high word too <***>
|
||
SWAP D0
|
||
MOVE #KeyDwnEvt, A0 ; Get event number
|
||
_PostEvent ; Post it
|
||
KbdDone
|
||
RTS ; And leave
|
||
PostKeyUp
|
||
MOVE #KeyUpEvt, A0 ; Get event number
|
||
BCLR #15, D0 ; Clear the up/down bit in the raw keycode <A230/17Oct86>
|
||
_PostEvent ; Post it
|
||
RTS ; And leave
|
||
|
||
; End KbdDrvr <C93/29Jul86>
|
||
|
||
;______________________________________________________________________
|
||
;
|
||
; FoundEx
|
||
; An exception exists for this particular keystroke. Process it appropriately.
|
||
;______________________________________________________________________
|
||
FoundEx ; <C201/07Oct86>
|
||
MOVE.B (A0)+, D1 ; Get the operand
|
||
BPL.S @notXORKey ; Skip if not <A274/27Oct86>
|
||
|
||
MOVEQ #0, D2 ; Clear out D2
|
||
MOVE.B D3, D2 ; Copy virtual keycode to D2
|
||
LSR.W #3, D2 ; Divide by 8 for byte offset
|
||
BTST D3, KeyBits(A2, D2) ; Get current key state
|
||
SEQ D0 ; Invert and put in D0
|
||
|
||
@notXORKey ; <A274/27Oct86>
|
||
MOVEQ #$F, D2 ; Prepare mask for ADB op
|
||
AND.B D1, D2 ; D2 is ADB op w/o net address
|
||
BEQ.S KbdDone ; If ADB op = 0 (Bus Reset), ignore key
|
||
|
||
TST.B KNoADBOp(A2) ; See if we should even do this
|
||
BNE NoExcept ; Skip if not
|
||
MOVEM.L D0/A1, -(SP) ; Save D0 & A1
|
||
MOVE.L A0, -(SP) ; Data address = mask
|
||
CMP.B #TalkCmd, D2 ; Is it a talk command?
|
||
BGE.S @kbdTalk ; Skip if so <A274/27Oct86>
|
||
PEA KbdBufFree ; Completion routine = KbdBufFree
|
||
BRA.S @kbdBufAlloc ; <A274/27Oct86>
|
||
@kbdTalk ; <A274/27Oct86>
|
||
PEA KbdListen ; Completion Routine = KbdListen
|
||
|
||
@kbdBufAlloc ; <A274/27Oct86>
|
||
LEA KNumBufs(A2), A1 ; Point to the number of available buffers
|
||
MOVE.B (A1)+, D1 ; Get the number of buffers
|
||
BEQ.S @kNoBufAvail ; Skip if none available <A274/27Oct86>
|
||
SUBQ.W #1, D1 ; Turn it into a zero based count
|
||
@kBufLoop ; <A274/27Oct86>
|
||
TST.B (A1)+ ; Is the buffer busy?
|
||
BEQ.S @kGotABuf ; No, Go use it <A274/27Oct86>
|
||
LEA KBufLen-1(A1), A1 ; Point to the next one
|
||
DBRA D1, @kBufLoop ; Go around again <A274/27Oct86>
|
||
BRA.S @kNoBufAvail ; It's a loss <A274/27Oct86>
|
||
|
||
@kGotABuf ; <A274/27Oct86>
|
||
MOVE.B D0, -1(A1) ; Store the up/down state in the busy info
|
||
BSET #1, -1(A1) ; Make sure it shows up as busy
|
||
MOVE.L A1, -(SP) ; Buffer Address
|
||
|
||
MOVE.B (A0), D1 ; Get length of source string
|
||
CMP.B #8, D1 ; Greater than 8?
|
||
BLS.S @kStrCopyLoop ; If not, no problem <A274/27Oct86>
|
||
MOVEQ #8, D1 ; Copy only the first 8 to avoid trashing mem
|
||
@kStrCopyLoop ; <A274/27Oct86>
|
||
MOVE.B (A0)+, (A1)+ ; Start copying the string
|
||
DBRA D1, @kStrCopyLoop ; Repeat D1+1 times <A274/27Oct86>
|
||
|
||
MOVE.W D3, D0 ; Get the FDB Address
|
||
CLR.B D0 ; Clear out the low byte
|
||
LSR.W #4, D0 ; Shift it down to form high nibble of ADB Command
|
||
OR.B D2, D0 ; Include low op nibble
|
||
MOVE.L SP, A0 ; Point to parameter block
|
||
_ADBOp ; Pray that everything is OK
|
||
BNE.S @kOpFailed ; Branch if not <A274/27Oct86>
|
||
ADDQ.L #4, SP ; Pop Buffer Address
|
||
@kNoBufAvail ; <A274/27Oct86>
|
||
ADDQ.L #8, SP ; Pop Completion and Data Address
|
||
MOVEM.L (SP)+, D0/A1 ; Restore D0 & A1
|
||
BRA NoExcept ; Finish dealing with the keystroke
|
||
|
||
@kOpFailed ; <A274/27Oct86>
|
||
MOVE.L (SP)+, A1 ; Get the buffer address
|
||
CLR.B -1(A1) ; Mark it as not busy
|
||
BRA.S @kNoBufAvail ; Punt <A274/27Oct86>
|
||
|
||
; End FoundEx <C201/07Oct86>
|
||
|
||
;______________________________________________________________________
|
||
;
|
||
; Routine: KbdListen
|
||
; Arguments: D0.B ADB Command
|
||
; D1.L DeviceType, OrigAddr, ADBAddr, Unused (byte order)
|
||
; A0 ADB Buffer Address
|
||
; A1 ADB Completion Routine Address (= KbdListen)
|
||
; A2 ADB Data Address
|
||
; Output: None
|
||
; Function: Sets or clears bits in mask pointed to by A2 in buffer pointed
|
||
; to by A0. Used to alter values of registers in ADB devices.
|
||
; Side Effects: Trashes A0, A1, A2, D0, D1, D2
|
||
;
|
||
; Modification history:
|
||
; 3 Oct 86 EMT Created
|
||
;______________________________________________________________________
|
||
KbdListen ; <C201/07Oct86>
|
||
MOVE.L A0, A1 ; Copy A0 into A1 so as to avoid trashing A2
|
||
MOVEQ #0, D1 ; Clear out D1
|
||
MOVE.B (A1)+, D1 ; Get length of buffer
|
||
MOVE.B (A2)+, D2 ; Get length of mask
|
||
CMP.B D2, D1 ; Is mask length smaller?
|
||
BLS.S @notSmall ; Skip if not <A274/27Oct86>
|
||
MOVE.B D2, D1 ; Use the mask length instead
|
||
@notSmall ; <A274/27Oct86>
|
||
; (A2) is a mask for (A0), 0 meaning don't change, 1 meaning clear or set
|
||
; depending upon the value of -1(A0).
|
||
TST.B -1(A0) ; PL = clear, MI = set
|
||
BPL.S @endClrLoop ; <A274/27Oct86>
|
||
BRA.S @endSetLoop ; <A274/27Oct86>
|
||
|
||
@setLoop ; <A274/27Oct86>
|
||
MOVE.B (A2)+, D2 ; Get the mask byte
|
||
OR.B D2, (A1)+ ; Set the correct bits
|
||
@endSetLoop ; <A274/27Oct86>
|
||
DBRA D1, @setLoop ; Go around again <A274/27Oct86>
|
||
BRA.S @kLoopDone ; <A274/27Oct86>
|
||
|
||
@clrLoop ; <A274/27Oct86>
|
||
MOVE.B (A2)+, D2 ; Get the mask byte
|
||
NOT.B D2 ; Invert it
|
||
AND.B D2, (A1)+ ; Clear the correct bits
|
||
@endClrLoop ; <A274/27Oct86>
|
||
DBRA D1, @clrLoop ; Go around again <A274/27Oct86>
|
||
|
||
@kLoopDone ; <A274/27Oct86>
|
||
CLR.L -(SP) ; No data address needed
|
||
PEA KbdBufFree ; Completion routine = KbdBufFree
|
||
MOVE.L A0, -(SP) ; Use the buffer one more time
|
||
MOVE.L SP, A0 ; Point to parameter block
|
||
BCLR #2, D0 ; Turn the talk into a listen command
|
||
_ADBOp
|
||
BNE.S @kLSuccess ; Branch on success <A274/27Oct86>
|
||
|
||
MOVE.L (SP), A0 ; Get the buffer address
|
||
CLR.B -1(A0) ; Mark it as not busy
|
||
@kLSuccess ; <A274/27Oct86>
|
||
LEA 12(SP), SP ; Pop the parameter block
|
||
RTS
|
||
|
||
; End KbdListen <C201/07Oct86>
|
||
|
||
;______________________________________________________________________
|
||
;
|
||
; Routine: KbdBufFree
|
||
; Arguments: D0.B ADB Command
|
||
; D1.L DeviceType, OrigAddr, ADBAddr, Unused (byte order)
|
||
; A0 ADB Buffer Address
|
||
; A1 ADB Completion Routine Address (= KbdListen)
|
||
; A2 ADB Data Address
|
||
; Output: None
|
||
; Function: Marks the buffer pointed to by A0 as free.
|
||
; Side Effects: None
|
||
;
|
||
; Modification history:
|
||
; 3 Oct 86 EMT Created
|
||
;______________________________________________________________________
|
||
KbdBufFree ; <C201/07Oct86>
|
||
CLR.B -1(A0)
|
||
RTS
|
||
; End KbdBufFree <C201/07Oct86>
|
||
;___________________________________________________________________________
|
||
;
|
||
|
||
;____________________________________________________________________________________
|
||
; P019 C570 23Dec86 ABO VInstall atalk:lap.a
|
||
; PA073 2Mar87 ABO VInstall atalk:nonres.a
|
||
; PAB185 29Jun87 ABO VInstall atalk:nonres.a
|
||
; s263 7sep87 bbm VInstall sounddriver
|
||
;
|
||
; P019 is to fix a rare(!!) bug in lap.a within the MPP driver.
|
||
; PB073 Fixes a re-entrancy problem in nonres.a within MPP.
|
||
; PAB185 Fixes an NBP lookup bug where if the response comes back too quickly it
|
||
; is written to location zero.
|
||
;
|
||
; 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.
|
||
;
|
||
; If we're doing a VInstall from Nonres, and the queue element we're installing
|
||
; is already there, don't install. If we're doing a lookup, skip the first write.
|
||
;
|
||
; 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.)
|
||
; 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 a hardwired number to HiIntMask (see s481).
|
||
|
||
NewVInstall PROC EXPORT
|
||
|
||
CalledFrom EQU $1C ; Where we were called from (return addr)
|
||
SkipBytes EQU 18 ; No. of bytes to skip write (PAB185)
|
||
|
||
VBLHnd EQU $43375C ; MPP VBL task address in ROM
|
||
ROMVInstall EQU $402C50 ; ROM VInstall address
|
||
NRVBLHnd EQU $434232 ; Nonres 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 ; <s263>
|
||
MOVE.L VBLAddr(A0),D1 ; D1 = VBL task address
|
||
AND.L MaskBC,D1 ; Mask off high bits to be sure
|
||
CMP.L #VBLHnd,D1 ; Called from MPP VBL task?
|
||
BNE.S @1 ; Branch if not
|
||
PEA NewVBLHnd ; Push address of patch
|
||
MOVE.L (SP)+,VBLAddr(A0) ; Set it
|
||
@1 CMP.L #NRVBLHnd,D1 ; Called from NBP VBL task?
|
||
BNE.S @30 ; Branch if not
|
||
|
||
; PAB185 start
|
||
MOVE.L -4(A0),A2 ; A2 -> queue element from call
|
||
CMP #LookupName,CSCode(A2) ; Was it a lookup request?
|
||
BNE.S @5 ; Branch if not
|
||
TST.B Count(A2) ; Check count
|
||
BEQ.S @3 ; Branch if zero (leave alone)
|
||
ADDQ.B #1,Count(A2) ; Need to add one since aren't sending now
|
||
@3 ADD.L #SkipBytes,CalledFrom(SP) ; Skip past the write
|
||
MOVE #1,VBLCount(A0) ; Set to send out real soon
|
||
; PAB185 end
|
||
|
||
@5 MOVE SR,-(SP) ; Save SR
|
||
MOVE #$2600,SR ; Disable interrupts
|
||
LEA VBLQueue+QHead,A2 ; A2 -> Head of VBL queue
|
||
@10 TST.L (A2) ; Done?
|
||
BEQ.S @20 ; Branch if so
|
||
MOVE.L (A2),A2 ; A2 -> next element
|
||
CMP.L A2,A0 ; Matches the one we're installing?
|
||
BNE.S @10 ; Loop if not
|
||
MOVE (SP)+,SR ; Restore SR
|
||
MOVEQ #0,D0 ; Indicate no error
|
||
RTS ; Return (already installed)
|
||
|
||
@20 MOVE (SP)+,SR ; Restore SR
|
||
@30 JMP ROMVInstall ; Jump to ROM VInstall code
|
||
|
||
NewVBLHnd MOVE SR,-(SP) ; Save interrupt status
|
||
MOVE #$2600,SR ; Interrupts off (SCCLockout)
|
||
JSR VBLHnd ; Call VBL task
|
||
MOVE (SP)+,SR ; Restore interrupts
|
||
RTS ; That's it
|
||
|
||
;___________________________________________________________________________
|
||
; P021 C491 08Dec86 DAF GetWVariant WindowMgr2.a:GetWVariant
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchSEROM.a 08Dec86 #P021 (GetWVariant) (GetWVariant)
|
||
;
|
||
;
|
||
; 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
|
||
|
||
;___________________________________________________________________________
|
||
; P022 C491 08Dec86 DAF GetCVariant ControlMgr1.a:GetCVariant
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchSEROM.a 08Dec86 #P022 (GetCVariant) (GetCVariant)
|
||
;
|
||
;
|
||
; 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
|
||
|
||
;___________________________________________________________________________
|
||
; PMA207 Cxxx 17Jul87 EHB PackBits
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchSEROM.a 17Jul87 #PMA207 (PackBits) (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'
|
||
|
||
|
||
;___________________________________________________________________________
|
||
; PA061 C628 25feb87 bbm added new trap rGetResource.
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchSEROM.a 25feb87 #PA061 (rGetResource) (rGetResource)
|
||
;
|
||
; 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
|
||
|
||
grStFr equ $0E ; size of the stack frame. (see note above)
|
||
|
||
NewrGetResource PROC EXPORT ;
|
||
|
||
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
|
||
|
||
|
||
;____________________________________________________________________________________
|
||
; PA081 03Mar87 SHF SCSICmd SCSIMgr.a:SCSICmd
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchSEROM.a 03Mar87 #PA081 (SCSICmd) (SCSICmd)
|
||
;
|
||
; This is a SCSI Manager fix for the timeout waiting for Command phase
|
||
; (the old value was found to be too short for some disk drives).
|
||
;
|
||
;
|
||
|
||
SCSIPatch PROC EXPORT
|
||
EXPORT NewSCSIGet,NewSCSICmd, NewSCSIRead, NewSCSIRBlind, NewSCSIWrite, NewSCSIWBlind
|
||
|
||
ROMGetArb EQU $41A2A0 ; "bsr Arbitrate" entry point <PMAB466/JWK>
|
||
ROMGetExit EQU $41A2AA ; finish the SCSIGet call <PMAB466/JWK>
|
||
ROMCmdDone EQU $41A2E4 ; finish the SCSI command
|
||
ROMWfnReq EQU $41A898 ; wait for *REQ to go away
|
||
ROMWfReq EQU $41A8C8 ; wait for *REQ
|
||
|
||
zeroReg EQU d7 ; SCSI Manager convention
|
||
|
||
; should be in a separate "SCSIMgrPrivate" include file <PMAB466/JWK>
|
||
numSCSIVect EQU 24 ; max. number of selectors <C936/06Nov87> <PMAB466/JWK>
|
||
jmpTblSize EQU numSCSIVect*4 ; <C936/06Nov87> <PMAB466/JWK>
|
||
G_State EQU jmpTblSize+1 ; byte <PMAB466/JWK>
|
||
|
||
;--------------------------------------------------------------------------
|
||
;
|
||
; FUNCTION SCSICmd(Buffer: Ptr, Count: INTEGER): INTEGER;
|
||
; (10) (8) (14)
|
||
;
|
||
; Send the target the given command. Returns 0 for success, or error.
|
||
;
|
||
|
||
NewSCSICmd
|
||
move.l 10(a6),a2 ; get the cmdblk address
|
||
move.w 8(a6),d2 ; get the length
|
||
|
||
; calculate a timeout of 256 ms (was 16 ms)
|
||
|
||
moveq.l #0,d3 ; clear upper word
|
||
move.w TimeSCCDB,d3 ; timing constant (1 ms.)
|
||
lsl.l #8,d3 ; multiply by 256
|
||
move.l d3,d4 ; set up d4 as high word
|
||
swap d4
|
||
|
||
move.b #iCD,sTCR+WrOffs(a3) ; match on cmd+write phase
|
||
move.w d3,d1 ; low word of count
|
||
move.w d4,d5 ; high word of count
|
||
jsr ROMWfReq ; wait for *REQ
|
||
bne.s CmdDone ; no *REQ
|
||
|
||
btst.b #bPM,sBSR(a3) ; does the phase still match?
|
||
bne.s CmdDbra ; branch if phase is OK
|
||
moveq.l #scPhaseErr,d0 ; else report it
|
||
bra.s CmdDone ; return the error
|
||
|
||
NextByte
|
||
move.b (a2)+,sODR+WrOffs(a3) ; load a command byte
|
||
move.b #iDB,sICR+WrOffs(a3) ; assert the data bus
|
||
|
||
move.w d3,d1 ; low word of count
|
||
move.w d4,d5 ; high word of count
|
||
jsr ROMWfReq ; wait for *REQ
|
||
bne.s CmdDone ; no *REQ
|
||
|
||
move.b #iACK+iDB,sICR+WrOffs(a3) ; set *ACK
|
||
move.w d3,d1 ; low word of count
|
||
move.w d4,d5 ; high word of count
|
||
jsr ROMWfnReq ; wait for *REQ to go away
|
||
bne.s CmdDone ; didn't go away
|
||
move.b zeroReg,sICR+WrOffs(a3) ; deassert *ACK and *DB
|
||
CmdDbra
|
||
dbra d2,NextByte ; do this for all bytes
|
||
moveq.l #0,d0 ; return success
|
||
|
||
CmdDone
|
||
jmp ROMCmdDone ; finish up in the ROM
|
||
|
||
;———————————————————————————————————————————————————————————————————————————————————————
|
||
;
|
||
; PMAB466 13Apr88 JWK SCSIGet SCSIMgr.a
|
||
;
|
||
; This cleans up the SCSIGet arbitration scheme. A "bset" instruction is used to
|
||
; test-and-set the SCSI Mgr's G_State global state variable. The ROM implementation
|
||
; could allow two processes into the SCSI Mgr code.
|
||
;
|
||
NewSCSIGet
|
||
bset.b #0,G_State(a4) ; mark SCSI Mgr state as "busy" <PMAB466/JWK>
|
||
beq.s @1 ; if zero, SCSI Mgr was free <PMAB466/JWK>
|
||
moveq.l #scMgrBusyErr,d0 ; SCSI Mgr is busy <PMAB466/JWK>
|
||
jmp ROMGetExit ; get out <PMAB466/JWK>
|
||
@1
|
||
jmp ROMGetArb ; jump to "bsr Arbitrate" and continue <PMAB466/JWK>
|
||
|
||
;____________________________________________________________________________________
|
||
; PMA211 20Jul87 SHF SCSIRead,SCSIRBlind,SCSIWrite,SCSIWBlind SCSIMgr.a:(see previous)
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchSEROM.a 20Jul87 #PMA211 (SCSIRead,SCSIRBlind,SCSIWrite,SCSIWBlind) (SCSIRead,SCSIRBlind,SCSIWrite,SCSIWBlind)
|
||
;
|
||
; This fixes the scLoop bug in the TIB interpreter where the interpretation was
|
||
; being aborted when the count field decremented to 0.
|
||
;
|
||
|
||
;--------------------------------------------------------------------------
|
||
;
|
||
; 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.
|
||
;
|
||
|
||
ROMDataXfer EQU $41A51C ; main data transfer (read/write)
|
||
ROMDataEnd EQU $41A376 ; finish up after TIB interpretation
|
||
|
||
|
||
NewSCSIWBlind
|
||
bset #15,d4 ; set blind mode flag
|
||
NewSCSIWrite
|
||
st d4 ; set flag for writes
|
||
bra.s DataCommon
|
||
|
||
NewSCSIRBlind
|
||
bset #15,d4 ; set blind mode flag
|
||
|
||
NewSCSIRead ; only start for reads
|
||
move.b #iIO,sTCR+WrOffs(a3) ; match Data In phase <PMA211>
|
||
move.b #iDMA,sMR+WrOffs(a3) ; DMA mode <PMA211>
|
||
move.b zeroReg,sIDMArx+WrOffs(a3) ; start DMA for a read <PMA211>
|
||
|
||
DataCommon
|
||
moveq.l #bDMAR,d3 ; bit for DREQ test used in DataXFER
|
||
move.l 8(a6),a1 ; get the control block pointer
|
||
bra.s exec ; branch into loop to continue
|
||
|
||
|
||
c_compare
|
||
move.b #1,d4 ; this means compare to DataXFER
|
||
; FALL THROUGH to c_inc
|
||
|
||
c_inc ; INC Addr,count
|
||
jsr ROMDataXFER ; move some data
|
||
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
|
||
beq.s c_loop ; 5
|
||
addq.w #4,d0
|
||
beq.s c_inc ; 1
|
||
subq.w #1,d0
|
||
beq.s c_noinc ; 2
|
||
subq.w #5,d0
|
||
beq.s c_stop ; 7
|
||
addq.w #4,d0
|
||
beq.s c_add ; 3
|
||
subq.w #1,d0
|
||
beq.s c_move ; 4
|
||
subq.w #2,d0
|
||
beq.s c_nop ; 6
|
||
subq.w #2,d0
|
||
beq.s c_compare ; 8
|
||
|
||
moveq.l #scBadParmsErr,d0 ; garbage parameters...
|
||
bra.s data_end
|
||
|
||
|
||
c_noinc ; NOINC addr,count
|
||
jsr ROMDataXFER ; move some data
|
||
beq.s next_cmd ; & process next command
|
||
bra.s data_end
|
||
|
||
c_add ; ADD addr,data
|
||
add.l d2,(a2) ; the count added to the where
|
||
bra.s next_cmd
|
||
|
||
c_move ; MOVE addr1,addr2
|
||
move.l d2,a0
|
||
move.l (a2),(a0) ; simple enough
|
||
bra.s next_cmd
|
||
|
||
c_loop ; LOOP relative addr,count
|
||
subq.l #1,d2 ; drop the count
|
||
beq.s next_cmd ; if count = 0, go to next instruction
|
||
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
|
||
jmp ROMDataEnd
|
||
|
||
|
||
;_________________________________________________________________________________________ <50> 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.
|
||
;
|
||
;_________________________________________________________________________________________
|
||
; QuantumWBlindSE - 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
|
||
; a6 = SCSI stack frame
|
||
; d7 = zero
|
||
;
|
||
Opt noclr ; set optimization level to no clr's <50> djw
|
||
|
||
Export QuantumWBlindSE
|
||
|
||
QuantumWBlindSE
|
||
|
||
maxOpcode Equ 8 ; max TIB opcodes (from SCSIPriv.a) <50> 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+WrOffs(a3) ; set to match data out phase (to zero)
|
||
move.b #iDMA,sMR+WrOffs(a3) ; enable DMA in mode register
|
||
move.b #iDB,sICR+WrOffs(a3) ; assert data bus in initiator command reg
|
||
move.b d7,sDMAtx+WrOffs(a3) ; 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
|
||
jmp (ROMDataEnd) ; continue in ROM <50> 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 of NCR 53C80
|
||
; a4 = ptr to SCSI globals
|
||
;
|
||
; 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
|
||
|
||
OldBusVct Equ -8
|
||
|
||
@savedregs Reg d2-d4/a1-a2/a5
|
||
|
||
; Setup for the transfer by installing our bus exception handler and saving
|
||
; registers.
|
||
|
||
movem.l @savedregs,-(sp)
|
||
|
||
lea.l sBSR(a3),a1 ; a1 = sBSR(a3) by convention
|
||
|
||
lea @Done,a5 ; set a5 as return addr from bus error
|
||
move.l BusErrVct,OldBusVct(a6) ; keep old vector
|
||
lea @BusErrHandler,a0 ; get addr of exception handler
|
||
move.l a0,BusErrVct ; install it in exception table
|
||
|
||
move.l SCSIHsk,a0 ; point to addr for pseudo-dma (hhsk)
|
||
adda.l #wroffs,a0 ; add in the write offset
|
||
|
||
moveq.l #noErr,d0 ; assume no error
|
||
move.l d2,d1 ; make a copy of the count - is it zero ?
|
||
beq @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.
|
||
|
||
sub.l #1,d2 ; dec number of bytes to xfer
|
||
move.b (a2)+,(a0) ; write data byte to output register
|
||
|
||
; 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 @Done ; exit
|
||
|
||
; Perform the write to the SCSI chip. First align the bytes to words, then
|
||
; align them to 32 byte chunks. Transfer the bulk of the data in 32 byte
|
||
; blocks.
|
||
; Reg d2.l = number of bytes to move
|
||
|
||
@doWrite
|
||
cmpi.l #3,d2 ; check for very short copy
|
||
bls.s @veryShort ; skip alignment if very short
|
||
|
||
move.l a2,d0 ; get addr of data buffer
|
||
andi.l #$00000003,d0 ; check for long word alignment
|
||
beq.s @Aligned ; if no alignment needed
|
||
subq.l #4,d0 ; bias by 4 to get correct index
|
||
add.l d0,d2 ; adjust the byte count (d0 = neg)
|
||
add.l d0,d0 ; adjust to word index
|
||
jmp @Aligned(pc,d0.w) ; do the alignment
|
||
move.b (a2)+,(a0) ; move a byte
|
||
move.b (a2)+,(a0) ; move a byte
|
||
move.b (a2)+,(a0) ; move a byte
|
||
@Aligned
|
||
move.l d2,d4 ; save tail byte count
|
||
lsr.w #2,d2 ; adjust to number of longs to move
|
||
moveq.l #7,d0 ; mask for starting index
|
||
and.l d2,d0 ; number of long words to move first
|
||
neg.w d0 ; negate to index backwards
|
||
add.w d0,d0 ; d0 = convert to index by 6 byte entries
|
||
move.w d0,d3 ; ...d3 = original value*2
|
||
add.w d0,d0 ; ...d0 = original value*4
|
||
add.w d3,d0 ; ...d0 = original value*6
|
||
lsr.l #3,d2 ; number of 32 byte blocks to move
|
||
move.l d2,d3 ; get number of 32*64K byte blks to move
|
||
swap d3 ; count in low word
|
||
jmp @CopyStart(pc,d0.w) ; jump into the loop
|
||
|
||
@CopyLoop move.l (a2)+,d0 ; ...fill d0 with 4 bytes
|
||
movep.l d0,0(a0) ; ...write 4 bytes to SCSI port
|
||
move.l (a2)+,d0 ; do this for 32 bytes
|
||
movep.l d0,0(a0)
|
||
move.l (a2)+,d0
|
||
movep.l d0,0(a0)
|
||
move.l (a2)+,d0
|
||
movep.l d0,0(a0)
|
||
move.l (a2)+,d0
|
||
movep.l d0,0(a0)
|
||
move.l (a2)+,d0
|
||
movep.l d0,0(a0)
|
||
move.l (a2)+,d0
|
||
movep.l d0,0(a0)
|
||
move.l (a2)+,d0
|
||
movep.l d0,0(a0)
|
||
@CopyStart dbra d2,@CopyLoop ; loop in chunks of 32 bytes
|
||
dbra d3,@CopyLoop ; loop in chunks of 32*64K bytes
|
||
|
||
andi.l #$00000003,d4 ; check for tail alignment
|
||
move.l d4,d2 ; d2 = number of bytes remaining
|
||
|
||
@veryShort
|
||
neg.w d2 ; negate to index backwards
|
||
add.w d2,d2 ;
|
||
jmp @Remaining(pc,d2.w) ; write remaining bytes
|
||
move.b (a2)+,(a0) ; move a byte
|
||
move.b (a2)+,(a0) ; move a byte
|
||
move.b (a2)+,(a0) ; move a byte
|
||
@Remaining
|
||
|
||
; 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
|
||
move.l OldBusVct(a6),BusErrVct ; restore previous Bus Error vector
|
||
movem.l (sp)+,@savedregs
|
||
tst.w d0 ; set the condition codes
|
||
rts ; we're done
|
||
|
||
|
||
;_________________________________________________________________________________________
|
||
; BusErrHandler - SCSI manager's bus exception handler
|
||
;
|
||
; Hardware handshaking data transfers require that the target peripheral be ready to
|
||
; receive or transmit a long word of data within 16 microseconds. Failure of the
|
||
; target to keep up will result in a bus error. In 68000 machines, no retries are
|
||
; possible so the transfer fails. It is up to the driver to retry.
|
||
;
|
||
; Determine whether the bus error belongs to the SCSI manager by examining the fault
|
||
; address. It should be an offset from the SCSIHsk base.
|
||
;
|
||
; Entry: a3 = base address of SCSI chip
|
||
; a5 = address to return to if bus exception
|
||
; a6 = SCSI mgr local stack frame ptr
|
||
;
|
||
; Output: d0 = error code
|
||
;
|
||
|
||
@BusErrHandler
|
||
move.l d0,-(sp) ; save d0
|
||
|
||
; Access to a number of SCSI addresses could cause a bus exception. Mask off the low
|
||
; bits of the fault address to get the base address. If it matches the SCSI chip's
|
||
; base address
|
||
|
||
moveq.l #$ffffff9c,d0 ; mask = $ffffff9c
|
||
and.l 2(sp),d0 ; clear variable bits of the fault address
|
||
cmp.l SCSIHsk,d0 ; was it a SCSI chip access ?
|
||
beq.s @ourErr ; if so, start processing the bus error
|
||
|
||
; Bus exception caused by someone else - call original exception handler
|
||
|
||
move.l (sp)+,d0 ; restore d0
|
||
move.l OldBusVct(a6),-(sp) ; jump to old bus error handler
|
||
rts
|
||
|
||
; Pop group 0 bus exception stack frame from stack and replace it with a normal
|
||
; group 1 (3 word) frame. Place a new return address in the exception frame and RTE.
|
||
|
||
@ourErr
|
||
move.w 8(sp),d0 ; get sr from stack
|
||
adda.w #7*2,sp ; dispose of the 7-word frame
|
||
move.l a5, -(sp) ; new return address
|
||
move.w d0,-(sp) ; sr value
|
||
|
||
; Determine whether this was a phase change or a device timeout from hardware handshaking
|
||
|
||
moveq.l #scBusTOErr,d0 ; assume a slow peripheral
|
||
btst.b #bREQ,sCSR(a3) ; is *REQ present ?
|
||
beq.s @ErrorDone ; no *REQ - assume timeout error
|
||
btst.b #bPM,sBSR(a3) ; phase change?
|
||
bne.s @ErrorDone ; no phase change
|
||
moveq.l #scPhaseErr,d0 ; return phase change error
|
||
@ErrorDone
|
||
rte ; 'return' from the fake exception
|
||
|
||
Endp
|
||
Opt all ; set optimization back to preset level <50> djw
|
||
|
||
;____________________________________________________________________________________
|
||
; PAB87 06Mar87 CSL patch out the JcrsrTask to support absolute cursor position.
|
||
; The whole Jcrsrtask routine is replaced by the patch below.
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchSEROM.a 06Mar87 #PAB87 (JcrsrTask) (JcrsrTask)
|
||
;
|
||
|
||
CrsrPtch PROC EXPORT
|
||
|
||
;
|
||
; ===================================================================
|
||
; Constants. Size of the mapping table.
|
||
; ===================================================================
|
||
;
|
||
MaxL EQU 8 ; Maximum value of L
|
||
;FDBByte0 EQU $164
|
||
;FDBByte1 EQU $165
|
||
;
|
||
; ===================================================================
|
||
; Globals. First words of this resource.
|
||
; ===================================================================
|
||
;
|
||
Cnt EQU 0 ; word: number of valid error deltas
|
||
MaxCnt EQU Cnt+2 ; word: limit on number of error deltas
|
||
Err7 EQU MaxCnt+2 ; word: time-7 error magnitude
|
||
Err6 EQU Err7+2 ; word: time-6 error magnitude
|
||
Err5 EQU Err6+2 ; word: time-5 error magnitude
|
||
Err4 EQU Err5+2 ; word: time-4 error magnitude
|
||
Err3 EQU Err4+2 ; word: time-3 error magnitude
|
||
Err2 EQU Err3+2 ; word: time-2 error magnitude
|
||
Err1 EQU Err2+2 ; word: time-1 error magnitude
|
||
Error EQU Err1+2 ; word: accumulated error
|
||
GSize EQU Error+2
|
||
;
|
||
;
|
||
; ===================================================================
|
||
; Code. @MouseMap+EntryOff
|
||
; ===================================================================
|
||
;
|
||
TST.B CrsrNew ; Mouse changed?
|
||
BEQ Done ; No … return
|
||
TST.B CrsrBusy ; Cursor locked?
|
||
BNE Done ; Yes … return
|
||
;
|
||
TST.B CrsrCouple ; Cursor coupled to mouse?
|
||
BEQ NoComp ; No … skip computation <DSV>
|
||
;
|
||
MOVE.W MTemp+H,D0 ; Find ∆Mx
|
||
SUB.W RawMouse+H,D0
|
||
;
|
||
MOVE.W MTemp+V,D1 ; Find ∆My
|
||
SUB.W RawMouse+V,D1
|
||
;
|
||
MOVE.W D0,D2 ; x := |∆Mx|
|
||
BGE.S AbsX1
|
||
NEG.W D2
|
||
AbsX1
|
||
;
|
||
MOVE.W D1,D3 ; y := |∆My|
|
||
BGE.S AbsY1
|
||
NEG.W D3
|
||
AbsY1
|
||
;
|
||
move.l MickeyBytes,a0 ; <10/7/86 SMH> get globals
|
||
CMP.W D2,D3 ; D3 := magnitude(x,y)
|
||
BLS.S MagDone
|
||
EXG D2,D3
|
||
MagDone
|
||
ASR.W #1,D3
|
||
ADD.W D2,D3
|
||
;
|
||
; *** BEGIN NEW ***
|
||
;
|
||
BNE.S DoComp ; Zero magnitude … don’t compute ***
|
||
MOVE.W #1,Cnt(A0) ; No hits ***
|
||
CLR.W Error(A0) ; No errors ***
|
||
BRA DoPin ; Update the cursor ***
|
||
DoComp
|
||
;
|
||
MOVEM.L D4-D5,-(A7) ; Save off registers
|
||
MOVE.W Cnt(A0),D4 ; D4 is the number of samples
|
||
CMP.W MaxCnt(A0),D4 ; Is Count less than MaxCnt
|
||
BGE.S CountOK
|
||
ADD.W #1,Cnt(A0) ; Yes … we will have one more error
|
||
CountOK
|
||
;
|
||
MOVE.W D3,D5 ; Magnitude at current time
|
||
;
|
||
MOVE.W D4,D2 ; Get Count
|
||
SUB.W #1,D2 ; Index into JTab
|
||
ASL.W #1,D2 ; REQUIRES BRA.S’s IN JUMP TABLES
|
||
JMP JTab(PC,D2.W) ; Jump to the right code per Count
|
||
;
|
||
JTab
|
||
BRA.S E1 ; Count = 1
|
||
BRA.S E2 ; Count = 2
|
||
BRA.S E3 ; Count = 3
|
||
BRA.S E4 ; Count = 4
|
||
BRA.S E5 ; Count = 5
|
||
BRA.S E6 ; Count = 6
|
||
BRA.S E7 ; Count = 7
|
||
; *** BRA.S E8 ; Count = 8 ***
|
||
;
|
||
E8 ADD.W Err7(A0),D5 ; Accumulate time-7 magnitude
|
||
;
|
||
E7 ADD.W Err6(A0),D5 ; Accumulate time-6 magnitude
|
||
MOVE.W Err6(A0),Err7(A0) ; Shift out time-6 magnitude
|
||
;
|
||
E6 ADD.W Err5(A0),D5 ; Accumulate time-5 magnitude
|
||
MOVE.W Err5(A0),Err6(A0) ; Shift out time-5 magnitude
|
||
;
|
||
E5 ADD.W Err4(A0),D5 ; Accumulate time-4 magnitude
|
||
MOVE.W Err4(A0),Err5(A0) ; Shift out time-4 magnitude
|
||
;
|
||
E4 ADD.W Err3(A0),D5 ; Accumulate time-3 magnitude
|
||
MOVE.W Err3(A0),Err4(A0) ; Shift out time-3 magnitude
|
||
;
|
||
E3 ADD.W Err2(A0),D5 ; Accumulate time-2 magnitude
|
||
MOVE.W Err2(A0),Err3(A0) ; Shift out time-2 magnitude
|
||
;
|
||
E2 ADD.W Err1(A0),D5 ; Accumulate time-1 magnitude
|
||
MOVE.W Err1(A0),Err2(A0) ; Shift out time-1 magnitude
|
||
;
|
||
E1 MOVE.W D3,Err1(A0) ; Shift out current magnitude
|
||
;
|
||
MOVE.W D4,D2 ; Round up the divide
|
||
ASR.W #1,D2 ; by half the denominator
|
||
ADD.W D2,D5
|
||
EXT.L D5 ; Set up for the divide
|
||
DIVU D4,D5 ; Find the average magnitude
|
||
;
|
||
MOVE.W D3,D4 ; Get the original magnitude
|
||
SUB.W D5,D3 ; Find distance to average magnitude
|
||
ADD.W Error(A0),D3 ; Add on the accumulated error
|
||
CMP.W #-1,D3 ; Define -1 div 2 = 0
|
||
BNE.S DivOK
|
||
CLR.W D3
|
||
DivOK ASR.W #1,D3 ; Get half of it
|
||
MOVE.W D3,Error(A0) ; Update it
|
||
ADD.W D5,D3 ; Desired mag is average+Error
|
||
;
|
||
CMP.W #255,D5 ; mag := MAX(mag,255)
|
||
BLS.S MaxDone
|
||
MOVE.B #255,D5
|
||
MaxDone
|
||
;
|
||
move.l MickeyBytes,a0 ; <10/7/86 SMH> get at globals
|
||
add #GSize,a0 ; <10/24/86 SMH> point to table
|
||
CLR.W D2 ; i := 0
|
||
;
|
||
Search
|
||
ADD.B #1,D2 ; repeat
|
||
CMP.B (A0)+,D5 ; i := i+1
|
||
BHI.S Search ; until mag ≤ Table[i]
|
||
;
|
||
MULS D2,D3 ; D4 := i*(Mag(∆M)+Error)
|
||
;
|
||
MULS D3,D0 ; ∆Cx := (∆Mx*i*(Mag(∆M)+Error))/Mag(∆M)
|
||
DIVS D4,D0 ; <<<<<< D3 >>>>>>>
|
||
;
|
||
MULS D3,D1 ; ∆Cy := (∆My*i*(Mag(∆M)+Error))/Mag(∆M)
|
||
DIVS D4,D1 ; <<<<<< D3 >>>>>>>
|
||
;
|
||
MOVEM.L (A7)+,D4-D5 ; Restore registers
|
||
;
|
||
; *** END NEW ***
|
||
;
|
||
ADD.W D0,RawMouse+H ; Update raw mouse location
|
||
ADD.W D1,RawMouse+V
|
||
;
|
||
DoPin
|
||
LEA CrsrPin,A0 ; Bounding rect for cursor ***
|
||
MOVE.L RawMouse,D0 ; Pin mouse inside rect
|
||
BSR.S PinGuts
|
||
;
|
||
MOVE.L D0,RawMouse ; Update cursor locations
|
||
MOVE.L D0,MTemp
|
||
;
|
||
AND.L MouseMask,D0 ; Do jerky masking to drop low bits
|
||
MOVE.L MouseOffset,D1 ; Get the offset
|
||
BEQ.S SkipPin ; Skip 2nd pin if not
|
||
ADD.L D1,D0 ; Do jerky offset
|
||
BSR.S PinGuts ; Pin mouse inside rect again
|
||
SkipPin
|
||
MOVE.L D0,Mouse ; Actual mouse location
|
||
;
|
||
Repaint
|
||
TST.B CrsrObscure ; Unpaint the cursor
|
||
BNE.S Unpainted
|
||
_HideCursor ; Hide the cursor
|
||
Unpainted
|
||
;
|
||
CLR.B CrsrNew ; Cursor is fresh
|
||
CLR.B CrsrObscure ; Cursor is not obscured
|
||
_ShowCursor ; Repaint the cursor
|
||
;
|
||
; *** BEGIN NEW ***
|
||
;
|
||
RTS ; Goodbye
|
||
;
|
||
Done
|
||
move.l MickeyBytes,a0 ; <10/7/86 SMH> get globals
|
||
MOVE.W #1,Cnt(A0) ; No hits
|
||
CLR.W Error(A0) ; No errors
|
||
RTS ; Goodbye
|
||
;
|
||
NoComp
|
||
move.l MickeyBytes,a0 ; <10/7/86 SMH> get globals
|
||
MOVE.W #1,Cnt(A0) ; No hits
|
||
CLR.W Error(A0) ; No errors
|
||
BRA.S Repaint ; Update the cursor
|
||
;
|
||
; *** END NEW ***
|
||
;
|
||
; ===================================================================
|
||
; PinGuts limits the point in D0 to the
|
||
; bounding rectangle pointed to by A0.
|
||
; ===================================================================
|
||
;
|
||
PinGuts
|
||
CMP.W Left(A0),D0 ; Check left side
|
||
BGE.S LeftOK
|
||
MOVE.W Left(A0),D0
|
||
LeftOK
|
||
;
|
||
CMP.W Right(A0),D0 ; Check right side
|
||
BLE.S RightOK
|
||
MOVE.W Right(A0),D0
|
||
SUB.W #1,D0
|
||
RightOK
|
||
SWAP D0 ; Deal with vertical coord
|
||
;
|
||
CMP.W Top(A0),D0 ; Check top
|
||
BGE.S TopOK
|
||
MOVE.W Top(A0),D0
|
||
TopOK
|
||
;
|
||
CMP.W Bottom(A0),D0 ; Check bottom
|
||
BLE.S BotOK
|
||
MOVE.W Bottom(A0),D0
|
||
SUB.W #1,D0
|
||
BotOK SWAP D0
|
||
;
|
||
RTS
|
||
ENDPROC
|
||
|
||
|
||
;____________________________________________________________________________________
|
||
; PMA100 CXXX 10Mar87 DAF FindWindow {TB}WindowMgr3.a
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchSEROM.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 $40C7D2
|
||
FWEntry2 EQU $40C7CE
|
||
|
||
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
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchSEROM.a 10Mar87 #PMA100 (InitWindows) (InitWindows)
|
||
;
|
||
; 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 $40BBCE
|
||
IWReEntry EQU $40BC4A
|
||
|
||
LINK A6,#-16 ; make a stack frame
|
||
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 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 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
|
||
|
||
ENDPROC
|
||
|
||
;-----------------------------------------------------------------------------
|
||
; PABM150 28Mar87 JTC&JAF New SysEnvirons call.
|
||
;
|
||
; Fix File Date Patch# Routine(s) Fixed Fix Routine(s)
|
||
;AppleSystemPatch PatchSEROM.a 28Mar87 #PABM150 (SysEnvirons) (SysEnvirons)
|
||
;
|
||
INCLUDE 'SysEnvirons.a' ;<PMAB449>
|
||
|
||
;____________________________________________________________________________________
|
||
; PA182 21May87 CSL DiskSelect SonyQDUtil.a:DiskSelect
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchSEROM.a 21May87 #PA182 (DiskSelect) (DiskSelect)
|
||
;
|
||
;
|
||
; This patch is to fix the performance of the upper internal floppy drive for SE.
|
||
;
|
||
RPowerDown EQU $00435316
|
||
RomAt1 EQU $00435350
|
||
RDiskSelect PROC
|
||
|
||
TST.W TimeOut(A1) ; timeout pending? <25Oct85>
|
||
BEQ.S @0 ; br if not <25Oct85>
|
||
MOVE.W TimeOutDrive(A1),D0 ; see if it's us <25Oct85>
|
||
CMP.W Drive(A1),D0 ; ? <25Oct85>
|
||
BEQ.S @0 ; br if so <25Oct85>
|
||
MOVEQ #0,D0 ; turn it off immediately <25Oct85>
|
||
JSR RPowerDown ; (it will still be selected) <25Oct85>
|
||
|
||
@0 CLR.W TimeOut(A1) ; clear pending timeout <11Jun85>
|
||
CMP.W #drive2,D1 ; if Drive=1 or 2, it's internal
|
||
BGT.S @1
|
||
CMP.W #drive1,D1 ;
|
||
BEQ.S @3 ; br if so
|
||
BCLR #vDriveSel,VBufD(A2) ; select internal drive 2
|
||
BRA.S @4 ; branch always
|
||
@3
|
||
BSET #vDriveSel,VBufD(A2) ; select drive 1
|
||
@4
|
||
TST.B IntDrive(A0) ; select internal drive
|
||
TST.B MtrOn(A0) ; assert /enb
|
||
RTS
|
||
@1
|
||
jmp RomAt1
|
||
|
||
ENDPROC
|
||
|
||
;____________________________________________________________________________________
|
||
; PA235 FClosePatch patch:
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchSEROM.a 19Aug87 PP235 (FClose) (DtrmV3,
|
||
; FlushCache,
|
||
; BTClose,
|
||
; BTFlush)
|
||
;
|
||
; This patch fixes a problem in FClose which results in the catalog and extents file
|
||
; BTCBs not being released for an Unmount call. The branch following a test for a system
|
||
; CNID was reversed.
|
||
;
|
||
; Patched using the "DtrmV3", "FlushCache", "BTClose", and "BTFlush" vectors.
|
||
;
|
||
; The corresponding source code change for this patch were made to TFSRFN2.a in
|
||
; the "FClose" routine.
|
||
;
|
||
; 11Sep87 BB/JB Fixed FlushCache patch to save/restore async return address
|
||
; on a6 stack (PA269)
|
||
; 25Sep87 BB/JB Modified FlushCache patch (PA235) to check for an Offline, Eject,
|
||
; UnMountVol, or HUnMountVol trap before releasing the BTree
|
||
; control blocks (PA290).
|
||
; <54> dnf/csd Remove checks for _Offline and _Eject as we no longer close the
|
||
; catalog and extents files on these calls.
|
||
;____________________________________________________________________________________
|
||
|
||
FClosePatches proc
|
||
|
||
export saveDtrmV3,DtrmV3Patch,svFlushCache,FlCachePatch,BTClosePatch,BTFlushPatch
|
||
|
||
svFlushCache dc.l 0 ; Save of real FlushCache's address from vector
|
||
saveDtrmV3 dc.l 0 ; Save of real DtrmV3's address from vector
|
||
CatBTCBPtr dc.l 0 ; BTCB addr for catalog file
|
||
ExtBTCBPtr dc.l 0 ; BTCB addr for extent file
|
||
|
||
DtrmV3Patch
|
||
;
|
||
; Fake a JSR to the real DtrmV3 routine
|
||
;
|
||
pea @0 ; Where the real DtrmV3 will return to
|
||
move.l saveDtrmV3,-(sp) ; Go to it for now...
|
||
rts
|
||
@0
|
||
beq.s @1 ; Any errors from DtrmV3?
|
||
rts ; Return them to our caller if so...
|
||
@1
|
||
movem.l a0/a1/d1,-(sp)
|
||
cmp.w #TSigWord,VCBSigWord(a2) ; HFS volume?
|
||
bne.s @3 ; No, must be MFS so exit...
|
||
tst.w vcbFSID(a2) ; External file system (AppleShare)?
|
||
bne.s @3 ; Yep--get out of here...
|
||
;
|
||
; See if we came from Unmount
|
||
;
|
||
move.w ioTrap(a0),d0 ; Get trap we were called from
|
||
bclr #HFSBit,d0 ; (For unconditional UnMount) <25Sep87>
|
||
cmp.w #$A00E,d0 ; Unmount trap?
|
||
bne.s @3 ; Exit if not...
|
||
;
|
||
; For calls coming from Unmount, we have to save the catalog and
|
||
; extent file BTCB addresses so they can be deallocated later at FlushCache time.
|
||
;
|
||
@2
|
||
move.l FCBsPtr,a1 ; FCB array base address
|
||
move.w vcbCTRef(a2),d1 ; Catalog file refnum from VCB
|
||
beq.s @3 ; Exit if invalid catalog file refnum...
|
||
move.l fcbBTCBPtr(a1,d1),d0 ; Get BTCB pointer from FCB
|
||
lea CatBTCBPtr,a0 ; ...and save it for later
|
||
move.l d0,(a0)
|
||
|
||
move.w vcbXTRef(a2),d1 ; Extent file refnum from VCB
|
||
beq.s @3 ; Exit if invalid extent file refnum...
|
||
move.l fcbBTCBPtr(a1,d1),d0 ; Get BTCB pointer from FCB
|
||
lea ExtBTCBPtr,a0 ; ...and save it for later
|
||
move.l d0,(a0)
|
||
@3
|
||
movem.l (sp)+,a0/a1/d1
|
||
moveq #0,d0 ; Pseudo completion code
|
||
rts
|
||
|
||
;____________________________________________________________________________________
|
||
;
|
||
; FlushCache patch deallocates orphaned BTCBs uncovered by the DtrmV3 patch above.
|
||
; Patch looks for a call from inside FlushBuffers to make sure the BTCBs are
|
||
; released after the catalog and extent files have been flushed and closed.
|
||
;
|
||
;____________________________________________________________________________________
|
||
|
||
fromFlBufs equ $404F38 ; 1st return from FlushCache in FlushBuffers in SE ROM
|
||
|
||
FlCachePatch
|
||
move.l (sp)+,-(a6) ; Save async return address <11Sep87>
|
||
pea @0 ; Where the real FlushCache will return...
|
||
move.l svFlushCache,-(sp) ; Fake a JSR to the real FlushCache
|
||
rts
|
||
@0
|
||
movem.l d0/a0/a1,-(sp) ; Save FlushCache's return code & some regs
|
||
|
||
cmp.l #fromFlBufs,(a6) ; Coming from FlushBuffers? <11Sep87>
|
||
bne.s @5 ; Exit if not...
|
||
;
|
||
; See if we came from Unmount
|
||
;
|
||
move.l FSQHead,a0 ; Get ptr to current operation <25Sep87>
|
||
move.w ioTrap(a0),d0 ; Get trap we were called from <25Sep87>
|
||
bclr #HFSBit,d0 ; (For unconditional UnMount) <25Sep87>
|
||
cmp.w #$a00e,d0 ; Unmount trap? <25Sep87>
|
||
bne.s @5 ; Exit if not... <25Sep87>
|
||
@1
|
||
lea CatBTCBPtr,a1 ; Get saved catalog file BTCB address
|
||
move.l (a1),d0
|
||
beq.s @2 ; Skip if not defined...
|
||
move.l d0,a0 ; Else, point to it
|
||
_DisposePtr ; Deallocate orphan BTCB
|
||
clr.l (a1) ; ...and zap its reference
|
||
@2
|
||
lea ExtBTCBPtr,a1 ; Get saved extent file BTCB address
|
||
move.l (a1),d0
|
||
beq.s @5 ; Skip if not defined...
|
||
move.l d0,a0 ; Else, point to it
|
||
_DisposePtr ; Deallocate orphan BTCB
|
||
clr.l (a1) ; ...and zap its reference
|
||
@5
|
||
movem.l (sp)+,d0/a0/a1 ; Restore return code and registers
|
||
move.l (a6)+,-(a7) ; Restore async return address <11Sep87>
|
||
tst.w d0 ; Strobe FlushCache's return code
|
||
rts
|
||
|
||
;____________________________________________________________________________________
|
||
;
|
||
; BTClose patch to avoid BTClosing non-system BTree files
|
||
;
|
||
;____________________________________________________________________________________
|
||
|
||
vBTClose equ $4081AC
|
||
|
||
BTClosePatch
|
||
move.l a1,-(sp)
|
||
move.l FCBsPtr,a1
|
||
cmp.l #FSUsrCNID,FCBFlNm(a1,d0) ; Is this a 'system file'?
|
||
move.l (sp)+,a1
|
||
blo.s @1 ; If so, really flush it...
|
||
moveq #0,d0 ; Else, do nothing and return SUCCESS...
|
||
rts
|
||
@1
|
||
jmp vBTClose
|
||
|
||
;____________________________________________________________________________________
|
||
;
|
||
; BTFlush patch to avoid BTFlushing non-system BTree files
|
||
;
|
||
;____________________________________________________________________________________
|
||
vBTFlush equ $40839E
|
||
|
||
BTFlushPatch
|
||
move.l a1,-(sp)
|
||
move.l FCBsPtr,a1
|
||
cmp.l #FSUsrCNID,FCBFlNm(a1,d0) ; Is this a 'system file'?
|
||
move.l (sp)+,a1
|
||
blo.s @1 ; If so, really flush it...
|
||
moveq #0,d0 ; Else, do nothing and return SUCCESS...
|
||
rts
|
||
@1
|
||
jmp vBTFlush
|
||
endproc ; *** End of FClose patches ***
|
||
|
||
|
||
;____________________________________________________________________________________
|
||
; PA244 Unmount patch:
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchSEROM.a 24Aug87 PA244 (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 PA244 to unconditionally unmount a
|
||
; volume if the HFS bit is set in the ioTrap word.
|
||
;____________________________________________________________________________________
|
||
UnmountPatch proc
|
||
|
||
RomFSQSync equ $4042e8 ; Mac SE FS queue sync
|
||
toUnmount equ $40508c ; Mac SE return from DtrmV3 in UnmountVol
|
||
|
||
jsr RomFSQSync ; Get in sync...
|
||
clr.b FlushOnly ; Setup same as UnmountVol
|
||
pea @1
|
||
move.l jDtrmV3,-(sp) ; Call DtrmV3 to do setup stuff
|
||
rts
|
||
@1 bne.s UnmountExit
|
||
;
|
||
; 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 Unmount patch ***
|
||
|
||
;____________________________________________________________________________________
|
||
; PMAB241 BadTrap Handler patch
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchIIROM.a 25Aug87 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 $40138E ; 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
|
||
|
||
IF (NOT hasSplineFonts) THEN ;<2.3-4april89-CEL>
|
||
;____________________________________________________________________________________
|
||
; PMA299 27Oct87 NMB StdTxMeas DrText
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchSEROM.a 27Oct87 #PMA299 (StdTxMeas) (DrText)
|
||
;
|
||
; This patch fixes QuickDraw so that it properly handles fonts in excess of 128Kb. This is done
|
||
; by checking the FNDESCENT field of the FontRec. If that value is positive, then that word is
|
||
; used as the upper 16 bits of the offset/width table pointer.
|
||
|
||
NewStdTxMeas PROC EXPORT
|
||
seDrTextAddr EQU $4136D6 ; Address of code after call from DrText in SE Rom
|
||
seSTMAddr EQU $413486 ; Beginning of StdTxMeas in SE ROM
|
||
seBack2DrText EQU $413954 ; ROM address to continue execution
|
||
|
||
CMPI.L #seDrTextAddr,(SP) ; Being called from DrText? *NB Patch*
|
||
BEQ.S seChgRtn ; Yes, change Return Address. *NB Patch*
|
||
JMP seSTMAddr ;Otherwise, jump to ROM (beginning of StdTxMeas) *NB Patch*
|
||
seChgRtn ADDQ.L #4,SP ;Pop the old return address off…
|
||
PEA seDrTextPatch ;Replace return address with patch code *NB Patch*
|
||
JMP seSTMAddr ;Now, jump to ROM (beginning of StdTxMeas) *NB Patch*
|
||
|
||
;____________________________________________________________________________________
|
||
; PMA299 27Oct87 NMB DrText DrText
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchSEROM.a 27Oct87 #PMA299 (DrText) (DrText)
|
||
;
|
||
; This patch completes the fix to QuickDraw so that it properly handles fonts in excess of 128Kb.
|
||
; This is done by checking the FNDESCENT field of the FontRec. If that value is positive,
|
||
; then that word is used as the upper 16 bits of the offset/width table pointer. However, the
|
||
; first code executed tests to see if the FNDESCENT is truly positive. If it is not, then the
|
||
; ROM version of DrText is executed instead.
|
||
|
||
SEfNDescent EQU 10 ;Word: *NB Patch*
|
||
SEMapRectROM EQU $418D58 ;ROM Address of MapRect *NB Patch*
|
||
SEGoHomeROM EQU $413DC6 ;ROM Address of GoHome in DrText *NB Patch*
|
||
SERSectROM EQU $414880 ;ROM Address of RSect *NB Patch*
|
||
SETrimRectROM EQU $41692A ;ROM Address of TrimRect *NB Patch*
|
||
SEShieldCursorROM EQU $412A34 ;ROM Address of ShieldCursor *NB Patch*
|
||
SEDrTextROM EQU $413696 ;ROM Address of DrText *NB Patch*
|
||
|
||
;-------------------------------------------
|
||
;
|
||
; KERNED STRIKE FONT FORMAT OFFSETS:
|
||
;
|
||
FORMAT EQU 0 ;WORD
|
||
MINCHAR EQU 2 ;WORD
|
||
MAXCHAR EQU 4 ;WORD
|
||
MAXWD EQU 6 ;WORD
|
||
FBBOX EQU 8 ;WORD
|
||
FBBOY EQU 10 ;WORD
|
||
FBBDX EQU 12 ;WORD
|
||
FBBDY EQU 14 ;WORD
|
||
LENGTH EQU 16 ;WORD
|
||
xfASCENT EQU 18 ;WORD
|
||
XOFFSET EQU 22 ;WORD
|
||
RASTER EQU 24 ;WORD
|
||
|
||
|
||
;------------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
||
;
|
||
PARAMSIZE EQU 14 ;SIZE OF PARAMETERS
|
||
COUNT EQU PARAMSIZE+8-2 ;WORD
|
||
TEXTADDR EQU COUNT-4 ;LONG
|
||
NUMER EQU TEXTADDR-4 ;LONG, POINT
|
||
DENOM EQU NUMER-4 ;LONG, POINT
|
||
|
||
|
||
;-----------------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
SAVESTK EQU -4 ;LONG
|
||
TEXTRECT EQU SAVESTK-8 ;RECT
|
||
TEXTR2 EQU TEXTRECT-8 ;RECT
|
||
MINRECT EQU TEXTR2-8 ;RECT
|
||
BUFEND EQU MINRECT-4 ;LONG
|
||
BUFSTART EQU BUFEND-4 ;LONG
|
||
BUFFSIZE EQU BUFSTART-2 ;WORD
|
||
BUFROW EQU BUFFSIZE-2 ;WORD
|
||
BUFLEFT EQU BUFROW-2 ;WORD
|
||
BUF2START EQU BUFLEFT-4 ;LONG
|
||
BUF2END EQU BUF2START-4 ;LONG
|
||
HEIGHT EQU BUF2END-2 ;WORD
|
||
SRCBITS EQU HEIGHT-14 ;BITMAP
|
||
DSTBITS EQU SRCBITS-14 ;BITMAP
|
||
FAKERGN EQU DSTBITS-10 ;RECTANGULAR REGION
|
||
FAKEPTR EQU FAKERGN-4 ;LONG, FAKE MASTER POINTER
|
||
SRCADDR EQU FAKEPTR-4 ;LONG
|
||
SRCROW EQU SRCADDR-2 ;WORD
|
||
FASTFLAG EQU SRCROW-2 ;BYTE
|
||
PENLOC EQU FASTFLAG-4 ;POINT
|
||
SRCPTR EQU PENLOC-4 ;LONG
|
||
DSTPTR EQU SRCPTR-4 ;LONG
|
||
STRETCH EQU DSTPTR-2 ;BOOLEAN
|
||
FROMRECT EQU STRETCH-8 ;RECT
|
||
TORECT EQU FROMRECT-8 ;RECT
|
||
SRCRECT EQU TORECT-8 ;RECT
|
||
DSTRECT EQU SRCRECT-8 ;RECT
|
||
SPWIDTH EQU DSTRECT-4 ;FIXED POINT
|
||
CHARLOC EQU SPWIDTH-4 ;FIXED POINT
|
||
INFO EQU CHARLOC-8 ;4 WORDS
|
||
HEIGHTAB EQU INFO-4 ;LONG
|
||
WIDTAB EQU HEIGHTAB-4 ;LONG
|
||
LOCTAB EQU WIDTAB-4 ;LONG
|
||
TOPHT EQU LOCTAB-2 ;word
|
||
HEIGHTFLAG EQU TOPHT-2 ;byte
|
||
MAXMIN EQU HEIGHTFLAG-2 ;word
|
||
MINCH EQU MAXMIN-2 ;word
|
||
SAVEA5 EQU MINCH-4 ;LONG
|
||
NUMER2 EQU SAVEA5-4 ;Point
|
||
DENOM2 EQU NUMER2-4 ;Point
|
||
VARSIZE EQU DENOM2 ;SIZE OF VARIABLES
|
||
|
||
; *NB Patch* We enter patch land immediately after a jump to StdTxMeas. That routine knows
|
||
; that if it is called from DrText that it should jump to the patch rather than return.
|
||
seDrTextPatch MOVE.L $99A,A2 ; Get handle to FontRecord
|
||
MOVE.L (A2),A2 ; Dereference
|
||
TST.W sefNDescent(A2) ; Is fNDescent>0?
|
||
BGT.S seDoDrTextPatch ; Yup, execute patch code
|
||
JMP seDrTextAddr ; Jump back to ROM.
|
||
seDoDrTextPatch MOVE (SP)+,D1 ;POP UNSCALED WIDTH RESULT
|
||
;
|
||
; StdTxMeas also stashes FMOutPtr in QD global FONTPTR,
|
||
; and unscaled fixed point text width in FixTxWid.
|
||
;
|
||
MOVE.L FONTPTR(A4),A4 ;POINT TO FMOUTPUT
|
||
MOVE.L 2(A4),A2 ;GET FONT HANDLE
|
||
MOVE.L (A2),A2 ;DE-REFERENCE IT
|
||
MOVE FBBDY(A2),TOPHT(A6) ;INIT TOPHT IN CASE OLD FONT
|
||
BTST #0,1(A2) ;DOES FONT HAVE HEIGHT TABLE ?
|
||
SNE HEIGHTFLAG(A6) ;REMEMBER FOR LATER
|
||
;
|
||
; Setup textRect, the rectangle bounding the entire string.
|
||
;
|
||
MOVE.L PNLOC(A3),D2 ;GET PEN LOCATION
|
||
MOVE.L D2,PENLOC(A6) ;SAVE FOR LATER
|
||
MOVE.W D2,TEXTRECT+LEFT(A6) ;TEXTRECT.LEFT := PNLOC.H
|
||
ADD.W D1,D2 ;right := left + width
|
||
MOVEQ #7,D0 ;get mode mask
|
||
AND TXMODE(A3),D0 ;is txMode = srcCopy ?
|
||
BEQ.S seNOSLOP ;yes, don't add slop
|
||
CMP #3,D0 ;is textMode > srcBic ?
|
||
BGT.S seNOSLOP ;yes, don't add slop
|
||
ADD.W #32,D2 ;SLOP FOR ITALIC,BOLD,OVERSTRIKE
|
||
seNOSLOP MOVE.W D2,TEXTRECT+RIGHT(A6) ;STORE IN TEXTRECT.RIGHT
|
||
SWAP D2 ;GET PNLOC.V
|
||
SUB xfASCENT(A2),D2 ;SUBTRACT ASCENT
|
||
MOVE D2,TEXTRECT+TOP(A6) ;TEXTRECT.TOP := PNLOC.V - ASCENT
|
||
ADD FBBDY(A2),D2 ;ADD HEIGHT
|
||
MOVE D2,TEXTRECT+BOTTOM(A6) ;TEXTRECT.BOTTOM := TOP + HEIGHT
|
||
MOVE.L TEXTRECT(A6),TEXTR2(A6) ;MAKE AN EXTRA COPY
|
||
MOVE.L TEXTRECT+4(A6),TEXTR2+4(A6) ;OF TEXTRECT IN TEXTR2
|
||
|
||
;
|
||
; Check for stretching
|
||
;
|
||
MOVE.L NUMER(A6),D0 ;GET NUMERATOR
|
||
CMP.L DENOM(A6),D0 ;ARE WE STRETCHING ?
|
||
SNE STRETCH(A6) ;REMEMBER THE ANSWER
|
||
BEQ.S seNOSTRCH ;CONTINUE IF NOT STRETCHING
|
||
|
||
;
|
||
; We will be stretching. Setup fromRect and toRect and map textR2.
|
||
;
|
||
MULU D0,D1 ;MULT WIDTH BY NUMER.H
|
||
DIVU DENOM+H(A6),D1 ;DIV BY DENOM.H
|
||
|
||
MOVE.L PENLOC(A6),D0 ;GET PENLOC
|
||
MOVE.L D0,TORECT+TOPLEFT(A6) ;SET UP TORECT TOPLEFT
|
||
ADD.W NUMER+H(A6),D0 ;CALC PENLOC.H + NUMER.H
|
||
MOVE D0,TORECT+RIGHT(A6) ;SET UP TORECT RIGHT
|
||
SWAP D0 ;GET PENLOC.V
|
||
ADD NUMER+V(A6),D0 ;CALC PENLOC.V + NUMER.V
|
||
MOVE D0,TORECT+BOTTOM(A6) ;SET UP TORECT BOTTOM
|
||
|
||
MOVE.L PENLOC(A6),D0 ;GET PENLOC
|
||
MOVE.L D0,FROMRECT+TOPLEFT(A6) ;SET UP FROMRECT TOPLEFT
|
||
ADD.W DENOM+H(A6),D0 ;CALC PENLOC.H + DENOM.H
|
||
MOVE D0,FROMRECT+RIGHT(A6) ;SET UP FROMRECT RIGHT
|
||
SWAP D0 ;GET PENLOC.V
|
||
ADD DENOM+V(A6),D0 ;CALC PENLOC.V + DENOM.V
|
||
MOVE D0,FROMRECT+BOTTOM(A6) ;SET UP FROMRECT BOTTOM
|
||
|
||
PEA TEXTR2(A6) ;PUSH TEXTR2
|
||
PEA FROMRECT(A6) ;PUSH FROMRECT
|
||
PEA TORECT(A6) ;PUSH TORECT
|
||
JSR seMapRectROM ; MAP TEXTR2 (PRESERVES ALL REGS) (MapRect) *NB Patch*
|
||
|
||
seNOSTRCH ADD D1,PNLOC+H(A3) ;BUMP PEN BY (SCALED) TEXT WIDTH
|
||
;
|
||
; Quit if the pen is hidden
|
||
;
|
||
TST PNVIS(A3) ;IS PNVIS < 0 ?
|
||
BLT seGoHome ;YES, QUIT *NB Patch*
|
||
;
|
||
; Calc minRect: the intersection of textRect, bitMap bounds,
|
||
; clipRgn and visRgn bounding boxes. Quit if no intersection.
|
||
;
|
||
PEA TEXTR2(A6) ;PUSH (MAPPED) TEXTRECT
|
||
PEA PORTBOUNDS(A3) ;PUSH BITMAP BOUNDS
|
||
MOVE.L CLIPRGN(A3),A0 ;GET CLIPRGN HANDLE
|
||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||
PEA RGNBBOX(A0) ;PUSH CLIPRGN BBOX
|
||
MOVE.L VISRGN(A3),A0 ;GET VISRGN HANDLE
|
||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||
PEA RGNBBOX(A0) ;PUSH VISRGN BBOX
|
||
MOVE #4,-(SP) ;PUSH NRECTS=4
|
||
PEA MINRECT(A6) ;PUSH DST ADDR
|
||
JSR seRSectROM ;CALC INTERSECTION (RSect) *NB Patch*
|
||
BEQ seGoHome ;QUIT IF NO INTERSECTION *NB Patch*
|
||
;
|
||
; Set up srcAddr, srcRow, and height
|
||
;
|
||
LEA 26(A2),A0 ;GET START OF FONT BITMAP
|
||
MOVE.L A0,SRCADDR(A6) ;SAVE FOR LATER
|
||
MOVE RASTER(A2),D1 ;GET WORDS PER ROW IN FONT
|
||
ADD D1,D1 ;DOUBLE FOR BYTES PER ROW
|
||
MOVE D1,SRCROW(A6) ;REMEMBER FOR LATER
|
||
MOVE FBBDY(A2),HEIGHT(A6) ;SETUP HEIGHT FOR LATER
|
||
;
|
||
; Test for fast case:
|
||
; not stretched, no color mapping, txMode = srcOr,
|
||
; not bold, italic, underlined, outlined or shadowed,
|
||
; visRgn and clipRgn both rectangular.
|
||
;
|
||
TST.W 6(A4) ;TEST BOLD AND ITALIC
|
||
BNE seNOTFAST ;NOT FAST UNLESS BOTH ZERO
|
||
CMP #1,TXMODE(A3) ;IS TEXT MODE SRCOR ?
|
||
BNE seNOTFAST ;NO, NOT FAST
|
||
TST.W 10(A4) ;TEST ULTHICK AND SHADOW
|
||
BNE seNOTFAST ;NOT FAST UNLESS BOTH ZERO
|
||
TST.B STRETCH(A6) ;IS TEXT STRETCHED ?
|
||
BNE seNOTFAST ;YES, NOT FAST
|
||
MOVE COLRBIT(A3),D1 ;ARE WE COLOR MAPPING ?
|
||
BMI.S seNOCOLOR ;NO, CONTINUE
|
||
MOVE.L BKCOLOR(A3),D0 ;YES GET BACKGROUND COLOR
|
||
NOT.L D0 ;INVERT IT
|
||
AND.L FGCOLOR(A3),D0 ;AND WITH FOREGROUND COLOR
|
||
BTST D1,D0 ;IS THAT PLANE NORMAL ?
|
||
BEQ seNOTFAST ;NO, NOT FAST
|
||
seNOCOLOR MOVE.L CLIPRGN(A3),A0 ;GET CLIPRGN HANDLE
|
||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||
MOVEQ #10,D0
|
||
CMP RGNSIZE(A0),D0 ;IS CLIPRGN RECTANGULAR ?
|
||
BNE.S seNOTFAST ;NO, NOT FAST
|
||
MOVE.L VISRGN(A3),A1 ;GET VISRGN HANDLE
|
||
MOVE.L (A1),A0 ;DE-REFERENCE IT
|
||
CMP RGNSIZE(A0),D0 ;IS VISRGN RECTANGULAR ?
|
||
BEQ.S seFAST ;YES, TAKE FAST OPTIMIZATION
|
||
;
|
||
; All systems go except for VisRgn not rectangular.
|
||
; Check if visRgn sect minRect is rectangular.
|
||
; IF TrimRect(visRgn,minRect) THEN take the fast way.
|
||
;
|
||
MOVE.L A1,-(SP) ;PUSH VISRGN
|
||
PEA MINRECT(A6) ;PUSH MINRECT
|
||
JSR seTrimRectROM ;Call TrimRect *NB Patch*
|
||
BLT seGoHome ;quit if intersection empty *NB Patch*
|
||
BGT.S seNOTFAST ;continue if non-rectangular
|
||
;
|
||
; Fast case, go directly to screen.
|
||
; If text is clipped vertically, then clear heightflag and update TOPHT
|
||
;
|
||
seFAST ST FASTFLAG(A6) ;REMEMBER WE'RE GOING FAST
|
||
MOVE MINRECT+TOP(A6),D0 ;GET MINRECT.TOP
|
||
MOVE MINRECT+BOTTOM(A6),D1 ;GET MINRECT.BOTTOM
|
||
SUB TEXTRECT+TOP(A6),D0 ;was top clipped ?
|
||
BNE.S seVCLIP ;yes, handle clip
|
||
CMP TEXTRECT+BOTTOM(A6),D1 ;was bottom clipped ?
|
||
BEQ.S seVCLIPOK ;no, continue
|
||
|
||
seVCLIP CLR.B HEIGHTFLAG(A6) ;can't use height table
|
||
MOVE.B D0,TOPHT(A6) ;use adjusted top
|
||
SUB MINRECT+TOP(A6),D1 ;calc clipped height
|
||
MOVE.B D1,TOPHT+1(A6) ;replace TOPHT
|
||
|
||
seVCLIPOK MOVE TEXTRECT+TOP(A6),D0 ;GET DST TOP
|
||
SUB PORTBOUNDS+TOP(A3),D0 ;CONVERT TO GLOBAL COORDINATES
|
||
MULS PORTBITS+ROWBYTES(A3),D0 ;MULT BY ROWBYTES
|
||
ADD.L PORTBITS+BASEADDR(A3),D0 ;ADD START OF DST BITMAP
|
||
MOVE.L D0,BUFSTART(A6) ;SET UP BUFSTART FOR LATER
|
||
MOVE PORTBITS+ROWBYTES(A3),BUFROW(A6) ;SET UP BUFROW FOR LATER
|
||
MOVE PORTBOUNDS+LEFT(A3),BUFLEFT(A6) ;REMEMBER BUFLEFT
|
||
PEA MINRECT(A6) ;PUSH SHIELD RECT
|
||
MOVE.L PORTBOUNDS+TOPLEFT(A3),-(SP) ;PUSH DELTA TO CONVERT TO GLOBAL
|
||
JSR seShieldCursorROM ;Hide Cursor if it intersects *NB Patch*
|
||
BRA seGETPTRS
|
||
|
||
;
|
||
; Slow case: Setup for an off-screen buffer.
|
||
;
|
||
; Calc bufLeft: (word-align to avoid shift)
|
||
;
|
||
seNOTFAST CLR.B FASTFLAG(A6) ;NOT GOING DIRECTLY TO SCREEN
|
||
MOVE TEXTRECT+LEFT(A6),D0 ;GET TEXTRECT LEFT
|
||
SUB PORTBOUNDS+LEFT(A3),D0 ;CONVERT TO GLOBAL
|
||
AND #$FFF0,D0 ;TRUNC TO WORD BOUND
|
||
SUB #32,D0 ;32 DOT SLOP FOR SLANT & SHADOW
|
||
ADD PORTBOUNDS+LEFT(A3),D0 ;RETURN TO LOCAL COORDS
|
||
MOVE D0,BUFLEFT(A6) ;REMEMBER FOR LATER
|
||
;
|
||
; Calculate buffer size
|
||
;
|
||
MOVE TEXTRECT+RIGHT(A6),D1 ;BUFRIGHT := TEXTRECT RIGHT
|
||
SUB D0,D1 ;WIDTH:=BUFRIGHT-BUFLEFT
|
||
LSR #5,D1 ;CONVERT DOTS TO LONGS
|
||
ADD #2,D1 ;ROUND UP PLUS EXTRA LONG
|
||
MOVE HEIGHT(A6),D3 ;GET HEIGHT
|
||
MULU D1,D3 ;BUFFSIZE:=HEIGHT*BUFROW LONGS
|
||
MOVE D3,BUFFSIZE(A6) ;SAVE FOR LATER
|
||
LSL #2,D1 ;QUAD BUFROW FOR BYTES
|
||
MOVE D1,BUFROW(A6) ;SAVE FOR LATER
|
||
;
|
||
; Calculate total stack requirements for off-screen buffers.
|
||
;
|
||
MOVE.L D3,D2 ;GET BUFFSIZE LONGS
|
||
TST.B 11(A4) ;ARE WE SHADOWING ?
|
||
BEQ.S @se1 ;NO, CONTINUE
|
||
ADD.L D2,D2 ;YES, CALC 2*BUFFSIZE
|
||
EXT.L D1 ;SIGN EXTEND BUFROW
|
||
ADD.L D1,D2 ;CALC TOTAL LONGS
|
||
@se1 LSL.L #2,D2 ;CALC TOTAL STACK BYTES NEEDED
|
||
ADD.L #1024,D2 ;ADD 1 KBYTE SLOP
|
||
;
|
||
; If stack is too small to allocate buffer(s), then recursively call
|
||
; DrText with the left half and the right half of the text string.
|
||
;
|
||
_StackAvail ;Get StackAvail IN D0 {StackSpace?}
|
||
CMP.L D0,D2 ;IS stackNeeded > stackAvail ?
|
||
BLE.S seSTACKOK ;NO, CONTINUE
|
||
|
||
MOVE.L PENLOC(A6),PNLOC(A3) ;RESTORE PNLOC TO ORIGINAL
|
||
|
||
MOVE COUNT(A6),D7 ;GET CHARACTER COUNT
|
||
LSR #1,D7 ;DIVIDE IN HALF
|
||
BEQ.S seGoHome ;GIVE UP IF COUNT WAS ONLY ONE *NB Patch*
|
||
MOVE D7,-(SP) ;PUSH NEW COUNT
|
||
MOVE.L TEXTADDR(A6),-(SP) ;PUSH TEXTADDR
|
||
MOVE.L NUMER2(A6),-(SP) ;PUSH ORIGINAL NUMER
|
||
MOVE.L DENOM2(A6),-(SP) ;PUSH ORIGINAL DENOM
|
||
JSR seDrTextROM ;DRAW THE FIRST HALF *NB Patch*
|
||
|
||
MOVE COUNT(A6),D0 ;GET ORIGINAL CHARACTER COUNT
|
||
SUB D7,D0 ;SUBTRACT CHARS ALREADY DONE
|
||
MOVE D0,-(SP) ;PUSH NEW COUNT
|
||
MOVE.L TEXTADDR(A6),A0 ;GET ORIGINAL TEXTADDR
|
||
ADD D7,A0 ;BUMP PAST CHARS ALREADY DONE
|
||
MOVE.L A0,-(SP) ;PUSH NEW TEXTADDR
|
||
MOVE.L NUMER2(A6),-(SP) ;PUSH ORIGINAL NUMER
|
||
MOVE.L DENOM2(A6),-(SP) ;PUSH ORIGINAL DENOM
|
||
JSR seDrTextROM ;DRAW THE SECOND HALF *NB Patch*
|
||
; BRA seGoHomeROM ;AND QUIT ! *NB Patch*
|
||
seGoHome JMP seGoHomeROM ;Hack so that I can jump to ROM with a Bcc instr. *NB patch*
|
||
;
|
||
; Allocate and clear an off-screen buffer
|
||
;
|
||
seSTACKOK SUB #1,D3 ;INIT DBRA LOOP COUNT
|
||
CLR.L -(SP) ;PAD BUFFER WITH AN EXTRA ZERO
|
||
MOVE.L SP,BUFEND(A6) ;REMEMBER WHERE BUFFER ENDS
|
||
seCLRLOOP CLR.L -(SP)
|
||
DBRA D3,seCLRLOOP ;ALLOCATE AND CLEAR BUFFER
|
||
MOVE.L SP,BUFSTART(A6) ;REMEMBER START OF BUFFER
|
||
CLR.L -(SP) ;PAD BUFFER WITH AN EXTRA ZERO
|
||
|
||
;
|
||
; Get pointers to location table, width table, and height table in font
|
||
;
|
||
seGETPTRS LEA 26(A2),A0 ;GET START OF FONT BITMAP
|
||
MOVE FBBDY(A2),D0 ;GET HEIGHT OF FONT BITMAP
|
||
MULU SRCROW(A6),D0 ;CALC TOTAL SIZE OF STRIKE
|
||
ADD.L D0,A0 ;A1 := START OF LOC TABLE
|
||
MOVE.L A0,LOCTAB(A6) ;SAVE FOR LATER
|
||
|
||
;*NB Patch* The code for DrText must be able to handle fonts >128K. In order to do this, the font has
|
||
; the fNDescent field > 0. We use whatever value fNDescent has (if >0) as the upper 16 bits of the
|
||
; 32 bit distance to the offset/width table. We normally just use LENGTH(A2), and clear the upper
|
||
; 16 bits, but here we use fNDescent as the upper 16 bits, giving us greater range.
|
||
MOVE.W sefNDescent(A2),D0 ;Examining for >128K fonts *NB Patch*
|
||
BPL.S seMore128K ;If fNescent>0, then font > 128K. *NB Patch*
|
||
CLR.W D0 ;If not pos, then clear out fNDescent and continue. *NB Patch**
|
||
seMore128K SWAP D0 ;Put fNDescent into upper word to augment LENGTH(A2) *NB Patch*
|
||
JMP seBack2DrText
|
||
ENDIF ;<2.3-4april89-CEL>
|
||
|
||
|
||
;____________________________________________________________________________________
|
||
; PMAB301 ATP delayed duplicate response bug patch
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchSEROM.a 16Nov87 PMAB301 SendRequest SendRequest
|
||
;
|
||
; 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. Patch installed in the ATP control hook.
|
||
;____________________________________________________________________________________
|
||
|
||
ATPPatch PROC EXPORT
|
||
|
||
ROMJATPEx2 EQU $4328DC
|
||
ROMSndRqInit EQU $4329B8
|
||
ToROMSendReq EQU $4328FC
|
||
ROMATPIgnore EQU $432DF2
|
||
ROMReadResp EQU $432E06
|
||
|
||
TCBE EQU 12 ; Number of TCB's
|
||
TSktNum EQU 4 ; Offset to socket no.
|
||
TQElPtr EQU TSktNum+TCBE ; Offset to qEl ptr
|
||
|
||
CMP #SendRequest,CSCode(A0) ; Is it SendRequest?
|
||
BNE.S AnRTS ; Just return if not
|
||
MOVE.L MaskBC,D3 ; D3 = mask value
|
||
AND.L (SP),D3 ; Mask calling address
|
||
CMP.L ROMBase,D3 ; Make sure called from ROM
|
||
BLO.S AnRTS ; Just return if not
|
||
ADDQ #4,SP ; Pop return address
|
||
MOVE.L AbusVars,A2 ; A2 -> MPP variables
|
||
MOVE.L ATPVars(A2),A2 ; A2 -> ATP variables
|
||
MOVE.L AddrBlock(A0),D3 ; D3 = address block from queue element
|
||
AND.B #FlagMask,ATPFlags(A0) ; Make sure nothing but flag bits
|
||
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 @20 ; Return error if none
|
||
JSR ROMSndRqInit ; Do initial setup. A3 -> data area.
|
||
BNE.S @20 ; Just return if error
|
||
CLR.B D1 ; Indicate we want a dynamic socket
|
||
LEA newATPRead,A1 ; A1 -> new socket listener
|
||
JMP ToROMSendReq ; Jump into ROM
|
||
|
||
@20 JMP ROMJATPEx2
|
||
|
||
AnRTS RTS ; Just return if not SendRequest
|
||
|
||
|
||
;
|
||
; This is the real patch. We make sure the TID matches before reading in
|
||
; the response
|
||
;
|
||
newATPRead MOVEQ #ATPHdSz,D3 ; D3 = size to read
|
||
CMP.B #ATP,-(A3) ; Make sure DDP type was ATP (46)
|
||
BNE.S @20 ; Ignore it if not, (RHA ptr now even)
|
||
JSR (A4) ; Read header into RHA
|
||
BNE.S AnRTS ; Just return if error
|
||
MOVE.L ATPVars(A2),A5 ; A5 -> our local variables
|
||
MOVE.B DDPDstSkt-DDPType-ATPHdSz(A3),D0 ; D0 = dest. socket no.
|
||
MOVE.B ATPControl-ATPHdSz(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
|
||
LEA TSktNum+TCBE(A5),A5 ; A5 -> past sockets
|
||
@10 CMP.B -(A5),D0 ; This it? (fast loop!)
|
||
DBEQ D2,@10 ; Try all we can
|
||
BNE.S @20 ; Ignore it if no match
|
||
SUB D2,A5 ; A5 -> start of TCB table
|
||
LSL #2,D2 ; D2 = offset to queue element pointer
|
||
ADD D2,A5 ; A5 -> queue element ptr, offset
|
||
MOVE.L TQElPtr-TSktNum(A5),A5 ; A5 -> queue element
|
||
;
|
||
; *** The actual fix ***
|
||
;
|
||
MOVE ATPTransID-ATPHdSz(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
|
||
|
||
;____________________________________________________________________________________
|
||
; PMAB372 Async serial driver patch
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchSEROM.a 26jan88 PMAB372 (AOutOpen,RAIntHnd) (RAIntHnd)
|
||
;AppleSystemPatch PatchSEROM.a 23Feb88 PMAB401 (Control) (Control)
|
||
;
|
||
; 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.
|
||
;
|
||
; In Control, if the patch was called from control, then clear reg D0 before returning. This
|
||
; fixes a bug where killIO returns without setting reg D0 to good status.
|
||
;
|
||
;
|
||
;AppleSystemPatch PatchIIROM.a 17Dec90 <51> (all driver entry points,InitSCC,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) at end of rtn.
|
||
; Also, we change the BAP stuff such that it is also supported in 6.x, not just 7.0
|
||
; -- Always get the driver storage pointer for port B from extended mem
|
||
; -- Call Gestalt in Open and Close to determine version of AppleTalk to see which
|
||
; port arbitration scheme we should use, ours or the LAP mgr's.
|
||
;
|
||
;AppleSystemPatch PatchIIROM.a 16Jan91 <52> (all A driver entry points)
|
||
; 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'.
|
||
; Also, fix the port arbitration code in Open and Close to make call to the
|
||
; new 'atkv' Gestalt call instead of the old 'atlk' call. We do this because
|
||
; the new call return atalk version number regardless of whether MPP driver
|
||
; is open (i.e. appletalk is active).
|
||
;
|
||
; <55> 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.
|
||
; <57> Status calls 9 and $8000 now return static version number instead
|
||
; of what's in the DCE.
|
||
|
||
asyncPatch PROC EXPORT
|
||
|
||
; Async serial driver equates
|
||
|
||
SerialVers equ 5 ; current version 3/91 <57>
|
||
|
||
SCCARWOFF equ 2 ; SCC A side R/W offset
|
||
SCCBRWOFF equ 0 ; SCC B side R/W offset
|
||
|
||
PortAVars EQU SerialVars ; 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
|
||
|
||
; next come variable offsets within the user's local variable buffer
|
||
|
||
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
|
||
;BufSize 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 ctl enb <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
|
||
DTRNegVal EQU 31 ;(1) WR5 value used to negate DTR
|
||
|
||
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)
|
||
LastTime EQU 114 ;(4) ticks time of last CTS pulse (clk detect)
|
||
|
||
SendXOnff EQU 118 ;(1) flag to xmit logic to send XOn/XOff
|
||
CharMask EQU 119 ;(1) $1F,$3F,$7F, or $FF mask for input chars
|
||
|
||
PEChar EQU 120 ;(1) char to change incoming parity errors to
|
||
AltChar EQU 121 ;(1) char to change incoming PEChars to
|
||
|
||
InSWHS1 EQU 122 ;(1) saved InSWHS state
|
||
CtlOptions EQU 123 ;(1) bits 0-6=0 (reserved). bit 7=1 to leave
|
||
; DTR state unchanged at close.
|
||
SaveExInt EQU 124 ;(4) saved Ext int vector
|
||
SaveTxInt EQU 128 ;(4) saved TxD int vector
|
||
SaveRxInt EQU 132 ;(4) saved RxD int vector
|
||
SaveSxInt EQU 136 ;(4) saved Special Rx int vector
|
||
|
||
LclVarSize EQU 140 ; output driver storage size
|
||
|
||
;come from addresses
|
||
fromAInOpen EQU $431c4a
|
||
fromAOutOpen EQU $431CAE
|
||
fromBOutOpen EQU $431CDC
|
||
fromBInOpen EQU $431c52
|
||
fromControl EQU $431F9A
|
||
fromStatus EQU $431f48
|
||
fromClose EQU $431ebc
|
||
fromInitSCC EQU $431e3a
|
||
|
||
; open call patch equates
|
||
backToAOutOpen EQU $431Cca
|
||
backToAInOpen EQU $431c4a
|
||
backToBOutOpen EQU $431Cf6
|
||
backToBInOpen EQU $431c56
|
||
ROM_TAIntHnd EQU $4321f4 ; interrupt handlers we're NOT patching
|
||
|
||
backToPollDtain EQU $432314 ;
|
||
ToContOut EQU $432216 ;
|
||
ToGoodFinish EQU $4321B0 ;
|
||
ToGetBufRegs EQU $43228E ;
|
||
ToGetBufCnt EQU $43229E ;
|
||
ToCtlXOff EQU $4323BC ;
|
||
ToPut EQU $4323B6 ;
|
||
backToPut EQU $4323B2 ;
|
||
ToRdReqDone EQU $432422 ;
|
||
ToCtlSet EQU $4320cc
|
||
toContOut1 EQU $43221a
|
||
|
||
; Control Patch equates
|
||
backToBypassControl EQU $431fac
|
||
ROM_CtlGood EQU $431fe2
|
||
ROM_CtlExit EQU $431fe4
|
||
; Control Call 16 patch equates
|
||
InitSCC EQU $431e2a
|
||
|
||
;
|
||
; Status patch equates
|
||
backToStatus EQU $431f62
|
||
|
||
;InitSCC patch equates
|
||
backToInitSCC EQU $431e3a
|
||
initData EQU $431df6
|
||
|
||
; Close patch equates
|
||
SyncOutput EQU $431f0e
|
||
InitSCC1 EQU $431e30
|
||
ResetData EQU $431e80
|
||
ResetLth EQU $10
|
||
freePort EQU $431efc
|
||
|
||
; bypass driver ROM entrypoint addresses <52>
|
||
;port A
|
||
ROM_AInEntryOpen EQU $431c48
|
||
ROM_AInEntryClose EQU $431f0a
|
||
ROM_AInEntryPrime EQU $432226
|
||
|
||
ROM_AOutEntryOpen EQU $431cac
|
||
ROM_AOutEntryClose EQU $431e90
|
||
ROM_AOutEntryPrime EQU $43216c
|
||
|
||
ROM_AEntryControl EQU $431f86
|
||
ROM_AEntryStatus EQU $431f34
|
||
|
||
;port B
|
||
backToBInOpenStart EQU $431c50
|
||
backToBOutOpenStart EQU $431cda
|
||
ToBOutClose EQU $431ea4
|
||
backToBInPrime EQU $432230
|
||
backToBOutPrime EQU $432176
|
||
backToBControl EQU $431f90
|
||
backToBStatus EQU $431f3e
|
||
|
||
; for BAP only interrupt handler patches
|
||
backToTXIntHnd EQU $4321f8
|
||
; for BAP only patches-- 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>
|
||
|
||
|
||
;
|
||
; Miscellaneous patch equates
|
||
;
|
||
BInDCEOffset EQU 28 ; offset of .BIn DCE handle from UTableBase
|
||
|
||
;**************************************
|
||
; Start of async serial driver code
|
||
;**************************************
|
||
|
||
MOVE.L D0,-(SP) ; save reg D0 <PMAB401>
|
||
MOVE.L 8(SP),D0 ; get D0 = return address <PMAB401>
|
||
AND.L Lo3Bytes,D0 ; strip any junk
|
||
CMP.L #fromAOutOpen,D0 ; test for ChkAConfig call from AOutOpen
|
||
BEQ.w OpenAFix ; called for SCC channel A
|
||
CMP.L #fromAInOpen,D0 ; test for ChkAConfig call from AInOpen
|
||
BEQ.w OpenAFix ; called for SCC channel A
|
||
CMP.L #fromBOutOpen,D0 ; test for ChkBConfig call from BOutOpen
|
||
BEQ.w OpenBFix ; called for SCC channel B
|
||
CMP.L #fromBInOpen,D0 ; test for ChkBConfig call from BInOpen
|
||
BEQ.w OpenBFix ; called for SCC channel B
|
||
|
||
MOVE.L 4(SP),D0 ; get immediate return address <PMAB401>
|
||
AND.L Lo3Bytes,D0 ; strip any junk <PMAB401>
|
||
CMP.L #fromControl,D0 ; test for call from Control <PMAB401>
|
||
BEQ.w ControlFix ; called from Control <PMAB401>
|
||
CMP.L #fromStatus,D0 ; test for call from status
|
||
BEQ.w StatusFix ; called from status
|
||
CMP.L #fromClose,D0 ; test for call from Close
|
||
BEQ.w CloseFix ; called from close
|
||
CMP.L #fromInitSCC,D0 ; test for call from initSCC
|
||
BEQ.w InitSCCFix ; called from initSCC
|
||
MOVE.L (SP)+,D0 ; restore reg D0
|
||
RTS ; back to ROM
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; Close fixes
|
||
; -- do that nutty BAP stuff to free port B
|
||
;
|
||
CloseFix
|
||
ADD.L #8,SP ; pop save reg d0 and rtrn addr--we jump back
|
||
move.l a1,-(sp) ; save DCE ptr
|
||
; for BAP
|
||
; if close is for port B,we'll just stomp over what ROM put in a6
|
||
cmpa.l #PortAVars,a6 ; from port A
|
||
beq.s @common ; yes, then move on to common code
|
||
move.l ExpandMem,a6 ; no, then get storage ptr for port B
|
||
lea ExpandMemRec.emSerdVars(a6),a6
|
||
@common
|
||
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
|
||
LeaROM ResetData,A3
|
||
MOVEQ #ResetLth,D1
|
||
|
||
pea @01 ; <patch> BSR initSCC1
|
||
move.l #InitSCC1,-(sp) ; shut down the channel
|
||
rts
|
||
@01
|
||
; 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 ; <60>
|
||
tst.w ExpandMemRec.emAppleTalkInactiveOnBoot(a0) ; <60> If AppleTalk is inactive, don’t set up the LAP manager
|
||
bnz.s @freeThePort ; <60> AppleTalk is not active.
|
||
move.l #'atkv',d0 ; what version of Appletalk? <52>
|
||
_Gestalt
|
||
tst.w d0 ; <60> Check error returned by Gestalt
|
||
bne.s @freeThePort ; <60> If an error occurred, AppleTalk is not active.
|
||
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
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; Routine: InitSCC
|
||
; 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.
|
||
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 <55>
|
||
extClkSrc equ %00101000 ; SCC clk src is TRxC (CTS) pin (WR11) <55>
|
||
intClkSrc equ %01010000 ; SCC clk src is baud rate generator (WR11) <55>
|
||
BRGEnbl equ %00000001 ; enable baud rate generator (WR14) <55>
|
||
BRGDsbl equ %00000000 ; disable baud rate generator (WR14) <55>
|
||
|
||
SCCDataTable
|
||
DC.B $02,9 ; status in low bits, MIE disabled
|
||
clkDvd 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 ; brgen/TRxC clk to rcvr, xmitter--default to internal
|
||
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/disable baud rate generator from RTxC pin --default to on
|
||
dc.b $A0,15 ; Break, CTS external ints (dcd not needed) <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
|
||
|
||
SCCDataTableLth EQU *-SCCDataTable ;
|
||
|
||
InitSCCFix
|
||
ADD.L #8,SP ; pop save reg d0 saved rtrn addr--we jump back
|
||
|
||
move.l a3,d0
|
||
cmpRA InitData,d0 ; are we initializing SCC?
|
||
bne @done
|
||
|
||
lea SCCDataTable,a3 ; use our RAM table instead of the ROM one
|
||
moveq #SCCDataTableLth,d1
|
||
|
||
movem.l d1/a0,-(sp) ; save out reg's <55>
|
||
|
||
; default to internally clocked state <55>
|
||
bset.b #clkDvdBit,StopBits(a2) ; default to a divide-by-16 clock <55>
|
||
moveq #intClkSrc,d0 ; internal clocking source <55>
|
||
moveq #BRGEnbl,d1 ; enable baud rate generator <55>
|
||
|
||
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 <55>
|
||
moveq #extClkSrc,d0 ; external clock source <55>
|
||
moveq #BRGDsbl,d1 ; disable baud rate generator <55>
|
||
clr.b HWHS(a2) ; make sure we're not trying to do HWHS <55>
|
||
|
||
@load lea ClkMode,a0 ; load params into InitSCC data table <55>
|
||
move.b d0,(a0) ; <55>
|
||
lea BRGEnable,a0 ; <55>
|
||
move.b d1,(a0) ; <55>
|
||
|
||
movem.l (sp)+,d1/a0 ; restore reg's <55>
|
||
|
||
@done move.l #backToInitSCC,-(sp) ; finish up in ROM
|
||
rts
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; Routine: Status
|
||
; Patch: We patch status to add a call to return the driver's version.
|
||
StatusFix
|
||
ADD.L #8,sp ; pop save reg d0 and return addr--we jump back to ROM
|
||
|
||
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 ; exit if not (only input side open)<14Oct85>
|
||
move.l #ROM_CtlExit,-(sp) ; just like ROM
|
||
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 #SerialVers,(a0) ; return the version <57>
|
||
move.l #ROM_CtlGood,-(sp)
|
||
rts
|
||
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; Routine: Control
|
||
; Patch: We patch control for the following reasons:
|
||
; 1) to add VM support for control call 9--lock/unlock the buffer
|
||
; 2) to add external clock support in control call 16
|
||
; Called from Control - clear reg D0 in case this call is for KillIO
|
||
ControlFix
|
||
ADD.L #8,SP ; from control - flush saved reg D0 and saved return addr
|
||
CLR.L D0 ; clear reg D0 for killIO <PMAB401>
|
||
|
||
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 parameters
|
||
MOVE.W (A0)+,D1 ; get opcode
|
||
|
||
cmpi #16,d1 ; opcode 16? (ctlOptions) <extClk>
|
||
beq CtlSwitchCTSClock ; <extClk>
|
||
move.l #backToBypassControl,-(sp); if not, let ROM handle it
|
||
rts
|
||
|
||
; Routine: SetCtlOptions -- Opcode 16
|
||
; 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.
|
||
; We must call InitSCC to get the clocking option to kick in.
|
||
; 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 <55>
|
||
pea @00 ; <55>
|
||
move.l #InitSCC,-(sp) ; jsr to ROM_InitSCC to set new values <55>
|
||
rts ; <55>
|
||
@00 ; <55>
|
||
move.l #ROM_CtlGood,-(sp) ; finish up in ROM <55>
|
||
rts
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; Open Fixes
|
||
;
|
||
;
|
||
|
||
; Channel A - replace receive routine vectors installed by async open
|
||
OpenAFix
|
||
ADD.L #4,SP ; pop save reg D0 - not needed <PMAB401>
|
||
MOVE.L (SP)+,A0 ; pop A0 = addr to continue ChkConfig
|
||
move.l (sp)+,a2 ; save async open ret addr
|
||
JSR (A0) ; finish ChkConfig (A1,D1,D2 params)
|
||
|
||
move.l a2,d1 ; get Open return addr
|
||
AND.L Lo3Bytes,D1 ; strip any junk
|
||
cmp.l #fromAOutOpen,D1 ; test for ChkAConfig call from AOutOpen
|
||
beq.s @out
|
||
|
||
@in lea AsyncAIn,a2 ; store new driver header for AIn into DCE
|
||
move.l a2,(a1)
|
||
move.l #backToAInOpen,-(sp) ; jump back into ROM in AInOpen
|
||
rts
|
||
|
||
@out lea AsyncAOut,a2 ; store new driver header for AOut into DCE
|
||
move.l a2,(a1)
|
||
LEA PortAVars,A2 ; local variables address
|
||
PEA NewPollDtain ; new disk poll routine
|
||
PEA NewSCAIntHnd ; new special RxD int handler
|
||
PEA NewRAIntHnd ; new RxD int handler
|
||
move.l #ROM_TAIntHnd,-(sp) ; ROM--TxD int handler
|
||
PEA Lvl2DT+16 ; SCC interrupt dispatch table, chan A
|
||
PEA NewExtAIntHnd ; External int handler
|
||
MOVE.L #backToAOutOpen,-(SP) ; JUMP BACK INTO ROM
|
||
RTS
|
||
|
||
; Channel B - almost the same patch as channel A
|
||
; Except of course for the BAP stuff
|
||
OpenBFix
|
||
move.l ExpandMem,a0 ; <60>
|
||
tst.w ExpandMemRec.emAppleTalkInactiveOnBoot(a0) ; <60> If AppleTalk is inactive, don’t set up the LAP manager
|
||
bnz.s @appleTalkInactive ; <60> AppleTalk is not active.
|
||
move.l #'atkv',d0 ; what version of Appletalk? <52>
|
||
_Gestalt
|
||
tst.w d0 ; <60> Did Gestalt return an error?
|
||
bne.s @appleTalkInactive ; <60> Yes, 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
|
||
add.l #4,sp ; pop saved d0 -- not needed
|
||
movea.l (sp)+,a0 ; pop A0 = addr to continue non-BAP ChkConfig
|
||
move.l (sp)+,a2 ; save Open return addr
|
||
|
||
jsr (a0)
|
||
bra.s @gotPort
|
||
|
||
@useLAP add.l #8,sp ; pop d0,ROM ChkConfig addr
|
||
move.l (sp)+,a2 ; save Open return addr
|
||
movem.l a1-a2,-(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)
|
||
cmp.w #noErr,d0 ; did we get the printer port?
|
||
beq.s @rstrReg ; yes
|
||
movem.l (sp)+,a1-a2 ; no,restore reg's
|
||
rts ; return to IO Core: we already popped ret addrs and regs
|
||
|
||
@rstrReg
|
||
movem.l (sp)+,a1-a2 ; restore reg's
|
||
@gotPort
|
||
move.l a2,d1 ; get Open return addr
|
||
|
||
AND.L Lo3Bytes,D1 ; strip any junk <PMAB401>
|
||
cmp.l #fromBOutOpen,D1 ; test for ChkBConfig call from BOutOpen
|
||
beq.s @out
|
||
|
||
; from .Bin
|
||
lea AsyncBIn,a2 ; store new driver header for BIn into DCE
|
||
move.l a2,(a1)
|
||
move.l #backToBInOpen,-(sp) ; jump back into ROM in BInOpen
|
||
rts
|
||
|
||
@out; from .Bout
|
||
lea AsyncBOut,a2
|
||
move.l a2,(a1) ; store new driver header for BOut into DCE
|
||
move.l ExpandMem,a2 ; get storage ptr
|
||
lea ExpandMemRec.emSerdVars(a2),a2
|
||
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
|
||
|
||
MOVE.L #backToBOutOpen,-(SP) ; JUMP BACK INTO ROM
|
||
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
|
||
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 ; and branch around 'redundant' 6.X code
|
||
|
||
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 <14Oct85>
|
||
|
||
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
|
||
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
|
||
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
|
||
JmpRom 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 28(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 #-128,D0 ; ($80) leave 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
|
||
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
|
||
|
||
;_______________________________________________________________________ <52>
|
||
;
|
||
; 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'
|
||
|
||
;_______________________________________________________________________ <52>
|
||
;
|
||
; jumping to ROM from our patched entry points
|
||
;
|
||
AInOpen jmp ROM_AInEntryOpen ;port a
|
||
AInClose jmp ROM_AInEntryClose
|
||
AInPrime jmp ROM_AInEntryPrime
|
||
|
||
AOutOpen jmp ROM_AOutEntryOpen
|
||
AOutClose jmp ROM_AOutEntryClose
|
||
AOutPrime jmp ROM_AOutEntryPrime
|
||
|
||
AControl jmp ROM_AEntryControl
|
||
AStatus jmp ROM_AEntryStatus
|
||
|
||
|
||
BInOpen move.l #backToBInOpenStart,-(sp) ; port b
|
||
rts
|
||
BOutOpen move.l #backToBOutOpenStart,-(sp)
|
||
rts
|
||
BInClose moveq #0,d0 ; shorter to return than to jump to ROM
|
||
rts
|
||
BOutClose move.l #ToBOutClose,-(sp) ; don't need to screw with this other than patch above
|
||
rts
|
||
BInPrime
|
||
move.l ExpandMem,a2 ; use ExpandMem instead of PortBVars
|
||
move.l ExpandMemRec.emSerdVars(a2),a2 ;
|
||
move.l #backToBInPrime,-(sp) ; location to return to BInPrime
|
||
rts
|
||
|
||
BOutPrime
|
||
move.l ExpandMem,a2 ; use ExpandMem instead of PortBVars
|
||
move.l ExpandMemRec.emSerdVars(a2),a2 ;
|
||
move.l #backToBOutPrime,-(sp) ; location to return to BOutPrime
|
||
rts
|
||
|
||
BControl
|
||
move.l ExpandMem,a2 ; use ExpandMem instead of PortBVars
|
||
move.l ExpandMemRec.emSerdVars(a2),a2 ;
|
||
move.l #backToBControl,-(sp) ; location to return to BControl
|
||
rts
|
||
|
||
BStatus
|
||
move.l ExpandMem,a2 ; use ExpandMem instead of PortBVars
|
||
move.l ExpandMemRec.emSerdVars(a2),a2 ;
|
||
move.l #backToBStatus,-(sp) ; location to return to BStatus
|
||
rts
|
||
|
||
;
|
||
; End of Async.a Patch <51><52>
|
||
;_____________________________________________________________________________________________
|
||
|
||
|
||
;____________________________________________________________________________________
|
||
; PA511 -- UpdAltMDB patch
|
||
;
|
||
; This patch fixes a problem that occurs when an HFS alternate MDB is to be
|
||
; updated on a SuperDrive 1440k floppy. The problem occurs due to the way
|
||
; the routine UpdAltMDB determines the size of a floppy disk. The driver
|
||
; for the SuperDrive implements a Status call that returns a drive size list.
|
||
; We attempt to use this Status call, and if it fails, default to the old
|
||
; way of determining drive size (1-sided, 2-sided flag in the DQE).
|
||
;
|
||
; Due to the fact that the UpdAltMDB routine is not vectored, this patch
|
||
; dynamically patches out GetBlock for the duration of all calls to ExtBTFile
|
||
; so that GetBlock checks for a call from within the UpdAltMDB routine.
|
||
; If detected, the above method of determining disk size is employed
|
||
; and the result placed in register D2, where it is later used to
|
||
; read/write the alternate MDB. Afterwards, the GetBlock "come-from"
|
||
; patch is undone until the next instance of a call to ExtBTFile.
|
||
;
|
||
; PA511 24Jun88 JB Added patch to fix UpdAltMDB to use correct disk address
|
||
; on 1440k disks
|
||
; PA548 27Jul88 JB Modified to not make 'Get Format List' Status call unless
|
||
; doing so to the Sony driver. Fixes problems with 3rd party
|
||
; disks that either die, return garbage, or ignore CSCode
|
||
; altogether. Hope this can change someday...
|
||
;____________________________________________________________________________________
|
||
AltMDBPatch PROC
|
||
EXPORT MyExtBTF,svExtBTFile
|
||
;
|
||
; Format List record returned by the SuperDrive version of the Sony Driver
|
||
;
|
||
; One record per possible drive configuration is returned on a
|
||
; Status call with csCode = 6. The entry with bit 6 in flflags set
|
||
; is the 'current disk' configuration and is the entry used to
|
||
; determine drive size.
|
||
;
|
||
FmtLstRec record 0 ;
|
||
frsize ds.l 1 ; Disk size in BYTES
|
||
frflags ds.b 1 ; flags
|
||
frspt ds.b 1 ; sectors per track
|
||
frtracks ds.w 1 ; total # of tracks
|
||
flrecsize equ * ; size of the format list record
|
||
endr
|
||
|
||
NFRecs equ 16 ; max # of FmtLstRec to allocate on the stack
|
||
|
||
;
|
||
; Save cells for some vectors:
|
||
;
|
||
svExtBTFile ds.l 1
|
||
svGetBlock ds.l 1
|
||
|
||
;
|
||
; "Come from" address for call to GetBlock out of the
|
||
; UpdAltMDB routine:
|
||
;
|
||
fromUAMDB EQU $408b84 ; SE=$408b84, MacII=$4080c648
|
||
|
||
MyExtBTF
|
||
;
|
||
; Install our GetBlock patch for the duration of this
|
||
; ExtBTFile call...
|
||
;
|
||
lea svGetBlock,a0 ; Install our GetBlock filter
|
||
move.l JGetBlock,(a0) ; ...for the duration of
|
||
lea MyGetBlock,a0 ; ...the call to ExtBTFile
|
||
move.l a0,JGetBlock ; We now "see" all GetBlock calls...
|
||
;
|
||
; Call the real ExtBTFile routine
|
||
;
|
||
move.l (sp)+,-(a6) ; Save async return address
|
||
pea @0 ; Where the real ExtBTFile will return...
|
||
move.l svExtBTFile,-(sp) ; Fake a JSR to the real ExtBTFile
|
||
rts
|
||
@0
|
||
;
|
||
; After calling ExtBTFile, undo the temporary patch to GetBlock...
|
||
;
|
||
lea svGetBlock,a0 ; Restore the real GetBlock routine
|
||
move.l (a0),JGetBlock ; ...vector (ROM **or** RAM Cache)
|
||
move.l (a6)+,-(sp) ; Restore our return addr
|
||
tst.w d0 ; Set condition codes
|
||
rts ; ...bye
|
||
|
||
;__________________________________________________________________
|
||
; This is where the real work is done. If this GetBlock filter
|
||
; catches a call from within the UpdAltMDB routine, we fudge the
|
||
; contents of D2, which is the block address of the alternate MDB.
|
||
;__________________________________________________________________
|
||
MyGetBlock
|
||
cmp.l #fromUAMDB,(sp) ; Call from within UpdAltMDB?
|
||
bne doGetBlock ; No, just do the old GetBlock...
|
||
;
|
||
; Get here on the call to GetBlock that we are looking for.
|
||
; Determine the real size of the disk and update D2 appropriately.
|
||
;
|
||
WITH FmtLstRec
|
||
|
||
movem.l a0/a2/d0/d1,-(sp) ; Save what we use...
|
||
|
||
|
||
;
|
||
; Try the Sony Driver control call to attempt to discover
|
||
; drive size. If it fails, revert to the old assumptions...
|
||
;
|
||
sub.w #NFRecs*flrecsize,sp ; Make space for the format records
|
||
move.l sp,a2 ; Save format record buffer address
|
||
;
|
||
; Push an ioparamblk on the stack
|
||
;
|
||
moveq #(ioQElSize+1)/2-1,d0 ;
|
||
@1 clr.w -(sp) ;
|
||
dbf d0,@1 ;
|
||
move.l sp,a0 ; Parameter block address
|
||
|
||
|
||
; Check here for Sony driver because 3rd party disk drivers don't <JB/27Jul88>
|
||
; correctly support _Status calls. Some don't even check the value <JB/27Jul88>
|
||
; of the CSCode parameter!!! For now, don't call any driver except <JB/27Jul88>
|
||
; our own Sony driver. Maybe someday we'll get all drivers to support <JB/27Jul88>
|
||
; the 'Format List' status call... <JB/27Jul88>
|
||
|
||
moveq #0,d2 ; Vol size in 512-byte blocks if not a Sony <JB/27Jul88>
|
||
move.w dQDrvSz(a3),d2 ; <JB/27Jul88>
|
||
cmp.w #dskRfN,dQRefNum(a3) ; Is this a Sony drive? <JB/27Jul88>
|
||
bne.s ckVersn ; Skip Status call if not, check DQE version...<JB/27Jul88>
|
||
|
||
move.w dQDrive(a3),ioVRefNum(a0) ; drive number
|
||
move.w dQRefNum(a3),ioRefNum(a0) ; driver refnum
|
||
move.w #FmtLstCode,csCode(a0) ; Opcode for 'Return Format List'
|
||
|
||
move.w #NFRecs,csParam(a0) ; max number of format records to return
|
||
move.l a2,csParam+2(a0) ; ptr to place to return format records
|
||
_Status ; Ask driver for drive sizes
|
||
bne.s guessiz ; If any error, guess the size...
|
||
;
|
||
; Scan the returned list of format records for the entry which
|
||
; describes the 'current disk'.
|
||
;
|
||
move.w csParam(a0),d0 ; Number of format entries returned
|
||
beq.s guessiz ; Go guess if driver returned zilch...
|
||
sub.w #1,d0 ; ...for DBF loop
|
||
@2
|
||
btst #6,frflags(a2) ; Is this entry for the 'current disk'
|
||
bne.s @3 ; Xfer if so...
|
||
add.w #flrecsize,a2 ; Else, point to next record
|
||
dbf d0,@2 ; ...and try again
|
||
bra.s guessiz ; No 'current disk' found, go guess...
|
||
@3
|
||
move.l frsize(a2),d2 ; Get drive size in BLOCKS
|
||
bra.s GVSzExit ; And return...
|
||
;
|
||
; Attempt to determine the drive size by looking at the
|
||
; drive queue element. This method used for any driver not
|
||
; supporting the control call.
|
||
;
|
||
guessiz:
|
||
|
||
move.w #800,d2 ; assume single-sided sony
|
||
tst.b dQDrvSz(a3) ; TwoSideFmt?
|
||
beq.s ckVersn ; br if not <JB/27Jul88>
|
||
add.l d2,d2 ; two-sided, double size
|
||
ckVersn: ; <JB/27Jul88>
|
||
|
||
tst.w qType(a3) ; new version element?
|
||
beq.s GVSzExit ; br if not
|
||
move.l dQDrvSz(a3),d2 ; it's a long in the new world
|
||
swap d2 ; but swapped for compatibility
|
||
GVSzExit
|
||
add.w #ioQElSize+(NFRecs*flrecsize),sp ; Discard stuff on the stack
|
||
|
||
movem.l (sp)+,a0/a2/d0/d1 ; Restore scratch registers
|
||
|
||
ENDWITH
|
||
|
||
subq #2,d2 ; Convert disk size in blocks to alt MDB address
|
||
|
||
;__________________________________________________________________
|
||
; Do the actual GetBlock call -- D2 adjusted, if necessary
|
||
;__________________________________________________________________
|
||
doGetBlock
|
||
move.l svGetBlock,-(sp) ; Continue in the real GetBlock...
|
||
rts
|
||
|
||
ENDPROC ; **** End of AltMDBPatch patch ****
|
||
|
||
;____________________________________________________________________________________
|
||
; PP332 Cache control trap
|
||
;
|
||
; 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 $4042e8 ; Mac SE FSQueueSync address
|
||
ROMCmdDone equ $4043a0 ; Mac SE 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
|
||
|
||
;____________________________________________________________________________________
|
||
; P005 S118 MapFBlock patch:
|
||
;
|
||
; 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 ROM76 - ROM78 only. A separate patch in ROM75Fix
|
||
; (PM119) is required for ROM75. This is due to the absense of MapFBlock and
|
||
; XFSearch vectors in ROM75.
|
||
;
|
||
; Patched using the "MapFBlock" vector. NOTE, this patch replaces the
|
||
; "jMapFBlock" 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
|
||
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
|
||
MOVEA.L jXFSearch,A0 ; call XFSearch via its vector <19Mar87>
|
||
JSR (A0) ; <19Mar87>
|
||
BNE.S MFExit ; exit on errors
|
||
|
||
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>
|
||
ADD.L D7,D3 ;
|
||
;
|
||
; calculate number of available bytes
|
||
;
|
||
MOVE.W D2,D6 ; end FABN + 1 * alloc blk size
|
||
MULU VCBAlBlkSiz+2(A2),D6 ; = ending file pos + 1
|
||
SUB.L D5,D6 ; - file position = size avail
|
||
|
||
CMP.L D4,D6 ; compare with desired number
|
||
BCS.S mFBlockOK ; < D4 bytes, leave it alone <02Oct85>
|
||
MOVE.L D4,D6 ; > D4 bytes, set to D4 bytes
|
||
|
||
mFBlockOK MOVEQ #0,D0 ; we're ok <01Oct85>
|
||
;
|
||
; clean up and exit
|
||
;
|
||
MFExit
|
||
ADD #lenFXVars,A6 ; de-allocate memory for FXM vars <02Oct85>
|
||
MOVEM.L (A6)+,D1-D2/D4-D5/D7/A0-A1/A3-A4 ; restore registers
|
||
MOVE.L (A6)+,-(SP) ; put return address back on stack
|
||
TST.W D0 ; set CCR for result <01Oct85>
|
||
RTS ; exit MapFBlock
|
||
ENDPROC
|
||
;____________________________________________________________________________________
|
||
; * * * End of MapFBlock patch * * *
|
||
;____________________________________________________________________________________
|
||
|
||
;_______________________________________________________________________
|
||
;<2.7> 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 MacSE.
|
||
;
|
||
; 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
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; 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
|
||
|
||
tst.l DTskQHdr ; 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 low memory variable DTQueue.
|
||
;
|
||
; 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 DTQueue,a1 ; get ptr to queue (SE--low-mem global)
|
||
|
||
move.l #(ToolTable+(4*lowEnqueueByte)), a2 ; calculate vector for Enqueue call
|
||
move.l (a2),a2 ; get addr of Enqueue from vector
|
||
jsr (a2) ; go Enqueue (on SE)
|
||
|
||
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
|
||
BSET.B #InDTQ,DTQFlags ; already in dispatcher? (SE--lowmem check)
|
||
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 thru the vectors on our specific machine to save time
|
||
; and avoid the trap dispatcher, which may be important for interrupt-time code.
|
||
|
||
lowDeQueuebyte EQU $16E
|
||
|
||
lea DTQueue,a1 ; get ptr to queue (SE--low-mem global)
|
||
move.l #(ToolTable+(4*lowDeQueuebyte)),a2 ; calc vector for Dequeue
|
||
move.l (a2),a2 ; get Dequeue addr from vector
|
||
jsr (a2) ; go Dequeue (on SE)
|
||
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 DTskQHdr,D0 ; get queue head (SE--lowmem)
|
||
BNE.S DspLoop ; loop if tasks exist
|
||
|
||
BCLR.b #InDTQ,DTQFlags ; clear indicator (SE--lowmem)
|
||
RTS ; and exit
|
||
|
||
endproc
|
||
;_______________________________________________________________________
|
||
; End of Patch code for:
|
||
;<2.7> Deferred Task Manager _DTInstall Trap, vDisptch
|
||
; EH Interrupt Handlers Lvl1Int, Lvl2Int, Lvl3Int
|
||
;_______________________________________________________________________
|
||
|
||
; ------------------------------------------------------------------------------------
|
||
;<<<END PATCH CODE>>> <- This is to make the end of this list easy to find with MPW.
|
||
;find /<<<END INSTALL CODE>>>/ "{active}" # Execute to find the next available change number.
|
||
|
||
;############################### END PATCH CODE ##############################################
|
||
;
|
||
;############################# PATCH INSTALL CODE ############################################
|
||
|
||
RAMSysInit PROC EXPORT
|
||
IMPORT SysBase,CutBack
|
||
|
||
Move.L D1,-(SP) ;save our handle
|
||
|
||
;############################# PATCH INSTALLS GO HERE ################################
|
||
|
||
; Initialize some new LowMems <5.9>
|
||
move.w #$0105,TimeViaDB; number of VIA accesses per millisecond <5.9>
|
||
|
||
; PMAB354 07Jan88 EMT Unimplemented Toolbox versions of 12 bisexual traps
|
||
INCLUDE 'ToolboxCastration.a'
|
||
|
||
; Install MapFBlock patch (P005,S118)
|
||
|
||
IMPORT MapFBPatch
|
||
|
||
LEA MapFBPatch,A0 ; install patch code
|
||
MOVE.L A0,jMapFBlock ;
|
||
|
||
; PA489 04May88 EMT Addition to PA419 - Remove Radius SetTrapAddress patch.
|
||
|
||
movem.l $F80078,d0/a0 ; hook contents
|
||
cmp.l #$55AAAA55,d0 ; sign of Zorro?
|
||
bne.s @notRadiusAcc ; if not the sign of AJH, go on
|
||
; If here, than a Radius Accellerator SE is installed, with ROM version <= 2.0
|
||
; Time to pull some teeth!
|
||
MOVEQ #$47, D0 ; SetTrapAddress #
|
||
_GetTrapAddress ; Get the address in A0
|
||
MOVE.L A0, $51C ; And stuff it back in the OS table.
|
||
@notRadiusAcc
|
||
|
||
; P014 TJ 09dec86 TJ WakeUp SonyQDUtil.a
|
||
IMPORT SonyWakeUp
|
||
MOVE.L #SONYVERLOC,A0
|
||
CMP.B #1,(A0) ; if sony driver is 1 then install patch
|
||
BNE.S @defer ; else don't install
|
||
LEA SonyWakeUp,A0 ; Point to Sony wakeup entry point
|
||
MOVE.L A0,$0246 ; ($246 == jWakeUp) Redirect Sony wakeup routine
|
||
@defer
|
||
|
||
; P015 12Dec86 EMT GetOSEvent OSEventMgr.a
|
||
InstOSTp GetOSEvent, $31 ; Replace GetOSEvent
|
||
|
||
; P015 12Dec86 EMT OSEventAvail OSEventMgr.a
|
||
InstOSTp OSEventAvail, $30 ; Replace OSEventAvail
|
||
|
||
; P015 12Dec86 EMT KbdDrvr kbd.a
|
||
MOVE.W KeyLast, KbdLast ; Move the global
|
||
CLR.W KeyLast ; Stop repeating
|
||
|
||
|
||
iADBAddr EQU -2
|
||
iDataAddr EQU iADBAddr-4
|
||
iCRAddr EQU iDataAddr-4
|
||
iOrigAddr EQU iCRAddr-1
|
||
iDeviceTy EQU iOrigAddr-1
|
||
iPBlock EQU iDeviceTy
|
||
iSPBlock EQU iCRAddr
|
||
iLocalData EQU iDeviceTy ; Just a stack frame
|
||
|
||
_CountADBs ; Count the number of ADB devices
|
||
MOVE.W D0, D2 ; Save it in D2
|
||
BEQ.S @DoneKInst ; Skip if there are none
|
||
LINK A6, #iLocalData
|
||
MOVEQ #2, D1 ; We're looking for keyboards
|
||
@KInstLoop
|
||
LEA iPBlock(A6), A0 ; the parameter block
|
||
MOVE.W D2, D0 ; the count
|
||
_GetIndADB ; Get the record
|
||
BMI.S @NextRec ; Skip if not valid
|
||
CMP.B iOrigAddr(A6), D1 ; Is this a keyboard?
|
||
BNE.S @NextRec ; Skip if not
|
||
IMPORT KbdDrvr
|
||
LEA KbdDrvr, A0 ; Get the address of my driver
|
||
MOVE.L A0, iCRAddr(A6) ; Put it in the parameter block
|
||
LEA iSPBlock(A6), A0 ; Point to the parameter block
|
||
_SetADBInfo ; Set it (ADB Address is still in D0)
|
||
@NextRec
|
||
SUBQ.W #1, D2 ; Decrement the count
|
||
BGT.S @KInstLoop ; Loop if >0
|
||
UNLK A6
|
||
@DoneKInst
|
||
|
||
|
||
; P019 C570 23Dec86 ABO VInstall atalk:lap.a
|
||
InstOSTp NewVInstall,$33 ; Replace VInstall
|
||
|
||
; P021 C491 08Dec86 DAF GetWVariant WindowMgr2.a:GetWVariant
|
||
InstToolTp GetWVariant,$0A ; install GetWVariant
|
||
|
||
; P022 C491 08Dec86 DAF GetCVariant ControlMgr1.a:GetCVariant
|
||
InstToolTp GetCVariant,$09 ; install GetCVariant
|
||
|
||
; PA061 C628 25feb87 bbm added new trap rGetResource.
|
||
InstToolTp NewrGetResource,$0C ; install rGetResource
|
||
|
||
; PMA314 25Nov87 EMT Patch GetResource to get MBDF instead of ROM override on Plus, SE
|
||
|
||
; PA081 03Mar87 SHF NewSCSICmd SCSIMgr.a:SCSICmd
|
||
; PMA211 20Jul87 SHF NewSCSI{Read,Write,RBlind,WBlind} SCSIMgr.a:SCSIRead, etc.
|
||
; PMAB466 13Apr88 JWK NewSCSIGet SCSIMgr.a:SCSIGet
|
||
MOVE.L SCSIGlobals,A1 ; pointer to SCSI globals
|
||
lea.l NewSCSIGet,a0 ; pointer to patch routine <PMAB466/JWK>
|
||
move.l a0,1*4(a1) ; SCSIGet = selector 1 <PMAB466/JWK>
|
||
LEA NewSCSICmd,A0 ; pointer to patch routine
|
||
MOVE.L A0,3*4(A1) ; SCSICmd = selector 3
|
||
LEA NewSCSIRead,A0 ; pointer to patch routine
|
||
MOVE.L A0,5*4(A1) ; SCSIRead = selector 5
|
||
LEA NewSCSIWrite,A0 ; pointer to patch routine
|
||
MOVE.L A0,6*4(A1) ; SCSIWrite = selector 6
|
||
LEA NewSCSIRBlind,A0 ; pointer to patch routine
|
||
MOVE.L A0,8*4(A1) ; SCSIWrite = selector 8
|
||
LEA QuantumWBlindSE,A0 ; new blind write for quantum 7.9 fix <50> djw
|
||
MOVE.L A0,9*4(A1) ; SCSIWBlind = selector 9
|
||
|
||
; PMAB295 20Oct87 SHF SCSISelect SCSIMgr.a:SCSISelect
|
||
|
||
ROM76Load EQU $404058 ; Mac SE SCSILoad <PMAB295>
|
||
ROM76Select EQU $41A2C4 ; Select code <PMAB295>
|
||
|
||
BSR.S @ClearBus ; clear up bus problems first <PMAB295>
|
||
MOVE.L SCSIGlobals,A0 ; pointer to SCSIMgr variables <PMAB295>
|
||
MOVE.L 2*4(A0),-(SP) ; save old Select vector <PMAB295>
|
||
LEA @Sel76Patch,A1 ; pointer to my patch routine <PMAB295>
|
||
MOVE.L A1,2*4(A0) ; patch out the Select vector <PMAB295>
|
||
|
||
MOVE.B #$FE,d0 ; try all drivers but 0 (int.) <PMAB295>
|
||
JSR ROM76Load ; take the leap of faith <PMAB295>
|
||
MOVE.L SCSIGlobals,A0 ; pointer to SCSIMgr variables <PMAB295>
|
||
MOVE.L (SP)+,2*4(a0) ; restore the old Select vector <PMAB295>
|
||
BSR.S @ClearBus ; clear up remaining problems <PMAB295>
|
||
BRA.S @SCSIDone
|
||
@ClearBus
|
||
CLR.W -(SP) ; prepare for return value <PMAB295>
|
||
_SCSIStat ; get current SCSI bus status <PMAB295>
|
||
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>
|
||
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
|
||
@Sel76Patch
|
||
MOVEQ.L #0,D0 ; clear upper bits <PMAB295>
|
||
MOVE.W 8(A6),D0 ; get the target's ID <PMAB295>
|
||
MOVE.W #25,d6 ; select timeout (ms) <PMAB295>
|
||
JMP ROM76Select ; go to rest of the ROM routine <PMAB295>
|
||
|
||
@SCSIDone
|
||
|
||
; PAB087 06Mar87 CSL JCrsrTask patch
|
||
LEA JCrsrTask,A0
|
||
IMPORT CrsrPtch
|
||
LEA CrsrPtch,A1
|
||
MOVE.L A1,(A0) ; install the TrimMeasure hook
|
||
|
||
;------------------------------------------------------------------------------
|
||
; 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>
|
||
|
||
; PABM150
|
||
InstOSTp mySysEnvirons,$90
|
||
|
||
; PA182 21May87 CSL DiskSelect SonyQDUtil.a:DiskSelect
|
||
IMPORT RDiskSelect
|
||
MOVE.L #SONYVERLOC,A0
|
||
CMP.B #1,(A0) ; if sony driver is 1 then install patch
|
||
BNE.S @defer2 ; else don't install
|
||
LEA RDiskSelect,A0
|
||
LEA JDiskSel,A1
|
||
Move.L A0,(A1)
|
||
@defer2
|
||
|
||
; PMA207 17Jul87 EHB PackBits ; bitmaps.a
|
||
InstToolTp NewPackBits,$CF ; patch PackBits
|
||
|
||
;
|
||
; PB235 -- Install FClose patches
|
||
;
|
||
FCloseInst
|
||
import saveDtrmV3,DtrmV3Patch,svFlushCache,FlCachePatch,BTClosePatch,BTFlushPatch
|
||
|
||
lea saveDtrmV3,a0 ; Save original address of DtrmV3
|
||
move.l jDtrmV3,(a0) ; ...so we can call it
|
||
LEA DtrmV3Patch,A0 ; install patch code
|
||
MOVE.L A0,jDtrmV3 ;
|
||
|
||
lea svFlushCache,a0 ; Save original address of FlushCache
|
||
move.l jFlushCache,(a0) ; ...so we can call it
|
||
lea FlCachePatch,a0 ; Install our patch
|
||
move.l a0,jFlushCache
|
||
|
||
lea BTClosePatch,a0 ; Install BTClose vector
|
||
move.l a0,jBTClose
|
||
|
||
lea BTFlushPatch,a0 ; Install BTFlush vector
|
||
move.l a0,jBTFlush
|
||
;
|
||
; PB235 -- End of FClose patch install
|
||
;
|
||
|
||
; PM244 -- Install Unmount patch
|
||
InstOSTp UnmountPatch,$0E ; <24Aug87>
|
||
|
||
; PMAB241 25Aug87 RDC - install BadTrap patch
|
||
IMPORT NewBadTrap
|
||
InstToolTp NewBadTrap,$1FF ; replace Debugger trap $A9FF
|
||
InstToolTp NewBadTrap,$3FF ; replace Debugger trap $ABFF
|
||
|
||
; PMAB301 16Nov87 ABO ATP SendRequest
|
||
MOVE.L AGBHandle, A0 ; <9> PWD 3/21/90 Check to see if AGBHandle is already
|
||
CMP.L #-1, A0 ; <9> allocated, if so, skip the _NewHandle
|
||
BNE.S @ATInstalled ; <9>
|
||
|
||
MOVEQ #AGBSize,D0 ; D0 = size of block
|
||
_NewHandle ,SYS,CLEAR ; Get it
|
||
BNE.S @NoATPPatch ; Error if can't
|
||
MOVE.L A0,AGBHandle ; Set in lowmem
|
||
@ATInstalled ; <9>
|
||
MOVE.L (A0),A0 ; A0 -> AppleTalk Global Block
|
||
LEA ATPPatch,A1 ; A1 -> patch to SendRequest
|
||
MOVE.L A1,ATPHook(A0) ; Set in patch hook
|
||
@NoATPPatch
|
||
|
||
; <1.7> 2Feb89 CCH Added Gestalt.
|
||
; <4.5> <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
|
||
|
||
; PMAB372 26Jan88 djw Install async serial driver patch for DTR bug ($BE is assigned vector)
|
||
; <51> 17Dec90 eh install new version number for driver
|
||
InstOSTp asyncPatch,$BE
|
||
SERDVersion equ 5
|
||
; install new version number
|
||
move.l #5*4,d0 ; first serial DCE is 5th entry in Utbl
|
||
moveq #4-1,d1 ; index through 4 dce's (adjusted for dbra)
|
||
@next movea.l UTableBase,a0 ; get ptr to the unit table
|
||
movea.l 0(a0,d0.w),a0 ; get DCE handle
|
||
movea.l (a0),a0 ; get DCE ptr
|
||
move.w #SERDVersion,dCtlQueue(a0) ; post new version
|
||
addq #4,d0 ; get next DCE
|
||
dbra d1,@next
|
||
|
||
;
|
||
; PA511 -- Install code for UpdAltMDB patch
|
||
;
|
||
IMPORT svExtBTFile,MyExtBTF
|
||
|
||
lea svExtBTFile,a0 ; Point to save of ROM routine
|
||
move.l jExtBTFile,(a0) ; Save addr of ROM routine
|
||
|
||
lea MyExtBTF,a0 ; Point to the patch
|
||
move.l a0,jExtBTFile ; Install ourselves in the vector
|
||
|
||
|
||
;_____________________________________________________________________________
|
||
; PP332
|
||
; Install Cache control trap
|
||
;_____________________________________________________________________________
|
||
InstOSTp CacheTrap,$74 ; install the HFS RAM disk cache control trap
|
||
;_____________________________________________________________________________
|
||
; End of Cache control trap installation
|
||
;_____________________________________________________________________________
|
||
|
||
; P012 C481 04dec86 CRC SetFractEnable fontmgr.a:SetFractEnable
|
||
InstToolTpNum $419E42,$14 ; set up SetFractEnable
|
||
|
||
IF NOT hasSplineFonts THEN
|
||
InstToolTp FMSwapFont,$101 ; replace FMSwapFont
|
||
InstToolTp NewStdTxMeas,$ED ; replace StdTxMeas
|
||
ENDIF
|
||
|
||
; 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 ; <4.8> <16>
|
||
PtchInst 27 ; <4.8> Must load after ptch 4 !
|
||
ENDIF ; <4.8>
|
||
|
||
|
||
;______________________________________________________________________
|
||
; Start of Initialization code for:
|
||
;<2.7> 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
|
||
|
||
|
||
; 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.l a0,jDTInstall ; stuff that extra vector
|
||
move.w #$A082,D0 ; get trap number
|
||
_SetTrapAddress NewOS ; install _DTInstall
|
||
|
||
;
|
||
; initialize the queue header, which is in low mem
|
||
;
|
||
lea DTQueue,a0 ; SE queue, low-mem global
|
||
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.7> Deferred Task Manager _DTInstall Trap, vDisptch
|
||
; EH Interrupt Handlers Lvl1Int, Lvl2Int, Lvl3Int
|
||
;_______________________________________________________________________
|
||
|
||
;<<<END INSTALL CODE>>> <- This is to make the end of this list easy to find with MPW.
|
||
;############################### END INSTALL CODE ####################################
|
||
;
|
||
;############################# PATCHES CUT BACK CODE #################################
|
||
;
|
||
LEA RAMSysInit,A1 ; cut back to here . . . <23Apr86 LAK>
|
||
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>
|
||
|
||
;########################### END PATCHES CUT BACK CODE ################################
|
||
|
||
UsesPtchInst ; Patch Install code ;<2.3-4april89-CEL>
|
||
End
|