-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdevhonk.h
450 lines (324 loc) · 13.7 KB
/
devhonk.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
#pragma once
// non-DMA (PC Speaker and Covox drivers)
// --wbcbz7 22o52o22
#include "snddefs.h"
#ifdef SNDLIB_DEVICE_ENABLE_NONDMA
#include <stdint.h>
#include "snddev.h"
#include "convert.h"
#include "sndmisc.h"
#include "cli.h"
#include "irq.h"
#include "dma.h"
#include "dpmi.h"
#include "sndioctl.h"
#pragma pack(push, 1)
// non-DMA sound device IRQ0 structure
struct snddev_irq0_struct {
_dpmi_rmpointer chain_rm; // real mode IRQ0 old routine
void __interrupt __far (*chain_pm)(); // protected mode ----//---
uint16_t data_port; // data port
_dpmi_rmpointer rm_callback; // rm->pm callback routine
void __near (*pm_callback)(); // pm callback routine (NEAR pointer -> same code segment!)
uint32_t rmcount; // rm handler invocations
uint32_t pmcount; // pm handler invocations
uint16_t data_port2; // data port #2 (for dual covox)
uint16_t bufferseg; // sound buffer segment (for rm hander) - rounded down to 4k paras (0x0000, 0x1000 up to 0xF000) ]
uint8_t* bufferofs; // sound buffer linear start (pm handler uses it as-is, rm handler uses only least 16bits + .bufferseg) ] seg:ofs pair for rm handler
uint32_t bufferpos; // current buffer position, relative to buffer start
uint32_t bufferlencur; // current buffer length
uint32_t bufferlen; // buffer length
uint32_t bufferlentotal; // total buffer length
uint32_t chain_acc; // IRQ0 old routine invocation accumulator
};
// driver patch table
struct snddev_patch_table {
// real-mode section
uint8_t *rm_start; // code/data start ] copy and lock range
uint8_t *rm_end; // code/data end ]
void (*rm_entry)(); // ISR entrypoint
// protected-mode section
uint8_t *pm_start; // code/data start ] copy and lock range
uint8_t *pm_end; // code/data end ]
void (*pm_entry)(); // ISR entrypoint
// patch table
uint16_t *rm_patch_dataseg; // pointer to WORD snddev_irq0_struct segment
uint32_t *rm_patch_dt; // pointer to DWORD chain_acc increment
uint32_t *pm_patch_dataseg; // pointer to DWORD flat 4G data selector
snddev_irq0_struct **pm_patch_dataofs; // pointer to DWORD snddev_irq0_struct linear offset
uint32_t *pm_patch_dt; // pointer to DWORD chain_acc increment
};
#pragma pack(pop)
extern "C" {
// driver patch table
extern snddev_patch_table snddev_irq0_patch_pcspeaker; // PC Speaker/Covox mono
extern snddev_patch_table snddev_irq0_patch_stereo1; // Stereo-On-1
extern snddev_patch_table snddev_irq0_patch_stereo1_fast; // Stereo-On-1, fast protocol (from FT2)
extern snddev_patch_table snddev_irq0_patch_dualcovox; // Dual Covox
};
// base non-DMA device driver
class sndNonDmaBase : public DmaBufferDevice {
public:
// constructor (nothing fancy here)
sndNonDmaBase(const char *name);
/*
// get device name
virtual char *getName();
// detect (0 if found + if (res != NULL) *res filled with current config)
virtual uint32_t detect(SoundDevice::deviceInfo *info = NULL);
*/
// select and init (use supplied *res info if (res != NULL))
virtual uint32_t init(SoundDevice::deviceInfo *info = NULL);
/*
// check if format is supported (0 if supported + passes pointer to converter procedure)
virtual uint32_t isFormatSupported(uint32_t sampleRate, soundFormat *fmt, soundFormatConverterInfo **conv);
// return converter for current format
soundFormatConverterInfo getFormatConverter(soundFormat *fmt);
*/
// init for playback
virtual uint32_t open(uint32_t sampleRate, soundFormat fmt, uint32_t bufferSize, uint32_t flags, soundDeviceCallback callback, void *userdata, soundFormatConverterInfo *conv);
// start playback (won't return immediately, calls callback to fill DMA buffer)
virtual uint32_t start();
// pause playback (start() or resume() for resume)
virtual uint32_t pause();
// resume playback
virtual uint32_t resume();
// get playback position in samples
virtual int64_t getPos();
// ioctl
virtual uint32_t ioctl(uint32_t function, void *data, uint32_t len);
// stop playback
virtual uint32_t stop();
// close playback
virtual uint32_t close();
// deinit device
virtual uint32_t done();
protected:
// init IRQ0 stuff
bool initIrq0();
// install IRQ0 handler
bool setupIrq0();
// uninstall IRQ0
bool removeIrq0();
// done IRQ0 stuff
bool doneIrq0();
// get play position in DMA buffer in bytes
virtual int32_t getPlayPos();
// advance play/render pointers
virtual void irqAdvancePos();
// get patch table
virtual snddev_patch_table* getPatchTable(soundFormat fmt);
// init port for playback
virtual bool initPort() { return true; }
// deinit port
virtual bool donePort() { return true; }
// init conversion table
virtual bool initConversionTab() { return true; }
// done conversion table
virtual bool doneConversionTab() { return true; }
// flags
bool isIrq0Initialised;
// --------------------- IRQ0 handler stuff -----------------------
// patch table pointer
snddev_patch_table *patchTable;
// instead of irqEntry i'll use separate structures
snddev_irq0_struct *irq0struct;
_dpmi_rmpointer rmCallback; // RM->PM callback
_dpmi_ptr irq0structBlock;
_dpmi_ptr realModeISRBlock;
void* realModeISREntry;
_dpmi_rmpointer oldIrq0RealMode;
void __interrupt __far (*oldIrq0ProtectedMode)();
uint32_t timerDivisor;
// --------------------------- IRQ stuff --------------------
static void callbackBouncer();
virtual bool irqProc();
// ---------------------- conversion table ------------------
uint8_t *convtab;
};
#ifdef SNDLIB_DEVICE_ENABLE_PC_SPEAKER
// PC speaker sound driver
class sndPcSpeaker : public sndNonDmaBase {
public:
// constructor (nothing fancy here)
sndPcSpeaker();
/*
// get device name
virtual char *getName();
*/
// detect (0 if found + if (res != NULL) *res filled with current config)
virtual uint32_t detect(SoundDevice::deviceInfo *info = NULL);
// select and init (use supplied *res info if (res != NULL))
//virtual uint32_t init(SoundDevice::deviceInfo *info = NULL);
/*
// check if format is supported (0 if supported + passes pointer to converter procedure)
virtual uint32_t isFormatSupported(uint32_t sampleRate, soundFormat *fmt, soundFormatConverterInfo **conv);
// return converter for current format
soundFormatConverterInfo getFormatConverter(soundFormat *fmt);
*/
// init for playback
//virtual uint32_t open(uint32_t sampleRate, soundFormat *fmt, uint32_t bufferSize, uint32_t flags, soundDeviceCallback callback, void *userdata, soundFormatConverterInfo *conv);
// start playback (won't return immediately, calls callback to fill DMA buffer)
//virtual uint32_t start();
// pause playback (start() for resume)
//virtual uint32_t pause();
// get playback position in samples
//virtual int64_t getPos();
// ioctl
//virtual uint32_t ioctl(uint32_t function, void *data, uint32_t len);
// stop playback
//virtual uint32_t stop();
// close playback
//virtual uint32_t close();
// deinit device
//virtual uint32_t done();
protected:
// init port for playback
virtual bool initPort();
// deinit port
virtual bool donePort();
// init conversion table
virtual bool initConversionTab();
// done conversion table
virtual bool doneConversionTab();
};
#endif
#ifdef SNDLIB_DEVICE_ENABLE_COVOX
// Covox driver
class sndCovox : public sndNonDmaBase {
public:
// constructor (nothing fancy here)
sndCovox(const char* name = "Covox LPT DAC");
/*
// get device name
virtual char *getName();
*/
// detect (0 if found + if (res != NULL) *res filled with current config)
virtual uint32_t detect(SoundDevice::deviceInfo *info = NULL);
// select and init (use supplied *res info if (res != NULL))
//virtual uint32_t init(SoundDevice::deviceInfo *info = NULL);
/*
// check if format is supported (0 if supported + passes pointer to converter procedure)
virtual uint32_t isFormatSupported(uint32_t sampleRate, soundFormat *fmt, soundFormatConverterInfo **conv);
// return converter for current format
soundFormatConverterInfo getFormatConverter(soundFormat *fmt);
*/
// init for playback
//virtual uint32_t open(uint32_t sampleRate, soundFormat *fmt, uint32_t bufferSize, uint32_t flags, soundDeviceCallback callback, void *userdata, soundFormatConverterInfo *conv);
// start playback (won't return immediately, calls callback to fill DMA buffer)
//virtual uint32_t start();
// pause playback (start() for resume)
//virtual uint32_t pause();
// get playback position in samples
//virtual int64_t getPos();
// ioctl
//virtual uint32_t ioctl(uint32_t function, void *data, uint32_t len);
// stop playback
//virtual uint32_t stop();
// close playback
//virtual uint32_t close();
// deinit device
//virtual uint32_t done();
protected:
// scan BIOS data area and fixup BIOS LPT resources
virtual void scanBDA();
// fill covox stuff
virtual uint32_t fillCodecInfo(SoundDevice::deviceInfo* info);
};
#endif
#ifdef SNDLIB_DEVICE_ENABLE_DUAL_COVOX
// Dual Covox driver
class sndDualCovox : public sndCovox {
public:
// constructor (nothing fancy here)
sndDualCovox();
/*
// get device name
virtual char *getName();
*/
// detect (0 if found + if (res != NULL) *res filled with current config)
virtual uint32_t detect(SoundDevice::deviceInfo *info = NULL);
// select and init (use supplied *res info if (res != NULL))
//virtual uint32_t init(SoundDevice::deviceInfo *info = NULL);
/*
// check if format is supported (0 if supported + passes pointer to converter procedure)
virtual uint32_t isFormatSupported(uint32_t sampleRate, soundFormat *fmt, soundFormatConverterInfo **conv);
// return converter for current format
soundFormatConverterInfo getFormatConverter(soundFormat *fmt);
*/
// init for playback
//virtual uint32_t open(uint32_t sampleRate, soundFormat *fmt, uint32_t bufferSize, uint32_t flags, soundDeviceCallback callback, void *userdata, soundFormatConverterInfo *conv);
// start playback (won't return immediately, calls callback to fill DMA buffer)
//virtual uint32_t start();
// pause playback (start() for resume)
//virtual uint32_t pause();
// get playback position in samples
//virtual int64_t getPos();
// ioctl
//virtual uint32_t ioctl(uint32_t function, void *data, uint32_t len);
// stop playback
//virtual uint32_t stop();
// close playback
//virtual uint32_t close();
// deinit device
//virtual uint32_t done();
protected:
// fill covox stuff
virtual uint32_t fillCodecInfo(SoundDevice::deviceInfo* info);
// get patch table
virtual snddev_patch_table* getPatchTable(soundFormat fmt);
};
#endif
#ifdef SNDLIB_DEVICE_ENABLE_STEREO_ON_1
// Stereo-on-1 ioctl definitions
enum {
SND_IOCTL_STEREO_ON_1_FAST_PROTOCOL_GET = SND_IOCTL_DEVICE_SPECIFIC,
SND_IOCTL_STEREO_ON_1_FAST_PROTOCOL_SET,
};
// Stereo-On-1 driver
class sndStereoOn1 : public sndCovox {
public:
// constructor (nothing fancy here)
sndStereoOn1();
/*
// get device name
virtual char *getName();
*/
// detect (0 if found + if (res != NULL) *res filled with current config)
virtual uint32_t detect(SoundDevice::deviceInfo *info = NULL);
// select and init (use supplied *res info if (res != NULL))
//virtual uint32_t init(SoundDevice::deviceInfo *info = NULL);
/*
// check if format is supported (0 if supported + passes pointer to converter procedure)
virtual uint32_t isFormatSupported(uint32_t sampleRate, soundFormat *fmt, soundFormatConverterInfo **conv);
// return converter for current format
soundFormatConverterInfo getFormatConverter(soundFormat *fmt);
*/
// init for playback
//virtual uint32_t open(uint32_t sampleRate, soundFormat *fmt, uint32_t bufferSize, uint32_t flags, soundDeviceCallback callback, void *userdata, soundFormatConverterInfo *conv);
// start playback (won't return immediately, calls callback to fill DMA buffer)
//virtual uint32_t start();
// pause playback (start() for resume)
//virtual uint32_t pause();
// get playback position in samples
//virtual int64_t getPos();
// ioctl
virtual uint32_t ioctl(uint32_t function, void *data, uint32_t len);
// stop playback
//virtual uint32_t stop();
// close playback
//virtual uint32_t close();
// deinit device
//virtual uint32_t done();
protected:
// init port for playback
virtual bool initPort();
// deinit port
virtual bool donePort();
// fill covox stuff
virtual uint32_t fillCodecInfo(SoundDevice::deviceInfo* info);
// get patch table
virtual snddev_patch_table* getPatchTable(soundFormat fmt);
};
#endif
#endif