Chatgpt wrote a crappy beeper
This commit is contained in:
parent
4a446c2d51
commit
554f16cc7d
6
Makefile
6
Makefile
@ -44,7 +44,9 @@ OBJECTS = ./kernel/kstart.o ./kernel.o ./console.o ./drivers/vga.o ./drivers/uar
|
|||||||
./fs/fs.o ./drivers/ata.o ./lib/string.o ./proc.o ./drivers/pit.o ./kernel/vm.o
|
./fs/fs.o ./drivers/ata.o ./lib/string.o ./proc.o ./drivers/pit.o ./kernel/vm.o
|
||||||
|
|
||||||
run: image.bin
|
run: image.bin
|
||||||
qemu-system-i386 -drive format=raw,file=$< -serial mon:stdio -qmp unix:qemu-monitor-socket,server,nowait
|
qemu-system-i386 -drive format=raw,file=$< -serial mon:stdio -qmp unix:qemu-monitor-socket,server,nowait \
|
||||||
|
-audiodev pa,id=SAUND \
|
||||||
|
-machine pcspk-audiodev=SAUND
|
||||||
|
|
||||||
run-nox: image.bin
|
run-nox: image.bin
|
||||||
qemu-system-i386 -nographic -drive format=raw,file=$< -serial mon:stdio -qmp unix:qemu-monitor-socket,server,nowait
|
qemu-system-i386 -nographic -drive format=raw,file=$< -serial mon:stdio -qmp unix:qemu-monitor-socket,server,nowait
|
||||||
@ -106,7 +108,7 @@ debug-nox: image.bin
|
|||||||
-ex "break _start" \
|
-ex "break _start" \
|
||||||
-ex "continue"
|
-ex "continue"
|
||||||
|
|
||||||
USERPROGS=./user/false ./user/greet ./user/div0 ./user/shout ./user/badputs ./user/bss ./user/snake
|
USERPROGS=./user/false ./user/greet ./user/div0 ./user/shout ./user/badputs ./user/bss ./user/snake ./user/player
|
||||||
|
|
||||||
fs.img: ./kernel.bin ./tools/mkfs $(USERPROGS)
|
fs.img: ./kernel.bin ./tools/mkfs $(USERPROGS)
|
||||||
./tools/mkfs $@ $< $(USERPROGS)
|
./tools/mkfs $@ $< $(USERPROGS)
|
||||||
|
|||||||
@ -299,6 +299,13 @@ static void handle_syscall(registers_t* r) {
|
|||||||
case SYS_getc:
|
case SYS_getc:
|
||||||
r->eax = handle_getc();
|
r->eax = handle_getc();
|
||||||
break;
|
break;
|
||||||
|
case SYS_set_beep:
|
||||||
|
if (r->ebx > MAX_BEEP_FREQUENCY_HZ) {
|
||||||
|
userspace_panic("Userspace panic: beep frequency out of range\n");
|
||||||
|
}
|
||||||
|
set_beep_frequency_hz(r->ebx);
|
||||||
|
r->eax = 0;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
userspace_panic("Userspace panic: Unknown syscall\n");
|
userspace_panic("Userspace panic: Unknown syscall\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,6 +23,11 @@ enum {
|
|||||||
PIT_MODES_SQUARE_WAVE_GENERATOR = 0x3,
|
PIT_MODES_SQUARE_WAVE_GENERATOR = 0x3,
|
||||||
PIT_MODES_SW_TRIGGERRED_STROBE = 0x4,
|
PIT_MODES_SW_TRIGGERRED_STROBE = 0x4,
|
||||||
PIT_MODES_HW_TRIGGERRED_STROBE = 0x5,
|
PIT_MODES_HW_TRIGGERRED_STROBE = 0x5,
|
||||||
|
|
||||||
|
PIT_COMMAND_PORT = 0x43,
|
||||||
|
PIT_CHANNEL0_DATA_PORT = 0x40,
|
||||||
|
PIT_CHANNEL2_DATA_PORT = 0x42,
|
||||||
|
PC_SPEAKER_PORT = 0x61,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -30,6 +35,7 @@ enum {
|
|||||||
static timer_callback callbacks[100];
|
static timer_callback callbacks[100];
|
||||||
static int registered_callbacks = 0;
|
static int registered_callbacks = 0;
|
||||||
static volatile uint32_t uptime_ms = 0;
|
static volatile uint32_t uptime_ms = 0;
|
||||||
|
static volatile uint32_t speaker_frequency_hz = 0;
|
||||||
|
|
||||||
void add_timer_callback(timer_callback tc) {
|
void add_timer_callback(timer_callback tc) {
|
||||||
callbacks[registered_callbacks++] = tc;
|
callbacks[registered_callbacks++] = tc;
|
||||||
@ -57,9 +63,9 @@ void init_pit() {
|
|||||||
.operating_mode = PIT_MODES_SQUARE_WAVE_GENERATOR,
|
.operating_mode = PIT_MODES_SQUARE_WAVE_GENERATOR,
|
||||||
.bcd = 0,
|
.bcd = 0,
|
||||||
};
|
};
|
||||||
port_byte_out(0x43, *(unsigned char *)(&cmd));
|
port_byte_out(PIT_COMMAND_PORT, *(unsigned char *)(&cmd));
|
||||||
port_byte_out(0x40, PIT_PROGRAM_REG & 0xff);
|
port_byte_out(PIT_CHANNEL0_DATA_PORT, PIT_PROGRAM_REG & 0xff);
|
||||||
port_byte_out(0x40, (PIT_PROGRAM_REG & 0xff00) >> 8);
|
port_byte_out(PIT_CHANNEL0_DATA_PORT, (PIT_PROGRAM_REG & 0xff00) >> 8);
|
||||||
|
|
||||||
register_interrupt_handler(IRQ0, timer_interrupt_handler);
|
register_interrupt_handler(IRQ0, timer_interrupt_handler);
|
||||||
add_timer_callback(timer_int_callback);
|
add_timer_callback(timer_int_callback);
|
||||||
@ -76,6 +82,45 @@ uint32_t get_uptime_ms(void) {
|
|||||||
return uptime_ms;
|
return uptime_ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_beep_frequency_hz(uint32_t frequency_hz) {
|
||||||
|
if (frequency_hz == 0) {
|
||||||
|
disable_beep();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t divisor = PIT_CRYSTAL_HZ / frequency_hz;
|
||||||
|
if (divisor == 0) {
|
||||||
|
divisor = 1;
|
||||||
|
}
|
||||||
|
if (divisor > 0xffff) {
|
||||||
|
divisor = 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pit_command_t cmd = {
|
||||||
|
.select_channel = PIT_SELECT_CHANNEL2,
|
||||||
|
.access_mode = PIT_ACCESS_MODE_LOHIBYTE,
|
||||||
|
.operating_mode = PIT_MODES_SQUARE_WAVE_GENERATOR,
|
||||||
|
.bcd = 0,
|
||||||
|
};
|
||||||
|
port_byte_out(PIT_COMMAND_PORT, *(unsigned char *)(&cmd));
|
||||||
|
port_byte_out(PIT_CHANNEL2_DATA_PORT, divisor & 0xff);
|
||||||
|
port_byte_out(PIT_CHANNEL2_DATA_PORT, (divisor & 0xff00) >> 8);
|
||||||
|
|
||||||
|
uint8_t speaker = port_byte_in(PC_SPEAKER_PORT);
|
||||||
|
port_byte_out(PC_SPEAKER_PORT, speaker | 0x03);
|
||||||
|
speaker_frequency_hz = frequency_hz;
|
||||||
|
}
|
||||||
|
|
||||||
|
void disable_beep(void) {
|
||||||
|
uint8_t speaker = port_byte_in(PC_SPEAKER_PORT);
|
||||||
|
port_byte_out(PC_SPEAKER_PORT, speaker & 0xfc);
|
||||||
|
speaker_frequency_hz = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t get_beep_frequency_hz(void) {
|
||||||
|
return speaker_frequency_hz;
|
||||||
|
}
|
||||||
|
|
||||||
void msleep(int ms) {
|
void msleep(int ms) {
|
||||||
sleep_counter = ms / 10;
|
sleep_counter = ms / 10;
|
||||||
while (sleep_counter > 0) {
|
while (sleep_counter > 0) {
|
||||||
|
|||||||
@ -2,10 +2,15 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define MAX_BEEP_FREQUENCY_HZ 44100u
|
||||||
|
|
||||||
typedef void (*timer_callback)(void);
|
typedef void (*timer_callback)(void);
|
||||||
|
|
||||||
void init_pit(void);
|
void init_pit(void);
|
||||||
void add_timer_callback(timer_callback tc);
|
void add_timer_callback(timer_callback tc);
|
||||||
|
|
||||||
uint32_t get_uptime_ms(void);
|
uint32_t get_uptime_ms(void);
|
||||||
|
void set_beep_frequency_hz(uint32_t frequency_hz);
|
||||||
|
void disable_beep(void);
|
||||||
|
uint32_t get_beep_frequency_hz(void);
|
||||||
void msleep(int ms);
|
void msleep(int ms);
|
||||||
|
|||||||
2
proc.c
2
proc.c
@ -1,4 +1,5 @@
|
|||||||
#include "proc.h"
|
#include "proc.h"
|
||||||
|
#include "drivers/pit.h"
|
||||||
#include "drivers/vga.h"
|
#include "drivers/vga.h"
|
||||||
|
|
||||||
struct context {
|
struct context {
|
||||||
@ -88,6 +89,7 @@ void run_elf(const char* name) {
|
|||||||
|
|
||||||
_Noreturn void killproc() {
|
_Noreturn void killproc() {
|
||||||
void* task_stack;
|
void* task_stack;
|
||||||
|
disable_beep();
|
||||||
if (!vga_is_text_mode()) {
|
if (!vga_is_text_mode()) {
|
||||||
switch_to_text_mode();
|
switch_to_text_mode();
|
||||||
vga_clear_screen();
|
vga_clear_screen();
|
||||||
|
|||||||
@ -14,6 +14,7 @@ enum {
|
|||||||
SYS_time_ms = 7,
|
SYS_time_ms = 7,
|
||||||
SYS_halt = 8,
|
SYS_halt = 8,
|
||||||
SYS_getc = 9,
|
SYS_getc = 9,
|
||||||
|
SYS_set_beep = 10,
|
||||||
};
|
};
|
||||||
|
|
||||||
int syscall(int call, uintptr_t arg);
|
int syscall(int call, uintptr_t arg);
|
||||||
|
|||||||
24
user/player.c
Normal file
24
user/player.c
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#include "../syscall.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
static uint32_t time_ms(void) {
|
||||||
|
return (uint32_t)syscall(SYS_time_ms, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wait_ms(uint32_t duration_ms) {
|
||||||
|
uint32_t start = time_ms();
|
||||||
|
while ((uint32_t)(time_ms() - start) < duration_ms) {
|
||||||
|
syscall(SYS_halt, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
syscall(SYS_set_beep, 10000);
|
||||||
|
wait_ms(1000);
|
||||||
|
|
||||||
|
syscall(SYS_set_beep, 15000);
|
||||||
|
wait_ms(1000);
|
||||||
|
|
||||||
|
// syscall(SYS_set_beep, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user