audio: add Apple Sound Chip (ASC) emulation

The Apple Sound Chip was primarily used by the Macintosh II to generate sound
in hardware which was previously handled by the toolbox ROM with software
interrupts.

Implement both the standard ASC and also the enhanced ASC (EASC) functionality
which is used in the Quadra 800.

Note that whilst real ASC hardware uses AUDIO_FORMAT_S8, this implementation uses
AUDIO_FORMAT_U8 instead because AUDIO_FORMAT_S8 is rarely used and not supported
by some audio backends like PulseAudio and DirectSound when played directly with
-audiodev out.mixing-engine=off.

Co-developed-by: Laurent Vivier <laurent@vivier.eu>
Co-developed-by: Volker Rümelin <vr_qemu@t-online.de>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Message-ID: <20231004083806.757242-8-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
This commit is contained in:
Mark Cave-Ayland
2023-10-06 10:33:43 +02:00
committed by Laurent Vivier
parent 6997f26d0d
commit ac13a6b3fd
7 changed files with 809 additions and 0 deletions
+2
View File
@@ -1231,6 +1231,7 @@ F: hw/display/macfb.c
F: hw/block/swim.c
F: hw/misc/djmemc.c
F: hw/misc/iosb.c
F: hw/audio/asc.c
F: hw/m68k/bootinfo.h
F: include/standard-headers/asm-m68k/bootinfo.h
F: include/standard-headers/asm-m68k/bootinfo-mac.h
@@ -1242,6 +1243,7 @@ F: include/hw/m68k/q800.h
F: include/hw/m68k/q800-glue.h
F: include/hw/misc/djmemc.h
F: include/hw/misc/iosb.h
F: include/hw/audio/asc.h
virt
M: Laurent Vivier <laurent@vivier.eu>
+3
View File
@@ -47,3 +47,6 @@ config PL041
config CS4231
bool
config ASC
bool
+708
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -1,6 +1,7 @@
system_ss.add(files('soundhw.c'))
system_ss.add(when: 'CONFIG_AC97', if_true: files('ac97.c'))
system_ss.add(when: 'CONFIG_ADLIB', if_true: files('fmopl.c', 'adlib.c'))
system_ss.add(when: 'CONFIG_ASC', if_true: files('asc.c'))
system_ss.add(when: 'CONFIG_CS4231', if_true: files('cs4231.c'))
system_ss.add(when: 'CONFIG_CS4231A', if_true: files('cs4231a.c'))
system_ss.add(when: 'CONFIG_ES1370', if_true: files('es1370.c'))
+10
View File
@@ -17,3 +17,13 @@ via_ac97_codec_write(uint8_t addr, uint16_t val) "0x%x <- 0x%x"
via_ac97_sgd_fetch(uint32_t curr, uint32_t addr, char stop, char eol, char flag, uint32_t len) "curr=0x%x addr=0x%x %c%c%c len=%d"
via_ac97_sgd_read(uint64_t addr, unsigned size, uint64_t val) "0x%"PRIx64" %d -> 0x%"PRIx64
via_ac97_sgd_write(uint64_t addr, unsigned size, uint64_t val) "0x%"PRIx64" %d <- 0x%"PRIx64
# asc.c
asc_read_fifo(const char fifo, int reg, unsigned size, uint64_t value) "fifo %c reg=0x%03x size=%u value=0x%"PRIx64
asc_read_reg(int reg, unsigned size, uint64_t value) "reg=0x%03x size=%u value=0x%"PRIx64
asc_read_extreg(const char fifo, int reg, unsigned size, uint64_t value) "fifo %c reg=0x%03x size=%u value=0x%"PRIx64
asc_fifo_get(const char fifo, int rptr, int cnt, uint64_t value) "fifo %c rptr=0x%x cnt=0x%x value=0x%"PRIx64
asc_write_fifo(const char fifo, int reg, unsigned size, int wrptr, int cnt, uint64_t value) "fifo %c reg=0x%03x size=%u wptr=0x%x cnt=0x%x value=0x%"PRIx64
asc_write_reg(int reg, unsigned size, uint64_t value) "reg=0x%03x size=%u value=0x%"PRIx64
asc_write_extreg(const char fifo, int reg, unsigned size, uint64_t value) "fifo %c reg=0x%03x size=%u value=0x%"PRIx64
asc_update_irq(int irq, int a, int b) "set IRQ to %d (A: 0x%x B: 0x%x)"
+1
View File
@@ -25,6 +25,7 @@ config Q800
select OR_IRQ
select DJMEMC
select IOSB
select ASC
config M68K_VIRT
bool
+84
View File
@@ -0,0 +1,84 @@
/*
* QEMU Apple Sound Chip emulation
*
* Apple Sound Chip (ASC) 344S0063
* Enhanced Apple Sound Chip (EASC) 343S1063
*
* Copyright (c) 2012-2018 Laurent Vivier <laurent@vivier.eu>
* Copyright (c) 2022 Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef HW_AUDIO_ASC_H
#define HW_AUDIO_ASC_H
#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "audio/audio.h"
#define ASC_FREQ 22257
enum {
ASC_TYPE_ASC = 0, /* original discrete Apple Sound Chip */
ASC_TYPE_EASC = 1 /* discrete Enhanced Apple Sound Chip */
};
#define ASC_FIFO_OFFSET 0x0
#define ASC_FIFO_SIZE 0x400
#define ASC_REG_OFFSET 0x800
#define ASC_REG_SIZE 0x60
#define ASC_EXTREG_OFFSET 0xf00
#define ASC_EXTREG_SIZE 0x20
typedef struct ASCFIFOState {
int index;
MemoryRegion mem_fifo;
uint8_t fifo[ASC_FIFO_SIZE];
uint8_t int_status;
int cnt;
int wptr;
int rptr;
MemoryRegion mem_extregs;
uint8_t extregs[ASC_EXTREG_SIZE];
int xa_cnt;
uint8_t xa_val;
uint8_t xa_flags;
int16_t xa_last[2];
} ASCFIFOState;
struct ASCState {
SysBusDevice parent_obj;
uint8_t type;
MemoryRegion asc;
MemoryRegion mem_fifo;
MemoryRegion mem_regs;
MemoryRegion mem_extregs;
QEMUSoundCard card;
SWVoiceOut *voice;
uint8_t *mixbuf;
int samples;
int shift;
/* Time when we were last able to generate samples */
int64_t fifo_empty_ns;
qemu_irq irq;
ASCFIFOState fifos[2];
uint8_t regs[ASC_REG_SIZE];
};
#define TYPE_ASC "apple-sound-chip"
OBJECT_DECLARE_SIMPLE_TYPE(ASCState, ASC)
#endif