mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-28 01:29:20 +00:00
4325cdcc78
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
2280 lines
86 KiB
Plaintext
2280 lines
86 KiB
Plaintext
;
|
||
; File: EGRET Manager.a
|
||
;
|
||
; Contains: Contains low level code to support sending and receiving
|
||
; packets (ADB, Pseudo Commands, Ticks, etc) to/from the Egret
|
||
; 6805uC.
|
||
;
|
||
; Written by: Gary Rensberger
|
||
;
|
||
; Copyright: © 1990-1993 by Apple Computer, Inc. All rights reserved.
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <SM19> 11/9/93 KW added some eieioSTP macros. Only expands for CygnusX1 ROM.
|
||
; <SM18> 9/29/93 SAM From mc900ftjesus.
|
||
; <MC3> 9/25/93 SAM Whoot! What a mess. Removed usless/redundant entry points and
|
||
; imports/exports by the thousands. Cleaned up tons of stuff.
|
||
; Changed the labels of a few routines to reflect the fact that
|
||
; they apply to both egret and cuda. Export ChkFirmware for
|
||
; vectorization. Backedout change <SM17>.
|
||
; <SM17> 9/23/93 PN Add condition for Egret
|
||
; <SM16> 7/12/93 kc Re-roll in ShiftRegIRQPatch to fix Quadra 900-950 ReadTime bug.
|
||
; <SM15> 12/1/92 RB Turned off the debug feature in Egret.
|
||
; <SM14> 11/20/92 GS Removed the CudaPDMPatch from the initialization of the DFAC and
|
||
; PDMs for Caboose or Cuda. This initialization for Cyclone is
|
||
; now done in the Gibbly.
|
||
; <SM13> 11/3/92 SWC Changed ShutdownEqu.a->Shutdown.a.
|
||
; <SM12> 10/02/92 AEK Conditionalize call to InitReliabitity to keep it from being
|
||
; called twice if not on an overpatched ROM
|
||
;
|
||
; <SM11> 9/18/92 GS Debug Enter - removed PDMSuspend command. DebugExit - add
|
||
; MacsbugContinue command, add Window update. EgretDFACandPDM
|
||
; routine - removed the Keybd NMI enable for the Cuda FW. In the
|
||
; Cuda FW, the command to enable/disable Keybd NMI no longer is a
|
||
; valid command. Keybd NMI is always enabled with the Cuda FW.
|
||
; <SM10> 6/26/92 GS (RBM) Removed the Enable KeyboardNMI call made in the
|
||
; EgretDFACandPDM
|
||
; routine. With the new version of Cuda FW (Cuda 0.22), the NMI
|
||
; is always ON.
|
||
; No longer has entry in the pseudo cmd table for SetDFACmode.
|
||
; Instead, a new
|
||
; command exists, called RdWrIIC to perform bidirectional IIC
|
||
; transactions.
|
||
; This requires special setup of the Cuda globals by the routine
|
||
; 'SetTransferParams' (see CudaMgr.a).
|
||
;
|
||
; <SM9> 5/24/92 RB Removed the routine QuadraEgretChanges since EgretDFACandPDM is
|
||
; a better version from the Pandora ROM. This routine gets called
|
||
; from StartInit.a
|
||
; <SM8> 5/24/92 RB Removing "patches" as they get rolled into the other
|
||
; sources...PowerSwitchIntPatch is out.
|
||
; <SM7> 5/23/92 RB Making Cyclone changes...Revised some patches rolled in from
|
||
; Terror. Pandora comments follow: with some duplications... Note
|
||
; that a lot of this code should be reworked with the ADBMgr, the
|
||
; first step is to get it all in... **** From EgretPatches.a: <P2>
|
||
; 4/24/92 GS Added a Egret Dispatch call to suspend/continue PDM
|
||
; when entering exiting Macsbug. This is to prevent problems of
|
||
; determining whether or not to ignore PDM messages. **** From
|
||
; EgretMgr.a: <P4> 2/10/92 GS Exported the PseudoTable for use by
|
||
; the CudaMgr.a code. Cleaned up some comments. <P3> 02/07/92 jmp
|
||
; Added some padding so that Pandora matches Horror. <P2> 1/16/92
|
||
; GS Added code to determine the Egret Firmware Type (Egret8,
|
||
; Caboose, Cuda), then set up the appropiate vectors for IRQ,
|
||
; Ticks, Dispatcher...
|
||
; ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
; Pre-Pandora ROM comments begin here.
|
||
; ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
; <5> 2/20/91 BG Fixed error in CheckPacket. The check for allowable
|
||
; pseudo-packets was a hard-coded name check instead of an
|
||
; end-of-table check.
|
||
; <4> 12/11/90 JJ Mac LC: Changes references to VISAChipBit to V8ChipBit.
|
||
; <3> 12/7/90 CCH Adjusted the patch code in CheckPacket so that it fits in the
|
||
; same number of bytes as the original code.
|
||
; <2> 12/6/90 BG (with GA) Rolled in Eclipse-related Egret/Caboose changes.
|
||
; <P9> 4/24/92 GS Removed DSorDebuggerPatch that was called from StartErr.a New
|
||
; code and PDM Selectors used by PDM removed the need. Updated
|
||
; the DebugUtil code in EgretPatches.a to handle these cases.
|
||
; **** From EgretPatchesToo.a:
|
||
; <P8> 4/24/92 KW (SWC,H5) Moved ADB and DebugUtil routines to ADBPrimitives.a.
|
||
; <P10> 4/10/92 gjs Make Timer Mgr Task fire off a Cuda Tickle pkt every 3 sec
|
||
; instead of 7 secs. Still having problem with 2nd User Alert
|
||
; with mulitple hits to Keybd Reset key. Also bump up the Timer
|
||
; Timeout passed back to Cuda.
|
||
; <P9> 4/08/92 gjs Upon installing a TimeMgr task to tickle Cuda during the User
|
||
; alert, send a tickle to cover the first 7-10 seconds of the
|
||
; display of the alert.
|
||
; <P8> 3/30/92 GS The KeyBdSwHandler has been changed to set up a User Alert
|
||
; if the KeybdPower switch has been depressed, or if the
|
||
; chassis swithc or Secure Key switch has been used for a power down
|
||
; a deferred Task will be executed, with out a User Alert.
|
||
; <P7> 3/17/92 GS The PowerSwitch Int Handler has been changed to user the new
|
||
; ShutDown mgr code in the system. This makes all _ShutDown trap
|
||
; calls with the selector set to 1 a soft power off.
|
||
; <P6> 3/3/92 GS Update some Cuda Code to save some regs in Tickle timer code,
|
||
; and begin to setup for the new power down msg to indicate kybd
|
||
; or chassis sw power down.
|
||
; <P5> 02/11/92 jmp The EgretDFACandPDAM routine (which used to be the
|
||
; EclipseEgretPatches routine) got bigger, so I moved it into the
|
||
; pad space, with a branch from the original location.
|
||
; <P4> 2/11/92 GS Update the Cuda Patches used to support SoftPower On/Off. Added
|
||
; comments and revision tags. Updated a patch label from
|
||
; EclipseEgretPatches to EgretDFACandPDM to better describe the
|
||
; function of the patch. Also added functionality to the patch to
|
||
; handle Caboose and Cuda firmware initializations.
|
||
; <P3> 02/07/92 jmp (jmp,H3/BG,Z19) Fixed ReGenSoundInt to wait in between disabling
|
||
; and re-enabling sound interrupts. Also changed ReGenSoundInt to
|
||
; work like Kip originally intended (i.e. regenerate interrupts
|
||
; only on the channel(s) that need it).
|
||
; <P2> 1/16/92 GS Rolled in the newPatches that are associated with the Cuda
|
||
; firmware for SoftPower On/Off.
|
||
; ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
; Pre-Pandora ROM comments begin here. (EgretPatchesToo)
|
||
; ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
; <H2> 12/21/91 jmp (BG,Z18) Added code to re-generate sound interrupts when
|
||
; checking the keyswitch values since reading port B causes
|
||
; interrupts to get cleared (stupid design of original VIAs).
|
||
;
|
||
; <SM6> 5/17/92 kc Roll in Horror sources. (prepend via equates with v)
|
||
; <SM5> 5/13/92 SES Fixed bug in ShiftRegIrq patch roll in. Additional sr restore
|
||
; instructions were added only where necessary instead of trying
|
||
; to restore "globally" right before exiting.
|
||
; <SM4> 5/5/92 SES Rolled in patches from PatchIIciROM.a, including ShiftRegIrq
|
||
; patch for saving/restoring sr, and addition of SCC polling in
|
||
; EgretDispatch. Also fixed minor bug in tickHandler where
|
||
; with/endwith directives were left out.
|
||
; <SM3> 5/4/92 FM fix typo
|
||
; <SM2> 5/4/92 FM Roll in changes from PatchIICiRom.a file that were "lost" in the
|
||
; review processÉ Changing the TickHandler to update the Time
|
||
; lo-mem global so that the RdDateTime can simply return whats in
|
||
; the global.
|
||
; <21> 1/20/92 KC Move RequestDonePatch into ADBMgr.a. Changed
|
||
; CheckForCabooseKeyswitch into TestFor KeyswCabooseBit macro
|
||
; call.
|
||
; <20> 1/13/92 kc Added Terror changes, origional comments below.
|
||
; {?} Added "Enable PDMMessage" and "SendDefault DFAC" to PseudoCntTable.
|
||
; {5} 2/20/91 BG Fixed error in CheckPacket. The check for allowable
|
||
; pseudo-packets was a hard-coded name check instead of an
|
||
; end-of-table check.
|
||
; <19> 12/29/91 RB Added Terror changes and rolled in patches to support Quadras.
|
||
; <18> 8/30/91 JSM Cleanup header, donÕt include SysErr.a since itÕs in
|
||
; StandardEqu.d.
|
||
; <17> 6/12/91 LN removed #include 'HardwareEqu.a'
|
||
; <16> 4/24/91 dba fix warning
|
||
; <15> 10/22/90 JJ Rex V8: Change VISAChipBit to V8ChipBit.
|
||
; <14> 5/15/90 GA Removing calls to SCCPollDelay. Routine not needed.
|
||
; <13> 5/8/90 GA Disabled all interrupts during interrupt handler to prevent
|
||
; AppleTalk from interrupting Egret Manager and the issuing a
|
||
; ReadXPram call which calls Egret Manager Synchronously. Changed
|
||
; the Delay100 routine to SCCPollDelay. It polls and buffers any
|
||
; serial data from the SCC and calls the Serial Driver PollProc
|
||
; routine if one is present. Modified SendEgretCmd to have a retry
|
||
; count to communicate with Egret. If the Retry count expires,
|
||
; EgretMgr calls Error1Handler. Modified SendPtype to read the
|
||
; interrupt flags register in the via 32767 times (Å41.9 millsecs
|
||
; max) and then try send the packet type again based on the retry
|
||
; count.
|
||
; <12> 4/25/90 GA Fixed a bug with SendDFAC to allow 1 to 4 bytes to be sent to
|
||
; Egret. Fixed a bug with the error reporting mechanism to return
|
||
; all 4 bytes of the error packet returned by Egret.
|
||
; <11> 4/10/90 GA Fixed a bug in the error checking code. Made a change to make
|
||
; KeyLite program work (returns parameter block byte count
|
||
; unchanged).
|
||
; <10> 4/2/90 GA Removing the Routine Read LastByte from the SendEgretCmd code.
|
||
; Also, fixing lines of source which have had their C/R changed to
|
||
; a Null ($00) character. We suspect that Romlister may trash
|
||
; source files which are open during the build.
|
||
; <9> 3/30/90 GA Added Error reporting for bad parameter blocks from the system
|
||
; to Egret.
|
||
; <8> 3/22/90 GA Changed the Via_Full Ack process on the last byte of
|
||
; transactions to clarify the Logic Analyzer displays.
|
||
; <7> 3/15/90 GA Ray and I added conditionalized code to send Stop Autopoll and
|
||
; send mode 0 one second interrupt command s in place of the
|
||
; SendNOPCmd to support the B3 release of Egret. This code will be
|
||
; inactivated when the final Egret parts come in.
|
||
; <6> 3/13/90 GA Added a routine called SENDNOPCMD. This routine is register
|
||
; driven and issues a command to Egret to Stop AutoPoll and one
|
||
; second interrupts in Egret
|
||
; <5> 3/9/90 GMR Optimized code in a few places. Moved assertion of SysSes bit to
|
||
; after test of XcvrSes, to fix bug on 2 byte tick packets.
|
||
; <4> 2/28/90 GMR Rewrote file.
|
||
; <3> 2/14/90 GA Added support code for Restart & shutdown in Egret. Issues stop
|
||
; autopoll & stop 1 sec interrupts prior to restarting the system.
|
||
; <2> 2/9/90 GA 1. Added two calls to DelayLoop to give Egret time to see
|
||
; transitions of SysSession signal.
|
||
;
|
||
; 2. SendWithCheck & SynChkSend now wait for the shift register
|
||
; interrupt bit to be asserted before exiting when a transaction
|
||
; is aborted.
|
||
;
|
||
; 3. Moved code which sends bitmap and starts autopoll to Egret into
|
||
; EgretMgr.a. ADBMgr now issues a JSR StartEgretAutopoll to do
|
||
; the same function. This makes the Erickson overpatch easier.
|
||
;
|
||
; <1> 2/3/90 GA first checked in
|
||
;
|
||
************************************************************************
|
||
machine mc68020
|
||
|
||
BLANKS ON
|
||
STRING ASIS
|
||
|
||
PRINT OFF
|
||
LOAD 'StandardEqu.d'
|
||
INCLUDE 'EgretEqu.a'
|
||
INCLUDE 'HardwarePrivateEqu.a'
|
||
INCLUDE 'UniversalEqu.a'
|
||
INCLUDE 'IOPEqu.a'
|
||
INCLUDE 'AppleDeskBusPriv.a'
|
||
INCLUDE 'ShutDown.a'
|
||
INCLUDE 'FSEqu.a'
|
||
INCLUDE 'PowerPrivEqu.a'
|
||
PRINT ON
|
||
|
||
include 'EgretEqu.a'
|
||
eject
|
||
|
||
EgretDebug EQU 0
|
||
|
||
EgretMgr PROC EXPORT
|
||
|
||
EXPORT InitEgretOrCuda, EgretDispatch, CheckPacket
|
||
EXPORT PseudoCntTable, ADBCntTable, SetResponseParams, ChkFirmware
|
||
|
||
IMPORT GetHardwareInfo, Error1Handler
|
||
IMPORT CudaDispatch,CudaShiftRegIRQ,CudaTickHandler
|
||
IMPORT CudaInit, SendCudaCmd
|
||
|
||
rayFix EQU 1 ; needed to fix Egret bug on old parts
|
||
ErrEgretInit equ $0030 ; TEMPORARY definition of error equate defined in STEQU.a
|
||
|
||
|
||
WITH EgretGlobals,EgretPB,RespHeader ; <60> rb
|
||
;===============================================================================================
|
||
; Routine: InitEgret
|
||
;
|
||
; Function: Allocates globals, sets vACR to shift in mode, sets up globals for an auto-response
|
||
; packet (ADB/Ticks).
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Destroys: a0-a2, d0-d2
|
||
;________________________________________________________________________________________________
|
||
InitEgretOrCuda
|
||
moveq.l #EgretGlobSize,D0 ; get size of globals
|
||
_NewPtr ,SYS,CLEAR ; allocate space on heap and clear
|
||
|
||
move.l a0,EgretBase ; save ptr to it
|
||
movea.l a0,a2 ;
|
||
|
||
move.w sr,-(sp) ; save irq enable status
|
||
ori.w #HiIntMask,sr ; mask out interrupts
|
||
|
||
lea workPb(a2),a0 ; pointer to work parameter block <SM7> rb
|
||
move.l a0,adbPb(a2) ; store in adb parameter block <SM7> rb
|
||
|
||
bsr SetResponseParams ; setup globals to handle auto response packets again
|
||
|
||
bsr.l ChkFirmware ; Set up dispatch,IRQ, and ticks (Sets up _EgretDispatch trap)
|
||
move.l a0,Lvl1DT+8 ; the level 1 dispatch table
|
||
move.l a1,tickComp(a2) ; set up default tick packet handler
|
||
|
||
movea.l VIA,a1 ; point to the VIA
|
||
eieioSTP
|
||
bclr.b #SRdir,vACR(a1) ; shift reg direction = input
|
||
eieioSTP
|
||
move.b #(1<<ifIRQ)|\
|
||
(1<<ifSR),vIER(a1) ; enable shift register interrupts
|
||
eieioSTP
|
||
move.w (sp)+,sr ; restore interrupts
|
||
rts
|
||
|
||
|
||
;________________________________________________________________________________________________
|
||
; Routine: EgretDispatch
|
||
;
|
||
; Function: This is the Egret manager trap routine. It waits for Egret to be idle, sends
|
||
; the first byte of the command packet. If Egret didn't abort, then it sets up
|
||
; globals for the IRQ handler, and if a completion routine was specified, it returns
|
||
; back to the caller. If no completion routine, then it waits synchronously for
|
||
; the command/response to finish, using the busy bit. When the IRQ handler has finished
|
||
; the response packet, it preps the globals to expect an auto-response packet
|
||
; (ticks or ADB), clears 'busy' and calls the completion routine (if any).
|
||
;
|
||
; Inputs: a0 - pointer to parameter block
|
||
;
|
||
; Outputs: d0 - result (0 for now)
|
||
;
|
||
; Destroys: a0-a2, d0-d1
|
||
;________________________________________________________________________________________________
|
||
EgretDispatch
|
||
bsr CheckPacket ; Validate the Packet type & command byte
|
||
bne @done ; Exit if Error packet
|
||
movea.l EgretBase,a2 ; a2 gets ptr to globals
|
||
movea.l VIA,a1 ; a1 points to VIA base
|
||
|
||
|
||
|
||
@checkSpecial
|
||
cmpi.b #specialPkt,pbCmdType(a0) ; is this a special command? <SM7> rb
|
||
bne.s @ckPDMInit ; check for Eclipse PowerDown Message Initialization <SM7> rb
|
||
|
||
move.l a0,ADBpb(a2) ; yes, is to set the ADB param block (for autopoll data). <SM7> rb
|
||
bra @done ; <SM7> rb
|
||
|
||
@ckPDMInit ; <SM7> rb
|
||
;
|
||
; Check for Eclipse PowerDown Message Vector
|
||
; Initialization.
|
||
;
|
||
cmpi.b #PDMVectPkt,pbCmdType(a0) ; check for PowerDown message vector Init <60> rb <SM7> rb
|
||
bne.s @EgretRestart ; Must be Egret Command <60> rb <SM7> rb
|
||
|
||
move.l pbParam(a0),PDMComp(a2) ; handler for Eclipse PowerDown Message Packet <60> rb <SM7> rb
|
||
bra @done ; and exit
|
||
|
||
@EgretRestart
|
||
|
||
|
||
move.w sr,-(sp) ; save SR
|
||
ori.w #hiIntMask,sr ; mask interrupts
|
||
eieioSTP
|
||
btst.b #xcvrSes,vBufB(a1) ; does Egret want to abort?
|
||
eieioSTP
|
||
beq.s @abort ; yes, wait for it to go away
|
||
bset.b #busy,flags(a2) ; not an abort, mark that we're busy.
|
||
eieioSTP
|
||
beq.s @sendPackType ; we were not busy before, so try to send the first byte
|
||
|
||
@abort move.w (sp)+,sr ; we were busy, enable interrupts
|
||
bsr pollByte ; poll shift reg, calling handler if interrupts masked
|
||
|
||
bra.s @EgretRestart ; and keep waiting for busy to go away...
|
||
|
||
@sendPackType ; interrupts masked here
|
||
eieioSTP
|
||
bset.b #sysSes,vBufB(a1) ; assert System Session (we're starting command packet)
|
||
eieioSTP
|
||
bset.b #SRdir,vACR(a1) ; switch to output
|
||
eieioSTP
|
||
move.b pbCmdType(a0),vSR(a1) ; send command packet to shift reg
|
||
eieioSTP
|
||
bset.b #viaFull,vBufB(a1) ; tell Egret we sent it
|
||
eieioSTP
|
||
|
||
;<SM4><SES> Rolled in from PatchIIciROM.a
|
||
;----------------------------------------------------------------------------------------------------
|
||
; This patch fixes possible loss of data to the SCC by calling
|
||
; the Poll Proc when SCC data is available.
|
||
;
|
||
; NOTE: This is a slightly modified version of the one from PatchIIciROM.a
|
||
;----------------------------------------------------------------------------------------------------
|
||
;_________________________
|
||
; If PollProc exists, Poll the SCC and save any available data
|
||
; When the shift register irq comes in call the PollProc
|
||
; then process the shift register irq data
|
||
;
|
||
movem.l d0/d1/a0-a4/a6,-(sp) ; save some registers
|
||
|
||
move.l sp,PollStack ; Pointer to buffer for polled bytes
|
||
|
||
eieioSTP
|
||
btst.b #0,SccIopFlag ; Check if we are in IOP mode (On Eclipse...)
|
||
eieioSTP
|
||
beq.s @NoPollWait ; If IOP then we don't need to poll
|
||
|
||
tst.l PollProc ; Check for a Poll Proc available
|
||
beq.s @NoPollWait ; If no Poll Proc then we don't need to poll
|
||
|
||
movea.l SccRd,a3 ; SCC may have data to get
|
||
movea.l a3,a6
|
||
addq.l #Actl,a3 ; Point to data available register (RR0)
|
||
addq.l #AData,a6 ; Point to the SCC data register
|
||
|
||
@wait
|
||
eieioSTP
|
||
btst.b #RxCa,(a3) ; Test for SCC data available
|
||
eieioSTP
|
||
beq.s @2
|
||
move.b (a6),-(sp) ; Push the data on the stack
|
||
@2
|
||
eieioSTP
|
||
btst.b #vShift,vIFR(a1) ; now wait for shift reg IRQ
|
||
|
||
eieioSTP
|
||
beq.s @wait
|
||
|
||
cmpa.l PollStack,SP ; Is there any poll data
|
||
beq.s @NoSCCData
|
||
;
|
||
; We have SCC data and a Poll Proc to call. Go call it
|
||
;
|
||
pea @NoSCCData ; Return addr for PollProc
|
||
move.l PollProc,-(SP) ; Point to the PollProc
|
||
rts ; Call the PollProc
|
||
|
||
|
||
@NoPollWait
|
||
eieioSTP
|
||
btst.b #vShift,vIFR(a1) ; now wait for shift reg IRQ
|
||
eieioSTP
|
||
|
||
beq.s @NoPollWait
|
||
|
||
@NoSCCData movem.l (sp)+,d0/d1/a0-a4/a6 ; restore work registers
|
||
|
||
@VsrIrq
|
||
eieioSTP
|
||
btst.b #xcvrSes,vBufB(a1) ; did Egret abort?
|
||
eieioSTP
|
||
bne.s @accepted ; no, then it will accept our packet
|
||
bclr.b #SRdir,vACR(a1) ; yes, switch back to input
|
||
eieioSTP
|
||
bclr.b #sysSes,vBufB(a1) ; ack the abort
|
||
eieioSTP
|
||
bsr CallShiftRegIRQ ; handle it
|
||
eieioSTP
|
||
bra.s @abort ; and wait
|
||
|
||
;<SM4><SES> end of EgretDispatch SCC poll fix
|
||
|
||
@accepted ; we sent the packetType, now set up for the IRQ handler
|
||
jsr SetTransferParams ; setup globals for this packet
|
||
bsr CallShiftRegIRQ ; transfer second byte (command) to start things
|
||
move.w (sp)+,sr ; now enable interrupts
|
||
eieioSTP
|
||
|
||
tst.l pbCompletion(a0) ; do we have a completion routine
|
||
eieioSTP
|
||
bne.s @done ; yes, then return asynchronously
|
||
|
||
@waitComplete
|
||
btst.b #busy,flags(a2) ; otherwise, are we still busy?
|
||
eieioSTP
|
||
beq.s @done ; no, then we're done...
|
||
|
||
bsr.s pollByte ; yes, poll out a byte if necessary
|
||
|
||
; bclr.b #busy,flags(a2) ; otherwise, are we still busy?
|
||
|
||
bra.s @waitComplete ; and wait here (synchronously)
|
||
|
||
@done moveq #0,d0 ; no errors for now
|
||
rts
|
||
|
||
;________________________________________________________________________________________________
|
||
;
|
||
; Validate the Packet type and Command if Pseudo Pkt.
|
||
;
|
||
; If an error is encountered with the packet a error packet will be
|
||
; built in the pbParam area of the parameter block as if Egret had
|
||
; returned the packet. Also, the pbResult field will contain a System
|
||
; error code for bad parameter block format.
|
||
;
|
||
; Entry: A0 = Parameter block pointer
|
||
;
|
||
; Exit: sr.Z = 0 if valid packet/pseudocmd nonzero otherwise
|
||
;
|
||
_________________________________________________________________________________________________
|
||
|
||
CheckPacket
|
||
cmp.b #SpecialPkt,pbCmdType(a0) ; could be an ADB initialization packet
|
||
beq.s @OkExit
|
||
|
||
cmp.b #PDMVectPkt,pbCmdType(a0) ; could be PowerDown message Vector Init Packet <60> rb
|
||
beq.s @OKExit ; if equal, CONTINUE <60> rb
|
||
|
||
cmp.b #ErrorPkt,pbCmdType(a0) ; ADB ($00) and Pseudo ($01) only
|
||
bhi.s @BadPkt ; Invalid packet
|
||
|
||
cmp.b #PseudoPkt,pbCmdType(a0) ; Check for pseudo commands
|
||
bne.s @OkExit ; On Pseudo Packets check the command
|
||
|
||
cmp.b #MaxPseudoCmd,pbCmd(a0) ; Validate the Pseudo command number {5}
|
||
bls.s @OkExit
|
||
|
||
@BadPseudo move.w #InvPseudo,pbParam(a0) ; report a pseudo command error
|
||
move.w pbCmdType(a0),pbParam+2(a0) ; we are faking an error packet
|
||
bra.s @ErrorExit
|
||
|
||
@BadPkt move.w #InvPkt,pbParam(a0) ; report invalid packet error
|
||
move.w pbCmdType(a0),pbParam+2(a0) ; we are faking an error packet
|
||
|
||
@ErrorExit move.w #paramErr,pbResult(a0) ; parameter error in result field
|
||
bra.s @Exit
|
||
|
||
@OkExit move.w #0,pbResult(a0) ; So far packet OK
|
||
@Exit rts
|
||
|
||
;________________________________________________________________________________________________
|
||
; Routine: PollByte
|
||
;
|
||
; Function: This routine checks to see if level 1 interrupts are masked, exits if not.
|
||
; If masked, it polls the flag register for a shift reg interrupt, and
|
||
; calls the handler if found.
|
||
;
|
||
; Inputs: a1 - VIA base ptr
|
||
; a2 - globals pointer
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Destroys: d0,d1
|
||
;________________________________________________________________________________________________
|
||
PollByte
|
||
|
||
move.w sr,d0 ; get 68xxx interrupt mask
|
||
andi.w #hiIntMask,d0 ; are we at interrupt level?
|
||
beq.s @exit ; no, just exit
|
||
eieioSTP
|
||
btst.b #vShift,vIFR(a1) ; yes, poll the shift reg
|
||
eieioSTP
|
||
beq.s @exit ; no shift reg interrupt, return
|
||
bsr.s CallShiftRegIRQ ; yes, handle it
|
||
@exit rts
|
||
|
||
|
||
;________________________________________________________________________________________________
|
||
; Routine: SendByte
|
||
;
|
||
; Function: This routine clears viaFull bit, delays 125us, sends a byte to the shift reg,
|
||
; then asserts viaFull bit.
|
||
;
|
||
; Inputs: d0 - byte to send
|
||
; a1 - VIA base ptr
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Destroys: d1
|
||
;________________________________________________________________________________________________
|
||
SendByte
|
||
eieioSTP
|
||
bclr.b #viaFull,vBufB(a1) ; negate via full
|
||
eieioSTP
|
||
bsr.s Delay100 ; give Egret time to see it
|
||
eieioSTP
|
||
move.b d0,vSR(a1) ; send the byte to the shift reg
|
||
eieioSTP
|
||
bset.b #viaFull,vBufB(a1) ; let Egret know it's there
|
||
eieioSTP
|
||
rts
|
||
|
||
;________________________________________________________________________________________________
|
||
CallShiftRegIRQ
|
||
movem.l a0-a3/d0-d3,-(sp) ; save regs like interrupt handler does
|
||
movea.l Lvl1DT+8,a0 ; get the shift reg IRQ handler
|
||
jsr (a0) ; call it
|
||
movem.l (sp)+,a0-a3/d0-d3 ; restore regs
|
||
rts
|
||
|
||
;________________________________________________________________________________________________
|
||
viaFullAck
|
||
eieioSTP
|
||
bset.b #viaFull,vBufB(a1) ; acknowlege the byte
|
||
eieioSTP
|
||
bsr.s Delay100 ; give Egret time to see it
|
||
eieioSTP
|
||
rts ; gets cleared on exit from IRQ handler
|
||
|
||
;________________________________________________________________________________________________
|
||
Delay100
|
||
move.l d1,-(sp) ; save d1
|
||
move.w timeViaDB,d1 ; 1 ms loop count
|
||
lsr.w #3,d1 ; / 8 = 125 us
|
||
; cmpi.b #boxQuadra900,boxFlag ; is this a Quadra900 ? <60> rb
|
||
; bne.s @loop ; no ? then skip <60> rb
|
||
add.w #EclipseDelay,d1 ; <60> rb, we need an extra 25 usecs on Eclipse <GAA Eclipse>
|
||
@loop
|
||
eieioSTP
|
||
tst.b (a1) ; access the VIA
|
||
eieioSTP
|
||
dbra d1,@loop
|
||
move.l (sp)+,d1 ; restore d1
|
||
eieioSTP
|
||
rts
|
||
|
||
;________________________________________________________________________________________________
|
||
; Routine: ShiftRegIRQ
|
||
;
|
||
; Function: This routine is called in response to a VIA shift reg interrupt. It will transfer
|
||
; the next byte in the current packet. When the packet is complete, the globals are
|
||
; prepped for an auto-response packet (ADB/Ticks), then the completion routine
|
||
; is called (if present).
|
||
;
|
||
; Inputs: a1 - VIA base ptr
|
||
;
|
||
; Outputs: a2 - globals pointer
|
||
;
|
||
; Destroys: a0-a2,d0,d1
|
||
;________________________________________________________________________________________________
|
||
EXPORT ShiftRegIRQ
|
||
|
||
ShiftRegIRQ
|
||
move.w sr,d3
|
||
ori.w #hiIntMask,sr ; mask interrupts <13>
|
||
movea.l EgretBase,a2 ; get ptr to globals <13>
|
||
bset.b #busy,flags(a2) ; make sure we're marked as busy
|
||
eieioSTP
|
||
|
||
btst.b #SRdir,vACR(a1) ; see if VIA direction is output
|
||
eieioSTP
|
||
beq.s @input ; no, then we're receiving..
|
||
|
||
tst.b vSR(a1) ; clear the shift reg interrupt
|
||
eieioSTP
|
||
tst.w sendHdrCnt(a2) ; any bytes left in header?
|
||
ble.s @ckSendData ; no, see if any send bytes left...
|
||
|
||
movea.l sendHdrPtr(a2),a0 ; get ptr to header
|
||
move.b (a0)+,d0 ; get next header byte
|
||
move.l a0,sendHdrPtr(a2) ; and update header ptr
|
||
bsr SendByte ; send the byte
|
||
subq.w #1,sendHdrCnt(a2) ; count it
|
||
move.w d3,sr ; restore interrupts <SM5><SES>
|
||
bra @exit ; and exit
|
||
@ckSendData
|
||
tst.w sendDataCnt(a2) ; any bytes left in data to send
|
||
ble.s @CmdFinished ; no, then we're finished with command packet
|
||
movea.l sendDataPtr(a2),a0 ; get current data ptr
|
||
move.b (a0)+,d0 ; yes, get next data byte
|
||
move.l a0,sendDataPtr(a2) ; and update the ptr
|
||
bsr SendByte ; send it
|
||
subq.w #1,sendDataCnt(a2) ; count it
|
||
move.w d3,sr ; restore interrupts <SM5><SES>
|
||
bra @exit ; and exit
|
||
@CmdFinished
|
||
eieioSTP
|
||
|
||
bclr.b #SRdir,vACR(a1) ; now switch to input
|
||
@sendCmd
|
||
eieioSTP
|
||
andi.b #~((1<<viaFull) | \ ; negate VIA full bit
|
||
(1<<sysSes)),vBufB(a1) ; negate System Session
|
||
eieioSTP
|
||
bsr.s Delay100 ; give Egret time to see System Session
|
||
move.w d3,sr ; restore interrupts <SM5><SES>
|
||
bra @exit ; and exit
|
||
|
||
@input ;-----------------------------------------------------------------------------
|
||
eieioSTP
|
||
move.b vSR(a1),d0 ; read the byte from shift reg into D0
|
||
eieioSTP
|
||
tst.w rcvHdrCnt(a2) ; any bytes left in response packet header?
|
||
ble.s @ckRcvData ; if not then must be data byte
|
||
|
||
@getHdrByte
|
||
eieioSTP
|
||
btst.b #sysSes,vBufB(a1) ; is System Session asserted?
|
||
eieioSTP
|
||
bne.s @notFirst ; yes, then this is not the first byte
|
||
bsr.s Delay100 ; delay 100us
|
||
bra.s @stuff
|
||
@notFirst
|
||
bsr.s viaFullAck ; acknowlege the byte using via full
|
||
@stuff move.w rcvHdrIndex(a2),d1 ; get index into header
|
||
lea rcvHeader(a2),a0 ; point to header buffer
|
||
move.b d0,(a0,d1.w) ; store byte away
|
||
addq.w #1,rcvHdrIndex(a2) ; bump to next byte
|
||
subq.w #1,rcvHdrCnt(a2) ; count it
|
||
ble.s @CheckError ; <12>
|
||
eieioSTP
|
||
btst.b #xcvrSes,vBufB(a1) ; is Egret done?
|
||
eieioSTP
|
||
bne.s @done ; yes, we're through...
|
||
bset.b #sysSes,vBufB(a1) ; make sure System Session is asserted <5>
|
||
eieioSTP
|
||
bra @exitRd ; not done with header yet... exit
|
||
|
||
@ckRcvData
|
||
movea.l rcvDataPtr(a2),a0 ; get ptr to receive data buffer
|
||
move.b d0,(a0)+ ; store the data byte
|
||
move.l a0,rcvDataPtr(a2) ; and update header ptr
|
||
subq.w #1,rcvDataCnt(a2) ; count it
|
||
bgt.s @ack ; not last, normal acknowlege
|
||
btst.b #openData,flags(a2) ; is this an open ended data packet?
|
||
|
||
eieioSTP
|
||
beq.s @ack ; no, normal acknowlege
|
||
bsr.s viaFullAck ; acknowlege the byte using via full <8>
|
||
eieioSTP
|
||
bclr.b #sysSes,vBufB(a1) ; yes, let Egret know we don't want more <8>
|
||
@wait
|
||
eieioSTP
|
||
btst.b #xcvrSes,vBufB(a1) ; wait for egret to acknowledge termination <8>
|
||
eieioSTP
|
||
beq.s @wait ; branch until xcvr session goes high <8>
|
||
bra.s @done ; and we're done
|
||
|
||
;
|
||
; If we have an error packet in progres then read 5 bytes instead of 4 for the header. <12>
|
||
; A flag will be set on the fourth byte of an error packet and will be cleared <12>
|
||
; after reading the fifth byte of the error packet. <12>
|
||
|
||
@CheckError lea rcvHeader(a2),a0 ; point to header buffer <12>
|
||
cmp.b #ErrorPkt,1(a0) ; check packet type for error packet <12>
|
||
bne.s @CheckDone ; not an error packet go check for data <12>
|
||
|
||
bclr.b #BadPkt,flags(a2) ; check for error packet in progress flag <12>
|
||
bne.s @CheckDone ; we read the fifth byte of the error packet <12>
|
||
@readbyte5 addq.w #1,rcvHdrCnt(a2) ; adjust the count before reading the fifth byte <12>
|
||
bset.b #BadPkt,flags(a2) ; set the flag then read the fifth byte <12>
|
||
bra @exitRd ; <12>
|
||
|
||
;
|
||
; Acknowledge the data byte
|
||
;
|
||
@ack bsr.s viaFullAck ; normal byte, acknowlege it
|
||
@checkDone
|
||
eieioSTP
|
||
btst.b #xcvrSes,vBufB(a1) ; was that Egrets last byte?
|
||
eieioSTP
|
||
bne.s @done ; yes, we're through...
|
||
tst.w rcvDataCnt(a2) ; any receive data bytes to get?
|
||
bgt @exitRd ; yes, then just exit
|
||
|
||
;---------------------------------------------------------------------------
|
||
@done
|
||
eieioSTP
|
||
bclr.b #viaFull,vBufB(a1) ; make sure via full is low
|
||
eieioSTP
|
||
bclr.b #sysSes,vBufB(a1) ; let Egret know we're done
|
||
eieioSTP
|
||
bsr delay100 ; Give Egret time to see transitions & Poll SCC <13>
|
||
|
||
movea.l curPb(a2),a0 ; a0 points to current param block
|
||
lea rcvHeader(a2),a1 ; a1 points to header buffer <11>
|
||
cmp.b #ErrorPkt,1(a1) ; check for Error response packet <11>
|
||
eieioSTP
|
||
bne.s @NotError
|
||
;
|
||
; The current transaction generated an Error <11>
|
||
;
|
||
move.l 1(a1),pbParam(a0) ; Return the Error Response packet to the caller (dont include attn byte) <11>
|
||
move.w #paramErr,pbResult(a0) ; and return a parameter block error <11>
|
||
|
||
@NotError cmpa.l adbPb(a2),a0 ; was this an implicit command?
|
||
beq.s @implicit ; yes, handle autopoll/tick packet
|
||
|
||
tst.b 1(a1) ; is this an ADB response?
|
||
bne.s @ckComp ; no, then data already transfered, call completion
|
||
|
||
@adbResp
|
||
IF rayFix THEN
|
||
cmpa.l adbPb(a2),a0 ; is this autopoll data
|
||
bne.s @skip ; no, don't fix ray's flag
|
||
bset.b #EgAutoPoll,2(a1) ; yes, fix em
|
||
eieioSTP
|
||
@skip
|
||
ENDIF
|
||
|
||
btst.b #EgAutoPoll,2(a1) ; check status, is this AutoPoll data?
|
||
eieioSTP
|
||
bne @ckAutoPollComp ; yes, handle if we have completion routine
|
||
|
||
move.b 2(a1),pbFlags(a0) ; explicit ADB command, stuff flags byte
|
||
move.w rcvHdrIndex(a2),d0 ; get header+data byte count
|
||
subq.w #4,d0 ; - header bytes
|
||
beq.s @dontupdate ; if no data received don't update the byte count <11>
|
||
move.w d0,pbByteCnt(a0) ; stuff data byte count
|
||
@dontupdate move.l pbBufPtr(a0),a2 ; get users buffer ptr
|
||
addq.w #4,a1 ; point at the data
|
||
bra.s @cnt
|
||
@xfer move.b (a1)+,(a2)+ ; copy the byte
|
||
eieioSTP
|
||
@cnt dbra d0,@xfer ; repeat for all bytes
|
||
|
||
move.l EgretBase,a2 ; get globals ptr again
|
||
|
||
@ckComp move.l pbCompletion(a0),d0 ; any completion routine?
|
||
beq @exitNoComp ; no, just exit
|
||
|
||
move.l d0,a1 ; yes, get it's address
|
||
move.l a0,-(sp) ; save param block ptr
|
||
bsr SetResponseParams ; setup globals to handle auto response packets again
|
||
move.w d3,sr ; restore interrupts
|
||
move.l (sp)+,a0 ; restore param block ptr
|
||
jmp (a1) ; and call it
|
||
|
||
|
||
;--------------------------------------------------------------------------------------------
|
||
; AutoPoll or Tick data, push it on stack and call completion rtn
|
||
|
||
@implicit
|
||
tst.b RespPktType(a1) ; is this an ADB response? <SM16>.start
|
||
beq.s @ckAutoPollComp ; yes, handle it
|
||
|
||
cmpi.b #tickPkt,RespPktType(a1) ; is this a short tick response?
|
||
beq.s @ckTickComp ; yes, handle it (has no param block)
|
||
|
||
cmpi.b #PDMPkt,RespPktType(a1) ; is this a PowerDown Message Packet?
|
||
beq.s @ckPowerDownComp ; yes, handle it
|
||
|
||
cmpi.b #pseudoPkt,RespPktType(a1) ; is this a pseudo command?
|
||
bne.s @InvalidPacket ; no, something is wrong
|
||
|
||
cmpi.b #RdTime,RespCmd(a1) ; is this a read time response?
|
||
beq.s @ckTickComp ; yes, handle it
|
||
|
||
@InvalidPacket
|
||
IF EgretDebug THEN ; We have an invalid packet
|
||
|
||
pea @InvPktStr ; call Macsbug
|
||
_DebugStr
|
||
bra.s @exitNoComp ; exit without completion
|
||
|
||
@InvPktStr dc.b $14,'INVALID EGRET Packet' ; Egret error string
|
||
align
|
||
Else
|
||
bra.s @exitNoComp ; exit without completion
|
||
Endif
|
||
|
||
@ckPowerDownComp
|
||
; call service routine if it exists. <SM16>.end
|
||
move.l PDMComp(a2),d2 ; get the completion routine address
|
||
beq.s @exitNoComp ; go away if vector is null
|
||
move.l d2,a3 ; call the Service routine
|
||
move.b RespCmd(a1),d0 ; get the powerDown Switch destination position
|
||
bsr.l SetResponseParams ; setup globals to handle auto response packets again
|
||
move.w d3,sr ; restore interrupts
|
||
jsr (a3)
|
||
bra.s @exit
|
||
|
||
|
||
@ckTickComp ; tick data, check for completion routine
|
||
move.l tickComp(a2),d2 ; get completion routine in d2
|
||
beq.s @exitNoComp ; none specified, just exit
|
||
bra.s @push ; otherwise, push response packet on stack, call it.
|
||
|
||
|
||
@ckAutoPollComp ; ADB autopoll data, check for completion rtn
|
||
IF rayFix THEN
|
||
bset.b #EgAutoPoll,2(a1) ; Set AutoPoll bit to fix bug in old Egret parts
|
||
ENDIF
|
||
tst.l a0 ; do we really have a current param block? (we should)
|
||
beq.s @exitNoComp ; no, exit
|
||
|
||
move.l pbCompletion(a0),d2 ; any completion routine? (keep in d2)
|
||
beq.s @exitNoComp ; no, just exit
|
||
|
||
@push suba.w #12,sp ; allocate 12 byte buffer on stack
|
||
movea.l sp,a2 ; point to the buffer
|
||
move.l (a1)+,(a2)+ ; copy response header onto stack
|
||
move.l (a1)+,(a2)+ ; copy response data onto stack
|
||
move.l (a1)+,(a2)+ ; copy response data onto stack
|
||
movea.l EgretBase,a2 ; restore ptr to globals
|
||
move.w rcvHdrIndex(a2),d0 ; d0 = # bytes in response header
|
||
subq.w #4,d0 ; byte count = # data bytes (strip off header bytes)
|
||
bsr SetResponseParams ; setup globals to handle auto response packets again
|
||
move.w d3,sr ; restore interrupts
|
||
|
||
move.l sp,a1 ; a1 = ptr to response packet
|
||
addq.l #2,a1 ; a1 = ptr to status flag
|
||
move.l d2,a3 ; get completion routine
|
||
jsr (a3) ; call it (a0 points to param block for ADB)
|
||
|
||
adda.w #12,sp ; pop buffer
|
||
bra.s @exit ; and exit
|
||
|
||
@exitNoComp ; no completion routine specified,
|
||
bsr SetResponseParams ; setup globals to handle auto response packets again
|
||
move.w d3,sr ; restore interrupts
|
||
bra.s @exit ; and exit
|
||
|
||
@exitRd
|
||
eieioSTP
|
||
bclr.b #viaFull,vBufB(a1) ; make sure via full is low
|
||
eieioSTP
|
||
move.w d3,sr ; restore interrupts <SM5><SES>
|
||
@exit rts
|
||
|
||
|
||
|
||
|
||
;________________________________________________________________________________________________
|
||
; Routine: SetTransferParams
|
||
;
|
||
; Function: This routine sets up transmit/receive ptrs (globals) for the packet pointed to by A0,
|
||
; for use by the Shift Reg interrupt handler.
|
||
;
|
||
; Inputs: a0 - Param block pointer
|
||
; a2 - Ptr to globals
|
||
;
|
||
; Outputs: none
|
||
; Destroys: d0,d1
|
||
;________________________________________________________________________________________________
|
||
SetTransferParams
|
||
move.l a1,-(sp) ; save a1
|
||
lea pbCmd(a0),a1
|
||
move.l a1,sendHdrPtr(a2) ; point to 1st byte of header to send
|
||
eieioSTP
|
||
moveq #0,d0
|
||
move.b pbCmd(a0),d0 ; get command
|
||
|
||
tst.b pbCmdType(a0) ; is this an ADB command?
|
||
bne.s @pseudo ; no, must be a pseudo command
|
||
|
||
andi.b #%00001111,d0 ; keep low 4 bits
|
||
lea ADBCntTable,a1 ; get ptr to our ADB command table
|
||
bra.s @check ; and look up our send/rcv byte counts
|
||
|
||
;
|
||
; Pseudo Command. Now Check for SEND DFAC and treat as special case if it is. <12>
|
||
; On DFAC, use the byte count in the parameter block as the count to send <12>
|
||
; to Egret instead the count contained in the PseudoCntTable. <12>
|
||
;
|
||
@pseudo
|
||
cmp.b #WrDFAC,pbCmd(a0) ; check for DFAC <12>
|
||
bne.s @notDFAC ; use the table if not DFAC <12>
|
||
|
||
move.w pbByteCnt(a0),d1 ; was Write DFAC use the byte count in the pBlock <12>
|
||
addq.w #1,d1 ; include the packet byte already sent <12>
|
||
move.w d1,sendHdrCnt(a2) ; set up header byte count <12>
|
||
eieioSTP
|
||
move.w #0,sendDataCnt(a2) ; do not send the bytes as data also <12>
|
||
eieioSTP
|
||
clr.w sendDataCnt(a2) ; no extended data bytes <12>
|
||
eieioSTP
|
||
clr.l sendDataPtr(a2) ; no extended data ptr <12>
|
||
eieioSTP
|
||
bra.s @rcvParams
|
||
|
||
@notDFAC lea PseudoCntTable,a1 ; get ptr to our pseudo command table
|
||
@check lsl.w #1,d0 ; x 2 for word table
|
||
move.w (a1,d0.w),d1 ; get send/rcv byte counts for this command
|
||
|
||
ror.w #8,d1 ; get send byte count in low byte
|
||
tst.b d1 ; is this an open-ended send command?
|
||
bmi.s @sendExt ; yes, branch...
|
||
move.b d1,d0 ; get byte count from table
|
||
ext.w d0 ; extend to word
|
||
addq.b #1,d0 ; data bytes + 1 = header byte count
|
||
move.w d0,sendHdrCnt(a2) ; set up header byte count
|
||
eieioSTP
|
||
clr.w sendDataCnt(a2) ; no extended data bytes
|
||
eieioSTP
|
||
clr.l sendDataPtr(a2) ; no extended data ptr
|
||
eieioSTP
|
||
bra.s @rcvParams ; now setup receive ptrs
|
||
|
||
@sendExt moveq #$7F,d0 ; prepare to mask sign
|
||
and.w d1,d0 ; get rid of sign
|
||
addq.w #1,d0 ; + 1 for command (packet type already sent)
|
||
move.w d0,sendHdrCnt(a2) ; set up header byte count
|
||
eieioSTP
|
||
move.w pbByteCnt(a0),sendDataCnt(a2) ; set up data byte count
|
||
eieioSTP
|
||
move.l pbBufPtr(a0),sendDataPtr(a2) ; set up send data ptr
|
||
eieioSTP
|
||
|
||
@rcvParams clr.w rcvHdrIndex(a2) ; reset index into header buffer
|
||
eieioSTP
|
||
move.w #4,rcvHdrCnt(a2) ; 4 byte header default
|
||
eieioSTP
|
||
asr.w #8,d1 ; get receive data byte count
|
||
bmi.s @rcvExt ; branch for open-ended reads
|
||
|
||
tst.b pbCmdType(a0) ; reading, is this a pseudo command?
|
||
beq.s @rcvADB ; no, must be adb data
|
||
|
||
lea pbParam(a0),a1 ; pseudo data will be received in pbParam
|
||
eieioSTP
|
||
move.l a1,rcvDataPtr(a2)
|
||
eieioSTP
|
||
move.w d1,rcvDataCnt(a2) ; get receive count from table
|
||
eieioSTP
|
||
bra.s @exit ; and exit
|
||
|
||
@rcvADB add.w d1,rcvHdrCnt(a2) ; total header bytes = 4 + ADB data
|
||
eieioSTP
|
||
clr.w rcvDataCnt(a2) ; not used
|
||
eieioSTP
|
||
bclr.b #openData,flags(a2) ; this is not an open ended data packet (readPram, read6805)
|
||
bra.s @exit
|
||
|
||
@rcvExt move.w pbByteCnt(a0),rcvDataCnt(a2) ; set up received data byte count
|
||
eieioSTP
|
||
move.l pbBufPtr(a0),rcvDataPtr(a2) ; set up received data buffer ptr
|
||
eieioSTP
|
||
bset.b #openData,flags(a2) ; this is an open ended data packet (readPram, read6805)
|
||
|
||
@exit move.l a0,curPb(a2) ; set up current param block
|
||
eieioSTP
|
||
movea.l (sp)+,a1 ; restore a1
|
||
rts
|
||
|
||
;________________________________________________________________________________________________
|
||
; Routine: SetResponseParams
|
||
;
|
||
; Function: This routine sets up transmit/receive ptrs (globals) for an auto response packet
|
||
; (e.g. ticks, ADB autopoll data), for use by the Shift Reg interrupt handler.
|
||
;
|
||
; Inputs: a2 - Ptr to globals
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Destroys: none
|
||
;________________________________________________________________________________________________
|
||
SetResponseParams
|
||
clr.l sendHdrPtr(a2) ; no command packet params
|
||
clr.w sendHdrCnt(a2) ;
|
||
clr.w sendDataCnt(a2) ;
|
||
clr.l sendDataPtr(a2) ;
|
||
|
||
move.w #12,rcvHdrCnt(a2) ; receive up to 12 response header bytes
|
||
clr.w rcvHdrIndex(a2) ; reset response header index
|
||
clr.w rcvDataCnt(a2) ; no extended data bytes
|
||
clr.l rcvDataPtr(a2) ; no receive data buffer
|
||
move.l adbPb(a2),curPb(a2) ; point to adb's autopoll param block
|
||
|
||
andi.b #~((1<<busy)|\ ; we're not busy now
|
||
(1<<openData)),flags(a2) ; we're not expecting an open ended data packet
|
||
|
||
rts
|
||
|
||
|
||
; <SM4><SES> put back function banner
|
||
;________________________________________________________________________________________________
|
||
; Routine: tickHandler
|
||
;
|
||
; Function: This is the completion routine for tick response packets.
|
||
;
|
||
; Inputs: a2 - ptr to globals
|
||
; (sp) - points to response packet
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Destroys: ???
|
||
;________________________________________________________________________________________________
|
||
; <SM22> FM This patch was rolled in from the PatchIIciRom.a file.
|
||
; <SM22> FM Its purpose is to keep the tim lo-mem up to date at
|
||
; <SM22> FM interrupt time so that the RdDateTime trap can simply
|
||
; <SM22> FM read the Time lo-mem global.
|
||
;----------------------------------------------------------------------------------------------------
|
||
; This patch fixes a bug in Egret Manager TickHandler routine. <89><101>
|
||
; The routine will store the 32 bit time passed by Egret to the
|
||
; system if the packet is a ReadRealTime into TIME lowmen.
|
||
; Decrements the lowmem Time by one to compensate for the interrupt
|
||
; Handler incrementing it by one and then calls the LVL1DT interrupt
|
||
; handler.
|
||
; If the packet is a tick packet then it calls LVL1DT to increment the
|
||
; time setting and check the alarm state.
|
||
;
|
||
; Entry:
|
||
; A1.l = Points at Response data buffer At Flags byte:
|
||
;
|
||
; +---------+----------+---------+---------+---------//-------+
|
||
; | Attn | Pkt Type | Flags | Pkt Cmd | 8 Bytes data Max |
|
||
; +---------+----------+---------+---------+---------//-------+
|
||
;
|
||
; A2.l = Points at Egret Manager Globals
|
||
;
|
||
;----------------------------------------------------------------------------------------------------
|
||
EXPORT TickHandler
|
||
TickHandler
|
||
WITH respPacket,EgretGlobals ; <SM4><SES>
|
||
|
||
subq.l #2,a1 ; <SM22> FM point to the beginning of the Response data buffer
|
||
cmpi.b #TickPkt,respPacket.respType(a1) ; <SM22> FM Check the Packet type
|
||
beq.s @CallLVL1DT ; <SM22> FM If tick packet just call LVL1DT handler
|
||
;
|
||
; The packet was a readTime packet from Egret. Update the Time lowmem and
|
||
; adjust it to compensate for the increment in the LVL1DT handler.
|
||
;
|
||
move.l respPacket.respData(a1),Time ; <SM22> FM write the new time in lowmem TIME
|
||
subq.l #1,Time ; <SM22> FM adjust to compensate for increment in LVL1DT
|
||
;
|
||
; JUMP to routine pointed to by the Contents of LVL1DT
|
||
;
|
||
|
||
@CallLVL1DT
|
||
|
||
move.l VIA,a1 ; point to the VIA
|
||
move.l LVL1DT,a0 ; get vector
|
||
jmp (a0)
|
||
|
||
ENDWITH ; <SM4><SES>
|
||
|
||
|
||
;________________________________________________________________________________________________
|
||
; These tables contain the transmit byte count and receive byte counts for each Egret command,
|
||
; one table for pseudo commands, and one table for ADB commands.
|
||
;
|
||
; tx byte cnt
|
||
; ____________
|
||
; bit 7 = 1 means pbByteCnt = number of data bytes to send after header
|
||
; bit 6-0 = # of pbParam bytes to send (in header)
|
||
;
|
||
; rx byte cnt
|
||
; ____________
|
||
; bit 7 = 1 means open ended read call (e.g. read6805, readPram)
|
||
; bit 6-0 = Pseudo Cmds: # of pbParam bytes to read into (after 4 byte header)
|
||
; bit 6-0 = ADB Cmds: # of data bytes to read into pbBufPtr
|
||
;________________________________________________________________________________________________
|
||
|
||
PseudoCntTable
|
||
dc.b $00, $00 ; 00 NoOperation send 0 bytes, receive 0 data bytes
|
||
dc.b $01, $00 ; 01 StartStopAutopoll send 1 byte, receive 0 data bytes
|
||
dc.b $02, $FF ; 02 Read6805 send 2 bytes, receive n data bytes
|
||
dc.b $00, $04 ; 03 ReadClock send 0 bytes, receive n data bytes
|
||
dc.b $00, $02 ; 04 GetRomSize send 0 bytes, receive 2 data bytes
|
||
dc.b $00, $02 ; 05 GetRomBase send 0 bytes, receive 2 data bytes
|
||
dc.b $00, $02 ; 06 GetRomHeader send 0 bytes, receive 2 data bytes
|
||
dc.b $02, $FF ; 07 ReadPRAM send 2 bytes, receive n data bytes
|
||
dc.b $82, $00 ; 08 Write6805 send 2+n bytes, receive 0 data bytes
|
||
dc.b $04, $00 ; 09 SetClock send 4 bytes, receive 0 data bytes
|
||
dc.b $00, $00 ; 0A PowerDown send 0 bytes, receive 0 data bytes
|
||
dc.b $04, $00 ; 0B SetPowerUp send 4 bytes, receive 0 data bytes
|
||
dc.b $82, $00 ; 0C WritePRAM send 2+n bytes, receive 0 data bytes
|
||
dc.b $01, $00 ; 0D SetResetFlag send 1 bytes, receive 0 data bytes
|
||
dc.b $01, $00 ; 0E SendDFAC send 1 bytes, receive 0 data bytes
|
||
dc.b $00, $02 ; 0F RunDiags send 0 bytes, receive 2 data bytes
|
||
dc.b $00, $01 ; 10 CtrlEnabSense send 0 bytes, receive 1 data bytes
|
||
; 10 BatterySense send 0 bytes, receive 1 data bytes
|
||
dc.b $00, $00 ; 11 Restart send 0 bytes, receive 0 data bytes
|
||
dc.b $01, $00 ; 12 SetVpp send 1 bytes, receive 0 data bytes
|
||
; 12 SetIPL send 1 bytes, receive 0 data bytes
|
||
dc.b $01, $00 ; 13 SetFileServer send 1 bytes, receive 0 data bytes
|
||
dc.b $01, $00 ; 14 SetAutoPoll send 1 bytes, receive 0 data bytes
|
||
dc.b $00, $02 ; 15 GetPramSize send 0 bytes, receive 2 data bytes
|
||
dc.b $00, $01 ; 16 GetAutoPollRate send 0 bytes, receive 1 data bytes
|
||
dc.b $01, $00 ; 17 SetBusDelay send 1 bytes, receive 0 data bytes
|
||
dc.b $00, $01 ; 18 GetBusDelay send 0 bytes, receive 1 data bytes
|
||
dc.b $02, $00 ; 19 SetDevList send 2 bytes, receive 0 data bytes
|
||
dc.b $00, $02 ; 1A GetDevList send 0 bytes, receive 2 data bytes
|
||
dc.b $01, $00 ; 1B SetOneSecMode send 1 bytes, receive 0 data bytes
|
||
dc.b $01, $00 ; 1C SetKbdNMI send 1 bytes, receive 0 data bytes
|
||
dc.b $01, $00 ; 1D SetPostParse send 1 bytes, receive 0 data bytes
|
||
dc.b $01, $00 ; 1E SetHangTime send 1 bytes, receive 0 data bytes
|
||
dc.b $00, $01 ; 1F GetHangTime send 0 bytes, receive 1 data bytes
|
||
dc.b $80, $00 ; 20 SendDefault DFAC send 0-4 bytes, receive 0 data bytes {?} rb
|
||
dc.b $01, $00 ; 21 Enable PDMMessage send 1 bytes, receive 0 data bytes {?} rb
|
||
dc.b $00, $00 ; 22 RdWrIIC send n bytes, receive n data bytes <S2> [rbm]
|
||
dc.b $01, $00 ; 23 Set WakeUpMode send 1 bytes, receive 0 data bytes <T2><SM7> rb
|
||
dc.b $01, $00 ; 24 Tickle PDM Timer send 1 bytes, receive 0 data bytes <T2><SM7> rb
|
||
|
||
|
||
ADBCntTable
|
||
dc.b $00, $00 ; 0000 SendReset send 0 bytes, receive 0 data bytes
|
||
dc.b $00, $00 ; 0001 Flush send 0 bytes, receive 0 data bytes
|
||
dc.b $00, $00 ; 0010 send 0 bytes, receive 0 data bytes
|
||
dc.b $00, $00 ; 0011 send 0 bytes, receive 0 data bytes
|
||
dc.b $00, $00 ; 0100 send 0 bytes, receive 0 data bytes
|
||
dc.b $00, $00 ; 0101 send 0 bytes, receive 0 data bytes
|
||
dc.b $00, $00 ; 0110 send 0 bytes, receive 0 data bytes
|
||
dc.b $00, $00 ; 0111 send 0 bytes, receive 0 data bytes
|
||
dc.b $80, $00 ; 10xx Listen send n bytes, receive 0 data bytes
|
||
dc.b $80, $00 ; 10xx Listen send n bytes, receive 0 data bytes
|
||
dc.b $80, $00 ; 10xx Listen send n bytes, receive 0 data bytes
|
||
dc.b $80, $00 ; 10xx Listen send n bytes, receive 0 data bytes
|
||
dc.b $00, $08 ; 11xx Talk send 0 bytes, receive 8 data bytes max
|
||
dc.b $00, $08 ; 11xx Talk send 0 bytes, receive 8 data bytes max
|
||
dc.b $00, $08 ; 11xx Talk send 0 bytes, receive 8 data bytes max
|
||
dc.b $00, $08 ; 11xx Talk send 0 bytes, receive 8 data bytes max
|
||
|
||
|
||
|
||
EndWith
|
||
|
||
|
||
Eject
|
||
;=========================================================================
|
||
; Routines: EgretInit
|
||
;
|
||
; This routine sends a NOP/WarmStart command to Egret. This routine is
|
||
; called early during rom Startup to stop autopoll and 1 sec irq. Also,
|
||
; the routine will issue a Send DFAC command to Egret to initialize the
|
||
; the DFAC hardware to a known state. The routine does not use ANY
|
||
; memory it is register driven only.
|
||
;
|
||
; NOTE: This routine actually sends a STOP AUTO POLL, SET ONE SECOND
|
||
; INTERRUPT MODE 0 call and a SEND DFAC command to Egret.
|
||
; The Stop Autopoll and set one second interrupt modes calls will
|
||
; be changed to a single NOP/WarmStart when Egret 3 becomes
|
||
; available (S/B 4/6/90).
|
||
;
|
||
; Inputs: NONE
|
||
;
|
||
; Outputs: NONE
|
||
;
|
||
; Destroys: D0, D1, D2, D3, A1, A5, A6, A4 (Egret 2 implementation)
|
||
; Destroys: D0, D3, A1, A5, A6 (Egret 3 implementation)
|
||
;
|
||
; NOTE: This routine is called via a BSR6 and returns via a RTS6
|
||
;-------------------------------------------------------------------------
|
||
EXPORT EgretInit
|
||
|
||
EgretInit movea.l DecoderInfo.VIA1Addr(a0),a1 ; get VIA 1 base address
|
||
eieioSTP
|
||
bclr.b #vSyssesbit,vBufB(a1) ; kill any pending transactions <8> <13>
|
||
eieioSTP
|
||
bclr.b #vViafullbit,vBufB(a1) ; <8> <13>
|
||
eieioSTP
|
||
moveq #$28,d0 ; we want to delay 4 millisecs
|
||
@killtime bsr5 delay100us ; in 100 usec increments
|
||
dbra d0,@killtime
|
||
move.l a6,a4 ; save the return address
|
||
|
||
if rayFix then
|
||
;
|
||
; Send the Stop autopoll pseudo command
|
||
;
|
||
move.l #(APoll << 16) + PseudoPkt,d0 ; first command to send is Stop Auto Poll
|
||
moveq #0,d1 ; sending one byte of data $00 = stop autopoll
|
||
moveq #1,d2
|
||
bsr6 SendEgretCmd ; send the command to Egret
|
||
tst.w d0 ; check for an error
|
||
bne.s @exit ; failed to send the command (hang timeout expired)
|
||
;
|
||
; Send the mode 0 1 second interrupt pseudo command
|
||
;
|
||
move.l #(Wr1SecMode << 16) + PseudoPkt,d0 ; mode 0 1 sec interrupts (stop 1 second irq)
|
||
moveq #0,d1 ; sending one byte of data
|
||
moveq #1,d2
|
||
bsr6 SendEgretCmd ; send the command to Egret
|
||
tst.w d0 ; negative if error
|
||
bne.s @exit ; failed to send the command (hang timeout expired)
|
||
|
||
else
|
||
;
|
||
; Send the NOP/WarmStart command
|
||
;
|
||
move.w #NopCmd,d0 ; Nop/WarmStart stops autopoll and 1 sec irq
|
||
swap d0 ; packet type Pseudo
|
||
move.w #pseudopkt,d0
|
||
moveq #0,d2 ; no data to send
|
||
bsr6 SendEgretCmd ; send the command to Egret
|
||
tst.w d0 ; nonzero if error
|
||
bne.s @exit ; failed to send the command (hang timeout expired)
|
||
|
||
endif
|
||
|
||
;
|
||
; Send Elsie/Erickson initial DFAC setting
|
||
;
|
||
with ProductInfo
|
||
|
||
moveq #0,d2 ; force full scan of hardware features <10>
|
||
bsr6 GetHardwareInfo ; get the ProductInfo Record <9>
|
||
btst.b #v8chipbit,ExtValid+3(a1) ; See if system has a VISA chip (bit7)<9><10>
|
||
beq.s @Erickson ; 0 = No Visa (Erickson) 1 = Visa (Elsie) <9>
|
||
|
||
move.l #ElsieDFAC,d1 ; Assume running on Erickson (Not Elsie) <9>
|
||
bra.s @sendit
|
||
|
||
@Erickson move.l #EricksonDFAC,d1 ; Erickson DFAC setting <9>
|
||
@sendit move.l #(WrDFAC << 16) + PseudoPkt,d0 ; Send DFAC command
|
||
moveq #1,d2 ; One byte to send
|
||
bsr6 SendEgretCmd ; send the command to Egret
|
||
tst.w d0 ; negative if error
|
||
@exit move.l a4,a6 ; restore return address
|
||
rts6 ; return to the caller
|
||
|
||
endwith
|
||
|
||
eject
|
||
************************************************************************************************************
|
||
* SendEgretCmd: This register based routine will send up to four bytes of data to Egret. The
|
||
* packet type, command, byte count and data are passed in registers. The routine
|
||
* will return with d0.w = $0000 if it sent the command successfully. A value of
|
||
* $FFFF signifies that the command did not get through. The system and Egret hung
|
||
* and the system aborted the transaction.
|
||
*
|
||
* WARNING: This routine will not error check the transaction requested. It is the responsibility of
|
||
* WARNING: the caller to make sure that the packet type, command, data and data byte count are valid
|
||
* WARNING: for the transaction requested. Failure to follow the rules will make this routine fail and
|
||
* WARNING: CRASH the system.
|
||
*
|
||
* Input:
|
||
* a0.l Pointer to Base address table
|
||
*
|
||
* d0.l = High word PACKET Command
|
||
* Low word PACKET Type
|
||
*
|
||
* d1.l = Up to four bytes of data to send
|
||
* Long word data byte assigment = byte 4, byte 3, byte 2, byte 1
|
||
* Byte 1 sent out first
|
||
*
|
||
* d2.l = Byte count to send. (0-4 bytes)
|
||
* Byte count > 4 will send four bytes only
|
||
*
|
||
* Output: d0.w $0000 if call succeeded, Nonzero if failed
|
||
*
|
||
* d1.l high word = flags, low word packet type returned by Egret
|
||
*
|
||
* Destroys: D2.l, D3.l, D4.l, A5.l, A4.l, A1.l
|
||
*
|
||
************************************************************************************************************
|
||
|
||
Export SendEgretCmd
|
||
SendEgretCmd
|
||
movea.l DecoderInfo.VIA1Addr(a0),a1 ; get VIA 1 base address <P2> <SM7> rb, start
|
||
move.l #((MaxTout<<16) OR MaxRetries),d4 ; number of retries before giving up with Egret <13>
|
||
bsr5 Delay100us
|
||
eieioSTP
|
||
btst.b #vsysSesBit,vBufB(a1) ; check for a transaction in progress
|
||
eieioSTP
|
||
beq.s @AllOK
|
||
|
||
@Timeout
|
||
eieioSTP
|
||
bclr.b #vsysSesBit,vBufB(a1) ; kill the rest of the transaction <8>
|
||
eieioSTP
|
||
bclr.b #vViaFullBit,vBufB(a1) ; <8>
|
||
eieioSTP
|
||
bsr5 Delay100us ; in progretss <8>
|
||
bsr5 Delay100us ; <8>
|
||
|
||
@AllOK swap.w d4 ; timeout in low word of d4 Retry count in high word <13>
|
||
eieioSTP
|
||
btst.b #vxcvrSesBit,vBufB(a1) ; check for abort pending
|
||
eieioSTP
|
||
beq IrqMissed ; MIssed Vsr Irq because of INITVIAS
|
||
bset #vsysSesBit,vBufB(a1) ; assert sysSesBit
|
||
eieioSTP
|
||
bsr5 @SendPtype ; send the packet type
|
||
beq RealAbort ; Discard Aborting transaction <SM7> rb, end
|
||
;
|
||
; If not abort transaction in progress then send the command byte
|
||
;
|
||
swap d0
|
||
bsr5 sendByte1 ; send the command byte
|
||
bsr5 delay100us ; give Egret time to see viaEmpty
|
||
;
|
||
; Now send number of bytes contained in d1 based on
|
||
; byte count contained in d2.w
|
||
;
|
||
move.l d1,d0 ; get the data to send
|
||
subq #1,d2 ; adjust for DBRA
|
||
cmp.w #3,d2 ; if count out of range quit
|
||
bhi.s @EndCmd ; if count valid then adjust for dbra
|
||
@sendloop bsr5 sendByte1
|
||
bsr5 delay100us
|
||
lsr.l #8,d0 ; move data byte to low byte of register
|
||
@loopEntry dbra d2,@sendloop ; decrement byte count
|
||
;
|
||
; Wait for the response packet header
|
||
;
|
||
@EndCmd
|
||
eieioSTP
|
||
bclr.b #SRdir,vACR(a1) ; shift in
|
||
eieioSTP
|
||
bclr.b #vSyssesbit,vBufB(a1) ; negate vSyssesbit
|
||
eieioSTP
|
||
bsr5 Delay100us
|
||
;
|
||
; Now receive the Standard Response packet Header
|
||
;
|
||
bsr5 readAttn ; get the Attention byte
|
||
eieioSTP
|
||
bsr5 Delay100us
|
||
eieioSTP
|
||
bset.b #vSyssesbit,vBufB(a1) ; assert vSyssesbit
|
||
eieioSTP
|
||
bsr5 readByte ; get the packet type
|
||
and #$00FF,d0 ; keep low byte only
|
||
swap d0 ; save the packet type
|
||
bsr5 readByte ; get the flags byte
|
||
and.w #$00FF,d0 ; keep low byte only
|
||
swap d0 ; keep the flags byte as an error code
|
||
exg d0,d1 ; save the packet type and flags returned
|
||
bsr5 readByte ; get the command
|
||
eieioSTP
|
||
bclr.b #vSyssesbit,vBufB(a1) ; negate vSyssesbit
|
||
eieioSTP
|
||
bsr5 Delay100us
|
||
;
|
||
; Check for an error packet returned by Egret
|
||
;
|
||
move.l d1,d0 ; save the packet type and flags
|
||
cmp.b #errorpkt,d0 ; check for error packet
|
||
beq.s @Exit ; error pkt then just exit
|
||
sub.w d0,d0 ; zero for success
|
||
@exit rts6
|
||
|
||
;--------------------------------------------------------------------------
|
||
@SendPtype ; <2>
|
||
eieioSTP
|
||
bset.b #SRdir,vACR(a1) ; shift out
|
||
eieioSTP
|
||
btst.b #vXcvrsesbit,vbufB(a1) ; check for abort
|
||
eieioSTP
|
||
beq.s @AbortReq ; go away if abort requested
|
||
move.b d0,vSR(a1) ; load byte into shift reg
|
||
eieioSTP
|
||
bset.b #vViafullbit,vBufB(a1) ; indicate shift reg is full
|
||
eieioSTP
|
||
;
|
||
; Check Vsr Irq until timeout. If timeout then check the retry count
|
||
; and Call Death Chimes if Retry count exausted.
|
||
;
|
||
@PollDelay
|
||
eieioSTP
|
||
btst.b #ifSR,vIFR(a1) ; wait for shift to complete
|
||
eieioSTP
|
||
bne.s @VsrIrq ; Go service Shift register Irq <13>
|
||
dbra.w d4,@PollDelay ; try again if timed out <13><SM7> rb
|
||
move.w #MaxTout,d4 ; Reset the Timeout <13><SM7> rb
|
||
swap.w d4 ; get the Retry count <13><SM7> rb
|
||
subq.w #1,d4 ; Try again if Retry count not Exausted <13><SM7> rb
|
||
beq.s @Timeout ; <13>
|
||
|
||
@DeadEgret move.w #ErrEgretInit,d7 ; Egret failed <13>
|
||
move.l #0001,d6 ; d6.l must be nonzero <13>
|
||
bigjmp Error1Handler,a3 ; Play death chimes <13>
|
||
|
||
@VsrIrq
|
||
eieioSTP
|
||
tst.b vSR(a1) ; clear the interrupt
|
||
eieioSTP
|
||
bclr.b #vViafullbit,vBufB(a1) ; now indicate shift reg empty
|
||
eieioSTP
|
||
;
|
||
; Delay 100 usec
|
||
;
|
||
move.w #DelayCnt,d3
|
||
@wait20
|
||
eieioSTP
|
||
tst.b (a1) ; sync to VIA clock
|
||
eieioSTP
|
||
dbra d3,@wait20 ; delay at least 100 us (very rough)
|
||
eieioSTP
|
||
btst.b #vXcvrsesbit,vbufB(a1) ; check for abort
|
||
eieioSTP
|
||
@AbortReq rts5
|
||
|
||
;--------------------------------------------------------------------------
|
||
; DumpAbort This routine will read all the data for an abort transaction and
|
||
; discard it. When done it will jump back to SendNopCmd entry point
|
||
; to retry our command. This command will eventually complete...
|
||
|
||
RealAbort
|
||
eieioSTP
|
||
bclr.b #vSyssesbit,vBufB(a1) ; deassert system session
|
||
eieioSTP
|
||
IrqMissed bsr5 Delay100us ; Let Egret see SysSes. ³ 125µsec
|
||
eieioSTP
|
||
bclr.b #SRdir,vACR(a1) ; shift in
|
||
eieioSTP
|
||
tst.b vSR(a1) ; discard the byte
|
||
eieioSTP
|
||
bset #vSyssesbit,vBufB(a1) ; assert vSyssesbit
|
||
eieioSTP
|
||
|
||
DumpAbort
|
||
|
||
eieioSTP
|
||
bclr #vViafullbit,vBufB(a1) ; then negate VIA full bit
|
||
eieioSTP
|
||
|
||
@loop
|
||
eieioSTP
|
||
btst.b #ifSR,vIFR(a1) ; wait for shift to complete
|
||
eieioSTP
|
||
beq.s @loop
|
||
bset.b #vViafullbit,vBufB(a1) ; acknowlege byte
|
||
eieioSTP
|
||
tst.b vSR(a1) ; discard the byte
|
||
eieioSTP
|
||
;
|
||
; Delay 100 usec
|
||
;
|
||
move.w #DelayCnt,d3 |