mirror of
https://github.com/rkujawa/rk65c02.git
synced 2026-04-22 06:16:39 +00:00
Add host-control callbacks and JIT-safe polling.
Expose stop/tick/request-stop APIs, keep host control active at JIT block boundaries, and document the control model with a fuller host example plus dependency-aware builds. Made-with: Cursor
This commit is contained in:
@@ -11,9 +11,7 @@ Currently, the following features are implemented:
|
||||
- 16-bit address space.
|
||||
- Minimal support for interrupts.
|
||||
- JIT using GNU Lightning.
|
||||
|
||||
The following notable features are missing:
|
||||
- Ability to execute callbacks in software utilizing this library.
|
||||
- Host callbacks for stop notification and periodic execution ticks.
|
||||
|
||||
The only external dependencies (besides standard C library) are Boehm GC and
|
||||
uthash. GNU Lightning is required for JIT support, but the library can be built
|
||||
@@ -27,3 +25,50 @@ with std syntax) are also necessary.
|
||||
|
||||
[](https://forthebadge.com)
|
||||
|
||||
## Host control API
|
||||
|
||||
Typical host integration pattern is:
|
||||
|
||||
1. Create and configure `rk65c02emu_t`.
|
||||
2. Register optional callbacks:
|
||||
- `rk65c02_on_stop_set()` to be notified why execution stopped.
|
||||
- `rk65c02_tick_set()` to periodically run host code while interpreter runs.
|
||||
3. Start execution with `rk65c02_start()` (or bounded execution with `rk65c02_step()`).
|
||||
4. Inspect or modify state (`e.regs`, bus reads/writes) and continue.
|
||||
|
||||
Host can request cooperative stop using:
|
||||
|
||||
- `rk65c02_request_stop(&e)` - asks emulator to stop at the next safe boundary.
|
||||
Stop reason is reported as `HOST`.
|
||||
|
||||
Notes:
|
||||
|
||||
- Tick callback works in both execution modes:
|
||||
- interpreter mode checks tick after each instruction;
|
||||
- JIT mode checks tick at compiled block boundaries (coarser granularity).
|
||||
- If precise per-instruction callback cadence is required, run without JIT.
|
||||
- `on_stop` is called when execution stops from `rk65c02_start()` and
|
||||
`rk65c02_step()` (for example: `STP`, `WAI`, `BREAKPOINT`, `HOST`,
|
||||
`STEPPED`, `EMUERROR`).
|
||||
- `rk65c02_stop_reason_string()` converts `emu_stop_reason_t` values to
|
||||
readable strings for logs/UI.
|
||||
|
||||
## Examples
|
||||
|
||||
`examples/` contains small host programs using the library:
|
||||
|
||||
- `min3` - computes minimum of three values using a ROM routine.
|
||||
- `mul_8bit_to_8bits` - multiplies two 8-bit values.
|
||||
- `host_control` - demonstrates full host-control flow with:
|
||||
- `rk65c02_on_stop_set()` callback.
|
||||
- `rk65c02_tick_set()` callback.
|
||||
- host-driven stop via `rk65c02_request_stop()`.
|
||||
- continuing with `rk65c02_step()` after stop.
|
||||
|
||||
Build examples with:
|
||||
|
||||
```sh
|
||||
make -C src
|
||||
make -C examples
|
||||
```
|
||||
|
||||
|
||||
+8
-2
@@ -1,6 +1,6 @@
|
||||
UNAME_S := $(shell uname -s)
|
||||
|
||||
CFLAGS=-Wall -pedantic -I../src -g
|
||||
CFLAGS=-Wall -pedantic -I../src -g -MMD -MP
|
||||
LDFLAGS=-lgc -llightning
|
||||
|
||||
LDFLAGS_MACOSX=-L/opt/local/lib
|
||||
@@ -15,7 +15,7 @@ RK6502LIB=../src/librk65c02.a
|
||||
VASM=vasm6502_std
|
||||
VASMFLAGS=-Fbin -wdc02
|
||||
|
||||
EXAMPLES=min3 mul_8bit_to_8bits
|
||||
EXAMPLES=min3 mul_8bit_to_8bits host_control
|
||||
EXAMPLES_ROMS:=$(addsuffix .rom,$(basename $(wildcard *.s)))
|
||||
|
||||
all : $(EXAMPLES) $(EXAMPLES_ROMS)
|
||||
@@ -26,6 +26,9 @@ min3 : min3.o $(RK6502LIB)
|
||||
mul_8bit_to_8bits : mul_8bit_to_8bits.o $(RK6502LIB)
|
||||
$(CC) -o $@ $(LDFLAGS) $< $(RK6502LIB)
|
||||
|
||||
host_control : host_control.o $(RK6502LIB)
|
||||
$(CC) -o $@ $(LDFLAGS) $< $(RK6502LIB)
|
||||
|
||||
%.rom : %.s
|
||||
$(VASM) $(VASMFLAGS) -o $@ $<
|
||||
|
||||
@@ -33,5 +36,8 @@ mul_8bit_to_8bits : mul_8bit_to_8bits.o $(RK6502LIB)
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
clean :
|
||||
rm -f *.o
|
||||
rm -f *.d
|
||||
rm -f $(EXAMPLES) $(EXAMPLES_ROMS)
|
||||
|
||||
-include $(wildcard *.d)
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bus.h"
|
||||
#include "rk65c02.h"
|
||||
|
||||
static const uint16_t load_addr = 0xC000;
|
||||
static const uint16_t counter_addr = 0x0200;
|
||||
|
||||
struct host_state {
|
||||
uint32_t ticks_seen;
|
||||
uint32_t tick_budget;
|
||||
bool stop_notified;
|
||||
};
|
||||
|
||||
static void
|
||||
on_stop(rk65c02emu_t *e, emu_stop_reason_t reason, void *ctx)
|
||||
{
|
||||
struct host_state *hs = ctx;
|
||||
|
||||
hs->stop_notified = true;
|
||||
printf("Emulation stopped: %s (PC=%#04x)\n",
|
||||
rk65c02_stop_reason_string(reason),
|
||||
e->regs.PC);
|
||||
}
|
||||
|
||||
static void
|
||||
on_tick(rk65c02emu_t *e, void *ctx)
|
||||
{
|
||||
struct host_state *hs = ctx;
|
||||
|
||||
hs->ticks_seen++;
|
||||
if (hs->ticks_seen >= hs->tick_budget)
|
||||
rk65c02_request_stop(e);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
struct host_state host = {
|
||||
.ticks_seen = 0,
|
||||
.tick_budget = 20000,
|
||||
.stop_notified = false,
|
||||
};
|
||||
rk65c02emu_t e;
|
||||
uint8_t counter_before;
|
||||
uint8_t counter_after;
|
||||
|
||||
e = rk65c02_load_rom("host_control.rom", load_addr, NULL);
|
||||
e.regs.SP = 0xFF;
|
||||
e.regs.PC = load_addr;
|
||||
|
||||
/*
|
||||
* Tick runs every 100 poll points and asks the core to stop after
|
||||
* tick_budget callbacks. In JIT mode poll points are block boundaries,
|
||||
* so cadence is coarser than per-instruction interpreter ticking.
|
||||
*/
|
||||
rk65c02_on_stop_set(&e, on_stop, &host);
|
||||
rk65c02_tick_set(&e, on_tick, 100, &host);
|
||||
rk65c02_jit_enable(&e, true);
|
||||
|
||||
counter_before = bus_read_1(e.bus, counter_addr);
|
||||
rk65c02_start(&e);
|
||||
counter_after = bus_read_1(e.bus, counter_addr);
|
||||
|
||||
printf("Tick callbacks: %" PRIu32 "\n", host.ticks_seen);
|
||||
printf("Counter at $%04x before=%u after=%u\n", counter_addr,
|
||||
counter_before, counter_after);
|
||||
printf("on_stop callback invoked: %s\n",
|
||||
host.stop_notified ? "yes" : "no");
|
||||
|
||||
/* Continue manually with stepping after host-initiated stop. */
|
||||
rk65c02_tick_clear(&e);
|
||||
host.stop_notified = false;
|
||||
rk65c02_step(&e, 5);
|
||||
printf("After 5-step run, stop reason is %s\n",
|
||||
rk65c02_stop_reason_string(e.stopreason));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
.org 0xC000
|
||||
|
||||
start:
|
||||
inc 0x0200
|
||||
bra start
|
||||
+5
-1
@@ -14,7 +14,8 @@ LIB_STATIC=librk65c02.a
|
||||
|
||||
LDFLAGS=-shared -lgc -llightning
|
||||
LDFLAGS_MACOSX=-L/opt/local/lib
|
||||
CFLAGS=-Wall -fpic -ggdb -Og -DHAVE_LIGHTNING
|
||||
#CFLAGS=-Wall -fpic -ggdb -Og -DHAVE_LIGHTNING -MMD -MP
|
||||
CFLAGS=-Wall -fpic -O3 -DHAVE_LIGHTNING -MMD -MP
|
||||
#CFLAGS=-Wall -fpic -Os -fplugin=annobin
|
||||
CFLAGS_MACOSX=-I/opt/local/include/uthash -I/opt/local/include
|
||||
|
||||
@@ -50,6 +51,9 @@ $(EMULATION).h : $(65C02ISA).csv $(EMULATION).awk
|
||||
|
||||
clean :
|
||||
rm -f $(65C02ISA).h $(EMULATION).h
|
||||
rm -f *.d
|
||||
rm -f $(LIB_OBJS) #$(CLI_OBJS)
|
||||
rm -f $(LIB_SO) $(LIB_STATIC) #$(CLI)
|
||||
|
||||
-include $(wildcard *.d)
|
||||
|
||||
|
||||
@@ -1353,8 +1353,13 @@ rk65c02_run_jit(rk65c02emu_t *e)
|
||||
|| e->trace || e->runtime_disassembly
|
||||
|| (e->bps_head != NULL)) {
|
||||
e->state = RUNNING;
|
||||
while (e->state == RUNNING)
|
||||
while (e->state == RUNNING) {
|
||||
rk65c02_poll_host_controls(e);
|
||||
if (e->state != RUNNING)
|
||||
break;
|
||||
rk65c02_exec(e);
|
||||
rk65c02_poll_host_controls(e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1364,6 +1369,10 @@ rk65c02_run_jit(rk65c02emu_t *e)
|
||||
struct rk65c02_jit_block *b;
|
||||
uint16_t pc;
|
||||
|
||||
rk65c02_poll_host_controls(e);
|
||||
if (e->state != RUNNING)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Honour any runtime changes in debugging state by
|
||||
* bailing out to the interpreter if needed.
|
||||
@@ -1383,6 +1392,7 @@ rk65c02_run_jit(rk65c02emu_t *e)
|
||||
}
|
||||
|
||||
b->fn(e);
|
||||
rk65c02_poll_host_controls(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
void rk65c02_run_jit(rk65c02emu_t *e);
|
||||
void rk65c02_poll_host_controls(rk65c02emu_t *e);
|
||||
|
||||
#ifdef HAVE_LIGHTNING
|
||||
/* BCD ADC/SBC helpers: JIT calls these when P_DECIMAL is set. */
|
||||
|
||||
+174
-7
@@ -37,6 +37,87 @@
|
||||
|
||||
void rk65c02_exec(rk65c02emu_t *);
|
||||
|
||||
static void
|
||||
rk65c02_maybe_call_on_stop(rk65c02emu_t *e)
|
||||
{
|
||||
if (e->on_stop != NULL)
|
||||
e->on_stop(e, e->stopreason, e->on_stop_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
rk65c02_apply_host_stop_request(rk65c02emu_t *e)
|
||||
{
|
||||
if (!(e->stop_requested))
|
||||
return;
|
||||
|
||||
e->state = STOPPED;
|
||||
e->stopreason = HOST;
|
||||
e->stop_requested = false;
|
||||
}
|
||||
|
||||
static void
|
||||
rk65c02_maybe_tick(rk65c02emu_t *e)
|
||||
{
|
||||
if (e->tick == NULL)
|
||||
return;
|
||||
|
||||
if ((e->state != RUNNING) && (e->state != STEPPING))
|
||||
return;
|
||||
|
||||
if (e->tick_interval == 0) {
|
||||
e->tick(e, e->tick_ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (e->tick_countdown > 0)
|
||||
e->tick_countdown--;
|
||||
|
||||
if (e->tick_countdown == 0) {
|
||||
e->tick(e, e->tick_ctx);
|
||||
e->tick_countdown = e->tick_interval;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
rk65c02_can_use_jit(const rk65c02emu_t *e)
|
||||
{
|
||||
return e->use_jit && e->jit != NULL && !(e->trace)
|
||||
&& !(e->runtime_disassembly) && (e->bps_head == NULL);
|
||||
}
|
||||
|
||||
void
|
||||
rk65c02_poll_host_controls(rk65c02emu_t *e)
|
||||
{
|
||||
assert(e != NULL);
|
||||
|
||||
rk65c02_apply_host_stop_request(e);
|
||||
rk65c02_maybe_tick(e);
|
||||
rk65c02_apply_host_stop_request(e);
|
||||
}
|
||||
|
||||
const char *
|
||||
rk65c02_stop_reason_string(emu_stop_reason_t reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case STP:
|
||||
return "STP";
|
||||
case WAI:
|
||||
return "WAI";
|
||||
case BREAKPOINT:
|
||||
return "BREAKPOINT";
|
||||
case WATCHPOINT:
|
||||
return "WATCHPOINT";
|
||||
case STEPPED:
|
||||
return "STEPPED";
|
||||
case HOST:
|
||||
return "HOST";
|
||||
case EMUERROR:
|
||||
return "EMUERROR";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
rk65c02emu_t
|
||||
rk65c02_load_rom(const char *path, uint16_t load_addr, bus_t *b)
|
||||
{
|
||||
@@ -77,6 +158,13 @@ rk65c02_init(bus_t *b)
|
||||
|
||||
e.use_jit = false;
|
||||
e.jit = NULL;
|
||||
e.stop_requested = false;
|
||||
e.on_stop = NULL;
|
||||
e.on_stop_ctx = NULL;
|
||||
e.tick = NULL;
|
||||
e.tick_ctx = NULL;
|
||||
e.tick_interval = 0;
|
||||
e.tick_countdown = 0;
|
||||
|
||||
rk65c02_log(LOG_DEBUG, "Initialized new emulator.");
|
||||
|
||||
@@ -180,14 +268,26 @@ rk65c02_start(rk65c02emu_t *e) {
|
||||
* and no debugging features that rely on per-instruction interpreter
|
||||
* state are active. Otherwise fall back to the interpreter loop.
|
||||
*/
|
||||
if (e->use_jit && e->jit != NULL && !(e->trace) && !(e->runtime_disassembly)
|
||||
&& (e->bps_head == NULL))
|
||||
e->stop_requested = false;
|
||||
e->tick_countdown = e->tick_interval;
|
||||
|
||||
if (rk65c02_can_use_jit(e))
|
||||
rk65c02_run_jit(e);
|
||||
else {
|
||||
e->state = RUNNING;
|
||||
while (e->state == RUNNING)
|
||||
while (e->state == RUNNING) {
|
||||
rk65c02_poll_host_controls(e);
|
||||
if (e->state != RUNNING)
|
||||
break;
|
||||
|
||||
rk65c02_exec(e);
|
||||
rk65c02_poll_host_controls(e);
|
||||
}
|
||||
}
|
||||
|
||||
rk65c02_poll_host_controls(e);
|
||||
if (e->state == STOPPED)
|
||||
rk65c02_maybe_call_on_stop(e);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -197,14 +297,76 @@ rk65c02_step(rk65c02emu_t *e, uint16_t steps) {
|
||||
|
||||
assert(e != NULL);
|
||||
|
||||
e->stop_requested = false;
|
||||
e->tick_countdown = e->tick_interval;
|
||||
e->state = STEPPING;
|
||||
while ((e->state == STEPPING) && (i < steps)) {
|
||||
rk65c02_poll_host_controls(e);
|
||||
if (e->state != STEPPING)
|
||||
break;
|
||||
|
||||
rk65c02_exec(e);
|
||||
rk65c02_poll_host_controls(e);
|
||||
i++;
|
||||
}
|
||||
|
||||
e->state = STOPPED;
|
||||
e->stopreason = STEPPED;
|
||||
rk65c02_poll_host_controls(e);
|
||||
if (e->state == STEPPING) {
|
||||
e->state = STOPPED;
|
||||
e->stopreason = STEPPED;
|
||||
}
|
||||
|
||||
if (e->state == STOPPED)
|
||||
rk65c02_maybe_call_on_stop(e);
|
||||
}
|
||||
|
||||
void
|
||||
rk65c02_on_stop_set(rk65c02emu_t *e, rk65c02_on_stop_cb_t cb, void *ctx)
|
||||
{
|
||||
assert(e != NULL);
|
||||
|
||||
e->on_stop = cb;
|
||||
e->on_stop_ctx = ctx;
|
||||
}
|
||||
|
||||
void
|
||||
rk65c02_on_stop_clear(rk65c02emu_t *e)
|
||||
{
|
||||
assert(e != NULL);
|
||||
|
||||
e->on_stop = NULL;
|
||||
e->on_stop_ctx = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
rk65c02_tick_set(rk65c02emu_t *e, rk65c02_tick_cb_t cb, uint32_t interval,
|
||||
void *ctx)
|
||||
{
|
||||
assert(e != NULL);
|
||||
|
||||
e->tick = cb;
|
||||
e->tick_ctx = ctx;
|
||||
e->tick_interval = interval;
|
||||
e->tick_countdown = interval;
|
||||
}
|
||||
|
||||
void
|
||||
rk65c02_tick_clear(rk65c02emu_t *e)
|
||||
{
|
||||
assert(e != NULL);
|
||||
|
||||
e->tick = NULL;
|
||||
e->tick_ctx = NULL;
|
||||
e->tick_interval = 0;
|
||||
e->tick_countdown = 0;
|
||||
}
|
||||
|
||||
void
|
||||
rk65c02_request_stop(rk65c02emu_t *e)
|
||||
{
|
||||
assert(e != NULL);
|
||||
|
||||
e->stop_requested = true;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -268,14 +430,19 @@ void
|
||||
rk65c02_panic(rk65c02emu_t *e, const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
bool was_active;
|
||||
|
||||
assert(e != NULL);
|
||||
|
||||
va_start(args, fmt);
|
||||
rk65c02_logv(LOG_CRIT, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
was_active = ((e->state == RUNNING) || (e->state == STEPPING));
|
||||
e->state = STOPPED;
|
||||
e->stopreason = EMUERROR;
|
||||
|
||||
/* TODO: run some UI callback. */
|
||||
e->stop_requested = false;
|
||||
if (!was_active)
|
||||
rk65c02_maybe_call_on_stop(e);
|
||||
}
|
||||
|
||||
|
||||
+63
-2
@@ -7,6 +7,8 @@
|
||||
#include "bus.h"
|
||||
|
||||
struct rk65c02_jit;
|
||||
struct rk65c02emu;
|
||||
typedef struct rk65c02emu rk65c02emu_t;
|
||||
|
||||
/**
|
||||
* @brief State of the emulator.
|
||||
@@ -30,6 +32,17 @@ typedef enum {
|
||||
EMUERROR /**< Due to emulator error. */
|
||||
} emu_stop_reason_t;
|
||||
|
||||
/**
|
||||
* @brief Callback executed when emulation stops.
|
||||
*/
|
||||
typedef void (*rk65c02_on_stop_cb_t)(rk65c02emu_t *e, emu_stop_reason_t reason,
|
||||
void *ctx);
|
||||
|
||||
/**
|
||||
* @brief Callback executed periodically while emulation is running.
|
||||
*/
|
||||
typedef void (*rk65c02_tick_cb_t)(rk65c02emu_t *e, void *ctx);
|
||||
|
||||
/**
|
||||
* @brief State of the emulated CPU registers.
|
||||
*/
|
||||
@@ -91,10 +104,15 @@ struct rk65c02emu {
|
||||
trace_t *trace_head; /**< Pointer to linked list with trace log. */
|
||||
bool use_jit; /**< Enable/disable JIT execution. */
|
||||
struct rk65c02_jit *jit; /**< Opaque JIT backend state. */
|
||||
bool stop_requested; /**< Host requested stop at next safe boundary. */
|
||||
rk65c02_on_stop_cb_t on_stop; /**< Callback executed after stop. */
|
||||
void *on_stop_ctx; /**< Host context for on_stop callback. */
|
||||
rk65c02_tick_cb_t tick; /**< Interpreter tick callback. */
|
||||
void *tick_ctx; /**< Host context for tick callback. */
|
||||
uint32_t tick_interval; /**< Tick period in instructions (0 = every insn). */
|
||||
uint32_t tick_countdown; /**< Internal countdown used by tick callback. */
|
||||
};
|
||||
|
||||
typedef struct rk65c02emu rk65c02emu_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize the new emulator instance. Set initial CPU state.
|
||||
* @param b Bus description.
|
||||
@@ -115,6 +133,49 @@ void rk65c02_start(rk65c02emu_t *e);
|
||||
*/
|
||||
void rk65c02_step(rk65c02emu_t *e, uint16_t steps);
|
||||
|
||||
/**
|
||||
* @brief Convert stop reason enum value to a static string.
|
||||
* @param reason Stop reason value.
|
||||
* @return Human-readable reason name.
|
||||
*/
|
||||
const char *rk65c02_stop_reason_string(emu_stop_reason_t reason);
|
||||
|
||||
/**
|
||||
* @brief Register callback executed whenever emulation stops.
|
||||
* @param e Emulator instance.
|
||||
* @param cb Callback function.
|
||||
* @param ctx Opaque host context passed back to callback.
|
||||
*/
|
||||
void rk65c02_on_stop_set(rk65c02emu_t *e, rk65c02_on_stop_cb_t cb, void *ctx);
|
||||
|
||||
/**
|
||||
* @brief Unregister on-stop callback.
|
||||
* @param e Emulator instance.
|
||||
*/
|
||||
void rk65c02_on_stop_clear(rk65c02emu_t *e);
|
||||
|
||||
/**
|
||||
* @brief Register periodic interpreter tick callback.
|
||||
* @param e Emulator instance.
|
||||
* @param cb Callback function.
|
||||
* @param interval Number of instructions between callbacks (0 = every insn).
|
||||
* @param ctx Opaque host context passed back to callback.
|
||||
*/
|
||||
void rk65c02_tick_set(rk65c02emu_t *e, rk65c02_tick_cb_t cb,
|
||||
uint32_t interval, void *ctx);
|
||||
|
||||
/**
|
||||
* @brief Unregister tick callback.
|
||||
* @param e Emulator instance.
|
||||
*/
|
||||
void rk65c02_tick_clear(rk65c02emu_t *e);
|
||||
|
||||
/**
|
||||
* @brief Request stop at the next safe execution boundary.
|
||||
* @param e Emulator instance.
|
||||
*/
|
||||
void rk65c02_request_stop(rk65c02emu_t *e);
|
||||
|
||||
char *rk65c02_regs_string_get(reg_state_t);
|
||||
void rk65c02_dump_regs(reg_state_t);
|
||||
void rk65c02_dump_stack(rk65c02emu_t *, uint8_t);
|
||||
|
||||
+5
-1
@@ -1,6 +1,7 @@
|
||||
UNAME_S := $(shell uname -s)
|
||||
|
||||
CFLAGS=-Wall -I../src -ggdb -Og
|
||||
CFLAGS=-Wall -I../src -O3 -MMD -MP
|
||||
#CFLAGS=-Wall -I../src -ggdb -Og -MMD -MP
|
||||
LDFLAGS=-latf-c -lgc -llightning
|
||||
|
||||
LDFLAGS_MACOSX=-L/opt/local/lib
|
||||
@@ -54,6 +55,9 @@ test_device_serial: test_device_serial.o $(UTILS) $(RK6502LIB)
|
||||
|
||||
clean :
|
||||
rm -f *.o
|
||||
rm -f *.d
|
||||
rm -f $(TESTS) $(BENCH)
|
||||
rm -f $(TESTROMS)
|
||||
|
||||
-include $(wildcard *.d)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user