git @ Cat's Eye Technologies linapple / 8c57060
Make all files use UNIX line-endings No other changes in this revision. T. Joseph Carter 3 years ago
9 changed file(s) with 1814 addition(s) and 1814 deletion(s). Raw diff Collapse all Expand all
0 // Motorola MC6821 PIA
1
2 typedef void (*mem_write_handler) (void* objFrom, void* objTo, int nAddr, BYTE byData);
3
4 typedef struct _STWriteHandler
5 {
6 void* objTo;
7 mem_write_handler func;
8 } STWriteHandler;
9
10 //
11
12 #define PIA_DDRA 0
13 #define PIA_CTLA 1
14 #define PIA_DDRB 2
15 #define PIA_CTLB 3
16
17 class C6821
18 {
19 public:
20 C6821();
21 virtual ~C6821();
22
23 BYTE GetPB();
24 BYTE GetPA();
25 void SetPB(BYTE byData);
26 void SetPA(BYTE byData);
27 void SetCA1( BYTE byData );
28 void SetCA2( BYTE byData );
29 void SetCB1( BYTE byData );
30 void SetCB2( BYTE byData );
31 void Reset();
32 BYTE Read( BYTE byRS );
33 void Write( BYTE byRS, BYTE byData );
34
35 void UpdateInterrupts();
36
37 void SetListenerA( void *objTo, mem_write_handler func );
38 void SetListenerB( void *objTo, mem_write_handler func );
39 void SetListenerCA2( void *objTo, mem_write_handler func );
40 void SetListenerCB2( void *objTo, mem_write_handler func );
41
42 protected:
43 BYTE m_byIA;
44 BYTE m_byCA1;
45 BYTE m_byICA2;
46 BYTE m_byOA;
47 BYTE m_byOCA2;
48 BYTE m_byDDRA;
49 BYTE m_byCTLA;
50 BYTE m_byIRQAState;
51
52 BYTE m_byIB;
53 BYTE m_byCB1;
54 BYTE m_byICB2;
55 BYTE m_byOB;
56 BYTE m_byOCB2;
57 BYTE m_byDDRB;
58 BYTE m_byCTLB;
59 BYTE m_byIRQBState;
60
61 STWriteHandler m_stOutA;
62 STWriteHandler m_stOutB;
63 STWriteHandler m_stOutCA2;
64 STWriteHandler m_stOutCB2;
65 STWriteHandler m_stOutIRQA;
66 STWriteHandler m_stOutIRQB;
67 };
0 // Motorola MC6821 PIA
1
2 typedef void (*mem_write_handler) (void* objFrom, void* objTo, int nAddr, BYTE byData);
3
4 typedef struct _STWriteHandler
5 {
6 void* objTo;
7 mem_write_handler func;
8 } STWriteHandler;
9
10 //
11
12 #define PIA_DDRA 0
13 #define PIA_CTLA 1
14 #define PIA_DDRB 2
15 #define PIA_CTLB 3
16
17 class C6821
18 {
19 public:
20 C6821();
21 virtual ~C6821();
22
23 BYTE GetPB();
24 BYTE GetPA();
25 void SetPB(BYTE byData);
26 void SetPA(BYTE byData);
27 void SetCA1( BYTE byData );
28 void SetCA2( BYTE byData );
29 void SetCB1( BYTE byData );
30 void SetCB2( BYTE byData );
31 void Reset();
32 BYTE Read( BYTE byRS );
33 void Write( BYTE byRS, BYTE byData );
34
35 void UpdateInterrupts();
36
37 void SetListenerA( void *objTo, mem_write_handler func );
38 void SetListenerB( void *objTo, mem_write_handler func );
39 void SetListenerCA2( void *objTo, mem_write_handler func );
40 void SetListenerCB2( void *objTo, mem_write_handler func );
41
42 protected:
43 BYTE m_byIA;
44 BYTE m_byCA1;
45 BYTE m_byICA2;
46 BYTE m_byOA;
47 BYTE m_byOCA2;
48 BYTE m_byDDRA;
49 BYTE m_byCTLA;
50 BYTE m_byIRQAState;
51
52 BYTE m_byIB;
53 BYTE m_byCB1;
54 BYTE m_byICB2;
55 BYTE m_byOB;
56 BYTE m_byOCB2;
57 BYTE m_byDDRB;
58 BYTE m_byCTLB;
59 BYTE m_byIRQBState;
60
61 STWriteHandler m_stOutA;
62 STWriteHandler m_stOutB;
63 STWriteHandler m_stOutCA2;
64 STWriteHandler m_stOutCB2;
65 STWriteHandler m_stOutIRQA;
66 STWriteHandler m_stOutIRQB;
67 };
0 #pragma once
1
2 #ifndef _VC71 // __VA_ARGS__ not supported on MSVC++ .NET 7.x
3 #ifdef _DEBUG
4 #define LOG(format, ...) LogOutput(format, __VA_ARGS__)
5 #else
6 #define LOG(...)
7 #endif
8 #endif
9
10 extern void LogOutput(LPCTSTR format, ...);
0 #pragma once
1
2 #ifndef _VC71 // __VA_ARGS__ not supported on MSVC++ .NET 7.x
3 #ifdef _DEBUG
4 #define LOG(format, ...) LogOutput(format, __VA_ARGS__)
5 #else
6 #define LOG(...)
7 #endif
8 #endif
9
10 extern void LogOutput(LPCTSTR format, ...);
0 #include "6821.h"
1 #include "Common.h"
2
3 #define WRITE_HANDLER(func) void func( void* objFrom, void* objTo, int nAddr, BYTE byData )
4 #define CALLBACK_HANDLER(func) void func( void* objFrom, void* objTo, LPARAM lParam )
5
6 extern class CMouseInterface sg_Mouse;
7
8 class CMouseInterface
9 {
10 public:
11 CMouseInterface();
12 virtual ~CMouseInterface();
13
14 void Initialize(LPBYTE pCxRomPeripheral, UINT uSlot);
15 void Uninitialize(){ m_bActive = false; }
16 void SetSlotRom();
17 static BYTE IORead(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft);
18 static BYTE IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft);
19
20 void SetPosition(int xvalue, int xrange, int yvalue, int yrange);
21 void SetButton(eBUTTON Button, eBUTTONSTATE State);
22 bool Active() { return m_bActive; }
23 void SetVBlank(bool bVBL);
24
25 protected:
26 void On6821_A(BYTE byData);
27 void On6821_B(BYTE byData);
28 void OnCommand();
29 void OnWrite();
30 void OnMouseEvent();
31 void Reset();
32
33 friend WRITE_HANDLER( M6821_Listener_A );
34 friend WRITE_HANDLER( M6821_Listener_B );
35 //friend CALLBACK_HANDLER( MouseHandler );
36
37 void SetPosition(int xvalue, int yvalue);
38 void ClampX(int iMinX, int iMaxX);
39 void ClampY(int iMinY, int iMaxY);
40
41
42 C6821 m_6821;
43
44 int m_nDataLen;
45 BYTE m_byMode;
46
47 BYTE m_by6821B;
48 BYTE m_by6821A;
49 BYTE m_byBuff[8]; // m_byBuff[0] is mode byte
50 int m_nBuffPos;
51
52 BYTE m_byState;
53 int m_nX;
54 int m_nY;
55 BOOL m_bBtn0;
56 BOOL m_bBtn1;
57
58 bool m_bVBL;
59
60 //
61
62 UINT m_iX;
63 UINT m_iRangeX;
64 UINT m_iMinX;
65 UINT m_iMaxX;
66 UINT m_iY;
67 UINT m_iRangeY;
68 UINT m_iMinY;
69 UINT m_iMaxY;
70
71 BOOL m_bButtons[2];
72
73 //
74
75 bool m_bActive;
76 LPBYTE m_pSlotRom;
77 UINT m_uSlot;
78 };
0 #include "6821.h"
1 #include "Common.h"
2
3 #define WRITE_HANDLER(func) void func( void* objFrom, void* objTo, int nAddr, BYTE byData )
4 #define CALLBACK_HANDLER(func) void func( void* objFrom, void* objTo, LPARAM lParam )
5
6 extern class CMouseInterface sg_Mouse;
7
8 class CMouseInterface
9 {
10 public:
11 CMouseInterface();
12 virtual ~CMouseInterface();
13
14 void Initialize(LPBYTE pCxRomPeripheral, UINT uSlot);
15 void Uninitialize(){ m_bActive = false; }
16 void SetSlotRom();
17 static BYTE IORead(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft);
18 static BYTE IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft);
19
20 void SetPosition(int xvalue, int xrange, int yvalue, int yrange);
21 void SetButton(eBUTTON Button, eBUTTONSTATE State);
22 bool Active() { return m_bActive; }
23 void SetVBlank(bool bVBL);
24
25 protected:
26 void On6821_A(BYTE byData);
27 void On6821_B(BYTE byData);
28 void OnCommand();
29 void OnWrite();
30 void OnMouseEvent();
31 void Reset();
32
33 friend WRITE_HANDLER( M6821_Listener_A );
34 friend WRITE_HANDLER( M6821_Listener_B );
35 //friend CALLBACK_HANDLER( MouseHandler );
36
37 void SetPosition(int xvalue, int yvalue);
38 void ClampX(int iMinX, int iMaxX);
39 void ClampY(int iMinY, int iMaxY);
40
41
42 C6821 m_6821;
43
44 int m_nDataLen;
45 BYTE m_byMode;
46
47 BYTE m_by6821B;
48 BYTE m_by6821A;
49 BYTE m_byBuff[8]; // m_byBuff[0] is mode byte
50 int m_nBuffPos;
51
52 BYTE m_byState;
53 int m_nX;
54 int m_nY;
55 BOOL m_bBtn0;
56 BOOL m_bBtn1;
57
58 bool m_bVBL;
59
60 //
61
62 UINT m_iX;
63 UINT m_iRangeX;
64 UINT m_iMinX;
65 UINT m_iMaxX;
66 UINT m_iY;
67 UINT m_iRangeY;
68 UINT m_iMinY;
69 UINT m_iMaxY;
70
71 BOOL m_bButtons[2];
72
73 //
74
75 bool m_bActive;
76 LPBYTE m_pSlotRom;
77 UINT m_uSlot;
78 };
0 #pragma once
1
2 void PrintDestroy();
3 void PrintLoadRom(LPBYTE pCxRomPeripheral, UINT uSlot);
4 void PrintReset();
5 void PrintUpdate(DWORD);
0 #pragma once
1
2 void PrintDestroy();
3 void PrintLoadRom(LPBYTE pCxRomPeripheral, UINT uSlot);
4 void PrintReset();
5 void PrintUpdate(DWORD);
0 #ifndef GENERIC_LIST
1 #define GENERIC_LIST
2
3 /*
4 Funciones para LISTAS:
5
6 void Delete()
7 void Instance(List<T> &l)
8 void Rewind(void)
9 void Forward(void)
10 void Next(void)
11 void Prev(void)
12 T *GetObj(void)
13 LLink<T> *GetPos(void)
14 bool EmptyP()
15 bool EndP()
16 bool LastP()
17 bool BeginP()
18 void Insert(T *o)
19 void Add(T *o)
20 void AddAfter(LLink<T> *pos,T *o)
21 bool Iterate(T *&o)
22 T *ExtractIni(void)
23 T *Extract(void)
24 bool MemberP(T *o)
25 T *MemberGet(T *o)
26 bool MemberRefP(T *o)
27 int Length()
28 void Copy(List l)
29 bool DeleteElement(T *o)
30 T *GetRandom(void)
31 void SetNoOriginal(void)
32 void SetOriginal(void)
33
34
35 bool operator==(List<T> &l)
36 T *operator[](int index)
37 */
38
39 template <class T> class LLink {
40 public:
41 LLink<T>(T *o,LLink<T> *n=NULL) {
42 obj=o;next=n;
43 };
44 ~LLink<T>() {delete obj;
45 if (next!=NULL) delete next;};
46 inline LLink<T> *Getnext() {return next;};
47 inline void Setnext(LLink<T> *n) {next=n;};
48 inline T *GetObj() {return obj;};
49 inline void Setobj(T *o) {obj=o;};
50
51 void Anade(T *o) {
52 if (next==NULL) {
53 LLink<T> *node=new LLink<T>(o);
54 next=node;
55 } else {
56 next->Anade(o);
57 }
58 };
59
60 private:
61 T *obj;
62 LLink<T> *next;
63 };
64
65 template <class T> class List {
66 public:
67 List<T>() {list=NULL;act=NULL;top=NULL;original=true;};
68 ~List<T>() {
69 if (original) {
70 delete list;
71 } /* if */
72 };
73 List<T>(List<T> &l) {list=l.list;act=list;top=l.top;original=false;};
74
75 void Delete() {
76 if (original) {
77 delete list;
78 } /* if */
79 list=NULL;
80 act=NULL;
81 top=NULL;
82 };
83
84 void Instance(List<T> &l) {list=l.list;act=list;top=l.top;original=false;};
85 void Rewind(void) {act=list;};
86 void Forward(void) {act=top;};
87 void Next(void) {
88 if (act!=NULL) act=act->Getnext();
89 };
90
91 void Prev(void) {
92 LLink<T> *tmp;
93
94 if (act!=list) {
95 tmp=list;
96 while(tmp->Getnext()!=act) tmp=tmp->Getnext();
97 act=tmp;
98 } /* if */
99 };
100
101 T *GetObj(void) {return act->GetObj();};
102 LLink<T> *GetPos(void) {return act;};
103 bool EmptyP() {return list==NULL;};
104 bool EndP() {return act==NULL;};
105 bool LastP() {return act==top;};
106 bool BeginP() {return act==list;};
107
108 void Insert(T *o) {
109 if (list==NULL) {
110 list=new LLink<T>(o);
111 top=list;
112 } else {
113 list=new LLink<T>(o,list);
114 } /* if */
115 };
116
117 void Add(T *o) {
118 if (list==NULL) {
119 list=new LLink<T>(o);
120 top=list;
121 } else {
122 top->Anade(o);
123 top=top->Getnext();
124 } /* if */
125 };
126
127 void AddAfter(LLink<T> *pos,T *o)
128 {
129 if (pos==NULL) {
130 if (list==NULL) {
131 list=new LLink<T>(o);
132 top=list;
133 } else {
134 list=new LLink<T>(o,list);
135 } /* if */
136 } else {
137 LLink<T> *nl=new LLink<T>(o);
138
139 nl->Setnext(pos->Getnext());
140 pos->Setnext(nl);
141 if (nl->Getnext()==NULL) top=nl;
142 } /* if */
143 } /* AddAfter */
144
145 T *operator[](int index) {
146 LLink<T> *tmp=list;
147 while(tmp!=NULL && index>0) {
148 tmp=tmp->Getnext();
149 index--;
150 } /* while */
151 if (tmp==NULL) throw;
152 return tmp->GetObj();
153 };
154
155 // this functions was added by me, beom beotiger, for sorting these Lists! Ha-ha-ha ^_^
156 void Swap(int index1, int index2) { // swap two object with index1, index2
157 LLink<T> *tmp=list;
158 LLink<T> *tmp2=list;
159 T *o;
160 while(tmp!=NULL && index1 > 0) { // find List obj for index1
161 tmp=tmp->Getnext();
162 index1--;
163 } /* while */
164 if (tmp==NULL) throw;
165 while(tmp2!=NULL && index2 > 0) { // find List object for index2
166 tmp2=tmp2->Getnext();
167 index2--;
168 } /* while */
169 if (tmp2==NULL) throw;
170
171 o = tmp->GetObj(); // temp
172 tmp->Setobj(tmp2->GetObj());
173 tmp2->Setobj(o);
174 // return tmp->GetObj(); inline T *GetObj() {return obj;};
175 };/* Swap */
176
177 bool Iterate(T *&o) {
178 if (EndP()) return false;
179 o=act->GetObj();
180 act=act->Getnext();
181 return true;
182 } /* Iterate */
183
184 T *ExtractIni(void) {
185 LLink<T> *tmp;
186 T *o;
187
188 if (list==NULL) return NULL;
189 o=list->GetObj();
190 tmp=list;
191 list=list->Getnext();
192 tmp->Setnext(NULL);
193 if (act==tmp) act=list;
194 if (top==act) top=NULL;
195 tmp->Setobj(NULL);
196 delete tmp;
197 return o;
198 } /* ExtractIni */
199
200 T *Extract(void) {
201 LLink<T> *tmp,*tmp2=NULL;
202 T *o;
203
204 if (list==NULL) return NULL;
205 tmp=list;
206 while(tmp->Getnext()!=NULL) {
207 tmp2=tmp;
208 tmp=tmp->Getnext();
209 } /* while */
210 o=tmp->GetObj();
211 if (tmp2==NULL) {
212 list=NULL;
213 top=NULL;
214 act=NULL;
215 } else {
216 tmp2->Setnext(NULL);
217 top=tmp2;
218 } /* if */
219
220 if (act==tmp) act=top;
221 tmp->Setobj(NULL);
222 delete tmp;
223 return o;
224 } /* Extract */
225
226 bool MemberP(T *o) {
227 LLink<T> *tmp;
228 tmp=list;
229 while(tmp!=NULL) {
230 if (*(tmp->GetObj())==*o) return true;
231 tmp=tmp->Getnext();
232 } /* while */
233 return false;
234 } /* MemberP */
235
236 T *MemberGet(T *o) {
237 LLink<T> *tmp;
238 tmp=list;
239 while(tmp!=NULL) {
240 if (*(tmp->GetObj())==*o) return tmp->GetObj();
241 tmp=tmp->Getnext();
242 } /* while */
243 return NULL;
244 } /* MemberGet */
245
246 bool MemberRefP(T *o) {
247 LLink<T> *tmp;
248 tmp=list;
249 while(tmp!=NULL) {
250 if (tmp->GetObj()==o) return true;
251 tmp=tmp->Getnext();
252 } /* while */
253 return false;
254 } /* MemberRefP */
255
256 int Length() {
257 LLink<T> *tmp;
258 int count=0;
259
260 tmp=list;
261 while(tmp!=NULL) {
262 tmp=tmp->Getnext();
263 count++;
264 } /* while */
265 return count;
266 };
267
268 void Copy(List l) {
269 T *o;
270 Delete();
271 original=true;
272 l.Rewind();
273 while(l.Iterate(o)) {
274 o=new T(*o);
275 Add(o);
276 } /* while */
277 } /* Copy */
278
279 bool DeleteElement(T *o)
280 {
281 LLink<T> *tmp1,*tmp2;
282
283 tmp1=list;
284 tmp2=NULL;
285 while(tmp1!=NULL && tmp1->GetObj()!=o) {
286 tmp2=tmp1;
287 tmp1=tmp1->Getnext();
288 } /* while */
289
290 if (tmp1!=NULL) {
291 if (tmp2==NULL) {
292 /* Eliminar el primer elemento de la lista: */
293 list=list->Getnext();
294 tmp1->Setnext(NULL);
295 if (act==tmp1) act=list;
296 tmp1->Setobj(NULL);
297 delete tmp1;
298 } else {
299 /* Eliminar un elemento intermedio: */
300 tmp2->Setnext(tmp1->Getnext());
301 if (act==tmp1) act=tmp1->Getnext();
302 if (top==tmp1) top=tmp2;
303 tmp1->Setnext(NULL);
304 tmp1->Setobj(NULL);
305 delete tmp1;
306 } /* if */
307 return true;
308 } else {
309 return false;
310 } /* if */
311
312 } /* DeleteOne */
313
314 T *GetRandom(void) {
315 int i,l=Length();
316 i=((rand()*l)/RAND_MAX);
317 if (i==l) i=l-1;
318
319 return operator[](i);
320 } /* GetRandom */
321
322 bool operator==(List<T> &l) {
323 LLink<T> *tmp1,*tmp2;
324
325 tmp1=list;
326 tmp2=l.list;
327 while(tmp1!=NULL && tmp2!=NULL) {
328 if (!((*(tmp1->GetObj()))==(*(tmp2->GetObj())))) return false;
329 tmp1=tmp1->Getnext();
330 tmp2=tmp2->Getnext();
331 } /* while */
332 return tmp1==tmp2;
333 } /* == */
334
335
336 void SetNoOriginal(void) {original=false;}
337 void SetOriginal(void) {original=true;}
338
339 private:
340 bool original;
341 LLink<T> *list,*top;
342 LLink<T> *act;
343 };
344
345
346 #endif
0 #ifndef GENERIC_LIST
1 #define GENERIC_LIST
2
3 /*
4 Funciones para LISTAS:
5
6 void Delete()
7 void Instance(List<T> &l)
8 void Rewind(void)
9 void Forward(void)
10 void Next(void)
11 void Prev(void)
12 T *GetObj(void)
13 LLink<T> *GetPos(void)
14 bool EmptyP()
15 bool EndP()
16 bool LastP()
17 bool BeginP()
18 void Insert(T *o)
19 void Add(T *o)
20 void AddAfter(LLink<T> *pos,T *o)
21 bool Iterate(T *&o)
22 T *ExtractIni(void)
23 T *Extract(void)
24 bool MemberP(T *o)
25 T *MemberGet(T *o)
26 bool MemberRefP(T *o)
27 int Length()
28 void Copy(List l)
29 bool DeleteElement(T *o)
30 T *GetRandom(void)
31 void SetNoOriginal(void)
32 void SetOriginal(void)
33
34
35 bool operator==(List<T> &l)
36 T *operator[](int index)
37 */
38
39 template <class T> class LLink {
40 public:
41 LLink<T>(T *o,LLink<T> *n=NULL) {
42 obj=o;next=n;
43 };
44 ~LLink<T>() {delete obj;
45 if (next!=NULL) delete next;};
46 inline LLink<T> *Getnext() {return next;};
47 inline void Setnext(LLink<T> *n) {next=n;};
48 inline T *GetObj() {return obj;};
49 inline void Setobj(T *o) {obj=o;};
50
51 void Anade(T *o) {
52 if (next==NULL) {
53 LLink<T> *node=new LLink<T>(o);
54 next=node;
55 } else {
56 next->Anade(o);
57 }
58 };
59
60 private:
61 T *obj;
62 LLink<T> *next;
63 };
64
65 template <class T> class List {
66 public:
67 List<T>() {list=NULL;act=NULL;top=NULL;original=true;};
68 ~List<T>() {
69 if (original) {
70 delete list;
71 } /* if */
72 };
73 List<T>(List<T> &l) {list=l.list;act=list;top=l.top;original=false;};
74
75 void Delete() {
76 if (original) {
77 delete list;
78 } /* if */
79 list=NULL;
80 act=NULL;
81 top=NULL;
82 };
83
84 void Instance(List<T> &l) {list=l.list;act=list;top=l.top;original=false;};
85 void Rewind(void) {act=list;};
86 void Forward(void) {act=top;};
87 void Next(void) {
88 if (act!=NULL) act=act->Getnext();
89 };
90
91 void Prev(void) {
92 LLink<T> *tmp;
93
94 if (act!=list) {
95 tmp=list;
96 while(tmp->Getnext()!=act) tmp=tmp->Getnext();
97 act=tmp;
98 } /* if */
99 };
100
101 T *GetObj(void) {return act->GetObj();};
102 LLink<T> *GetPos(void) {return act;};
103 bool EmptyP() {return list==NULL;};
104 bool EndP() {return act==NULL;};
105 bool LastP() {return act==top;};
106 bool BeginP() {return act==list;};
107
108 void Insert(T *o) {
109 if (list==NULL) {
110 list=new LLink<T>(o);
111 top=list;
112 } else {
113 list=new LLink<T>(o,list);
114 } /* if */
115 };
116
117 void Add(T *o) {
118 if (list==NULL) {
119 list=new LLink<T>(o);
120 top=list;
121 } else {
122 top->Anade(o);
123 top=top->Getnext();
124 } /* if */
125 };
126
127 void AddAfter(LLink<T> *pos,T *o)
128 {
129 if (pos==NULL) {
130 if (list==NULL) {
131 list=new LLink<T>(o);
132 top=list;
133 } else {
134 list=new LLink<T>(o,list);
135 } /* if */
136 } else {
137 LLink<T> *nl=new LLink<T>(o);
138
139 nl->Setnext(pos->Getnext());
140 pos->Setnext(nl);
141 if (nl->Getnext()==NULL) top=nl;
142 } /* if */
143 } /* AddAfter */
144
145 T *operator[](int index) {
146 LLink<T> *tmp=list;
147 while(tmp!=NULL && index>0) {
148 tmp=tmp->Getnext();
149 index--;
150 } /* while */
151 if (tmp==NULL) throw;
152 return tmp->GetObj();
153 };
154
155 // this functions was added by me, beom beotiger, for sorting these Lists! Ha-ha-ha ^_^
156 void Swap(int index1, int index2) { // swap two object with index1, index2
157 LLink<T> *tmp=list;
158 LLink<T> *tmp2=list;
159 T *o;
160 while(tmp!=NULL && index1 > 0) { // find List obj for index1
161 tmp=tmp->Getnext();
162 index1--;
163 } /* while */
164 if (tmp==NULL) throw;
165 while(tmp2!=NULL && index2 > 0) { // find List object for index2
166 tmp2=tmp2->Getnext();
167 index2--;
168 } /* while */
169 if (tmp2==NULL) throw;
170
171 o = tmp->GetObj(); // temp
172 tmp->Setobj(tmp2->GetObj());
173 tmp2->Setobj(o);
174 // return tmp->GetObj(); inline T *GetObj() {return obj;};
175 };/* Swap */
176
177 bool Iterate(T *&o) {
178 if (EndP()) return false;
179 o=act->GetObj();
180 act=act->Getnext();
181 return true;
182 } /* Iterate */
183
184 T *ExtractIni(void) {
185 LLink<T> *tmp;
186 T *o;
187
188 if (list==NULL) return NULL;
189 o=list->GetObj();
190 tmp=list;
191 list=list->Getnext();
192 tmp->Setnext(NULL);
193 if (act==tmp) act=list;
194 if (top==act) top=NULL;
195 tmp->Setobj(NULL);
196 delete tmp;
197 return o;
198 } /* ExtractIni */
199
200 T *Extract(void) {
201 LLink<T> *tmp,*tmp2=NULL;
202 T *o;
203
204 if (list==NULL) return NULL;
205 tmp=list;
206 while(tmp->Getnext()!=NULL) {
207 tmp2=tmp;
208 tmp=tmp->Getnext();
209 } /* while */
210 o=tmp->GetObj();
211 if (tmp2==NULL) {
212 list=NULL;
213 top=NULL;
214 act=NULL;
215 } else {
216 tmp2->Setnext(NULL);
217 top=tmp2;
218 } /* if */
219
220 if (act==tmp) act=top;
221 tmp->Setobj(NULL);
222 delete tmp;
223 return o;
224 } /* Extract */
225
226 bool MemberP(T *o) {
227 LLink<T> *tmp;
228 tmp=list;
229 while(tmp!=NULL) {
230 if (*(tmp->GetObj())==*o) return true;
231 tmp=tmp->Getnext();
232 } /* while */
233 return false;
234 } /* MemberP */
235
236 T *MemberGet(T *o) {
237 LLink<T> *tmp;
238 tmp=list;
239 while(tmp!=NULL) {
240 if (*(tmp->GetObj())==*o) return tmp->GetObj();
241 tmp=tmp->Getnext();
242 } /* while */
243 return NULL;
244 } /* MemberGet */
245
246 bool MemberRefP(T *o) {
247 LLink<T> *tmp;
248 tmp=list;
249 while(tmp!=NULL) {
250 if (tmp->GetObj()==o) return true;
251 tmp=tmp->Getnext();
252 } /* while */
253 return false;
254 } /* MemberRefP */
255
256 int Length() {
257 LLink<T> *tmp;
258 int count=0;
259
260 tmp=list;
261 while(tmp!=NULL) {
262 tmp=tmp->Getnext();
263 count++;
264 } /* while */
265 return count;
266 };
267
268 void Copy(List l) {
269 T *o;
270 Delete();
271 original=true;
272 l.Rewind();
273 while(l.Iterate(o)) {
274 o=new T(*o);
275 Add(o);
276 } /* while */
277 } /* Copy */
278
279 bool DeleteElement(T *o)
280 {
281 LLink<T> *tmp1,*tmp2;
282
283 tmp1=list;
284 tmp2=NULL;
285 while(tmp1!=NULL && tmp1->GetObj()!=o) {
286 tmp2=tmp1;
287 tmp1=tmp1->Getnext();
288 } /* while */
289
290 if (tmp1!=NULL) {
291 if (tmp2==NULL) {
292 /* Eliminar el primer elemento de la lista: */
293 list=list->Getnext();
294 tmp1->Setnext(NULL);
295 if (act==tmp1) act=list;
296 tmp1->Setobj(NULL);
297 delete tmp1;
298 } else {
299 /* Eliminar un elemento intermedio: */
300 tmp2->Setnext(tmp1->Getnext());
301 if (act==tmp1) act=tmp1->Getnext();
302 if (top==tmp1) top=tmp2;
303 tmp1->Setnext(NULL);
304 tmp1->Setobj(NULL);
305 delete tmp1;
306 } /* if */
307 return true;
308 } else {
309 return false;
310 } /* if */
311
312 } /* DeleteOne */
313
314 T *GetRandom(void) {
315 int i,l=Length();
316 i=((rand()*l)/RAND_MAX);
317 if (i==l) i=l-1;
318
319 return operator[](i);
320 } /* GetRandom */
321
322 bool operator==(List<T> &l) {
323 LLink<T> *tmp1,*tmp2;
324
325 tmp1=list;
326 tmp2=l.list;
327 while(tmp1!=NULL && tmp2!=NULL) {
328 if (!((*(tmp1->GetObj()))==(*(tmp2->GetObj())))) return false;
329 tmp1=tmp1->Getnext();
330 tmp2=tmp2->Getnext();
331 } /* while */
332 return tmp1==tmp2;
333 } /* == */
334
335
336 void SetNoOriginal(void) {original=false;}
337 void SetOriginal(void) {original=true;}
338
339 private:
340 bool original;
341 LLink<T> *list,*top;
342 LLink<T> *act;
343 };
344
345
346 #endif
0 // Based on MAME's 6821pia.c
1 // - by Kyle Kim (Apple in PC)
2
3 //
4 // From mame.txt (http://www.mame.net/readme.html)
5 //
6 // VI. Reuse of Source Code
7 // --------------------------
8 // This chapter might not apply to specific portions of MAME (e.g. CPU
9 // emulators) which bear different copyright notices.
10 // The source code cannot be used in a commercial product without the written
11 // authorization of the authors. Use in non-commercial products is allowed, and
12 // indeed encouraged. If you use portions of the MAME source code in your
13 // program, however, you must make the full source code freely available as
14 // well.
15 // Usage of the _information_ contained in the source code is free for any use.
16 // However, given the amount of time and energy it took to collect this
17 // information, if you find new information we would appreciate if you made it
18 // freely available as well.
19 //
20
21 #include "wincompat.h"
22 #include "6821.h"
23
24 // Ctrl-A(B) register bit mask define
25 /*
26 0 1
27 bit0 IRQ1_DISABLED IRQ1_ENABLED
28 bit1 C1_HIGH_TO_LOW C1_LOW_TO_HIGH
29 bit2 DDR_SELECTED OUTPUT_SELECTED
30
31 bit3 RESET_C2 SET_C2 ( C2_OUTPUT & C2_SETMODE )
32 bit3 STROBE_C1_RESET STROBE_E_RESET ( C2_OUTPUT & C2_STROBE_MODE )
33 bit4 C2_STROBE_MODE C2_SETMODE ( C2_OUTPUT )
34
35 bit3 IRQ2_DISABLED IRQ2_ENABLED ( C2_INPUT )
36 bit4 C2_HIGH_TO_LOW C2_HIGH_TO_LOW ( C2_INPUT )
37 bit5 C2_INPUT C2_OUTPUT
38 */
39 #define PIA_IRQ1 0x80
40 #define PIA_IRQ2 0x40
41 #define SET_IRQ1(c) c |= PIA_IRQ1;
42 #define SET_IRQ2(c) c |= PIA_IRQ2;
43 #define CLEAR_IRQ1(c) c &= ~PIA_IRQ1;
44 #define CLEAR_IRQ2(c) c &= ~PIA_IRQ2;
45 #define IRQ1(c) ( c & PIA_IRQ1 )
46 #define IRQ2(c) ( c & PIA_IRQ2 )
47
48 #define IRQ1_ENABLED(c) ( c & 0x01 )
49 #define IRQ1_DISABLED(c) !( c & 0x01 )
50 #define C1_LOW_TO_HIGH(c) ( c & 0x02 )
51 #define C1_HIGH_TO_LOW(c) !( c & 0x02 )
52 #define OUTPUT_SELECTED(c) ( c & 0x04 )
53 #define DDR_SELECTED(c) !( c & 0x04 )
54 #define IRQ2_ENABLED(c) ( c & 0x08 )
55 #define IRQ2_DISABLED(c) !( c & 0x08 )
56 #define STROBE_E_RESET(c) ( c & 0x08 )
57 #define STROBE_C1_RESET(c) !( c & 0x08 )
58 #define SET_C2(c) ( c & 0x08 )
59 #define RESET_C2(c) !( c & 0x08 )
60 #define C2_LOW_TO_HIGH(c) ( c & 0x10 )
61 #define C2_HIGH_TO_LOW(c) !( c & 0x10 )
62 #define C2_SET_MODE(c) ( c & 0x10 )
63 #define C2_STROBE_MODE(c) !( c & 0x10 )
64 #define C2_OUTPUT(c) ( c & 0x20 )
65 #define C2_INPUT(c) !( c & 0x20 )
66
67 #define PIA_W_CALLBACK(st, val) \
68 if ( st.func ) st.func( this, st.objTo, 0, val )
69
70 //////////////////////////////////////////////////////////////////////
71
72 C6821::C6821()
73 {
74 Reset();
75 m_stOutA.objTo = NULL;
76 m_stOutA.func = NULL;
77 m_stOutB.objTo = NULL;
78 m_stOutB.func = NULL;
79 m_stOutCA2.objTo = NULL;
80 m_stOutCA2.func = NULL;
81 m_stOutCB2.objTo = NULL;
82 m_stOutCB2.func = NULL;
83 m_stOutIRQA.objTo = NULL;
84 m_stOutIRQA.func = NULL;
85 m_stOutIRQB.objTo = NULL;
86 m_stOutIRQB.func = NULL;
87 }
88
89 C6821::~C6821()
90 {
91
92 }
93
94 void C6821::SetListenerA(void *objTo, mem_write_handler func)
95 {
96 m_stOutA.objTo = objTo;
97 m_stOutA.func = func;
98 }
99
100 void C6821::SetListenerB(void *objTo, mem_write_handler func)
101 {
102 m_stOutB.objTo = objTo;
103 m_stOutB.func = func;
104 }
105
106 void C6821::SetListenerCA2(void *objTo, mem_write_handler func)
107 {
108 m_stOutCA2.objTo = objTo;
109 m_stOutCA2.func = func;
110 }
111
112 void C6821::SetListenerCB2(void *objTo, mem_write_handler func)
113 {
114 m_stOutCB2.objTo = objTo;
115 m_stOutCB2.func = func;
116 }
117
118 BYTE C6821::Read(BYTE byRS)
119 {
120 BYTE retval = 0;
121 byRS &= 3;
122 switch (byRS) {
123 /******************* port A output/DDR read *******************/
124 case PIA_DDRA:
125 // read output register
126 if (OUTPUT_SELECTED(m_byCTLA)) {
127 // combine input and output values
128 retval = (m_byOA & m_byDDRA) | (m_byIA & ~m_byDDRA);
129 // IRQ flags implicitly cleared by a read
130 CLEAR_IRQ1(m_byCTLA);
131 CLEAR_IRQ1(m_byCTLB);
132 UpdateInterrupts();
133 // CA2 is configured as output and in read strobe mode
134 if (C2_OUTPUT(m_byCTLA) && C2_STROBE_MODE(m_byCTLA)) {
135 // this will cause a transition low; call the output function if we're currently high
136 if (m_byOCA2)
137 PIA_W_CALLBACK(m_stOutCA2, 0);
138 m_byOCA2 = 0;
139
140 // if the CA2 strobe is cleared by the E, reset it right away
141 if (STROBE_E_RESET(m_byCTLA)) {
142 PIA_W_CALLBACK(m_stOutCA2, 1);
143 m_byOCA2 = 1;
144 }
145 }
146 }
147 // read DDR register
148 else {
149 retval = m_byDDRA;
150 }
151 break;
152
153 /******************* port B output/DDR read *******************/
154 case PIA_DDRB:
155
156 // read output register
157 if (OUTPUT_SELECTED(m_byCTLB)) {
158 // combine input and output values
159 retval = (m_byOB & m_byDDRB) + (m_byIB & ~m_byDDRB);
160
161 // IRQ flags implicitly cleared by a read
162 CLEAR_IRQ2(m_byCTLA);
163 CLEAR_IRQ2(m_byCTLB);
164 UpdateInterrupts();
165 }
166 /* read DDR register */
167 else {
168 retval = m_byDDRB;
169 }
170 break;
171
172 /******************* port A control read *******************/
173 case PIA_CTLA:
174 // read control register
175 retval = m_byCTLA;
176 // when CA2 is an output, IRQA2 = 0, and is not affected by CA2 transitions.
177 if (C2_OUTPUT(m_byCTLA))
178 retval &= ~PIA_IRQ2;
179 break;
180
181 /******************* port B control read *******************/
182 case PIA_CTLB:
183 retval = m_byCTLB;
184 // when CB2 is an output, IRQB2 = 0, and is not affected by CB2 transitions.
185 if (C2_OUTPUT(m_byCTLB))
186 retval &= ~PIA_IRQ2;
187 break;
188
189 }
190
191 return retval;
192 }
193
194 void C6821::Write(BYTE byRS, BYTE byData)
195 {
196 byRS &= 3;
197
198 switch( byRS ) {
199 /******************* port A output/DDR write *******************/
200 case PIA_DDRA:
201
202 // write output register
203 if (OUTPUT_SELECTED(m_byCTLA)) {
204 // update the output value
205 m_byOA = byData;
206
207 // send it to the output function
208 if (m_byDDRA)
209 PIA_W_CALLBACK(m_stOutA, m_byOA & m_byDDRA);
210 }
211
212 // write DDR register
213 else {
214 if (m_byDDRA != byData) {
215 m_byDDRA = byData;
216
217 // send it to the output function
218 if (m_byDDRA)
219 PIA_W_CALLBACK(m_stOutA, m_byOA & m_byDDRA);
220 }
221 }
222 break;
223
224 /******************* port B output/DDR write *******************/
225 case PIA_DDRB:
226
227 // write output register
228 if (OUTPUT_SELECTED(m_byCTLB)) {
229 // update the output value
230 m_byOB = byData;
231
232 // send it to the output function
233 if (m_byDDRB)
234 PIA_W_CALLBACK(m_stOutB, m_byOB & m_byDDRB);
235
236 // CB2 is configured as output and in write strobe mode
237 if (C2_OUTPUT(m_byCTLB) && C2_STROBE_MODE(m_byCTLB)) {
238 // this will cause a transition low; call the output function if we're currently high
239 if (m_byOCB2)
240 PIA_W_CALLBACK(m_stOutCB2, 0);
241 m_byOCB2 = 0;
242
243 // if the CB2 strobe is cleared by the E, reset it right away
244 if (STROBE_E_RESET(m_byCTLB)) {
245 PIA_W_CALLBACK(m_stOutCB2, 1);
246 m_byOCB2 = 1;
247 }
248 }
249 }
250 // write DDR register
251 else {
252 if (m_byDDRB != byData) {
253 m_byDDRB = byData;
254
255 // send it to the output function
256 if (m_byDDRB)
257 PIA_W_CALLBACK(m_stOutB, m_byOB & m_byDDRB);
258 }
259 }
260 break;
261
262 /******************* port A control write *******************/
263 case PIA_CTLA:
264 // Bit 7 and 6 read only
265 byData &= 0x3f;
266
267 // CA2 is configured as output and in set/reset mode
268 if (C2_OUTPUT(byData)) {
269 // determine the new value
270 int temp = SET_C2(byData) ? 1 : 0;
271
272 // if this creates a transition, call the CA2 output function
273 if (m_byOCA2 ^ temp)
274 PIA_W_CALLBACK(m_stOutCA2, temp);
275
276 // set the new value
277 m_byOCA2 = temp;
278 }
279
280 // update the control register
281 m_byCTLA = (m_byCTLA & ~0x3F) | byData;
282
283 // update externals
284 UpdateInterrupts();
285 break;
286
287 /******************* port B control write *******************/
288 case PIA_CTLB:
289
290 /* Bit 7 and 6 read only - PD 16/01/00 */
291
292 byData &= 0x3f;
293
294 // CB2 is configured as output and in set/reset mode
295 if (C2_OUTPUT(byData)) {
296 // determine the new value
297 int temp = SET_C2(byData) ? 1 : 0;
298
299 // if this creates a transition, call the CA2 output function
300 if (m_byOCB2 ^ temp)
301 PIA_W_CALLBACK(m_stOutCB2, temp);
302
303 // set the new value
304 m_byOCB2 = temp;
305 }
306
307 // update the control register
308 m_byCTLB = (m_byCTLB & ~0x3F) | byData;
309
310 // update externals
311 UpdateInterrupts();
312 break;
313 }
314
315 }
316
317 void C6821::Reset()
318 {
319 m_byIA = 0;
320 m_byCA1 = 0;
321 m_byICA2 = 0;
322 m_byOA = 0;
323 m_byOCA2 = 0;
324 m_byDDRA = 0;
325 m_byCTLA = 0;
326 m_byIRQAState = 0;
327
328 m_byIB = 0;
329 m_byCB1 = 0;
330 m_byICB2 = 0;
331 m_byOB = 0;
332 m_byOCB2 = 0;
333 m_byDDRB = 0;
334 m_byCTLB = 0;
335 m_byIRQBState = 0;
336 }
337
338 void C6821::UpdateInterrupts()
339 {
340 BYTE byNewState;
341
342 // start with IRQ A
343 byNewState = 0;
344 if ( ( IRQ1( m_byCTLA ) && IRQ1_ENABLED( m_byCTLA ) ) ||
345 ( IRQ2( m_byCTLA ) && IRQ2_ENABLED( m_byCTLA ) ) )
346 byNewState = 1;
347
348 if ( byNewState != m_byIRQAState )
349 {
350 m_byIRQAState = byNewState;
351 PIA_W_CALLBACK( m_stOutIRQA, m_byIRQAState );
352 }
353
354 /* then do IRQ B */
355 byNewState = 0;
356 if ( ( IRQ1( m_byCTLB ) && IRQ1_ENABLED( m_byCTLB ) ) ||
357 ( IRQ2( m_byCTLB ) && IRQ2_ENABLED( m_byCTLB ) ) )
358 byNewState = 1;
359
360 if ( byNewState != m_byIRQBState )
361 {
362 m_byIRQBState = byNewState;
363 PIA_W_CALLBACK( m_stOutIRQB, m_byIRQBState );
364 }
365 }
366
367 void C6821::SetCA1(BYTE byData)
368 {
369 byData = byData ? 1 : 0;
370
371 // the new state has caused a transition
372 if ( m_byCA1 ^ byData )
373 {
374 // handle the active transition
375 if ( ( byData && C1_LOW_TO_HIGH( m_byCTLA ) ) ||
376 ( !byData && C1_HIGH_TO_LOW( m_byCTLA ) ) )
377 {
378 // mark the IRQ
379 SET_IRQ1(m_byCTLA);
380
381 // update externals
382 UpdateInterrupts();
383
384 // CA2 is configured as output and in read strobe mode and cleared by a CA1 transition
385 if ( C2_OUTPUT( m_byCTLA ) && C2_STROBE_MODE( m_byCTLA ) && STROBE_C1_RESET( m_byCTLA ) )
386 {
387 // call the CA2 output function
388 if ( !m_byOCA2 )
389 PIA_W_CALLBACK( m_stOutCA2, 1 );
390
391 // clear CA2
392 m_byOCA2 = 1;
393 }
394 }
395 }
396
397 // set the new value for CA1
398 m_byCA1 = byData;
399 }
400
401 void C6821::SetCA2(BYTE byData)
402 {
403 byData = byData ? 1 : 0;
404
405 // CA2 is in input mode
406 if ( C2_INPUT( m_byCTLA ) )
407 {
408 // the new state has caused a transition
409 if ( m_byICA2 ^ byData )
410 {
411 // handle the active transition
412 if ((byData && C2_LOW_TO_HIGH(m_byCTLA)) ||
413 (!byData && C2_HIGH_TO_LOW(m_byCTLA))) {
414 // mark the IRQ
415 SET_IRQ2(m_byCTLA);
416
417 // update externals
418 UpdateInterrupts();
419 }
420 }
421 }
422
423 // set the new value for CA2
424 m_byICA2 = byData;
425 }
426
427 void C6821::SetCB1(BYTE byData)
428 {
429 byData = byData ? 1 : 0;
430
431 // the new state has caused a transition
432 if ( m_byCB1 ^ byData )
433 {
434 // handle the active transition
435 if ( ( byData && C1_LOW_TO_HIGH( m_byCTLB ) ) ||
436 ( !byData && C1_HIGH_TO_LOW( m_byCTLB ) ) )
437 {
438 // mark the IRQ
439 SET_IRQ1( m_byCTLB );
440
441 // update externals
442 UpdateInterrupts();
443
444 // CB2 is configured as output and in read strobe mode and cleared by a CA1 transition
445 if ( C2_OUTPUT( m_byCTLB ) && C2_STROBE_MODE( m_byCTLB ) && STROBE_C1_RESET( m_byCTLB ) )
446 {
447 // the IRQ1 flag must have also been cleared
448 if ( !IRQ1( m_byCTLB ) )
449 {
450 // call the CB2 output function
451 if ( !m_byOCB2 )
452 PIA_W_CALLBACK( m_stOutCB2, 1 );
453
454 // clear CB2
455 m_byOCB2 = 1;
456 }
457 }
458 }
459 }
460
461 // set the new value for CA1
462 m_byCB1 = byData;
463
464 }
465
466 void C6821::SetCB2(BYTE byData)
467 {
468 byData = byData ? 1 : 0;
469
470 // CA2 is in input mode
471 if ( C2_INPUT( m_byCTLB ) )
472 {
473 // the new state has caused a transition
474 if ( m_byICB2 ^ byData )
475 {
476 // handle the active transition
477 if ( ( byData && C2_LOW_TO_HIGH( m_byCTLB ) ) ||
478 ( !byData && C2_HIGH_TO_LOW( m_byCTLB ) ) )
479 {
480 // mark the IRQ
481 SET_IRQ2( m_byCTLB );
482
483 // update externals
484 UpdateInterrupts();
485 }
486 }
487 }
488
489 // set the new value for CA2
490 m_byICB2 = byData;
491 }
492
493 void C6821::SetPA(BYTE byData)
494 {
495 m_byIA = byData;
496 }
497
498 void C6821::SetPB(BYTE byData)
499 {
500 m_byIB = byData;
501 }
502
503 BYTE C6821::GetPA()
504 {
505 return m_byOA & m_byDDRA;
506 }
507
508 BYTE C6821::GetPB()
509 {
510 return m_byOB & m_byDDRB;
511 }
0 // Based on MAME's 6821pia.c
1 // - by Kyle Kim (Apple in PC)
2
3 //
4 // From mame.txt (http://www.mame.net/readme.html)
5 //
6 // VI. Reuse of Source Code
7 // --------------------------
8 // This chapter might not apply to specific portions of MAME (e.g. CPU
9 // emulators) which bear different copyright notices.
10 // The source code cannot be used in a commercial product without the written
11 // authorization of the authors. Use in non-commercial products is allowed, and
12 // indeed encouraged. If you use portions of the MAME source code in your
13 // program, however, you must make the full source code freely available as
14 // well.
15 // Usage of the _information_ contained in the source code is free for any use.
16 // However, given the amount of time and energy it took to collect this
17 // information, if you find new information we would appreciate if you made it
18 // freely available as well.
19 //
20
21 #include "wincompat.h"
22 #include "6821.h"
23
24 // Ctrl-A(B) register bit mask define
25 /*
26 0 1
27 bit0 IRQ1_DISABLED IRQ1_ENABLED
28 bit1 C1_HIGH_TO_LOW C1_LOW_TO_HIGH
29 bit2 DDR_SELECTED OUTPUT_SELECTED
30
31 bit3 RESET_C2 SET_C2 ( C2_OUTPUT & C2_SETMODE )
32 bit3 STROBE_C1_RESET STROBE_E_RESET ( C2_OUTPUT & C2_STROBE_MODE )
33 bit4 C2_STROBE_MODE C2_SETMODE ( C2_OUTPUT )
34
35 bit3 IRQ2_DISABLED IRQ2_ENABLED ( C2_INPUT )
36 bit4 C2_HIGH_TO_LOW C2_HIGH_TO_LOW ( C2_INPUT )
37 bit5 C2_INPUT C2_OUTPUT
38 */
39 #define PIA_IRQ1 0x80
40 #define PIA_IRQ2 0x40
41 #define SET_IRQ1(c) c |= PIA_IRQ1;
42 #define SET_IRQ2(c) c |= PIA_IRQ2;
43 #define CLEAR_IRQ1(c) c &= ~PIA_IRQ1;
44 #define CLEAR_IRQ2(c) c &= ~PIA_IRQ2;
45 #define IRQ1(c) ( c & PIA_IRQ1 )
46 #define IRQ2(c) ( c & PIA_IRQ2 )
47
48 #define IRQ1_ENABLED(c) ( c & 0x01 )
49 #define IRQ1_DISABLED(c) !( c & 0x01 )
50 #define C1_LOW_TO_HIGH(c) ( c & 0x02 )
51 #define C1_HIGH_TO_LOW(c) !( c & 0x02 )
52 #define OUTPUT_SELECTED(c) ( c & 0x04 )
53 #define DDR_SELECTED(c) !( c & 0x04 )
54 #define IRQ2_ENABLED(c) ( c & 0x08 )
55 #define IRQ2_DISABLED(c) !( c & 0x08 )
56 #define STROBE_E_RESET(c) ( c & 0x08 )
57 #define STROBE_C1_RESET(c) !( c & 0x08 )
58 #define SET_C2(c) ( c & 0x08 )
59 #define RESET_C2(c) !( c & 0x08 )
60 #define C2_LOW_TO_HIGH(c) ( c & 0x10 )
61 #define C2_HIGH_TO_LOW(c) !( c & 0x10 )
62 #define C2_SET_MODE(c) ( c & 0x10 )
63 #define C2_STROBE_MODE(c) !( c & 0x10 )
64 #define C2_OUTPUT(c) ( c & 0x20 )
65 #define C2_INPUT(c) !( c & 0x20 )
66
67 #define PIA_W_CALLBACK(st, val) \
68 if ( st.func ) st.func( this, st.objTo, 0, val )
69
70 //////////////////////////////////////////////////////////////////////
71
72 C6821::C6821()
73 {
74 Reset();
75 m_stOutA.objTo = NULL;
76 m_stOutA.func = NULL;
77 m_stOutB.objTo = NULL;
78 m_stOutB.func = NULL;
79 m_stOutCA2.objTo = NULL;
80 m_stOutCA2.func = NULL;
81 m_stOutCB2.objTo = NULL;
82 m_stOutCB2.func = NULL;
83 m_stOutIRQA.objTo = NULL;
84 m_stOutIRQA.func = NULL;
85 m_stOutIRQB.objTo = NULL;
86 m_stOutIRQB.func = NULL;
87 }
88
89 C6821::~C6821()
90 {
91
92 }
93
94 void C6821::SetListenerA(void *objTo, mem_write_handler func)
95 {
96 m_stOutA.objTo = objTo;
97 m_stOutA.func = func;
98 }
99
100 void C6821::SetListenerB(void *objTo, mem_write_handler func)
101 {
102 m_stOutB.objTo = objTo;
103 m_stOutB.func = func;
104 }
105
106 void C6821::SetListenerCA2(void *objTo, mem_write_handler func)
107 {
108 m_stOutCA2.objTo = objTo;
109 m_stOutCA2.func = func;
110 }
111
112 void C6821::SetListenerCB2(void *objTo, mem_write_handler func)
113 {
114 m_stOutCB2.objTo = objTo;
115 m_stOutCB2.func = func;
116 }
117
118 BYTE C6821::Read(BYTE byRS)
119 {
120 BYTE retval = 0;
121 byRS &= 3;
122 switch (byRS) {
123 /******************* port A output/DDR read *******************/
124 case PIA_DDRA:
125 // read output register
126 if (OUTPUT_SELECTED(m_byCTLA)) {
127 // combine input and output values
128 retval = (m_byOA & m_byDDRA) | (m_byIA & ~m_byDDRA);
129 // IRQ flags implicitly cleared by a read
130 CLEAR_IRQ1(m_byCTLA);
131 CLEAR_IRQ1(m_byCTLB);
132 UpdateInterrupts();
133 // CA2 is configured as output and in read strobe mode
134 if (C2_OUTPUT(m_byCTLA) && C2_STROBE_MODE(m_byCTLA)) {
135 // this will cause a transition low; call the output function if we're currently high
136 if (m_byOCA2)
137 PIA_W_CALLBACK(m_stOutCA2, 0);
138 m_byOCA2 = 0;
139
140 // if the CA2 strobe is cleared by the E, reset it right away
141 if (STROBE_E_RESET(m_byCTLA)) {
142 PIA_W_CALLBACK(m_stOutCA2, 1);
143 m_byOCA2 = 1;
144 }
145 }
146 }
147 // read DDR register
148 else {
149 retval = m_byDDRA;
150 }
151 break;
152
153 /******************* port B output/DDR read *******************/
154 case PIA_DDRB:
155
156 // read output register
157 if (OUTPUT_SELECTED(m_byCTLB)) {
158 // combine input and output values
159 retval = (m_byOB & m_byDDRB) + (m_byIB & ~m_byDDRB);
160
161 // IRQ flags implicitly cleared by a read
162 CLEAR_IRQ2(m_byCTLA);
163 CLEAR_IRQ2(m_byCTLB);
164 UpdateInterrupts();
165 }
166 /* read DDR register */
167 else {
168 retval = m_byDDRB;
169 }
170 break;
171
172 /******************* port A control read *******************/
173 case PIA_CTLA:
174 // read control register
175 retval = m_byCTLA;
176 // when CA2 is an output, IRQA2 = 0, and is not affected by CA2 transitions.
177 if (C2_OUTPUT(m_byCTLA))
178 retval &= ~PIA_IRQ2;
179 break;
180
181 /******************* port B control read *******************/
182 case PIA_CTLB:
183 retval = m_byCTLB;
184 // when CB2 is an output, IRQB2 = 0, and is not affected by CB2 transitions.
185 if (C2_OUTPUT(m_byCTLB))
186 retval &= ~PIA_IRQ2;
187 break;
188
189 }
190
191 return retval;
192 }
193
194 void C6821::Write(BYTE byRS, BYTE byData)
195 {
196 byRS &= 3;
197
198 switch( byRS ) {
199 /******************* port A output/DDR write *******************/
200 case PIA_DDRA:
201
202 // write output register
203 if (OUTPUT_SELECTED(m_byCTLA)) {
204 // update the output value
205 m_byOA = byData;
206
207 // send it to the output function
208 if (m_byDDRA)
209 PIA_W_CALLBACK(m_stOutA, m_byOA & m_byDDRA);
210 }
211
212 // write DDR register
213 else {
214 if (m_byDDRA != byData) {
215 m_byDDRA = byData;
216
217 // send it to the output function
218 if (m_byDDRA)
219 PIA_W_CALLBACK(m_stOutA, m_byOA & m_byDDRA);
220 }
221 }
222 break;
223
224 /******************* port B output/DDR write *******************/
225 case PIA_DDRB:
226
227 // write output register
228 if (OUTPUT_SELECTED(m_byCTLB)) {
229 // update the output value
230 m_byOB = byData;
231
232 // send it to the output function
233 if (m_byDDRB)
234 PIA_W_CALLBACK(m_stOutB, m_byOB & m_byDDRB);
235
236 // CB2 is configured as output and in write strobe mode
237 if (C2_OUTPUT(m_byCTLB) && C2_STROBE_MODE(m_byCTLB)) {
238 // this will cause a transition low; call the output function if we're currently high
239 if (m_byOCB2)
240 PIA_W_CALLBACK(m_stOutCB2, 0);
241 m_byOCB2 = 0;
242
243 // if the CB2 strobe is cleared by the E, reset it right away
244 if (STROBE_E_RESET(m_byCTLB)) {
245 PIA_W_CALLBACK(m_stOutCB2, 1);
246 m_byOCB2 = 1;
247 }
248 }
249 }
250 // write DDR register
251 else {
252 if (m_byDDRB != byData) {
253 m_byDDRB = byData;
254
255 // send it to the output function
256 if (m_byDDRB)
257 PIA_W_CALLBACK(m_stOutB, m_byOB & m_byDDRB);
258 }
259 }
260 break;
261
262 /******************* port A control write *******************/
263 case PIA_CTLA:
264 // Bit 7 and 6 read only
265 byData &= 0x3f;
266
267 // CA2 is configured as output and in set/reset mode
268 if (C2_OUTPUT(byData)) {
269 // determine the new value
270 int temp = SET_C2(byData) ? 1 : 0;
271
272 // if this creates a transition, call the CA2 output function
273 if (m_byOCA2 ^ temp)
274 PIA_W_CALLBACK(m_stOutCA2, temp);
275
276 // set the new value
277 m_byOCA2 = temp;
278 }
279
280 // update the control register
281 m_byCTLA = (m_byCTLA & ~0x3F) | byData;
282
283 // update externals
284 UpdateInterrupts();
285 break;
286
287 /******************* port B control write *******************/
288 case PIA_CTLB:
289
290 /* Bit 7 and 6 read only - PD 16/01/00 */
291
292 byData &= 0x3f;
293
294 // CB2 is configured as output and in set/reset mode
295 if (C2_OUTPUT(byData)) {
296 // determine the new value
297 int temp = SET_C2(byData) ? 1 : 0;
298
299 // if this creates a transition, call the CA2 output function
300 if (m_byOCB2 ^ temp)
301 PIA_W_CALLBACK(m_stOutCB2, temp);
302
303 // set the new value
304 m_byOCB2 = temp;
305 }
306
307 // update the control register
308 m_byCTLB = (m_byCTLB & ~0x3F) | byData;
309
310 // update externals
311 UpdateInterrupts();
312 break;
313 }
314
315 }
316
317 void C6821::Reset()
318 {
319 m_byIA = 0;
320 m_byCA1 = 0;
321 m_byICA2 = 0;
322 m_byOA = 0;
323 m_byOCA2 = 0;
324 m_byDDRA = 0;
325 m_byCTLA = 0;
326 m_byIRQAState = 0;
327
328 m_byIB = 0;
329 m_byCB1 = 0;
330 m_byICB2 = 0;
331 m_byOB = 0;
332 m_byOCB2 = 0;
333 m_byDDRB = 0;
334 m_byCTLB = 0;
335 m_byIRQBState = 0;
336 }
337
338 void C6821::UpdateInterrupts()
339 {
340 BYTE byNewState;
341
342 // start with IRQ A
343 byNewState = 0;
344 if ( ( IRQ1( m_byCTLA ) && IRQ1_ENABLED( m_byCTLA ) ) ||
345 ( IRQ2( m_byCTLA ) && IRQ2_ENABLED( m_byCTLA ) ) )
346 byNewState = 1;
347
348 if ( byNewState != m_byIRQAState )
349 {
350 m_byIRQAState = byNewState;
351 PIA_W_CALLBACK( m_stOutIRQA, m_byIRQAState );
352 }
353
354 /* then do IRQ B */
355 byNewState = 0;
356 if ( ( IRQ1( m_byCTLB ) && IRQ1_ENABLED( m_byCTLB ) ) ||
357 ( IRQ2( m_byCTLB ) && IRQ2_ENABLED( m_byCTLB ) ) )
358 byNewState = 1;
359
360 if ( byNewState != m_byIRQBState )
361 {
362 m_byIRQBState = byNewState;
363 PIA_W_CALLBACK( m_stOutIRQB, m_byIRQBState );
364 }
365 }
366
367 void C6821::SetCA1(BYTE byData)
368 {
369 byData = byData ? 1 : 0;
370
371 // the new state has caused a transition
372 if ( m_byCA1 ^ byData )
373 {
374 // handle the active transition
375 if ( ( byData && C1_LOW_TO_HIGH( m_byCTLA ) ) ||
376 ( !byData && C1_HIGH_TO_LOW( m_byCTLA ) ) )
377 {
378 // mark the IRQ
379 SET_IRQ1(m_byCTLA);
380
381 // update externals
382 UpdateInterrupts();
383
384 // CA2 is configured as output and in read strobe mode and cleared by a CA1 transition
385 if ( C2_OUTPUT( m_byCTLA ) && C2_STROBE_MODE( m_byCTLA ) && STROBE_C1_RESET( m_byCTLA ) )
386 {
387 // call the CA2 output function
388 if ( !m_byOCA2 )
389 PIA_W_CALLBACK( m_stOutCA2, 1 );
390
391 // clear CA2
392 m_byOCA2 = 1;
393 }
394 }
395 }
396
397 // set the new value for CA1
398 m_byCA1 = byData;
399 }
400
401 void C6821::SetCA2(BYTE byData)
402 {
403 byData = byData ? 1 : 0;
404
405 // CA2 is in input mode
406 if ( C2_INPUT( m_byCTLA ) )
407 {
408 // the new state has caused a transition
409 if ( m_byICA2 ^ byData )
410 {
411 // handle the active transition
412 if ((byData && C2_LOW_TO_HIGH(m_byCTLA)) ||
413 (!byData && C2_HIGH_TO_LOW(m_byCTLA))) {
414 // mark the IRQ
415 SET_IRQ2(m_byCTLA);
416
417 // update externals
418 UpdateInterrupts();
419 }
420 }
421 }
422
423 // set the new value for CA2
424 m_byICA2 = byData;
425 }
426
427 void C6821::SetCB1(BYTE byData)
428 {
429 byData = byData ? 1 : 0;
430
431 // the new state has caused a transition
432 if ( m_byCB1 ^ byData )
433 {
434 // handle the active transition
435 if ( ( byData && C1_LOW_TO_HIGH( m_byCTLB ) ) ||
436 ( !byData && C1_HIGH_TO_LOW( m_byCTLB ) ) )
437 {
438 // mark the IRQ
439 SET_IRQ1( m_byCTLB );
440
441 // update externals
442 UpdateInterrupts();
443
444 // CB2 is configured as output and in read strobe mode and cleared by a CA1 transition
445 if ( C2_OUTPUT( m_byCTLB ) && C2_STROBE_MODE( m_byCTLB ) && STROBE_C1_RESET( m_byCTLB ) )
446 {
447 // the IRQ1 flag must have also been cleared
448 if ( !IRQ1( m_byCTLB ) )
449 {
450 // call the CB2 output function
451 if ( !m_byOCB2 )
452 PIA_W_CALLBACK( m_stOutCB2, 1 );
453
454 // clear CB2
455 m_byOCB2 = 1;
456 }
457 }
458 }
459 }
460
461 // set the new value for CA1
462 m_byCB1 = byData;
463
464 }
465
466 void C6821::SetCB2(BYTE byData)
467 {
468 byData = byData ? 1 : 0;
469
470 // CA2 is in input mode
471 if ( C2_INPUT( m_byCTLB ) )
472 {
473 // the new state has caused a transition
474 if ( m_byICB2 ^ byData )
475 {
476 // handle the active transition
477 if ( ( byData && C2_LOW_TO_HIGH( m_byCTLB ) ) ||
478 ( !byData && C2_HIGH_TO_LOW( m_byCTLB ) ) )
479 {
480 // mark the IRQ
481 SET_IRQ2( m_byCTLB );
482
483 // update externals
484 UpdateInterrupts();
485 }
486 }
487 }
488
489 // set the new value for CA2
490 m_byICB2 = byData;
491 }
492
493 void C6821::SetPA(BYTE byData)
494 {
495 m_byIA = byData;
496 }
497
498 void C6821::SetPB(BYTE byData)
499 {
500 m_byIB = byData;
501 }
502
503 BYTE C6821::GetPA()
504 {
505 return m_byOA & m_byDDRA;
506 }
507
508 BYTE C6821::GetPB()
509 {
510 return m_byOB & m_byDDRB;
511 }
0 /*
1 AppleWin : An Apple //e emulator for Windows
2
3 Copyright (C) 1994-1996, Michael O'Brien
4 Copyright (C) 1999-2001, Oliver Schmidt
5 Copyright (C) 2002-2005, Tom Charlesworth
6 Copyright (C) 2006-2007, Tom Charlesworth, Michael Pohoreski, Nick Westgate
7
8 AppleWin is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 AppleWin is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with AppleWin; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 /* Description: Log
24 *
25 * Author: Nick Westgate
26 */
27
28 #include "stdafx.h"
29 //#pragma hdrstop
30 #include <string.h>
31
32 //---------------------------------------------------------------------------
33
34 void LogOutput(LPCTSTR format, ...)
35 {
36 TCHAR output[256];
37
38 va_list args;
39 va_start(args, format);
40
41 vsnprintf(output, sizeof(output) - 1, format, args);
42 // OutputDebugString(output);
43 fprintf(stderr, "%s", output);
44 }
45
46 //---------------------------------------------------------------------------
0 /*
1 AppleWin : An Apple //e emulator for Windows
2
3 Copyright (C) 1994-1996, Michael O'Brien
4 Copyright (C) 1999-2001, Oliver Schmidt
5 Copyright (C) 2002-2005, Tom Charlesworth
6 Copyright (C) 2006-2007, Tom Charlesworth, Michael Pohoreski, Nick Westgate
7
8 AppleWin is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 AppleWin is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with AppleWin; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 /* Description: Log
24 *
25 * Author: Nick Westgate
26 */
27
28 #include "stdafx.h"
29 //#pragma hdrstop
30 #include <string.h>
31
32 //---------------------------------------------------------------------------
33
34 void LogOutput(LPCTSTR format, ...)
35 {
36 TCHAR output[256];
37
38 va_list args;
39 va_start(args, format);
40
41 vsnprintf(output, sizeof(output) - 1, format, args);
42 // OutputDebugString(output);
43 fprintf(stderr, "%s", output);
44 }
45
46 //---------------------------------------------------------------------------
0 // Based on Apple in PC's mousecard.cpp
1 // - Permission given by Kyle Kim to reuse in AppleWin
2 /* Adaptation for SDL and POSIX (l) by beom beotiger, Nov-Dec 2007 */
3
4 #include "stdafx.h"
5 //#pragma hdrstop
6 //#include "resource.h"
7 #include "MouseInterface.h"
8
9 // Sets mouse mode
10 #define MOUSE_SET 0x00
11 // Reads mouse position
12 #define MOUSE_READ 0x10
13 // Services mouse interrupt
14 #define MOUSE_SERV 0x20
15 // Clears mouse positions to 0 (for delta mode)
16 #define MOUSE_CLEAR 0x30
17 // Sets mouse position to a user-defined pos
18 #define MOUSE_POS 0x40
19 // Resets mouse clamps to default values
20 // Sets mouse position to 0,0
21 #define MOUSE_INIT 0x50
22 // Sets mouse bounds in a window
23 #define MOUSE_CLAMP 0x60
24 // Sets mouse to upper-left corner of clamp win
25 #define MOUSE_HOME 0x70
26
27 // Set VBL Timing : 0x90 is 60Hz, 0x91 is 50Hz
28 #define MOUSE_TIME 0x90
29
30 #define BIT0 0x01
31 #define BIT1 0x02
32 #define BIT2 0x04
33 #define BIT3 0x08
34 #define BIT4 0x10
35 #define BIT5 0x20
36 #define BIT6 0x40
37 #define BIT7 0x80
38
39
40 char MouseInterface_rom[] =
41 "\x2C\x58\xFF\x70\x1B\x38\x90\x18\xB8\x50\x15\x01\x20\xF4\xF4\xF4"
42 "\xF4\x00\xB3\xC4\x9B\xA4\xC0\x8A\xDD\xBC\x48\xF0\x53\xE1\xE6\xEC"
43 "\x08\x78\x8D\xF8\x07\x48\x98\x48\x8A\x48\x20\x58\xFF\xBA\xBD\x00"
44 "\x01\xAA\x08\x0A\x0A\x0A\x0A\x28\xA8\xAD\xF8\x07\x8E\xF8\x07\x48"
45 "\xA9\x08\x70\x67\x90\x4D\xB0\x55\x29\x01\x09\xF0\x9D\x38\x06\xA9"
46 "\x02\xD0\x40\x29\x0F\x09\x90\xD0\x35\xFF\xFF\xB9\x83\xC0\x29\xFB"
47 "\x99\x83\xC0\xA9\x3E\x99\x82\xC0\xB9\x83\xC0\x09\x04\x99\x83\xC0"
48 "\xB9\x82\xC0\x29\xC1\x1D\xB8\x05\x99\x82\xC0\x68\xF0\x0A\x6A\x90"
49 "\x75\x68\xAA\x68\xA8\x68\x28\x60\x18\x60\x29\x01\x09\x60\x9D\x38"
50 "\x06\xA9\x0E\x9D\xB8\x05\xA9\x01\x48\xD0\xC0\xA9\x0C\x9D\xB8\x05"
51 "\xA9\x02\xD0\xF4\xA9\x30\x9D\x38\x06\xA9\x06\x9D\xB8\x05\xA9\x00"
52 "\x48\xF0\xA8\xC9\x10\xB0\xD2\x9D\x38\x07\x90\xEA\xA9\x04\xD0\xEB"
53 "\xA9\x40\xD0\xCA\xA4\x06\xA9\x60\x85\x06\x20\x06\x00\x84\x06\xBA"
54 "\xBD\x00\x01\xAA\x0A\x0A\x0A\x0A\xA8\xA9\x20\xD0\xC9\xA9\x70\xD0"
55 "\xC5\x48\xA9\xA0\xD0\xA8\x29\x0F\x09\xB0\xD0\xBA\xA9\xC0\xD0\xB6"
56 "\xA9\x02\xD0\xB7\xA2\x03\x38\x60\xFF\xFF\xFF\xD6\xFF\xFF\xFF\x01"
57 "\x98\x48\xA5\x06\x48\xA5\x07\x48\x86\x07\xA9\x27\x85\x06\x20\x58"
58 "\xFC\xA0\x00\xB1\x06\xF0\x06\x20\xED\xFD\xC8\xD0\xF6\x68\x85\x07"
59 "\x68\x85\x06\x68\xA8\xD0\x5B\xC1\xF0\xF0\xEC\xE5\xCD\xEF\xF5\xF3"
60 "\xE5\x8D\xC3\xEF\xF0\xF9\xF2\xE9\xE7\xE8\xF4\xA0\xB1\xB9\xB8\xB3"
61 "\xA0\xE2\xF9\xA0\xC1\xF0\xF0\xEC\xE5\xA0\xC3\xEF\xED\xF0\xF5\xF4"
62 "\xE5\xF2\xAC\xA0\xC9\xEE\xE3\xAE\x8D\x8D\xC2\xE1\xE3\xE8\xED\xE1"
63 "\xEE\xAF\xCD\xE1\xF2\xEB\xF3\xAF\xCD\xE1\xE3\xCB\xE1\xF9\x8D\x00"
64 "\xB9\x82\xC0\x29\xF1\x1D\xB8\x05\x99\x82\xC0\x68\x30\x0C\xF0\x80"
65 "\xD0\x09\xA9\x00\x9D\xB8\x05\x48\xF0\xE6\x60\xBD\x38\x07\x29\x0F"
66 "\x09\x20\x9D\x38\x07\x8A\x48\x48\x48\x48\xA9\xAA\x48\xBD\x38\x06"
67 "\x48\xA9\x0C\x9D\xB8\x05\xA9\x00\x48\xF0\xC5\xA9\xB3\x48\xAD\x78"
68 "\x04\x18\x90\xEC\xA9\xBC\x48\xAD\xF8\x04\x18\x90\xE3\xA9\x81\x48"
69 "\x7E\x38\x06\x90\x05\xAD\x78\x05\xB0\xD6\x8A\x48\xA9\xD8\x48\xA9"
70 "\x0C\x9D\xB8\x05\xA9\x01\x48\xD0\x97\xBD\x38\x06\x8D\x78\x05\x60"
71 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
72 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC2"
73 "\xBD\x38\x07\x29\x0F\x09\x40\x9D\x38\x07\x8A\x48\x48\x48\xA9\x11"
74 "\xD0\x27\xA9\x1E\x48\xA9\x0C\x9D\xB8\x05\xA9\x01\x48\xD0\x51\xAD"
75 "\xB3\xFB\xC9\x06\xD0\x21\xAD\x19\xC0\x30\xFB\xAD\x19\xC0\x10\xFB"
76 "\xAD\x19\xC0\x30\xFB\xA9\x7F\xD0\x00\x48\xA9\x50\x48\xA9\x0C\x9D"
77 "\xB8\x05\xA9\x00\x48\xF0\x29\xA5\x06\x48\xA5\x07\x48\x98\x48\xA9"
78 "\x20\x85\x07\xA0\x00\x84\x06\xA9\x00\x91\x06\xC8\xD0\xFB\xE6\x07"
79 "\xA5\x07\xC9\x40\xD0\xF1\x68\xA8\xA5\x08\x48\xA9\x00\xF0\x1C\xFF"
80 "\xB9\x82\xC0\x29\xF1\x1D\xB8\x05\x99\x82\xC0\x68\x30\x0A\xF0\x80"
81 "\xA9\x00\x9D\xB8\x05\x48\xF0\xE8\x60\xD0\xAE\xA9\x01\x8D\xD0\x3F"
82 "\x8D\xE0\x3F\xAD\x57\xC0\xAD\x54\xC0\xAD\x52\xC0\xAD\x50\xC0\xEA"
83 "\x85\x06\x85\x07\x85\x08\xE6\x06\xD0\x0E\xE6\x07\xD0\x0C\xE6\x08"
84 "\xA5\x08\xC9\x01\x90\x0A\xB0\x1F\x08\x28\x08\x28\xA9\x00\xA5\x00"
85 "\xAD\xFF\xCF\xB9\x82\xC0\x4A\xEA\xEA\xB0\xDB\xAD\xFF\xCF\xB9\x82"
86 "\xC0\x4A\xA5\x00\xEA\xB0\xCF\x68\x85\x08\x68\x85\x07\x68\x85\x06"
87 "\xA9\xE3\xD0\xA5\xAD\x51\xC0\xAD\x56\xC0\x18\x90\x93\xFF\xFF\xFF"
88 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC1"
89 "\xBD\x38\x06\xC9\x20\xD0\x06\xA9\x7F\x69\x01\x70\x01\xB8\xB9\x82"
90 "\xC0\x30\xFB\xB9\x81\xC0\x29\xFB\x99\x81\xC0\xA9\xFF\x99\x80\xC0"
91 "\xB9\x81\xC0\x09\x04\x99\x81\xC0\xBD\x38\x06\x99\x80\xC0\xB9\x82"
92 "\xC0\x09\x20\x99\x82\xC0\xB9\x82\xC0\x10\xFB\x29\xDF\x99\x82\xC0"
93 "\x70\x44\xBD\x38\x06\xC9\x30\xD0\x35\xA9\x00\x9D\xB8\x04\x9D\xB8"
94 "\x03\x9D\x38\x05\x9D\x38\x04\xF0\x25\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
95 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
96 "\xB9\x82\xC0\x29\xF1\x1D\xB8\x05\x99\x82\xC0\x68\xF0\x82\xA9\x00"
97 "\x9D\xB8\x05\x48\xF0\xEA\xB9\x81\xC0\x29\xFB\x99\x81\xC0\xA9\x00"
98 "\x99\x80\xC0\xB9\x81\xC0\x09\x04\x99\x81\xC0\xB9\x82\xC0\x0A\x10"
99 "\xFA\xB9\x80\xC0\x9D\x38\x06\xB9\x82\xC0\x09\x10\x99\x82\xC0\xB9"
100 "\x82\xC0\x0A\x30\xFA\xB9\x82\xC0\x29\xEF\x99\x82\xC0\xBD\xB8\x06"
101 "\x29\xF1\x1D\x38\x06\x9D\xB8\x06\x29\x0E\xD0\xB2\xA9\x00\x9D\xB8"
102 "\x05\xA9\x02\x48\xD0\x9A\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
103 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
104 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC3"
105 "\xE4\x37\xD0\x2D\xA9\x07\xC5\x36\xF0\x27\x85\x36\x68\xC9\x8D\xF0"
106 "\x74\x29\x01\x09\x80\x9D\x38\x07\x8A\x48\xA9\x84\x48\xBD\x38\x07"
107 "\x4A\xA9\x80\xB0\x01\x0A\x48\xA9\x0C\x9D\xB8\x05\xA9\x00\x48\xF0"
108 "\x3F\xE4\x39\xD0\xD7\xA9\x05\x85\x38\xBD\x38\x07\x29\x01\xD0\x14"
109 "\x68\x68\x68\x68\xA9\x00\x9D\xB8\x03\x9D\xB8\x04\x9D\x38\x04\x9D"
110 "\x38\x05\xF0\x3C\xBD\x38\x07\x29\x01\x09\x80\x9D\x38\x07\x8A\x48"
111 "\xA9\xA1\x48\xA9\x10\x48\xA9\x0C\xD0\x30\xFF\xFF\xFF\xFF\xFF\xFF"
112 "\xB9\x82\xC0\x29\xF1\x1D\xB8\x05\x99\x82\xC0\x68\x30\x11\xF0\x80"
113 "\x6A\xB0\x89\x90\xB4\xA9\x00\x9D\xB8\x05\xA9\x01\x48\xD0\xE1\x60"
114 "\xA9\xC0\x9D\xB8\x06\x8C\x22\x02\xA9\x0A\x9D\xB8\x05\xA9\x00\x48"
115 "\xF0\xCE\x68\x68\x68\x68\xA9\x05\x9D\x38\x06\xB9\x81\xC0\x29\xFB"
116 "\x99\x81\xC0\xA9\x00\x99\x80\xC0\xB9\x81\xC0\x09\x04\x99\x81\xC0"
117 "\xB9\x82\xC0\x0A\x10\xFA\xB9\x80\xC0\x48\xB9\x82\xC0\x09\x10\x99"
118 "\x82\xC0\xB9\x82\xC0\x0A\x30\xFA\xB9\x82\xC0\x29\xEF\x99\x82\xC0"
119 "\xDE\x38\x06\xD0\xDB\x68\x9D\xB8\x06\x68\x9D\x38\x05\x68\x9D\x38"
120 "\x04\x68\x9D\xB8\x04\x68\x9D\xB8\x03\x18\x90\x99\xFF\xFF\xFF\xC8"
121 "\x8A\x48\x48\x48\xA9\x12\x48\xBC\xB8\x03\xBD\xB8\x04\xAA\x98\xA0"
122 "\x05\xD0\x6D\xAE\xF8\x07\xA9\x24\x48\xBC\x38\x04\xBD\x38\x05\xAA"
123 "\x98\xA0\x0C\xD0\x5B\xAE\xF8\x07\xA9\x43\x48\xAD\x00\xC0\x0A\x08"
124 "\xBD\xB8\x06\x2A\x2A\x2A\x29\x03\x49\x03\x38\x69\x00\x28\xA2\x00"
125 "\xA0\x10\xD0\x4D\xA9\x8D\x8D\x11\x02\x48\xA9\x11\x48\x48\xA9\x00"
126 "\xF0\x12\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
127 "\xFF\xFF\xFF\xFF\xAE\xF8\x07\xAC\x22\x02\x9D\xB8\x05\xA9\x01\x48"
128 "\xB9\x82\xC0\x29\xF1\x1D\xB8\x05\x99\x82\xC0\x68\x30\x4E\xF0\x80"
129 "\xE0\x80\x90\x0D\x49\xFF\x69\x00\x48\x8A\x49\xFF\x69\x00\xAA\x68"
130 "\x38\x8D\x21\x02\x8E\x20\x02\xA9\xAB\x90\x02\xA9\xAD\x48\xA9\xAC"
131 "\x99\x01\x02\xA2\x11\xA9\x00\x18\x2A\xC9\x0A\x90\x02\xE9\x0A\x2E"
132 "\x21\x02\x2E\x20\x02\xCA\xD0\xF0\x09\xB0\x99\x00\x02\x88\xF0\x08"
133 "\xC0\x07\xF0\x04\xC0\x0E\xD0\xDB\x68\x99\x00\x02\x60\xFF\xFF\xFF"
134 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
135 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
136 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xCD"
137 "\xB8\x50\x13\xBD\x38\x07\x29\x01\xF0\x47\xA9\x10\x48\xA9\x05\x9D"
138 "\x38\x06\xA9\x7F\x69\x01\xB9\x82\xC0\x30\xFB\xB9\x81\xC0\x29\xFB"
139 "\x99\x81\xC0\xA9\xFF\x99\x80\xC0\xB9\x81\xC0\x09\x04\x99\x81\xC0"
140 "\x68\x99\x80\xC0\xB9\x82\xC0\x09\x20\x99\x82\xC0\xB9\x82\xC0\x10"
141 "\xFB\x29\xDF\x99\x82\xC0\x70\x3F\x70\x07\xBD\x38\x07\x4A\x4A\x4A"
142 "\x4A\xB8\x9D\xB8\x05\xF0\x02\xA9\x80\x48\x50\x14\xFF\xFF\xFF\xFF"
143 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
144 "\xB9\x82\xC0\x29\xF1\x1D\xB8\x05\x99\x82\xC0\x68\xF0\x82\xC9\x02"
145 "\xF0\x81\xD0\x02\xF0\xC2\xB8\xB9\x81\xC0\x29\xFB\x99\x81\xC0\xA9"
146 "\x00\x99\x80\xC0\xB9\x81\xC0\x09\x04\x99\x81\xC0\xB9\x82\xC0\x0A"
147 "\x10\xFA\xB9\x80\xC0\x70\x05\x9D\x38\x06\x50\x01\x48\xB9\x82\xC0"
148 "\x09\x10\x99\x82\xC0\xB9\x82\xC0\x0A\x30\xFA\xB9\x82\xC0\x29\xEF"
149 "\x99\x82\xC0\x50\x19\xDE\x38\x06\xD0\xD2\x68\x9D\xB8\x06\x68\x9D"
150 "\x38\x05\x68\x9D\x38\x04\x68\x9D\xB8\x04\x68\x9D\xB8\x03\xA9\x00"
151 "\xF0\xA2\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
152 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC1"
153 "\xBD\x38\x06\xC9\x40\xF0\x22\xC9\x60\xF0\x0D\xC9\x61\xF0\x09\xC9"
154 "\xA0\xD0\x2E\x48\xA9\x02\xD0\x45\xAD\xF8\x05\x48\xAD\x78\x05\x48"
155 "\xAD\xF8\x04\x48\xAD\x78\x04\xB0\x0F\xBD\x38\x05\x48\xBD\x38\x04"
156 "\x48\xBD\xB8\x04\x48\xBD\xB8\x03\x48\xBD\x38\x06\x48\xA9\x05\xD0"
157 "\x1C\x29\x0C\x4A\x4A\x4A\xB0\x3E\x4A\x90\x0C\xAD\x78\x05\x48\xBD"
158 "\x38\x06\x48\xA9\x02\xD0\x06\xBD\x38\x06\x48\xA9\x01\x9D\x38\x06"
159 "\xD0\x4F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
160 "\xB9\x82\xC0\x29\xF1\x1D\xB8\x05\x99\x82\xC0\x68\xD0\x82\xA9\x00"
161 "\x9D\xB8\x05\x48\xF0\xEA\x4A\xB0\x13\xAD\xF8\x04\x48\xAD\x78\x04"
162 "\x48\xBD\x38\x06\x48\xA9\x03\x9D\x38\x06\xD0\x15\xAD\x78\x05\x48"
163 "\xAD\xF8\x04\x48\xAD\x78\x04\x48\xBD\x38\x06\x48\xA9\x04\x9D\x38"
164 "\x06\xB9\x82\xC0\x30\xFB\xB9\x81\xC0\x29\xFB\x99\x81\xC0\xA9\xFF"
165 "\x99\x80\xC0\xB9\x81\xC0\x09\x04\x99\x81\xC0\x68\x99\x80\xC0\xB9"
166 "\x82\xC0\x09\x20\x99\x82\xC0\xB9\x82\xC0\x10\xFB\x29\xDF\x99\x82"
167 "\xC0\xDE\x38\x06\xF0\x98\xB9\x82\xC0\x30\xFB\x10\xD6\xFF\xFF\xFF"
168 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xCE"
169 ;
170
171
172 WRITE_HANDLER( M6821_Listener_B )
173 {
174 ((CMouseInterface*)objTo)->On6821_B( byData );
175 }
176
177 WRITE_HANDLER( M6821_Listener_A )
178 {
179 ((CMouseInterface*)objTo)->On6821_A( byData );
180 }
181
182 //CALLBACK_HANDLER( MouseHandler )
183 //{
184 // ((CMouseInterface*)objTo)->OnMouseEvent();
185 //}
186
187 //===========================================================================
188
189 CMouseInterface::CMouseInterface() :
190 m_pSlotRom(NULL)
191 {
192 m_6821.SetListenerB( this, M6821_Listener_B );
193 m_6821.SetListenerA( this, M6821_Listener_A );
194 // g_cDIMouse.SetMouseListener( this, MouseHandler );
195 m_by6821A = 0;
196 m_by6821B = 0x40; // Set PB6
197 m_6821.SetPB(m_by6821B);
198 m_bVBL = FALSE;
199
200 //
201
202 m_iX = 0;
203 m_iMinX = 0;
204 m_iMaxX = 1023;
205 m_iRangeX = 0;
206
207 m_iY = 0;
208 m_iMinY = 0;
209 m_iMaxY = 1023;
210 m_iRangeY = 0;
211
212 m_bButtons[0] = m_bButtons[1] = FALSE;
213
214 //
215
216 Reset();
217 memset( m_byBuff, 0, sizeof( m_byBuff ) );
218 m_bActive = false;
219 }
220
221 CMouseInterface::~CMouseInterface()
222 {
223 delete [] m_pSlotRom;
224 }
225
226 //===========================================================================
227
228 void CMouseInterface::Initialize(LPBYTE pCxRomPeripheral, UINT uSlot)
229 {
230 const UINT FW_SIZE = 2*1024;
231
232 // HRSRC hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_MOUSEINTERFACE_FW), "FIRMWARE");
233 // if(hResInfo == NULL)
234 // return;
235 //
236 // DWORD dwResSize = SizeofResource(NULL, hResInfo);
237 // if(dwResSize != FW_SIZE)
238 // return;
239 //
240 // HGLOBAL hResData = LoadResource(NULL, hResInfo);
241 // if(hResData == NULL)
242 // return;
243
244 // instead of reading wndzooozes resources, just read it from a mere file on a disk!? bb
245 // #define IDR_MOUSEINTERFACE_FW "MouseInterface.rom"
246 // char BUFFER[FW_SIZE];
247 // FILE * hdfile = NULL;
248 // hdfile = fopen(IDR_MOUSEINTERFACE_FW, "rb");
249 // if(hdfile == NULL) return; // no file?
250 // UINT nbytes = fread(BUFFER, 1, FW_SIZE, hdfile);
251 // fclose(hdfile);
252 // if(nbytes != FW_SIZE) return; // have not read enough?
253 //
254
255 BYTE* pData = (BYTE*) MouseInterface_rom; // NB. Don't need to unlock resource
256
257 m_uSlot = uSlot;
258
259 if (m_pSlotRom == NULL)
260 {
261 m_pSlotRom = new BYTE [FW_SIZE];
262
263 if (m_pSlotRom)
264 memcpy(m_pSlotRom, pData, FW_SIZE);
265 }
266
267 //
268
269 SetSlotRom();
270 RegisterIoHandler(uSlot, &CMouseInterface::IORead, &CMouseInterface::IOWrite, NULL, NULL, this, NULL);
271 m_bActive = true;
272 printf("MouseInterface Rom loaded and registered\n");
273 }
274
275 void CMouseInterface::SetSlotRom()
276 {
277 LPBYTE pCxRomPeripheral = MemGetCxRomPeripheral();
278 if (pCxRomPeripheral == NULL)
279 return;
280
281 UINT uOffset = (m_by6821B << 7) & 0x0700;
282 memcpy(pCxRomPeripheral+m_uSlot*256, m_pSlotRom+uOffset, 256);
283 if (mem)
284 memcpy(mem+0xC000+m_uSlot*256, m_pSlotRom+uOffset, 256);
285 }
286
287 //===========================================================================
288
289 BYTE CMouseInterface::IORead(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft)
290 {
291 UINT uSlot = ((uAddr & 0xff) >> 4) - 8;
292 CMouseInterface* pMouseIF = (CMouseInterface*) MemGetSlotParameters(uSlot);
293
294 BYTE byRS;
295 byRS = uAddr & 3;
296 return pMouseIF->m_6821.Read( byRS );
297 }
298
299 BYTE CMouseInterface::IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft)
300 {
301 UINT uSlot = ((uAddr & 0xff) >> 4) - 8;
302 CMouseInterface* pMouseIF = (CMouseInterface*) MemGetSlotParameters(uSlot);
303
304 BYTE byRS;
305 byRS = uAddr & 3;
306 pMouseIF->m_6821.Write( byRS, uValue );
307
308 return 0;
309 }
310
311 //===========================================================================
312
313 void CMouseInterface::On6821_A(BYTE byData)
314 {
315 m_by6821A = byData;
316 }
317
318 void CMouseInterface::On6821_B(BYTE byData)
319 {
320 BYTE byDiff = ( m_by6821B ^ byData ) & 0x3E;
321
322 if ( byDiff )
323 {
324 m_by6821B &= ~0x3E;
325 m_by6821B |= byData & 0x3E;
326 if ( byDiff & BIT5 ) // Write to 0285 chip
327 {
328 if ( byData & BIT5 )
329 m_by6821B |= BIT7; // OK, I'm ready to read from MC6821
330 else // Clock Activate for read
331 {
332 m_byBuff[m_nBuffPos++] = m_by6821A;
333 if ( m_nBuffPos == 1 )
334 OnCommand();
335 if ( m_nBuffPos == m_nDataLen || m_nBuffPos > 7 )
336 {
337 OnWrite(); // Have written all, Commit the command.
338 m_nBuffPos = 0;
339 }
340 m_by6821B &= ~BIT7; // for next reading
341 m_6821.SetPB( m_by6821B );
342 }
343
344 }
345 if ( byDiff & BIT4 ) // Read from 0285 chip ?
346 {
347 if ( byData & BIT4 )
348 m_by6821B &= ~BIT6; // OK, I'll prepare next value
349 else // Clock Activate for write
350 {
351 if ( m_nBuffPos ) // if m_nBuffPos is 0, something goes wrong!
352 m_nBuffPos++;
353 if ( m_nBuffPos == m_nDataLen || m_nBuffPos > 7 )
354 m_nBuffPos = 0; // Have read all, ready for next command.
355 else
356 m_6821.SetPA( m_byBuff[m_nBuffPos] );
357 m_by6821B |= BIT6; // for next writing
358 }
359 }
360 m_6821.SetPB( m_by6821B );
361
362 //
363
364 SetSlotRom(); // Update Cn00 ROM page
365 }
366 }
367
368
369 void CMouseInterface::OnCommand()
370 {
371 switch( m_byBuff[0] & 0xF0 )
372 {
373 case MOUSE_SET:
374 m_nDataLen = 1;
375 m_byMode = m_byBuff[0] & 0x0F;
376 break;
377 case MOUSE_READ: // Read
378 m_nDataLen = 6;
379 m_byState &= 0x20;
380 m_nX = m_iX;
381 m_nY = m_iY;
382 if ( m_bBtn0 ) m_byState |= 0x40; // Previous Button 0
383 if ( m_bBtn1 ) m_byState |= 0x01; // Previous Button 1
384 m_bBtn0 = m_bButtons[0];
385 m_bBtn1 = m_bButtons[1];
386 if ( m_bBtn0 ) m_byState |= 0x80; // Current Button 0
387 if ( m_bBtn1 ) m_byState |= 0x10; // Current Button 1
388 m_byBuff[1] = m_nX & 0xFF;
389 m_byBuff[2] = ( m_nX >> 8 ) & 0xFF;
390 m_byBuff[3] = m_nY & 0xFF;
391 m_byBuff[4] = ( m_nY >> 8 ) & 0xFF;
392 m_byBuff[5] = m_byState; // button 0/1 interrupt status
393 m_byState &= ~0x20;
394 break;
395 case MOUSE_SERV:
396 m_nDataLen = 2;
397 m_byBuff[1] = m_byState & ~0x20; // reason of interrupt
398 CpuIrqDeassert(IS_MOUSE);
399 break;
400 case MOUSE_CLEAR:
401 Reset();
402 m_nDataLen = 1;
403 break;
404 case MOUSE_POS:
405 m_nDataLen = 5;
406 break;
407 case MOUSE_INIT:
408 m_nDataLen = 3;
409 m_byBuff[1] = 0xFF; // I don't know what it is
410 break;
411 case MOUSE_CLAMP:
412 m_nDataLen = 5;
413 break;
414 case MOUSE_HOME:
415 m_nDataLen = 1;
416 SetPosition( 0, 0 );
417 break;
418 case MOUSE_TIME: // 0x90
419 switch( m_byBuff[0] & 0x0C )
420 {
421 case 0x00: m_nDataLen = 1; break; // write cmd ( #$90 is DATATIME 60Hz, #$91 is 50Hz )
422 case 0x04: m_nDataLen = 3; break; // write cmd, $0478, $04F8
423 case 0x08: m_nDataLen = 2; break; // write cmd, $0578
424 case 0x0C: m_nDataLen = 4; break; // write cmd, $0478, $04F8, $0578
425 }
426 break;
427 case 0xA0:
428 m_nDataLen = 2;
429 break;
430 case 0xB0:
431 case 0xC0:
432 m_nDataLen = 1;
433 break;
434 default:
435 m_nDataLen = 1;
436 //TRACE( "CMD : UNKNOWN CMD : #$%02X\n", m_byBuff[0] );
437 //_ASSERT(0);
438 break;
439 }
440 m_6821.SetPA( m_byBuff[1] );
441 }
442
443 void CMouseInterface::OnWrite()
444 {
445 int nMin, nMax;
446 switch( m_byBuff[0] & 0xF0 )
447 {
448 case MOUSE_CLAMP:
449 nMin = ( m_byBuff[3] << 8 ) | m_byBuff[1];
450 nMax = ( m_byBuff[4] << 8 ) | m_byBuff[2];
451 if ( m_byBuff[0] & 1 ) // Clamp Y
452 ClampY( nMin, nMax );
453 else // Clamp X
454 ClampX( nMin, nMax );
455 break;
456 case MOUSE_POS:
457 m_nX = ( m_byBuff[2] << 8 ) | m_byBuff[1];
458 m_nY = ( m_byBuff[4] << 8 ) | m_byBuff[3];
459 SetPosition( m_nX, m_nY );
460 break;
461 case MOUSE_INIT:
462 m_nX = 0;
463 m_nY = 0;
464 ClampX( 0, 1023 );
465 ClampY( 0, 1023 );
466 SetPosition( 0, 0 );
467 break;
468 }
469 }
470
471 void CMouseInterface::OnMouseEvent()
472 {
473 int byState = 0;
474
475 if ( !( m_byMode & 1 ) ) // Mouse Off
476 return;
477
478 BOOL bBtn0 = m_bButtons[0];
479 BOOL bBtn1 = m_bButtons[1];
480 if ( (UINT) m_nX != m_iX || (UINT) m_nY != m_iY )
481 byState |= 0x22; // X/Y moved since last READMOUSE | Movement interrupt
482 if ( m_bBtn0 != bBtn0 || m_bBtn1 != bBtn1 )
483 byState |= 0x04; // Button 0/1 interrupt
484 if ( m_bVBL )
485 byState |= 0x08;
486 //byState &= m_byMode & 0x2E;
487 byState &= ((m_byMode & 0x0E) | 0x20); // Keep "X/Y moved since last READMOUSE" for next MOUSE_READ (Contiki v1.3 uses this)
488
489 if ( byState & 0x0E )
490 {
491 m_byState |= byState;
492 CpuIrqAssert(IS_MOUSE);
493 }
494 }
495
496 void CMouseInterface::SetVBlank(bool bVBL)
497 {
498 if ( m_bVBL != bVBL )
499 {
500 m_bVBL = bVBL;
501 if ( m_bVBL ) // Rising edge
502 OnMouseEvent();
503 }
504 }
505
506 void CMouseInterface::Reset()
507 {
508 m_nBuffPos = 0;
509 m_nDataLen = 1;
510
511 m_byMode = 0;
512 m_byState = 0;
513 m_nX = 0;
514 m_nY = 0;
515 m_bBtn0 = 0;
516 m_bBtn1 = 0;
517 ClampX( 0, 1023 );
518 ClampY( 0, 1023 );
519 SetPosition( 0, 0 );
520
521 // CpuIrqDeassert(IS_MOUSE);
522 }
523
524 //===========================================================================
525
526 void CMouseInterface::ClampX(int iMinX, int iMaxX)
527 {
528 if ( iMinX < 0 || iMinX > iMaxX )
529 return;
530 m_iMaxX = iMaxX;
531 m_iMinX = iMinX;
532 if ( m_iX > m_iMaxX ) m_iX = m_iMaxX; else if ( m_iX < m_iMinX ) m_iX = m_iMinX;
533 }
534
535 void CMouseInterface::ClampY(int iMinY, int iMaxY)
536 {
537 if ( iMinY < 0 || iMinY > iMaxY )
538 return;
539 m_iMaxY = iMaxY;
540 m_iMinY = iMinY;
541 if ( m_iY > m_iMaxY ) m_iY = m_iMaxY; else if ( m_iY < m_iMinX ) m_iY = m_iMinY;
542 }
543
544 void CMouseInterface::SetPosition(int xvalue, int yvalue)
545 {
546 if ((m_iRangeX == 0) || (m_iRangeY == 0))
547 {
548 m_nX = m_iX = m_iMinX;
549 m_nY = m_iY = m_iMinY;
550 return;
551 }
552
553 m_iX = (UINT) ((xvalue*m_iMaxX) / m_iRangeX);
554 m_iY = (UINT) ((yvalue*m_iMaxY) / m_iRangeY);
555 }
556
557 void CMouseInterface::SetPosition(int xvalue, int xrange, int yvalue, int yrange)
558 {
559 m_iRangeX = (UINT) xrange;
560 m_iRangeY = (UINT) yrange;
561
562 SetPosition(xvalue, yvalue);
563 OnMouseEvent();
564 }
565
566 void CMouseInterface::SetButton(eBUTTON Button, eBUTTONSTATE State)
567 {
568 m_bButtons[Button]= (State == BUTTON_DOWN) ? TRUE : FALSE;
569 OnMouseEvent();
570 }
0 // Based on Apple in PC's mousecard.cpp
1 // - Permission given by Kyle Kim to reuse in AppleWin
2 /* Adaptation for SDL and POSIX (l) by beom beotiger, Nov-Dec 2007 */
3
4 #include "stdafx.h"
5 //#pragma hdrstop
6 //#include "resource.h"
7 #include "MouseInterface.h"
8
9 // Sets mouse mode
10 #define MOUSE_SET 0x00
11 // Reads mouse position
12 #define MOUSE_READ 0x10
13 // Services mouse interrupt
14 #define MOUSE_SERV 0x20
15 // Clears mouse positions to 0 (for delta mode)
16 #define MOUSE_CLEAR 0x30
17 // Sets mouse position to a user-defined pos
18 #define MOUSE_POS 0x40
19 // Resets mouse clamps to default values
20 // Sets mouse position to 0,0
21 #define MOUSE_INIT 0x50
22 // Sets mouse bounds in a window
23 #define MOUSE_CLAMP 0x60
24 // Sets mouse to upper-left corner of clamp win
25 #define MOUSE_HOME 0x70
26
27 // Set VBL Timing : 0x90 is 60Hz, 0x91 is 50Hz
28 #define MOUSE_TIME 0x90
29
30 #define BIT0 0x01
31 #define BIT1 0x02
32 #define BIT2 0x04
33 #define BIT3 0x08
34 #define BIT4 0x10
35 #define BIT5 0x20
36 #define BIT6 0x40
37 #define BIT7 0x80
38
39
40 char MouseInterface_rom[] =
41 "\x2C\x58\xFF\x70\x1B\x38\x90\x18\xB8\x50\x15\x01\x20\xF4\xF4\xF4"
42 "\xF4\x00\xB3\xC4\x9B\xA4\xC0\x8A\xDD\xBC\x48\xF0\x53\xE1\xE6\xEC"
43 "\x08\x78\x8D\xF8\x07\x48\x98\x48\x8A\x48\x20\x58\xFF\xBA\xBD\x00"
44 "\x01\xAA\x08\x0A\x0A\x0A\x0A\x28\xA8\xAD\xF8\x07\x8E\xF8\x07\x48"
45 "\xA9\x08\x70\x67\x90\x4D\xB0\x55\x29\x01\x09\xF0\x9D\x38\x06\xA9"
46 "\x02\xD0\x40\x29\x0F\x09\x90\xD0\x35\xFF\xFF\xB9\x83\xC0\x29\xFB"
47 "\x99\x83\xC0\xA9\x3E\x99\x82\xC0\xB9\x83\xC0\x09\x04\x99\x83\xC0"
48 "\xB9\x82\xC0\x29\xC1\x1D\xB8\x05\x99\x82\xC0\x68\xF0\x0A\x6A\x90"
49 "\x75\x68\xAA\x68\xA8\x68\x28\x60\x18\x60\x29\x01\x09\x60\x9D\x38"
50 "\x06\xA9\x0E\x9D\xB8\x05\xA9\x01\x48\xD0\xC0\xA9\x0C\x9D\xB8\x05"
51 "\xA9\x02\xD0\xF4\xA9\x30\x9D\x38\x06\xA9\x06\x9D\xB8\x05\xA9\x00"
52 "\x48\xF0\xA8\xC9\x10\xB0\xD2\x9D\x38\x07\x90\xEA\xA9\x04\xD0\xEB"
53 "\xA9\x40\xD0\xCA\xA4\x06\xA9\x60\x85\x06\x20\x06\x00\x84\x06\xBA"
54 "\xBD\x00\x01\xAA\x0A\x0A\x0A\x0A\xA8\xA9\x20\xD0\xC9\xA9\x70\xD0"
55 "\xC5\x48\xA9\xA0\xD0\xA8\x29\x0F\x09\xB0\xD0\xBA\xA9\xC0\xD0\xB6"
56 "\xA9\x02\xD0\xB7\xA2\x03\x38\x60\xFF\xFF\xFF\xD6\xFF\xFF\xFF\x01"
57 "\x98\x48\xA5\x06\x48\xA5\x07\x48\x86\x07\xA9\x27\x85\x06\x20\x58"
58 "\xFC\xA0\x00\xB1\x06\xF0\x06\x20\xED\xFD\xC8\xD0\xF6\x68\x85\x07"
59 "\x68\x85\x06\x68\xA8\xD0\x5B\xC1\xF0\xF0\xEC\xE5\xCD\xEF\xF5\xF3"
60 "\xE5\x8D\xC3\xEF\xF0\xF9\xF2\xE9\xE7\xE8\xF4\xA0\xB1\xB9\xB8\xB3"
61 "\xA0\xE2\xF9\xA0\xC1\xF0\xF0\xEC\xE5\xA0\xC3\xEF\xED\xF0\xF5\xF4"
62 "\xE5\xF2\xAC\xA0\xC9\xEE\xE3\xAE\x8D\x8D\xC2\xE1\xE3\xE8\xED\xE1"
63 "\xEE\xAF\xCD\xE1\xF2\xEB\xF3\xAF\xCD\xE1\xE3\xCB\xE1\xF9\x8D\x00"
64 "\xB9\x82\xC0\x29\xF1\x1D\xB8\x05\x99\x82\xC0\x68\x30\x0C\xF0\x80"
65 "\xD0\x09\xA9\x00\x9D\xB8\x05\x48\xF0\xE6\x60\xBD\x38\x07\x29\x0F"
66 "\x09\x20\x9D\x38\x07\x8A\x48\x48\x48\x48\xA9\xAA\x48\xBD\x38\x06"
67 "\x48\xA9\x0C\x9D\xB8\x05\xA9\x00\x48\xF0\xC5\xA9\xB3\x48\xAD\x78"
68 "\x04\x18\x90\xEC\xA9\xBC\x48\xAD\xF8\x04\x18\x90\xE3\xA9\x81\x48"
69 "\x7E\x38\x06\x90\x05\xAD\x78\x05\xB0\xD6\x8A\x48\xA9\xD8\x48\xA9"
70 "\x0C\x9D\xB8\x05\xA9\x01\x48\xD0\x97\xBD\x38\x06\x8D\x78\x05\x60"
71 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
72 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC2"
73 "\xBD\x38\x07\x29\x0F\x09\x40\x9D\x38\x07\x8A\x48\x48\x48\xA9\x11"
74 "\xD0\x27\xA9\x1E\x48\xA9\x0C\x9D\xB8\x05\xA9\x01\x48\xD0\x51\xAD"
75 "\xB3\xFB\xC9\x06\xD0\x21\xAD\x19\xC0\x30\xFB\xAD\x19\xC0\x10\xFB"
76 "\xAD\x19\xC0\x30\xFB\xA9\x7F\xD0\x00\x48\xA9\x50\x48\xA9\x0C\x9D"
77 "\xB8\x05\xA9\x00\x48\xF0\x29\xA5\x06\x48\xA5\x07\x48\x98\x48\xA9"
78 "\x20\x85\x07\xA0\x00\x84\x06\xA9\x00\x91\x06\xC8\xD0\xFB\xE6\x07"
79 "\xA5\x07\xC9\x40\xD0\xF1\x68\xA8\xA5\x08\x48\xA9\x00\xF0\x1C\xFF"
80 "\xB9\x82\xC0\x29\xF1\x1D\xB8\x05\x99\x82\xC0\x68\x30\x0A\xF0\x80"
81 "\xA9\x00\x9D\xB8\x05\x48\xF0\xE8\x60\xD0\xAE\xA9\x01\x8D\xD0\x3F"
82 "\x8D\xE0\x3F\xAD\x57\xC0\xAD\x54\xC0\xAD\x52\xC0\xAD\x50\xC0\xEA"
83 "\x85\x06\x85\x07\x85\x08\xE6\x06\xD0\x0E\xE6\x07\xD0\x0C\xE6\x08"
84 "\xA5\x08\xC9\x01\x90\x0A\xB0\x1F\x08\x28\x08\x28\xA9\x00\xA5\x00"
85 "\xAD\xFF\xCF\xB9\x82\xC0\x4A\xEA\xEA\xB0\xDB\xAD\xFF\xCF\xB9\x82"
86 "\xC0\x4A\xA5\x00\xEA\xB0\xCF\x68\x85\x08\x68\x85\x07\x68\x85\x06"
87 "\xA9\xE3\xD0\xA5\xAD\x51\xC0\xAD\x56\xC0\x18\x90\x93\xFF\xFF\xFF"
88 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC1"
89 "\xBD\x38\x06\xC9\x20\xD0\x06\xA9\x7F\x69\x01\x70\x01\xB8\xB9\x82"
90 "\xC0\x30\xFB\xB9\x81\xC0\x29\xFB\x99\x81\xC0\xA9\xFF\x99\x80\xC0"
91 "\xB9\x81\xC0\x09\x04\x99\x81\xC0\xBD\x38\x06\x99\x80\xC0\xB9\x82"
92 "\xC0\x09\x20\x99\x82\xC0\xB9\x82\xC0\x10\xFB\x29\xDF\x99\x82\xC0"
93 "\x70\x44\xBD\x38\x06\xC9\x30\xD0\x35\xA9\x00\x9D\xB8\x04\x9D\xB8"
94 "\x03\x9D\x38\x05\x9D\x38\x04\xF0\x25\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
95 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
96 "\xB9\x82\xC0\x29\xF1\x1D\xB8\x05\x99\x82\xC0\x68\xF0\x82\xA9\x00"
97 "\x9D\xB8\x05\x48\xF0\xEA\xB9\x81\xC0\x29\xFB\x99\x81\xC0\xA9\x00"
98 "\x99\x80\xC0\xB9\x81\xC0\x09\x04\x99\x81\xC0\xB9\x82\xC0\x0A\x10"
99 "\xFA\xB9\x80\xC0\x9D\x38\x06\xB9\x82\xC0\x09\x10\x99\x82\xC0\xB9"
100 "\x82\xC0\x0A\x30\xFA\xB9\x82\xC0\x29\xEF\x99\x82\xC0\xBD\xB8\x06"
101 "\x29\xF1\x1D\x38\x06\x9D\xB8\x06\x29\x0E\xD0\xB2\xA9\x00\x9D\xB8"
102 "\x05\xA9\x02\x48\xD0\x9A\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
103 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
104 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC3"
105 "\xE4\x37\xD0\x2D\xA9\x07\xC5\x36\xF0\x27\x85\x36\x68\xC9\x8D\xF0"
106 "\x74\x29\x01\x09\x80\x9D\x38\x07\x8A\x48\xA9\x84\x48\xBD\x38\x07"
107 "\x4A\xA9\x80\xB0\x01\x0A\x48\xA9\x0C\x9D\xB8\x05\xA9\x00\x48\xF0"
108 "\x3F\xE4\x39\xD0\xD7\xA9\x05\x85\x38\xBD\x38\x07\x29\x01\xD0\x14"
109 "\x68\x68\x68\x68\xA9\x00\x9D\xB8\x03\x9D\xB8\x04\x9D\x38\x04\x9D"
110 "\x38\x05\xF0\x3C\xBD\x38\x07\x29\x01\x09\x80\x9D\x38\x07\x8A\x48"
111 "\xA9\xA1\x48\xA9\x10\x48\xA9\x0C\xD0\x30\xFF\xFF\xFF\xFF\xFF\xFF"
112 "\xB9\x82\xC0\x29\xF1\x1D\xB8\x05\x99\x82\xC0\x68\x30\x11\xF0\x80"
113 "\x6A\xB0\x89\x90\xB4\xA9\x00\x9D\xB8\x05\xA9\x01\x48\xD0\xE1\x60"
114 "\xA9\xC0\x9D\xB8\x06\x8C\x22\x02\xA9\x0A\x9D\xB8\x05\xA9\x00\x48"
115 "\xF0\xCE\x68\x68\x68\x68\xA9\x05\x9D\x38\x06\xB9\x81\xC0\x29\xFB"
116 "\x99\x81\xC0\xA9\x00\x99\x80\xC0\xB9\x81\xC0\x09\x04\x99\x81\xC0"
117 "\xB9\x82\xC0\x0A\x10\xFA\xB9\x80\xC0\x48\xB9\x82\xC0\x09\x10\x99"
118 "\x82\xC0\xB9\x82\xC0\x0A\x30\xFA\xB9\x82\xC0\x29\xEF\x99\x82\xC0"
119 "\xDE\x38\x06\xD0\xDB\x68\x9D\xB8\x06\x68\x9D\x38\x05\x68\x9D\x38"
120 "\x04\x68\x9D\xB8\x04\x68\x9D\xB8\x03\x18\x90\x99\xFF\xFF\xFF\xC8"
121 "\x8A\x48\x48\x48\xA9\x12\x48\xBC\xB8\x03\xBD\xB8\x04\xAA\x98\xA0"
122 "\x05\xD0\x6D\xAE\xF8\x07\xA9\x24\x48\xBC\x38\x04\xBD\x38\x05\xAA"
123 "\x98\xA0\x0C\xD0\x5B\xAE\xF8\x07\xA9\x43\x48\xAD\x00\xC0\x0A\x08"
124 "\xBD\xB8\x06\x2A\x2A\x2A\x29\x03\x49\x03\x38\x69\x00\x28\xA2\x00"
125 "\xA0\x10\xD0\x4D\xA9\x8D\x8D\x11\x02\x48\xA9\x11\x48\x48\xA9\x00"
126 "\xF0\x12\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
127 "\xFF\xFF\xFF\xFF\xAE\xF8\x07\xAC\x22\x02\x9D\xB8\x05\xA9\x01\x48"
128 "\xB9\x82\xC0\x29\xF1\x1D\xB8\x05\x99\x82\xC0\x68\x30\x4E\xF0\x80"
129 "\xE0\x80\x90\x0D\x49\xFF\x69\x00\x48\x8A\x49\xFF\x69\x00\xAA\x68"
130 "\x38\x8D\x21\x02\x8E\x20\x02\xA9\xAB\x90\x02\xA9\xAD\x48\xA9\xAC"
131 "\x99\x01\x02\xA2\x11\xA9\x00\x18\x2A\xC9\x0A\x90\x02\xE9\x0A\x2E"
132 "\x21\x02\x2E\x20\x02\xCA\xD0\xF0\x09\xB0\x99\x00\x02\x88\xF0\x08"
133 "\xC0\x07\xF0\x04\xC0\x0E\xD0\xDB\x68\x99\x00\x02\x60\xFF\xFF\xFF"
134 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
135 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
136 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xCD"
137 "\xB8\x50\x13\xBD\x38\x07\x29\x01\xF0\x47\xA9\x10\x48\xA9\x05\x9D"
138 "\x38\x06\xA9\x7F\x69\x01\xB9\x82\xC0\x30\xFB\xB9\x81\xC0\x29\xFB"
139 "\x99\x81\xC0\xA9\xFF\x99\x80\xC0\xB9\x81\xC0\x09\x04\x99\x81\xC0"
140 "\x68\x99\x80\xC0\xB9\x82\xC0\x09\x20\x99\x82\xC0\xB9\x82\xC0\x10"
141 "\xFB\x29\xDF\x99\x82\xC0\x70\x3F\x70\x07\xBD\x38\x07\x4A\x4A\x4A"
142 "\x4A\xB8\x9D\xB8\x05\xF0\x02\xA9\x80\x48\x50\x14\xFF\xFF\xFF\xFF"
143 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
144 "\xB9\x82\xC0\x29\xF1\x1D\xB8\x05\x99\x82\xC0\x68\xF0\x82\xC9\x02"
145 "\xF0\x81\xD0\x02\xF0\xC2\xB8\xB9\x81\xC0\x29\xFB\x99\x81\xC0\xA9"
146 "\x00\x99\x80\xC0\xB9\x81\xC0\x09\x04\x99\x81\xC0\xB9\x82\xC0\x0A"
147 "\x10\xFA\xB9\x80\xC0\x70\x05\x9D\x38\x06\x50\x01\x48\xB9\x82\xC0"
148 "\x09\x10\x99\x82\xC0\xB9\x82\xC0\x0A\x30\xFA\xB9\x82\xC0\x29\xEF"
149 "\x99\x82\xC0\x50\x19\xDE\x38\x06\xD0\xD2\x68\x9D\xB8\x06\x68\x9D"
150 "\x38\x05\x68\x9D\x38\x04\x68\x9D\xB8\x04\x68\x9D\xB8\x03\xA9\x00"
151 "\xF0\xA2\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
152 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC1"
153 "\xBD\x38\x06\xC9\x40\xF0\x22\xC9\x60\xF0\x0D\xC9\x61\xF0\x09\xC9"
154 "\xA0\xD0\x2E\x48\xA9\x02\xD0\x45\xAD\xF8\x05\x48\xAD\x78\x05\x48"
155 "\xAD\xF8\x04\x48\xAD\x78\x04\xB0\x0F\xBD\x38\x05\x48\xBD\x38\x04"
156 "\x48\xBD\xB8\x04\x48\xBD\xB8\x03\x48\xBD\x38\x06\x48\xA9\x05\xD0"
157 "\x1C\x29\x0C\x4A\x4A\x4A\xB0\x3E\x4A\x90\x0C\xAD\x78\x05\x48\xBD"
158 "\x38\x06\x48\xA9\x02\xD0\x06\xBD\x38\x06\x48\xA9\x01\x9D\x38\x06"
159 "\xD0\x4F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
160 "\xB9\x82\xC0\x29\xF1\x1D\xB8\x05\x99\x82\xC0\x68\xD0\x82\xA9\x00"
161 "\x9D\xB8\x05\x48\xF0\xEA\x4A\xB0\x13\xAD\xF8\x04\x48\xAD\x78\x04"
162 "\x48\xBD\x38\x06\x48\xA9\x03\x9D\x38\x06\xD0\x15\xAD\x78\x05\x48"
163 "\xAD\xF8\x04\x48\xAD\x78\x04\x48\xBD\x38\x06\x48\xA9\x04\x9D\x38"
164 "\x06\xB9\x82\xC0\x30\xFB\xB9\x81\xC0\x29\xFB\x99\x81\xC0\xA9\xFF"
165 "\x99\x80\xC0\xB9\x81\xC0\x09\x04\x99\x81\xC0\x68\x99\x80\xC0\xB9"
166 "\x82\xC0\x09\x20\x99\x82\xC0\xB9\x82\xC0\x10\xFB\x29\xDF\x99\x82"
167 "\xC0\xDE\x38\x06\xF0\x98\xB9\x82\xC0\x30\xFB\x10\xD6\xFF\xFF\xFF"
168 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xCE"
169 ;
170
171
172 WRITE_HANDLER( M6821_Listener_B )
173 {
174 ((CMouseInterface*)objTo)->On6821_B( byData );
175 }
176
177 WRITE_HANDLER( M6821_Listener_A )
178 {
179 ((CMouseInterface*)objTo)->On6821_A( byData );
180 }
181
182 //CALLBACK_HANDLER( MouseHandler )
183 //{
184 // ((CMouseInterface*)objTo)->OnMouseEvent();
185 //}
186
187 //===========================================================================
188
189 CMouseInterface::CMouseInterface() :
190 m_pSlotRom(NULL)
191 {
192 m_6821.SetListenerB( this, M6821_Listener_B );
193 m_6821.SetListenerA( this, M6821_Listener_A );
194 // g_cDIMouse.SetMouseListener( this, MouseHandler );
195 m_by6821A = 0;
196 m_by6821B = 0x40; // Set PB6
197 m_6821.SetPB(m_by6821B);
198 m_bVBL = FALSE;
199
200 //
201
202 m_iX = 0;
203 m_iMinX = 0;
204 m_iMaxX = 1023;
205 m_iRangeX = 0;
206
207 m_iY = 0;
208 m_iMinY = 0;
209 m_iMaxY = 1023;
210 m_iRangeY = 0;
211
212 m_bButtons[0] = m_bButtons[1] = FALSE;
213
214 //
215
216 Reset();
217 memset( m_byBuff, 0, sizeof( m_byBuff ) );
218 m_bActive = false;
219 }
220
221 CMouseInterface::~CMouseInterface()
222 {
223 delete [] m_pSlotRom;
224 }
225
226 //===========================================================================
227
228 void CMouseInterface::Initialize(LPBYTE pCxRomPeripheral, UINT uSlot)
229 {
230 const UINT FW_SIZE = 2*1024;
231
232 // HRSRC hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_MOUSEINTERFACE_FW), "FIRMWARE");
233 // if(hResInfo == NULL)
234 // return;
235 //
236 // DWORD dwResSize = SizeofResource(NULL, hResInfo);
237 // if(dwResSize != FW_SIZE)
238 // return;
239 //
240 // HGLOBAL hResData = LoadResource(NULL, hResInfo);
241 // if(hResData == NULL)
242 // return;
243
244 // instead of reading wndzooozes resources, just read it from a mere file on a disk!? bb
245 // #define IDR_MOUSEINTERFACE_FW "MouseInterface.rom"
246 // char BUFFER[FW_SIZE];
247 // FILE * hdfile = NULL;
248 // hdfile = fopen(IDR_MOUSEINTERFACE_FW, "rb");
249 // if(hdfile == NULL) return; // no file?
250 // UINT nbytes = fread(BUFFER, 1, FW_SIZE, hdfile);
251 // fclose(hdfile);
252 // if(nbytes != FW_SIZE) return; // have not read enough?
253 //
254
255 BYTE* pData = (BYTE*) MouseInterface_rom; // NB. Don't need to unlock resource
256
257 m_uSlot = uSlot;
258
259 if (m_pSlotRom == NULL)
260 {
261 m_pSlotRom = new BYTE [FW_SIZE];
262
263 if (m_pSlotRom)
264 memcpy(m_pSlotRom, pData, FW_SIZE);
265 }
266
267 //
268
269 SetSlotRom();
270 RegisterIoHandler(uSlot, &CMouseInterface::IORead, &CMouseInterface::IOWrite, NULL, NULL, this, NULL);
271 m_bActive = true;
272 printf("MouseInterface Rom loaded and registered\n");
273 }
274
275 void CMouseInterface::SetSlotRom()
276 {
277 LPBYTE pCxRomPeripheral = MemGetCxRomPeripheral();
278 if (pCxRomPeripheral == NULL)
279 return;
280
281 UINT uOffset = (m_by6821B << 7) & 0x0700;
282 memcpy(pCxRomPeripheral+m_uSlot*256, m_pSlotRom+uOffset, 256);
283 if (mem)
284 memcpy(mem+0xC000+m_uSlot*256, m_pSlotRom+uOffset, 256);
285 }
286
287 //===========================================================================
288
289 BYTE CMouseInterface::IORead(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft)
290 {
291 UINT uSlot = ((uAddr & 0xff) >> 4) - 8;
292 CMouseInterface* pMouseIF = (CMouseInterface*) MemGetSlotParameters(uSlot);
293
294 BYTE byRS;
295 byRS = uAddr & 3;
296 return pMouseIF->m_6821.Read( byRS );
297 }
298
299 BYTE CMouseInterface::IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft)
300 {
301 UINT uSlot = ((uAddr & 0xff) >> 4) - 8;
302 CMouseInterface* pMouseIF = (CMouseInterface*) MemGetSlotParameters(uSlot);
303
304 BYTE byRS;
305 byRS = uAddr & 3;
306 pMouseIF->m_6821.Write( byRS, uValue );
307
308 return 0;
309 }
310
311 //===========================================================================
312
313 void CMouseInterface::On6821_A(BYTE byData)
314 {
315 m_by6821A = byData;
316 }
317
318 void CMouseInterface::On6821_B(BYTE byData)
319 {
320 BYTE byDiff = ( m_by6821B ^ byData ) & 0x3E;
321
322 if ( byDiff )
323 {
324 m_by6821B &= ~0x3E;
325 m_by6821B |= byData & 0x3E;
326 if ( byDiff & BIT5 ) // Write to 0285 chip
327 {
328 if ( byData & BIT5 )
329 m_by6821B |= BIT7; // OK, I'm ready to read from MC6821
330 else // Clock Activate for read
331 {
332 m_byBuff[m_nBuffPos++] = m_by6821A;
333 if ( m_nBuffPos == 1 )
334 OnCommand();
335 if ( m_nBuffPos == m_nDataLen || m_nBuffPos > 7 )
336 {
337 OnWrite(); // Have written all, Commit the command.
338 m_nBuffPos = 0;
339 }
340 m_by6821B &= ~BIT7; // for next reading
341 m_6821.SetPB( m_by6821B );
342 }
343
344 }
345 if ( byDiff & BIT4 ) // Read from 0285 chip ?
346 {
347 if ( byData & BIT4 )
348 m_by6821B &= ~BIT6; // OK, I'll prepare next value
349 else // Clock Activate for write
350 {
351 if ( m_nBuffPos ) // if m_nBuffPos is 0, something goes wrong!
352 m_nBuffPos++;
353 if ( m_nBuffPos == m_nDataLen || m_nBuffPos > 7 )
354 m_nBuffPos = 0; // Have read all, ready for next command.
355 else
356 m_6821.SetPA( m_byBuff[m_nBuffPos] );
357 m_by6821B |= BIT6; // for next writing
358 }
359 }
360 m_6821.SetPB( m_by6821B );
361
362 //
363
364 SetSlotRom(); // Update Cn00 ROM page
365 }
366 }
367
368
369 void CMouseInterface::OnCommand()
370 {
371 switch( m_byBuff[0] & 0xF0 )
372 {
373 case MOUSE_SET:
374 m_nDataLen = 1;
375 m_byMode = m_byBuff[0] & 0x0F;
376 break;
377 case MOUSE_READ: // Read
378 m_nDataLen = 6;
379 m_byState &= 0x20;
380 m_nX = m_iX;
381 m_nY = m_iY;
382 if ( m_bBtn0 ) m_byState |= 0x40; // Previous Button 0
383 if ( m_bBtn1 ) m_byState |= 0x01; // Previous Button 1
384 m_bBtn0 = m_bButtons[0];
385 m_bBtn1 = m_bButtons[1];
386 if ( m_bBtn0 ) m_byState |= 0x80; // Current Button 0
387 if ( m_bBtn1 ) m_byState |= 0x10; // Current Button 1
388 m_byBuff[1] = m_nX & 0xFF;
389 m_byBuff[2] = ( m_nX >> 8 ) & 0xFF;
390 m_byBuff[3] = m_nY & 0xFF;
391 m_byBuff[4] = ( m_nY >> 8 ) & 0xFF;
392 m_byBuff[5] = m_byState; // button 0/1 interrupt status
393 m_byState &= ~0x20;
394 break;
395 case MOUSE_SERV:
396 m_nDataLen = 2;
397 m_byBuff[1] = m_byState & ~0x20; // reason of interrupt
398 CpuIrqDeassert(IS_MOUSE);
399 break;
400 case MOUSE_CLEAR:
401 Reset();
402 m_nDataLen = 1;
403 break;
404 case MOUSE_POS:
405 m_nDataLen = 5;
406 break;
407 case MOUSE_INIT:
408 m_nDataLen = 3;
409 m_byBuff[1] = 0xFF; // I don't know what it is
410 break;
411 case MOUSE_CLAMP:
412 m_nDataLen = 5;
413 break;
414 case MOUSE_HOME:
415 m_nDataLen = 1;
416 SetPosition( 0, 0 );
417 break;
418 case MOUSE_TIME: // 0x90
419 switch( m_byBuff[0] & 0x0C )
420 {
421 case 0x00: m_nDataLen = 1; break; // write cmd ( #$90 is DATATIME 60Hz, #$91 is 50Hz )
422 case 0x04: m_nDataLen = 3; break; // write cmd, $0478, $04F8
423 case 0x08: m_nDataLen = 2; break; // write cmd, $0578
424 case 0x0C: m_nDataLen = 4; break; // write cmd, $0478, $04F8, $0578
425 }
426 break;
427 case 0xA0:
428 m_nDataLen = 2;
429 break;
430 case 0xB0:
431 case 0xC0:
432 m_nDataLen = 1;
433 break;
434 default:
435 m_nDataLen = 1;
436 //TRACE( "CMD : UNKNOWN CMD : #$%02X\n", m_byBuff[0] );
437 //_ASSERT(0);
438 break;
439 }
440 m_6821.SetPA( m_byBuff[1] );
441 }
442
443 void CMouseInterface::OnWrite()
444 {
445 int nMin, nMax;
446 switch( m_byBuff[0] & 0xF0 )
447 {
448 case MOUSE_CLAMP:
449 nMin = ( m_byBuff[3] << 8 ) | m_byBuff[1];
450 nMax = ( m_byBuff[4] << 8 ) | m_byBuff[2];
451 if ( m_byBuff[0] & 1 ) // Clamp Y
452 ClampY( nMin, nMax );
453 else // Clamp X
454 ClampX( nMin, nMax );
455 break;
456 case MOUSE_POS:
457 m_nX = ( m_byBuff[2] << 8 ) | m_byBuff[1];
458 m_nY = ( m_byBuff[4] << 8 ) | m_byBuff[3];
459 SetPosition( m_nX, m_nY );
460 break;
461 case MOUSE_INIT:
462 m_nX = 0;
463 m_nY = 0;
464 ClampX( 0, 1023 );
465 ClampY( 0, 1023 );
466 SetPosition( 0, 0 );
467 break;
468 }
469 }
470
471 void CMouseInterface::OnMouseEvent()
472 {
473 int byState = 0;
474
475 if ( !( m_byMode & 1 ) ) // Mouse Off
476 return;
477
478 BOOL bBtn0 = m_bButtons[0];
479 BOOL bBtn1 = m_bButtons[1];
480 if ( (UINT) m_nX != m_iX || (UINT) m_nY != m_iY )
481 byState |= 0x22; // X/Y moved since last READMOUSE | Movement interrupt
482 if ( m_bBtn0 != bBtn0 || m_bBtn1 != bBtn1 )
483 byState |= 0x04; // Button 0/1 interrupt
484 if ( m_bVBL )
485 byState |= 0x08;
486 //byState &= m_byMode & 0x2E;
487 byState &= ((m_byMode & 0x0E) | 0x20); // Keep "X/Y moved since last READMOUSE" for next MOUSE_READ (Contiki v1.3 uses this)
488
489 if ( byState & 0x0E )
490 {
491 m_byState |= byState;
492 CpuIrqAssert(IS_MOUSE);
493 }
494 }
495
496 void CMouseInterface::SetVBlank(bool bVBL)
497 {
498 if ( m_bVBL != bVBL )
499 {
500 m_bVBL = bVBL;
501 if ( m_bVBL ) // Rising edge
502 OnMouseEvent();
503 }
504 }
505
506 void CMouseInterface::Reset()
507 {
508 m_nBuffPos = 0;
509 m_nDataLen = 1;
510
511 m_byMode = 0;
512 m_byState = 0;
513 m_nX = 0;
514 m_nY = 0;
515 m_bBtn0 = 0;
516 m_bBtn1 = 0;
517 ClampX( 0, 1023 );
518 ClampY( 0, 1023 );
519 SetPosition( 0, 0 );
520
521 // CpuIrqDeassert(IS_MOUSE);
522 }
523
524 //===========================================================================
525
526 void CMouseInterface::ClampX(int iMinX, int iMaxX)
527 {
528 if ( iMinX < 0 || iMinX > iMaxX )
529 return;
530 m_iMaxX = iMaxX;
531 m_iMinX = iMinX;
532 if ( m_iX > m_iMaxX ) m_iX = m_iMaxX; else if ( m_iX < m_iMinX ) m_iX = m_iMinX;
533 }
534
535 void CMouseInterface::ClampY(int iMinY, int iMaxY)
536 {
537 if ( iMinY < 0 || iMinY > iMaxY )
538 return;
539 m_iMaxY = iMaxY;
540 m_iMinY = iMinY;
541 if ( m_iY > m_iMaxY ) m_iY = m_iMaxY; else if ( m_iY < m_iMinX ) m_iY = m_iMinY;
542 }
543
544 void CMouseInterface::SetPosition(int xvalue, int yvalue)
545 {
546 if ((m_iRangeX == 0) || (m_iRangeY == 0))
547 {
548 m_nX = m_iX = m_iMinX;
549 m_nY = m_iY = m_iMinY;
550 return;
551 }
552
553 m_iX = (UINT) ((xvalue*m_iMaxX) / m_iRangeX);
554 m_iY = (UINT) ((yvalue*m_iMaxY) / m_iRangeY);
555 }
556
557 void CMouseInterface::SetPosition(int xvalue, int xrange, int yvalue, int yrange)
558 {
559 m_iRangeX = (UINT) xrange;
560 m_iRangeY = (UINT) yrange;
561
562 SetPosition(xvalue, yvalue);
563 OnMouseEvent();
564 }
565
566 void CMouseInterface::SetButton(eBUTTON Button, eBUTTONSTATE State)
567 {
568 m_bButtons[Button]= (State == BUTTON_DOWN) ? TRUE : FALSE;
569 OnMouseEvent();
570 }
0 /*
1 AppleWin : An Apple //e emulator for Windows
2
3 Copyright (C) 1994-1996, Michael O'Brien
4 Copyright (C) 1999-2001, Oliver Schmidt
5 Copyright (C) 2002-2005, Tom Charlesworth
6 Copyright (C) 2006-2007, Tom Charlesworth, Michael Pohoreski, Nick Westgate
7
8 AppleWin is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 AppleWin is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with AppleWin; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 /* Description: Parallel Printer Interface Card emulation
24 *
25 * Author: Nick Westgate
26 */
27
28 /* Adaptation for SDL and POSIX (l) by beom beotiger, Nov-Dec 2007 */
29
30 #include "stdafx.h"
31 //#pragma hdrstop
32 //#include "resource.h"
33
34 char Parallel_bin[] =
35 "\x18\xB0\x38\x48\x8A\x48\x98\x48\x08\x78\x20\x58\xFF\xBA\x68\x68"
36 "\x68\x68\xA8\xCA\x9A\x68\x28\xAA\x90\x38\xBD\xB8\x05\x10\x19\x98"
37 "\x29\x7F\x49\x30\xC9\x0A\x90\x3B\xC9\x78\xB0\x29\x49\x3D\xF0\x21"
38 "\x98\x29\x9F\x9D\x38\x06\x90\x7E\xBD\xB8\x06\x30\x14\xA5\x24\xDD"
39 "\x38\x07\xB0\x0D\xC9\x11\xB0\x09\x09\xF0\x3D\x38\x07\x65\x24\x85"
40 "\x24\x4A\x38\xB0\x6D\x18\x6A\x3D\xB8\x06\x90\x02\x49\x81\x9D\xB8"
41 "\x06\xD0\x53\xA0\x0A\x7D\x38\x05\x88\xD0\xFA\x9D\xB8\x04\x9D\x38"
42 "\x05\x38\xB0\x43\xC5\x24\x90\x3A\x68\xA8\x68\xAA\x68\x4C\xF0\xFD"
43 "\x90\xFE\xB0\xFE\x99\x80\xC0\x90\x37\x49\x07\xA8\x49\x0A\x0A\xD0"
44 "\x06\xB8\x85\x24\x9D\x38\x07\xBD\xB8\x06\x4A\x70\x02\xB0\x23\x0A"
45 "\x0A\xA9\x27\xB0\xCF\xBD\x38\x07\xFD\xB8\x04\xC9\xF8\x90\x03\x69"
46 "\x27\xAC\xA9\x00\x85\x24\x18\x7E\xB8\x05\x68\xA8\x68\xAA\x68\x60"
47 "\x90\x27\xB0\x00\x10\x11\xA9\x89\x9D\x38\x06\x9D\xB8\x06\xA9\x28"
48 "\x9D\xB8\x04\xA9\x02\x85\x36\x98\x5D\x38\x06\x0A\xF0\x90\x5E\xB8"
49 "\x05\x98\x48\x8A\x0A\x0A\x0A\x0A\xA8\xBD\x38\x07\xC5\x24\x68\xB0"
50 "\x05\x48\x29\x80\x09\x20\x2C\x58\xFF\xF0\x03\xFE\x38\x07\x70\x84"
51 ;
52
53
54 static DWORD inactivity = 0;
55 static FILE* file = NULL;
56 DWORD const PRINTDRVR_SIZE = 0x100;
57
58 //===========================================================================
59
60
61
62
63 static BYTE /*__stdcall*/ PrintStatus(WORD, WORD, BYTE, BYTE, ULONG);
64 static BYTE /*__stdcall*/ PrintTransmit(WORD, WORD, BYTE, BYTE value, ULONG);
65
66 VOID PrintLoadRom(LPBYTE pCxRomPeripheral, const UINT uSlot)
67 {
68 // HRSRC hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_PRINTDRVR_FW), "FIRMWARE");
69 // if(hResInfo == NULL)
70 // return;
71 //
72 // DWORD dwResSize = SizeofResource(NULL, hResInfo);
73 // if(dwResSize != PRINTDRVR_SIZE)
74 // return;
75 //
76 // HGLOBAL hResData = LoadResource(NULL, hResInfo);
77 // if(hResData == NULL)
78 // return;
79
80
81 // #define IDR_PRINTDRVR_FW "Parallel.rom"
82 // char BUFFER[PRINTDRVR_SIZE];
83 // FILE * hdfile = NULL;
84 // hdfile = fopen(IDR_PRINTDRVR_FW, "rb");
85 // if(hdfile == NULL) return; // no file?
86 // UINT nbytes = fread(BUFFER, 1, PRINTDRVR_SIZE, hdfile);
87 // fclose(hdfile);
88 // if(nbytes != PRINTDRVR_SIZE) return; // have not read enough?
89 //
90 BYTE* pData = (BYTE*) Parallel_bin; // NB. Don't need to unlock resource
91
92 // if(pData == NULL)
93 // return;
94
95 memcpy(pCxRomPeripheral + uSlot*256, pData, PRINTDRVR_SIZE);
96
97 //
98
99 RegisterIoHandler(uSlot, PrintStatus, PrintTransmit, NULL, NULL, NULL, NULL);
100 }
101
102 //===========================================================================
103 static BOOL CheckPrint()
104 {
105 inactivity = 0;
106 if (file == NULL)
107 {
108 /* TCHAR filepath[MAX_PATH * 2];
109 _tcsncpy(filepath, g_sProgramDir, MAX_PATH);
110 _tcsncat(filepath, _T("Printer.txt"), MAX_PATH);*/
111 file = fopen(g_sParallelPrinterFile, "ab"); // always for appending?
112 }
113 return (file != NULL);
114 }
115
116 //===========================================================================
117 static void ClosePrint()
118 {
119 if (file != NULL)
120 {
121 fclose(file);
122 file = NULL;
123 }
124 inactivity = 0;
125 }
126
127 //===========================================================================
128 void PrintDestroy()
129 {
130 ClosePrint();
131 }
132
133 //===========================================================================
134 void PrintUpdate(DWORD totalcycles)
135 {
136 if (file == NULL)
137 {
138 return;
139 }
140 if ((inactivity += totalcycles) > (10 * 1000 * 1000)) // around 10 seconds
141 {
142 // inactive, so close the file (next print will overwrite it)
143 ClosePrint();
144 }
145 }
146
147 //===========================================================================
148 void PrintReset()
149 {
150 ClosePrint();
151 }
152
153 //===========================================================================
154 static BYTE /*__stdcall*/ PrintStatus(WORD, WORD, BYTE, BYTE, ULONG)
155 {
156 CheckPrint();
157 return 0xFF; // status - TODO?
158 }
159
160 //===========================================================================
161 static BYTE /*__stdcall*/ PrintTransmit(WORD, WORD, BYTE, BYTE value, ULONG)
162 {
163 if (!CheckPrint())
164 {
165 return 0;
166 }
167 char c = value & 0x7F;
168 fwrite(&c, 1, 1, file);
169 return 0;
170 }
171
172 //===========================================================================
0 /*
1 AppleWin : An Apple //e emulator for Windows
2
3 Copyright (C) 1994-1996, Michael O'Brien
4 Copyright (C) 1999-2001, Oliver Schmidt
5 Copyright (C) 2002-2005, Tom Charlesworth
6 Copyright (C) 2006-2007, Tom Charlesworth, Michael Pohoreski, Nick Westgate
7
8 AppleWin is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 AppleWin is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15