diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-05-15 21:40:41 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-05-15 21:40:41 +0200 |
commit | 3cba2a8a7872794516488ac5dfe240e946b1288d (patch) | |
tree | abf359c90dbee15228f34669c7d5613d111e77f0 | |
parent | dcf490ecab4fea2eb2cb80508ae68d77c328739d (diff) | |
download | serenity-3cba2a8a7872794516488ac5dfe240e946b1288d.zip |
Kernel: Add a beep() syscall that beeps the PC speaker.
Hook this up in Terminal so that the '\a' character generates a beep.
Finally emit an '\a' character in the shell line editing code when
backspacing at the start of the line.
-rw-r--r-- | Applications/Terminal/Terminal.cpp | 2 | ||||
-rw-r--r-- | Kernel/Devices/PCSpeaker.cpp | 20 | ||||
-rw-r--r-- | Kernel/Devices/PCSpeaker.h | 7 | ||||
-rw-r--r-- | Kernel/Makefile | 1 | ||||
-rw-r--r-- | Kernel/Scheduler.cpp | 13 | ||||
-rw-r--r-- | Kernel/Scheduler.h | 1 | ||||
-rw-r--r-- | Kernel/Syscall.cpp | 3 | ||||
-rw-r--r-- | Kernel/Syscall.h | 1 | ||||
-rw-r--r-- | Kernel/i8253.cpp | 20 | ||||
-rw-r--r-- | Kernel/i8253.h | 19 | ||||
-rwxr-xr-x | Kernel/run | 9 | ||||
-rw-r--r-- | LibC/unistd.cpp | 5 | ||||
-rw-r--r-- | LibC/unistd.h | 1 | ||||
-rw-r--r-- | Shell/LineEditor.cpp | 5 |
14 files changed, 82 insertions, 25 deletions
diff --git a/Applications/Terminal/Terminal.cpp b/Applications/Terminal/Terminal.cpp index 6604c4b8e3..bd252abce3 100644 --- a/Applications/Terminal/Terminal.cpp +++ b/Applications/Terminal/Terminal.cpp @@ -576,7 +576,7 @@ void Terminal::on_char(byte ch) } return; case '\a': - // FIXME: Bell! + beep(); return; case '\t': { for (unsigned i = m_cursor_column; i < columns(); ++i) { diff --git a/Kernel/Devices/PCSpeaker.cpp b/Kernel/Devices/PCSpeaker.cpp new file mode 100644 index 0000000000..347dd33b62 --- /dev/null +++ b/Kernel/Devices/PCSpeaker.cpp @@ -0,0 +1,20 @@ +#include <Kernel/Devices/PCSpeaker.h> +#include <Kernel/i8253.h> +#include <Kernel/IO.h> +#include <Kernel/i386.h> + +void PCSpeaker::tone_on(int frequency) +{ + IO::out8(PIT_CTL, TIMER2_SELECT | WRITE_WORD | MODE_SQUARE_WAVE); + word timer_reload = BASE_FREQUENCY / frequency; + + IO::out8(TIMER2_CTL, LSB(timer_reload)); + IO::out8(TIMER2_CTL, MSB(timer_reload)); + + IO::out8(0x61, IO::in8(0x61) | 3); +} + +void PCSpeaker::tone_off() +{ + IO::out8(0x61, IO::in8(0x61) & ~3); +} diff --git a/Kernel/Devices/PCSpeaker.h b/Kernel/Devices/PCSpeaker.h new file mode 100644 index 0000000000..9791feb94e --- /dev/null +++ b/Kernel/Devices/PCSpeaker.h @@ -0,0 +1,7 @@ +#pragma once + +class PCSpeaker { +public: + static void tone_on(int frequency); + static void tone_off(); +}; diff --git a/Kernel/Makefile b/Kernel/Makefile index af0321c651..1e721dbe17 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -49,6 +49,7 @@ KERNEL_OBJS = \ Net/Routing.o \ Net/NetworkTask.o \ ProcessTracer.o \ + Devices/PCSpeaker.o \ File.o VFS_OBJS = \ diff --git a/Kernel/Scheduler.cpp b/Kernel/Scheduler.cpp index 3ee614533b..356a009b63 100644 --- a/Kernel/Scheduler.cpp +++ b/Kernel/Scheduler.cpp @@ -5,6 +5,7 @@ #include <AK/TemporaryChange.h> #include <Kernel/Alarm.h> #include <Kernel/FileSystem/FileDescriptor.h> +#include <Kernel/Devices/PCSpeaker.h> //#define LOG_EVERY_CONTEXT_SWITCH //#define SCHEDULER_DEBUG @@ -30,6 +31,7 @@ Thread* g_last_fpu_thread; Thread* g_finalizer; static Process* s_colonel_process; qword g_uptime; +static qword s_beep_timeout; struct TaskRedirectionData { word selector; @@ -43,6 +45,12 @@ bool Scheduler::is_active() return s_active; } +void Scheduler::beep() +{ + PCSpeaker::tone_on(440); + s_beep_timeout = g_uptime + 100; +} + bool Scheduler::pick_next() { ASSERT_INTERRUPTS_DISABLED(); @@ -395,6 +403,11 @@ void Scheduler::timer_tick(RegisterDump& regs) ++g_uptime; + if (s_beep_timeout && g_uptime > s_beep_timeout) { + PCSpeaker::tone_off(); + s_beep_timeout = 0; + } + if (current->tick()) return; diff --git a/Kernel/Scheduler.h b/Kernel/Scheduler.h index 6ea5d5bcfa..da3c5c8e3e 100644 --- a/Kernel/Scheduler.h +++ b/Kernel/Scheduler.h @@ -25,6 +25,7 @@ public: static void prepare_to_modify_tss(Thread&); static Process* colonel(); static bool is_active(); + static void beep(); private: static void prepare_for_iret_to_new_process(); }; diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index 7487f1bb04..0c083f7a32 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -60,6 +60,9 @@ static dword handle(RegisterDump& regs, dword function, dword arg1, dword arg2, case Syscall::SC_yield: Scheduler::yield(); break; + case Syscall::SC_beep: + Scheduler::beep(); + break; case Syscall::SC_donate: return current->process().sys$donate((int)arg1); case Syscall::SC_gettid: diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index 1844826888..d2c884bade 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -103,6 +103,7 @@ __ENUMERATE_SYSCALL(exit_thread) \ __ENUMERATE_SYSCALL(mknod) \ __ENUMERATE_SYSCALL(writev) \ + __ENUMERATE_SYSCALL(beep) \ namespace Syscall { diff --git a/Kernel/i8253.cpp b/Kernel/i8253.cpp index 56d49ca0fa..8a8171e125 100644 --- a/Kernel/i8253.cpp +++ b/Kernel/i8253.cpp @@ -37,26 +37,6 @@ asm( " iret\n" ); -/* Timer related ports */ -#define TIMER0_CTL 0x40 -#define TIMER1_CTL 0x41 -#define TIMER2_CTL 0x42 -#define PIT_CTL 0x43 - -/* Building blocks for PIT_CTL */ -#define TIMER0_SELECT 0x00 -#define TIMER1_SELECT 0x40 -#define TIMER2_SELECT 0x80 - -#define MODE_COUNTDOWN 0x00 -#define MODE_ONESHOT 0x02 -#define MODE_RATE 0x04 -#define MODE_SQUARE_WAVE 0x06 - -#define WRITE_WORD 0x30 - -#define BASE_FREQUENCY 1193182 - static dword s_ticks_this_second; static dword s_seconds_since_boot; diff --git a/Kernel/i8253.h b/Kernel/i8253.h index 737880c00d..c537036f2a 100644 --- a/Kernel/i8253.h +++ b/Kernel/i8253.h @@ -3,6 +3,25 @@ #include <AK/Types.h> #define TICKS_PER_SECOND 1000 +/* Timer related ports */ +#define TIMER0_CTL 0x40 +#define TIMER1_CTL 0x41 +#define TIMER2_CTL 0x42 +#define PIT_CTL 0x43 + +/* Building blocks for PIT_CTL */ +#define TIMER0_SELECT 0x00 +#define TIMER1_SELECT 0x40 +#define TIMER2_SELECT 0x80 + +#define MODE_COUNTDOWN 0x00 +#define MODE_ONESHOT 0x02 +#define MODE_RATE 0x04 +#define MODE_SQUARE_WAVE 0x06 + +#define WRITE_WORD 0x30 + +#define BASE_FREQUENCY 1193182 namespace PIT { diff --git a/Kernel/run b/Kernel/run index 93a9cd7554..ee0532bd7c 100755 --- a/Kernel/run +++ b/Kernel/run @@ -14,7 +14,8 @@ elif [ "$1" = "qn" ]; then $SERENITY_EXTRA_QEMU_ARGS \ -device e1000 \ -kernel kernel \ - -hda _fs_contents + -hda _fs_contents \ + -soundhw pcspk elif [ "$1" = "qtap" ]; then # ./run qtap: qemu with tap sudo $SERENITY_QEMU_BIN -s -m $ram_size \ @@ -23,7 +24,8 @@ elif [ "$1" = "qtap" ]; then -netdev tap,ifname=tap0,id=br0 \ -device e1000,netdev=br0 \ -kernel kernel \ - -hda _fs_contents + -hda _fs_contents \ + -soundhw pcspk else # ./run: qemu with user networking $SERENITY_QEMU_BIN -s -m $ram_size \ @@ -32,6 +34,7 @@ else -netdev user,id=breh,hostfwd=tcp:127.0.0.1:8888-192.168.5.2:8888 \ -device e1000,netdev=breh \ -kernel kernel \ - -hda _fs_contents + -hda _fs_contents \ + -soundhw pcspk fi diff --git a/LibC/unistd.cpp b/LibC/unistd.cpp index e07463d9bf..baa99bbd5d 100644 --- a/LibC/unistd.cpp +++ b/LibC/unistd.cpp @@ -475,4 +475,9 @@ int donate(int tid) __RETURN_WITH_ERRNO(rc, rc, -1); } +void beep() +{ + syscall(SC_beep); +} + } diff --git a/LibC/unistd.h b/LibC/unistd.h index 172cbcd8a1..b184a5a435 100644 --- a/LibC/unistd.h +++ b/LibC/unistd.h @@ -14,6 +14,7 @@ __BEGIN_DECLS extern char** environ; +void beep(); int systrace(pid_t); int gettid(); int donate(int tid); diff --git a/Shell/LineEditor.cpp b/Shell/LineEditor.cpp index deab4b8553..547960858e 100644 --- a/Shell/LineEditor.cpp +++ b/Shell/LineEditor.cpp @@ -147,8 +147,11 @@ String LineEditor::get_line() } auto do_backspace = [&] { - if (m_cursor == 0) + if (m_cursor == 0) { + fputc('\a', stdout); + fflush(stdout); return; + } m_buffer.remove(m_cursor - 1); --m_cursor; putchar(8); |