Fixed audio playing
[kvidha.git] / sb.c
1 #include <SDL/SDL.h>\r
2 \r
3 #include "dblbuf.h"\r
4 #include "executor.h"\r
5 #include "kvidha.h"\r
6 \r
7 static unsigned short SoundBufferPos;\r
8 \r
9 void StartPlayBack(void)\r
10 {\r
11     SDL_PauseAudio(0);\r
12     return;\r
13 }\r
14 \r
15 static void SBCallback(void *uudata, signed short *Buffer, int Length)\r
16 {\r
17     int i;\r
18     unsigned short Pos, Cur, Left;\r
19     \r
20     Pos = 0;\r
21     Length /= 2;\r
22     while(Length > 0)\r
23     {\r
24         if(SoundBufferPos >= (SB_SIZE >> 1))\r
25         {\r
26             FillBuffer();\r
27             SoundBufferPos = 0;\r
28         }\r
29         Left = (SB_SIZE >> 1) - SoundBufferPos;\r
30         Cur = (Length > Left)?Left:Length;\r
31         for(i = 0; i < Cur; i++)\r
32             Buffer[Pos + i] = (((signed char)SoundBuffer[SoundBufferPos + i]) - 128) * 255;\r
33         Pos += Cur;\r
34         SoundBufferPos += Cur;\r
35         Length -= Cur;\r
36     }\r
37 }\r
38 \r
39 unsigned char SBReset(void)\r
40 {\r
41     SDL_AudioSpec my, got;\r
42     \r
43     SoundBufferPos = SB_SIZE;\r
44     my.freq = 44100;\r
45     my.format = AUDIO_S16;\r
46     my.channels = 1;\r
47     my.samples = SB_SIZE >> 1;\r
48     my.callback = (void (*)(void *, unsigned char *, int))SBCallback;\r
49     if(SDL_OpenAudio(&my, &got) < 0)\r
50     {\r
51         printf("Could not open SDL audio: %s\n", SDL_GetError());\r
52         return(1);\r
53     }\r
54     if((got.freq != 44100) ||\r
55        (got.format != AUDIO_S16) ||\r
56        (got.channels != 1))\r
57     {\r
58         printf("Audio format mismatch(%i %i %i)!\n", got.freq, got.format, got.channels);\r
59         return(1);\r
60     }\r
61     return(0);\r
62 }\r
63 \r
64 void TerminatePlayBack(void)\r
65 {\r
66     SDL_PauseAudio(1);\r
67     return;\r
68 }\r
69 \r
70 /*void DSPOutput(unsigned char Value)\r
71 {\r
72     while((inp(DSPAddress + 12) & 0x80) == 0x80);\r
73     outp(DSPAddress + 12, Value);\r
74 }\r
75 \r
76 unsigned char DSPInput(void)\r
77 {\r
78     while((inp(DSPAddress + 14) & 0x80) == 0);\r
79     return(inp(DSPAddress + 10));\r
80 }\r
81 \r
82 void StartPlayBack(void)\r
83 {\r
84     unsigned long PhysAddress;\r
85 \r
86     PhysAddress = ((unsigned long)DOSSoundBuffer.rm_segment << 4);\r
87     outp((DMAChannel < 4)?10:0xD4, 4 | (DMAChannel & 3));\r
88     outp((DMAChannel < 4)?12:0xD8, 0);\r
89     outp((DMAChannel < 4)?11:0xD6, 0x58 | (DMAChannel & 3));\r
90     outp(DMAAddress, (unsigned char)(PhysAddress & 0xFF));\r
91     outp(DMAAddress, (unsigned char)((PhysAddress & 0xFF00) >> 8));\r
92     outp(DMAPage, (unsigned char)((PhysAddress & 0x0F0000) >> 16));\r
93     outp(DMACount, (unsigned char)((SB_SIZE - 1) & 0xFF));\r
94     outp(DMACount, (unsigned char)(((SB_SIZE - 1) & 0xFF00) >> 8));\r
95     outp((DMAChannel < 4)?10:0xD4, (DMAChannel & 3));\r
96     DSPOutput(0x40);\r
97     DSPOutput((unsigned char)(((65536 - (256000000 / ((unsigned long)SBSampleRate))) & 0xFF00) / 0x100));\r
98     DSPOutput(0x48);\r
99     DSPOutput((unsigned char)((SB_SIZE - 2) >> 1));\r
100     DSPOutput((unsigned char)((SB_SIZE - 2) >> 9));\r
101     DSPOutput(0x1C);\r
102 }\r
103 \r
104 void SBInt(void)\r
105 {\r
106     if(DMAChannel < 4)\r
107     {\r
108         inp(DSPAddress + 14);\r
109     } else {\r
110         outp(DSPAddress + 4, 0x82);\r
111         if((inp(DSPAddress + 5) & 2) == 2)\r
112             inp(DSPAddress + 15);\r
113     }\r
114     if(ReadyBuffer == 0)\r
115         ReadyBuffer = 1;\r
116     else\r
117         ReadyBuffer = 0;\r
118     BufferReady = 1;\r
119     FillBuffer();\r
120     outp(PICAddress, 0x20);\r
121 }\r
122 \r
123 unsigned char SBReset(void)\r
124 {\r
125     unsigned short i, Success;\r
126     unsigned long o;\r
127 \r
128     Success = 0;\r
129     for(i = 0; (i < 5) && (Success == 0); i++)\r
130     {\r
131         outp(DSPAddress + 6, 1);\r
132         for(o = 0; o < 100000; o++);\r
133         outp(DSPAddress + 6, 0);\r
134         if(DSPInput() == 0xAA)\r
135             Success = 1;\r
136     }\r
137     if(Success == 0)\r
138         return(1);\r
139     switch(DMAChannel)\r
140     {\r
141         case 0:\r
142             DMAPage = 0x87;\r
143             break;\r
144         case 1:\r
145             DMAPage = 0x83;\r
146             break;\r
147         case 2:\r
148             DMAPage = 0x81;\r
149             break;\r
150         case 3:\r
151             DMAPage = 0x82;\r
152             break;\r
153         case 4:\r
154             DMAPage = 0x8F;\r
155             break;\r
156         case 5:\r
157             DMAPage = 0x8B;\r
158             break;\r
159         case 6:\r
160             DMAPage = 0x89;\r
161             break;\r
162         case 7:\r
163             DMAPage = 0x8A;\r
164             break;\r
165         default:\r
166             return(2);\r
167     }\r
168     if(DMAChannel < 4)\r
169     {\r
170         DMAAddress = DMAChannel << 1;\r
171         DMACount = (DMAChannel << 1) + 1;\r
172     } else {\r
173         DMAAddress = 0xC0 + ((DMAChannel - 4) << 2);\r
174         DMACount = 0xC2 + ((DMAChannel - 4) << 2);\r
175     }\r
176     PICAddress = (IRQLine >= 8)?0xA0:0x20;\r
177     outp(DSPAddress + 4, 10);\r
178     outp(DSPAddress + 5, 0);\r
179     outp(DSPAddress + 4, 4);\r
180     outp(DSPAddress + 5, 255);\r
181     outp(DSPAddress + 4, 34);\r
182     outp(DSPAddress + 5, 255);\r
183     DSPOutput(0xD1);\r
184     SetISR(IRQLine + ((IRQLine >= 8)?0x68:8), (unsigned long)SBInt, &NewSBInt, &OldSBInt);\r
185     OldMask = inp(PICAddress + 1);\r
186     outp(PICAddress + 1, OldMask & ~(1 << ((IRQLine >= 8)?(IRQLine - 8):IRQLine)));\r
187     return(0);\r
188 }\r
189 \r
190 void TerminatePlayBack(void)\r
191 {\r
192     DSPOutput((unsigned char)((DMAChannel < 4)?0xDA:0xD9));\r
193     outp(PICAddress + 1, OldMask);\r
194     ReturnISR(IRQLine + ((IRQLine >= 8)?0x68:8), &NewSBInt, &OldSBInt);\r
195 }\r
196 */\r