5
FakeNES - A portable, Open Source NES emulator.
7
Distributed under the Clarified Artistic License.
9
addr.h: CPU addressing mode emulation macros.
11
Copyright (c) 2001-2006, Randy McDowell.
12
Copyright (c) 2001-2006, Charles Bilyue'.
14
This is free software. See 'LICENSE' for details.
15
You must read and accept the license prior to use.
17
This file contains macros for emulating addressing mode
18
behavior, for the Ricoh RP2A03G CPU.
23
/* Addressing modes */
24
/* These macros calculate effective addresses, store them in */
25
/* an implied variable, and update the Program Counter register. */
27
/* address set to 'zero_page_address' */
28
#define Address_Zero_Page() \
29
zero_page_address = Fetch(PC.word + 1); PC.word += 2
31
#define Address_Zero_Page_Index_X() \
32
Address_Zero_Page(); zero_page_address += R->X
34
#define Address_Zero_Page_Index_Y() \
35
Address_Zero_Page(); zero_page_address += R->Y
37
/* address set to 'address' */
38
#define Address_Zero_Page_Indirect() \
39
address.bytes.low = Read_ZP(zero_page_address); \
40
address.bytes.high = Read_ZP(zero_page_address + 1)
42
#define Address_Indexed_Indirect_X() \
43
Address_Zero_Page_Index_X(); \
44
Address_Zero_Page_Indirect()
46
#define Address_Absolute() \
47
Fetch16(address); PC.word += 3
49
#define Address_Absolute_Index_X(Rg) \
50
Address_Absolute(address); address.word += R->X
52
#define Address_Absolute_Index_Y(Rg) \
53
Address_Absolute(address); address.word += R->Y
55
#define Address_Indirect_Indexed_Y(address) \
56
Address_Zero_Page(); \
57
Address_Zero_Page_Indirect(); \
61
/* These macros calculate and read from effective addresses. */
63
#define Read_Immediate(Rg) \
64
Rg=Fetch(PC.word + 1); PC.word += 2
67
#define Read_Zero_Page(Rg) \
68
Address_Zero_Page(); Rg = Read_ZP(zero_page_address)
70
#define Read_Zero_Page_Index_X(Rg) \
71
Address_Zero_Page_Index_X(); Rg = Read_ZP(zero_page_address)
73
#define Read_Zero_Page_Index_Y(Rg) \
74
Address_Zero_Page_Index_Y(); Rg = Read_ZP(zero_page_address)
77
#define Read_Indexed_Indirect_X(Rg) \
78
Address_Indexed_Indirect_X(); Rg = Read(address.word)
80
#define Read_Absolute(Rg) \
81
Address_Absolute(); Rg = Read(address.word)
83
#define Read_Absolute_Indexed(Rg,Index) \
84
address.bytes.low += Index; \
85
Rg=Read(address.word); \
86
if (address.bytes.low < Index) \
88
R->Cycles += CYCLE_LENGTH; \
89
address.word += 0x100; \
90
Rg = Read(address.word); \
93
#define Read_Absolute_Index_X(Rg) \
95
Read_Absolute_Indexed(Rg, R->X)
97
#define Read_Absolute_Index_Y(Rg) \
99
Read_Absolute_Indexed(Rg, R->Y)
101
#define Read_Indirect_Indexed_Y(Rg) \
102
Address_Zero_Page(); \
103
Address_Zero_Page_Indirect(); \
104
Read_Absolute_Indexed(Rg, R->Y)
106
/* These macros calculate and write to effective addresses. */
108
#define Write_Zero_Page(Rg) \
109
Address_Zero_Page(); Write_ZP(zero_page_address, Rg)
111
#define Write_Zero_Page_Index_X(Rg) \
112
Address_Zero_Page_Index_X(); Write_ZP(zero_page_address, Rg)
114
#define Write_Zero_Page_Index_Y(Rg) \
115
Address_Zero_Page_Index_Y(); Write_ZP(zero_page_address, Rg)
118
#define Write_Indexed_Indirect_X(Rg) \
119
Address_Indexed_Indirect_X(); Write(address.word, Rg)
121
#define Write_Absolute(Rg) \
122
Address_Absolute(); Write(address.word, Rg)
124
#define Write_Absolute_Indexed(Rg,Index) \
125
address.bytes.low += Index; \
126
Read(address.word); \
127
if (address.bytes.low < Index) \
129
address.word += 0x100; \
131
Write(address.word, Rg);
133
#define Write_Absolute_Index_X(Rg) \
134
Address_Absolute(); \
135
Write_Absolute_Indexed(Rg, R->X)
137
#define Write_Absolute_Index_Y(Rg) \
138
Address_Absolute(); \
139
Write_Absolute_Indexed(Rg, R->Y)
141
#define Write_Indirect_Indexed_Y(Rg) \
142
Address_Zero_Page(); \
143
Address_Zero_Page_Indirect(); \
144
Write_Absolute_Indexed(Rg, R->Y)
146
/* These macros calculate effective addresses and perform */
147
/* read-modify-write operations to the addressed data. */
149
#define RMW_Zero_Page(Cmd) \
150
Address_Zero_Page(); \
151
data = Read_ZP(zero_page_address); \
152
Write_ZP(zero_page_address, data); \
154
Write_ZP(zero_page_address, data)
156
#define RMW_Zero_Page_Index_X(Cmd) \
157
Address_Zero_Page_Index_X(); \
158
data = Read_ZP(zero_page_address); \
159
Write_ZP(zero_page_address, data); \
161
Write_ZP(zero_page_address, data)
163
#define RMW_Absolute(Cmd) \
164
Address_Absolute(); \
165
data = Read(address.word); \
166
Write(address.word, data); \
168
Write(address.word, data)
170
#define RMW_Absolute_Index_X(Cmd) \
171
Address_Absolute(); \
172
address.bytes.low += R->X; \
173
Read(address.word); \
174
if (address.bytes.low < R->X) \
176
address.word += 0x100; \
178
data = Read(address.word); \
179
Write(address.word, data); \
181
Write(address.word, data)