| 53 |
} conf = {0x220, 44100}; |
} conf = {0x220, 44100}; |
| 54 |
|
|
| 55 |
typedef struct { |
typedef struct { |
| 56 |
|
QEMUSoundCard card; |
| 57 |
int ticking[2]; |
int ticking[2]; |
| 58 |
int enabled; |
int enabled; |
| 59 |
int active; |
int active; |
| 71 |
#endif |
#endif |
| 72 |
} AdlibState; |
} AdlibState; |
| 73 |
|
|
| 74 |
static AdlibState adlib; |
static AdlibState glob_adlib; |
| 75 |
|
|
| 76 |
static void adlib_stop_opl_timer (AdlibState *s, size_t n) |
static void adlib_stop_opl_timer (AdlibState *s, size_t n) |
| 77 |
{ |
{ |
| 91 |
if (s->ticking[i]) { |
if (s->ticking[i]) { |
| 92 |
uint64_t delta; |
uint64_t delta; |
| 93 |
|
|
| 94 |
delta = AUD_time_stamp_get_elapsed_usec_out (s->voice, &s->ats); |
delta = AUD_get_elapsed_usec_out (s->voice, &s->ats); |
| 95 |
ldebug ( |
ldebug ( |
| 96 |
"delta = %f dexp = %f expired => %d\n", |
"delta = %f dexp = %f expired => %d\n", |
| 97 |
delta / 1000000.0, |
delta / 1000000.0, |
| 142 |
|
|
| 143 |
static void timer_handler (int c, double interval_Sec) |
static void timer_handler (int c, double interval_Sec) |
| 144 |
{ |
{ |
| 145 |
AdlibState *s = &adlib; |
AdlibState *s = &glob_adlib; |
| 146 |
unsigned n = c & 1; |
unsigned n = c & 1; |
| 147 |
#ifdef DEBUG |
#ifdef DEBUG |
| 148 |
double interval; |
double interval; |
| 149 |
|
int64_t exp; |
| 150 |
#endif |
#endif |
| 151 |
|
|
| 152 |
if (interval_Sec == 0.0) { |
if (interval_Sec == 0.0) { |
| 264 |
|
|
| 265 |
s->active = 0; |
s->active = 0; |
| 266 |
s->enabled = 0; |
s->enabled = 0; |
| 267 |
|
AUD_remove_card (&s->card); |
| 268 |
} |
} |
| 269 |
|
|
| 270 |
void Adlib_init (void) |
int Adlib_init (AudioState *audio) |
| 271 |
{ |
{ |
| 272 |
AdlibState *s = &adlib; |
AdlibState *s = &glob_adlib; |
| 273 |
|
audsettings_t as; |
| 274 |
|
|
| 275 |
|
if (!audio) { |
| 276 |
|
dolog ("No audio state\n"); |
| 277 |
|
return -1; |
| 278 |
|
} |
| 279 |
|
|
| 280 |
#ifdef HAS_YMF262 |
#ifdef HAS_YMF262 |
| 281 |
if (YMF262Init (1, 14318180, conf.freq)) { |
if (YMF262Init (1, 14318180, conf.freq)) { |
| 282 |
dolog ("YMF262Init %d failed\n", conf.freq); |
dolog ("YMF262Init %d failed\n", conf.freq); |
| 283 |
return; |
return -1; |
| 284 |
} |
} |
| 285 |
else { |
else { |
| 286 |
YMF262SetTimerHandler (0, timer_handler, 0); |
YMF262SetTimerHandler (0, timer_handler, 0); |
| 290 |
s->opl = OPLCreate (OPL_TYPE_YM3812, 3579545, conf.freq); |
s->opl = OPLCreate (OPL_TYPE_YM3812, 3579545, conf.freq); |
| 291 |
if (!s->opl) { |
if (!s->opl) { |
| 292 |
dolog ("OPLCreate %d failed\n", conf.freq); |
dolog ("OPLCreate %d failed\n", conf.freq); |
| 293 |
return; |
return -1; |
| 294 |
} |
} |
| 295 |
else { |
else { |
| 296 |
OPLSetTimerHandler (s->opl, timer_handler, 0); |
OPLSetTimerHandler (s->opl, timer_handler, 0); |
| 298 |
} |
} |
| 299 |
#endif |
#endif |
| 300 |
|
|
| 301 |
|
as.freq = conf.freq; |
| 302 |
|
as.nchannels = SHIFT; |
| 303 |
|
as.fmt = AUD_FMT_S16; |
| 304 |
|
|
| 305 |
|
AUD_register_card (audio, "adlib", &s->card); |
| 306 |
|
|
| 307 |
s->voice = AUD_open_out ( |
s->voice = AUD_open_out ( |
| 308 |
|
&s->card, |
| 309 |
s->voice, |
s->voice, |
| 310 |
"adlib", |
"adlib", |
| 311 |
s, |
s, |
| 312 |
adlib_callback, |
adlib_callback, |
| 313 |
conf.freq, |
&as |
|
SHIFT, |
|
|
AUD_FMT_S16 |
|
| 314 |
); |
); |
| 315 |
if (!s->voice) { |
if (!s->voice) { |
| 316 |
Adlib_fini (s); |
Adlib_fini (s); |
| 317 |
return; |
return -1; |
| 318 |
} |
} |
| 319 |
|
|
| 320 |
s->samples = AUD_get_buffer_size_out (s->voice) >> SHIFT; |
s->samples = AUD_get_buffer_size_out (s->voice) >> SHIFT; |
| 324 |
dolog ("not enough memory for adlib mixing buffer (%d)\n", |
dolog ("not enough memory for adlib mixing buffer (%d)\n", |
| 325 |
s->samples << SHIFT); |
s->samples << SHIFT); |
| 326 |
Adlib_fini (s); |
Adlib_fini (s); |
| 327 |
return; |
return -1; |
| 328 |
} |
} |
| 329 |
|
|
| 330 |
register_ioport_read (0x388, 4, 1, adlib_read, s); |
register_ioport_read (0x388, 4, 1, adlib_read, s); |
| 335 |
|
|
| 336 |
register_ioport_read (conf.port + 8, 2, 1, adlib_read, s); |
register_ioport_read (conf.port + 8, 2, 1, adlib_read, s); |
| 337 |
register_ioport_write (conf.port + 8, 2, 1, adlib_write, s); |
register_ioport_write (conf.port + 8, 2, 1, adlib_write, s); |
| 338 |
|
|
| 339 |
|
return 0; |
| 340 |
} |
} |