示例#1
0
bool SCPlayer::SCPlayer_impl::init(const int mixerFreq)
{
  // Initialise SAASound
  debug_print("Initialising SAA emulator.");
  _saa = CreateCSAASound();
  _saa->SetSoundParameters(SAAP_NOFILTER | SAAP_44100 | SAAP_16BIT | SAAP_STEREO);
  if (mixerFreq != 44100)
    _saa->SendCommand(SAACMD_SetSampleRate, mixerFreq);
  _period = mixerFreq / 50;

  // Initialise CPU
  debug_print("Initialising Z80 CPU.");
  ResetZ80(&_z80);
  _z80.User = reinterpret_cast<void *> (this);
  _z80.PC.W = stub;
  _ram[stub] = 0xcd; // CALL
  _ram[stub+1] = 0; _ram[stub+2] = 0x80;
  _ram[stub+3] = 0xed; _ram[stub+4] = 0xfe; // Patch
  if(_eTracker == true)
  {
    debug_print("Initialising eTracker player.");
    ExecZ80(&_z80, Z80Cycles);
    _ram[stub+1] = 6;
  }

  debug_print(std::hex);

  return true;
}
示例#2
0
void Z80_reset(void)
{
	ResetZ80(&Z80_regs);
	Z80_regs.SP.W = 0;
}
示例#3
0
// RESET EMULATED MACHINE -----------------------------------------------------
void        Machine_Reset (void)
{
    int     i;
    static byte VDPInit [16] =
    {
        /* Values set by BIOS */
        0x36, /*0xA0*/ 0x80 /* zero for Coleco */, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x00,
        0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00
        /* Old (guessed ?) values */
        // 0x06, 0x00, 0x0E, 0xFF, 0xFF, 0x7F, 0x00, 0x00,
        // 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00
    };

    #ifdef DEBUG_WHOLE
        Msg (MSGT_DEBUG, "Machine_Reset();");
    #endif

    // Unpause machine if necessary
    if (machine & MACHINE_PAUSED)
        Machine_Pause ();

    // Set driver & machine stuff
    drv_set (cur_machine.driver_id);

    Machine_Set_Mapper          ();
    if ((machine & MACHINE_RUN) != 0 /*== MACHINE_RUN */ && (cur_drv->id != DRV_NES))
        Machine_Set_Mapping      (); // ^^ FIXME: the test above isn't beautiful since MACHINE_RUN contains multiple flags, but I'm unsure which of them is actually needed to perform the correct test
    Machine_Set_Handler_IO      ();
    Machine_Set_Handler_Read    ();
    Machine_Set_Handler_Write   ();
    Machine_Set_Handler_Loop    ();
    Machine_Set_Country         ();
    Machine_Set_IPeriod         ();
    Machine_Set_TV_Lines        ();

    // VDP MODEL --------------------------------------------------------------
    if (DB_CurrentEntry && DB_CurrentEntry->emu_vdp_model != -1)
        cur_machine.VDP.model = DB_CurrentEntry->emu_vdp_model;
    else
    {
        if (cur_drv->id == DRV_GG)
            cur_machine.VDP.model = VDP_MODEL_315_5378;
        else
            cur_machine.VDP.model = VDP_MODEL_315_5226;
    }

    // 3-D GLASSES ------------------------------------------------------------
    sms.Glasses_Register = ((Glasses.Mode == GLASSES_MODE_SHOW_ONLY_LEFT) ? 1 : 0);

    // CPU (MARAT FAIZULLIN'S CORE) -------------------------------------------
    CPU_Loop_Stop = TRUE;
    CPU_ForceNMI  = FALSE;

#ifdef MARAT_Z80
    sms.R.IPeriod = opt.Cur_IPeriod;
    sms.R.Trace = FALSE;
    ResetZ80 (&sms.R);
    sms.R.IFF |= IFF_IM1;
    sms.R.IAutoReset = FALSE;
    sms.R.TrapBadOps = FALSE;

    // CPU (MAME'S CORE) ------------------------------------------------------
#elif MAME_Z80
    z80_reset (NULL);
    z80_set_irq_callback (Get_IRQ_Vector);
    z80_set_irq_line (0, ASSERT_LINE);
    z80_set_irq_line (0, CLEAR_LINE);

    // CPU (RICHARD MITTON'S CORE) --------------------------------------------
#elif RAZE_Z80
    z80_init_memmap ();
    z80_add_write (0x0000, 0xFFFF, Z80_MAP_HANDLED, WrZ80);
    for (i = 0; i < 4; i ++)
    {
        z80_add_read ((i * 0x2000), (i * 0x2000) + 0x1FFF, Z80_MAP_DIRECT, Mem_Pages [i]);
        z80_map_fetch ((i * 0x2000), (i * 0x2000) + 0x1FFF, Mem_Pages [i]);
    }
    for (i = 4; i < 8; i ++)
    {
        z80_map_fetch ((i * 0x2000), (i * 0x2000) + 0x1FFF, Mem_Pages [i]);
        z80_map_read ((i * 0x2000), (i * 0x2000) + 0x1FFF, Mem_Pages [i]);
    }
    z80_set_in (InZ80);
    z80_set_out (OutZ80);
    z80_end_memmap ();
    z80_reset ();
#endif

    // MEMORY -----------------------------------------------------------------
    memset (RAM,  0, 0x10000);      // Clear all RAM
    memset (VRAM, 0, 0x04000);      // Clear all VRAM
    PRAM = PRAM_Static;
    memset (PRAM, 0, 0x00040);      // Clear all PRAM (palette)

    // Unload BIOS if...
    if ((cur_drv->id != DRV_SMS || sms.Country != COUNTRY_EXPORT) && (machine & MACHINE_ROM_LOADED))
    {
        #ifdef DEBUG_WHOLE
            Msg (MSGT_DEBUG, "Machine_Reset(): BIOS_Unload()");
        #endif
        BIOS_Unload ();
    }

    // GRAPHICS ---------------------------------------------------------------
    for (i = 0; i < 16; i++)
        Tms_VDP_Out (i, ((i == 1 && cur_drv->id == DRV_COLECO) ? 0x00 : VDPInit [i]));
    for (i = 0; i < MAX_TILES; i++)
        tgfx.Tile_Dirty [i] = TILE_DIRTY_DECODE | TILE_DIRTY_REDRAW;

    VDP_UpdateLineLimits();

    clear_bitmap (screenbuffer_1);
    clear_bitmap (screenbuffer_2);
    screenbuffer = screenbuffer_1;
    screenbuffer_next = screenbuffer_2;

    cur_machine.VDP.sprite_shift_x = 0;
    cur_machine.VDP.scroll_x_latched = 0;
    cur_machine.VDP.scroll_y_latched = 0;
    memset(cur_machine.VDP.scroll_x_latched_table, 0, sizeof(cur_machine.VDP.scroll_x_latched_table));
    tsms.VDP_Video_Change = VDP_VIDEO_CHANGE_ALL;

    // GRAPHICS: SPRITE FLICKERING --------------------------------------------
    if (g_Configuration.sprite_flickering & SPRITE_FLICKERING_AUTO)
    {
        if (DB_CurrentEntry && (DB_CurrentEntry->flags & DB_FLAG_EMU_SPRITE_FLICKER))
            g_Configuration.sprite_flickering |= SPRITE_FLICKERING_ENABLED;
        else
            g_Configuration.sprite_flickering &= ~SPRITE_FLICKERING_ENABLED;
    }

    // PALETTE ----------------------------------------------------------------
    //if (machine & MACHINE_POWER_ON)
    Palette_Emulation_Reset();

    // INPUT/OUTPUT/VDP -------------------------------------------------------
    sms.VDP_Status = 0x00;
    sms.VDP_Address = 0x0000;
    sms.VDP_Access_Mode = VDP_Access_Mode_1;
    sms.VDP_Access_First = 0x00;
    sms.VDP_Pal = 0x00;
    sms.VDP_ReadLatch = 0x00;
    sms.Lines_Left = 255;
    sms.Pending_HBlank = FALSE;
	sms.Pending_NMI = FALSE;
    tsms.VDP_Line = 0;

    // CONTROLLERS ------------------------------------------------------------
    for (i = 0; i < 8; i ++)
        tsms.Control [i] = 0xFFFF; /* 0x3FFF */
    tsms.Control_GG = /*0x20 | 0x80*/ 0;
    tsms.Control_Start_Pause = 0;
    tsms.Periph_Nat = 0;
    sms.Input_Mode = 0x07;

    // SOUND ------------------------------------------------------------------
    sms.FM_Register = 0;
    sms.FM_Magic = 0;
    // if (fm_use == TRUE) fm_init (FM_ALL_INIT);
    // resume_fm ();
    FM_Reset ();
    SN76489_Reset (cur_machine.TV->CPU_clock, audio_sample_rate);
    if (Sound.LogVGM.Logging == VGM_LOGGING_ACCURACY_SAMPLE)
        VGM_Update_Timing (&Sound.LogVGM);

    // Reset sound cycle counter
    Sound_Update_Count = 0;
    Sound_CycleCounter = 0;

    // FIXME: add a reset handler per driver, instead of the code below...

    // GAME GEAR COMMUNICATION PORT
    if (cur_machine.driver_id == DRV_GG)
    {
        Comm_Reset ();
    }

    // SF-7000
    if (cur_machine.driver_id == DRV_SF7000)
    {
        SF7000_Reset ();
    }

    // NINTENDO CRAP
    if (cur_machine.driver_id == DRV_NES /* && cfg.NES_Enabled */)
    {
        ROM = Game_ROM;
        NES_Reset ();
    }

    // DEBUGGER ---------------------------------------------------------------
    #ifdef MEKA_Z80_DEBUGGER
        Debugger_MachineReset ();
    #endif
}
int StartSMS(char *Cartridge)
{
  static char *Countries[16] =
  {
    NULL,NULL,NULL,NULL,NULL,"Japan","Japan, USA, Europe","USA, Europe",
    NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
  };
  static char *Sizes[16] =
  {
    ">128kB",NULL,NULL,NULL,NULL,NULL,NULL,NULL,
    NULL,NULL,NULL,NULL,"32kB","64kB","128kB",NULL
  };
  static byte VDPInit[16] =
  {
    0x00,0x60,0x0E,0x00,0x00,0x7F,0x00,0x00,
    0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00
  };

  FILE *F;
  int I,J,*T;
  char *P;
  reg R;

  /*** STARTUP CODE starts here: ***/
  T=(int *)"\01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
#ifdef LSB_FIRST
  if(*T!=1)
  {
    puts("********** This machine is high-endian. **********");
    puts("Take #define LSB_FIRST out and compile MasterGear again.");
    return(0);
  }
#else
  if(*T==1)
  {
    puts("********* This machine is low-endian. **********");
    puts("Insert #define LSB_FIRST and compile MasterGear again.");
    return(0);
  }
#endif

  RAM=VRAM=NULL;
  ROMPages=0;ROMMask=0;
  for(J=0;J<256;J++) ROMMap[J]=NULL;
  SaveName=NULL;Battery=0;

  if(Verbose) printf("Allocating 64kB for CPU address space...");
  if(!(RAM=(byte*)malloc(0x10000))) { if(Verbose) puts("FAILED");return(0); }
  memset(RAM,NORAM,0x10000);
  if(Verbose) printf("OK\nAllocating 16kB for Video address space...");
  if(!(VRAM=(byte*)malloc(0x4040))) { if(Verbose) puts("FAILED");return(0); }
  memset(VRAM,NORAM,0x4040);
  PRAM=VRAM+0x4000;

  if(Verbose) printf("OK\nOpening %s...",Cartridge);
  P=NULL;

#ifdef ZLIB
#define fopen          gzopen
#define fclose         gzclose
#define fread(B,N,L,F) gzread(F,B,(L)*(N))
#endif

  if(F=fopen(Cartridge,"rb"))
  {
    for(ROMPages=0;ROMPages<256;ROMPages++)
      if(!(ROMMap[ROMPages]=(byte*)malloc(0x4000)))
      { P="MALLOC FAILED";break; }
      else
      {
        J=fread(ROMMap[ROMPages],1,0x4000,F);
        if(!J)        { P=NULL;break; }
        if(J==512) // cartridge w/header
        {
           fclose(F);
           for(J=0;J<ROMPages;J++) free(ROMMap[J]);
           if(F=fopen(Cartridge,"rb"))
           {
              for(ROMPages=0;ROMPages<256;ROMPages++)
              if(!(ROMMap[ROMPages]=(byte*)malloc(0x4000)))
                 { P="MALLOC FAILED";break; }
              else
              {
                 if (ROMPages == 0) J=fread(ROMMap[ROMPages],1,512,F); // skip header
                 J=fread(ROMMap[ROMPages],1,0x4000,F);
                 if(!J)        { P=NULL;break; }
                 if(J!=0x4000) { P="SHORT FILE";break; }
              }
           }
           fclose(F);
           break;
        }
        if(J!=0x4000) { P="SHORT FILE";break; }
      }
    fclose(F);
  }
  else P="NOT FOUND";

#ifdef ZLIB
#undef fopen
#undef fclose
#undef fread
#endif

  /* Exit if there was a problem */
  if(P) { if(Verbose) puts(P);return(0); }

  /* I = Country Code, J = ROM Size */
  J=ROMMap[1][0x3FFF];I=J>>4;J&=0x0F;
  /* Enforce Japanese/English nationalization if needed */
  if(!Country) if(I==5) Country=2; else if(I==7) Country=1;

  /* Print out cartridge data if needed */
  if(Verbose)
  {
    printf("%d pages loaded\n",ROMPages);
    if(GameGear&&ROMMap[1])
    {
      if(Countries[I]) printf("  Country: %s\n",Countries[I]);
      else             printf("  Country: Unknown (%d)\n",I);
      if(Sizes[J])     printf("  Size:    %s\n",Sizes[J]);
      else             printf("  Size:    Unknown (%d)\n",J);
    }
  }

  /* Generate the .SAV file name and try to load it. */
  /* If found the .SAV file, assume battery backup.  */
    if(SaveName=(char*)malloc(strlen(Cartridge)+10))
  {
    strcpy(SaveName,Cartridge);
    if(P=strrchr(SaveName,'.')) strcpy(P,".sav");
    else strcat(SaveName,".sav");
    if(F=fopen(SaveName,"rb"))
    {
      if(Verbose) printf("Found %s...reading...",SaveName);
      J=(fread(RAM+0x8000,1,0x4000,F)==0x4000);
      if(Verbose) puts(J? "OK":"FAILED");
      fclose(F);
    }
  }

//  if(SndName)
//  {
//    if(Verbose) printf("Logging soundtrack to %s...",SndName);
//    SndStream=fopen(SndName,"wb");
//    if(Verbose) puts(SndStream? "OK":"FAILED");
//    if(SndStream)
//      fwrite
//      ("SND\032\001\004\062\0\0\0\0\0\0\0\0\0\376\003\002",1,19,SndStream);
//  }

  /* Calculate IPeriod from VPeriod */
  IPeriod=VPeriod/280;
  if(IPeriod<10) IPeriod=10;
  VPeriod=IPeriod*280;

  if(Verbose)
  {
    printf("Initializing CPU and System Hardware:\n");
    printf("  VBlank = %d opcodes\n  HBlank = %d opcodes\n",VPeriod,IPeriod);
  }

  for(J=1;J<ROMPages;J<<=1);
  ROMMask=J-1;
  EnWrite=0;
  RAM[0xC000]=RAM[0xDFFC]=0x00;
  Page[0]=ROMMap[RAM[0xDFFD]=0&ROMMask];
  Page[1]=Page[0]+0x2000;
  Page[2]=ROMMap[RAM[0xDFFE]=1&ROMMask];
  Page[3]=Page[2]+0x2000;
  Page[4]=ROMMap[RAM[0xDFFF]=2&ROMMask];
  Page[5]=Page[4]+0x2000;
  Page[6]=Page[7]=RAM+0xC000;

  memcpy(VDP,VDPInit,16);                /* VDP registers              */
  VKey=DKey=RKey=1;                      /* Accessing VRAM...          */
  VAddr=0x0000;PAddr=0;                  /* ...from address 0000h      */
  BGColor=0;                             /* Background color           */
  CURLINE=0;                             /* Current scanline           */
  VDPStatus=0x00;                        /* VDP status register        */
  ChrTab=VRAM+0x3800;                    /* Screen buffer at 3800h     */
  SprTab=VRAM+0x3F00;                    /* Sprite attributes at 3F00h */
  SprGen=VRAM;                           /* Sprite patterns at 0000h   */
  ChrPal=PRAM;                           /* Screen palette             */
  SprPal=PRAM+(GameGear? 0x20:0x10);     /* Sprite palette             */
  MinLine=GameGear? (192-144)/2:0;       /* First scanline to refresh  */
  MaxLine=MinLine+(GameGear? 143:191);   /* Last scanline to refresh   */
  LinesLeft=255;                         /* Lines left to line inte-pt */
  SetScroll();                           /* ScrollX,ScrollY            */
  JoyState=0xFFFF;                       /* Joypad state               */
  NoiseMode=0x00;                        /* Noise channel modes        */
  Freq[0]=Freq[1]=Freq[2]=Freq[3]=0;     /* Sound channel frequencies  */
  Volume[0]=Volume[1]=0;                 /* Sound channel volumes      */
  Volume[2]=Volume[3]=0;
  ResetZ80(&R);                          /* Reset Z80 registers        */

  if(Verbose) printf("RUNNING ROM CODE...\n");
  J=Z80(R);

  if(Verbose) printf("EXITED at PC = %04Xh.\n",J);
  return(1);
}
示例#5
0
void cal_maratz80_reset(cal_cpu cpu)
{
    ResetZ80(cpu->data.d_maratz80);
}
示例#6
0
文件: machine.c 项目: teege/meka
// RESET EMULATED MACHINE -----------------------------------------------------
void        Machine_Reset(void)
{
    int     i;
    static byte VDPInit [16] =
    {
        /* Values set by BIOS */
        0x36, /*0xA0*/ 0x80 /* zero for Coleco */, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x00,
        0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00
        /* Old (guessed ?) values */
        // 0x06, 0x00, 0x0E, 0xFF, 0xFF, 0x7F, 0x00, 0x00,
        // 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00
    };

    #ifdef DEBUG_WHOLE
        Msg(MSGT_DEBUG, "Machine_Reset();");
    #endif

    // Unpause machine if necessary
    if (g_machine_flags & MACHINE_PAUSED)
        Machine_Pause();

    // Set driver & machine stuff
    drv_set (g_machine.driver_id);

    Machine_Set_Mapper         ();
    if ((g_machine_flags & MACHINE_RUN) != 0 /*== MACHINE_RUN */)
        Machine_Set_Mapping    (); // ^^ FIXME: the test above isn't beautiful since MACHINE_RUN contains multiple flags, but I'm unsure which of them is actually needed to perform the correct test
    Machine_Set_Handler_IO     ();
    Machine_Set_Handler_Read   ();
    Machine_Set_Handler_Write  ();
    Machine_Set_Handler_Loop   ();
    Machine_Set_Country        ();
    Machine_Set_IPeriod        ();
    Machine_Set_TV_Lines       ();

    // VDP MODEL --------------------------------------------------------------
    if (DB.current_entry && DB.current_entry->emu_vdp_model != -1)
	{
        g_machine.VDP.model = DB.current_entry->emu_vdp_model;
	}
    else
    {
        if (g_driver->id == DRV_GG)
            g_machine.VDP.model = VDP_MODEL_315_5378;
        else
            g_machine.VDP.model = VDP_MODEL_315_5226;
    }

    // 3-D GLASSES ------------------------------------------------------------
    sms.Glasses_Register = ((Glasses.Mode == GLASSES_MODE_SHOW_ONLY_LEFT) ? 1 : 0);
    if (Glasses.Mode == GLASSES_MODE_SHOW_ONLY_LEFT) {
        sms.Glasses_Register = 1;
    }

    // CPU (MARAT FAIZULLIN'S CORE) -------------------------------------------
    CPU_Loop_Stop = TRUE;
    CPU_ForceNMI  = FALSE;

#ifdef MARAT_Z80
    sms.R.IPeriod = opt.Cur_IPeriod;
    sms.R.Trace = FALSE;
    ResetZ80 (&sms.R);
    sms.R.IFF |= IFF_IM1;
    sms.R.IAutoReset = FALSE;
    sms.R.TrapBadOps = FALSE;

    // CPU (MAME'S CORE) ------------------------------------------------------
#elif MAME_Z80
    z80_reset (NULL);
    z80_set_irq_callback (Get_IRQ_Vector);
    z80_set_irq_line (0, ASSERT_LINE);
    z80_set_irq_line (0, CLEAR_LINE);

    // CPU (RICHARD MITTON'S CORE) --------------------------------------------
#elif RAZE_Z80
    z80_init_memmap();
    z80_add_write (0x0000, 0xFFFF, Z80_MAP_HANDLED, WrZ80);
    for (i = 0; i < 4; i ++)
    {
        z80_add_read ((i * 0x2000), (i * 0x2000) + 0x1FFF, Z80_MAP_DIRECT, Mem_Pages [i]);
        z80_map_fetch ((i * 0x2000), (i * 0x2000) + 0x1FFF, Mem_Pages [i]);
    }
    for (i = 4; i < 8; i ++)
    {
        z80_map_fetch ((i * 0x2000), (i * 0x2000) + 0x1FFF, Mem_Pages [i]);
        z80_map_read ((i * 0x2000), (i * 0x2000) + 0x1FFF, Mem_Pages [i]);
    }
    z80_set_in (InZ80);
    z80_set_out (OutZ80);
    z80_end_memmap();
    z80_reset();
#endif

    // MEMORY -----------------------------------------------------------------

	// Clear RAM
	if (g_driver->id == DRV_SMS && sms.Country == COUNTRY_JAPAN)
	{
		// On Japanese SMS clear RAM with 0xF0 patterns
		// I am not sure how reliable is that pattern but this is what I'm seeing on my JSMS
		// In theory this should be applied to all drivers, all countries, etc. but the exact
		// behavior of other systems and bioses should be inspected more in details before
		// generalizing that.
		// The game "Ali Baba" require a non-00 and non-FF memory pattern to run to a bug
		// in the code which makes it execute uninitialized memory from 0xFF07 onward.
		// An F0 pattern correspond to RET P which happens to fix the game.

		memset (RAM, 0xF0, 0x10000);
	}
	else
	{
		memset (RAM, 0x00, 0x10000);
	}
    memset (VRAM, 0, 0x04000);      // Clear all VRAM
    memset (PRAM, 0, 0x00040);      // Clear all PRAM (palette)

	#ifdef DEBUG_UNINITIALIZED_RAM_ACCESSES
		memset (RAM_IsUninitialized, 1, 0x2000);
	#endif

    // Unload BIOS if...
    if ((g_driver->id != DRV_SMS || sms.Country != COUNTRY_EXPORT) && (g_machine_flags & MACHINE_ROM_LOADED))
    {
        #ifdef DEBUG_WHOLE
            Msg(MSGT_DEBUG, "Machine_Reset(): BIOS_Unload()");
        #endif
        BIOS_Unload();
    }

    // GRAPHICS ---------------------------------------------------------------
    for (i = 0; i < 16; i++)
        Tms_VDP_Out (i, ((i == 1 && g_driver->id == DRV_COLECO) ? 0x00 : VDPInit [i]));
    for (i = 0; i < MAX_TILES; i++)
        tgfx.Tile_Dirty [i] = TILE_DIRTY_DECODE | TILE_DIRTY_REDRAW;

    VDP_UpdateLineLimits();

	//assert(!Screenbuffer_IsLocked());
	al_set_target_bitmap(screenbuffer_1);
    al_clear_to_color(COLOR_BLACK);
	al_set_target_bitmap(screenbuffer_2);
    al_clear_to_color(COLOR_BLACK);
    //screenbuffer = screenbuffer_1;
    //screenbuffer_next = screenbuffer_2;

    g_machine.VDP.sprite_shift_x = 0;
    g_machine.VDP.scroll_x_latched = 0;
    g_machine.VDP.scroll_y_latched = 0;
    memset(g_machine.VDP.scroll_x_latched_table, 0, sizeof(g_machine.VDP.scroll_x_latched_table));
    tsms.VDP_Video_Change = VDP_VIDEO_CHANGE_ALL;

    // GRAPHICS: SPRITE FLICKERING --------------------------------------------
    if (g_configuration.sprite_flickering & SPRITE_FLICKERING_AUTO)
    {
        if (DB.current_entry && (DB.current_entry->flags & DB_FLAG_EMU_SPRITE_FLICKER))
            g_configuration.sprite_flickering |= SPRITE_FLICKERING_ENABLED;
        else
            g_configuration.sprite_flickering &= ~SPRITE_FLICKERING_ENABLED;
    }

    // PALETTE ----------------------------------------------------------------
    //if (machine & MACHINE_POWER_ON)
    Palette_Emulation_Reset();

    // INPUT/OUTPUT/VDP -------------------------------------------------------
    sms.VDP_Status = 0x00;
    sms.VDP_Address = 0x0000;
    sms.VDP_Access_Mode = VDP_Access_Mode_1;
    sms.VDP_Access_First = 0x00;
    sms.VDP_Pal = 0x00;
    sms.VDP_ReadLatch = 0x00;
    sms.Lines_Left = 255;
    sms.Pending_HBlank = FALSE;
	sms.Pending_NMI = FALSE;
    tsms.VDP_Line = 0;

    // CONTROLLERS ------------------------------------------------------------
    for (i = 0; i < 8; i ++)
        tsms.Control [i] = 0xFFFF; /* 0x3FFF */
    tsms.Control_GG = /*0x20 | 0x80*/ 0;
    tsms.Control_Start_Pause = 0;
    tsms.Port3F = 0;
    sms.Input_Mode = 0x07;

    // SOUND ------------------------------------------------------------------
    sms.FM_Register = 0;
    sms.FM_Magic = 0;
    // if (fm_use == TRUE) fm_init (FM_ALL_INIT);
    // resume_fm();
    FM_Reset();
	SN76489_Reset (g_machine.TV->CPU_clock, Sound.SampleRate);
    if (Sound.LogVGM.Logging == VGM_LOGGING_ACCURACY_SAMPLE)
        VGM_Update_Timing (&Sound.LogVGM);

	Sound_ResetCycleCounter();

    // FIXME: add a reset handler per driver, instead of the code below...

    // GAME GEAR COMMUNICATION PORT
    if (g_machine.driver_id == DRV_GG)
        Comm_Reset();

    // SF-7000
    if (g_machine.driver_id == DRV_SF7000)
        SF7000_Reset();

    // DEBUGGER ---------------------------------------------------------------
    #ifdef MEKA_Z80_DEBUGGER
        Debugger_MachineReset();
    #endif
}