mac-rom/OS/EgretMgr.a

1542 lines
58 KiB
Plaintext
Raw Normal View History

;
; 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: <09> 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...
; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; Pre-Pandora ROM comments begin here.
; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; <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.
; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; Pre-Pandora ROM comments begin here. (EgretPatchesToo)
; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; <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<73> 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<6F>t include SysErr.a since it<69>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 (<28>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 9bb0
;
; 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
move.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
nop
eieioSTP
move.b #(1<<ifIRQ)|\
(1<<ifSR),vIER(a1) ; enable shift register interrupts
nop
eieioSTP
move.w (sp)+,sr ; restore interrupts
bsr NewEgretFunc
rts
;________________________________________________________________________________________________
; Routine: EgretDispatch 9bfa
;
; 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)
nop
eieioSTP
bset.b #SRdir,vACR(a1) ; switch to output
nop
eieioSTP
move.b pbCmdType(a0),vSR(a1) ; send command packet to shift reg
nop
eieioSTP
bset.b #viaFull,vBufB(a1) ; tell Egret we sent it
nop
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-d3/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-d3/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
nop
eieioSTP
bclr.b #sysSes,vBufB(a1) ; ack the abort
nop
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
; 9ce2
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
; 9d26
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
; 9d3a
eieioSTP
bclr.b #viaFull,vBufB(a1) ; negate via full
nop
eieioSTP
bsr.s Delay100 ; give Egret time to see it
eieioSTP
move.b d0,vSR(a1) ; send the byte to the shift reg
nop
eieioSTP
bset.b #viaFull,vBufB(a1) ; let Egret know it's there
nop
eieioSTP
rts
;________________________________________________________________________________________________
CallShiftRegIRQ
; 9d50
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
; 9d60
eieioSTP
bset.b #viaFull,vBufB(a1) ; acknowlege the byte
nop
eieioSTP
bsr.s Delay100 ; give Egret time to see it
eieioSTP
rts ; gets cleared on exit from IRQ handler
;________________________________________________________________________________________________
NewDelay100
; 9d6a
tst.l $13e
beq.s Delay100
btst.b #0, $bfe
beq.s Delay100
MoveM.L D0-D3/A0-A4/A6, -(SP)
Move.L SP, (PollStack)
MoveA.L (SCCRd), A3
Move (TimeSCCDB), D1
LsR #$3, D1
BTst.B #$0, $2(A3)
BEQ.B (* + $6)
Move.B $6(A3), -(SP)
DBF D1, (* + -$C)
Nop
CmpA.L (PollStack), SP
BEQ.B (* + $C)
Lea.L $6(A3), A6
Jsr ([$13E])
MoveM.L (SP)+, D0-D3/A0-A4/A6
Rts
Delay100
; 9db2
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 9dc8
;
; 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
nop
eieioSTP
beq.s @input ; no, then we're receiving..
tst.b vSR(a1) ; clear the shift reg interrupt
nop
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
nop
@sendCmd
eieioSTP
andi.b #~((1<<viaFull) | \ ; negate VIA full bit
(1<<sysSes)),vBufB(a1) ; negate System Session
nop
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
nop
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>
nop
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>
nop
@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
nop
eieioSTP
bclr.b #sysSes,vBufB(a1) ; let Egret know we're done
nop
eieioSTP
bsr newdelay100 ; 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
nop
eieioSTP
move.w d3,sr ; restore interrupts <SM5><SES>
@exit rts
;________________________________________________________________________________________________
; Routine: SetTransferParams 9fee
;
; 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 a0ac
;
; 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 a0da
;
; 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
; a0f8
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
dc.b $00, $00
dc.b $01, $00
ADBCntTable
; a142
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
;--------------------------------------------------------------------------
;ChkFirmware a166 <P2>
;
; This routine will determine if the Egret Chip is using Egret 8 or Caboose
; firmware or the new Cuda firmware. Based on this result, the IRQ handler,
; Dispatcher, and Tick handler vectors are set up...
; Inputs:
; A2 -> EgretGlobals
; Outputs:
; A0 -> ShiftRegIRQ
; A1 -> TickHandler
; Trashes:
; A0,A1
ChkFirmware ; <P2>
movem.l a2/d0-d2, -(sp) ; preserve used regs
@haveCuda ;
biglea CudaDispatch, a0 ; Cuda FW dispatcher
move.l #$92,d0 ; set $92 trap
_SetTrapAddress ,NEWOS
biglea CudaShiftRegIRQ,a0 ; stuff Cuda IRQ handler in
biglea CudaTickHandler,a1 ; stuff Cuda tick handler in
@chkDone
movem.l (sp)+, a2/d0-d2 ; restore used regs
rts
NewEgretFunc
; a196
Link A6, #-$14
Move.L #$7000000, D0
And.L (UnivROMFlags), D0
CmpI.L #$3000000, D0
BNE.B (* + $42)
MoveA.L A7, A0
Move.B #$1, (A0)
Move.B #$2, $1(A0)
Clr.L $2(A0)
Move #$A1, $2(A0)
Move #$1, $6(A0)
Lea.L $4(A0), A1
Move.L A1, $8(A0)
Clr $C(A0)
Clr $E(A0)
Clr.L $10(A0)
_EgretDispatch
Move.B #$8, $1(A0)
BClr.B #$5, $4(A0)
_EgretDispatch
Unlk A6
Rts
Tst.L D3
BMI.B (* + $44)
BSet.B #$2, $15E(A3)
BNE.B (* + $4C)
Move.B D3, $171(A3)
Move D2, $176(A3)
Move.L A2, $178(A3)
BSet.B #$0, $15E(A3)
BNE.B (* + $1C)
Lea.L @ExplicitCompleted, A0
Move.L A0, $180(A3)
Lea.L $184(A3), A0
Clr.L $10(A0)
Bsr.B (* + $E)
Move.L #$1010000, D0
Bsr.B (* + $40)
Lea.L $170(A3), A0
MoveQ.L #$0, D1
MoveA.L ($648), A2
Jmp (A2)
BTst.B #$5, $15D(A3)
BNE.B (* + $A)
BSet.B #$1, $15E(A3)
BEQ.B (* + $4)
Rts
Lea.L $184(A3), A0
Lea.L (* + $9A), A1
Move.L A1, $10(A0)
Bsr.B (* + -$26)
Move.L #$1190000, D0
Move $14E(A3), D0
Bsr.B (* + $8)
Move.L #$101FF00, D0
SubA #$14, A7
MoveA.L A7, A0
Move.L D0, (A0)
Clr.L $10(A0)
Bsr.B (* + -$46)
Lea.L $14(A7), A7
Rts
;_______________________________________________________________________
;
; Routine: @ExplicitCompleted a27c
; Inputs: A0 - Pointer to the EgretPB of the Explicit Request
;
; Outputs: D2 - length of receive buffer data
; D3 - command byte / SRQ flag (bit 31)
; A2 - pointer to buffer containing receive data
; A3 - pointer to ADBBase
;
; Calls: exits through ImplicitRequestDone / ExplicitRequestDone
; Called by: Egret Manager, Asynchronous request completion routine
;
; Function: Completion routine for servicing explicit ADB requests.
;
;_______________________________________________________________________
with ADBVars,EgretPB
import ExplicitRequestDone, ImplicitRequestDone
@ExplicitCompleted ; A0 := pointer to EgretPB
if EgretDebug then
btst.b #EgAutoPoll,pbFlags(a0) ; see if this was from auto poll
beq.s @ExplicitOK ; if not, we're still OK
_Debugger ; something is wrong with this picture
@ExplicitOK
endif
moveq.l #(1<<EgSRQ),d3 ; mask to test for SRQ pending
and.b pbFlags(a0),d3 ; isolate the SRQ flag
neg.l d3 ; set bit 31 if SRQ pending
move.b pbCmd(a0),d3 ; get the ADB command byte
moveq #0,d2 ; zero extend the length
move.w pbByteCnt(a0),d2 ; get the length
movea.l pbBufPtr(a0),a2 ; get the buffer pointer
bsr.s @FillInVars ; setup A3, and ADB globals for ADB Parser
bclr.b #fDBExpRunning,fDBAuFlag(a3) ; explicit command completed, allow new ones
;
; For Egret must check the ADB Device address against the Device Bitmap <5>
; to see if the device exists. If it does not, force Egret to Poll the Mouse
; as the MRU device and Keyboard as the LRU device. (Bug Fix for Egret)
;
; Entry: a3.l = ADB Globals
; d0.b = ADB device address
move.w devmap(a3),d1 ; get the ADB device Bitmap
btst.l d0,d1 ; check bit position in low word
bne.s @exit ; Device Exits
;------------------------------------------------------------------------------
; Force the MRU & LRU values to Mouse & Keyboard to work around bug where Egret
; AutoPolls devices which are not in the DevMap.
;
; Entry: NONE
;
; Exit: NONE
;
; Destroys: NONE
;
;------------------------------------------------------------------------------
suba.l #EgretPbSize,sp ; make room for Egret Manager PB
movea.l sp,a0
move.l #0,pbCompletion(a0) ; no Completion vector
move.w #((pseudoPkt << 8) + \
Wr6805addr),pbCmdType(a0) ; packet type & command
move.w #((MouseAddr * $1000) + \ ; Mouse & Keyboard into MRU & LRU
(KbdAddr * $10)),-(sp) ; Mouse Addr in bits C-F, Kbd Addr bits 4-7
move.l sp,pbBufPtr(a0) ; buffer pointer in PB
move.w #MRUAddr,pbParam(a0) ; Egret address to write
move.w #2,pbByteCnt(a0) ; 2 bytes to write
_EgretDispatch ; issue the call
adda.l #EgretPbSize+2,sp ; Discard Buffer & Parameter block <5>
@exit
bigjmp ExplicitRequestDone,a0 ; Return control to the ADB Manager
@FillInVars movea.l ADBBase,a3 ; point to ADB globals in low memory
; keep the ADB Parser program happy by updating the following variables
; They are not used by this implementation, but we fill them in with approximate
; values to make the tool happy.
move.b d3,fDBCmd(a3) ; last ADB command
move.b d3,pollCmd(a3) ; assume that it was a poll command
move.b d3,d0 ; copy the command
lsr.b #4,d0 ; get the address
move.b d0,pollAddr(a3) ; assume that it was a poll address
rts ; all done
Title 'KbdADB - ADB Manager - ImplicitCompleted'
;_______________________________________________________________________
;
; Routine: @ImplicitCompleted a2ec
; Inputs: A0 - Pointer to the EgretPB of the Implicit Request
; D0 - Number of data bytes returned (word, 0..8)
; A1 - Pointer to Flags, Command, Data Buffer
;
; Outputs: D2 - length of receive buffer data
; D3 - command byte / SRQ flag (bit 31)
; A2 - pointer to buffer containing receive data
; A3 - pointer to ADBBase
;
; Calls: exits through ImplicitRequestDone / ExplicitRequestDone
; Called by: Egret Manager, Asynchronous request completion routine
;
; Function: Completion routine for servicing explicit ADB requests.
;
;_______________________________________________________________________
@ImplicitCompleted
if EgretDebug then
btst.b #EgAutoPoll,(a1) ; see if this was from auto poll
bne.s @ImplicitOK ; if so, we're still OK
_Debugger ; something is wrong with this picture
@ImplicitOK
endif
moveq.l #(1<<EgSRQ),d3 ; mask to test for SRQ pending
and.b (a1)+,d3 ; isolate the SRQ flag
neg.l d3 ; set bit 31 if SRQ pending
move.b (a1)+,d3 ; get the ADB command byte
moveq #0,d2 ; zero extend the length
move.w d0,d2 ; get the length
movea.l a1,a2 ; get the buffer pointer
bsr.s @FillInVars ; setup A3, and ADB globals for ADB Parser
bigjmp ImplicitRequestDone,a0 ; Return control to the ADB Manager
endwith
Export DebugEnterCont
DebugEnterCont
a2fc
with ProductInfo
move.l UnivRomFlags,d0 ; get the Universal system flags
andi.l #ADBMask,d0 ; we want ADB
cmpi.l #ADBEgret,d0 ; and specifically EGRET version of ADB
bne.s @EgretDone
endwith
;
; Build a Egret Parameter block to stop 1 second interrupts
;
WITH EgretPb
move.l a0,-(sp) ; work registers
suba.l #EgretPB.EgretPbSize,sp ; room for parameter block
move.l sp,a0 ; point to the parameter block
move.w #(EgretPB.EgretPBSize/2)-1,d0 ; clear the PB area a word at a time
move.l a0,-(sp) ; save pointer to parameter block
@Loop move.w #0,(a0)+ ; zeros forces mode 0 & no Completion vector
dbra d0,@Loop
move.l (sp)+,a0 ; restore parameter block pointer
move.w #((pseudoPkt << 8) + Wr1SecMode),EgretPB.pbCmdType(a0) ; Packet type & command
_EgretDispatch
;
; Suspend the PDM, with out reseting vars within Cuda
;
move.w #(PseudoPkt << 8) \
+ EnDisPDM,pbCmdType(a0); Enable PowerDown Messages <P3>
clr.l pbParam(a0) ; clr parameter blk <P3>
move.b #PDMSuspend,pbParam(a0) ; PDM Continue <P3>
clr.l pbCompletion(a0) ; No Completion <P3>
; _EgretDispatch <SM11> gjs
adda.l #EgretPB.EgretPbSize,sp ; discard parameter block
move.l (sp)+,a0 ; restore work registers
ENDWITH
@EgretDone
moveq.l #noErr,d0 ; return with success
rts
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Export DebugExitCont
DebugExitCont
; a346
with ProductInfo
move.l UnivRomFlags,d0 ; get the Universal system flags
andi.l #ADBMask,d0 ; we want ADB
cmpi.l #ADBEgret,d0 ; and specifically EGRET version of ADB
bne.s @EgretDone
endwith
;
; Build a Egret Parameter block to start 1 second interrupts (Mode 3)
;
WITH EgretPB
move.l a0,-(sp) ; work registers
suba.l #EgretPB.EgretPbSize,sp ; room for parameter block
move.l sp,a0 ; point to the parameter block
move.w #(EgretPB.EgretPBSize/2)-1,d0 ; clear the PB area a word at a time
move.l a0,-(sp) ; save pointer to parameter block
@Loop move.w #0,(a0)+ ; zeros forces mode 0 & no Completion vector
dbra d0,@Loop
move.l (sp)+,a0 ; restore parameter block pointer
move.w #((pseudoPkt << 8) + Wr1SecMode),EgretPB.pbCmdType(a0) ; Packet type & command
move.b #Mode3Clock,EgretPB.pbParam(a0) ; Turn on Mode 3 clock data packets
_EgretDispatch
;
; Macsbug Continue the PDM
;
move.w #(PseudoPkt << 8) \
+ EnDisPDM,pbCmdType(a0); Enable PowerDown Messages <P3>
clr.l pbParam(a0) ; clr parameter blk <P3>
move.b #PDMDebugCont,pbParam(a0) ; Macsbug Continue <SM11> gjs <P3>
clr.l pbCompletion(a0) ; No Completion <P3>
_EgretDispatch
adda.l #EgretPB.EgretPbSize,sp ; discard parameter block
move.l (sp)+,a0 ; restore work registers
@EgretDone
ENDWITH
moveq.l #noErr,d0 ; return with success
CLR.B DSWndUpdate ; flag GNE to remove the alert . . . just in case <SM11> gjs
rts
ENDP
END