Exemple #1
0
void m1snd_addz80(long clock, void *handlers)
{
	char *z80cctx;
	int cpunum;

	z80cctx = malloc(4*1024);
	cpunum = timer_add_cpu(CPU_Z80C, clock, z80_execute, z80_getcycles, z80_yield, z80_getctx, z80_setctx, z80cctx);

	memory_register_cpu(cpunum, 8, M1_CPU_LE);

//	printf("adding Z80 #%d\n", cpunum);

	z80_init();
	z80_reset(NULL);
	z80_set_irq_callback(z80_irq_callback);
	z80_vector = 0xff;

	z80_getctx(z80cctx);
}
Exemple #2
0
int32 qsf_command(void *handle, int32 command, int32 parameter)
{
    qsf_synth_t *s = handle;
	switch (command)
	{
		case COMMAND_RESTART:
            memcpy (s->RAM, s->initRAM, 0x1000);
            memcpy (s->RAM2, s->initRAM2, 0x1000);

            if (s->z80) {
                z80_reset(s->z80, NULL);
                z80_set_irq_callback(s->z80, qsf_irq_cb);
            }
            qsound_sh_stop (s->qs);
            s->qs = qsound_sh_start(&qsintf);
            s->samples_to_next_tick = samples_per_tick;
			return AO_SUCCESS;
		
	}
	return AO_FAIL;
}
Exemple #3
0
/* Reset Z80 emulator */
void cpu_reset(void)
{
    z80_reset(0);
    z80_set_irq_callback(sms_irq_callback);
}
Exemple #4
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
}
Exemple #5
0
void system_load_state(void *fd)
{
    int i;
    uint8 reg[0x40];

    /* Initialize everything */
    cpu_reset();
    system_reset();

    /* Load VDP context */
    fread(&vdp, sizeof(t_vdp), 1, fd);

    /* Load SMS context */
    fread(&sms, sizeof(t_sms), 1, fd);

    /* Load Z80 context */
    fread(Z80_Context, sizeof(Z80_Regs), 1, fd);
    fread(&after_EI, sizeof(int), 1, fd);

    /* Load YM2413 registers */
    fread(reg, 0x40, 1, fd);

    /* Load SN76489 context */
    fread(&sn[0], sizeof(t_SN76496), 1, fd);

    /* Restore callbacks */
    z80_set_irq_callback(sms_irq_callback);

    cpu_readmap[0] = cart.rom + 0x0000; /* 0000-3FFF */
    cpu_readmap[1] = cart.rom + 0x2000;
    cpu_readmap[2] = cart.rom + 0x4000; /* 4000-7FFF */
    cpu_readmap[3] = cart.rom + 0x6000;
    cpu_readmap[4] = cart.rom + 0x0000; /* 0000-3FFF */
    cpu_readmap[5] = cart.rom + 0x2000;
    cpu_readmap[6] = sms.ram;
    cpu_readmap[7] = sms.ram;

    cpu_writemap[0] = sms.dummy;
    cpu_writemap[1] = sms.dummy;
    cpu_writemap[2] = sms.dummy;         
    cpu_writemap[3] = sms.dummy;
    cpu_writemap[4] = sms.dummy;         
    cpu_writemap[5] = sms.dummy;
    cpu_writemap[6] = sms.ram;           
    cpu_writemap[7] = sms.ram;

    sms_mapper_w(3, sms.fcr[3]);
    sms_mapper_w(2, sms.fcr[2]);
    sms_mapper_w(1, sms.fcr[1]);
    sms_mapper_w(0, sms.fcr[0]);

    /* Force full pattern cache update */
    is_vram_dirty = 1;
    memset(vram_dirty, 1, 0x200);

    /* Restore palette */
    for(i = 0; i < PALETTE_SIZE; i += 1)
        palette_sync(i);

    /* Restore sound state */
    if(snd.enabled)
    {
        /* Clear YM2413 context */
        OPLL_reset(opll) ;
        OPLL_reset_patch(opll,0) ;            /* if use default voice data. */ 

        /* Restore rhythm enable first */
        ym2413_write(0, 0, 0x0E);
        ym2413_write(0, 1, reg[0x0E]);

        /* User instrument settings */
        for(i = 0x00; i <= 0x07; i += 1)
        {
            ym2413_write(0, 0, i);
            ym2413_write(0, 1, reg[i]);
        }

        /* Channel frequency */
        for(i = 0x10; i <= 0x18; i += 1)
        {
            ym2413_write(0, 0, i);
            ym2413_write(0, 1, reg[i]);
        }

        /* Channel frequency + ctrl. */
        for(i = 0x20; i <= 0x28; i += 1)
        {
            ym2413_write(0, 0, i);
            ym2413_write(0, 1, reg[i]);
        }

        /* Instrument and volume settings  */
        for(i = 0x30; i <= 0x38; i += 1)
        {
            ym2413_write(0, 0, i);
            ym2413_write(0, 1, reg[i]);
        }
    }
}
Exemple #6
0
void *qsf_start(const char *path, uint8 *buffer, uint32 length)
{
    qsf_synth_t *s = malloc (sizeof (qsf_synth_t));
    memset (s, 0, sizeof (qsf_synth_t));

	uint8 *file = NULL, *lib_decoded = NULL, *lib_raw_file = NULL;
	uint64 file_len, lib_len, lib_raw_length;
	corlett_t *lib;

	s->z80 = z80_init();
	s->z80->userdata = s;

	s->Z80ROM = malloc(512*1024);
	s->QSamples = malloc(8*1024*1024);

	s->skey1 = s->skey2 = 0;
	s->akey = 0;
	s->xkey = 0;
	s->cur_bank = 0;

	// Decode the current QSF
	if (corlett_decode(buffer, length, &file, &file_len, &s->c) != AO_SUCCESS)
	{
		return AO_FAIL;
	}

	// Get the library file
	if (s->c->lib[0] != 0)
	{
		uint64 tmp_length;
	
        char libpath[PATH_MAX];
        ao_getlibpath (path, s->c->lib, libpath, sizeof (libpath));

#if DEBUG_LOADER	
        printf("Loading library: %s\n", libpath);
#endif
        if (ao_get_lib(libpath, &lib_raw_file, &tmp_length) != AO_SUCCESS)
        {
            free (file);
            qsf_stop (s);
            return NULL;
		}
		lib_raw_length = tmp_length;
		
		if (corlett_decode(lib_raw_file, lib_raw_length, &lib_decoded, &lib_len, &lib) != AO_SUCCESS)
		{
			free(lib_raw_file);
            free (file);
            qsf_stop (s);
            return NULL;
		}
				
		// Free up raw file
		free(lib_raw_file);

		// use the contents
		qsf_walktags(s, lib_decoded, lib_decoded+lib_len);
		
		// Dispose the corlett structure for the lib - we don't use it
		free(lib);
		if (lib_decoded) {
            free (lib_decoded);
            lib_decoded = NULL;
        }
	}

	// now patch the file into RAM OVER the libraries
	qsf_walktags(s, file, file+file_len);

	free(file);

	if ((s->skey1 != 0) && (s->skey2 != 0))
	{
		#if DEBUG_LOADER
		printf("Decoding Kabuki: skey1 %08x skey2 %08x akey %04x xkey %02x\n", skey1, skey2, akey, xkey);
		#endif

		s->uses_kabuki = 1;
		cps1_decode((unsigned char *)s->Z80ROM, s->skey1, s->skey2, s->akey, s->xkey);
	}

	// set qsfby tag
	strcpy(s->qsfby, "n/a");
	if (s->c)
	{
		int i;
		for (i = 0; i < MAX_UNKNOWN_TAGS; i++)
		{
			if (!strcasecmp(s->c->tag_name[i], "qsfby"))
			{
				strcpy(s->qsfby, s->c->tag_data[i]);
			}
		}
	}

	memcpy (s->initRAM, s->RAM, 0x1000);
	memcpy (s->initRAM2, s->RAM2, 0x1000);

    if (s->z80) {
        z80_reset(s->z80, NULL);
        z80_set_irq_callback(s->z80, qsf_irq_cb);
    }
	qsintf.sample_rom = s->QSamples;
	s->qs = qsound_sh_start(&qsintf);
	s->samples_to_next_tick = samples_per_tick;

	return s;
}
Exemple #7
0
int load_state_from_mem(void *stor)
{
    int i;

    /* Initialize everything */
    z80_reset(0);
    z80_set_irq_callback(sms_irq_callback);
    system_reset();
    if(snd.enabled)
        sound_reset();

    //davex: header is not saved in memory state
    

    // Load VDP context 
    memcpy(&vdp, stor, sizeof(vdp_t)); //VDP context
    stor += sizeof(vdp_t);
    
    
    //Load SMS context (1/3)
    memcpy(&sms, stor, sizeof(sms_t) );
    stor += sizeof(sms_t); 
    
    //Load SMS context (2/3)
    memcpy(&cart.fcr[0],stor, 1 );
    stor += 1; 
    memcpy(&cart.fcr[1],stor, 1 );
    stor += 1; 
    memcpy(&cart.fcr[2],stor, 1 );
    stor += 1; 
    memcpy(&cart.fcr[3],stor, 1 );
    stor += 1; 
        
    //Load SMS context (3/3)
    memcpy(&cart.sram, stor, 0x8000);
    stor += 0x8000;
    

    // Load Z80 context 
    memcpy(Z80_Context, stor, sizeof(Z80_Regs) );
    stor += sizeof(Z80_Regs);
    memcpy(&after_EI, stor,  sizeof(int) );
    stor += sizeof(int);
    
    
    // Load YM2413 context
    FM_SetContext(stor);
    stor += FM_GetContextSize();
    
    // Load SN76489 context
    SN76489_SetContext(0, stor);
   

    /* Restore callbacks */
    z80_set_irq_callback(sms_irq_callback);

    for(i = 0x00; i <= 0x2F; i++)
    {
        cpu_readmap[i]  = &cart.rom[(i & 0x1F) << 10];
        cpu_writemap[i] = dummy_write;
    }

    for(i = 0x30; i <= 0x3F; i++)
    {
        cpu_readmap[i] = &sms.wram[(i & 0x07) << 10];
        cpu_writemap[i] = &sms.wram[(i & 0x07) << 10];
    }

    sms_mapper_w(3, cart.fcr[3]);
    sms_mapper_w(2, cart.fcr[2]);
    sms_mapper_w(1, cart.fcr[1]);
    sms_mapper_w(0, cart.fcr[0]);

    /* Force full pattern cache update */
    bg_list_index = 0x200;
    for(i = 0; i < 0x200; i++)
    {
        bg_name_list[i] = i;
        bg_name_dirty[i] = -1;
    }

    /* Restore palette */
    for(i = 0; i < PALETTE_SIZE; i++)
        palette_sync(i, 1);
 
    viewport_check();

    return 1;
}
Exemple #8
0
void system_load_state(void *fd)
{
    int i;
    uint8 *buf;
    char id[4];
    uint16 version;

    /* Initialize everything */
    z80_reset(0);
    z80_set_irq_callback(sms_irq_callback);
    system_reset();
    if(snd.enabled)
        sound_reset();

    /* Read header */
    fread(id, 4, 1, fd);
    fread(&version, 2, 1, fd);

    /* Load VDP context */
    fread(&vdp, sizeof(vdp_t), 1, fd);

    /* Load SMS context */
    fread(&sms, sizeof(sms_t), 1, fd);

    cart.fcr[0] = fgetc(fd);
    cart.fcr[1] = fgetc(fd);
    cart.fcr[2] = fgetc(fd);
    cart.fcr[3] = fgetc(fd);
    fread(cart.sram, 0x8000, 1, fd);

    /* Load Z80 context */
    fread(Z80_Context, sizeof(Z80_Regs), 1, fd);
    fread(&after_EI, sizeof(int), 1, fd);

    /* Load YM2413 context */
    buf = malloc(FM_GetContextSize());
    fread(buf, FM_GetContextSize(), 1, fd);
    FM_SetContext(buf);
    free(buf);

    /* Load SN76489 context */
    buf = malloc(SN76489_GetContextSize());
    fread(buf, SN76489_GetContextSize(), 1, fd);
    SN76489_SetContext(0, buf);
    free(buf);

    /* Restore callbacks */
    z80_set_irq_callback(sms_irq_callback);

    for(i = 0x00; i <= 0x2F; i++)
    {
        cpu_readmap[i]  = &cart.rom[(i & 0x1F) << 10];
        cpu_writemap[i] = dummy_write;
    }

    for(i = 0x30; i <= 0x3F; i++)
    {
        cpu_readmap[i] = &sms.wram[(i & 0x07) << 10];
        cpu_writemap[i] = &sms.wram[(i & 0x07) << 10];
    }

    sms_mapper_w(3, cart.fcr[3]);
    sms_mapper_w(2, cart.fcr[2]);
    sms_mapper_w(1, cart.fcr[1]);
    sms_mapper_w(0, cart.fcr[0]);

    /* Force full pattern cache update */
    bg_list_index = 0x200;
    for(i = 0; i < 0x200; i++)
    {
        bg_name_list[i] = i;
        bg_name_dirty[i] = -1;
    }

    /* Restore palette */
    for(i = 0; i < PALETTE_SIZE; i++)
        palette_sync(i, 1);

    viewport_check();
}
int32 qsf_start(uint8 *buffer, uint32 length)
{
	uint8 *file, *lib_decoded, *lib_raw_file;
	uint64 file_len, lib_len, lib_raw_length;
	corlett_t *lib;

	z80_init();

	Z80ROM = malloc(512*1024);
	QSamples = malloc(8*1024*1024);

	skey1 = skey2 = 0;
	akey = 0;
	xkey = 0;
	cur_bank = 0;

	memset(RAM, 0, 0x1000);
	memset(RAM2, 0, 0x1000);
		
	// Decode the current QSF
	if (corlett_decode(buffer, length, &file, &file_len, &c) != AO_SUCCESS)
	{
		return AO_FAIL;
	}

	// Get the library file
	if (c->lib[0] != 0)
	{
		uint64 tmp_length;
	
		#if DEBUG_LOADER	
		printf("Loading library: %s\n", c->lib);
		#endif
		if (ao_get_lib(c->lib, &lib_raw_file, &tmp_length) != AO_SUCCESS)
		{
			return AO_FAIL;
		}
		lib_raw_length = tmp_length;
		
		if (corlett_decode(lib_raw_file, lib_raw_length, &lib_decoded, &lib_len, &lib) != AO_SUCCESS)
		{
			free(lib_raw_file);
			return AO_FAIL;
		}
				
		// Free up raw file
		free(lib_raw_file);

		// use the contents
		qsf_walktags(lib_decoded, lib_decoded+lib_len);
		
		// Dispose the corlett structure for the lib - we don't use it
		free(lib);
	}

	// now patch the file into RAM OVER the libraries
	qsf_walktags(file, file+file_len);

	free(file);

	if ((skey1 != 0) && (skey2 != 0))
	{
		#if DEBUG_LOADER
		printf("Decoding Kabuki: skey1 %08x skey2 %08x akey %04x xkey %02x\n", skey1, skey2, akey, xkey);
		#endif

		uses_kabuki = 1;
		cps1_decode((unsigned char *)Z80ROM, skey1, skey2, akey, xkey);
	}

	// set qsfby tag
	strcpy(qsfby, "n/a");
	if (c)
	{
		int i;
		for (i = 0; i < MAX_UNKNOWN_TAGS; i++)
		{
			if (!strcasecmp(c->tag_name[i], "qsfby"))
			{
				strcpy(qsfby, c->tag_data[i]);
			}
		}
	}

	z80_reset(NULL);
	z80_set_irq_callback(qsf_irq_cb);
	qsintf.sample_rom = QSamples;
	qsound_sh_start(&qsintf);

	return AO_SUCCESS;
}
Exemple #10
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 (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
}