Skip to content

Commit

Permalink
added int 0x17 for the ringing of bell (like what we have on a teletype)
Browse files Browse the repository at this point in the history
  • Loading branch information
Anivice committed Jan 15, 2025
1 parent 4ce856a commit c31baf8
Show file tree
Hide file tree
Showing 11 changed files with 196 additions and 28 deletions.
57 changes: 51 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ set(compiler_options

-fno-eliminate-unused-debug-types
-fno-omit-frame-pointer
-std=c++23
-lasan -lubsan -fPIC --pie
)

Expand All @@ -76,7 +75,6 @@ set(linker_options

# Stack protection
-fstack-protector-all # Link with stack protection for all functions
-std=c++23
-lasan -lubsan -fPIC --pie --whole-file
)

Expand Down Expand Up @@ -116,8 +114,40 @@ if (("${COMPILE_WITH_MEMORY_SANITIZERS}" STREQUAL "True") AND ("${COMPILE_WITH_T
message(FATAL_ERROR "Memory sanitizers and thread sanitizers are mutually exclusive!")
endif ()

add_compile_options(${compiler_options})
add_link_options(${linker_options})
set(optimization_flags
-O3
-march=native
-mtune=native
-flto
-fomit-frame-pointer
-ffast-math
-fstrict-aliasing
-fdata-sections
-ffunction-sections
-fno-rtti
)

set(optimization_link_flags
-O3
-march=native
-mtune=native
-flto
-fomit-frame-pointer
-ffast-math
-fstrict-aliasing
-fdata-sections
-ffunction-sections
-fno-rtti
-Wl,--gc-sections
)

if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
add_compile_options(${compiler_options})
add_link_options(${linker_options})
else ()
add_compile_options(${optimization_flags})
add_compile_options(${optimization_link_flags})
endif ()

# Read and process the information file
set(information_file "${CMAKE_CURRENT_SOURCE_DIR}/sysdarft_info.txt")
Expand Down Expand Up @@ -160,11 +190,26 @@ target_include_directories(SysdarftModule PUBLIC src/include)
add_library(SysdarftGlobalEvents OBJECT src/GlobalEvents.cpp)
target_include_directories(SysdarftGlobalEvents PUBLIC src/include)

# Audio files
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/resources/bell.c
COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/resources
COMMAND rm -f bell.wav
COMMAND mknod bell.wav p
COMMAND cat "${CMAKE_CURRENT_SOURCE_DIR}/resources/bell.wav" > bell.wav &
COMMAND xxd -i bell.wav > ${CMAKE_CURRENT_BINARY_DIR}/resources/bell.c
DEPENDS resources/bell.wav
COMMENT "Building audio resources.."
)

# Curses:
find_package(Curses REQUIRED)
add_library(SysdarftCursesUI OBJECT src/SysdarftCursesUI.cpp)
find_package(SFML COMPONENTS audio system REQUIRED)
add_library(SysdarftCursesUI OBJECT
src/SysdarftCursesUI.cpp
${CMAKE_CURRENT_BINARY_DIR}/resources/bell.c)
target_include_directories(SysdarftCursesUI PUBLIC src/include)
target_link_libraries(SysdarftCursesUI PUBLIC ${CURSES_LIBRARIES})
target_link_libraries(SysdarftCursesUI PUBLIC ${CURSES_LIBRARIES} sfml-audio sfml-system)

# CPU
add_library(SysdarftCPU OBJECT
Expand Down
Binary file added resources/bell.wav
Binary file not shown.
2 changes: 1 addition & 1 deletion scripts/generate_readme.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ echo -n "Automatically generating README.md..."
SOURCE_DIR="$1"
cd "$SOURCE_DIR" || exit 1

LIST=$(git ls-files);
LIST=$(git ls-files | grep -v wav);
lines=0;
size=0;
for FILE in $LIST;
Expand Down
11 changes: 7 additions & 4 deletions src/MainCompile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ void disassemble(const std::string & binary_filename, const uint64_t org)
ss << std::hex << std::setfill('0') << std::setw(16) << std::uppercase
<< bad_data.front().first;
ss << ": .8bit_data <";
for (size_t i = 0; i < bad_data.size(); ++i) {
ss << bad_data[i].second << (i < bad_data.size() - 1 ? ", " : "");
for (auto & [location, data] : bad_data) {
ss << " " << data << ",";
}
ss << ">";
ss << " >";
bad_data.clear();
lines.push_back(ss.str());
};
Expand Down Expand Up @@ -111,7 +111,10 @@ void disassemble(const std::string & binary_filename, const uint64_t org)
}
}

