Skip to content

Commit

Permalink
MEGA65: new memory decoder #209 #378
Browse files Browse the repository at this point in the history
This quite big change rewrites the MEGA65 emulation memory decoder
subsystem. Some of the reasons:

* Create a new, not overcomplicated decoder which can be understood at
  all without major headache, and can be also faster as per #209
* Taking account some new findings about how C65 worked (both Xemu and
  MEGA65 was wrong here) and adopted since then by MEGA65 as per #378
* More about the future (not ready in this commit): allow functionality
  for debugger implementation "watchmem" which can monitor about every
  memory r/w events debugger want to check as per #11

This commit is quite big as was mentioned, and may introduce some
regressions. So it's important to have feedback in those cases. Also it
changes the behaviour of memory decoding (#378). The new decoder seems
to be already faster than the old one and more easy to understand and
maintain. Also there is some room for future improvements still in every
areas, including optimizations. The "memwatch" part currently is not
usable though, but the basis are there to be able to implement that at
all (wouldn't be possible with the older scheme).
  • Loading branch information
lgblgblgb committed May 12, 2024
1 parent b6db38e commit 45f9ebf
Show file tree
Hide file tree
Showing 18 changed files with 1,108 additions and 903 deletions.
122 changes: 65 additions & 57 deletions targets/mega65/cpu_custom_functions.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* A work-in-progess MEGA65 (Commodore 65 clone origins) emulator
Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
Copyright (C)2016-2022 LGB (Gábor Lénárt) <[email protected]>
Copyright (C)2016-2024 LGB (Gábor Lénárt) <[email protected]>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand All @@ -25,49 +25,37 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef __XEMU_MEGA65_CPU_CUSTOM_FUNCTIONS_H_INCLUDED
#define __XEMU_MEGA65_CPU_CUSTOM_FUNCTIONS_H_INCLUDED

#ifdef CPU_CUSTOM_MEMORY_FUNCTIONS_H
#define CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR static XEMU_INLINE
#else
#ifndef ALLOW_CPU_CUSTOM_FUNCTIONS_INCLUDE
#error "cpu_custom_functions.h must not be included by anything other than the CPU emulator and memory_mapper.c"
#endif
#define CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR
#endif
#define MEM_USE_DATA_POINTERS

#if 1
#define CALL_MEMORY_READER(slot,addr) mem_page_rd_f[slot](mem_page_rd_o[slot] + ((addr) & 0xFF))
#define CALL_MEMORY_WRITER(slot,addr,data) mem_page_wr_f[slot](mem_page_wr_o[slot] + ((addr) & 0xFF), data)
#define CALL_MEMORY_READER_PAGED(slot,addr) mem_page_rd_f[slot](mem_page_rd_o[slot] + addr)
#define CALL_MEMORY_WRITER_PAGED(slot,addr,data) mem_page_wr_f[slot](mem_page_wr_o[slot] + addr, data)
#define SAVE_USED_SLOT(slot) last_slot_ref = slot
#define MEMORY_HANDLERS_ADDR_TYPE int area_offset
#define GET_READER_OFFSET() area_offset
#define GET_WRITER_OFFSET() area_offset
#define GET_OFFSET_BYTE_ONLY() area_offset
#define GET_USED_SLOT() last_slot_ref
#ifdef MEM_USE_DATA_POINTERS
#define MEM_DATA_POINTER_HINTING_STRENGTH(_condition) XEMU_LIKELY(_condition)
//#define MEM_DATA_POINTER_HINTING_STRENGTH(_condition) (_condition)
#endif

#if 0
#define CALL_MEMORY_READER(slot,addr) mem_page_rd_f[slot](slot, addr)
#define CALL_MEMORY_WRITER(slot,addr,data) mem_page_wr_f[slot](slot, addr, data)
#define CALL_MEMORY_READER_PAGED(slot,addr) mem_page_rd_f[slot](slot, addr)
#define CALL_MEMORY_WRITER_PAGED(slot,addr,data) mem_page_wr_f[slot](slot, addr, data)
#define SAVE_USED_SLOT(slot)
#define MEMORY_HANDLERS_ADDR_TYPE int slot, Uint8 lo_addr
#define GET_READER_OFFSET() (mem_page_rd_o[slot] + lo_addr)
#define GET_WRITER_OFFSET() (mem_page_wr_o[slot] + lo_addr)
#define GET_OFFSET_BYTE_ONLY() lo_addr
#define GET_USED_SLOT() slot
#ifdef CPU_CUSTOM_MEMORY_FUNCTIONS_H
# define CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR static XEMU_INLINE
#else
# ifndef ALLOW_CPU_CUSTOM_FUNCTIONS_INCLUDE
# error "cpu_custom_functions.h must not be included by anything other than the CPU emulator and memory_mapper.c"
# endif
# define CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR
#endif

extern Uint32 ref_slot;

typedef Uint8 (*mem_slot_rd_func_t)(const Uint32 addr32);
typedef void (*mem_slot_wr_func_t)(const Uint32 addr32, const Uint8 data);

typedef Uint8 (*mem_page_rd_f_type)(MEMORY_HANDLERS_ADDR_TYPE);
typedef void (*mem_page_wr_f_type)(MEMORY_HANDLERS_ADDR_TYPE, Uint8 data);
#define MEM_SLOTS_TOTAL_EXPORTED 0x106
extern mem_slot_rd_func_t mem_slot_rd_func[MEM_SLOTS_TOTAL_EXPORTED];
extern mem_slot_wr_func_t mem_slot_wr_func[MEM_SLOTS_TOTAL_EXPORTED];
extern Uint32 mem_slot_rd_addr32[MEM_SLOTS_TOTAL_EXPORTED];
extern Uint32 mem_slot_wr_addr32[MEM_SLOTS_TOTAL_EXPORTED];
#ifdef MEM_USE_DATA_POINTERS
extern Uint8 *mem_slot_rd_data[MEM_SLOTS_TOTAL_EXPORTED];
extern Uint8 *mem_slot_wr_data[MEM_SLOTS_TOTAL_EXPORTED];
#endif

extern int mem_page_rd_o[];
extern int mem_page_wr_o[];
extern mem_page_rd_f_type mem_page_rd_f[];
extern mem_page_wr_f_type mem_page_wr_f[];
extern int cpu_rmw_old_data;

extern void cpu65_write_linear_opcode_callback ( Uint8 data );
Expand All @@ -77,40 +65,60 @@ extern Uint32 cpu65_read_linear_long_opcode_callback ( const Uint8 index );

extern void cpu65_illegal_opcode_callback ( void );

extern int memory_cpurd2linear_xlat ( Uint16 cpu_addr);
extern Uint32 memory_cpu_addr_to_linear ( const Uint16 cpu_addr, Uint32 *wr_addr_p );
#define memory_cpurd2linear_xlat(_cpu_addr) memory_cpu_addr_to_linear(_cpu_addr,NULL)

CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR Uint8 cpu65_read_callback ( Uint16 addr ) {
return CALL_MEMORY_READER(addr >> 8, addr);
}
CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR void cpu65_write_callback ( Uint16 addr, Uint8 data ) {
CALL_MEMORY_WRITER(addr >> 8, addr, data);
}
CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR Uint8 cpu65_read_paged_callback ( Uint8 page, Uint8 addr8 ) {
return CALL_MEMORY_READER_PAGED(page, addr8);
CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR Uint8 cpu65_read_callback ( const Uint16 addr16 )
{
#ifdef MEM_USE_DATA_POINTERS
register const Uint8 *p = mem_slot_rd_data[addr16 >> 8];
if (MEM_DATA_POINTER_HINTING_STRENGTH(p))
return p[addr16 & 0xFFU];
#endif
ref_slot = addr16 >> 8;
return mem_slot_rd_func[ref_slot](mem_slot_rd_addr32[ref_slot] + (addr16 & 0xFFU));
}
CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR void cpu65_write_paged_callback ( Uint8 page, Uint8 addr8, Uint8 data ) {
CALL_MEMORY_WRITER_PAGED(page, addr8, data);

CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR void cpu65_write_callback ( const Uint16 addr16, const Uint8 data )
{
#ifdef MEM_USE_DATA_POINTERS
register Uint8 *p = mem_slot_wr_data[addr16 >> 8];
if (MEM_DATA_POINTER_HINTING_STRENGTH(p)) {
p[addr16 & 0xFFU] = data;
return;
}
#endif
ref_slot = addr16 >> 8;
mem_slot_wr_func[ref_slot](mem_slot_wr_addr32[ref_slot] + (addr16 & 0xFFU), data);
}

// Called in case of an RMW (read-modify-write) opcode write access.
// Original NMOS 6502 would write the old_data first, then new_data.
// It has no inpact in case of normal RAM, but it *does* with an I/O register in some cases!
// CMOS line of 65xx (probably 65CE02 as well?) seems not write twice, but read twice.
// However this leads to incompatibilities, as some software used the RMW behavour by intent.
// Thus MEGA65 fixed the problem to "restore" the old way of RMW behaviour.
// I also follow this path here, even if it's *NOT* what 65CE02 would do actually!
CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR void cpu65_write_rmw_callback ( Uint16 addr, Uint8 old_data, Uint8 new_data ) {
CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR void cpu65_write_rmw_callback ( const Uint16 addr16, const Uint8 old_data, const Uint8 new_data )
{
// Nah! It seems, enabling this, makes some software _slower_ ... Like polymega. Probably it does lots of I/O writes, so this
// extra optimization just takes time to check which won't be used anyway in case of I/O. Oh, well.
#if 0
#ifdef MEM_USE_DATA_POINTERS
// if there is data pointer, it cannot be I/O anyway, so the whole RMW business shouldn't matter here
register Uint8 *p = mem_slot_wr_data[addr16 >> 8];
if (p) {
p[addr16 & 0xFFU] = new_data;
return;
}
#endif
#endif
cpu_rmw_old_data = old_data;
// It's the backend's (which realizes the op) responsibility to handle or not handle the RMW behaviour,
// based on the fact if cpu_rmw_old_data is non-negative (being an int type) when it holds the "old_data".
CALL_MEMORY_WRITER(addr >> 8, addr, new_data);
ref_slot = addr16 >> 8;
mem_slot_wr_func[ref_slot](mem_slot_wr_addr32[ref_slot] + (addr16 & 0xFFU), new_data);
cpu_rmw_old_data = -1;
}
CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR void cpu65_write_rmw_paged_callback ( Uint8 page, Uint8 addr8, Uint8 old_data, Uint8 new_data ) {
cpu_rmw_old_data = old_data;
CALL_MEMORY_WRITER_PAGED(page, addr8, new_data);
cpu_rmw_old_data = -1;
}

#undef CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR

#endif
6 changes: 3 additions & 3 deletions targets/mega65/dma65.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* F018 DMA core emulation for MEGA65
Part of the Xemu project. https://github.com/lgblgblgb/xemu
Copyright (C)2016-2023 LGB (Gábor Lénárt) <[email protected]>
Copyright (C)2016-2024 LGB (Gábor Lénárt) <[email protected]>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -87,13 +87,13 @@ static struct {

static inline Uint8 io_dma_reader ( const unsigned int addr )
{
return io_read((addr & 0xFFFU) + (vic_iomode << 12));
return io_read((addr & 0xFFFU) + (io_mode << 12));
}


static inline void io_dma_writer ( const unsigned int addr, Uint8 data )
{
io_write((addr & 0xFFFU) + (vic_iomode << 12), data);
io_write((addr & 0xFFFU) + (io_mode << 12), data);
}


Expand Down
2 changes: 1 addition & 1 deletion targets/mega65/dma65.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* F018 DMA core emulation for MEGA65
Part of the Xemu project. https://github.com/lgblgblgb/xemu
Copyright (C)2016-2023 LGB (Gábor Lénárt) <[email protected]>
Copyright (C)2016-2024 LGB (Gábor Lénárt) <[email protected]>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down
8 changes: 4 additions & 4 deletions targets/mega65/hdos.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* A work-in-progess MEGA65 (Commodore 65 clone origins) emulator
Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
Copyright (C)2016-2023 LGB (Gábor Lénárt) <[email protected]>
Copyright (C)2016-2024 LGB (Gábor Lénárt) <[email protected]>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -97,7 +97,7 @@ static int copy_mem_from_user ( Uint8 *target, int max_size, const int terminato
// DOS calls should not have user specified data >= $8000!
if (source_cpu_addr >= 0x8000)
return -1;
const Uint8 byte = memory_debug_read_cpu_addr(source_cpu_addr++);
const Uint8 byte = debug_read_cpu_byte(source_cpu_addr++);
*target++ = byte;
len++;
if (len >= max_size) {
Expand All @@ -124,7 +124,7 @@ static int copy_mem_to_user ( unsigned int target_cpu_addr, const Uint8 *source,
while (size) {
if (target_cpu_addr >= 0x8000)
return -1;
memory_debug_write_cpu_addr(target_cpu_addr++, *source++);
debug_write_cpu_byte(target_cpu_addr++, *source++);
size--;
len++;
}
Expand Down Expand Up @@ -465,7 +465,7 @@ static void hdos_virt_loadfile ( const Uint32 addr_base )
break;
}
for (const Uint8 *b = buffer; ret > 0; ret--, b++, addr_ofs++)
memory_debug_write_phys_addr(addr_base + (addr_ofs & 0xFFFFFF), *b);
debug_write_linear_byte(addr_base + (addr_ofs & 0xFFFFFF), *b);
}
close(fd);
if (ret < 0 || loaded != st.st_size) {
Expand Down
2 changes: 1 addition & 1 deletion targets/mega65/hdos.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* A work-in-progess MEGA65 (Commodore 65 clone origins) emulator
Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
Copyright (C)2016-2023 LGB (Gábor Lénárt) <[email protected]>
Copyright (C)2016-2024 LGB (Gábor Lénárt) <[email protected]>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down
71 changes: 40 additions & 31 deletions targets/mega65/hypervisor.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* A work-in-progess MEGA65 (Commodore 65 clone origins) emulator
Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
Copyright (C)2016-2023 LGB (Gábor Lénárt) <[email protected]>
Copyright (C)2016-2024 LGB (Gábor Lénárt) <[email protected]>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -37,7 +37,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <errno.h>


int in_hypervisor; // mega65 hypervisor mode
bool in_hypervisor; // mega65 hypervisor mode
char hyppo_version_string[64];
int hickup_is_overriden = 0;
int hypervisor_is_debugged = 0;
Expand Down Expand Up @@ -108,7 +108,7 @@ void hypervisor_enter_via_write_trap ( int trapno )
if (do_nop_check) {
// FIXME: for real there should be a memory reading function independent to the one used by the CPU, since
// this has some side effects to just fetch a byte to check something, which is otherwise used normally to fetch CPU opcodes and such
Uint8 skipped_byte = cpu65_read_callback(cpu65.pc);
Uint8 skipped_byte = debug_read_cpu_byte(cpu65.pc);
if (XEMU_UNLIKELY(skipped_byte != 0xEA && skipped_byte != 0xB8)) { // $EA = opcode for NOP, $B8 = opcode for CLV
char msg[256];
snprintf(msg, sizeof msg,
Expand Down Expand Up @@ -160,27 +160,26 @@ void hypervisor_enter ( int trapno )
D6XX_registers[0x4F] = map_megabyte_high >> 20;
D6XX_registers[0x50] = memory_get_cpu_io_port(0);
D6XX_registers[0x51] = memory_get_cpu_io_port(1);
D6XX_registers[0x52] = vic_iomode;
D6XX_registers[0x52] = io_mode;
//D6XX_registers[0x53] = 0; // GS $D653 - Hypervisor DMAgic source MB - *UNUSED*
//D6XX_registers[0x54] = 0; // GS $D654 - Hypervisor DMAgic destination MB - *UNUSED*
dma_get_list_addr_as_bytes(D6XX_registers + 0x55); // GS $D655-$D658 - Hypervisor DMAGic list address bits 27-0
// Now entering into hypervisor mode
in_hypervisor = 1; // this will cause apply_memory_config to map hypervisor RAM, also for checks later to out-of-bound execution of hypervisor RAM, etc ...
// In hypervisor mode, VIC4 I/O mode is implied. I also disable $D02F writing to take effect while in hypervisor mode in vic4.c!
vic_iomode = VIC4_IOMODE;
memory_set_cpu_io_port_ddr_and_data(0x3F, 0x35); // sets all-RAM + I/O config up!
// Now entering into hypervisor mode: we use memory_reconfigure() to set all the stuff needed + setting up "in_hypervisor" value as well
memory_reconfigure(
0, // D030 ROM banking turning off
VIC4_IOMODE, // VIC4 I/O mode to be used (on MEGA65, in hypervisor mode it's always the case! the handler in vic4.c ensures, we cannot even modify this)
0x3F, 0x35, // set CPU I/O port DDR+DATA: all-RAM + I/O config
map_megabyte_low, map_offset_low, // low mapping is left as-is
0xFFU << 20, 0xF0000U, // high mapping though is being modified
(map_mask & 0xFU) | 0x30U, // mapping: 0011XXXX (it seems low region map mask is not changed by hypervisor entry)
true // this will sets in_hypervisor to TRUE!!!!
);
cpu65.pf_d = 0; // clear decimal mode ... according to Paul, punnishment will be done, if it's removed :-)
cpu65.pf_i = 1; // disable IRQ in hypervisor mode
cpu65.pf_e = 1; // 8 bit stack in hypervisor mode
cpu65.sphi = 0xBE00; // set a nice shiny stack page
cpu65.bphi = 0xBF00; // ... and base page (aka zeropage)
cpu65.s = 0xFF;
// Set mapping for the hypervisor
map_mask = (map_mask & 0xF) | 0x30; // mapping: 0011XXXX (it seems low region map mask is not changed by hypervisor entry)
map_megabyte_high = 0xFF << 20;
map_offset_high = 0xF0000;
memory_set_vic3_rom_mapping(0); // for VIC-III rom mapping disable in hypervisor mode
memory_set_do_map(); // now the memory mapping is changed
machine_set_speed(0); // set machine speed (hypervisor always runs at M65 fast ... ??) FIXME: check this!
cpu65.pc = 0x8000 | (trapno << 2); // load PC with the address assigned for the given trap number
DEBUG("HYPERVISOR: entering into hypervisor mode, trap=$%02X (A=$%02X) @ $%04X -> $%04X" NL, trapno, cpu65.a, D6XX_registers[0x48] | (D6XX_registers[0x49] << 8), cpu65.pc);
Expand Down Expand Up @@ -255,7 +254,15 @@ void hypervisor_start_machine ( void )
hyppo_version_string[0] = '\0';
hdos_init(configdb.hdosvirt, configdb.hdosdir);
}
in_hypervisor = 0;
memory_reconfigure(
0,
VIC4_IOMODE,
0x3F, 0x35,
0, 0,
0, 0,
0,
false // this will set in_hypervisor to FALSE to ensure hypervisor_enter() won't fail if reset from hypervisor mode
);
hypervisor_queued_trap = -1;
hypervisor_is_first_call = 1;
execution_range_check_gate = 0;
Expand All @@ -280,7 +287,7 @@ static inline void first_leave ( void )
cpu65.pc = new_pc;
// Since we have overriden ROM, we also must take the responsibility to do what Hyppo would also do:
// uploading chargen from the loaded ROM into the "char WOM".
memcpy(char_wom, main_ram + 0x2D000, 0x1000);
memcpy(char_ram, main_ram + 0x2D000, 0x1000);
} else {
DEBUGPRINT("ROM: no custom force-ROM policy, PC remains at $%04X" NL, cpu65.pc);
}
Expand Down Expand Up @@ -328,21 +335,23 @@ void hypervisor_leave ( void )
cpu65.pc = D6XX_registers[0x48] | (D6XX_registers[0x49] << 8);
if (current_hdos_func >= 0)
hdos_leave(current_hdos_func);
map_offset_low = ((D6XX_registers[0x4A] & 0xF) << 16) | (D6XX_registers[0x4B] << 8);
map_offset_high = ((D6XX_registers[0x4C] & 0xF) << 16) | (D6XX_registers[0x4D] << 8);
map_mask = (D6XX_registers[0x4A] >> 4) | (D6XX_registers[0x4C] & 0xF0);
map_megabyte_low = D6XX_registers[0x4E] << 20;
map_megabyte_high = D6XX_registers[0x4F] << 20;
memory_set_cpu_io_port_ddr_and_data(D6XX_registers[0x50], D6XX_registers[0x51]);
vic_iomode = D6XX_registers[0x52] & 3;
// Now leaving hypervisor mode: we use memory_reconfigure() to set all the stuff needed + setting up "in_hypervisor" value as well
memory_reconfigure(
vic_registers[0x30], // restore D030 ROM banking
D6XX_registers[0x52] & 3, // restore VIC4 I/O mode
D6XX_registers[0x50], D6XX_registers[0x51], // restore CPU I/O port DDR+DATA
D6XX_registers[0x4E] << 20, // restore MAP low megabyte
((D6XX_registers[0x4A] & 0xF) << 16) | (D6XX_registers[0x4B] << 8), // restore MAP low offset
D6XX_registers[0x4F] << 20, // restore MAP high megabyte
((D6XX_registers[0x4C] & 0xF) << 16) | (D6XX_registers[0x4D] << 8), // restore MAP high offset
(D6XX_registers[0x4A] >> 4) | (D6XX_registers[0x4C] & 0xF0), // restore MAP mask
false // this will sets in_hypervisor to FALSE!!!!
);
// GS $D653 - Hypervisor DMAgic source MB - *UNUSED*
// GS $D654 - Hypervisor DMAgic destination MB - *UNUSED*
dma_set_list_addr_from_bytes(D6XX_registers + 0x55); // GS $D655-$D658 - Hypervisor DMAGic list address bits 27-0
// Now leaving hypervisor mode ...
in_hypervisor = 0;
machine_set_speed(0); // restore speed ...
memory_set_vic3_rom_mapping(vic_registers[0x30]); // restore possible active VIC-III mapping
memory_set_do_map(); // restore mapping ...
if (XEMU_UNLIKELY(hypervisor_is_first_call)) {
if (trap_current != TRAP_RESET)
FATAL("First hypervisor TRAP is not RESET?!");
Expand Down Expand Up @@ -650,9 +659,9 @@ void hypervisor_debug ( void )
DEBUG("HYPERDEBUG: warning, execution in hypervisor memory without SPHI == $BE but $%02X" NL, cpu65.sphi >> 8);
if (XEMU_UNLIKELY(cpu65.bphi != 0xBF00))
DEBUG("HYPERDEBUG: warning, execution in hypervisor memory without BPHI == $BF but $%02X" NL, cpu65.bphi >> 8);
// FIXME: remove this? Reason: this is not even possible as in hypervisor mode vic_iomode cannot be altered via the usual $D02F "KEY" register ... [if there are no bugs ...]
if (XEMU_UNLIKELY(vic_iomode != VIC4_IOMODE))
DEBUG("HYPERDEBUG: warning, execution in hypervisor memory with VIC I/O mode of %X" NL, iomode_hexdigitids[vic_iomode]);
// FIXME: remove this? Reason: this is not even possible as in hypervisor mode io_mode cannot be altered via the usual $D02F "KEY" register ... [if there are no bugs ...]
if (XEMU_UNLIKELY(io_mode != VIC4_IOMODE))
DEBUG("HYPERDEBUG: warning, execution in hypervisor memory with VIC I/O mode of %X" NL, iomode_hexdigitids[io_mode]);
}
const Uint16 now_sp = cpu65.sphi | cpu65.s;
int sp_diff = (int)prev_sp - (int)now_sp;
Expand Down Expand Up @@ -710,7 +719,7 @@ void hypervisor_debug ( void )
(pf & CPU65_PF_I) ? 'I' : 'i',
(pf & CPU65_PF_Z) ? 'Z' : 'z',
(pf & CPU65_PF_C) ? 'C' : 'c',
iomode_hexdigitids[vic_iomode],
iomode_hexdigitids[io_mode],
within_hypervisor_ram ? debug_info[cpu65.pc - 0x8000].src_fn : "<NOT>",
within_hypervisor_ram ? debug_info[cpu65.pc - 0x8000].src_ln : 0,
within_hypervisor_ram ? debug_info[cpu65.pc - 0x8000].sym_name : "<NOT>",
Expand Down
Loading

0 comments on commit 45f9ebf

Please sign in to comment.