1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 03:47:34 +00:00

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.
This commit is contained in:
Andreas Kling 2019-05-15 21:40:41 +02:00
parent dcf490ecab
commit 3cba2a8a78
14 changed files with 82 additions and 25 deletions

View file

@ -576,7 +576,7 @@ void Terminal::on_char(byte ch)
} }
return; return;
case '\a': case '\a':
// FIXME: Bell! beep();
return; return;
case '\t': { case '\t': {
for (unsigned i = m_cursor_column; i < columns(); ++i) { for (unsigned i = m_cursor_column; i < columns(); ++i) {

View file

@ -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);
}

View file

@ -0,0 +1,7 @@
#pragma once
class PCSpeaker {
public:
static void tone_on(int frequency);
static void tone_off();
};

View file

@ -49,6 +49,7 @@ KERNEL_OBJS = \
Net/Routing.o \ Net/Routing.o \
Net/NetworkTask.o \ Net/NetworkTask.o \
ProcessTracer.o \ ProcessTracer.o \
Devices/PCSpeaker.o \
File.o File.o
VFS_OBJS = \ VFS_OBJS = \

View file

@ -5,6 +5,7 @@
#include <AK/TemporaryChange.h> #include <AK/TemporaryChange.h>
#include <Kernel/Alarm.h> #include <Kernel/Alarm.h>
#include <Kernel/FileSystem/FileDescriptor.h> #include <Kernel/FileSystem/FileDescriptor.h>
#include <Kernel/Devices/PCSpeaker.h>
//#define LOG_EVERY_CONTEXT_SWITCH //#define LOG_EVERY_CONTEXT_SWITCH
//#define SCHEDULER_DEBUG //#define SCHEDULER_DEBUG
@ -30,6 +31,7 @@ Thread* g_last_fpu_thread;
Thread* g_finalizer; Thread* g_finalizer;
static Process* s_colonel_process; static Process* s_colonel_process;
qword g_uptime; qword g_uptime;
static qword s_beep_timeout;
struct TaskRedirectionData { struct TaskRedirectionData {
word selector; word selector;
@ -43,6 +45,12 @@ bool Scheduler::is_active()
return s_active; return s_active;
} }
void Scheduler::beep()
{
PCSpeaker::tone_on(440);
s_beep_timeout = g_uptime + 100;
}
bool Scheduler::pick_next() bool Scheduler::pick_next()
{ {
ASSERT_INTERRUPTS_DISABLED(); ASSERT_INTERRUPTS_DISABLED();
@ -395,6 +403,11 @@ void Scheduler::timer_tick(RegisterDump& regs)
++g_uptime; ++g_uptime;
if (s_beep_timeout && g_uptime > s_beep_timeout) {
PCSpeaker::tone_off();
s_beep_timeout = 0;
}
if (current->tick()) if (current->tick())
return; return;

View file

@ -25,6 +25,7 @@ public:
static void prepare_to_modify_tss(Thread&); static void prepare_to_modify_tss(Thread&);
static Process* colonel(); static Process* colonel();
static bool is_active(); static bool is_active();
static void beep();
private: private:
static void prepare_for_iret_to_new_process(); static void prepare_for_iret_to_new_process();
}; };

View file

@ -60,6 +60,9 @@ static dword handle(RegisterDump& regs, dword function, dword arg1, dword arg2,
case Syscall::SC_yield: case Syscall::SC_yield:
Scheduler::yield(); Scheduler::yield();
break; break;
case Syscall::SC_beep:
Scheduler::beep();
break;
case Syscall::SC_donate: case Syscall::SC_donate:
return current->process().sys$donate((int)arg1); return current->process().sys$donate((int)arg1);
case Syscall::SC_gettid: case Syscall::SC_gettid:

View file

@ -103,6 +103,7 @@
__ENUMERATE_SYSCALL(exit_thread) \ __ENUMERATE_SYSCALL(exit_thread) \
__ENUMERATE_SYSCALL(mknod) \ __ENUMERATE_SYSCALL(mknod) \
__ENUMERATE_SYSCALL(writev) \ __ENUMERATE_SYSCALL(writev) \
__ENUMERATE_SYSCALL(beep) \
namespace Syscall { namespace Syscall {

View file

@ -37,26 +37,6 @@ asm(
" iret\n" " 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_ticks_this_second;
static dword s_seconds_since_boot; static dword s_seconds_since_boot;

View file

@ -3,6 +3,25 @@
#include <AK/Types.h> #include <AK/Types.h>
#define TICKS_PER_SECOND 1000 #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 { namespace PIT {

View file

@ -14,7 +14,8 @@ elif [ "$1" = "qn" ]; then
$SERENITY_EXTRA_QEMU_ARGS \ $SERENITY_EXTRA_QEMU_ARGS \
-device e1000 \ -device e1000 \
-kernel kernel \ -kernel kernel \
-hda _fs_contents -hda _fs_contents \
-soundhw pcspk
elif [ "$1" = "qtap" ]; then elif [ "$1" = "qtap" ]; then
# ./run qtap: qemu with tap # ./run qtap: qemu with tap
sudo $SERENITY_QEMU_BIN -s -m $ram_size \ sudo $SERENITY_QEMU_BIN -s -m $ram_size \
@ -23,7 +24,8 @@ elif [ "$1" = "qtap" ]; then
-netdev tap,ifname=tap0,id=br0 \ -netdev tap,ifname=tap0,id=br0 \
-device e1000,netdev=br0 \ -device e1000,netdev=br0 \
-kernel kernel \ -kernel kernel \
-hda _fs_contents -hda _fs_contents \
-soundhw pcspk
else else
# ./run: qemu with user networking # ./run: qemu with user networking
$SERENITY_QEMU_BIN -s -m $ram_size \ $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 \ -netdev user,id=breh,hostfwd=tcp:127.0.0.1:8888-192.168.5.2:8888 \
-device e1000,netdev=breh \ -device e1000,netdev=breh \
-kernel kernel \ -kernel kernel \
-hda _fs_contents -hda _fs_contents \
-soundhw pcspk
fi fi

View file

@ -475,4 +475,9 @@ int donate(int tid)
__RETURN_WITH_ERRNO(rc, rc, -1); __RETURN_WITH_ERRNO(rc, rc, -1);
} }
void beep()
{
syscall(SC_beep);
}
} }

View file

@ -14,6 +14,7 @@ __BEGIN_DECLS
extern char** environ; extern char** environ;
void beep();
int systrace(pid_t); int systrace(pid_t);
int gettid(); int gettid();
int donate(int tid); int donate(int tid);

View file

@ -147,8 +147,11 @@ String LineEditor::get_line()
} }
auto do_backspace = [&] { auto do_backspace = [&] {
if (m_cursor == 0) if (m_cursor == 0) {
fputc('\a', stdout);
fflush(stdout);
return; return;
}
m_buffer.remove(m_cursor - 1); m_buffer.remove(m_cursor - 1);
--m_cursor; --m_cursor;
putchar(8); putchar(8);