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