|
|
1.1 ! root 1: /* ! 2: * UAE - The Unusable Amiga Emulator ! 3: * ! 4: * CIA chip support v0.1 ! 5: * v0.0: 950301 ! 6: * stubs ! 7: * v0.1: 950304 ! 8: * hopefully all the timer functionality is implemented correctly ! 9: * ! 10: * (c) 1995 Bernd Schmidt ! 11: */ ! 12: ! 13: #include <iostream.h> ! 14: #include <iomanip.h> ! 15: ! 16: #include "amiga.h" ! 17: #include "memory.h" ! 18: #include "disk.h" ! 19: ! 20: static UBYTE ciaaicr,ciaaimask,ciabicr,ciabimask; ! 21: static UBYTE ciaacra,ciaacrb,ciabcra,ciabcrb; ! 22: static UWORD ciaata,ciaatb,ciabta,ciabtb; ! 23: static UWORD ciaala,ciaalb,ciabla,ciablb; ! 24: static ULONG ciaatod,ciabtod,ciaatol,ciabtol,ciaaalarm,ciabalarm; ! 25: static bool ciaatlatch,ciabtlatch; ! 26: static UBYTE ciaapra,ciaaprb,ciaadra,ciaadrb,ciaasdr; ! 27: static UBYTE ciabpra,ciabprb,ciabdra,ciabdrb,ciabsdr; ! 28: static int div10,hsync,vsync; ! 29: ! 30: static void setclr(UBYTE &p, UBYTE val) ! 31: { ! 32: cout << "setclr\n"; ! 33: if (val & 0x80) { ! 34: p |= val & 0x7F; ! 35: } else { ! 36: p &= ~val; ! 37: } ! 38: } ! 39: ! 40: static void RethinkICRA() ! 41: { ! 42: if (ciaaimask & ciaaicr) { ! 43: ciaaicr |= 0x80; ! 44: mem.put_word(0xDFF09C,0x8008); ! 45: cout << "CIA A int\n"; ! 46: } else { ! 47: ciaaicr &= 0x7F; ! 48: mem.put_word(0xDFF09C,0x0008); ! 49: } ! 50: } ! 51: ! 52: static void RethinkICRB() ! 53: { ! 54: if (ciabimask & ciabicr) { ! 55: ciabicr |= 0x80; ! 56: mem.put_word(0xDFF09C,0xA000); ! 57: cout << "CIA B int\n"; ! 58: } else { ! 59: ciabicr &= 0x7F; ! 60: mem.put_word(0xDFF09C,0x2000); ! 61: } ! 62: } ! 63: ! 64: UBYTE ReadCIAA(UWORD addr) ! 65: { ! 66: UBYTE tmp; ! 67: ! 68: switch(addr & 0xf){ ! 69: case 0: ! 70: return (DISK_status() & 0x3C) | 0xc0; // no mouse ! 71: case 1: ! 72: return ciaaprb; ! 73: case 2: ! 74: return ciaadra; ! 75: case 3: ! 76: return ciaadrb; ! 77: case 4: ! 78: return ciaata & 0xff; ! 79: case 5: ! 80: return ciaata >> 8; ! 81: case 6: ! 82: return ciaatb & 0xff; ! 83: case 7: ! 84: return ciaatb >> 8; ! 85: case 8: ! 86: if (ciaatlatch) { ! 87: ciaatlatch = 0; ! 88: return ciaatol & 0xff; ! 89: } else return ciaatod & 0xff; ! 90: case 9: ! 91: if (ciaatlatch) return (ciaatol >> 8) & 0xff; ! 92: else return (ciaatod >> 8) & 0xff; ! 93: case 10: ! 94: ciaatlatch = 1; ciaatol = ciaatod; // ??? only if not already latched? ! 95: return (ciaatol >> 16) & 0xff; ! 96: case 12: ! 97: return ciaasdr; ! 98: case 13: ! 99: tmp = ciaaicr; ciaaicr = 0; RethinkICRA(); return tmp; ! 100: case 14: ! 101: return ciaacra; ! 102: case 15: ! 103: return ciaacrb; ! 104: } ! 105: return 0; ! 106: } ! 107: ! 108: UBYTE ReadCIAB(UWORD addr) ! 109: { ! 110: UBYTE tmp; ! 111: ! 112: switch(addr & 0xf){ ! 113: case 0: ! 114: return ciabpra; ! 115: case 1: ! 116: return ciabprb; ! 117: case 2: ! 118: return ciabdra; ! 119: case 3: ! 120: return ciabdrb; ! 121: case 4: ! 122: return ciabta & 0xff; ! 123: case 5: ! 124: return ciabta >> 8; ! 125: case 6: ! 126: return ciabtb & 0xff; ! 127: case 7: ! 128: return ciabtb >> 8; ! 129: case 8: ! 130: if (ciabtlatch) { ! 131: ciabtlatch = 0; ! 132: return ciabtol & 0xff; ! 133: } else return ciabtod & 0xff; ! 134: case 9: ! 135: if (ciabtlatch) return (ciabtol >> 8) & 0xff; ! 136: else return (ciabtod >> 8) & 0xff; ! 137: case 10: ! 138: ciabtlatch = 1; ciabtol = ciabtod; ! 139: return (ciabtol >> 16) & 0xff; ! 140: case 12: ! 141: return ciabsdr; ! 142: case 13: ! 143: tmp = ciabicr; ciabicr = 0; RethinkICRB(); return tmp; ! 144: case 14: ! 145: return ciabcra; ! 146: case 15: ! 147: return ciabcrb; ! 148: } ! 149: return 0; ! 150: } ! 151: ! 152: void WriteCIAA(UWORD addr,UBYTE val) ! 153: { ! 154: switch(addr & 0xf){ ! 155: case 0: ! 156: ciaapra = (ciaapra & ~0x3) | (val & 0x3); break; ! 157: case 1: ! 158: ciaaprb = val; break; ! 159: case 2: ! 160: ciaadra = val; break; ! 161: case 3: ! 162: ciaadrb = val; break; ! 163: case 4: ! 164: ciaala = (ciaala & 0xff00) | val; ! 165: break; ! 166: case 5: ! 167: ciaala = (ciaala & 0xff) | (val << 8); ! 168: if ((ciaacra & 1) == 0) ciaata = ciaala; ! 169: if (ciaacra & 8) { ciaata = ciaala; ciaacra |= 1; }//??? load latch always? ! 170: break; ! 171: case 6: ! 172: ciaalb = (ciaalb & 0xff00) | val; ! 173: break; ! 174: case 7: ! 175: ciaalb = (ciaalb & 0xff) | (val << 8); ! 176: if ((ciaacrb & 1) == 0) ciaatb = ciaalb; ! 177: if (ciaacrb & 8) { ciaatb = ciaalb; ciaacrb |= 1; } ! 178: break; ! 179: case 8: ! 180: if (ciaacrb & 0x80){ ! 181: ciaaalarm = (ciaaalarm & ~0xff) | val; ! 182: } else { ! 183: ciaatod = (ciaatod & ~0xff) | val; ! 184: } ! 185: break; ! 186: case 9: ! 187: if (ciaacrb & 0x80){ ! 188: ciaaalarm = (ciaaalarm & ~0xff00) | (val << 8); ! 189: } else { ! 190: ciaatod = (ciaatod & ~0xff00) | (val << 8); ! 191: } ! 192: break; ! 193: case 10: ! 194: if (ciaacrb & 0x80){ ! 195: ciaaalarm = (ciaaalarm & ~0xff0000) | (val << 16); ! 196: } else { ! 197: ciaatod = (ciaatod & ~0xff0000) | (val << 16); ! 198: } ! 199: break; ! 200: case 12: ! 201: ciaasdr = val; break; ! 202: case 13: ! 203: setclr(ciaaimask,val); break; // ??? call RethinkICR() ? ! 204: case 14: ! 205: ciaacra = val; ! 206: if (ciaacra & 0x10){ ! 207: ciaacra &= ~0x10; ! 208: ciaata = ciaala; ! 209: } ! 210: cout << "CIAACRA write" << val << "\n"; ! 211: break; ! 212: case 15: ! 213: ciaacrb = val; ! 214: if (ciaacrb & 0x10){ ! 215: ciaacrb &= ~0x10; ! 216: ciaatb = ciaalb; ! 217: } ! 218: cout << "CIAACRB write" << val << "\n"; ! 219: break; ! 220: } ! 221: } ! 222: ! 223: void WriteCIAB(UWORD addr,UBYTE val) ! 224: { ! 225: switch(addr & 0xf){ ! 226: case 0: ! 227: ciabpra = (ciabpra & ~0x3) | (val & 0x3); break; ! 228: case 1: ! 229: ciabprb = val; DISK_select(val); break; ! 230: case 2: ! 231: ciabdra = val; break; ! 232: case 3: ! 233: ciabdrb = val; break; ! 234: case 4: ! 235: ciabla = (ciabla & 0xff00) | val; ! 236: break; ! 237: case 5: ! 238: ciabla = (ciabla & 0xff) | (val << 8); ! 239: if ((ciabcra & 1) == 0) ciabta = ciabla; ! 240: if (ciabcra & 8) { ciabta = ciabla; ciabcra |= 1; } ! 241: break; ! 242: case 6: ! 243: ciablb = (ciablb & 0xff00) | val; ! 244: break; ! 245: case 7: ! 246: ciablb = (ciablb & 0xff) | (val << 8); ! 247: if ((ciabcrb & 1) == 0) ciabtb = ciablb; ! 248: if (ciabcrb & 8) { ciabtb = ciablb; ciabcrb |= 1; } ! 249: break; ! 250: case 8: ! 251: if (ciabcrb & 0x80){ ! 252: ciabalarm = (ciabalarm & ~0xff) | val; ! 253: } else { ! 254: ciabtod = (ciabtod & ~0xff) | val; ! 255: } ! 256: break; ! 257: case 9: ! 258: if (ciabcrb & 0x80){ ! 259: ciabalarm = (ciabalarm & ~0xff00) | (val << 8); ! 260: } else { ! 261: ciabtod = (ciabtod & ~0xff00) | (val << 8); ! 262: } ! 263: break; ! 264: case 10: ! 265: if (ciabcrb & 0x80){ ! 266: ciabalarm = (ciabalarm & ~0xff0000) | (val << 16); ! 267: } else { ! 268: ciabtod = (ciabtod & ~0xff0000) | (val << 16); ! 269: } ! 270: break; ! 271: case 12: ! 272: ciabsdr = val; break; ! 273: case 13: ! 274: setclr(ciabimask,val); break; ! 275: case 14: ! 276: ciabcra = val; ! 277: if (ciabcra & 0x10){ ! 278: ciabcra &= ~0x10; ! 279: ciabta = ciabla; ! 280: } ! 281: break; ! 282: cout << "CIABCRA write" << val << "\n"; ! 283: case 15: ! 284: ciabcrb = val; ! 285: if (ciabcrb & 0x10){ ! 286: ciabcrb &= ~0x10; ! 287: ciabtb = ciablb; ! 288: } ! 289: break; ! 290: cout << "CIBACRB write" << val << "\n"; ! 291: } ! 292: } ! 293: ! 294: void CIA_reset() ! 295: { ! 296: ciaatlatch = ciabtlatch = 0; ! 297: ciaatod = ciabtod = 0; ! 298: ciaaicr = ciabicr = ciaaimask = ciabimask = 0; ! 299: ciaacra = ciaacrb = ciabcra = ciabcrb = 0x4; // outmode = toggle; ! 300: div10 = 0; hsync = vsync = 0; ! 301: } ! 302: ! 303: void CIA_hsync() { hsync = 1; } ! 304: void CIA_vsync() { vsync = 1; } ! 305: ! 306: void CIA_cycle() ! 307: { ! 308: int aovfla = 0, aovflb = 0, bovfla = 0, bovflb = 0; ! 309: //int foo = ciaacra | ciaacrb | ciabcra | ciabcrb; ! 310: ! 311: if (++div10 > 9) { ! 312: // if (foo & 1) cout << "CIA is ON: ICRs "<< hex << (int)ciaaimask << " " << (int)ciabimask << "!\n"; ! 313: div10 = 0; ! 314: // CIA A timers ! 315: if ((ciaacra & 0x21) == 0x01) { ! 316: if (ciaata-- == 0) { ! 317: aovfla = 1; ! 318: if ((ciaacrb & 0x61) == 0x41) { ! 319: if (ciaatb-- == 0) aovflb = 1; ! 320: } ! 321: } ! 322: } ! 323: if ((ciaacrb & 0x61) == 0x01) { ! 324: if (ciaatb-- == 0) { ! 325: aovflb = 1; ! 326: } ! 327: } ! 328: // CIA B timers ! 329: if ((ciabcra & 0x21) == 0x01) { ! 330: if (ciabta-- == 0) { ! 331: bovfla = 1; ! 332: if ((ciabcrb & 0x61) == 0x41) { ! 333: if (ciabtb-- == 0) bovflb = 1; ! 334: } ! 335: } ! 336: } ! 337: if ((ciabcrb & 0x61) == 0x01) { ! 338: if (ciabtb-- == 0) { ! 339: bovflb = 1; ! 340: } ! 341: } ! 342: if (aovfla) { ! 343: ciaaicr |= 1; RethinkICRA(); ! 344: ciaata = ciaala; ! 345: if (ciaacra & 0x8) ciaacra &= ~1; ! 346: } ! 347: if (aovflb) { ! 348: ciaaicr |= 2; RethinkICRA(); ! 349: ciaatb = ciaalb; ! 350: if (ciaacrb & 0x8) ciaacrb &= ~1; ! 351: } ! 352: if (bovfla) { ! 353: ciabicr |= 1; RethinkICRB(); ! 354: ciabta = ciabla; ! 355: if (ciabcra & 0x8) ciabcra &= ~1; ! 356: } ! 357: if (bovflb) { ! 358: ciabicr |= 2; RethinkICRA(); ! 359: ciabtb = ciablb; ! 360: if (ciabcrb & 0x8) ciabcrb &= ~1; ! 361: } ! 362: } ! 363: if (hsync){ ! 364: hsync = 0; ! 365: ciabtod++; ! 366: ciabtod &= 0xFFFFFF; ! 367: if (ciabtod == ciabalarm) { ! 368: ciabicr |= 4; RethinkICRB(); ! 369: } ! 370: } ! 371: if (vsync){ ! 372: vsync = 0; ! 373: ciaatod++; ! 374: ciaatod &= 0xFFFFFF; ! 375: if (ciaatod == ciaaalarm) { ! 376: ciaaicr |= 4; RethinkICRA(); ! 377: } ! 378: } ! 379: ! 380: } ! 381: ! 382: void dumpcia() ! 383: { ! 384: cout << hex << setw(2); ! 385: cout << "A: CRA: " << (int)ciaacra << " CRB: " <<(int)ciaacrb << "IMASK: " << ! 386: (int)ciaaimask << " TOD: " << ciaatod << (ciaatlatch ? " latched" : "") << ! 387: " TA: " << ciaata << " TB:" << ciaatb << "\n"; ! 388: cout << "B: CRA: " << (int)ciabcra << " CRB: " <<(int)ciabcrb << "IMASK: " << ! 389: (int)ciabimask << " TOD: " << ciabtod << (ciabtlatch ? " latched" : "") << ! 390: " TA:" << ciabta << " TB:" << ciabtb << "\n"; ! 391: } ! 392: ! 393: UWORD cia64k::wget(UWORD addr) ! 394: { ! 395: return bget(addr+1); ! 396: } ! 397: ! 398: UBYTE cia64k::bget(UWORD addr) ! 399: { ! 400: // cout << "CIA read at " << addr << "\n"; ! 401: if ((addr & 0xF0FF) == 0xE001) ! 402: return ReadCIAA((addr & 0xF00) >> 8); ! 403: if ((addr & 0xF0FF) == 0xD000) ! 404: return ReadCIAB((addr & 0xF00) >> 8); ! 405: return 0; ! 406: } ! 407: ! 408: void cia64k::wput(UWORD addr,UWORD value) ! 409: { ! 410: bput(addr+1,value); ! 411: } ! 412: ! 413: void cia64k::bput(UWORD addr,UBYTE value) ! 414: { ! 415: // cout << "CIA write " << (int)value << " at " << addr << "\n"; ! 416: if ((addr & 0xF0FF) == 0xE001) ! 417: WriteCIAA((addr & 0xF00) >> 8,value); ! 418: if ((addr & 0xF0FF) == 0xD000) ! 419: WriteCIAB((addr & 0xF00) >> 8,value); ! 420: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.