|
Xemu [doxygen]
hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
|
Go to the documentation of this file.
41 static SDL_AudioDeviceID audio = 0;
47 static int mouse_x = 0;
48 static int mouse_y = 0;
49 static int shift_status = 0;
60 #define IO_REMAP_VIRTUAL 0x110000
63 #define ROM_C000_REMAP 0x20000
64 #define ROM_8000_REMAP 0x30000
65 #define ROM_A000_REMAP 0x30000
66 #define ROM_E000_REMAP 0x30000
68 #define ROM_C64_CHR_REMAP 0x20000
69 #define ROM_C64_KERNAL_REMAP 0x20000
70 #define ROM_C64_BASIC_REMAP 0x20000
72 static int addr_trans_rd[16];
73 static int addr_trans_wr[16];
75 static int map_offset_low;
76 static int map_offset_high;
101 addr_trans_wr[0] = addr_trans_rd[0] = addr_trans_wr[1] = addr_trans_rd[1] = (map_mask & 1) ? map_offset_low : 0;
102 addr_trans_wr[2] = addr_trans_rd[2] = addr_trans_wr[3] = addr_trans_rd[3] = (map_mask & 2) ? map_offset_low : 0;
103 addr_trans_wr[4] = addr_trans_rd[4] = addr_trans_wr[5] = addr_trans_rd[5] = (map_mask & 4) ? map_offset_low : 0;
104 addr_trans_wr[6] = addr_trans_rd[6] = addr_trans_wr[7] = addr_trans_rd[7] = (map_mask & 8) ? map_offset_low : 0;
108 addr_trans_wr[8] = addr_trans_rd[8] = addr_trans_wr[9] = addr_trans_rd[9] =
ROM_8000_REMAP;
109 else if (map_mask & 16)
110 addr_trans_wr[8] = addr_trans_rd[8] = addr_trans_wr[9] = addr_trans_rd[9] = map_offset_high;
112 addr_trans_wr[8] = addr_trans_rd[8] = addr_trans_wr[9] = addr_trans_rd[9] = 0;
115 addr_trans_wr[0xA] = addr_trans_rd[0xA] = addr_trans_wr[0xB] = addr_trans_rd[0xB] =
ROM_A000_REMAP;
116 else if ((map_mask & 32))
117 addr_trans_wr[0xA] = addr_trans_rd[0xA] = addr_trans_wr[0xB] = addr_trans_rd[0xB] = map_offset_high;
119 addr_trans_wr[0xA] = addr_trans_wr[0xB] = 0;
127 addr_trans_wr[0xC] = addr_trans_rd[0xC] = (map_mask & 64) ? map_offset_high : 0;
130 addr_trans_wr[0xD] = addr_trans_rd[0xD] = map_offset_high;
135 addr_trans_wr[0xD] = 0;
141 addr_trans_wr[0xE] = addr_trans_rd[0xE] = addr_trans_wr[0xF] = addr_trans_rd[0xF] =
ROM_E000_REMAP;
142 else if (map_mask & 128)
143 addr_trans_wr[0xE] = addr_trans_rd[0xE] = addr_trans_wr[0xF] = addr_trans_rd[0xF] = map_offset_high;
145 addr_trans_wr[0xE] = addr_trans_wr[0xF] = 0;
152 static void cia1_setint_cb (
int level )
154 DEBUG(
"%s: IRQ level changed to %d" NL, cia1.name, level);
158 cpu65.irqLevel &= ~1;
162 static inline void nmi_set (
int level,
int mask )
174 nmi_new_level = nmi_level |
mask;
176 nmi_new_level = nmi_level & (~
mask);
177 if ((!nmi_level) && nmi_new_level) {
178 DEBUG(
"NMI edge is emulated towards the CPU (%d->%d)" NL, nmi_level, nmi_new_level);
181 nmi_level = nmi_new_level;
186 static void cia2_setint_cb (
int level )
199 static Uint8 port_d607 = 0xFF;
202 static Uint8 cia1_in_b (
void )
204 #ifdef FAKE_TYPING_SUPPORT
205 if (
XEMU_UNLIKELY(c64_fake_typing_enabled) && (((cia1.PRA | (~cia1.DDRA)) & 0xFF) != 0xFF) && (((cia1.PRB | (~cia1.DDRB)) & 0xFF) == 0xFF))
206 c64_handle_fake_typing_internals(cia1.PRA | (~cia1.DDRA));
208 return c64_keyboard_read_on_CIA1_B(
209 cia1.PRA | (~cia1.DDRA),
210 cia1.PRB | (~cia1.DDRB),
216 static Uint8 cia1_in_a (
void )
218 return c64_keyboard_read_on_CIA1_A(
219 cia1.PRB | (~cia1.DDRB),
220 cia1.PRA | (~cia1.DDRA),
234 static Uint8 cia2_in_a (
void )
246 static Uint8 cia2_in_b (
void )
258 static void audio_callback(
void *userdata,
Uint8 *
stream,
int len)
260 DEBUG(
"AUDIO: audio callback, wants %d samples" NL, len);
268 #ifdef XEMU_SNAPSHOT_SUPPORT
269 static void c65_snapshot_saver_on_exit_callback (
void )
286 DEBUGPRINT(
"C65FDC: configuring F011 FDC (#%d) with have_disk=%d, can_write=%d" NL, which,
have_disk, can_write);
293 DEBUG(
"SDCARD: D81: reading sector at d81_pos=(%d,%d,%d), return value=%d" NL, side, track, sector, ret);
299 DEBUG(
"SDCARD: D81: writing sector at d81_pos=(%d,%d,%d), return value=%d" NL, side, track, sector, ret);
315 static void c65_init (
int sid_cycles_per_sec,
int sound_mix_freq )
318 SDL_AudioSpec audio_want, audio_got;
324 #ifdef HID_KBD_MAP_CFG_SUPPORT
376 SDL_memset(&audio_want, 0,
sizeof(audio_want));
377 audio_want.freq = sound_mix_freq;
378 audio_want.format = AUDIO_S16SYS;
379 audio_want.channels = 2;
380 audio_want.samples = 1024;
381 audio_want.callback = audio_callback;
382 audio_want.userdata = NULL;
383 audio = SDL_OpenAudioDevice(NULL, 0, &audio_want, &audio_got, 0);
386 for (i = 0; i < SDL_GetNumAudioDevices(0); i++)
387 DEBUG(
"AUDIO: audio device is #%d: %s" NL, i, SDL_GetAudioDeviceName(i, 0));
389 if (audio_want.freq != audio_got.freq || audio_want.format != audio_got.format || audio_want.channels != audio_got.channels) {
390 SDL_CloseAudioDevice(audio);
394 DEBUG(
"AUDIO: initialized (#%d), %d Hz, %d channels, %d buffer sample size." NL, audio, audio_got.freq, audio_got.channels, audio_got.samples);
399 DEBUG(
"INIT: end of initialization!" NL);
401 #ifdef XEMU_SNAPSHOT_SUPPORT
402 xemusnap_init(c65_snapshot_definition);
407 atexit(c65_snapshot_saver_on_exit_callback);
420 cpu65.cpu_inhibit_interrupts = 1;
421 DEBUG(
"CPU: MAP opcode, input A=$%02X X=$%02X Y=$%02X Z=$%02X" NL, cpu65.a, cpu65.x, cpu65.y, cpu65.z);
422 map_offset_low = (cpu65.a << 8) | ((cpu65.x & 15) << 16);
423 map_offset_high = (cpu65.y << 8) | ((cpu65.z & 15) << 16);
424 map_mask = (cpu65.z & 0xF0) | (cpu65.x >> 4);
425 DEBUG(
"MEM: applying new memory configuration because of MAP CPU opcode" NL);
426 DEBUG(
"LOW -OFFSET = $%X" NL, map_offset_low);
427 DEBUG(
"HIGH-OFFSET = $%X" NL, map_offset_high);
428 DEBUG(
"MASK = $%02X" NL, map_mask);
436 if (cpu65.cpu_inhibit_interrupts) {
437 cpu65.cpu_inhibit_interrupts = 0;
438 DEBUG(
"CPU: EOM, interrupts were disabled because of MAP till the EOM" NL);
440 DEBUG(
"CPU: NOP in not treated as EOM (no MAP before)" NL);
444 static inline Uint8 read_some_sid_register (
int addr )
447 switch (
addr & 0x1F) {
464 static inline void write_some_sid_register (
int addr,
Uint8 data )
467 DEBUG(
"SID%d: writing register $%04X ($%04X) with data $%02X @ PC=$%04X" NL, ((
addr >> 6) & 1) + 1,
addr & 0x1F,
addr + 0xD000,
data, cpu65.pc);
487 return read_some_sid_register(
addr);
518 return read_some_sid_register(
addr);
562 write_some_sid_register(
addr,
data);
614 write_some_sid_register(
addr,
data);
662 DEBUG(
"MEM: applying new memory configuration because of CPU port writing" NL);
671 # ifdef ALLOW_256K_RAMEXP
672 || (
addr >= 0x40000 &&
addr < 0x80000)
688 DEBUG(
"DMA-C65-BACKEND: writing memory above 1Mbyte (addr=$%X,data=%02X) PC=%04X" NL,
addr,
data, cpu65.pc);
703 DEBUG(
"DMA-C65-BACKEND: reading memory above 1Mbyte (addr=$%X) PC=%04X" NL,
addr, cpu65.pc);
713 register int phys_addr = addr_trans_rd[
addr >> 12] +
addr;
715 return memory[phys_addr & 0xFFFFF];
725 register int phys_addr = addr_trans_wr[
addr >> 12] +
addr;
743 int phys_addr = addr_trans_wr[
addr >> 12] +
addr;
747 DEBUG(
"CPU: RMW opcode is used on I/O area for $%04X" NL,
addr);
765 static void shutdown_callback (
void )
768 for (a = 0; a < 0x40; a++)
772 #if !defined(XEMU_ARCH_HTML)
776 DEBUGPRINT(
"VIC3: D011=$%02X D018=$%02X D030=$%02X D031=$%02X" NL,
779 DEBUG(
"Execution has been stopped at PC=$%04X [$%05X]" NL, cpu65.pc, addr_trans_rd[cpu65.pc >> 12] + cpu65.pc);
810 if (key == SDL_SCANCODE_F10) {
812 }
else if (key == SDL_SCANCODE_KP_ENTER) {
814 }
else if (key == SDL_SCANCODE_LSHIFT) {
816 }
else if (key == SDL_SCANCODE_RSHIFT) {
823 if (key == SDL_SCANCODE_LSHIFT) {
825 }
else if (key == SDL_SCANCODE_RSHIFT) {
827 }
else if (pos == -2 && key == 0) {
829 OSD(-1, -1,
"Mouse grab activated. Press\nboth SHIFTs together to cancel.");
832 if (handled == SDL_BUTTON_RIGHT) {
841 #ifdef XEMU_FILES_SCREENSHOT_SUPPORT
843 static inline void do_pending_screenshot (
void )
848 if (!xemu_screenshot_png(
857 const char *p = strrchr(xemu_screenshot_full_path,
DIRSEP_CHR);
859 OSD(-1, -1,
"%s", p + 1);
865 static void update_emulator (
void )
867 #ifdef XEMU_FILES_SCREENSHOT_SUPPORT
870 do_pending_screenshot();
888 static void emulation_loop (
void )
926 int main (
int argc,
char **argv )
959 #ifdef FAKE_TYPING_SUPPORT
962 c64_register_fake_typing(fake_typing_for_load64);
964 c64_register_fake_typing(fake_typing_for_go64);
966 c64_register_fake_typing(fake_typing_for_load65);
970 SDL_PauseAudioDevice(audio, 0);
981 #ifdef XEMU_SNAPSHOT_SUPPORT
985 #define SNAPSHOT_C65_BLOCK_VERSION 0
986 #define SNAPSHOT_C65_BLOCK_SIZE 0x100
989 int c65emu_snapshot_load_state (
const struct xemu_snapshot_definition_st *def,
struct xemu_snapshot_block_st *
block )
991 Uint8 buffer[SNAPSHOT_C65_BLOCK_SIZE];
993 if (
block->block_version != SNAPSHOT_C65_BLOCK_VERSION ||
block->sub_counter ||
block->sub_size !=
sizeof buffer)
994 RETURN_XSNAPERR_USER(
"Bad C65 block syntax");
995 a = xemusnap_read_file(buffer,
sizeof buffer);
998 map_mask = (int)P_AS_BE32(buffer + 0);
999 map_offset_low = (int)P_AS_BE32(buffer + 4);
1000 map_offset_high = (int)P_AS_BE32(buffer + 8);
1001 cpu65.cpu_inhibit_interrupts = (int)P_AS_BE32(buffer + 12);
1006 int c65emu_snapshot_save_state (
const struct xemu_snapshot_definition_st *def )
1008 Uint8 buffer[SNAPSHOT_C65_BLOCK_SIZE];
1009 int a = xemusnap_write_block_header(def->idstr, SNAPSHOT_C65_BLOCK_VERSION);
1011 memset(buffer, 0xFF,
sizeof buffer);
1013 U32_AS_BE(buffer + 0, map_mask);
1014 U32_AS_BE(buffer + 4, map_offset_low);
1015 U32_AS_BE(buffer + 8, map_offset_high);
1016 U32_AS_BE(buffer + 12, cpu65.cpu_inhibit_interrupts);
1017 return xemusnap_write_sub_block(buffer,
sizeof buffer);
1021 int c65emu_snapshot_loading_finalize (
const struct xemu_snapshot_definition_st *def,
struct xemu_snapshot_block_st *
block )
void sid_render(struct SidEmulation *sidemu, short *buffer, unsigned long len, int step)
void d81access_close_all(void)
void inject_ready_check_do(void)
#define USE_LOCKED_TEXTURE
#define ROM_C64_BASIC_REMAP
void dma_init_set_rev(unsigned int revision, Uint8 *rom_ver_signature)
void cia_ugly_tod_updater(struct Cia6526 *cia, const struct tm *t, Uint8 sec10, int hour_offset)
Uint8 cia_read(struct Cia6526 *cia, int addr)
Uint8 hostfs_read_reg1(void)
#define D81ACCESS_AUTOCLOSE
Uint8 fdc_read_reg(int addr)
void fdc_set_disk(int which, int in_have_disk, int in_have_write)
int d81access_read_sect(const int which, Uint8 *buffer, const Uint8 side, const Uint8 track, const Uint8 sector, const int sector_size)
int d81access_write_sect(const int which, Uint8 *buffer, const Uint8 side, const Uint8 track, const Uint8 sector, const int sector_size)
Uint8 read_phys_mem(int addr)
int fdc_cb_wr_sec(const int which, Uint8 *buffer, const Uint8 side, const Uint8 track, const Uint8 sector)
int cpu_cycles_per_scanline
char current_rom_filepath[PATH_MAX]
const struct KeyMappingDefault c64_key_map[]
int register_screenshot_request
void hostfs_init(const char *basedir, const char *subdir)
int c65_reset_asked(void)
void d81access_init(void)
int emu_callback_key(int pos, SDL_Scancode key, int pressed, int handled)
void cpu65_write_callback(Uint16 addr, Uint8 data)
void io_write(int addr, Uint8 data)
void write_phys_mem_for_dma(int addr, Uint8 data)
int osd_init_with_defaults(void)
#define ROM_C64_CHR_REMAP
void cia_tick(struct Cia6526 *cia, int ticks)
int d81access_attach_fsobj(int which, const char *fn, int mode)
int inject_ready_check_status
void c64_toggle_joy_emu(void)
void configdb_define_emulator_options(void)
Uint8 read_phys_mem_for_dma(int addr)
void cpu65_do_nop_callback(void)
void vic3_write_palette_reg(int num, Uint8 data)
void cpu65_write_rmw_callback(Uint16 addr, Uint8 old_data, Uint8 new_data)
#define VIRTUAL_SHIFT_POS
Uint8 vic3_registers[0x80]
int dump_memory(const char *fn)
Uint8 c64_get_joy_state(void)
#define ERROR_WINDOW(...)
void d81access_cb_chgmode(const int which, const int mode)
int main(int argc, char **argv)
void hostfs_write_reg1(Uint8 data)
int vic3_render_scanline(void)
struct configdb_st configdb
void fdc_write_reg(int addr, Uint8 data)
int fdc_cb_rd_sec(const int which, Uint8 *buffer, const Uint8 side, const Uint8 track, const Uint8 sector)
#define ROM_C64_KERNAL_REMAP
#define SID_CYCLES_PER_SEC
void dma_write_reg(int addr, Uint8 data)
void write_phys_mem(int addr, Uint8 data)
char emulator_speed_title[]
void sid_write_reg(struct SidEmulation *sidemu, int reg, unsigned char val)
Uint8 cpu65_read_callback(Uint16 addr)
#define CPU_STEP_MULTI_OPS
void cia_init(struct Cia6526 *cia, const char *name, void(*outa)(Uint8 data), void(*outb)(Uint8 data), void(*outsr)(Uint8 data), Uint8(*ina)(void), Uint8(*inb)(void), Uint8(*insr)(void), void(*setint)(int level))
void apply_memory_config(void)
int dma_update_multi_steps(int do_for_cycles)
void fdc_init(Uint8 *cache_set)
Uint8 vic3_read_reg(int addr)
void cia_dump_state(struct Cia6526 *cia)
void vic3_select_bank(int bank)
void hostfs_flush_all(void)
Uint8 dma_read_reg(int addr)
void clear_emu_events(void)
void hostfs_write_reg0(Uint8 data)
Uint8 hostfs_read_reg0(void)
int inject_register_prg(const char *prg_fn, int prg_mode)
void dma_init(unsigned int revision)
void vic3_open_frame_access(void)
void sid_init(struct SidEmulation *sidemu, unsigned long cyclesPerSec, unsigned long mixfrq)
#define AUDIO_SAMPLE_FREQ
void cpu65_do_aug_callback(void)
int c65_load_rom(const char *fn, unsigned int dma_rev)
struct SidEmulation sids[2]
#define ALLOW_512K_RAMEXP
char scanline_render_debug_info[320]
#define IS_RESTORE_PRESSED()
void vic3_write_reg(int addr, Uint8 data)
void vic3_check_raster_interrupt(void)
void cia_write(struct Cia6526 *cia, int addr, Uint8 data)