summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-05-15 21:40:41 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-05-15 21:40:41 +0200
commit3cba2a8a7872794516488ac5dfe240e946b1288d (patch)
treeabf359c90dbee15228f34669c7d5613d111e77f0
parentdcf490ecab4fea2eb2cb80508ae68d77c328739d (diff)
downloadserenity-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.cpp2
-rw-r--r--Kernel/Devices/PCSpeaker.cpp20
-rw-r--r--Kernel/Devices/PCSpeaker.h7
-rw-r--r--Kernel/Makefile1
-rw-r--r--Kernel/Scheduler.cpp13
-rw-r--r--Kernel/Scheduler.h1
-rw-r--r--Kernel/Syscall.cpp3
-rw-r--r--Kernel/Syscall.h1
-rw-r--r--Kernel/i8253.cpp20
-rw-r--r--Kernel/i8253.h19
-rwxr-xr-xKernel/run9
-rw-r--r--LibC/unistd.cpp5
-rw-r--r--LibC/unistd.h1
-rw-r--r--Shell/LineEditor.cpp5
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);