|
|
1.1.1.3 root 1: /*
1.1 root 2: * UAE - The Un*x Amiga Emulator
1.1.1.3 root 3: *
1.1 root 4: * CIA chip support
5: *
6: * Copyright 1995 Bernd Schmidt, Alessandro Bissacco
1.1.1.3 root 7: * Copyright 1996, 1997 Stefan Reinauer, Christian Schmitt
1.1 root 8: */
9:
10: #include "sysconfig.h"
11: #include "sysdeps.h"
12: #include <assert.h>
13:
14: #include "config.h"
15: #include "options.h"
1.1.1.3 root 16: #include "threaddep/penguin.h"
1.1 root 17: #include "events.h"
18: #include "memory.h"
19: #include "custom.h"
20: #include "cia.h"
1.1.1.3 root 21: #include "serial.h"
1.1 root 22: #include "disk.h"
23: #include "xwin.h"
24: #include "keybuf.h"
25: #include "gui.h"
26:
27: #define DIV10 5 /* Yes, a bad identifier. */
28:
29: /* battclock stuff */
30: #define RTC_D_ADJ 8
31: #define RTC_D_IRQ 4
32: #define RTC_D_BUSY 2
33: #define RTC_D_HOLD 1
34: #define RTC_E_t1 8
35: #define RTC_E_t0 4
36: #define RTC_E_INTR 2
37: #define RTC_E_MASK 1
38: #define RTC_F_TEST 8
39: #define RTC_F_24_12 4
40: #define RTC_F_STOP 2
41: #define RTC_F_RSET 1
42:
1.1.1.3 root 43: static unsigned int clock_control_d = RTC_D_ADJ + RTC_D_HOLD;
44: static unsigned int clock_control_e = 0;
45: static unsigned int clock_control_f = RTC_F_24_12;
46:
47: unsigned int ciaaicr,ciaaimask,ciabicr,ciabimask;
48: unsigned int ciaacra,ciaacrb,ciabcra,ciabcrb;
49: unsigned long ciaata,ciaatb,ciabta,ciabtb;
50: unsigned long ciaatod,ciabtod,ciaatol,ciabtol,ciaaalarm,ciabalarm;
1.1.1.2 root 51: int ciaatlatch,ciabtlatch;
1.1.1.3 root 52:
53: unsigned int ciabpra;
54:
55: unsigned int gui_ledstate;
56:
57: static unsigned long ciaala,ciaalb,ciabla,ciablb;
58: static int ciaatodon, ciabtodon;
59: static unsigned int ciaapra,ciaaprb,ciaadra,ciaadrb,ciaasdr;
60: static unsigned int ciabprb,ciabdra,ciabdrb,ciabsdr;
1.1 root 61: static int div10;
1.1.1.2 root 62: static int kbstate, kback, ciaasdr_unread = 0;
1.1 root 63:
64: static int prtopen;
65: static FILE *prttmp;
66:
1.1.1.3 root 67: static void setclr(unsigned int *p, unsigned int val)
1.1 root 68: {
69: if (val & 0x80) {
70: *p |= val & 0x7F;
71: } else {
72: *p &= ~val;
73: }
74: }
75:
76: static void RethinkICRA(void)
77: {
78: if (ciaaimask & ciaaicr) {
79: ciaaicr |= 0x80;
80: custom_bank.wput(0xDFF09C,0x8008);
81: } else {
82: ciaaicr &= 0x7F;
83: /* custom_bank.wput(0xDFF09C,0x0008);*/
84: }
85: }
86:
87: static void RethinkICRB(void)
88: {
89: #if 0 /* ??? What's this then? */
90: if (ciabicr & 0x10) {
91: custom_bank.wput(0xDFF09C,0x9000);
92: }
93: #endif
94: if (ciabimask & ciabicr) {
95: ciabicr |= 0x80;
96: custom_bank.wput(0xDFF09C,0xA000);
97: } else {
98: ciabicr &= 0x7F;
99: /* custom_bank.wput(0xDFF09C,0x2000);*/
100: }
101: }
102:
103: static int lastdiv10;
104:
105: static void CIA_update(void)
106: {
107: unsigned long int ccount = cycles - eventtab[ev_cia].oldcycles + lastdiv10;
108: unsigned long int ciaclocks = ccount / DIV10;
109:
110: int aovfla = 0, aovflb = 0, bovfla = 0, bovflb = 0;
111:
112: lastdiv10 = div10;
113: div10 = ccount % DIV10;
1.1.1.3 root 114:
1.1 root 115: /* CIA A timers */
116: if ((ciaacra & 0x21) == 0x01) {
117: assert((ciaata+1) >= ciaclocks);
118: if ((ciaata+1) == ciaclocks) {
119: aovfla = 1;
120: if ((ciaacrb & 0x61) == 0x41) {
1.1.1.3 root 121: if (ciaatb-- == 0) aovflb = 1;
1.1 root 122: }
1.1.1.3 root 123: }
1.1 root 124: ciaata -= ciaclocks;
125: }
126: if ((ciaacrb & 0x61) == 0x01) {
127: assert((ciaatb+1) >= ciaclocks);
128: if ((ciaatb+1) == ciaclocks) aovflb = 1;
129: ciaatb -= ciaclocks;
130: }
1.1.1.3 root 131:
1.1 root 132: /* CIA B timers */
133: if ((ciabcra & 0x21) == 0x01) {
134: assert((ciabta+1) >= ciaclocks);
135: if ((ciabta+1) == ciaclocks) {
136: bovfla = 1;
137: if ((ciabcrb & 0x61) == 0x41) {
138: if (ciabtb-- == 0) bovflb = 1;
139: }
1.1.1.3 root 140: }
1.1 root 141: ciabta -= ciaclocks;
142: }
143: if ((ciabcrb & 0x61) == 0x01) {
144: assert ((ciabtb+1) >= ciaclocks);
145: if ((ciabtb+1) == ciaclocks) bovflb = 1;
146: ciabtb -= ciaclocks;
147: }
148: if (aovfla) {
149: ciaaicr |= 1; RethinkICRA();
150: ciaata = ciaala;
151: if (ciaacra & 0x8) ciaacra &= ~1;
152: }
153: if (aovflb) {
154: ciaaicr |= 2; RethinkICRA();
155: ciaatb = ciaalb;
156: if (ciaacrb & 0x8) ciaacrb &= ~1;
157: }
158: if (bovfla) {
159: ciabicr |= 1; RethinkICRB();
160: ciabta = ciabla;
161: if (ciabcra & 0x8) ciabcra &= ~1;
162: }
163: if (bovflb) {
164: ciabicr |= 2; RethinkICRB();
165: ciabtb = ciablb;
166: if (ciabcrb & 0x8) ciabcrb &= ~1;
167: }
168: }
169:
170: static void CIA_calctimers(void)
171: {
172: int ciaatimea = -1, ciaatimeb = -1, ciabtimea = -1, ciabtimeb = -1;
173:
174: eventtab[ev_cia].oldcycles = cycles;
1.1.1.3 root 175:
1.1 root 176: if ((ciaacra & 0x21) == 0x01) {
1.1.1.3 root 177: ciaatimea = (DIV10-div10) + DIV10*ciaata;
1.1 root 178: }
179: if ((ciaacrb & 0x61) == 0x41) {
180: /* Timer B will not get any pulses if Timer A is off. */
181: if (ciaatimea >= 0) {
182: /* If Timer A is in one-shot mode, and Timer B needs more than
183: * one pulse, it will not underflow. */
184: if (ciaatb == 0 || (ciaacra & 0x8) == 0) {
185: /* Otherwise, we can determine the time of the underflow. */
186: ciaatimeb = ciaatimea + ciaala * DIV10 * ciaatb;
187: }
188: }
189: }
190: if ((ciaacrb & 0x61) == 0x01) {
191: ciaatimeb = (DIV10-div10) + DIV10*ciaatb;
192: }
193:
194: if ((ciabcra & 0x21) == 0x01) {
1.1.1.3 root 195: ciabtimea = (DIV10-div10) + DIV10*ciabta;
1.1 root 196: }
197: if ((ciabcrb & 0x61) == 0x41) {
198: /* Timer B will not get any pulses if Timer A is off. */
199: if (ciabtimea >= 0) {
200: /* If Timer A is in one-shot mode, and Timer B needs more than
201: * one pulse, it will not underflow. */
202: if (ciabtb == 0 || (ciabcra & 0x8) == 0) {
203: /* Otherwise, we can determine the time of the underflow. */
204: ciabtimeb = ciabtimea + ciabla * DIV10 * ciabtb;
205: }
206: }
207: }
208: if ((ciabcrb & 0x61) == 0x01) {
209: ciabtimeb = (DIV10-div10) + DIV10*ciabtb;
210: }
211: eventtab[ev_cia].active = (ciaatimea != -1 || ciaatimeb != -1
212: || ciabtimea != -1 || ciabtimeb != -1);
213: if (eventtab[ev_cia].active) {
214: unsigned long int ciatime = ~0L;
215: if (ciaatimea != -1) ciatime = ciaatimea;
216: if (ciaatimeb != -1 && ciaatimeb < ciatime) ciatime = ciaatimeb;
217: if (ciabtimea != -1 && ciabtimea < ciatime) ciatime = ciabtimea;
218: if (ciabtimeb != -1 && ciabtimeb < ciatime) ciatime = ciabtimeb;
219: eventtab[ev_cia].evtime = ciatime + cycles;
220: }
221: events_schedule();
222: }
223:
224: void CIA_handler(void)
225: {
226: CIA_update();
227: CIA_calctimers();
228: }
229:
1.1.1.8 root 230: void cia_diskindex(void)
1.1 root 231: {
232: ciabicr |= 0x10;
233: RethinkICRB();
234: }
235:
236: void CIA_hsync_handler(void)
237: {
1.1.1.3 root 238: static unsigned int keytime = 0, sleepyhead = 0;
1.1 root 239:
240: if (ciabtodon)
241: ciabtod++;
242: ciabtod &= 0xFFFFFF;
243:
244: if (ciabtod == ciabalarm) {
245: ciabicr |= 4; RethinkICRB();
246: }
1.1.1.3 root 247:
248: /* check wether the serial port gets some data */
249: if (doreadser)
250: doreadser = SERDATS();
251:
1.1 root 252: if (keys_available() && kback && (++keytime & 15) == 0) {
1.1.1.3 root 253: /*
1.1.1.2 root 254: * This hack lets one possible ciaaicr cycle go by without any key
255: * being read, for every cycle in which a key is pulled out of the
256: * queue. If no hack is used, a lot of key events just get lost
257: * when you type fast. With a simple hack that waits for ciaasdr
258: * to be read before feeding it another, it will keep up until the
259: * queue gets about 14 characters ahead and then lose events, and
260: * the mouse pointer will freeze while typing is being taken in.
261: * With this hack, you can type 30 or 40 characters ahead with little
262: * or no lossage, and the mouse doesn't get stuck. The tradeoff is
263: * that the total slowness of typing appearing on screen is worse.
264: */
1.1.1.3 root 265: if (ciaasdr_unread == 2)
266: ciaasdr_unread = 0;
267: else if (ciaasdr_unread == 0) {
268: switch (kbstate) {
1.1.1.2 root 269: case 0:
1.1.1.3 root 270: ciaasdr = (uae_s8)~0xFB; /* aaarghh... stupid compiler */
271: kbstate++;
272: break;
1.1.1.2 root 273: case 1:
1.1.1.3 root 274: kbstate++;
275: ciaasdr = (uae_s8)~0xFD;
276: break;
1.1.1.2 root 277: case 2:
1.1.1.3 root 278: ciaasdr = ~get_next_key();
279: ciaasdr_unread = 1; /* interlock to prevent lost keystrokes */
280: break;
1.1.1.2 root 281: }
282: ciaaicr |= 8;
283: RethinkICRA();
284: sleepyhead = 0;
1.1.1.3 root 285: } else if (!(++sleepyhead & 15))
286: ciaasdr_unread = 0; /* give up on this key event after unread for a long time */
1.1 root 287: }
288: }
289:
290: void CIA_vsync_handler()
1.1.1.3 root 291: {
292: if (ciaatodon)
1.1 root 293: ciaatod++;
294: ciaatod &= 0xFFFFFF;
295: if (ciaatod == ciaaalarm) {
296: ciaaicr |= 4; RethinkICRA();
297: }
1.1.1.3 root 298:
299: doreadser = 1;
300: serstat = -1;
301: serial_flush_buffer();
1.1 root 302: }
303:
1.1.1.3 root 304: static uae_u8 ReadCIAA(unsigned int addr)
1.1 root 305: {
1.1.1.3 root 306: unsigned int tmp;
307:
1.1.1.5 root 308: switch(addr & 0xf) {
1.1.1.7 root 309: case 0:
1.1.1.3 root 310: if (currprefs.use_serial && (serstat < 0)) /* Only read status when needed */
311: serstat=serial_readstatus(); /* and only once per frame */
312:
1.1 root 313: tmp = (DISK_status() & 0x3C);
1.1.1.6 root 314: if ((JSEM_ISMOUSE (0, &currprefs) && !buttonstate[0])
315: || (!JSEM_ISMOUSE (0, &currprefs) && !(joy0button & 1)))
1.1.1.3 root 316: tmp |= 0x40;
317: if (!(joy1button & 1))
318: tmp |= 0x80;
1.1 root 319: return tmp;
1.1.1.7 root 320: case 1:
321: /* Returning 0xFF is necessary for Tie Break - otherwise its joystick
322: code won't work. */
323: return prtopen ? ciaaprb : 0xFF;
324: case 2:
1.1 root 325: return ciaadra;
1.1.1.7 root 326: case 3:
1.1 root 327: return ciaadrb;
1.1.1.7 root 328: case 4:
1.1 root 329: return ciaata & 0xff;
1.1.1.7 root 330: case 5:
1.1 root 331: return ciaata >> 8;
1.1.1.7 root 332: case 6:
1.1 root 333: return ciaatb & 0xff;
1.1.1.7 root 334: case 7:
1.1 root 335: return ciaatb >> 8;
1.1.1.7 root 336: case 8:
1.1 root 337: if (ciaatlatch) {
338: ciaatlatch = 0;
339: return ciaatol & 0xff;
1.1.1.3 root 340: } else
341: return ciaatod & 0xff;
1.1.1.7 root 342: case 9:
1.1.1.3 root 343: if (ciaatlatch)
344: return (ciaatol >> 8) & 0xff;
345: else
346: return (ciaatod >> 8) & 0xff;
1.1.1.7 root 347: case 10:
1.1.1.3 root 348: ciaatlatch = 1;
349: ciaatol = ciaatod; /* ??? only if not already latched? */
1.1 root 350: return (ciaatol >> 16) & 0xff;
1.1.1.7 root 351: case 12:
1.1.1.3 root 352: if (ciaasdr == 1) ciaasdr_unread = 2;
1.1 root 353: return ciaasdr;
1.1.1.7 root 354: case 13:
1.1 root 355: tmp = ciaaicr; ciaaicr = 0; RethinkICRA(); return tmp;
1.1.1.7 root 356: case 14:
1.1 root 357: return ciaacra;
1.1.1.7 root 358: case 15:
1.1 root 359: return ciaacrb;
360: }
361: return 0;
362: }
363:
1.1.1.3 root 364: static uae_u8 ReadCIAB(unsigned int addr)
1.1 root 365: {
1.1.1.3 root 366: unsigned int tmp;
367:
1.1.1.5 root 368: switch(addr & 0xf) {
1.1.1.7 root 369: case 0:
1.1.1.3 root 370: if (currprefs.use_serial && serstat < 0) /* Only read status when needed */
371: serstat=serial_readstatus(); /* and only once per frame */
1.1.1.7 root 372: /* Returning some 1 bits is necessary for Tie Break - otherwise its joystick
373: code won't work. */
374: return ciabpra | (prtopen ? 0 : 3);
375: case 1:
1.1 root 376: return ciabprb;
1.1.1.7 root 377: case 2:
1.1 root 378: return ciabdra;
1.1.1.7 root 379: case 3:
1.1 root 380: return ciabdrb;
1.1.1.7 root 381: case 4:
1.1 root 382: return ciabta & 0xff;
1.1.1.7 root 383: case 5:
1.1 root 384: return ciabta >> 8;
1.1.1.7 root 385: case 6:
1.1 root 386: return ciabtb & 0xff;
1.1.1.7 root 387: case 7:
1.1 root 388: return ciabtb >> 8;
1.1.1.7 root 389: case 8:
1.1 root 390: if (ciabtlatch) {
391: ciabtlatch = 0;
392: return ciabtol & 0xff;
1.1.1.3 root 393: } else
394: return ciabtod & 0xff;
1.1.1.7 root 395: case 9:
1.1.1.3 root 396: if (ciabtlatch)
397: return (ciabtol >> 8) & 0xff;
398: else
399: return (ciabtod >> 8) & 0xff;
1.1.1.7 root 400: case 10:
1.1.1.3 root 401: ciabtlatch = 1;
402: ciabtol = ciabtod;
1.1 root 403: return (ciabtol >> 16) & 0xff;
1.1.1.7 root 404: case 12:
1.1 root 405: return ciabsdr;
1.1.1.7 root 406: case 13:
1.1 root 407: tmp = ciabicr; ciabicr = 0; RethinkICRB();
408: return tmp;
1.1.1.7 root 409: case 14:
1.1 root 410: return ciabcra;
1.1.1.7 root 411: case 15:
1.1 root 412: return ciabcrb;
413: }
414: return 0;
415: }
416:
1.1.1.3 root 417: static void WriteCIAA(uae_u16 addr,uae_u8 val)
1.1 root 418: {
1.1.1.3 root 419: int oldled, oldovl;
1.1.1.5 root 420: switch(addr & 0xf) {
1.1.1.7 root 421: case 0:
1.1.1.3 root 422: oldovl = ciaapra & 1;
1.1 root 423: oldled = ciaapra & 2;
424: ciaapra = (ciaapra & ~0x3) | (val & 0x3); LED(ciaapra & 0x2);
1.1.1.3 root 425: gui_ledstate &= ~1;
426: gui_ledstate |= ((~ciaapra & 2) >> 1);
1.1 root 427: if ((ciaapra & 2) != oldled)
428: gui_led (0, !(ciaapra & 2));
1.1.1.3 root 429: if ((ciaapra & 1) != oldovl) {
430: map_banks(oldovl || ersatzkickfile ? &chipmem_bank : &kickmem_bank, 0, 32);
431: }
1.1 root 432: break;
1.1.1.7 root 433: case 1:
1.1 root 434: ciaaprb = val;
435: if (prtopen==1) {
436: #ifndef __DOS__
1.1.1.4 root 437: fprintf (prttmp, "%c",val);
1.1 root 438: #else
439: fputc (val, prttmp);
440: fflush (prttmp);
441: #endif
442: if (val==0x04) {
1.1.1.2 root 443: #if defined(__unix) && !defined(__BEOS__) && !defined(__DOS__)
1.1 root 444: pclose (prttmp);
445: #else
446: fclose (prttmp);
447: #endif
448: prtopen = 0;
449: }
1.1.1.3 root 450: } else {
1.1.1.2 root 451: #if defined(__unix) && !defined(__BEOS__) && !defined(__DOS__)
1.1.1.6 root 452: prttmp = (FILE *)popen ((const char *)currprefs.prtname, "w");
1.1 root 453: #else
1.1.1.6 root 454: prttmp = (FILE *)fopen ((const char *)currprefs.prtname, "wb");
1.1 root 455: #endif
456: if (prttmp != NULL) {
457: prtopen = 1;
458: #ifndef __DOS__
459: fprintf (prttmp,"%c",val);
460: #else
461: fputc (val, prttmp);
462: fflush (prttmp);
463: #endif
464: }
1.1.1.3 root 465: }
1.1 root 466: ciaaicr |= 0x10;
467: break;
1.1.1.7 root 468: case 2:
1.1 root 469: ciaadra = val; break;
1.1.1.7 root 470: case 3:
1.1 root 471: ciaadrb = val; break;
1.1.1.7 root 472: case 4:
1.1 root 473: CIA_update();
474: ciaala = (ciaala & 0xff00) | val;
475: CIA_calctimers();
476: break;
1.1.1.7 root 477: case 5:
1.1 root 478: CIA_update();
479: ciaala = (ciaala & 0xff) | (val << 8);
480: if ((ciaacra & 1) == 0)
481: ciaata = ciaala;
1.1.1.3 root 482: if (ciaacra & 8) {
483: ciaata = ciaala;
484: ciaacra |= 1;
1.1 root 485: }
486: CIA_calctimers();
487: break;
1.1.1.7 root 488: case 6:
1.1 root 489: CIA_update();
490: ciaalb = (ciaalb & 0xff00) | val;
491: CIA_calctimers();
492: break;
1.1.1.7 root 493: case 7:
1.1 root 494: CIA_update();
495: ciaalb = (ciaalb & 0xff) | (val << 8);
496: if ((ciaacrb & 1) == 0)
497: ciaatb = ciaalb;
1.1.1.3 root 498: if (ciaacrb & 8) {
1.1 root 499: ciaatb = ciaalb;
1.1.1.3 root 500: ciaacrb |= 1;
1.1 root 501: }
502: CIA_calctimers();
503: break;
1.1.1.7 root 504: case 8:
1.1.1.5 root 505: if (ciaacrb & 0x80) {
1.1 root 506: ciaaalarm = (ciaaalarm & ~0xff) | val;
507: } else {
508: ciaatod = (ciaatod & ~0xff) | val;
509: ciaatodon = 1;
510: }
511: break;
1.1.1.7 root 512: case 9:
1.1.1.5 root 513: if (ciaacrb & 0x80) {
1.1 root 514: ciaaalarm = (ciaaalarm & ~0xff00) | (val << 8);
515: } else {
516: ciaatod = (ciaatod & ~0xff00) | (val << 8);
517: ciaatodon = 0;
518: }
519: break;
1.1.1.7 root 520: case 10:
1.1.1.5 root 521: if (ciaacrb & 0x80) {
1.1 root 522: ciaaalarm = (ciaaalarm & ~0xff0000) | (val << 16);
523: } else {
524: ciaatod = (ciaatod & ~0xff0000) | (val << 16);
525: ciaatodon = 0;
526: }
527: break;
1.1.1.7 root 528: case 12:
1.1 root 529: ciaasdr = val; break;
1.1.1.7 root 530: case 13:
1.1 root 531: setclr(&ciaaimask,val); break; /* ??? call RethinkICR() ? */
1.1.1.7 root 532: case 14:
1.1 root 533: CIA_update();
534: ciaacra = val;
1.1.1.5 root 535: if (ciaacra & 0x10) {
1.1 root 536: ciaacra &= ~0x10;
537: ciaata = ciaala;
538: }
539: if (ciaacra & 0x40) {
540: kback = 1;
541: }
542: CIA_calctimers();
543: break;
1.1.1.7 root 544: case 15:
1.1 root 545: CIA_update();
1.1.1.3 root 546: ciaacrb = val;
1.1.1.5 root 547: if (ciaacrb & 0x10) {
1.1 root 548: ciaacrb &= ~0x10;
549: ciaatb = ciaalb;
550: }
551: CIA_calctimers();
552: break;
553: }
554: }
555:
1.1.1.3 root 556: static void WriteCIAB(uae_u16 addr,uae_u8 val)
1.1 root 557: {
1.1.1.3 root 558: int oldval;
1.1.1.5 root 559: switch(addr & 0xf) {
1.1.1.7 root 560: case 0:
1.1.1.3 root 561: if (currprefs.use_serial) {
1.1.1.7 root 562: oldval = ciabpra;
563: ciabpra = serial_writestatus(oldval,val);
1.1.1.3 root 564: } else
1.1.1.7 root 565: ciabpra = val;
1.1.1.3 root 566: break;
1.1.1.7 root 567: case 1:
1.1 root 568: ciabprb = val; DISK_select(val); break;
1.1.1.7 root 569: case 2:
1.1 root 570: ciabdra = val; break;
1.1.1.7 root 571: case 3:
1.1 root 572: ciabdrb = val; break;
1.1.1.7 root 573: case 4:
1.1 root 574: CIA_update();
575: ciabla = (ciabla & 0xff00) | val;
576: CIA_calctimers();
577: break;
1.1.1.7 root 578: case 5:
1.1 root 579: CIA_update();
580: ciabla = (ciabla & 0xff) | (val << 8);
1.1.1.3 root 581: if ((ciabcra & 1) == 0)
1.1 root 582: ciabta = ciabla;
583: if (ciabcra & 8) {
1.1.1.3 root 584: ciabta = ciabla;
585: ciabcra |= 1;
586: }
1.1 root 587: CIA_calctimers();
588: break;
1.1.1.7 root 589: case 6:
1.1 root 590: CIA_update();
591: ciablb = (ciablb & 0xff00) | val;
592: CIA_calctimers();
593: break;
1.1.1.7 root 594: case 7:
1.1 root 595: CIA_update();
596: ciablb = (ciablb & 0xff) | (val << 8);
597: if ((ciabcrb & 1) == 0)
598: ciabtb = ciablb;
599: if (ciabcrb & 8) {
600: ciabtb = ciablb;
601: ciabcrb |= 1;
602: }
603: CIA_calctimers();
604: break;
1.1.1.7 root 605: case 8:
1.1.1.5 root 606: if (ciabcrb & 0x80) {
1.1 root 607: ciabalarm = (ciabalarm & ~0xff) | val;
608: } else {
609: ciabtod = (ciabtod & ~0xff) | val;
610: ciabtodon = 1;
611: }
612: break;
1.1.1.7 root 613: case 9:
1.1.1.5 root 614: if (ciabcrb & 0x80) {
1.1 root 615: ciabalarm = (ciabalarm & ~0xff00) | (val << 8);
616: } else {
617: ciabtod = (ciabtod & ~0xff00) | (val << 8);
618: ciabtodon = 0;
619: }
620: break;
1.1.1.7 root 621: case 10:
1.1.1.5 root 622: if (ciabcrb & 0x80) {
1.1 root 623: ciabalarm = (ciabalarm & ~0xff0000) | (val << 16);
624: } else {
625: ciabtod = (ciabtod & ~0xff0000) | (val << 16);
626: ciabtodon = 0;
627: }
628: break;
1.1.1.7 root 629: case 12:
1.1.1.3 root 630: ciabsdr = val;
1.1 root 631: break;
1.1.1.7 root 632: case 13:
1.1.1.3 root 633: setclr(&ciabimask,val);
1.1 root 634: break;
1.1.1.7 root 635: case 14:
1.1 root 636: CIA_update();
637: ciabcra = val;
1.1.1.5 root 638: if (ciabcra & 0x10) {
1.1 root 639: ciabcra &= ~0x10;
640: ciabta = ciabla;
641: }
642: CIA_calctimers();
643: break;
1.1.1.7 root 644: case 15:
1.1 root 645: CIA_update();
1.1.1.3 root 646: ciabcrb = val;
1.1.1.5 root 647: if (ciabcrb & 0x10) {
1.1 root 648: ciabcrb &= ~0x10;
649: ciabtb = ciablb;
650: }
651: CIA_calctimers();
652: break;
653: }
654: }
655:
656: void CIA_reset(void)
657: {
658: kback = 1;
659: kbstate = 0;
1.1.1.3 root 660:
1.1 root 661: ciaatlatch = ciabtlatch = 0;
1.1.1.3 root 662: ciaapra = 3;
1.1 root 663: ciaatod = ciabtod = 0; ciaatodon = ciabtodon = 0;
664: ciaaicr = ciabicr = ciaaimask = ciabimask = 0;
665: ciaacra = ciaacrb = ciabcra = ciabcrb = 0x4; /* outmode = toggle; */
666: ciaala = ciaalb = ciabla = ciablb = ciaata = ciaatb = ciabta = ciabtb = 0xFFFF;
667: div10 = 0;
668: lastdiv10 = 0;
669: CIA_calctimers();
1.1.1.2 root 670: ciabpra = 0x8C;
1.1.1.3 root 671: if (! ersatzkickfile)
672: map_banks(&kickmem_bank, 0, 32);
673:
674: if (currprefs.use_serial) serial_dtr_off(); /* Drop DTR at reset */
1.1 root 675: }
676:
677: void dumpcia(void)
678: {
679: printf("A: CRA: %02x, CRB: %02x, IMASK: %02x, TOD: %08lx %7s TA: %04lx, TB: %04lx\n",
1.1.1.3 root 680: (int)ciaacra, (int)ciaacrb, (int)ciaaimask, ciaatod,
1.1 root 681: ciaatlatch ? " latched" : "", ciaata, ciaatb);
682: printf("B: CRA: %02x, CRB: %02x, IMASK: %02x, TOD: %08lx %7s TA: %04lx, TB: %04lx\n",
1.1.1.3 root 683: (int)ciabcra, (int)ciabcrb, (int)ciabimask, ciabtod,
1.1 root 684: ciabtlatch ? " latched" : "", ciabta, ciabtb);
685: }
686:
687: /* CIA memory access */
688:
1.1.1.3 root 689: static uae_u32 cia_lget (uaecptr) REGPARAM;
690: static uae_u32 cia_wget (uaecptr) REGPARAM;
691: static uae_u32 cia_bget (uaecptr) REGPARAM;
692: static void cia_lput (uaecptr, uae_u32) REGPARAM;
693: static void cia_wput (uaecptr, uae_u32) REGPARAM;
694: static void cia_bput (uaecptr, uae_u32) REGPARAM;
1.1 root 695:
696: addrbank cia_bank = {
697: cia_lget, cia_wget, cia_bget,
698: cia_lput, cia_wput, cia_bput,
699: default_xlate, default_check
700: };
701:
1.1.1.3 root 702: uae_u32 REGPARAM2 cia_lget (uaecptr addr)
1.1 root 703: {
1.1.1.9 ! root 704: special_mem |= S_READ;
! 705: return cia_bget (addr + 3);
1.1 root 706: }
707:
1.1.1.3 root 708: uae_u32 REGPARAM2 cia_wget (uaecptr addr)
1.1 root 709: {
1.1.1.9 ! root 710: special_mem |= S_READ;
! 711: return cia_bget (addr + 1);
1.1 root 712: }
713:
1.1.1.3 root 714: uae_u32 REGPARAM2 cia_bget (uaecptr addr)
1.1 root 715: {
1.1.1.9 ! root 716: special_mem |= S_READ;
1.1 root 717: if ((addr & 0x3001) == 0x2001)
1.1.1.3 root 718: return ReadCIAA((addr & 0xF00) >> 8);
1.1 root 719: if ((addr & 0x3001) == 0x1000)
1.1.1.3 root 720: return ReadCIAB((addr & 0xF00) >> 8);
1.1 root 721: return 0;
722: }
723:
1.1.1.3 root 724: void REGPARAM2 cia_lput (uaecptr addr, uae_u32 value)
1.1 root 725: {
1.1.1.9 ! root 726: special_mem |= S_WRITE;
! 727: cia_bput (addr + 3, value); /* FIXME ? */
1.1 root 728: }
729:
1.1.1.3 root 730: void REGPARAM2 cia_wput (uaecptr addr, uae_u32 value)
1.1 root 731: {
1.1.1.9 ! root 732: special_mem |= S_WRITE;
! 733: cia_bput (addr + 1, value);
1.1 root 734: }
735:
1.1.1.3 root 736: void REGPARAM2 cia_bput (uaecptr addr, uae_u32 value)
1.1 root 737: {
1.1.1.9 ! root 738: special_mem |= S_WRITE;
1.1 root 739: if ((addr & 0x3001) == 0x2001)
1.1.1.9 ! root 740: WriteCIAA ((addr & 0xF00) >> 8, value);
1.1 root 741: if ((addr & 0x3001) == 0x1000)
1.1.1.9 ! root 742: WriteCIAB ((addr & 0xF00) >> 8, value);
1.1 root 743: }
744:
745: /* battclock memory access */
746:
1.1.1.3 root 747: static uae_u32 clock_lget (uaecptr) REGPARAM;
748: static uae_u32 clock_wget (uaecptr) REGPARAM;
749: static uae_u32 clock_bget (uaecptr) REGPARAM;
750: static void clock_lput (uaecptr, uae_u32) REGPARAM;
751: static void clock_wput (uaecptr, uae_u32) REGPARAM;
752: static void clock_bput (uaecptr, uae_u32) REGPARAM;
1.1 root 753:
754: addrbank clock_bank = {
755: clock_lget, clock_wget, clock_bget,
756: clock_lput, clock_wput, clock_bput,
757: default_xlate, default_check
758: };
759:
1.1.1.3 root 760: uae_u32 REGPARAM2 clock_lget (uaecptr addr)
1.1 root 761: {
1.1.1.9 ! root 762: special_mem |= S_READ;
! 763: return clock_bget (addr + 3);
1.1 root 764: }
765:
1.1.1.3 root 766: uae_u32 REGPARAM2 clock_wget (uaecptr addr)
1.1 root 767: {
1.1.1.9 ! root 768: special_mem |= S_READ;
! 769: return clock_bget (addr + 1);
1.1 root 770: }
771:
1.1.1.3 root 772: uae_u32 REGPARAM2 clock_bget (uaecptr addr)
1.1 root 773: {
1.1.1.9 ! root 774: time_t t = time(0);
1.1 root 775: struct tm *ct;
1.1.1.9 ! root 776:
! 777: ct = localtime (&t);
! 778: special_mem |= S_READ;
! 779:
1.1.1.7 root 780: switch (addr & 0x3f) {
781: case 0x03: return ct->tm_sec % 10;
782: case 0x07: return ct->tm_sec / 10;
783: case 0x0b: return ct->tm_min % 10;
784: case 0x0f: return ct->tm_min / 10;
785: case 0x13: return ct->tm_hour % 10;
786: case 0x17: return ct->tm_hour / 10;
787: case 0x1b: return ct->tm_mday % 10;
788: case 0x1f: return ct->tm_mday / 10;
789: case 0x23: return (ct->tm_mon+1) % 10;
790: case 0x27: return (ct->tm_mon+1) / 10;
791: case 0x2b: return ct->tm_year % 10;
792: case 0x2f: return ct->tm_year / 10;
793:
794: case 0x33: return ct->tm_wday; /*Hack by -=SR=- */
795: case 0x37: return clock_control_d;
796: case 0x3b: return clock_control_e;
797: case 0x3f: return clock_control_f;
1.1 root 798: }
799: return 0;
800: }
801:
1.1.1.3 root 802: void REGPARAM2 clock_lput (uaecptr addr, uae_u32 value)
1.1 root 803: {
1.1.1.9 ! root 804: special_mem |= S_WRITE;
1.1 root 805: /* No way */
806: }
807:
1.1.1.3 root 808: void REGPARAM2 clock_wput (uaecptr addr, uae_u32 value)
1.1 root 809: {
1.1.1.9 ! root 810: special_mem |= S_WRITE;
1.1 root 811: /* No way */
812: }
813:
1.1.1.3 root 814: void REGPARAM2 clock_bput (uaecptr addr, uae_u32 value)
1.1 root 815: {
1.1.1.9 ! root 816: special_mem |= S_WRITE;
1.1.1.7 root 817: switch (addr & 0x3f) {
1.1.1.9 ! root 818: case 0x37: clock_control_d = value; break;
! 819: case 0x3b: clock_control_e = value; break;
! 820: case 0x3f: clock_control_f = value; break;
1.1 root 821: }
822: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.