-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathm_snd_dos32.c
106 lines (91 loc) · 1.75 KB
/
m_snd_dos32.c
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
/*
WATCOM PMODEW DOS32 audio backend, uses real adlib/opl2/opl3
*/
#include <dos.h>
#include "m_snd.h"
int clock_value = 0x1234BE / 0x12;
int clock_ticks = 0;
void (__interrupt __far *prev_int_08)();
void __interrupt __far _int08_handler();
void rad_update_frame();
void rad_adlib_reset();
void rad_adlib_write(unsigned char adl_reg,unsigned char adl_data);
int LM_SND_Init()
{
rad_adlib_reset();
rad_adlib_write(0x01, 0x20);
rad_adlib_write(0x08, 0x00);
rad_adlib_write(0xBD, 0x00);
prev_int_08 = _dos_getvect(8);
_dos_setvect(8, _int08_handler);
return 1;
}
int LM_SND_Deinit()
{
_dos_setvect(8, prev_int_08);
rad_adlib_reset();
return 1;
}
void rad_set_timer(int value)
{
if(value < 18) value = 18;
_asm {
mov eax, 0x1234BE
xor edx, edx
mov ecx, value
div ecx
mov clock_value, eax
mov ecx, eax
mov al,0B6h
out 43h,al
mov al,cl
out 40h,al
mov al,ch
out 40h,al
}
}
void rad_adlib_write(unsigned char adl_reg,unsigned char adl_data)
{
_asm {
mov dx, 0x388
mov al, [adl_reg]
out dx, al
in al, dx
in al, dx
in al, dx
in al, dx
in al, dx
in al, dx
inc dx
mov al, [adl_data]
out dx, al
dec edx
mov ah, 16h
loc_0_2353:
in al, dx
dec ah
jnz loc_0_2353
}
}
void rad_adlib_reset()
{
for(int r = 0x40; r < 0x56; r++) rad_adlib_write(r, 0x7f);
for(int r = 0xB0; r < 0xB9; r++) rad_adlib_write(r, 0);
}
void __interrupt __far _int08_handler()
{
rad_update_frame();
if(clock_value == (0x1234BE / 0x12)) goto _call_old; // if normal timer
clock_ticks += clock_value;
if(clock_ticks < 0x10000)
{
_asm {
mov al,20h
out 20h,al
}
return;
}
_call_old:
clock_ticks -= 0x10000;
(*prev_int_08)();
}