summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2024-12-02 18:42:26 +0100
committerAnton Kling <anton@kling.gg>2024-12-02 18:42:26 +0100
commitd72629680450d0160e0a84d580a83119fe51338b (patch)
tree965ea7d602ffb08c5b5e42dc5ab78092accde60d /kernel
parent7d67bd2d9e690a662c1c8b51b245e83f2c6c5c74 (diff)
ac97: Messy fixes to audio
It seems to work completely now, but it is still very messy.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/drivers/ac97.c92
1 files changed, 39 insertions, 53 deletions
diff --git a/kernel/drivers/ac97.c b/kernel/drivers/ac97.c
index 6554fdb..acc6dcb 100644
--- a/kernel/drivers/ac97.c
+++ b/kernel/drivers/ac97.c
@@ -43,7 +43,7 @@ void add_buffer(void) {
pointer += 2;
*pointer = 128000 / 2;
pointer++;
- *pointer = (1 << 14);
+ *pointer = 0;
pointer++;
}
}
@@ -78,76 +78,62 @@ void start(void) {
}
int ac97_can_write(void) {
- u8 process_num = inb(nabm.address + 0x10 + 0x4);
- if (!buffers[entry].has_played) {
- if (31 == process_num) {
- outb(nabm.address + 0x10 + 0x5, entry);
- buffers[31].has_played = 1;
- }
- for (int i = 0; i < process_num; i++) {
- buffers[i].has_played = 1;
+ u8 read_ptr = inb(nabm.address + 0x10 + 0x4);
+
+ u8 buffer_left;
+ if (entry >= read_ptr) {
+ buffer_left = 32 - entry;
+ if (0 == read_ptr && buffer_left > 0) {
+ buffer_left--;
}
+ } else {
+ buffer_left = read_ptr - entry - 1;
}
- u8 delta = abs((int)process_num - (int)entry);
- if (delta > 3) {
- return 0;
- }
- return buffers[entry].has_played;
+
+ return (buffer_left > 0);
}
static int write_buffer(u8 *buffer, size_t size) {
- u8 process_num = inb(nabm.address + 0x10 + 0x4);
- if (!buffers[entry].has_played && 128000 == buffers[entry].data_written) {
- if (31 == process_num) {
- outb(nabm.address + 0x10 + 0x5, entry);
- buffers[31].has_played = 1;
- }
- for (int i = 0; i < process_num; i++) {
- buffers[i].has_played = 1;
- }
- if (!buffers[entry].has_played) {
- return 0;
+ assert(size <= 128000);
+ u8 read_ptr = inb(nabm.address + 0x10 + 0x4);
+
+ u8 buffer_left;
+ if (entry >= read_ptr) {
+ buffer_left = 32 - entry;
+ if (0 == read_ptr && buffer_left > 0) {
+ buffer_left--;
}
+ } else {
+ buffer_left = read_ptr - entry - 1;
}
- u8 delta = abs((int)process_num - (int)entry);
- if (delta > 3) {
+ if (0 == buffer_left) {
return 0;
}
- size_t offset = buffers[entry].data_written;
- memset((u8 *)buffers[entry].data + offset, 0, 128000 - offset);
- size_t wl = min(size, 128000 - offset);
- memcpy((u8 *)buffers[entry].data + offset, buffer, wl);
- buffers[entry].data_written += wl;
- buffers[entry].has_played = 0;
-
- if (128000 == buffers[entry].data_written) {
- u8 current_valid = inb(nabm.address + 0x10 + 0x5);
- if (current_valid <= entry) {
- outb(nabm.address + 0x10 + 0x5, entry);
- }
- entry++;
- if (entry > 31) {
- entry = 0;
- }
- }
+ memset((u8 *)buffers[entry].data, 0, 128000);
+ memcpy((u8 *)buffers[entry].data, buffer, size);
+ outb(nabm.address + 0x10 + 0x5, entry);
+ entry = (entry + 1) % 32;
start();
return 1;
}
+char tmp_buffer[128000];
+size_t tmp_buffer_count = 0;
int ac97_add_pcm(u8 *buffer, size_t len) {
- size_t rc = 0;
- for (; len > 0;) {
- size_t wl = min(len, 128000);
- if (!write_buffer(buffer + rc, wl)) {
- break;
- }
- rc += wl;
- len -= wl;
+ size_t wl = min(len, 128000 - tmp_buffer_count);
+ memcpy(tmp_buffer + tmp_buffer_count, buffer, wl);
+ tmp_buffer_count += wl;
+ if (tmp_buffer_count < 128000) {
+ return wl;
+ }
+ if (!write_buffer(tmp_buffer, 128000)) {
+ return wl;
}
- return rc;
+ tmp_buffer_count = 0;
+ return wl;
}
void ac97_init(void) {