diff --git a/CMakeLists.txt b/CMakeLists.txt index fde52c981..01fe63ceb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -370,6 +370,7 @@ add_executable(sysdarft-system src/SysdarftConsole/ShowBreakpoint.cpp src/SysdarftConsole/Stepi.cpp src/SysdarftConsole/Watcher.cpp + src/SysdarftConsole/logo.c ) target_include_directories(sysdarft-system PUBLIC ${ASIO_INCLUDE_DIR} src/include src/include/crow) target_link_libraries(sysdarft-system PUBLIC Sysdarft nlohmann_json::nlohmann_json) diff --git a/README.md b/README.md index 6c87092d6..1523517ab 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Sysdarft -![Lines of Code](https://img.shields.io/badge/ProjectLines-46524-cyan) -![Size of Code](https://img.shields.io/badge/ProjectSize-5128%20K-yellow) +![Lines of Code](https://img.shields.io/badge/ProjectLines-62209-cyan) +![Size of Code](https://img.shields.io/badge/ProjectSize-9216%20K-yellow) [![Automated CMake Test Workflow](https://github.com/Anivice/Sysdarft/actions/workflows/CMake_GitHub_Action.yml/badge.svg)](https://github.com/Anivice/Sysdarft/actions/workflows/CMake_GitHub_Action.yml) Sysdarft is a hypothetical binary 64bit architecture. diff --git a/doc/Sysdarft.md b/doc/Sysdarft.md index 331f0f7b4..b8b4aa230 100644 --- a/doc/Sysdarft.md +++ b/doc/Sysdarft.md @@ -13,12 +13,13 @@ This notation is described below. In illustrations of data structures in memory, unlike Intel architecture manuals, -smaller addresses appear toward the top of the figure; -addresses increase toward the bottom. -Bit positions are numbered from right to left, -with the leftest one being LSB (Least Significant Bit) and the rightest one being MSB (Most Significant Bit). -The numerical value of a set bit is equal to two raised to the power of the bit position. -This is similar to the illustration of all Intel Architectures as well as that of most ARM and RISC. +smaller addresses appear toward the *top* of the figure; +addresses increase toward the *bottom*. +Similarly, however, +bit positions are numbered from right to left, +with the leftmost bit being LSB (Least Significant Bit) and the rightmost bit being MSB (Most Significant Bit), +and the numerical value of a set bit is equal to two raised to the power of the bit position, +same ways identical to Intel architectures as well as that of most ARM and RISC. ![Bit and Byte Order](BitAndByteOrder.png) @@ -42,7 +43,18 @@ Danny Cohen adopted the term endianness from Jonathan Swift's Gulliver's Travels where Swift described a conflict between sects of Lilliputians divided into those breaking the shell of a boiled egg from the big end or from the little end. Little-endian system recognizes that the least significant byte is the byte whose address is the smallest in memory, -and data is traversed from the smallest address towards bigger ones. +and data is traversed from the smallest address towards larger ones. + +## Hexadecimal and Binary Numbers + +Base 16 (hexadecimal) numbers are represented by a string of hexadecimal digits +which are characters from the following set: +`0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `A`, `B`, `C`, `D`, `E`, `F`, +preceded by `0x` as an indication (for example, `0xFBCA23`). +Base 2 (binary) numbers are represented by a string of `1`s and `0`s, followed by a binary suffix $n_2$ +(for example, $1010_2$). +The $n_2$ designation is only used in situations where confusion as to the type of number might arise +[@Intel64AndIA32ArchitecturesSoftwareDevelopersManualCombinedVolumes]. ## Processor @@ -50,7 +62,7 @@ Central Processing Unit, or CPU, is a processor that performs operations on an external data source, usually memory or some other data stream[@OxfordEnglishDictionary]. -## Registers and Memory +## Registers *Registers are primitives used in hardware design that are also visible to the programmer when the computer is completed, @@ -58,11 +70,27 @@ so you can think of registers as the bricks of computer construction.* [@ComputerOrganizationAndDesign] CPU relies on registers to perform most of the tasks. -Registers are fix-sized data storages inside the CPU +Registers are fix-sized data storages inside the CPU. + +## Memory + +Memory is accessible space outside the CPU. +The amount of memory a system can access is called *Accessible Memory*. +The maximum memory space a typical $64$-bit system can access is named *Addressable Memory*. +The minimum memory unit is called *byte*. +A typical single byte consists of $8$ binary bits. +Each byte is assigned an address in memory space, +from `0x0000000000000000` to the maximum value `0xFFFFFFFFFFFFFFFF`. -## Reserved Bits +## Exceptions -Part of the CPU Register +An exception is an event that typically occurs when an instruction causes an error +[@Intel64AndIA32ArchitecturesSoftwareDevelopersManualCombinedVolumes]. +An exception is a specific error type. +For example, an attempt to divide by zero causes an exception. +Reporting an exception is called *throw*, +or *an exception of `DIV/0` (divided by `0`) being thrown*, +which typically aborts any process followed by the position where exception occurs. # **CPU Registers** @@ -89,7 +117,7 @@ mentioned above, named `%FER0`, `%FER1`, ..., `%FER15`. Half-extended registers, or HERs, are $32\text{-bit}$ registers for general purposes. There are eight HERs, named `HER0`, `HER1`, ..., `HER7`. -The eight $32\text{-bit}$ registers are actually derived from the first four $64\text{-bit}$ registers, +The eight $32\text{-bit}$ registers are actually split from the first four $64\text{-bit}$ registers, specifically `FER0` through `FER3`. This means that modifying the contents of *either* of the $32\text{-bit}$ or $64\text{-bit}$ versions of these registers will affect content of *both* of the $32\text{-bit}$ and $64\text{-bit}$ registers, @@ -100,14 +128,17 @@ as they share the same underlying space. Extended registers[^EXR], or EXRs, are $16\text{-bit}$ registers used for general purposes. There are 8 EXRs, named `EXR0`, `EXR1`, ..., `EXR7`. Similar to *Half-Extended Registers*, -these $16\text{-bit}$ registers are derived from the first four $32\text{-bit}$ registers, +these $16\text{-bit}$ registers are split from the first four $32\text{-bit}$ registers, specifically `HER0` through `HER3`. [^EXR]: -The reason why $16\text{-bit}$ registers are called *Extended Registers* -is that they extend the original $8\text{-bit}$ registers. -In contrast, $32\text{-bit}$ registers are referred to as *Half-Extended Registers* -is because they are half the size of *Fully Extended Registers*, which are $64\text{-bit}$ in width. +The reason why $16\text{-bit}$ registers are referred to as *Extended Registers* +while $32\text{-bit}$ registers are *Half-Extended Registers* +is that Extended Registers extend the original $8\text{-bit}$ registers +while the *Half* in Half-Extended Registers is an indication of their sizes being +half the size of *Fully Extended Registers*, which are $64\text{-bit}$ in width. +This naming crisis arises due to the lack of communication during the development, +and the scope of the project has grown so enormous that revising the code base is painful and seemingly unnecessary. Similarly, this means that modifying the contents of either type of registers will affect content inside @@ -150,10 +181,9 @@ $\text{Physical Address} = \text{Segment Address} \ll 4 + \text{Segment Offset}$ *where* -- *Physical Address* is an address seen by the memory unit, commonly referred to as a physical address - [@OperatingSystemConcepts]. +- *Physical Address* is an address seen by the memory unit[@OperatingSystemConcepts]. - *Segment Address* being the address of the segment, which is its physical address shifting four bits - to the right ($\text{Physical Address} \over 2^{4}$). + to the right ($\text{Physical Address} \over 2^{4}$)[@INTEL80386PROGRAMMERSREFERENCEMANUAL]. - *Segment Offset* being the length from the current position to the start of the segment. - *$x \ll n$* being the bit left shifting operation, value $x$ shifting $n$ bits towards the left ($x \times 2^n$). @@ -167,18 +197,21 @@ and this is program relocation. Before the discussion of program relocation, the concepts of *Absolute Code* and *Position-Independent Code* (PIC) need to be established first. +#### Absolute Code Absolute code, and an absolute object module, is code that...runs only at a specific location in memory. The Loader loads an absolute object module only into the specific location the module must occupy[@iRMX86ApplicationLoaderReferenceManual]. +#### Position-Independent Code Position-independent code (commonly referred to as PIC) differs from absolute code in that PIC can be loaded into any memory location. The advantage of PIC over absolute code is that PIC does not require you to reserve a specific block of memory[@iRMX86ApplicationLoaderReferenceManual]. -If the code is BIOS, then its position and size in the memory is static and known. -However, As a user program, its memory location is arbitrary and should not be predetermined. +If the code is PIC, like BIOS, then its position and size in the memory is static and known. +However, As a user program, which would not be able to and should not assume which specific part of memory is free, +as its location in memory is arbitrary and should not be predetermined. The operating system loads it wherever it deems appropriate. Using absolute code will eliminate the flexibility of user programs; thus, position-independent code should be employed instead. @@ -202,7 +235,7 @@ an unintended or erroneous jump in a program's execution flow due to attempting to return from a subroutine after the stack pointer or activation record have been corrupted or incorrect computation of the destination address of a jump or subroutine call [@ComputerOrganization], -or in this case, damaging the segment address resulting in incorrect computation +or in this case, altering and possibly damaging the segment address resulting in incorrect computation of the next instruction location in memory. Therefore, `%CB` is usually not modified directly but rather changed indirectly through operations like a long call or long jump. @@ -211,8 +244,8 @@ like a long call or long jump. There are four registers that can be used together to reference two data segments: Data Base (`%DB`), Data Pointer (`%DP`), Extended Base (`%EB`), and Extended Pointer (`%EP`). -These registers function in pairs—`%DB` with `%DP` and `%EB` with `%EP`—to address and access -two data segments. +These registers function in pairs, i.e., `%DB` with `%DP` and `%EB` with `%EP`, to address and access +two data segments simultaneously. ### Stack Management @@ -877,7 +910,7 @@ until an internal interrupt wake itself. # **Appendix B: Examples** -## Example A, Disk I/O +## **Example A, Disk I/O** ``` 00000000000C1800: 30 01 64 A2 02 64 E3 18 JMP <%CB>, <$(0xC18E3)> @@ -974,7 +1007,11 @@ until an internal interrupt wake itself. 00000000000C1A35: 00 NOP ``` -## Example B, Real Time Clock +# Result of Example A + +![Disk I/O, Disk Being an ASCII Text File of a Disassembled BIOS Code](diskio.png) + +# Example B, Real Time Clock ``` 00000000000C1800: 20 64 01 64 A1 02 64 FF MOV .64bit <%SP>, <$(0xFFF)> @@ -1059,4 +1096,8 @@ until an internal interrupt wake itself. 00000000000C1A1D: 00 NOP ``` +# Result of Example B + +![Real Time Clock, Number Being UNIX Timestamp, With Keyboard Interrupt Invoked Deliberately](rtc.png) + # References diff --git a/doc/diskio.png b/doc/diskio.png new file mode 100644 index 000000000..328f3b96a Binary files /dev/null and b/doc/diskio.png differ diff --git a/doc/references.bib b/doc/references.bib index 5f7db6ad1..2dedac4dc 100644 --- a/doc/references.bib +++ b/doc/references.bib @@ -123,3 +123,10 @@ @book{OnHolyWarsAndAPleaForPeace year = {1981}, publisher = {IEEE Computer} } + +@book{INTEL80386PROGRAMMERSREFERENCEMANUAL, + title = {INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986}, + author = {Intel}, + year = {1986}, + publisher = {© INTEL CORPORATION} +} diff --git a/doc/rtc.png b/doc/rtc.png new file mode 100644 index 000000000..3ff86e569 Binary files /dev/null and b/doc/rtc.png differ diff --git a/src/SysdarftConsole/SysdarftMain.cpp b/src/SysdarftConsole/SysdarftMain.cpp index a3beb8a08..3748e3a65 100644 --- a/src/SysdarftConsole/SysdarftMain.cpp +++ b/src/SysdarftConsole/SysdarftMain.cpp @@ -4,6 +4,8 @@ #include #include +extern "C" void printLogo(); + void print_help(const char *program_name) { std::stringstream ss; @@ -60,6 +62,7 @@ void print_help(const char *program_name) void print_version() { + printLogo(); std::cout << "Sysdarft 64bit Hypothetical Architecture Version " << SYSDARFT_VERSION << std::endl << SYSDARFT_INFORMATION << std::endl; diff --git a/src/SysdarftConsole/logo.c b/src/SysdarftConsole/logo.c new file mode 100644 index 000000000..50dd45d1d --- /dev/null +++ b/src/SysdarftConsole/logo.c @@ -0,0 +1,80 @@ +/*** + * + * dddddddd + * SSSSSSSSSSSSSSS d::::::d ffffffffffffffff tttt + * SS:::::::::::::::S d::::::d f::::::::::::::::f ttt:::t + * S:::::SSSSSS::::::S d::::::d f::::::::::::::::::f t:::::t + * S:::::S SSSSSSS d:::::d f::::::fffffff:::::f t:::::t + * S:::::S yyyyyyy yyyyyyy ssssssssss ddddddddd:::::d aaaaaaaaaaaaa rrrrr rrrrrrrrr f:::::f ffffffttttttt:::::ttttttt + * S:::::S y:::::y y:::::y ss::::::::::s dd::::::::::::::d a::::::::::::a r::::rrr:::::::::r f:::::f t:::::::::::::::::t + * S::::SSSS y:::::y y:::::y ss:::::::::::::s d::::::::::::::::d aaaaaaaaa:::::a r:::::::::::::::::r f:::::::ffffff t:::::::::::::::::t + * SS::::::SSSSS y:::::y y:::::y s::::::ssss:::::sd:::::::ddddd:::::d a::::a rr::::::rrrrr::::::r f::::::::::::f tttttt:::::::tttttt + * SSS::::::::SS y:::::y y:::::y s:::::s ssssss d::::::d d:::::d aaaaaaa:::::a r:::::r r:::::r f::::::::::::f t:::::t + * SSSSSS::::S y:::::y y:::::y s::::::s d:::::d d:::::d aa::::::::::::a r:::::r rrrrrrr f:::::::ffffff t:::::t + * S:::::S y:::::y:::::y s::::::s d:::::d d:::::d a::::aaaa::::::a r:::::r f:::::f t:::::t + * S:::::S y:::::::::y ssssss s:::::s d:::::d d:::::d a::::a a:::::a r:::::r f:::::f t:::::t tttttt + * SSSSSSS S:::::S y:::::::y s:::::ssss::::::sd::::::ddddd::::::dda::::a a:::::a r:::::r f:::::::f t::::::tttt:::::t + * S::::::SSSSSS:::::S y:::::y s::::::::::::::s d:::::::::::::::::da:::::aaaa::::::a r:::::r f:::::::f tt::::::::::::::t + * S:::::::::::::::SS y:::::y s:::::::::::ss d:::::::::ddd::::d a::::::::::aa:::a r:::::r f:::::::f tt:::::::::::tt + * SSSSSSSSSSSSSSS y:::::y sssssssssss ddddddddd ddddd aaaaaaaaaa aaaa rrrrrrr fffffffff ttttttttttt + * y:::::y + * y:::::y + * y:::::y + * y:::::y + * yyyyyyy + * + * + */ + +#include + +#define RED "\x1b[31;1m" +#define GREEN "\x1b[32;1m" +#define YELLOW "\x1b[33;1m" +#define BLUE "\x1b[34;1m" +#define WHITE "\x1b[37;1m" +#define GREY "\x1b[90;1m" +#define RESET "\x1b[0m" + +static constexpr char logo[] = +" * dddddddd *\n" +" * SSSSSSSSSSSSSSS d::::::d ffffffffffffffff tttt *\n" +" * SS:::::::::::::::S d::::::d f::::::::::::::::f ttt:::t *\n" +" * S:::::SSSSSS::::::S d::::::d f::::::::::::::::::f t:::::t *\n" +" * S:::::S SSSSSSS d:::::d f::::::fffffff:::::f t:::::t *\n" +" * S:::::S yyyyyyy yyyyyyy ssssssssss ddddddddd:::::d aaaaaaaaaaaaa rrrrr rrrrrrrrr f:::::f ffffffttttttt:::::ttttttt *\n" +" * S:::::S y:::::y y:::::y ss::::::::::s dd::::::::::::::d a::::::::::::a r::::rrr:::::::::r f:::::f t:::::::::::::::::t *\n" +" * S::::SSSS y:::::y y:::::y ss:::::::::::::s d::::::::::::::::d aaaaaaaaa:::::a r:::::::::::::::::r f:::::::ffffff t:::::::::::::::::t *\n" +" * SS::::::SSSSS y:::::y y:::::y s::::::ssss:::::sd:::::::ddddd:::::d a::::a rr::::::rrrrr::::::r f::::::::::::f tttttt:::::::tttttt *\n" +" * SSS::::::::SS y:::::y y:::::y s:::::s ssssss d::::::d d:::::d aaaaaaa:::::a r:::::r r:::::r f::::::::::::f t:::::t *\n" +" * SSSSSS::::S y:::::y y:::::y s::::::s d:::::d d:::::d aa::::::::::::a r:::::r rrrrrrr f:::::::ffffff t:::::t *\n" +" * S:::::S y:::::y:::::y s::::::s d:::::d d:::::d a::::aaaa::::::a r:::::r f:::::f t:::::t *\n" +" * S:::::S y:::::::::y ssssss s:::::s d:::::d d:::::d a::::a a:::::a r:::::r f:::::f t:::::t tttttt *\n" +" * SSSSSSS S:::::S y:::::::y s:::::ssss::::::sd::::::ddddd::::::dda::::a a:::::a r:::::r f:::::::f t::::::tttt:::::t *\n" +" * S::::::SSSSSS:::::S y:::::y s::::::::::::::s d:::::::::::::::::da:::::aaaa::::::a r:::::r f:::::::f tt::::::::::::::t *\n" +" * S:::::::::::::::SS y:::::y s:::::::::::ss d:::::::::ddd::::d a::::::::::aa:::a r:::::r f:::::::f tt:::::::::::tt *\n" +" * SSSSSSSSSSSSSSS y:::::y sssssssssss ddddddddd ddddd aaaaaaaaaa aaaa rrrrrrr fffffffff ttttttttttt *\n" +" * y:::::y *\n" +" * y:::::y *\n" +" * y:::::y *\n" +" * y:::::y *\n" +" * yyyyyyy *\n" +"\n\n"; + +void printLogo() +{ + for (unsigned int i = 0; i < sizeof(logo); i++) + { + if (logo[i] != '\n') { + if (logo[i] == ' ' || logo[i] == '*') { + printf(GREY "%%" RESET); + } else if (logo[i] == ':') { + printf(WHITE "%%" RESET); + } else { + printf(BLUE "%c" RESET, logo[i]); + } + } else { + printf("%c", logo[i]); + } + } +} diff --git a/src/SysdarftCursesUI.cpp b/src/SysdarftCursesUI.cpp index 14e23bf4e..5595d28fc 100644 --- a/src/SysdarftCursesUI.cpp +++ b/src/SysdarftCursesUI.cpp @@ -70,7 +70,7 @@ void SysdarftCursesUI::start_again() void SysdarftCursesUI::ringbell() { running = true; - sound_thread_pool.emplace_back(std::thread(play_bell_sound, std::ref(running))); + sound_thread_pool.emplace_back(play_bell_sound, std::ref(running)); } void SysdarftCursesUI::cleanup()