sys7.1-doc-wip/Patches/PatchPortableROM.a

3799 lines
141 KiB
Plaintext
Raw Normal View History

2019-07-27 14:37:48 +00:00
;
; 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, dont set up the serial port
; for use by AppleTalk. This is part of a large conspiracy to
; convince the universe that AppleTalk really isnt 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 its 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 Gestalts 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 theyre 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
; cpus.
; <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, dont 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, dont 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 were 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 Gestalts 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