/*
ADBEMDEV.c
Copyright (C) 2008 Paul C. Pratt
You can redistribute this file and/or modify it under the terms
of version 2 of the GNU General Public License as published by
the Free Software Foundation. You should have received a copy
of the license along with this file; see the file COPYING.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
license for more details.
*//*
Apple Desktop Bus EMulated DEVice
*/#ifndef AllFiles#include"SYSDEPNS.h"#include"MYOSGLUE.h"#include"EMCONFIG.h"#include"GLOBGLUE.h"#endif#include"ADBEMDEV.h"#ifdef _VIA_Debug#include<stdio.h>#endif/*
ReportAbnormalID unused 0x0C06 - 0x0CFF
*/IMPORTPROCADB_ShiftOutData(ui3bv);IMPORTFUNCui3bADB_ShiftInData(void);#include"ADBSHARE.h"LOCALVARblnrADB_ListenDatBuf;LOCALVARui3bADB_IndexDatBuf;GLOBALPROCADB_DoNewState(void){ui3bstate=ADB_st1*2+ADB_st0;#ifdef _VIA_Debugfprintf(stderr,"ADB_DoNewState: %d\n",state);#endif{ADB_Int=1;switch(state){case0:/* Start a new command */if(ADB_ListenDatBuf){ADB_ListenDatBuf=falseblnr;ADB_SzDatBuf=ADB_IndexDatBuf;ADB_EndListen();}ADB_TalkDatBuf=falseblnr;ADB_IndexDatBuf=0;ADB_CurCmd=ADB_ShiftInData();/* which sets interrupt, acknowleding command */#ifdef _VIA_Debugfprintf(stderr,"in: %d\n",ADB_CurCmd);#endifswitch((ADB_CurCmd>>2)&3){case0:/* reserved */switch(ADB_CurCmd&3){case0:/* Send Reset */ADB_DoReset();break;case1:/* Flush */ADB_Flush();break;case2:/* reserved */case3:/* reserved */ReportAbnormalID(0x0C01,"Reserved ADB command");break;}break;case1:/* reserved */ReportAbnormalID(0x0C02,"Reserved ADB command");break;case2:/* listen */ADB_ListenDatBuf=trueblnr;#ifdef _VIA_Debugfprintf(stderr,"*** listening\n");#endifbreak;case3:/* talk */ADB_DoTalk();break;}break;case1:/* Transfer date byte (even) */case2:/* Transfer date byte (odd) */if(!ADB_ListenDatBuf){/*
will get here even if no pending talk data,
when there is pending event from device
other than the one polled by the last talk
command. this probably indicates a bug.
*/if((!ADB_TalkDatBuf)||(ADB_IndexDatBuf>=ADB_SzDatBuf)){ADB_ShiftOutData(0xFF);ADB_Data=1;ADB_Int=0;}else{#ifdef _VIA_Debugfprintf(stderr,"*** talk one\n");#endifADB_ShiftOutData(ADB_DatBuf[ADB_IndexDatBuf]);ADB_Data=1;ADB_IndexDatBuf+=1;}}else{if(ADB_IndexDatBuf>=ADB_MaxSzDatBuf){ReportAbnormalID(0x0C03,"ADB listen too much");/* ADB_MaxSzDatBuf isn't big enough */(void)ADB_ShiftInData();}else{#ifdef _VIA_Debugfprintf(stderr,"*** listen one\n");#endifADB_DatBuf[ADB_IndexDatBuf]=ADB_ShiftInData();ADB_IndexDatBuf+=1;}}break;case3:/* idle */if(ADB_ListenDatBuf){ReportAbnormalID(0x0C04,"ADB idle follows listen");/* apparently doesn't happen */}if(ADB_TalkDatBuf){if(ADB_IndexDatBuf!=0){ReportAbnormalID(0x0C05,"idle when not done talking");}ADB_ShiftOutData(0xFF);/* ADB_Int = 0; */}elseif(CheckForADBanyEvt()){if(((ADB_CurCmd>>2)&3)==3){ADB_DoTalk();}ADB_ShiftOutData(0xFF);/* ADB_Int = 0; */}break;}}}GLOBALPROCADBstate_ChangeNtfy(void){#ifdef _VIA_Debugfprintf(stderr,"ADBstate_ChangeNtfy: %d, %d, %d\n",ADB_st1,ADB_st0,GetCuriCount());#endifICT_add(kICT_ADB_NewState,348160UL*kCycleScale/64*kMyClockMult);/*
Macintosh Family Hardware Reference say device "must res