From a523267d021ecebe77950a20ae156b6f6cf2db6e Mon Sep 17 00:00:00 2001 From: tracer-ics2023 Date: Sat, 21 Sep 2024 14:59:08 +0800 Subject: [PATCH] =?UTF-8?q?>=20=20compile=20NEMU=20221220000=20=E5=BC=A0?= =?UTF-8?q?=E4=B8=89=20Linux=20zzy=205.15.146.1-microsoft-standard-WSL2=20?= =?UTF-8?q?#1=20SMP=20Thu=20Jan=2011=2004:09:03=20UTC=202024=20x86=5F64=20?= =?UTF-8?q?x86=5F64=20x86=5F64=20GNU/Linux=20=2014:59:07=20up=204=20days,?= =?UTF-8?q?=2010:04,=20=201=20user,=20=20load=20average:=200.58,=200.47,?= =?UTF-8?q?=200.52?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../am/src/platform/nemu/ioe/audio.c | 23 ++++++++++------ nemu/src/device/audio.c | 27 +++++++++++++------ 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/abstract-machine/am/src/platform/nemu/ioe/audio.c b/abstract-machine/am/src/platform/nemu/ioe/audio.c index 21e0035..34bd632 100644 --- a/abstract-machine/am/src/platform/nemu/ioe/audio.c +++ b/abstract-machine/am/src/platform/nemu/ioe/audio.c @@ -35,14 +35,21 @@ void __am_audio_status(AM_AUDIO_STATUS_T *stat) { } void __am_audio_play(AM_AUDIO_PLAY_T *ctl) { - for (int i = 0; i < ctl->buf.end - ctl->buf.start; i++) { - if (inl(AUDIO_COUNT_ADDR) == audio_sbuf_size) { - i--; - continue; - } else { - outb(AUDIO_SBUF_ADDR + audio_write, ((uint8_t*)ctl->buf.start)[i]); - audio_write = (audio_write + 1) % audio_sbuf_size; - outl(AUDIO_COUNT_ADDR, inl(AUDIO_COUNT_ADDR) + 1); + int cnt = ctl->buf.end - ctl->buf.start, i = 0; + while (cnt) { + // lock sbuf + outl(AUDIO_INIT_ADDR, 1 << 1); + for (; i < cnt; i++) { + if (inl(AUDIO_COUNT_ADDR) == audio_sbuf_size) { + i--; + break; + } else { + outb(AUDIO_SBUF_ADDR + audio_write, ((uint8_t*)ctl->buf.start)[i]); + audio_write = (audio_write + 1) % audio_sbuf_size; + outl(AUDIO_COUNT_ADDR, inl(AUDIO_COUNT_ADDR) + 1); + } } + // unlock sbuf + outl(AUDIO_INIT_ADDR, 0); } } diff --git a/nemu/src/device/audio.c b/nemu/src/device/audio.c index 64f5977..e4286a2 100644 --- a/nemu/src/device/audio.c +++ b/nemu/src/device/audio.c @@ -17,7 +17,7 @@ #include #include -#include +#include enum { reg_freq, @@ -32,12 +32,14 @@ enum { static uint8_t *sbuf = NULL; static uint32_t *audio_base = NULL; static uint32_t pos_read = 0; -static atomic_char32_t audio_count = 0; +static uint32_t audio_count = 0; +static mtx_t mtx_audio; #define MIN(a, b) ((a) < (b) ? (a) : (b)) static void audio_callback(void *userdata, uint8_t *stream, int len) { - uint32_t count = atomic_load(&audio_count); + mtx_lock(&mtx_audio); + uint32_t count = audio_count; uint32_t read_cnt = MIN(count, len); uint32_t to_end_cnt = CONFIG_SB_SIZE - pos_read; int32_t out_bound_cnt = read_cnt - to_end_cnt; @@ -52,10 +54,14 @@ static void audio_callback(void *userdata, uint8_t *stream, int len) { pos_read %= CONFIG_SB_SIZE; // if (len > read_cnt) memset(stream + read_cnt, 0, len - read_cnt); count -= read_cnt; - atomic_store(&audio_count, count); + audio_count = count; + mtx_unlock(&mtx_audio); } static inline void init_audio_dev() { + int ret = mtx_init(&mtx_audio, mtx_plain); + assert(ret == thrd_success); + SDL_AudioSpec s = {}; s.format = AUDIO_S16SYS; // 假设系统中音频数据的格式总是使用16位有符号数来表示 s.userdata = NULL; // 不使用 @@ -81,14 +87,19 @@ static void audio_io_handler(uint32_t offset, int len, bool is_write) { assert(is_write == false); break; case reg_init: - if (is_write && audio_base[reg_init] != 0) { - init_audio_dev(); + if (is_write) { + if (audio_base[reg_init] & 1) init_audio_dev(); + if (audio_base[reg_init] & 1 << 1) { + mtx_lock(&mtx_audio); + } else { + mtx_unlock(&mtx_audio); + } } break; case reg_count: // TODO: must be add a lock here - if (is_write) atomic_store(&audio_count, audio_base[reg_count]); - else audio_base[reg_count] = atomic_load(&audio_count); + if (is_write) audio_count = audio_base[reg_count]; + else audio_base[reg_count] = audio_count; break; default: assert(0);