Example #1
0
void _z80_init(void)
{
#ifdef CPUZ80_CZ80_CORE
	Cz80_Init(&neocd_cz80_struc);
	Cz80_Set_Fetch(&neocd_cz80_struc,0x0000,0xFFFF,(u32)((void *)&mame_z80mem));
	Cz80_Set_ReadB(&neocd_cz80_struc,&cpu_readmem8);
	Cz80_Set_WriteB(&neocd_cz80_struc,&cpu_writemem8);
#if CZ80_USE_WORD_HANDLER
	Cz80_Set_ReadW(&neocd_cz80_struc,&cpu_readmem16);
	Cz80_Set_WriteW(&neocd_cz80_struc,&cpu_writemem16);
#endif
	Cz80_Set_INPort(&neocd_cz80_struc,(CZ80_READ *)&mame_z80_readport16);
	Cz80_Set_OUTPort(&neocd_cz80_struc,(CZ80_WRITE *)&mame_z80_writeport16);
	Cz80_Set_IRQ_Callback(&neocd_cz80_struc,cpu_z80_irq_callback);
	Cz80_Reset(&neocd_cz80_struc);
	//Cz80_Exec(&neocd_cz80_struc,100000);
#endif
#ifdef CPUZ80_MAMEZ80_CORE
	z80_init();
	/*
	z80map1 = mame_z80mem + 0x8000;
	z80map2 = mame_z80mem + 0xc000;
	z80map3 = mame_z80mem + 0xe000;
	z80map4 = mame_z80mem + 0xf000;
	z80_bank[0]=0x8000;
	z80_bank[1]=0xc000;
	z80_bank[2]=0xe000;
	z80_bank[3]=0xf000;
	*/
	z80_reset(NULL);
	//z80_set_irq_callback(cpu_z80_irq_callback);
#endif
}
Example #2
0
void cpu_z80_init(void)
{
    z80_init_memmap();
    z80_map_fetch(0x0000, 0x7fff, memory.rom.cpu_z80.p);
    z80_map_fetch(0x8000, 0xbfff, memory.rom.cpu_z80.p + 0x8000);
    z80_map_fetch(0xc000, 0xdfff, memory.rom.cpu_z80.p + 0xc000);
    z80_map_fetch(0xe000, 0xefff, memory.rom.cpu_z80.p + 0xe000);
    z80_map_fetch(0xf000, 0xf7ff, memory.rom.cpu_z80.p + 0xf000);
    z80_map_fetch(0xf800, 0xffff, memory.z80_ram);

    z80_add_read(0x0000, 0x7fff, Z80_MAP_DIRECT, memory.rom.cpu_z80.p);
    z80_map_read(0x8000, 0xbfff, memory.rom.cpu_z80.p + 0x8000);
    z80_map_read(0xc000, 0xdfff, memory.rom.cpu_z80.p + 0xc000);
    z80_map_read(0xe000, 0xefff, memory.rom.cpu_z80.p + 0xe000);
    z80_map_read(0xf000, 0xf7ff, memory.rom.cpu_z80.p + 0xf000);
    z80_add_read(0xf800, 0xffff, Z80_MAP_DIRECT, memory.z80_ram);

    z80_bank[0]=0x8000;
    z80_bank[1]=0xc000;
    z80_bank[2]=0xe000;
    z80_bank[3]=0xf000;

    z80_add_write(0xf800, 0xffff, Z80_MAP_DIRECT, memory.z80_ram);

    z80_end_memmap();

    z80_set_in(z80_port_read);
    z80_set_out(z80_port_write);

/*    z80_set_fetch_callback(&debug);*/

    cpu_z80_init_save_state();

    z80_reset();
}
Example #3
0
/* C128-specific reset sequence.  */
void machine_specific_reset(void)
{
    serial_traps_reset();

    ciacore_reset(machine_context.cia1);
    ciacore_reset(machine_context.cia2);
    sid_reset();

    rs232drv_reset();
    rsuser_reset();

    printer_reset();

    vdc_reset();

    /* The VIC-II must be the *last* to be reset.  */
    vicii_reset();

    cartridge_reset();
    drive_reset();
    datasette_reset();

    z80mem_initialize();
    z80_reset();
}
Example #4
0
void cps1_driver_reset(void)
{
	m68000_reset();
	z80_reset();

	coin_counter_reset();

	sound_data = 0x00;
	cps1_sound_fade_timer = 0;
}
Example #5
0
void cps2_driver_reset(void)
{
	m68000_reset();
	z80_reset();
	if(!option_sound_enable) qsound_sharedram1[0xfff] = 0x77;

	coin_counter_reset();

	next_update_first_line = FIRST_VISIBLE_LINE;
}
Example #6
0
void Z80_reset(void)
{
	Z80Enabled = 0;

	z80_writebyte = NGP_z80_writebyte;
	z80_readbyte = NGP_z80_readbyte;
	z80_writeport = NGP_z80_writeport;
	z80_readport = NGP_z80_readport;

	z80_init();
	z80_reset();
}
Example #7
0
void z80_set_reset_line(int state)
{
	if (z80_suspended & SUSPEND_REASON_RESET)
	{
		if (state == CLEAR_LINE)
			z80_suspended &= ~SUSPEND_REASON_RESET;
	}
	else if (state == ASSERT_LINE)
	{
		z80_suspended |= SUSPEND_REASON_RESET;
		z80_reset();
	}
}
Example #8
0
void gen_reset_w(int state)
{
	//printf("ZRESET: %d, %d\n", state, md_timestamp);
    zreset = (state & 1);
    zbusack = 1 ^ (zbusreq & zreset);

    MDSound_SetYM2612Reset(!zreset);

    if(zreset == 0)
    {
     z80_reset();
    }
}
Example #9
0
/* Handle reset button if poweron=0;
   handle hard reset or initial poweron if poweron=1 */
