修复部分syscall的BUG
This commit is contained in:
parent
37677878c0
commit
ab6763337a
|
@ -6,45 +6,32 @@ void print_info(){
|
||||||
|
|
||||||
struct sysinfo *info = get_sysinfo();
|
struct sysinfo *info = get_sysinfo();
|
||||||
|
|
||||||
printf(" .:=*#&&@@@@@@&&#+=:. \n"
|
printf(" .:=*#&&@@@@@@&&#+=:. \n");
|
||||||
" -+&@@@@@@@@@@@@@@@@@@@- ----------. -----------------\n"
|
printf(" -+&@@@@@@@@@@@@@@@@@@@- \03300C5CD;----------.\033C6C6C6; -----------------\n");
|
||||||
" -*@@@@@@@@@@@@@@@@@@@@&=.-&@@@@@@@@@@+ OSName: %s\n"
|
printf(" -*@@@@@@@@@@@@@@@@@@@@&=\03300C5CD;.-&@@@@@@@@@@+\033C6C6C6; OSName: %s\n",info->osname);
|
||||||
" =&@@@@@@@@@@@@@@@@@@@@@=.-&@@@@@@@@@@@@+ Kernel: %s\n"
|
printf(" =&@@@@@@@@@@@@@@@@@@@@@=\03300C5CD;.-&@@@@@@@@@@@@+\033C6C6C6; Kernel: %s\n",info->kenlname);
|
||||||
" -&@@@@@@@@@@@@@@@@@@@@@=.-&@@@@@@@@@@@@@@+ CPU Vendor: %s\n"
|
printf(" -&@@@@@@@@@@@@@@@@@@@@@=\03300C5CD;.-&@@@@@@@@@@@@@@+\033C6C6C6; CPU Vendor: %s\n",info->cpu_vendor);
|
||||||
" *@@@@@@@@@@@@@@@@@@@@@=.-&@@@@@@@@@@@@@@@@+ CPU: %s\n"
|
printf(" *@@@@@@@@@@@@@@@@@@@@@=\03300C5CD;.-&@@@@@@@@@@@@@@@@+\033C6C6C6; CPU: %s\n",info->cpu_name);
|
||||||
" .&@@@@@@@@@@@@@@@&*=-:: :#@@@@@@@@@@@@@@@@@@= Memory: %dMB\n"
|
printf(" .&@@@@@@@@@@@@@@@&*=-:: \03300C5CD;:#@@@@@@@@@@@@@@@@@@=\033C6C6C6; Memory: %dMB\n",info->phy_mem_size);
|
||||||
" &@@@@@@@@@@@@@&=. #@@@@@@@@@@@@@@@@@#:.= Console: CPOS_USER_SHELL\n"
|
printf(" &@@@@@@@@@@@@@&=. \03300C5CD;#@@@@@@@@@@@@@@@@@#:.\033C6C6C6;= Console: CPOS_USER_SHELL\n");
|
||||||
" *@@@@@@@@@@@@@- #@@@@@@@@@@@@@@@#:.=@@+ PCI Device: %d\n"
|
printf(" *@@@@@@@@@@@@@- \03300C5CD;#@@@@@@@@@@@@@@@#:.\033C6C6C6;=@@+ PCI Device: %d\n",info->pci_device);
|
||||||
":@@@@@@@@@@@@&. #@@@@@@@@@@@@@#: =@@@@@. Resolution: %d x %d\n"
|
printf(":@@@@@@@@@@@@&. \03300C5CD;#@@@@@@@@@@@@@#:\033C6C6C6; =@@@@@. Resolution: %d x %d\n",info->frame_width,info->frame_height);
|
||||||
"#@@@@@@@@@@@@. #@@@@@@@@@@@#: =@@@@@@@+ Time: %d/%d/%d %d:%d\n"
|
printf("#@@@@@@@@@@@@. \03300C5CD;#@@@@@@@@@@@#:\033C6C6C6; =@@@@@@@+ Time: %d/%d/%d %d:%d:%d\n",info->year,info->mon,
|
||||||
"@@@@@@@@@@@@+ *&&&&&&&&&#- =@@@@@@@@@&\n"
|
info->day,info->hour,info->min,info->sec);
|
||||||
"@@@@@@@@@@@@- :@@@@@@@@@@@@\n"
|
printf("@@@@@@@@@@@@+ \03300C5CD;*&&&&&&&&&#-\033C6C6C6; =@@@@@@@@@&\n");
|
||||||
"@@@@@@@@@@@@+ #@@@@@@@@@@@&\n"
|
printf("@@@@@@@@@@@@- :@@@@@@@@@@@@\n");
|
||||||
"*@@@@@@@@@@@@. :@@@@@@@@@@@@+\n"
|
printf("@@@@@@@@@@@@+ #@@@@@@@@@@@&\n");
|
||||||
":@@@@@@@@@@@@&. :@@@@@@@@@@@@@.\n"
|
printf("*@@@@@@@@@@@@. :@@@@@@@@@@@@+\n");
|
||||||
" *@@@@@@@@@@@@@= =@@@@@@@@@@@@@+ \n"
|
printf(":@@@@@@@@@@@@&. :@@@@@@@@@@@@@.\n");
|
||||||
" #@@@@@@@@@@@@@&+: :+@@@@@@@@@@@@@@# \n"
|
printf(" *@@@@@@@@@@@@@= =@@@@@@@@@@@@@+ \n");
|
||||||
" #@@@@@@@@@@@@@@@&*+=----=+#&@@@@@@@@@@@@@@@* \n"
|
printf(" #@@@@@@@@@@@@@&+: :+@@@@@@@@@@@@@@# \n");
|
||||||
" +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+ \n"
|
printf(" #@@@@@@@@@@@@@@@&*+=----=+#&@@@@@@@@@@@@@@@* \n");
|
||||||
" :&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#: \n"
|
printf(" +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+ \n");
|
||||||
" -#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#- \n"
|
printf(" :&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#: \n");
|
||||||
" :*@@@@@@@@@@@@@@@@@@@@@@@@@@@&+: \n"
|
printf(" -#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#- \n");
|
||||||
" :+#@@@@@@@@@@@@@@@@@@@@#+: \n"
|
printf(" :*@@@@@@@@@@@@@@@@@@@@@@@@@@@&+: \n");
|
||||||
" :=+*#&@@@@@@&#*+-: \n",
|
printf(" :+#@@@@@@@@@@@@@@@@@@@@#+: \n");
|
||||||
info->osname,
|
printf(" :=+*#&@@@@@@&#*+-: \n");
|
||||||
info->kenlname,
|
|
||||||
info->cpu_vendor,
|
|
||||||
info->cpu_name,
|
|
||||||
info->phy_mem_size,
|
|
||||||
info->pci_device,
|
|
||||||
info->frame_width,
|
|
||||||
info->frame_height,
|
|
||||||
info->year,
|
|
||||||
info->mon,
|
|
||||||
info->day,
|
|
||||||
info->hour,
|
|
||||||
info->min,
|
|
||||||
info->sec);
|
|
||||||
|
|
||||||
free_info(info);
|
free_info(info);
|
||||||
}
|
}
|
|
@ -70,7 +70,7 @@ int main(){
|
||||||
|
|
||||||
if (!strcmp("version", argv[0])){
|
if (!strcmp("version", argv[0])){
|
||||||
print_info();
|
print_info();
|
||||||
}if (!strcmp("system", argv[0])){
|
}else if (!strcmp("system", argv[0])){
|
||||||
exit(0);
|
exit(0);
|
||||||
}else if (!strcmp("help", argv[0]) || !strcmp("?", argv[0]) || !strcmp("h", argv[0])) {
|
}else if (!strcmp("help", argv[0]) || !strcmp("?", argv[0]) || !strcmp("h", argv[0])) {
|
||||||
printf("-=[CoolPotShell Helper]=-\n");
|
printf("-=[CoolPotShell Helper]=-\n");
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/*
|
||||||
#include "../include/sb16.h"
|
#include "../include/sb16.h"
|
||||||
#include "../include/io.h"
|
#include "../include/io.h"
|
||||||
#include "../include/printf.h"
|
#include "../include/printf.h"
|
||||||
|
@ -8,83 +9,108 @@
|
||||||
static void *const DMA_BUF_ADDR1 = (void *)0x90000; // 不能跨越 64K 边界
|
static void *const DMA_BUF_ADDR1 = (void *)0x90000; // 不能跨越 64K 边界
|
||||||
static void *const DMA_BUF_ADDR2 = (void *)0x90000 + DMA_BUF_SIZE; // 不能跨越 64K 边界
|
static void *const DMA_BUF_ADDR2 = (void *)0x90000 + DMA_BUF_SIZE; // 不能跨越 64K 边界
|
||||||
|
|
||||||
struct sb16 sb;
|
#define STAT_OFF 0 // 未开启
|
||||||
|
#define STAT_WAITING 1 // 等待第一个缓冲区
|
||||||
|
#define STAT_PAUSED 2 // 已暂停
|
||||||
|
#define STAT_PLAYING 3 // 正在播放音频
|
||||||
|
#define STAT_CLOSING 4 // 正在等待播放完毕并关闭
|
||||||
|
|
||||||
void sb_exch_dmaaddr() {
|
#if VSOUND_RWAPI
|
||||||
char *addr = sb.addr1;
|
static void sb_exch_dmaaddr() {
|
||||||
sb.addr1 = sb.addr2;
|
char *addr = sb.addr1;
|
||||||
sb.addr2 = addr;
|
sb.addr1 = sb.addr2;
|
||||||
size_t size = sb.size1;
|
sb.addr2 = addr;
|
||||||
sb.size1 = sb.size2;
|
size_t size = sb.size1;
|
||||||
sb.size2 = size;
|
sb.size1 = sb.size2;
|
||||||
|
sb.size2 = size;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void sb_out(uint8_t cmd) {
|
static void sb_send(uint8_t cmd) {
|
||||||
while (io_in8(SB_WRITE) & 128)
|
waitif(io_in8(SB_WRITE) & MASK(7));
|
||||||
;
|
|
||||||
io_out8(SB_WRITE, cmd);
|
io_out8(SB_WRITE, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sb16_do_dma() {
|
#if VSOUND_RWAPI
|
||||||
// 设置采样率
|
static void sb16_do_dma() {
|
||||||
sb_out(CMD_SOSR); // 44100 = 0xAC44
|
size_t dmasize;
|
||||||
sb_out((SAMPLE_RATE >> 8) & 0xFF); // 0xAC
|
size_t len;
|
||||||
sb_out(SAMPLE_RATE & 0xFF); // 0x44
|
if (sb.auto_mode) {
|
||||||
|
dmasize = 2 * DMA_BUF_SIZE;
|
||||||
|
len = sb.depth == 8 ? DMA_BUF_SIZE : DMA_BUF_SIZE / 2;
|
||||||
|
len = sb.channels == 2 ? len / 2 : len;
|
||||||
|
if (sb.status != STAT_WAITING) return;
|
||||||
|
} else {
|
||||||
|
dmasize = sb.size2;
|
||||||
|
len = sb.depth == 8 ? sb.size2 : sb.size2 / 2;
|
||||||
|
len = sb.channels == 2 ? len / 2 : len;
|
||||||
|
}
|
||||||
|
|
||||||
dma_xfer(sb.channel, (uint32_t)(sb.addr2), sb.size2, 0);
|
byte mode = (sb.auto_mode ? 16 : 0) | 0x48; // 0x48 为播放 0x44 为录音
|
||||||
if (sb.mode == MODE_MONO8) {
|
dma_start(mode, sb.dma_channel, sb.addr2, dmasize, sb.depth == 16);
|
||||||
sb_out(CMD_SINGLE_OUT8);
|
if (sb.auto_mode) {
|
||||||
sb_out(MODE_MONO8);
|
sb_send(sb.depth == 8 ? CMD_AUTO_OUT8 : CMD_AUTO_OUT16);
|
||||||
|
} else {
|
||||||
|
sb_send(sb.depth == 8 ? CMD_SINGLE_OUT8 : CMD_SINGLE_OUT16);
|
||||||
|
}
|
||||||
|
sb_send(sb.mode);
|
||||||
|
|
||||||
|
sb_send((len - 1) & 0xff);
|
||||||
|
sb_send(((len - 1) >> 8) & 0xff);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if VSOUND_RWAPI
|
||||||
|
static void sb16_send_buffer() {
|
||||||
|
if (sb.size1 == 0) return;
|
||||||
|
sb_exch_dmaaddr();
|
||||||
|
sb16_do_dma();
|
||||||
|
if (sb.status == STAT_WAITING) sb.status = STAT_PLAYING;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void sb16_do_close() {
|
||||||
|
if (sb.auto_mode) {
|
||||||
|
sb_send(sb.depth == 8 ? 0xD9 : 0xDA);
|
||||||
} else {
|
} else {
|
||||||
sb_out(CMD_SINGLE_OUT16);
|
sb_send(CMD_OFF);
|
||||||
sb_out(MODE_STEREO16);
|
|
||||||
}
|
}
|
||||||
|
sb.use_task = null;
|
||||||
sb_out((sb.size2 - 1) & 0xFF);
|
sb.status = STAT_OFF;
|
||||||
sb_out(((sb.size2 - 1) >> 8) & 0xFF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sb16_do_close() {
|
static vsound_t snd;
|
||||||
sb_out(CMD_OFF); // 关闭声卡
|
|
||||||
sb.use_task = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sb16_handler(registers_t *reg) {
|
void sb16_handler(registers_t *reg) {
|
||||||
io_in8(SB_INTR16);
|
|
||||||
uint8_t state = io_in8(SB_STATE);
|
|
||||||
|
|
||||||
io_cli();
|
io_in8(sb.depth == 16 ? SB_INTR16 : SB_STATE);
|
||||||
|
|
||||||
|
#if VSOUND_RWAPI
|
||||||
sb.size2 = 0;
|
sb.size2 = 0;
|
||||||
if (sb.size1 > 0) {
|
if (sb.size1 == 0) sb.status = STAT_WAITING;
|
||||||
sb_exch_dmaaddr();
|
sb16_send_buffer();
|
||||||
sb16_do_dma();
|
#else
|
||||||
}
|
vsound_played(snd);
|
||||||
io_cli();
|
#endif
|
||||||
|
|
||||||
if (sb.status > 0) {
|
if (sb.status == STAT_CLOSING) {
|
||||||
sb16_do_close();
|
sb16_do_close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void disable_sb16() {
|
void sb16_init() {
|
||||||
sb.addr1 = DMA_BUF_ADDR1;
|
|
||||||
sb.addr2 = DMA_BUF_ADDR2;
|
|
||||||
sb.mode = MODE_STEREO16;
|
|
||||||
sb.channel = 5;
|
|
||||||
sb.use_task = NULL;
|
sb.use_task = NULL;
|
||||||
sb.size1 = 0;
|
sb.status = STAT_OFF;
|
||||||
sb.size2 = 0;
|
register_interrupt_handler(SB16_IRQ + 0x20, sb16_handler);
|
||||||
sb.status = 0;
|
|
||||||
register_interrupt_handler(SB16_IRQ + 0x20, (uint32_t)sb16_handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sb_reset() {
|
static void sb_reset() {
|
||||||
io_out8(SB_RESET, 1);
|
io_out8(SB_RESET, 1);
|
||||||
sleep(10);
|
auto oldcnt = timerctl.count;
|
||||||
|
waitif(timerctl.count <= oldcnt + 10);
|
||||||
io_out8(SB_RESET, 0);
|
io_out8(SB_RESET, 0);
|
||||||
uint8_t state = io_in8(SB_READ);
|
uint8_t state = io_in8(SB_READ);
|
||||||
logkf("sb16 reset state 0x%x\n", state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sb_intr_irq() {
|
static void sb_intr_irq() {
|
||||||
|
@ -96,58 +122,159 @@ static void sb_intr_irq() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sb_turn(bool on) {
|
static void sb16_set_samplerate(uint16_t rate) {
|
||||||
if (on)
|
sb_send(CMD_SOSR);
|
||||||
sb_out(CMD_ON);
|
sb_send(rate >> 8);
|
||||||
else
|
sb_send(rate & 0xff);
|
||||||
sb_out(CMD_OFF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t sb_time_constant(uint8_t channels, uint16_t sample) {
|
static void sb16_set_volume(double volume) {
|
||||||
return 65536 - (256000000 / (channels * sample));
|
volume = max(0, min(volume, 1));
|
||||||
}
|
klogd("set sb16 volume to %d%%", (int)(volume * 100));
|
||||||
|
|
||||||
void sb16_set_volume(uint8_t level) {
|
|
||||||
logkf("set sb16 volume to %d/255\n", level);
|
|
||||||
io_out8(SB_MIXER, 0x22);
|
io_out8(SB_MIXER, 0x22);
|
||||||
io_out8(SB_MIXER_DATA, level);
|
io_out8(SB_MIXER_DATA, volume * 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sb16_open() {
|
extern bool is_vbox;
|
||||||
while (sb.use_task) {}
|
|
||||||
io_cli();
|
static int sb16_open(vsound_t vsound) {
|
||||||
|
uint16_t fmt = vsound->fmt;
|
||||||
|
uint16_t channels = vsound->channels;
|
||||||
|
uint32_t rate = vsound->rate;
|
||||||
|
double volume = vsound->volume;
|
||||||
|
|
||||||
sb.use_task = get_current();
|
sb.use_task = get_current();
|
||||||
io_sti();
|
|
||||||
sb_reset(); // 重置 DSP
|
|
||||||
sb_intr_irq(); // 设置中断
|
|
||||||
sb_out(CMD_ON); // 打开声卡
|
|
||||||
|
|
||||||
sb.mode = MODE_MONO8;
|
sb_reset(); // 重置 DSP
|
||||||
sb.channel = 1;
|
sb_intr_irq(); // 设置中断
|
||||||
sb.size1 = 0;
|
sb_send(CMD_ON); // 打开声卡
|
||||||
sb.size2 = 0;
|
|
||||||
sb.status = 0;
|
|
||||||
|
|
||||||
// sb.mode = MODE_STEREO16;
|
if (fmt == SOUND_FMT_S16 || fmt == SOUND_FMT_U16) {
|
||||||
// sb.channel = 5;
|
sb.depth = 16;
|
||||||
|
sb.dma_channel = 5;
|
||||||
|
} else if (fmt == SOUND_FMT_U8 || fmt == SOUND_FMT_S8) {
|
||||||
|
sb.depth = 8;
|
||||||
|
sb.dma_channel = 1;
|
||||||
|
}
|
||||||
|
if (channels == 1) {
|
||||||
|
sb.mode = (fmt == SOUND_FMT_S16 || fmt == SOUND_FMT_S8) ? MODE_SMONO : MODE_UMONO;
|
||||||
|
} else {
|
||||||
|
sb.mode = (fmt == SOUND_FMT_S16 || fmt == SOUND_FMT_S8) ? MODE_SSTEREO : MODE_USTEREO;
|
||||||
|
}
|
||||||
|
sb.status = STAT_WAITING;
|
||||||
|
#if VSOUND_RWAPI
|
||||||
|
sb.addr1 = DMA_BUF_ADDR1;
|
||||||
|
sb.addr2 = DMA_BUF_ADDR2;
|
||||||
|
sb.size1 = 0;
|
||||||
|
sb.size2 = 0;
|
||||||
|
#endif
|
||||||
|
sb.channels = channels;
|
||||||
|
sb.auto_mode = is_vbox ? true : false;
|
||||||
|
|
||||||
|
sb16_set_samplerate(rate);
|
||||||
|
sb16_set_volume(volume);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sb16_close() {
|
static void sb16_close(vsound_t vsound) {
|
||||||
sb.status = 1;
|
if (sb.status == STAT_PLAYING) {
|
||||||
if (sb.size2 > 0) return;
|
sb.status = STAT_CLOSING;
|
||||||
sb16_do_close();
|
} else {
|
||||||
|
sb16_do_close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int sb16_write(char *data, size_t size) {
|
#if VSOUND_RWAPI
|
||||||
while (sb.size1) {}
|
static int sb16_write(vsound_t vsound, const void *data, size_t len) {
|
||||||
|
size_t size = len * vsound->settings.bytes_per_sample;
|
||||||
memcpy(sb.addr1, data, size);
|
while (size > 0) {
|
||||||
sb.size1 = size;
|
waitif(sb.size1 == DMA_BUF_SIZE);
|
||||||
|
asm_cli;
|
||||||
if (sb.size2 > 0) return size;
|
size_t nwrite = min(size, DMA_BUF_SIZE - sb.size1);
|
||||||
|
memcpy(sb.addr1 + sb.size1, data, nwrite);
|
||||||
sb_exch_dmaaddr();
|
sb.size1 += nwrite;
|
||||||
sb16_do_dma();
|
data += nwrite;
|
||||||
|
size -= nwrite;
|
||||||
return size;
|
asm_sti;
|
||||||
|
if (sb.auto_mode) {
|
||||||
|
if (sb.status == STAT_WAITING && sb.size1 == DMA_BUF_SIZE) sb16_send_buffer();
|
||||||
|
} else {
|
||||||
|
if (sb.status == STAT_WAITING) sb16_send_buffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !VSOUND_RWAPI
|
||||||
|
static int sb16_start_dma(vsound_t vsound, void *addr) {
|
||||||
|
size_t dmasize;
|
||||||
|
size_t len;
|
||||||
|
if (sb.auto_mode) {
|
||||||
|
dmasize = 2 * DMA_BUF_SIZE;
|
||||||
|
len = DMA_BUF_SIZE / vsound->bytes_per_sample;
|
||||||
|
if (sb.status != STAT_WAITING) return 0;
|
||||||
|
} else {
|
||||||
|
dmasize = DMA_BUF_SIZE;
|
||||||
|
len = DMA_BUF_SIZE / vsound->bytes_per_sample;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte mode = (sb.auto_mode ? 16 : 0) | 0x48; // 0x48 为播放 0x44 为录音
|
||||||
|
dma_start(mode, sb.dma_channel, addr, dmasize, sb.depth == 16);
|
||||||
|
if (sb.auto_mode) {
|
||||||
|
sb_send(sb.depth == 8 ? CMD_AUTO_OUT8 : CMD_AUTO_OUT16);
|
||||||
|
} else {
|
||||||
|
sb_send(sb.depth == 8 ? CMD_SINGLE_OUT8 : CMD_SINGLE_OUT16);
|
||||||
|
}
|
||||||
|
sb_send(sb.mode);
|
||||||
|
|
||||||
|
sb_send((len - 1) & 0xff);
|
||||||
|
sb_send(((len - 1) >> 8) & 0xff);
|
||||||
|
|
||||||
|
if (sb.status == STAT_WAITING) sb.status = STAT_PLAYING;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct vsound vsound = {
|
||||||
|
.is_output = true,
|
||||||
|
#if VSOUND_RWAPI
|
||||||
|
.is_rwmode = true,
|
||||||
|
#endif
|
||||||
|
.name = "sb16",
|
||||||
|
.open = sb16_open,
|
||||||
|
.close = sb16_close,
|
||||||
|
#if VSOUND_RWAPI
|
||||||
|
.write = sb16_write,
|
||||||
|
#else
|
||||||
|
.start_dma = sb16_start_dma,
|
||||||
|
.bufsize = DMA_BUF_SIZE,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static const i16 fmts[] = {
|
||||||
|
SOUND_FMT_S8, SOUND_FMT_U8, SOUND_FMT_S16, SOUND_FMT_U16, -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const i32 rates[] = {
|
||||||
|
8000, 11025, 16000, 22050, 24000, 32000, 44100, 47250, 48000, 50000, -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
void sb16_regist() {
|
||||||
|
snd = &vsound;
|
||||||
|
if (!vsound_regist(snd)) {
|
||||||
|
klogw("注册 sb16 失败");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vsound_set_supported_fmts(snd, fmts, -1);
|
||||||
|
vsound_set_supported_rates(snd, rates, -1);
|
||||||
|
vsound_set_supported_ch(snd, 1);
|
||||||
|
vsound_set_supported_ch(snd, 2);
|
||||||
|
#if !VSOUND_RWAPI
|
||||||
|
vsound_addbuf(snd, DMA_BUF_ADDR1);
|
||||||
|
vsound_addbuf(snd, DMA_BUF_ADDR2);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
|
@ -31,53 +31,35 @@
|
||||||
#define CMD_RP16 0xD6 // Resume playback of 16 bit channel
|
#define CMD_RP16 0xD6 // Resume playback of 16 bit channel
|
||||||
#define CMD_VERSION 0xE1 // Turn speaker off
|
#define CMD_VERSION 0xE1 // Turn speaker off
|
||||||
|
|
||||||
#define MODE_MONO8 0x00
|
#define MODE_SMONO (0b01 << 4)
|
||||||
#define MODE_STEREO8 0x20
|
#define MODE_SSTEREO (0b11 << 4)
|
||||||
#define MODE_MONO16 0x10
|
#define MODE_UMONO (0b00 << 4)
|
||||||
#define MODE_STEREO16 0x30
|
#define MODE_USTEREO (0b10 << 4)
|
||||||
|
|
||||||
#define STATUS_READ 0x80 // read buffer status
|
#define STATUS_READ 0x80 // read buffer status
|
||||||
#define STATUS_WRITE 0x80 // write buffer status
|
#define STATUS_WRITE 0x80 // write buffer status
|
||||||
|
|
||||||
#define DMA_BUF_SIZE 0x8000 // 缓冲区长度
|
#define DMA_BUF_SIZE 4096 // 缓冲区长度
|
||||||
#define SAMPLE_RATE 44100 // 采样率
|
#define SB16_IRQ 5
|
||||||
#define SB16_IRQ 5
|
|
||||||
|
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "isr.h"
|
#include "isr.h"
|
||||||
|
|
||||||
struct WAV16_HEADER {
|
static struct {
|
||||||
char riff[4];
|
struct task_struct *use_task; //
|
||||||
int size;
|
int status; //
|
||||||
char wave[4];
|
bool auto_mode; //
|
||||||
char fmt[4];
|
#if VSOUND_RWAPI
|
||||||
int fmt_size;
|
void *volatile addr1; // DMA 地址
|
||||||
short format;
|
volatile size_t size1; //
|
||||||
short channel;
|
void *volatile addr2; // DMA 地址
|
||||||
int sample_rate;
|
volatile size_t size2; //
|
||||||
int byte_per_sec;
|
#endif
|
||||||
} __attribute__((packed));
|
uint8_t mode; // 模式
|
||||||
|
uint8_t dma_channel; // DMA 通道
|
||||||
struct sb16 {
|
uint8_t depth; // 采样深度
|
||||||
struct task_struct *use_task;
|
int channels; // 声道数
|
||||||
int status;
|
} sb;
|
||||||
char *addr1; // DMA 地址
|
|
||||||
volatile size_t size1; //
|
|
||||||
char *addr2; // DMA 地址
|
|
||||||
volatile size_t size2; //
|
|
||||||
uint8_t mode; // 模式
|
|
||||||
uint8_t channel; // DMA 通道
|
|
||||||
};
|
|
||||||
|
|
||||||
void sb16_handler(registers_t *reg);
|
|
||||||
void sb_exch_dmaaddr();
|
|
||||||
void sb16_do_dma();
|
|
||||||
void sb16_do_close();
|
|
||||||
void disable_sb16();
|
|
||||||
void sb16_close();
|
|
||||||
int sb16_write(char *data, size_t size);
|
|
||||||
void sb16_open();
|
|
||||||
void sb16_set_volume(uint8_t level);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -73,6 +73,7 @@ int check_task(int *pid){
|
||||||
}
|
}
|
||||||
|
|
||||||
int check_task_usershell(int *pid){
|
int check_task_usershell(int *pid){
|
||||||
|
while (1) asm("hlt");
|
||||||
struct task_struct *shell = found_task_pid(*pid);
|
struct task_struct *shell = found_task_pid(*pid);
|
||||||
while (1){
|
while (1){
|
||||||
if(shell->state == TASK_DEATH){
|
if(shell->state == TASK_DEATH){
|
||||||
|
@ -153,7 +154,6 @@ void kernel_main(multiboot_t *multiboot) {
|
||||||
}
|
}
|
||||||
init_eh();
|
init_eh();
|
||||||
klogf(true,"Kernel load done!\n");
|
klogf(true,"Kernel load done!\n");
|
||||||
kernel_thread(sound_test,NULL,"Sound");
|
|
||||||
|
|
||||||
io_sti();
|
io_sti();
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@ static char syscall_getch(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,ui
|
||||||
|
|
||||||
static void syscall_exit(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,uint32_t edi){
|
static void syscall_exit(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,uint32_t edi){
|
||||||
task_kill(get_current()->pid);
|
task_kill(get_current()->pid);
|
||||||
//printf("PID[%d] exit code: %d",get_current()->pid,ebx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* syscall_malloc(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,uint32_t edi){
|
static void* syscall_malloc(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,uint32_t edi){
|
||||||
|
@ -84,13 +83,13 @@ struct sysinfo{
|
||||||
static void* syscall_sysinfo(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,uint32_t edi){
|
static void* syscall_sysinfo(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,uint32_t edi){
|
||||||
struct sysinfo *info = (struct sysinfo *) user_alloc(get_current(), sizeof(struct sysinfo));
|
struct sysinfo *info = (struct sysinfo *) user_alloc(get_current(), sizeof(struct sysinfo));
|
||||||
cpu_t *cpu = get_cpuid();
|
cpu_t *cpu = get_cpuid();
|
||||||
char *os_name = user_alloc(get_current(), strlen(OS_NAME));
|
char *os_name = (char *)user_alloc(get_current(), strlen(OS_NAME));
|
||||||
char *kernel = user_alloc(get_current(), strlen(OS_NAME));
|
char *kernel = (char *)user_alloc(get_current(), strlen(KERNEL_NAME));
|
||||||
char *cpu_vendor = user_alloc(get_current(), strlen(cpu->vendor));
|
|
||||||
char *cpu_name = user_alloc(get_current(), strlen(cpu->model_name));
|
|
||||||
|
|
||||||
memcpy(os_name,OS_NAME, 40);
|
char *cpu_vendor = (char *)user_alloc(get_current(), strlen(cpu->vendor));
|
||||||
memcpy(kernel,KERNEL_NAME, 40);
|
char *cpu_name = (char *)user_alloc(get_current(), strlen(cpu->model_name));
|
||||||
|
memcpy(os_name,OS_NAME, strlen(OS_NAME));
|
||||||
|
memcpy(kernel,KERNEL_NAME, strlen(KERNEL_NAME));
|
||||||
memcpy(cpu_vendor,cpu->vendor, strlen(cpu->vendor));
|
memcpy(cpu_vendor,cpu->vendor, strlen(cpu->vendor));
|
||||||
memcpy(cpu_name,cpu->model_name, strlen(cpu->model_name));
|
memcpy(cpu_name,cpu->model_name, strlen(cpu->model_name));
|
||||||
|
|
||||||
|
@ -111,6 +110,8 @@ static void* syscall_sysinfo(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi
|
||||||
info->min = get_min();
|
info->min = get_min();
|
||||||
info->sec = get_sec();
|
info->sec = get_sec();
|
||||||
|
|
||||||
|
kfree(cpu);
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,6 +133,7 @@ void *sycall_handlers[MAX_SYSCALLS] = {
|
||||||
typedef size_t (*syscall_t)(size_t, size_t, size_t, size_t, size_t);
|
typedef size_t (*syscall_t)(size_t, size_t, size_t, size_t, size_t);
|
||||||
|
|
||||||
size_t syscall() {
|
size_t syscall() {
|
||||||
|
io_cli();
|
||||||
volatile size_t eax, ebx, ecx, edx, esi, edi;
|
volatile size_t eax, ebx, ecx, edx, esi, edi;
|
||||||
asm("mov %%eax, %0\n\t" : "=r"(eax));
|
asm("mov %%eax, %0\n\t" : "=r"(eax));
|
||||||
asm("mov %%ebx, %0\n\t" : "=r"(ebx));
|
asm("mov %%ebx, %0\n\t" : "=r"(ebx));
|
||||||
|
|
|
@ -66,20 +66,6 @@ static uint8_t gen(int t) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void sound_test() {
|
void sound_test() {
|
||||||
logk("sound test has been started\n");
|
|
||||||
F = g(0);
|
|
||||||
G = g(T);
|
|
||||||
const int total = T + ((128 - F) + (128 - G)) * K;
|
|
||||||
sb16_open();
|
|
||||||
sb16_set_volume(128);
|
|
||||||
uint8_t *buffer = kmalloc(buffer_len);
|
|
||||||
for (int offset = 0;; offset++) {
|
|
||||||
if (offset * buffer_len >= total) break;
|
|
||||||
for (int i = 0; i < buffer_len; i++)
|
|
||||||
buffer[i] = gen(i + offset * buffer_len);
|
|
||||||
sb16_write(buffer, buffer_len);
|
|
||||||
}
|
|
||||||
sb16_close();
|
|
||||||
kfree(buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue