Revision 5e2a6443
b/hw/sb16.c | ||
---|---|---|
33 | 33 |
|
34 | 34 |
#define DEREF(x) (void)x |
35 | 35 |
#define log(...) fprintf (stderr, "sb16: " __VA_ARGS__) |
36 |
#define Fail(...) do { \ |
|
37 |
fprintf (stderr, "sb16: " __VA_ARGS__); \ |
|
38 |
abort (); \ |
|
39 |
} while (0) |
|
40 | 36 |
|
41 | 37 |
/* #define DEBUG_SB16 */ |
42 | 38 |
#ifdef DEBUG_SB16 |
... | ... | |
66 | 62 |
|
67 | 63 |
static int mix_block, noirq; |
68 | 64 |
|
69 |
static struct mixer { |
|
70 |
int nreg; |
|
71 |
uint8_t regs[0x83]; |
|
72 |
} mixer; |
|
73 |
|
|
74 |
static struct dsp { |
|
65 |
typedef struct SB16State { |
|
75 | 66 |
int in_index; |
76 | 67 |
int out_data_len; |
77 | 68 |
int fmt_stereo; |
... | ... | |
94 | 85 |
uint8_t out_data[10]; |
95 | 86 |
|
96 | 87 |
int left_till_irq; |
97 |
} dsp; |
|
98 | 88 |
|
99 |
#define nocmd ~0 |
|
89 |
/* mixer state */ |
|
90 |
int mixer_nreg; |
|
91 |
uint8_t mixer_regs[0x83]; |
|
92 |
} SB16State; |
|
100 | 93 |
|
101 |
static void log_dsp (const char *cap) |
|
102 |
{ |
|
103 |
DEREF (cap); |
|
94 |
/* XXX: suppress that and use a context */ |
|
95 |
static struct SB16State dsp; |
|
104 | 96 |
|
97 |
static void log_dsp (SB16State *dsp) |
|
98 |
{ |
|
105 | 99 |
linfo ("%c:%c:%d:%c:dmabuf=%d:pos=%d:freq=%d:timeconst=%d:speaker=%d\n", |
106 |
dsp.fmt_stereo ? 'S' : 'M',
|
|
107 |
dsp.fmt_signed ? 'S' : 'U',
|
|
108 |
dsp.fmt_bits,
|
|
109 |
dsp.dma_auto ? 'a' : 's',
|
|
110 |
dsp.dma_buffer_size,
|
|
111 |
dsp.dma_pos,
|
|
112 |
dsp.freq,
|
|
113 |
dsp.time_const,
|
|
114 |
dsp.speaker);
|
|
100 |
dsp->fmt_stereo ? 'S' : 'M',
|
|
101 |
dsp->fmt_signed ? 'S' : 'U',
|
|
102 |
dsp->fmt_bits,
|
|
103 |
dsp->dma_auto ? 'a' : 's',
|
|
104 |
dsp->dma_buffer_size,
|
|
105 |
dsp->dma_pos,
|
|
106 |
dsp->freq,
|
|
107 |
dsp->time_const,
|
|
108 |
dsp->speaker);
|
|
115 | 109 |
} |
116 | 110 |
|
117 | 111 |
static void control (int hold) |
... | ... | |
203 | 197 |
dsp.speaker = 1; |
204 | 198 |
} |
205 | 199 |
|
206 |
static void command (uint8_t cmd) |
|
200 |
static void command (SB16State *dsp, uint8_t cmd)
|
|
207 | 201 |
{ |
208 |
char *msg; |
|
209 |
|
|
210 |
msg = (char *) -1; |
|
211 |
|
|
212 | 202 |
linfo ("%#x\n", cmd); |
213 | 203 |
|
214 | 204 |
if (cmd > 0xaf && cmd < 0xd0) { |
... | ... | |
220 | 210 |
case 12: |
221 | 211 |
break; |
222 | 212 |
default: |
223 |
msg = "wrong bits";
|
|
213 |
log("%#x wrong bits", cmd);
|
|
224 | 214 |
goto error; |
225 | 215 |
} |
226 |
dsp.needed_bytes = 3;
|
|
216 |
dsp->needed_bytes = 3;
|
|
227 | 217 |
} |
228 | 218 |
else { |
229 | 219 |
switch (cmd) { |
... | ... | |
234 | 224 |
return; |
235 | 225 |
|
236 | 226 |
case 0x10: |
237 |
dsp.needed_bytes = 1;
|
|
227 |
dsp->needed_bytes = 1;
|
|
238 | 228 |
break; |
239 | 229 |
|
240 | 230 |
case 0x14: |
241 |
dsp.needed_bytes = 2;
|
|
242 |
dsp.dma_buffer_size = 0;
|
|
231 |
dsp->needed_bytes = 2;
|
|
232 |
dsp->dma_buffer_size = 0;
|
|
243 | 233 |
break; |
244 | 234 |
|
245 | 235 |
case 0x20: |
246 |
dsp.out_data[dsp.out_data_len++] = 0xff;
|
|
236 |
dsp->out_data[dsp->out_data_len++] = 0xff;
|
|
247 | 237 |
break; |
248 | 238 |
|
249 | 239 |
case 0x35: |
... | ... | |
251 | 241 |
break; |
252 | 242 |
|
253 | 243 |
case 0x40: |
254 |
dsp.freq = -1;
|
|
255 |
dsp.time_const = -1;
|
|
256 |
dsp.needed_bytes = 1;
|
|
244 |
dsp->freq = -1;
|
|
245 |
dsp->time_const = -1;
|
|
246 |
dsp->needed_bytes = 1;
|
|
257 | 247 |
break; |
258 | 248 |
|
259 | 249 |
case 0x41: |
260 | 250 |
case 0x42: |
261 |
dsp.freq = -1;
|
|
262 |
dsp.time_const = -1;
|
|
263 |
dsp.needed_bytes = 2;
|
|
251 |
dsp->freq = -1;
|
|
252 |
dsp->time_const = -1;
|
|
253 |
dsp->needed_bytes = 2;
|
|
264 | 254 |
break; |
265 | 255 |
|
266 | 256 |
case 0x47: /* Continue Auto-Initialize DMA 16bit */ |
267 | 257 |
break; |
268 | 258 |
|
269 | 259 |
case 0x48: |
270 |
dsp.needed_bytes = 2;
|
|
260 |
dsp->needed_bytes = 2;
|
|
271 | 261 |
break; |
272 | 262 |
|
273 | 263 |
case 0x27: /* ????????? */ |
... | ... | |
275 | 265 |
return; |
276 | 266 |
|
277 | 267 |
case 0x80: |
278 |
cmd = nocmd;
|
|
268 |
cmd = -1;
|
|
279 | 269 |
break; |
280 | 270 |
|
281 | 271 |
case 0x90: |
... | ... | |
284 | 274 |
uint8_t d0; |
285 | 275 |
|
286 | 276 |
d0 = 4; |
287 |
if (dsp.fmt_signed) d0 |= 16;
|
|
288 |
if (dsp.fmt_stereo) d0 |= 32;
|
|
277 |
if (dsp->fmt_signed) d0 |= 16;
|
|
278 |
if (dsp->fmt_stereo) d0 |= 32;
|
|
289 | 279 |
dma_cmd (cmd == 0x90 ? 0xc4 : 0xc0, d0, -1); |
290 |
cmd = nocmd;
|
|
280 |
cmd = -1;
|
|
291 | 281 |
break; |
292 | 282 |
} |
293 | 283 |
|
... | ... | |
296 | 286 |
return; |
297 | 287 |
|
298 | 288 |
case 0xd1: |
299 |
dsp.speaker = 1;
|
|
289 |
dsp->speaker = 1;
|
|
300 | 290 |
break; |
301 | 291 |
|
302 | 292 |
case 0xd3: |
303 |
dsp.speaker = 0;
|
|
293 |
dsp->speaker = 0;
|
|
304 | 294 |
return; |
305 | 295 |
|
306 | 296 |
case 0xd4: |
... | ... | |
317 | 307 |
|
318 | 308 |
case 0xd9: |
319 | 309 |
control (0); |
320 |
dsp.dma_auto = 0;
|
|
310 |
dsp->dma_auto = 0;
|
|
321 | 311 |
return; |
322 | 312 |
|
323 | 313 |
case 0xda: |
324 | 314 |
control (0); |
325 |
dsp.dma_auto = 0;
|
|
315 |
dsp->dma_auto = 0;
|
|
326 | 316 |
break; |
327 | 317 |
|
328 | 318 |
case 0xe0: |
329 |
dsp.needed_bytes = 1;
|
|
319 |
dsp->needed_bytes = 1;
|
|
330 | 320 |
break; |
331 | 321 |
|
332 | 322 |
case 0xe1: |
333 |
dsp.out_data[dsp.out_data_len++] = sb.ver_lo;
|
|
334 |
dsp.out_data[dsp.out_data_len++] = sb.ver_hi;
|
|
323 |
dsp->out_data[dsp->out_data_len++] = sb.ver_lo;
|
|
324 |
dsp->out_data[dsp->out_data_len++] = sb.ver_hi;
|
|
335 | 325 |
return; |
336 | 326 |
|
337 | 327 |
case 0xf2: |
338 |
dsp.out_data[dsp.out_data_len++] = 0xaa;
|
|
339 |
mixer.regs[0x82] |= mixer.regs[0x80];
|
|
328 |
dsp->out_data[dsp->out_data_len++] = 0xaa;
|
|
329 |
dsp->mixer_regs[0x82] |= dsp->mixer_regs[0x80];
|
|
340 | 330 |
pic_set_irq (sb.irq, 1); |
341 | 331 |
return; |
342 | 332 |
|
343 | 333 |
default: |
344 |
msg = "is unknown";
|
|
334 |
log("%#x is unknown", cmd);
|
|
345 | 335 |
goto error; |
346 | 336 |
} |
347 | 337 |
} |
348 |
dsp.cmd = cmd;
|
|
338 |
dsp->cmd = cmd;
|
|
349 | 339 |
return; |
350 | 340 |
|
351 | 341 |
error: |
352 |
Fail ("%#x %s", cmd, msg); |
|
353 | 342 |
return; |
354 | 343 |
} |
355 | 344 |
|
356 |
static void complete (void)
|
|
345 |
static void complete (SB16State *dsp)
|
|
357 | 346 |
{ |
358 | 347 |
linfo ("complete command %#x, in_index %d, needed_bytes %d\n", |
359 |
dsp.cmd, dsp.in_index, dsp.needed_bytes);
|
|
348 |
dsp->cmd, dsp->in_index, dsp->needed_bytes);
|
|
360 | 349 |
|
361 |
if (dsp.cmd > 0xaf && dsp.cmd < 0xd0) {
|
|
350 |
if (dsp->cmd > 0xaf && dsp->cmd < 0xd0) {
|
|
362 | 351 |
int d0, d1, d2; |
363 | 352 |
|
364 |
d0 = dsp.in_data[0];
|
|
365 |
d1 = dsp.in_data[1];
|
|
366 |
d2 = dsp.in_data[2];
|
|
353 |
d0 = dsp->in_data[0];
|
|
354 |
d1 = dsp->in_data[1];
|
|
355 |
d2 = dsp->in_data[2];
|
|
367 | 356 |
|
368 | 357 |
ldebug ("d0 = %d, d1 = %d, d2 = %d\n", |
369 | 358 |
d0, d1, d2); |
370 |
dma_cmd (dsp.cmd, d0, d1 + (d2 << 8));
|
|
359 |
dma_cmd (dsp->cmd, d0, d1 + (d2 << 8));
|
|
371 | 360 |
} |
372 | 361 |
else { |
373 |
switch (dsp.cmd) {
|
|
362 |
switch (dsp->cmd) {
|
|
374 | 363 |
|
375 | 364 |
case 0x10: |
376 | 365 |
break; |
... | ... | |
381 | 370 |
int save_left; |
382 | 371 |
int save_pos; |
383 | 372 |
|
384 |
d0 = dsp.in_data[0];
|
|
385 |
d1 = dsp.in_data[1];
|
|
373 |
d0 = dsp->in_data[0];
|
|
374 |
d1 = dsp->in_data[1];
|
|
386 | 375 |
|
387 |
save_left = dsp.left_till_irq;
|
|
388 |
save_pos = dsp.dma_pos;
|
|
376 |
save_left = dsp->left_till_irq;
|
|
377 |
save_pos = dsp->dma_pos;
|
|
389 | 378 |
dma_cmd (0xc0, 0, d0 + (d1 << 8)); |
390 |
dsp.left_till_irq = save_left;
|
|
391 |
dsp.dma_pos = save_pos;
|
|
379 |
dsp->left_till_irq = save_left;
|
|
380 |
dsp->dma_pos = save_pos;
|
|
392 | 381 |
|
393 | 382 |
linfo ("set buffer size data[%d, %d] %d pos %d\n", |
394 |
d0, d1, dsp.dma_buffer_size, dsp.dma_pos);
|
|
383 |
d0, d1, dsp->dma_buffer_size, dsp->dma_pos);
|
|
395 | 384 |
break; |
396 | 385 |
} |
397 | 386 |
|
398 | 387 |
case 0x40: |
399 |
dsp.time_const = dsp.in_data[0];
|
|
400 |
linfo ("set time const %d\n", dsp.time_const);
|
|
388 |
dsp->time_const = dsp->in_data[0];
|
|
389 |
linfo ("set time const %d\n", dsp->time_const);
|
|
401 | 390 |
break; |
402 | 391 |
|
403 | 392 |
case 0x41: |
404 | 393 |
case 0x42: |
405 |
dsp.freq = dsp.in_data[1] + (dsp.in_data[0] << 8);
|
|
394 |
dsp->freq = dsp->in_data[1] + (dsp->in_data[0] << 8);
|
|
406 | 395 |
linfo ("set freq %#x, %#x = %d\n", |
407 |
dsp.in_data[1], dsp.in_data[0], dsp.freq);
|
|
396 |
dsp->in_data[1], dsp->in_data[0], dsp->freq);
|
|
408 | 397 |
break; |
409 | 398 |
|
410 | 399 |
case 0x48: |
411 |
dsp.dma_buffer_size = dsp.in_data[1] + (dsp.in_data[0] << 8);
|
|
400 |
dsp->dma_buffer_size = dsp->in_data[1] + (dsp->in_data[0] << 8);
|
|
412 | 401 |
linfo ("set dma len %#x, %#x = %d\n", |
413 |
dsp.in_data[1], dsp.in_data[0], dsp.dma_buffer_size);
|
|
402 |
dsp->in_data[1], dsp->in_data[0], dsp->dma_buffer_size);
|
|
414 | 403 |
break; |
415 | 404 |
|
416 | 405 |
case 0xe0: |
417 |
dsp.out_data_len = 1;
|
|
418 |
linfo ("data = %#x\n", dsp.in_data[0]);
|
|
419 |
dsp.out_data[0] = dsp.in_data[0] ^ 0xff;
|
|
406 |
dsp->out_data_len = 1;
|
|
407 |
linfo ("data = %#x\n", dsp->in_data[0]);
|
|
408 |
dsp->out_data[0] = dsp->in_data[0] ^ 0xff;
|
|
420 | 409 |
break; |
421 | 410 |
|
422 | 411 |
default: |
423 |
goto error; |
|
412 |
log ("unrecognized command %#x", dsp->cmd); |
|
413 |
return; |
|
424 | 414 |
} |
425 | 415 |
} |
426 | 416 |
|
427 |
dsp.cmd = -1;
|
|
417 |
dsp->cmd = -1;
|
|
428 | 418 |
return; |
429 |
|
|
430 |
error: |
|
431 |
Fail ("unrecognized command %#x", dsp.cmd); |
|
432 | 419 |
} |
433 | 420 |
|
434 | 421 |
static IO_WRITE_PROTO (dsp_write) |
435 | 422 |
{ |
423 |
SB16State *dsp = opaque; |
|
436 | 424 |
int iport; |
437 | 425 |
|
438 | 426 |
iport = nport - sb.port; |
... | ... | |
440 | 428 |
switch (iport) { |
441 | 429 |
case 0x6: |
442 | 430 |
if (0 == val) |
443 |
dsp.v2x6 = 0;
|
|
444 |
else if ((1 == val) && (0 == dsp.v2x6)) {
|
|
445 |
dsp.v2x6 = 1;
|
|
446 |
dsp.out_data[dsp.out_data_len++] = 0xaa;
|
|
431 |
dsp->v2x6 = 0;
|
|
432 |
else if ((1 == val) && (0 == dsp->v2x6)) {
|
|
433 |
dsp->v2x6 = 1;
|
|
434 |
dsp->out_data[dsp->out_data_len++] = 0xaa;
|
|
447 | 435 |
} |
448 | 436 |
else |
449 |
dsp.v2x6 = ~0;
|
|
437 |
dsp->v2x6 = ~0;
|
|
450 | 438 |
break; |
451 | 439 |
|
452 | 440 |
case 0xc: /* write data or command | write status */ |
453 |
if (0 == dsp.needed_bytes) {
|
|
454 |
command (val); |
|
455 |
if (0 == dsp.needed_bytes) {
|
|
456 |
log_dsp (__func__);
|
|
441 |
if (0 == dsp->needed_bytes) {
|
|
442 |
command (dsp, val);
|
|
443 |
if (0 == dsp->needed_bytes) {
|
|
444 |
log_dsp (dsp);
|
|
457 | 445 |
} |
458 | 446 |
} |
459 | 447 |
else { |
460 |
dsp.in_data[dsp.in_index++] = val;
|
|
461 |
if (dsp.in_index == dsp.needed_bytes) {
|
|
462 |
dsp.needed_bytes = 0;
|
|
463 |
dsp.in_index = 0;
|
|
464 |
complete (); |
|
465 |
log_dsp (__func__);
|
|
448 |
dsp->in_data[dsp->in_index++] = val;
|
|
449 |
if (dsp->in_index == dsp->needed_bytes) {
|
|
450 |
dsp->needed_bytes = 0;
|
|
451 |
dsp->in_index = 0;
|
|
452 |
complete (dsp);
|
|
453 |
log_dsp (dsp);
|
|
466 | 454 |
} |
467 | 455 |
} |
468 | 456 |
break; |
469 | 457 |
|
470 | 458 |
default: |
471 |
Fail ("(nport=%#x, val=%#x)", nport, val); |
|
459 |
log ("(nport=%#x, val=%#x)", nport, val); |
|
460 |
break; |
|
472 | 461 |
} |
473 | 462 |
} |
474 | 463 |
|
475 | 464 |
static IO_READ_PROTO (dsp_read) |
476 | 465 |
{ |
477 |
char *msg;
|
|
466 |
SB16State *dsp = opaque;
|
|
478 | 467 |
int iport, retval; |
479 | 468 |
|
480 |
msg = (char *) -1; |
|
481 | 469 |
iport = nport - sb.port; |
482 | 470 |
|
483 | 471 |
switch (iport) { |
... | ... | |
486 | 474 |
return 0; |
487 | 475 |
|
488 | 476 |
case 0xa: /* read data */ |
489 |
if (dsp.out_data_len) { |
|
490 |
retval = dsp.out_data[--dsp.out_data_len]; |
|
491 |
} |
|
492 |
else { |
|
493 |
#if 1 |
|
494 |
lwarn ("empty output buffer\n"); |
|
495 |
retval = 0; |
|
496 |
#else |
|
497 |
msg = "empty output buffer"; |
|
477 |
if (dsp->out_data_len) { |
|
478 |
retval = dsp->out_data[--dsp->out_data_len]; |
|
479 |
} else { |
|
480 |
log("empty output buffer\n"); |
|
498 | 481 |
goto error; |
499 |
#endif |
|
500 | 482 |
} |
501 | 483 |
break; |
502 | 484 |
|
... | ... | |
505 | 487 |
break; |
506 | 488 |
|
507 | 489 |
case 0xd: /* timer interrupt clear */ |
490 |
log("timer interrupt clear\n"); |
|
508 | 491 |
goto error; |
509 | 492 |
|
510 | 493 |
case 0xe: /* data available status | irq 8 ack */ |
511 | 494 |
/* XXX drop pic irq line here? */ |
512 | 495 |
ldebug ("8 ack\n"); |
513 |
retval = (0 == dsp.out_data_len) ? 0 : 0x80;
|
|
514 |
mixer.regs[0x82] &= ~mixer.regs[0x80];
|
|
496 |
retval = (0 == dsp->out_data_len) ? 0 : 0x80;
|
|
497 |
dsp->mixer_regs[0x82] &= ~dsp->mixer_regs[0x80];
|
|
515 | 498 |
pic_set_irq (sb.irq, 0); |
516 | 499 |
break; |
517 | 500 |
|
... | ... | |
519 | 502 |
/* XXX drop pic irq line here? */ |
520 | 503 |
ldebug ("16 ack\n"); |
521 | 504 |
retval = 0xff; |
522 |
mixer.regs[0x82] &= ~mixer.regs[0x80];
|
|
505 |
dsp->mixer_regs[0x82] &= ~dsp->mixer_regs[0x80];
|
|
523 | 506 |
pic_set_irq (sb.irq, 0); |
524 | 507 |
break; |
525 | 508 |
|
... | ... | |
535 | 518 |
return retval; |
536 | 519 |
|
537 | 520 |
error: |
538 |
Fail ("(nport=%#x) %s", nport, msg);
|
|
521 |
return 0;
|
|
539 | 522 |
} |
540 | 523 |
|
541 | 524 |
static IO_WRITE_PROTO(mixer_write_indexb) |
542 | 525 |
{ |
543 |
mixer.nreg = val & 0xff; |
|
526 |
SB16State *dsp = opaque; |
|
527 |
dsp->mixer_nreg = val & 0xff; |
|
544 | 528 |
} |
545 | 529 |
|
546 | 530 |
static IO_WRITE_PROTO(mixer_write_datab) |
547 | 531 |
{ |
548 |
mixer.regs[mixer.nreg] = val; |
|
532 |
SB16State *dsp = opaque; |
|
533 |
dsp->mixer_regs[dsp->mixer_nreg] = val; |
|
549 | 534 |
} |
550 | 535 |
|
551 | 536 |
static IO_WRITE_PROTO(mixer_write_indexw) |
... | ... | |
556 | 541 |
|
557 | 542 |
static IO_READ_PROTO(mixer_read) |
558 | 543 |
{ |
559 |
return mixer.regs[mixer.nreg]; |
|
544 |
SB16State *dsp = opaque; |
|
545 |
return dsp->mixer_regs[dsp->mixer_nreg]; |
|
560 | 546 |
} |
561 | 547 |
|
562 | 548 |
void SB16_run (void) |
... | ... | |
607 | 593 |
|
608 | 594 |
static int SB_read_DMA (void *opaque, target_ulong addr, int size) |
609 | 595 |
{ |
596 |
SB16State *dsp = opaque; |
|
610 | 597 |
int free, till, copy, written; |
611 | 598 |
|
612 |
if (0 == dsp.speaker)
|
|
599 |
if (0 == dsp->speaker)
|
|
613 | 600 |
return 0; |
614 | 601 |
|
615 |
if (dsp.left_till_irq < 0) {
|
|
616 |
dsp.left_till_irq += dsp.dma_buffer_size;
|
|
617 |
return dsp.dma_pos;
|
|
602 |
if (dsp->left_till_irq < 0) {
|
|
603 |
dsp->left_till_irq += dsp->dma_buffer_size;
|
|
604 |
return dsp->dma_pos;
|
|
618 | 605 |
} |
619 | 606 |
|
620 | 607 |
free = AUD_get_free (); |
621 | 608 |
|
622 | 609 |
if ((free <= 0) || (0 == size)) { |
623 |
return dsp.dma_pos;
|
|
610 |
return dsp->dma_pos;
|
|
624 | 611 |
} |
625 | 612 |
|
626 | 613 |
if (mix_block > 0) { |
... | ... | |
630 | 617 |
copy = free; |
631 | 618 |
} |
632 | 619 |
|
633 |
till = dsp.left_till_irq;
|
|
620 |
till = dsp->left_till_irq;
|
|
634 | 621 |
|
635 | 622 |
ldebug ("addr:%#010x free:%d till:%d size:%d\n", |
636 | 623 |
addr, free, till, size); |
637 | 624 |
if (till <= copy) { |
638 |
if (0 == dsp.dma_auto) {
|
|
625 |
if (0 == dsp->dma_auto) {
|
|
639 | 626 |
copy = till; |
640 | 627 |
} |
641 | 628 |
} |
642 | 629 |
|
643 | 630 |
written = write_audio (addr, size, copy); |
644 |
dsp.left_till_irq -= written;
|
|
631 |
dsp->left_till_irq -= written;
|
|
645 | 632 |
AUD_adjust_estimate (free - written); |
646 | 633 |
|
647 |
if (dsp.left_till_irq <= 0) {
|
|
648 |
mixer.regs[0x82] |= mixer.regs[0x80];
|
|
634 |
if (dsp->left_till_irq <= 0) {
|
|
635 |
dsp->mixer_regs[0x82] |= dsp->mixer_regs[0x80];
|
|
649 | 636 |
if (0 == noirq) { |
650 | 637 |
ldebug ("request irq\n"); |
651 | 638 |
pic_set_irq(sb.irq, 1); |
652 | 639 |
} |
653 | 640 |
|
654 |
if (0 == dsp.dma_auto) {
|
|
641 |
if (0 == dsp->dma_auto) {
|
|
655 | 642 |
control (0); |
656 | 643 |
} |
657 | 644 |
} |
658 | 645 |
|
659 | 646 |
ldebug ("pos %5d free %5d size %5d till % 5d copy %5d dma size %5d\n", |
660 |
dsp.dma_pos, free, size, dsp.left_till_irq, copy,
|
|
661 |
dsp.dma_buffer_size);
|
|
647 |
dsp->dma_pos, free, size, dsp->left_till_irq, copy,
|
|
648 |
dsp->dma_buffer_size);
|
|
662 | 649 |
|
663 |
if (dsp.left_till_irq <= 0) {
|
|
664 |
dsp.left_till_irq += dsp.dma_buffer_size;
|
|
650 |
if (dsp->left_till_irq <= 0) {
|
|
651 |
dsp->left_till_irq += dsp->dma_buffer_size;
|
|
665 | 652 |
} |
666 | 653 |
|
667 |
return dsp.dma_pos;
|
|
654 |
return dsp->dma_pos;
|
|
668 | 655 |
} |
669 | 656 |
|
670 | 657 |
static int magic_of_irq (int irq) |
... | ... | |
703 | 690 |
|
704 | 691 |
void SB16_init (void) |
705 | 692 |
{ |
693 |
SB16State *s = &dsp; |
|
706 | 694 |
int i; |
707 | 695 |
static const uint8_t dsp_write_ports[] = {0x6, 0xc}; |
708 | 696 |
static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf}; |
709 | 697 |
|
710 |
mixer.regs[0x0e] = ~0;
|
|
711 |
mixer.regs[0x80] = magic_of_irq (sb.irq);
|
|
712 |
mixer.regs[0x81] = 0x20 | (sb.dma << 1);
|
|
698 |
s->mixer_regs[0x0e] = ~0;
|
|
699 |
s->mixer_regs[0x80] = magic_of_irq (sb.irq);
|
|
700 |
s->mixer_regs[0x81] = 0x20 | (sb.dma << 1);
|
|
713 | 701 |
|
714 | 702 |
DEREF (irq_of_magic); |
715 | 703 |
|
716 | 704 |
for (i = 0x30; i < 0x48; i++) { |
717 |
mixer.regs[i] = 0x20;
|
|
705 |
s->mixer_regs[i] = 0x20;
|
|
718 | 706 |
} |
719 | 707 |
|
720 | 708 |
for (i = 0; i < LENOFA (dsp_write_ports); i++) { |
721 |
register_ioport_write (sb.port + dsp_write_ports[i], 1, 1, dsp_write, NULL);
|
|
709 |
register_ioport_write (sb.port + dsp_write_ports[i], 1, 1, dsp_write, s);
|
|
722 | 710 |
} |
723 | 711 |
|
724 | 712 |
for (i = 0; i < LENOFA (dsp_read_ports); i++) { |
725 |
register_ioport_read (sb.port + dsp_read_ports[i], 1, 1, dsp_read, NULL);
|
|
713 |
register_ioport_read (sb.port + dsp_read_ports[i], 1, 1, dsp_read, s);
|
|
726 | 714 |
} |
727 | 715 |
|
728 |
register_ioport_write (sb.port + 0x4, 1, 1, mixer_write_indexb, NULL);
|
|
729 |
register_ioport_write (sb.port + 0x4, 1, 2, mixer_write_indexw, NULL);
|
|
730 |
register_ioport_read (sb.port + 0x5, 1, 1, mixer_read, NULL);
|
|
731 |
register_ioport_write (sb.port + 0x5, 1, 1, mixer_write_datab, NULL);
|
|
716 |
register_ioport_write (sb.port + 0x4, 1, 1, mixer_write_indexb, s);
|
|
717 |
register_ioport_write (sb.port + 0x4, 1, 2, mixer_write_indexw, s);
|
|
718 |
register_ioport_read (sb.port + 0x5, 1, 1, mixer_read, s);
|
|
719 |
register_ioport_write (sb.port + 0x5, 1, 1, mixer_write_datab, s);
|
|
732 | 720 |
|
733 |
DMA_register_channel (sb.hdma, SB_read_DMA, NULL);
|
|
734 |
DMA_register_channel (sb.dma, SB_read_DMA, NULL);
|
|
721 |
DMA_register_channel (sb.hdma, SB_read_DMA, s);
|
|
722 |
DMA_register_channel (sb.dma, SB_read_DMA, s);
|
|
735 | 723 |
} |
Also available in: Unified diff