md.cpp

来自「DGen源码最后版本」· C++ 代码 · 共 590 行 · 第 1/2 页

CPP
590
字号
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;

  last_render_method=last_bpp=-1;

  snd_mute=mjazz=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=0xff1; layer_sel=0xff;
  render_method=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;

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

#ifdef COMPILE_WITH_STAR
  if (s68000init()!=0) { dprintf ("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 STARSCREAM_PROGRAMREGION[6]; if (!fetch)     return;
  readbyte= new STARSCREAM_DATAREGION[5]; if (!readbyte)  return;
  readword= new STARSCREAM_DATAREGION[5]; if (!readword)  return;
  writebyte=new STARSCREAM_DATAREGION[5]; if (!writebyte) return;
  writeword=new STARSCREAM_DATAREGION[5]; if (!writeword) return;
  memory_map();

  // point star stuff
  cpu.u_fetch =     fetch;
  cpu.u_readbyte =  readbyte;
  cpu.u_readword =  readword;
  cpu.u_writebyte = writebyte;
  cpu.u_writeword = writeword;

  cpu.s_fetch =     fetch;
  cpu.s_readbyte =  readbyte;
  cpu.s_readword =  readword;
  cpu.s_writebyte = writebyte;
  cpu.s_writeword = 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;
}


// NOTE - I have split this off so you can plug in a cart without resetting
// e.g. for resetting Genie Codes
int md::plug_in_without_reset(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;

  byteswap_memory(cart,len); // for starscream
  romlen=len;
  rom=cart;

// Joe's bit for save ram:
  // Get saveram start, length (remember byteswapping)
  // First check magic, if there is saveram
  if(rom[0x1b1] == 'R' && rom[0x1b0] == 'A')
    {
      save_start = rom[0x1b5] << 24 | rom[0x1b4] << 16 | 
                   rom[0x1b7] << 8  | rom[0x1b6];
      save_len = rom[0x1b9] << 24 | rom[0x1b8] << 16 |
  	         rom[0x1bb] << 8  | rom[0x1ba];
      // Make sure start is even, end is odd, for alignment
// A ROM that I came across had the start and end bytes of
// the save ram the same and wouldn't work.  Fix this as seen
// fit, I know it could probably use some work. [PKH]
      if(save_start != save_len) {
        if(save_start & 1) --save_start;
          if(!(save_len & 1)) ++save_len;
            save_len -= (save_start - 1);
        saveram = (unsigned char*)malloc(save_len);
        if (saveram!=NULL) memset(saveram,0,save_len);
      }
      else {
        save_start = save_len = 0;
        saveram = NULL;
      }
    }
  else
    {
      save_start = save_len = 0;
      saveram = NULL;
    }

  dprintf ("ROM len %x\n",romlen);
  dprintf ("Save RAM is at %x len %x\n",save_start,save_len);

#ifdef COMPILE_WITH_STAR
  memory_map(); // Update memory map to include this cartridge
#endif
  return 0;
}

// THIS IS FOR BACKWARDS COMPATIBILTY
int md::plug_in(unsigned char *cart,int len)
{
  plug_in(cart,len);
  reset(); // Reset megadrive
  return 0;
}

int md::unplug()
{
  if (rom==NULL) return 1; if (romlen<=0) return 1;

  if (rom!=NULL) free(rom); romlen=0;
  if (saveram!=NULL) free(saveram); saveram=NULL;
  romlen = save_start = save_len = 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,int do_reset)
{
  // 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_without_reset(temp,len); // md then deallocates it when it's done
  if (do_reset) reset();

  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 + =
减小字号Ctrl + -
显示快捷键?