1
0
mirror of https://github.com/rkujawa/rk65c02.git synced 2026-03-11 18:42:35 +00:00
Files
rk65c02/examples/host_control.c
Radosław Kujawa 2cd7094f10 examples: fix comments, add PASS/Expected, improve docs
- min3.s: fix BPL comment (branch if B >= C)
- min3.c: document stack ABI in header
- host_control.c: add Expected in header, explicit PASS at exit
- mmu_cart.c: comment tick interval 0 (poll every opportunity)
- mul_8bit_to_8bits.c: note interpreter-only and stack ABI
- README: run mmu_mpu with timeout when testing
- doc/MMU.md: add build/run note, mmu_pae no .rom, mmu_mpu timeout

Made-with: Cursor
2026-03-07 13:48:53 +01:00

94 lines
2.3 KiB
C

/*
* Host control example — on_stop, tick, request_stop, step.
*
* Build: make host_control host_control.rom
* Run: ./host_control
*
* Demonstrates: on_stop callback, tick callback, host-driven stop, step() after stop.
* Expected: emulation stops with HOST (after tick_budget callbacks), on_stop and
* tick run; then a 5-step run completes. Exit 0.
*/
#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));
printf("PASS: host control (on_stop, tick, request_stop, step) demonstrated.\n");
return 0;
}