40 #define ALLOW_CPU_CUSTOM_FUNCTIONS_INCLUDE
50 #define chip_ram (main_ram + 0)
51 #define fast_ram (main_ram + 0x20000)
52 #define extra_ram (main_ram + 0x40000)
92 #define MEM_SLOT_C64_8KROM_A000 0x200
93 #define MEM_SLOT_C64_4KROM_D000 0x220
94 #define MEM_SLOT_OLD_4K_IO_D000 0x230
95 #define MEM_SLOT_C64_8KROM_E000 0x240
96 #define MEM_SLOT_C65_8KROM_8000 0x260
97 #define MEM_SLOT_C65_8KROM_A000 0x280
98 #define MEM_SLOT_C65_8KROM_E000 0x2A0
99 #define MEM_SLOT_C65_4KROM_C000 0x2C0
100 #define MEM_SLOT_DMA_RD_SRC 0x2D0
101 #define MEM_SLOT_DMA_WR_SRC 0x2D1
102 #define MEM_SLOT_DMA_RD_DST 0x2D2
103 #define MEM_SLOT_DMA_WR_DST 0x2D3
104 #define MEM_SLOT_DMA_RD_LST 0x2D4
105 #define MEM_SLOT_CPU_32BIT 0x2D5
106 #define MEM_SLOT_DEBUG_RESOLVER 0x2D6
107 #define MEM_SLOTS 0x2D7
109 #define VIC3_ROM_MASK_8000 0x08
110 #define VIC3_ROM_MASK_A000 0x10
111 #define VIC3_ROM_MASK_C000 0x20
112 #define VIC3_ROM_MASK_E000 0x80
114 #define MAP_MARKER_DUMMY_OFFSET 0x2000
125 static int applied_memcfg[9];
126 static int memcfg_cpu_io_port_policy_A000_to_BFFF;
127 static int memcfg_cpu_io_port_policy_D000_to_DFFF;
128 static int memcfg_cpu_io_port_policy_E000_to_FFFF;
130 static const int memcfg_cpu_io_port_policies_A000_to_BFFF[8] = {
133 static const int memcfg_cpu_io_port_policies_D000_to_DFFF[8] = {
136 static const int memcfg_cpu_io_port_policies_E000_to_FFFF[8] = {
140 static Uint8 memcfg_vic3_rom_mapping_last, memcfg_cpu_io_port_last;
141 static Uint8 cpu_io_port[2];
143 static int map_marker_low, map_marker_high;
148 #define DEFINE_READER(name) static Uint8 name ( MEMORY_HANDLERS_ADDR_TYPE )
149 #define DEFINE_WRITER(name) static void name ( MEMORY_HANDLERS_ADDR_TYPE, Uint8 data )
217 sprintf(msg,
"Unhandled memory read operation for linear address $%X (PC=$%04X)",
GET_READER_OFFSET(), cpu65.pc);
236 sprintf(msg,
"Unhandled memory write operation for linear address $%X data = $%02X (PC=$%04X)",
GET_WRITER_OFFSET(),
data, cpu65.pc);
241 FATAL(
"Exit on request after illegal memory access");
253 FATAL(
"Unhandled physical memory mapping on read map. Xemu software bug?");
256 FATAL(
"Unhandled physical memory mapping on write map. Xemu software bug?");
259 FATAL(
"Unreferenced physical memory mapping on read map. Xemu software bug?");
262 FATAL(
"Unreferenced physical memory mapping on write map. Xemu software bug?");
340 { 0x100, 0x1F7FF, chip_ram_from_page1_reader, chip_ram_from_page1_writer },
342 { 0, 0xFF, zero_physical_page_reader, zero_physical_page_writer },
344 { 0x20000, 0x3FFFF, fast_ram_reader, fast_ram_writer },
345 { 0x40000, 0x5FFFF, extra_ram_reader, extra_ram_writer },
347 { 0x1F800, 0x1FFFF, colour_ram_reader, colour_ram_writer },
350 { 0xFFD0000, 0xFFD3FFF, m65_io_reader, m65_io_writer },
352 { 0xFF80000, 0xFF87FFF, colour_ram_reader, colour_ram_writer },
353 { 0xFFF8000, 0xFFFBFFF, hypervisor_ram_reader, hypervisor_ram_writer },
354 { 0xFF7E000, 0xFF7FFFF, dummy_reader, char_wom_writer },
355 { 0xFFDE800, 0xFFDEFFF, eth_buffer_reader, eth_buffer_writer },
356 { 0xFFD6000, 0xFFD6FFF, disk_buffers_reader, disk_buffers_writer },
357 { 0xFFD7000, 0xFFD7FFF, i2c_io_reader, i2c_io_writer },
358 { 0x8000000, 0x8000000 +
SLOW_RAM_SIZE - 1, slow_ram_reader, slow_ram_writer },
359 { 0x8000000 +
SLOW_RAM_SIZE, 0xFDFFFFF, dummy_reader, dummy_writer },
360 { 0x4000000, 0x7FFFFFF, dummy_reader, dummy_writer },
361 { 0xFE00000, 0xFE000FF, opl3_reader, opl3_writer },
362 { 0x60000, 0xFFFFF, dummy_reader, dummy_writer },
364 { 0, 0xFFFFFFF, invalid_mem_reader, invalid_mem_writer },
366 { INT_MIN, INT_MAX, fatal_mem_reader, fatal_mem_writer }
370 0x10000001, 0x10000000, unreferenced_mem_reader, unreferenced_mem_writer
380 static void phys_addr_decoder (
int phys,
int slot,
int hint_slot )
384 if (mem_page_phys[slot] == phys)
386 mem_page_phys[slot] = phys;
393 if (hint_slot >= 0 && mem_page_refp[hint_slot]->
end < 0xFFFFFFF) {
394 p = mem_page_refp[hint_slot];
395 if (phys >= p->
start && phys <= p->
end) {
397 DEBUGMEM(
"MEM: PHYS-MAP: slot#$%03X: slot hint TAKEN :)" NL, slot);
403 for (p = m65_memory_map; phys < p->
start || phys > p->
end; p++)
411 mem_page_refp[slot] = p;
413 DEBUGMEM(
"MEM: PHYS-MAP: slot#$%03X: phys = $%X mapped (area: $%X-$%X, rd_o=%X, wr_o=%X) [hint slot was: %03X]" NL,
424 static void XEMU_INLINE phys_addr_decoder_array (
int megabyte_offset,
int offset,
int slot,
int slots,
int hint_slot )
430 phys_addr_decoder(megabyte_offset | (offset & 0xFFFFF), slot, hint_slot);
439 #define MEM_TABLE_COPY(to,from,pages) do { \
440 memcpy(mem_page_rd_o + (to), mem_page_rd_o + (from), sizeof(int) * (pages)); \
441 memcpy(mem_page_wr_o + (to), mem_page_wr_o + (from), sizeof(int) * (pages)); \
442 memcpy(mem_page_rd_f + (to), mem_page_rd_f + (from), sizeof(mem_page_rd_f_type) * (pages)); \
443 memcpy(mem_page_wr_f + (to), mem_page_wr_f + (from), sizeof(mem_page_wr_f_type) * (pages)); \
444 memcpy(mem_page_refp + (to), mem_page_refp + (from), sizeof(const struct m65_memory_map_st*) * (pages)); \
445 memcpy(mem_page_phys + (to), mem_page_phys + (from), sizeof(int) * (pages)); \
451 static void init_helper_custom_memtab_policy (
472 mem_page_phys[slot] = 1;
473 mem_page_refp[slot] = &impossible_mapping;
488 mem_page_phys[a] = 1;
489 phys_addr_decoder((a & 0xFF) << 8, a, -1);
512 memcfg_vic3_rom_mapping_last = 0xFF;
513 memcfg_cpu_io_port_last = 0xFF;
524 for (a = 0; a < 9; a++)
535 DEBUG(
"MEM: End of memory initiailization" NL);
542 static void apply_memory_config_0000_to_7FFF (
void ) {
546 if (applied_memcfg[0] != map_marker_low) {
548 applied_memcfg[0] = map_marker_low;
552 if (applied_memcfg[0]) {
554 applied_memcfg[0] = 0;
559 if (applied_memcfg[1] != map_marker_low) {
561 applied_memcfg[1] = map_marker_low;
565 if (applied_memcfg[1]) {
567 applied_memcfg[1] = 0;
572 if (applied_memcfg[2] != map_marker_low) {
574 applied_memcfg[2] = map_marker_low;
578 if (applied_memcfg[2]) {
580 applied_memcfg[2] = 0;
585 if (applied_memcfg[3] != map_marker_low) {
587 applied_memcfg[3] = map_marker_low;
590 if (applied_memcfg[3]) {
592 applied_memcfg[3] = 0;
596 static void apply_memory_config_8000_to_9FFF (
void ) {
598 if (applied_memcfg[4] >= 0) {
600 applied_memcfg[4] = -1;
603 if (applied_memcfg[4] != map_marker_high) {
605 applied_memcfg[4] = map_marker_high;
608 if (applied_memcfg[4]) {
610 applied_memcfg[4] = 0;
614 static void apply_memory_config_A000_to_BFFF (
void ) {
616 if (applied_memcfg[5] >= 0) {
618 applied_memcfg[5] = -1;
621 if (applied_memcfg[5] != map_marker_high) {
623 applied_memcfg[5] = map_marker_high;
626 if (applied_memcfg[5] != memcfg_cpu_io_port_policy_A000_to_BFFF) {
627 MEM_TABLE_COPY(0xA0, memcfg_cpu_io_port_policy_A000_to_BFFF, 0x20);
628 applied_memcfg[5] = memcfg_cpu_io_port_policy_A000_to_BFFF;
632 static void apply_memory_config_C000_to_CFFF (
void ) {
635 if (applied_memcfg[6] >= 0) {
637 applied_memcfg[6] = -1;
640 if (applied_memcfg[6] != map_marker_high) {
642 applied_memcfg[6] = map_marker_high;
645 if (applied_memcfg[6]) {
647 applied_memcfg[6] = 0;
651 static void apply_memory_config_D000_to_DFFF (
void ) {
654 if (applied_memcfg[7] != map_marker_high) {
656 applied_memcfg[7] = map_marker_high;
659 if (applied_memcfg[7] != memcfg_cpu_io_port_policy_D000_to_DFFF) {
660 MEM_TABLE_COPY(0xD0, memcfg_cpu_io_port_policy_D000_to_DFFF, 0x10);
661 applied_memcfg[7] = memcfg_cpu_io_port_policy_D000_to_DFFF;
665 static void apply_memory_config_E000_to_FFFF (
void ) {
667 if (applied_memcfg[8] >= 0) {
669 applied_memcfg[8] = -1;
672 if (applied_memcfg[8] != map_marker_high) {
674 applied_memcfg[8] = map_marker_high;
677 if (applied_memcfg[8] != memcfg_cpu_io_port_policy_E000_to_FFFF) {
678 MEM_TABLE_COPY(0xE0, memcfg_cpu_io_port_policy_E000_to_FFFF, 0x20);
679 applied_memcfg[8] = memcfg_cpu_io_port_policy_E000_to_FFFF;
699 if (
value != memcfg_vic3_rom_mapping_last) {
700 Uint8 change = memcfg_vic3_rom_mapping_last ^
value;
701 DEBUG(
"MEM: VIC-III ROM mapping change $%02X -> %02X" NL, memcfg_vic3_rom_mapping_last,
value);
702 memcfg_vic3_rom_mapping_last =
value;
705 apply_memory_config_8000_to_9FFF();
707 apply_memory_config_A000_to_BFFF();
709 apply_memory_config_C000_to_CFFF();
711 apply_memory_config_E000_to_FFFF();
716 static void apply_cpu_io_port_config (
void )
718 Uint8 desired = (cpu_io_port[1] | (~cpu_io_port[0])) & 7;
719 if (desired != memcfg_cpu_io_port_last) {
720 DEBUG(
"MEM: CPUIOPORT: port composite value (new one) is %d" NL, desired);
721 memcfg_cpu_io_port_last = desired;
722 memcfg_cpu_io_port_policy_A000_to_BFFF = memcfg_cpu_io_port_policies_A000_to_BFFF[desired];
723 memcfg_cpu_io_port_policy_D000_to_DFFF = memcfg_cpu_io_port_policies_D000_to_DFFF[desired];
724 memcfg_cpu_io_port_policy_E000_to_FFFF = memcfg_cpu_io_port_policies_E000_to_FFFF[desired];
726 apply_memory_config_A000_to_BFFF();
727 apply_memory_config_D000_to_DFFF();
728 apply_memory_config_E000_to_FFFF();
729 DEBUG(
"MEM: CPUIOPORT: new config had been applied" NL);
750 apply_cpu_io_port_config();
759 apply_cpu_io_port_config();
765 return cpu_io_port[
addr];
783 apply_memory_config_0000_to_7FFF();
784 apply_memory_config_8000_to_9FFF();
785 apply_memory_config_A000_to_BFFF();
786 apply_memory_config_C000_to_CFFF();
787 apply_memory_config_D000_to_DFFF();
788 apply_memory_config_E000_to_FFFF();
789 DEBUG(
"MEM: memory_set_do_map() applied" NL);
819 cpu65.cpu_inhibit_interrupts = 1;
820 DEBUG(
"CPU: MAP opcode, input A=$%02X X=$%02X Y=$%02X Z=$%02X" NL, cpu65.a, cpu65.x, cpu65.y, cpu65.z);
823 map_mask = (cpu65.z & 0xF0) | ( cpu65.x >> 4);
829 DEBUG(
"MEM: applying new memory configuration because of MAP CPU opcode" NL);
841 if (cpu65.cpu_inhibit_interrupts) {
842 cpu65.cpu_inhibit_interrupts = 0;
843 DEBUG(
"CPU: EOM, interrupts were disabled because of MAP till the EOM" NL);
845 DEBUG(
"CPU: NOP not treated as EOM (no MAP before)" NL);
871 register int addr = cpu_get_flat_addressing_mode_address(cpu65.z);
878 register int addr = cpu_get_flat_addressing_mode_address(cpu65.z);
887 for (
int shift = 0, ret = 0,
addr = cpu_get_flat_addressing_mode_address(
index) ;; ) {
900 for (
int a = 0,
addr = cpu_get_flat_addressing_mode_address(
index) ;; ) {
968 int slot = cpu_addr >> 8;