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