Last active
January 7, 2021 04:37
-
-
Save pervognsen/d93f7b77db8231935495e5ec29bb9b79 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Option 1: two dispatches, separated address modes and operations | |
#define ABSOLUTE_X \ | |
0x1C: case 0x1D: case 0x1E: case 0x1F: \ | |
case 0x3C: case 0x3D: case 0x3E: case 0x3F: \ | |
case 0x5C: case 0x5D: case 0x5E: case 0x5F: \ | |
case 0x7C: case 0x7D: case 0x7E: case 0x7F: \ | |
case 0x9C: case 0x9D: \ | |
case 0xBC: case 0xBD: \ | |
case 0xDC: case 0xDD: case 0xDE: case 0xDF: \ | |
case 0xFC: case 0xFD: case 0xFE: case 0xFF | |
// ... | |
#define ADC \ | |
0x61: case 0x65: case 0x69: case 0x6D: \ | |
case 0x71: case 0x75: case 0x79: case 0x7D | |
// ... | |
switch (instruction) { | |
// Absolute 16-bit address plus X | |
case ABSOLUTE_X: | |
address = READ16(pc + 1) + x; | |
pc += 3; | |
break; | |
// ... | |
} | |
// ... | |
switch (instruction) { | |
// Add with carry | |
case ADC: { | |
int sum = (int)a + (int)b + (int)c; | |
SET_CV(a, b, sum); | |
a = (uint8_t)sum; | |
SET_ZN(a); | |
break; | |
} | |
// ... | |
} | |
// Option 2: one dispatch, fused address modes and operations | |
// Absolute 16-bit address plus X | |
#define ABSOLUTE_X \ | |
{ \ | |
address = READ16(pc + 1) + x; \ | |
pc += 3; \ | |
} | |
// ... | |
// Add with carry | |
#define ADC \ | |
{ \ | |
int sum = (int)a + (int)b + (int)c; \ | |
SET_CV(a, b, sum); \ | |
a = (uint8_t)sum; \ | |
SET_ZN(a); \ | |
} | |
// ... | |
#define CASE(byte, operation, addressing_mode) \ | |
case byte: { \ | |
addressing_mode \ | |
b = READ8(address); \ | |
operation \ | |
break; \ | |
} | |
// ... | |
switch (instruction) { | |
CASE(0x7D, ADC, ABSOLUTE_X) | |
// ... | |
} | |
// Option 3: Like option 2 but with forced-inline functions rather than macros. Relies heavily on optimizer doing the right thing. | |
FORCE_INLINE | |
void ABSOLUTE_X(cpu_t *cpu) { | |
cpu->address = READ16(cpu->pc + 1) + cpu->x; | |
cpu->pc += 3; | |
} | |
// ... | |
FORCE_INLINE | |
void ADC(cpu_t *cpu) { | |
int sum = (int)cpu->a + (int)cpu->b + (int)cpu->c; | |
SET_CV(cpu->a, cpu->b, sum); | |
cpu->a = (uint8_t)sum; | |
SET_ZN(cpu->a); | |
} | |
// ... | |
#define CASE(byte, operation, addressing_mode) \ | |
case byte: { \ | |
addressing_mode(cpu); \ | |
cpu->b = READ8(cpu->address); \ | |
operation(cpu); \ | |
break; \ | |
} | |
// ... | |
switch (instruction) { | |
CASE(0x7D, ADC, ABSOLUTE_X) | |
// ... | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment