From 1176fad12b27e23181c96746486da581e577e628 Mon Sep 17 00:00:00 2001 From: Anivice Ives Date: Tue, 14 Jan 2025 17:15:28 +0800 Subject: [PATCH] Added multiple features 1. Added floppy Disk A, B support 2. Added dynamic memory change 3. Implemented interruption mask 4. Moved all error classes to headers 5. Fixed disassembler incorrect memory decoding 6. Added two instructions for flag control --- CMakeLists.txt | 2 +- src/SysdarftIOHub.cpp | 6 - src/SysdarftMain.cpp | 362 ++++++++++++++++++++++---- src/coding/Assembler.cpp | 5 - src/coding/DecodeTarget.cpp | 1 + src/coding/EncodeInstruction.cpp | 6 - src/coding/PreProcessor.cpp | 5 - src/cpu/Operations/Misc.cpp | 14 + src/cpu/SysdarftCPUInterruption.cpp | 48 ++-- src/cpu/SysdarftInstructionExec.cpp | 4 +- src/cpu/SysdarftMemory.cpp | 11 +- src/cpu/cpu/operation_triggerer.cpp | 112 -------- src/ext_dev/SysdarftHardDisk.cpp | 120 +-------- src/include/EncodingDecoding.h | 30 ++- src/include/InstructionSet.h | 17 ++ src/include/SysdarftCPU.h | 10 +- src/include/SysdarftCPUDecoder.h | 14 +- src/include/SysdarftDisks.h | 85 ++++++ src/include/SysdarftDisks.inl | 139 ++++++++++ src/include/SysdarftHardDisk.h | 26 -- src/include/SysdarftIOHub.h | 16 +- src/include/SysdarftInstructionExec.h | 4 +- src/include/SysdarftMemory.h | 4 +- tests/example.sysasm | 1 + tests/test.arithmetic.cpp | 2 +- tests/test.controlflow.cpp | 2 +- tests/test.dataTsf.cpp | 2 +- tests/test.decode.cpp | 2 +- tests/test.executor.cpp | 2 +- tests/test.io.cpp | 4 +- tests/test.lgAbit.cpp | 2 +- tests/test.memory.cpp | 3 +- tests/test.operand.cpp | 2 +- tests/test.preprocessor.cpp | 7 +- 34 files changed, 685 insertions(+), 385 deletions(-) delete mode 100644 src/cpu/cpu/operation_triggerer.cpp create mode 100644 src/include/SysdarftDisks.h create mode 100644 src/include/SysdarftDisks.inl delete mode 100644 src/include/SysdarftHardDisk.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d0d1465a..48560a77f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -202,7 +202,7 @@ target_include_directories(SysdarftCoding PUBLIC src/include) add_library(SysdarftICH OBJECT src/include/SysdarftIOHub.h src/SysdarftIOHub.cpp - src/include/SysdarftHardDisk.h + src/include/SysdarftDisks.h src/ext_dev/SysdarftHardDisk.cpp ) target_include_directories(SysdarftICH PUBLIC src/include) diff --git a/src/SysdarftIOHub.cpp b/src/SysdarftIOHub.cpp index 799ee8a52..da2b66d57 100644 --- a/src/SysdarftIOHub.cpp +++ b/src/SysdarftIOHub.cpp @@ -1,12 +1,6 @@ #include #include -class SysdarftNoSuchDevice final : public SysdarftBaseError -{ -public: - explicit SysdarftNoSuchDevice(const std::string& msg) : SysdarftBaseError("No such device: " + msg) { } -}; - SysdarftExternalDeviceBaseClass & SysdarftIOHub::query_device_based_on_port(const uint64_t port) { for (const auto & deviceMap : device_list) diff --git a/src/SysdarftMain.cpp b/src/SysdarftMain.cpp index fc0c660be..534aed534 100644 --- a/src/SysdarftMain.cpp +++ b/src/SysdarftMain.cpp @@ -1,11 +1,49 @@ +#include #include -#include #include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include #include #include +#include + +struct option_complicated +{ + const char *name; + int has_arg; + int *flag; + int val; + const char * arg_explain; +}; + +static option_complicated long_options[] = { + {"help", no_argument, nullptr, 'h', "Show this help message"}, + {"version", no_argument, nullptr, 'v', "Output version information"}, + {"module", required_argument, nullptr, 'm', "Load a module\n" + "This option can be used multiple times\n" + "to load multiple modules"}, + {"verbose", no_argument, nullptr, 'V', "Enable verbose mode" }, + {"compile", required_argument, nullptr, 'c', "Compile a file\n" + "This option can be used multiple times\n" + "to compile multiple files into one single binary"}, + {"output", required_argument, nullptr, 'o', "Output file for compilation"}, + {"format", required_argument, nullptr, 'f', "Compile format. It can be bin, exe, or sys"}, + {"disassem",required_argument, nullptr, 'd', "Disassemble a file"}, + {"origin", required_argument, nullptr, 'g', "Redefine origin for disassembler\n" + "When left unset, origin is 0."}, + {"bios", required_argument, nullptr, 'b', "Specify a BIOS firmware binary"}, + {"hdd", required_argument, nullptr, 'L', "Specify a Hard Disk"}, + {"fda", required_argument, nullptr, 'A', "Specify floppy disk A"}, + {"fdb", required_argument, nullptr, 'B', "Specify floppy disk B"}, + {"boot", no_argument, nullptr, 'S', "Boot the system"}, + {nullptr, 0, nullptr, 0, nullptr } +}; // Each option name maps to a list of string values. using ParsedOptions = std::map>; @@ -15,7 +53,7 @@ using ParsedOptions = std::map>; // 2) A vector of positional arguments (non-option arguments). using ParsedArgs = std::pair>; -ParsedArgs get_args(int argc, char** argv, struct option long_options[]) +ParsedArgs get_args(const int argc, char** argv, option long_options[]) { // Build the short options string from the long_options array std::string short_opts; @@ -34,12 +72,14 @@ ParsedArgs get_args(int argc, char** argv, struct option long_options[]) std::vector positional_args; // Parse - while (true) { + while (true) + { int opt_index = 0; - int option = getopt_long(argc, argv, short_opts.c_str(), long_options, &opt_index); + const int option = getopt_long(argc, argv, short_opts.c_str(), long_options, &opt_index); if (option == -1) { break; // No more options } + if (option == '?') { // Unknown or invalid option throw std::invalid_argument("Unknown or invalid option encountered."); @@ -67,17 +107,56 @@ ParsedArgs get_args(int argc, char** argv, struct option long_options[]) void print_help(const char *program_name) { - std::cout - << "Usage: " << program_name << " [OPTIONS]\n" - << "Options:\n" - << " -h, --help Show this help message\n" - << " -v, --version Show version information\n" - << " -m, --module Load a configuration file\n" - << " -V, --verbose Enable verbose mode. Additional debug messages will be printed\n" - << " -c, --compile Add a file to compilation list\n" - << " -o, --output Output file\n" - << " -f, --format File formant for compilation. They can be bin, exe, or sys.\n" - << std::endl; + std::stringstream ss; + ss << "Usage: " << program_name << " [OPTIONS]\n" + << "Options:\n"; + + uint64_t max_length_of_arguments = 0; + for (int i = 0; i < std::size(long_options) - 1; i++) + { + const auto& opt = long_options[i]; + auto this_len = std::strlen(opt.name) + 1 /* val */ + 5 /* `-[val], --[name]`, 5 additional characters */; + max_length_of_arguments = std::max(this_len, max_length_of_arguments); + } + + const auto before_explanation = max_length_of_arguments + 10 + 4; + + // Dynamically generate help text for each option + for (int i = 0; i < std::size(long_options) - 1; i++) + { + const auto& opt = long_options[i]; + std::stringstream this_line; + this_line << " "; + + // Print short option if provided + if (opt.val) { + this_line << "-" << static_cast(opt.val) << ", "; + } else { + this_line << " "; // Indent if no short option + } + + // Print long option + this_line << "--" << opt.name; + + // If option requires an argument, show placeholder + if (opt.has_arg) { + this_line << " "; + } + + const auto printed_len = this_line.str().length(); + const auto space = before_explanation - printed_len; + const std::string padding(space, ' '); + const std::string next_line_padding(before_explanation, ' '); + this_line << padding; + + std::string exp = opt.arg_explain; + replace_all(exp, "\n", "\n " + next_line_padding); + this_line << exp; + + ss << this_line.str() << std::endl; + } + + std::cout << ss.str(); } void print_version() @@ -87,33 +166,129 @@ void print_version() << SYSDARFT_INFORMATION << std::endl; } -int main(int argc, char** argv) +void compile_to_binary(const std::vector< std::string > & source_files, const std::string & binary_filename) { - debug::set_thread_name("Sysdarft Watcher"); - - static struct option long_options[] = { - {"help", no_argument, nullptr, 'h'}, - {"version", no_argument, nullptr, 'v'}, - {"module", required_argument, nullptr, 'm'}, - {"verbose", no_argument, nullptr, 'V'}, - {"compile", required_argument, nullptr, 'c'}, - {"output", required_argument, nullptr, 'o'}, - {"format", required_argument, nullptr, 'f'}, - {nullptr, 0, nullptr, 0 } - }; + try { + std::vector < std::vector < uint8_t > > binary_cct; + for (const std::string & source_file : source_files) + { + std::fstream file(source_file, std::ios::in | std::ios::out); + if (!file.is_open()) { + throw SysdarftAssemblerError("Could not open file " + source_file); + } - try + std::vector < uint8_t > binary; + CodeProcessing(binary, file); + + file.close(); + binary_cct.emplace_back(binary); + } + + std::ofstream file(binary_filename, std::ios::out | std::ios::binary); + if (!file.is_open()) { + throw SysdarftAssemblerError("Could not open file " + binary_filename); + } + + for (const auto & cct : binary_cct) { + file.write(reinterpret_cast(cct.data()), cct.size()); + } + + file.close(); + } catch (const std::exception & e) { + throw SysdarftAssemblerError(e.what()); + } +} + +class SysdarftDisassemblerError final : public SysdarftBaseError +{ +public: + explicit SysdarftDisassemblerError(const std::string & message) : + SysdarftBaseError("Disassembler failed to process data: " + message) { } +}; + +void disassemble(const std::string & binary_filename, const uint64_t org) +{ + std::ifstream file(binary_filename, std::ios::in | std::ios::binary); + std::vector < uint8_t > assembled_code; + auto file_size = std::filesystem::file_size(binary_filename); + + // read + if (!file.is_open()) { + throw SysdarftDisassemblerError("Could not open file " + binary_filename); + } + + assembled_code.resize(file_size); + file.read((char*)(assembled_code.data()), file_size); + if (static_cast(file.gcount()) != file_size) { + throw SysdarftDisassemblerError("Short read on file " + binary_filename); + } + + file.close(); + + const auto space = assembled_code.size(); + std::vector < std::string > lines; + while (!assembled_code.empty()) { - std::vector < std::unique_ptr > loaded_modules; - auto [parsed_options, positional_args] = get_args(argc, argv, long_options); + std::stringstream off; + std::vector < std::string > line; + off << std::hex << std::setfill('0') << std::setw(16) << std::uppercase + << space - assembled_code.size() + org; - if (parsed_options.empty() && positional_args.empty()) - { - log("Not enough arguments.\n"); - print_help(argv[0]); - return EXIT_FAILURE; + decode_instruction(line, assembled_code); + + if (!line.empty()) { + off << ": " << line[0]; + } else { + off << ": " << "(bad)"; } + lines.push_back(off.str()); + } + + for (const auto& line : lines) { + std::cout << line << "\n"; + } +} + +void complicated_to_gnu(option * dest, const option_complicated * src) +{ + uint64_t offset = 0; + while (src[offset].name) + { + dest[offset].name = src[offset].name; + dest[offset].flag = src[offset].flag; + dest[offset].has_arg = src[offset].has_arg; + dest[offset].val = src[offset].val; + offset++; + } + + dest[offset] = {nullptr, 0, nullptr, 0 }; +} + +void boot_sysdarft( + const std::string & bios, + const std::string & hdd, + const std::string & fda, + const std::string & fdb) +{ + +} + +int main(int argc, char** argv) +{ + try + { + std::vector> loaded_modules; + std::unique_ptr < option[] > gnu_long_options = std::make_unique < option[] > (std::size(long_options)); + complicated_to_gnu(gnu_long_options.get(), long_options); + auto [parsed_options, positional_args] + = get_args(argc, argv, gnu_long_options.get()); + + auto exit_failure_on_error = [&]()->void { + std::cout << "Use -h or --help to see usage" << std::endl; + exit(EXIT_FAILURE); + }; + // Handle --help option if (parsed_options.contains("help")) { print_help(argv[0]); @@ -129,7 +304,7 @@ int main(int argc, char** argv) // Handle --verbose option if (parsed_options.contains("verbose")) { debug::verbose = true; - log("Verbose mode enabled.\n"); + std::cerr << "Verbose mode enabled." << std::endl; } // Handle --module option @@ -142,17 +317,116 @@ int main(int argc, char** argv) } } + // compile file if (parsed_options.contains("compile")) { - const auto output_file = parsed_options["output"]; - const auto format = parsed_options["format"]; - - for (const auto src_files = parsed_options["compile"]; - const auto & src_file : src_files) + try { + const auto output_file = parsed_options["output"]; + const auto format = parsed_options["format"]; + const auto src_files = parsed_options["compile"]; + const auto org_assembly = parsed_options["original"]; + + if (format.size() != 1) { + std::cerr << "ERROR: Unknown compilation format!" << std::endl; + exit_failure_on_error(); + } + + if (output_file.size() != 1) { + std::cerr << "ERROR: No or multiple output file specified!" << std::endl; + exit_failure_on_error(); + } + + if (src_files.size() == 0) { + std::cerr << "ERROR: No input files specified!" << std::endl; + exit_failure_on_error(); + } + + if (format.at(0) == "bin") { + compile_to_binary(src_files, output_file.at(0)); + } else if (format.at(0) == "exe") { + std::cerr << "ERROR: Feature not implemented!" << std::endl; + exit_failure_on_error(); + } else if (format.at(0) == "sys") { + std::cerr << "ERROR: Feature not implemented!" << std::endl; + exit_failure_on_error(); + } else { + exit_failure_on_error(); + } + } catch (std::out_of_range &) { + std::cerr << "ERROR: missing format, input file, or output file!" << std::endl; + exit_failure_on_error(); + } catch (SysdarftAssemblerError & e) { + std::cerr << "ERROR: Error when compiling code:\n" << e.what() << std::endl; } + + return EXIT_SUCCESS; + } + + if (parsed_options.contains("disassem")) + { + try { + const auto src_files = parsed_options["disassem"]; + if (src_files.size() == 0) { + std::cerr << "ERROR: No input files specified!" << std::endl; + exit_failure_on_error(); + } + + // redefine origin + uint64_t origin = 0; + if (parsed_options.contains("origin")) { + auto expression = parsed_options["origin"][0]; + process_base16(expression); + origin = std::strtoull(expression.c_str(), nullptr, 10); + } + + const std::string line = "================================================================"; + + for (const auto & src_file : src_files) + { + const int len = (line.length() - (src_file.length() + 4)) / 2; + const int space_after = line.length() - len * 2 - 2 - src_file.length(); + const std::string line_before_n_after(len, '='); + const std::string string_space_after(space_after, ' '); + std::cout << ";" << line << std::endl; + std::cout << ";" << line_before_n_after << " " + << src_file << string_space_after << line_before_n_after << std::endl; + std::cout << ";" << line << std::endl; + + disassemble(src_file, origin); + + std::cout << ";" << line << std::endl; + } + + } catch (std::out_of_range &) { + std::cerr << "ERROR: Missing disassemble option!" << std::endl; + exit_failure_on_error(); + } catch (SysdarftBaseError & e) { + std::cerr << "ERROR: " << e.what() << std::endl; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; + } + + if (parsed_options.contains("boot")) + { + if (parsed_options["bios"].size() != 1) { + std::cerr << "ERROR: Missing BIOS!" << std::endl; + exit_failure_on_error(); + } + + const std::string bios_path = parsed_options["bios"][0]; + std::string hdd; + std::string fda; + std::string fdb; + + boot_sysdarft(bios_path, hdd, fda, fdb); + return EXIT_SUCCESS; } + print_help(argv[0]); + print_version(); return EXIT_SUCCESS; } catch (const std::invalid_argument& e) { std::cerr << "Argument parsing error: " << e.what() << std::endl; diff --git a/src/coding/Assembler.cpp b/src/coding/Assembler.cpp index 6176e4ea3..969bb015d 100644 --- a/src/coding/Assembler.cpp +++ b/src/coding/Assembler.cpp @@ -3,11 +3,6 @@ #include #include -class SysdarftCompileError final : public SysdarftBaseError { -public: - explicit SysdarftCompileError(const std::string& msg) : SysdarftBaseError("Error during compilation: " + msg) { } -}; - void replace_all( std::string & input, const std::string & target, diff --git a/src/coding/DecodeTarget.cpp b/src/coding/DecodeTarget.cpp index 4fd14a756..2d7ad7613 100644 --- a/src/coding/DecodeTarget.cpp +++ b/src/coding/DecodeTarget.cpp @@ -87,6 +87,7 @@ void decode_memory(std::vector & output, std::vector < uint8_t > & return true; }; + operands.emplace_back("("); if (!decode_each_parameter()) { return; } operands.emplace_back(", "); if (!decode_each_parameter()) { return; } diff --git a/src/coding/EncodeInstruction.cpp b/src/coding/EncodeInstruction.cpp index 848100426..82b7f7526 100644 --- a/src/coding/EncodeInstruction.cpp +++ b/src/coding/EncodeInstruction.cpp @@ -9,12 +9,6 @@ std::regex target_pattern(R"(<\s*(?:\*\s*(?:1|2|4|8|16)\&(8|16|32|64)\s*\([^,]+, std::regex instruction_pattern(R"(([A-Z-0-9]+))"); std::regex operation_width(R"(.8BIT|.16BIT|.32BIT|.64BIT)"); -class InstructionExpressionError final : public SysdarftBaseError { -public: - explicit InstructionExpressionError(const std::string& message) : - SysdarftBaseError("Instruction Expression Error: " + message) { } -}; - std::vector clean_line(const std::string & _input) { std::vector ret; diff --git a/src/coding/PreProcessor.cpp b/src/coding/PreProcessor.cpp index d428ac678..be0390804 100644 --- a/src/coding/PreProcessor.cpp +++ b/src/coding/PreProcessor.cpp @@ -3,11 +3,6 @@ #include #include -class SysdarftPreProcessorError final : public SysdarftBaseError { -public: - explicit SysdarftPreProcessorError(const std::string& msg) : SysdarftBaseError("Error encountered in preprocessor: " + msg) { } -}; - const std::regex org_pattern(R"(\s*\.org\s+((?:0x[0-9A-Fa-f]+)|(?:\d+))\s*)", std::regex_constants::icase); // .org 0x123 const std::regex lab_pattern(R"(\s*\.lab\s+([A-Za-z._][A-Za-z0-9._]*(?:\s*,\s*[A-Za-z._][A-Za-z0-9._]*)*)\s*)", std::regex_constants::icase); diff --git a/src/cpu/Operations/Misc.cpp b/src/cpu/Operations/Misc.cpp index cfe91c082..06281f834 100644 --- a/src/cpu/Operations/Misc.cpp +++ b/src/cpu/Operations/Misc.cpp @@ -9,3 +9,17 @@ void SysdarftCPUInstructionExecutor::hlt(__uint128_t, WidthAndOperandsType &) { SystemHalted = true; } + +void SysdarftCPUInstructionExecutor::igni(__uint128_t, WidthAndOperandsType &) +{ + auto fg = SysdarftRegister::load(); + fg.InterruptionMask = 1; + SysdarftRegister::store(fg); +} + +void SysdarftCPUInstructionExecutor::alwi(__uint128_t, WidthAndOperandsType &) +{ + auto fg = SysdarftRegister::load(); + fg.InterruptionMask = 0; + SysdarftRegister::store(fg); +} diff --git a/src/cpu/SysdarftCPUInterruption.cpp b/src/cpu/SysdarftCPUInterruption.cpp index b1bff6c3a..3f7180ab0 100644 --- a/src/cpu/SysdarftCPUInterruption.cpp +++ b/src/cpu/SysdarftCPUInterruption.cpp @@ -28,24 +28,34 @@ void SysdarftCPUInterruption::do_interruption(const uint64_t code) { if (code <= 0x1F) { - // hardware interruptions + // hardware interruptions, unmaskable switch (code) { - case 0x00: do_interruption_fatal_0x00(); return; - case 0x03: do_interruption_debug_0x03(); return; - case 0x10: do_interruption_tty_0x10(); return; - case 0x11: do_interruption_set_cur_pos_0x11(); return; - case 0x12: do_interruption_set_cur_visib_0x12(); return; - case 0x13: do_interruption_newline_0x13(); return; - case 0x14: do_interruption_getinput_0x14(); return; - case 0x15: do_interruption_cur_pos_0x15(); return; - default: log("Interruption ", code, " not implemented\n"); return; + case 0x00: do_interruption_fatal_0x00(); return; + case 0x03: do_interruption_debug_0x03(); return; + case 0x10: do_interruption_tty_0x10(); return; + case 0x11: do_interruption_set_cur_pos_0x11(); return; + case 0x12: do_interruption_set_cur_visib_0x12(); return; + 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; } } - // software interruptions - const auto location = do_interruption_lookup(code); - do_preserve_cpu_state(); - do_jump_table(location); + if (auto fg = SysdarftRegister::load(); + !fg.InterruptionMask) + { + // software interruptions, maskable + const auto location = do_interruption_lookup(code); + do_preserve_cpu_state(); + + // mask + fg.InterruptionMask = 1; + SysdarftRegister::store(fg); + + // setup jump table + do_jump_table(location); + } } SysdarftCPUInterruption::InterruptionPointer SysdarftCPUInterruption::do_interruption_lookup(const uint64_t code) @@ -83,11 +93,6 @@ void SysdarftCPUInterruption::do_iret() // SysdarftRegister::store(SP); } -class SysdarftCPUFatal final : public SysdarftBaseError { -public: - SysdarftCPUFatal() : SysdarftBaseError("CPU is met with a unrecoverable fatal error") { } -}; - // Hardware Interruptions void SysdarftCPUInterruption::do_interruption_fatal_0x00() { @@ -142,3 +147,8 @@ void SysdarftCPUInterruption::do_interruption_cur_pos_0x15() const uint16_t linear = cursor_y * V_WIDTH + cursor_x; SysdarftRegister::store(linear); } + +void SysdarftCPUInterruption::do_get_system_hardware_info_0x16() +{ + SysdarftRegister::store(TotalMemory); +} diff --git a/src/cpu/SysdarftInstructionExec.cpp b/src/cpu/SysdarftInstructionExec.cpp index d57926fc9..33811830d 100644 --- a/src/cpu/SysdarftInstructionExec.cpp +++ b/src/cpu/SysdarftInstructionExec.cpp @@ -1,11 +1,13 @@ #include #include -SysdarftCPUInstructionExecutor::SysdarftCPUInstructionExecutor() +SysdarftCPUInstructionExecutor::SysdarftCPUInstructionExecutor(const uint64_t memory) : SysdarftCPUInstructionDecoder(memory) { // Misc make_instruction_execution_procedure(OPCODE_NOP, &SysdarftCPUInstructionExecutor::nop); make_instruction_execution_procedure(OPCODE_HLT, &SysdarftCPUInstructionExecutor::hlt); + make_instruction_execution_procedure(OPCODE_HLT, &SysdarftCPUInstructionExecutor::igni); + make_instruction_execution_procedure(OPCODE_HLT, &SysdarftCPUInstructionExecutor::alwi); // Arithmetic make_instruction_execution_procedure(OPCODE_ADD, &SysdarftCPUInstructionExecutor::add); diff --git a/src/cpu/SysdarftMemory.cpp b/src/cpu/SysdarftMemory.cpp index 35f68d591..c35e658e5 100644 --- a/src/cpu/SysdarftMemory.cpp +++ b/src/cpu/SysdarftMemory.cpp @@ -2,14 +2,15 @@ #include #include -SysdarftCPUMemoryAccess::SysdarftCPUMemoryAccess() +SysdarftCPUMemoryAccess::SysdarftCPUMemoryAccess(const uint64_t totalMemory) { - // We assume TotalMemory and BLOCK_SIZE are defined in the header. - // Example: TotalMemory = 32UL * 1024 * 1024, BLOCK_SIZE = 4096, etc. - std::lock_guard lock(MemoryAccessMutex); - Memory.clear(); + TotalMemory = totalMemory; + + if (totalMemory == 0) { + throw SysdarftBaseError("Total memory is zero"); + } // Fill the vector with (TotalMemory / BLOCK_SIZE) blocks const uint64_t numBlocks = TotalMemory / BLOCK_SIZE; diff --git a/src/cpu/cpu/operation_triggerer.cpp b/src/cpu/cpu/operation_triggerer.cpp deleted file mode 100644 index f3fc5182b..000000000 --- a/src/cpu/cpu/operation_triggerer.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include -#include -#include - -void processor::triggerer_thread(std::atomic & running) -{ - const std::chrono::nanoseconds period_ns(1'000'000'000 / frequencyHz); - const std::chrono::nanoseconds MAX_DURATION_NS = period_ns + std::chrono::nanoseconds(); - const unsigned long long ops_num = frequencyHz; - - log("[CPU] Starting execution of ", ops_num, " operations per second.\n"); - log("[CPU] Frequency set to: ", frequencyHz, " Hz.\n"); - log("[CPU] Period per operation: ", period_ns.count(), " nanoseconds.\n"); - log("[CPU] Maximum allowed duration per operation: ", MAX_DURATION_NS.count(), " nanoseconds.\n"); - - __uint128_t timestamp = 0; - - while (running) - { - auto op_start = std::chrono::steady_clock::now(); - - operation(timestamp); - - auto op_end = std::chrono::steady_clock::now(); - if (const auto duration = std::chrono::duration_cast(op_end - op_start); - duration > MAX_DURATION_NS) { - log("[CPU] Delayed ", duration - MAX_DURATION_NS, " for current cycle!\n"); - } else { - std::this_thread::sleep_for(MAX_DURATION_NS * wait_scale.load() - duration); - } - - timestamp++; - } -} - -void processor::collaborate() -{ - log("[CPU] CPU time frame precision collaboration started.\n"); - log("[CPU] Please wait for 10 seconds for the collaboration procedure to finish!\n"); - - std::atomic ins_count = 0; - std::atomic running = true; - std::atomic stopped = false; - - auto minimum_operation = [&ins_count]() { - ++ins_count; - }; - - auto triggerer = [&]()->void - { - const std::chrono::nanoseconds period_ns(1'000'000'000 / frequencyHz); - const std::chrono::nanoseconds MAX_DURATION_NS = period_ns + std::chrono::nanoseconds(); - - __uint128_t timestamp = 0; - - while (running) - { - auto op_start = std::chrono::steady_clock::now(); - - minimum_operation(); - - auto op_end = std::chrono::steady_clock::now(); - const auto duration = std::chrono::duration_cast(op_end - op_start); - - if (duration > MAX_DURATION_NS) { - log("[CPU] Delayed ", duration - MAX_DURATION_NS, " ns for current cycle!\n"); - } else { - std::this_thread::sleep_for(MAX_DURATION_NS - duration); - } - - timestamp++; - } - - stopped = true; - }; - - std::thread T1(triggerer); - T1.detach(); - - std::this_thread::sleep_for(std::chrono::seconds(10)); - - running = false; - while (!stopped) { - std::this_thread::sleep_for(std::chrono::nanoseconds(1)); - } - - const auto expected = frequencyHz * 10; - const uint64_t actual = ins_count; - - wait_scale = static_cast(actual) / static_cast(expected); - - log("[CPU] CPU time frame precision collaboration done.\n"); -} - -void processor::start_triggering() -{ - if (has_instance) { - throw MultipleCPUInstanceCreation(); - } - has_instance = true; - triggerer.start(); -} - -void processor::stop_triggering() -{ - if (has_instance) - { - triggerer.stop(); - has_instance = false; - } -} diff --git a/src/ext_dev/SysdarftHardDisk.cpp b/src/ext_dev/SysdarftHardDisk.cpp index 85d3ed791..9f66d47da 100644 --- a/src/ext_dev/SysdarftHardDisk.cpp +++ b/src/ext_dev/SysdarftHardDisk.cpp @@ -1,5 +1,5 @@ #include -#include +#include std::streamoff getFileSize(std::fstream& file) { @@ -15,121 +15,3 @@ std::streamoff getFileSize(std::fstream& file) return size; } - -class SysdarftDiskError final : public SysdarftBaseError { -public: - explicit SysdarftDiskError(const std::string & msg) : SysdarftBaseError(msg) { } -}; - -SysdarftHardDisk::SysdarftHardDisk(const std::string &file_name) -{ - _sysdarftHardDiskFile.open(file_name); - if (!_sysdarftHardDiskFile.is_open()) { - throw SysdarftDiskError("Cannot open file " + file_name); - } - - device_buffer.emplace(HDD_REG_SIZE, ControllerDataStream()); - device_buffer.emplace(HDD_REG_START_SEC, ControllerDataStream()); - device_buffer.emplace(HDD_REG_SEC_COUNT, ControllerDataStream()); - device_buffer.emplace(HDD_CMD_REQUEST_RD, ControllerDataStream()); - device_buffer.emplace(HDD_CMD_REQUEST_WR, ControllerDataStream()); -} - -bool SysdarftHardDisk::request_read(const uint64_t port) -{ - const uint64_t size = getFileSize(_sysdarftHardDiskFile); - - if (port == HDD_REG_SIZE) - { - device_buffer.at(port).push(size); - return true; - } - else if (port == HDD_CMD_REQUEST_RD) - { - if (const uint64_t ops_end_sector = (start_sector + sector_count) * 512; - ops_end_sector > size) - { - return false; - } - - const uint64_t start_off = start_sector * 512; - const uint64_t length = sector_count * 512; - - if (length == 0 || start_off + length > size) { - return false; - } - - // Seek to the specified offset - _sysdarftHardDiskFile.seekg(static_cast(start_off), std::ios::beg); - if (!_sysdarftHardDiskFile) { - return false; - } - - auto & buffer = device_buffer.at(port).device_buffer; - buffer.resize(length); - - // Read 'length' bytes from the file - _sysdarftHardDiskFile.read((char*)buffer.data(), static_cast(length)); - - if (const std::streamsize bytesRead = _sysdarftHardDiskFile.gcount(); - bytesRead < static_cast(length)) - { - return false; - } - - return true; - } - - return false; -} - -bool SysdarftHardDisk::request_write(const uint64_t port) -{ - const uint64_t size = getFileSize(_sysdarftHardDiskFile); - if (port == HDD_REG_START_SEC) - { - start_sector = device_buffer.at(port).pop(); - return true; - } - else if (port == HDD_REG_SEC_COUNT) - { - sector_count = device_buffer.at(port).pop(); - return true; - } - else if (port == HDD_CMD_REQUEST_WR) - { - if (const uint64_t ops_end_sector = (start_sector + sector_count) * 512; - ops_end_sector > size) - { - return false; - } - - const uint64_t start_off = start_sector * 512; - const uint64_t length = sector_count * 512; - if (length == 0 || start_off + length > size) { - return false; - } - - auto & buffer = device_buffer.at(port).device_buffer; - - if (length != buffer.size()) { - return false; - } - - // Seek to the specified offset - _sysdarftHardDiskFile.seekp(static_cast(start_off), std::ios::beg); - if (!_sysdarftHardDiskFile) { - return false; - } - - _sysdarftHardDiskFile.write((char*)buffer.data(), static_cast(length)); - if (!_sysdarftHardDiskFile) { - return false; - } - - buffer.clear(); - return true; - } - - return false; -} diff --git a/src/include/EncodingDecoding.h b/src/include/EncodingDecoding.h index c7ef19ea9..96fae3c40 100644 --- a/src/include/EncodingDecoding.h +++ b/src/include/EncodingDecoding.h @@ -56,6 +56,17 @@ class CodeBufferEmptiedWhenPop final : public SysdarftBaseError { SysdarftBaseError("Code buffer emptied before pop finished: " + msg) { } }; +class InstructionExpressionError final : public SysdarftBaseError { +public: + explicit InstructionExpressionError(const std::string& message) : + SysdarftBaseError("Instruction Expression Error: " + message) { } +}; + +class SysdarftPreProcessorError final : public SysdarftBaseError { +public: + explicit SysdarftPreProcessorError(const std::string& msg) : SysdarftBaseError("Error encountered in preprocessor: " + msg) { } +}; + inline std::string & remove_space(std::string & str) { std::erase(str, ' '); @@ -149,16 +160,17 @@ struct SYSDARFT_EXPORT_SYMBOL parsed_target_t typedef std::map < std::string, std::pair < uint64_t /* line position */, std::vector < uint64_t > > > defined_line_marker_t; -void process_base16(std::string & input); -std::string execute_bc(const std::string& input); -void replace_all( std::string & input, const std::string & target, const std::string & replacement); -parsed_target_t encode_target(std::vector &, const std::string&); -void decode_target(std::vector &, std::vector &); +void SYSDARFT_EXPORT_SYMBOL process_base16(std::string &); +void SYSDARFT_EXPORT_SYMBOL replace_all(std::string &, const std::string &, const std::string &); +std::string execute_bc(const std::string &); +parsed_target_t encode_target(std::vector < uint8_t > &, const std::string &); +void decode_target(std::vector < std::string > &, std::vector < uint8_t > &); -void SYSDARFT_EXPORT_SYMBOL encode_instruction(std::vector &, const std::string &); +void SYSDARFT_EXPORT_SYMBOL encode_instruction(std::vector < uint8_t > &, const std::string &); void SYSDARFT_EXPORT_SYMBOL decode_instruction(std::vector < std::string > &, std::vector &); -void SYSDARFT_EXPORT_SYMBOL SysdarftCompile(std::vector < std::vector > & code, - std::basic_iostream& file, uint64_t org, defined_line_marker_t & defined_line_marker); -void SYSDARFT_EXPORT_SYMBOL CodeProcessing(std::vector & code, std::basic_istream& file); +void SYSDARFT_EXPORT_SYMBOL SysdarftCompile(std::vector < std::vector < uint8_t > > &, + std::basic_iostream < char > &, + uint64_t, defined_line_marker_t &); +void SYSDARFT_EXPORT_SYMBOL CodeProcessing(std::vector < uint8_t > &, std::basic_istream < char > &); #endif // INSTRUCTIONS_H diff --git a/src/include/InstructionSet.h b/src/include/InstructionSet.h index 4219d16a6..18c61e3b9 100644 --- a/src/include/InstructionSet.h +++ b/src/include/InstructionSet.h @@ -58,6 +58,8 @@ #define OPCODE_IRET (0x3B) #define OPCODE_HLT (0x40) +#define OPCODE_IGNI (0x41) +#define OPCODE_ALWI (0x42) #define OPCODE_IN (0x50) #define OPCODE_OUT (0x51) @@ -382,6 +384,20 @@ const std::unordered_map> instructi } }, + { "IGNI", { + {ENTRY_OPCODE, OPCODE_IGNI }, + {ENTRY_ARGUMENT_COUNT, 0}, + {ENTRY_REQUIRE_OPERATION_WIDTH_SPECIFICATION, 0}, + } + }, + + { "ALWI", { + {ENTRY_OPCODE, OPCODE_ALWI }, + {ENTRY_ARGUMENT_COUNT, 0}, + {ENTRY_REQUIRE_OPERATION_WIDTH_SPECIFICATION, 0}, + } + }, + //////////////////////////////////////////////////////////////////////////////////////////// { "IN", { @@ -411,6 +427,7 @@ const std::unordered_map> instructi {ENTRY_REQUIRE_OPERATION_WIDTH_SPECIFICATION, 1}, } }, + }; #endif //INSTRUCTION_DEFINITION_H \ No newline at end of file diff --git a/src/include/SysdarftCPU.h b/src/include/SysdarftCPU.h index f03567937..69ce3b770 100644 --- a/src/include/SysdarftCPU.h +++ b/src/include/SysdarftCPU.h @@ -8,10 +8,6 @@ #include #include -inline unsigned long long operator"" _Hz(const unsigned long long freq) { - return freq; -} - class MultipleCPUInstanceCreation final : public SysdarftBaseError { public: @@ -19,4 +15,10 @@ class MultipleCPUInstanceCreation final : public SysdarftBaseError SysdarftBaseError("Trying to create multiple CPU instances!") { } }; +class SYSDARFT_EXPORT_SYMBOL SysdarftCPU final : protected SysdarftCPUInstructionExecutor { +public: + explicit SysdarftCPU(const uint64_t memory, std::vector < uint8_t > bios) : + SysdarftCPUInstructionExecutor(memory) { } +}; + #endif //CPU_H diff --git a/src/include/SysdarftCPUDecoder.h b/src/include/SysdarftCPUDecoder.h index 74a39fc51..5dc35438e 100644 --- a/src/include/SysdarftCPUDecoder.h +++ b/src/include/SysdarftCPUDecoder.h @@ -30,6 +30,11 @@ class SysdarftBadInterruption final : public SysdarftBaseError { explicit SysdarftBadInterruption(const std::string & msg) : SysdarftBaseError("Bad interruption: " + msg) { } }; +class SysdarftCPUFatal final : public SysdarftBaseError { +public: + SysdarftCPUFatal() : SysdarftBaseError("CPU is met with a unrecoverable fatal error") { } +}; + class OperandType; class DecoderDataAccess @@ -38,6 +43,8 @@ class DecoderDataAccess public SysdarftCursesUI { protected: + explicit DecoderDataAccess(const uint64_t memory) : SysdarftCPUMemoryAccess(memory) { } + template < typename DataType > DataType pop_code_and_inc_ip() { @@ -177,7 +184,7 @@ class SYSDARFT_EXPORT_SYMBOL SysdarftCPUInterruption : public DecoderDataAccess * [0x13] NEW LINE * [0x14] GET INPUT, INPUT == EXR0 * [0x15] GET CURSOR POSITION POSITION == EXR0 - * [0x16] + * [0x16] GET SYSTEM HARDWARE INFO * [0x17] * [0x18] * [0x19] @@ -202,12 +209,15 @@ class SYSDARFT_EXPORT_SYMBOL SysdarftCPUInterruption : public DecoderDataAccess void do_interruption_newline_0x13(); void do_interruption_getinput_0x14(); void do_interruption_cur_pos_0x15(); + void do_get_system_hardware_info_0x16(); protected: std::atomic hd_int_flag = false; void do_interruption(uint64_t code); void do_iret(); + + explicit SysdarftCPUInterruption(const uint64_t memory) : DecoderDataAccess(memory) { } }; class SYSDARFT_EXPORT_SYMBOL SysdarftCPUInstructionDecoder : public SysdarftCPUInterruption @@ -224,6 +234,8 @@ class SYSDARFT_EXPORT_SYMBOL SysdarftCPUInstructionDecoder : public SysdarftCPUI }; ActiveInstructionType pop_instruction_from_ip_and_increase_ip(); + + explicit SysdarftCPUInstructionDecoder(const uint64_t total_memory) : SysdarftCPUInterruption(total_memory) { } }; #endif //SYSDARFTCPUINSTRUCTIONDECODER_H diff --git a/src/include/SysdarftDisks.h b/src/include/SysdarftDisks.h new file mode 100644 index 000000000..76124c917 --- /dev/null +++ b/src/include/SysdarftDisks.h @@ -0,0 +1,85 @@ +#ifndef SYSDARFTHARDDISK_H +#define SYSDARFTHARDDISK_H + +#include +#include + +#define FDA_REG_SIZE (0x116) +#define FDA_REG_START_SEC (0x117) +#define FDA_REG_SEC_COUNT (0x118) +#define FDA_CMD_REQUEST_RD (0x119) +#define FDA_CMD_REQUEST_WR (0x11A) + +#define FDB_REG_SIZE (0x126) +#define FDB_REG_START_SEC (0x127) +#define FDB_REG_SEC_COUNT (0x128) +#define FDB_CMD_REQUEST_RD (0x129) +#define FDB_CMD_REQUEST_WR (0x12A) + +#define HDD_REG_SIZE (0x136) +#define HDD_REG_START_SEC (0x137) +#define HDD_REG_SEC_COUNT (0x138) +#define HDD_CMD_REQUEST_RD (0x139) +#define HDD_CMD_REQUEST_WR (0x13A) + +class SysdarftDiskError final : public SysdarftDeviceIOError { +public: + explicit SysdarftDiskError(const std::string & msg) : SysdarftDeviceIOError(msg) { } +}; + +template < unsigned REG_SIZE, + unsigned REG_START_SEC, + unsigned REG_SEC_COUNT, + unsigned CMD_REQUEST_RD, + unsigned CMD_REQUEST_WR > +class SYSDARFT_EXPORT_SYMBOL SysdarftDiskImager : public SysdarftExternalDeviceBaseClass +{ +private: + std::fstream _sysdarftHardDiskFile; + uint64_t start_sector = 0; + uint64_t sector_count = 0; + +public: + explicit SysdarftDiskImager(const std::string & file_name); + bool request_read(uint64_t) override; + bool request_write(uint64_t) override; +}; + +class SYSDARFT_EXPORT_SYMBOL SysdarftHardDisk final : public SysdarftDiskImager + < HDD_REG_SIZE, + HDD_REG_START_SEC, + HDD_REG_SEC_COUNT, + HDD_CMD_REQUEST_RD, + HDD_CMD_REQUEST_WR > +{ +public: + explicit SysdarftHardDisk(const std::string & file_name) : SysdarftDiskImager(file_name) { } +}; + +class SYSDARFT_EXPORT_SYMBOL SysdarftFloppyDiskA final : public SysdarftDiskImager + < FDA_REG_SIZE, + FDA_REG_START_SEC, + FDA_REG_SEC_COUNT, + FDA_CMD_REQUEST_RD, + FDA_CMD_REQUEST_WR > +{ +public: + explicit SysdarftFloppyDiskA(const std::string & file_name) : SysdarftDiskImager(file_name) { } +}; + +class SYSDARFT_EXPORT_SYMBOL SysdarftFloppyDiskB final : public SysdarftDiskImager + < FDB_REG_SIZE, + FDB_REG_START_SEC, + FDB_REG_SEC_COUNT, + FDB_CMD_REQUEST_RD, + FDB_CMD_REQUEST_WR > +{ +public: + explicit SysdarftFloppyDiskB(const std::string & file_name) : SysdarftDiskImager(file_name) { } +}; + +std::streamoff SYSDARFT_EXPORT_SYMBOL getFileSize(std::fstream&); + +#include "SysdarftDisks.inl" + +#endif //SYSDARFTHARDDISK_H diff --git a/src/include/SysdarftDisks.inl b/src/include/SysdarftDisks.inl new file mode 100644 index 000000000..1bd09072c --- /dev/null +++ b/src/include/SysdarftDisks.inl @@ -0,0 +1,139 @@ +#ifndef SYSDARFTDISKS_INL +#define SYSDARFTDISKS_INL + +#include "SysdarftDisks.h" + +template < unsigned REG_SIZE, + unsigned REG_START_SEC, + unsigned REG_SEC_COUNT, + unsigned CMD_REQUEST_RD, + unsigned CMD_REQUEST_WR > +SysdarftDiskImager < REG_SIZE, REG_START_SEC, REG_SEC_COUNT, CMD_REQUEST_RD, CMD_REQUEST_WR > :: +SysdarftDiskImager(const std::string &file_name) +{ + _sysdarftHardDiskFile.open(file_name); + if (!_sysdarftHardDiskFile.is_open()) { + throw SysdarftDiskError("Cannot open file " + file_name); + } + + device_buffer.emplace(REG_SIZE, ControllerDataStream()); + device_buffer.emplace(REG_START_SEC, ControllerDataStream()); + device_buffer.emplace(REG_SEC_COUNT, ControllerDataStream()); + device_buffer.emplace(CMD_REQUEST_RD, ControllerDataStream()); + device_buffer.emplace(CMD_REQUEST_WR, ControllerDataStream()); +} + +template < unsigned REG_SIZE, + unsigned REG_START_SEC, + unsigned REG_SEC_COUNT, + unsigned CMD_REQUEST_RD, + unsigned CMD_REQUEST_WR > +bool +SysdarftDiskImager < REG_SIZE, REG_START_SEC, REG_SEC_COUNT, CMD_REQUEST_RD, CMD_REQUEST_WR > :: +request_read(const uint64_t port) +{ + const uint64_t size = getFileSize(_sysdarftHardDiskFile); + + if (port == REG_SIZE) + { + device_buffer.at(port).push(size); + return true; + } + else if (port == CMD_REQUEST_RD) + { + if (const uint64_t ops_end_sector = (start_sector + sector_count) * 512; + ops_end_sector > size) + { + return false; + } + + const uint64_t start_off = start_sector * 512; + const uint64_t length = sector_count * 512; + + if (length == 0 || start_off + length > size) { + return false; + } + + // Seek to the specified offset + _sysdarftHardDiskFile.seekg(static_cast(start_off), std::ios::beg); + if (!_sysdarftHardDiskFile) { + return false; + } + + auto & buffer = device_buffer.at(port).device_buffer; + buffer.resize(length); + + // Read 'length' bytes from the file + _sysdarftHardDiskFile.read((char*)buffer.data(), static_cast(length)); + + if (const std::streamsize bytesRead = _sysdarftHardDiskFile.gcount(); + bytesRead < static_cast(length)) + { + return false; + } + + return true; + } + + return false; +} + +template < unsigned REG_SIZE, + unsigned REG_START_SEC, + unsigned REG_SEC_COUNT, + unsigned CMD_REQUEST_RD, + unsigned CMD_REQUEST_WR > +bool +SysdarftDiskImager < REG_SIZE, REG_START_SEC, REG_SEC_COUNT, CMD_REQUEST_RD, CMD_REQUEST_WR > :: +request_write(const uint64_t port) +{ + const uint64_t size = getFileSize(_sysdarftHardDiskFile); + if (port == REG_START_SEC) + { + start_sector = device_buffer.at(port).pop(); + return true; + } + else if (port == REG_SEC_COUNT) + { + sector_count = device_buffer.at(port).pop(); + return true; + } + else if (port == CMD_REQUEST_WR) + { + if (const uint64_t ops_end_sector = (start_sector + sector_count) * 512; + ops_end_sector > size) + { + return false; + } + + const uint64_t start_off = start_sector * 512; + const uint64_t length = sector_count * 512; + if (length == 0 || start_off + length > size) { + return false; + } + + auto & buffer = device_buffer.at(port).device_buffer; + + if (length != buffer.size()) { + return false; + } + + // Seek to the specified offset + _sysdarftHardDiskFile.seekp(static_cast(start_off), std::ios::beg); + if (!_sysdarftHardDiskFile) { + return false; + } + + _sysdarftHardDiskFile.write((char*)buffer.data(), static_cast(length)); + if (!_sysdarftHardDiskFile) { + return false; + } + + buffer.clear(); + return true; + } + + return false; +} + +#endif //SYSDARFTDISKS_INL diff --git a/src/include/SysdarftHardDisk.h b/src/include/SysdarftHardDisk.h deleted file mode 100644 index b6307d12f..000000000 --- a/src/include/SysdarftHardDisk.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef SYSDARFTHARDDISK_H -#define SYSDARFTHARDDISK_H - -#include -#include - -#define HDD_REG_SIZE (0x136) -#define HDD_REG_START_SEC (0x137) -#define HDD_REG_SEC_COUNT (0x138) -#define HDD_CMD_REQUEST_RD (0x139) -#define HDD_CMD_REQUEST_WR (0x13A) - -class SYSDARFT_EXPORT_SYMBOL SysdarftHardDisk final : public SysdarftExternalDeviceBaseClass -{ -private: - std::fstream _sysdarftHardDiskFile; - uint64_t start_sector = 0; - uint64_t sector_count = 0; - -public: - explicit SysdarftHardDisk(const std::string & file_name); - bool request_read(uint64_t) override; - bool request_write(uint64_t) override; -}; - -#endif //SYSDARFTHARDDISK_H diff --git a/src/include/SysdarftIOHub.h b/src/include/SysdarftIOHub.h index bd772065c..d5d18b56f 100644 --- a/src/include/SysdarftIOHub.h +++ b/src/include/SysdarftIOHub.h @@ -7,6 +7,17 @@ #include #include +class SysdarftNoSuchDevice final : public SysdarftBaseError +{ +public: + explicit SysdarftNoSuchDevice(const std::string& msg) : SysdarftBaseError("No such device: " + msg) { } +}; + +class SysdarftDeviceIOError : public SysdarftBaseError { +public: + explicit SysdarftDeviceIOError(const std::string& msg) : SysdarftBaseError("Device I/O Error: " + msg) { } +}; + class ControllerDataStream { public: std::vector < uint8_t > device_buffer; @@ -46,11 +57,6 @@ class SysdarftExternalDeviceBaseClass virtual bool request_write(uint64_t /* IO Port */) { return false; } }; -class SysdarftDeviceIOError final : public SysdarftBaseError { -public: - explicit SysdarftDeviceIOError(const std::string& msg) : SysdarftBaseError("Device I/O Error: " + msg) { } -}; - class SYSDARFT_EXPORT_SYMBOL SysdarftIOHub { private: diff --git a/src/include/SysdarftInstructionExec.h b/src/include/SysdarftInstructionExec.h index acb87c80f..10df51546 100644 --- a/src/include/SysdarftInstructionExec.h +++ b/src/include/SysdarftInstructionExec.h @@ -82,6 +82,8 @@ class SYSDARFT_EXPORT_SYMBOL SysdarftCPUInstructionExecutor : public SysdarftCPU // Misc add_instruction_exec(nop); add_instruction_exec(hlt); + add_instruction_exec(igni); + add_instruction_exec(alwi); // Arithmetic add_instruction_exec(add); @@ -141,7 +143,7 @@ class SYSDARFT_EXPORT_SYMBOL SysdarftCPUInstructionExecutor : public SysdarftCPU protected: // initialization - SysdarftCPUInstructionExecutor(); + explicit SysdarftCPUInstructionExecutor(uint64_t memory); // general code execution void execute(__uint128_t timestamp); diff --git a/src/include/SysdarftMemory.h b/src/include/SysdarftMemory.h index 57bd9cedd..b916a5315 100644 --- a/src/include/SysdarftMemory.h +++ b/src/include/SysdarftMemory.h @@ -35,9 +35,9 @@ class SYSDARFT_EXPORT_SYMBOL SysdarftCPUMemoryAccess protected: std::mutex MemoryAccessMutex; std::vector < std::array < uint8_t, BLOCK_SIZE > > Memory; - std::atomic TotalMemory = 32 * 1024 * 1024; // 32MB Memory + std::atomic TotalMemory = 0; // 32MB Memory - SysdarftCPUMemoryAccess(); + explicit SysdarftCPUMemoryAccess(uint64_t totalMemory); void read_memory(uint64_t address, char * _dest, uint64_t size); void write_memory(uint64_t address, const char* _source, uint64_t size); diff --git a/tests/example.sysasm b/tests/example.sysasm index ed344c550..1abd6eb7c 100644 --- a/tests/example.sysasm +++ b/tests/example.sysasm @@ -63,3 +63,4 @@ _int3: iret _stack_frame: +.resvb < 16 - ( (@ - @@) % 16 ) > diff --git a/tests/test.arithmetic.cpp b/tests/test.arithmetic.cpp index eb0ab8efc..fcfc067f5 100644 --- a/tests/test.arithmetic.cpp +++ b/tests/test.arithmetic.cpp @@ -35,7 +35,7 @@ class Exec final : public SysdarftCPUInstructionExecutor { log("\n\n\n"); } - Exec() + Exec() : SysdarftCPUInstructionExecutor(32 * 1024 * 1024) { bindBreakpointHandler(this, &Exec::h_breakpoint_handler); bindIsBreakHere(this, &Exec::h_is_break_here); diff --git a/tests/test.controlflow.cpp b/tests/test.controlflow.cpp index e61583c16..879f6fbcd 100644 --- a/tests/test.controlflow.cpp +++ b/tests/test.controlflow.cpp @@ -37,7 +37,7 @@ class Exec final : public SysdarftCPUInstructionExecutor { log("\n\n\n"); } - Exec() + Exec() : SysdarftCPUInstructionExecutor(32 * 1024 * 1024) { bindBreakpointHandler(this, &Exec::h_breakpoint_handler); bindIsBreakHere(this, &Exec::h_is_break_here); diff --git a/tests/test.dataTsf.cpp b/tests/test.dataTsf.cpp index 196fa7b51..4b7b8b5a3 100644 --- a/tests/test.dataTsf.cpp +++ b/tests/test.dataTsf.cpp @@ -35,7 +35,7 @@ class Exec final : public SysdarftCPUInstructionExecutor { log("\n\n\n"); } - Exec() + Exec() : SysdarftCPUInstructionExecutor(32 * 1024 * 1024) { bindBreakpointHandler(this, &Exec::h_breakpoint_handler); bindIsBreakHere(this, &Exec::h_is_break_here); diff --git a/tests/test.decode.cpp b/tests/test.decode.cpp index 6d68b4a42..7cfda5748 100644 --- a/tests/test.decode.cpp +++ b/tests/test.decode.cpp @@ -4,7 +4,7 @@ class CodeBase : public SysdarftCPUInstructionDecoder { public: - CodeBase() + CodeBase() : SysdarftCPUInstructionDecoder(32 * 1024 * 1024) { std::vector buffer; encode_instruction(buffer, "add .64bit <*2&64($(255), %FER14, $(4))>, <$(114514)>"); diff --git a/tests/test.executor.cpp b/tests/test.executor.cpp index e4f766dcd..6b56543d5 100644 --- a/tests/test.executor.cpp +++ b/tests/test.executor.cpp @@ -36,7 +36,7 @@ class Exec final : public SysdarftCPUInstructionExecutor { show_context(); } - Exec() + Exec() : SysdarftCPUInstructionExecutor(32 * 1024 * 1024) { bindBreakpointHandler(this, &Exec::h_breakpoint_handler); bindIsBreakHere(this, &Exec::h_is_break_here); diff --git a/tests/test.io.cpp b/tests/test.io.cpp index c12287391..6cd7f7c39 100644 --- a/tests/test.io.cpp +++ b/tests/test.io.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include class Exec final : public SysdarftCPUInstructionExecutor { public: @@ -38,7 +38,7 @@ class Exec final : public SysdarftCPUInstructionExecutor { log("\n\n\n"); } - Exec() + Exec() : SysdarftCPUInstructionExecutor(32 * 1024 * 1024) { bindBreakpointHandler(this, &Exec::h_breakpoint_handler); bindIsBreakHere(this, &Exec::h_is_break_here); diff --git a/tests/test.lgAbit.cpp b/tests/test.lgAbit.cpp index 105f0236d..53d859a06 100644 --- a/tests/test.lgAbit.cpp +++ b/tests/test.lgAbit.cpp @@ -35,7 +35,7 @@ class Exec final : public SysdarftCPUInstructionExecutor { log("\n\n\n"); } - Exec() + Exec() : SysdarftCPUInstructionExecutor(32 * 1024 * 1024) { bindBreakpointHandler(this, &Exec::h_breakpoint_handler); bindIsBreakHere(this, &Exec::h_is_break_here); diff --git a/tests/test.memory.cpp b/tests/test.memory.cpp index 6174f3217..9a7400d2d 100644 --- a/tests/test.memory.cpp +++ b/tests/test.memory.cpp @@ -12,7 +12,8 @@ class Memory final : public SysdarftCPUMemoryAccess { public: - Memory() = default; + Memory() : SysdarftCPUMemoryAccess(32 * 1024 * 1024) { } + const uint64_t TotalMemory = SysdarftCPUMemoryAccess::TotalMemory; // Random write helper diff --git a/tests/test.operand.cpp b/tests/test.operand.cpp index 5c6fe0040..2e42233d2 100644 --- a/tests/test.operand.cpp +++ b/tests/test.operand.cpp @@ -4,7 +4,7 @@ class CodeBase : public DecoderDataAccess { public: - CodeBase() + CodeBase() : DecoderDataAccess(32 * 1024 * 1024) { std::vector buffer; encode_instruction(buffer, "mov .64bit <*1&64($(0), $(0), $(0))>, <%FER6>"); diff --git a/tests/test.preprocessor.cpp b/tests/test.preprocessor.cpp index 2ffb3eb06..88297efaa 100644 --- a/tests/test.preprocessor.cpp +++ b/tests/test.preprocessor.cpp @@ -4,11 +4,11 @@ #include #include #include -#include +#include class Exec final : public SysdarftCPUInstructionExecutor { public: - Exec() + Exec() : SysdarftCPUInstructionExecutor(32 * 1024 * 1024) { SysdarftCursesUI::initialize(); device_list.emplace_back(std::make_unique("hda.img")); @@ -21,7 +21,7 @@ class Exec final : public SysdarftCPUInstructionExecutor { write_memory(off++, (char*)&c, 1); } - for (int i = 0; i < 400000; i++) { + for (int i = 0; i < 80000; i++) { execute(0); } } @@ -35,5 +35,4 @@ class Exec final : public SysdarftCPUInstructionExecutor { int main() { Exec base; - sleep(1); }