Skip to content

Commit

Permalink
various fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
ziplantil committed Oct 21, 2022
1 parent 91b4f61 commit 9d3eb86
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 12 deletions.
41 changes: 32 additions & 9 deletions include/w65c02s.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@
w65c02s.h -- cycle-accurate C emulator of the WDC 65C02S
as a single-header library
by ziplantil 2022 -- under the CC0 license
version: 2022-10-21
version: 2022-10-22
please report issues to <https://github.com/ziplantil/w65c02s.h>
*******************************************************************************/

#ifdef __cplusplus
extern "C" {
#undef W65C02S_HAS_BOOL
#define W65C02S_HAS_BOOL 1
#endif

#ifndef W65C02S_H
#define W65C02S_H

Expand Down Expand Up @@ -641,8 +648,9 @@ struct w65c02s_cpu {
#define W65C02S_INLINE static
#endif

#if W65C02S_C23
#include <stddef.h>

#if W65C02S_C23
#define W65C02S_UNREACHABLE() unreachable()
#define W65C02S_ASSUME(x) do { if (!(x)) unreachable(); } while (0)
#elif W65C02S_GNUC
Expand Down Expand Up @@ -1045,7 +1053,7 @@ static uint8_t w65c02s_oper_adc_d(struct w65c02s_cpu *cpu,
W65C02S_SET_P_ADJ(W65C02S_P_C, fc);
/* keep W65C02S_P_V as in binary addition */
W65C02S_SET_P(W65C02S_P_C, fc);
return q;
return (uint8_t)q;
}

static uint8_t w65c02s_oper_sbc_d(struct w65c02s_cpu *cpu,
Expand All @@ -1068,13 +1076,13 @@ static uint8_t w65c02s_oper_sbc_d(struct w65c02s_cpu *cpu,
W65C02S_SET_P_ADJ(W65C02S_P_C, fc);
/* keep W65C02S_P_V as in binary addition */
W65C02S_SET_P(W65C02S_P_C, fc);
return q;
return (uint8_t)q;
}

W65C02S_INLINE uint8_t w65c02s_oper_adc(struct w65c02s_cpu *cpu,
uint8_t a, uint8_t b) {
uint8_t r;
unsigned c = W65C02S_GET_P(W65C02S_P_C);
uint8_t c = W65C02S_GET_P(W65C02S_P_C);
W65C02S_SET_P(W65C02S_P_V, w65c02s_oper_adc_v(a, b, c));
r = w65c02s_mark_nzc8(cpu, a + b + c);
if (!W65C02S_GET_P(W65C02S_P_D)) return r;
Expand All @@ -1084,7 +1092,7 @@ W65C02S_INLINE uint8_t w65c02s_oper_adc(struct w65c02s_cpu *cpu,
W65C02S_INLINE uint8_t w65c02s_oper_sbc(struct w65c02s_cpu *cpu,
uint8_t a, uint8_t b) {
uint8_t r;
unsigned c = W65C02S_GET_P(W65C02S_P_C);
uint8_t c = W65C02S_GET_P(W65C02S_P_C);
b = ~b;
W65C02S_SET_P(W65C02S_P_V, w65c02s_oper_adc_v(a, b, c));
r = w65c02s_mark_nzc8(cpu, a + b + c);
Expand Down Expand Up @@ -1816,7 +1824,7 @@ static unsigned w65c02s_mode_rmw_absolute_x(W65C02S_PARAMS_MODE) {
cpu->tr[0] += cpu->x;
if (!overflow && w65c02s_fast_rmw_absx(cpu->oper))
W65C02S_SKIP_TO_NEXT(4);
cpu->tr[1] += overflow;
cpu->tr[1] += (uint8_t)overflow;
}
W65C02S_READ(W65C02S_GET_T16(0));
W65C02S_CYCLE(4)
Expand Down Expand Up @@ -2009,10 +2017,10 @@ static unsigned w65c02s_mode_nop_5c(W65C02S_PARAMS_MODE) {
W65C02S_CYCLE(2)
cpu->tr[1] = W65C02S_READ(cpu->pc++);
W65C02S_CYCLE(3)
cpu->tr[1] = -1;
cpu->tr[1] = (uint8_t)-1;
W65C02S_READ(W65C02S_GET_T16(0));
W65C02S_CYCLE(4)
cpu->tr[0] = -1;
cpu->tr[0] = (uint8_t)-1;
W65C02S_READ(W65C02S_GET_T16(0));
W65C02S_CYCLE(5)
W65C02S_READ(W65C02S_GET_T16(0));
Expand Down Expand Up @@ -2054,9 +2062,11 @@ static unsigned w65c02s_mode_int_wait_stop(W65C02S_PARAMS_MODE) {
}

static unsigned w65c02s_mode_implied_1c(W65C02S_PARAMS_MODE) {
(void)cpu;
#if W65C02S_COARSE
return 1; /* spent 1 cycle doing nothing */
#else
(void)cont;
return 0; /* return immediately */
#endif
}
Expand Down Expand Up @@ -2672,6 +2682,9 @@ void w65c02s_init(struct w65c02s_cpu *cpu,
#if !W65C02S_LINK
cpu->mem_read = mem_read ? mem_read : &w65c02s_openbus_read;
cpu->mem_write = mem_write ? mem_write : &w65c02s_openbus_write;
#else
(void)mem_read;
(void)mem_write;
#endif
cpu->hook_brk = NULL;
cpu->hook_stp = NULL;
Expand Down Expand Up @@ -2788,6 +2801,8 @@ bool w65c02s_hook_brk(struct w65c02s_cpu *cpu, bool (*brk_hook)(uint8_t)) {
cpu->hook_brk = brk_hook;
return true;
#else
(void)cpu;
(void)brk_hook;
return false;
#endif
}
Expand All @@ -2798,6 +2813,8 @@ bool w65c02s_hook_stp(struct w65c02s_cpu *cpu, bool (*stp_hook)(void)) {
cpu->hook_stp = stp_hook;
return true;
#else
(void)cpu;
(void)stp_hook;
return false;
#endif
}
Expand All @@ -2808,6 +2825,8 @@ bool w65c02s_hook_end_of_instruction(struct w65c02s_cpu *cpu,
cpu->hook_eoi = instruction_hook;
return true;
#else
(void)cpu;
(void)instruction_hook;
return false;
#endif
}
Expand Down Expand Up @@ -2894,3 +2913,7 @@ void w65c02s_reg_set_pc(struct w65c02s_cpu *cpu, uint16_t v) {
}

#endif /* W65C02S_IMPL */

#ifdef __cplusplus
}
#endif
2 changes: 1 addition & 1 deletion test/benchmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
w65c02s.h -- cycle-accurate C emulator of the WDC 65C02S
as a single-header library
by ziplantil 2022 -- under the CC0 license
version: 2022-10-21
version: 2022-10-22
busdump.c - bus dump program
*******************************************************************************/
Expand Down
80 changes: 80 additions & 0 deletions test/breaktest.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*******************************************************************************
w65c02s.h -- cycle-accurate C emulator of the WDC 65C02S
as a single-header library
by ziplantil 2022 -- under the CC0 license
version: 2022-10-22
breaktest.c - w65c02s_break test program
*******************************************************************************/

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define W65C02S_IMPL 1
#define W65C02S_LINK 1
#include "w65c02s.h"

#if __STDC_VERSION__ >= 201112L
_Alignas(128)
#endif
uint8_t ram[65536];
struct w65c02s_cpu cpu;
unsigned long cycles;
unsigned long break_cycles;

uint8_t w65c02s_read(uint16_t a) {
if (!--break_cycles) w65c02s_break(&cpu);
return ram[a];
}

void w65c02s_write(uint16_t a, uint8_t v) {
if (!--break_cycles) w65c02s_break(&cpu);
ram[a] = v;
}

uint16_t vector = 0;

static size_t loadmemfromfile(const char *filename) {
FILE *file = fopen(filename, "rb");
size_t size = 0;

if (!file) {
perror("fopen");
return 0;
}

size = fread(ram, 1, 0x10000UL, file);
fclose(file);
return size;
}

int main(int argc, char *argv[]) {
if (argc <= 4) {
printf("%s <file_in> <vector> <cyclecount> <breakcyclecount>\n", argv[0]);
return EXIT_FAILURE;
}

if (!loadmemfromfile(argv[1])) {
return EXIT_FAILURE;
}

vector = strtoul(argv[2], NULL, 16);
cycles = strtoul(argv[3], NULL, 0);
break_cycles = -1;

w65c02s_init(&cpu, NULL, NULL, NULL);
/* RESET cycles */
w65c02s_run_cycles(&cpu, 7);

break_cycles = strtoul(argv[4], NULL, 0);

printf("Running %lu cycles but breaking after %lu cycles\n", cycles, break_cycles);
cpu.pc = vector;
cycles = w65c02s_run_cycles(&cpu, cycles);
printf("Ran %lu cycles\n", cycles);

return EXIT_SUCCESS;
}
2 changes: 1 addition & 1 deletion test/busdump.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
w65c02s.h -- cycle-accurate C emulator of the WDC 65C02S
as a single-header library
by ziplantil 2022 -- under the CC0 license
version: 2022-10-21
version: 2022-10-22
busdump.c - bus dump program
*******************************************************************************/
Expand Down
2 changes: 1 addition & 1 deletion test/monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
w65c02s.h -- cycle-accurate C emulator of the WDC 65C02S
as a single-header library
by ziplantil 2022 -- under the CC0 license
version: 2022-10-21
version: 2022-10-22
monitor.c - test monitor
*******************************************************************************/
Expand Down

0 comments on commit 9d3eb86

Please sign in to comment.