Import Debian changes 1.23-11
[debian-dgen.git] / mem.cpp
blob2ecb40b0b5b89a88900ebafb5eecacbb767d3de7
1 // DGen/SDL v1.15+
2 // Megadrive C++ module - misc memory
4 #include <stdio.h>
5 #include "md.h"
6 // md.h also has include fm.h
8 // This is to handle memory accesses outside of ROM and RAM
9 // e.g. c00000 and a00000 addresses
10 // REMEMBER NOT TO USE ANY STATIC variables, because they
11 // will exist thoughout ALL megadrives!
13 unsigned char md::z80_read(unsigned int a)
15 if (a<0x2000) return z80ram[a&0xffff];
18 if ((a&0xfffc)==0x4000) // 00 01 02 03 - not sure about reads
20 return myfm_read(a&3);
23 if (a>=0x8000)
25 int addr68k;
26 addr68k=z80_bank68k<<15;
27 addr68k+=a&0x7fff;
29 return misc_readbyte(addr68k);
32 return 0;
35 unsigned short md::z80_port_read(unsigned short a)
37 int ret=0;
39 // dprintf("z80 port read %.2x return %.4x\n",a,ret);
41 return ret;
43 void md::z80_port_write(unsigned short a,unsigned char v)
45 // dprintf("z80 port write %.2x %.2x\n",a,v);
49 void md::z80_write(unsigned int a,unsigned char v)
51 if ((a&0xfffc)==0x4000) // 00 01 02 03
53 myfm_write(a&3,v,1);
54 return ;
56 if (a==0x7f11)
57 { mysn_write(v); return; }
59 if (a==0x6000)
61 z80_bank68k>>=1;
62 z80_bank68k+=(v&1)<<8;
63 z80_bank68k&=0x1ff; // 9 bits and filled in the new top one
64 return ;
66 if (a<0x2000) { z80ram[a&0xffff]=v; return; }
69 if (a>=0x8000)
71 int addr68k;
72 addr68k=z80_bank68k<<15;
73 addr68k+=a&0x7fff;
74 misc_writebyte(addr68k,v);
75 return;
78 // dprintf("z80 write %.4x %.2x\n",a,v);
79 return;
83 unsigned md::misc_readbyte(unsigned a)
85 unsigned char ret=0;
86 a&=0x00ffffff; // in case stars didn't clip to 24-bit bus
89 // In case it's a rom read after all
90 if (a<0xa00000) {
91 // Saveram
92 if((save_active) && (save_len) &&
93 (a >= save_start) && ((a - save_start) < save_len)) {
94 return saveram[(a^1) - save_start];
96 else if ((signed)(a^1)<romlen) { ret=rom[(a^1)]; goto end; }
99 // In case it's a ram read after all
100 if (a>=0xe00000) if (a<=0xffffff) { ret=ram[(a^1)&0xffff]; goto end; }
102 // GFX data read (byte)
103 if ((a&0xfffffffe)==0x00c00000) // 00 or 01
104 { ret=vdp.readbyte(); goto end; }
107 if ((a&0xfffffffc)==0xa04000)
109 ret=myfm_read(a&3); goto end;
112 if ((a>=0xa00000)&&(a<0xa08000))
114 // Read from z80's memory
115 ret=z80_read(a&0x7fff); goto end;
118 // I/O port access
119 if ((a&0xfffffe)==0xa10002)
121 if (aoo3_six==3)
123 // Extended pad info
124 if (aoo3_toggle==0) ret=((pad[0]>>8)&0x30)+0x00;
125 else ret=((pad[0])&0x30)+0x40+((pad[0]>>16)&0xf);
127 else
129 if (aoo3_toggle==0)
131 if (aoo3_six==4) ret=((pad[0]>>8)&0x30)+0x00+0x0f;
132 else ret=((pad[0]>>8)&0x30)+0x00+(pad[0]&3);
134 else ret=((pad[0])&0x30)+0x40+(pad[0]&15);
136 goto end;
139 if ((a&0xfffffe)==0xa10004)
141 if (aoo5_six==3)
143 // Extended pad info
144 if (aoo5_toggle==0x00) ret=((pad[1]>>8)&0x30)+0x00;
145 else ret=((pad[1])&0x30)+0x40+((pad[1]>>16)&0xf);
147 else
149 if (aoo5_toggle==0x00)
151 if (aoo5_six==4) ret=((pad[1]>>8)&0x30)+0x00+0x0f;
152 else ret=((pad[1]>>8)&0x30)+0x00+(pad[1]&3);
154 else ret=((pad[1])&0x30)+0x40+(pad[1]&15);
156 goto end;
159 if (a==0xa10001)
161 // overseas/pal/disk/0/ md version (0-f) - may make games act different!
162 if ((country_ver&0xff0)==0xff0)
164 // autodetect country
165 int headcode=0x80,avail=0;
166 int i;
167 for (i=0;i<3;i++)
169 int ch=misc_readbyte(0x1f0+i);
170 if (ch=='U') avail|=1;
171 else if (ch=='E') avail|=2;
172 else if (ch=='J') avail|=4;
174 if (avail&1) headcode=0x80;
175 else if (avail&2) headcode=0x80;
176 else if (avail&4) headcode=0x00;
177 ret=headcode+(country_ver&0x0f) | (pal? 0x40 : 0);
179 else ret=country_ver;
180 goto end;
183 if (a==0xa11000) {ret=0xff; goto end; }
184 if (a==0xa11001) {ret=0xff; goto end; }
185 if (a==0xa11100)
187 ret=z80_online; goto end;
189 if (a==0xa11101) {ret=0x00; goto end; }
190 if (a==0xa11200) {ret=0xff; goto end; }
191 if (a==0xa11201) {ret=0xff; goto end; }
193 // Genecyst style - toggles fifo full/empty
194 if (a==0xc00004)
196 // This is the genecyst fudge for FIFO full/empty
197 coo4^=0x03;
198 ret=coo4; goto end;
200 if (a==0xc00005)
202 // This is the genecyst fudge for in h-blank
203 //coo5^=0x04;
204 ret=coo5 | (pal? 1 : 0); goto end;
207 if (a==0xc00008) { ret=calculate_coo8(); goto end; }
208 if (a==0xc00009) { ret=calculate_coo9(); goto end; }
211 end:
212 return ret;
215 void md::misc_writebyte(unsigned a,unsigned d)
217 a&=0x00ffffff; // in case stars didn't clip to 24-bit bus
219 // Saveram write
220 if(save_len && !save_prot) if(a >= save_start)
221 if ((a - save_start) < save_len)
222 { saveram[(a^1) - save_start] = d; return; }
224 // In case it's a ram write after all
226 if (a>=0xe00000) if (a<=0xffffff) { ram[(a^1)&0xffff]=d; return; }
228 // GFX data write (byte)
229 if ((a&0xfffffffe)==0x00c00000) // 00 or 01
230 { vdp.writebyte(d); return; }
232 if ((a&0xfffffffc)==0xa04000)
234 myfm_write(a&3,d,1);
235 return;
238 if (a==0xc00011)
240 mysn_write(d); return;
243 if (a==0xa11100)
245 //d8 (W) 0: BUSREQ CANCEL
246 // 1: BUSREQ REQUEST
247 if (d==1) z80_online=0;
248 else z80_online=1;
249 return;
251 if (a==0xa11101) return;
252 if (a==0xa11200)
254 if (d==0)
255 mz80reset();
256 return;
258 if (a==0xa11201) return;
260 if ((a>=0xa00000)&&(a<0xa08000))
262 // Write into z80's memory
263 z80_write(a&0x7fff,d);
264 return;
267 // I/O port access
268 if (a==0xa10003)
270 if (aoo3_six>=0 && (d&0x40)==0 && aoo3_toggle ) aoo3_six++;
272 if (aoo3_six>0xc00000) aoo3_six&=~0x400000;
273 // keep it circling around a high value
275 if (d&0x40) aoo3_toggle=1; else aoo3_toggle=0;
276 aoo3_six_timeout=0;
277 return;
279 if (a==0xa10005)
281 if (aoo5_six>=0 && (d&0x40)==0 && aoo5_toggle ) aoo5_six++;
283 if (aoo5_six>0xc00000) aoo5_six&=~0x400000;
284 // keep it circling around a high value
286 if (d&0x40) aoo5_toggle=1; else aoo5_toggle=0;
287 aoo5_six_timeout=0;
288 return;
290 // Saveram status (thanks Steve :)
291 if(a==0xa130f1)
293 // Bit 0: 0=rom active, 1=sram active
294 // Bit 1: 0=writeable, 1=write protect
295 save_active = d & 1;
296 save_prot = d & 2;
300 unsigned md::misc_readword(unsigned a)
302 unsigned int ret=0;
304 a&=0x00ffffff; // in case stars didn't clip to 24-bit bus
306 if ((a&0xfffffffc)==0x00c00000) // 00 or 02
308 ret=vdp.readword();
309 goto end;
312 // else pass onto readbyte
313 ret =misc_readbyte(a)<<8;
314 ret|=misc_readbyte(a+1);
315 goto end;
317 end:
318 return ret;
321 void md::misc_writeword(unsigned a,unsigned d)
323 a&=0x00ffffff; // in case stars didn't clip to 24-bit bus
325 // GFX data write (word)
326 if ((a&0xfffffffc)==0x00c00000) // 00 or 02
328 vdp.writeword(d);
329 return;
332 if ((a&0xfffffffc)==0x00c00004) // 04 or 06
334 if (coo_waiting)
336 // Okay completed the vdp command
337 coo_cmd|=d; coo_waiting=0;
339 vdp.command(coo_cmd);
340 return;
342 if ((d&0xc000)==0x8000)
344 int addr; addr=d>>8; addr&=0x1f;
345 if (vdp.reg[addr]!=(d&0xff))
347 // Store dirty information down to 1byte level in bits
348 int byt,bit;
349 byt=addr; bit=byt&7; byt>>=3; byt&=0x03;
350 vdp.dirt[0x30+byt]|=(1<<bit); vdp.dirt[0x34]|=8;
352 vdp.reg[addr]=d&0xff;
353 return;
355 coo_cmd=d<<16; coo_waiting=1;
356 return;
359 // else pass onto writebyte
360 misc_writebyte(a,d>>8);
361 misc_writebyte(a+1,d&255);