Xemu [doxygen]  hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
cpu_custom_functions.h
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 /* This source defines the memory access primitives used by the CPU emulator.
20  Do *NOT* include this header, it's intended for the CPU emulator, and
21  for memory_mapper.c. Some dual-mode solution is here, ie it can support
22  in-lined functions and "normal" ones. You must edit xemu-target.h for
23  that, commeting in/out the line with CPU_CUSTOM_MEMORY_FUNCTIONS_H #define */
24 
25 #ifndef __XEMU_MEGA65_CPU_CUSTOM_FUNCTIONS_H_INCLUDED
26 #define __XEMU_MEGA65_CPU_CUSTOM_FUNCTIONS_H_INCLUDED
27 
28 #ifdef CPU_CUSTOM_MEMORY_FUNCTIONS_H
29 #define CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR static XEMU_INLINE
30 #else
31 #ifndef ALLOW_CPU_CUSTOM_FUNCTIONS_INCLUDE
32 #error "cpu_custom_functions.h must not be included by anything other than the CPU emulator and memory_mapper.c"
33 #endif
34 #define CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR
35 #endif
36 
37 #if 1
38 #define CALL_MEMORY_READER(slot,addr) mem_page_rd_f[slot](mem_page_rd_o[slot] + ((addr) & 0xFF))
39 #define CALL_MEMORY_WRITER(slot,addr,data) mem_page_wr_f[slot](mem_page_wr_o[slot] + ((addr) & 0xFF), data)
40 #define CALL_MEMORY_READER_PAGED(slot,addr) mem_page_rd_f[slot](mem_page_rd_o[slot] + addr)
41 #define CALL_MEMORY_WRITER_PAGED(slot,addr,data) mem_page_wr_f[slot](mem_page_wr_o[slot] + addr, data)
42 #define SAVE_USED_SLOT(slot) last_slot_ref = slot
43 #define MEMORY_HANDLERS_ADDR_TYPE int area_offset
44 #define GET_READER_OFFSET() area_offset
45 #define GET_WRITER_OFFSET() area_offset
46 #define GET_OFFSET_BYTE_ONLY() area_offset
47 #define GET_USED_SLOT() last_slot_ref
48 #endif
49 
50 #if 0
51 #define CALL_MEMORY_READER(slot,addr) mem_page_rd_f[slot](slot, addr)
52 #define CALL_MEMORY_WRITER(slot,addr,data) mem_page_wr_f[slot](slot, addr, data)
53 #define CALL_MEMORY_READER_PAGED(slot,addr) mem_page_rd_f[slot](slot, addr)
54 #define CALL_MEMORY_WRITER_PAGED(slot,addr,data) mem_page_wr_f[slot](slot, addr, data)
55 #define SAVE_USED_SLOT(slot)
56 #define MEMORY_HANDLERS_ADDR_TYPE int slot, Uint8 lo_addr
57 #define GET_READER_OFFSET() (mem_page_rd_o[slot] + lo_addr)
58 #define GET_WRITER_OFFSET() (mem_page_wr_o[slot] + lo_addr)
59 #define GET_OFFSET_BYTE_ONLY() lo_addr
60 #define GET_USED_SLOT() slot
61 #endif
62 
63 
66 
67 extern int mem_page_rd_o[];
68 extern int mem_page_wr_o[];
71 extern int cpu_rmw_old_data;
72 
77 
78 extern void cpu65_illegal_opcode_callback ( void );
79 
80 extern int memory_cpurd2linear_xlat ( Uint16 cpu_addr);
81 
83  return CALL_MEMORY_READER(addr >> 8, addr);
84 }
87 }
89  return CALL_MEMORY_READER_PAGED(page, addr8);
90 }
92  CALL_MEMORY_WRITER_PAGED(page, addr8, data);
93 }
94 // Called in case of an RMW (read-modify-write) opcode write access.
95 // Original NMOS 6502 would write the old_data first, then new_data.
96 // It has no inpact in case of normal RAM, but it *does* with an I/O register in some cases!
97 // CMOS line of 65xx (probably 65CE02 as well?) seems not write twice, but read twice.
98 // However this leads to incompatibilities, as some software used the RMW behavour by intent.
99 // Thus MEGA65 fixed the problem to "restore" the old way of RMW behaviour.
100 // I also follow this path here, even if it's *NOT* what 65CE02 would do actually!
102  cpu_rmw_old_data = old_data;
103  // It's the backend's (which realizes the op) responsibility to handle or not handle the RMW behaviour,
104  // based on the fact if cpu_rmw_old_data is non-negative (being an int type) when it holds the "old_data".
105  CALL_MEMORY_WRITER(addr >> 8, addr, new_data);
106  cpu_rmw_old_data = -1;
107 }
109  cpu_rmw_old_data = old_data;
110  CALL_MEMORY_WRITER_PAGED(page, addr8, new_data);
111  cpu_rmw_old_data = -1;
112 }
113 
114 #undef CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR
115 
116 #endif
cpu65_write_rmw_callback
CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR void cpu65_write_rmw_callback(Uint16 addr, Uint8 old_data, Uint8 new_data)
Definition: cpu_custom_functions.h:101
mem_page_wr_f_type
void(* mem_page_wr_f_type)(MEMORY_HANDLERS_ADDR_TYPE, Uint8 data)
Definition: cpu_custom_functions.h:65
cpu_rmw_old_data
int cpu_rmw_old_data
Definition: memory_mapper.c:123
index
int index
Definition: vera.c:66
cpu65_read_linear_opcode_callback
Uint8 cpu65_read_linear_opcode_callback(void)
Definition: memory_mapper.c:869
CALL_MEMORY_WRITER_PAGED
#define CALL_MEMORY_WRITER_PAGED(slot, addr, data)
Definition: cpu_custom_functions.h:41
CALL_MEMORY_READER_PAGED
#define CALL_MEMORY_READER_PAGED(slot, addr)
Definition: cpu_custom_functions.h:40
addr
int addr
Definition: dma65.c:81
cpu65_illegal_opcode_callback
void cpu65_illegal_opcode_callback(void)
Definition: commodore_geos.c:709
mem_page_rd_f_type
Uint8(* mem_page_rd_f_type)(MEMORY_HANDLERS_ADDR_TYPE)
Definition: cpu_custom_functions.h:64
m65-memcontent-generator.data
data
Definition: m65-memcontent-generator.py:119
CALL_MEMORY_READER
#define CALL_MEMORY_READER(slot, addr)
Definition: cpu_custom_functions.h:38
Uint32
uint32_t Uint32
Definition: fat32.c:49
mem_page_rd_o
int mem_page_rd_o[]
Definition: memory_mapper.c:117
memory_cpurd2linear_xlat
int memory_cpurd2linear_xlat(Uint16 cpu_addr)
Definition: memory_mapper.c:966
Uint8
uint8_t Uint8
Definition: fat32.c:51
cpu65_write_linear_opcode_callback
void cpu65_write_linear_opcode_callback(Uint8 data)
Definition: memory_mapper.c:876
CALL_MEMORY_WRITER
#define CALL_MEMORY_WRITER(slot, addr, data)
Definition: cpu_custom_functions.h:39
mem_page_wr_f
mem_page_wr_f_type mem_page_wr_f[]
Definition: memory_mapper.c:120
cpu65_write_callback
CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR void cpu65_write_callback(Uint16 addr, Uint8 data)
Definition: cpu_custom_functions.h:85
cpu65_read_callback
CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR Uint8 cpu65_read_callback(Uint16 addr)
Definition: cpu_custom_functions.h:82
mem_page_wr_o
int mem_page_wr_o[]
Definition: memory_mapper.c:118
mem_page_rd_f
mem_page_rd_f_type mem_page_rd_f[]
Definition: memory_mapper.c:119
Uint16
uint16_t Uint16
Definition: fat32.c:50
CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR
#define CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR
Definition: cpu_custom_functions.h:34
cpu65_write_paged_callback
CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR void cpu65_write_paged_callback(Uint8 page, Uint8 addr8, Uint8 data)
Definition: cpu_custom_functions.h:91
cpu65_read_linear_long_opcode_callback
Uint32 cpu65_read_linear_long_opcode_callback(const Uint8 index)
Definition: memory_mapper.c:885
MEMORY_HANDLERS_ADDR_TYPE
#define MEMORY_HANDLERS_ADDR_TYPE
Definition: cpu_custom_functions.h:43
cpu65_write_rmw_paged_callback
CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR void cpu65_write_rmw_paged_callback(Uint8 page, Uint8 addr8, Uint8 old_data, Uint8 new_data)
Definition: cpu_custom_functions.h:108
cpu65_read_paged_callback
CPU_CUSTOM_FUNCTIONS_INLINE_DECORATOR Uint8 cpu65_read_paged_callback(Uint8 page, Uint8 addr8)
Definition: cpu_custom_functions.h:88
cpu65_write_linear_long_opcode_callback
void cpu65_write_linear_long_opcode_callback(const Uint8 index, Uint32 data)
Definition: memory_mapper.c:898