void trs_reset(int poweron)
{
    trs_emu_mouse = FALSE;

#ifndef ANDROID
    /* Close disks opened by Z80 programs */
    do_emt_resetdisk();
#endif
    /* Reset devices (Model I SYSRES, Model III/4 RESET) */
    trs_cassette_reset();
    trs_timer_speed(0);
    trs_disk_init(poweron); // also inits trs_hard and trs_stringy
    /* I'm told that the hard disk controller is enabled on powerup */
    /* XXX should trs_hard_init do this, then? */
    trs_hard_out(TRS_HARD_CONTROL,
		 TRS_HARD_SOFTWARE_RESET|TRS_HARD_DEVICE_ENABLE);
    if (trs_model == 5) {
        /* Switch in boot ROM */
	z80_out(0x9C, 1);
    }
    if (trs_model >= 4) {
        /* Turn off various memory map and video mode bits */
	z80_out(0x84, 0);
    }
    if (trs_model >= 3) {
	grafyx_write_mode(0);
	trs_interrupt_mask_write(0);
	trs_nmi_mask_write(0);
    }
    if (trs_model == 3) {
        grafyx_m3_reset();
    }
    if (trs_model == 1) {
	hrg_onoff(0);		/* Switch off HRG1B hi-res graphics. */
    }
    trs_kb_reset();  /* Part of keyboard stretch kludge */

    trs_cancel_event();
    trs_timer_interrupt(0);
    if (poweron || trs_model >= 4) {
        /* Reset processor */
	z80_reset();
    } else {
	/* Signal a nonmaskable interrupt. */
	trs_reset_button_interrupt(1);
	trs_schedule_event(trs_reset_button_interrupt, 0, 2000);
    }
}
Example #10
0
void neogeo_driver_reset(void)
{
    memset(exmem, 0, sizeof(exmem));
    memset(exmem_latch, 0, sizeof(exmem_latch));
    memset(exmem_bank, 0, sizeof(exmem_bank));
    exmem_counter = 0;

    upload_mode = UPLOAD_IMMIDIATE;
    upload_type = UNKNOWN_TYPE;
    upload_offset1 = 0;
    upload_offset2 = 0;
    upload_length = 0;
    upload_pattern = 0;
    upload_executing = 0;

    memcpy(memory_region_cpu1, neogeo_vectors[1], 0x100);	// game vector

    watchdog_reset_w(0, 0, 0);

    raster_line = 0;
    raster_counter = RASTER_COUNTER_START;
    scanline_read = 0;

    display_position_interrupt_start = 1000;
    display_position_interrupt_counter = 0;
    display_position_interrupt_control = 0;
    display_counter = 0;

    vblank_interrupt_pending = 0;
    display_position_interrupt_pending = 0;

    sound_code = 0;
    result_code = 0;
    pending_command = 0;

    auto_animation_frame_counter = 0;
    auto_animation_speed = 0;
    auto_animation_disabled = 0;
    auto_animation_counter = 0;

    neogeo_reset_driver_type();

    m68000_reset();
    z80_reset();
}
Example #11
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);
}
Example #12
0
void gen_reset (unsigned int hard_reset)
{
	if (hard_reset)
	{
		/* Clear RAM */
		memset (work_ram, 0, sizeof (work_ram));
		memset (zram, 0, sizeof (zram));

		/* Reset ROM mapping */
    if (config.bios_enabled == 3)
    {
      rom_readmap[0] = &bios_rom[0];
      rom_size = 0x800;
    }
    else
    {
      rom_readmap[0] = &cart_rom[0];
      rom_size = genromsize;
    }

		uint8 i;
    for (i=1; i<8; i++) rom_readmap[i] = &cart_rom[i << 19];
	}

	gen_running = 1;
	zreset = 0;		/* Z80 is reset */
	zbusreq = 0;	/* Z80 has control of the Z bus */
	zbusack = 1;	/* Z80 is busy using the Z bus */
	zbank = 0;		/* Assume default bank is 000000-007FFF */
	zirq = 0;		/* No interrupts occuring */
	resetline = -1;

	/* Reset CPUs */
	m68k_pulse_reset ();
	z80_reset ();
	_YM2612_Reset();	

#ifdef NGC
  /* register SOFTRESET */
  SYS_SetResetCallback(set_softreset);
#endif

}
Example #13
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;
}
Example #14
0
int sms_z80_init(void) {
    cpuz80 = (CrabZ80_t *)malloc(sizeof(CrabZ80_t));

    if(cpuz80 == NULL) {
        fprintf(stderr, "Out of memory while initializing Z80 in debug mode\n");
        return -1;
    }

    /* Initialize CrabZ80 */
    CrabZ80_init(cpuz80);
    CrabZ80_reset(cpuz80);

    CrabZ80_set_memwrite(cpuz80, sms_debug_memwrite);
    CrabZ80_set_memread(cpuz80, sms_debug_memread);
    CrabZ80_set_portwrite(cpuz80, sms_debug_portwrite);
    CrabZ80_set_portread(cpuz80, sms_debug_portread);

    z80_init();
    z80_reset();

    return 0;
}
Example #15
0
void cpu_z80_init(void)
{
    //  init_mamez80_mem();
    z80_init();

    /* bank initalisation */
    /*
    z80map1 = memory.sm1 + 0x8000;
    z80map2 = memory.sm1 + 0xc000;
    z80map3 = memory.sm1 + 0xe000;
    z80map4 = memory.sm1 + 0xf000;

    z80_bank[0]=0x8000;
    z80_bank[1]=0xc000;
    z80_bank[2]=0xe000;
    z80_bank[3]=0xf000;
    */
    //memcpy(mame_z80mem, memory.sm1, 0xf800);
    z80_reset(NULL);
    //set_irq_callback(mame_z80_irq_callback);
    //z80_init_save_state();
}
Example #16
0
void gen_reset(void)
{
    /* Clear RAM */
#ifndef MEM2
    memset(work_ram, 0, sizeof(work_ram));
    memset(zram, 0, sizeof(zram));
#else
    memset(work_ram, 0, 0x10000);
    memset(zram, 0, 0x2000);
#endif

    gen_running = 1;
    zreset  = 0;    /* Z80 is reset */
    zbusreq = 0;    /* Z80 has control of the Z bus */
    zbusack = 1;    /* Z80 is busy using the Z bus */
    zbank   = 0;    /* Assume default bank is 000000-007FFF */
    zirq    = 0;    /* No interrupts occuring */

    gen_io_reset();

    C68k_Reset(&Main68K);
    z80_reset();
}
Example #17
0
void gen_reset_w (unsigned int state)
{
	int z80_cycles_to_run;

	if (state)
	{
		/* stop RESET process */
		if (!zbusreq && !zreset)
		{
			/* Z80 started */
			/* z80 was OFF during the last 68k cycles */
			/* we burn the appropriate number of z80 cycles */
			z80_cycles_to_run = line_z80 + ((count_m68k - line_m68k)*7)/15;
			count_z80 = z80_cycles_to_run;
		}
	}
	else
	{
		/* start RESET process */
		if (!zbusreq && zreset)
		{
			/* Z80 stopped */
			/* z80 was ON during the last 68k cycles */
			/* we execute the appropriate number of z80 cycles */
			z80_cycles_to_run = line_z80 + ((count_m68k - line_m68k)*7)/15;
			z80_run(z80_cycles_to_run);
		}

		/* Reset Z80 & YM2612 */
		_YM2612_Reset();
		z80_reset ();
	}

	zreset = state;
	zbusack = 1 ^ (zbusreq & zreset);
}
Example #18
0
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;
}
Example #19
0
void Z80_SetEnable(bool set)
{
 Z80Enabled = set;
 if(!set)
  z80_reset();
}
Example #20
0
int main(void) {
 v = no_routine;
 v_hook = no_routine;
 h_hook = no_routine;
 pal_mutex = 0;

 VDP_SET_REGISTER(MODE_SET_1, 0x16);
 VDP_SET_REGISTER(NAME_TABLE_SCROLLA_BASE, SCROLL_A_ADDR(0xc000));
 VDP_SET_REGISTER(NAME_TABLE_WINDOW_BASE,  SCROLL_A_ADDR(0x10000));
 VDP_SET_REGISTER(NAME_TABLE_SCROLLB_BASE, SCROLL_B_ADDR(0xe000));
 VDP_SET_REGISTER(SPRITE_ATTRIBUTE_BASE,   SPRITE_ADDR(SPRITE_BASE));
 VDP_SET_REGISTER(0x06, 0x00);
 VDP_SET_REGISTER(BACKGROUND_COLOR, 0x00);
 VDP_SET_REGISTER(0x08, 0x01);
 VDP_SET_REGISTER(0x09, 0x01);
 VDP_SET_REGISTER(H_COUNTER, 1);
 VDP_SET_REGISTER(MODE_SET_3, HORIZONTAL_LINE);
 VDP_SET_REGISTER(MODE_SET_4, CELLW_40);
 VDP_SET_REGISTER(HSCROLL_BASE, HSCROLL_ADDR( 0xfc00));
 VDP_SET_REGISTER(0x0e, 0x00);
 VDP_SET_INC(0x02);
 VDP_SET_REGISTER(SCROLL_SIZE, SCROLL_WIDTH_64);
 VDP_SET_REGISTER(WINDOW_X, 0x00);
 VDP_SET_REGISTER(WINDOW_Y, 0x00);
 VDP_SET_REGISTER(19, 0x00);
 VDP_SET_REGISTER(20, 0x00);
 VDP_SET_REGISTER(21, 0x00);
 VDP_SET_REGISTER(22, 0x00);

 z80_write(0,z80_prog, Z80_PROG_LEN);
 z80_reset();

 brightness = -8;
 fade_to = -8;
 updating_palette = 0;
 dma_corrupt = 0; 

 secret_pos = 0;
 lcontroller = 0;
 song_pos = 0;
 song_ticks = 0;

 VDP_SET_REGISTER(MODE_SET_2, 0x74);

 proc[0]();//  init_sega();
 for(;;) {
  SYNC;
  update_palette();
  
  if(song_ticks == 0)  {
   h_hook = no_routine;
   v_hook = no_routine;
   fade_to = -8;
   brightness = -8;
   update_palette();
   proc[song_pos*2]();
   song_ticks = 0;
  }

  update_vgm_pos();
  
  proc[(song_pos*2)+1](); 

  song_ticks++;
  if(vgm_pos>=scenes[song_pos]) {
   song_pos++;
   song_ticks = 0;
  }


  lcontroller = controller;
  controller = poll_ctrl1();
  if((controller != lcontroller) && (controller != 0)) {
   if(secret_msg[secret_pos] == controller) 
    secret_pos++;
   else
    secret_pos = 0;
   if(secret_pos == 4) secret();
  } 
 }

}
Example #21
0
File: sms.c Project: Cpasjuste/psms
/* Reset Z80 emulator */
void cpu_reset(void)
{
    z80_reset(0);
    z80_set_irq_callback(sms_irq_callback);
}
Example #22
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;
}
Example #23
0
File: machine.c Project: 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
}
Example #24
0
void neogeo_driver_reset(void)
{
#ifdef ADHOC
	if (adhoc_enable)
	{
		pd4990a.seconds = 0;
		pd4990a.minutes = 0;
		pd4990a.hours   = 0;
		pd4990a.days    = 0;
		pd4990a.month   = 0;
		pd4990a.year    = 0;
		pd4990a.weekday = 0;
	}
	else
#endif
	{
		pspTime today;
		int y, m, d;

		sceRtcGetCurrentClockLocalTime(&today);

		pd4990a.seconds = ((today.seconds / 10) << 4) + (today.seconds % 10);
		pd4990a.minutes = ((today.minutes / 10) << 4) + (today.minutes % 10);
		pd4990a.hours   = ((today.hour    / 10) << 4) + (today.hour    % 10);
		pd4990a.days    = ((today.day     / 10) << 4) + (today.day     % 10);
		pd4990a.month   = today.month;
		pd4990a.year    = (((today.year % 100) / 10) << 4) + (today.year % 10);

		y = today.year;
		m = today.month;
		d = today.day;
		if (m == 1 || m == 2) { y--; m += 12; }
		pd4990a.weekday = (y + (y / 4) - (y / 100) + (y / 400) + ((13 * m + 8) / 5) + d) % 7;
	}

	memset(neogeo_ram, 0, 0x10000);

	memcpy(memory_region_cpu1, neogeo_vectors[0], 0x80);	// bios vector
	main_cpu_vector_table_source = 0;

	watchdog_reset_w(0, 0, 0);

	raster_counter = RASTER_COUNTER_START;
	scanline_read = 0;

	display_position_interrupt_counter = 0;
	display_position_interrupt_control = 0;
	display_counter = 0;

	vblank_interrupt_pending = 0;
	display_position_interrupt_pending = 0;

	sound_code = 0;
	result_code = 0;
	pending_command = 0;

	auto_animation_frame_counter = 0;
	auto_animation_speed = 0;
	auto_animation_disabled = 0;
	auto_animation_counter = 0;

	neogeo_rng = 0x2345;
	save_ram_unlocked = 0;

	controller_select = 0;

	neogeo_reset_driver_type();

	if (machine_init_type == INIT_ms5pcb
	||	machine_init_type == INIT_svcpcb)
	{
		memcpy(memory_region_user1, memory_region_user1 + 0x20000 + neogeo_hard_dipsw * 0x20000, 0x20000);
	}
#if !RELEASE
	if (machine_init_type == INIT_kog)
	{
		memory_region_cpu1[0x1ffffc/2] = neogeo_hard_dipsw;
	}
#endif

	m68000_reset();
	z80_reset();
}
Example #25
0
File: z80.cpp Project: shaos/zpring
/* Set up the z80 emulation */
void z80_init(int debug)
{
  z80_init_tables();
  z80_reset();
  if(debug) fdebug = fopen("debug.out","wt");
}
Example #26
0
void gen_reset(int hard_reset)
{
  /* System Reset */
  if (hard_reset)
  {
    /* clear RAM */
    memset (work_ram, 0x00, sizeof (work_ram));
    memset (zram, 0x00, sizeof (zram));

  }
  else
  {
    /* reset YM2612 (on hard reset, this is done by sound_reset) */
    fm_reset(0);
  }

  /* 68k & Z80 could restart anywhere in VDP frame (Bonkers, Eternal Champions, X-Men 2) */
  mcycles_68k = mcycles_z80 = (uint32)((MCYCLES_PER_LINE * lines_per_frame) * ((double)rand() / (double)RAND_MAX));
  //mcycles_68k = mcycles_z80 = 0;

  if (system_hw == SYSTEM_PBC)
  {
    /* reset MS cartridge hardware */
    sms_cart_reset();

    /* Z80 is running */
    zstate = 1;

    /* 68k is halted */
    m68k_pulse_halt();
  }
  else
  {
    /* reset MD cartridge hardware */
    md_cart_reset(hard_reset);

    /* Z80 bus is released & Z80 is reseted */
    m68k_memory_map[0xa0].read8   = m68k_read_bus_8;
    m68k_memory_map[0xa0].read16  = m68k_read_bus_16;
    m68k_memory_map[0xa0].write8  = m68k_unused_8_w;
    m68k_memory_map[0xa0].write16 = m68k_unused_16_w;
    zstate = 0;

    /* assume default bank is $000000-$007FFF */
    zbank = 0;  

    /* TMSS & OS ROM support */
    if (config.tmss & 1)
    {
      /* clear TMSS register */
      memset(tmss, 0x00, sizeof(tmss));

      /* VDP access is locked by default */
      int i;
      for (i=0xc0; i<0xe0; i+=8)
      {
        m68k_memory_map[i].read8   = m68k_lockup_r_8;
        m68k_memory_map[i].read16  = m68k_lockup_r_16;
        m68k_memory_map[i].write8  = m68k_lockup_w_8;
        m68k_memory_map[i].write16 = m68k_lockup_w_16;
        zbank_memory_map[i].read   = zbank_lockup_r;
        zbank_memory_map[i].write  = zbank_lockup_w;
      }

      /* OS ROM is mapped at $000000-$0007FF */
      if (config.tmss & 2)
      {
        m68k_memory_map[0].base = bios_rom;
      }
    }

    /* reset 68k */
    m68k_pulse_reset();
  }

  /* reset Z80 */
  z80_reset();
}
Example #27
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
}
Example #28
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;
}
Example #29
0
void sms_z80_reset(void) {
    CrabZ80_reset(cpuz80);
    z80_reset();
}
Example #30
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();
}