OXYGENHUB
◆ main enhanced-x16-emulator / src / debug_server.h
4.0 KiB · Objective-C · last changed chore(): initial commit 25 days ago source blame history raw
1
// Commander X16 Emulator — Debug Adapter Protocol (DAP) Server
2
// Speaks DAP over TCP for direct IDE integration (VS, VS Code, etc.)
3
// Transport: Content-Length framed JSON over TCP, default port 9009
4
5
#ifndef _DEBUG_SERVER_H_
6
#define _DEBUG_SERVER_H_
7
8
#include <stdbool.h>
9
#include <stdint.h>
10
11
#define DEBUG_SERVER_DEFAULT_PORT 9009
12
13
// The server needs cJSON, which is optional at configure time. When it is not
14
// available the emulator is built without it and every entry point below
15
// becomes a no-op, so callers -- the CPU loop, the debugger, the store path --
16
// do not have to be littered with #ifdefs for a feature they only notify.
17
#ifndef HAS_DAP
18
19
static inline int  debug_server_init(int port) { (void)port; return -1; }
20
static inline int  debug_server_poll(void) { return 0; }
21
static inline void debug_server_notify_stopped(const char *reason) { (void)reason; }
22
static inline bool debug_server_has_client(void) { return false; }
23
static inline bool debug_server_is_enabled(void) { return false; }
24
static inline void debug_server_output(const char *category, const char *text) { (void)category; (void)text; }
25
static inline void debug_server_invalidate_breakpoints_in_range(uint32_t start, uint32_t end) { (void)start; (void)end; }
26
static inline void debug_server_retry_unverified_breakpoints(void) { }
27
static inline void debug_server_note_resumed(void) { }
28
static inline void debug_server_shutdown(void) { }
29
30
#else
31
32
// Start listening on the given port. Returns 0 on success, -1 on error.
33
int  debug_server_init(int port);
34
35
// Poll for client commands. Non-blocking.
36
// Returns: 0 = no action, 1 = mode was changed by a remote command
37
int  debug_server_poll(void);
38
39
// Send DAP "stopped" event to the connected client.
40
// reason: "breakpoint", "step", "user", etc.
41
void debug_server_notify_stopped(const char *reason);
42
43
// Returns true if a debug client is currently connected.
44
bool debug_server_has_client(void);
45
46
// Returns true if the DAP server is enabled (--debugport was used).
47
bool debug_server_is_enabled(void);
48
49
// Forward text to a connected DAP client's debug console (OutputEvent). No-op
50
// if no client is connected. category is "console"/"stdout"/"stderr"/etc.
51
void debug_server_output(const char *category, const char *text);
52
53
// Breakpoint bookkeeping hooks driven by the shared runtime-load handler when a
54
// module is (re)loaded. No-ops when no DAP client is connected.
55
void debug_server_invalidate_breakpoints_in_range(uint32_t start, uint32_t end);
56
void debug_server_retry_unverified_breakpoints(void);
57
58
// Breakpoints are owned, not reconstructed. debug_core records which of -bp,
59
// the SDL debugger's F9, and the four kinds this file can ask for wants each
60
// entry, so a client session can clear everything it asked for with
61
// debug_bp_clear_owner() and nothing else is disturbed. Ask the core; do not
62
// rebuild that ownership out here from per-table flags or address refcounts.
63
//
64
// KNOWN LIMITATION, and a deliberate one: the core is the single source of
65
// truth for what is ARMED, but each front end owns its own VIEW. A breakpoint
66
// the user sets with F9 does not appear in a connected client's UI, and one the
67
// user deletes with F9 may be sent again by the client -- DAP's setBreakpoints
68
// replaces a source's whole list from the client's own model, and the
69
// specification tells clients to keep using their own properties rather than
70
// the adapter's. Emitting `breakpoint` events with reason `new`/`removed` would
71
// paper over this in VS Code specifically, but nothing in the protocol requires
72
// a client to act on them, so the divergence is documented rather than faked.
73
74
// The machine has resumed. Called from the debugger's own execution control, so
75
// that a local F5/F10/F11 is accounted for the same way a DAP continue is: the
76
// next stop is then reported once, rather than suppressed as a duplicate of a
77
// halt that is already over.
78
void debug_server_note_resumed(void);
79
80
// Clean shutdown — close sockets, free resources.
81
void debug_server_shutdown(void);
82
83
#endif // HAS_DAP
84
85
#endif