|
|
1.1 ! root 1: /*****************************************************************************/ ! 2: /* Generator - Sega Genesis emulation - (c) James Ponder 1997-1998 */ ! 3: /*****************************************************************************/ ! 4: /* */ ! 5: /* z80.c */ ! 6: /* */ ! 7: /*****************************************************************************/ ! 8: ! 9: #include <stdlib.h> ! 10: #include <stdio.h> ! 11: #include <string.h> ! 12: ! 13: #include "generator.h" ! 14: #include "cpuz80.h" ! 15: #include "cpu68k.h" ! 16: #include "memz80.h" ! 17: #include "ui.h" ! 18: ! 19: #include "z80/mz80.h" ! 20: ! 21: UINT8 cpuz80_read_actual(UINT32 addr, struct MemoryReadByte *me); ! 22: void cpuz80_write_actual(UINT32 addr, UINT8 data, struct MemoryWriteByte *me); ! 23: UINT16 cpuz80_ioread_actual(UINT16 addr, struct z80PortRead *me); ! 24: void cpuz80_iowrite_actual(UINT16 addr, UINT8 data, struct z80PortWrite *me); ! 25: ! 26: /*** variables externed ***/ ! 27: ! 28: uint8 *cpuz80_ram = NULL; ! 29: uint32 cpuz80_bank = 0; ! 30: unsigned int cpuz80_active = 0; ! 31: ! 32: /*** global variables ***/ ! 33: ! 34: static unsigned int cpuz80_lastsync = 0; ! 35: static unsigned int cpuz80_resetting = 0; ! 36: static CONTEXTMZ80 cpuz80_z80; ! 37: ! 38: static struct MemoryReadByte cpuz80_read[] = { ! 39: { 0x0000, 0xFFFF, cpuz80_read_actual, NULL }, ! 40: { -1, -1, NULL, NULL } ! 41: }; ! 42: ! 43: static struct MemoryWriteByte cpuz80_write[] = { ! 44: { 0x0000, 0xFFFF, cpuz80_write_actual, NULL }, ! 45: { -1, -1, NULL, NULL } ! 46: }; ! 47: ! 48: static struct z80PortRead cpuz80_ioread[] = { ! 49: { 0x0000, 0x00FF, cpuz80_ioread_actual, NULL }, ! 50: { -1, -1, NULL, NULL } ! 51: }; ! 52: ! 53: static struct z80PortWrite cpuz80_iowrite[] = { ! 54: { 0x0000, 0x00FF, cpuz80_iowrite_actual, NULL }, ! 55: { -1, -1, NULL, NULL } ! 56: }; ! 57: ! 58: UINT8 cpuz80_read_actual(UINT32 addr, struct MemoryReadByte *me) ! 59: { ! 60: (void)me; ! 61: return memz80_fetchbyte((uint32)addr); ! 62: } ! 63: ! 64: void cpuz80_write_actual(UINT32 addr, UINT8 data, struct MemoryWriteByte *me) ! 65: { ! 66: (void)me; ! 67: memz80_storebyte((uint32)addr, (uint8)data); ! 68: } ! 69: ! 70: UINT16 cpuz80_ioread_actual(UINT16 addr, struct z80PortRead *me) ! 71: { ! 72: (void)me; ! 73: return cpuz80_portread((uint16)addr); ! 74: } ! 75: ! 76: void cpuz80_iowrite_actual(UINT16 addr, UINT8 data, struct z80PortWrite *me) ! 77: { ! 78: (void)me; ! 79: cpuz80_portwrite((uint16)addr, (uint8)data); ! 80: } ! 81: ! 82: /*** cpuz80_init - initialise this sub-unit ***/ ! 83: ! 84: int cpuz80_init(void) ! 85: { ! 86: /* mz80init(); */ ! 87: cpuz80_reset(); ! 88: return 0; ! 89: } ! 90: ! 91: /*** cpuz80_reset - reset z80 sub-unit ***/ ! 92: ! 93: void cpuz80_reset(void) ! 94: { ! 95: if (!cpuz80_ram) { ! 96: if ((cpuz80_ram = malloc(LEN_SRAM)) == NULL) { ! 97: fprintf(stderr, "Out of memory\n"); ! 98: exit(1); ! 99: } ! 100: } ! 101: memset(cpuz80_ram, 0, LEN_SRAM); ! 102: cpuz80_resetcpu(); ! 103: cpuz80_bank = 0; ! 104: cpuz80_active = 0; ! 105: cpuz80_lastsync = 0; ! 106: cpuz80_resetting = 0; ! 107: /* mz80GetContext(&cpuz80_z80); */ ! 108: memset(&cpuz80_z80, 0, sizeof(cpuz80_z80)); ! 109: cpuz80_z80.z80Base = cpuz80_ram; ! 110: cpuz80_z80.z80MemRead = cpuz80_read; ! 111: cpuz80_z80.z80MemWrite = cpuz80_write; ! 112: cpuz80_z80.z80IoRead = cpuz80_ioread; ! 113: cpuz80_z80.z80IoWrite = cpuz80_iowrite; ! 114: mz80SetContext(&cpuz80_z80); ! 115: mz80reset(); ! 116: } ! 117: ! 118: /*** cpuz80_resetcpu - reset z80 cpu ***/ ! 119: ! 120: void cpuz80_resetcpu(void) ! 121: { ! 122: mz80reset(); ! 123: cpuz80_resetting = 1; /* suspends execution */ ! 124: } ! 125: ! 126: /*** cpuz80_unresetcpu - unreset z80 cpu ***/ ! 127: ! 128: void cpuz80_unresetcpu(void) ! 129: { ! 130: cpuz80_resetting = 0; /* un-suspends execution */ ! 131: } ! 132: ! 133: /*** cpuz80_bankwrite - data is being written to latch ***/ ! 134: ! 135: void cpuz80_bankwrite(uint8 data) ! 136: { ! 137: cpuz80_bank = (((cpuz80_bank >> 1) | ((data & 1) <<23)) & 0xff8000); ! 138: /* ! 139: if (gen_debug) ! 140: printf("BANK WRITE: %d --> %08X\n", data, cpuz80_bank); ! 141: */ ! 142: } ! 143: ! 144: /*** cpuz80_stop - stop the processor ***/ ! 145: ! 146: void cpuz80_stop(void) ! 147: { ! 148: cpuz80_sync(); ! 149: cpuz80_active = 0; ! 150: } ! 151: ! 152: /*** cpuz80_start - start the processor ***/ ! 153: ! 154: void cpuz80_start(void) ! 155: { ! 156: cpuz80_sync(); ! 157: cpuz80_active = 1; ! 158: } ! 159: ! 160: /*** cpuz80_endfield - reset counters ***/ ! 161: ! 162: void cpuz80_endfield(void) ! 163: { ! 164: cpuz80_lastsync = 0; ! 165: } ! 166: ! 167: /*** cpuz80_sync - synchronise ***/ ! 168: ! 169: void cpuz80_sync(void) ! 170: { ! 171: int cpu68k_wanted = cpu68k_clocks - cpuz80_lastsync; ! 172: int wanted = (cpu68k_wanted<0?0:cpu68k_wanted)*7/16; ! 173: int acheived; ! 174: ! 175: if (cpuz80_active && !cpuz80_resetting) { ! 176: /* ui_log(LOG_USER, "executing %d z80 clocks @ %X", wanted, ! 177: cpuz80_z80.z80pc); */ ! 178: mz80exec(wanted); ! 179: acheived = mz80GetElapsedTicks(1); ! 180: /* this if/else statement below, I'm not entirely sure this is a good ! 181: idea, perhaps just doing cpuz80_lastsync = cpu68k_clocks; always is ! 182: better? hmm. */ ! 183: if (acheived > wanted) { ! 184: cpuz80_lastsync = cpu68k_clocks; ! 185: } else { ! 186: cpuz80_lastsync = cpuz80_lastsync + acheived*16/7; ! 187: } ! 188: } else { ! 189: cpuz80_lastsync = cpu68k_clocks; ! 190: } ! 191: } ! 192: ! 193: /*** cpuz80_interrupt - cause an interrupt on the z80 */ ! 194: ! 195: void cpuz80_interrupt(void) ! 196: { ! 197: if (!cpuz80_resetting) ! 198: mz80int(0); ! 199: } ! 200: ! 201: /*** cpuz80_portread - port read from z80 */ ! 202: ! 203: uint8 cpuz80_portread(uint8 port) ! 204: { ! 205: LOG_VERBOSE(("[Z80] Port read to %X", port)); ! 206: return 0; ! 207: } ! 208: ! 209: /*** cpuz80_portwrite - z80 write to port */ ! 210: ! 211: void cpuz80_portwrite(uint8 port, uint8 value) ! 212: { ! 213: LOG_VERBOSE(("[Z80] Port write to %X of %X", port, value)); ! 214: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.