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:
parent
dcf490ecab
commit
3cba2a8a78
14 changed files with 82 additions and 25 deletions
|
@ -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) {
|
||||||
|
|
20
Kernel/Devices/PCSpeaker.cpp
Normal file
20
Kernel/Devices/PCSpeaker.cpp
Normal 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);
|
||||||
|
}
|
7
Kernel/Devices/PCSpeaker.h
Normal file
7
Kernel/Devices/PCSpeaker.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class PCSpeaker {
|
||||||
|
public:
|
||||||
|
static void tone_on(int frequency);
|
||||||
|
static void tone_off();
|
||||||
|
};
|
|
@ -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 = \
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue