1 /* gngeo a neogeo emulator
2 * Copyright (C) 2001 Peponas Mathieu
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #include "940shared.h"
20 #include "mvs.h"
21 #include "DrZ80.h"
22 #include "2610intf.h"
23
24 Uint16 z80_bank[4];
25 static Uint8 *z80map1, *z80map2, *z80map3, *z80map4;
26 Uint8 drz80mem[0x10000];
27 Uint32 mydrz80_Z80PC,mydrz80_Z80SP;
28
29 struct DrZ80 mydrz80;
30 //extern Z80_Regs Z80;
31
drz80_rebasePC(unsigned short address)32 unsigned int drz80_rebasePC(unsigned short address)
33 {
34 //if (address==0x66)
35 //printf("Rebase PC %x\n",address);
36 mydrz80.Z80PC_BASE = (unsigned int)drz80mem;
37 mydrz80.Z80PC = mydrz80.Z80PC_BASE + address;
38 return mydrz80.Z80PC_BASE + address;
39 }
40
drz80_rebaseSP(unsigned short address)41 unsigned int drz80_rebaseSP(unsigned short address)
42 {
43 //printf("Rebase SP %x\n",address);
44 mydrz80.Z80SP_BASE = (unsigned int)drz80mem;
45 mydrz80.Z80SP = mydrz80.Z80SP_BASE + address;
46 return mydrz80.Z80SP_BASE + address;
47 }
48
drz80_read8(unsigned short address)49 unsigned char drz80_read8(unsigned short address) {
50 return (drz80mem[address&0xFFFF]);
51 }
52
drz80_read16(unsigned short address)53 unsigned short drz80_read16(unsigned short address) {
54 return drz80_read8(address) | (drz80_read8(address + 1) << 8);
55 }
56
drz80_write8(unsigned char data,unsigned short address)57 void drz80_write8(unsigned char data,unsigned short address) {
58 if (address>=0xf800) drz80mem[address&0xFFFF]=data;
59 }
60
drz80_write16(unsigned short data,unsigned short address)61 void drz80_write16(unsigned short data,unsigned short address) {
62 drz80_write8(data & 0xFF,address);
63 drz80_write8(data >> 8,address + 1);
64 }
65 /* cpu interface implementation */
cpu_z80_switchbank(Uint8 bank,Uint16 PortNo)66 void cpu_z80_switchbank(Uint8 bank, Uint16 PortNo)
67 {
68 //printf("Switch bank %x %x\n",bank,PortNo);
69 if (bank<=3)
70 z80_bank[bank]=PortNo;
71
72 switch (bank) {
73 case 0:
74 z80map1 = shared_data->sm1 + (0x4000 * ((PortNo >> 8) & 0x0f));
75 memcpy(drz80mem + 0x8000, z80map1, 0x4000);
76 break;
77 case 1:
78 z80map2 = shared_data->sm1 + (0x2000 * ((PortNo >> 8) & 0x1f));
79 memcpy(drz80mem + 0xc000, z80map2, 0x2000);
80 break;
81 case 2:
82 z80map3 = shared_data->sm1 + (0x1000 * ((PortNo >> 8) & 0x3f));
83 memcpy(drz80mem + 0xe000, z80map3, 0x1000);
84 break;
85 case 3:
86 z80map4 = shared_data->sm1 + (0x0800 * ((PortNo >> 8) & 0x7f));
87 memcpy(drz80mem + 0xf000, z80map4, 0x0800);
88 break;
89 }
90 }
91
92
93 /* Z80 IO port handler */
z80_port_read(Uint16 PortNo)94 Uint8 z80_port_read(Uint16 PortNo)
95 {
96 //printf("z80_port_read PC=%04x p=%04x ",cpu_z80_get_pc(),PortNo);
97 //printf("z80_port_read p=%04x \n",PortNo);
98 switch (PortNo & 0xff) {
99 case 0x0:
100 shared_ctl->pending_command = 0;
101 //printf("Reseting command. Return sndcode %x\n",sound_code);
102 return shared_ctl->sound_code;
103 break;
104
105 case 0x4:
106 //printf("v=%02x\n",YM2610_status_port_0_A_r(0));
107 return YM2610_status_port_A_r(0);
108 break;
109
110 case 0x5:
111 //printf("v=%02x\n",YM2610_read_port_0_r(0));
112 return YM2610_read_port_r(0);
113 break;
114
115 case 0x6:
116 //printf("v=%02x\n",YM2610_status_port_0_B_r(0));
117 return YM2610_status_port_B_r(0);
118 break;
119
120 case 0x08:
121 //printf("v=00 (sb3)\n");
122 cpu_z80_switchbank(3, PortNo);
123 return 0;
124 break;
125
126 case 0x09:
127 //printf("v=00 (sb2)\n");
128 cpu_z80_switchbank(2, PortNo);
129 return 0;
130 break;
131
132 case 0x0a:
133 //printf("v=00 (sb1)\n");
134 cpu_z80_switchbank(1, PortNo);
135 return 0;
136 break;
137
138 case 0x0b:
139 //printf("v=00 (sb0)\n");
140 cpu_z80_switchbank(0, PortNo);
141 return 0;
142 break;
143 };
144
145 return 0;
146 }
147
z80_port_write(Uint16 PortNb,Uint8 Value)148 void z80_port_write(Uint16 PortNb, Uint8 Value)
149 {
150 Uint8 data = Value;
151 //printf("z80_port_write PC=%04x OP=%02x p=%04x v=%02x\n",cpu_z80_get_pc(),memory.sm1[cpu_z80_get_pc()],PortNb,Value);
152 //printf("Write port %04x %02x\n",PortNb,Value);
153 switch (PortNb & 0xff) {
154 case 0x4:
155 YM2610_control_port_A_w(0, data);
156 break;
157
158 case 0x5:
159 YM2610_data_port_A_w(0, data);
160 break;
161
162 case 0x6:
163 YM2610_control_port_B_w(0, data);
164 break;
165
166 case 0x7:
167 YM2610_data_port_B_w(0, data);
168 break;
169
170 case 0xC:
171 //printf("Setting result code to %0x\n",Value);
172 shared_ctl->result_code = Value;
173 break;
174 }
175 }
176
drz80_writeport16(Uint16 port,Uint8 value)177 void drz80_writeport16(Uint16 port, Uint8 value)
178 {
179 //printf("Write port %d=%d\n",port,value);
180 z80_port_write(port, value);
181 }
182
drz80_readport16(Uint16 port)183 Uint8 drz80_readport16(Uint16 port)
184 {
185 //printf("Read port %d\n",port);
186 return z80_port_read(port);
187 }
188
189
drz80_irq_callback(void)190 void drz80_irq_callback(void)
191 {
192 //if (mydrz80.Z80_IRQ ==0x2)
193 //mydrz80.Z80_IRQ = 0x00;
194 //printf("Irq have been accepted %x %x\n",mydrz80.Z80_IRQ,mydrz80.Z80IF);
195 }
196
197 #if 0
198 static void pre_save_state(void) {
199
200 memcpy(shared_data->z80_ram,drz80mem+0xf800,0x800);
201 mydrz80_Z80PC=mydrz80.Z80PC-mydrz80.Z80PC_BASE;
202 mydrz80_Z80SP=mydrz80.Z80SP-mydrz80.Z80SP_BASE;
203 }
204
205 static void post_load_state(void) {
206 int i;
207
208 mydrz80.z80_rebasePC=drz80_rebasePC;
209 mydrz80.z80_rebaseSP=drz80_rebaseSP;
210 mydrz80.z80_read8 =drz80_read8;
211 mydrz80.z80_read16 =drz80_read16;
212 mydrz80.z80_write8 =drz80_write8;
213 mydrz80.z80_write16 =drz80_write16;
214 mydrz80.z80_in =drz80_readport16; /*z80_in*/
215 mydrz80.z80_out =drz80_writeport16; /*z80_out*/
216
217 drz80_rebasePC(mydrz80_Z80PC);
218 drz80_rebaseSP(mydrz80_Z80SP);
219
220 for (i=0;i<4;i++) {
221 cpu_z80_switchbank(i,z80_bank[i]);
222 }
223 memcpy(drz80mem+0xf800,shared_data->z80_ram,0x800);
224
225 }
226
227 static void z80_init_save_state(void) {
228
229 create_state_register(ST_Z80,"drz80",1,(void *)&mydrz80,sizeof(mydrz80),REG_UINT8);
230 create_state_register(ST_Z80,"pc",1,(void *)&mydrz80_Z80PC,sizeof(Uint16),REG_UINT32);
231 create_state_register(ST_Z80,"sp",1,(void *)&mydrz80_Z80SP,sizeof(Uint16),REG_UINT32);
232 create_state_register(ST_Z80,"bank",1,(void *)z80_bank,sizeof(Uint16)*4,REG_UINT16);
233 create_state_register(ST_Z80,"z80_ram",1,(void *)shared_data->z80_ram,sizeof(Uint8)*0x800,REG_UINT8);
234
235 set_post_load_function(ST_Z80,post_load_state);
236 set_pre_save_function(ST_Z80,pre_save_state);
237 }
238 #endif
239
cpu_z80_init(void)240 void cpu_z80_init(void)
241 {
242
243
244 memset (&mydrz80, 0, sizeof(mydrz80));
245
246 mydrz80.z80_rebasePC=drz80_rebasePC;
247 mydrz80.z80_rebaseSP=drz80_rebaseSP;
248 mydrz80.z80_read8 =drz80_read8;
249 mydrz80.z80_read16 =drz80_read16;
250 mydrz80.z80_write8 =drz80_write8;
251 mydrz80.z80_write16 =drz80_write16;
252 mydrz80.z80_in =drz80_readport16; /*z80_in*/
253 mydrz80.z80_out =drz80_writeport16; /*z80_out*/
254 //mydrz80.z80_irq_callback=drz80_irq_callback;
255 mydrz80.Z80A = 0x00 <<24;
256 mydrz80.Z80F = (1<<2); /* set ZFlag */
257 mydrz80.Z80BC = 0x0000 <<16;
258 mydrz80.Z80DE = 0x0000 <<16;
259 mydrz80.Z80HL = 0x0000 <<16;
260 mydrz80.Z80A2 = 0x00 <<24;
261 mydrz80.Z80F2 = 1<<2; /* set ZFlag */
262 mydrz80.Z80BC2 = 0x0000 <<16;
263 mydrz80.Z80DE2 = 0x0000 <<16;
264 mydrz80.Z80HL2 = 0x0000 <<16;
265 mydrz80.Z80IX = 0xFFFF;// <<16;
266 mydrz80.Z80IY = 0xFFFF;// <<16;
267 mydrz80.Z80I = 0x00;
268 mydrz80.Z80IM = 0x01;
269 mydrz80.Z80_IRQ = 0x00;
270 mydrz80.Z80IF = 0x00;
271 mydrz80.Z80PC=mydrz80.z80_rebasePC(0);
272 mydrz80.Z80SP=mydrz80.z80_rebaseSP(0xffff);/*0xf000;*/
273
274
275
276 /* bank initalisation */
277 z80map1 = shared_data->sm1 + 0x8000;
278 z80map2 = shared_data->sm1 + 0xc000;
279 z80map3 = shared_data->sm1 + 0xe000;
280 z80map4 = shared_data->sm1 + 0xf000;
281
282
283
284 z80_bank[0]=0x8000;
285 z80_bank[1]=0xc000;
286 z80_bank[2]=0xe000;
287 z80_bank[3]=0xf000;
288
289 memcpy(drz80mem, shared_data->sm1, 0xf800);
290
291 //z80_init_save_state();
292 }
cpu_z80_run(int nbcycle)293 void cpu_z80_run(int nbcycle)
294 {
295 DrZ80Run(&mydrz80, nbcycle);
296 }
297
cpu_z80_nmi(void)298 void cpu_z80_nmi(void)
299 {
300 mydrz80.Z80_IRQ |= 0x02;
301 }
cpu_z80_raise_irq(int l)302 void cpu_z80_raise_irq(int l)
303 {
304 mydrz80.Z80_IRQ |= 0x1;
305 }
cpu_z80_lower_irq(void)306 void cpu_z80_lower_irq(void)
307 {
308 mydrz80.Z80_IRQ &= ~0x1;
309 }
310