Xemu [doxygen]  hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
mega65.c
Go to the documentation of this file.
1 /* A work-in-progess MEGA65 (Commodore 65 clone origins) emulator
2  Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
3  Copyright (C)2016-2022 LGB (Gábor Lénárt) <lgblgblgb@gmail.com>
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18 
19 
20 #include "xemu/emutools.h"
21 #include "xemu/emutools_files.h"
22 #include "mega65.h"
23 #include "xemu/cpu65.h"
24 #include "dma65.h"
25 #include "xemu/emutools_hid.h"
26 #include "vic4.h"
27 #include "sdcard.h"
28 #include "uart_monitor.h"
29 #include "hypervisor.h"
30 #include "xemu/c64_kbd_mapping.h"
31 #include "xemu/emutools_config.h"
32 #include "xemu/emutools_umon.h"
33 #include "m65_snapshot.h"
34 #include "memory_mapper.h"
35 #include "io_mapper.h"
36 #include "ethernet65.h"
37 #include "input_devices.h"
38 #include "memcontent.h"
39 #include "xemu/emutools_gui.h"
40 #include "audio65.h"
41 #include "inject.h"
42 #include "configdb.h"
44 #include "rom.h"
45 
46 // "Typical" size in default settings (video standard is PAL, default border settings).
47 // See also vic4.h
48 // It's just here to give an initial window size. Though if it's not the same what
49 // hyppo/ROM will set, then soon you see a resize event which is kinda "ugly" for a
50 // second. Thus I try to setup some typical value which is the final result in most
51 // cases.
52 #define INITIAL_WINDOW_WIDTH 705
53 #define INITIAL_WINDOW_HEIGHT 576
54 
55 static int nmi_level; // please read the comment at nmi_set() below
56 
57 int newhack = 0;
58 
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;
66 #endif
67 static int trace_step_trigger = 0;
68 #ifdef HAS_UARTMON_SUPPORT
69 static void (*m65mon_callback)(void) = NULL;
70 #endif
71 static const char emulator_paused_title[] = "TRACE/PAUSE";
72 static char emulator_speed_title[64] = "";
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 };
75 const char *cpu_clock_speed_string = "";
76 static unsigned int cpu_clock_speed_str_index = 0;
77 static unsigned int cpu_cycles_per_scanline;
78 int cpu_cycles_per_step = 100; // some init value, will be overriden, but it must be greater initially than "only a few" anyway
79 
80 static Uint8 nvram_original[sizeof nvram];
81 static int uuid_must_be_saved = 0;
82 
84 
85 Uint8 last_dd00_bits = 3; // Bank 0
86 const char *last_reset_type;
87 
88 
89 
91 {
92  // FIXME: implement this, it won't be ever seen now, as not even switch to 6502 NMOS persona is done yet ...
93  FATAL("Internal error: 6502 NMOS persona is not supported yet.");
94 }
95 
96 
97 //#define C128_SPEED_BIT_BUG 1
98 #define C128_SPEED_BIT_BUG 0
99 
100 
101 void machine_set_speed ( int verbose )
102 {
103  int speed_wanted;
104  // Actually the rule would be something like that (this comment is here by intent, for later implementation FIXME TODO), some VHDL draft only:
105  // cpu_speed := vicii_2mhz&viciii_fast&viciv_fast
106  // if hypervisor_mode='0' and ((speed_gate='1') and (force_fast='0')) then -- LGB: vicii_2mhz seems to be a low-active signal?
107  // case cpu_speed is ...... 100=1MHz, 101=1MHz, 110=3.5MHz, 111=50Mhz, 000=2MHz, 001=50MHz, 010=3.5MHz, 011=50MHz
108  // else 50MHz end if;
109  // it seems hypervisor always got full speed, and force_fast (ie, POKE 0,65) always forces the max
110  // TODO: what is speed_gate? (it seems to be a PMOD input and/or keyboard controll with CAPS-LOCK)
111  // TODO: how 2MHz is selected, it seems a double decoded VIC-X registers which is not so common in VIC modes yet, I think ...
112  //Uint8 desired = (in_hypervisor || force_fast) ? 7 : (((c128_d030_reg & 1) << 2) | ((vic_registers[0x31] & 64) >> 5) | ((vic_registers[0x54] & 64) >> 6));
113  //if (desired == current_speed_config)
114  // return;
115  if (verbose)
116  DEBUGPRINT("SPEED: in_hypervisor=%d force_fast=%d c128_fast=%d, c65_fast=%d m65_fast=%d" NL,
117  in_hypervisor, D6XX_registers[0x7D] & 16, (c128_d030_reg & 1), vic_registers[0x31] & 64, vic_registers[0x54] & 64
118  );
119  // ^1 at c128... because it was inverted :-O --> FIXME: this is ugly workaround, the switch statement should be re-organized
120  speed_wanted = (in_hypervisor || (D6XX_registers[0x7D] & 16)) ? 7 : ((((c128_d030_reg & 1) ^ C128_SPEED_BIT_BUG) << 2) | ((vic_registers[0x31] & 64) >> 5) | ((vic_registers[0x54] & 64) >> 6));
121  // videostd_changed: we also want to force recalulation if PAL/NTSC change happened, even if the speed setting remains the same!
122  if (speed_wanted != speed_current || videostd_changed) {
123  speed_current = speed_wanted;
124  videostd_changed = 0;
125  switch (speed_wanted) {
126  // NOTE: videostd_1mhz_cycles_per_scanline is set by vic4.c and also includes the video standard
127  case 4: // 100 - 1MHz
128  case 5: // 101 - 1MHz
130  cpu_clock_speed_str_index = 0;
131  cpu65_set_timing(0);
132  break;
133  case 0: // 000 - 2MHz
135  cpu_clock_speed_str_index = 1;
136  cpu65_set_timing(0);
137  break;
138  case 2: // 010 - 3.5MHz
139  case 6: // 110 - 3.5MHz
141  cpu_clock_speed_str_index = 2;
142  cpu65_set_timing(1);
143  break;
144  case 1: // 001 - 40MHz (or Xemu specified custom speed)
145  case 3: // 011 - -- "" --
146  case 7: // 111 - -- "" --
148  cpu_clock_speed_str_index = 3;
149  cpu65_set_timing(2);
150  break;
151  }
152  cpu_clock_speed_string = cpu_clock_speed_strs[cpu_clock_speed_str_index];
153  DEBUG("SPEED: CPU speed is set to %s, cycles per scanline: %d in %s (1MHz cycles per scanline: %f)" NL, cpu_clock_speed_string, cpu_cycles_per_scanline, videostd_name, videostd_1mhz_cycles_per_scanline);
155  cpu_cycles_per_step = cpu_cycles_per_scanline; // if in trace mode (or hyper-debug ...), do not set this! So set only if non-trace and non-hyper-debug
156  }
157 }
158 
159 
160 static void cia1_setint_cb ( int level )
161 {
162  DEBUG("%s: IRQ level changed to %d" NL, cia1.name, level);
163  if (level)
164  cpu65.irqLevel |= 1;
165  else
166  cpu65.irqLevel &= ~1;
167 }
168 
169 
170 static inline void nmi_set ( int level, int mask )
171 {
172  // NMI is a low active _EDGE_ triggered 65xx input ... In my emulator though, the signal
173  // is "high active", and also we must form the "edge" ourselves from "level". NMI level is
174  // set as a 2bit number, on bit 0, CIA2, on bit 1, keyboard RESTORE key. Thus having zero
175  // value for level means (in the emu!) that not RESTORE key is pressed neither CIA2 has active
176  // IRQ output, non-zero value means some activation. Well, if I am not confused enough here,
177  // this should mean that nmi_level zero->non-zero transit should produce the edge (which should
178  // be the falling edge in the real hardware anyway ... but the rising here. heh, I should follow
179  // the signal level of the hardware in my emulator, honestly ...)
180  int nmi_new_level;
181  if (level)
182  nmi_new_level = nmi_level | mask;
183  else
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);
187  cpu65.nmiEdge = 1; // the "NMI edge" trigger is deleted by the CPU emulator itself (it's not a level trigger)
188  }
189  nmi_level = nmi_new_level;
190 }
191 
192 
193 static void cia2_setint_cb ( int level )
194 {
195  nmi_set(level, 1);
196 }
197 
198 
199 static void cia2_out_a ( Uint8 data )
200 {
201  // XXX My code
202 #if 0
203  vic2_16k_bank = ((~(data | (~cia2.DDRA))) & 3) << 14;
204  vic_vidp_legacy = 1;
205  vic_chrp_legacy = 1;
206  vic_sprp_legacy = 1;
207  // TODO FIXME: add sprites pointers!
208  DEBUG("VIC2: 16K BANK is set to $%04X (CIA mask=$%02X)" NL, vic2_16k_bank, cia2.DDRA);
209 #endif
210  // Code from HMW, XXX FIXME
211  // Note, I have removed the REG_CRAM2K since it's not possible to hit this callback anyways if CIA is "covered" by colour RAM
212  if (REG_HOTREG) {
213  // Bank select
214  data &= (cia2.DDRA & 3); // Mask bank bits through CIA DDR register bits
215  REG_SCRNPTR_B1 = (~data << 6) | (REG_SCRNPTR_B1 & 0x3F);
216  REG_CHARPTR_B1 = (~data << 6) | (REG_CHARPTR_B1 & 0x3F);
217  REG_SPRPTR_B1 = (~data << 6) | (REG_SPRPTR_B1 & 0x3F);
219  //DEBUGPRINT("VIC2: (hotreg)Wrote to $DD00: $%02x screen=$%08x char=$%08x spr=$%08x" NL, data, SCREEN_ADDR, CHARSET_ADDR, SPRITE_POINTER_ADDR);
220  }
221 }
222 
223 
224 static Uint8 cia2_in_a ( void )
225 {
226  // CIA for real seems to always read their input pins on reading the data
227  // register, even if it's output. However VIC bank for example should be
228  // readable back this way. Trying to implement here something at least
229  // resembling a real situation, also taking account the DATA and CLK lines
230  // of the IEC bus has input and output too with inverter gates. Though note,
231  // IEC bus otherwise is not emulated by Xemu yet.
232  return (cia2.PRA & 0x3F) | ((~cia2.PRA << 2) & 0xC0);
233 }
234 
235 
236 static Uint8 cia2_in_b ( void )
237 {
238  // Some kind of ad-hoc stuff, allow to read back data out register if the
239  // port bit is output, otherwise (input) give bit '1', by virtually
240  // emulation a pull-up as its kind. It seems to be needed, as some C65 ROMs
241  // actually has check for some user port lines and doing "interesting"
242  // things (mostly crashing ...) when something sensed as grounded.
243  // It was a kind of hw debug feature for early C65 ROMs.
244  return cia2.PRB | ~cia2.DDRB;
245 }
246 
247 
248 #ifdef XEMU_SNAPSHOT_SUPPORT
249 static void m65_snapshot_saver_on_exit_callback ( void )
250 {
251  if (!configdb.snapsave)
252  return;
253  if (xemusnap_save(configdb.snapsave))
254  ERROR_WINDOW("Could not save snapshot \"%s\": %s", configdb.snapsave, xemusnap_error_buffer);
255  else
256  INFO_WINDOW("Snapshot has been saved to \"%s\".", configdb.snapsave);
257 }
258 #endif
259 
260 
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 )
262 {
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);
266  sha1_hash_str hash_str;
267  if (XEMU_LIKELY(!fn || !*fn)) {
268  sha1_checksum_as_string(hash_str, source_ptr, source_size);
269  DEBUGPRINT("MEMCONTENT: \"%s\" (%s) was not requested, using the built-in ($%X bytes) [%s]." NL, name, desc, source_size, hash_str);
270  goto internal;
271  }
272  const int size = xemu_load_file(fn, target_ptr, min_size, max_size, desc);
273  if (XEMU_UNLIKELY(size > 0)) {
274  sha1_checksum_as_string(hash_str, target_ptr, size);
275  DEBUGPRINT("MEMCONTENT: \"%s\" (%s) loaded custom object ($%X bytes) from external file [%s]: %s" NL, name, desc, size, hash_str, xemu_load_filepath);
276  return size;
277  }
278  sha1_checksum_as_string(hash_str, source_ptr, source_size);
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);
280 internal:
281  memcpy(target_ptr, source_ptr, source_size);
282  return 0;
283 }
284 
285 
286 static void preinit_memory_for_start ( void )
287 {
288  // This is an absolute minimum flash utility to replace the official one ;)
289  // As Xemu does not have flash (it does not deal with real bitstreams, being an emulator), the official
290  // flash utility during the boot process would throw ugly error and wait for a key to continue, which
291  // is annoying. This short code just creates the minimal thing the flash utility expected to do, to be
292  // able to continue without any side effect.
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
297  };
298  // Option/name Description Target memory ptr Built-in source ptr Built-in size Minsize Maxsize External-filename(or-NULL)
299  // -------------- ---------------------- ------------------- ---------------------- --------------------------- -------- -------- --------------------------
300  preinit_memory_item("extfreezer", "Freezer", main_ram + 0x12000, meminitdata_freezer, MEMINITDATA_FREEZER_SIZE, 0x00100, 0x0E000, configdb.extfreezer);
301  preinit_memory_item("extinitrom", "Initial boot-ROM", main_ram + 0x20000, meminitdata_initrom, MEMINITDATA_INITROM_SIZE, 0x20000, 0x20000, configdb.extinitrom);
302  preinit_memory_item("extonboard", "On-boarding utility", main_ram + 0x40000, meminitdata_onboard, MEMINITDATA_ONBOARD_SIZE, 0x00020, 0x10000, configdb.extonboard);
303  preinit_memory_item("extflashutil", "MEGA-flash utility", main_ram + 0x50000, megaflashutility, sizeof megaflashutility, 0x00020, 0x07D00, configdb.extflashutil);
304  preinit_memory_item("extbanner", "MEGA65 banner", main_ram + 0x57D00, meminitdata_banner, MEMINITDATA_BANNER_SIZE, 0x01000, 0x08300, configdb.extbanner);
305  preinit_memory_item("extchrwom", "Character-WOM", char_wom, meminitdata_chrwom, MEMINITDATA_CHRWOM_SIZE, 0x01000, 0x01000, configdb.extchrwom);
306  preinit_memory_item("extcramutils", "Utils in CRAM", colour_ram, meminitdata_cramutils, MEMINITDATA_CRAMUTILS_SIZE, 0x08000, 0x08000, configdb.extcramutils);
308  preinit_memory_item("hickup", "Hyppo-Hickup", hypervisor_ram, meminitdata_hickup, MEMINITDATA_HICKUP_SIZE, 0x04000, 0x04000, configdb.hickup);
309  // ----------------------------------------------------------------------------------------------------------------------------------------------------------
310  if (!hickup_is_overriden)
311  hypervisor_debug_invalidate("no external hickup is loaded, built-in one does not have debug info");
312 }
313 
314 
315 static void mega65_init ( void )
316 {
317  last_reset_type = "XEMU-STARTUP";
321  hid_init(
322  c64_key_map,
324  SDL_ENABLE // joy HID events enabled
325  );
326  input_init();
327 #ifdef HID_KBD_MAP_CFG_SUPPORT
328  hid_keymap_from_config_file(configdb.keymap);
329 #endif
330  joystick_emu = 2; // use joystick port #2 by default
331  nmi_level = 0;
332  // *** FPGA switches ...
333  do {
334  int switches[16], r = xemucfg_integer_list_from_string(configdb.fpga, switches, 16, ",");
335  if (r < 0)
336  FATAL("Too many FPGA switches specified for option 'fpga'");
337  while (r--) {
338  DEBUGPRINT("FPGA switch is turned on: #%d" NL, switches[r]);
339  if (switches[r] < 0 || switches[r] > 15)
340  FATAL("Invalid switch sepcifictation for option 'fpga': %d", switches[r]);
341  fpga_switches |= 1 << (switches[r]);
342  }
343  } while (0);
344  // *** Initializes memory subsystem of MEGA65 emulation itself
345  memory_init();
346  // Load contents of NVRAM.
347  // Also store as "nvram_original" so we can sense on shutdown of the emu, if we need to up-date the on-disk version
348  // If we fail to load it (does not exist?) it will be written out anyway on exit.
349  if (xemu_load_file(NVRAM_FILE_NAME, nvram, sizeof nvram, sizeof nvram, "Cannot load NVRAM state. Maybe first run of Xemu?\nOn next Xemu run, it should have been corrected though automatically!\nSo no need to worry.") == sizeof nvram) {
350  memcpy(nvram_original, nvram, sizeof nvram);
351  } else {
352  // could not load from disk. Initialize to soma values.
353  // Also, set nvram and nvram_original being different, so exit handler will sense the situation and save it.
354  memset(nvram, 0, sizeof nvram);
355  memset(nvram_original, 0xAA, sizeof nvram);
356  }
357  // Let's generate (if it does not exist) an UUID for myself. It can be read back via the 'UUID' registers.
358  if (xemu_load_file(UUID_FILE_NAME, mega65_uuid, sizeof mega65_uuid, sizeof mega65_uuid, NULL) != sizeof mega65_uuid) {
359  for (int a = 0; a < sizeof mega65_uuid; a++) {
360  mega65_uuid[a] = rand();
361  }
362  uuid_must_be_saved = 1;
363  }
364  // Fill memory with the needed pre-initialized regions to be able to start.
365  preinit_memory_for_start();
366 #if 0
367  // If we have no -8 option given, but we found a suitable disk image in the pref-dir,
368  // with the desired name, let's use that! In this way, it may cure some complains,
369  // that the default disk is "inside" the SD-card image which is hard to deal with.
370  // FIXME: remove this ugliness and solve this in a more fine way! XXX
371  if (!configdb.disk8) {
372  static const char default_d81_fn[] = "default.d81";
373  char *fn = xemu_malloc(strlen(sdl_pref_dir) + strlen(default_d81_fn) + 1);
374  sprintf(fn, "%s%s", sdl_pref_dir, default_d81_fn);
376  if (size != OFF_T_ERROR) {
377  if (size == (off_t)D81_SIZE) {
378  DEBUGPRINT("DISK: using external default disk image, since without -8 we found: %s" NL, fn);
379  configdb.disk8 = fn;
380  } else {
381  ERROR_WINDOW("Found: %s\nfor default external disk image,\nbut it has wrong size", fn);
382  free(fn);
383  }
384  } else
385  free(fn);
386  }
387 #endif
388  // *** Image file for SDCARD support, and other related init functions handled there as well (eg d81access, fdc init ... related registers, etc)
390  FATAL("Cannot find SD-card image (which is a must for MEGA65 emulation): %s", configdb.sdimg);
391  // *** Initialize VIC4
392  vic_init();
393  // *** CIAs
394  cia_init(&cia1, "CIA-1",
395  NULL, // callback: OUTA
396  NULL, // callback: OUTB
397  NULL, // callback: OUTSR
398  cia1_in_a, // callback: INA ~ joy#2
399  cia1_in_b, // callback: INB ~ keyboard
400  NULL, // callback: INSR
401  cia1_setint_cb // callback: SETINT
402  );
403  cia_init(&cia2, "CIA-2",
404  cia2_out_a, // callback: OUTA
405  NULL, // callback: OUTB
406  NULL, // callback: OUTSR
407  cia2_in_a, // callback: INA
408  cia2_in_b, // callback: INB
409  NULL, // callback: INSR
410  cia2_setint_cb // callback: SETINT ~ that would be NMI in our case
411  );
412  cia2.DDRA = 3; // Ugly workaround ... I think, SD-card setup "CRAM UTIL" (or better: Hyppo) should set this by its own. Maybe Xemu bug, maybe not?
413  // *** Initialize DMA (we rely on memory and I/O decoder provided functions here for the purpose)
415  // *** Drive 8 external mount
416  if (configdb.disk8)
417  sdcard_force_external_mount(0, configdb.disk8, "Mount failure on CLI/CFG requested drive-8");
418  // *** Drive 9 external mount
419  if (configdb.disk9)
420  sdcard_force_external_mount(1, configdb.disk9, "Mount failure on CLI/CFG requested drive-9");
421 #ifdef HAS_UARTMON_SUPPORT
422  uartmon_init(configdb.uartmon);
423 #endif
424  sprintf(fast_mhz_in_string, "%.2fMHz", configdb.fast_mhz);
425  DEBUGPRINT("SPEED: fast clock is set to %.2fMHz." NL, configdb.fast_mhz);
426  cpu65_init_mega_specific();
427  cpu65_reset(); // reset CPU (though it fetches its reset vector, we don't use that on M65, but the KS hypervisor trap)
428  rom_protect = 0;
430  speed_current = 0;
432  if (configdb.useutilmenu)
433  hwa_kbd_fake_key(0x20);
434  DEBUG("INIT: end of initialization!" NL);
435 #ifdef XEMU_SNAPSHOT_SUPPORT
436  xemusnap_init(m65_snapshot_definition);
437  if (configdb.snapload) {
438  if (xemusnap_load(configdb.snapload))
439  FATAL("Couldn't load snapshot \"%s\": %s", configdb.snapload, xemusnap_error_buffer);
440  }
441  atexit(m65_snapshot_saver_on_exit_callback);
442 #endif
443 }
444 
445 
446 int dump_memory ( const char *fn )
447 {
448  if (fn && *fn) {
449  DEBUGPRINT("MEM: Dumping memory into file: %s" NL, fn);
450  return xemu_save_file(fn, main_ram, (128 + 256) * 1024, "Cannot dump memory into file");
451  } else {
452  return 0;
453  }
454 }
455 
456 
457 static void shutdown_callback ( void )
458 {
459  // Write out NVRAM if changed!
460  if (memcmp(nvram, nvram_original, sizeof(nvram))) {
461  DEBUGPRINT("NVRAM: changed, writing out on exit." NL);
462  xemu_save_file(NVRAM_FILE_NAME, nvram, sizeof nvram, "Cannot save changed NVRAM state! NVRAM changes will be lost!");
463  }
464  if (uuid_must_be_saved) {
465  uuid_must_be_saved = 0;
466  DEBUGPRINT("UUID: must be saved." NL);
468  }
469  eth65_shutdown();
470  for (int a = 0; a < 0x40; a++)
471  DEBUG("VIC-3 register $%02X is %02X" NL, a, vic_registers[a]);
472  cia_dump_state (&cia1);
473  cia_dump_state (&cia2);
474 #if !defined(XEMU_ARCH_HTML)
476 #endif
477 #ifdef HAS_UARTMON_SUPPORT
478  uartmon_close();
479 #endif
480 #ifdef HAVE_XEMU_UMON
481  xumon_stop();
482 #endif
483 #ifdef XEMU_HAS_SOCKET_API
484  xemusock_uninit();
485 #endif
487  if (emulation_is_running)
488  DEBUGPRINT("CPU: Execution ended at PC=$%04X (linear=%X)" NL, cpu65.pc, memory_cpurd2linear_xlat(cpu65.pc));
489 }
490 
491 
492 void reset_mega65 ( void )
493 {
494  static const char reset_debug_msg[] = "SYSTEM: RESET - ";
495  last_reset_type = "COLD";
496  DEBUGPRINT("%sBEGIN" NL, reset_debug_msg);
497  memset(D7XX + 0x20, 0, 0x40); // stop audio DMA possibly going on
499  preinit_memory_for_start();
500  hwa_kbd_disable_selector(0); // FIXME: do we need this, or hyppo will make it so for us?
501  eth65_reset();
502  D6XX_registers[0x7D] &= ~16; // FIXME: other default speed controls on reset?
503  c128_d030_reg = 0xFF;
506  map_mask = 0;
507  in_hypervisor = 0;
508  vic_registers[0x30] = 0; // FIXME: hack! we need this, and memory_set_vic3_rom_mapping above too :(
511  vic_reset(); // FIXME: we may need a RESET on VIC-IV what ROM would not initialize but could be used by some MEGA65-aware program? [and hyppo does not care to reset?]
512  cpu65_reset();
513  dma_reset();
514  nmi_level = 0;
517  DEBUGPRINT("%sEND" NL, reset_debug_msg);
518 }
519 
520 
522 {
523  last_reset_type = "WARM";
524  D6XX_registers[0x7D] &= ~16; // FIXME: other default speed controls on reset?
525  c128_d030_reg = 0xFF;
528  map_mask = 0;
529  in_hypervisor = 0;
530  vic_registers[0x30] = 0; // FIXME: hack! we need this, and memory_set_vic3_rom_mapping above too :(
533  cpu65_reset();
534 }
535 
536 
537 int reset_mega65_asked ( void )
538 {
539  if (ARE_YOU_SURE("Are you sure to RESET your emulated machine?", i_am_sure_override | ARE_YOU_SURE_DEFAULT_YES)) {
540  reset_mega65();
541  return 1;
542  } else
543  return 0;
544 }
545 
546 
547 #ifdef HAS_UARTMON_SUPPORT
548 void m65mon_show_regs ( void )
549 {
550  Uint8 pf = cpu65_get_pf();
551  umon_printf(
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 " // register banned message and things from PC to SP
554  "%04X %04X %02X %02X %02X " // from MAPL to P
555  "%c%c%c%c%c%c%c%c ", // P-FLAGS
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,
558  pf, 0, // flags
559  (pf & CPU65_PF_N) ? 'N' : '-',
560  (pf & CPU65_PF_V) ? 'V' : '-',
561  (pf & CPU65_PF_E) ? 'E' : '-',
562  '-',
563  (pf & CPU65_PF_D) ? 'D' : '-',
564  (pf & CPU65_PF_I) ? 'I' : '-',
565  (pf & CPU65_PF_Z) ? 'Z' : '-',
566  (pf & CPU65_PF_C) ? 'C' : '-'
567  );
568 }
569 
571 {
572  int n = 16;
573  umon_printf(":000%04X:", addr);
574  while (n--)
575  umon_printf("%02X", cpu65_read_callback(addr++));
576 }
577 
578 void m65mon_dumpmem28 ( int addr )
579 {
580  int n = 16;
581  addr &= 0xFFFFFFF;
582  umon_printf(":%07X:", addr);
583  while (n--)
584  umon_printf("%02X", memory_debug_read_phys_addr(addr++));
585 }
586 
587 void m65mon_setmem28( int addr, int cnt, Uint8* vals )
588 {
589  for (int k = 0; k < cnt; k++)
590  {
592  }
593 }
594 
595 void m65mon_set_trace ( int m )
596 {
597  paused = m;
598 }
599 
600 #ifdef TRACE_NEXT_SUPPORT
601 void m65mon_do_next ( void )
602 {
603  if (paused) {
604  umon_send_ok = 0; // delay command execution!
605  m65mon_callback = m65mon_show_regs; // register callback
606  trace_next_trigger = 2; // if JSR, then trigger until RTS to next_addr
607  orig_sp = cpu65.sphi | cpu65.s;
608  paused = 0;
609  } else {
610  umon_printf(UMON_SYNTAX_ERROR "trace can be used only in trace mode");
611  }
612 }
613 #endif
614 
615 void m65mon_do_trace ( void )
616 {
617  if (paused) {
618  umon_send_ok = 0; // delay command execution!
619  m65mon_callback = m65mon_show_regs; // register callback
620  trace_step_trigger = 1; // trigger one step
621  } else {
622  umon_printf(UMON_SYNTAX_ERROR "trace can be used only in trace mode");
623  }
624 }
625 
626 void m65mon_do_trace_c ( void )
627 {
628  umon_printf(UMON_SYNTAX_ERROR "command 'tc' is not implemented yet");
629 }
630 #ifdef TRACE_NEXT_SUPPORT
631 void m65mon_next_command ( void )
632 {
633  if (paused)
634  m65mon_do_next();
635 }
636 #endif
637 void m65mon_empty_command ( void )
638 {
639  if (paused)
640  m65mon_do_trace();
641 }
642 
643 void m65mon_breakpoint ( int brk )
644 {
645  breakpoint_pc = brk;
646  if (brk < 0)
648  else
650 }
651 #endif
652 
653 
654 static void update_emulator ( void )
655 {
657  // XXX: some things has been moved here from the main loop, however update_emulator is called from other places as well, FIXME check if it causes problems or not!
661  strcpy(emulator_speed_title, cpu_clock_speed_strs[cpu_clock_speed_str_index]);
662  strcat(emulator_speed_title, " ");
663  strcat(emulator_speed_title, videostd_name);
666  nmi_set(IS_RESTORE_PRESSED(), 2); // Custom handling of the restore key ...
667  // this part is used to trigger 'RESTORE trap' with long press on RESTORE.
668  // see input_devices.c for more information
670 #ifdef HAS_UARTMON_SUPPORT
671  uartmon_update();
672 #endif
673  // Screen updating, final phase
674  //vic4_close_frame_access();
675  // Let's sleep ...
677  // Ugly CIA trick to maintain realtime TOD in CIAs :)
678 // if (seconds_timer_trigger) {
679  const struct tm *t = xemu_get_localtime();
680  const Uint8 sec10ths = xemu_get_microseconds() / 100000;
681  // UPDATE CIA TODs:
682  cia_ugly_tod_updater(&cia1, t, sec10ths, configdb.rtc_hour_offset);
684  // UPDATE the RTC too:
685  rtc_regs[0] = XEMU_BYTE_TO_BCD(t->tm_sec); // seconds
686  rtc_regs[1] = XEMU_BYTE_TO_BCD(t->tm_min); // minutes
687  //rtc_regs[2] = xemu_hour_to_bcd12h(t->tm_hour, configdb.rtc_hour_offset); // hours
688  rtc_regs[2] = XEMU_BYTE_TO_BCD((t->tm_hour + configdb.rtc_hour_offset + 24) % 24) | 0x80; // hours (24H format, bit 7 always set)
689  rtc_regs[3] = XEMU_BYTE_TO_BCD(t->tm_mday); // day of mounth
690  rtc_regs[4] = XEMU_BYTE_TO_BCD(t->tm_mon) + 1; // month
691  rtc_regs[5] = XEMU_BYTE_TO_BCD(t->tm_year - 100); // year
692 // }
693 }
694 
695 
696 static void emulation_loop ( void )
697 {
698  static int cycles = 0; // used for "balance" CPU cycles per scanline, must be static!
701  // video standard (PAL/NTSC) affects the "CPU cycles per scanline" variable, which is used in this main emulation loop below.
702  // thus, if vic-4 emulation set videostd_changed, we should react with enforce a re-calibration.
703  // videostd_changed is set by vic4_open_frame_access() in vic4.c, thus we do here right after calling it.
704  // machine_set_speed() will react to videostd_changed flag, so it's just enough to call it from here
706  for (;;) {
707 #ifdef TRACE_NEXT_SUPPORT
708  if (trace_next_trigger == 2) {
709  if (cpu65.op == 0x20) { // was the current opcode a JSR $nnnn ? (0x20)
710  trace_next_trigger = 1; // if so, let's loop until the stack pointer returns back, then pause
711  } else {
712  trace_next_trigger = 0; // if the current opcode wasn't a JSR, then lets pause immediately after
713  paused = 1;
714  }
715  } else if (trace_next_trigger == 1) { // are we presently stepping over a JSR?
716  if ((cpu65.sphi | cpu65.s) == orig_sp ) { // did the current sp return to its original position?
717  trace_next_trigger = 0; // if so, lets pause the emulation, as we have successfully stepped over the JSR
718  paused = 1;
719  }
720  }
721 #endif
722  while (XEMU_UNLIKELY(paused)) { // paused special mode, ie tracing support, or something ...
724  break; // if DMA is pending, do not allow monitor/etc features
725 #ifdef HAS_UARTMON_SUPPORT
726  if (m65mon_callback) { // delayed uart monitor command should be finished ...
727  m65mon_callback();
728  m65mon_callback = NULL;
729  uartmon_finish_command();
730  }
731 #endif
732  // we still need to feed our emulator with update events ... It also slows this pause-busy-loop down to every full frames (~25Hz) <--- XXX totally inaccurate now!
733  // note, that it messes timing up a bit here, as there is update_emulator() calls later in the "normal" code as well
734  // this can be a bug, but real-time emulation is not so much an issue if you eg doing trace of your code ...
735  // XXX it's maybe a problem to call this!!! update_emulator() is called here which closes frame but no no reopen then ... FIXME: handle this somehow!
736  update_emulator();
737  if (trace_step_trigger) {
738  // if monitor trigges a step, break the pause loop, however we will get back the control on the next
739  // iteration of the infinite "for" loop, as "paused" is not altered
740  trace_step_trigger = 0;
741  break; // break the pause loop now
742  }
743  // Decorate window title about the mode.
744  // If "paused" mode is switched off ie by a monitor command (called from update_emulator() above!)
745  // then it will resets back the the original state, etc
746  window_title_custom_addon = paused ? (char*)emulator_paused_title : NULL;
747  if (paused != paused_old) {
748  paused_old = paused;
749  if (paused) {
750  DEBUGPRINT("TRACE: entering into trace mode @ $%04X" NL, cpu65.pc);
752  } else {
753  DEBUGPRINT("TRACE: leaving trace mode @ $%04X" NL, cpu65.pc);
754  if (breakpoint_pc < 0)
756  else
758  }
759  }
760  }
763  if (XEMU_UNLIKELY(breakpoint_pc == cpu65.pc)) {
764  DEBUGPRINT("TRACE: Breakpoint @ $%04X hit, Xemu moves to trace mode after the execution of this opcode." NL, cpu65.pc);
765  paused = 1;
766  }
767  cycles += XEMU_UNLIKELY(dma_status) ? dma_update_multi_steps(cpu_cycles_per_scanline) : cpu65_step(
768 #ifdef CPU_STEP_MULTI_OPS
770 #endif
771  ); // FIXME: this is maybe not correct, that DMA's speed depends on the fast/slow clock as well?
772  if (cycles >= cpu_cycles_per_scanline) {
773  cycles -= cpu_cycles_per_scanline;
774  cia_tick(&cia1, 32); // FIXME: why 32?????? why fixed????? what should be the CIA "tick" frequency for real? Is it dependent on NTSC/PAL?
775  cia_tick(&cia2, 32);
777  break; // break the (main, "for") loop, if frame is over!
778  }
779  }
780  update_emulator();
781 }
782 
783 
784 int main ( int argc, char **argv )
785 {
786  xemu_pre_init(APP_ORG, TARGET_NAME, "The Evolving MEGA65 emulator from LGB");
788  if (xemucfg_parse_all(argc, argv))
789  return 1;
790  // xemucfg_dump_db("After returning from xemucfg_parse_all in main()");
791  DEBUGPRINT("XEMU: emulated MEGA65 model ID: %d" NL, configdb.mega65_model);
792 #ifdef HAVE_XEMU_INSTALLER
793  xemu_set_installer(configdb.installer);
794 #endif
795  newhack = !newhack; // hehe, the meaning is kind of inverted, but never mind ...
796  if (newhack)
797  DEBUGPRINT("WARNING: *** NEW M65 HACK MODE ACTIVATED ***" NL);
798  /* Initiailize SDL - note, it must be before loading ROMs, as it depends on path info from SDL! */
800  if (xemu_post_init(
801  TARGET_DESC APP_DESC_APPEND, // window title
802  1, // resizable window
803  TEXTURE_WIDTH, TEXTURE_HEIGHT, // texture sizes
804  TEXTURE_WIDTH, TEXTURE_HEIGHT, // logical size (used with keeping aspect ratio by the SDL render stuffs)
805  INITIAL_WINDOW_WIDTH, // window size
806  INITIAL_WINDOW_HEIGHT, // -- "" --
807  TEXTURE_FORMAT, // pixel format
808  0, // we have *NO* pre-defined colours as with more simple machines (too many we need). we want to do this ourselves!
809  NULL, // -- "" --
810  NULL, // -- "" --
811  configdb.sdlrenderquality, // render scaling quality
812  USE_LOCKED_TEXTURE, // 1 = locked texture access
813  shutdown_callback // registered shutdown function
814  ))
815  return 1;
818  // Initialize MEGA65
819  mega65_init();
820  audio65_init(
821  SID_CYCLES_PER_SEC, // SID cycles per sec
822  AUDIO_SAMPLE_FREQ, // sound mix freq
826  );
827  DEBUGPRINT("MEM: UNHANDLED memory policy: %d" NL, configdb.skip_unhandled_mem);
829  skip_unhandled_mem = 3; // silent ignore all = 3
830  else
831  skip_unhandled_mem = 0; // ask = 0
832  eth65_init(
833 #ifdef HAVE_ETHERTAP
834  configdb.ethertap
835 #else
836  NULL
837 #endif
838  );
839 #ifdef HAVE_XEMU_UMON
840  if (configdb.umon == 1)
841  configdb.umon = XUMON_DEFAULT_PORT;
842  xumon_init(configdb.umon);
843 #endif
844  if (configdb.prg)
846 #ifdef FAKE_TYPING_SUPPORT
847  if (configdb.go64) {
848  if (configdb.autoload)
849  c64_register_fake_typing(fake_typing_for_load64);
850  else
851  c64_register_fake_typing(fake_typing_for_go64);
852  } else if (configdb.autoload)
853  c64_register_fake_typing(fake_typing_for_load65);
854 #endif
859  audio65_start();
861  if (!configdb.syscon)
862  sysconsole_close(NULL);
864  emulation_is_running = 1;
865  // FIXME: for emscripten (anyway it does not work too much currently) there should be 50 or 60 (PAL/NTSC) instead of (fixed, and wrong!) 25!!!!!!
866  XEMU_MAIN_LOOP(emulation_loop, 25, 1);
867  return 0;
868 }
869 
870 /* --- SNAPSHOT RELATED --- */
871 
872 #ifdef XEMU_SNAPSHOT_SUPPORT
873 
874 #include <string.h>
875 
876 #define SNAPSHOT_M65_BLOCK_VERSION 2
877 #define SNAPSHOT_M65_BLOCK_SIZE (0x100 + sizeof(D6XX_registers) + sizeof(D7XX))
878 
879 
880 int m65emu_snapshot_load_state ( const struct xemu_snapshot_definition_st *def, struct xemu_snapshot_block_st *block )
881 {
882  Uint8 buffer[SNAPSHOT_M65_BLOCK_SIZE];
883  int a;
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);
887  if (a) return a;
888  /* loading state ... */
889  memcpy(D6XX_registers, buffer + 0x100, sizeof D6XX_registers);
890  memcpy(D7XX, buffer + 0x200, sizeof D7XX);
891  in_hypervisor = 1; // simulate hypervisor mode, to allow to write some regs now instead of causing a TRAP now ...
892  io_write(0x367D, D6XX_registers[0x7D]); // write $(D)67D in VIC-IV I/O mode! (sets ROM protection, linear addressing mode enable ...)
893  // TODO FIXME: see if there is a need for other registers from D6XX_registers to write back to take effect on loading snapshot!
894  // end of spec, hypervisor-needed faked mode for loading snapshot ...
895  map_mask = (int)P_AS_BE32(buffer + 0);
896  map_offset_low = (int)P_AS_BE32(buffer + 4);
897  map_offset_high = (int)P_AS_BE32(buffer + 8);
898  cpu65.cpu_inhibit_interrupts = (int)P_AS_BE32(buffer + 12);
899  in_hypervisor = (int)P_AS_BE32(buffer + 16); // sets hypervisor state from snapshot (hypervisor/userspace)
900  map_megabyte_low = (int)P_AS_BE32(buffer + 20);
901  map_megabyte_high = (int)P_AS_BE32(buffer + 24);
902  //force_fast_loaded = (int)P_AS_BE32(buffer + 28); // activated in m65emu_snapshot_loading_finalize() as force_fast can be set at multiple places through loading snapshot!
903  // +32 is free for 4 bytes now ... can be used later
904  memory_set_cpu_io_port_ddr_and_data(buffer[36], buffer[37]);
905  return 0;
906 }
907 
908 
909 int m65emu_snapshot_save_state ( const struct xemu_snapshot_definition_st *def )
910 {
911  Uint8 buffer[SNAPSHOT_M65_BLOCK_SIZE];
912  int a = xemusnap_write_block_header(def->idstr, SNAPSHOT_M65_BLOCK_VERSION);
913  if (a) return a;
914  memset(buffer, 0xFF, sizeof buffer);
915  /* saving state ... */
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);
920  U32_AS_BE(buffer + 16, in_hypervisor);
921  U32_AS_BE(buffer + 20, map_megabyte_low);
922  U32_AS_BE(buffer + 24, map_megabyte_high);
923  //U32_AS_BE(buffer + 28, force_fast); // see notes on this at load_state and finalize stuff!
924  // +32 is free for 4 bytes now ... can be used later
925  buffer[36] = memory_get_cpu_io_port(0);
926  buffer[37] = memory_get_cpu_io_port(1);
927  memcpy(buffer + 0x100, D6XX_registers, sizeof D6XX_registers);
928  memcpy(buffer + 0x200, D7XX, sizeof D7XX);
929  return xemusnap_write_sub_block(buffer, sizeof buffer);
930 }
931 
932 
933 int m65emu_snapshot_loading_finalize ( const struct xemu_snapshot_definition_st *def, struct xemu_snapshot_block_st *block )
934 {
935  DEBUGPRINT("SNAP: loaded (finalize-callback: begin)" NL);
936  memory_set_vic3_rom_mapping(vic_registers[0x30]);
938  //force_fast = force_fast_loaded; // force_fast is handled through different places, so we must have a "finalize" construct and saved separately to have the actual effect ...
940  DEBUGPRINT("SNAP: loaded (finalize-callback: end)" NL);
941  OSD(-1, -1, "Snapshot has been loaded.");
942  return 0;
943 }
944 #endif
xemu_pre_init
void xemu_pre_init(const char *app_organization, const char *app_name, const char *slogan)
Definition: emutools.c:651
dma_reset
void dma_reset(void)
Definition: dma65.c:488
inject_ready_check_do
void inject_ready_check_do(void)
Definition: inject.c:234
USE_LOCKED_TEXTURE
#define USE_LOCKED_TEXTURE
Definition: commodore_65.h:26
eth65_reset
void eth65_reset(void)
Definition: ethernet65.c:542
configdb_st::romfromsd
int romfromsd
Definition: configdb.h:47
reset_mega65_cpu_only
void reset_mega65_cpu_only(void)
Definition: mega65.c:521
configdb_st::audiobuffersize
int audiobuffersize
Definition: configdb.h:105
TARGET_DESC
#define TARGET_DESC
Definition: xemu-target.h:2
memory_init
void memory_init(void)
Definition: memory_mapper.c:479
configdb_st::extinitrom
char * extinitrom
Definition: configdb.h:40
m65mon_do_trace_c
void m65mon_do_trace_c(void)
configdb_st::hickuprep
char * hickuprep
Definition: configdb.h:37
cia_ugly_tod_updater
void cia_ugly_tod_updater(struct Cia6526 *cia, const struct tm *t, Uint8 sec10, int hour_offset)
Definition: cia6526.c:270
vic4.h
NVRAM_FILE_NAME
#define NVRAM_FILE_NAME
Definition: mega65.h:29
configdb.h
map_megabyte_high
int map_megabyte_high
Definition: memory_mapper.c:142
configdb_st::fullscreen_requested
int fullscreen_requested
Definition: configdb.h:35
CPU65_PF_E
#define CPU65_PF_E
Definition: cpu65.h:25
machine_set_speed
void machine_set_speed(int verbose)
Definition: mega65.c:101
vic_init
void vic_init(Uint8 **lo8_pointers, Uint8 **hi4_pointers)
Definition: vic6561.c:168
MEMINITDATA_CHRWOM_SIZE
#define MEMINITDATA_CHRWOM_SIZE
Definition: memcontent.h:23
xemu_timekeeping_delay
void xemu_timekeeping_delay(int td_em)
Definition: emutools.c:405
emutools.h
sysconsole_close
void sysconsole_close(const char *waitmsg)
Definition: emutools.c:1393
sha1_hash_str
char sha1_hash_str[41]
Definition: emutools.h:237
window_title_custom_addon
char * window_title_custom_addon
Definition: emutools.c:90
char_wom
Uint8 char_wom[0x2000]
Definition: memory_mapper.c:67
configdb_st::prg
char * prg
Definition: configdb.h:33
configdb_st::useinitrom
int useinitrom
Definition: configdb.h:79
XEMU_MAIN_LOOP
#define XEMU_MAIN_LOOP(func, p1, p2)
Definition: emutools.h:58
sdcard_force_external_mount
int sdcard_force_external_mount(const int unit, const char *filename, const char *cry)
Definition: sdcard.c:925
C65_MHZ_CLOCK
#define C65_MHZ_CLOCK
Definition: mega65.h:45
audio65_init
void audio65_init(int sid_cycles_per_sec, int sound_mix_freq, int volume, int separation, unsigned int buffer_size)
Definition: audio65.c:382
configdb_st::extonboard
char * extonboard
Definition: configdb.h:43
Cia6526::DDRB
Uint8 DDRB
Definition: cia6526.h:46
configdb_st::fpga
char * fpga
Definition: configdb.h:35
MEMINITDATA_FREEZER_SIZE
#define MEMINITDATA_FREEZER_SIZE
Definition: memcontent.h:47
xemu_get_localtime
struct tm * xemu_get_localtime(void)
Definition: emutools.c:187
configdb_st::extchrwom
char * extchrwom
Definition: configdb.h:41
ethernet65.h
configdb_st::rtc_hour_offset
int rtc_hour_offset
Definition: configdb.h:94
configdb_st::mastervolume
int mastervolume
Definition: configdb.h:100
videostd_1mhz_cycles_per_scanline
float videostd_1mhz_cycles_per_scanline
Definition: vic4.c:85
cpu_cycles_per_scanline
int cpu_cycles_per_scanline
Definition: vic3.c:64
MEMINITDATA_ONBOARD_SIZE
#define MEMINITDATA_ONBOARD_SIZE
Definition: memcontent.h:39
audio65_start
void audio65_start(void)
Definition: audio65.c:367
OFF_T_ERROR
#define OFF_T_ERROR
Definition: fat32.c:42
hypervisor_hdos_close_descriptors
void hypervisor_hdos_close_descriptors(void)
Definition: hdos.c:820
hypervisor_debug_init
int hypervisor_debug_init(const char *fn, int hypervisor_debug, int use_hypervisor_serial_out_asciizer)
Definition: hypervisor.c:421
m65mon_dumpmem16
void m65mon_dumpmem16(Uint16 addr)
input_devices.h
cpu65_illegal_opcode_callback
void cpu65_illegal_opcode_callback(void)
Definition: mega65.c:90
configdb_st::extcramutils
char * extcramutils
Definition: configdb.h:39
configdb_st::extfreezer
char * extfreezer
Definition: configdb.h:44
c64_key_map
const struct KeyMappingDefault c64_key_map[]
Definition: c64_kbd_mapping.c:33
CPU65_PF_Z
#define CPU65_PF_Z
Definition: cpu65.h:29
xemucfg_integer_list_from_string
int xemucfg_integer_list_from_string(const char *value, int *result, int maxitems, const char *delims)
configdb_st::skip_unhandled_mem
int skip_unhandled_mem
Definition: configdb.h:88
memory_set_vic3_rom_mapping
void memory_set_vic3_rom_mapping(Uint8 value)
Definition: memory_mapper.c:689
hwa_kbd_disable_selector
void hwa_kbd_disable_selector(int state)
Definition: input_devices.c:86
cpu_cycles_per_step
int cpu_cycles_per_step
Definition: mega65.c:78
UUID_FILE_NAME
#define UUID_FILE_NAME
Definition: mega65.h:30
i_am_sure_override
int i_am_sure_override
Definition: emutools.c:74
configdb_st::usestubrom
int usestubrom
Definition: configdb.h:78
hypervisor_ram
Uint8 hypervisor_ram[0x4000]
Definition: memory_mapper.c:69
CPU65_PF_D
#define CPU65_PF_D
Definition: cpu65.h:27
rom_load_custom
int rom_load_custom(const char *fn)
Definition: rom.c:240
meminitdata_hickup
const Uint8 meminitdata_hickup[MEMINITDATA_HICKUP_SIZE]
Definition: memcontent.c:159
joystick_emu
int joystick_emu
Definition: c64_kbd_mapping.c:137
map_offset_high
int map_offset_high
Definition: memory_mapper.c:142
m65mon_show_regs
void m65mon_show_regs(void)
configdb_st::go64
int go64
Definition: configdb.h:34
C128_MHZ_CLOCK
#define C128_MHZ_CLOCK
Definition: mega65.h:44
vic4_render_scanline
int vic4_render_scanline(void)
Definition: vic4.c:1462
vic4_open_frame_access
void vic4_open_frame_access(void)
Definition: vic4.c:373
configdb_st::rom
char * rom
Definition: configdb.h:32
m65mon_breakpoint
void m65mon_breakpoint(int brk)
videostd_name
const char * videostd_name
Definition: vic4.c:83
C64_MHZ_CLOCK
#define C64_MHZ_CLOCK
Definition: mega65.h:43
colour_ram
Uint8 colour_ram[0x8000]
Definition: memory_mapper.c:65
INFO_WINDOW
#define INFO_WINDOW(...)
Definition: xep128.h:114
io_mapper.h
addr
int addr
Definition: dma65.c:81
meminitdata_freezer
const Uint8 meminitdata_freezer[MEMINITDATA_FREEZER_SIZE]
Definition: memcontent.c:6824
fn
const char * fn
Definition: roms.c:42
configdb_st::disk8
char * disk8
Definition: configdb.h:30
configdb_st::snapsave
char * snapsave
Definition: configdb.h:33
hid_handle_all_sdl_events
void hid_handle_all_sdl_events(void)
Definition: emutools_hid.c:613
m65mon_setmem28
void m65mon_setmem28(int addr, int cnt, Uint8 *vals)
dma_status
Uint8 dma_status
Definition: dma65.c:51
io_write
void io_write(int addr, Uint8 data)
Definition: commodore_65.c:546
xemucfg_parse_all
int xemucfg_parse_all(int argc, char **argv)
memory_debug_read_phys_addr
Uint8 memory_debug_read_phys_addr(int addr)
Definition: memory_mapper.c:954
vic_vidp_legacy
int vic_vidp_legacy
REG_HOTREG
#define REG_HOTREG
Definition: vic4.h:102
rom_protect
int rom_protect
Definition: memory_mapper.c:144
emutools_gui.h
configdb_st::keymap
char * keymap
Definition: configdb.h:32
m65-memcontent-generator.data
data
Definition: m65-memcontent-generator.py:119
mega65.h
skip_unhandled_mem
int skip_unhandled_mem
Definition: memory_mapper.c:145
osd_init_with_defaults
int osd_init_with_defaults(void)
Definition: osd.c:131
kbd_trigger_restore_trap
void kbd_trigger_restore_trap(void)
Definition: input_devices.c:260
reset_mega65
void reset_mega65(void)
Definition: mega65.c:492
rom_initrom_requested
int rom_initrom_requested
Definition: rom.c:33
hid_init
void hid_init(const struct KeyMappingDefault *key_map_in, Uint8 virtual_shift_pos_in, int joy_enable)
Definition: emutools_hid.c:300
REG_SCRNPTR_B1
#define REG_SCRNPTR_B1
Definition: vic4.h:108
paused
int paused
Definition: enterprise128.c:53
memory_cpurd2linear_xlat
int memory_cpurd2linear_xlat(Uint16 cpu_addr)
Definition: memory_mapper.c:966
cia_tick
void cia_tick(struct Cia6526 *cia, int ticks)
Definition: cia6526.c:281
MEMINITDATA_BANNER_SIZE
#define MEMINITDATA_BANNER_SIZE
Definition: memcontent.h:35
hwa_kbd_fake_key
void hwa_kbd_fake_key(Uint8 k)
Definition: input_devices.c:96
rom_from_prefdir_allowed
int rom_from_prefdir_allowed
Definition: rom.c:34
cia2
struct Cia6526 cia1 cia2
Definition: commodore_65.c:44
Uint8
uint8_t Uint8
Definition: fat32.c:51
Cia6526::DDRA
Uint8 DDRA
Definition: cia6526.h:46
inject_ready_check_status
int inject_ready_check_status
Definition: inject.c:31
xemu_set_full_screen
void xemu_set_full_screen(int setting)
Definition: emutools.c:311
c128_d030_reg
Uint8 c128_d030_reg
Definition: vic4.c:49
configdb_st::cpusinglestep
int cpusinglestep
Definition: configdb.h:32
meminitdata_cramutils
const Uint8 meminitdata_cramutils[MEMINITDATA_CRAMUTILS_SIZE]
Definition: memcontent.c:675
sha1_checksum_as_string
void sha1_checksum_as_string(sha1_hash_str hash_str, const Uint8 *data, Uint32 size)
Definition: emutools.c:1853
inject.h
main_ram
Uint8 main_ram[512<< 10]
Definition: memory_mapper.c:47
CPU65_PF_C
#define CPU65_PF_C
Definition: cpu65.h:30
configdb_st::sdlrenderquality
int sdlrenderquality
Definition: configdb.h:35
D81_SIZE
#define D81_SIZE
Definition: d81access.h:22
configdb_define_emulator_options
void configdb_define_emulator_options(void)
Definition: configdb.c:36
xemugui_init
int xemugui_init(const char *name)
Definition: emutools_gui.c:82
cpu_clock_speed_string
const char * cpu_clock_speed_string
Definition: mega65.c:75
MEMINITDATA_HICKUP_SIZE
#define MEMINITDATA_HICKUP_SIZE
Definition: memcontent.h:27
configdb_st::hickup
char * hickup
Definition: configdb.h:36
block
Uint32 block
Definition: fat32.c:156
REG_SPRPTR_B1
#define REG_SPRPTR_B1
Definition: vic4.h:117
map_offset_low
int map_offset_low
Definition: memory_mapper.c:142
TARGET_NAME
#define TARGET_NAME
Definition: xemu-target.h:1
emutools_files.h
configdb_st::extbanner
char * extbanner
Definition: configdb.h:38
memory_get_cpu_io_port
Uint8 memory_get_cpu_io_port(int addr)
Definition: memory_mapper.c:763
vic_sprp_legacy
int vic_sprp_legacy
Definition: vic4.h:246
APP_ORG
#define APP_ORG
Definition: emutools.h:50
xemu_malloc
void * xemu_malloc(size_t size)
Definition: emutools.c:226
Cia6526::PRA
Uint8 PRA
Definition: cia6526.h:46
DEBUGPRINT
#define DEBUGPRINT(...)
Definition: emutools_basicdefs.h:171
xemu_save_file
int xemu_save_file(const char *filename_in, void *data, int size, const char *cry)
Definition: emutools_files.c:622
m65mon_set_trace
void m65mon_set_trace(int m)
TEXTURE_WIDTH
#define TEXTURE_WIDTH
Definition: vic4.h:41
vic4_close_frame_access
void vic4_close_frame_access(void)
Definition: vic4.c:217
map_mask
int map_mask
Definition: memory_mapper.c:142
emutools_socketapi.h
m65mon_empty_command
void m65mon_empty_command(void)
vic_reset
void vic_reset(void)
Definition: vic4.c:143
VIRTUAL_SHIFT_POS
#define VIRTUAL_SHIFT_POS
Definition: commodore_lcd.c:84
xemu_get_microseconds
unsigned int xemu_get_microseconds(void)
Definition: emutools.c:205
configdb_st::hicked
int hicked
Definition: configdb.h:92
Cia6526::PRB
Uint8 PRB
Definition: cia6526.h:46
ERROR_WINDOW
#define ERROR_WINDOW(...)
Definition: xep128.h:116
memory_mapper.h
rom_clear_reports
void rom_clear_reports(void)
Definition: rom.c:48
sdcard_init
int sdcard_init(const char *fn, const int virtsd_flag, const int default_d81_is_from_sd_in)
Definition: sdcard.c:328
XEMU_LIKELY
#define XEMU_LIKELY(__x__)
Definition: emutools_basicdefs.h:124
uart_monitor.h
memory_set_do_map
void memory_set_do_map(void)
Definition: memory_mapper.c:774
mega65_uuid
Uint8 mega65_uuid[8]
Definition: memory_mapper.c:73
last_dd00_bits
Uint8 last_dd00_bits
Definition: mega65.c:85
map_megabyte_low
int map_megabyte_low
Definition: memory_mapper.c:142
rtc_regs
Uint8 rtc_regs[6]
Definition: memory_mapper.c:75
configdb_st::autoload
int autoload
Definition: configdb.h:34
hypervisor_debug_invalidate
void hypervisor_debug_invalidate(const char *reason)
Definition: hypervisor.c:411
NL
#define NL
Definition: fat32.c:37
CPU65_PF_V
#define CPU65_PF_V
Definition: cpu65.h:24
eth65_init
int eth65_init(const char *options)
Definition: ethernet65.c:560
CPU65_PF_I
#define CPU65_PF_I
Definition: cpu65.h:28
configdb_st::useutilmenu
int useutilmenu
Definition: configdb.h:80
emutools_config.h
hypervisor.h
configdb
struct configdb_st configdb
Definition: configdb.c:34
newhack
int newhack
Definition: mega65.c:57
compress_sd_image.r
def r
Definition: compress_sd_image.py:76
vic_chrp_legacy
int vic_chrp_legacy
Definition: vic4.h:246
xemu_post_init
int xemu_post_init(const char *window_title, int is_resizable, int texture_x_size, int texture_y_size, int logical_x_size, int logical_y_size, int win_x_size, int win_y_size, Uint32 pixel_format, int n_colours, const Uint8 *colours, Uint32 *store_palette, int render_scale_quality, int locked_texture_update, void(*shutdown_callback)(void))
Definition: emutools.c:908
xemu_load_file
int xemu_load_file(const char *filename, void *store_to, int min_size, int max_size, const char *cry)
Definition: emutools_files.c:674
SID_CYCLES_PER_SEC
#define SID_CYCLES_PER_SEC
Definition: commodore_65.h:32
m65mon_dumpmem28
void m65mon_dumpmem28(int addr)
DMA_FEATURE_DYNMODESET
#define DMA_FEATURE_DYNMODESET
Definition: dma65.h:24
emulator_speed_title
char emulator_speed_title[]
Definition: commodore_65.c:78
rom.h
cpu65.h
cpu65_read_callback
Uint8 cpu65_read_callback(Uint16 addr)
Definition: commodore_65.c:711
rom_stubrom_requested
int rom_stubrom_requested
Definition: rom.c:32
CPU_STEP_MULTI_OPS
#define CPU_STEP_MULTI_OPS
Definition: xemu-target.h:6
cia_init
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))
Definition: cia6526.c:98
configdb_st::selectedgui
char * selectedgui
Definition: configdb.h:68
ARE_YOU_SURE_DEFAULT_YES
#define ARE_YOU_SURE_DEFAULT_YES
Definition: emutools.h:125
xemu_timekeeping_start
void xemu_timekeeping_start(void)
Definition: emutools.c:1122
meminitdata_onboard
const Uint8 meminitdata_onboard[MEMINITDATA_ONBOARD_SIZE]
Definition: memcontent.c:2371
hypervisor_debug
void hypervisor_debug(void)
Definition: hypervisor.c:598
dma_update_multi_steps
int dma_update_multi_steps(int do_for_cycles)
Definition: dma65.c:405
configdb_st::syscon
int syscon
Definition: configdb.h:34
size
int size
Definition: inject.c:37
cia_dump_state
void cia_dump_state(struct Cia6526 *cia)
Definition: cia6526.c:323
configdb_st::hyperdebug
int hyperdebug
Definition: configdb.h:75
fpga_switches
int fpga_switches
Definition: io_mapper.c:37
main
int main(int argc, char **argv)
Definition: mega65.c:784
m65mon_do_trace
void m65mon_do_trace(void)
D6XX_registers
Uint8 D6XX_registers[0x100]
Definition: io_mapper.c:38
cpu65_reset
void cpu65_reset(void)
Definition: cpu65.c:353
ARE_YOU_SURE
int ARE_YOU_SURE(const char *s, int flags)
Definition: emutools.c:1202
configdb_st::stereoseparation
int stereoseparation
Definition: configdb.h:99
hypervisor_is_debugged
int hypervisor_is_debugged
Definition: hypervisor.c:43
REG_CHARPTR_B1
#define REG_CHARPTR_B1
Definition: vic4.h:114
sdcard.h
reset_mega65_asked
int reset_mega65_asked(void)
Definition: mega65.c:537
meminitdata_banner
const Uint8 meminitdata_banner[MEMINITDATA_BANNER_SIZE]
Definition: memcontent.c:1703
OSD
#define OSD(...)
Definition: xep128.h:100
xemu_load_filepath
char xemu_load_filepath[PATH_MAX]
Definition: emutools_files.c:35
cpu65_get_pf
Uint8 cpu65_get_pf(void)
Definition: cpu65.c:331
inject_register_prg
int inject_register_prg(const char *prg_fn, int prg_mode)
Definition: inject.c:140
videostd_frametime
int videostd_frametime
Definition: vic4.c:84
memory_debug_write_phys_addr
void memory_debug_write_phys_addr(int addr, Uint8 data)
Definition: memory_mapper.c:960
in_hypervisor
int in_hypervisor
Definition: hypervisor.c:40
dma_init
void dma_init(unsigned int revision)
Definition: dma65.c:465
memcontent.h
configdb_st::sdimg
char * sdimg
Definition: configdb.h:45
audio65_sid_inc_framecount
void audio65_sid_inc_framecount(void)
Definition: audio65.c:120
m65_snapshot.h
mask
int mask
Definition: dma65.c:83
dump_memory
int dump_memory(const char *fn)
Definition: mega65.c:446
AUDIO_SAMPLE_FREQ
#define AUDIO_SAMPLE_FREQ
Definition: commodore_65.h:33
APP_DESC_APPEND
#define APP_DESC_APPEND
Definition: emutools.h:52
Uint16
uint16_t Uint16
Definition: fat32.c:50
xemugui_iteration
int xemugui_iteration(void)
Definition: emutools_gui.c:120
emutools_hid.h
configdb_st::mega65_model
int mega65_model
Definition: configdb.h:91
meminitdata_chrwom
const Uint8 meminitdata_chrwom[MEMINITDATA_CHRWOM_SIZE]
Definition: memcontent.c:27
DMA_FEATURE_HACK
#define DMA_FEATURE_HACK
Definition: dma65.h:26
configdb_st::snapload
char * snapload
Definition: configdb.h:33
dma65.h
TEXTURE_HEIGHT
#define TEXTURE_HEIGHT
Definition: vic4.h:42
xemu_window_snap_to_optimal_size
void xemu_window_snap_to_optimal_size(int forced)
Definition: emutools.c:808
configdb_st::disk9
char * disk9
Definition: configdb.h:31
configdb_st::dmarev
int dmarev
Definition: configdb.h:35
configdb_st::prgmode
int prgmode
Definition: configdb.h:35
hypervisor_start_machine
void hypervisor_start_machine(void)
Definition: hypervisor.c:248
name
const char * name
Definition: joystick.c:46
INITIAL_WINDOW_HEIGHT
#define INITIAL_WINDOW_HEIGHT
Definition: mega65.c:53
nvram
Uint8 nvram[64]
Definition: memory_mapper.c:71
meminitdata_initrom
const Uint8 meminitdata_initrom[MEMINITDATA_INITROM_SIZE]
Definition: memcontent.c:2724
DEBUG
#define DEBUG(...)
Definition: emutools_basicdefs.h:167
videostd_changed
int videostd_changed
Definition: vic4.c:86
eth65_shutdown
void eth65_shutdown(void)
Definition: ethernet65.c:521
TEXTURE_FORMAT
#define TEXTURE_FORMAT
Definition: mega65.h:39
configdb_st::fast_mhz
double fast_mhz
Definition: configdb.h:101
last_reset_type
const char * last_reset_type
Definition: mega65.c:86
cpu65_step
int cpu65_step(void)
Definition: cpu65.c:796
CPU65_PF_N
#define CPU65_PF_N
Definition: cpu65.h:23
MEMINITDATA_CRAMUTILS_SIZE
#define MEMINITDATA_CRAMUTILS_SIZE
Definition: memcontent.h:31
sdl_pref_dir
char * sdl_pref_dir
Definition: emutools.c:97
FATAL
#define FATAL(...)
Definition: xep128.h:117
IS_RESTORE_PRESSED
#define IS_RESTORE_PRESSED()
Definition: c64_kbd_mapping.h:33
D7XX
Uint8 D7XX[0x100]
Definition: io_mapper.c:39
MEMINITDATA_INITROM_SIZE
#define MEMINITDATA_INITROM_SIZE
Definition: memcontent.h:43
configdb_st::defd81fromsd
int defd81fromsd
Definition: configdb.h:48
configdb_st::dumpmem
char * dumpmem
Definition: configdb.h:32
window_title_info_addon
char * window_title_info_addon
Definition: emutools.c:91
vic_registers
Uint8 vic_registers[0x80]
Definition: vic4.c:43
registered_screenshot_request
int registered_screenshot_request
Definition: mega65.c:83
xemu_safe_file_size_by_name
off_t xemu_safe_file_size_by_name(const char *name)
Definition: emutools_files.c:592
input_init
void input_init(void)
Definition: input_devices.c:410
configdb_st::hyperserialascii
int hyperserialascii
Definition: configdb.h:77
XEMU_UNLIKELY
#define XEMU_UNLIKELY(__x__)
Definition: emutools_basicdefs.h:125
audio65.h
c64_kbd_mapping.h
configdb_st::extflashutil
char * extflashutil
Definition: configdb.h:42
hickup_is_overriden
int hickup_is_overriden
Definition: hypervisor.c:42
C128_SPEED_BIT_BUG
#define C128_SPEED_BIT_BUG
Definition: mega65.c:98
INITIAL_WINDOW_WIDTH
#define INITIAL_WINDOW_WIDTH
Definition: mega65.c:52
emutools_umon.h
memory_set_cpu_io_port_ddr_and_data
void memory_set_cpu_io_port_ddr_and_data(Uint8 p0, Uint8 p1)
Definition: memory_mapper.c:755