OXYGENHUB
◆ main enhanced-x16-emulator / src / ymglue.h
4.0 KiB · Objective-C · last changed chore(): initial commit 25 days ago source blame history raw
9120e874 Andy McCall 1
#ifndef YMGLUE_H
2
#define YMGLUE_H
3
4
#ifdef __cplusplus
5
extern "C" {
6
#endif
7
	#include <stdint.h>
8
	#include <stdbool.h>
9
10
	uint8_t YM_read_status(void);
11
	void YM_Create(int clock);
12
	void YM_init(int sample_rate, int frame_rate);
13
	void YM_stream_update(uint16_t* output, uint32_t numsamples);
14
	void YM_write_reg(uint8_t reg, uint8_t val);
15
	bool YM_irq(void);
16
17
	// ─── Debugger accessors ─────────────────────────────────────────────────
18
	// Read-only views of the YM2151 for the ImGui debugger's FM panel. Called
19
	// from the emulator main thread — the same thread that runs
20
	// YM_stream_update() via audio_render() — so no locking is needed.
21
22
	#define YM_NUM_CHANNELS  8
23
	#define YM_NUM_OPERATORS (YM_NUM_CHANNELS * 4)
24
	#define YM_NUM_REGS      0x100
25
26
	// ymfm envelope_state values (ymfm.h). Only these four occur on the OPM.
27
	enum ym_eg_state {
28
		YM_EG_ATTACK  = 1,
29
		YM_EG_DECAY   = 2,
30
		YM_EG_SUSTAIN = 3,
31
		YM_EG_RELEASE = 4,
32
	};
33
34
	struct ym_debug_operator {
35
		uint8_t  eg_state;       // enum ym_eg_state
36
		uint16_t eg_attenuation; // 0 (loudest) .. 0x3FF (silent)
37
	};
38
39
	// Register byte as last *accepted* by the chip. YM_write_reg drops writes
40
	// that arrive while the chip is busy, and those are not shadowed either, so
41
	// this reflects what the chip actually holds.
42
	uint8_t YM_debug_get_reg(uint8_t reg);
43
44
	// Live key-on state for a channel, as a mask of operator SLOTS:
45
	// bit 0 = M1, 1 = M2, 2 = C1, 3 = C2 — the same order used to address the
46
	// $40-$FF per-operator registers (base + slot*8 + channel).
47
	// NOTE: this is deliberately NOT the bit order of the $08 key-on register,
48
	// whose bits 3-6 select operators as M1, C1, M2, C2. The glue normalizes
49
	// that quirk so callers can index key-on the same way they index registers.
50
	uint8_t YM_debug_get_keyon(int ch);
51
52
	// Live envelope state of one of the 32 operators. `op` is the ymfm operator
53
	// index: channel + 8 * slot, matching the $40-$FF register offsets. Returns
54
	// false (leaving *out untouched) for an out-of-range index.
55
	bool YM_debug_get_operator(int op, struct ym_debug_operator *out);
56
57
	// Status byte without the read side effects of the CPU-visible port, and
58
	// the busy state tracked by the glue's busy timer.
59
	uint8_t YM_debug_get_status(void);
60
	bool    YM_debug_is_busy(void);
61
62
	// ─── Scope capture ──────────────────────────────────────────────────────
63
	// Self-arming per-channel capture, same contract as the PSG's (see
64
	// vera_psg.h): reading (re)arms it for roughly half a second. This one
65
	// matters most — while armed, each sample costs one extra ymfm output()
66
	// call per channel — so it really does need to switch itself off.
67
68
	#define YM_SCOPE_SAMPLES 2048
69
	#define YM_SCOPE_MIX_L   YM_NUM_CHANNELS // summed YM output, left
70
	#define YM_SCOPE_MIX_R   (YM_NUM_CHANNELS + 1)
71
	#define YM_SCOPE_STREAMS (YM_NUM_CHANNELS + 2)
72
73
	// Copy the most recent `max_samples` samples of stream `ch` (a channel
74
	// index, or YM_SCOPE_MIX_L/R) into `dest`, oldest first. All streams share
75
	// one write index, so reads are time-aligned. Returns the sample count
76
	// written; always (re)arms capture, even for an invalid stream.
77
	unsigned YM_debug_scope_read(int ch, int16_t* dest, unsigned max_samples);
78
79
	// Predict the next `num_samples` from the current chip state WITHOUT
80
	// advancing it. Fills every stream of `dest`; returns the count written.
81
	//
82
	// For the debugger: capture is self-arming and nothing renders audio while
83
	// paused, so a scope opened at a breakpoint has an empty ring. Envelopes,
84
	// LFO and operator phase are all live chip state, so we can run the chip
85
	// forward over a ymfm save-state round-trip and show what it is about to
86
	// emit, then put it back exactly as it was.
87
	//
88
	// This is a projection, not captured output; label it as such.
89
	unsigned YM_debug_scope_predict(int16_t (*dest)[YM_SCOPE_SAMPLES], unsigned num_samples);
90
91
#ifdef __cplusplus
92
}
93
#endif
94
95
#endif