📄 md113.cpp
字号:
// DGen v1.13+
// Megadrive C++ module (one_frame_hints is now in mdfr.cpp)
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "md.h"
char def_prof[]="?";
extern "C" char *prof_name=def_prof;
// This is the 'static' StarScream/MZ80 multitasker
// which detects which megadrive is active (by which star_mz80_on() has been called
// and forwards to the appropriate misc_read/writebyte/word/z80 function
// of the appropriate instance (grrrr - bloody C++)
// ********************************************************
// ********************************************************
// STARSCREAM 0.26 DOESNT WORK - I'm TAKING OUT MULTI MD SUPPORT
// to test - BASICALLY MD.CPP IS MAIMED !!!
// ********************************************************
// ********************************************************
// ********************************************************
static md* which=0;
int md::star_mz80_on()
{
#ifdef COMPILE_WITH_STAR
s68000SetContext(&cpu);
#endif
mz80SetContext(&z80);
which=this;
return 0;
}
int md::star_mz80_off()
{
which=0;
#ifdef COMPILE_WITH_STAR
s68000GetContext(&cpu);
#endif
mz80GetContext(&z80);
return 0;
}
extern "C"
{
unsigned root_readbyte(unsigned a)
{ if (which) return which->misc_readbyte(a); else return 0x00; }
unsigned root_readword(unsigned a)
{ if (which) return which->misc_readword(a); else return 0x0000; }
unsigned root_readlong(unsigned a)
{
unsigned int tot=0;
tot|=root_readword(a)<<16;
tot|=root_readword(a+2);
return tot;
}
void root_writebyte(unsigned a,unsigned d)
{ if (which) which->misc_writebyte(a,d); }
void root_writeword(unsigned a,unsigned d)
{ if (which) which->misc_writeword(a,d); }
void root_writelong(unsigned a,unsigned d)
{
root_writeword(a,(d>>16)&0xffff);
root_writeword(a+2,d&0xffff);
}
}
#ifdef COMPILE_WITH_MUSA
// Okay: a bit for MUSASHI
extern "C"
{
// read/write functions called by the CPU to access memory.
// while values used are 32 bits, only the appropriate number
// of bits are relevant (i.e. in write_memory_8, only the lower 8 bits
// of value should be written to memory).
// address will be a 24-bit value.
/* Read from anywhere */
int m68k_read_memory_8(int address) { return root_readbyte(address); }
int m68k_read_memory_16(int address) {
return root_readword(address);
}
int m68k_read_memory_32(int address) { return root_readlong(address); }
/* Read data immediately following the PC */
int m68k_read_immediate_8(int address) { return root_readbyte(address); }
int m68k_read_immediate_16(int address) { return root_readword(address); }
int m68k_read_immediate_32(int address) { return root_readlong(address); }
/* Read an instruction (16-bit word immeditately after PC) */
int m68k_read_instruction(int address) { return root_readword(address); }
/* Write to anywhere */
void m68k_write_memory_8(int address, int value) { root_writebyte(address,value); }
void m68k_write_memory_16(int address, int value) { root_writeword(address,value); }
void m68k_write_memory_32(int address, int value) { root_writelong(address,value); }
}
#endif
UINT8 root_z80_read(UINT32 a,struct MemoryReadByte *huh)
{
(void)(huh);
if (which) return which->z80_read(a); return 0x00;
}
void root_z80_write(UINT32 a,UINT8 d,struct MemoryWriteByte *huh)
{
(void)(huh);
if (which) which->z80_write(a,d);
}
UINT16 root_z80_port_read(UINT16 a, struct z80PortRead *huh)
{
(void)(huh);
if (which) return which->z80_port_read(a); return 0x0000;
}
void root_z80_port_write(UINT16 a,UINT8 d, struct z80PortWrite *huh)
{
(void)(huh);
if (which) which->z80_port_write(a,d);
}
// ***************************************
// NB - one frame Hints is now in mdfr.cpp
// ***************************************
#ifdef COMPILE_WITH_STAR
int md::memory_map()
{
int i=0,j=0;
int rommax=romlen;
if (rommax>0xa00000) rommax=0xa00000;
if (rommax<0) rommax=0;
static struct STARSCREAM_PROGRAMREGION fetch[] =
{
// {0x000000, rommax-1 , (unsigned)rom - 0x000000},
// {0xff0000, 0xffffff , (unsigned)ram - 0xff0000},
{-1, -1, NULL}
};
static struct STARSCREAM_DATAREGION data1[] =
{
{0x000000, 0xffffff , root_readbyte, 0},
{-1, -1, NULL, NULL}
};
static struct STARSCREAM_DATAREGION data2[] =
{
{0x000000, 0xffffff , root_readword, 0},
{-1, -1, NULL, NULL}
};
static struct STARSCREAM_DATAREGION data3[] =
{
{0x000000, 0xffffff , root_writebyte, 0},
{-1, -1, NULL, NULL}
};
static struct STARSCREAM_DATAREGION data4[] =
{
{0x000000, 0xffffff , root_writeword, 0},
{-1, -1, NULL, NULL}
};
star_mz80_on();
// point star stuff
s68000context.s_fetch = s68000context.u_fetch = fetch;
s68000context.s_readbyte = s68000context.u_readbyte = data1;
s68000context.s_readword = s68000context.u_readword = data2;
s68000context.s_writebyte = s68000context.u_writebyte = data3;
s68000context.s_writeword = s68000context.u_writeword = data4;
{
int ret;
ret=s68000init();
dprintf ("s68000init returned %d\n",ret);
ret=s68000reset();
dprintf ("s68000reset returned %d\n",ret);
dprintf ("pc: %x\n",s68000readPC());
}
star_mz80_off();
return 0;
}
#endif
int md::reset()
{
dprintf("Reset\n");
star_mz80_on(); // testing
memset(ram,0xff,0x10000); // testing
memset(z80ram,0xff,0x2000); // testing
#ifdef COMPILE_WITH_STAR
if (cpu_emu==0) s68000reset();
#endif
#ifdef COMPILE_WITH_MUSA
if (cpu_emu==1) m68k_pulse_reset(NULL);
#endif
mz80reset();
vdp.reset();
// zero = natural state of select line?
z80_bank68k=z80_online=z80_extra_cycles
=coo_waiting=coo_cmd=aoo3_toggle=aoo5_toggle=
aoo3_six=aoo5_six=aoo3_six_timeout=aoo5_six_timeout
=coo4=coo5=pause=0;
pad[0]=pad[1]=0xf303f; // Untouched pad
{
int s,r;
for (s=0;s<2;s++)
for (r=0;r<0x100;r++)
fm_reg[s][r]=-1; // -1 = use mame's default
for (r=0;r<4;r++)
ras_fm_ticker[r]=0;
}
fm_sel[0]=fm_sel[1]=fm_tover[0]=fm_tover[1]=0;
dac_data=0x80; // the middle
dac_enable=0;
odo=odo_line_start=odo_line_len=ras=0;
//odo_frame_max=0;
hint_countdown=0;
z80_int_pending=0;
star_mz80_off();
return 0;
}
static struct MemoryReadByte mem_read[]=
{
{0x2000,0xffff,root_z80_read},
{(UINT32) -1,(UINT32) -1,NULL}
};
static struct MemoryWriteByte mem_write[]=
{
{0x2000,0xffff,root_z80_write},
{(UINT32) -1,(UINT32) -1,NULL}
};
static struct z80PortRead io_read[] ={
{0x00,0x00ff,root_z80_port_read},
{(UINT16) -1,(UINT16) -1,NULL}
};
static struct z80PortWrite io_write[]={
{0x00,0x00ff,root_z80_port_write},
{(UINT16) -1,(UINT16) -1,NULL}
};
int md::z80_init()
{
// Set up the z80
star_mz80_on();
mz80reset();
// Modify the default context
mz80GetContext(&z80);
// point mz80 stuff
z80.z80Base=z80ram;
z80.z80MemRead=mem_read;
z80.z80MemWrite=mem_write;
z80.z80IoRead=io_read;
z80.z80IoWrite=io_write;
mz80SetContext(&z80);
mz80reset();
star_mz80_off();
return 0;
}
md::md()
{
romlen=ok=0;
mem=rom=ram=z80ram=NULL;
snd_mute=0;
#ifdef COMPILE_WITH_STAR
fetch=NULL;
readbyte=readword=writebyte=writeword=NULL;
memset(&cpu,0,sizeof(cpu));
#endif
memset(&z80,0,sizeof(z80));
romfilename[0]=0;
country_ver=0xff0; layer_sel=0xff;
line_based=0;
memset(romfilename,0,sizeof(romfilename));
ok=0;
if (!vdp.okay()) return;
vdp.belongs=this;
// Format of pad is: __SA____ UDLRBC__
rom=mem=ram=z80ram=NULL;
mem=(unsigned char *)malloc(0x20000);
if (mem==NULL) return;
memset(mem,0,0x20000);
ram= mem+0x00000;
z80ram=mem+0x10000;
romlen=0;
cpu_emu=-1; // Do we have a cpu emu?
#ifdef COMPILE_WITH_STAR
// Dave: Rich said doing point star stuff is done after s68000init
// in Asgard68000, so just in case...
fetch= new struct STARSCREAM_PROGRAMREGION[5]; if (!fetch) return;
readbyte= new struct STARSCREAM_DATAREGION[4]; if (!readbyte) return;
readword= new struct STARSCREAM_DATAREGION[4]; if (!readword) return;
writebyte=new struct STARSCREAM_DATAREGION[4]; if (!writebyte) return;
writeword=new struct STARSCREAM_DATAREGION[4]; if (!writeword) return;
memory_map();
cpu_emu=0; // zero=starscream, one=musashi
#else
#ifdef COMPILE_WITH_MUSA
cpu_emu=1; // zero=starscream, one=musashi
#endif
#endif
star_mz80_on(); // VERY IMPORTANT - Must call before using stars/mz80!!
star_mz80_off(); // VERY IMPORTANT - Must call after using stars/mz80!!
#ifdef COMPILE_WITH_MUSA
m68k_pulse_reset(NULL);
#endif
z80_init();
reset(); // reset megadrive
ok=1;
}
md::~md()
{
romfilename[0]=0;
if (rom!=NULL) unplug();
free(mem);
rom=mem=ram=z80ram=NULL;
#ifdef COMPILE_WITH_STAR
if (fetch) delete[] fetch;
if (readbyte) delete[] readbyte;
if (readword) delete[] readword;
if (writebyte) delete[] writebyte;
if (writeword) delete[] writeword;
#endif
ok=0;
}
// Byteswaps memory
int byteswap_memory(unsigned char *start,int len)
{ int i; unsigned char tmp;
for (i=0;i<len;i+=2)
{ tmp=start[i+0]; start[i+0]=start[i+1]; start[i+1]=tmp; }
return 0;
}
int md::plug_in(unsigned char *cart,int len)
{
// Plug in the cartridge specified by the uchar *
// NB - The megadrive will free() it if unplug() is called, or it exits
// So it must be a single piece of malloced data
if (cart==NULL) return 1; if (len<=0) return 1;
if (len>=0x200)
{
// Show header
int i;
static char ln[0x32]="";
memcpy(ln,cart+0x100,0x20);ln[0x20]='\n';ln[0x21]=0;
dprintf (" %s",ln);
memcpy(ln,cart+0x120,0x30);ln[0x30]='\n';ln[0x31]=0;
dprintf (" %s",ln);
memcpy(ln,cart+0x150,0x30);ln[0x30]='\n';ln[0x31]=0;
dprintf (" %s",ln);
memcpy(ln,cart+0x180,0x0e);ln[0x0e]='\n';ln[0x0f]=0;
dprintf (" %s",ln);
memcpy(ln,cart+0x1f0,0x10);ln[0x10]='\n';ln[0x11]=0;
dprintf (" Versions (Jap/USA/Europe): %s",ln);
}
byteswap_memory(cart,len); // for starscream
romlen=len;
rom=cart;
#ifdef COMPILE_WITH_STAR
memory_map(); // Update memory map to include this cartridge
#endif
reset(); // Reset megadrive
return 0;
}
int md::unplug()
{
if (rom==NULL) return 1; if (romlen<=0) return 1;
free(rom); romlen=0;
#ifdef COMPILE_WITH_STAR
memory_map(); // Update memory map to include no rom
#endif
memset(romfilename,0,sizeof(romfilename));
reset();
return 0;
}
extern "C" int load_rom_into(char *name, unsigned char **rombuffer, int *len);
int md::load(char *name)
{
// Convenience function - calls romload.c functions
unsigned char *temp=NULL;
int len=0;
if (name==NULL) return 1;
load_rom_into(name, &temp, &len);
if (temp==NULL) return 1;
// Register name
strncpy(romfilename,name,255);
plug_in((unsigned char *)temp,len); // md then deallocates it when it's done
return 0;
}
int md::change_cpu_emu(int to)
{
// Note - stars/mz80 isn't run here, so star_mz80_on() not necessary
#ifdef COMPILE_WITH_STAR
#ifdef COMPILE_WITH_MUSA
if (cpu_emu==0 && to==1)
{
int i;
for (i=0;i<8;i++) m68k_poke_dr(i,cpu.dreg[i]);
for (i=0;i<8;i++) m68k_poke_ar(i,cpu.areg[i]);
m68k_poke_pc(cpu.pc);
m68k_poke_sr(cpu.sr);
}
if (cpu_emu==1 && to==0)
{
int i;
for (i=0;i<8;i++) cpu.dreg[i]=m68k_peek_dr(i);
for (i=0;i<8;i++) cpu.areg[i]=m68k_peek_ar(i);
cpu.pc=m68k_peek_pc();
cpu.sr=m68k_peek_sr();
}
#endif
#endif
cpu_emu=to;
return 0;
}
int md::z80dump()
{
FILE *hand;
hand=fopen("dgz80ram","wb");
if (hand!=NULL)
{ fwrite(z80ram,1,0x10000,hand); fclose(hand); }
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -