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; }
void Z80_reset(void) { ResetZ80(&Z80_regs); Z80_regs.SP.W = 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); }
void cal_maratz80_reset(cal_cpu cpu) { ResetZ80(cpu->data.d_maratz80); }
// 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 }