forked from TASEmulators/BizHawk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathc65c02.h
231 lines (189 loc) · 6.2 KB
/
c65c02.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
//
// Copyright (c) 2004 K. Wilkins
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from
// the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
//////////////////////////////////////////////////////////////////////////////
// Handy - An Atari Lynx Emulator //
// Copyright (c) 1996,1997 //
// K. Wilkins //
//////////////////////////////////////////////////////////////////////////////
// 65C02 Emulation class //
//////////////////////////////////////////////////////////////////////////////
// //
// This class emulates a 65C02 processor. It is interfaced to the rest of //
// the system via the PEEK/POKE macros and a number of global variables //
// //
// K. Wilkins //
// August 1997 //
// //
//////////////////////////////////////////////////////////////////////////////
// Revision History: //
// ----------------- //
// //
// 01Aug1997 KW Document header added & class documented. //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef C65C02_H
#define C65C02_H
//#include <crtdbg.h>
//#define TRACE_CPU
#ifdef TRACE_CPU
#define TRACE_CPU0(msg) _RPT1(_CRT_WARN,"C65C02::"msg" (Time=%012d)\n",gSystemCycleCount)
#define TRACE_CPU1(msg,arg1) _RPT2(_CRT_WARN,"C65C02::"msg" (Time=%012d)\n",arg1,gSystemCycleCount)
#define TRACE_CPU2(msg,arg1,arg2) _RPT3(_CRT_WARN,"C65C02::"msg" (Time=%012d)\n",arg1,arg2,gSystemCycleCount)
#define TRACE_CPU3(msg,arg1,arg2,arg3) _RPT4(_CRT_WARN,"C65C02::"msg" (Time=%012d)\n",arg1,arg2,arg3,gSystemCycleCount)
#else
#define TRACE_CPU0(msg)
#define TRACE_CPU1(msg,arg1)
#define TRACE_CPU2(msg,arg1,arg2)
#define TRACE_CPU3(msg,arg1,arg2,arg3)
#endif
//
// Handy definitions
//
#define NMI_VECTOR 0xfffa
#define BOOT_VECTOR 0xfffc
#define IRQ_VECTOR 0xfffe
#define MAX_CPU_BREAKPOINTS 8
//
// ACCESS MACROS
//
//#define CPU_PEEK(m) (mSystem.Peek_CPU(m))
//#define CPU_PEEKW(m) (mSystem.PeekW_CPU(m))
//#define CPU_POKE(m1,m2) (mSystem.Poke_CPU(m1,m2))
#define CPU_PEEK(m) (((m<0xfc00)?mRamPointer[m]:mSystem.Peek_CPU(m)))
#define CPU_PEEKW(m) (((m<0xfc00)?(mRamPointer[m]+(mRamPointer[m+1]<<8)):mSystem.PeekW_CPU(m)))
#define CPU_POKE(m1,m2) {if(m1<0xfc00) mRamPointer[m1]=m2; else mSystem.Poke_CPU(m1,m2);}
enum { illegal=0,
accu,
imm,
absl,
zp,
zpx,
zpy,
absx,
absy,
iabsx,
impl,
rel,
zrel,
indx,
indy,
iabs,
ind
};
typedef struct
{
int PS; // Processor status register 8 bits
int A; // Accumulator 8 bits
int X; // X index register 8 bits
int Y; // Y index register 8 bits
int SP; // Stack Pointer 8 bits
int Opcode; // Instruction opcode 8 bits
int Operand;// Intructions operand 16 bits
int PC; // Program Counter 16 bits
bool NMI;
bool IRQ;
bool WAIT;
}C6502_REGS;
//
// The CPU emulation macros
//
#include "c6502mak.h"
//
// The CPU emulation macros
//
class C65C02
{
public:
C65C02(CSystem& parent)
:mSystem(parent)
{
TRACE_CPU0("C65C02()");
// Compute the BCD lookup table
for(uint16 t=0;t<256;++t)
{
mBCDTable[0][t]=((t >> 4) * 10) + (t & 0x0f);
mBCDTable[1][t]=(((t % 100) / 10) << 4) | (t % 10);
}
Reset();
}
~C65C02()
{
TRACE_CPU0("~C65C02()");
}
public:
void Reset();
void Update();
void SetRegs(C6502_REGS ®s);
void GetRegs(C6502_REGS ®s);
inline int GetPC() { return mPC; }
template<bool isReader>void SyncState(NewState *ns);
private:
CSystem &mSystem;
// CPU Flags & status
int mA; // Accumulator 8 bits
int mX; // X index register 8 bits
int mY; // Y index register 8 bits
int mSP; // Stack Pointer 8 bits
int mOpcode; // Instruction opcode 8 bits
int mOperand; // Intructions operand 16 bits
int mPC; // Program Counter 16 bits
int mN; // N flag for processor status register
int mV; // V flag for processor status register
int mB; // B flag for processor status register
int mD; // D flag for processor status register
int mI; // I flag for processor status register
int mZ; // Z flag for processor status register
int mC; // C flag for processor status register
int mIRQActive;
uint8 *mRamPointer;
// Associated lookup tables
int mBCDTable[2][256];
//
// Opcode prototypes
//
private:
// Answers value of the Processor Status register
INLINE int PS() const
{
uint8 ps = 0x20;
if(mN) ps|=0x80;
if(mV) ps|=0x40;
if(mB) ps|=0x10;
if(mD) ps|=0x08;
if(mI) ps|=0x04;
if(mZ) ps|=0x02;
if(mC) ps|=0x01;
return ps;
}
// Change the processor flags to correspond to the given value
INLINE void PS(int ps)
{
mN=ps&0x80;
mV=ps&0x40;
mB=ps&0x10;
mD=ps&0x08;
mI=ps&0x04;
mZ=ps&0x02;
mC=ps&0x01;
}
};
#endif