|
|
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 "options.h"
1.1.1.12 root 15: #include "threaddep/thread.h"
1.1 root 16: #include "events.h"
17: #include "memory.h"
18: #include "custom.h"
19: #include "cia.h"
1.1.1.3 root 20: #include "serial.h"
1.1 root 21: #include "disk.h"
22: #include "xwin.h"
1.1.1.18 root 23: #include "inputdevice.h"
1.1 root 24: #include "keybuf.h"
25: #include "gui.h"
1.1.1.11 root 26: #include "savestate.h"
1.1.1.20! root 27: #include "audio.h"
1.1 root 28:
1.1.1.10 root 29: #define DIV10 (5*CYCLE_UNIT) /* Yes, a bad identifier. */
1.1 root 30:
31: /* battclock stuff */
32: #define RTC_D_ADJ 8
33: #define RTC_D_IRQ 4
34: #define RTC_D_BUSY 2
35: #define RTC_D_HOLD 1
36: #define RTC_E_t1 8
37: #define RTC_E_t0 4
38: #define RTC_E_INTR 2
39: #define RTC_E_MASK 1
40: #define RTC_F_TEST 8
41: #define RTC_F_24_12 4
42: #define RTC_F_STOP 2
43: #define RTC_F_RSET 1
44:
1.1.1.3 root 45: static unsigned int clock_control_d = RTC_D_ADJ + RTC_D_HOLD;
46: static unsigned int clock_control_e = 0;
47: static unsigned int clock_control_f = RTC_F_24_12;
48:
1.1.1.16 root 49: static unsigned int ciaaicr, ciaaimask, ciabicr, ciabimask;
50: static unsigned int ciaacra, ciaacrb, ciabcra, ciabcrb;
1.1.1.10 root 51:
52: /* Values of the CIA timers. */
1.1.1.16 root 53: static unsigned long ciaata, ciaatb, ciabta, ciabtb;
1.1.1.10 root 54: /* Computed by compute_passed_time. */
1.1.1.16 root 55: static unsigned long ciaata_passed, ciaatb_passed, ciabta_passed, ciabtb_passed;
1.1.1.10 root 56:
1.1.1.16 root 57: static unsigned long ciaatod, ciabtod, ciaatol, ciabtol, ciaaalarm, ciabalarm;
58: static int ciaatlatch, ciabtlatch;
1.1.1.20! root 59: static int oldled, oldovl;
1.1.1.3 root 60:
1.1.1.16 root 61: static unsigned int ciabpra;
1.1.1.3 root 62:
63: unsigned int gui_ledstate;
64:
1.1.1.11 root 65: static unsigned long ciaala, ciaalb, ciabla, ciablb;
1.1.1.3 root 66: static int ciaatodon, ciabtodon;
1.1.1.11 root 67: static unsigned int ciaapra, ciaaprb, ciaadra, ciaadrb, ciaasdr;
68: static unsigned int ciabprb, ciabdra, ciabdrb, ciabsdr;
1.1 root 69: static int div10;
1.1.1.2 root 70: static int kbstate, kback, ciaasdr_unread = 0;
1.1 root 71:
72: static int prtopen;
73: static FILE *prttmp;
1.1.1.18 root 74: static int warned = 10;
1.1 root 75:
1.1.1.10 root 76: static void setclr (unsigned int *p, unsigned int val)
1.1 root 77: {
78: if (val & 0x80) {
79: *p |= val & 0x7F;
80: } else {
81: *p &= ~val;
82: }
83: }
84:
1.1.1.10 root 85: static void RethinkICRA (void)
1.1 root 86: {
87: if (ciaaimask & ciaaicr) {
88: ciaaicr |= 0x80;
1.1.1.17 root 89: INTREQ_0 (0x8000 | 0x0008);
1.1 root 90: } else {
91: ciaaicr &= 0x7F;
92: /* custom_bank.wput(0xDFF09C,0x0008);*/
93: }
94: }
95:
1.1.1.10 root 96: static void RethinkICRB (void)
1.1 root 97: {
98: if (ciabimask & ciabicr) {
99: ciabicr |= 0x80;
1.1.1.17 root 100: INTREQ_0 (0x8000 | 0x2000);
1.1 root 101: } else {
102: ciabicr &= 0x7F;
103: }
104: }
105:
1.1.1.11 root 106: void rethink_cias (void)
107: {
108: RethinkICRA ();
109: RethinkICRB ();
110: }
111:
1.1.1.10 root 112: /* Figure out how many CIA timer cycles have passed for each timer since the
113: last call of CIA_calctimers. */
1.1 root 114:
1.1.1.10 root 115: static void compute_passed_time (void)
1.1 root 116: {
1.1.1.10 root 117: unsigned long int ccount = (get_cycles () - eventtab[ev_cia].oldcycles + div10);
118: unsigned long int ciaclocks = ccount / DIV10;
119:
120: ciaata_passed = ciaatb_passed = ciabta_passed = ciabtb_passed = 0;
121:
122: /* CIA A timers */
123: if ((ciaacra & 0x21) == 0x01) {
1.1.1.20! root 124: assert ((ciaata + 1) >= ciaclocks);
1.1.1.10 root 125: ciaata_passed = ciaclocks;
126: }
127: if ((ciaacrb & 0x61) == 0x01) {
1.1.1.20! root 128: assert ((ciaatb + 1) >= ciaclocks);
1.1.1.10 root 129: ciaatb_passed = ciaclocks;
130: }
131:
132: /* CIA B timers */
133: if ((ciabcra & 0x21) == 0x01) {
1.1.1.20! root 134: assert ((ciabta + 1) >= ciaclocks);
1.1.1.10 root 135: ciabta_passed = ciaclocks;
136: }
137: if ((ciabcrb & 0x61) == 0x01) {
1.1.1.20! root 138: assert ((ciabtb + 1) >= ciaclocks);
1.1.1.10 root 139: ciabtb_passed = ciaclocks;
140: }
141: }
142:
143: /* Called to advance all CIA timers to the current time. This expects that
144: one of the timer values will be modified, and CIA_calctimers will be called
145: in the same cycle. */
146:
147: static void CIA_update (void)
148: {
149: unsigned long int ccount = (get_cycles () - eventtab[ev_cia].oldcycles + div10);
1.1 root 150: unsigned long int ciaclocks = ccount / DIV10;
151:
152: int aovfla = 0, aovflb = 0, bovfla = 0, bovflb = 0;
153:
154: div10 = ccount % DIV10;
1.1.1.3 root 155:
1.1 root 156: /* CIA A timers */
157: if ((ciaacra & 0x21) == 0x01) {
1.1.1.20! root 158: assert ((ciaata + 1) >= ciaclocks);
! 159: if ((ciaata + 1) == ciaclocks) {
1.1 root 160: aovfla = 1;
161: if ((ciaacrb & 0x61) == 0x41) {
1.1.1.18 root 162: if (ciaatb-- == 0)
163: aovflb = 1;
1.1 root 164: }
1.1.1.3 root 165: }
1.1 root 166: ciaata -= ciaclocks;
167: }
168: if ((ciaacrb & 0x61) == 0x01) {
1.1.1.20! root 169: assert ((ciaatb + 1) >= ciaclocks);
! 170: if ((ciaatb + 1) == ciaclocks)
1.1.1.18 root 171: aovflb = 1;
1.1 root 172: ciaatb -= ciaclocks;
173: }
1.1.1.3 root 174:
1.1 root 175: /* CIA B timers */
176: if ((ciabcra & 0x21) == 0x01) {
1.1.1.20! root 177: assert ((ciabta + 1) >= ciaclocks);
! 178: if ((ciabta + 1) == ciaclocks) {
1.1 root 179: bovfla = 1;
180: if ((ciabcrb & 0x61) == 0x41) {
1.1.1.18 root 181: if (ciabtb-- == 0)
182: bovflb = 1;
1.1 root 183: }
1.1.1.3 root 184: }
1.1 root 185: ciabta -= ciaclocks;
186: }
187: if ((ciabcrb & 0x61) == 0x01) {
1.1.1.20! root 188: assert ((ciabtb + 1) >= ciaclocks);
! 189: if ((ciabtb + 1) == ciaclocks)
1.1.1.18 root 190: bovflb = 1;
1.1 root 191: ciabtb -= ciaclocks;
192: }
193: if (aovfla) {
1.1.1.20! root 194: ciaaicr |= 1; RethinkICRA ();
1.1 root 195: ciaata = ciaala;
196: if (ciaacra & 0x8) ciaacra &= ~1;
197: }
198: if (aovflb) {
1.1.1.20! root 199: ciaaicr |= 2; RethinkICRA ();
1.1 root 200: ciaatb = ciaalb;
201: if (ciaacrb & 0x8) ciaacrb &= ~1;
202: }
203: if (bovfla) {
1.1.1.20! root 204: ciabicr |= 1; RethinkICRB ();
1.1 root 205: ciabta = ciabla;
206: if (ciabcra & 0x8) ciabcra &= ~1;
207: }
208: if (bovflb) {
1.1.1.20! root 209: ciabicr |= 2; RethinkICRB ();
1.1 root 210: ciabtb = ciablb;
211: if (ciabcrb & 0x8) ciabcrb &= ~1;
212: }
213: }
214:
1.1.1.10 root 215: /* Call this only after CIA_update has been called in the same cycle. */
216:
217: static void CIA_calctimers (void)
1.1 root 218: {
1.1.1.17 root 219: long int ciaatimea = -1, ciaatimeb = -1, ciabtimea = -1, ciabtimeb = -1;
1.1 root 220:
1.1.1.10 root 221: eventtab[ev_cia].oldcycles = get_cycles ();
1.1 root 222: if ((ciaacra & 0x21) == 0x01) {
1.1.1.10 root 223: ciaatimea = (DIV10 - div10) + DIV10 * ciaata;
1.1 root 224: }
225: if ((ciaacrb & 0x61) == 0x41) {
226: /* Timer B will not get any pulses if Timer A is off. */
227: if (ciaatimea >= 0) {
228: /* If Timer A is in one-shot mode, and Timer B needs more than
229: * one pulse, it will not underflow. */
230: if (ciaatb == 0 || (ciaacra & 0x8) == 0) {
231: /* Otherwise, we can determine the time of the underflow. */
1.1.1.15 root 232: /* This may overflow, however. So just ignore this timer and
233: use the fact that we'll call CIA_handler for the A timer. */
234: #if 0
1.1 root 235: ciaatimeb = ciaatimea + ciaala * DIV10 * ciaatb;
1.1.1.15 root 236: #endif
1.1 root 237: }
238: }
239: }
240: if ((ciaacrb & 0x61) == 0x01) {
1.1.1.10 root 241: ciaatimeb = (DIV10 - div10) + DIV10 * ciaatb;
1.1 root 242: }
243:
244: if ((ciabcra & 0x21) == 0x01) {
1.1.1.10 root 245: ciabtimea = (DIV10 - div10) + DIV10 * ciabta;
1.1 root 246: }
247: if ((ciabcrb & 0x61) == 0x41) {
248: /* Timer B will not get any pulses if Timer A is off. */
249: if (ciabtimea >= 0) {
250: /* If Timer A is in one-shot mode, and Timer B needs more than
251: * one pulse, it will not underflow. */
252: if (ciabtb == 0 || (ciabcra & 0x8) == 0) {
253: /* Otherwise, we can determine the time of the underflow. */
1.1.1.15 root 254: #if 0
1.1 root 255: ciabtimeb = ciabtimea + ciabla * DIV10 * ciabtb;
1.1.1.15 root 256: #endif
1.1 root 257: }
258: }
259: }
260: if ((ciabcrb & 0x61) == 0x01) {
1.1.1.10 root 261: ciabtimeb = (DIV10 - div10) + DIV10 * ciabtb;
1.1 root 262: }
263: eventtab[ev_cia].active = (ciaatimea != -1 || ciaatimeb != -1
264: || ciabtimea != -1 || ciabtimeb != -1);
265: if (eventtab[ev_cia].active) {
266: unsigned long int ciatime = ~0L;
267: if (ciaatimea != -1) ciatime = ciaatimea;
268: if (ciaatimeb != -1 && ciaatimeb < ciatime) ciatime = ciaatimeb;
269: if (ciabtimea != -1 && ciabtimea < ciatime) ciatime = ciabtimea;
270: if (ciabtimeb != -1 && ciabtimeb < ciatime) ciatime = ciabtimeb;
1.1.1.10 root 271: eventtab[ev_cia].evtime = ciatime + get_cycles ();
1.1 root 272: }
273: events_schedule();
274: }
275:
1.1.1.10 root 276: void CIA_handler (void)
1.1 root 277: {
1.1.1.10 root 278: CIA_update ();
279: CIA_calctimers ();
1.1 root 280: }
281:
1.1.1.10 root 282: void cia_diskindex (void)
1.1 root 283: {
284: ciabicr |= 0x10;
1.1.1.20! root 285: RethinkICRB ();
! 286: }
! 287:
! 288: static int checkalarm (unsigned long tod, unsigned long alarm, int inc)
! 289: {
! 290: if (tod == alarm)
! 291: return 1;
! 292: if (!inc)
! 293: return 0;
! 294: /* emulate buggy TODMED counter.
! 295: * it counts: .. 29 2A 2B 2C 2D 2E 2F 20 30 31 32 ..
! 296: * (2F->20->30 only takes couple of cycles but it will trigger alarm..
! 297: */
! 298: if (tod & 0x000fff)
! 299: return 0;
! 300: if (((tod - 1) & 0xfff000) == alarm)
! 301: return 1;
! 302: return 0;
! 303: }
! 304:
! 305: STATIC_INLINE void ciab_checkalarm (int inc)
! 306: {
! 307: if (checkalarm (ciabtod, ciabalarm, inc)) {
! 308: ciabicr |= 4;
! 309: RethinkICRB ();
! 310: }
! 311: }
! 312:
! 313: STATIC_INLINE void ciaa_checkalarm (int inc)
! 314: {
! 315: if (checkalarm (ciaatod, ciaaalarm, inc)) {
! 316: ciaaicr |= 4;
! 317: RethinkICRA ();
! 318: }
1.1 root 319: }
320:
1.1.1.10 root 321: void CIA_hsync_handler (void)
1.1 root 322: {
1.1.1.3 root 323: static unsigned int keytime = 0, sleepyhead = 0;
1.1 root 324:
1.1.1.20! root 325: if (ciabtodon) {
1.1 root 326: ciabtod++;
1.1.1.20! root 327: ciabtod &= 0xFFFFFF;
! 328: ciab_checkalarm (1);
! 329: }
1.1 root 330:
331: if (ciabtod == ciabalarm) {
1.1.1.20! root 332: ciabicr |= 4; RethinkICRB ();
1.1 root 333: }
1.1.1.3 root 334:
335: /* check wether the serial port gets some data */
336: if (doreadser)
337: doreadser = SERDATS();
338:
1.1.1.18 root 339: if (keys_available() && kback && (ciaacra & 0x40) == 0 && (++keytime & 15) == 0) {
1.1.1.3 root 340: /*
1.1.1.2 root 341: * This hack lets one possible ciaaicr cycle go by without any key
342: * being read, for every cycle in which a key is pulled out of the
343: * queue. If no hack is used, a lot of key events just get lost
344: * when you type fast. With a simple hack that waits for ciaasdr
345: * to be read before feeding it another, it will keep up until the
346: * queue gets about 14 characters ahead and then lose events, and
347: * the mouse pointer will freeze while typing is being taken in.
348: * With this hack, you can type 30 or 40 characters ahead with little
349: * or no lossage, and the mouse doesn't get stuck. The tradeoff is
350: * that the total slowness of typing appearing on screen is worse.
351: */
1.1.1.17 root 352: if (ciaasdr_unread == 2) {
1.1.1.3 root 353: ciaasdr_unread = 0;
1.1.1.17 root 354: } else if (ciaasdr_unread == 0) {
1.1.1.3 root 355: switch (kbstate) {
1.1.1.2 root 356: case 0:
1.1.1.3 root 357: ciaasdr = (uae_s8)~0xFB; /* aaarghh... stupid compiler */
358: kbstate++;
359: break;
1.1.1.2 root 360: case 1:
1.1.1.3 root 361: kbstate++;
362: ciaasdr = (uae_s8)~0xFD;
363: break;
1.1.1.2 root 364: case 2:
1.1.1.3 root 365: ciaasdr = ~get_next_key();
366: ciaasdr_unread = 1; /* interlock to prevent lost keystrokes */
367: break;
1.1.1.2 root 368: }
369: ciaaicr |= 8;
1.1.1.20! root 370: RethinkICRA ();
1.1.1.2 root 371: sleepyhead = 0;
1.1.1.17 root 372: } else if (!(++sleepyhead & 15)) {
1.1.1.3 root 373: ciaasdr_unread = 0; /* give up on this key event after unread for a long time */
1.1.1.17 root 374: }
1.1 root 375: }
376: }
377:
1.1.1.10 root 378: void CIA_vsync_handler ()
1.1.1.3 root 379: {
1.1.1.20! root 380: if (ciaatodon) {
1.1 root 381: ciaatod++;
1.1.1.20! root 382: ciaatod &= 0xFFFFFF;
! 383: ciaa_checkalarm (1);
1.1 root 384: }
1.1.1.3 root 385:
386: doreadser = 1;
387: serstat = -1;
388: serial_flush_buffer();
1.1 root 389: }
390:
1.1.1.20! root 391: static void bfe001_change (void)
! 392: {
! 393: uae_u8 v = ciaapra;
! 394:
! 395: v |= ~ciaadra; /* output is high when pin's direction is input */
! 396: if ((v & 2) != oldled) {
! 397: int led = (v & 2) ? 0 : 1;
! 398: oldled = v & 2;
! 399: gui_ledstate &= ~1;
! 400: gui_ledstate |= led;
! 401: gui_data.powerled = led;
! 402: gui_led (0, led);
! 403: led_filter_audio ();
! 404: }
! 405: if ((v & 1) != oldovl) {
! 406: int i = (allocated_chipmem>>16) > 32 ? allocated_chipmem >> 16 : 32;
! 407: oldovl = v & 1;
! 408:
! 409: if (!oldovl || ersatzkickfile) {
! 410: map_overlay (1);
! 411: } else if (!(currprefs.chipset_mask & CSMASK_AGA)) {
! 412: /* pin disconnected in AGA chipset, CD audio mute on/off on CD32 */
! 413: map_overlay (0);
! 414: }
! 415: }
! 416: }
! 417:
1.1.1.10 root 418: static uae_u8 ReadCIAA (unsigned int addr)
1.1 root 419: {
1.1.1.3 root 420: unsigned int tmp;
421:
1.1.1.10 root 422: compute_passed_time ();
1.1.1.18 root 423:
1.1.1.10 root 424: switch (addr & 0xf) {
1.1.1.7 root 425: case 0:
1.1.1.3 root 426: if (currprefs.use_serial && (serstat < 0)) /* Only read status when needed */
427: serstat=serial_readstatus(); /* and only once per frame */
428:
1.1 root 429: tmp = (DISK_status() & 0x3C);
1.1.1.18 root 430: tmp |= handle_joystick_buttons (ciaadra);
431: tmp |= (ciaapra | (ciaadra ^ 3)) & 0x03;
432: if (ciaadra & 0x40)
433: tmp = (tmp & ~0x40) | (ciaapra & 0x40);
434: if (ciaadra & 0x80)
435: tmp = (tmp & ~0x80) | (ciaapra & 0x80);
1.1 root 436: return tmp;
1.1.1.7 root 437: case 1:
438: /* Returning 0xFF is necessary for Tie Break - otherwise its joystick
439: code won't work. */
440: return prtopen ? ciaaprb : 0xFF;
441: case 2:
1.1 root 442: return ciaadra;
1.1.1.7 root 443: case 3:
1.1 root 444: return ciaadrb;
1.1.1.7 root 445: case 4:
1.1.1.10 root 446: return (ciaata - ciaata_passed) & 0xff;
1.1.1.7 root 447: case 5:
1.1.1.10 root 448: return (ciaata - ciaata_passed) >> 8;
1.1.1.7 root 449: case 6:
1.1.1.10 root 450: return (ciaatb - ciaatb_passed) & 0xff;
1.1.1.7 root 451: case 7:
1.1.1.10 root 452: return (ciaatb - ciaatb_passed) >> 8;
1.1.1.7 root 453: case 8:
1.1 root 454: if (ciaatlatch) {
455: ciaatlatch = 0;
456: return ciaatol & 0xff;
1.1.1.3 root 457: } else
458: return ciaatod & 0xff;
1.1.1.7 root 459: case 9:
1.1.1.3 root 460: if (ciaatlatch)
461: return (ciaatol >> 8) & 0xff;
462: else
463: return (ciaatod >> 8) & 0xff;
1.1.1.7 root 464: case 10:
1.1.1.3 root 465: ciaatlatch = 1;
466: ciaatol = ciaatod; /* ??? only if not already latched? */
1.1 root 467: return (ciaatol >> 16) & 0xff;
1.1.1.7 root 468: case 12:
1.1.1.18 root 469: if (ciaasdr_unread == 1)
470: ciaasdr_unread = 2;
1.1 root 471: return ciaasdr;
1.1.1.7 root 472: case 13:
1.1.1.20! root 473: tmp = ciaaicr; ciaaicr = 0; RethinkICRA ();
1.1.1.17 root 474: return tmp;
1.1.1.7 root 475: case 14:
1.1 root 476: return ciaacra;
1.1.1.7 root 477: case 15:
1.1 root 478: return ciaacrb;
479: }
480: return 0;
481: }
482:
1.1.1.10 root 483: static uae_u8 ReadCIAB (unsigned int addr)
1.1 root 484: {
1.1.1.3 root 485: unsigned int tmp;
486:
1.1.1.10 root 487: compute_passed_time ();
488:
489: switch (addr & 0xf) {
1.1.1.7 root 490: case 0:
1.1.1.3 root 491: if (currprefs.use_serial && serstat < 0) /* Only read status when needed */
492: serstat=serial_readstatus(); /* and only once per frame */
1.1.1.7 root 493: /* Returning some 1 bits is necessary for Tie Break - otherwise its joystick
494: code won't work. */
495: return ciabpra | (prtopen ? 0 : 3);
496: case 1:
1.1 root 497: return ciabprb;
1.1.1.7 root 498: case 2:
1.1 root 499: return ciabdra;
1.1.1.7 root 500: case 3:
1.1 root 501: return ciabdrb;
1.1.1.7 root 502: case 4:
1.1.1.10 root 503: return (ciabta - ciabta_passed) & 0xff;
1.1.1.7 root 504: case 5:
1.1.1.10 root 505: return (ciabta - ciabta_passed) >> 8;
1.1.1.7 root 506: case 6:
1.1.1.10 root 507: return (ciabtb - ciabtb_passed) & 0xff;
1.1.1.7 root 508: case 7:
1.1.1.10 root 509: return (ciabtb - ciabtb_passed) >> 8;
1.1.1.7 root 510: case 8:
1.1 root 511: if (ciabtlatch) {
512: ciabtlatch = 0;
513: return ciabtol & 0xff;
1.1.1.3 root 514: } else
515: return ciabtod & 0xff;
1.1.1.7 root 516: case 9:
1.1.1.3 root 517: if (ciabtlatch)
518: return (ciabtol >> 8) & 0xff;
519: else
520: return (ciabtod >> 8) & 0xff;
1.1.1.7 root 521: case 10:
1.1.1.3 root 522: ciabtlatch = 1;
523: ciabtol = ciabtod;
1.1 root 524: return (ciabtol >> 16) & 0xff;
1.1.1.7 root 525: case 12:
1.1 root 526: return ciabsdr;
1.1.1.7 root 527: case 13:
1.1.1.20! root 528: tmp = ciabicr; ciabicr = 0; RethinkICRB ();
1.1 root 529: return tmp;
1.1.1.7 root 530: case 14:
1.1 root 531: return ciabcra;
1.1.1.7 root 532: case 15:
1.1 root 533: return ciabcrb;
534: }
535: return 0;
536: }
537:
1.1.1.20! root 538: static void WriteCIAA (uae_u16 addr, uae_u8 val)
1.1 root 539: {
1.1.1.3 root 540: int oldled, oldovl;
1.1.1.10 root 541: switch (addr & 0xf) {
1.1.1.7 root 542: case 0:
1.1.1.20! root 543: ciaapra = (ciaapra & ~0x3) | (val & 0x3);
! 544: bfe001_change ();
1.1 root 545: break;
1.1.1.7 root 546: case 1:
1.1 root 547: ciaaprb = val;
548: if (prtopen==1) {
549: #ifndef __DOS__
1.1.1.4 root 550: fprintf (prttmp, "%c",val);
1.1 root 551: #else
552: fputc (val, prttmp);
553: fflush (prttmp);
554: #endif
555: if (val==0x04) {
1.1.1.2 root 556: #if defined(__unix) && !defined(__BEOS__) && !defined(__DOS__)
1.1 root 557: pclose (prttmp);
558: #else
559: fclose (prttmp);
560: #endif
561: prtopen = 0;
562: }
1.1.1.3 root 563: } else {
1.1.1.2 root 564: #if defined(__unix) && !defined(__BEOS__) && !defined(__DOS__)
1.1.1.6 root 565: prttmp = (FILE *)popen ((const char *)currprefs.prtname, "w");
1.1 root 566: #else
1.1.1.6 root 567: prttmp = (FILE *)fopen ((const char *)currprefs.prtname, "wb");
1.1 root 568: #endif
569: if (prttmp != NULL) {
570: prtopen = 1;
571: #ifndef __DOS__
572: fprintf (prttmp,"%c",val);
573: #else
574: fputc (val, prttmp);
575: fflush (prttmp);
576: #endif
577: }
1.1.1.3 root 578: }
1.1 root 579: ciaaicr |= 0x10;
580: break;
1.1.1.7 root 581: case 2:
1.1.1.17 root 582: ciaadra = val;
1.1.1.20! root 583: bfe001_change ();
1.1.1.17 root 584: break;
1.1.1.7 root 585: case 3:
1.1.1.17 root 586: ciaadrb = val;
587: break;
1.1.1.7 root 588: case 4:
1.1.1.10 root 589: CIA_update ();
1.1 root 590: ciaala = (ciaala & 0xff00) | val;
1.1.1.10 root 591: CIA_calctimers ();
1.1 root 592: break;
1.1.1.7 root 593: case 5:
1.1.1.10 root 594: CIA_update ();
1.1 root 595: ciaala = (ciaala & 0xff) | (val << 8);
596: if ((ciaacra & 1) == 0)
597: ciaata = ciaala;
1.1.1.3 root 598: if (ciaacra & 8) {
599: ciaata = ciaala;
600: ciaacra |= 1;
1.1 root 601: }
1.1.1.10 root 602: CIA_calctimers ();
1.1 root 603: break;
1.1.1.7 root 604: case 6:
1.1.1.10 root 605: CIA_update ();
1.1 root 606: ciaalb = (ciaalb & 0xff00) | val;
1.1.1.10 root 607: CIA_calctimers ();
1.1 root 608: break;
1.1.1.7 root 609: case 7:
1.1.1.10 root 610: CIA_update ();
1.1 root 611: ciaalb = (ciaalb & 0xff) | (val << 8);
612: if ((ciaacrb & 1) == 0)
613: ciaatb = ciaalb;
1.1.1.3 root 614: if (ciaacrb & 8) {
1.1 root 615: ciaatb = ciaalb;
1.1.1.3 root 616: ciaacrb |= 1;
1.1 root 617: }
1.1.1.10 root 618: CIA_calctimers ();
1.1 root 619: break;
1.1.1.7 root 620: case 8:
1.1.1.5 root 621: if (ciaacrb & 0x80) {
1.1 root 622: ciaaalarm = (ciaaalarm & ~0xff) | val;
623: } else {
624: ciaatod = (ciaatod & ~0xff) | val;
625: ciaatodon = 1;
626: }
627: break;
1.1.1.7 root 628: case 9:
1.1.1.5 root 629: if (ciaacrb & 0x80) {
1.1 root 630: ciaaalarm = (ciaaalarm & ~0xff00) | (val << 8);
631: } else {
632: ciaatod = (ciaatod & ~0xff00) | (val << 8);
633: ciaatodon = 0;
634: }
635: break;
1.1.1.7 root 636: case 10:
1.1.1.5 root 637: if (ciaacrb & 0x80) {
1.1 root 638: ciaaalarm = (ciaaalarm & ~0xff0000) | (val << 16);
639: } else {
640: ciaatod = (ciaatod & ~0xff0000) | (val << 16);
641: ciaatodon = 0;
642: }
643: break;
1.1.1.7 root 644: case 12:
1.1.1.17 root 645: ciaasdr = val;
646: break;
1.1.1.7 root 647: case 13:
1.1.1.17 root 648: setclr(&ciaaimask,val);
649: break;
1.1.1.7 root 650: case 14:
1.1.1.10 root 651: CIA_update ();
1.1 root 652: ciaacra = val;
1.1.1.5 root 653: if (ciaacra & 0x10) {
1.1 root 654: ciaacra &= ~0x10;
655: ciaata = ciaala;
656: }
1.1.1.17 root 657: if (ciaacra & 0x40)
1.1 root 658: kback = 1;
1.1.1.10 root 659: CIA_calctimers ();
1.1 root 660: break;
1.1.1.7 root 661: case 15:
1.1.1.10 root 662: CIA_update ();
1.1.1.3 root 663: ciaacrb = val;
1.1.1.5 root 664: if (ciaacrb & 0x10) {
1.1 root 665: ciaacrb &= ~0x10;
666: ciaatb = ciaalb;
667: }
1.1.1.10 root 668: CIA_calctimers ();
1.1 root 669: break;
670: }
671: }
672:
1.1.1.20! root 673: static void WriteCIAB (uae_u16 addr, uae_u8 val)
1.1 root 674: {
1.1.1.3 root 675: int oldval;
1.1.1.10 root 676: switch (addr & 0xf) {
1.1.1.7 root 677: case 0:
1.1.1.3 root 678: if (currprefs.use_serial) {
1.1.1.7 root 679: oldval = ciabpra;
1.1.1.20! root 680: ciabpra = serial_writestatus (oldval, val);
1.1.1.3 root 681: } else
1.1.1.20! root 682: ciabpra = val;
1.1.1.3 root 683: break;
1.1.1.7 root 684: case 1:
1.1 root 685: ciabprb = val; DISK_select(val); break;
1.1.1.7 root 686: case 2:
1.1 root 687: ciabdra = val; break;
1.1.1.7 root 688: case 3:
1.1 root 689: ciabdrb = val; break;
1.1.1.7 root 690: case 4:
1.1.1.10 root 691: CIA_update ();
1.1 root 692: ciabla = (ciabla & 0xff00) | val;
1.1.1.10 root 693: CIA_calctimers ();
1.1 root 694: break;
1.1.1.7 root 695: case 5:
1.1.1.10 root 696: CIA_update ();
1.1 root 697: ciabla = (ciabla & 0xff) | (val << 8);
1.1.1.3 root 698: if ((ciabcra & 1) == 0)
1.1 root 699: ciabta = ciabla;
700: if (ciabcra & 8) {
1.1.1.3 root 701: ciabta = ciabla;
702: ciabcra |= 1;
703: }
1.1.1.10 root 704: CIA_calctimers ();
1.1 root 705: break;
1.1.1.7 root 706: case 6:
1.1.1.10 root 707: CIA_update ();
1.1 root 708: ciablb = (ciablb & 0xff00) | val;
1.1.1.10 root 709: CIA_calctimers ();
1.1 root 710: break;
1.1.1.7 root 711: case 7:
1.1.1.10 root 712: CIA_update ();
1.1 root 713: ciablb = (ciablb & 0xff) | (val << 8);
714: if ((ciabcrb & 1) == 0)
715: ciabtb = ciablb;
716: if (ciabcrb & 8) {
717: ciabtb = ciablb;
718: ciabcrb |= 1;
719: }
1.1.1.10 root 720: CIA_calctimers ();
1.1 root 721: break;
1.1.1.7 root 722: case 8:
1.1.1.5 root 723: if (ciabcrb & 0x80) {
1.1 root 724: ciabalarm = (ciabalarm & ~0xff) | val;
725: } else {
726: ciabtod = (ciabtod & ~0xff) | val;
727: ciabtodon = 1;
728: }
729: break;
1.1.1.7 root 730: case 9:
1.1.1.5 root 731: if (ciabcrb & 0x80) {
1.1 root 732: ciabalarm = (ciabalarm & ~0xff00) | (val << 8);
733: } else {
734: ciabtod = (ciabtod & ~0xff00) | (val << 8);
735: ciabtodon = 0;
736: }
737: break;
1.1.1.7 root 738: case 10:
1.1.1.5 root 739: if (ciabcrb & 0x80) {
1.1 root 740: ciabalarm = (ciabalarm & ~0xff0000) | (val << 16);
741: } else {
742: ciabtod = (ciabtod & ~0xff0000) | (val << 16);
743: ciabtodon = 0;
744: }
745: break;
1.1.1.7 root 746: case 12:
1.1.1.3 root 747: ciabsdr = val;
1.1 root 748: break;
1.1.1.7 root 749: case 13:
1.1.1.3 root 750: setclr(&ciabimask,val);
1.1 root 751: break;
1.1.1.7 root 752: case 14:
1.1.1.10 root 753: CIA_update ();
1.1 root 754: ciabcra = val;
1.1.1.5 root 755: if (ciabcra & 0x10) {
1.1 root 756: ciabcra &= ~0x10;
757: ciabta = ciabla;
758: }
1.1.1.10 root 759: CIA_calctimers ();
1.1 root 760: break;
1.1.1.7 root 761: case 15:
1.1.1.10 root 762: CIA_update ();
1.1.1.3 root 763: ciabcrb = val;
1.1.1.5 root 764: if (ciabcrb & 0x10) {
1.1 root 765: ciabcrb &= ~0x10;
766: ciabtb = ciablb;
767: }
1.1.1.10 root 768: CIA_calctimers ();
1.1 root 769: break;
770: }
771: }
772:
1.1.1.10 root 773: void CIA_reset (void)
1.1 root 774: {
775: kback = 1;
776: kbstate = 0;
1.1.1.20! root 777: oldovl = -1;
! 778: oldled = -1;
1.1.1.3 root 779:
1.1.1.11 root 780: if (!savestate_state) {
781: ciaatlatch = ciabtlatch = 0;
782: ciaapra = 3;
783: ciaatod = ciabtod = 0; ciaatodon = ciabtodon = 0;
784: ciaaicr = ciabicr = ciaaimask = ciabimask = 0;
785: ciaacra = ciaacrb = ciabcra = ciabcrb = 0x4; /* outmode = toggle; */
786: ciaala = ciaalb = ciabla = ciablb = ciaata = ciaatb = ciabta = ciabtb = 0xFFFF;
787: ciabpra = 0x8C;
1.1.1.13 root 788: div10 = 0;
1.1.1.11 root 789: }
1.1.1.10 root 790: CIA_calctimers ();
1.1.1.14 root 791: if (! ersatzkickfile) {
792: int i = allocated_chipmem > 0x200000 ? allocated_chipmem >> 16 : 32;
793: map_banks (&kickmem_bank, 0, i, 0x80000);
794: }
1.1.1.3 root 795:
1.1.1.18 root 796: if (currprefs.use_serial && !savestate_state)
1.1.1.11 root 797: serial_dtr_off (); /* Drop DTR at reset */
798:
799: if (savestate_state) {
1.1.1.20! root 800: bfe001_change ();
1.1.1.11 root 801: /* select drives */
802: DISK_select (ciabprb);
803: }
1.1 root 804: }
805:
1.1.1.10 root 806: void dumpcia (void)
1.1 root 807: {
1.1.1.13 root 808: printf("A: CRA: %02x, CRB: %02x, IMASK: %02x, TOD: %08lx %7s TA: %04lx (%04lx), TB: %04lx (%04lx)\n",
1.1.1.3 root 809: (int)ciaacra, (int)ciaacrb, (int)ciaaimask, ciaatod,
1.1.1.13 root 810: ciaatlatch ? "L" : "", ciaata, ciaala, ciaatb, ciaalb);
811: printf("B: CRA: %02x, CRB: %02x, IMASK: %02x, TOD: %08lx %7s TA: %04lx (%04lx), TB: %04lx (%04lx)\n",
1.1.1.3 root 812: (int)ciabcra, (int)ciabcrb, (int)ciabimask, ciabtod,
1.1.1.13 root 813: ciabtlatch ? "L" : "", ciabta, ciabla, ciabtb, ciablb);
1.1 root 814: }
815:
816: /* CIA memory access */
817:
1.1.1.3 root 818: static uae_u32 cia_lget (uaecptr) REGPARAM;
819: static uae_u32 cia_wget (uaecptr) REGPARAM;
820: static uae_u32 cia_bget (uaecptr) REGPARAM;
821: static void cia_lput (uaecptr, uae_u32) REGPARAM;
822: static void cia_wput (uaecptr, uae_u32) REGPARAM;
823: static void cia_bput (uaecptr, uae_u32) REGPARAM;
1.1 root 824:
825: addrbank cia_bank = {
826: cia_lget, cia_wget, cia_bget,
827: cia_lput, cia_wput, cia_bput,
1.1.1.20! root 828: default_xlate, default_check, NULL, "CIA"
1.1 root 829: };
830:
1.1.1.15 root 831: static void cia_wait (void)
1.1 root 832: {
1.1.1.15 root 833: if (!div10)
834: return;
835: do_cycles (DIV10 - div10 + CYCLE_UNIT);
836: CIA_handler ();
837: }
838:
839: uae_u32 REGPARAM2 cia_bget (uaecptr addr)
840: {
841: int r = (addr & 0xf00) >> 8;
1.1.1.18 root 842: uae_u8 v;
843:
1.1.1.15 root 844: cia_wait ();
1.1.1.18 root 845: v = 0xff;
1.1.1.15 root 846: switch ((addr >> 12) & 3)
847: {
848: case 0:
1.1.1.18 root 849: v = (addr & 1) ? ReadCIAA (r) : ReadCIAB (r);
850: break;
1.1.1.15 root 851: case 1:
1.1.1.18 root 852: v = (addr & 1) ? 0xff : ReadCIAB (r);
853: break;
1.1.1.15 root 854: case 2:
1.1.1.18 root 855: v = (addr & 1) ? ReadCIAA (r) : 0xff;
856: break;
857: #if 0
858: case 3:
859: if (currprefs.cpu_level == 0 && currprefs.cpu_compatible)
860: v = (addr & 1) ? regs.irc : regs.irc >> 8;
861: if (warned > 0) {
1.1.1.20! root 862: write_log ("cia_bget: unknown CIA address %x PC=%x\n", addr, m68k_getpc ());
1.1.1.18 root 863: warned--;
864: }
865: break;
866: #endif
1.1.1.15 root 867: }
1.1.1.18 root 868: return v;
1.1 root 869: }
870:
1.1.1.3 root 871: uae_u32 REGPARAM2 cia_wget (uaecptr addr)
1.1 root 872: {
1.1.1.15 root 873: int r = (addr & 0xf00) >> 8;
1.1.1.18 root 874: uae_u16 v;
1.1.1.15 root 875: cia_wait ();
1.1.1.18 root 876: v = 0xffff;
1.1.1.15 root 877: switch ((addr >> 12) & 3)
878: {
879: case 0:
1.1.1.18 root 880: v = (ReadCIAB (r) << 8) | ReadCIAA (r);
881: break;
1.1.1.15 root 882: case 1:
1.1.1.18 root 883: v = (ReadCIAB (r) << 8) | 0xff;
884: break;
1.1.1.15 root 885: case 2:
1.1.1.18 root 886: v = (0xff << 8) | ReadCIAA (r);
887: break;
1.1.1.15 root 888: }
1.1.1.18 root 889: return v;
1.1 root 890: }
891:
1.1.1.15 root 892: uae_u32 REGPARAM2 cia_lget (uaecptr addr)
1.1 root 893: {
1.1.1.15 root 894: uae_u32 v;
895: v = cia_wget (addr) << 16;
896: v |= cia_wget (addr + 2);
897: return v;
1.1 root 898: }
899:
1.1.1.15 root 900: void REGPARAM2 cia_bput (uaecptr addr, uae_u32 value)
1.1 root 901: {
1.1.1.15 root 902: int r = (addr & 0xf00) >> 8;
903: cia_wait ();
904: if ((addr & 0x2000) == 0)
905: WriteCIAB (r, value);
906: if ((addr & 0x1000) == 0)
907: WriteCIAA (r, value);
1.1 root 908: }
909:
1.1.1.3 root 910: void REGPARAM2 cia_wput (uaecptr addr, uae_u32 value)
1.1 root 911: {
1.1.1.15 root 912: int r = (addr & 0xf00) >> 8;
913: cia_wait ();
914: if ((addr & 0x2000) == 0)
915: WriteCIAB (r, value >> 8);
916: if ((addr & 0x1000) == 0)
917: WriteCIAA (r, value & 0xff);
1.1 root 918: }
919:
1.1.1.15 root 920: void REGPARAM2 cia_lput (uaecptr addr, uae_u32 value)
1.1 root 921: {
1.1.1.15 root 922: cia_wput (addr, value >> 16);
923: cia_wput (addr + 2, value & 0xffff);
1.1 root 924: }
925:
926: /* battclock memory access */
927:
1.1.1.3 root 928: static uae_u32 clock_lget (uaecptr) REGPARAM;
929: static uae_u32 clock_wget (uaecptr) REGPARAM;
930: static uae_u32 clock_bget (uaecptr) REGPARAM;
931: static void clock_lput (uaecptr, uae_u32) REGPARAM;
932: static void clock_wput (uaecptr, uae_u32) REGPARAM;
933: static void clock_bput (uaecptr, uae_u32) REGPARAM;
1.1 root 934:
935: addrbank clock_bank = {
936: clock_lget, clock_wget, clock_bget,
937: clock_lput, clock_wput, clock_bput,
1.1.1.20! root 938: default_xlate, default_check, NULL, "Battery backed up clock"
1.1 root 939: };
940:
1.1.1.3 root 941: uae_u32 REGPARAM2 clock_lget (uaecptr addr)
1.1 root 942: {
1.1.1.9 root 943: return clock_bget (addr + 3);
1.1 root 944: }
945:
1.1.1.3 root 946: uae_u32 REGPARAM2 clock_wget (uaecptr addr)
1.1 root 947: {
1.1.1.9 root 948: return clock_bget (addr + 1);
1.1 root 949: }
950:
1.1.1.3 root 951: uae_u32 REGPARAM2 clock_bget (uaecptr addr)
1.1 root 952: {
1.1.1.9 root 953: time_t t = time(0);
1.1 root 954: struct tm *ct;
1.1.1.9 root 955:
956: ct = localtime (&t);
957:
1.1.1.7 root 958: switch (addr & 0x3f) {
959: case 0x03: return ct->tm_sec % 10;
960: case 0x07: return ct->tm_sec / 10;
961: case 0x0b: return ct->tm_min % 10;
962: case 0x0f: return ct->tm_min / 10;
963: case 0x13: return ct->tm_hour % 10;
964: case 0x17: return ct->tm_hour / 10;
965: case 0x1b: return ct->tm_mday % 10;
966: case 0x1f: return ct->tm_mday / 10;
967: case 0x23: return (ct->tm_mon+1) % 10;
968: case 0x27: return (ct->tm_mon+1) / 10;
969: case 0x2b: return ct->tm_year % 10;
970: case 0x2f: return ct->tm_year / 10;
971:
972: case 0x33: return ct->tm_wday; /*Hack by -=SR=- */
973: case 0x37: return clock_control_d;
974: case 0x3b: return clock_control_e;
975: case 0x3f: return clock_control_f;
1.1 root 976: }
977: return 0;
978: }
979:
1.1.1.3 root 980: void REGPARAM2 clock_lput (uaecptr addr, uae_u32 value)
1.1 root 981: {
982: /* No way */
983: }
984:
1.1.1.3 root 985: void REGPARAM2 clock_wput (uaecptr addr, uae_u32 value)
1.1 root 986: {
987: /* No way */
988: }
989:
1.1.1.3 root 990: void REGPARAM2 clock_bput (uaecptr addr, uae_u32 value)
1.1 root 991: {
1.1.1.7 root 992: switch (addr & 0x3f) {
1.1.1.9 root 993: case 0x37: clock_control_d = value; break;
994: case 0x3b: clock_control_e = value; break;
995: case 0x3f: clock_control_f = value; break;
1.1 root 996: }
997: }
1.1.1.11 root 998:
999: /* CIA-A and CIA-B save/restore code */
1000:
1.1.1.19 root 1001: const uae_u8 *restore_cia (int num, const uae_u8 *src)
1.1.1.11 root 1002: {
1003: uae_u8 b;
1004: uae_u16 w;
1005: uae_u32 l;
1006:
1007: /* CIA registers */
1008: b = restore_u8 (); /* 0 PRA */
1009: if (num) ciabpra = b; else ciaapra = b;
1010: b = restore_u8 (); /* 1 PRB */
1011: if (num) ciabprb = b; else ciaaprb = b;
1012: b = restore_u8 (); /* 2 DDRA */
1013: if (num) ciabdra = b; else ciaadra = b;
1014: b = restore_u8 (); /* 3 DDRB */
1015: if (num) ciabdrb = b; else ciaadrb = b;
1016: w = restore_u16 (); /* 4 TA */
1017: if (num) ciabta = w; else ciaata = w;
1018: w = restore_u16 (); /* 6 TB */
1019: if (num) ciabtb = w; else ciaatb = w;
1020: l = restore_u8 (); /* 8/9/A TOD */
1021: l |= restore_u8 () << 8;
1022: l |= restore_u8 () << 16;
1023: if (num) ciabtod = l; else ciaatod = l;
1024: restore_u8 (); /* B unused */
1025: b = restore_u8 (); /* C SDR */
1026: if (num) ciabsdr = b; else ciaasdr = b;
1027: b = restore_u8 (); /* D ICR INFORMATION (not mask!) */
1028: if (num) ciabicr = b; else ciaaicr = b;
1029: b = restore_u8 (); /* E CRA */
1030: if (num) ciabcra = b; else ciaacra = b;
1031: b = restore_u8 (); /* F CRB */
1032: if (num) ciabcrb = b; else ciaacrb = b;
1033:
1034: /* CIA internal data */
1035:
1036: b = restore_u8 (); /* ICR MASK */
1037: if (num) ciabimask = b; else ciaaimask = b;
1038: w = restore_u8 (); /* timer A latch */
1039: w |= restore_u8 () << 8;
1.1.1.13 root 1040: if (num) ciabla = w; else ciaala = w;
1.1.1.11 root 1041: w = restore_u8 (); /* timer B latch */
1042: w |= restore_u8 () << 8;
1043: if (num) ciablb = w; else ciaalb = w;
1044: w = restore_u8 (); /* TOD latched value */
1045: w |= restore_u8 () << 8;
1046: w |= restore_u8 () << 16;
1047: if (num) ciabtol = w; else ciaatol = w;
1048: l = restore_u8 (); /* alarm */
1049: l |= restore_u8 () << 8;
1050: l |= restore_u8 () << 16;
1051: if (num) ciabalarm = l; else ciaaalarm = l;
1052: b = restore_u8 ();
1053: if (num) ciabtlatch = b & 1; else ciaatlatch = b & 1; /* is TOD latched? */
1054: if (num) ciabtodon = b & 2; else ciaatodon = b & 2; /* is TOD stopped? */
1055: if (num) {
1056: div10 = CYCLE_UNIT * restore_u8 ();
1057: }
1058: return src;
1059: }
1060:
1.1.1.18 root 1061: uae_u8 *save_cia (int num, int *len, uae_u8 *dstptr)
1.1.1.11 root 1062: {
1063: uae_u8 *dstbak,*dst, b;
1064: uae_u16 t;
1065:
1.1.1.18 root 1066: if (dstptr)
1067: dstbak = dst = dstptr;
1068: else
1069: dstbak = dst = malloc (16 + 12 + 1);
1.1.1.11 root 1070:
1071: compute_passed_time ();
1072:
1073: /* CIA registers */
1074:
1075: b = num ? ciabpra : ciaapra; /* 0 PRA */
1076: save_u8 (b);
1077: b = num ? ciabprb : ciaaprb; /* 1 PRB */
1078: save_u8 (b);
1079: b = num ? ciabdra : ciaadra; /* 2 DDRA */
1.1.1.18 root 1080: save_u8 (b);
1.1.1.11 root 1081: b = num ? ciabdrb : ciaadrb; /* 3 DDRB */
1082: save_u8 (b);
1083: t = (num ? ciabta - ciabta_passed : ciaata - ciaata_passed);/* 4 TA */
1084: save_u16 (t);
1085: t = (num ? ciabtb - ciabtb_passed : ciaatb - ciaatb_passed);/* 8 TB */
1086: save_u16 (t);
1087: b = (num ? ciabtod : ciaatod); /* 8 TODL */
1088: save_u8 (b);
1089: b = (num ? ciabtod >> 8 : ciaatod >> 8); /* 9 TODM */
1090: save_u8 (b);
1091: b = (num ? ciabtod >> 16 : ciaatod >> 16); /* A TODH */
1092: save_u8 (b);
1093: save_u8 (0); /* B unused */
1094: b = num ? ciabsdr : ciaasdr; /* C SDR */
1095: save_u8 (b);
1096: b = num ? ciabicr : ciaaicr; /* D ICR INFORMATION (not mask!) */
1097: save_u8 (b);
1098: b = num ? ciabcra : ciaacra; /* E CRA */
1099: save_u8 (b);
1100: b = num ? ciabcrb : ciaacrb; /* F CRB */
1101: save_u8 (b);
1102:
1103: /* CIA internal data */
1104:
1105: save_u8 (num ? ciabimask : ciaaimask); /* ICR */
1106: b = (num ? ciabla : ciaala); /* timer A latch LO */
1107: save_u8 (b);
1108: b = (num ? ciabla >> 8 : ciaala >> 8); /* timer A latch HI */
1109: save_u8 (b);
1110: b = (num ? ciablb : ciaalb); /* timer B latch LO */
1111: save_u8 (b);
1112: b = (num ? ciablb >> 8 : ciaalb >> 8); /* timer B latch HI */
1113: save_u8 (b);
1114: b = (num ? ciabtol : ciaatol); /* latched TOD LO */
1115: save_u8 (b);
1116: b = (num ? ciabtol >> 8 : ciaatol >> 8); /* latched TOD MED */
1117: save_u8 (b);
1118: b = (num ? ciabtol >> 16 : ciaatol >> 16); /* latched TOD HI */
1119: save_u8 (b);
1120: b = (num ? ciabalarm : ciaaalarm); /* alarm LO */
1121: save_u8 (b);
1.1.1.20! root 1122: b = (num ? ciabalarm >> 8 : ciaaalarm >> 8); /* alarm MED */
1.1.1.11 root 1123: save_u8 (b);
1124: b = (num ? ciabalarm >> 16 : ciaaalarm >> 16); /* alarm HI */
1125: save_u8 (b);
1126: b = 0;
1127: if (num)
1128: b |= ciabtlatch ? 1 : 0;
1129: else
1130: b |= ciaatlatch ? 1 : 0; /* is TOD latched? */
1131: if (num)
1132: b |= ciabtodon ? 2 : 0;
1133: else
1134: b |= ciaatodon ? 2 : 0; /* TOD stopped? */
1135: save_u8 (b);
1136: if (num) {
1137: /* Save extra state with CIAB. */
1138: save_u8 (div10 / CYCLE_UNIT);
1139: }
1140: *len = dst - dstbak;
1141: return dstbak;
1142: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.