*-nemu,ioe: add audio
This commit is contained in:
parent
90104ba9d2
commit
f47f582b59
|
@ -4,6 +4,7 @@ AM_SRCS += nemu/common/trm.c \
|
|||
nemu/common/input.c \
|
||||
nemu/common/timer.c \
|
||||
nemu/common/video.c \
|
||||
nemu/common/audio.c \
|
||||
dummy/mpe.c \
|
||||
|
||||
CFLAGS += -I$(AM_HOME)/am/src/nemu/include
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
#include <am.h>
|
||||
#include <amdev.h>
|
||||
#include <klib.h>
|
||||
#include <nemu.h>
|
||||
|
||||
static uint8_t* const sbuf = (uint8_t *)AUDIO_SBUF_ADDR;
|
||||
static int sbuf_size = 0;
|
||||
static int head = 0;
|
||||
|
||||
void __am_audio_init() {
|
||||
}
|
||||
|
||||
static int audio_write(uint8_t *buf, int len) {
|
||||
uint32_t count = inl(AUDIO_COUNT_ADDR);
|
||||
int free = sbuf_size - count;
|
||||
int nwrite = len;
|
||||
if (free < len) nwrite = free;
|
||||
|
||||
if (nwrite + head < sbuf_size) {
|
||||
memcpy(sbuf + head, buf, nwrite);
|
||||
head += nwrite;
|
||||
} else {
|
||||
int first_cpy_len = sbuf_size - head;
|
||||
memcpy(sbuf + head, buf, first_cpy_len);
|
||||
memcpy(sbuf, buf + first_cpy_len, nwrite - first_cpy_len);
|
||||
head = nwrite - first_cpy_len;
|
||||
}
|
||||
count += nwrite;
|
||||
outl(AUDIO_COUNT_ADDR, count);
|
||||
return nwrite;
|
||||
}
|
||||
|
||||
size_t __am_audio_write(uintptr_t reg, void *buf, size_t size) {
|
||||
switch (reg) {
|
||||
case _DEVREG_AUDIO_INIT: {
|
||||
_DEV_AUDIO_INIT_t *init = (_DEV_AUDIO_INIT_t *)buf;
|
||||
outl(AUDIO_FREQ_ADDR, init->freq);
|
||||
outl(AUDIO_CHANNELS_ADDR, init->channels);
|
||||
outl(AUDIO_SAMPLES_ADDR, init->samples);
|
||||
outl(AUDIO_SBUF_SIZE_ADDR, init->bufsize);
|
||||
outl(AUDIO_INIT_ADDR, 1);
|
||||
sbuf_size = init->bufsize;
|
||||
|
||||
head = 0;
|
||||
return size;
|
||||
}
|
||||
case _DEVREG_AUDIO_SBCTRL: {
|
||||
_DEV_AUDIO_SBCTRL_t *ctl = (_DEV_AUDIO_SBCTRL_t *)buf;
|
||||
if (ctl->wait) {
|
||||
assert(ctl->len <= sbuf_size);
|
||||
while (sbuf_size - inl(AUDIO_COUNT_ADDR) < ctl->len);
|
||||
}
|
||||
ctl->len = audio_write(ctl->stream, ctl->len);
|
||||
return size;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t __am_audio_read(uintptr_t reg, void *buf, size_t size) {
|
||||
switch (reg) {
|
||||
case _DEVREG_AUDIO_SBSTAT: {
|
||||
_DEV_AUDIO_SBSTAT_t *stat = (_DEV_AUDIO_SBSTAT_t *)buf;
|
||||
stat->count = inl(AUDIO_COUNT_ADDR);
|
||||
stat->bufsize = sbuf_size;
|
||||
return size;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -3,10 +3,12 @@
|
|||
|
||||
void __am_vga_init();
|
||||
void __am_timer_init();
|
||||
void __am_audio_init();
|
||||
|
||||
int _ioe_init() {
|
||||
__am_vga_init();
|
||||
__am_timer_init();
|
||||
__am_audio_init();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -14,12 +16,15 @@ size_t __am_timer_read(uintptr_t reg, void *buf, size_t size);
|
|||
size_t __am_video_read(uintptr_t reg, void *buf, size_t size);
|
||||
size_t __am_video_write(uintptr_t reg, void *buf, size_t size);
|
||||
size_t __am_input_read(uintptr_t reg, void *buf, size_t size);
|
||||
size_t __am_audio_read(uintptr_t reg, void *buf, size_t size);
|
||||
size_t __am_audio_write(uintptr_t reg, void *buf, size_t size);
|
||||
|
||||
size_t _io_read(uint32_t dev, uintptr_t reg, void *buf, size_t size) {
|
||||
switch (dev) {
|
||||
case _DEV_INPUT: return __am_input_read(reg, buf, size);
|
||||
case _DEV_TIMER: return __am_timer_read(reg, buf, size);
|
||||
case _DEV_VIDEO: return __am_video_read(reg, buf, size);
|
||||
case _DEV_AUDIO: return __am_audio_read(reg, buf, size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -27,6 +32,7 @@ size_t _io_read(uint32_t dev, uintptr_t reg, void *buf, size_t size) {
|
|||
size_t _io_write(uint32_t dev, uintptr_t reg, void *buf, size_t size) {
|
||||
switch (dev) {
|
||||
case _DEV_VIDEO: return __am_video_write(reg, buf, size);
|
||||
case _DEV_AUDIO: return __am_audio_write(reg, buf, size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,13 @@
|
|||
# define SCREEN_ADDR 0x100
|
||||
# define SYNC_ADDR 0x104
|
||||
# define FB_ADDR 0xa0000000
|
||||
# define AUDIO_FREQ_ADDR 0x200
|
||||
# define AUDIO_CHANNELS_ADDR 0x204
|
||||
# define AUDIO_SAMPLES_ADDR 0x208
|
||||
# define AUDIO_SBUF_SIZE_ADDR 0x20c
|
||||
# define AUDIO_INIT_ADDR 0x210
|
||||
# define AUDIO_COUNT_ADDR 0x214
|
||||
# define AUDIO_SBUF_ADDR 0xa0800000
|
||||
#elif defined(__ARCH_RISCV64_NOOP) || defined(__ARCH_RISCV32_NOOP)
|
||||
# define KBD_ADDR 0x40900000
|
||||
# define RTC_ADDR 0x4800bff8
|
||||
|
@ -25,6 +32,13 @@
|
|||
# define SCREEN_ADDR 0xa1000100
|
||||
# define SYNC_ADDR 0xa1000104
|
||||
# define FB_ADDR 0xa0000000
|
||||
# define AUDIO_FREQ_ADDR 0xa1000200
|
||||
# define AUDIO_CHANNELS_ADDR 0xa1000204
|
||||
# define AUDIO_SAMPLES_ADDR 0xa1000208
|
||||
# define AUDIO_SBUF_SIZE_ADDR 0xa100020c
|
||||
# define AUDIO_INIT_ADDR 0xa1000210
|
||||
# define AUDIO_COUNT_ADDR 0xa1000214
|
||||
# define AUDIO_SBUF_ADDR 0xa0800000
|
||||
#endif
|
||||
|
||||
#define MMIO_BASE 0xa0000000
|
||||
|
|
Loading…
Reference in New Issue