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
|
typedef unsigned char byte;
byte acc, X, Y, S, P = 0x00;
byte Memory[4096]; // TO DO. Add expansion capability to memory.
/*
To Do.
+ Find variables better passed as pointers instead
*/
// FLAGS
const byte flag_N = 0x80; // Negative (Note that byte cast is necessary here only)
const byte flag_V = 0x40; // Overflow
const byte flag_B = 0x10; // BRK command
const byte flag_D = 0x08; // Decimal mode
const byte flag_I = 0x04; // IRQ disable
const byte flag_Z = 0x02; // Zero
const byte flag_C = 0x01; // Carry
byte getFlag(byte flag) {
return ((P & flag) == flag) ? 1 : 0;
}
void setFlag(byte flag, int x) { //OVERLOAD TO ACCEPT INT AS WELL
if (x == 1){
if ((P & flag) == 0x0) P += flag;
}else if (x == 0){
if ((P & flag) == flag) P -= flag;
}
else{
fprintf(stderr, "setFlag() passed arg neither 0 or 1");
}
}
void toggleFlag(byte flag) {
P = ((P & flag) == flag) ? (P + flag) : (P - flag);
}
// BCD
byte toBCD(byte x){
if (x < 100){
byte a = ((x / 10) << 4);
byte b = (x % 10);
return (a + b);
}
else{
fprintf(stderr, "Number greater than 99 passed to toBCD()");
}
}
byte fromBCD(byte x){
byte a = ((x >> 4) * 10);
byte b = (x & 0xF);
return (a + b);
}
// Class of instructions
//each one has every type of addressing mode, inherited from a base class.
// the different addressing modes will be distinguished when the bytecode is called, it will run the instructions function with a selection for the
/* example
Immediate ADC #$44 $69 2 2
instruction(0x69); -> ADC({enum for immediate});
Zero Page ADC $44 $65 2 3
instruction(0x65); -> ADC({enum for Zero Page});
*/
// Set particular flags
// Functions which quickly set specific flags that are straightforward checks, and are repeated often.
void setFlagN(byte x){
if (x ^ flag_N == flag_N){
setFlag(flag_N, 1);
}else{ //not sure if this should be present, I think it is
setFlag(flag_N, 0);
}
}
//Perform prior to any changes
void setFlagV(byte x, byte y){
if ((x & flag_N) == (y & flag_N)){
if (((x + y) & (flag_N ^ 0xFF)) > 0x7F) setFlag(flag_V, 1);
else setFlag(flag_V, 0);
}else{
if (((x - y) & (flag_N ^ 0xFF)) > 0x7F) setFlag(flag_V, 1);
else setFlag(flag_V, 0);
}
}
/*void setFlagB(){ //WORK ON
setFlag(flag_B, 1);
}*/ //Dont really need since its dependent on the BRK insturction
/*void setFlagD(){
setFlag(flag_D, 1);
}*/
void setFlagI(){ //WORK ON
setFlag(flag_Z, 1);
}
void setFlagZ(int x){
if (x == 0) {
setFlag(flag_Z, 1);
}
}
//Only 6 instructions, 2 not including stack instructions, use the carry flag.
/*void setFlagC(){ // NOTE. Must make setFlagC functional with independence. Look into carrying on 6502
setFlag(flag_Z, 1);
}*/
|