This commit is contained in:
Stefan Arentz 2018-02-21 21:53:06 +00:00 committed by GitHub
commit 031605f3c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 279 additions and 264 deletions

View File

@ -20,6 +20,8 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include <sys/utsname.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
@ -30,13 +32,26 @@
#include "mem.h"
#include "utl.h"
#define CPU_BENCH_ITERATIONS (10 * 1000 * 1000)
uint64_t get_iterations() {
struct utsname name;
if (uname(&name) == 0) {
if (strcmp(name.machine, "x86_64") == 0) {
return 1000 * 1000 * 1000;
}
if (strcmp(name.machine, "armv6l") == 0) {
return 100 * 1000 * 1000;
}
}
return 10 * 1000 * 1000;
}
void test(struct cpu_t *cpu, uint8_t opcode) {
uint64_t runs[3];
struct cpu_instruction_t *ins = &cpu->instructions[opcode];
uint64_t iterations = get_iterations();
for (int run = 0; run < 3; run++) {
struct timespec start;
if (clock_gettime(CLOCK_REALTIME, &start) != 0) {
@ -44,19 +59,22 @@ void test(struct cpu_t *cpu, uint8_t opcode) {
exit(1);
}
cpu->state.x = 0x12;
cpu->state.y = 0x12;
switch (ins->bytes) {
case 1:
for (uint64_t i = 0; i < CPU_BENCH_ITERATIONS; i++) {
for (uint64_t i = 0; i < iterations; i++) {
((cpu_instruction_handler_t) ins->handler)(cpu);
}
break;
case 2:
for (uint64_t i = 0; i < CPU_BENCH_ITERATIONS; i++) {
for (uint64_t i = 0; i < iterations; i++) {
((cpu_instruction_handler_byte_t) ins->handler)(cpu, 0x12);
}
break;
case 3:
for (uint64_t i = 0; i < CPU_BENCH_ITERATIONS; i++) {
for (uint64_t i = 0; i < iterations; i++) {
((cpu_instruction_handler_word_t) ins->handler)(cpu, 0x1234);
}
break;

349
src/ins.c
View File

@ -36,7 +36,110 @@
#include "lua.h"
#endif
static void update_zn(struct cpu_t *cpu, uint8_t v) {
// Getters
static inline uint8_t get_byte_abs(struct cpu_t *cpu, uint16_t addr) {
return mem_get_byte(cpu, addr);
}
static inline uint8_t get_byte_absx(struct cpu_t *cpu, uint16_t addr) {
return mem_get_byte(cpu, addr + cpu->state.x);
}
static inline uint8_t get_byte_absy(struct cpu_t *cpu, uint16_t addr) {
return mem_get_byte(cpu, addr + cpu->state.y);
}
static inline uint8_t get_byte_zpg(struct cpu_t *cpu, uint8_t addr) {
return cpu->ram[addr];
}
static inline uint8_t get_byte_zpgx(struct cpu_t *cpu, uint8_t addr) {
return cpu->ram[((uint16_t) addr + cpu->state.x) & 0x00ff];
}
static inline uint8_t get_byte_zpgy(struct cpu_t *cpu, uint8_t addr) {
return cpu->ram[((uint16_t) addr + cpu->state.y) & 0x00ff];
}
static inline uint8_t get_byte_indx(struct cpu_t *cpu, uint8_t addr) {
uint16_t a = *((uint16_t*) &cpu->ram[(addr + cpu->state.x) & 0x00ff]);
return mem_get_byte(cpu, a);
}
static inline uint8_t get_byte_indy(struct cpu_t *cpu, uint8_t addr) {
uint16_t a = *((uint16_t*) &cpu->ram[addr]) + cpu->state.y;
return mem_get_byte(cpu, a);
}
static inline uint8_t get_byte_ind(struct cpu_t *cpu, uint8_t addr) {
uint16_t a = *((uint16_t*) &cpu->ram[addr]);
return mem_get_byte(cpu, a);
}
// Setters
static inline void set_byte_zpg(struct cpu_t *cpu, uint8_t addr, uint8_t v) {
cpu->ram[addr] = v;
}
static inline void set_byte_zpgx(struct cpu_t *cpu, uint8_t addr, uint8_t v) {
cpu->ram[((uint16_t) addr + cpu->state.x) & 0x00ff] = v;
}
static inline void set_byte_zpgy(struct cpu_t *cpu, uint8_t addr, uint8_t v) {
cpu->ram[((uint16_t) addr + cpu->state.y) & 0x00ff] = v;
}
static inline void set_byte_abs(struct cpu_t *cpu, uint16_t addr, uint8_t v) {
mem_set_byte(cpu, addr, v);
}
static inline void set_byte_absx(struct cpu_t *cpu, uint16_t addr, uint8_t v) {
mem_set_byte(cpu, addr+cpu->state.x, v);
}
static inline void set_byte_absy(struct cpu_t *cpu, uint16_t addr, uint8_t v) {
mem_set_byte(cpu, addr+cpu->state.y, v);
}
static inline void set_byte_indx(struct cpu_t *cpu, uint8_t addr, uint8_t v) {
uint16_t a = *((uint16_t*) &cpu->ram[(addr + cpu->state.x) & 0x0ff]);
mem_set_byte(cpu, a, v);
}
static inline void set_byte_indy(struct cpu_t *cpu, uint8_t addr, uint8_t v) {
uint16_t a = *((uint16_t*) &cpu->ram[addr]) + cpu->state.y;
mem_set_byte(cpu, a, v);
}
static inline void set_byte_ind(struct cpu_t *cpu, uint8_t addr, uint8_t v) {
uint16_t a = *((uint16_t*) &cpu->ram[addr]);
mem_set_byte(cpu, a, v);
}
// Modifiers
static inline void mod_byte_zpg(struct cpu_t *cpu, uint8_t addr, mem_mod_t op) {
cpu->ram[addr] = op(cpu, cpu->ram[addr]);
}
static inline void mod_byte_zpgx(struct cpu_t *cpu, uint8_t addr, mem_mod_t op) {
uint8_t a = ((uint16_t) addr + cpu->state.x) & 0x00ff;
cpu->ram[a] = op(cpu, cpu->ram[a]);
}
static inline void mod_byte_abs(struct cpu_t *cpu, uint16_t addr, mem_mod_t op) {
set_byte_abs(cpu, addr, op(cpu, get_byte_abs(cpu, addr)));
}
static inline void mod_byte_absx(struct cpu_t *cpu, uint16_t addr, mem_mod_t op) {
set_byte_absx(cpu, addr, op(cpu, get_byte_absx(cpu, addr)));
}
// Utilities
static inline void update_zn(struct cpu_t *cpu, uint8_t v) {
cpu->state.z = (v == 0x00);
cpu->state.n = (v & 0x80);
}
@ -85,31 +188,31 @@ static void adc_imm(struct cpu_t *cpu, uint8_t oper) {
}
static void adc_zpg(struct cpu_t *cpu, uint8_t oper) {
adc(cpu, mem_get_byte_zpg(cpu, oper));
adc(cpu, get_byte_zpg(cpu, oper));
}
static void adc_zpgx(struct cpu_t *cpu, uint8_t oper) {
adc(cpu, mem_get_byte_zpgx(cpu, oper));
adc(cpu, get_byte_zpgx(cpu, oper));
}
static void adc_abs(struct cpu_t *cpu, uint16_t oper) {
adc(cpu, mem_get_byte_abs(cpu, oper));
adc(cpu, get_byte_abs(cpu, oper));
}
static void adc_absx(struct cpu_t *cpu, uint16_t oper) {
adc(cpu, mem_get_byte_absx(cpu, oper));
adc(cpu, get_byte_absx(cpu, oper));
}
static void adc_absy(struct cpu_t *cpu, uint16_t oper) {
adc(cpu, mem_get_byte_absy(cpu, oper));
adc(cpu, get_byte_absy(cpu, oper));
}
static void adc_indx(struct cpu_t *cpu, uint8_t oper) {
adc(cpu, mem_get_byte_indx(cpu, oper));
adc(cpu, get_byte_indx(cpu, oper));
}
static void adc_indy(struct cpu_t *cpu, uint8_t oper) {
adc(cpu, mem_get_byte_indy(cpu, oper));
adc(cpu, get_byte_indy(cpu, oper));
}
/* AND */
@ -124,31 +227,31 @@ static void and_imm(struct cpu_t *cpu, uint8_t oper) {
}
static void and_zpg(struct cpu_t *cpu, uint8_t oper) {
and(cpu, mem_get_byte_zpg(cpu, oper));
and(cpu, get_byte_zpg(cpu, oper));
}
static void and_zpgx(struct cpu_t *cpu, uint8_t oper) {
and(cpu, mem_get_byte_zpgx(cpu, oper));
and(cpu, get_byte_zpgx(cpu, oper));
}
static void and_abs(struct cpu_t *cpu, uint16_t oper) {
and(cpu, mem_get_byte_abs(cpu, oper));
and(cpu, get_byte_abs(cpu, oper));
}
static void and_absx(struct cpu_t *cpu, uint16_t oper) {
and(cpu, mem_get_byte_absx(cpu, oper));
and(cpu, get_byte_absx(cpu, oper));
}
static void and_absy(struct cpu_t *cpu, uint16_t oper) {
and(cpu, mem_get_byte_absy(cpu, oper));
and(cpu, get_byte_absy(cpu, oper));
}
static void and_indx(struct cpu_t *cpu, uint8_t oper) {
and(cpu, mem_get_byte_indx(cpu, oper));
and(cpu, get_byte_indx(cpu, oper));
}
static void and_indy(struct cpu_t *cpu, uint8_t oper) {
and(cpu, mem_get_byte_indy(cpu, oper));
and(cpu, get_byte_indy(cpu, oper));
}
/* ASL */
@ -166,19 +269,19 @@ static void asl_acc(struct cpu_t *cpu) {
}
static void asl_zpg(struct cpu_t *cpu, uint8_t oper) {
mem_mod_byte_zpg(cpu, oper, asl);
mod_byte_zpg(cpu, oper, asl);
}
static void asl_zpgx(struct cpu_t *cpu, uint8_t oper) {
mem_mod_byte_zpgx(cpu, oper, asl);
mod_byte_zpgx(cpu, oper, asl);
}
static void asl_abs(struct cpu_t *cpu, uint16_t oper) {
mem_mod_byte_abs(cpu, oper, asl);
mod_byte_abs(cpu, oper, asl);
}
static void asl_absx(struct cpu_t *cpu, uint16_t oper) {
mem_mod_byte_absx(cpu, oper, asl);
mod_byte_absx(cpu, oper, asl);
}
/* BIT */
@ -191,11 +294,11 @@ static void bit(struct cpu_t *cpu, uint8_t m) {
}
static void bit_zpg(struct cpu_t *cpu, uint8_t oper) {
bit(cpu, mem_get_byte_zpg(cpu, oper));
bit(cpu, get_byte_zpg(cpu, oper));
}
static void bit_abs(struct cpu_t *cpu, uint16_t oper) {
bit(cpu, mem_get_byte_abs(cpu, oper));
bit(cpu, get_byte_abs(cpu, oper));
}
/* Bxx Branches */
@ -290,31 +393,31 @@ static void cmp_imm(struct cpu_t *cpu, uint8_t oper) {
}
static void cmp_zpg(struct cpu_t *cpu, uint8_t oper) {
cmp(cpu, mem_get_byte_zpg(cpu, oper));
cmp(cpu, get_byte_zpg(cpu, oper));
}
static void cmp_zpgx(struct cpu_t *cpu, uint8_t oper) {
cmp(cpu, mem_get_byte_zpgx(cpu, oper));
cmp(cpu, get_byte_zpgx(cpu, oper));
}
static void cmp_abs(struct cpu_t *cpu, uint16_t oper) {
cmp(cpu, mem_get_byte_abs(cpu, oper));
cmp(cpu, get_byte_abs(cpu, oper));
}
static void cmp_absx(struct cpu_t *cpu, uint16_t oper) {
cmp(cpu, mem_get_byte_absx(cpu, oper));
cmp(cpu, get_byte_absx(cpu, oper));
}
static void cmp_absy(struct cpu_t *cpu, uint16_t oper) {
cmp(cpu, mem_get_byte_absy(cpu, oper));
cmp(cpu, get_byte_absy(cpu, oper));
}
static void cmp_indx(struct cpu_t *cpu, uint8_t oper) {
cmp(cpu, mem_get_byte_indx(cpu, oper));
cmp(cpu, get_byte_indx(cpu, oper));
}
static void cmp_indy(struct cpu_t *cpu, uint8_t oper) {
cmp(cpu, mem_get_byte_indy(cpu, oper));
cmp(cpu, get_byte_indy(cpu, oper));
}
/* CPX */
@ -330,11 +433,11 @@ static void cpx_imm(struct cpu_t *cpu, uint8_t oper) {
}
static void cpx_zpg(struct cpu_t *cpu, uint8_t oper) {
cpx(cpu, mem_get_byte_zpg(cpu, oper));
cpx(cpu, get_byte_zpg(cpu, oper));
}
static void cpx_abs(struct cpu_t *cpu, uint16_t oper) {
cpx(cpu, mem_get_byte_abs(cpu, oper));
cpx(cpu, get_byte_abs(cpu, oper));
}
/* CPY */
@ -350,11 +453,11 @@ static void cpy_imm(struct cpu_t *cpu, uint8_t oper) {
}
static void cpy_zpg(struct cpu_t *cpu, uint8_t oper) {
cpy(cpu, mem_get_byte_zpg(cpu, oper));
cpy(cpu, get_byte_zpg(cpu, oper));
}
static void cpy_abs(struct cpu_t *cpu, uint16_t oper) {
cpy(cpu, mem_get_byte_abs(cpu, oper));
cpy(cpu, get_byte_abs(cpu, oper));
}
/* DEx */
@ -366,19 +469,19 @@ static uint8_t dec(struct cpu_t *cpu, uint8_t b) {
}
static void dec_zpg(struct cpu_t *cpu, uint8_t oper) {
mem_mod_byte_zpg(cpu, oper, dec);
mod_byte_zpg(cpu, oper, dec);
}
static void dec_zpgx(struct cpu_t *cpu, uint8_t oper) {
mem_mod_byte_zpgx(cpu, oper, dec);
mod_byte_zpgx(cpu, oper, dec);
}
static void dec_abs(struct cpu_t *cpu, uint16_t oper) {
mem_mod_byte_abs(cpu, oper, dec);
mod_byte_abs(cpu, oper, dec);
}
static void dec_absx(struct cpu_t *cpu, uint16_t oper) {
mem_mod_byte_absx(cpu, oper, dec);
mod_byte_absx(cpu, oper, dec);
}
static void dex(struct cpu_t *cpu) {
@ -403,31 +506,31 @@ static void eor_imm(struct cpu_t *cpu, uint8_t oper) {
}
static void eor_zpg(struct cpu_t *cpu, uint8_t oper) {
eor(cpu, mem_get_byte_zpg(cpu, oper));
eor(cpu, get_byte_zpg(cpu, oper));
}
static void eor_zpgx(struct cpu_t *cpu, uint8_t oper) {
eor(cpu, mem_get_byte_zpgx(cpu, oper));
eor(cpu, get_byte_zpgx(cpu, oper));
}
static void eor_abs(struct cpu_t *cpu, uint16_t oper) {
eor(cpu, mem_get_byte_abs(cpu, oper));
eor(cpu, get_byte_abs(cpu, oper));
}
static void eor_absx(struct cpu_t *cpu, uint16_t oper) {
eor(cpu, mem_get_byte_absx(cpu, oper));
eor(cpu, get_byte_absx(cpu, oper));
}
static void eor_absy(struct cpu_t *cpu, uint16_t oper) {
eor(cpu, mem_get_byte_absy(cpu, oper));
eor(cpu, get_byte_absy(cpu, oper));
}
static void eor_indx(struct cpu_t *cpu, uint8_t oper) {
eor(cpu, mem_get_byte_indx(cpu, oper));
eor(cpu, get_byte_indx(cpu, oper));
}
static void eor_indy(struct cpu_t *cpu, uint8_t oper) {
eor(cpu, mem_get_byte_indy(cpu, oper));
eor(cpu, get_byte_indy(cpu, oper));
}
/* INx */
@ -439,19 +542,19 @@ static uint8_t inc(struct cpu_t *cpu, uint8_t b) {
}
static void inc_zpg(struct cpu_t *cpu, uint8_t oper) {
mem_mod_byte_zpg(cpu, oper, inc);
mod_byte_zpg(cpu, oper, inc);
}
static void inc_zpgx(struct cpu_t *cpu, uint8_t oper) {
mem_mod_byte_zpgx(cpu, oper, inc);
mod_byte_zpgx(cpu, oper, inc);
}
static void inc_abs(struct cpu_t *cpu, uint16_t oper) {
mem_mod_byte_abs(cpu, oper, inc);
mod_byte_abs(cpu, oper, inc);
}
static void inc_absx(struct cpu_t *cpu, uint16_t oper) {
mem_mod_byte_absx(cpu, oper, inc);
mod_byte_absx(cpu, oper, inc);
}
static void inx(struct cpu_t *cpu) {
@ -489,37 +592,37 @@ static void lda_imm(struct cpu_t *cpu, uint8_t oper) {
}
static void lda_zpg(struct cpu_t *cpu, uint8_t oper) {
cpu->state.a = mem_get_byte_zpg(cpu, oper);
cpu->state.a = get_byte_zpg(cpu, oper);
update_zn(cpu, cpu->state.a);
}
static void lda_zpgx(struct cpu_t *cpu, uint8_t oper) {
cpu->state.a = mem_get_byte_zpgx(cpu, oper);
cpu->state.a = get_byte_zpgx(cpu, oper);
update_zn(cpu, cpu->state.a);
}
static void lda_abs(struct cpu_t *cpu, uint16_t oper) {
cpu->state.a = mem_get_byte_abs(cpu, oper);
cpu->state.a = get_byte_abs(cpu, oper);
update_zn(cpu, cpu->state.a);
}
static void lda_absx(struct cpu_t *cpu, uint16_t oper) {
cpu->state.a = mem_get_byte_absx(cpu, oper);
cpu->state.a = get_byte_absx(cpu, oper);
update_zn(cpu, cpu->state.a);
}
static void lda_absy(struct cpu_t *cpu, uint16_t oper) {
cpu->state.a = mem_get_byte_absy(cpu, oper);
cpu->state.a = get_byte_absy(cpu, oper);
update_zn(cpu, cpu->state.a);
}
static void lda_indx(struct cpu_t *cpu, uint8_t oper) {
cpu->state.a = mem_get_byte_indx(cpu, oper);
cpu->state.a = get_byte_indx(cpu, oper);
update_zn(cpu, cpu->state.a);
}
static void lda_indy(struct cpu_t *cpu, uint8_t oper) {
cpu->state.a = mem_get_byte_indy(cpu, oper);
cpu->state.a = get_byte_indy(cpu, oper);
update_zn(cpu, cpu->state.a);
}
@ -531,22 +634,22 @@ static void ldx_imm(struct cpu_t *cpu, uint8_t oper) {
}
static void ldx_zpg(struct cpu_t *cpu, uint8_t oper) {
cpu->state.x = mem_get_byte_zpg(cpu, oper);
cpu->state.x = get_byte_zpg(cpu, oper);
update_zn(cpu, cpu->state.x);
}
static void ldx_zpgy(struct cpu_t *cpu, uint8_t oper) {
cpu->state.x = mem_get_byte_zpgy(cpu, oper);
cpu->state.x = get_byte_zpgy(cpu, oper);
update_zn(cpu, cpu->state.x);
}
static void ldx_abs(struct cpu_t *cpu, uint16_t oper) {
cpu->state.x = mem_get_byte_abs(cpu, oper);
cpu->state.x = get_byte_abs(cpu, oper);
update_zn(cpu, cpu->state.x);
}
static void ldx_absy(struct cpu_t *cpu, uint16_t oper) {
cpu->state.x = mem_get_byte_absy(cpu, oper);
cpu->state.x = get_byte_absy(cpu, oper);
update_zn(cpu, cpu->state.x);
}
@ -558,22 +661,22 @@ static void ldy_imm(struct cpu_t *cpu, uint8_t oper) {
}
static void ldy_zpg(struct cpu_t *cpu, uint8_t oper) {
cpu->state.y = mem_get_byte_zpg(cpu, oper);
cpu->state.y = get_byte_zpg(cpu, oper);
update_zn(cpu, cpu->state.y);
}
static void ldy_zpgx(struct cpu_t *cpu, uint8_t oper) {
cpu->state.y = mem_get_byte_zpgx(cpu, oper);
cpu->state.y = get_byte_zpgx(cpu, oper);
update_zn(cpu, cpu->state.y);
}
static void ldy_abs(struct cpu_t *cpu, uint16_t oper) {
cpu->state.y = mem_get_byte_abs(cpu, oper);
cpu->state.y = get_byte_abs(cpu, oper);
update_zn(cpu, cpu->state.y);
}
static void ldy_absx(struct cpu_t *cpu, uint16_t oper) {
cpu->state.y = mem_get_byte_absx(cpu, oper);
cpu->state.y = get_byte_absx(cpu, oper);
update_zn(cpu, cpu->state.y);
}
@ -591,18 +694,18 @@ static void lsr_acc(struct cpu_t *cpu) {
}
static void lsr_zpg(struct cpu_t *cpu, uint8_t oper) {
mem_mod_byte_zpg(cpu, oper, lsr);
mod_byte_zpg(cpu, oper, lsr);
}
static void lsr_zpgx(struct cpu_t *cpu, uint8_t oper) {
mem_mod_byte_zpgx(cpu, oper, lsr);
mod_byte_zpgx(cpu, oper, lsr);
}
static void lsr_abs(struct cpu_t *cpu, uint16_t oper) {
mem_mod_byte_abs(cpu, oper, lsr);
mod_byte_abs(cpu, oper, lsr);
}
static void lsr_absx(struct cpu_t *cpu, uint16_t oper) {
mem_mod_byte_absx(cpu, oper, lsr);
mod_byte_absx(cpu, oper, lsr);
}
/* NOP */
@ -622,31 +725,31 @@ static void ora_imm(struct cpu_t *cpu, uint8_t oper) {
}
static void ora_zpg(struct cpu_t *cpu, uint8_t oper) {
ora(cpu, mem_get_byte_zpg(cpu, oper));
ora(cpu, get_byte_zpg(cpu, oper));
}
static void ora_zpgx(struct cpu_t *cpu, uint8_t oper) {
ora(cpu, mem_get_byte_zpgx(cpu, oper));
ora(cpu, get_byte_zpgx(cpu, oper));
}
static void ora_abs(struct cpu_t *cpu, uint16_t oper) {
ora(cpu, mem_get_byte_abs(cpu, oper));
ora(cpu, get_byte_abs(cpu, oper));
}
static void ora_absx(struct cpu_t *cpu, uint16_t oper) {
ora(cpu, mem_get_byte_absx(cpu, oper));
ora(cpu, get_byte_absx(cpu, oper));
}
static void ora_absy(struct cpu_t *cpu, uint16_t oper) {
ora(cpu, mem_get_byte_absy(cpu, oper));
ora(cpu, get_byte_absy(cpu, oper));
}
static void ora_indx(struct cpu_t *cpu, uint8_t oper) {
ora(cpu, mem_get_byte_indx(cpu, oper));
ora(cpu, get_byte_indx(cpu, oper));
}
static void ora_indy(struct cpu_t *cpu, uint8_t oper) {
ora(cpu, mem_get_byte_indy(cpu, oper));
ora(cpu, get_byte_indy(cpu, oper));
}
@ -684,19 +787,19 @@ static void rol_acc(struct cpu_t *cpu) {
}
static void rol_zpg(struct cpu_t *cpu, uint8_t oper) {
mem_mod_byte_zpg(cpu, oper, rol);
mod_byte_zpg(cpu, oper, rol);
}
static void rol_zpgx(struct cpu_t *cpu, uint8_t oper) {
mem_mod_byte_zpgx(cpu, oper, rol);
mod_byte_zpgx(cpu, oper, rol);
}
static void rol_abs(struct cpu_t *cpu, uint16_t oper) {
mem_mod_byte_abs(cpu, oper, rol);
mod_byte_abs(cpu, oper, rol);
}
static void rol_absx(struct cpu_t *cpu, uint16_t oper) {
mem_mod_byte_absx(cpu, oper, rol);
mod_byte_absx(cpu, oper, rol);
}
/* ROR */
@ -714,19 +817,19 @@ static void ror_acc(struct cpu_t *cpu) {
}
static void ror_zpg(struct cpu_t *cpu, uint8_t oper) {
mem_mod_byte_zpg(cpu, oper, ror);
mod_byte_zpg(cpu, oper, ror);
}
static void ror_zpgx(struct cpu_t *cpu, uint8_t oper) {
mem_mod_byte_zpgx(cpu, oper, ror);
mod_byte_zpgx(cpu, oper, ror);
}
static void ror_abs(struct cpu_t *cpu, uint16_t oper) {
mem_mod_byte_abs(cpu, oper, ror);
mod_byte_abs(cpu, oper, ror);
}
static void ror_absx(struct cpu_t *cpu, uint16_t oper) {
mem_mod_byte_absx(cpu, oper, ror);
mod_byte_absx(cpu, oper, ror);
}
/* RTI */
@ -786,31 +889,31 @@ static void sbc_imm(struct cpu_t *cpu, uint8_t oper) {
}
static void sbc_zpg(struct cpu_t *cpu, uint8_t oper) {
sbc(cpu, mem_get_byte_zpg(cpu, oper));
sbc(cpu, get_byte_zpg(cpu, oper));
}
static void sbc_zpgx(struct cpu_t *cpu, uint8_t oper) {
sbc(cpu, mem_get_byte_zpgx(cpu, oper));
sbc(cpu, get_byte_zpgx(cpu, oper));
}
static void sbc_abs(struct cpu_t *cpu, uint16_t oper) {
sbc(cpu, mem_get_byte_abs(cpu, oper));
sbc(cpu, get_byte_abs(cpu, oper));
}
static void sbc_absx(struct cpu_t *cpu, uint16_t oper) {
sbc(cpu, mem_get_byte_absx(cpu, oper));
sbc(cpu, get_byte_absx(cpu, oper));
}
static void sbc_absy(struct cpu_t *cpu, uint16_t oper) {
sbc(cpu, mem_get_byte_absy(cpu, oper));
sbc(cpu, get_byte_absy(cpu, oper));
}
static void sbc_indx(struct cpu_t *cpu, uint8_t oper) {
sbc(cpu, mem_get_byte_indx(cpu, oper));
sbc(cpu, get_byte_indx(cpu, oper));
}
static void sbc_indy(struct cpu_t *cpu, uint8_t oper) {
sbc(cpu, mem_get_byte_indy(cpu, oper));
sbc(cpu, get_byte_indy(cpu, oper));
}
/* SEx */
@ -830,59 +933,59 @@ static void sei(struct cpu_t *cpu) {
/* STA */
static void sta_zpg(struct cpu_t *cpu, uint8_t oper) {
mem_set_byte_zpg(cpu, oper, cpu->state.a);
set_byte_zpg(cpu, oper, cpu->state.a);
}
static void sta_zpgx(struct cpu_t *cpu, uint8_t oper) {
mem_set_byte_zpgx(cpu, oper, cpu->state.a);
set_byte_zpgx(cpu, oper, cpu->state.a);
}
static void sta_abs(struct cpu_t *cpu, uint16_t oper) {
mem_set_byte_abs(cpu, oper, cpu->state.a);
set_byte_abs(cpu, oper, cpu->state.a);
}
static void sta_absx(struct cpu_t *cpu, uint16_t oper) {
mem_set_byte_absx(cpu, oper, cpu->state.a);
set_byte_absx(cpu, oper, cpu->state.a);
}
static void sta_absy(struct cpu_t *cpu, uint16_t oper) {
mem_set_byte_absy(cpu, oper, cpu->state.a);
set_byte_absy(cpu, oper, cpu->state.a);
}
static void sta_indx(struct cpu_t *cpu, uint8_t oper) {
mem_set_byte_indx(cpu, oper, cpu->state.a);
set_byte_indx(cpu, oper, cpu->state.a);
}
static void sta_indy(struct cpu_t *cpu, uint8_t oper) {
mem_set_byte_indy(cpu, oper, cpu->state.a);
set_byte_indy(cpu, oper, cpu->state.a);
}
/* STX */
static void stx_zpg(struct cpu_t *cpu, uint8_t oper) {
mem_set_byte_zpg(cpu, oper, cpu->state.x);
set_byte_zpg(cpu, oper, cpu->state.x);
}
static void stx_zpgy(struct cpu_t *cpu, uint8_t oper) {
mem_set_byte_zpgy(cpu, oper, cpu->state.x);
set_byte_zpgy(cpu, oper, cpu->state.x);
}
static void stx_abs(struct cpu_t *cpu, uint16_t oper) {
mem_set_byte_abs(cpu, oper, cpu->state.x);
set_byte_abs(cpu, oper, cpu->state.x);
}
/* STY */
static void sty_zpg(struct cpu_t *cpu, uint8_t oper) {
mem_set_byte_zpg(cpu, oper, cpu->state.y);
set_byte_zpg(cpu, oper, cpu->state.y);
}
static void sty_zpgx(struct cpu_t *cpu, uint8_t oper) {
mem_set_byte_zpgx(cpu, oper, cpu->state.y);
set_byte_zpgx(cpu, oper, cpu->state.y);
}
static void sty_abs(struct cpu_t *cpu, uint16_t oper) {
mem_set_byte_abs(cpu, oper, cpu->state.y);
set_byte_abs(cpu, oper, cpu->state.y);
}
/* Txx */
@ -1191,36 +1294,36 @@ struct cpu_instruction_t instructions[256] = {
// EWM_CPU_MODEL_65C02
static void ora_ind(struct cpu_t *cpu, uint8_t oper) {
ora(cpu, mem_get_byte_ind(cpu, oper));
ora(cpu, get_byte_ind(cpu, oper));
}
static void and_ind(struct cpu_t *cpu, uint8_t oper) {
and(cpu, mem_get_byte_ind(cpu, oper));
and(cpu, get_byte_ind(cpu, oper));
}
static void eor_ind(struct cpu_t *cpu, uint8_t oper) {
eor(cpu, mem_get_byte_ind(cpu, oper));
eor(cpu, get_byte_ind(cpu, oper));
}
static void adc_ind(struct cpu_t *cpu, uint8_t oper) {
adc(cpu, mem_get_byte_ind(cpu, oper));
adc(cpu, get_byte_ind(cpu, oper));
}
static void sta_ind(struct cpu_t *cpu, uint8_t oper) {
mem_set_byte_ind(cpu, oper, cpu->state.a);
set_byte_ind(cpu, oper, cpu->state.a);
}
static void lda_ind(struct cpu_t *cpu, uint8_t oper) {
cpu->state.a = mem_get_byte_ind(cpu, oper);
cpu->state.a = get_byte_ind(cpu, oper);
update_zn(cpu, cpu->state.a);
}
static void cmp_ind(struct cpu_t *cpu, uint8_t oper) {
cmp(cpu, mem_get_byte_ind(cpu, oper));
cmp(cpu, get_byte_ind(cpu, oper));
}
static void sbc_ind(struct cpu_t *cpu, uint8_t oper) {
sbc(cpu, mem_get_byte_ind(cpu, oper));
sbc(cpu, get_byte_ind(cpu, oper));
}
static void bit_imm(struct cpu_t *cpu, uint8_t oper) {
@ -1229,11 +1332,11 @@ static void bit_imm(struct cpu_t *cpu, uint8_t oper) {
}
static void bit_zpgx(struct cpu_t *cpu, uint8_t oper) {
bit(cpu, mem_get_byte_zpgx(cpu, oper));
bit(cpu, get_byte_zpgx(cpu, oper));
}
static void bit_absx(struct cpu_t *cpu, uint16_t oper) {
bit(cpu, mem_get_byte_absx(cpu, oper));
bit(cpu, get_byte_absx(cpu, oper));
}
static void dec_acc(struct cpu_t *cpu) {
@ -1273,47 +1376,47 @@ static void ply(struct cpu_t *cpu) {
}
static void stz_zpg(struct cpu_t *cpu, uint8_t oper) {
mem_set_byte_zpg(cpu, oper, 0x00);
set_byte_zpg(cpu, oper, 0x00);
}
static void stz_zpgx(struct cpu_t *cpu, uint8_t oper) {
mem_set_byte_zpgx(cpu, oper, 0x00);
set_byte_zpgx(cpu, oper, 0x00);
}
static void stz_abs(struct cpu_t *cpu, uint16_t oper) {
mem_set_byte_abs(cpu, oper, 0x00);
set_byte_abs(cpu, oper, 0x00);
}
static void stz_absx(struct cpu_t *cpu, uint16_t oper) {
mem_set_byte_absx(cpu, oper, 0x00);
set_byte_absx(cpu, oper, 0x00);
}
static void trb_zpg(struct cpu_t *cpu, uint8_t oper) {
cpu->state.z = (mem_get_byte(cpu, oper) & cpu->state.a) == 0;
uint8_t r = mem_get_byte(cpu, oper) & ~cpu->state.a;
mem_set_byte_zpg(cpu, oper, r);
set_byte_zpg(cpu, oper, r);
}
static void trb_abs(struct cpu_t *cpu, uint16_t oper) {
cpu->state.z = (mem_get_byte(cpu, oper) & cpu->state.a) == 0;
uint8_t r = mem_get_byte(cpu, oper) & (cpu->state.a ^ 0xff);
mem_set_byte_abs(cpu, oper, r);
set_byte_abs(cpu, oper, r);
}
static void tsb_zpg(struct cpu_t *cpu, uint8_t oper) {
cpu->state.z = (mem_get_byte(cpu, oper) & cpu->state.a) == 0;
uint8_t r = mem_get_byte(cpu, oper) | cpu->state.a;
mem_set_byte_zpg(cpu, oper, r);
set_byte_zpg(cpu, oper, r);
}
static void tsb_abs(struct cpu_t *cpu, uint16_t oper) {
cpu->state.z = (mem_get_byte(cpu, oper) & cpu->state.a) == 0;
uint8_t r = mem_get_byte(cpu, oper) | cpu->state.a;
mem_set_byte_abs(cpu, oper, r);
set_byte_abs(cpu, oper, r);
}
static void bbr(struct cpu_t *cpu, uint8_t bit, uint8_t zp, int8_t label) {
if ((mem_get_byte_zpg(cpu, zp) & bit) == 0) {
if ((get_byte_zpg(cpu, zp) & bit) == 0) {
cpu->state.pc += label;
}
}
@ -1351,7 +1454,7 @@ static void bbr7(struct cpu_t *cpu, uint16_t oper) {
}
static void bbs(struct cpu_t *cpu, uint8_t bit, uint8_t zp, int8_t label) {
if ((mem_get_byte_zpg(cpu, zp) & bit) != 0) {
if ((get_byte_zpg(cpu, zp) & bit) != 0) {
cpu->state.pc += label;
}
}
@ -1389,7 +1492,7 @@ static void bbs7(struct cpu_t *cpu, uint16_t oper) {
}
static void rmb(struct cpu_t *cpu, uint8_t bit, uint8_t zp) {
mem_set_byte_zpg(cpu, zp, mem_get_byte(cpu, zp) & ~bit);
set_byte_zpg(cpu, zp, mem_get_byte(cpu, zp) & ~bit);
}
static void rmb0(struct cpu_t *cpu, uint8_t oper) {
@ -1425,7 +1528,7 @@ static void rmb7(struct cpu_t *cpu, uint8_t oper) {
}
static void smb(struct cpu_t *cpu, uint8_t bit, uint8_t zp) {
mem_set_byte_zpg(cpu, zp, mem_get_byte(cpu, zp) | bit);
set_byte_zpg(cpu, zp, mem_get_byte(cpu, zp) | bit);
}
static void smb0(struct cpu_t *cpu, uint8_t oper) {

112
src/mem.c
View File

@ -50,8 +50,6 @@ uint8_t mem_get_byte(struct cpu_t *cpu, uint16_t addr) {
return 0;
}
extern struct ewm_two_t *two;
void mem_set_byte(struct cpu_t *cpu, uint16_t addr, uint8_t v) {
if (addr < cpu->ram_size) {
cpu->ram[addr] = v;
@ -70,125 +68,17 @@ void mem_set_byte(struct cpu_t *cpu, uint16_t addr, uint8_t v) {
}
}
// Getters
uint8_t mem_get_byte_abs(struct cpu_t *cpu, uint16_t addr) {
return mem_get_byte(cpu, addr);
}
uint8_t mem_get_byte_absx(struct cpu_t *cpu, uint16_t addr) {
return mem_get_byte(cpu, addr + cpu->state.x);
}
uint8_t mem_get_byte_absy(struct cpu_t *cpu, uint16_t addr) {
return mem_get_byte(cpu, addr + cpu->state.y);
}
uint8_t mem_get_byte_zpg(struct cpu_t *cpu, uint8_t addr) {
return mem_get_byte(cpu, addr);
}
uint8_t mem_get_byte_zpgx(struct cpu_t *cpu, uint8_t addr) {
return mem_get_byte(cpu, ((uint16_t) addr + cpu->state.x) & 0x00ff);
}
uint8_t mem_get_byte_zpgy(struct cpu_t *cpu, uint8_t addr) {
return mem_get_byte(cpu, ((uint16_t) addr + cpu->state.y) & 0x00ff);
}
uint8_t mem_get_byte_indx(struct cpu_t *cpu, uint8_t addr) {
return mem_get_byte(cpu, (((uint16_t) cpu->ram[((uint16_t)addr+1+cpu->state.x)&0x00ff] << 8) | (uint16_t) cpu->ram[((uint16_t) addr+cpu->state.x) & 0x00ff]));
}
uint8_t mem_get_byte_indy(struct cpu_t *cpu, uint8_t addr) {
return mem_get_byte(cpu, (((uint16_t) cpu->ram[addr+1] << 8) | (uint16_t) cpu->ram[addr]) + cpu->state.y);
}
uint8_t mem_get_byte_ind(struct cpu_t *cpu, uint8_t addr) {
return mem_get_byte(cpu, ((uint16_t) cpu->ram[addr+1] << 8) | (uint16_t) cpu->ram[addr]);
}
// TODO Where are these used?
uint16_t mem_get_word(struct cpu_t *cpu, uint16_t addr) {
return ((uint16_t) mem_get_byte(cpu, addr+1) << 8) | (uint16_t) mem_get_byte(cpu, addr);
}
// Setters
void mem_set_byte_zpg(struct cpu_t *cpu, uint8_t addr, uint8_t v) {
mem_set_byte(cpu, addr, v);
}
void mem_set_byte_zpgx(struct cpu_t *cpu, uint8_t addr, uint8_t v) {
mem_set_byte(cpu, ((uint16_t) addr + cpu->state.x) & 0x00ff, v);
}
void mem_set_byte_zpgy(struct cpu_t *cpu, uint8_t addr, uint8_t v) {
mem_set_byte(cpu, ((uint16_t) addr + cpu->state.y) & 0x00ff, v);
}
void mem_set_byte_abs(struct cpu_t *cpu, uint16_t addr, uint8_t v) {
mem_set_byte(cpu, addr, v);
}
void mem_set_byte_absx(struct cpu_t *cpu, uint16_t addr, uint8_t v) {
mem_set_byte(cpu, addr+cpu->state.x, v);
}
void mem_set_byte_absy(struct cpu_t *cpu, uint16_t addr, uint8_t v) {
mem_set_byte(cpu, addr+cpu->state.y, v);
}
void mem_set_byte_indx(struct cpu_t *cpu, uint8_t addr, uint8_t v) {
mem_set_byte(cpu, (((uint16_t) cpu->ram[((uint16_t)addr+1+cpu->state.x)&0x00ff] << 8) | (uint16_t) cpu->ram[((uint16_t) addr+cpu->state.x) & 0x00ff]), v);
}
void mem_set_byte_indy(struct cpu_t *cpu, uint8_t addr, uint8_t v) {
mem_set_byte(cpu, (((uint16_t) cpu->ram[addr+1] << 8) | (uint16_t) cpu->ram[addr]) + cpu->state.y, v);
}
void mem_set_byte_ind(struct cpu_t *cpu, uint8_t addr, uint8_t v) {
mem_set_byte(cpu, (((uint16_t) cpu->ram[addr+1] << 8) | (uint16_t) cpu->ram[addr]), v);
}
void mem_set_word(struct cpu_t *cpu, uint16_t addr, uint16_t v) {
mem_set_byte(cpu, addr+0, (uint8_t) v); // TODO Did I do this right?
mem_set_byte(cpu, addr+1, (uint8_t) (v >> 8));
}
/* MOD */
void mem_mod_byte_zpg(struct cpu_t *cpu, uint8_t addr, mem_mod_t op) {
mem_set_byte_zpg(cpu, addr, op(cpu, mem_get_byte_zpg(cpu, addr)));
}
void mem_mod_byte_zpgx(struct cpu_t *cpu, uint8_t addr, mem_mod_t op) {
mem_set_byte_zpgx(cpu, addr, op(cpu, mem_get_byte_zpgx(cpu, addr)));
}
void mem_mod_byte_zpgy(struct cpu_t *cpu, uint8_t addr, mem_mod_t op) {
mem_set_byte_zpgy(cpu, addr, op(cpu, mem_get_byte_zpgy(cpu, addr)));
}
void mem_mod_byte_abs(struct cpu_t *cpu, uint16_t addr, mem_mod_t op) {
mem_set_byte_abs(cpu, addr, op(cpu, mem_get_byte_abs(cpu, addr)));
}
void mem_mod_byte_absx(struct cpu_t *cpu, uint16_t addr, mem_mod_t op) {
mem_set_byte_absx(cpu, addr, op(cpu, mem_get_byte_absx(cpu, addr)));
}
void mem_mod_byte_absy(struct cpu_t *cpu, uint16_t addr, mem_mod_t op) {
mem_set_byte_absy(cpu, addr, op(cpu, mem_get_byte_absy(cpu, addr)));
}
void mem_mod_byte_indx(struct cpu_t *cpu, uint8_t addr, mem_mod_t op) {
mem_set_byte_indx(cpu, addr, op(cpu, mem_get_byte_indx(cpu, addr)));
}
void mem_mod_byte_indy(struct cpu_t *cpu, uint8_t addr, mem_mod_t op) {
mem_set_byte_indy(cpu, addr, op(cpu, mem_get_byte_indy(cpu, addr)));
}
// For parsing --memory options
struct ewm_memory_option_t *parse_memory_option(char *s) {

View File

@ -32,34 +32,34 @@ typedef uint8_t (*mem_mod_t)(struct cpu_t *cpu, uint8_t b);
uint8_t mem_get_byte(struct cpu_t *cpu, uint16_t addr);
void mem_set_byte(struct cpu_t *cpu, uint16_t addr, uint8_t v);
uint8_t mem_get_byte_abs(struct cpu_t *cpu, uint16_t addr);
uint8_t mem_get_byte_absx(struct cpu_t *cpu, uint16_t addr);
uint8_t mem_get_byte_absy(struct cpu_t *cpu, uint16_t addr);
uint8_t mem_get_byte_zpg(struct cpu_t *cpu, uint8_t addr);
uint8_t mem_get_byte_zpgx(struct cpu_t *cpu, uint8_t addr);
uint8_t mem_get_byte_zpgy(struct cpu_t *cpu, uint8_t addr);
uint8_t mem_get_byte_indx(struct cpu_t *cpu, uint8_t addr);
uint8_t mem_get_byte_indy(struct cpu_t *cpu, uint8_t addr);
uint8_t mem_get_byte_ind(struct cpu_t *cpu, uint8_t addr);
/* uint8_t mem_get_byte_abs(struct cpu_t *cpu, uint16_t addr); */
/* uint8_t mem_get_byte_absx(struct cpu_t *cpu, uint16_t addr); */
/* uint8_t mem_get_byte_absy(struct cpu_t *cpu, uint16_t addr); */
/* uint8_t mem_get_byte_zpg(struct cpu_t *cpu, uint8_t addr); */
/* uint8_t mem_get_byte_zpgx(struct cpu_t *cpu, uint8_t addr); */
/* uint8_t mem_get_byte_zpgy(struct cpu_t *cpu, uint8_t addr); */
/* uint8_t mem_get_byte_indx(struct cpu_t *cpu, uint8_t addr); */
/* uint8_t mem_get_byte_indy(struct cpu_t *cpu, uint8_t addr); */
/* uint8_t mem_get_byte_ind(struct cpu_t *cpu, uint8_t addr); */
void mem_set_byte_zpg(struct cpu_t *cpu, uint8_t addr, uint8_t v);
void mem_set_byte_zpgx(struct cpu_t *cpu, uint8_t addr, uint8_t v);
void mem_set_byte_zpgy(struct cpu_t *cpu, uint8_t addr, uint8_t v);
void mem_set_byte_abs(struct cpu_t *cpu, uint16_t addr, uint8_t v);
void mem_set_byte_absx(struct cpu_t *cpu, uint16_t addr, uint8_t v);
void mem_set_byte_absy(struct cpu_t *cpu, uint16_t addr, uint8_t v);
void mem_set_byte_indx(struct cpu_t *cpu, uint8_t addr, uint8_t v);
void mem_set_byte_indy(struct cpu_t *cpu, uint8_t addr, uint8_t v);
void mem_set_byte_ind(struct cpu_t *cpu, uint8_t addr, uint8_t v);
/* void mem_set_byte_zpg(struct cpu_t *cpu, uint8_t addr, uint8_t v); */
/* void mem_set_byte_zpgx(struct cpu_t *cpu, uint8_t addr, uint8_t v); */
/* void mem_set_byte_zpgy(struct cpu_t *cpu, uint8_t addr, uint8_t v); */
/* void mem_set_byte_abs(struct cpu_t *cpu, uint16_t addr, uint8_t v); */
/* void mem_set_byte_absx(struct cpu_t *cpu, uint16_t addr, uint8_t v); */
/* void mem_set_byte_absy(struct cpu_t *cpu, uint16_t addr, uint8_t v); */
/* void mem_set_byte_indx(struct cpu_t *cpu, uint8_t addr, uint8_t v); */
/* void mem_set_byte_indy(struct cpu_t *cpu, uint8_t addr, uint8_t v); */
/* void mem_set_byte_ind(struct cpu_t *cpu, uint8_t addr, uint8_t v); */
void mem_mod_byte_zpg(struct cpu_t *cpu, uint8_t addr, mem_mod_t op);
void mem_mod_byte_zpgx(struct cpu_t *cpu, uint8_t addr, mem_mod_t op);
void mem_mod_byte_zpgy(struct cpu_t *cpu, uint8_t addr, mem_mod_t op);
void mem_mod_byte_abs(struct cpu_t *cpu, uint16_t addr, mem_mod_t op);
void mem_mod_byte_absx(struct cpu_t *cpu, uint16_t addr, mem_mod_t op);
void mem_mod_byte_absy(struct cpu_t *cpu, uint16_t addr, mem_mod_t op);
void mem_mod_byte_indx(struct cpu_t *cpu, uint8_t addr, mem_mod_t op);
void mem_mod_byte_indy(struct cpu_t *cpu, uint8_t addr, mem_mod_t op);
/* void mem_mod_byte_zpg(struct cpu_t *cpu, uint8_t addr, mem_mod_t op); */
/* void mem_mod_byte_zpgx(struct cpu_t *cpu, uint8_t addr, mem_mod_t op); */
/* void mem_mod_byte_zpgy(struct cpu_t *cpu, uint8_t addr, mem_mod_t op); */
/* void mem_mod_byte_abs(struct cpu_t *cpu, uint16_t addr, mem_mod_t op); */
/* void mem_mod_byte_absx(struct cpu_t *cpu, uint16_t addr, mem_mod_t op); */
/* void mem_mod_byte_absy(struct cpu_t *cpu, uint16_t addr, mem_mod_t op); */
/* void mem_mod_byte_indx(struct cpu_t *cpu, uint8_t addr, mem_mod_t op); */
/* void mem_mod_byte_indy(struct cpu_t *cpu, uint8_t addr, mem_mod_t op); */
uint16_t mem_get_word(struct cpu_t *cpu, uint16_t addr);
void mem_set_word(struct cpu_t *cpu, uint16_t addr, uint16_t v);

View File

@ -28,6 +28,7 @@
#include "mem.h"
#include "utl.h"
#if 0
#define MEM_BENCH_ITERATIONS (100 * 1000 * 1000)
#define MEM_GET_TEST(NAME, ADDR) \
@ -150,8 +151,10 @@ void test(struct cpu_t *cpu, char *name, test_run_t test_run) {
printf("%-32s %8llu\n", name, duration_ms);
}
#endif
int main(int argc, char **argv) {
#if 0
struct cpu_t *cpu = cpu_create(EWM_CPU_MODEL_6502);
cpu_add_ram_data(cpu, 0, 0xffff, malloc(0xffff));
cpu_reset(cpu);
@ -185,4 +188,5 @@ int main(int argc, char **argv) {
RUN_TEST(mem_set_byte_ind, 0x12);
RUN_TEST(mem_set_byte_indx, 0x12);
RUN_TEST(mem_set_byte_indy, 0x12);
#endif
}