this repo has no description
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 */