md.cpp

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

CPP
590
字号
// DGen v1.14+
// 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++)

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       is now in mdfr.cpp
// ***************************************

int md::has_save_ram()
{
  if (saveram!=NULL && save_len>0) return 1;
  return 0;
}


#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;

// PROGRAMREGIONS
  i=0;
  if(save_len>0 && saveram!=NULL)
    { fetch[i].lowaddr=save_start; fetch[i].highaddr=save_start+save_len-1;
      fetch[i].offset=(unsigned)saveram-save_start; i++; }
  if (rommax>0)
  { fetch[i].lowaddr=0x000000; fetch[i].highaddr=rommax-1; fetch[i].offset=(unsigned)rom-0x000000; i++; }
  fetch[i].lowaddr=0xff0000; fetch[i].highaddr=0xffffff; fetch[i].offset=(unsigned)ram-  0xff0000; i++;
// Testing
  fetch[i].lowaddr=0xffff0000; fetch[i].highaddr=0xffffffff; fetch[i].offset=(unsigned)ram-0xffff0000; i++;
// Testing 2
  fetch[i].lowaddr=0xff000000; fetch[i].highaddr=0xff000000+rommax-1; fetch[i].offset=(unsigned)rom-0xff000000; i++;
// Save RAM
  fetch[i].lowaddr=fetch[i].highaddr=0xffffffff; fetch[i].offset=0; i++;

  i=0; j=0;

// DATAREGIONS
#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 ***************
  if (rommax>0)
  {
// Cartridge save RAM memory (read/write)
    if(save_len>0 && saveram!=NULL)
    {
      readbyte[i].lowaddr=    readword[i].lowaddr=
      writebyte[i].lowaddr=   writeword[i].lowaddr=   save_start;
      readbyte[i].highaddr=   readword[i].highaddr=
      writebyte[i].highaddr=  writeword[i].highaddr=  save_start+save_len-1;
      readbyte[i].memorycall= readword[i].memorycall=
      writebyte[i].memorycall=writeword[i].memorycall=NULL;
      readbyte[i].userdata=   readword[i].userdata=
      writebyte[i].userdata=  writeword[i].userdata=  saveram;
      i++;
    }
// 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()
{
  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;
}

⌨️ 快捷键说明

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