~jazzva/fakenes/ubuntu

« back to all changes in this revision

Viewing changes to src/include/core/addr.h

  • Committer: Sasa Bodiroza
  • Date: 2007-08-15 05:37:49 UTC
  • Revision ID: jazzva@gmail.com-20070815053749-76l0xj66tzgt290p
Upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
 
 
3
/*
 
4
 
 
5
FakeNES - A portable, Open Source NES emulator.
 
6
 
 
7
Distributed under the Clarified Artistic License.
 
8
 
 
9
addr.h: CPU addressing mode emulation macros.
 
10
 
 
11
Copyright (c) 2001-2006, Randy McDowell.
 
12
Copyright (c) 2001-2006, Charles Bilyue'.
 
13
 
 
14
This is free software.  See 'LICENSE' for details.
 
15
You must read and accept the license prior to use.
 
16
 
 
17
This file contains macros for emulating addressing mode
 
18
behavior, for the Ricoh RP2A03G CPU.
 
19
 
 
20
*/
 
21
 
 
22
 
 
23
/* Addressing modes */
 
24
/* These macros calculate effective addresses, store them in */
 
25
/* an implied variable, and update the Program Counter register. */
 
26
 
 
27
/* address set to 'zero_page_address' */
 
28
#define Address_Zero_Page() \
 
29
    zero_page_address = Fetch(PC.word + 1); PC.word += 2
 
30
 
 
31
#define Address_Zero_Page_Index_X() \
 
32
    Address_Zero_Page(); zero_page_address += R->X
 
33
 
 
34
#define Address_Zero_Page_Index_Y() \
 
35
    Address_Zero_Page(); zero_page_address += R->Y
 
36
 
 
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)
 
41
 
 
42
#define Address_Indexed_Indirect_X() \
 
43
    Address_Zero_Page_Index_X(); \
 
44
    Address_Zero_Page_Indirect()
 
45
 
 
46
#define Address_Absolute() \
 
47
    Fetch16(address); PC.word += 3
 
48
 
 
49
#define Address_Absolute_Index_X(Rg) \
 
50
    Address_Absolute(address); address.word += R->X
 
51
 
 
52
#define Address_Absolute_Index_Y(Rg) \
 
53
    Address_Absolute(address); address.word += R->Y
 
54
 
 
55
#define Address_Indirect_Indexed_Y(address) \
 
56
    Address_Zero_Page(); \
 
57
    Address_Zero_Page_Indirect(); \
 
58
    address.word += R->Y
 
59
 
 
60
 
 
61
/* These macros calculate and read from effective addresses. */
 
62
 
 
63
#define Read_Immediate(Rg) \
 
64
    Rg=Fetch(PC.word + 1); PC.word += 2
 
65
 
 
66
 
 
67
#define Read_Zero_Page(Rg) \
 
68
    Address_Zero_Page(); Rg = Read_ZP(zero_page_address)
 
69
 
 
70
#define Read_Zero_Page_Index_X(Rg) \
 
71
    Address_Zero_Page_Index_X(); Rg = Read_ZP(zero_page_address)
 
72
 
 
73
#define Read_Zero_Page_Index_Y(Rg) \
 
74
    Address_Zero_Page_Index_Y(); Rg = Read_ZP(zero_page_address)
 
75
 
 
76
 
 
77
#define Read_Indexed_Indirect_X(Rg) \
 
78
    Address_Indexed_Indirect_X(); Rg = Read(address.word)
 
79
 
 
80
#define Read_Absolute(Rg) \
 
81
    Address_Absolute(); Rg = Read(address.word)
 
82
 
 
83
#define Read_Absolute_Indexed(Rg,Index) \
 
84
    address.bytes.low += Index; \
 
85
    Rg=Read(address.word); \
 
86
    if (address.bytes.low < Index) \
 
87
    { \
 
88
        R->Cycles += CYCLE_LENGTH; \
 
89
        address.word += 0x100; \
 
90
        Rg = Read(address.word); \
 
91
    }
 
92
 
 
93
#define Read_Absolute_Index_X(Rg) \
 
94
    Address_Absolute(); \
 
95
    Read_Absolute_Indexed(Rg, R->X)
 
96
 
 
97
#define Read_Absolute_Index_Y(Rg) \
 
98
    Address_Absolute(); \
 
99
    Read_Absolute_Indexed(Rg, R->Y)
 
100
 
 
101
#define Read_Indirect_Indexed_Y(Rg) \
 
102
    Address_Zero_Page(); \
 
103
    Address_Zero_Page_Indirect(); \
 
104
    Read_Absolute_Indexed(Rg, R->Y)
 
105
 
 
106
/* These macros calculate and write to effective addresses. */
 
107
 
 
108
#define Write_Zero_Page(Rg) \
 
109
    Address_Zero_Page(); Write_ZP(zero_page_address, Rg)
 
110
 
 
111
#define Write_Zero_Page_Index_X(Rg) \
 
112
    Address_Zero_Page_Index_X(); Write_ZP(zero_page_address, Rg)
 
113
 
 
114
#define Write_Zero_Page_Index_Y(Rg) \
 
115
    Address_Zero_Page_Index_Y(); Write_ZP(zero_page_address, Rg)
 
116
 
 
117
 
 
118
#define Write_Indexed_Indirect_X(Rg) \
 
119
    Address_Indexed_Indirect_X(); Write(address.word, Rg)
 
120
 
 
121
#define Write_Absolute(Rg) \
 
122
    Address_Absolute(); Write(address.word, Rg)
 
123
 
 
124
#define Write_Absolute_Indexed(Rg,Index) \
 
125
    address.bytes.low += Index; \
 
126
    Read(address.word); \
 
127
    if (address.bytes.low < Index) \
 
128
    { \
 
129
        address.word += 0x100; \
 
130
    } \
 
131
    Write(address.word, Rg);
 
132
 
 
133
#define Write_Absolute_Index_X(Rg) \
 
134
    Address_Absolute(); \
 
135
    Write_Absolute_Indexed(Rg, R->X)
 
136
 
 
137
#define Write_Absolute_Index_Y(Rg) \
 
138
    Address_Absolute(); \
 
139
    Write_Absolute_Indexed(Rg, R->Y)
 
140
 
 
141
#define Write_Indirect_Indexed_Y(Rg) \
 
142
    Address_Zero_Page(); \
 
143
    Address_Zero_Page_Indirect(); \
 
144
    Write_Absolute_Indexed(Rg, R->Y)
 
145
 
 
146
/* These macros calculate effective addresses and perform */
 
147
/* read-modify-write operations to the addressed data. */
 
148
 
 
149
#define RMW_Zero_Page(Cmd) \
 
150
    Address_Zero_Page(); \
 
151
    data = Read_ZP(zero_page_address); \
 
152
    Write_ZP(zero_page_address, data); \
 
153
    Cmd(data); \
 
154
    Write_ZP(zero_page_address, data)
 
155
 
 
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); \
 
160
    Cmd(data); \
 
161
    Write_ZP(zero_page_address, data)
 
162
 
 
163
#define RMW_Absolute(Cmd) \
 
164
    Address_Absolute(); \
 
165
    data = Read(address.word); \
 
166
    Write(address.word, data); \
 
167
    Cmd(data); \
 
168
    Write(address.word, data)
 
169
 
 
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) \
 
175
    { \
 
176
        address.word += 0x100; \
 
177
    } \
 
178
    data = Read(address.word); \
 
179
    Write(address.word, data); \
 
180
    Cmd(data); \
 
181
    Write(address.word, data)
 
182