/*------------------------------------------------------------------------- Audio command callback. Input: Timer Pointer to the timer that triggered the callback. Data Data associated with the timer. ---------------------------------------------------------------------------*/ void neogeo_audio_command_timer_callback ( TIMER *Timer, Uint32 Data ) { Uint32 Z80_Elapsed; /* Post the audio command to the Z80 */ neogeo_audio_command = Data; z80_set_irq_line ( INPUT_LINE_NMI, ASSERT_LINE ); z80_set_irq_line ( INPUT_LINE_NMI, CLEAR_LINE ); /* Let the Z80 take the command into account */ Z80_Elapsed = z80_execute ( REF_TO_Z80 ( 2000 ) ); neogeo_z80_time_to_execute -= Z80_TO_REF ( Z80_Elapsed ); neogeo_z80_time_this_vbl += Z80_TO_REF ( Z80_Elapsed ); }
// 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 }
/* Run the virtual console emulation for one frame */ void system_frame(int skip_render) { static int iline_table[] = {0xC0, 0xE0, 0xF0}; int lpf = (sms.display == DISPLAY_NTSC) ? 262 : 313; int iline; /* Debounce pause key */ if(input.system & INPUT_PAUSE) { if(!sms.paused) { sms.paused = 1; z80_set_irq_line(IRQ_LINE_NMI, ASSERT_LINE); z80_set_irq_line(IRQ_LINE_NMI, CLEAR_LINE); } } else { sms.paused = 0; } text_counter = 0; /* End of frame, parse sprites for line 0 on line 261 (VCount=$FF) */ if(vdp.mode <= 7) parse_line(0); for(vdp.line = 0; vdp.line < lpf;) { z80_execute(227); iline = iline_table[vdp.extended]; if(!skip_render) { render_line(vdp.line); } if(vdp.line <= iline) { vdp.left -= 1; if(vdp.left == -1) { vdp.left = vdp.reg[0x0A]; vdp.hint_pending = 1; z80_execute(16); if(vdp.reg[0x00] & 0x10) { z80_set_irq_line(0, ASSERT_LINE); } } } else { vdp.left = vdp.reg[0x0A]; } if(vdp.line == iline) { vdp.status |= 0x80; vdp.vint_pending = 1; z80_execute(16); if(vdp.reg[0x01] & 0x20) { z80_set_irq_line(0, ASSERT_LINE); } } sound_update(vdp.line); ++vdp.line; if(vdp.mode <= 7) parse_line(vdp.line); } }
static TIMER_CALLBACK( qsound_interrupt ) { z80_set_irq_line(0, HOLD_LINE); timer_set(QSOUND_INTERRUPT, TIME_IN_HZ(251), 0, qsound_interrupt); }
void cps1_sound_interrupt(int state) { z80_set_irq_line(0, state ? ASSERT_LINE : CLEAR_LINE); }
// Z80 scanline handler word Loop_SMS (void) { int Interrupt = INT_NONE; tsms.VDP_Line = (tsms.VDP_Line + 1) % g_machine.TV_lines; // Debugger hook #ifdef MEKA_Z80_DEBUGGER if (Debugger.active) Debugger_RasterLine_Hook(tsms.VDP_Line); #endif // Update sound cycle counter0 Sound.CycleCounter += opt.Cur_IPeriod; if (tsms.VDP_Line == 0) { Interrupt_Loop_Misc_Line_Zero(); g_machine.VDP.scroll_x_latched = sms.VDP[8]; g_machine.VDP.scroll_y_latched = sms.VDP[9]; sms.Lines_Left = sms.VDP [10]; } // Screen Refresh if (tsms.VDP_Line >= g_driver->y_show_start && tsms.VDP_Line <= g_driver->y_show_end) { g_machine.VDP.scroll_x_latched_table[tsms.VDP_Line] = g_machine.VDP.scroll_x_latched; if (tsms.VDP_VideoMode > 3) Refresh_Line_5(); g_machine.VDP.scroll_x_latched = sms.VDP[8]; if (g_driver->vdp == VDP_TMS9918) Check_Sprites_Collision_Modes_1_2_3_Line (tsms.VDP_Line); if (tsms.VDP_Line == g_driver->y_show_end) { //if (g_driver->vdp == VDP_TMS) // Check_Sprites_Collision_Modes_1_2_3(); // Msg(MSGT_DEBUG, "Loop_SMS: Video_RefreshScreen()"); Video_RefreshScreen(); if ((opt.Force_Quit) || (CPU_Loop_Stop)) Macro_Stop_CPU; } } if (tsms.VDP_Line <= g_driver->y_int) { if (sms.Lines_Left -- <= 0) { sms.Lines_Left = sms.VDP [10]; sms.Pending_HBlank = TRUE; #ifdef DEBUG_VDP Msg(MSGT_DEBUG, "%d @ Lines_Left == 0, HBlank == %d, Reloading VDP[10] = %d", tsms.VDP_Line, (HBlank_ON) ? 1 : 0, sms.VDP [10]); #endif } if ((sms.Pending_HBlank) && (HBlank_ON)) Interrupt = INT_IRQ; } else #if 1 { // -------------------------------------------------------------------------- // New interrupt code // -------------------------------------------------------------------------- // FIXME: Needless to say, this is vastly incorrect but has given pretty // good result so far. // -------------------------------------------------------------------------- if (tsms.VDP_Line == g_driver->y_int + 1) sms.VDP_Status |= VDP_STATUS_VBlank; else if (tsms.VDP_Line > g_driver->y_int && tsms.VDP_Line <= (g_driver->y_int + 32) && (sms.VDP_Status & VDP_STATUS_VBlank) && (VBlank_ON)) Interrupt = INT_IRQ; else if (tsms.VDP_Line == g_driver->y_int + 33) // Interruption duration. Isn't that scary-lame? Interrupt_Loop_Misc; } #else // -------------------------------------------------------------------------- // Original interrupt code // -------------------------------------------------------------------------- { if (tsms.VDP_Line == 193) sms.VDP_Status |= VDP_STATUS_VBlank; else if (tsms.VDP_Line <= 224 && (sms.VDP_Status & 0x80) && (VBlank_ON)) Interrupt = INT_IRQ; else if (tsms.VDP_Line == 225) Interrupt_Loop_Misc; } #endif // ---------------------------------------------------------------------------- if (Interrupt == INT_IRQ) { #ifdef MARAT_Z80 sms.R.IRequest = INT_IRQ; #elif MAME_Z80 z80_set_irq_line (0, ASSERT_LINE); #endif } return (Interrupt); }
void sms_z80_clear_irq(void) { CrabZ80_clear_irq(cpuz80); z80_set_irq_line(1, 0); }
void sms_z80_nmi(void) { CrabZ80_pulse_nmi(cpuz80); z80_set_irq_line(INPUT_LINE_NMI, 1); }
void sms_z80_assert_irq(void) { CrabZ80_assert_irq(cpuz80, 0xFFFFFFFF); z80_set_irq_line(1, 1); }
static void timer_tick(qsf_synth_t *s) { z80_set_irq_line(s->z80, 0, ASSERT_LINE); z80_set_irq_line(s->z80, 0, CLEAR_LINE); }
word Loop_SG1000_SC3000 (void) { int Interrupt = INT_NONE; // Update sound cycle counter Sound.CycleCounter += opt.Cur_IPeriod; tsms.VDP_Line = (tsms.VDP_Line + 1) % g_machine.TV_lines; // Debugger hook #ifdef MEKA_Z80_DEBUGGER if (Debugger.active) Debugger_RasterLine_Hook(tsms.VDP_Line); #endif if (tsms.VDP_Line == 0) { Interrupt_Loop_Misc; Interrupt_Loop_Misc_Line_Zero(); } if (tsms.VDP_Line >= 0 && tsms.VDP_Line < 192) { // Skip collision check if the sprite collision flag is already set if (!(sms.VDP_Status & VDP_STATUS_SpriteCollision)) Check_Sprites_Collision_Modes_1_2_3_Line (tsms.VDP_Line); } if (tsms.VDP_Line == 192) { if (fskipper.Show_Current_Frame) { // Msg(MSGT_DEBUG, "Loop_SG1000_SC3000: Refresh_Modes_0_1_2_3()"); Refresh_Modes_0_1_2_3(); } sms.VDP_Status |= VDP_STATUS_VBlank; //if (!(sms.VDP_Status & VDP_STATUS_SpriteCollision)) // Check_Sprites_Collision_Modes_1_2_3(); // Note: refresh screen may reset the system, so you can NOT change // the status AFTER it, or else it would screw the newly emulated code // Msg(MSGT_DEBUG, "Loop_SG1000_SC3000: Video_RefreshScreen()"); Video_RefreshScreen(); if ((opt.Force_Quit) || (CPU_Loop_Stop)) Macro_Stop_CPU; } if ((VBlank_ON) /* && (sms.VDP_Access_Mode == VDP_Access_Mode_1) */ && (sms.VDP_Status & VDP_STATUS_VBlank)) { Interrupt = INT_IRQ; // Msg(MSGT_DEBUG, "At PC=%04X: V-Blank", CPU_GetPC); } if (Interrupt == INT_IRQ) { #ifdef MARAT_Z80 sms.R.IRequest = Interrupt; #elif MAME_Z80 z80_set_irq_line (0, ASSERT_LINE); #endif } else // Note: NMI should have the priority over standard Interrupts (by definition) // but this behavior is weird to emulate, and should not to be needed in the // case we are using CPU_ForceNMI now. if (CPU_ForceNMI) { CPU_ForceNMI = FALSE; sms.R.IRequest = Interrupt; return (INT_NMI); } return (Interrupt); }
static void timer_tick(void) { z80_set_irq_line(0, ASSERT_LINE); z80_set_irq_line(0, CLEAR_LINE); }
// 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 }