|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * Gayle (and motherboard resources) memory bank ! 5: * ! 6: * (c) 2006 - 2007 Toni Wilen ! 7: */ ! 8: ! 9: #define GAYLE_LOG 0 ! 10: #define IDE_LOG 0 ! 11: #define MBRES_LOG 0 ! 12: ! 13: #include "sysconfig.h" ! 14: #include "sysdeps.h" ! 15: ! 16: #include "options.h" ! 17: ! 18: #include "memory.h" ! 19: #include "custom.h" ! 20: #include "newcpu.h" ! 21: #include "gayle.h" ! 22: #include "zfile.h" ! 23: #include "filesys.h" ! 24: #include "savestate.h" ! 25: #include "gui.h" ! 26: ! 27: /* ! 28: D80000 to D8FFFF 64 KB SPARE chip select ! 29: D90000 to D9FFFF 64 KB ARCNET chip select ! 30: DA0000 to DA3FFF 16 KB IDE drive ! 31: DA4000 to DA4FFF 16 KB IDE reserved ! 32: DA8000 to DAFFFF 32 KB Credit Card and IDE configregisters ! 33: DB0000 to DBFFFF 64 KB Not used(reserved for external IDE) ! 34: * DC0000 to DCFFFF 64 KB Real Time Clock(RTC) ! 35: DD0000 to DDFFFF 64 KB A3000 DMA controller ! 36: DD0000 to DD1FFF A4000 DMAC ! 37: DD2000 to DDFFFF A4000 IDE ! 38: DE0000 to DEFFFF 64 KB Motherboard resources ! 39: */ ! 40: ! 41: #define NCR_OFFSET 0x40 ! 42: ! 43: /* Gayle definitions from Linux drivers */ ! 44: ! 45: /* PCMCIA stuff */ ! 46: ! 47: #define GAYLE_RAM (0x600000+zTwoBase) ! 48: #define GAYLE_RAMSIZE (0x400000) ! 49: #define GAYLE_ATTRIBUTE (0xa00000+zTwoBase) ! 50: #define GAYLE_ATTRIBUTESIZE (0x020000) ! 51: #define GAYLE_IO (0xa20000+zTwoBase) /* 16bit and even 8bit registers */ ! 52: #define GAYLE_IOSIZE (0x010000) ! 53: #define GAYLE_IO_8BITODD (0xa30000+zTwoBase) /* odd 8bit registers */ ! 54: /* offset for accessing odd IO registers */ ! 55: #define GAYLE_ODD (GAYLE_IO_8BITODD-GAYLE_IO-1) ! 56: ! 57: #define GAYLE_ADDRESS (0xda8000) /* gayle main registers base address */ ! 58: #define GAYLE_RESET (0xa40000) /* write 0x00 to start reset, ! 59: read 1 byte to stop reset */ ! 60: /* GAYLE_CARDSTATUS bit def */ ! 61: #define GAYLE_CS_CCDET 0x40 /* credit card detect */ ! 62: #define GAYLE_CS_BVD1 0x20 /* battery voltage detect 1 */ ! 63: #define GAYLE_CS_SC 0x20 /* credit card status change */ ! 64: #define GAYLE_CS_BVD2 0x10 /* battery voltage detect 2 */ ! 65: #define GAYLE_CS_DA 0x10 /* digital audio */ ! 66: #define GAYLE_CS_WR 0x08 /* write enable (1 == enabled) */ ! 67: #define GAYLE_CS_BSY 0x04 /* credit card busy */ ! 68: #define GAYLE_CS_IRQ 0x04 /* interrupt request */ ! 69: ! 70: /* GAYLE_CONFIG bit def ! 71: (bit 0-1 for program voltage, bit 2-3 for access speed */ ! 72: #define GAYLE_CFG_0V 0x00 ! 73: #define GAYLE_CFG_5V 0x01 ! 74: #define GAYLE_CFG_12V 0x02 ! 75: ! 76: #define GAYLE_CFG_100NS 0x08 ! 77: #define GAYLE_CFG_150NS 0x04 ! 78: #define GAYLE_CFG_250NS 0x00 ! 79: #define GAYLE_CFG_720NS 0x0c ! 80: ! 81: /* IDE stuff */ ! 82: ! 83: /* Bases of the IDE interfaces */ ! 84: #define GAYLE_BASE_4000 0xdd2020 /* A4000/A4000T */ ! 85: #define GAYLE_BASE_1200 0xda0000 /* A1200/A600 and E-Matrix 530 */ ! 86: /* IDE drive registers */ ! 87: #define IDE_DATA 0x00 ! 88: #define IDE_ERROR 0x01 /* see err-bits */ ! 89: #define IDE_NSECTOR 0x02 /* nr of sectors to read/write */ ! 90: #define IDE_SECTOR 0x03 /* starting sector */ ! 91: #define IDE_LCYL 0x04 /* starting cylinder */ ! 92: #define IDE_HCYL 0x05 /* high byte of starting cyl */ ! 93: #define IDE_SELECT 0x06 /* 101dhhhh , d=drive, hhhh=head */ ! 94: #define IDE_STATUS 0x07 /* see status-bits */ ! 95: #define IDE_DEVCON 0x0406 ! 96: #define IDE_DRVADDR 0x0407 ! 97: /* STATUS bits */ ! 98: #define IDE_STATUS_ERR 0x01 ! 99: #define IDE_STATUS_IDX 0x02 ! 100: #define IDE_STATUS_DRQ 0x08 ! 101: #define IDE_STATUS_DSC 0x10 ! 102: #define IDE_STATUS_DRDY 0x40 ! 103: #define IDE_STATUS_BSY 0x80 ! 104: /* ERROR bits */ ! 105: #define IDE_ERR_ABRT 0x04 ! 106: ! 107: /* ! 108: * These are at different offsets from the base ! 109: */ ! 110: #define GAYLE_IRQ_4000 0x3020 /* MSB = 1, Harddisk is source of interrupt */ ! 111: #define GAYLE_IRQ_1200 0x9000 ! 112: #define GAYLE_INT_1200 0xA000 ! 113: ! 114: /* GAYLE_IRQ bit def */ ! 115: #define GAYLE_IRQ_IDE 0x80 ! 116: #define GAYLE_IRQ_CCDET 0x40 ! 117: #define GAYLE_IRQ_BVD1 0x20 ! 118: #define GAYLE_IRQ_SC 0x20 ! 119: #define GAYLE_IRQ_BVD2 0x10 ! 120: #define GAYLE_IRQ_DA 0x10 ! 121: #define GAYLE_IRQ_WR 0x08 ! 122: #define GAYLE_IRQ_BSY 0x04 ! 123: #define GAYLE_IRQ_IRQ 0x04 ! 124: #define GAYLE_IRQ_IDEACK1 0x02 ! 125: #define GAYLE_IRQ_IDEACK0 0x01 ! 126: ! 127: struct ide_hdf ! 128: { ! 129: uae_u8 secbuf[512 * 256]; ! 130: uae_u8 multiple_mode; ! 131: uae_u8 status; ! 132: int irq_delay; ! 133: int num; ! 134: }; ! 135: ! 136: static struct ide_hdf idedrive[4]; ! 137: ! 138: static int gayle_id_cnt; ! 139: static uae_u8 gayle_irq, gayle_intena; ! 140: static uae_u8 ide_select, ide_nsector, ide_sector, ide_lcyl, ide_hcyl, ide_devcon, ide_error, ide_feat; ! 141: static uae_u8 ide_nsector2, ide_sector2, ide_lcyl2, ide_hcyl2, ide_feat2; ! 142: static int ide_drv, ide2, ide_splitter; ! 143: ! 144: static struct ide_hdf *ide; ! 145: ! 146: STATIC_INLINE void pw (int offset, uae_u16 w) ! 147: { ! 148: ide->secbuf[offset * 2 + 0] = (uae_u8)w; ! 149: ide->secbuf[offset * 2 + 1] = w >> 8; ! 150: } ! 151: ! 152: static void ps (int offset, char *s, int max) ! 153: { ! 154: int i, len; ! 155: ! 156: offset *= 2; ! 157: len = strlen(s); ! 158: for (i = 0; i < max; i++) { ! 159: char c = ' '; ! 160: if (i < len) ! 161: c = s[i]; ! 162: ide->secbuf[offset ^ 1] = c; ! 163: offset++; ! 164: } ! 165: } ! 166: ! 167: static void ide_interrupt(void) ! 168: { ! 169: ide->status |= IDE_STATUS_BSY; ! 170: ide->irq_delay = 2; ! 171: } ! 172: ! 173: static void ide_interrupt_do(struct ide_hdf *ide) ! 174: { ! 175: ide->status &= ~IDE_STATUS_BSY; ! 176: if (gayle_intena & GAYLE_IRQ_IDE) { ! 177: gayle_irq |= GAYLE_IRQ_IDE; ! 178: INTREQ (0x8000 | 0x0008); ! 179: } ! 180: } ! 181: ! 182: static void ide_fail(void) ! 183: { ! 184: ide_error |= IDE_ERR_ABRT; ! 185: #if 0 ! 186: if (ide_drv == 1 && idedrive[ide2 + 1].hdhfd.size == 0) ! 187: idedrive[ide2].status |= IDE_STATUS_ERR; ! 188: #endif ! 189: ide->status |= IDE_STATUS_ERR; ! 190: ide_interrupt(); ! 191: } ! 192: ! 193: static void ide_recalibrate(void) ! 194: { ! 195: write_log ("IDE%d recalibrate\n", ide->num); ! 196: ide_sector = 0; ! 197: ide_lcyl = ide_hcyl = 0; ! 198: ide_interrupt(); ! 199: } ! 200: ! 201: static void ide_identify_drive(void) ! 202: { ! 203: int totalsecs; ! 204: int v; ! 205: ! 206: ide_fail(); ! 207: return; ! 208: } ! 209: ! 210: static void ide_initialize_drive_parameters(void) ! 211: { ! 212: ide_error |= IDE_ERR_ABRT; ! 213: ide->status |= IDE_STATUS_ERR; ! 214: ide_interrupt(); ! 215: } ! 216: ! 217: static void ide_set_multiple_mode(void) ! 218: { ! 219: write_log ("IDE%d drive multiple mode = %d\n", ide->num, ide_nsector); ! 220: ide->multiple_mode = ide_nsector; ! 221: ide_interrupt(); ! 222: } ! 223: ! 224: static void ide_set_features(void) ! 225: { ! 226: write_log ("IDE%d set features %02.2X (%02.2X)\n", ide->num, ide_feat, ide_nsector); ! 227: ide_fail(); ! 228: } ! 229: ! 230: static void ide_read_sectors(int multi) ! 231: { ! 232: ide_fail(); ! 233: } ! 234: ! 235: static void ide_write_sectors(int multi) ! 236: { ! 237: ide_fail(); ! 238: } ! 239: ! 240: static void ide_do_command(uae_u8 cmd) ! 241: { ! 242: if (IDE_LOG > 1) ! 243: write_log ("**** IDE%d command %02.2X\n", ide->num, cmd); ! 244: ide->status &= ~(IDE_STATUS_DRDY | IDE_STATUS_DRQ | IDE_STATUS_ERR); ! 245: ide_error = 0; ! 246: ! 247: if (cmd == 0x10) { /* recalibrate */ ! 248: ide_recalibrate(); ! 249: } else if (cmd == 0xec) { /* identify drive */ ! 250: ide_identify_drive(); ! 251: } else if (cmd == 0x91) { /* initialize drive parameters */ ! 252: ide_initialize_drive_parameters(); ! 253: } else if (cmd == 0xc6) { /* set multiple mode */ ! 254: ide_set_multiple_mode(); ! 255: } else if (cmd == 0x20 || cmd == 0x21) { /* read sectors */ ! 256: ide_read_sectors(0); ! 257: } else if (cmd == 0x30 || cmd == 0x31) { /* write sectors */ ! 258: ide_write_sectors(0); ! 259: } else if (cmd == 0xc4) { /* read multiple */ ! 260: ide_read_sectors(1); ! 261: } else if (cmd == 0xc5) { /* write multiple */ ! 262: ide_write_sectors(1); ! 263: } else if (cmd == 0x50) { /* format track (nop) */ ! 264: ide_interrupt(); ! 265: } else if (cmd == 0xa1) { /* ATAPI identify (IDE HD is not ATAPI) */ ! 266: ide_fail(); ! 267: } else if (cmd == 0xef) { /* set features */ ! 268: ide_set_features(); ! 269: } else { ! 270: ide_fail(); ! 271: write_log ("IDE: unknown command %x\n", cmd); ! 272: } ! 273: } ! 274: ! 275: static uae_u16 ide_get_data (void) ! 276: { ! 277: if (IDE_LOG > 0) ! 278: write_log ("IDE%d DATA read without DRQ!?\n", ide->num); ! 279: return 0xffff; ! 280: } ! 281: ! 282: static void ide_put_data (uae_u16 v) ! 283: { ! 284: if (IDE_LOG > 0) ! 285: write_log ("IDE%d DATA write without DRQ!?\n", ide->num); ! 286: } ! 287: ! 288: static int get_ide_reg (uaecptr addr) ! 289: { ! 290: uaecptr a = addr; ! 291: addr &= 0xffff; ! 292: if (addr >= 0x3020 && addr <= 0x3021 && currprefs.cs_ide == 2) ! 293: return -1; ! 294: addr &= ~0x2020; ! 295: addr >>= 2; ! 296: ide2 = 0; ! 297: if (addr & 0x400) { ! 298: if (ide_splitter) { ! 299: ide2 = 2; ! 300: addr &= ~0x400; ! 301: } ! 302: } ! 303: ide = &idedrive[ide_drv + ide2]; ! 304: return addr; ! 305: } ! 306: ! 307: static uae_u32 ide_read (uaecptr addr) ! 308: { ! 309: int ide_reg; ! 310: uae_u8 v = 0; ! 311: ! 312: addr &= 0xffff; ! 313: if (IDE_LOG > 1 && addr != 0x2000 && addr != 0x2001 && addr != 0x2020 && addr != 0x2021 && addr != GAYLE_IRQ_1200) ! 314: write_log ("IDE_READ %08.8X PC=%X\n", addr, m68k_getpc ()); ! 315: if (currprefs.cs_ide <= 0) { ! 316: if (addr == 0x201c) // AR1200 IDE detection hack ! 317: return 0x7f; ! 318: return 0xff; ! 319: } ! 320: if (addr >= GAYLE_IRQ_4000 && addr <= GAYLE_IRQ_4000 + 1 && currprefs.cs_ide == 2) { ! 321: uae_u8 v = gayle_irq; ! 322: gayle_irq = 0; ! 323: return v; ! 324: } ! 325: if (addr >= 0x4000) { ! 326: if (addr == GAYLE_IRQ_1200) { ! 327: if (currprefs.cs_ide == 1) ! 328: return gayle_irq; ! 329: return 0; ! 330: } else if (addr == GAYLE_INT_1200) { ! 331: if (currprefs.cs_ide == 1) ! 332: return gayle_intena; ! 333: return 0; ! 334: } ! 335: return 0; ! 336: } ! 337: ide_reg = get_ide_reg(addr); ! 338: /* Emulated "ide killer". Prevents long KS boot delay if no drives installed */ ! 339: if (ide_reg == IDE_STATUS) ! 340: return 0x7f; ! 341: return 0xff; ! 342: ! 343: } ! 344: ! 345: static void ide_write (uaecptr addr, uae_u32 val) ! 346: { ! 347: int ide_reg; ! 348: ! 349: addr &= 0xffff; ! 350: ide_devcon &= ~0x80; ! 351: if (IDE_LOG > 1 && addr != 0x2000 && addr != 0x2001 && addr != 0x2020 && addr != 0x2021 && addr != GAYLE_IRQ_1200) ! 352: write_log ("IDE_WRITE %08.8X=%02.2X PC=%X\n", addr, (uae_u32)val & 0xff, m68k_getpc ()); ! 353: if (currprefs.cs_ide <= 0) ! 354: return; ! 355: if (currprefs.cs_ide == 1) { ! 356: if (addr == GAYLE_IRQ_1200) { ! 357: gayle_irq = 0; ! 358: return; ! 359: } ! 360: if (addr == GAYLE_INT_1200) { ! 361: gayle_intena = val; ! 362: return; ! 363: } ! 364: } ! 365: if (addr >= 0x4000) ! 366: return; ! 367: ide_reg = get_ide_reg(addr); ! 368: if (IDE_LOG > 2 && ide_reg > 0) ! 369: write_log ("IDE%d register %d=%02.2X\n", ide->num, ide_reg, (uae_u32)val & 0xff); ! 370: switch (ide_reg) ! 371: { ! 372: case IDE_DRVADDR: ! 373: break; ! 374: case IDE_DEVCON: ! 375: ide_devcon = val; ! 376: break; ! 377: case IDE_DATA: ! 378: break; ! 379: case IDE_ERROR: ! 380: ide_feat2 = ide_feat; ! 381: ide_feat = val; ! 382: break; ! 383: case IDE_NSECTOR: ! 384: ide_nsector2 = ide_nsector; ! 385: ide_nsector = val; ! 386: break; ! 387: case IDE_SECTOR: ! 388: ide_sector2 = ide_sector; ! 389: ide_sector = val; ! 390: break; ! 391: case IDE_LCYL: ! 392: ide_lcyl2 = ide_lcyl; ! 393: ide_lcyl = val; ! 394: break; ! 395: case IDE_HCYL: ! 396: ide_hcyl2 = ide_hcyl; ! 397: ide_hcyl = val; ! 398: break; ! 399: case IDE_SELECT: ! 400: ide_select = val; ! 401: ide_drv = (val & 0x10) ? 1 : 0; ! 402: break; ! 403: case IDE_STATUS: ! 404: ide_do_command (val); ! 405: break; ! 406: } ! 407: } ! 408: ! 409: static int gayle_read (uaecptr addr) ! 410: { ! 411: uaecptr oaddr = addr; ! 412: uae_u32 v = 0; ! 413: #ifdef JIT ! 414: special_mem |= S_READ; ! 415: #endif ! 416: v = ide_read(addr); ! 417: if (GAYLE_LOG) ! 418: write_log ("GAYLE_READ %08.8X=%02.2X PC=%08.8X\n", oaddr, (uae_u32)v & 0xff, m68k_getpc ()); ! 419: return v; ! 420: } ! 421: static void gayle_write (uaecptr addr, int val) ! 422: { ! 423: #ifdef JIT ! 424: special_mem |= S_WRITE; ! 425: #endif ! 426: if (GAYLE_LOG) ! 427: write_log ("GAYLE_WRITE %08.8X=%02.2X PC=%08.8X\n", addr, (uae_u32)val & 0xff, m68k_getpc ()); ! 428: ide_write(addr, val); ! 429: } ! 430: ! 431: static uae_u32 gayle_lget (uaecptr) REGPARAM; ! 432: static uae_u32 gayle_wget (uaecptr) REGPARAM; ! 433: static uae_u32 gayle_bget (uaecptr) REGPARAM; ! 434: static void gayle_lput (uaecptr, uae_u32) REGPARAM; ! 435: static void gayle_wput (uaecptr, uae_u32) REGPARAM; ! 436: static void gayle_bput (uaecptr, uae_u32) REGPARAM; ! 437: ! 438: addrbank gayle_bank = { ! 439: gayle_lget, gayle_wget, gayle_bget, ! 440: gayle_lput, gayle_wput, gayle_bput, ! 441: default_xlate, default_check, NULL, "Gayle (low)" ! 442: }; ! 443: ! 444: #if 0 ! 445: static int isa4000t (uaecptr addr) ! 446: { ! 447: if (currprefs.cs_mbdmac != 2) ! 448: return 0; ! 449: if ((addr & 0xffff) >= (GAYLE_BASE_4000 & 0xffff)) ! 450: return 0; ! 451: return 1; ! 452: } ! 453: #endif ! 454: ! 455: static uae_u32 REGPARAM2 gayle_lget (uaecptr addr) ! 456: { ! 457: uae_u32 v; ! 458: #ifdef JIT ! 459: special_mem |= S_READ; ! 460: #endif ! 461: v = gayle_wget (addr) << 16; ! 462: v |= gayle_wget (addr + 2); ! 463: return v; ! 464: } ! 465: static uae_u32 REGPARAM2 gayle_wget (uaecptr addr) ! 466: { ! 467: int ide_reg; ! 468: uae_u16 v; ! 469: #ifdef JIT ! 470: special_mem |= S_READ; ! 471: #endif ! 472: #if 0 ! 473: if (isa4000t(addr)) { ! 474: addr -= NCR_OFFSET; ! 475: return (ncr_bget2 (addr) << 8) | ncr_bget2 (addr + 1); ! 476: } ! 477: #endif ! 478: ide_reg = get_ide_reg (addr); ! 479: if (ide_reg == IDE_DATA) ! 480: return ide_get_data (); ! 481: v = gayle_bget (addr) << 8; ! 482: v |= gayle_bget (addr + 1); ! 483: return v; ! 484: } ! 485: static uae_u32 REGPARAM2 gayle_bget (uaecptr addr) ! 486: { ! 487: #ifdef JIT ! 488: special_mem |= S_READ; ! 489: #endif ! 490: #if 0 ! 491: if (isa4000t(addr)) { ! 492: addr -= NCR_OFFSET; ! 493: return ncr_bget2(addr); ! 494: } ! 495: #endif ! 496: return gayle_read (addr); ! 497: } ! 498: ! 499: static void REGPARAM2 gayle_lput (uaecptr addr, uae_u32 value) ! 500: { ! 501: #ifdef JIT ! 502: special_mem |= S_WRITE; ! 503: #endif ! 504: gayle_wput (addr, value >> 16); ! 505: gayle_wput (addr + 2, value & 0xffff); ! 506: } ! 507: static void REGPARAM2 gayle_wput (uaecptr addr, uae_u32 value) ! 508: { ! 509: int ide_reg; ! 510: #ifdef JIT ! 511: special_mem |= S_WRITE; ! 512: #endif ! 513: #if 0 ! 514: if (isa4000t (addr)) { ! 515: addr -= NCR_OFFSET; ! 516: ncr_bput2 (addr, value >> 8); ! 517: ncr_bput2 (addr + 1, value); ! 518: return; ! 519: } ! 520: #endif ! 521: ide_reg = get_ide_reg (addr); ! 522: if (ide_reg == IDE_DATA) { ! 523: ide_put_data(value); ! 524: return; ! 525: } ! 526: gayle_bput (addr, value >> 8); ! 527: gayle_bput (addr + 1, value & 0xff); ! 528: } ! 529: ! 530: static void REGPARAM2 gayle_bput (uaecptr addr, uae_u32 value) ! 531: { ! 532: #ifdef JIT ! 533: special_mem |= S_WRITE; ! 534: #endif ! 535: #if 0 ! 536: if (isa4000t(addr)) { ! 537: addr -= NCR_OFFSET; ! 538: ncr_bput2(addr, value); ! 539: return; ! 540: } ! 541: #endif ! 542: gayle_write (addr, value); ! 543: } ! 544: ! 545: static void gayle2_write(uaecptr addr, uae_u32 v) ! 546: { ! 547: gayle_id_cnt = 0; ! 548: } ! 549: ! 550: static uae_u32 gayle2_read(uaecptr addr) ! 551: { ! 552: uae_u8 v = 0; ! 553: addr &= 0xffff; ! 554: if (addr == 0x1000) { ! 555: /* Gayle ID */ ! 556: if ((gayle_id_cnt & 3) == 2) ! 557: v = 0x7f; ! 558: else ! 559: v = 0x80; ! 560: gayle_id_cnt++; ! 561: } ! 562: return v; ! 563: } ! 564: ! 565: static uae_u32 gayle2_lget (uaecptr) REGPARAM; ! 566: static uae_u32 gayle2_wget (uaecptr) REGPARAM; ! 567: static uae_u32 gayle2_bget (uaecptr) REGPARAM; ! 568: static void gayle2_lput (uaecptr, uae_u32) REGPARAM; ! 569: static void gayle2_wput (uaecptr, uae_u32) REGPARAM; ! 570: static void gayle2_bput (uaecptr, uae_u32) REGPARAM; ! 571: ! 572: addrbank gayle2_bank = { ! 573: gayle2_lget, gayle2_wget, gayle2_bget, ! 574: gayle2_lput, gayle2_wput, gayle2_bput, ! 575: default_xlate, default_check, NULL, "Gayle (high)" ! 576: }; ! 577: ! 578: static uae_u32 REGPARAM2 gayle2_lget (uaecptr addr) ! 579: { ! 580: uae_u32 v; ! 581: #ifdef JIT ! 582: special_mem |= S_READ; ! 583: #endif ! 584: v = gayle2_wget (addr) << 16; ! 585: v |= gayle2_wget (addr + 2); ! 586: return v; ! 587: } ! 588: static uae_u32 REGPARAM2 gayle2_wget (uaecptr addr) ! 589: { ! 590: uae_u16 v; ! 591: #ifdef JIT ! 592: special_mem |= S_READ; ! 593: #endif ! 594: v = gayle2_bget (addr) << 8; ! 595: v |= gayle2_bget (addr + 1); ! 596: return v; ! 597: } ! 598: static uae_u32 REGPARAM2 gayle2_bget (uaecptr addr) ! 599: { ! 600: #ifdef JIT ! 601: special_mem |= S_READ; ! 602: #endif ! 603: return gayle2_read (addr); ! 604: } ! 605: ! 606: static void REGPARAM2 gayle2_lput (uaecptr addr, uae_u32 value) ! 607: { ! 608: #ifdef JIT ! 609: special_mem |= S_WRITE; ! 610: #endif ! 611: gayle2_wput (addr, value >> 16); ! 612: gayle2_wput (addr + 2, value & 0xffff); ! 613: } ! 614: ! 615: static void REGPARAM2 gayle2_wput (uaecptr addr, uae_u32 value) ! 616: { ! 617: #ifdef JIT ! 618: special_mem |= S_WRITE; ! 619: #endif ! 620: gayle2_bput (addr, value >> 8); ! 621: gayle2_bput (addr + 1, value & 0xff); ! 622: } ! 623: ! 624: static void REGPARAM2 gayle2_bput (uaecptr addr, uae_u32 value) ! 625: { ! 626: #ifdef JIT ! 627: special_mem |= S_WRITE; ! 628: #endif ! 629: gayle2_write (addr, value); ! 630: } ! 631: ! 632: static uae_u8 ramsey_config; ! 633: static int gary_coldboot, gary_toenb, gary_timeout; ! 634: static int garyidoffset; ! 635: ! 636: static void mbres_write (uaecptr addr, uae_u32 val, int size) ! 637: { ! 638: addr &= 0xffff; ! 639: ! 640: if (MBRES_LOG > 0) ! 641: write_log ("MBRES_WRITE %08X=%08X (%d) PC=%08X S=%d\n", addr, val, size, m68k_getpc (), regs.s); ! 642: if (regs.s) { /* CPU FC = supervisor only */ ! 643: if (addr == 0x1002) ! 644: garyidoffset = -1; ! 645: if (addr == 0x03) ! 646: ramsey_config = val; ! 647: if (addr == 0x02) ! 648: gary_coldboot = (val & 0x80) ? 1 : 0; ! 649: if (addr == 0x01) ! 650: gary_toenb = (val & 0x80) ? 1 : 0; ! 651: if (addr == 0x00) ! 652: gary_timeout = (val & 0x80) ? 1 : 0; ! 653: } else { ! 654: custom_bank.wput (addr, val); ! 655: } ! 656: } ! 657: ! 658: static uae_u32 mbres_read (uaecptr addr, int size) ! 659: { ! 660: uae_u32 v = 0; ! 661: addr &= 0xffff; ! 662: ! 663: if (regs.s) { /* CPU FC = supervisor only */ ! 664: /* Gary ID (I don't think this exists in real chips..) */ ! 665: if (addr == 0x1002 && currprefs.cs_fatgaryrev >= 0) { ! 666: garyidoffset++; ! 667: garyidoffset &= 7; ! 668: v = (currprefs.cs_fatgaryrev << garyidoffset) & 0x80; ! 669: } ! 670: if (addr == 0x43) { /* RAMSEY revision */ ! 671: if (currprefs.cs_ramseyrev >= 0) ! 672: v = currprefs.cs_ramseyrev; ! 673: } ! 674: if (addr == 0x03) { /* RAMSEY config */ ! 675: if (currprefs.cs_ramseyrev >= 0) ! 676: v = ramsey_config; ! 677: } ! 678: if (addr == 0x02) { /* coldreboot flag */ ! 679: if (currprefs.cs_fatgaryrev >= 0) ! 680: v = gary_coldboot ? 0x80 : 0x00; ! 681: } ! 682: if (addr == 0x01) { /* toenb flag */ ! 683: if (currprefs.cs_fatgaryrev >= 0) ! 684: v = gary_toenb ? 0x80 : 0x00; ! 685: } ! 686: if (addr == 0x00) { /* timeout flag */ ! 687: if (currprefs.cs_fatgaryrev >= 0) ! 688: v = gary_timeout ? 0x80 : 0x00; ! 689: } ! 690: } else { ! 691: v = custom_bank.wget (addr); ! 692: } ! 693: if (MBRES_LOG > 0) ! 694: write_log ("MBRES_READ %08X=%08X (%d) PC=%08X S=%d\n", addr, v, size, m68k_getpc (), regs.s); ! 695: return v; ! 696: } ! 697: ! 698: static uae_u32 mbres_lget (uaecptr) REGPARAM; ! 699: static uae_u32 mbres_wget (uaecptr) REGPARAM; ! 700: static uae_u32 mbres_bget (uaecptr) REGPARAM; ! 701: static void mbres_lput (uaecptr, uae_u32) REGPARAM; ! 702: static void mbres_wput (uaecptr, uae_u32) REGPARAM; ! 703: static void mbres_bput (uaecptr, uae_u32) REGPARAM; ! 704: ! 705: static uae_u32 REGPARAM2 mbres_lget (uaecptr addr) ! 706: { ! 707: uae_u32 v; ! 708: #ifdef JIT ! 709: special_mem |= S_READ; ! 710: #endif ! 711: v = mbres_wget (addr) << 16; ! 712: v |= mbres_wget (addr + 2); ! 713: return v; ! 714: } ! 715: static uae_u32 REGPARAM2 mbres_wget (uaecptr addr) ! 716: { ! 717: #ifdef JIT ! 718: special_mem |= S_READ; ! 719: #endif ! 720: return mbres_read (addr, 2); ! 721: } ! 722: static uae_u32 REGPARAM2 mbres_bget (uaecptr addr) ! 723: { ! 724: #ifdef JIT ! 725: special_mem |= S_READ; ! 726: #endif ! 727: return mbres_read (addr, 1); ! 728: } ! 729: ! 730: static void REGPARAM2 mbres_lput (uaecptr addr, uae_u32 value) ! 731: { ! 732: #ifdef JIT ! 733: special_mem |= S_WRITE; ! 734: #endif ! 735: mbres_wput (addr, value >> 16); ! 736: mbres_wput (addr + 2, value & 0xffff); ! 737: } ! 738: ! 739: static void REGPARAM2 mbres_wput (uaecptr addr, uae_u32 value) ! 740: { ! 741: #ifdef JIT ! 742: special_mem |= S_WRITE; ! 743: #endif ! 744: mbres_write (addr, value, 2); ! 745: } ! 746: ! 747: static void REGPARAM2 mbres_bput (uaecptr addr, uae_u32 value) ! 748: { ! 749: #ifdef JIT ! 750: special_mem |= S_WRITE; ! 751: #endif ! 752: mbres_write (addr, value, 1); ! 753: } ! 754: ! 755: addrbank mbres_bank = { ! 756: mbres_lget, mbres_wget, mbres_bget, ! 757: mbres_lput, mbres_wput, mbres_bput, ! 758: default_xlate, default_check, NULL, "Motherboard Resources" ! 759: }; ! 760: ! 761: void gayle_hsync (void) ! 762: { ! 763: int i; ! 764: ! 765: for (i = 0; i < 4; i++) { ! 766: struct ide_hdf *ide = &idedrive[i]; ! 767: if (ide->irq_delay > 0) { ! 768: ide->irq_delay--; ! 769: if (ide->irq_delay == 0) ! 770: ide_interrupt_do (ide); ! 771: } ! 772: } ! 773: } ! 774: ! 775: static uae_u32 gayle_attr_read (uaecptr addr) ! 776: { ! 777: uae_u8 v = 0; ! 778: write_log ("R: %x %x\n", addr, m68k_getpc ()); ! 779: addr &= 262144 - 1; ! 780: switch (addr) ! 781: { ! 782: case 0: ! 783: v = 0x91; ! 784: break; ! 785: case 2: ! 786: v = 0x05; ! 787: break; ! 788: case 4: ! 789: v = 0x23; ! 790: break; ! 791: } ! 792: return v; ! 793: } ! 794: static void gayle_attr_write (uaecptr addr, uae_u32 v) ! 795: { ! 796: write_log ("W: %x=%x %x\n", addr, v, m68k_getpc ()); ! 797: addr &= 262144 - 1; ! 798: if (addr == 0x40000) { ! 799: if (v) ! 800: write_log ("GAYLE: Reset active\n"); ! 801: else ! 802: write_log ("GAYLE: Reset non-active\n"); ! 803: } ! 804: } ! 805: ! 806: static uae_u32 gayle_attr_lget (uaecptr) REGPARAM; ! 807: static uae_u32 gayle_attr_wget (uaecptr) REGPARAM; ! 808: static uae_u32 gayle_attr_bget (uaecptr) REGPARAM; ! 809: static void gayle_attr_lput (uaecptr, uae_u32) REGPARAM; ! 810: static void gayle_attr_wput (uaecptr, uae_u32) REGPARAM; ! 811: static void gayle_attr_bput (uaecptr, uae_u32) REGPARAM; ! 812: ! 813: addrbank gayle_attr_bank = { ! 814: gayle_attr_lget, gayle_attr_wget, gayle_attr_bget, ! 815: gayle_attr_lput, gayle_attr_wput, gayle_attr_bput, ! 816: default_xlate, default_check, NULL, "Gayle PCMCIA attribute" ! 817: }; ! 818: ! 819: static uae_u32 REGPARAM2 gayle_attr_lget (uaecptr addr) ! 820: { ! 821: uae_u32 v; ! 822: #ifdef JIT ! 823: special_mem |= S_READ; ! 824: #endif ! 825: v = gayle_attr_wget (addr) << 16; ! 826: v |= gayle_attr_wget (addr + 2); ! 827: return v; ! 828: } ! 829: static uae_u32 REGPARAM2 gayle_attr_wget (uaecptr addr) ! 830: { ! 831: uae_u16 v; ! 832: #ifdef JIT ! 833: special_mem |= S_READ; ! 834: #endif ! 835: v = gayle_attr_bget (addr) << 8; ! 836: v |= gayle_attr_bget (addr + 1); ! 837: return v; ! 838: } ! 839: static uae_u32 REGPARAM2 gayle_attr_bget (uaecptr addr) ! 840: { ! 841: #ifdef JIT ! 842: special_mem |= S_READ; ! 843: #endif ! 844: return gayle_attr_read (addr); ! 845: } ! 846: ! 847: static void REGPARAM2 gayle_attr_lput (uaecptr addr, uae_u32 value) ! 848: { ! 849: #ifdef JIT ! 850: special_mem |= S_WRITE; ! 851: #endif ! 852: gayle_attr_wput (addr, value >> 16); ! 853: gayle_attr_wput (addr + 2, value & 0xffff); ! 854: } ! 855: ! 856: static void REGPARAM2 gayle_attr_wput (uaecptr addr, uae_u32 value) ! 857: { ! 858: #ifdef JIT ! 859: special_mem |= S_WRITE; ! 860: #endif ! 861: gayle_attr_bput (addr, value >> 8); ! 862: gayle_attr_bput (addr + 1, value & 0xff); ! 863: } ! 864: ! 865: static void REGPARAM2 gayle_attr_bput (uaecptr addr, uae_u32 value) ! 866: { ! 867: #ifdef JIT ! 868: special_mem |= S_WRITE; ! 869: #endif ! 870: gayle_attr_write (addr, value); ! 871: } ! 872: ! 873: static void initide (void) ! 874: { ! 875: int i; ! 876: ! 877: if (savestate_state == STATE_RESTORE) ! 878: return; ! 879: ide_error = 1; ! 880: ide_sector = ide_nsector = 1; ! 881: ide_select = 0; ! 882: ide_lcyl = ide_hcyl = ide_devcon = ide_feat = 0; ! 883: ide_drv = 0; ! 884: ide_splitter = 0; ! 885: gayle_irq = gayle_intena = 0; ! 886: if (currprefs.cs_ide == 2) ! 887: gayle_intena = 0xff; ! 888: ! 889: } ! 890: ! 891: void gayle_reset (int hardreset) ! 892: { ! 893: static char bankname[100]; ! 894: initide (); ! 895: if (hardreset) { ! 896: ramsey_config = 0; ! 897: gary_coldboot = 1; ! 898: gary_timeout = 0; ! 899: gary_toenb = 0; ! 900: } ! 901: strcpy (bankname, "Gayle (low)"); ! 902: if (currprefs.cs_ide == 2) ! 903: strcpy (bankname, "A4000 IDE"); ! 904: #if 0 ! 905: if (currprefs.cs_mbdmac == 2) { ! 906: strcat (bankname," + NCR53C710 SCSI"); ! 907: ncr_reset (); ! 908: } ! 909: #endif ! 910: gayle_bank.name = bankname; ! 911: } ! 912: ! 913: const uae_u8 *restore_gayle (const uae_u8 *src) ! 914: { ! 915: changed_prefs.cs_ide = restore_u8(); ! 916: gayle_intena = restore_u8(); ! 917: gayle_irq = restore_u8(); ! 918: ide_error = 0; ! 919: return src; ! 920: } ! 921: ! 922: uae_u8 *save_gayle (int *len) ! 923: { ! 924: uae_u8 *dstbak, *dst; ! 925: ! 926: if (currprefs.cs_ide <= 0) ! 927: return NULL; ! 928: dstbak = dst = (uae_u8*)malloc (1000); ! 929: save_u8 (currprefs.cs_ide); ! 930: save_u8 (gayle_intena); ! 931: save_u8 (gayle_irq); ! 932: *len = dst - dstbak; ! 933: return dstbak; ! 934: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.