mirror of
https://github.com/elliotnunn/sys7.1-doc-wip.git
synced 2024-12-12 04:29:09 +00:00
3799 lines
141 KiB
Plaintext
3799 lines
141 KiB
Plaintext
|
;
|
|||
|
; File: PatchPortableROM.a
|
|||
|
;
|
|||
|
; Contains: patches for the first ROMs shipped in a Macintosh Portable ($037A)
|
|||
|
;
|
|||
|
; Copyright: © 1985-1992 by Apple Computer, Inc., all rights reserved.
|
|||
|
;
|
|||
|
; Change History (most recent first):
|
|||
|
;
|
|||
|
; <66> 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.
|
|||
|
; <65> 12/26/91 RB Rename definition of SleepQRec in the serial patch because it is
|
|||
|
; also used for Power Mgr.
|
|||
|
; <64> 12/2/91 SAM Using official boxflag equates now.
|
|||
|
; <63> 10/28/91 SAM/KSM Rolled in Regatta file:
|
|||
|
; Added Asahi Sony icons.
|
|||
|
; To distinguish between the Portable and Asahi (It's a Sony!)
|
|||
|
; that have the same ROM number & boxFlag, if the ROM minor
|
|||
|
; version is 1.1f1 then boxAsahi is jammed into BoxFlag. This is
|
|||
|
; placed before Gestalt gets loaded and uses boxFlag.
|
|||
|
; <62> 8/30/91 DTY Define onHcMac in this file because it’s not an available
|
|||
|
; feature in BBSStartup any more.
|
|||
|
; <60> 6/12/91 LN added #include 'InternalOnlyEqu.a'
|
|||
|
; <59> 6/12/91 LN removed #include 'HardwareEqu.a'
|
|||
|
; <58> 3/18/91 gbm SAM, #gbm-0009: Take out code that saves and restores logical
|
|||
|
; memory size and physical memory size around the installation of
|
|||
|
; the RAM-based Gestalt (the portable ROM does it wrong, and we
|
|||
|
; don't want its values)
|
|||
|
; <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/15/91 DTY kip, #fixGestalt: Add Gestalt fixes ('ptch' 5) to Portable
|
|||
|
; because some of Gestalt’s globals are trashed.
|
|||
|
; <55> 3/4/91 dba dty: get rid of SysVers conditionals
|
|||
|
; <54> 2/26/91 eh (djw) Fixed bug that was causing crash on serial read if a break
|
|||
|
; is received. An address offset was off by 2.
|
|||
|
; <53> 2/21/91 eh (djw) Fixed bug in the serial driver that was preventing use of
|
|||
|
; one port when Nike was printing on the other.
|
|||
|
; <52> 1/19/91 mbs (jg) Include ATalkPrivateEQU.a to get AGBHandle equates since
|
|||
|
; they were moved out of ATalkEQU.a.
|
|||
|
; <51> 1/19/91 eh (djw) Patch Port A async serial driver headers to insert
|
|||
|
; signature longword used by serial driver linked patch. Insert
|
|||
|
; signature before already patched Port B headers. Changed port b
|
|||
|
; arbitration code to call the new 'atkv' Gestall call instead of
|
|||
|
; the old 'atlk'.
|
|||
|
; <50> 1/14/91 eh (djw) Added external clocking support for Nike Printer to the
|
|||
|
; Async Serial Driver.
|
|||
|
; <49> 12/15/90 djw Add SCSI Mgr support for Quantum 7.9 ROM problem by adding a
|
|||
|
; separate TIB interpreter and replacing blind write
|
|||
|
; <48> 12/14/90 dnf (jsm) Nuke the dummy patch on ExtFSHook.
|
|||
|
; <47> 12/14/90 DFH <bbm> Removed MoveHHi and StackSpace patches. They were to
|
|||
|
; workaround a SuperCard 1.0 bug, but SuperCard 1.5 has been
|
|||
|
; available for some time. SuperCard 1.0 initialization code
|
|||
|
; lowered ApplLimit directly instead of calling SetApplLimit. This
|
|||
|
; left HiHeapMark up high, so StackSpace returned less than the
|
|||
|
; true amount, and SuperCard put up an alert because it thinks the
|
|||
|
; stack is getting full. SuperCard 1.5 calls SetApplLimit, so
|
|||
|
; HiHeapMark is OK.
|
|||
|
; <46> 11/14/90 JSM <bbm> Move come-from patch on _TEAutoView to fix dialog manager
|
|||
|
; bug to DialogManagerPatches.a.
|
|||
|
; <45> 9/25/90 KIP Change Sound Mgr. to a linked patch.
|
|||
|
; <44> 9/21/90 VL Moved PowerMgr patches to PowerMgrPatches.a so that SystemTask
|
|||
|
; will not be patched before the Notification Manager gets to
|
|||
|
; patch it.
|
|||
|
; <43> 9/20/90 KST Install a dummy patch for ExtFSPatch so that it will work for a
|
|||
|
; linkpatch.
|
|||
|
; <42> 8/18/90 dba get rid of ptchInst 7 and 8 (Sony Format and Eject patches) as
|
|||
|
; they are now linked patches
|
|||
|
; <41> 8/14/90 DTY Removed TextEdit patches since they’re in a linked patch now.
|
|||
|
; (For real this time.)
|
|||
|
; <40> 8/14/90 JWK NEEDED FOR SIXPACK: Removed old Slot Mgr Gestalt selectors.
|
|||
|
; <39> 8/13/90 JWK NEEDED FOR SIXPACK: Added NuBus and Serial Gestalt selectors.
|
|||
|
; <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> 7/30/90 dnf Remove installation of ptch 18 (File Manager) and ptch 6 (Btree
|
|||
|
; Manager), now linked patches
|
|||
|
; <36> 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
|
|||
|
; <35> 7/20/90 DTY Removed ptchInst 10 & 11 (Bass patches) since Bass is (finally)
|
|||
|
; a linked patch.
|
|||
|
; <34> 7/19/90 CCH NEEDED FOR SIXPACK: Removed HwPriv patch, its now a
|
|||
|
; linked-patch.
|
|||
|
; <33> 7/19/90 GMR Install ptch 7 to change eject track from 79 to 40.
|
|||
|
; <32> 7/16/90 gbm Warning cleanup
|
|||
|
; <31> 7/2/90 DTY Removed ptchInst 21 since Resource Manager extensions are now a
|
|||
|
; linked patch.
|
|||
|
; <30> 6/25/90 DTY Removed ptchInst 9 since ScrollSpeedFix is now a linked patch.
|
|||
|
; <29> 6/19/90 VL Remove PtchInst 29 since MiscPatches is a linked patch
|
|||
|
; now.
|
|||
|
; <28> 6/12/90 JSM Remove PtchInst 33 since PPC Toolbox is a linked patch now.
|
|||
|
; <27> 6/7/90 EMT Remove PtchInst 17 since Layer Manager is a linked patch now.
|
|||
|
; <26> 6/7/90 VL Remove ptchinst 28 since HelpMgr is a linked patch now.
|
|||
|
; <25> 5/29/90 DDG NEEDED FOR SIXPACK: Changed all the sixpack conditionals from
|
|||
|
; six-point-oh-seven to six-point-oh-six.
|
|||
|
; <24> 5/10/90 JSM AliasMgr now a linked patch, don't install it here anymore.
|
|||
|
; <23> 5/4/90 HJR Reset the projector date on this file.
|
|||
|
; <22> 5/3/90 MSH Fixed the modem and can't read 800k disks bug.
|
|||
|
; <21> 5/1/90 CCH Added some Gestalt patches (nMgr, Misc, removed VIA,SCC,RBV).
|
|||
|
; <20> 4/21/90 csd added patch install of ptch 16 (PrGlue).
|
|||
|
; <19> 4/16/90 DDG Rolled over changes from the split off sources including a
|
|||
|
; hwpriv patch and installing patch 25 (generic system patch). I
|
|||
|
; also changed the spline fonts equate to use the build variable
|
|||
|
; hasSplineFonts.
|
|||
|
; <18> 4/4/90 KON Removed ptchinst 36 and 44 since they are now linked patches.
|
|||
|
; <17> 3/29/90 KON Add ptch 40, quickdraw stuff for all B&W machines.
|
|||
|
; <16> 3/27/90 PKE Deleted import (currently conditionalized out) of NewSwapIcon,
|
|||
|
; which no longer exists in this PTCH.
|
|||
|
; <15> 3/26/90 PKE Moved definition of symbols that control Script Mgr patch and
|
|||
|
; 'ptch' installation into ScriptPriv.a. Renamed symbols and added
|
|||
|
; some.
|
|||
|
; <14> 3/23/90 NC Added ptch 43 for System 6.0.6 on up. This is for Sound.
|
|||
|
; <13> 3/4/90 PKE Changed _UprText to _UpperText to match new Traps.a.
|
|||
|
; <12> 2/28/90 PKE For 7.0, moved Script Mgr ROM patches into ‘ptch’ 39: patches to
|
|||
|
; _Pack6 and _GetIndADB, fixes to String2Date/InitDateCache,
|
|||
|
; installation of some new vectors, and the change to SwapIcon.
|
|||
|
; For all of these except the SwapIcon change, the code is still
|
|||
|
; here but conditionalized differently (in case we need it for
|
|||
|
; 6.1).
|
|||
|
; <11> 2/22/90 PKE Replaced obsolete _LwrStringToUpr opword with _UprText. Removed
|
|||
|
; setting of temporary sVectFixSpExtra vector (see <4>); we no
|
|||
|
; longer need it.
|
|||
|
; <10> 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.
|
|||
|
; <9> 1/29/90 MSH Misplaced label. All better now.
|
|||
|
; <8> 1/29/90 MSH PowerOff fix is changed to remove the power control call to the
|
|||
|
; PMGR. The call prevented the AppleTalk driver from resetting
|
|||
|
; the SCC before closing. Added a wake up procedure for the sleep
|
|||
|
; queue to reset the SCC whenever waking and no one is using the
|
|||
|
; driver. GMR added a patch to the EDisk driver to return
|
|||
|
; IOActCount correctly.
|
|||
|
; <7> 1/18/90 MSH Roll in latest version of Pmgr trap from main sources. Fixed the
|
|||
|
; trap to preserve the VIA sound enable bit. Added intercept to
|
|||
|
; PowerOff trap to reset the SCC before calling the ROM version.
|
|||
|
; <6> 1/12/90 CCH Added include of “HardwarePrivateEqu.a”.
|
|||
|
; <5> 1/11/90 PKE Changed quotes in previous comment to “” so scripts don't get
|
|||
|
; messed up.
|
|||
|
; <4> 1/11/90 PKE Initialize Script Manager's new sVectFixSpExtra vector. Changed
|
|||
|
; so PtchInst 0 is conditionalized on “Scripts604 OR (SysVers >=
|
|||
|
; $605)” instead of “Scripts604 OR (SysVers >= $700)”; at the
|
|||
|
; moment, this won't affect anything since Scripts604 is presently
|
|||
|
; TRUE for the 6.0.5 build.
|
|||
|
; <3> 1/4/90 BBM NEEDED FOR 6.0.5. We now patch out the soundmanger on all
|
|||
|
; cpu’s.
|
|||
|
; <2> 1/4/90 dba converted header; used PatchMacros setTrap and stuffOldTrap
|
|||
|
; instead of Set/GetTrapAddress (makes the object code a little
|
|||
|
; bit shorter)
|
|||
|
; <1> 12/17/89 CCH Adding for the first time into BBS.
|
|||
|
; <6.1> 12/13/89 MSH NEEDED FOR 6.0.5:Two more fixes. 1) Added fix to PMGR ADB send
|
|||
|
; command. Commands
|
|||
|
; <6.0> 12/11/89 GMR Added ptchInst 8; Sony Format patch is now in it's own patch
|
|||
|
; file (FormatPatch.a).
|
|||
|
; <5.9> 12/8/89 PKE NEEDED FOR Scripts604 AND FOR (6.0.5 <= SysVers < 7.0): Patch
|
|||
|
; LwrString to handle 2-byte chars via Transliterate (yuck). For
|
|||
|
; 7.0, we do this elsewhere.
|
|||
|
; <5.8> 12/4/89 MSH NEEDED FOR 6.0.5: Completely new patch for the PmgrOpPatch to
|
|||
|
; fix two problems. 1) Moved the delay in SerialPower to fix poor
|
|||
|
; hardware design, i.e. let the -5v generator to stabilize before
|
|||
|
; turning on the other power planes. 2) Added modem port polling
|
|||
|
; to PmgrOp to support high speed (57.6kb) serial.
|
|||
|
; <5.7> 11/29/89 GGD NEEDED FOR 6.0.5: Re-Enabled the SANE optimization to bypass the
|
|||
|
; Package Manager which never made it into 6.0.4.
|
|||
|
; <5.6> 11/21/89 EMT NEEDED FOR 6.0.5: Added humane scrolling.
|
|||
|
; <5.5> 11/17/89 PKE Tail patch on _GetIndADB to fix Script Mgr SwapKybd routine,
|
|||
|
; which cleared ADB keyboard driver dead state as a word: should
|
|||
|
; be a long.
|
|||
|
; <5.4> 11/6/89 PKE NEEDED FOR 6.0.5!! Bug fixes for InitDateCache and String2Date
|
|||
|
; needed for HyperCard. InitDateCache: Fixed CopyArray to use
|
|||
|
; correct register (A4) for source pointer, and to initialize all
|
|||
|
; relevant bytes of length register (D0). String2Date: if first
|
|||
|
; relevant (i.e., day or month name) alpha token is a month name,
|
|||
|
; we now search the day name list if we find another alpha token
|
|||
|
; (fixes BRC #54946). Rearranged Cache structure to fix invalid
|
|||
|
; use of month/day name index. Also (applies to 7.0 only) - fixed
|
|||
|
; install for 4.7 to use lea instead of leaROM.
|
|||
|
; <5.3> 10/15/89 BAL Added support for 32-Bit QuickDraw pictures via ptch 36
|
|||
|
; <5.2> 10/6/89 JSM Removed SnarfMan 'ptch', now PACK 13.
|
|||
|
; <5.1> 9/26/89 CVC Added PPC Toolobox as a 'ptch'.
|
|||
|
; <5.0> 9/25/89 EMT Added ptchs 18, 6, 29.
|
|||
|
; <4.9> 9/19/89 RLC Added Balloon Help (ptch 28) to file.
|
|||
|
; <4.8> 9/18/89 BBM Install resource manager extensions, ptch 21
|
|||
|
; <4.7> 9/18/89 PKE For 7.0, patch Script Manager internal routine SwapIcon to use
|
|||
|
; new 'kscn' resource type instead of 'SICN'.
|
|||
|
; <4.6> 9/17/89 PKE Decided to patch out GetScript/SetScript entirely in ptch 27, so
|
|||
|
; we no longer patch them here (see 4.5). Also, for 7.0 we now
|
|||
|
; install the Script Manager's Gestalt function in ptch 27 instead
|
|||
|
; of here (see 2.7).
|
|||
|
; <4.5> 9/6/89 PKE Patch Script Manager GetScript/SetScript routines to support
|
|||
|
; additional font info verbs for 7.0, and set up this font info in
|
|||
|
; Roman ScriptRecord. Set new sVectCallInterface vector. Redo
|
|||
|
; Script Manager version setup, using new smgrVersPTCHRom equate.
|
|||
|
; <4.4> 9/4/89 PKE Install Script Manager 7.0 extensions, ptch 27. Set Script Mgr
|
|||
|
; version for 7.0.
|
|||
|
; <4.3> 8/28/89 PKE For 7.0, initialize additional Script Mgr vectors for
|
|||
|
; SMgrCalcRect and SMgrInitFonts.
|
|||
|
; <4.2> 8/27/89 PKE NEEDED FOR Scripts604, 6.0.5: Bump Script Manager version for
|
|||
|
; Scripts604 or SysVers > $604, since IntlForce bug fix (3.8) is
|
|||
|
; installed.
|
|||
|
; <4.1> 8/25/89 SMB NEEDED FOR Scripts604: install TextEdit (ptch0) for 6.0.4 Script
|
|||
|
; System builds.
|
|||
|
; <4.0> 8/21/89 PKE NEEDED FOR 6.0.4: Conditionalize 3.8 for Scripts604 OR (SysVers
|
|||
|
; > $604)
|
|||
|
; <3.9> 8/21/89 PKE NEEDED FOR 6.0.4!: Patch RelString,UprString,CmpString to
|
|||
|
; re-introduce the bug in which "`" is converted to uppercase as
|
|||
|
; "a". This is necessary to prevent HFS problems, since existing
|
|||
|
; disk catalogs use the old, buggy sorting.
|
|||
|
; <3.8> 8/21/89 PKE NEEDED FOR 6.0.4 SCRIPTS BUILD, 6.0.5: Extend Pack6 patch to fix
|
|||
|
; a problem in LwrString,CharType,Transliterate,FindWord. These
|
|||
|
; routines should save the IntlForce flags then clear them before
|
|||
|
; the IUGetIntl call, restoring the flags afterward. This is so we
|
|||
|
; get the itl2 tables for the correct script (instead of the
|
|||
|
; tables for the system script).
|
|||
|
; <3.7> 8/21/89 PKE NEEDED FOR 6.0.4!!: Patch Pack6 to fix me-too problem with
|
|||
|
; pointer to unlocked handle in Transliterate; affects Roman
|
|||
|
; system (this problem looks familiar; did I dream that I already
|
|||
|
; fixed this one?).
|
|||
|
; <3.6> 8/20/89 PKE NEEDED FOR 6.0.4: Added (from PatchIIciROM.a) MkTbl macro and
|
|||
|
; code to fix up patch addresses. This is needed to make
|
|||
|
; JmpROM/JsrROM/CmpRA work, and fixes a problem in the
|
|||
|
; InitProcMenu patch (3.4).
|
|||
|
; <3.5> 8/19/89 MSH Commented out GGD's Sane Optimization, it breaks Excel 2.2.
|
|||
|
; <3.4> 8/16/89 dba NEEDED FOR 6.0.4: InitProcMenu bug fixed: MBDF ID was not put in
|
|||
|
; MenuList if MenuList was already allocated (InitMenus already
|
|||
|
; called)
|
|||
|
; <3.3> 8/15/89 prp Added Alias Manager and Folder Manager support.
|
|||
|
; <3.2> 8/11/89 MSH Expanded the Sleep trap patch to fix the passing of the sleepnow
|
|||
|
; code to the sleep queue entries, sleepnow should be converted to
|
|||
|
; sleepdemand before calling them.
|
|||
|
; <3.1> 8/10/89 CCH NEEDED FOR 6.0.4: Added gestalt location error patch and
|
|||
|
; installation.
|
|||
|
; <3.0> 8/9/89 CCH NEEDED FOR 6.0.4: Added patch to gestaltQuickdrawVersion to
|
|||
|
; return two digit versions. Added patch to make
|
|||
|
; gestaltLowMemorySize and gestaltParityAttr exist on Portable.
|
|||
|
; <2.9> 8/8/89 dba NEEDED FOR 6.0.4: added InitProcMenu patch
|
|||
|
; <2.8> 8/7/89 PKE NEEDED FOR 6.0.4: In gestaltScriptMgr function, if gestalt
|
|||
|
; selector is undefined, just leave gestalt result alone.
|
|||
|
; <2.7> 8/5/89 PKE NEEDED FOR 6.0.4: Add Gestalt function for Script Manager,
|
|||
|
; install corresponding Gestalt selectors.
|
|||
|
; <2.6> 7/26/89 GGD NEEDED FOR 6.0.4 Added SANE optimization to bypass the package
|
|||
|
; manager and dispatch directly to the SANE package in ROM.
|
|||
|
; <2.5> 7/24/89 PKE NEEDED FOR 6.0.4: Remove Script Manager patches, since these
|
|||
|
; were fixed in Esprit ROM after all.
|
|||
|
; <2.4> 7/19/89 JSM Install SnarfMan 'ptch'.
|
|||
|
; <2.3> 7/10/89 PKE NEEDED FOR 6.0.4: Put in Script Manager ROM patch code, but
|
|||
|
; don't install patches yet (we need to wait for final ROM and
|
|||
|
; adjust addresses accordingly). We patch InitResources,
|
|||
|
; UprString, GetFormatOrder to match changes in Aurora ROM that
|
|||
|
; were too late for Esprit.
|
|||
|
; <2.2> 7/3/89 NJC Sound Manager Extensions (ptch 23) rolled in for real.
|
|||
|
; <2.1> 6/19/89 MSH Low power resource ID numbers changed.
|
|||
|
; <2.0> 5/31/89 CEL Only defined Spline_Font variable if it is undefined - makes it
|
|||
|
; easier to build test 6.0.4 systems
|
|||
|
; <1.9> 5/25/89 EMT Correctly detach all SICN and STR resources.
|
|||
|
; <1.8> 5/25/89 EMT Added Window Manager extensions for Esprit.
|
|||
|
; <1.7> 5/24/89 MSH Detach all SICN and STR resources.
|
|||
|
; <1.6> 5/3/89 CEL Rolling in Bass for the first time into EASE…
|
|||
|
; <1.5> 3/30/89 MSH Load both the system disk version and the rom version.
|
|||
|
; <1.4> 3/30/89 MSH Added a load of the watch cursor from rom and saved the pointer
|
|||
|
; in pmgr locals.
|
|||
|
; <1.3> 3/30/89 MSH Removed the unmount patch completely, in rom now.
|
|||
|
; <1.2> 3/22/89 MSH Cache control trap moved to ROM and Unmount patch made
|
|||
|
; universal. Unmount install searches ROM for required entry
|
|||
|
; points and pokes them into vectors for unmount patch to use.
|
|||
|
; <1.1> 3/15/89 MSH Real patches added today. Unmount patch for AppleShare ("ptch
|
|||
|
; 8"), is loaded if there. Cache trap is here now but will be
|
|||
|
; rolled into ROM for next release.
|
|||
|
; <1.0> 3/6/89 CCH Adding to EASE for first time.
|
|||
|
;
|
|||
|
|
|||
|
STRING ASIS
|
|||
|
|
|||
|
if (&type('onHcMac') = 'UNDEFINED') then
|
|||
|
onHcMac: equ 1
|
|||
|
endif
|
|||
|
|
|||
|
if (&TYPE('has3rdFloppy') = 'UNDEFINED') then
|
|||
|
has3rdFloppy: equ 0
|
|||
|
endif
|
|||
|
|
|||
|
LOAD 'StandardEqu.d'
|
|||
|
INCLUDE 'PatchMacros.a'
|
|||
|
INCLUDE 'GestaltEqu.a' ; added <08/05/89 pke>
|
|||
|
INCLUDE 'GestaltPrivateEqu.a' ; <21>
|
|||
|
INCLUDE 'PackMacs.a' ; <3.7> <08/21/89 pke>
|
|||
|
INCLUDE 'ScriptPriv.a' ; <3.8> <08/21/89 pke>
|
|||
|
INCLUDE 'ApplDeskBus.a' ; <5.5>
|
|||
|
INCLUDE 'HardwarePrivateEqu.a'
|
|||
|
INCLUDE 'ATalkEqu.a' ; <v6.1>
|
|||
|
INCLUDE 'ATalkPrivateEQU.a' ; <1/19/91 mbs>
|
|||
|
INCLUDE 'EDiskEqu.a' ; <8>
|
|||
|
Include 'SCSIEqu.a' ; <49> djw
|
|||
|
Include 'SCSIPriv.a' ; <49> djw
|
|||
|
Include 'InternalOnlyEqu.a'
|
|||
|
Include 'SonyEqu.a'
|
|||
|
|
|||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|||
|
;;; Misc Equates & Macros
|
|||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|||
|
|
|||
|
UnimplementedTrap EQU $A89F ; unimplemented trap
|
|||
|
|
|||
|
|
|||
|
IF (&TYPE('SPLINE_FONT') = 'UNDEFINED') THEN
|
|||
|
SPLINE_FONT: EQU hasSplineFonts
|
|||
|
ENDIF
|
|||
|
|
|||
|
IF (&TYPE('Scripts604') = 'UNDEFINED') THEN
|
|||
|
Scripts604: EQU 0
|
|||
|
ENDIF
|
|||
|
|
|||
|
; The following symbols are defined in ScriptPriv.a. They control whether <15>
|
|||
|
; various Script Mgr patches are resident and installed here (since many
|
|||
|
; are also included in 'ptch' 39 or 27), and also control installation of
|
|||
|
; Script Mgr 'ptch' resources.
|
|||
|
;
|
|||
|
; doScriptMgrGestalt ; in ptch 27
|
|||
|
; doScriptMgrPack6Fix ; in ptch 39
|
|||
|
; doScriptMgrStr2DatFix ; in ptch 39
|
|||
|
; doScriptMgrRstKCHRFix ; in ptch 39
|
|||
|
; doScriptMgrLwrString2 ; in ptch 27
|
|||
|
; doScriptMgrSetROMVers ; in ptch 39
|
|||
|
; doScriptMgrNewVectors ; in ptch 39
|
|||
|
; installScriptMgrPtch27
|
|||
|
; installScriptMgrPtch39
|
|||
|
;
|
|||
|
;-------------------------------------------------------------------------------
|
|||
|
|
|||
|
|
|||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|||
|
;;; End Macros
|
|||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ROM37AFix PROC EXPORT
|
|||
|
IMPORT PatchInit
|
|||
|
EXPORT StartPatch,CutBack
|
|||
|
|
|||
|
; Cut back Code:
|
|||
|
;
|
|||
|
; SysBase is the entry point for ROM37AFix Upon entry D1.L contains our handle.
|
|||
|
|
|||
|
StartPatch
|
|||
|
Bra PatchInit ; Go do initialization stuff. D1 contains handle to us.
|
|||
|
DC.B 'PTCH' ; resource type
|
|||
|
DC.W $37A ; patch ID $37A.
|
|||
|
DC.W 1 ; current version number.
|
|||
|
|
|||
|
; cut back the ram-based system code to exclude this initialization code
|
|||
|
; d0 = size to cut patch down to (EndOfPatch - StartPatch)
|
|||
|
; a0 = handle to this PTCH resource (passed into SysBase in D1 from SysPatch)
|
|||
|
|
|||
|
CutBack
|
|||
|
_SetHandleSize ; adjust our size
|
|||
|
Moveq #$7F,D0 ; a soon to be large number
|
|||
|
Swap D0
|
|||
|
_CompactMem ,SYS ; of course there must be a comma!
|
|||
|
Rts ; all done
|
|||
|
|
|||
|
ENDPROC ; added <2.3 07/10/89 pke>
|
|||
|
|
|||
|
;#########################################################################################
|
|||
|
;################################ PATCH CODE GOES HERE ###################################
|
|||
|
;#########################################################################################
|
|||
|
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
;
|
|||
|
; 12/13/89 MSH ASendRequestPatch - Fixes a bug that has existed since initial design. <v6.1>
|
|||
|
; There is a small window of time where a Send Request queue element is put in the queue
|
|||
|
; for later transmission and an interrupt occurs. The interrupt uses the same data storage
|
|||
|
; area and effectively wipes out the send. This patch masks interrupts during the posting
|
|||
|
; of the element to provent it being overwritten.
|
|||
|
;
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
|
|||
|
TCBE EQU 12
|
|||
|
TSktNum EQU 4
|
|||
|
TQElPtr EQU $10
|
|||
|
NextTID EQU $2B0
|
|||
|
TTimeout EQU $40
|
|||
|
OurDCE EQU $2AC
|
|||
|
|
|||
|
; Find a free TCB and open a dynamic socket for the transaction.
|
|||
|
|
|||
|
ATPPatch PROC EXPORT
|
|||
|
ASendRequest CMP.L #$92AA12,(SP) ; was this called from ROM?
|
|||
|
BNE.S @ATPPatchDone ; exit if not
|
|||
|
CMP.W #sendRequest,csCode(A0) ; is this a send request
|
|||
|
BNE.S @ATPPatchDone ; exit if not
|
|||
|
|
|||
|
ADDQ #4,SP ; throw away return address
|
|||
|
MOVE.L AbusVars,A2 ; A1 -> MPP variables
|
|||
|
MOVE.L ATPVars(A2),A2 ; A2 -> our local variables
|
|||
|
AND.B #FlagMask,ATPFlags(A0) ; Leave only flag bits
|
|||
|
|
|||
|
MOVE.W #TooManyReqs,D0 ; Assume error case
|
|||
|
MOVEQ #TCBE-1,D2 ; D2 = offset into TCB table
|
|||
|
@10 TST.B TSktNum(A2,D2) ; Is this entry free?
|
|||
|
DBEQ D2,@10 ; Find one
|
|||
|
BNE.S @ATPPatchexit ; Error if none found
|
|||
|
|
|||
|
; BSR SndRqInit ; Set A3 -> data area
|
|||
|
JSR $92AE6A
|
|||
|
BNE.S @ATPPatchexit ; Error
|
|||
|
CLR.B D1
|
|||
|
|
|||
|
; LEA ATPRead,A1 ; A1 -> socket listener
|
|||
|
MOVE.L #$92B2F4,A1
|
|||
|
MOVE.L A1,Listener(A3) ; Set in q element
|
|||
|
MOVE.W #OpenSkt,D0 ; D0 = code for open socket
|
|||
|
|
|||
|
; BSR CallMPP ; Do the open socket
|
|||
|
JSR $92AEE6
|
|||
|
BEQ.S @15 ; Branch on no error
|
|||
|
|
|||
|
; BSR FreeDataArea ; Free up MPP data area
|
|||
|
JSR $92B600
|
|||
|
|
|||
|
; BRA.S @AtpExit
|
|||
|
|
|||
|
@ATPPatchExit MOVE.L OurDCE(A2),A1
|
|||
|
MOVE.L JIODone,A0
|
|||
|
JMP (A0) ; Go to IODone vector
|
|||
|
|
|||
|
@ATPPatchDone RTS
|
|||
|
|
|||
|
|
|||
|
; Set info in the TCB and write out the request
|
|||
|
|
|||
|
@15 MOVE.B Socket(A3),D1 ; D1 = socket number from DDP
|
|||
|
|
|||
|
; BSR SndRqCommon ; Set up
|
|||
|
JSR $92AE7C
|
|||
|
|
|||
|
MOVE.L A0,TQElPtr(A2,D2) ; Set it to our q element
|
|||
|
LEA NextTID(A2),A1 ; A1 -> NextTID
|
|||
|
MOVE.W (A1),ReqTID(A0) ; Set in q element for caller
|
|||
|
BSET #TIDValid,ATPFlags(A0) ; TID now valid
|
|||
|
ADDQ #1,(A1) ; Next
|
|||
|
LSR #2,D2 ; Next offset
|
|||
|
MOVE.B D1,TSktNum(A2,D2) ; Set socket num
|
|||
|
LEA TTimeout(A2,D2),A1 ; A1 -> place for timeout
|
|||
|
CLR.B (A1) ; Hold off timer now
|
|||
|
MOVE.L A1,-(SP) ; Save A1
|
|||
|
BSR SendRDequeue ; Dequeue call
|
|||
|
MOVE.L (SP)+,A1 ; Restore A1
|
|||
|
|
|||
|
; BSR ReTransSetup ; Setup for transmission
|
|||
|
JSR $92AF20
|
|||
|
|
|||
|
; BSR DoWrite ; Write out the request
|
|||
|
JSR $92AE9C
|
|||
|
|
|||
|
; BSR FreeDataArea ; Free up data area
|
|||
|
JSR $92B600
|
|||
|
|
|||
|
MOVE.B TimeoutVal(A0),(A1) ; Start timer
|
|||
|
MOVEQ #0,D0
|
|||
|
RTS
|
|||
|
|
|||
|
SendRDequeue MOVE SR,-(SP) ; Hold off interrupts
|
|||
|
MOVE #SCCLockOut,SR
|
|||
|
|
|||
|
|
|||
|
; BRA Dequeue ; Dequeue the request and return
|
|||
|
JMP $92ABA2
|
|||
|
|
|||
|
ENDP ; <v6.1>
|
|||
|
|
|||
|
;____________________________________________________________________________ <21>
|
|||
|
; Patches to Gestalt Functions
|
|||
|
;____________________________________________________________________________
|
|||
|
; The _Gestalt trap is patched to ensure that new gestalt functions
|
|||
|
; reside in the System Heap.
|
|||
|
;
|
|||
|
; The following gestalt selectors are patched or added in this file:
|
|||
|
; - gestaltLowMemorySize
|
|||
|
; - gestaltParityAttr
|
|||
|
; - gestaltMiscAttr
|
|||
|
; - gesaltNotificationMgrAttr
|
|||
|
; - gestaltQuickdrawVersion
|
|||
|
; - gestaltNuBusConnectors <39>
|
|||
|
; - gestaltSerialAttr <39>
|
|||
|
;
|
|||
|
; The following gestalt selectors are removed in this file:
|
|||
|
; - gestaltRBVAddr
|
|||
|
; - gestaltSCCReadAddr
|
|||
|
; - gestaltSCCWriteAddr
|
|||
|
; - gestaltVIA1Addr
|
|||
|
; - gestaltVIA2Addr
|
|||
|
; - gestaltSlotAttr <40>
|
|||
|
; - gestaltSlotCount <40>
|
|||
|
; - gestaltFirstSlot <40>
|
|||
|
;
|
|||
|
|
|||
|
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
;
|
|||
|
; <3.1> 8/10/89 CCH GestaltPatch - This patch ensures that new gestalt functions are in
|
|||
|
; the system heap or in ROM. It does this by intercepting the OS trap $AD and
|
|||
|
; performing a check on the gestalt function address passed in. It does not perform
|
|||
|
; this check on standard _Gestalt traps, only on _NewGestalt and _ReplaceGestalt traps.
|
|||
|
;
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
|
|||
|
gestaltTrapID EQU $A1AD ; trap ID of _Gestalt function
|
|||
|
|
|||
|
GestaltPatch PROC EXPORT
|
|||
|
EXPORT gestaltAddr
|
|||
|
|
|||
|
cmp.w #GestaltTrapID,d1 ; are they adding a function?
|
|||
|
beq.s @goROM ; if not, then skip patch
|
|||
|
move.l SysZone,a1 ; get ptr to system zone header
|
|||
|
cmpa.l (a1),a0 ; is gestalt function below system heap?
|
|||
|
bls.s @goROM ; if so, then no error
|
|||
|
cmpa.l RomBase,a0 ; is gestalt function in ROM?
|
|||
|
bcc.s @goROM ; if so, then no error
|
|||
|
move.l #gestaltLocationErr,d0 ; otherwise, return a location error
|
|||
|
rts
|
|||
|
|
|||
|
@goROM move.l gestaltAddr,a1 ; get original trap address
|
|||
|
jmp (a1) ; jump into Gestalt trap in ROM
|
|||
|
|
|||
|
gestaltAddr dc.l 0 ; space to store original trap addr
|
|||
|
|
|||
|
ENDP
|
|||
|
|
|||
|
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
;
|
|||
|
; Record to describe gestalt function parameters
|
|||
|
;
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
|
|||
|
gestaltParmFrame record {oldA6},decrement
|
|||
|
result ds.w 1 ; OSErr
|
|||
|
argSize equ *-8
|
|||
|
gestaltSelector ds.l 1 ; packed array [1..4] of char
|
|||
|
gestaltResult ds.l 1 ; addr of longint result
|
|||
|
return ds.l 1
|
|||
|
oldA6 ds.l 1
|
|||
|
localFrame equ *
|
|||
|
endR
|
|||
|
|
|||
|
|
|||
|
;____________________________________________________________________________ CCH <8>
|
|||
|
; Gestalt function to effectively remove a selector
|
|||
|
;
|
|||
|
; The following is a gestalt function that will return an error as if the
|
|||
|
; selector were undefined.
|
|||
|
;
|
|||
|
; Routine gestaltUndef (
|
|||
|
; gestaltSelector: OSType; = PACKED ARRAY [1..4] OF CHAR;
|
|||
|
; VAR gestaltResult: Longint;
|
|||
|
; ): OSErr; = Integer;
|
|||
|
;
|
|||
|
|
|||
|
gestaltUndef PROC EXPORT
|
|||
|
|
|||
|
with gestaltParmFrame
|
|||
|
link a6,#localFrame
|
|||
|
|
|||
|
move.w #gestaltUndefSelectorErr,result(a6) ; return an error
|
|||
|
|
|||
|
unlk a6
|
|||
|
move.l (sp)+,a0 ; get return value
|
|||
|
add.l #argSize,sp ; restore stack pointer
|
|||
|
jmp (a0) ; return
|
|||
|
|
|||
|
ENDP
|
|||
|
|
|||
|
|
|||
|
;____________________________________________________________________________ CCH <10>
|
|||
|
; Gestalt function for gestaltMiscAttr
|
|||
|
;
|
|||
|
; The following is a patch to the gestaltMiscAttr selector. It returns
|
|||
|
; miscellaneous information about things.
|
|||
|
;
|
|||
|
; Routine gestaltMisc (
|
|||
|
; gestaltSelector: OSType; = PACKED ARRAY [1..4] OF CHAR;
|
|||
|
; VAR gestaltResult: Longint;
|
|||
|
; ): OSErr; = Integer;
|
|||
|
;
|
|||
|
|
|||
|
UserDelayTrap EQU $A84C ; user delay trap <21>
|
|||
|
|
|||
|
gestaltMisc PROC EXPORT
|
|||
|
|
|||
|
with gestaltParmFrame
|
|||
|
link a6,#localFrame
|
|||
|
|
|||
|
clr.l d3 ; clear result
|
|||
|
@hasBootGlobs bclr #gestaltBootGlobals,d3 ; we don't have boot globals <21>
|
|||
|
|
|||
|
@userDelay move.w #UnimplementedTrap,D0 ; get loc of unimplemented trap <58>
|
|||
|
_GetTrapAddress ,newTool ; get the address into A0
|
|||
|
Move.l A0,D2 ; save it for a sec
|
|||
|
Move.l #UserDelayTrap,D0 ; trap ID to check for scrolling throttle
|
|||
|
_GetTrapAddress ,newTool ; get the address of it
|
|||
|
cmp.l a0,d2 ; is it unimplemented?
|
|||
|
beq.s @squareMenus ; nope.. <58>
|
|||
|
bset #gestaltScrollingThrottle,d3 ; <58>
|
|||
|
|
|||
|
@squareMenus move.b NTSC,d0 ; get a copy of the NTSC byte <58>
|
|||
|
andi.b #$0F,d0 ; only look at bottom nibble <58>
|
|||
|
bne.s @next ; if it's non-zero, menus aren't square <58>
|
|||
|
bset #gestaltSquareMenuBar,d3 ; otherwise, it is! <58>
|
|||
|
|
|||
|
@next
|
|||
|
move.l d3,d0 ; put result into d0 <58>
|
|||
|
|
|||
|
move.l gestaltResult(a6),a0 ; get address to place result
|
|||
|
move.l d0,(a0) ;
|
|||
|
move.w #noErr,result(a6) ; return no error
|
|||
|
|
|||
|
unlk a6
|
|||
|
move.l (sp)+,a0 ; get return value
|
|||
|
add.l #argSize,sp ; restore stack pointer
|
|||
|
jmp (a0) ; return
|
|||
|
|
|||
|
ENDP
|
|||
|
|
|||
|
|
|||
|
;____________________________________________________________________________ CCH <20>
|
|||
|
; Gestalt function for gestaltNotificationMgrAttr
|
|||
|
;
|
|||
|
; The following is a patch to the gestaltNotificationMgrAttr selector.
|
|||
|
; It indicates existence of the notification manager trap.
|
|||
|
;
|
|||
|
; Routine gestaltNMgr (
|
|||
|
; gestaltSelector: OSType; = PACKED ARRAY [1..4] OF CHAR;
|
|||
|
; VAR gestaltResult: Longint;
|
|||
|
; ): OSErr; = Integer;
|
|||
|
;
|
|||
|
NMInstallTrap EQU $A05E ; notification manager install trap <20>
|
|||
|
|
|||
|
|
|||
|
gestaltNMgr PROC EXPORT
|
|||
|
|
|||
|
with gestaltParmFrame
|
|||
|
link a6,#localFrame
|
|||
|
|
|||
|
clr.l d0 ; clear result
|
|||
|
Move.w #UnimplementedTrap,D0 ; get loc of unimplemented trap
|
|||
|
_GetTrapAddress ,newTool ; get the address into A0
|
|||
|
Move.l A0,D2 ; save it for a sec
|
|||
|
Move.l #NMInstallTrap,D0 ; trap ID to check for notification mgr
|
|||
|
_GetTrapAddress ,newTool ; get the address of it
|
|||
|
Cmp.l A0,D2 ; is it unimplemented?
|
|||
|
Beq.s @noNMgr ; it is?!
|
|||
|
bset #gestaltNotificationPresent,d0 ; otherwise it exists
|
|||
|
|
|||
|
@noNMgr move.l gestaltResult(a6),a0 ; get address to place result
|
|||
|
move.l d0,(a0) ;
|
|||
|
move.w #noErr,result(a6) ; return no error
|
|||
|
|
|||
|
unlk a6
|
|||
|
move.l (sp)+,a0 ; get return value
|
|||
|
add.l #argSize,sp ; restore stack pointer
|
|||
|
jmp (a0) ; return
|
|||
|
|
|||
|
ENDP
|
|||
|
|
|||
|
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
;
|
|||
|
; <3.0> 8/10/89 CCH GestaltLowMem - This is the gestaltLowMemorySize selector, which
|
|||
|
; was created after the Esprit ROM froze.
|
|||
|
;
|
|||
|
; Routine gestaltLowMem ( gestaltSelector: OSType; VAR gestaltResult: Longint) : OSErr;
|
|||
|
;
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
|
|||
|
GestaltLowMem PROC EXPORT
|
|||
|
|
|||
|
with gestaltParmFrame
|
|||
|
link a6,#localFrame
|
|||
|
|
|||
|
move.l gestaltResult(a6),a0 ; get address to place result
|
|||
|
move.l SysZone,(a0) ; system zone starts at top of low-mem
|
|||
|
move.w #noErr,result(a6) ; return no error
|
|||
|
|
|||
|
unlk a6
|
|||
|
move.l (sp)+,a0 ; get return value
|
|||
|
add.l #argSize,sp ; restore stack pointer
|
|||
|
jmp (a0) ; return
|
|||
|
|
|||
|
ENDP
|
|||
|
|
|||
|
|
|||
|
;----------------------------------------------------------------------------------------- <40>
|
|||
|
;
|
|||
|
; <39> 8/13/90 JWK GestaltSerial - This is the gestaltSerialAttr selector.
|
|||
|
; The Portable has GPI connected on both ports.
|
|||
|
|
|||
|
GestaltSerial PROC EXPORT ; Portable has no serial attributes
|
|||
|
|
|||
|
with gestaltParmFrame
|
|||
|
link a6,#localFrame
|
|||
|
|
|||
|
move.l gestaltResult(a6),a0 ; get address to place result
|
|||
|
move.l #(1<<gestaltHasGPIaToDCDa)|\ ; GPIa connected to DCDa
|
|||
|
(1<<gestaltHasGPIaToRTxCa)|\ ; GPIa connected to RTxCa clock input
|
|||
|
(1<<gestaltHasGPIbToDCDb),(a0) ; GPIb connected to DCDb
|
|||
|
move.w #noErr,result(a6) ; return no error
|
|||
|
|
|||
|
unlk a6
|
|||
|
move.l (sp)+,a0 ; get return value
|
|||
|
add.l #argSize,sp ; restore stack pointer
|
|||
|
jmp (a0) ; return
|
|||
|
|
|||
|
ENDP
|
|||
|
|
|||
|
|
|||
|
;----------------------------------------------------------------------------------------- <39>
|
|||
|
;
|
|||
|
; <39> 8/13/90 JWK GestaltNBCon - This is the gestaltNuBusConnectors selector.
|
|||
|
; GestaltSerial - This is the gestaltSerialAttr selector.
|
|||
|
; Since the Portable should return zero, we share the GestaltParity function's code
|
|||
|
; to return a zero.
|
|||
|
;
|
|||
|
|
|||
|
GestaltNBCon PROC EXPORT ; Portable has no NuBus
|
|||
|
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
;
|
|||
|
; <3.0> 8/10/89 CCH GestaltParity - This is the gestaltParityAttr selector, which was
|
|||
|
; created after the Esprit ROM froze.
|
|||
|
;
|
|||
|
; Routine gestaltParity ( gestaltSelector: OSType; VAR gestaltResult: Longint) : OSErr;
|
|||
|
;
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
|
|||
|
GestaltParity PROC EXPORT
|
|||
|
|
|||
|
with gestaltParmFrame
|
|||
|
link a6,#localFrame
|
|||
|
|
|||
|
move.l gestaltResult(a6),a0 ; get address to place result
|
|||
|
move.l #0,(a0) ; Portable will never have parity
|
|||
|
move.w #noErr,result(a6) ; return no error
|
|||
|
|
|||
|
unlk a6
|
|||
|
move.l (sp)+,a0 ; get return value
|
|||
|
add.l #argSize,sp ; restore stack pointer
|
|||
|
jmp (a0) ; return
|
|||
|
|
|||
|
ENDP
|
|||
|
|
|||
|
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
;
|
|||
|
; <3.0> 8/10/89 CCH GestaltQDVers - This is the gestaltQDVersion selector, which was
|
|||
|
; created after the Esprit ROM froze.
|
|||
|
;
|
|||
|
; Routine GestaltQDVers ( gestaltSelector: OSType; VAR gestaltResult: Longint) : OSErr;
|
|||
|
;
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
|
|||
|
GestaltQDVers PROC EXPORT
|
|||
|
|
|||
|
with gestaltParmFrame
|
|||
|
link a6,#localFrame
|
|||
|
|
|||
|
move.l gestaltResult(a6),a0 ; get address to place result
|
|||
|
move.l #gestaltOriginalQD,(a0) ; Portable has original QD
|
|||
|
move.w #noErr,result(a6) ; return no error
|
|||
|
|
|||
|
unlk a6
|
|||
|
move.l (sp)+,a0 ; get return value
|
|||
|
add.l #argSize,sp ; restore stack pointer
|
|||
|
jmp (a0) ; return
|
|||
|
|
|||
|
ENDP
|
|||
|
|
|||
|
|
|||
|
IF doScriptMgrGestalt AND (NOT installScriptMgrPtch27) THEN ; <4.6><15>
|
|||
|
;********************************************************************************
|
|||
|
;******** start of Gestalt function for Script Mgr <2.7> <08/05/89 pke> *********
|
|||
|
;********************************************************************************
|
|||
|
;
|
|||
|
; The following Gestalt Function is an interface between the Gestalt mechanism
|
|||
|
; and the Script Manager's GetEnvirons routine. Currently, it only supports two
|
|||
|
; Gestalt selectors: gestaltScriptMgrVersion and gestaltScriptCount.
|
|||
|
;
|
|||
|
; Routine gestaltScriptMgr (
|
|||
|
; gestaltSelector: OSType; = PACKED ARRAY [1..4] OF CHAR;
|
|||
|
; VAR gestaltResult: Longint;
|
|||
|
; ): OSErr; = Integer;
|
|||
|
;
|
|||
|
; <08/05/89 pke> New today
|
|||
|
;_________________________________________________________________________________
|
|||
|
|
|||
|
gestaltScriptMgr proc export
|
|||
|
|
|||
|
;_________________________________________________________________________________
|
|||
|
|
|||
|
export gestaltSMgrTable ; table for installation <8/05/89 pke>
|
|||
|
|
|||
|
|
|||
|
with gestaltParmFrame
|
|||
|
link a6,#localFrame
|
|||
|
|
|||
|
; initialize loop, set up default return values
|
|||
|
move.l gestaltSelector(a6),d0 ; selector value
|
|||
|
;; move.l gestaltResult(a6),a0 ; addr for result
|
|||
|
;; clr.l (a0) ; initially set result to 0
|
|||
|
move.l #gestaltUndefSelectorErr,result(a6) ; assume unknown selector
|
|||
|
lea gestaltSMgrTable,a1
|
|||
|
|
|||
|
; loop to find Gestalt selector in table
|
|||
|
@gestaltLoop
|
|||
|
move.l (a1)+,d1 ; get next table entry
|
|||
|
beq.s @gestaltDone ; end of list, quit
|
|||
|
move.w (a1)+,d2 ; now get GetEnvirons verb
|
|||
|
cmp.l d0,d1 ; is selector correct?
|
|||
|
bne.s @gestaltLoop ; no, get next one
|
|||
|
|
|||
|
; ok, we found the Gestalt selector. Now call GetEnvirons with correct verb
|
|||
|
clr.l -(sp) ; space for result
|
|||
|
move.w d2,-(sp) ; push verb
|
|||
|
_GetEnvirons
|
|||
|
move.l gestaltResult(a6),a0 ; addr for result
|
|||
|
move.l (sp)+,(a0) ; pop result into Gestalt
|
|||
|
move.w #noErr,result(a6) ; return no error
|
|||
|
; all done
|
|||
|
@gestaltDone
|
|||
|
|
|||
|
unlk a6
|
|||
|
move.l (sp)+,a0
|
|||
|
add.l #argSize,sp
|
|||
|
jmp (a0)
|
|||
|
|
|||
|
endWith
|
|||
|
|
|||
|
; Table for converting between gestalt selectors and GetEnvirons verbs. Each pair
|
|||
|
; consists of a long with the gestalt selector, followed by a word with the
|
|||
|
; GetEnvirons verb. This table and the equate files where the Gestalt selectors
|
|||
|
; are defined are the only things that need to change to add new Gestalt selectors
|
|||
|
; for the Script Manager.
|
|||
|
|
|||
|
gestaltSMgrTable
|
|||
|
dc.l gestaltScriptMgrVersion
|
|||
|
dc.w smVersion
|
|||
|
|
|||
|
dc.l gestaltScriptCount
|
|||
|
dc.w smEnabled
|
|||
|
|
|||
|
dc.l 0 ; terminator
|
|||
|
|
|||
|
endProc
|
|||
|
|
|||
|
;********** end of Gestalt function for Script Mgr <2.7> <08/05/89 pke> **********
|
|||
|
ENDIF ; <4.6>
|
|||
|
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
|
|||
|
; The following patch fixes the head of InitProcMenu. The wrong version was rolled into
|
|||
|
; the ROM, so we replace the head with this.
|
|||
|
|
|||
|
NewInitProcMenu proc export
|
|||
|
|
|||
|
ROMIMCommon equ $11446 ; place to rejoin ROM in InitMenus
|
|||
|
|
|||
|
; the following code is copied out of the Menu Manager InitProcMenu
|
|||
|
|
|||
|
move.l (sp)+,a0 ; get the return address
|
|||
|
move.w (sp)+,d1 ; get the MBDF resource ID
|
|||
|
move.l a0,-(sp) ; put return address back on the stack
|
|||
|
jsrROM ROMIMCommon ; call InitMenus <3.4>
|
|||
|
move.l MenuList,a0 ; get the menu list <3.4>
|
|||
|
move.l (a0),a0 ; dereference the menu list <3.4>
|
|||
|
move.w d1,mbResID(a0) ; store MBDF ID <3.4>
|
|||
|
rts ; return to InitProcMenu caller <3.4>
|
|||
|
|
|||
|
endproc
|
|||
|
|
|||
|
|
|||
|
;____________________________________________________________________________
|
|||
|
; Script Manager patch to Pack6, fixes problem with pointer to unlocked
|
|||
|
; handle in Transliterate. <3.7><08/21/89 pke>
|
|||
|
; Also fixes another problem in LwrString, CharType, Transliterate, FindWord:
|
|||
|
; These routines need to have the Script Manager IntlForce flag cleared
|
|||
|
; before calling IUGetIntl (this flag must be saved beforehand and restored
|
|||
|
; afterward). This ensures that the itl2 tables used by these routines apply
|
|||
|
; to the current script. <3.8><08/21/89 pke>
|
|||
|
; Only do the second fix for Scripts604 OR (SysVers > $604) <4.0><08/21/89 pke>
|
|||
|
;
|
|||
|
|
|||
|
IF doScriptMgrPack6Fix AND (NOT installScriptMgrPtch39) THEN ; <12><15>
|
|||
|
|
|||
|
ptchPack6 PROC Export
|
|||
|
|
|||
|
fromROMLwrString EQU $0797A
|
|||
|
fromROMCharType EQU $1745C
|
|||
|
fromROMFindWord EQU $176B6
|
|||
|
|
|||
|
fromROMTranslit EQU $1760A
|
|||
|
toROMTranslit EQU $17610
|
|||
|
ROMPack6 EQU $1E3F4
|
|||
|
|
|||
|
tlRecord record {a6link},decr
|
|||
|
result ds.w 1 ; function result.
|
|||
|
tlArgs equ *-8 ; size of arguments.
|
|||
|
srcHandle ds.l 1 ; srcHandle.
|
|||
|
dstHandle ds.l 1 ; dstHandle.
|
|||
|
target ds.w 1 ; target.
|
|||
|
srcMask ds.l 1 ; srcMask.
|
|||
|
selector ds.l 1 ; selector
|
|||
|
return ds.l 1 ; return address.
|
|||
|
a6link ds.l 1 ; old a6 register.
|
|||
|
tlLocals equ * ; size of local variables.
|
|||
|
endr
|
|||
|
|
|||
|
cmp.w #iuGetIntl,4(sp) ; is it an IUGetIntl call?
|
|||
|
bne.s @NoPatch ; skip if not (optimization)
|
|||
|
CmpRA fromROMLwrString,(sp)
|
|||
|
beq.s @PatchOther
|
|||
|
CmpRA fromROMCharType,(sp)
|
|||
|
beq.s @PatchOther
|
|||
|
CmpRA fromROMFindWord,(sp)
|
|||
|
beq.s @PatchOther
|
|||
|
CmpRA fromROMTranslit,(sp)
|
|||
|
beq.s @PatchTrans ; Translit is special - 2 bugs
|
|||
|
@NoPatch
|
|||
|
JmpROM ROMPack6 ; nothing interesting to do
|
|||
|
|
|||
|
@PatchTrans
|
|||
|
; We get here if we came from the _IUGetIntl in Transliterate (IUGetIntl is a
|
|||
|
; macro that pushes a selector and then does a _Pack6 trap). A few instructions
|
|||
|
; before the _IUgetIntl, we had handles in a1 and a2 which were then dereferenced
|
|||
|
; into the same registers. We want to postpone this dereferencing till after
|
|||
|
; _Pack6. Fortunately, the original handles are still available in Transliterate's
|
|||
|
; a6 frame, so we can get them after the Pack6 call, dereference them again, and
|
|||
|
; stuff them where they belong. We also need to clear the IntlForce flag around
|
|||
|
; Pack6 if it is set.
|
|||
|
|
|||
|
WITH tlRecord, SMgrRecord
|
|||
|
addq #4,sp ; kill old return address
|
|||
|
|
|||
|
GetSMgrCore a0 ; get pointer to SMgrRecord
|
|||
|
tst.b smgrIntlForce(a0) ; check IntlForce flag
|
|||
|
bne.s @fixFlag ; if set, go fix it
|
|||
|
|
|||
|
JsrROM ROMPack6
|
|||
|
bra.s @doDeref
|
|||
|
@fixFlag
|
|||
|
clr.b smgrIntlForce(a0) ; now force it to 0
|
|||
|
JsrROM ROMPack6
|
|||
|
GetSMgrCore a0 ; get pointer to SMgrRecord
|
|||
|
st smgrIntlForce(a0) ; restore IntlForce
|
|||
|
@doDeref
|
|||
|
; The next two lines are what follow the _IUGetIntl in the ROM Transliterate
|
|||
|
move.l (sp)+,a4 ;
|
|||
|
movem.l (sp)+,a1/d1-d2 ;
|
|||
|
; Now we expect to have pointers in a1 and a2, so set them up again (this is
|
|||
|
; the fix) and jump back into ROM:
|
|||
|
move.l srcHandle(a6),a1 ; get source handle.
|
|||
|
move.l dstHandle(a6),a2 ; get destination handle.
|
|||
|
move.l (a1),a1 ; get source pointer.
|
|||
|
move.l (a2),a2 ; get destination pointer.
|
|||
|
JmpROM toROMTranslit
|
|||
|
ENDWITH
|
|||
|
|
|||
|
@PatchOther
|
|||
|
; We get here if we came from the _IUGetIntl in LwrString, CharType, or
|
|||
|
; FindWord. If IntlForce is currently zero, we just JMP to the old Pack6.
|
|||
|
; Otherwise, we copy part of the stack in order to save the return address,
|
|||
|
; then JSR to Pack6, then fix up the stack.
|
|||
|
|
|||
|
WITH SMgrRecord
|
|||
|
GetSMgrCore a0 ; get pointer to SMgrRecord
|
|||
|
tst.b smgrIntlForce(a0) ; check IntlForce flag
|
|||
|
beq.s @NoPatch ; if already 0, nothing to do
|
|||
|
clr.b smgrIntlForce(a0) ; now force it to 0
|
|||
|
|
|||
|
; At this point the stack has 12 bytes that are significant for Pack6:
|
|||
|
; 8(sp).L = space for returned handle
|
|||
|
; 6(sp).W = argument, specifies which itlx
|
|||
|
; 4(sp).W = Pack6 routine selector = #iuGetIntl
|
|||
|
; 0(sp).L = return address
|
|||
|
; We now copy the selector, argument, and return space below the return address.
|
|||
|
; This sets up the stack correctly for the JsrROM (which will add a new return
|
|||
|
; address) while preserving our original return address.
|
|||
|
|
|||
|
clr.l -(sp) ; new place for returned handle
|
|||
|
move.l 8(sp),-(sp) ; copy selector and arguments
|
|||
|
|
|||
|
; Now this piece of stack has changed as follows:
|
|||
|
; 16(sp).L = old space for returned handle
|
|||
|
; 14(sp).W = old copy of argument (unnecessary)
|
|||
|
; 12(sp).W = old copy of selector (unnecessary)
|
|||
|
; 8(sp).L = old return address
|
|||
|
; 4(sp).L = new space for returned handle
|
|||
|
; 2(sp).W = new copy of argument, specifies which itlx
|
|||
|
; 0(sp).W = new copy of Pack6 routine selector = #iuGetIntl
|
|||
|
; We are now set up to call Pack6:
|
|||
|
|
|||
|
JsrROM ROMPack6
|
|||
|
|
|||
|
; The last stack picture:
|
|||
|
; 12(sp).L = old space for returned handle
|
|||
|
; 10(sp).W = nothing useful
|
|||
|
; 8(sp).W = nothing useful
|
|||
|
; 4(sp).L = old return address
|
|||
|
; 0(sp).L = returned handle
|
|||
|
; We need to copy the returned handle to where it should go, clean up the stack,
|
|||
|
; set IntlForce, and return.
|
|||
|
|
|||
|
move.l (sp)+,8(sp) ; copy returned handle to its place
|
|||
|
move.l (sp)+,a1 ; get return address
|
|||
|
addq #4,sp ; finish cleaning up stack
|
|||
|
GetSMgrCore a0 ; get pointer to SMgrRecord
|
|||
|
st smgrIntlForce(a0) ; restore IntlForce
|
|||
|
|
|||
|
; Now we just have the returned handle on the stack (see, no picture).
|
|||
|
|
|||
|
jmp (a1) ; go home (I'm about to).
|
|||
|
|
|||
|
ENDWITH
|
|||
|
ENDPROC
|
|||
|
|
|||
|
ENDIF ; <12>
|
|||
|
|
|||
|
;============================================================================ pke <3.9>
|
|||
|
; Patch UprString,RelString,CmpString to reintroduce the bug in which "`" is
|
|||
|
; converted to uppercase as "a". This is necessary to prevent HFS problems,
|
|||
|
; since existing disk catalogs use the old, buggy sorting. All we need to do
|
|||
|
; is patch them up to the point where they access the UpperTab table, which
|
|||
|
; does not have the necessary bug in ROM.
|
|||
|
;
|
|||
|
; A/UX uses the ROM versions of these routines, so we can install them for
|
|||
|
; A/UX.
|
|||
|
;
|
|||
|
PROC
|
|||
|
EXPORT NewUprString,NewCmpString,NewRelString
|
|||
|
|
|||
|
ROMUprStringAfterEntString equ $079D4
|
|||
|
ROMRelStringAfterEntString equ $079FE
|
|||
|
ROMEntStringAfterLEAUpperTab equ $07A5E
|
|||
|
|
|||
|
;______________________________________________________________________
|
|||
|
;
|
|||
|
; Routine: UprString
|
|||
|
; Arguments: D0.W (input) -- string length
|
|||
|
; A0.L (input) -- pointer to string to canonize
|
|||
|
; Opcode bit 10 -- 0 - map to upper case; 1 - case sensitive
|
|||
|
; Opcode bit 9 -- 0 - diacritical sensitive; 1 - strip diacrits
|
|||
|
; All registers are preserved.
|
|||
|
; Function: UprString is a utility routine which, according to
|
|||
|
; a pair of input booleans, strips diacritical marks
|
|||
|
; and/or maps all characters to upper case.
|
|||
|
;
|
|||
|
;______________________________________________________________________
|
|||
|
|
|||
|
NewUprString
|
|||
|
BSR EntString ; changed
|
|||
|
jmpRom ROMUprStringAfterEntString
|
|||
|
|
|||
|
;______________________________________________________________________
|
|||
|
;
|
|||
|
; Routine: CmpString, RelString
|
|||
|
; Arguments: D0.L (input) -- high-order word = string 0 length
|
|||
|
; low-order word = string 1 length
|
|||
|
; A0.L (input) -- pointer to string 0
|
|||
|
; A1.L (input) -- pointer to string 1
|
|||
|
; D0.W (output) --
|
|||
|
; CmpString -- result code = 0, 1 for equal, unequal.
|
|||
|
; RelString -- result code = -1, 0, 1 according as string 0
|
|||
|
; is <, =, > than string 1, respectively.
|
|||
|
; Opcode bit 10 -- 0 - map to upper case; 1 - case sensitive
|
|||
|
; Opcode bit 9 -- 0 - diacritical sensitive; 1 - strip diacrits
|
|||
|
; Pascal register conventions are observed.
|
|||
|
;
|
|||
|
; Calling Sequence for Pascal strings:
|
|||
|
; LEA str0,A0
|
|||
|
; LEA str1,A1
|
|||
|
; MOVEQ #0,D0
|
|||
|
; MOVE.B (A0)+,D0
|
|||
|
; SWAP D0
|
|||
|
; MOVE.B (A1)+,D0
|
|||
|
; _CmpString
|
|||
|
;
|
|||
|
; Function: CmpString is a utility routine to compare two strings for
|
|||
|
; equality. The strings are pointed to by A0 and A1
|
|||
|
; on entry; the result is returned in D0.
|
|||
|
; Two booleans determine the flavor of the compare:
|
|||
|
; Marks --
|
|||
|
; if set, all diacritical marks are ignored.
|
|||
|
; Case --
|
|||
|
; if set, all characters are mapped to upper case.
|
|||
|
;______________________________________________________________________
|
|||
|
|
|||
|
;
|
|||
|
; To expedite CmpString, test for length differences first. If they're the same,
|
|||
|
; use the absolute value of RelString's return.
|
|||
|
;
|
|||
|
|
|||
|
NewCmpString
|
|||
|
MOVE.W D0,D2 ; str 1 length
|
|||
|
SWAP D0 ; str 0 length
|
|||
|
CMP.W D0,D2
|
|||
|
BNE.S CSQuickNE
|
|||
|
SWAP D0 ; realign for fresh start in RelString
|
|||
|
BSR.S NewRelString ; count on CCR from last D0 store <3.9>
|
|||
|
BPL.S @1
|
|||
|
NEG.L D0 ; -1 ---> 1
|
|||
|
@1
|
|||
|
RTS
|
|||
|
CSQuickNE
|
|||
|
MOVEQ #1,D0 ; must differ since lengths do
|
|||
|
RTS
|
|||
|
|
|||
|
|
|||
|
;
|
|||
|
; Register usage:
|
|||
|
; D0 = shorter string length = loop index
|
|||
|
; D1 = trap opcode, with embedded booleans
|
|||
|
; D2 = string 0 input buffer
|
|||
|
; D3 = string 1 input buffer
|
|||
|
; D4 = -1, 0, 1 according to string lengths
|
|||
|
;
|
|||
|
; A0 = string 0 pointer
|
|||
|
; A1 = string 1 pointer
|
|||
|
;
|
|||
|
; Output:
|
|||
|
; D0 = -1, 0, 1
|
|||
|
; CCR reflects D0
|
|||
|
; D1-D2/A0-A1 trash
|
|||
|
;
|
|||
|
|
|||
|
NewRelString
|
|||
|
BSR.S EntString
|
|||
|
jmpROM ROMRelStringAfterEntString ; <3.9>
|
|||
|
|
|||
|
;______________________________________________________________________
|
|||
|
;
|
|||
|
; Utility EntString saves regs D3-D4/A2-A3, sets up opword for quick
|
|||
|
; test in Canonizer, and primes A2 with UpperTab and A3 with CmpTab.
|
|||
|
; D2 is cleared for use by Canonizer.
|
|||
|
;
|
|||
|
; Utility ExtString cleans up and returns, leaving CCR. It is jumped to...
|
|||
|
;______________________________________________________________________
|
|||
|
EntString
|
|||
|
MOVE.L (SP)+,D2 ; return address
|
|||
|
MOVEM.L D2-D4/A2-A3,-(SP) ; return on top
|
|||
|
LEA UpperTab,A2
|
|||
|
jmpROM ROMEntStringAfterLEAUpperTab ; <3.9>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
;
|
|||
|
; Handy macro allows for ease in building big, regular tables.
|
|||
|
; ASSEMBLER WON'T ALLOW EIGHTH ARGUMENT ON SAME LINE!!!!!!!!!!!!!!
|
|||
|
;
|
|||
|
MACRO
|
|||
|
crow
|
|||
|
DC.B (&Syslst[1]),( &Syslst[1]+1),( &Syslst[1]+2),( &Syslst[1]+3),( &Syslst[1]+4),( &Syslst[1]+5),( &Syslst[1]+6)
|
|||
|
DC.B (&Syslst[1]+7)
|
|||
|
ENDM
|
|||
|
|
|||
|
MACRO
|
|||
|
dcrow
|
|||
|
crow &Syslst[1]
|
|||
|
crow &Syslst[1]+8
|
|||
|
ENDM
|
|||
|
|
|||
|
|
|||
|
;_________________________________________________________________________________________________________
|
|||
|
;
|
|||
|
; <3.9> <08/21/89 dba/pke>
|
|||
|
;
|
|||
|
; Note the $61 at the beginning of the lower-case letters. In Feb. 89 for the ROMs, Peter E. fixed the
|
|||
|
; upper casing of the "`" (backquote) character. Previously, it would turn into "a" (ASCII $61).
|
|||
|
; Unfortunately, to our dismay, all of our old HFS disks require that this bug be perpetuated forever,
|
|||
|
; at least for the ordering of HFS names in the B-Tree, which use RelString. We also realized that
|
|||
|
; others may be using the string traps to order internal data structure. Because of all of this, we
|
|||
|
; are reintroducing the bug. The uppercase version of backquote is hereby declared to be lower-case a.
|
|||
|
;
|
|||
|
|
|||
|
UpperTab
|
|||
|
; Special chars, punctuation, digits, upper-case letters.
|
|||
|
dcrow $00
|
|||
|
dcrow $10
|
|||
|
dcrow $20
|
|||
|
dcrow $30
|
|||
|
dcrow $40
|
|||
|
dcrow $50
|
|||
|
|
|||
|
; Lower-case letters and some symbols.
|
|||
|
DC.B $61,( 'A'),( 'B'),( 'C'),( 'D'),( 'E'),( 'F'),( 'G') ; fixed ` <02/29/89 pke> unfixed <3.9>
|
|||
|
crow $48
|
|||
|
crow $50
|
|||
|
DC.B ('X'),( 'Y'),( 'Z'), $7B, $7C, $7D, $7E, $7F
|
|||
|
|
|||
|
; Accented characters.
|
|||
|
crow $80
|
|||
|
DC.B $CB, $89, $80, $CC, $81, $82, $83, $8F
|
|||
|
DC.B $90, $91, $92, $93, $94, $95, $84, $97
|
|||
|
DC.B $98, $99, $85, $CD, $9C, $9D, $9E, $86
|
|||
|
|
|||
|
; Symbols and upper-case AE and O-slash
|
|||
|
dcrow $A0
|
|||
|
|
|||
|
; Symbols and ae, o-slash
|
|||
|
crow $B0
|
|||
|
DC.B $B8, $B9, $BA, $BB, $BC, $BD, $AE, $AF
|
|||
|
|
|||
|
; Symbols, upper A-acute, A-tilde, O-tilde, OE, and oe
|
|||
|
crow $C0
|
|||
|
DC.B $C8, $C9, $CA, $CB, $CC, $CD, $CE, $CE
|
|||
|
|
|||
|
; Symbols and undefineds. y-umlaut cannot map up.
|
|||
|
dcrow $D0
|
|||
|
dcrow $E0
|
|||
|
dcrow $F0
|
|||
|
|
|||
|
; End of UpperTab
|
|||
|
;_________________________________________________________________________________________________________
|
|||
|
|
|||
|
ENDPROC
|
|||
|
|
|||
|
|
|||
|
IF doScriptMgrStr2DatFix AND (NOT installScriptMgrPtch39) THEN ; <5.4><12><15>
|
|||
|
;============================================================================ pke <5.4>
|
|||
|
; Patch Script Manager routines InitDateCache and String2Date for bug fixes
|
|||
|
; needed by HyperCard.
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
|
|||
|
proc
|
|||
|
export NewInitDateCache,NewString2Date
|
|||
|
|
|||
|
ROMValidLong equ $1895A ; <5.4>
|
|||
|
ROMBlock2String equ $18996 ; <5.4>
|
|||
|
ROMMatchString equ $18A02 ; <5.4>
|
|||
|
; in InitDateCache ($18A60):
|
|||
|
ROMAfter2ndJSRCopyArray equ $18BC8 ; <5.4>
|
|||
|
ROMExit equ $18C40 ; <5.4>
|
|||
|
; in/after String2Date (18C6E):
|
|||
|
ROMAfterDBNE equ $18DB4 ; <5.4>
|
|||
|
ROMDTComExit equ $18F04 ; <5.4>
|
|||
|
ROMFixValue equ $18F4C ; <5.4>
|
|||
|
ROMDateTimeEntry equ $18F5C ; <5.4>
|
|||
|
|
|||
|
WhiteSpace EQU 1 ; token number for white space
|
|||
|
AlphaToken EQU 4 ; token number for string
|
|||
|
NumericToken EQU 5 ; token number for number
|
|||
|
AltNumericToken equ $B ; alternate token type for numbers
|
|||
|
NonAlphNumToken EQU 16 ; token numbers starting here correspond to non-alpha numeric tokens
|
|||
|
MaxTokens EQU 32 ; number of tokens for which there is space
|
|||
|
|
|||
|
omdy EQU 0 ; date order constants
|
|||
|
odmy EQU 1
|
|||
|
oymd EQU 2
|
|||
|
|
|||
|
Str15 EQU 16 ; length of string[15]
|
|||
|
DayMonthLen equ 15 ; length of days and months
|
|||
|
NumDays EQU 7 ; length of various arrays
|
|||
|
NumMonths EQU 12
|
|||
|
DayList EQU NumDays*Str15
|
|||
|
MonthList EQU NumMonths*Str15
|
|||
|
NumStrBytes EQU 300
|
|||
|
|
|||
|
Cache RECORD 0
|
|||
|
version ds.w 1
|
|||
|
CurrentDate DS LongDateRec
|
|||
|
BaseDate DS LongDateRec
|
|||
|
theDays DS.B DayList ; <5.4>
|
|||
|
theMonths DS.B MonthList ; <5.4>
|
|||
|
theEveStr DS.B Str15
|
|||
|
theMornStr DS.B Str15
|
|||
|
the24hrStr DS.B Str15
|
|||
|
theTimeSep DS.W 1
|
|||
|
theDateSep DS.W 1
|
|||
|
theDateOrder DS.b 1
|
|||
|
longDateOrder ds.b 1
|
|||
|
theAbbrLen DS.W 1
|
|||
|
TBlock DS tokenBlock
|
|||
|
CacheSize equ *
|
|||
|
theTimeStrings equ theEveStr
|
|||
|
ENDR
|
|||
|
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
; function InitDateCache(theCache: CachePtr): OSErr;
|
|||
|
;
|
|||
|
; InitDateCache will initialize the items in the DateCacheRecord pointed to by theCache^
|
|||
|
; and set the initialized item to true
|
|||
|
;
|
|||
|
; The bug fixes are in the CopyArray subroutine <5.4>.
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
|
|||
|
idcSaveRegs REG A2-A4/D3/d4
|
|||
|
|
|||
|
InitCacheRec RECORD {A6link},decr
|
|||
|
Result DS.W 1 ; offset to function result (integer)
|
|||
|
paramBegin EQU *
|
|||
|
theCache DS.L 1 ; pointer to the cache record
|
|||
|
selector ds.l 1 ; added for resource
|
|||
|
paramEnd EQU *
|
|||
|
return DS.L 1
|
|||
|
A6link DS.L 1
|
|||
|
theTokens DS.B 2*TokenRec.tokenRecSize
|
|||
|
Intl0 DS.L 1 ; handle, not pointer
|
|||
|
Intl1 DS.L 1 ; handle, not pointer
|
|||
|
altSpace ds.w 1 ; use top byte
|
|||
|
aLongDate ds LongDateTime ;
|
|||
|
localsize EQU *
|
|||
|
ENDR
|
|||
|
|
|||
|
WITH InitCacheRec,LongDateField
|
|||
|
|
|||
|
NewInitDateCache
|
|||
|
LINK A6,#localsize ; Establish local frame and variables
|
|||
|
MOVEM.L idcSaveRegs,-(SP) ; saved used registers
|
|||
|
CLR.W Result(A6) ; clear function result
|
|||
|
|
|||
|
MOVE.L theCache(A6),A2 ; cache addr
|
|||
|
|
|||
|
move.b #' ',altSpace(a6) ; assume no alt space
|
|||
|
|
|||
|
sub.l #6,sp ; reserve returns
|
|||
|
_IntlScript ; get the script
|
|||
|
move.w #smScriptRight,-(sp) ; get flag
|
|||
|
_GetScript ; get value
|
|||
|
tst.l (sp)+ ; got it?
|
|||
|
beq.s @NoAltSpace ; no
|
|||
|
move.b #' '+$80,altSpace(a6) ; use alt space.
|
|||
|
@NoAltSpace
|
|||
|
|
|||
|
WITH Cache
|
|||
|
|
|||
|
lea aLongDate(a6),a0 ; @temp
|
|||
|
clr.l (a0)+ ; no high
|
|||
|
move.l Time,(a0)+ ; low = current
|
|||
|
pea aLongDate(a6) ; extended
|
|||
|
pea CurrentDate(A2) ; get current date from system global time and convert to date
|
|||
|
_LongSecs2Date
|
|||
|
|
|||
|
lea aLongDate(a6),a0 ; @temp
|
|||
|
clr.l (a0)+ ; no high
|
|||
|
clr.l (a0)+ ; low = current
|
|||
|
pea aLongDate(a6) ; extended
|
|||
|
pea BaseDate(A2) ; get base date and convert to date
|
|||
|
_LongSecs2Date
|
|||
|
|
|||
|
; IUGetIntl(0): Handle
|
|||
|
|
|||
|
CLR.L -(SP)
|
|||
|
CLR.W -(SP)
|
|||
|
_IUGetIntl
|
|||
|
MOVE.L (SP)+,Intl0(A6)
|
|||
|
|
|||
|
move.w ResErr,d0 ; did intl0 load in all right
|
|||
|
BEQ.S GotIntl0Ok ; if so, go on
|
|||
|
|
|||
|
MOVE.W d0,Result(A6)
|
|||
|
BRA Exit
|
|||
|
|
|||
|
GotIntl0Ok
|
|||
|
; IUGetIntl(1): Handle
|
|||
|
|
|||
|
CLR.L -(SP)
|
|||
|
MOVE.W #1,-(SP)
|
|||
|
_IUGetIntl
|
|||
|
MOVE.L (SP)+,Intl1(A6)
|
|||
|
|
|||
|
TST.W ResErr ; did intl0 load in all right
|
|||
|
BEQ.S GetSeparators ; if so, go on
|
|||
|
|
|||
|
MOVE.W ResErr,Result(A6)
|
|||
|
BRA Exit
|
|||
|
|
|||
|
GetSeparators
|
|||
|
MOVE.L Intl0(A6),A3
|
|||
|
; Lock itl0 across Block2String calls (which can now move memory)
|
|||
|
move.l a3,a0
|
|||
|
_MoveHHi
|
|||
|
move.l a3,a0
|
|||
|
_HLock
|
|||
|
|
|||
|
MOVE.L (A3),A3 ; now a3 is pointer to itl0
|
|||
|
|
|||
|
; Block2String(eveStr,theEveStr,4,true)
|
|||
|
|
|||
|
LEA eveStr(A3),A0 ; get international 0 record for evening string
|
|||
|
LEA theEveStr(A2),A1
|
|||
|
MOVEQ #4,D0
|
|||
|
MOVE.B #1,D1
|
|||
|
move.b altSpace(a6),d2 ; pass alt string
|
|||
|
JsrROM ROMBlock2String ; convert packed array of char into string <5.4>
|
|||
|
; with no leading spaces
|
|||
|
; Block2String(mornStr,theMornStr,4,true)
|
|||
|
|
|||
|
LEA mornStr(A3),A0 ; get international 0 record for morning string
|
|||
|
LEA theMornStr(A2),A1
|
|||
|
MOVEQ #4,D0
|
|||
|
MOVE.B #1,D1
|
|||
|
move.b altSpace(a6),d2 ; pass alt string
|
|||
|
JsrROM ROMBlock2String ; convert packed array of char into string <5.4>
|
|||
|
; with no leading spaces
|
|||
|
; Block2String(time1Stuff,the24hrStr,1,true)
|
|||
|
|
|||
|
LEA timeSuff(A3),A0 ; get international 0 record for 24 hour string
|
|||
|
LEA the24hrStr(A2),A1
|
|||
|
MOVEQ #1,D0
|
|||
|
MOVE.B #1,D1
|
|||
|
move.b altSpace(a6),d2 ; pass alt string
|
|||
|
JsrROM ROMBlock2String ; convert packed array of char into string <5.4>
|
|||
|
; with no leading spaces
|
|||
|
|
|||
|
MOVE.B timeSep(A3),theTimeSep(A2) ; get time separator from intl 0
|
|||
|
MOVE.B dateOrder(A3),theDateOrder(A2)
|
|||
|
MOVE.B dateSep(A3),(theTimeSep + 1)(A2)
|
|||
|
|
|||
|
; Now unlock itl0
|
|||
|
move.l Intl0(A6),a0
|
|||
|
_HUnlock
|
|||
|
|
|||
|
MOVE.L Intl1(A6),A3
|
|||
|
|
|||
|
; Lock itl1 across Copy Array calls; it calls Block2String, which can now move memory
|
|||
|
move.l a3,a0
|
|||
|
_MoveHHi
|
|||
|
move.l a3,a0
|
|||
|
_HLock
|
|||
|
|
|||
|
MOVE.L (A3),A3 ; now a3 is pointer to itl1
|
|||
|
|
|||
|
; Get the long date order and convert
|
|||
|
; false => dmy, true => mdy; otherwise fancy stuff
|
|||
|
|
|||
|
move.l #omdy,d1 ; assume false
|
|||
|
clr.w d0 ; wordize
|
|||
|
move.b lngDateFmt(a3),d0 ; get long format
|
|||
|
beq.s @GotLong ; done
|
|||
|
move.l #odmy,d1 ; assume true
|
|||
|
cmp.b #$FF,d0 ; true?
|
|||
|
beq.s @GotLong ; yes, got it
|
|||
|
|
|||
|
; if we are looking at the long date, only the day and year are important,
|
|||
|
; since the dayOfWeek and month are both strings. Walk through the format until
|
|||
|
; we find either one or the other
|
|||
|
|
|||
|
@LongFmtLoop
|
|||
|
move.b d0,d2 ; get bottom half-nybble
|
|||
|
and.b #3,d2 ; got it
|
|||
|
cmp.b #longDay,d2 ; day?
|
|||
|
beq.s @GotLong ; yes, return #odmy
|
|||
|
cmp.b #longYear,d2 ; year?
|
|||
|
beq.s @LongYearFirst ; go for it
|
|||
|
lsr.b #2,d0 ; strip bottom
|
|||
|
bne.s @LongFmtLoop ; repeat until done
|
|||
|
@LongYearFirst
|
|||
|
move.l #oymd,d1 ; year first (also if none found)
|
|||
|
|
|||
|
@GotLong
|
|||
|
move.b d1,longDateOrder(a2) ; set it
|
|||
|
|
|||
|
; continue
|
|||
|
MOVE.B abbrLen(A3),theAbbrLen(A2) ; get abbrLen
|
|||
|
|
|||
|
; changed order for more convenience in the later routine
|
|||
|
lea months(a3),a4 ; source of days
|
|||
|
LEA theMonths(A2),a1 ; destination names of the day and months
|
|||
|
MOVE.L #(numMonths - 1),D3 ; load day and months from intl 1 rec into space
|
|||
|
jsr CopyArray ; copy days
|
|||
|
|
|||
|
lea days(a3),a4 ; source of days
|
|||
|
LEA theDays(A2),a1 ; destination names of the day and months
|
|||
|
MOVE.L #(numDays - 1),D3 ; load day and months from intl 1 rec into space
|
|||
|
jsr CopyArray ; copy days
|
|||
|
|
|||
|
; Now continue with ROM code
|
|||
|
JmpROM ROMAfter2ndJSRCopyArray ; <5.4>
|
|||
|
Exit
|
|||
|
JmpROM ROMExit ; <5.4>
|
|||
|
|
|||
|
; little subroutine for code savings
|
|||
|
; a4 is source pointer
|
|||
|
; a1 is dest pointer
|
|||
|
; d3 is byte length
|
|||
|
|
|||
|
CopyArray
|
|||
|
move.l a1,d4 ; dest ptr
|
|||
|
|
|||
|
@LOOP MOVE.L A4,A0 ; move string from intl 1 rec <5.4>
|
|||
|
MOVE.L d4,A1 ; into local frame
|
|||
|
moveq #0,d0 ; Block2String wants a long! <5.4>
|
|||
|
MOVE.B (A0)+,D0 ; with length from first byte of string
|
|||
|
MOVEQ #1,D1 ; with no local frame
|
|||
|
move.b altSpace(a6),d2 ; pass alt string
|
|||
|
JsrROM ROMBlock2String ; search <5.4>
|
|||
|
ADD.L #Str15,d4 ; get next string to transfer
|
|||
|
ADD.w #Str15,A4 ; into next string in local frame <5.4>
|
|||
|
DBRA D3,@LOOP
|
|||
|
rts
|
|||
|
|
|||
|
ENDWITH ; Cache
|
|||
|
ENDWITH
|
|||
|
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
;function String2Date( textPtr: Ptr;
|
|||
|
; textLen: longint;
|
|||
|
; theCache: DateCachePtr;
|
|||
|
; var lengthUsed: longint;
|
|||
|
; var DateTime: LongDateRec): Integer;
|
|||
|
;
|
|||
|
; String2Date will look for a date in the text given it according to the international
|
|||
|
; resource format. Using the Tokenizer routine it will look for a dayofWeek (which will
|
|||
|
; be a string), a month (either a string or a number) and a day and year (both numbers).
|
|||
|
; If the month is a number, order is decided by the ShortDate format in INTL 0; otherwise
|
|||
|
; String2Date uses a table. Note if only two numbers are found they are assumed to be day
|
|||
|
; and month. If one number is found it is assumed to be a date. Missing fields are
|
|||
|
; filled in by the current date and time
|
|||
|
;
|
|||
|
; Register Usage
|
|||
|
;
|
|||
|
; A2 - Work register D3 - loop control register
|
|||
|
; A3 - Work register D4 - MonthFound
|
|||
|
; A4 - Cache Addr D5 - ResultNum
|
|||
|
; D6 - AbbrLen
|
|||
|
; D7 - NumDelimsFound
|
|||
|
;
|
|||
|
; The bug fixes are: … <5.4>
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
|
|||
|
s2dSaveRegs REG D3-D7/A2-a4 ; removed a5
|
|||
|
|
|||
|
DateFrame RECORD {A6link},decr
|
|||
|
Result DS.W 1 ; offset to function result (integer)
|
|||
|
paramBegin EQU *
|
|||
|
textPtr DS.L 1 ; offset to Date2Time's paramters
|
|||
|
textLen DS.L 1
|
|||
|
theCache DS.L 1 ; @DateCacheRecord
|
|||
|
RestofText DS.L 1 ; @Longint
|
|||
|
DateTime DS.L 1 ; @LongDateRec
|
|||
|
selector ds.l 1 ; added for resource
|
|||
|
paramEnd EQU *
|
|||
|
return DS.L 1
|
|||
|
A6link DS.L 1
|
|||
|
theTokens DS.B MaxTokens*TokenRec.tokenRecSize ; storage for tokens found by tokenizer
|
|||
|
theDate DS LongDateRec ; date time rec
|
|||
|
results DS.W 3 ; three temporary results
|
|||
|
myDateOrder DS.W 1
|
|||
|
DayFound DS.W 1
|
|||
|
lastItemSep DS.W 1
|
|||
|
lastToken DS.W 1
|
|||
|
lastTokenAddr DS.L 1
|
|||
|
lastExToken DS.W 1
|
|||
|
dummyLongDate ds LongDateTime
|
|||
|
stringStorage DS.B NumStrBytes
|
|||
|
localsize EQU *
|
|||
|
ENDR
|
|||
|
|
|||
|
WITH DateFrame
|
|||
|
With Cache,LongDateField
|
|||
|
|
|||
|
NewString2Date
|
|||
|
LINK A6,#localsize ; Establish local frame and variables
|
|||
|
MOVEM.L s2dSaveRegs,-(SP) ; saved used registers
|
|||
|
JsrROM ROMDateTimeEntry ; initialize & call _IntlTokenize
|
|||
|
|
|||
|
; Note that DateTimeEntry also does the following:
|
|||
|
; 1. moves theCache(a6) into a4
|
|||
|
; 2. moves TheTokens(a6) into a3
|
|||
|
; 3. sets result(a6)
|
|||
|
; 4. clears D7,D6; sets D5.L = -1
|
|||
|
; 5. after IntlTokenize, sets D3= number of tokens - 1
|
|||
|
|
|||
|
tst.w result(a6) ; entry failed?
|
|||
|
bne DTComExit ; bail if so
|
|||
|
|
|||
|
; specific stuff
|
|||
|
|
|||
|
MOVEQ #-1,D4 ; initialize MonthFound to -1
|
|||
|
CLR.W DayFound(A6)
|
|||
|
LEA CurrentDate(A4),A1 ; source
|
|||
|
LEA theDate(A6),A0 ;
|
|||
|
MOVE.L (A1)+,(A0)+ ; era, year
|
|||
|
MOVE.L (A1)+,(A0)+ ; month, day
|
|||
|
MOVE.L (A1)+,(A0)+ ; hour, minute
|
|||
|
move.w (a1)+,(a0)+ ; second
|
|||
|
CLR.W (A0)+ ; clear out dayOfWeek. Will either be set by user or be set
|
|||
|
; in the course of the validity check of the date
|
|||
|
MOVE.B theAbbrLen(A4),D6
|
|||
|
|
|||
|
WITH TokenRec
|
|||
|
|
|||
|
@TokenLoop
|
|||
|
MOVE.W theToken(A3),D1 ; get token code from TokenRec record at (A3)
|
|||
|
CMP.W #NonAlphNumToken,D1 ; is it a separator
|
|||
|
BGE.S @FoundSeparator
|
|||
|
SUB.W #WhiteSpace,D1 ; was it a white space?
|
|||
|
BEQ @TokenLoopEnd ; ignore
|
|||
|
SUBQ.W #(AlphaToken - WhiteSpace),D1 ; is it an alpha token?
|
|||
|
beq.s @FoundAlpha
|
|||
|
SUBQ.W #(NumericToken - AlphaToken),D1 ; is it a number token?
|
|||
|
BEQ.S @NumberToken
|
|||
|
SUBQ.W #(AltNumericToken - NumericToken),D1 ; is it a number token?
|
|||
|
BEQ.S @NumberToken ;
|
|||
|
BRA @TokenLoopEnd ; ignore any other characters
|
|||
|
|
|||
|
@FoundSeparator
|
|||
|
TST.B D7 ; possible separator. Has a separator already been found
|
|||
|
BEQ.S @OneDelimFound ; no, so no error yet
|
|||
|
OR.W #TooManySeps,Result(A6) ; yes, so now we have too many separators
|
|||
|
|
|||
|
@OneDelimFound
|
|||
|
ADDQ.B #1,D7 ; record separator found
|
|||
|
TST.w D5 ; is this after the first number loaded? (.w) <1/5/88med>
|
|||
|
BMI @TokenLoopEnd ; if we have not reached a number yet go on
|
|||
|
BNE.S @CheckDateSep ; if we loaded in a number then check consistency
|
|||
|
|
|||
|
MOVE.W D1,lastItemSep(A6) ; otherwise update lastItemSep with just found separator
|
|||
|
BRA @TokenLoopEnd
|
|||
|
|
|||
|
@CheckDateSep
|
|||
|
CMP.W lastItemSep(A6),D1 ; are they consistent
|
|||
|
BEQ @TokenLoopEnd ; if yes, than go on
|
|||
|
|
|||
|
OR.W #SepNotIntlSep+sepNotConsistent,Result(A6) ; record warning
|
|||
|
BRA @TokenLoopEnd
|
|||
|
|
|||
|
@NumberToken
|
|||
|
; check for numbers separated only by white space
|
|||
|
tst.w d7 ; got a separator?
|
|||
|
bne.s @1 ; yes
|
|||
|
tst.w d5 ; first number?
|
|||
|
blt.s @1 ; yes, skip
|
|||
|
bne.s @0 ; have 1 number
|
|||
|
move.w #WhiteSpace,lastItemSep(A6) ; set separator
|
|||
|
bra.s @1 ; continue
|
|||
|
@0
|
|||
|
cmp.w #WhiteSpace,lastItemSep(a6) ; same?
|
|||
|
beq.s @1 ; yes, continue
|
|||
|
or.w #SepNotIntlSep+sepNotConsistent,Result(A6) ; record warning
|
|||
|
@1
|
|||
|
; end of white space check
|
|||
|
|
|||
|
CLR.L D7 ; clear out past separators
|
|||
|
CMP.W #2,D5 ; make sure that results array is not full
|
|||
|
BGE @ExtrnsToken ; if full, record warning and search <5.4>
|
|||
|
; for final string (remove .s)
|
|||
|
|
|||
|
; ValidLong(position,textLength): longint
|
|||
|
|
|||
|
MOVE.L stringPosition(A3),A0
|
|||
|
JsrROM ROMValidLong ; get number in text at TokenRec.position <5.4>
|
|||
|
BMI DTComExit
|
|||
|
|
|||
|
JsrROM ROMFixValue ; <5.4>
|
|||
|
bra @TokenRecognized ; get next token (remove .s) <5.4>
|
|||
|
|
|||
|
@FoundAlpha
|
|||
|
CLR.L D7 ; clear out past separators
|
|||
|
|
|||
|
; UprString(newTextPtr,AbbrLen) ; and make it uppercase for case insensitive search
|
|||
|
|
|||
|
MOVE.L stringPosition(A3),A2
|
|||
|
ADDQ.L #1,A2
|
|||
|
MOVE.L A2,A0
|
|||
|
MOVE.L length(A3),D0 ; use real length
|
|||
|
|
|||
|
_UpperText ; _LwrString with uppercase function <11><13>
|
|||
|
|
|||
|
TST.W D4
|
|||
|
BPL.S @SearchForDay ; <5.4>
|
|||
|
|
|||
|
; MatchString(newTextPtr,AbbrLen,@months,15,12): integer
|
|||
|
|
|||
|
CLR.W -(SP) ; attempt to find a day/month string which matches alpha token
|
|||
|
MOVE.L A2,-(SP)
|
|||
|
MOVE.W length+2(a3),-(SP) ; push length as integer
|
|||
|
MOVE.W D6,-(SP) ; push minlen as integer
|
|||
|
PEA theDays(A4) ; <5.4>
|
|||
|
MOVE.W #DayMonthLen,-(SP)
|
|||
|
MOVE.W #NumMonths+NumDays,-(SP) ; check for both at once
|
|||
|
JsrROM ROMMatchString ; <5.4>
|
|||
|
MOVE.W (SP)+,D2 ; save in D2
|
|||
|
BLE.S @ExtrnsToken ; checking both
|
|||
|
|
|||
|
; decide between days and months
|
|||
|
|
|||
|
sub.w #NumDays,d2 ; months?
|
|||
|
ble.s @CheckForDay ; no, do days
|
|||
|
|
|||
|
; got a month
|
|||
|
CMP.W #2,D5 ; is result array already full?
|
|||
|
BGE.S @ExtrnsToken ; if so, then its not a needed token
|
|||
|
|
|||
|
ADDQ.W #1,D5 ; is in range, result is not full and string
|
|||
|
MOVE.W D5,D1 ; did not match as a day
|
|||
|
ADD.W D1,D1 ; double index for integer array
|
|||
|
LEA results(A6),A1 ; ResultNum:= ResultNum + 1
|
|||
|
MOVE.W D2,(A1,D1.W) ; results[ResultNum]:= match result
|
|||
|
MOVE.W D5,D4 ; MonthFound:= resultNum
|
|||
|
BRA.S @TokenRecognized
|
|||
|
|
|||
|
; if day not found yet, we need to see if current string matches a day <5.4>
|
|||
|
@SearchForDay
|
|||
|
TST.B DayFound(a6) ; have we found one yet?
|
|||
|
BNE.S @ExtrnsToken ; day already found, record warning
|
|||
|
|
|||
|
CLR.W -(SP) ; attempt to find a day string which matches alpha token
|
|||
|
MOVE.L A2,-(SP)
|
|||
|
MOVE.W length+2(a3),-(SP) ; push length as integer
|
|||
|
MOVE.W D6,-(SP) ; push minlen as integer
|
|||
|
PEA theDays(A4)
|
|||
|
MOVE.W #DayMonthLen,-(SP)
|
|||
|
MOVE.W #NumDays,-(SP) ; just check days this time
|
|||
|
JsrROM ROMMatchString ; <5.4>
|
|||
|
MOVE.W (SP)+,D2 ; save in D2
|
|||
|
BLE.S @ExtrnsToken ; checking both
|
|||
|
|
|||
|
BRA.S @HaveDay
|
|||
|
|
|||
|
@CheckForDay
|
|||
|
TST.B DayFound(a6) ; off of a6!
|
|||
|
BNE.S @ExtrnsToken ; day already found, record warning
|
|||
|
|
|||
|
add.w #NumDays,d2 ; restore days <5.4>
|
|||
|
@HaveDay ; <5.4>
|
|||
|
ST DayFound(A6) ; record that day was found <5.4>
|
|||
|
|
|||
|
MOVE.W D2,theDate.dayOfWeek(A6) ; otherwise, load dayOfWeek into date time record
|
|||
|
|
|||
|
TST.W D5 ; is dayOfWeek between two numbers (.w)
|
|||
|
BMI.S @NoWarning ; if no number has been found yet, go on
|
|||
|
OR.W #fieldOrderNotIntl,Result(A6) ; record warning
|
|||
|
@NoWarning
|
|||
|
BRA.S @TokenRecognized
|
|||
|
|
|||
|
@ExtrnsToken
|
|||
|
TST.W lastExToken(A6) ; is this the first extraneous token found?
|
|||
|
BPL.S @TokenLoopEnd ; no, go on
|
|||
|
|
|||
|
MOVE.W D3,lastExToken(A6) ; a string which we don't recognize has been found
|
|||
|
BRA.S @TokenLoopEnd ; record warning and go on
|
|||
|
|
|||
|
@TokenRecognized
|
|||
|
MOVE.W D3,lastToken(A6)
|
|||
|
MOVE.L A3,lastTokenAddr(A6) ; save loop and token addr for later use
|
|||
|
|
|||
|
@TokenLoopEnd
|
|||
|
ADD.L #tokenRecSize,A3 ; add size of TokenRec record to A3 to get next token
|
|||
|
CMP.W #2,D5 ; if the result array full (.w)
|
|||
|
SGE D0
|
|||
|
AND.B DayFound(A6),D0 ; and dayofWeek string been found
|
|||
|
DBNE D3,@TokenLoop ; then stop loop, otherwise go until all tokens are looked at
|
|||
|
|
|||
|
JmpROM ROMAfterDBNE
|
|||
|
;======================================================================
|
|||
|
DTComExit
|
|||
|
JmpROM ROMDTComExit
|
|||
|
|
|||
|
endproc
|
|||
|
|
|||
|
ENDIF
|
|||
|
|
|||
|
IF doScriptMgrRstKCHRFix AND (NOT installScriptMgrPtch39) THEN ; <5.5><12><15>
|
|||
|
;============================================================================ pke <5.5>
|
|||
|
; Tail patch on _GetIndADB to fix bug in Script Manager ResetKCHR routine
|
|||
|
; called by SwapKybd: it clears ADB keyboard driver dead state as a word,
|
|||
|
; should be a long.
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
|
|||
|
proc
|
|||
|
export ptchGetIndADB
|
|||
|
|
|||
|
ROMAfterGetIndADB equ $17B0A
|
|||
|
ROMAfterClrDeadKey equ $17B1A
|
|||
|
ROM@1dbra equ $17B26
|
|||
|
|
|||
|
|
|||
|
ptchGetIndADB
|
|||
|
CmpRA ROMAfterGetIndADB,OSTrapReturnAddressDepth(sp) ; From ResetKCHR?
|
|||
|
bne.s @0 ; if not, just continue with trap
|
|||
|
lea ptchResetKCHR,a1 ; a1 is not a param for GetIndADB
|
|||
|
move.l a1,OSTrapReturnAddressDepth(sp) ; so trap returns to patch, not ROM
|
|||
|
@0 BackToTrap oldGetIndADB ; now get on with the trap
|
|||
|
|
|||
|
|
|||
|
; When we reach the patch below, we are in ResetKCHR just after the _GetIndADB
|
|||
|
|
|||
|
rkRecord record {a6link},decr
|
|||
|
rkArgs equ *-8 ; size of arguments.
|
|||
|
pointer ds.l 1 ; new KCHR pointer.
|
|||
|
return ds.l 1 ; return address.
|
|||
|
a6link ds.l 1 ; old a6 register.
|
|||
|
adb ds ADBDataBlock ; ADB data structure.
|
|||
|
oldKeyboard ds.l 1 ; old keyboard pointer
|
|||
|
rkLocals equ * ; size of local variables.
|
|||
|
endr
|
|||
|
|
|||
|
ptchResetKCHR
|
|||
|
with rkRecord
|
|||
|
|
|||
|
cmp.b #kybdADBAddr,adb.origADBAddr(a6) ; is it a keyboard?
|
|||
|
bne.s @1 ; no -> skip it.
|
|||
|
move.l adb.dbDataAreaAddr(a6),a0 ; load data area pointer.
|
|||
|
clr.l KybdDriverData.deadKey(a0) ; clear dead state - long! <5.5>
|
|||
|
JmpROM ROMAfterClrDeadKey ; <5.5>
|
|||
|
|
|||
|
@1 JmpROM ROM@1dbra ; <5.5>
|
|||
|
|
|||
|
endwith
|
|||
|
endproc
|
|||
|
|
|||
|
ENDIF
|
|||
|
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
|
|||
|
IF doScriptMgrLwrString2 AND (NOT installScriptMgrPtch27) THEN ; <5.9><15>
|
|||
|
;============================================================================ pke <5.9>
|
|||
|
; Patch LwrString to handle 2-byte chars via Transliterate.
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
; routine: LwrString
|
|||
|
; input: a0 textPtr
|
|||
|
; d0.w length
|
|||
|
; d1.w trap word; the following bits are significant in 7.0 only:
|
|||
|
; Opcode bits
|
|||
|
; 10 9 Function
|
|||
|
; -- -- --------
|
|||
|
; 0 0 convert to lower-case
|
|||
|
; 0 1 strip diacritics
|
|||
|
; 1 0 convert to upper-case
|
|||
|
; 1 1 convert to upper-case and strip diacritics
|
|||
|
; output: d0.w error
|
|||
|
; function: Change text pointed to by a0 according to opcode bits. Before 7.0, we
|
|||
|
; just assume that these bits are 0 and act accordingly.
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
|
|||
|
proc
|
|||
|
export ptchLwrString
|
|||
|
|
|||
|
lwrTrFrame record {a6link},decr
|
|||
|
return ds.l 1 ; return address
|
|||
|
a6link ds.l 1 ; link pointer
|
|||
|
sourcePtr ds.l 1 ; orig source ptr
|
|||
|
sourceLen ds.l 1 ; orig source len
|
|||
|
sourceHndl ds.l 1 ; new handle with copy of source
|
|||
|
destHndl ds.l 1 ; new handle for transliterate result
|
|||
|
errCode ds.w 1 ; err code to be returned in d0
|
|||
|
lwrTrLocals equ * ; size of locals
|
|||
|
endr
|
|||
|
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
; NOTE: For 2-byte scripts, we need to call Transliterate. So, the first thing to
|
|||
|
; do is figure out what script we're in. We also test for length <= 0 (tests >32K).
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
|
|||
|
ptchLwrString
|
|||
|
ext.l d0 ; as fast as tst.w and we need ext.l later
|
|||
|
ble lwrRTS ; if bad length, quit
|
|||
|
movem.l a0/d0/d1,-(sp) ; save important registers
|
|||
|
subq.l #2,sp ; make room for return
|
|||
|
_FontScript ; find script of port
|
|||
|
move.w (sp)+,d2 ; pop it into d2
|
|||
|
movem.l (sp)+,a0/d0/d1 ; restore important registers
|
|||
|
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
; Here we make use of the fact that a word redraw flag of 1 (or anything >0)
|
|||
|
; indicates a 2-byte script.
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
|
|||
|
with SMgrRecord,ScriptRecord
|
|||
|
lsl.w #2,d2 ; make script code a long offset
|
|||
|
move.l IntlSpec,a1 ; get SMgrRecord pointer
|
|||
|
move.l smgrEntry(a1,d2.w),d2 ; get ScriptRecord pointer
|
|||
|
beq lwrRTS ; if nil (script not installed), do nothing
|
|||
|
move.l d2,a1
|
|||
|
tst.b scriptEnabled(a1) ; is script enabled?
|
|||
|
beq lwrRTS ; if not, do nothing
|
|||
|
tst.b scriptRedraw(a1) ; is it a 2-byte script?
|
|||
|
ble not2Byte ; if not, go use normal LwrString
|
|||
|
endwith
|
|||
|
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
; OK, we need to set up for Transliterate: set up source & dest handles
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
|
|||
|
with lwrTrFrame
|
|||
|
link a6,#lwrTrLocals ; create local storage
|
|||
|
move.l a0,sourcePtr(a6) ; save source ptr
|
|||
|
move.l d0,sourceLen(a6) ; save length
|
|||
|
_PtrToHand ; make new handle containing copy of text
|
|||
|
move.w d0,errCode(a6) ; save err code
|
|||
|
bne.s lwrTrUnlk ; if error in PtrToHand, quit
|
|||
|
move.l a0,sourceHndl(a6) ; save new source handle
|
|||
|
move.l sourceLen(a6),d0 ; get length again
|
|||
|
_NewHandle ; make new handle with random contents
|
|||
|
move.w d0,errCode(a6) ; save err code
|
|||
|
bne.s lwrTrDisp1Hndl ; if error in NewHandle, quit
|
|||
|
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
; Now do Transliterate and check result: dest length should equal source length
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
|
|||
|
move.l a0,destHndl(a6) ; save new dest handle
|
|||
|
subq.l #2,sp ; space for Transliterate error code
|
|||
|
move.l sourceHndl(a6),-(sp) ; push source handle
|
|||
|
move.l a0,-(sp) ; push dest handle (still in a0)
|
|||
|
move.w #smTransLower+smTransAscii,-(sp) ; lower-case conversion, target=Roman
|
|||
|
move.l #smMaskAscii,-(sp) ; convert Roman only
|
|||
|
_Transliterate
|
|||
|
move.w (sp)+,errCode(a6) ; save error code
|
|||
|
bne.s lwrTrDisp2Hndl ; if error in Transliterate, quit
|
|||
|
move.l destHndl(a6),a0 ; now check result…
|
|||
|
_GetHandleSize
|
|||
|
move.w d0,errCode(a6) ; save err code
|
|||
|
tst.l d0 ; .l, because the result is really a long
|
|||
|
blt.s lwrTrDisp2Hndl ; if error in GetHandleSize, quit
|
|||
|
move.w #-1,errCode(a6) ; assume len err; need a better err code!
|
|||
|
cmp.l sourceLen(a6),d0 ; should be same as source len
|
|||
|
bne.s lwrTrDisp2Hndl ; if not, set err and bail
|
|||
|
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
; Copy result (destHndl) to original text buffer (sourcePtr).
|
|||
|
; NOTE: For large text blocks, _BlockMove might be faster than this loop.
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
|
|||
|
move.l destHndl(a6),a0 ; get dest handle and…
|
|||
|
move.l (a0),a0 ; deref it to get source ptr for this copy
|
|||
|
move.l sourcePtr(a6),a1 ; old source ptr is dest for this copy
|
|||
|
move.l sourceLen(a6),d0 ; length for copy (we know it is >= 1)
|
|||
|
subq.l #1,d0 ; set up for dbra
|
|||
|
@1 move.b (a0)+,(a1)+ ; copy a byte
|
|||
|
dbra d0,@1 ; loop till done
|
|||
|
clr.w errCode(a6) ; no errors!
|
|||
|
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
; Exits - need to dispose of handles we created
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
|
|||
|
lwrTrDisp2Hndl
|
|||
|
move.l destHndl(a6),a0 ;
|
|||
|
_DisposHandle ;
|
|||
|
lwrTrDisp1Hndl
|
|||
|
move.l sourceHndl(a6),a0 ;
|
|||
|
_DisposHandle ;
|
|||
|
lwrTrUnlk
|
|||
|
move.w errCode(a6),d0 ; set err code
|
|||
|
unlk a6 ;
|
|||
|
rts
|
|||
|
endwith
|
|||
|
|
|||
|
lwrRTS
|
|||
|
clr.w d0
|
|||
|
rts
|
|||
|
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
; This is not a 2-byte script, just use old LwrString.
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
not2Byte
|
|||
|
BackToTrap oldLwrString ;
|
|||
|
endproc
|
|||
|
|
|||
|
ENDIF
|
|||
|
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
;
|
|||
|
; 1/27/90 GMR EDiskPatch - Fixes EDisk drivers Prime routine by patching HWDepProcs
|
|||
|
; which get called by prime after the move is complete. The new HWDepProcs
|
|||
|
; first check to see if called by Prime, and if so, stuff the byte count (in d4)
|
|||
|
; on the stacks 'scratch longword', which will later be pulled off and stored
|
|||
|
; in ioActCnt and added to dCtlPos at the end of Prime. We patch each of
|
|||
|
; the HWDepProcs (even SLIM's, though they presently are not used).
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
|
|||
|
EDiskPatch PROC
|
|||
|
EXPORT HWDepRAM,HWDepROM,HWDepSLIM,vRAMExit,vROMExit,vSLIMExit
|
|||
|
|
|||
|
HWDepRAM move.l d0,-(sp) ; save d0
|
|||
|
move.l 4(sp),d0 ; get return address
|
|||
|
and.l Lo3Bytes,d0 ; only check 24 bit part of address
|
|||
|
cmpi.l #$00929F54,d0 ; were we called by Prime? (just before the bug)?
|
|||
|
bne.s @exit ; no, get out of here
|
|||
|
move.l d4,8(sp) ; yes, fix bug by stuffing the byte count on stack
|
|||
|
@exit move.l (sp)+,d0 ; restore d0
|
|||
|
vRAMExit jmp $00900000 ; and jump back to orig HWDep proc
|
|||
|
|
|||
|
HWDepROM move.l d0,-(sp) ; save d0
|
|||
|
move.l 4(sp),d0 ; get return address
|
|||
|
and.l Lo3Bytes,d0 ; only check 24 bit part of address
|
|||
|
cmpi.l #$00929F54,d0 ; were we called by Prime? (just before the bug)?
|
|||
|
bne.s @exit ; no, get out of here
|
|||
|
move.l d4,8(sp) ; yes, fix bug by stuffing the byte count on stack
|
|||
|
@exit move.l (sp)+,d0 ; restore d0
|
|||
|
vROMExit jmp $00900000 ; and jump back to orig HWDep proc
|
|||
|
|
|||
|
HWDepSLIM move.l d0,-(sp) ; save d0
|
|||
|
move.l 4(sp),d0 ; get return address
|
|||
|
and.l Lo3Bytes,d0 ; only check 24 bit part of address
|
|||
|
cmpi.l #$00929F54,d0 ; were we called by Prime? (just before the bug)?
|
|||
|
bne.s @exit ; no, get out of here
|
|||
|
move.l d4,8(sp) ; yes, fix bug by stuffing the byte count on stack
|
|||
|
@exit move.l (sp)+,d0 ; restore d0
|
|||
|
vSLIMExit jmp $00900000 ; and jump back to orig HWDep proc
|
|||
|
|
|||
|
ENDPROC
|
|||
|
|
|||
|
; ----------------------------------------------------------------------------
|
|||
|
|
|||
|
|
|||
|
;_________________________________________________________________________________________ <50><51> EVA
|
|||
|
; Async Serial Driver Patch
|
|||
|
;
|
|||
|
; Traps patched: -- The AsyncVector, which is in the middle of the OS ToolTable
|
|||
|
; is patched, Trap number = $A0BE
|
|||
|
;
|
|||
|
; HISTORY:
|
|||
|
; <50> New patch:
|
|||
|
; added nike printer support:
|
|||
|
; -- patched control call 16 in bypass driver to use bit 6 for setting
|
|||
|
; external/internal clocking modes.
|
|||
|
; -- Patched both bypass and IOP code to add status call to return version.
|
|||
|
; -- Patched InitSCC routine in bypass driver to use this RAM-based table so
|
|||
|
; that clocking mode is now variable instead of hard-wired to internal only.
|
|||
|
; -- Patched bypass mode driver to set bit 3 of AsyncErr if break rcvd.
|
|||
|
; added BAP support:
|
|||
|
; -- patched out .Bin and .Bout driver headers to get driver storage pointer
|
|||
|
; from expanded mem.
|
|||
|
; -- patched out B port interrupt handlers to get driver storage pointer
|
|||
|
; from expanded mem and to get DCE pointer from Unit Table.
|
|||
|
;
|
|||
|
; <51> 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).
|
|||
|
;
|
|||
|
; <53> 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.
|
|||
|
; <54> Fix address offset for the readrqdone routine. we were off by 2.
|
|||
|
; We were crashing if read pending and break rcv'd.
|
|||
|
; <57> Status calls 9 and $8000 return static version number instead
|
|||
|
; of what's in the DCE.
|
|||
|
;_______________________________________________________________________
|
|||
|
|
|||
|
AsyncPatch proc
|
|||
|
export SerialPatch
|
|||
|
;
|
|||
|
; equates
|
|||
|
;
|
|||
|
PortAVars EQU SerialVars ; serial chan A variables and buffer
|
|||
|
SerialVers equ 5 ; current version number 3/91 <57>
|
|||
|
;
|
|||
|
; Bypass driver var offsets
|
|||
|
;
|
|||
|
|
|||
|
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
|
|||
|
serBufSize 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 <14Oct85>
|
|||
|
DTRNegVal EQU 31 ;(1) WR5 value used to negate DTR <14Oct85>
|
|||
|
|
|||
|
SCCReset EQU 32 ;(1) WR9 value for reset
|
|||
|
|
|||
|
StopBits EQU 33 ;(1) stop bits/parity option (WR4 value)
|
|||
|
WR1AVal EQU 34 ;(1) first WR1 value to write
|
|||
|
WR3AVal EQU 35 ;(1) first WR3 value to write
|
|||
|
WR5AVal EQU 36 ;(1) first WR5 value to write
|
|||
|
BaudLoCnst EQU 37 ;(2) 2 byte baud rate constant (WR12-13)
|
|||
|
BaudHiCnst EQU 38
|
|||
|
RcvrBits EQU 39 ;(1) 1 byte receiver bits/char (WR3 value)
|
|||
|
XmitBits EQU 40 ;(1) 1 byte xmitter bits/char (WR5 value)
|
|||
|
WReqPin EQU 41 ;(1) w/req pin state (WR1 value)
|
|||
|
lastSetup EQU 42 ;(2) last SCC init values . . .
|
|||
|
|
|||
|
BufIndex EQU 44 ;(2) index into local buffer (insert)
|
|||
|
BufOutdex EQU 46 ;(2) index into local buffer (remove)
|
|||
|
LocalBuf EQU 48 ;(64) local buffer for input chars
|
|||
|
|
|||
|
LclBufSize EQU 64 ; default input buffer size = 64 bytes
|
|||
|
HSCount EQU 112 ;(2) count of CTS pulses in VBL time (clk detect) <14Oct85>
|
|||
|
LastTime EQU 114 ;(4) ticks time of last CTS pulse (clk detect) <14Oct85>
|
|||
|
|
|||
|
SendXOnff EQU 118 ;(1) flag to xmit logic to send XOn/XOff <14Oct85>
|
|||
|
CharMask EQU 119 ;(1) $1F,$3F,$7F, or $FF mask for input chars <14Oct85>
|
|||
|
|
|||
|
PEChar EQU 120 ;(1) char to change incoming parity errors to <14Oct85>
|
|||
|
AltChar EQU 121 ;(1) char to change incoming PEChars to <14Oct85>
|
|||
|
|
|||
|
InSWHS1 EQU 122 ;(1) saved InSWHS state <14Oct85>
|
|||
|
CtlOptions EQU 123 ;(1) bits 0-6=0 (reserved). bit 7=1 to leave <14Oct85>
|
|||
|
; DTR state unchanged at close.
|
|||
|
SaveExInt EQU 124 ;(4) saved Ext int vector <14Oct85>
|
|||
|
SaveTxInt EQU 128 ;(4) saved TxD int vector <14Oct85>
|
|||
|
SaveRxInt EQU 132 ;(4) saved RxD int vector <14Oct85>
|
|||
|
SaveSxInt EQU 136 ;(4) saved Special Rx int vector <14Oct85>
|
|||
|
|
|||
|
SleepQRec1 EQU 140 ;(12)sleep queue record for chrysalis <v1.2> <65> rb
|
|||
|
LclVarSize EQU 152 ; output driver storage size <v1.2>
|
|||
|
|
|||
|
|
|||
|
;____________________________________________________________________
|
|||
|
;
|
|||
|
; ROM address offsets
|
|||
|
;
|
|||
|
;____________________________________________________________________
|
|||
|
|
|||
|
; come from patch equates
|
|||
|
fromAOutOpen EQU $30d84
|
|||
|
fromAInOpen EQU $30d18
|
|||
|
fromBOutOpen EQU $30db8
|
|||
|
fromBInOpen EQU $30d20
|
|||
|
fromControl EQU $31122
|
|||
|
fromClose EQU $31036
|
|||
|
fromStatus EQU $310d0
|
|||
|
fromInitSCC EQU $30f2e
|
|||
|
|
|||
|
; open call patch equates
|
|||
|
backToAOutOpen EQU $30da4 ; returning to finish up Open routines in ROM
|
|||
|
backToAInOpen EQU $30d18
|
|||
|
backToBOutOpen EQU $30dd6
|
|||
|
backToBInOpen EQU $30d24
|
|||
|
|
|||
|
ROM_PollDtain EQU $31470 ; rom routines addresses we must push on the stack
|
|||
|
ROM_SCAIntHnd EQU $3155c
|
|||
|
ROM_RAIntHnd EQU $314ac
|
|||
|
ROM_TAIntHnd EQU $3137c
|
|||
|
ROM_SleepA EQU $30f74
|
|||
|
ROM_SleepB EQU $30f7a
|
|||
|
|
|||
|
ToContOut1 EQU $313a2 ; return to finish up interrupt routines in ROM
|
|||
|
ToRdReqDone EQU $315aa ;<54>
|
|||
|
ToCtlSet EQU $31254
|
|||
|
|
|||
|
; Control patch equates for bypass driver
|
|||
|
backToControl EQU $31134 ; for fixing control calls
|
|||
|
ROM_CtlGood EQU $3116a
|
|||
|
ROM_CtlExit EQU $3116c
|
|||
|
; Control Call 16 patch equates
|
|||
|
InitSCC EQU $30f1e
|
|||
|
|
|||
|
; Status patch equates for bypass driver
|
|||
|
backToStatus EQU $310ea
|
|||
|
|
|||
|
; InitSCC patch equates for bypass driver
|
|||
|
backToInitSCC EQU $30f2e
|
|||
|
initData EQU $30eea
|
|||
|
|
|||
|
; close patch equates
|
|||
|
SyncOutput EQU $31096
|
|||
|
InitSCC1 EQU $30f24
|
|||
|
ResetData EQU $30ffa
|
|||
|
ResetLth EQU $10
|
|||
|
freePort EQU $3107c
|
|||
|
|
|||
|
; bypass driver ROM entrypoint addresses <51>
|
|||
|
;port A
|
|||
|
ROM_AInEntryOpen EQU $30d16
|
|||
|
ROM_AInEntryClose EQU $31092
|
|||
|
ROM_AInEntryPrime EQU $313ae
|
|||
|
|
|||
|
ROM_AOutEntryOpen EQU $30d82
|
|||
|
ROM_AOutEntryClose EQU $3100a
|
|||
|
ROM_AOutEntryPrime EQU $312f4
|
|||
|
|
|||
|
ROM_AEntryControl EQU $3110e
|
|||
|
ROM_AEntryStatus EQU $310bc
|
|||
|
|
|||
|
;port B
|
|||
|
backToBInOpenStart EQU $30d1e
|
|||
|
backToBOutOpenStart EQU $30db4
|
|||
|
ToBOutClose EQU $3101e
|
|||
|
backToBInPrime EQU $313b8
|
|||
|
backToBOutPrime EQU $312fe
|
|||
|
backToBControl EQU $31118
|
|||
|
backToBStatus EQU $310c6
|
|||
|
|
|||
|
|
|||
|
; for BAP only interrupt handler patches
|
|||
|
backToSCIntHnd EQU $31568
|
|||
|
backToRXIntHnd EQU $314b8
|
|||
|
backToTXIntHnd EQU $31380
|
|||
|
; 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
|
|||
|
|
|||
|
;_______________________________________
|
|||
|
;
|
|||
|
; Bypass Patch Code Entry Point
|
|||
|
; (Patched Bypass mode routines here)
|
|||
|
;
|
|||
|
;
|
|||
|
|
|||
|
SerialPatch
|
|||
|
move.l d0,-(SP) ; save reg d0
|
|||
|
move.l 8(SP),D0 ; get D0 = return address
|
|||
|
_StripAddress ; strip nasty high bits
|
|||
|
|
|||
|
cmpRA fromAInOpen,D0 ; test for ChkAConfig call from AInOpen
|
|||
|
beq.w OpenAFix
|
|||
|
|
|||
|
cmpRA fromAOutOpen,D0 ; test for ChkAConfig call from AOutOpen
|
|||
|
beq.w OpenAFix
|
|||
|
|
|||
|
cmpRA fromBOutOpen,D0 ; test for ChkBConfig call from BOutOpen
|
|||
|
beq.w OpenBFix
|
|||
|
|
|||
|
cmpRA fromBInOpen,D0 ; test for ChkBConfig call from BInOpen
|
|||
|
beq.w OpenBFix
|
|||
|
|
|||
|
move.l 4(sp),d0 ; one less level indirection for non-open calls
|
|||
|
_StripAddress ; strip nasty high bits
|
|||
|
|
|||
|
cmpRA fromControl,d0 ; to fix bypass control calls
|
|||
|
beq.w ControlFix
|
|||
|
|
|||
|
cmpRA fromStatus,d0 ; to fix bypass control calls
|
|||
|
beq.w StatusFix
|
|||
|
|
|||
|
cmpRA fromClose,d0 ; to fix initSCC routine
|
|||
|
beq.w CloseFix
|
|||
|
|
|||
|
cmpRA fromInitSCC,d0 ; to fix initSCC routine
|
|||
|
beq.w InitSCCFix
|
|||
|
|
|||
|
move.l (sp)+,d0 ; restore regs
|
|||
|
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>
|
|||
|
|
|||
|
jsrROM SyncOutput ; delay until last char has cleared <14Oct85>
|
|||
|
; output buffer
|
|||
|
LeaROM ResetData,A3
|
|||
|
MOVEQ #ResetLth,D1
|
|||
|
jsrROM InitSCC1 ; shut down the channel
|
|||
|
|
|||
|
; 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>
|
|||
|
|
|||
|
LEA SleepQRec1(A2),A0 ; A0 = ptr to sleep queue entry <v1.2> <65> rb
|
|||
|
_SlpQRemove ; Remove slpq proc <v2.1>
|
|||
|
|
|||
|
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
|
|||
|
jmpROM freePort ; port a; finish up in ROM
|
|||
|
|
|||
|
@freeB
|
|||
|
move.l ExpandMem,a0 ; <66>
|
|||
|
tst.w ExpandMemRec.emAppleTalkInactiveOnBoot(a0) ; <66> If AppleTalk is inactive, don’t set up the LAP manager
|
|||
|
bnz.s @freeThePort ; <66> AppleTalk is not active.
|
|||
|
move.l #'atkv',d0 ; what version of Appletalk? <51>
|
|||
|
_Gestalt
|
|||
|
tst.w d0 ; <66> Did Gestalt return an error?
|
|||
|
bne.s @freeThePort ; <66> Yes, so 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
|
|||
|
jmpROM freePort ; no, then finish up in ROM
|
|||
|
|
|||
|
@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 D3,D0 ; port selector
|
|||
|
OR.B #(1<<SerialOff),D0 ; on/off bit, 1 = power off
|
|||
|
_SerialPower ; power off hardware <v2.3>
|
|||
|
|
|||
|
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 <53>
|
|||
|
extClkSrc equ %00101000 ; SCC clk src is TRxC (CTS) pin (WR11) <53>
|
|||
|
intClkSrc equ %01010000 ; SCC clk src is baud rate generator (WR11) <53>
|
|||
|
BRGEnbl equ %00000001 ; enable baud rate generator (WR14) <53>
|
|||
|
BRGDsbl equ %00000000 ; disable baud rate generator (WR14) <53>
|
|||
|
|
|||
|
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 and saved rtrn addr--we jump back
|
|||
|
|
|||
|
move.l a3,d0
|
|||
|
_StripAddress
|
|||
|
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 <53>
|
|||
|
|
|||
|
; default to internally clocked state <53>
|
|||
|
bset.b #clkDvdBit,StopBits(a2) ; default to a divide-by-16 clock <53>
|
|||
|
moveq #intClkSrc,d0 ; internal clocking source <53>
|
|||
|
moveq #BRGEnbl,d1 ; enable baud rate generator <53>
|
|||
|
|
|||
|
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 <53>
|
|||
|
moveq #extClkSrc,d0 ; external clock source <53>
|
|||
|
moveq #BRGDsbl,d1 ; disable baud rate generator <53>
|
|||
|
clr.b HWHS(a2) ; make sure we're not trying to do HWHS <53>
|
|||
|
|
|||
|
@load lea ClkMode,a0 ; load params into InitSCC data table <53>
|
|||
|
move.b d0,(a0) ; <53>
|
|||
|
lea BRGEnable,a0 ; <53>
|
|||
|
move.b d1,(a0) ; <53>
|
|||
|
|
|||
|
movem.l (sp)+,d1/a0 ; restore reg's <53>
|
|||
|
|
|||
|
@done jmpROM backToInitSCC ; finish up in ROM
|
|||
|
|
|||
|
|
|||
|
;_______________________________________________________________________
|
|||
|
;
|
|||
|
; 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 rtrn addr--we jump back
|
|||
|
|
|||
|
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>
|
|||
|
jmpROM ROM_CtlExit ; just like ROM
|
|||
|
|
|||
|
@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
|
|||
|
jmpROM BackToStatus ; no
|
|||
|
|
|||
|
@version move.b #SerialVers,(a0) ; return the version <57>
|
|||
|
jmpROM ROM_CtlGood
|
|||
|
|
|||
|
;_______________________________________________________________________
|
|||
|
;
|
|||
|
; Routine: Control
|
|||
|
; Patch: We patch control for the following reasons:
|
|||
|
; 1) to add external clock support in control call 16
|
|||
|
;
|
|||
|
ControlFix
|
|||
|
ADD.L #8,SP ; pop save reg d0 and rtrn addr--we jump back
|
|||
|
|
|||
|
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>
|
|||
|
|
|||
|
moveq #0,d0 ; for the killIO call
|
|||
|
LEA CSCode(A0),A0 ; get parameters
|
|||
|
MOVE.W (A0)+,D1 ; get opcode
|
|||
|
|
|||
|
cmpi #16,d1 ; opcode 16? (ctlOptions) <extClk>
|
|||
|
beq CtlSwitchCTSClock ; <extClk>
|
|||
|
jmpROM backToControl ; if not, let ROM handle it
|
|||
|
|
|||
|
|
|||
|
; 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 <53>
|
|||
|
jsrROM InitSCC ; set up the SCC according to new value <53>
|
|||
|
jmpROM ROM_CtlGood ; finish up in ROM <53>
|
|||
|
|
|||
|
|
|||
|
;_______________________________________________________________________
|
|||
|
;
|
|||
|
; Open Fixes
|
|||
|
;
|
|||
|
;
|
|||
|
; note that no stack fiddling is allowed, as the chkConfigure EXPECTS to be called directly
|
|||
|
; from the open routine, and will not go to IOCore with error properly should one occur.
|
|||
|
|
|||
|
; Common code for open patches
|
|||
|
|
|||
|
OpenAFix
|
|||
|
add.l #4,sp ; saved d0 not needed
|
|||
|
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,d0 ; get Open return addr
|
|||
|
_StripAddress
|
|||
|
cmpRA fromAOutOpen,d0 ; 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)
|
|||
|
JmpRom backToAInOpen ; jump back into ROM in AInOpen
|
|||
|
|
|||
|
@out lea AsyncAOut,a2 ; store new driver header for AOut into DCE
|
|||
|
move.l a2,(a1)
|
|||
|
LEA PortAVars,A2 ; local variables address
|
|||
|
PEAROM ROM_SleepA ; sleep proc for sleep queue entry <v1.2>
|
|||
|
peaROM ROM_PollDtaIn,-(sp) ; ROM--this proc handles disk poll data <20Oct85>
|
|||
|
peaROM ROM_SCAIntHnd,-(sp) ; ROM--Special RxD int handler <20Oct85>
|
|||
|
peaROM ROM_RAIntHnd,-(sp) ; ROM--RxD int handler <20Oct85>
|
|||
|
peaROM ROM_TAIntHnd,-(sp) ; ROM--TxD int handler <20Oct85>
|
|||
|
PEA Lvl2DT+16 ; SCC interrupt dispatch table, chan A <20Oct85>
|
|||
|
PEA NewExtAIntHnd ; External int handler <20Oct85>
|
|||
|
jmpROM backToAOutOpen ; JUMP BACK INTO ROM
|
|||
|
|
|||
|
|
|||
|
; Channel B - almost the same patch as channel A
|
|||
|
; Except of course for the BAP stuff
|
|||
|
OpenBFix
|
|||
|
move.l ExpandMem,a0 ; <66>
|
|||
|
tst.w ExpandMemRec.emAppleTalkInactiveOnBoot(a0) ; <66> If AppleTalk is inactive, don’t set up the LAP manager
|
|||
|
bnz.s @appleTalkInactive ; <66> AppleTalk is not active.
|
|||
|
move.l #'atkv',d0 ; what version of Appletalk? <51>
|
|||
|
_Gestalt
|
|||
|
tst.w d0 ; <66> Check for an error from Gestalt
|
|||
|
bne.s @appleTalkInactive ; <66> 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, 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 d1/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)+,d1/a1-a2 ; restore reg's
|
|||
|
rts ; no,return to IO Core: we already popped ret addrs and regs
|
|||
|
|
|||
|
@rstrReg
|
|||
|
movem.l (sp)+,d1/a1-a2 ; restore reg's
|
|||
|
@pwrPort
|
|||
|
MOVE.W D1,D0 ; Send port to power
|
|||
|
_SerialPower ; check for powering things up <v1.1><v2.3>
|
|||
|
|
|||
|
@gotPort
|
|||
|
move.l a2,d0 ; get Open return addr
|
|||
|
_StripAddress
|
|||
|
cmpRA fromBOutOpen,d0 ; 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)
|
|||
|
JmpRom backToBInOpen ; jump back into ROM in BInOpen
|
|||
|
|
|||
|
@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
|
|||
|
PEAROM ROM_SleepB ; sleep proc for sleep queue entry <v1.2>
|
|||
|
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
|
|||
|
|
|||
|
JmpRom backToBOutOpen ; JUMP BACK INTO ROM
|
|||
|
|
|||
|
;________________________________________________________________________
|
|||
|
;
|
|||
|
; Routine: RXIntHnd
|
|||
|
;
|
|||
|
; Arguments: A0 (input) -- chan A/B control read address
|
|||
|
; A1 (input) -- chan A/B control write address
|
|||
|
;
|
|||
|
; Patch: forBAP, get driver storage ptr from expanded mem
|
|||
|
; get DCE ptr from UTable
|
|||
|
|
|||
|
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
|
|||
|
jmpROM backToRXIntHnd ; and branch around 'redundant' 6.X code
|
|||
|
;________________________________________________________________________
|
|||
|
;
|
|||
|
; Routine: SCIntHnd
|
|||
|
;
|
|||
|
; Arguments: A0 (input) -- channel A/B control read address
|
|||
|
; A1 (input) -- channel A/B control write address
|
|||
|
;
|
|||
|
; 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
|
|||
|
move.b #1,(a1)
|
|||
|
jmpROM backToSCIntHnd ; back to ROM
|
|||
|
|
|||
|
;________________________________________________________________________
|
|||
|
;
|
|||
|
; Routine: TBIntHnd
|
|||
|
;
|
|||
|
; Patch: forBAP, get driver storage ptr from expanded mem
|
|||
|
; get DCE ptr from UTable
|
|||
|
NewTBIntHnd
|
|||
|
move.l ExpandMem,a2 ; use ExpandMem instead of PortBVars
|
|||
|
move.l ExpandMemRec.emSerdVars(a2),a2
|
|||
|
JmpRom backToTXIntHnd ; back to ROM
|
|||
|
|
|||
|
|
|||
|
;________________________________________________________________________
|
|||
|
;
|
|||
|
; Routine: ExtIntHnd
|
|||
|
;
|
|||
|
; Patch: forBAP, get driver storage ptr from expanded mem
|
|||
|
; get DCE ptr from UTable
|
|||
|
; -- 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 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>
|
|||
|
jsrROM ToCtlSet ; <patch>
|
|||
|
|
|||
|
|
|||
|
@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>
|
|||
|
jmpROM toContOut1 ;<patch> BRA ContOut1--if freshly asserted, continue output<14Oct85>
|
|||
|
|
|||
|
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
|
|||
|
@0 RTS ; and return
|
|||
|
|
|||
|
@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 @0 ; just return if done <7.1>
|
|||
|
|
|||
|
jmpROM ToRdReqDone ; return to ROM code
|
|||
|
|
|||
|
;_______________________________________________________________________ <51>
|
|||
|
;
|
|||
|
; 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'
|
|||
|
|
|||
|
|
|||
|
;_______________________________________________________________________ <51>
|
|||
|
;
|
|||
|
; jumping to ROM from our patched entry points
|
|||
|
;
|
|||
|
AInOpen jmpROM ROM_AInEntryOpen ;port a
|
|||
|
AInClose jmpROM ROM_AInEntryClose
|
|||
|
AInPrime jmpROM ROM_AInEntryPrime
|
|||
|
|
|||
|
AOutOpen jmpROM ROM_AOutEntryOpen
|
|||
|
AOutClose jmpROM ROM_AOutEntryClose
|
|||
|
AOutPrime jmpROM ROM_AOutEntryPrime
|
|||
|
|
|||
|
AControl jmpROM ROM_AEntryControl
|
|||
|
AStatus jmpROM ROM_AEntryStatus
|
|||
|
|
|||
|
|
|||
|
BInOpen JmpRom backToBInOpenStart ;port
|
|||
|
BOutOpen JmpRom backToBOutOpenStart
|
|||
|
BInClose
|
|||
|
moveq #0,d0 ; shorter to return than to jump to ROM
|
|||
|
rts
|
|||
|
BOutClose
|
|||
|
JmpRom ToBOutClose ; don't need to screw with this other than
|
|||
|
; patch above
|
|||
|
BInPrime
|
|||
|
move.l ExpandMem,a2 ; use ExpandMem instead of PortBVars
|
|||
|
move.l ExpandMemRec.emSerdVars(a2),a2 ;
|
|||
|
JmpRom backToBInPrime ; location to return to BInPrime
|
|||
|
|
|||
|
BOutPrime
|
|||
|
move.l ExpandMem,a2 ; use ExpandMem instead of PortBVars
|
|||
|
move.l ExpandMemRec.emSerdVars(a2),a2 ;
|
|||
|
JmpRom backToBOutPrime ; location to return to BOutPrime
|
|||
|
|
|||
|
BControl
|
|||
|
move.l ExpandMem,a2 ; use ExpandMem instead of PortBVars
|
|||
|
move.l ExpandMemRec.emSerdVars(a2),a2 ;
|
|||
|
JmpRom backToBControl ; location to return to BControl
|
|||
|
|
|||
|
BStatus
|
|||
|
move.l ExpandMem,a2 ; use ExpandMem instead of PortBVars
|
|||
|
move.l ExpandMemRec.emSerdVars(a2),a2 ;
|
|||
|
JmpRom backToBStatus ; location to return to BStatus
|
|||
|
|
|||
|
endproc
|
|||
|
;
|
|||
|
; End of Async.a Patch
|
|||
|
;_________________________________________________________________________________________ <50><51> EVA
|
|||
|
;_________________________________________________________________________________________ <49> 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.
|
|||
|
;
|
|||
|
;_________________________________________________________________________________________
|
|||
|
; QuantumWBlindPortable - 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 <49> djw
|
|||
|
|
|||
|
Proc
|
|||
|
Export QuantumWBlindPortable
|
|||
|
|
|||
|
QuantumWBlindPortable
|
|||
|
|
|||
|
ROMDataEnd Equ $006CEC
|
|||
|
|
|||
|
; 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
|
|||
|
movea.l ROMBase,a0 ; get base of rom
|
|||
|
adda.l #ROMDataEnd,a0 ; add offset to SCSI mgr in rom
|
|||
|
jmp (a0) ; continue in ROM
|
|||
|
|
|||
|
|
|||
|
|
|||
|
;_________________________________________________________________________________________
|
|||
|
; 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.
|
|||
|
|
|||
|
With scsiGlobalRecord
|
|||
|
|
|||
|
FastWriteFix
|
|||
|
|
|||
|
@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,OldBusErrVct(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 OldBusErrVct(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 OldBusErrVct(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 ; end scsi
|
|||
|
|
|||
|
Opt all ; set optimization back to preset level <49> djw
|
|||
|
|
|||
|
|
|||
|
;--------------------------------------------------------------------------------------------- <4> msh
|
|||
|
;
|
|||
|
; DrvTblAsahi - This icon data replaces the ROM based data in the Asahi Sony Driver because
|
|||
|
; the machine icon is different than the original Portable. The format of the
|
|||
|
; table and icon data is taken directly from the file "SonyIcon.a". Even though
|
|||
|
; Asahi only supports one drive, three table entries are included to be sure.
|
|||
|
;
|
|||
|
;--------------------------------------------------------------------------------------------- <4> msh
|
|||
|
|
|||
|
Proc
|
|||
|
Export DrvTblAsahi
|
|||
|
|
|||
|
DrvTblAsahi ; Macintosh Asahi table <4> msh
|
|||
|
dc.w DisketteIcon-DrvTblAsahi ;drive 3 logical icon,
|
|||
|
dc.w ExtAsahiIcon-DrvTblAsahi ;physical icon,
|
|||
|
dc.w $0103 ;primary ext removable 800K Sony
|
|||
|
|
|||
|
dc.w DisketteIcon-DrvTblAsahi ;drive 3 logical icon,
|
|||
|
dc.w ExtAsahiIcon-DrvTblAsahi ;physical icon,
|
|||
|
dc.w $0103 ;primary ext removable 800K Sony
|
|||
|
|
|||
|
dc.w DisketteIcon-DrvTblAsahi ;drive 3 logical icon,
|
|||
|
dc.w ExtAsahiIcon-DrvTblAsahi ;physical icon,
|
|||
|
dc.w $0103 ;primary ext removable 800K Sony <4> msh
|
|||
|
|
|||
|
; Plain Sony Diskette icon
|
|||
|
|
|||
|
ALIGN 2 ;force alignment so offsets are even <4> msh
|
|||
|
|
|||
|
DisketteIcon dc.w $7FFF,$FFF8,$8100,$0104,$8100,$7102,$8100,$8901
|
|||
|
dc.w $8100,$8901,$8100,$8901,$8100,$8901,$8100,$8901
|
|||
|
dc.w $8100,$7101,$8100,$0101,$80FF,$FE01,$8000,$0001
|
|||
|
dc.w $8000,$0001,$8000,$0001,$8000,$0001,$8000,$0001
|
|||
|
dc.w $8000,$0001,$8000,$0001,$87FF,$FFE1,$8800,$0011
|
|||
|
dc.w $8800,$0011,$8800,$0011,$8800,$0011,$8800,$0011
|
|||
|
dc.w $8800,$0011,$8800,$0011,$8800,$0011,$8800,$0011
|
|||
|
dc.w $8800,$0011,$8800,$0011,$8800,$0011,$7FFF,$FFFE
|
|||
|
|
|||
|
dc.w $7FFF,$FFF8,$FFFF,$FFFC,$FFFF,$FFFE,$FFFF,$FFFF
|
|||
|
dc.w $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF
|
|||
|
dc.w $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF
|
|||
|
dc.w $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF
|
|||
|
dc.w $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF
|
|||
|
dc.w $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF
|
|||
|
dc.w $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF
|
|||
|
dc.w $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$7FFF,$FFFE
|
|||
|
dc.w $0 ;old HD-20 driver drive ID string (null here)
|
|||
|
|
|||
|
; External Floppy icon (Asahi only supports an external drive) <4> msh
|
|||
|
|
|||
|
ExtAsahiIcon dc.w $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000
|
|||
|
dc.w $0000,$0000,$0000,$0000,$0000,$0004,$0000,$000A
|
|||
|
dc.w $0000,$0012,$0000,$0024,$0000,$0048,$0000,$0090
|
|||
|
dc.w $0000,$0120,$0000,$0240,$0000,$0480,$0000,$0900
|
|||
|
dc.w $0000,$1200,$0000,$1400,$006D,$BC00,$00FF,$E400
|
|||
|
dc.w $1F00,$0400,$2000,$0400,$3FFF,$F800,$0000,$0000
|
|||
|
dc.w $0000,$0000,$007F,$FC40,$0040,$04C0,$004F,$E5FC
|
|||
|
dc.w $0040,$04C0,$007F,$FC40,$0000,$0000,$0000,$0000
|
|||
|
|
|||
|
dc.w $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000
|
|||
|
dc.w $0000,$0000,$0000,$0000,$0000,$0004,$0000,$000E
|
|||
|
dc.w $0000,$001E,$0000,$003C,$0000,$0078,$0000,$00F0
|
|||
|
dc.w $0000,$01E0,$0000,$03C0,$0000,$0780,$0000,$0F00
|
|||
|
dc.w $0000,$1E00,$0000,$1C00,$006D,$BC00,$00FF,$FC00
|
|||
|
dc.w $1FFF,$FC00,$3FFF,$FC00,$3FFF,$F800,$0000,$0000
|
|||
|
dc.w $0000,$0000,$007F,$FC40,$007F,$FCC0,$007F,$FDFC
|
|||
|
dc.w $007F,$FCC0,$007F,$FC40,$0000,$0000,$0000,$0000
|
|||
|
dc.w $0 ;old HD-20 driver drive ID string (null here)
|
|||
|
endp
|
|||
|
|
|||
|
EndOfPatch PROC EXPORT
|
|||
|
|
|||
|
;#########################################################################################
|
|||
|
;############################### INSTALL CODE GOES HERE ##################################
|
|||
|
;#########################################################################################
|
|||
|
|
|||
|
PatchInit PROC EXPORT
|
|||
|
IMPORT EndOfPatch,StartPatch,Cutback
|
|||
|
IMPORT FixupTbl ; <3.6>
|
|||
|
IMPORT DrvTblAsahi ; <4> msh
|
|||
|
|
|||
|
MOVE.L D1,-(SP) ; Save our handle
|
|||
|
|
|||
|
;____________________________________________________________________________
|
|||
|
; Fixup patch addresses ; added <3.6>
|
|||
|
;
|
|||
|
; The Fixing up of addresses generated by the CMPRA, JSRROM & JMPROM
|
|||
|
; Breaks down as follows:
|
|||
|
;
|
|||
|
; Addressing High Byte in Action
|
|||
|
; mode: instruction:
|
|||
|
; ---------- ------------ ------
|
|||
|
; 24 bit NZ Do not alter the address in the instruction.
|
|||
|
; Used with CMPRA to a ROM Resource.
|
|||
|
; 32 bit NZ Mask out 12 high bits from the address
|
|||
|
; in the instruction, leaving a ROM offset
|
|||
|
; Then add in ROMBase.
|
|||
|
; either Zero Normal Case. Add ROMBase to the address
|
|||
|
; in the instruction.
|
|||
|
;
|
|||
|
; Registers:
|
|||
|
; D0: Address Size Flag. Pos: 24 bit mode; Neg: 32 bit Mode
|
|||
|
; D1: Entry from table of offsets of locations to be fixed up
|
|||
|
; D2: (RomBase)
|
|||
|
; A0: Pointer into table of offsets of locations to be fixed up.
|
|||
|
; A1: Base of fixup table; also location from which offsets are computed.
|
|||
|
|
|||
|
move.l RomBase, D2
|
|||
|
moveq #-1, D0
|
|||
|
_StripAddress
|
|||
|
lea FixupTbl, A0
|
|||
|
move.l A0, A1
|
|||
|
FixUpLooP move.l (A0)+, D1
|
|||
|
beq.s @1
|
|||
|
tst.b 0(A1, D1.L)
|
|||
|
beq.s @AddIt
|
|||
|
tst.l D0 ; If Address has any high bits set
|
|||
|
bpl.s FixUpLoop ; 24 Bit mode; Dont alter this one.
|
|||
|
and.w #$f, 0(A1, D1.L); 32 Bit Mode; Clear High 12 bits.
|
|||
|
|
|||
|
@AddIt add.l D2, 0(A1, D1.L) ; Normal Case: Add in ROMBase
|
|||
|
bra.s FixUpLoop
|
|||
|
@1
|
|||
|
|
|||
|
;#########################################################################################
|
|||
|
;################################ BEGIN PATCH INSTALLS ###################################
|
|||
|
;#########################################################################################
|
|||
|
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
;
|
|||
|
; Begin startup initialization
|
|||
|
;
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
|
|||
|
|
|||
|
;------------------------------------------------------------------------------------ <2> SAM
|
|||
|
; The Portable and the "Its a Sony!" Derringer have the same ROM but have different
|
|||
|
; features. We need to distiguish between the two (ie change box flag & Gestalt).
|
|||
|
;------------------------------------------------------------------------------------
|
|||
|
|
|||
|
MOVE.L ROMBase,A0 ; Get base of ROM
|
|||
|
CMPI.W #$11F1,18(A0) ; Is this a (Sony) Asahi? (ROM release number) 1.1f1
|
|||
|
BNE.S @Portable ; -> Nope, do nothing
|
|||
|
|
|||
|
MOVE.B #boxPowerBook100,boxFlag ; Slam boxFlag (Gestalt will use this when it gets loaded) <64>
|
|||
|
|
|||
|
MOVE.L SonyVars,A0 ; To replace the floppy drive icons,
|
|||
|
LEA DrvTblAsahi,A1 ; insert pointer to new table directly
|
|||
|
MOVE.L A1,DrvTblPtr(A0) ; into Sony variables
|
|||
|
|
|||
|
@Portable
|
|||
|
|
|||
|
IMPORT ATPPatch ; 12/13/89 <v6.1>
|
|||
|
|
|||
|
ATPpatchInstall
|
|||
|
|
|||
|
MOVEA.L AGBHandle,A0
|
|||
|
CMP.L #-1,A0 ; has it been set up yet?
|
|||
|
BNE.S @haveAGB ; yes
|
|||
|
|
|||
|
MOVEQ #AGBSize,D0 ; D0 = size of RAM we need for AGB
|
|||
|
_NewHandle ,SYS,CLEAR ; vars are all zero'd
|
|||
|
BNE @atpinstalldone ; return on error
|
|||
|
MOVE.L A0,AGBHandle
|
|||
|
@haveAGB
|
|||
|
MOVEA.L (A0),A0 ; A0->AGB
|
|||
|
PEA ATPPatch
|
|||
|
MOVE.L (SP)+,atpHook(A0)
|
|||
|
|
|||
|
@atpinstalldone ; <v6.1>
|
|||
|
|
|||
|
;********************* Start of SANE Package Optimization ********************* GGD <2.6><3.5><5.7>
|
|||
|
;_______________________________________________________________________
|
|||
|
; Optimize the SANE packages which are ROM Resources, by having the dispatch
|
|||
|
; table entry point right to the first instruction of the package, instead
|
|||
|
; of going through the Package Manager which finds the package by de-referencing
|
|||
|
; a handle.
|
|||
|
;_______________________________________________________________________
|
|||
|
|
|||
|
OptimizePACKs
|
|||
|
lea @PackOptTable,a3; point to the optimization table
|
|||
|
@optLoop move.w (a3)+,d0 ; get the package number
|
|||
|
bmi.s @done ; exit at end of list
|
|||
|
move.w d0,-(sp) ; push the package number
|
|||
|
_InitPack ; get the ROM resource, update AppPacks table
|
|||
|
move.w (a3)+,d1 ; get the trap word
|
|||
|
move.w (a3)+,a0 ; get the low mem address
|
|||
|
move.l (a0),d0 ; get the handle
|
|||
|
beq.s @optLoop ; if null, skip it
|
|||
|
movea.l d0,a0 ; setup to de-reference it
|
|||
|
move.l (a0),d0 ; get a pointer to the routine
|
|||
|
beq.s @optLoop ; if null, skip it
|
|||
|
movea.l d0,a0 ; setup pointer to code
|
|||
|
cmpi.b #$60,(a0) ; see if first instruction is a BRA.S
|
|||
|
bne.s @branchOptDone ; if not, don't optimize it
|
|||
|
move.w (a0)+,d0 ; get the BRA.S instruction
|
|||
|
ext.w d0 ; extend the branch displacement
|
|||
|
adda.w d0,a0 ; update the entry point address
|
|||
|
@branchOptDone
|
|||
|
move.w d1,d0 ; setup the trap word
|
|||
|
_SetTrapAddress ; go directly to the first instr of the package
|
|||
|
bra.s @optLoop ; optimize the next package
|
|||
|
|
|||
|
@PackOptTable
|
|||
|
dc.w 4 ; package number 4
|
|||
|
_FP68K ; trap name for PACK 4
|
|||
|
dc.w AppPacks+4*4 ; low mem address of handle to PACK 4
|
|||
|
|
|||
|
dc.w 5 ; package number 5
|
|||
|
_Elems68K ; trap name for PACK 5
|
|||
|
dc.w AppPacks+5*4 ; low mem address of handle to PACK 5
|
|||
|
|
|||
|
dc.w -1 ; package number -1, end of list
|
|||
|
@done
|
|||
|
;********************* End of SANE Package Optimization ********************* GGD <2.6>
|
|||
|
|
|||
|
;———————————————————————————————————————————————————————————————————————————— <56>
|
|||
|
; The GestaltFuction.a file is used to build a ptch for machines without
|
|||
|
; Gestalt in ROM, but it also contains fixes and improvements that are not
|
|||
|
; in the Portable ROMs OR in the GestaltPatches.a file... The changes are not
|
|||
|
; trivial, so we’re punting and loading the Gestalt ptch on Portable ROMs, too...
|
|||
|
;
|
|||
|
; Before we do, though, we throw away any storage that Gestalt has allocated.
|
|||
|
;
|
|||
|
|
|||
|
move.l ExpandMem, a0
|
|||
|
move.l ExpandMemRec.emGestalt(a0), a0 ; get Gestalt’s pointer
|
|||
|
_DisposPtr ; now throw away the old pointer
|
|||
|
|
|||
|
move.l GestaltGlobals.longH(a0), a0 ; get the table handle
|
|||
|
_DisposHandle ; and toss it away!
|
|||
|
|
|||
|
PtchInst 5 ; Gestalt ptch
|
|||
|
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
;
|
|||
|
; <3.1> 8/10/89 CCH - This installs the Gestalt location error patch.
|
|||
|
;
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
|
|||
|
import gestaltPatch,gestaltAddr
|
|||
|
|
|||
|
stuffOldTrap gestaltAddr,GestaltTrapID
|
|||
|
setTrap gestaltPatch,GestaltTrapID
|
|||
|
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
;
|
|||
|
; <3.0> 8/10/89 CCH - This installs/modifies various Gestalt functions that changed
|
|||
|
; after the Esprit ROM went final.
|
|||
|
;
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
gestaltRBVAddr EQU 'rbv '
|
|||
|
gestaltSCCReadAddr EQU 'sccr'
|
|||
|
gestaltSCCWriteAddr EQU 'sccw'
|
|||
|
gestaltVIA1Addr EQU 'via1'
|
|||
|
gestaltVIA2Addr EQU 'via2'
|
|||
|
gestaltSlotAttr EQU 'slot' ; <40>
|
|||
|
gestaltSlotCount EQU 'nubs' ; <40>
|
|||
|
gestaltFirstSlot EQU 'slt1' ; <40>
|
|||
|
|
|||
|
import gestaltParity,gestaltLowMem,gestaltQDVers
|
|||
|
|
|||
|
lea gestaltNBCon,a0 ; address of gestaltNuBusConnectors patch <39>
|
|||
|
move.l #gestaltNuBusConnectors,d0 ; selector to ADD
|
|||
|
_NewGestalt
|
|||
|
|
|||
|
lea gestaltSerial,a0 ; address of gestaltSerialAttr patch <39>
|
|||
|
move.l #gestaltSerialAttr,d0 ; selector to ADD
|
|||
|
_NewGestalt
|
|||
|
|
|||
|
lea gestaltParity,a0 ; address of gestaltParityAttr patch
|
|||
|
move.l #gestaltParityAttr,d0 ; selector to ADD
|
|||
|
_NewGestalt
|
|||
|
|
|||
|
lea gestaltLowMem,a0 ; address of gestaltLowMemSize patch
|
|||
|
move.l #gestaltLowMemorySize,d0 ; selector to ADD
|
|||
|
_NewGestalt
|
|||
|
|
|||
|
lea gestaltQDVers,a0 ; address of gestaltQDVersion patch
|
|||
|
move.l #gestaltQuickdrawVersion,d0 ; selector to REPLACE
|
|||
|
_ReplaceGestalt
|
|||
|
|
|||
|
lea gestaltMisc,a0 ; addr of gestaltMisc patch
|
|||
|
move.l #gestaltMiscAttr,d0 ; selector to ADD
|
|||
|
_NewGestalt
|
|||
|
|
|||
|
lea gestaltNMgr,a0 ; addr of gestaltNotificationMgrAttr patch
|
|||
|
move.l #gestaltNotificationMgrAttr,d0 ; selector to ADD
|
|||
|
_NewGestalt
|
|||
|
|
|||
|
lea gestaltUndef,a0 ; addr of gestaltUndef patch
|
|||
|
move.l #gestaltRBVAddr,d0 ; selector to REPLACE
|
|||
|
_ReplaceGestalt
|
|||
|
|
|||
|
lea gestaltUndef,a0 ; addr of gestaltUndef patch
|
|||
|
move.l #gestaltSCCReadAddr,d0 ; selector to REPLACE
|
|||
|
_ReplaceGestalt
|
|||
|
|
|||
|
lea gestaltUndef,a0 ; addr of gestaltUndef patch
|
|||
|
move.l #gestaltSCCWriteAddr,d0 ; selector to REPLACE
|
|||
|
_ReplaceGestalt
|
|||
|
|
|||
|
lea gestaltUndef,a0 ; addr of gestaltUndef patch
|
|||
|
move.l #gestaltVIA1Addr,d0 ; selector to REPLACE
|
|||
|
_ReplaceGestalt
|
|||
|
|
|||
|
lea gestaltUndef,a0 ; addr of gestaltUndef patch
|
|||
|
move.l #gestaltVIA2Addr,d0 ; selector to REPLACE
|
|||
|
_ReplaceGestalt
|
|||
|
|
|||
|
lea gestaltUndef,a0 ; addr of gestaltUndef patch <40>
|
|||
|
move.l #gestaltSlotAttr,d0 ; selector to REPLACE
|
|||
|
_ReplaceGestalt
|
|||
|
|
|||
|
lea gestaltUndef,a0 ; addr of gestaltUndef patch <40>
|
|||
|
move.l #gestaltSlotCount,d0 ; selector to REPLACE
|
|||
|
_ReplaceGestalt
|
|||
|
|
|||
|
lea gestaltUndef,a0 ; addr of gestaltUndef patch <40>
|
|||
|
move.l #gestaltFirstSlot,d0 ; selector to REPLACE
|
|||
|
_ReplaceGestalt
|
|||
|
|
|||
|
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
|
|||
|
|
|||
|
IF doScriptMgrGestalt AND (NOT installScriptMgrPtch27) THEN ; <4.6><15>
|
|||
|
;********* start of Gestalt install for Script Mgr <2.7> <08/05/89 pke> *********
|
|||
|
|
|||
|
import gestaltScriptMgr,gestaltSMgrTable
|
|||
|
|
|||
|
lea gestaltSMgrTable,a3 ; table of Gestalt selectors
|
|||
|
; and GetEnvirons verbs
|
|||
|
@loopInstallGestalt
|
|||
|
move.l (a3)+,d0 ; get next Gestalt selector
|
|||
|
beq.s @doneInstallGestalt ; 0 means we're done
|
|||
|
addq.l #2,a3 ; skip GetEnvirons verb
|
|||
|
lea gestaltScriptMgr,a0 ; push gestaltFunction ProcPtr
|
|||
|
_NewGestalt
|
|||
|
; ignore OSErr in d0 (what can
|
|||
|
; we do if it is not noErr?)
|
|||
|
bra.s @loopInstallGestalt
|
|||
|
@doneInstallGestalt
|
|||
|
|
|||
|
;********** end of Gestalt install for Script Mgr <2.7> <08/05/89 pke> **********
|
|||
|
ENDIF ; <4.6>
|
|||
|
|
|||
|
;-----------------------------------------------------------------------------------------
|
|||
|
|
|||
|
; Install Menu Manager patches
|
|||
|
|
|||
|
InstToolTp NewInitProcMenu,$8
|
|||
|
|
|||
|
;________________________________________________________________ <3.7><08/21/89 pke>
|
|||
|
; Patch to Pack6 to fix Script Manager routines
|
|||
|
;
|
|||
|
IF doScriptMgrPack6Fix AND (NOT installScriptMgrPtch39) THEN ; <12><15>
|
|||
|
InstToolTp ptchPack6,$1ED
|
|||
|
ENDIF
|
|||
|
|
|||
|
;____________________________________________________________________________ pke <3.9>
|
|||
|
; Install patches to UprString,CmpString,RelString
|
|||
|
|
|||
|
InstOSTp NewUprString,$54
|
|||
|
InstOSTp NewCmpString,$3C
|
|||
|
InstOSTp NewRelString,$50
|
|||
|
|
|||
|
;____________________________________________________________________________
|
|||
|
; Bump Script Manager version number for IntlForce bug fix (SysVers < $700) pke <4.2>
|
|||
|
; Set Script Manager version (SysVers >= $700) pke <4.4>
|
|||
|
; redo using new symbol smgrVersPTCHRom pke <4.5>
|
|||
|
|
|||
|
IF doScriptMgrSetROMVers AND (NOT installScriptMgrPtch39) THEN ; <12><15>
|
|||
|
With SMgrRecord
|
|||
|
GetSMgrCore a0
|
|||
|
move.w #smgrVersPTCHRom,smgrVersion(a0)
|
|||
|
EndWith
|
|||
|
ENDIF
|
|||
|
|
|||
|
;____________________________________________________________________________
|
|||
|
; Initialize additional Script Manager vectors pke <4.3>
|
|||
|
; Add CallInterface pke <4.5>
|
|||
|
; Add NewSwapIcon (7.0 only, moved to ptch 39) pke <4.7>
|
|||
|
|
|||
|
IF doScriptMgrNewVectors AND (NOT installScriptMgrPtch27) THEN ; <12><15>
|
|||
|
|
|||
|
ROMSMgrCalcRect EQU $17C84
|
|||
|
ROMSMgrInitFonts EQU $17CDE
|
|||
|
ROMCallInterface EQU $17E6A ; <4.5>
|
|||
|
|
|||
|
With SMgrRecord
|
|||
|
GetSMgrCore a0
|
|||
|
leaRom ROMSMgrCalcRect,a1
|
|||
|
move.l a1,sVectSMgrCalcRect(a0)
|
|||
|
leaRom ROMSMgrInitFonts,a1
|
|||
|
move.l a1,sVectSMgrInitFonts(a0)
|
|||
|
leaRom ROMCallInterface,a1 ; <4.5>
|
|||
|
move.l a1,sVectCallInterface(a0) ; <4.5>
|
|||
|
EndWith
|
|||
|
ENDIF
|
|||
|
|
|||
|
;____________________________________________________________________________ pke <4.4>
|
|||
|
; Install Script Manager 7.0 extensions, ROM patches
|
|||
|
|
|||
|
IF installScriptMgrPtch39 THEN ; <15>
|
|||
|
PtchInst 39 ; <12>
|
|||
|
ENDIF
|
|||
|
IF installScriptMgrPtch27 THEN ; <15>
|
|||
|
PtchInst 27 ; <4.4>
|
|||
|
ENDIF
|
|||
|
|
|||
|
;____________________________________________________________________________ pke <5.4>
|
|||
|
; Install patches for Script Manager routines InitDateCache, String2Date
|
|||
|
|
|||
|
IF doScriptMgrStr2DatFix AND (NOT installScriptMgrPtch39) THEN ; <12><15>
|
|||
|
smInitDateCacheOff equ -16 ; DispTable offset for InitDateCache
|
|||
|
smString2DateOff equ -20 ; DispTable offset for String2Date
|
|||
|
|
|||
|
With SMgrRecord
|
|||
|
GetSMgrCore a1
|
|||
|
move.l smgrDispTable(a1),a1
|
|||
|
|
|||
|
lea NewInitDateCache,a0
|
|||
|
move.l a0,smInitDateCacheOff(a1)
|
|||
|
lea NewString2Date,a0
|
|||
|
move.l a0,smString2DateOff(a1)
|
|||
|
|
|||
|
EndWith
|
|||
|
ENDIF
|
|||
|
|
|||
|
;____________________________________________________________________________ pke <5.5>
|
|||
|
; Install Script Manager tail patch to _GetIndADB, fixes the way SwapKybd
|
|||
|
; clears dead key state in ADB keyboard driver data structure
|
|||
|
|
|||
|
IF doScriptMgrRstKCHRFix AND (NOT installScriptMgrPtch39) THEN ; <12><15>
|
|||
|
PatchOSJump oldGetIndADB,$78 ; set addr for BackToTrap
|
|||
|
InstOSTp ptchGetIndADB,$78 ; …and then install patch
|
|||
|
ENDIF
|
|||
|
|
|||
|
;____________________________________________________________________________ pke <5.9>
|
|||
|
; Install Script Manager patch to LwrString so it handles 2-byte chars
|
|||
|
|
|||
|
IF doScriptMgrLwrString2 AND (NOT installScriptMgrPtch27) THEN ; <5.9><15>
|
|||
|
PatchOSJump oldLwrString,$56 ; set addr for BackToTrap
|
|||
|
InstOSTp ptchLwrString,$56 ; …and then install patch
|
|||
|
ENDIF
|
|||
|
|
|||
|
;____________________________________________________________________________ GMR <8>
|
|||
|
; Install EDisk Prime patch, to properly update ioActCnt, dCtlPos properly
|
|||
|
; after a read/write.
|
|||
|
|
|||
|
EDiskPrimeInst
|
|||
|
eDiskRefNum equ -49 ; DRVR id = 48, refnum = -49
|
|||
|
IMPORT HWDepRAM,HWDepROM,HWDepSLIM,vRAMExit,vROMExit,vSLIMExit
|
|||
|
WITH EDiskDriveInfo,EDiskVars
|
|||
|
move.l DrvQHdr+QHead,d0 ; get the drive queue head
|
|||
|
@loop beq.s @done ; if drive queue is empty
|
|||
|
movea.l d0,a0 ; a0 := drive queue element
|
|||
|
cmpi.w #EDiskRefNum,DQRefNum(a0) ; belong to an EDisk?
|
|||
|
beq.s @match
|
|||
|
@next move.l QLink(a0),d0 ; check next drive queue element
|
|||
|
bra.s @loop
|
|||
|
|
|||
|
@match movea.l HWDepProcPtr(a0),a1 ; get old Proc ptr
|
|||
|
move.b DriveInfo+3(a0),d0 ; get disk type
|
|||
|
|
|||
|
subi.b #16,d0
|
|||
|
bne.s @romDisk
|
|||
|
lea HWDepRAM,a2 ; get ptr to start of new RAM proc
|
|||
|
cmp.l a1,a2 ; already patched this drive type?
|
|||
|
beq.s @next ; yes, skip
|
|||
|
move.l a1,vRAMExit+2-HWDepRAM(a2) ; tail patch old rtn into new rtn
|
|||
|
move.l a2,HWDepProcPtr(a0) ; stuff new proc ptr into globals
|
|||
|
bra.s @next
|
|||
|
|
|||
|
@romDisk subq.b #1,d0
|
|||
|
bne.s @slimDisk
|
|||
|
lea HWDepROM,a2 ; get ptr to start of new RAM proc
|
|||
|
cmp.l a1,a2 ; already patched this drive type?
|
|||
|
beq.s @next ; yes, skip
|
|||
|
move.l a1,vROMExit+2-HWDepROM(a2) ; tail patch old rtn into new rtn
|
|||
|
move.l a2,HWDepProcPtr(a0) ; stuff new proc ptr into globals
|
|||
|
bra.s @next
|
|||
|
|
|||
|
@slimDisk subq.b #1,d0
|
|||
|
bne.s @next ; not one we know about, try next drive
|
|||
|
lea HWDepSLIM,a2 ; get ptr to start of new RAM proc
|
|||
|
cmp.l a1,a2 ; already patched this drive type?
|
|||
|
beq.s @next ; yes, skip
|
|||
|
move.l a1,vSLIMExit+2-HWDepSLIM(a2) ; tail patch old rtn into new rtn
|
|||
|
move.l a2,HWDepProcPtr(a0) ; stuff new proc ptr into globals
|
|||
|
bra.s @next
|
|||
|
@done
|
|||
|
ENDWITH
|
|||
|
|
|||
|
;_________________________________________________________________________________________ EVA <50>
|
|||
|
; Install Async Serial Driver Vector Address
|
|||
|
; Install latesta version number for driver
|
|||
|
Import SerialPatch
|
|||
|
InstOSTp SerialPatch,$A0BE
|
|||
|
|
|||
|
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
|
|||
|
|
|||
|
;_________________________________________________________________________________________ <49> djw
|
|||
|
; Install the SCSI Manager patch for the Quantum 7.9 ROM fix
|
|||
|
|
|||
|
Import QuantumWBlindPortable
|
|||
|
with scsiGlobalRecord
|
|||
|
|
|||
|
movea.l SCSIGlobals,a1 ; get ptr to SCSI globals
|
|||
|
lea QuantumWBlindPortable,a0 ; a0 = TIB interpreter patch
|
|||
|
move.l a0,jvWBlind(a1) ; replace vector to blind write routine
|
|||
|
|
|||
|
endwith
|
|||
|
|
|||
|
|
|||
|
;————————————————————————————————————————————————————————————————————————————————————————
|
|||
|
;############################### END PATCH INSTALL CODE #################################
|
|||
|
;————————————————————————————————————————————————————————————————————————————————————————
|
|||
|
|
|||
|
CalcPatchSize Lea StartPatch,A1 ; start of patch code
|
|||
|
Lea EndOfPatch,A0 ; end of patch code
|
|||
|
Sub.l A1,A0 ; calc size of resident code
|
|||
|
Move.l A0,D0 ; SetHandleSize takes new size in D0
|
|||
|
Move.l (SP)+,A0 ; restore the handle passed by SysPatch
|
|||
|
|
|||
|
Bra CutBack ; go cut the install code off and exit
|
|||
|
|
|||
|
ENDPROC
|
|||
|
|
|||
|
UsesPtchInst ; PatchInstall code macro <1.6-4april89-CEL>
|
|||
|
|
|||
|
Proc
|
|||
|
Export FixupTbl
|
|||
|
|
|||
|
;################## TABLE OF LOCATIONS TO BE OFFSET BY [ROMBase] ######### <3.6> pke
|
|||
|
;
|
|||
|
; Table contains one entry for each reference to a ROM address from the
|
|||
|
; JmpROM, JsrROM, and CmpRA macros. &RomFixIndex is a count of the total
|
|||
|
; number of these references, and is also used to synthesize the label
|
|||
|
; names for them. The reference labels have the form
|
|||
|
; RXXX000, RXXX001, RXXX002, ...
|
|||
|
; See the Macro definitions for JmpROM, JsrROM and CmpRA (near the top of
|
|||
|
; this file) for more info.
|
|||
|
;
|
|||
|
; MkTbl is a macro only because assembler while loops will not work
|
|||
|
; outside of macros.
|
|||
|
;
|
|||
|
MACRO
|
|||
|
MkTbl
|
|||
|
gbla &RomFixIndex
|
|||
|
while &RomFixIndex <> 0 do
|
|||
|
&RomFIxIndex seta &RomFixIndex - 1
|
|||
|
dc.l RXXX&I2S(&ROMFIXINDEX,-3) - FixUpTbl
|
|||
|
endwhile
|
|||
|
dc.l 0 ; Zero entry marks end of table
|
|||
|
ENDM
|
|||
|
|
|||
|
FixupTbl MkTbl
|
|||
|
|
|||
|
;########################### END PATCHES CUT BACK CODE ################################
|
|||
|
|
|||
|
EndProc
|
|||
|
|
|||
|
END
|