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