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