mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-27 10:29:32 +00:00
4325cdcc78
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
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
|