; ; 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): ; ; 11/9/93 KW added some eieioSTP macros. Only expands for CygnusX1 ROM. ; 9/29/93 SAM From mc900ftjesus. ; 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 . ; 9/23/93 PN Add condition for Egret ; 7/12/93 kc Re-roll in ShiftRegIRQPatch to fix Quadra 900-950 ReadTime bug. ; 12/1/92 RB Turned off the debug feature in Egret. ; 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. ; 11/3/92 SWC Changed ShutdownEqu.a->Shutdown.a. ; 10/02/92 AEK Conditionalize call to InitReliabitity to keep it from being ; called twice if not on an overpatched ROM ; ; 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. ; 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). ; ; 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 ; 5/24/92 RB Removing "patches" as they get rolled into the other ; sources...PowerSwitchIntPatch is out. ; 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: ; 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: 2/10/92 GS Exported the PseudoTable for use by ; the CudaMgr.a code. Cleaned up some comments. 02/07/92 jmp ; Added some padding so that Pandora matches Horror. 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. ; 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: ; 4/24/92 KW (SWC,H5) Moved ADB and DebugUtil routines to ADBPrimitives.a. ; 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. ; 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. ; 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. ; 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. ; 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. ; 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. ; 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. ; 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). ; 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) ; ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ ;

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). ; ; 5/17/92 kc Roll in Horror sources. (prepend via equates with v) ; 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. ; 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. ; 5/4/92 FM fix typo ; 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 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 rb move.l a0,adbPb(a2) ; store in adb parameter block 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< rb bne.s @ckPDMInit ; check for Eclipse PowerDown Message Initialization rb move.l a0,ADBpb(a2) ; yes, is to set the ADB param block (for autopoll data). rb bra @done ; rb @ckPDMInit ; rb ; ; Check for Eclipse PowerDown Message Vector ; Initialization. ; cmpi.b #PDMVectPkt,pbCmdType(a0) ; check for PowerDown message vector Init <60> rb rb bne.s @EgretRestart ; Must be Egret Command <60> rb rb move.l pbParam(a0),PDMComp(a2) ; handler for Eclipse PowerDown Message Packet <60> rb 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 ; 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 ; 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 @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 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 bra @exit ; and exit @CmdFinished eieioSTP bclr.b #SRdir,vACR(a1) ; now switch to input nop @sendCmd eieioSTP andi.b #~((1< 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? .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. .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 @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< 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: ??? ;________________________________________________________________________________________________ ; FM This patch was rolled in from the PatchIIciRom.a file. ; FM Its purpose is to keep the tim lo-mem up to date at ; FM interrupt time so that the RdDateTime trap can simply ; 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 ; subq.l #2,a1 ; FM point to the beginning of the Response data buffer cmpi.b #TickPkt,respPacket.respType(a1) ; FM Check the Packet type beq.s @CallLVL1DT ; 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 ; FM write the new time in lowmem TIME subq.l #1,Time ; 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 ; ;________________________________________________________________________________________________ ; 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 [rbm] dc.b $01, $00 ; 23 Set WakeUpMode send 1 bytes, receive 0 data bytes rb dc.b $01, $00 ; 24 Tickle PDM Timer send 1 bytes, receive 0 data bytes 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 ; ; 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 ; 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< ; 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< clr.l pbParam(a0) ; clr parameter blk move.b #PDMSuspend,pbParam(a0) ; PDM Continue clr.l pbCompletion(a0) ; No Completion ; _EgretDispatch 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 ;₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯ 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 clr.l pbParam(a0) ; clr parameter blk move.b #PDMDebugCont,pbParam(a0) ; Macsbug Continue gjs clr.l pbCompletion(a0) ; No Completion _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 gjs rts ENDP END