|
Xemu [doxygen]
hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
|
Go to the documentation of this file.
52 #define INITIAL_WINDOW_WIDTH 705
53 #define INITIAL_WINDOW_HEIGHT 576
59 static int emulation_is_running = 0;
60 static int speed_current = -1;
61 static int paused = 0, paused_old = 0;
62 static int breakpoint_pc = -1;
63 #ifdef TRACE_NEXT_SUPPORT
64 static int orig_sp = 0;
65 static int trace_next_trigger = 0;
67 static int trace_step_trigger = 0;
68 #ifdef HAS_UARTMON_SUPPORT
69 static void (*m65mon_callback)(void) = NULL;
71 static const char emulator_paused_title[] =
"TRACE/PAUSE";
73 static char fast_mhz_in_string[16] =
"";
74 static const char *cpu_clock_speed_strs[4] = {
"1MHz",
"2MHz",
"3.5MHz", fast_mhz_in_string };
76 static unsigned int cpu_clock_speed_str_index = 0;
81 static int uuid_must_be_saved = 0;
93 FATAL(
"Internal error: 6502 NMOS persona is not supported yet.");
98 #define C128_SPEED_BIT_BUG 0
116 DEBUGPRINT(
"SPEED: in_hypervisor=%d force_fast=%d c128_fast=%d, c65_fast=%d m65_fast=%d" NL,
123 speed_current = speed_wanted;
125 switch (speed_wanted) {
130 cpu_clock_speed_str_index = 0;
135 cpu_clock_speed_str_index = 1;
141 cpu_clock_speed_str_index = 2;
148 cpu_clock_speed_str_index = 3;
160 static void cia1_setint_cb (
int level )
162 DEBUG(
"%s: IRQ level changed to %d" NL, cia1.name, level);
166 cpu65.irqLevel &= ~1;
170 static inline void nmi_set (
int level,
int mask )
182 nmi_new_level = nmi_level |
mask;
184 nmi_new_level = nmi_level & (~
mask);
185 if ((!nmi_level) && nmi_new_level) {
186 DEBUG(
"NMI edge is emulated towards the CPU (%d->%d)" NL, nmi_level, nmi_new_level);
189 nmi_level = nmi_new_level;
193 static void cia2_setint_cb (
int level )
208 DEBUG(
"VIC2: 16K BANK is set to $%04X (CIA mask=$%02X)" NL, vic2_16k_bank,
cia2.
DDRA);
224 static Uint8 cia2_in_a (
void )
236 static Uint8 cia2_in_b (
void )
248 #ifdef XEMU_SNAPSHOT_SUPPORT
249 static void m65_snapshot_saver_on_exit_callback (
void )
261 static int preinit_memory_item (
const char *
name,
const char *desc,
Uint8 *target_ptr,
const Uint8 *source_ptr,
const int source_size,
const int min_size,
const int max_size,
const char *
fn )
263 if (source_size < min_size || source_size > max_size || min_size > max_size)
264 FATAL(
"MEMCONTENT: internal error, memcontent item \"%s\" (%s) given size (%d) is outside of interval %d...%d",
name, desc, source_size, min_size, max_size);
265 memset(target_ptr, 0, max_size);
269 DEBUGPRINT(
"MEMCONTENT: \"%s\" (%s) was not requested, using the built-in ($%X bytes) [%s]." NL,
name, desc, source_size, hash_str);
279 DEBUGPRINT(
"MEMCONTENT: \"%s\" (%s) **FAILED** to load custom file (using default - $%X bytes [%s]) by filename request: %s" NL,
name, desc, source_size, hash_str,
fn);
281 memcpy(target_ptr, source_ptr, source_size);
286 static void preinit_memory_for_start (
void )
293 static const Uint8 megaflashutility[] = {
294 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
295 0xA9, 0x00, 0x8D, 0x00, 0x00, 0xA9, 0x47, 0x8D, 0x2F, 0xD0, 0xA9, 0x53, 0x8D, 0x2F, 0xD0, 0xA9,
296 0x4C, 0x8D, 0x7F, 0xCF, 0x4C, 0x7F, 0xCF
303 preinit_memory_item(
"extflashutil",
"MEGA-flash utility",
main_ram + 0x50000, megaflashutility,
sizeof megaflashutility, 0x00020, 0x07D00,
configdb.
extflashutil);
315 static void mega65_init (
void )
327 #ifdef HID_KBD_MAP_CFG_SUPPORT
336 FATAL(
"Too many FPGA switches specified for option 'fpga'");
339 if (switches[
r] < 0 || switches[
r] > 15)
340 FATAL(
"Invalid switch sepcifictation for option 'fpga': %d", switches[
r]);
355 memset(nvram_original, 0xAA,
sizeof nvram);
362 uuid_must_be_saved = 1;
365 preinit_memory_for_start();
372 static const char default_d81_fn[] =
"default.d81";
378 DEBUGPRINT(
"DISK: using external default disk image, since without -8 we found: %s" NL,
fn);
381 ERROR_WINDOW(
"Found: %s\nfor default external disk image,\nbut it has wrong size",
fn);
390 FATAL(
"Cannot find SD-card image (which is a must for MEGA65 emulation): %s",
configdb.
sdimg);
421 #ifdef HAS_UARTMON_SUPPORT
426 cpu65_init_mega_specific();
434 DEBUG(
"INIT: end of initialization!" NL);
435 #ifdef XEMU_SNAPSHOT_SUPPORT
436 xemusnap_init(m65_snapshot_definition);
441 atexit(m65_snapshot_saver_on_exit_callback);
457 static void shutdown_callback (
void )
460 if (memcmp(
nvram, nvram_original,
sizeof(
nvram))) {
464 if (uuid_must_be_saved) {
465 uuid_must_be_saved = 0;
470 for (
int a = 0; a < 0x40; a++)
471 DEBUG(
"VIC-3 register $%02X is %02X" NL, a, vic_registers[a]);
474 #if !defined(XEMU_ARCH_HTML)
477 #ifdef HAS_UARTMON_SUPPORT
480 #ifdef HAVE_XEMU_UMON
483 #ifdef XEMU_HAS_SOCKET_API
487 if (emulation_is_running)
494 static const char reset_debug_msg[] =
"SYSTEM: RESET - ";
497 memset(
D7XX + 0x20, 0, 0x40);
499 preinit_memory_for_start();
547 #ifdef HAS_UARTMON_SUPPORT
552 "PC A X Y Z B SP MAPL MAPH LAST-OP P P-FLAGS RGP uS IO\r\n"
553 "%04X %02X %02X %02X %02X %02X %04X "
554 "%04X %04X %02X %02X %02X "
556 cpu65.pc, cpu65.a, cpu65.x, cpu65.y, cpu65.z, cpu65.bphi >> 8, cpu65.sphi | cpu65.s,
557 map_offset_low >> 8, map_offset_high >> 8, cpu65.op,
573 umon_printf(
":000%04X:",
addr);
582 umon_printf(
":%07X:",
addr);
589 for (
int k = 0; k < cnt; k++)
600 #ifdef TRACE_NEXT_SUPPORT
601 void m65mon_do_next (
void )
606 trace_next_trigger = 2;
607 orig_sp = cpu65.sphi | cpu65.s;
610 umon_printf(UMON_SYNTAX_ERROR
"trace can be used only in trace mode");
620 trace_step_trigger = 1;
622 umon_printf(UMON_SYNTAX_ERROR
"trace can be used only in trace mode");
628 umon_printf(UMON_SYNTAX_ERROR
"command 'tc' is not implemented yet");
630 #ifdef TRACE_NEXT_SUPPORT
631 void m65mon_next_command (
void )
654 static void update_emulator (
void )
661 strcpy(emulator_speed_title, cpu_clock_speed_strs[cpu_clock_speed_str_index]);
662 strcat(emulator_speed_title,
" ");
670 #ifdef HAS_UARTMON_SUPPORT
685 rtc_regs[0] = XEMU_BYTE_TO_BCD(t->tm_sec);
686 rtc_regs[1] = XEMU_BYTE_TO_BCD(t->tm_min);
689 rtc_regs[3] = XEMU_BYTE_TO_BCD(t->tm_mday);
690 rtc_regs[4] = XEMU_BYTE_TO_BCD(t->tm_mon) + 1;
691 rtc_regs[5] = XEMU_BYTE_TO_BCD(t->tm_year - 100);
696 static void emulation_loop (
void )
698 static int cycles = 0;
707 #ifdef TRACE_NEXT_SUPPORT
708 if (trace_next_trigger == 2) {
709 if (cpu65.op == 0x20) {
710 trace_next_trigger = 1;
712 trace_next_trigger = 0;
715 }
else if (trace_next_trigger == 1) {
716 if ((cpu65.sphi | cpu65.s) == orig_sp ) {
717 trace_next_trigger = 0;
725 #ifdef HAS_UARTMON_SUPPORT
726 if (m65mon_callback) {
728 m65mon_callback = NULL;
729 uartmon_finish_command();
737 if (trace_step_trigger) {
740 trace_step_trigger = 0;
747 if (paused != paused_old) {
750 DEBUGPRINT(
"TRACE: entering into trace mode @ $%04X" NL, cpu65.pc);
753 DEBUGPRINT(
"TRACE: leaving trace mode @ $%04X" NL, cpu65.pc);
754 if (breakpoint_pc < 0)
764 DEBUGPRINT(
"TRACE: Breakpoint @ $%04X hit, Xemu moves to trace mode after the execution of this opcode." NL, cpu65.pc);
772 if (cycles >= cpu_cycles_per_scanline) {
784 int main (
int argc,
char **argv )
792 #ifdef HAVE_XEMU_INSTALLER
793 xemu_set_installer(
configdb.installer);
797 DEBUGPRINT(
"WARNING: *** NEW M65 HACK MODE ACTIVATED ***" NL);
839 #ifdef HAVE_XEMU_UMON
846 #ifdef FAKE_TYPING_SUPPORT
849 c64_register_fake_typing(fake_typing_for_load64);
851 c64_register_fake_typing(fake_typing_for_go64);
853 c64_register_fake_typing(fake_typing_for_load65);
864 emulation_is_running = 1;
872 #ifdef XEMU_SNAPSHOT_SUPPORT
876 #define SNAPSHOT_M65_BLOCK_VERSION 2
877 #define SNAPSHOT_M65_BLOCK_SIZE (0x100 + sizeof(D6XX_registers) + sizeof(D7XX))
880 int m65emu_snapshot_load_state (
const struct xemu_snapshot_definition_st *def,
struct xemu_snapshot_block_st *
block )
882 Uint8 buffer[SNAPSHOT_M65_BLOCK_SIZE];
884 if (
block->block_version != SNAPSHOT_M65_BLOCK_VERSION ||
block->sub_counter ||
block->sub_size !=
sizeof buffer)
885 RETURN_XSNAPERR_USER(
"Bad M65 block syntax");
886 a = xemusnap_read_file(buffer,
sizeof buffer);
890 memcpy(
D7XX, buffer + 0x200,
sizeof D7XX);
895 map_mask = (int)P_AS_BE32(buffer + 0);
898 cpu65.cpu_inhibit_interrupts = (int)P_AS_BE32(buffer + 12);
909 int m65emu_snapshot_save_state (
const struct xemu_snapshot_definition_st *def )
911 Uint8 buffer[SNAPSHOT_M65_BLOCK_SIZE];
912 int a = xemusnap_write_block_header(def->idstr, SNAPSHOT_M65_BLOCK_VERSION);
914 memset(buffer, 0xFF,
sizeof buffer);
916 U32_AS_BE(buffer + 0, map_mask);
917 U32_AS_BE(buffer + 4, map_offset_low);
918 U32_AS_BE(buffer + 8, map_offset_high);
919 U32_AS_BE(buffer + 12, cpu65.cpu_inhibit_interrupts);
928 memcpy(buffer + 0x200,
D7XX,
sizeof D7XX);
929 return xemusnap_write_sub_block(buffer,
sizeof buffer);
933 int m65emu_snapshot_loading_finalize (
const struct xemu_snapshot_definition_st *def,
struct xemu_snapshot_block_st *
block )
935 DEBUGPRINT(
"SNAP: loaded (finalize-callback: begin)" NL);
941 OSD(-1, -1,
"Snapshot has been loaded.");
void inject_ready_check_do(void)
#define USE_LOCKED_TEXTURE
void reset_mega65_cpu_only(void)
void m65mon_do_trace_c(void)
void cia_ugly_tod_updater(struct Cia6526 *cia, const struct tm *t, Uint8 sec10, int hour_offset)
void machine_set_speed(int verbose)
void vic_init(Uint8 **lo8_pointers, Uint8 **hi4_pointers)
#define MEMINITDATA_CHRWOM_SIZE
int sdcard_force_external_mount(const int unit, const char *filename, const char *cry)
void audio65_init(int sid_cycles_per_sec, int sound_mix_freq, int volume, int separation, unsigned int buffer_size)
#define MEMINITDATA_FREEZER_SIZE
float videostd_1mhz_cycles_per_scanline
int cpu_cycles_per_scanline
#define MEMINITDATA_ONBOARD_SIZE
void hypervisor_hdos_close_descriptors(void)
int hypervisor_debug_init(const char *fn, int hypervisor_debug, int use_hypervisor_serial_out_asciizer)
void m65mon_dumpmem16(Uint16 addr)
void cpu65_illegal_opcode_callback(void)
const struct KeyMappingDefault c64_key_map[]
void memory_set_vic3_rom_mapping(Uint8 value)
Uint8 hypervisor_ram[0x4000]
int rom_load_custom(const char *fn)
const Uint8 meminitdata_hickup[MEMINITDATA_HICKUP_SIZE]
void m65mon_show_regs(void)
int vic4_render_scanline(void)
void vic4_open_frame_access(void)
void m65mon_breakpoint(int brk)
const char * videostd_name
const Uint8 meminitdata_freezer[MEMINITDATA_FREEZER_SIZE]
void m65mon_setmem28(int addr, int cnt, Uint8 *vals)
void io_write(int addr, Uint8 data)
Uint8 memory_debug_read_phys_addr(int addr)
int osd_init_with_defaults(void)
int rom_initrom_requested
int memory_cpurd2linear_xlat(Uint16 cpu_addr)
void cia_tick(struct Cia6526 *cia, int ticks)
#define MEMINITDATA_BANNER_SIZE
int rom_from_prefdir_allowed
int inject_ready_check_status
const Uint8 meminitdata_cramutils[MEMINITDATA_CRAMUTILS_SIZE]
void configdb_define_emulator_options(void)
const char * cpu_clock_speed_string
#define MEMINITDATA_HICKUP_SIZE
Uint8 memory_get_cpu_io_port(int addr)
void m65mon_set_trace(int m)
void vic4_close_frame_access(void)
void m65mon_empty_command(void)
#define VIRTUAL_SHIFT_POS
#define ERROR_WINDOW(...)
void rom_clear_reports(void)
int sdcard_init(const char *fn, const int virtsd_flag, const int default_d81_is_from_sd_in)
void memory_set_do_map(void)
void hypervisor_debug_invalidate(const char *reason)
int eth65_init(const char *options)
struct configdb_st configdb
#define SID_CYCLES_PER_SEC
void m65mon_dumpmem28(int addr)
#define DMA_FEATURE_DYNMODESET
char emulator_speed_title[]
Uint8 cpu65_read_callback(Uint16 addr)
int rom_stubrom_requested
#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))
const Uint8 meminitdata_onboard[MEMINITDATA_ONBOARD_SIZE]
void hypervisor_debug(void)
int dma_update_multi_steps(int do_for_cycles)
void cia_dump_state(struct Cia6526 *cia)
int main(int argc, char **argv)
void m65mon_do_trace(void)
Uint8 D6XX_registers[0x100]
int hypervisor_is_debugged
int reset_mega65_asked(void)
const Uint8 meminitdata_banner[MEMINITDATA_BANNER_SIZE]
int inject_register_prg(const char *prg_fn, int prg_mode)
void memory_debug_write_phys_addr(int addr, Uint8 data)
void dma_init(unsigned int revision)
void audio65_sid_inc_framecount(void)
int dump_memory(const char *fn)
#define AUDIO_SAMPLE_FREQ
const Uint8 meminitdata_chrwom[MEMINITDATA_CHRWOM_SIZE]
void hypervisor_start_machine(void)
#define INITIAL_WINDOW_HEIGHT
const Uint8 meminitdata_initrom[MEMINITDATA_INITROM_SIZE]
void eth65_shutdown(void)
const char * last_reset_type
#define MEMINITDATA_CRAMUTILS_SIZE
#define IS_RESTORE_PRESSED()
#define MEMINITDATA_INITROM_SIZE
Uint8 vic_registers[0x80]
int registered_screenshot_request
#define C128_SPEED_BIT_BUG
#define INITIAL_WINDOW_WIDTH
void memory_set_cpu_io_port_ddr_and_data(Uint8 p0, Uint8 p1)