process_bad_data();
if (!bad_data.empty())
{
process_bad_data();
}

for (const auto& line : lines) {
std::cout << line << "\n";
Expand Down
24 changes: 22 additions & 2 deletions src/SysdarftCursesUI.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
// SysdarftCursesUI.cpp
#include <cstring>
#include <SysdarftCursesUI.h>
#include <cstring>
#include <thread>

std::mutex bell_memory_access_mutex;

SysdarftCursesUI::SysdarftCursesUI()
: cursor_x(0), cursor_y(0), offset_x(0), offset_y(0)
: cursor_x(0), cursor_y(0), offset_x(0), offset_y(0), vsb(1)
{
// Initialize video memory with spaces
for (auto & y : video_memory)
Expand All @@ -14,6 +17,17 @@ SysdarftCursesUI::SysdarftCursesUI()
}
}

SysdarftCursesUI::~SysdarftCursesUI()
{
running = false;
for (auto & thread : sound_thread_pool)
{
if (thread.joinable()) {
thread.join();
}
}
}

void SysdarftCursesUI::initialize()
{
if (is_inited) {
Expand Down Expand Up @@ -50,6 +64,12 @@ void SysdarftCursesUI::start_again()
render_screen();
}

void SysdarftCursesUI::ringbell()
{
running = true;
sound_thread_pool.emplace_back(std::thread(play_bell_sound, std::ref(running)));
}

void SysdarftCursesUI::cleanup()
{
if (is_inited) {
Expand Down
38 changes: 27 additions & 11 deletions src/cpu/SysdarftCPUInterruption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,20 @@ SysdarftCPUInterruption::SysdarftCPUInterruption(const uint64_t memory) :

void SysdarftCPUInterruption::do_interruption(const uint64_t code)
{
auto do_interruption = [&](decltype(SysdarftRegister::load<FlagRegisterType>()) & fg)
{
// software interruptions, maskable
const auto location = do_interruption_lookup(code);
do_preserve_cpu_state();

// mask
fg.InterruptionMask = 1;
SysdarftRegister::store<FlagRegisterType>(fg);

// setup jump table
do_jump_table(location);
};

if (code <= 0x1F)
{
// hardware interruptions, unmaskable
Expand All @@ -57,23 +71,20 @@ void SysdarftCPUInterruption::do_interruption(const uint64_t code)
case 0x13: do_interruption_newline_0x13(); return;
case 0x14: do_interruption_getinput_0x14(); return;
case 0x15: do_interruption_cur_pos_0x15(); return;
default: log("Hardware interruption ", code, " not implemented\n"); return;
case 0x16: do_get_system_hardware_info_0x16(); return;
case 0x17: do_ring_bell_0x17(); return;
default:
auto fg = SysdarftRegister::load<FlagRegisterType>();
// do interruption, but doesn't check interruption mask since
// this is not maskable interruptions
do_interruption(fg);
}
}

if (auto fg = SysdarftRegister::load<FlagRegisterType>();
!fg.InterruptionMask)
{
// software interruptions, maskable
const auto location = do_interruption_lookup(code);
do_preserve_cpu_state();

// mask
fg.InterruptionMask = 1;
SysdarftRegister::store<FlagRegisterType>(fg);

// setup jump table
do_jump_table(location);
do_interruption(fg);
}
}

Expand Down Expand Up @@ -189,3 +200,8 @@ void SysdarftCPUInterruption::do_get_system_hardware_info_0x16()
{
SysdarftRegister::store<FullyExtendedRegisterType, 0>(TotalMemory);
}

void SysdarftCPUInterruption::do_ring_bell_0x17()
{
SysdarftCursesUI::ringbell();
}
10 changes: 6 additions & 4 deletions src/include/SysdarftCPUDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ class SYSDARFT_EXPORT_SYMBOL SysdarftCPUInterruption : public DecoderDataAccess

/*
* Interruption table:
* Hardware Reserved:
* Hardware Reserved: [1-F], INVOKED BY HARDWARE, NOT MASKABLE
* [0x00] FATAL ERROR (ErrorCode == %EXR0)
* [0x01] DIV/0
* [0x02] IO ERROR
Expand All @@ -189,14 +189,15 @@ class SYSDARFT_EXPORT_SYMBOL SysdarftCPUInterruption : public DecoderDataAccess
* [0x0D]
* [0x0E]
* [0x0F]
* [10-1F], INVOKED BY USER FOR SPECIFIC HARDWARE FUNCTIONS, NOT MASKABLE
* [0x10] TELETYPE (EXR0 == Character ASCII Code)
* [0x11] SET CURSOR POSITION (EXR0 == LinearOffset)
* [0x12] SET CURSOR VISIBILITY (EXR0 == Visibility)
* [0x13] NEW LINE
* [0x14] GET INPUT, INPUT == EXR0
* [0x15] GET CURSOR POSITION POSITION == EXR0
* [0x16] GET SYSTEM HARDWARE INFO
* [0x17]
* [0x15] GET CURSOR POSITION == EXR0
* [0x16] GET SYSTEM HARDWARE INFO [TOTAL MEMORY == FER0]
* [0x17] RING BELL
* [0x18]
* [0x19]
* [0x1A]
Expand All @@ -222,6 +223,7 @@ class SYSDARFT_EXPORT_SYMBOL SysdarftCPUInterruption : public DecoderDataAccess
void do_interruption_getinput_0x14();
void do_interruption_cur_pos_0x15();
void do_get_system_hardware_info_0x16();
void do_ring_bell_0x17();

std::atomic<bool> hd_int_flag = false;

Expand Down
31 changes: 31 additions & 0 deletions src/include/SysdarftCursesUI.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@

#include <ncurses.h>
#include <string>
#include <thread>
#include <SFML/Audio.hpp>
#include <SysdarftDebug.h>

extern unsigned char bell_wav[];
extern unsigned int bell_wav_len;
extern std::mutex bell_memory_access_mutex;

// -----------------------------------------------------
// Virtual screen dimensions
// -----------------------------------------------------
Expand All @@ -14,6 +20,7 @@ static constexpr int V_HEIGHT = 25;
class SYSDARFT_EXPORT_SYMBOL SysdarftCursesUI {
public:
SysdarftCursesUI();
~SysdarftCursesUI();
void initialize();
void cleanup();
void set_cursor(int x, int y);
Expand All @@ -22,6 +29,7 @@ class SYSDARFT_EXPORT_SYMBOL SysdarftCursesUI {
void newline();
void handle_resize();
void start_again();
void ringbell();

protected:
int cursor_x;
Expand All @@ -33,9 +41,32 @@ class SYSDARFT_EXPORT_SYMBOL SysdarftCursesUI {
char video_memory[V_HEIGHT][V_WIDTH]{};
bool is_inited = false;
int vsb;
std::atomic < bool > running;

void recalc_offsets();
void render_screen();

std::vector<std::thread> sound_thread_pool;
static void play_bell_sound(const std::atomic < bool > & running_flag)
{
sf::SoundBuffer buffer;
{
std::lock_guard<std::mutex> guard(bell_memory_access_mutex);
if (!buffer.loadFromMemory(bell_wav, bell_wav_len)) {
log("Failed to load bell wav from memory");
return;
}
}

sf::Sound sound;
sound.setBuffer(buffer);
sound.play();

// Wait until the sound finishes playing
while (running_flag && sound.getStatus() == sf::Sound::Playing) {
sf::sleep(sf::milliseconds(50));
}
};
};

#endif // UI_CURSES_H
8 changes: 8 additions & 0 deletions src/include/SysdarftRegister.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,12 @@ class SysdarftRegister
} else if constexpr (std::is_same_v<AccessRegisterType, CurrentProcedureStackPreservationSpaceType>) {
return Registers.CurrentProcedureStackPreservationSpace;
} else {
#ifdef __DEBUG__
throw UnknownRegisterIdentification("Invalid register type: "
+ std::string(typeid(AccessRegisterType).name()));
#else
throw UnknownRegisterIdentification("Invalid register type");
#endif
}
}

Expand Down Expand Up @@ -554,9 +558,13 @@ class SysdarftRegister
} else if constexpr (std::is_same_v<AccessRegisterType, CurrentProcedureStackPreservationSpaceType>) {
Registers.CurrentProcedureStackPreservationSpace = Reg;
} else {
#ifdef __DEBUG__
throw UnknownRegisterIdentification("Invalid register type [AccessRegisterType = "
+ std::string(typeid(AccessRegisterType).name())
+ ", AccessRegisterIndex = " + std::to_string(AccessRegisterIndex));
#else
throw UnknownRegisterIdentification("Invalid register type");
#endif
}
}

Expand Down
Loading

0 comments on commit c31baf8

Please sign in to comment.