this repo has no description
at main 213 lines 5.2 kB view raw
1/* 2 ADBEMDEV.c 3 4 Copyright (C) 2008 Paul C. Pratt 5 6 You can redistribute this file and/or modify it under the terms 7 of version 2 of the GNU General Public License as published by 8 the Free Software Foundation. You should have received a copy 9 of the license along with this file; see the file COPYING. 10 11 This file is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 license for more details. 15*/ 16 17/* 18 Apple Desktop Bus EMulated DEVice 19*/ 20 21#include "PICOMMON.h" 22 23#if EmADB 24 25#include "ADBEMDEV.h" 26 27#ifdef _VIA_Debug 28#include <stdio.h> 29#endif 30 31/* 32 ReportAbnormalID unused 0x0C06 - 0x0CFF 33*/ 34 35IMPORTPROC ADB_ShiftOutData(ui3b v); 36IMPORTFUNC ui3b ADB_ShiftInData(void); 37 38#include "ADBSHARE.h" 39 40LOCALVAR blnr ADB_ListenDatBuf; 41LOCALVAR ui3b ADB_IndexDatBuf; 42 43GLOBALPROC ADB_DoNewState(void) 44{ 45 ui3b state = ADB_st1 * 2 + ADB_st0; 46#ifdef _VIA_Debug 47 fprintf(stderr, "ADB_DoNewState: %d\n", state); 48#endif 49 { 50 ADB_Int = 1; 51 switch (state) { 52 case 0: /* Start a new command */ 53 if (ADB_ListenDatBuf) { 54 ADB_ListenDatBuf = falseblnr; 55 ADB_SzDatBuf = ADB_IndexDatBuf; 56 ADB_EndListen(); 57 } 58 ADB_TalkDatBuf = falseblnr; 59 ADB_IndexDatBuf = 0; 60 ADB_CurCmd = ADB_ShiftInData(); 61 /* which sets interrupt, acknowleding command */ 62#ifdef _VIA_Debug 63 fprintf(stderr, "in: %d\n", ADB_CurCmd); 64#endif 65 switch ((ADB_CurCmd >> 2) & 3) { 66 case 0: /* reserved */ 67 switch (ADB_CurCmd & 3) { 68 case 0: /* Send Reset */ 69 ADB_DoReset(); 70 break; 71 case 1: /* Flush */ 72 ADB_Flush(); 73 break; 74 case 2: /* reserved */ 75 case 3: /* reserved */ 76 ReportAbnormalID(0x0C01, 77 "Reserved ADB command"); 78 break; 79 } 80 break; 81 case 1: /* reserved */ 82 ReportAbnormalID(0x0C02, 83 "Reserved ADB command"); 84 break; 85 case 2: /* listen */ 86 ADB_ListenDatBuf = trueblnr; 87#ifdef _VIA_Debug 88 fprintf(stderr, "*** listening\n"); 89#endif 90 break; 91 case 3: /* talk */ 92 ADB_DoTalk(); 93 break; 94 } 95 break; 96 case 1: /* Transfer date byte (even) */ 97 case 2: /* Transfer date byte (odd) */ 98 if (! ADB_ListenDatBuf) { 99 /* 100 will get here even if no pending talk data, 101 when there is pending event from device 102 other than the one polled by the last talk 103 command. this probably indicates a bug. 104 */ 105 if ((! ADB_TalkDatBuf) 106 || (ADB_IndexDatBuf >= ADB_SzDatBuf)) 107 { 108 ADB_ShiftOutData(0xFF); 109 ADB_Data = 1; 110 ADB_Int = 0; 111 } else { 112#ifdef _VIA_Debug 113 fprintf(stderr, "*** talk one\n"); 114#endif 115 ADB_ShiftOutData(ADB_DatBuf[ADB_IndexDatBuf]); 116 ADB_Data = 1; 117 ADB_IndexDatBuf += 1; 118 } 119 } else { 120 if (ADB_IndexDatBuf >= ADB_MaxSzDatBuf) { 121 ReportAbnormalID(0x0C03, "ADB listen too much"); 122 /* ADB_MaxSzDatBuf isn't big enough */ 123 (void) ADB_ShiftInData(); 124 } else { 125#ifdef _VIA_Debug 126 fprintf(stderr, "*** listen one\n"); 127#endif 128 ADB_DatBuf[ADB_IndexDatBuf] = ADB_ShiftInData(); 129 ADB_IndexDatBuf += 1; 130 } 131 } 132 break; 133 case 3: /* idle */ 134 if (ADB_ListenDatBuf) { 135 ReportAbnormalID(0x0C04, "ADB idle follows listen"); 136 /* apparently doesn't happen */ 137 } 138 if (ADB_TalkDatBuf) { 139 if (ADB_IndexDatBuf != 0) { 140 ReportAbnormalID(0x0C05, 141 "idle when not done talking"); 142 } 143 ADB_ShiftOutData(0xFF); 144 /* ADB_Int = 0; */ 145 } else if (CheckForADBanyEvt()) { 146 if (((ADB_CurCmd >> 2) & 3) == 3) { 147 ADB_DoTalk(); 148 } 149 ADB_ShiftOutData(0xFF); 150 /* ADB_Int = 0; */ 151 } 152 break; 153 } 154 } 155} 156 157GLOBALPROC ADBstate_ChangeNtfy(void) 158{ 159#ifdef _VIA_Debug 160 fprintf(stderr, "ADBstate_ChangeNtfy: %d, %d, %d\n", 161 ADB_st1, ADB_st0, GetCuriCount()); 162#endif 163 ICT_add(kICT_ADB_NewState, 164 348160UL * kCycleScale / 64 * kMyClockMult); 165 /* 166 Macintosh Family Hardware Reference say device "must respond 167 to talk command within 260 microseconds", which translates 168 to about 190 instructions. But haven't seen much problems 169 even for very large values (tens of thousands), and do see 170 problems for small values. 50 is definitely too small, 171 mouse doesn't move smoothly. There may still be some 172 signs of this problem with 150. 173 174 On the other hand, how fast the device must respond may 175 not be related to how fast the ADB transceiver responds. 176 */ 177} 178 179GLOBALPROC ADB_DataLineChngNtfy(void) 180{ 181#ifdef _VIA_Debug 182 fprintf(stderr, "ADB_DataLineChngNtfy: %d\n", ADB_Data); 183#endif 184} 185 186GLOBALPROC ADB_Update(void) 187{ 188 ui3b state = ADB_st1 * 2 + ADB_st0; 189 190 if (state == 3) { /* idle */ 191 if (ADB_TalkDatBuf) { 192 /* ignore, presumably being taken care of */ 193 } else if (CheckForADBanyEvt()) 194 { 195 if (((ADB_CurCmd >> 2) & 3) == 3) { 196 ADB_DoTalk(); 197 } 198 ADB_ShiftOutData(0xFF); 199 /* 200 Wouldn't expect this would be needed unless 201 there is actually talk data. But without it, 202 ADB never polls the other devices. Clearing 203 ADB_Int has no effect. 204 */ 205 /* 206 ADB_Int = 0; 207 seems to have no effect, which probably indicates a bug 208 */ 209 } 210 } 211} 212 213#endif /* EmADB */