13
#include "qemu/osdep.h"
14
#include "qemu/timer.h"
17
#include "audio/audio.h"
18
#include "hw/audio/asc.h"
19
#include "hw/qdev-properties.h"
20
#include "migration/vmstate.h"
81
#define ASC_SIZE 0x2000
97
#define ASC_FIFO_STATUS_HALF_FULL 1
98
#define ASC_FIFO_STATUS_FULL_EMPTY 2
100
#define ASC_EXTREGS_FIFOCTRL 0x8
101
#define ASC_EXTREGS_INTCTRL 0x9
102
#define ASC_EXTREGS_CDXA_DECOMP_FILT 0x10
104
#define ASC_FIFO_CYCLE_TIME ((NANOSECONDS_PER_SECOND / ASC_FREQ) * \
107
static void asc_raise_irq(ASCState *s)
109
qemu_set_irq(s->irq, 1);
112
static void asc_lower_irq(ASCState *s)
114
qemu_set_irq(s->irq, 0);
117
static uint8_t asc_fifo_get(ASCFIFOState *fs)
119
ASCState *s = container_of(fs, ASCState, fifos[fs->index]);
120
bool fifo_half_irq_enabled = fs->extregs[ASC_EXTREGS_INTCTRL] & 1;
125
val = fs->fifo[fs->rptr];
126
trace_asc_fifo_get('A' + fs->index, fs->rptr, fs->cnt, val);
132
if (fs->cnt <= 0x1ff) {
134
fs->int_status |= ASC_FIFO_STATUS_HALF_FULL;
137
fs->int_status &= ~ASC_FIFO_STATUS_HALF_FULL;
140
if (fs->cnt == 0x1ff && fifo_half_irq_enabled) {
147
fs->int_status |= ASC_FIFO_STATUS_FULL_EMPTY;
154
static int generate_fifo(ASCState *s, int maxsamples)
156
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
157
uint8_t *buf = s->mixbuf;
160
while (wcount < maxsamples) {
165
bool hasdata = false;
167
for (i = 0; i < 2; i++) {
168
ASCFIFOState *fs = &s->fifos[i];
170
switch (fs->extregs[ASC_EXTREGS_FIFOCTRL] & 0x83) {
181
if (fs->xa_cnt == -1) {
183
fs->xa_flags = asc_fifo_get(fs);
187
shift = fs->xa_flags & 0xf;
188
filter = fs->xa_flags >> 4;
189
f0 = (int8_t)fs->extregs[ASC_EXTREGS_CDXA_DECOMP_FILT +
191
f1 = (int8_t)fs->extregs[ASC_EXTREGS_CDXA_DECOMP_FILT +
194
if ((fs->xa_cnt & 1) == 0) {
200
fs->xa_val = asc_fifo_get(fs);
201
d = (fs->xa_val & 0xf) << 12;
203
d = (fs->xa_val & 0xf0) << 8;
205
t = (d >> shift) + (((fs->xa_last[0] * f0) +
206
(fs->xa_last[1] * f1) + 32) >> 6);
209
} else if (t > 32767) {
218
val = (uint8_t)(t / 256) ^ 0x80;
222
fs->xa_last[1] = fs->xa_last[0];
223
fs->xa_last[0] = (int16_t)t;
225
if (fs->xa_cnt == 28) {
236
val = asc_fifo_get(fs);
244
buf[wcount * 2 + i] = val;
260
if (s->fifos[0].cnt == 0 && s->fifos[1].cnt == 0) {
261
if (!s->fifo_empty_ns) {
263
s->fifo_empty_ns = now;
264
} else if (now > (s->fifo_empty_ns + ASC_FIFO_CYCLE_TIME)) {
266
s->fifos[0].int_status |= ASC_FIFO_STATUS_HALF_FULL |
267
ASC_FIFO_STATUS_FULL_EMPTY;
268
s->fifos[1].int_status |= ASC_FIFO_STATUS_HALF_FULL |
269
ASC_FIFO_STATUS_FULL_EMPTY;
270
s->fifo_empty_ns = now;
275
s->fifo_empty_ns = 0;
281
static int generate_wavetable(ASCState *s, int maxsamples)
283
uint8_t *buf = s->mixbuf;
284
int channel, count = 0;
286
while (count < maxsamples) {
287
uint32_t left = 0, right = 0;
290
for (channel = 0; channel < 4; channel++) {
291
ASCFIFOState *fs = &s->fifos[channel >> 1];
292
int chanreg = ASC_WAVETABLE + (channel << 3);
293
uint32_t phase, incr, offset;
295
phase = ldl_be_p(&s->regs[chanreg]);
296
incr = ldl_be_p(&s->regs[chanreg + sizeof(uint32_t)]);
299
offset = (phase >> 15) & 0x1ff;
300
sample = fs->fifo[0x200 * (channel >> 1) + offset];
302
stl_be_p(&s->regs[chanreg], phase);
308
buf[count * 2] = left >> 2;
309
buf[count * 2 + 1] = right >> 2;
317
static void asc_out_cb(void *opaque, int free_b)
319
ASCState *s = opaque;
320
int samples, generated;
326
samples = MIN(s->samples, free_b >> s->shift);
328
switch (s->regs[ASC_MODE] & 3) {
335
generated = generate_fifo(s, samples);
339
generated = generate_wavetable(s, samples);
345
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
346
int silent_samples = muldiv64(now - s->fifo_empty_ns,
347
NANOSECONDS_PER_SECOND, ASC_FREQ);
349
if (silent_samples > ASC_FIFO_CYCLE_TIME / 2) {
357
AUD_write(s->voice, s->silentbuf, samples << s->shift);
362
AUD_write(s->voice, s->mixbuf, generated << s->shift);
365
static uint64_t asc_fifo_read(void *opaque, hwaddr addr,
368
ASCFIFOState *fs = opaque;
370
trace_asc_read_fifo('A' + fs->index, addr, size, fs->fifo[addr]);
371
return fs->fifo[addr];
374
static void asc_fifo_write(void *opaque, hwaddr addr, uint64_t value,
377
ASCFIFOState *fs = opaque;
378
ASCState *s = container_of(fs, ASCState, fifos[fs->index]);
379
bool fifo_half_irq_enabled = fs->extregs[ASC_EXTREGS_INTCTRL] & 1;
381
trace_asc_write_fifo('A' + fs->index, addr, size, fs->wptr, fs->cnt, value);
383
if (s->regs[ASC_MODE] == 1) {
384
fs->fifo[fs->wptr++] = value;
388
if (fs->cnt <= 0x1ff) {
390
fs->int_status |= ASC_FIFO_STATUS_HALF_FULL;
393
fs->int_status &= ~ASC_FIFO_STATUS_HALF_FULL;
396
if (fs->cnt == 0x200 && fifo_half_irq_enabled) {
401
if (fs->cnt == 0x3ff) {
403
fs->int_status |= ASC_FIFO_STATUS_FULL_EMPTY;
407
fs->fifo[addr] = value;
412
static const MemoryRegionOps asc_fifo_ops = {
413
.read = asc_fifo_read,
414
.write = asc_fifo_write,
416
.min_access_size = 1,
417
.max_access_size = 1,
419
.endianness = DEVICE_BIG_ENDIAN,
422
static void asc_fifo_reset(ASCFIFOState *fs);
424
static uint64_t asc_read(void *opaque, hwaddr addr,
427
ASCState *s = opaque;
428
uint64_t prev, value;
443
prev = (s->fifos[0].int_status & 0x3) |
444
(s->fifos[1].int_status & 0x3) << 2;
446
s->fifos[0].int_status = 0;
447
s->fifos[1].int_status = 0;
452
value = s->regs[addr];
456
trace_asc_read_reg(addr, size, value);
460
static void asc_write(void *opaque, hwaddr addr, uint64_t value,
463
ASCState *s = opaque;
468
if (value != s->regs[ASC_MODE]) {
469
asc_fifo_reset(&s->fifos[0]);
470
asc_fifo_reset(&s->fifos[1]);
473
AUD_set_active_out(s->voice, 1);
475
AUD_set_active_out(s->voice, 0);
481
asc_fifo_reset(&s->fifos[0]);
482
asc_fifo_reset(&s->fifos[1]);
490
int vol = (value & 0xe0);
492
AUD_set_volume_out(s->voice, 0, vol, vol);
497
trace_asc_write_reg(addr, size, value);
498
s->regs[addr] = value;
501
static const MemoryRegionOps asc_regs_ops = {
504
.endianness = DEVICE_BIG_ENDIAN,
506
.min_access_size = 1,
507
.max_access_size = 1,
511
static uint64_t asc_ext_read(void *opaque, hwaddr addr,
514
ASCFIFOState *fs = opaque;
517
value = fs->extregs[addr];
519
trace_asc_read_extreg('A' + fs->index, addr, size, value);
523
static void asc_ext_write(void *opaque, hwaddr addr, uint64_t value,
526
ASCFIFOState *fs = opaque;
528
trace_asc_write_extreg('A' + fs->index, addr, size, value);
530
fs->extregs[addr] = value;
533
static const MemoryRegionOps asc_extregs_ops = {
534
.read = asc_ext_read,
535
.write = asc_ext_write,
537
.min_access_size = 1,
538
.max_access_size = 1,
540
.endianness = DEVICE_BIG_ENDIAN,
543
static int asc_post_load(void *opaque, int version)
545
ASCState *s = ASC(opaque);
547
if (s->regs[ASC_MODE] != 0) {
548
AUD_set_active_out(s->voice, 1);
554
static const VMStateDescription vmstate_asc_fifo = {
555
.name = "apple-sound-chip.fifo",
557
.minimum_version_id = 0,
558
.fields = (const VMStateField[]) {
559
VMSTATE_UINT8_ARRAY(fifo, ASCFIFOState, ASC_FIFO_SIZE),
560
VMSTATE_UINT8(int_status, ASCFIFOState),
561
VMSTATE_INT32(cnt, ASCFIFOState),
562
VMSTATE_INT32(wptr, ASCFIFOState),
563
VMSTATE_INT32(rptr, ASCFIFOState),
564
VMSTATE_UINT8_ARRAY(extregs, ASCFIFOState, ASC_EXTREG_SIZE),
565
VMSTATE_INT32(xa_cnt, ASCFIFOState),
566
VMSTATE_UINT8(xa_val, ASCFIFOState),
567
VMSTATE_UINT8(xa_flags, ASCFIFOState),
568
VMSTATE_INT16_ARRAY(xa_last, ASCFIFOState, 2),
569
VMSTATE_END_OF_LIST()
573
static const VMStateDescription vmstate_asc = {
574
.name = "apple-sound-chip",
576
.minimum_version_id = 0,
577
.post_load = asc_post_load,
578
.fields = (const VMStateField[]) {
579
VMSTATE_STRUCT_ARRAY(fifos, ASCState, 2, 0, vmstate_asc_fifo,
581
VMSTATE_UINT8_ARRAY(regs, ASCState, ASC_REG_SIZE),
582
VMSTATE_INT64(fifo_empty_ns, ASCState),
583
VMSTATE_END_OF_LIST()
587
static void asc_fifo_reset(ASCFIFOState *fs)
596
static void asc_fifo_init(ASCFIFOState *fs, int index)
598
ASCState *s = container_of(fs, ASCState, fifos[index]);
602
name = g_strdup_printf("asc.fifo%c", 'A' + index);
603
memory_region_init_io(&fs->mem_fifo, OBJECT(s), &asc_fifo_ops, fs,
604
name, ASC_FIFO_SIZE);
607
name = g_strdup_printf("asc.extregs%c", 'A' + index);
608
memory_region_init_io(&fs->mem_extregs, OBJECT(s), &asc_extregs_ops,
609
fs, name, ASC_EXTREG_SIZE);
613
static void asc_reset_hold(Object *obj, ResetType type)
615
ASCState *s = ASC(obj);
617
AUD_set_active_out(s->voice, 0);
619
memset(s->regs, 0, sizeof(s->regs));
620
asc_fifo_reset(&s->fifos[0]);
621
asc_fifo_reset(&s->fifos[1]);
622
s->fifo_empty_ns = 0;
624
if (s->type == ASC_TYPE_ASC) {
626
s->fifos[0].extregs[ASC_EXTREGS_INTCTRL] = 1;
627
s->fifos[1].extregs[ASC_EXTREGS_INTCTRL] = 1;
631
static void asc_unrealize(DeviceState *dev)
633
ASCState *s = ASC(dev);
636
g_free(s->silentbuf);
638
AUD_remove_card(&s->card);
641
static void asc_realize(DeviceState *dev, Error **errp)
643
ASCState *s = ASC(dev);
644
struct audsettings as;
646
if (!AUD_register_card("Apple Sound Chip", &s->card, errp)) {
652
as.fmt = AUDIO_FORMAT_U8;
653
as.endianness = AUDIO_HOST_ENDIANNESS;
655
s->voice = AUD_open_out(&s->card, s->voice, "asc.out", s, asc_out_cb,
658
s->samples = AUD_get_buffer_size_out(s->voice) >> s->shift;
659
s->mixbuf = g_malloc0(s->samples << s->shift);
661
s->silentbuf = g_malloc0(s->samples << s->shift);
662
memset(s->silentbuf, 0x80, s->samples << s->shift);
665
if (s->type == ASC_TYPE_EASC) {
666
memory_region_add_subregion(&s->asc, ASC_EXTREG_OFFSET,
667
&s->fifos[0].mem_extregs);
668
memory_region_add_subregion(&s->asc,
669
ASC_EXTREG_OFFSET + ASC_EXTREG_SIZE,
670
&s->fifos[1].mem_extregs);
674
static void asc_init(Object *obj)
676
ASCState *s = ASC(obj);
677
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
679
memory_region_init(&s->asc, OBJECT(obj), "asc", ASC_SIZE);
681
asc_fifo_init(&s->fifos[0], 0);
682
asc_fifo_init(&s->fifos[1], 1);
684
memory_region_add_subregion(&s->asc, ASC_FIFO_OFFSET,
685
&s->fifos[0].mem_fifo);
686
memory_region_add_subregion(&s->asc,
687
ASC_FIFO_OFFSET + ASC_FIFO_SIZE,
688
&s->fifos[1].mem_fifo);
690
memory_region_init_io(&s->mem_regs, OBJECT(obj), &asc_regs_ops, s,
691
"asc.regs", ASC_REG_SIZE);
692
memory_region_add_subregion(&s->asc, ASC_REG_OFFSET, &s->mem_regs);
694
sysbus_init_irq(sbd, &s->irq);
695
sysbus_init_mmio(sbd, &s->asc);
698
static Property asc_properties[] = {
699
DEFINE_AUDIO_PROPERTIES(ASCState, card),
700
DEFINE_PROP_UINT8("asctype", ASCState, type, ASC_TYPE_ASC),
701
DEFINE_PROP_END_OF_LIST(),
704
static void asc_class_init(ObjectClass *oc, void *data)
706
DeviceClass *dc = DEVICE_CLASS(oc);
707
ResettableClass *rc = RESETTABLE_CLASS(oc);
709
dc->realize = asc_realize;
710
dc->unrealize = asc_unrealize;
711
set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
712
dc->vmsd = &vmstate_asc;
713
device_class_set_props(dc, asc_properties);
714
rc->phases.hold = asc_reset_hold;
717
static const TypeInfo asc_info_types[] = {
720
.parent = TYPE_SYS_BUS_DEVICE,
721
.instance_size = sizeof(ASCState),
722
.instance_init = asc_init,
723
.class_init = asc_class_init,
727
DEFINE_TYPES(asc_info_types)