sys7.1-doc-wip/Patches/PatchPortableROM.a
2019-07-27 22:37:48 +08:00

3799 lines
141 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;
; 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