This repository has been archived by the owner on Aug 17, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathfake6502.h
192 lines (136 loc) · 5.68 KB
/
fake6502.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
// -------------------------------------------------------------------
#ifndef FAKE6502_H
#define FAKE6502_H
// -------------------------------------------------------------------
#ifdef __cplusplus
extern "C" {
#endif
// -------------------------------------------------------------------
// include's
// -------------------------------------------------------------------
#include <stdint.h>
// -------------------------------------------------------------------
// define's
// -------------------------------------------------------------------
#define FAKE6502_CARRY_FLAG 0x01
#define FAKE6502_ZERO_FLAG 0x02
#define FAKE6502_INTERRUPT_FLAG 0x04
#define FAKE6502_DECIMAL_FLAG 0x08
#define FAKE6502_BREAK_FLAG 0x10
#define FAKE6502_CONSTANT_FLAG 0x20
#define FAKE6502_OVERFLOW_FLAG 0x40
#define FAKE6502_SIGN_FLAG 0x80
#define FAKE6502_STACK_BASE 0x100
// -------------------------------------------------------------------
// macro's
// -------------------------------------------------------------------
// operator fn prototypes
#ifdef FAKE6502_OPS_STATIC
#define FAKE6502_FN_OPCODE(m_name) \
static void m_name(fake6502_context *c)
#define FAKE6502_FN_ADDR_MODE(m_name) \
static void m_name(fake6502_context *c)
#else
#define FAKE6502_FN_OPCODE(m_name) \
void m_name(fake6502_context *c)
#define FAKE6502_FN_ADDR_MODE(m_name) \
void m_name(fake6502_context *c)
#endif
// c = a pointer to the fake6502_context
// flag modifier macros
#define fake6502_carry_set(c) (c)->cpu.flags |= FAKE6502_CARRY_FLAG
#define fake6502_carry_clear(c) (c)->cpu.flags &= (~FAKE6502_CARRY_FLAG)
#define fake6502_zero_set(c) (c)->cpu.flags |= FAKE6502_ZERO_FLAG
#define fake6502_zero_clear(c) (c)->cpu.flags &= (~FAKE6502_ZERO_FLAG)
#define fake6502_interrupt_set(c) (c)->cpu.flags |= FAKE6502_INTERRUPT_FLAG
#define fake6502_interrupt_clear(c) (c)->cpu.flags &= (~FAKE6502_INTERRUPT_FLAG)
#define fake6502_decimal_set(c) (c)->cpu.flags |= FAKE6502_DECIMAL_FLAG
#define fake6502_decimal_clear(c) (c)->cpu.flags &= (~FAKE6502_DECIMAL_FLAG)
#define fake6502_overflow_set(c) (c)->cpu.flags |= FAKE6502_OVERFLOW_FLAG
#define fake6502_overflow_clear(c) (c)->cpu.flags &= (~FAKE6502_OVERFLOW_FLAG)
#define fake6502_sign_set(c) (c)->cpu.flags |= FAKE6502_SIGN_FLAG
#define fake6502_sign_clear(c) (c)->cpu.flags &= (~FAKE6502_SIGN_FLAG)
#define fake6502_accum_save(c, n) (c)->cpu.a = (uint8_t)((n)&0x00FF)
// flag calculation macros
#define fake6502_zero_calc(c, n) \
{ \
if ((n) & 0x00FF) \
fake6502_zero_clear(c); \
else \
fake6502_zero_set(c); \
}
#define fake6502_sign_calc(c, n) \
{ \
if ((n) & 0x0080) \
fake6502_sign_set(c); \
else \
fake6502_sign_clear(c); \
}
#define fake6502_carry_calc(c, n) \
{ \
if ((n) & 0xFF00) \
fake6502_carry_set(c); \
else \
fake6502_carry_clear(c); \
}
// n = result, m = accumulator, o = memory
#define fake6502_overflow_calc(c, n, m, o) \
{ \
if (((n) ^ (uint16_t)(m)) & ((n) ^ (o)) & 0x0080) \
fake6502_overflow_set(c); \
else \
fake6502_overflow_clear(c); \
}
// -------------------------------------------------------------------
// typedef's
// -------------------------------------------------------------------
typedef struct fake6502_cpu_state {
uint8_t a;
uint8_t x;
uint8_t y;
uint8_t flags;
uint8_t s;
uint16_t pc;
} fake6502_cpu_state;
typedef struct fake6502_emu_state {
int instructions;
int clockticks;
uint16_t ea;
uint8_t opcode;
} fake6502_emu_state;
typedef struct fake6502_context {
fake6502_cpu_state cpu;
fake6502_emu_state emu;
void *state_host;
} fake6502_context;
typedef struct fake6502_opcode {
void (*addr_mode)(fake6502_context *c);
void (*opcode)(fake6502_context *c);
int clockticks;
} fake6502_opcode;
// -------------------------------------------------------------------
// global's
// -------------------------------------------------------------------
extern fake6502_opcode fake6502_opcodes[];
// -------------------------------------------------------------------
// prototype's
// -------------------------------------------------------------------
extern void fake6502_push_8(fake6502_context *c, uint8_t pushval);
extern void fake6502_push_16(fake6502_context *c, uint16_t pushval);
extern uint8_t fake6502_pull_8(fake6502_context *c);
extern uint16_t fake6502_pull_16(fake6502_context *c);
extern uint16_t fake6502_get_value(fake6502_context *c);
extern void fake6502_put_value(fake6502_context *c, uint16_t saveval);
extern void fake6502_reset(fake6502_context *c);
extern void fake6502_irq(fake6502_context *c);
extern void fake6502_nmi(fake6502_context *c);
extern void fake6502_step(fake6502_context *c);
extern uint8_t fake6502_mem_read(fake6502_context *c, uint16_t address);
extern void fake6502_mem_write(fake6502_context *c, uint16_t address, uint8_t val);
// -------------------------------------------------------------------
#ifdef __cplusplus
}
#endif
// -------------------------------------------------------------------
#endif
// -------------------------------------------------------------------