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