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