OXYGENHUB
◆ rrdc-perf enhanced-x16-emulator / src / dbg_load.h
4.7 KiB · Objective-C · last changed chore(): initial commit 25 days ago source blame history raw
1
// Commander X16 Emulator — debug info for programs the guest loads at runtime.
2
//
3
// Debug info given on the command line only ever describes the program that was
4
// named there. The moment the program under test loads something of its own --
5
// an overlay, a second stage, a level -- source lookups stop describing what is
6
// actually executing. This watches host-filesystem loads and merges the debug
7
// info that sits beside each loaded file.
8
//
9
// The facts about a load are collected per channel, as the transfer happens,
10
// rather than read out of globals when it finishes. Two channels can be open at
11
// once, and a load that crosses $C000 moves the RAM bank mid-transfer, so
12
// anything sampled at the end describes the wrong thing.
13
14
#ifndef _DBG_LOAD_H_
15
#define _DBG_LOAD_H_
16
17
#include <stdbool.h>
18
#include <stdint.h>
19
20
#ifdef __cplusplus
21
extern "C" {
22
#endif
23
24
#define DBG_LOAD_PATH_MAX 1024
25
#define DBG_LOAD_CHANNELS 16
26
27
// Everything known about one completed load, copied out of the channel so it
28
// cannot be disturbed by whatever the guest does next.
29
typedef struct {
30
	char     path[DBG_LOAD_PATH_MAX]; // host path the data came from
31
	uint16_t addr;                    // where the first byte landed
32
	uint8_t  bank;                    // RAM bank mapped at that moment
33
	uint32_t size;                    // bytes transferred into memory
34
	bool     valid;
35
} dbg_load_event_t;
36
37
// Whether to act on loads at all.
38
//
39
// The policy is a tri-state because "on" normally means "whenever the debugger
40
// is on", and the debugger can be switched on by the running machine itself
41
// (emu_write register 0) long after the command line was parsed. A snapshot
42
// taken at startup would then be wrong for the rest of the session.
43
//
44
//   policy < 0  follow the debugger
45
//   policy == 0 off, whatever the debugger is doing
46
//   policy > 0  on, whatever the debugger is doing
47
void dbg_load_set_policy(int policy);
48
49
// The debugger was switched on or off. Ignored unless the policy is to follow.
50
void dbg_load_note_debugger(bool on);
51
52
// Force it on or off, equivalent to setting the policy to 1 or 0.
53
void dbg_load_set_enabled(bool on);
54
bool dbg_load_is_enabled(void);
55
56
// ---- Reported by the file layer --------------------------------------------
57
// The host path behind -prg. That load bypasses filename resolution entirely:
58
// the KERNAL asks for ":*" and the file layer hands back an already-open
59
// handle, so nothing ever resolves a name for it. Without recording the path up
60
// front, the most common debugging workflow there is would be the one case that
61
// silently got no symbols.
62
void dbg_load_set_prg_path(const char *path);
63
64
// A channel was opened onto that -prg file.
65
void dbg_load_begin_prg(int channel);
66
67
// A channel was opened to read `host_path`. Forgets anything the channel was
68
// previously doing.
69
void dbg_load_begin(int channel, const char *host_path);
70
71
// One byte of a block transfer is going to `addr` with `bank` mapped, `last`
72
// marking the final byte of the file. Reported just before the write rather
73
// than just after, because the transfer loop closes its channel the moment it
74
// sees the end of the file.
75
//
76
// Counting the byte and finishing the load are one call on purpose. They were
77
// three, and that close landed between them -- so the completion ran a few
78
// lines before the last byte was counted, and every load came out one byte
79
// short. Doing both here means the call site cannot order them wrongly.
80
//
81
// Only the first call for a channel records the destination: that is the one
82
// that says where the program starts, and which bank it started in. A load
83
// crossing $C000 moves the RAM bank on as it goes, so a later byte would name a
84
// different segment.
85
void dbg_load_note_byte(int channel, uint16_t addr, uint8_t bank, bool last);
86
87
// The channel was closed without finishing; drop what was collected.
88
void dbg_load_abandon(int channel);
89
90
// ---- Consumed by the debugger ----------------------------------------------
91
// Take the completed load, if there is one. Clears it, so it is reported once.
92
bool dbg_load_take(dbg_load_event_t *out);
93
94
// Take any completed load and merge the debug info beside it: load the .dbg
95
// first, then tell it which bank the program went into, because loading
96
// replaces the mappings in that address range and would discard an annotation
97
// made beforehand. Returns true if debug info was loaded.
98
bool dbg_load_poll(void);
99
100
// Whether a host path names a .dbg file. A wildcard LOAD can match the debug
101
// info sitting beside a program, and reading that as debug info for itself
102
// would attribute its segments to wherever its text happened to land.
103
bool dbg_load_path_is_dbg(const char *path);
104
105
// Forget everything. For machine reset and tests.
106
void dbg_load_reset(void);
107
108
#ifdef __cplusplus
109
}
110
#endif
111
112
#endif // _DBG_LOAD_H_