|
|
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.