⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 md_old.cpp

📁 十七种模拟器源代码 非常有用的作课程设计不可缺少的
💻 CPP
字号:
// DGen v1.11+
// Megadrive C++ module (one_frame_hints is now in mdfr.cpp)x

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "md.h"

// 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++)


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;

// FETCH: Set up 2 or 3 FETCH sections
  i=0;
  if (rommax>0)
  { fetch[i].lowaddr=0x000000; fetch[i].highaddr=rommax-1; fetch[i].off=(unsigned)rom-0x000000; i++; }
  fetch[i].lowaddr=0xff0000; fetch[i].highaddr=0xffffff; fetch[i].off=(unsigned)ram-  0xff0000; i++;
// Testing
  fetch[i].lowaddr=0xffff0000; fetch[i].highaddr=0xffffffff; fetch[i].off=(unsigned)ram-0xffff0000; i++;
// Testing 2
  fetch[i].lowaddr=0xff000000; fetch[i].highaddr=0xff000000+rommax-1; fetch[i].off=(unsigned)rom-0xff000000; i++;
  fetch[i].lowaddr=fetch[i].highaddr=0xffffffff; fetch[i].off=0; i++;

  i=0; j=0;

#if 0
// Simple version ***************
  readbyte[i].lowaddr=   readword[i].lowaddr=
  writebyte[j].lowaddr=  writeword[j].lowaddr=   0;
  readbyte[i].highaddr=  readword[i].highaddr=
  writebyte[j].highaddr= writeword[j].highaddr=  0xffffffff;

  readbyte[i].memorycall=(void *) root_readbyte;
  readword[i].memorycall=(void *) root_readword;
  writebyte[j].memorycall=(void *)root_writebyte;
  writeword[j].memorycall=(void *)root_writeword;

  readbyte[i].userdata=  readword[i].userdata=
  writebyte[j].userdata= writeword[j].userdata=  NULL;
  i++; j++;
// Simple version end ***************

#else
// Faster version ***************
// IO: Set up 3/4 read sections, and 2/3 write sections
  if (rommax>0)
  {
// Cartridge ROM memory (read only)
    readbyte[i].lowaddr=   readword[i].lowaddr=   0x000000;
    readbyte[i].highaddr=  readword[i].highaddr=  rommax-1;
    readbyte[i].memorycall=readword[i].memorycall=NULL;
    readbyte[i].userdata=  readword[i].userdata=  rom;
    i++;

// misc memory (e.g. aoo and coo) through root_rw
    readbyte[i].lowaddr=   readword[i].lowaddr=
    writebyte[j].lowaddr=  writeword[j].lowaddr=   rommax;
  }
  else
    readbyte[i].lowaddr=   readword[i].lowaddr=
    writebyte[j].lowaddr=  writeword[j].lowaddr=   0;

  readbyte[i].highaddr=  readword[i].highaddr=
  writebyte[j].highaddr= writeword[j].highaddr=  0xfeffff;

  readbyte[i].memorycall=(void *) root_readbyte;
  readword[i].memorycall=(void *) root_readword;
  writebyte[j].memorycall=(void *)root_writebyte;
  writeword[j].memorycall=(void *)root_writeword;

  readbyte[i].userdata=  readword[i].userdata=
  writebyte[j].userdata= writeword[j].userdata=  NULL;
  i++; j++;

// scratch RAM memory
  readbyte[i].lowaddr =   readword[i].lowaddr =
  writebyte[j].lowaddr =  writeword[j].lowaddr =   0xff0000;
  readbyte[i].highaddr=   readword[i].highaddr=
  writebyte[j].highaddr=  writeword[j].highaddr=   0xffffff;
  readbyte[i].memorycall= readword[i].memorycall=
  writebyte[j].memorycall=writeword[j].memorycall= NULL;
  readbyte[i].userdata=  readword[i].userdata =
  writebyte[j].userdata= writeword[j].userdata =   ram;
  i++; j++;
// Faster version end ***************
#endif

// The end
   readbyte[i].lowaddr  =   readword[i].lowaddr  =
  writebyte[j].lowaddr  =  writeword[j].lowaddr  =
   readbyte[i].highaddr =   readword[i].highaddr =
  writebyte[j].highaddr =  writeword[j].highaddr = 0xffffffff;

   readbyte[i].memorycall=  readword[i].memorycall=
  writebyte[j].memorycall= writeword[j].memorycall=
   readbyte[i].userdata=    readword[i].userdata =
  writebyte[j].userdata=   writeword[j].userdata = NULL;
  i++; j++;

  return 0;
}
#endif

int md::reset()
{
  eprintf("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
    =coo4=coo5=pause=0;
  last_a3_six=-1; last_a5_six=-1;
  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( int (*ievprintf) (char *format,va_list arg) )
{
  evprintf=ievprintf;

  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;

  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;

  star_mz80_on();  // VERY IMPORTANT - Must call before using stars/mz80!!

#ifdef COMPILE_WITH_STAR
  if (s68000init()!=0) { eprintf ("s68000init failed!\n"); return; }
#endif

  star_mz80_off(); // VERY IMPORTANT - Must call after using stars/mz80!!

  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 S68000MEMORYFETCH[5]; if (!fetch)     return;
  readbyte= new S68000MEMORYIO[4]; if (!readbyte)  return;
  readword= new S68000MEMORYIO[4]; if (!readword)  return;
  writebyte=new S68000MEMORYIO[4]; if (!writebyte) return;
  writeword=new S68000MEMORYIO[4]; if (!writeword) return;
  memory_map();

  // point star stuff
  cpu.memoryfetch =     fetch;
  cpu.memoryreadbyte =  readbyte;
  cpu.memoryreadword =  readword;
  cpu.memorywritebyte = writebyte;
  cpu.memorywriteword = writeword;
  cpu_emu=0; // zero=starscream, one=musashi
#else
#ifdef COMPILE_WITH_MUSA
  cpu_emu=1; // zero=starscream, one=musashi

#endif
#endif

#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;
    eprintf ("  %s",ln);
    memcpy(ln,cart+0x120,0x30);ln[0x30]='\n';ln[0x31]=0;
    eprintf ("  %s",ln);
    memcpy(ln,cart+0x150,0x30);ln[0x30]='\n';ln[0x31]=0;
    eprintf ("  %s",ln);
    memcpy(ln,cart+0x180,0x0e);ln[0x0e]='\n';ln[0x0f]=0;
    eprintf ("  %s",ln);

    memcpy(ln,cart+0x1f0,0x10);ln[0x10]='\n';ln[0x11]=0;
    eprintf ("  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 *into);

int md::load(char *name)
{
  // Convenience function - calls romload.c functions
  unsigned char *temp=NULL; int len=0;
  if (name==NULL) return 1;
 
  len=load_rom_into(name,NULL);
  if (len<=0) return 1;
  temp=(unsigned char *)malloc(len);
  if (temp==NULL) return 1;
  load_rom_into(name,temp);
  // Register name
  strncpy(romfilename,name,255);
  plug_in(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;
}

// Redirect eprintf calls to an external eprintf
int md::eprintf(char *format, ...)
{
  static int reentry=0;
  if (reentry) return 1; reentry=1;

  va_list arg;
  va_start(arg,format);

  if (evprintf) evprintf(format,arg);

  va_end(arg);

  reentry=0; return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -