2 // Megadrive C++ module - misc memory
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);
26 addr68k
=z80_bank68k
<<15;
29 return misc_readbyte(addr68k
);
35 unsigned short md::z80_port_read(unsigned short a
)
39 // dprintf("z80 port read %.2x return %.4x\n",a,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
57 { mysn_write(v
); return; }
62 z80_bank68k
+=(v
&1)<<8;
63 z80_bank68k
&=0x1ff; // 9 bits and filled in the new top one
66 if (a
<0x2000) { z80ram
[a
&0xffff]=v
; return; }
72 addr68k
=z80_bank68k
<<15;
74 misc_writebyte(addr68k
,v
);
78 // dprintf("z80 write %.4x %.2x\n",a,v);
83 unsigned md::misc_readbyte(unsigned a
)
86 a
&=0x00ffffff; // in case stars didn't clip to 24-bit bus
89 // In case it's a rom read after all
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
;
119 if ((a
&0xfffffe)==0xa10002)
124 if (aoo3_toggle
==0) ret
=((pad
[0]>>8)&0x30)+0x00;
125 else ret
=((pad
[0])&0x30)+0x40+((pad
[0]>>16)&0xf);
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);
139 if ((a
&0xfffffe)==0xa10004)
144 if (aoo5_toggle
==0x00) ret
=((pad
[1]>>8)&0x30)+0x00;
145 else ret
=((pad
[1])&0x30)+0x40+((pad
[1]>>16)&0xf);
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);
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;
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
;
183 if (a
==0xa11000) {ret
=0xff; goto end
; }
184 if (a
==0xa11001) {ret
=0xff; goto end
; }
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
196 // This is the genecyst fudge for FIFO full/empty
202 // This is the genecyst fudge for in h-blank
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
; }
215 void md::misc_writebyte(unsigned a
,unsigned d
)
217 a
&=0x00ffffff; // in case stars didn't clip to 24-bit bus
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)
240 mysn_write(d
); return;
245 //d8 (W) 0: BUSREQ CANCEL
247 if (d
==1) z80_online
=0;
251 if (a
==0xa11101) return;
258 if (a
==0xa11201) return;
260 if ((a
>=0xa00000)&&(a
<0xa08000))
262 // Write into z80's memory
263 z80_write(a
&0x7fff,d
);
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;
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;
290 // Saveram status (thanks Steve :)
293 // Bit 0: 0=rom active, 1=sram active
294 // Bit 1: 0=writeable, 1=write protect
300 unsigned md::misc_readword(unsigned a
)
304 a
&=0x00ffffff; // in case stars didn't clip to 24-bit bus
306 if ((a
&0xfffffffc)==0x00c00000) // 00 or 02
312 // else pass onto readbyte
313 ret
=misc_readbyte(a
)<<8;
314 ret
|=misc_readbyte(a
+1);
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
332 if ((a
&0xfffffffc)==0x00c00004) // 04 or 06
336 // Okay completed the vdp command
337 coo_cmd
|=d
; coo_waiting
=0;
339 vdp
.command(coo_cmd
);
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
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;
355 coo_cmd
=d
<<16; coo_waiting
=1;
359 // else pass onto writebyte
360 misc_writebyte(a
,d
>>8);
361 misc_writebyte(a
+1,d
&255);