diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index bbcbbe7d..d639adc2 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,7 +1,7 @@ --- name: Feature request about: Suggest an idea for this project -title: '' +m_title: '' labels: '' assignees: '' diff --git a/README.md b/README.md index ff9fe822..5867193c 100644 --- a/README.md +++ b/README.md @@ -53,8 +53,8 @@ Kernel Cleanup - [x] Cross-Compiler - [x] Better Scripts - [x] GUI Bug Fixes -- [ ] Better Commenting and Doxygen Documentation -- [ ] Use better c++ coding conventions +- [x] Better Commenting and Doxygen Documentation +- [x] Use better c++ coding conventions - [ ] CMAKE Build System (and maybe get it building and debugging in CLion) - [ ] Clean up all the TODOs - [ ] Rewrite Readme diff --git a/docs/Bugs.md b/docs/Bugs.md deleted file mode 100644 index ca266b95..00000000 --- a/docs/Bugs.md +++ /dev/null @@ -1,18 +0,0 @@ - -# Known Bugs -| Status | #Issue Code | Info | -|:------:|:-----------:|:-------------------------------------------------:| -| Fixing | X | Example | -| Known | | Event handlers only trigger for one event handler | -| Known | | Windows have to be weirdly clicked to resize | - - -# Annoying -Bugs that were simple to fix but took forever to find - -| Time Spent | Bug | Fix | Fix Commit | -|:----------:|:----------------------------------------:|:-------------------------------------------------:|:-----------------------------------------------------------------------------------------------:| -| 2:00 | amd network driver not sending/reciveing | - Change 0x7FF -> 0xF7FF AND write(1) -> write(2) | [Github](https://github.com/maxtyson123/max-os/commit/4a0a080a271a9bf27d9cc3701c7d32b40aa2bab3) | -| 3:44 | amd network driver not init | - PCI read/write check fail AND driver issue | [Github](https://github.com/maxtyson123/max-os/commit/4a0a080a271a9bf27d9cc3701c7d32b40aa2bab3) | - - diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 1474688c..26bb716d 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -16,7 +16,7 @@ To keep the code understanble please make sure it is formatted and reable. Addit ## We Use [GitHub Flow](https://guides.github.com/introduction/flow/index.html), So All Code Changes Happen Through Pull Requests Pull requests are the best way to propose changes to the codebase (we use [GitHub Flow](https://guides.github.com/introduction/flow/index.html)). We actively welcome your pull requests: -1. Fork the repo and create your branch from `master`. +1. Fork the repo and create your branch from `m_is_master`. 2. If you've added code that should be tested, add tests. 3. If you've changed APIs, update the documentation. 4. Ensure the test suite passes. @@ -26,12 +26,12 @@ Pull requests are the best way to propose changes to the codebase (we use [GitHu ## Report bugs using GitHub's [issues](https://github.com/briandk/transcriptase-atom/issues) We use GitHub issues to track public bugs. Report a bug by [opening a new issue](); it's that easy! -## Write bug reports with detail, background, and sample code +## write bug reports with detail, m_background, and sample code [This is an example](http://stackoverflow.com/q/12488905/180626) of a bug report someone wrote, and I think it's not a bad model. Here's [another example from Craig Hockenberry](http://www.openradar.me/11905408), an app developer whom I greatly respect. **Great Bug Reports** tend to have: -- A quick summary and/or background +- A quick summary and/or m_background - Steps to reproduce - Be specific! - Give sample code if you can. [This stackoverflow question](http://stackoverflow.com/q/12488905/180626) includes sample code that *anyone* with a base R setup can run to reproduce what I was seeing diff --git a/docs/Goals.md b/docs/Goals.md index b1539c48..dbe4bcb1 100644 --- a/docs/Goals.md +++ b/docs/Goals.md @@ -59,6 +59,6 @@ # Other - Clipboard -- Privelges (Rings, Read/Write) +- Privelges (Rings, read/write) - Apps installer - App store \ No newline at end of file diff --git a/docs/Notes.md b/docs/Notes.md index 4200dbb0..133a9d7f 100644 --- a/docs/Notes.md +++ b/docs/Notes.md @@ -8,7 +8,7 @@ These are my notes relative to various parts of the OS + [Data Send and Receive](#data-send-and-receive) + [Interrupts](#interrupts) + [Peripheral Component Interconnect (PCI)](#peripheral-component-interconnect-pci) - + [Base Address Registers](#base-address-registers) + + [base Address Registers](#base-address-registers) + [RTC Timer](#rtc-timer) - [Files And Drives](#files-and-drives) + [Hard-drives](#hard-drives) @@ -19,7 +19,7 @@ These are my notes relative to various parts of the OS + [GUI - Framework](#gui-framework) - [System Stuff](#system-stuff) + [Multitasking](#multitasking) - + [Threads](#threads) + + [m_threads](#threads) + [Dynamic Memory Management / Heap](#dynamic-memory-management-heap) + [System Calls](#system-calls) - [Networking](#networking) @@ -103,15 +103,15 @@ This relates to "pci.cpp", See also [PCI](https://www.lowlevel.eu/wiki/Periphera - The PCI controller will also tell more general information such as class and subclass IDs, which are useful for compatibility modes - Once the PCI driver is set up then it becomes easy to extend the OS as in future all that needs to be done is to get the device ID and write drivers for them -### Base Address Registers -- The solution for having multiple PCI devices (two GPUS, two screens etc…) is to have a Base Address Registers (BAR) -- Base address registers are registers in the PCI configuration space, which in a more simple way is just storing the address of a PCI device in memory -- There are two types of BARs, one is the I/O BAR, this is for devices that communicate bit by bit e.g. mouse where the position is read from the port each interrupt +### base Address Registers +- The solution for having multiple PCI devices (two GPUS, two screens etc…) is to have a base Address Registers (BAR) +- base address registers are registers in the PCI configuration space, which in a more simple way is just storing the address of a PCI device in memory +- There are two types of BARs, one is the I/O BAR, this is for devices that communicate bit by bit e.g. mouse where the m_position is read from the port each interrupt - The I/O base address register is 4 bytes long: - - Lowest bit: Type Of register: (I/O bit = 1) - - Second-lowest bit: Reserved - - Bits 3 - 16: Port Number (MUST BE MULTIPLE OF 4) -- Memory mapping is another type of BAR, this one is where the device takes x memory location, and to communicate with it just write/read from that location in memory. This is better performance-wise as the CPU can do other tasks while that is updating in the background +- Memory mapping is another type of BAR, this one is where the device takes x memory location, and to communicate with it just write/read from that location in memory. This is better performance-wise as the CPU can do other m_tasks while that is updating in the m_background - The Memory Mapping BAR is 4 bytes long: - - Lowest Bit: Type Of register: (MemMap bit = 0) - - Second and third: (00 = 32bit BAR) or (01 = 20bit BAR) or (10 = 64bit BAR) @@ -121,7 +121,7 @@ This relates to "pci.cpp", See also [PCI](https://www.lowlevel.eu/wiki/Periphera ### RTC Timer See also [RTC](https://wiki.osdev.org/RTC) - The RTC (Real Time Clock) is a device that is connected to the PCI controller and is used to keep track of time -- The ports used for the RTC are 0x70(Write) and 0x71(Read) +- The ports used for the RTC are 0x70(write) and 0x71(read) - The base frequency of the RTC is 32768 Hz, it is possible to change this frequency but that can mess with the time keeping - The RTC has a register called the CMOS RAM, which is a 128 byte long memory that can be read and written to, it stores the time and date - To get the time certain registers need to be read from te data port (0x71). Before doing this updates need to be disabled so that the time is not changed while reading it. @@ -142,7 +142,7 @@ See also [RTC](https://wiki.osdev.org/RTC) - As hard drives have been around for a long time, they are well documented and easy to implement - SATA devices are almost always compatible to ATA or AHCI (Advanced Host Controller Interface) - Using the PCI controller, SATA hard drives can be found on class id 0x01 and subclass id 0x06 -- There are two different ways of accessing a hard-drive. The first one is PIO (Programed Input Output) which is relatively simple to implement but rather slow (maxs out at 16 M/Bs) +- There are two different ways of accessing a hard-drive. The m_first_memory_chunk one is PIO (Programed Input Output) which is relatively simple to implement but rather slow (maxs out at 16 M/Bs) - The second and better way would be DMA (Direct Memory Access) , which simply just writes the data to a memory location and sends an interrupt once finished - Although it is better to read from the PCI devices list, the ports can just be hard coded - For the Implementation of PIO: @@ -155,18 +155,18 @@ See also [RTC](https://wiki.osdev.org/RTC) ### Partion Table - This OS will use the MS DOS partition table is because it is the most common and well documented. Additionalym Windows uses it and so does Linux - This partion table is simple so it is easy to implement, but it is also limited to 4 primary partitions and 1 extended partition. -- The partition table is located at the end of the first sector of the hard drive -- At the start of the first sector there is a 440 byte boot sector, which is used to boot the OS. The bootstraper will then look at the partition table to find the OS partition. +- The partition table is located at the end of the m_first_memory_chunk sector of the hard drive +- At the start of the m_first_memory_chunk sector there is a 440 byte boot sector, which is used to boot the OS. The bootstraper will then look at the partition table to find the OS partition. - After the boot sector there are 4 bytes of signature. - Then there is 2 bytes that are unused - Then there is the partition table which is 64 bytes long and has 4 entries of 16 bytes each -- At the end there are 2 magic bytes (0x55, 0xAA) which is used to check if the partition table is valid +- At the end there are 2 magic bytes (0x55, 0xAA) which is used to check if the partition table is m_valid - The structure of the partition table is as follows: - - First 1 byte: Bootable flag (0x80 = bootable, 0x00 = not bootable) (There can only be one bootable partition per hard drive) -- - Next 3 bytes: Cylinder Head Sector (CHS) address of the first sector of the partition +- - Next 3 bytes: Cylinder Head Sector (CHS) address of the m_first_memory_chunk sector of the partition - - Next 1 byte: Partition type (0x00 = empty, 0x01 = FAT12, 0x04 = FAT16, 0x05 = Extended, 0x06 = FAT16, 0x07 = NTFS, 0x0B = FAT32, 0x0C = FAT32, 0x0E = FAT16, 0x0F = Extended, 0x11 = Hidden FAT12, 0x14 = Hidden FAT16, 0x16 = Hidden FAT16, 0x1B = Hidden FAT32, 0x1C = Hidden FAT32, 0x1E = Hidden FAT16, 0x42 = MBR, 0x82 = Linux Swap, 0x83 = Linux, 0x84 = Hibernation, 0x85 = Linux Extended, 0x86 = NTFS Volume Set, 0x87 = NTFS Volume Set, 0xA5 = FreeBSD, 0xA6 = OpenBSD, 0xA9 = NetBSD, 0xB7 = BSDI, 0xB8 = BSDI Swap, 0xEB = BeOS, 0xEE = GPT, 0xEF = EFI System, 0xFB = VMWare File System, 0xFC = VMWare Swap) - - Next 3 bytes: Cylinder Head Sector (CHS) address of the last sector of the partition -- - Next 4 bytes: LBA address of the first sector of the partition +- - Next 4 bytes: LBA address of the m_first_memory_chunk sector of the partition - - Next 4 bytes: Number of sectors in the partition ### Fat 32 File System @@ -219,11 +219,11 @@ See also [FAT32](https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#FAT - The structure of a directory entry is as follows: - - First 8 bytes: File name (8.3 format) - - Next 3 bytes: File extension -- - Next 1 byte: File attributes (0x01 = Read Only, 0x02 = Hidden, 0x04 = System, 0x08 = Volume ID, 0x10 = Directory, 0x20 = Archive, 0x40 = Device, 0x80 = Unused) +- - Next 1 byte: File attributes (0x01 = read Only, 0x02 = Hidden, 0x04 = System, 0x08 = Volume ID, 0x10 = Directory, 0x20 = Archive, 0x40 = Device, 0x80 = Unused) - - Next 1 byte: Reserved (0) - - Next 7 bytes: Creation time - - Next 2 bytes: Cluster high -- - Next 4 bytes: Write time e.t.c +- - Next 4 bytes: write time e.t.c - - Next 2 bytes: Cluster low - - Next 4 bytes: File size - The cluster low and high are basicly pointers to where the directory entry is located on the hard drive or where the file is located on the hard drive @@ -235,14 +235,14 @@ See also [FAT32](https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#FAT - A cluster can only belong to one file at a time. This is useful as that means that when a file is being read or expand the operating system doesnt need to split the cluster up. # Graphics -Here are the notes on graphics for the operating system. (May need to read hardware communication first) +Here are the notes on graphics for the operating system. (May need to read hardware communication m_first_memory_chunk) ### Graphics Mode {VGA} - To write pixels and such to the screen for a GUI the graphics card needs to be put into graphics mode (grub puts it into text mode by default) - There are two ways of doing this, via the BIOS 0x13 Interrupt or by directly telling the GPU. - As the BIOS interrupt 0x13 is only for 16Bit operating system (MaxOS is 32bit) graphics mode would have to be set via the GPU - Setting graphics mode via the GPU is incredibly complicated therefore the script ['modes.c' by Chris Giese](https://files.osdev.org/mirrors/geezer/osd/graphics/modes.c) is used -- To set the graphics mode via the GPU different sets of values have to be sent to different places, for example a 320px wide by 200px height x 8-bit colour depth graphics mode would have to be set by sending these values: +- To set the graphics mode via the GPU different sets of values have to be sent to different places, for example a 320px wide by 200px m_height x 8-bit colour depth graphics mode would have to be set by sending these values: - - Misc Port: 0x63, - - Sequencer Port: 0x03, 0x01, 0x0F, 0x00, 0x0E, - - (CRTC) Cathode ray tube controller Port: 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, @@ -252,8 +252,8 @@ Here are the notes on graphics for the operating system. (May need to read hardw - However, communicating with these ports aren't that easy as there is an index port (to tell where the data should be put) and a data port (push the data) - And on the CRTC port there is special indexes and data that has to be set for it to unlocked before writing actual data (the reason it has to be unlocked is that if incorrect data is the hardware could be damaged) - Similarly, the AC port has to be reset before each index & data write. -- The VGA class that was written should have a class above that call graphicsContext which would define methods such as renderPixel(...), drawRect(...), drawLine(...), drawCircle(...) and sub-classes such as color. -- The draw functions should rely on the renderPixel function therefore in different graphics modes that are derived from that graphicsContext class can be supported. +- The VGA class that was written should have a class above that call m_graphics_context which would define methods such as render_pixel(...), drawRect(...), draw_line(...), draw_circle(...) and sub-classes such as color. +- The draw functions should rely on the render_pixel function therefore in different graphics modes that are derived from that m_graphics_context class can be supported. ### VESA - VESA is a legacy extension to VGA that allows for a higher color depth and larger screen resolutions @@ -283,16 +283,16 @@ Here are the notes on graphics for the operating system. (May need to read hardw ### GUI - Framework See also: Bresenham line algorithm (use for later) -- The GUI framework will have a base class called Widget, which should have a draw function. This draw function would get a graphicsContext and draw itself onto of it using the graphicContext's draw methods. -- Thees widgets will have parents and such, therefore their draw positions will be relative, meaning there has to be a function to get the absolute position. -- Widgets will also have a width and height, and a function to check if a co-ordinate is inside itself (used for mouse handling and such) -- To handle mouse input, the widget will use a mouse event handler and handle the events onMouseDown, onMouseMoveWidget, onMouseUpEvent. However, the mouse handler won't be on the widget itself, rather it would be on the desktop. -- This is because the mouse movement is reported in relative-ness not absolute position (desktop would store mouse position and update it based on the movement, the object can just query the x,y pos from the desktop). -- A subclass of the widget would be a composite class, which would contain an array of child widgets, and it would pass methods on to the children (e.g. the child gets drawn last so its on top) +- The GUI framework will have a base class called Widget, which should have a draw function. This draw function would get a m_graphics_context and draw itself onto of it using the graphicContext's draw methods. +- Thees widgets will have parents and such, therefore their draw positions will be relative, meaning there has to be a function to get the absolute m_position. +- Widgets will also have a m_width and m_height, and a function to check if a co-ordinate is inside itself (used for mouse handling and such) +- To handle mouse input, the widget will use a mouse event handler and handle the events onMouseDown, on_mouse_move_widget, on_mouse_up_event. However, the mouse handler won't be on the widget itself, rather it would be on the desktop. +- This is because the mouse movement is reported in relative-ness not absolute m_position (desktop would store mouse m_position and update it based on the movement, the object can just query the x,y pos from the desktop). +- A subclass of the widget would be a composite class, which would contain an array of child widgets, and it would pass methods on to the m_children (e.g. the child gets drawn last so its on m_top) - To get which widget to preform the keyEvent or mouseEvent the desktop will have a function of getting the focused widget -- The desktop will work like the composite widget, but will have to override the mouseHandler class as mouse passes movement in relative to last position (moved x pixels) so the desktop will have to translate the restiveness into absolute positions +- The desktop will work like the composite widget, but will have to override the mouseHandler class as mouse passes movement in relative to last m_position (moved x pixels) so the desktop will have to translate the restiveness into absolute positions - For better performance, instead of re-drawing the screen every time just draw it once and then when a gui object changes (e.g. moving a window) memory the object to the new state and then redraw any invalid parts (invalid is where places where there used to be the gui object) -- To draw text the "modes.c" has various 8x8 Bitmap fonts. Using these fonts a Text widget can be made that gets the characters of a string from the font and then print all the pixels in that character. +- To draw text the "modes.c" has various 8x8 Bitmap fonts. Using these fonts a Text widget can be made that gets the characters of a string from the m_font and then print all the pixels in that character. # System Stuff @@ -303,26 +303,26 @@ See also [Stack](https://wiki.osdev.org/Stack), **Note this needs better explain - Before Multitasking: A timer interrupt occurs and what happens is the processor pushes some registers on the stack (e.g. pointer to where it was executing before the interrupt). The processor then goes into the interrupt manager (see interrupts.cpp) and executes the handler for that interrupt. Once the handler has finished executing the processor then carry's on what it was executing before (hence why the pointer was pushed to the stack). - However, to do multithreading the current way of executing in the OS needs to change. First the OS will take another portion of the RAM, reserve it for multitasking, and make its own stack there for every task. - Therefore, when a task is created a memory region is made. Information for the processor is then explicitly writen into segments in that region e.g. the instruction pointer at the entry point -- Previously: the interstubs.s file pushed the current processor values (interstubs line 64: save the registers) and then pushed the stack pointer (interstubs line 80: Invoke C++ handlers) and then load register again +- Previously: the interstubs.s file pushed the current processor values (interstubs line 64: save the registers) and then pushed the stack pointer (interstubs line 80: Invoke C++ m_handlers) and then load register again - (Carrying on "Previously") The handler function would have the pointer to the stack (passed as var: esp). The return value of handle interrupt is then written into esp and then executed by processor. -- Now with multitasking the return value for the handle interrupt function would be changed to point to the top of the new task's stack. +- Now with multitasking the return value for the handle interrupt function would be changed to point to the m_top of the new task's stack. - To sum up: - - The kernel will be executing function "X" and receive an interrupt - - kernel will execute the interrupt handler - - The interrupt handler will then return a pointer to the new task - - Kernel will then execute the new task instead of executing function "X" -- To schedule processes fairly, a round-robin scheduler generally employs time-sharing, giving each job a time slot or quantum (its allowance of CPU time), and interrupting the job if it is not completed by then. The job is resumed next time a time slot is assigned to that task. If the task terminates or changes its state to waiting during its attributed time quantum, the scheduler selects the first task in the ready queue to execute +- To schedule processes fairly, a round-robin scheduler generally employs time-sharing, giving each job a time slot or quantum (its allowance of CPU time), and interrupting the job if it is not completed by then. The job is resumed next time a time slot is assigned to that task. If the task terminates or changes its state to waiting during its attributed time quantum, the scheduler selects the m_first_memory_chunk task in the ready queue to execute -### Threads +### m_threads See also: [Thread](https://wiki.osdev.org/Thread) -- A thread is a lightweight process. It is a sequence of instructions within a program that can be executed independently of other code. Threads can be created and managed by a thread library. -- Threads are often used in parallel computing, where they can be used to perform multiple tasks simultaneously. Threads are also used in multimedia, where they can be used to perform different tasks in real time. For example, a thread can be used to play a sound while another thread is used to display a graphic. -- Threads are also used in operating systems, where they can be used to perform different tasks simultaneously. For example, a thread can be used to play a sound while another thread is used to display a graphic. +- A thread is a lightweight process. It is a sequence of instructions within a program that can be executed independently of other code. m_threads can be created and managed by a thread library. +- m_threads are often used in parallel computing, where they can be used to perform multiple m_tasks simultaneously. m_threads are also used in multimedia, where they can be used to perform different m_tasks in real time. For example, a thread can be used to play a sound while another thread is used to display a graphic. +- m_threads are also used in operating systems, where they can be used to perform different m_tasks simultaneously. For example, a thread can be used to play a sound while another thread is used to display a graphic. - The main difference between a thread and a process is that threads share the same address space, while processes have separate address spaces. This means that threads can share data and code, while processes cannot. This also means that threads are faster than processes, because they do not need to be loaded into memory. - To implement threads in the OS, the kernel will have to implement a thread class. This class will have a function to create a thread, and a function to execute the thread. The thread class will also have a function to get the current thread. - The thread class will also have a function to get the current thread. This function will be used to get the current thread, and then the thread will be able to access its own stack. - Yeilding is when a thread gives up its time slice and allows another thread to run. This is done by calling the yeild function on the thread class. -- Processes and threads are different. A process is a program in execution. A thread is a component of a process. A process can have multiple threads. Threads are often used to implement concurrency within a process. Threads are also used to implement parallelism, where multiple processes can run simultaneously on a multi-core processor. +- Processes and threads are different. A process is a program in execution. A thread is a component of a process. A process can have multiple threads. m_threads are often used to implement concurrency within a process. m_threads are also used to implement parallelism, where multiple processes can run simultaneously on a multi-core processor. ### Dynamic Memory Management / Heap See also [Double Linked List](https://en.wikipedia.org/wiki/Linked_list#Doubly_linked_list) @@ -343,7 +343,7 @@ See also [Double Linked List](https://en.wikipedia.org/wiki/Linked_list#Doubly_l - - size_t : size - These Memory Chunks are just a linked list (double linked) and every chunk that has dropped from the RAM will be entered into the list, which is how the OS will keep track of used / free memory - More than one free chunk in a row is bad as it means larger data that could have had fit into those two chunks if they were combined won't be able to. This can be prevented merging a chunk with another if it is deallocated next to another un allocated chunk. -- To find memory easier see [multiboot.h](https://github.com/cstack/osdev/blob/master/multiboot.h), however I will implement my own for copyright reasons which will just use the multiboot structure +- To find memory easier see [multiboot.h](https://github.com/cstack/osdev/blob/m_is_master/multiboot.h), however I will implement my own for copyright reasons which will just use the multiboot structure - Now that there is memory management objects will be able to use the "new" and "delete" methods, allowing for virtual deconstructions - However, if there is no free memory then the function will return 0 which would work if in user space as memory pointer 0 is out of bounds. The OS cant throw an exception like c++ normally would as currently there is no exception handler @@ -363,9 +363,9 @@ See also [OSDev - PCNET](https://wiki.osdev.org/AMD_PCNET), [LowLevel - PCNET](h - To get networking capability in the OS a driver for the virtualized network chip (am79c971) has to be written - This device is a complicated one to write a driver for. However, it will follow the same implementation as the other drivers: a class derived from driver, a class derived from interrupt handler (interrupt number and port number can be gotten from PCI) - The device takes a lot of code to initialize (similar to loads for setting VGA graphics mode). -- The networking device can have multiple send and receive buffers and for every buffer there needs to be an instance of a struct (which mainly has a pointer to that buffer) +- The networking device can have multiple send and receive buffers and for every m_buffer there needs to be an instance of a struct (which mainly has a pointer to that m_buffer) - A problem with this though is that this is one of those devices that use some bits in the address for other purposes meaning it needs to be a multiple of 16 (similar to bar) -- So the buffer will be 2KB but then an additional 15 bytes are added on and then 4 bytes are removed. This allows for the multiple of 16 to be found +- So the m_buffer will be 2KB but then an additional 15 bytes are added on and then 4 bytes are removed. This allows for the multiple of 16 to be found ### Handler See also [Wikipedia - Ethernet Frame](https://en.wikipedia.org/wiki/Ethernet_frame) @@ -386,8 +386,8 @@ See also [Wikipedia - ARP](https://en.wikipedia.org/wiki/Address_Resolution_Prot - The ARP data block is as follows: (known as the payload in the raw-data) - - First 2 Bytes: Hardware type (e.g. ethernet or WLAN) - - Next 2 Bytes: Protocol (Will have already received this from handler 0x0806) -- - Next 1 Byte: Size of hardware address (Mac Address = 6) -- - Next 1 Byte: Size of protocol address (IP Address = 4) +- - Next 1 Byte: m_size of hardware address (Mac Address = 6) +- - Next 1 Byte: m_size of protocol address (IP Address = 4) - - Next 2 Bytes: Command (What does the sender what Question/Response) - - Next 6 Bytes: Mac address of the sender - - Next 4 Bytes: IP address of the sender @@ -458,23 +458,23 @@ See also [Wikipedia - UDP](https://en.wikipedia.org/wiki/User_Datagram_Protocol) ### Transmission Control Protocol See also [Wikipedia - TCP](https://en.wikipedia.org/wiki/Transmission_Control_Protocol) - The Transmission Control Protocol (TCP) is one of the main protocols of the Internet protocol suite. It originated in the initial network implementation in which it complemented the Internet Protocol. It provides reliable, ordered, and error-checked delivery of a stream of octets (bytes) between applications running on hosts communicating via an IP network. Major internet applications such as the World Wide Web, email, remote administration, and file transfer rely on TCP. Applications that do not require reliable data stream service may use the User Datagram Protocol (UDP), which provides a connectionless datagram service that emphasizes reduced latency over reliability. -- TCP is a connection-oriented protocol, which means that two computers must first establish a connection before exchanging data. +- TCP is a connection-oriented protocol, which means that two computers must m_first_memory_chunk establish a connection before exchanging data. - The reason it is connection oriented is that it requires the host to acknowledge receipt of the data. This means that if the data is lost it will be resent and the application will know. This is fine for applications that require the data to be received. -- TCP is a reliable protocol, which means that it will resend any lost packets. This is done by using a sequence number and an acknowledgement number. The sequence number is the number of the first byte in the data. The acknowledgement number is the number of the next byte that is expected. If the acknowledgement number is not the same as the sequence number, the data is resent. +- TCP is a reliable protocol, which means that it will resend any lost packets. This is done by using a sequence number and an acknowledgement number. The sequence number is the number of the m_first_memory_chunk byte in the data. The acknowledgement number is the number of the next byte that is expected. If the acknowledgement number is not the same as the sequence number, the data is resent. - The TCP data block is as follows: (known as the payload in the raw-data) - - First 2 Bytes: Source Port (Port that the data is coming from) - - Next 2 Bytes: Destination Port (Port that the data is going to) -- - Next 4 Bytes: Sequence Number (Number of the first byte in the data) +- - Next 4 Bytes: Sequence Number (Number of the m_first_memory_chunk byte in the data) - - Next 4 Bytes: Acknowledgement Number (Number of the next byte that is expected) - - Next 1 Byte: Header Length (Length of the TCP header) - - Next 1 Byte: Flags (Flags that are set) -- - Next 2 Bytes: Window Size (Window is the amount of data that can be sent before an acknowledgement is required) +- - Next 2 Bytes: Window m_size (Window is the amount of data that can be sent before an acknowledgement is required) - - Next 2 Bytes: Checksum (CRC) - - Next 2 Bytes: Urgent Pointer (Pointer to the urgent data) - - Next 0 - 65507 Bytes: Data (Payload) -- For security, the sender and receiver agree on an offset. This is the number of bytes that are added to the sequence number. This means that the sequence number is not the same as the data. This is to prevent people from being able to guess the sequence number and therefore the data, intercepting it and sending malicious data whilst impersonating the sender. +- For security, the sender and receiver agree on an m_offset. This is the number of bytes that are added to the sequence number. This means that the sequence number is not the same as the data. This is to prevent people from being able to guess the sequence number and therefore the data, intercepting it and sending malicious data whilst impersonating the sender. - To disconnect, the sender sends a FIN packet. The receiver then sends an ACK packet. The sender then sends an ACK packet. The receiver then sends a FIN packet. The sender then sends an ACK packet. The receiver then sends an ACK packet. -- To create the checksum the TCP header and the data is added together. The checksum is then added to the header. The checksum is then calculated again. If the checksum is the same then the data is valid. +- To create the checksum the TCP header and the data is added together. The checksum is then added to the header. The checksum is then calculated again. If the checksum is the same then the data is m_valid. - It is calculated by adding the 16-bit words together. If the result is greater than 16 bits, then the carry is added to the result. The result is then inverted. - The command flags are what are sent in the TCP header. The flags are as follows: - - FIN: The connection is finished (1) diff --git a/docs/Styles/ClionCodeStyleSettings.xml b/docs/Styles/ClionCodeStyleSettings.xml new file mode 100644 index 00000000..67ab8988 --- /dev/null +++ b/docs/Styles/ClionCodeStyleSettings.xml @@ -0,0 +1,29 @@ + + + + + + + + \ No newline at end of file diff --git a/docs/Styles/Coding Style.md b/docs/Styles/Coding Style.md new file mode 100644 index 00000000..334fa9aa --- /dev/null +++ b/docs/Styles/Coding Style.md @@ -0,0 +1,561 @@ + +# MaxOS C++ coding style + + +This document describes the coding style used for C++ code in the Max Operating System project. All new code should conform to this style. + +### Names + +A combination of CamelCase, snake\_case, and SCREAMING\_CASE: + +- Use CamelCase (Capitalize the m_first_memory_chunk letter, including all letters in an acronym) in a class, struct, or namespace name +- Use snake\_case (all lowercase, with underscores separating words) for variable and function names +- Use SCREAMING\_CASE for constants (both global and static member variables) + +###### Right: + +```cpp +struct Entry; +size_t buffer_size; +class FileDescriptor; +String absolute_path(); +``` + +###### Wrong: + +```cpp +struct data; +size_t bufferSize; +class Filedescriptor; +String MIME_Type(); +``` + +Use full words, except in the rare case where an abbreviation would be more canonical and easier to understand. + +###### Right: + +```cpp +size_t character_size; +size_t length; +short tab_index; // More canonical. +``` + +###### Wrong: + +```cpp +size_t char_size; +size_t len; +short tabulation_index; // Goofy. +``` + +Data members in C++ classes should be private. Static data members should be prefixed by "s\_". Other data members should be prefixed by "m\_". Global variables should be prefixed by "g\_". + +###### Right: + +```cpp +class String { +public: + ... + +private: + int m_length { 0 }; +}; +``` + +###### Wrong: + +```cpp +class String { +public: + ... + + int length { 0 }; +}; +``` + +Precede setters with the word "set". Use bare words for getters. Setter and getter names should match the names of the variables being set/gotten. + +###### Right: + +```cpp +void set_count(int); // Sets m_count. +int count() const; // Returns m_count. +``` + +###### Wrong: + +```cpp +void set_count(int); // Sets m_the_count. +int get_count() const; // Returns m_the_count. +``` + +Precede getters that return values through out arguments with the word "get". + +###### Right: + +```cpp +void get_filename_and_inode_id(String&, InodeIdentifier&) const; +``` + +###### Wrong: + +```cpp +void filename_and_inode_id(String&, InodeIdentifier&) const; +``` + +Use descriptive verbs in function names. + +###### Right: + +```cpp +bool convert_to_ascii(short*, size_t); +``` + +###### Wrong: + +```cpp +bool to_ascii(short*, size_t); +``` + + +Leave meaningless variable names out of function declarations. A good rule of thumb is if the parameter type name contains the parameter name (without trailing numbers or pluralization), then the parameter name isn't needed. Usually, there should be a parameter name for bools, strings, and numerical types. + +###### Right: + +```cpp +void set_count(int); + +void do_something(Context*); +``` + +###### Wrong: + +```cpp +void set_count(int count); + +void do_something(Context* context); +``` + +Enum members should use InterCaps with an initial capital letter. + +Prefer `const` to `#define`. Prefer inline functions to macros. + +`#defined` constants should use all uppercase names with words separated by underscores. + + +### Other Punctuation + +Constructors for C++ classes should initialize their members using C++ initializer syntax. Each member (and superclass) should be indented on a separate line, with the colon or comma preceding the member on that line. Prefer initialization at member definition whenever possible. + +###### Right: + +```cpp +class MyClass { + ... + Document* m_document { nullptr }; + int m_my_member { 0 }; +}; + +MyClass::MyClass(Document* document) + : MySuperClass() + , m_document(document) +{ +} + +MyOtherClass::MyOtherClass() + : MySuperClass() +{ +} +``` + +###### Wrong: + +```cpp +MyClass::MyClass(Document* document) : MySuperClass() +{ + m_myMember = 0; + m_document = document; +} + +MyClass::MyClass(Document* document) : MySuperClass() + : m_my_member(0) // This should be in the header. +{ + m_document = document; +} + +MyOtherClass::MyOtherClass() : MySuperClass() {} +``` + +Prefer index or range-for over iterators in Vector iterations for terse, easier-to-read code. + +###### Right: + +```cpp +for (auto& child : m_children) + child->do_child_thing(); +``` + + +#### OK: + +```cpp +for (int i = 0; i < m_children.size(); ++i) + m_children[i]->do_child_thing(); +``` + +###### Wrong: + +```cpp +for (auto it = m_children.begin(); it != m_children.end(); ++it) + (*it)->do_child_thing(); +``` + +### Pointers and References + +Both pointer types and reference types should be written with no space between the type name and the `*` or `&`. + +An out argument of a function should be passed by reference except rare cases where it is optional in which case it should be passed by pointer. + +###### Right: + +```cpp +void MyClass::get_some_value(OutArgumentType& out_argument) const +{ + out_argument = m_value; +} + +void MyClass::do_something(OutArgumentType* out_argument) const +{ + do_the_thing(); + if (out_argument) + *out_argument = m_value; +} +``` + +###### Wrong: + +```cpp +void MyClass::get_some_value(OutArgumentType* outArgument) const +{ + *out_argument = m_value; +} +``` + +### Classes + +For types with methods, prefer `class` over `struct`. + +* For classes, make public getters and setters, keep members private with `m_` prefix. +* For structs, let everything be public and skip the `m_` prefix. + +###### Right: + +```cpp +struct Thingy { + String name; + int frob_count { 0 }; +}; + +class Doohickey { +public: + String const& name() const { return m_name; } + int frob_count() const { return m_frob_count; } + + void jam(); + +private: + String m_name; + int m_frob_count { 0 }; +} +``` + +###### Wrong: + +```cpp +struct Thingy { +public: + String m_name; + int frob_count() const { return m_frob_count; } + +private: + int m_frob_count { 0 }; +} + +class Doohickey { +public: + String const& name() const { return this->name; } + + void jam(); + + String name; + int frob_count { 0 }; +}; +``` + + +### Comments + +Comments should be the line above the code they are describing. They should not be inline + +Make comments look like sentences by starting with a capital letter and ending with a period (punctuation). One exception may be end of line comments like this `if (x == y) // false for NaN`. + +Use TODO for things that need to be done, FIXME for things that need to be fixed, and HACK for things that are ugly but work. Use FIXME when you think there is a better way to do something but you don't know what it is yet. + + +###### Right: + +```cpp +// FIXME: Make this code handle jpg in addition to the png support. +draw_jpg(); +``` + +###### Wrong: + +```cpp +draw_jpg(); // FIXME(joe): Make this code handle jpg in addition to the png support. +``` + +```cpp +// TODO: Make this code handle jpg in addition to the png support. +draw_jpg(); +``` + +Explain *why* the code does something. The code itself should already say what is happening. + +###### Right: + +```cpp +// Go to the next page. +i++; +``` + +```cpp +// Let users toggle the advice functionality by clicking on catdog. +catdog_widget.on_click = [&] { + if (advice_timer->is_active()) + advice_timer->stop(); + else + advice_timer->start(); +}; +``` + +###### Even better: + +```cpp +page_index++; +``` + +###### Wrong: + +```cpp +i++; // Increment i. +``` + +```cpp +// If the user clicks, toggle the timer state. +catdog_widget.on_click = [&] { + if (advice_timer->is_active()) + advice_timer->stop(); + else + advice_timer->start(); +}; +``` + + +### Doxygen + +Functions and classes should be documented with Doxygen c + +To document a function, use the following format: + +```cpp +/** + * @brief Brief description of the function. + * + * Longer description of the function. + * + * @param param_name Description of the parameter. + * @return Description of the return value. + */ +``` + +To document a class, use the following format: +```cpp +/** + * @class Class name + * @brief Brief description of the class. + * + * Longer description of the class. + */ +``` + +```cpp + +###### Right: + +```cpp +/** + * @brief Returns the length of the string. + * + * @return The length of the string. + */ +size_t length() const; +``` + +###### Wrong: + +```cpp +/** + * @brief Returns the length of the string. + */ +size_t length() const; +``` + +```cpp +/** + * @brief Returns the length of the string. + * + * @return The length of the string. + */ +size_t length(string const& str) const; +``` + + +### Overriding Virtual Methods + +The declaration of a virtual method inside a class must be declared with the `virtual` keyword. All subclasses of that class must also specify either the `override` keyword when overriding the virtual method, or the `final` keyword when overriding the virtual method and requiring that no further subclasses can override it. + +###### Right: + +```cpp +class Person { +public: + virtual String description() { ... }; +} + +class Student : public Person { +public: + virtual String description() override { ... }; // This is correct because it contains both the "virtual" and "override" keywords to indicate that the method is overridden. +} + +``` + +```cpp +class Person { +public: + virtual String description() { ... }; +} + +class Student : public Person { +public: + virtual String description() final { ... }; // This is correct because it contains both the "virtual" and "final" keywords to indicate that the method is overridden and that no subclasses of "Student" can override "description". +} + +``` + +###### Wrong: + +```cpp +class Person { +public: + virtual String description() { ... }; +} + +class Student : public Person { +public: + String description() override { ... }; // This is incorrect because it uses only the "override" keyword to indicate that the method is virtual. Instead, it should use both the "virtual" and "override" keywords. +} +``` + +```cpp +class Person { +public: + virtual String description() { ... }; +} + +class Student : public Person { +public: + String description() final { ... }; // This is incorrect because it uses only the "final" keyword to indicate that the method is virtual and final. Instead, it should use both the "virtual" and "final" keywords. +} +``` + +```cpp +class Person { +public: + virtual String description() { ... }; +} + +class Student : public Person { +public: + virtual String description() { ... }; // This is incorrect because it uses only the "virtual" keyword to indicate that the method is overridden. +} +``` + +### Omission of curly braces from statement blocks + +Curly braces may only be omitted from `if`/`else`/`for`/`while`/etc. statement blocks if the body is a single line. + +Additionally, if any body of a connected if/else statement requires curly braces according to this rule, all of them do. + +###### Right: +```cpp +if (condition) + foo(); +``` + +```cpp +if (condition) { + foo(); + bar(); +} +``` + +```cpp +if (condition) { + foo(); +} else if (condition) { + bar(); + baz(); +} else { + qux(); +} +``` + +```cpp +for (size_t i = i; condition; ++i) { + if (other_condition) + foo(); +} +``` + +##### OK: + +```cpp +if (condition) { + foo(); +} +``` + +###### Wrong: + +```cpp +if (condition) + // There is a comment here. + foo(); +``` + +```cpp +if (condition) + foo(); +else { + bar(); + baz(); +} else + qux(); +``` + +```cpp +for (size_t i = i; condition; ++i) + if (other_condition) + foo(); +``` \ No newline at end of file diff --git a/docs/Styles/Interface Style.md b/docs/Styles/Interface Style.md new file mode 100644 index 00000000..1bdc7284 --- /dev/null +++ b/docs/Styles/Interface Style.md @@ -0,0 +1,79 @@ +# Guidelines for user interface text in MaxOS + +## Capitalization + +MaxOS employs two capitalization styles: + +- Book m_title capitalization +- Sentence-style capitalization + +### Book m_title capitalization + +In this style, we capitalize the m_first_memory_chunk letter of the m_first_memory_chunk and last word, +as well as all words in between, *except* articles (a, an, the); +the seven coordinating conjunctions (for, and, nor, but, or, yet, so); +and prepositions with up to four letters (at, by, for, with, into, ...) + +#### Examples: +- Create New Layer +- Copy URL +- Move to Front +- Save and Exit +- Sort by Name + +#### Used for: + +- Button text +- Icon labels +- Menu names +- Menu items +- Tab titles +- Window titles +- Tooltips + +### Sentence-style capitalization + +This style follows basic English sentence capitalization. +We capitalize the m_first_memory_chunk letter of the m_first_memory_chunk word, along with the m_first_memory_chunk letter +of proper names, weekdays, etc. + +#### Examples: +- An error occurred +- Use system defaults +- Copy the selected text +- Enable Linux compatibility hacks + +#### Used for: + +- Check box labels +- Group box labels +- List items +- Messages (as in message boxes) +- Radio button labels +- Status bar text +- Text box labels + +## Ellipses + +The ellipsis, represented by a series of three periods (...), has two special +functions in the interface: + +- Eliding text +- Foreshadowing additional user input + +The m_first_memory_chunk occurs programmatically, but the second requires care when setting +text manually. + +Control text which implies an action whose effect is incomplete pending further +user input should end in an ellipsis. Opening a new window does not in itself +justify the use of an ellipsis; the dialog must be an intermediate step toward +completing the action. + +Ellipses should be used sparingly elsewhere to avoid confusion with elision. + +#### Examples: +- Save As... +- Browse... +- Insert Emoji... + + \ No newline at end of file diff --git a/docs/commit.md b/docs/commit.md deleted file mode 100644 index 1ef66968..00000000 --- a/docs/commit.md +++ /dev/null @@ -1,2 +0,0 @@ -# Windows Fix - 20/10/23 -- \ No newline at end of file diff --git a/kernel/include/common/colour.h b/kernel/include/common/colour.h index 9c0ca597..f8a413b3 100644 --- a/kernel/include/common/colour.h +++ b/kernel/include/common/colour.h @@ -12,13 +12,18 @@ namespace maxOS{ namespace common { + /*** + * @class Colour + * @brief Stores the red, green, blue and alpha values of a colour + */ class Colour { public: - uint8_t red; - uint8_t green; - uint8_t blue; - uint8_t alpha; + uint8_t red { 0 }; + uint8_t green { 0 }; + uint8_t blue { 0 }; + uint8_t alpha { 0 }; + Colour(); Colour(uint8_t red, uint8_t green, uint8_t blue); diff --git a/kernel/include/common/eventHandler.h b/kernel/include/common/eventHandler.h index 3e415219..1738d505 100644 --- a/kernel/include/common/eventHandler.h +++ b/kernel/include/common/eventHandler.h @@ -13,6 +13,12 @@ namespace maxOS{ namespace common{ + /** + * @class Event + * @brief Used to store information about an event, has a type and a return value + * + * @tparam EventType The type of event + */ template class Event { public: @@ -24,28 +30,40 @@ namespace maxOS{ uint8_t* bufferValue; uint32_t intValue; bool boolValue; - } returnValue; + } return_value; }; + /** + * @class EventHandler + * @brief Used to handle an event + * + * @tparam EventType The type of event + */ template class EventHandler { public: EventHandler(); ~EventHandler(); - virtual Event* onEvent(Event* event); + virtual Event* on_event(Event* event); }; + /** + * @class EventManager + * @brief Manages the m_handlers for a type of event, raises events and calls the m_handlers + * + * @tparam EventType The type of event + */ template class EventManager { protected: - Vector*> handlers; + Vector*> m_handlers; public: EventManager(); ~EventManager(); - void connectEventHandler(EventHandler* handler); - void disconnectEventHandler(EventHandler* handler); - Vector*> raiseEvent(Event* event); + void connect_event_handler(EventHandler* handler); + void disconnect_event_handler(EventHandler* handler); + Vector*> raise_event(Event* event); }; @@ -69,11 +87,12 @@ namespace maxOS{ } /** - * This function is called when an event is raised + * @brief This function is called when an event is raised + * * @tparam EventType The type of event * @param event The event that was raised */ - template Event* EventHandler::onEvent(Event *event) { + template Event* EventHandler::on_event(Event* event) { return event; } @@ -87,46 +106,50 @@ namespace maxOS{ /** - * Connect an event handler to the event manager + * @brief Connect an event handler to the event manager if it is not already connected + * * @tparam EventType The type of event * @param handler The event handler to connect */ - template void EventManager::connectEventHandler(EventHandler *handler) { + template void EventManager::connect_event_handler(EventHandler* handler) { // If the handler is already connected, return - if(handlers.find(handler) != handlers.end()) { + if(m_handlers.find(handler) != m_handlers.end()) { return; } - handlers.pushBack(handler); + m_handlers.push_back(handler); } /** - * Disconnect an event handler from the event manager + * @brief Disconnect an event handler from the event manager if it is connected + * * @tparam EventType The type of event * @param handler The event handler to disconnect */ - template void EventManager::disconnectEventHandler(EventHandler *handler) { + template void EventManager::disconnect_event_handler(EventHandler* handler) { // If the handler is not connected, return - if(handlers.find(handler) == handlers.end()) { + if(m_handlers.find(handler) == m_handlers.end()) { return; } - handlers.erase(handler); + m_handlers.erase(handler); } /** - * Raise an event + * @brief Calls the on_event function of all the event m_handlers connected to the event manager and returns a list of the results + * * @tparam EventType The type of event * @param event The event to raise + * @return A list of the results of the event m_handlers */ - template Vector*> EventManager::raiseEvent(Event *event) { + template Vector*> EventManager::raise_event(Event* event) { // Store a list of the results of the event handlers Vector*> results; - for(typename Vector*>::iterator handler = handlers.begin(); handler != handlers.end(); ++handler) { - results.pushBack((*handler)->onEvent(event)); + for(auto& handler : m_handlers) { + results.push_back(handler->on_event(event)); } return results; } diff --git a/kernel/include/common/graphicsContext.h b/kernel/include/common/graphicsContext.h index 81bdc720..d57e99e0 100644 --- a/kernel/include/common/graphicsContext.h +++ b/kernel/include/common/graphicsContext.h @@ -12,57 +12,61 @@ namespace maxOS { namespace common { + /** + * @class GraphicsContext + * @brief Draws pixels to the screen, and handles drawing lines, rectangles and circles + */ class GraphicsContext { protected: - bool mirrorYAxis; + bool mirror_y_axis { false }; - uint32_t width; - uint32_t height; - uint32_t colorDepth; + uint32_t m_width { 0 }; + uint32_t m_height { 0 }; + uint32_t m_color_depth { 0 }; - Colour colourPallet[256]; + Colour m_colour_pallet[256]; - virtual void renderPixel(uint32_t x, uint32_t y, uint32_t colour); - virtual void renderPixel8Bit(uint32_t x, uint32_t y, uint8_t colour); - virtual void renderPixel16Bit(uint32_t x, uint32_t y, uint16_t colour); - virtual void renderPixel24Bit(uint32_t x, uint32_t y, uint32_t colour); - virtual void renderPixel32Bit(uint32_t x, uint32_t y, uint32_t colour); + virtual void render_pixel(uint32_t x, uint32_t y, uint32_t colour); + virtual void render_pixel_8_bit(uint32_t x, uint32_t y, uint8_t colour); + virtual void render_pixel_16_bit(uint32_t x, uint32_t y, uint16_t colour); + virtual void render_pixel_24_bit(uint32_t x, uint32_t y, uint32_t colour); + virtual void render_pixel_32_bit(uint32_t x, uint32_t y, uint32_t colour); - virtual uint32_t getRenderedPixel(uint32_t x, uint32_t y); - virtual uint8_t getRenderedPixel8Bit(uint32_t x, uint32_t y); - virtual uint16_t getRenderedPixel16Bit(uint32_t x, uint32_t y); - virtual uint32_t getRenderedPixel24Bit(uint32_t x, uint32_t y); - virtual uint32_t getRenderedPixel32Bit(uint32_t x, uint32_t y); + virtual uint32_t get_rendered_pixel(uint32_t x, uint32_t y); + virtual uint8_t get_rendered_pixel_8_bit(uint32_t x, uint32_t y); + virtual uint16_t get_rendered_pixel_16_bit(uint32_t x, uint32_t y); + virtual uint32_t get_rendered_pixel_24_bit(uint32_t x, uint32_t y); + virtual uint32_t get_rendered_pixel_32_bit(uint32_t x, uint32_t y); public: GraphicsContext(); ~GraphicsContext(); - uint32_t colourToInt(Colour colour); - Colour intToColour(uint32_t colour); + uint32_t colour_to_int(Colour); + Colour int_to_colour(uint32_t); - uint32_t getWidth(); - uint32_t getHeight(); + uint32_t get_width(); + uint32_t get_height(); - void putPixel(int32_t x, int32_t y, Colour colour); + void put_pixel(int32_t x, int32_t y, Colour colour); void putPixel(int32_t x, int32_t y, int32_t colour); - Colour getPixel(int32_t x, int32_t y); - void invertPixel(int32_t x, int32_t y); + Colour get_pixel(int32_t x, int32_t y); + void invert_pixel(int32_t x, int32_t y); - void drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, Colour colour); + void draw_line(int32_t x0, int32_t y0, int32_t x1, int32_t y1, Colour colour); void drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t colour); - void drawRectangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, Colour colour); - void drawRectangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t colour); + void draw_rectangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, Colour colour); + void draw_rectangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t colour); - void fillRectangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, Colour colour); - void fillRectangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t colour); + void fill_rectangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, Colour colour); + void fill_rectangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t colour); - void drawCircle(int32_t x0, int32_t y0, int32_t radius, Colour colour); - void drawCircle(int32_t x0, int32_t y0, int32_t radius, uint32_t colour); + void draw_circle(int32_t x0, int32_t y0, int32_t radius, Colour colour); + void draw_circle(int32_t x0, int32_t y0, int32_t radius, uint32_t colour); - void fillCircle(int32_t x0, int32_t y0, int32_t radius, Colour colour); + void fill_circle(int32_t x0, int32_t y0, int32_t radius, Colour colour); void fillCircle(int32_t x0, int32_t y0, int32_t radius, uint32_t colour); }; diff --git a/kernel/include/common/inputStream.h b/kernel/include/common/inputStream.h index e109ba6b..7b28a9f3 100644 --- a/kernel/include/common/inputStream.h +++ b/kernel/include/common/inputStream.h @@ -16,72 +16,102 @@ namespace maxOS{ // Forward declaration template class GenericInputStream; + /** + * @class InputStreamEventHandler + * @brief Handles read and end of stream events from a set of streams + * + * @tparam Type The type of data the stream is handling + */ template class InputStreamEventHandler { friend class GenericInputStream; protected: - common::Vector*> genericInputStreams; + common::Vector*> + m_generic_input_streams; public: InputStreamEventHandler(); ~InputStreamEventHandler(); - virtual void onStreamRead(Type readElement); - virtual void onEndOfStream(GenericInputStream* stream); + virtual void on_stream_read(Type); + virtual void on_end_of_stream(GenericInputStream*); }; + /** + * @class InputStreamProcessor + * @brief Converts one stream data type into another + * + * @tparam Type + * @tparam ProcessorType + */ template class InputStreamProcessor : public InputStreamEventHandler, public GenericInputStream { public: InputStreamProcessor(); - InputStreamProcessor(InputStreamEventHandler* genericStreamEventHandler); + InputStreamProcessor(InputStreamEventHandler* generic_stream_event_handler); ~InputStreamProcessor(); - void onEndOfStream(GenericInputStream* stream); + virtual void on_end_of_stream(GenericInputStream* stream) override; }; + /** + * @class InputStreamSocket + * @brief Passes read events on to the handlers + * + * @tparam Type The type of data the stream is handling + */ template class InputStreamSocket : public InputStreamProcessor { public: InputStreamSocket(); - InputStreamSocket(InputStreamEventHandler* processorHandler); + InputStreamSocket(InputStreamEventHandler*); ~InputStreamSocket(); - void onStreamRead(Type readElement); + virtual void on_stream_read(Type) override; }; - - + /** + * @class InputStreamBuffer + * @brief Buffers data from a stream and fires an event when a certain element is read + * + * @tparam Type The type of data the stream is handling + */ template class InputStreamBuffer : protected InputStreamProcessor { protected: - Type buffer[10240]; // Buffer o - int offset; - Type eventFireElement; - Type terminationElement; + Type m_buffer[10240]; //TODO: Probaby make this dynamic + int m_offset { 0 }; + Type m_event_fire_element; + Type m_termination_element; public: - InputStreamBuffer(Type eventFireElement, Type terminationElement); + InputStreamBuffer(Type event_fire_element, Type termination_element); ~InputStreamBuffer(); - void onStreamRead(Type readElement); - void onEndOfStream(GenericInputStream* stream); + virtual void on_stream_read(Type) override; + virtual void on_end_of_stream(GenericInputStream*) override; void flush(); }; + /** + * @class GenericInputStream + * @brief Manages the connection of a stream to handlers + * + * @tparam Type The type of data the stream is handling + */ template class GenericInputStream{ protected: - common::Vector*> inputStreamEventHandlers; + common::Vector*> m_input_stream_event_handlers; public: GenericInputStream(); - GenericInputStream(InputStreamEventHandler* inputStreamEventHandler); + GenericInputStream(InputStreamEventHandler*); ~GenericInputStream(); - void connectInputStreamEventHandler(InputStreamEventHandler* inputStreamEventHandler); - void disconnectInputStreamEventHandler(InputStreamEventHandler* inputStreamEventHandler); + void connect_input_stream_event_handler(InputStreamEventHandler*); + void disconnect_input_stream_event_handler(InputStreamEventHandler*); }; @@ -91,17 +121,22 @@ namespace maxOS{ // The ">>" operator is used to read data from a stream, it takes a stream to read from and a processor to convert the data into another type template GenericInputStream& operator>>(GenericInputStream& source, InputStreamProcessor& processor); + /** + * @class InputStream + * @brief A stream that handles strings + */ class InputStream : public GenericInputStream { public: - InputStream(InputStreamEventHandler* inputStreamEventHandler); + InputStream(InputStreamEventHandler*); }; ///_______________________________________________TEMPLATES_________________________________________________________________/// /** - * @details Creates a new InputStreamProcessor + * @breif Creates a new InputStreamProcessor + * * @tparam Type the type of data the stream is handling */ template InputStreamEventHandler::InputStreamEventHandler() { @@ -109,38 +144,44 @@ namespace maxOS{ } /** - * @details Destroys the InputStreamProcessor and disconnects it from all streams + * @breif Destroys the InputStreamProcessor and disconnects it from all streams + * * @tparam Type the type of data the stream is handling */ template InputStreamEventHandler::~InputStreamEventHandler() { - // Loop through all the streams and disconnect this handler from them - while(!genericInputStreams.empty()) - (*genericInputStreams.begin())->disconnectInputStreamEventHandler(this); + + // Disconnect the handler from all streams + while(!m_generic_input_streams.empty()) + (*m_generic_input_streams.begin()) -> disconnect_input_stream_event_handler(this); } /** - * @details Called when data is read from a stream (overridden by subclasses) + * @breif Called when data is read from a stream (overridden by subclasses) + * * @tparam Type the type of data the stream is handling - * @param readElement The element that was read from the stream + * @param read_element The element that was read from the stream */ - template void InputStreamEventHandler::onStreamRead(Type readElement) { + template void InputStreamEventHandler::on_stream_read(Type read_element) { } /** - * @details Called when a stream has finished. Removes the stream from the array of streams + * @breif Called when a stream has finished. Removes the stream from the array of streams + * * @tparam Type The type of data the stream is handling * @param stream The stream that has finished */ - template void InputStreamEventHandler::onEndOfStream(GenericInputStream *stream) { - // Remove the stream from the array of streams as it has finished - genericInputStreams.erase(stream); + template void InputStreamEventHandler::on_end_of_stream(GenericInputStream *stream) { + + // Remove the stream + m_generic_input_streams.erase(stream); } /** - * @details Creates a new InputStreamProcessor + * @breif Creates a new InputStreamProcessor + * * @tparam Type The type of data the stream is handling * @tparam ProcessorType The type of data to convert the data into via the processor */ @@ -152,20 +193,22 @@ namespace maxOS{ } /** - * @details Creates a new InputStreamProcessor + * @breif Creates a new InputStreamProcessor + * * @tparam Type The type of data the stream is handling * @tparam ProcessorType The type of data to convert the data into via the processor - * @param genericStreamEventHandler The event handler to handle the data (passed to the GenericInputStream constructor) + * @param generic_stream_event_handler The event handler to handle the data */ - template InputStreamProcessor::InputStreamProcessor(InputStreamEventHandler *genericStreamEventHandler) + template InputStreamProcessor::InputStreamProcessor(InputStreamEventHandler *generic_stream_event_handler) : InputStreamEventHandler(), - GenericInputStream(genericStreamEventHandler) + GenericInputStream(generic_stream_event_handler) { } /** - * @details Destroys the InputStreamProcessor + * @breif Destroys the InputStreamProcessor + * * @tparam Type The type of data the stream is handling * @tparam ProcessorType The type of data to convert the data into via the processor */ @@ -174,24 +217,26 @@ namespace maxOS{ } /** - * @details Called when a stream has finished. Passes the event on to the internetProtocolHandlers and then removes the stream from the array of streams + * @breif Called when a stream has finished. Passes the event on to the handlers and then removes the stream from the array of streams + * * @tparam Type The type of data the stream is handling * @tparam ProcessorType The type of data to convert the data into via the processor * @param stream The stream that has finished */ - template void InputStreamProcessor::onEndOfStream(GenericInputStream* stream) { + template void InputStreamProcessor::on_end_of_stream(GenericInputStream* stream) { - // Loop through and run the end of stream event on the handlers - for(typename Vector*>::iterator inputStreamEventHandler = this -> inputStreamEventHandlers.begin(); inputStreamEventHandler != this -> inputStreamEventHandlers.end(); inputStreamEventHandler++) - (*inputStreamEventHandler) -> onEndOfStream(this); + // Pass the end of stream event on to the handlers + for(auto& event_handler : this -> m_input_stream_event_handlers) + event_handler -> on_end_of_stream(this); - // Run the default end of stream event, this removes the stream from the array of streams - InputStreamEventHandler::onEndOfStream(stream); + // Remove the stream + InputStreamEventHandler::on_end_of_stream(stream); } /** - * @details Creates a new InputStreamSocket + * @breif Creates a new InputStreamSocket + * * @tparam Type The type of data the stream is handling */ template InputStreamSocket::InputStreamSocket() { @@ -199,18 +244,20 @@ namespace maxOS{ } /** - * @details Creates a new InputStreamSocket and connects it to the handler + * @breif Creates a new InputStreamSocket and connects it to the handler + * * @tparam Type The type of data the stream is handling (and the sockets processor type) - * @param processorHandler The handler to pass to InputStreamProcessor + * @param processor_handler The handler to pass to InputStreamProcessor */ - template InputStreamSocket::InputStreamSocket(InputStreamEventHandler *processorHandler) - : InputStreamProcessor(processorHandler) + template InputStreamSocket::InputStreamSocket(InputStreamEventHandler *processor_handler) + : InputStreamProcessor(processor_handler) { } /** - * @details Destroys the InputStreamSocket + * @breif Destroys the InputStreamSocket + * * @tparam Type The type of data the stream is handling */ template InputStreamSocket::~InputStreamSocket() { @@ -218,35 +265,36 @@ namespace maxOS{ } /** - * @details Called when data is read from a stream. Passes the event on to the internetProtocolHandlers + * @breif Called when data is read from a stream. Passes the event on to the internetProtocolHandlers + * * @tparam Type The type of data the stream is handling - * @param readElement The element that was read from the stream + * @param read_element The element that was read from the stream */ - template void InputStreamSocket::onStreamRead(Type readElement) { + template void InputStreamSocket::on_stream_read(Type read_element) { // Pass the read event on to the handlers - for(typename Vector*>::iterator inputStreamEventHandler = this -> inputStreamEventHandlers.begin(); inputStreamEventHandler != this -> inputStreamEventHandlers.end(); inputStreamEventHandler++) - (*inputStreamEventHandler)->onStreamRead(readElement); + for(auto& event_handler : this -> m_input_stream_event_handlers) + event_handler -> on_stream_read(read_element); } /** - * @details Creates a new InputStreamBuffer + * @breif Creates a new InputStreamBuffer + * * @tparam Type The type of data the stream is handling - * @param eventFireElement The element to fire the event on - * @param terminationElement The element that signifies the end of the part of the stream to be buffered (e.g a newline) + * @param event_fire_element The element to fire the event on + * @param termination_element The element that signifies the end of the part of the stream to be buffered (e.g a newline) */ - template InputStreamBuffer::InputStreamBuffer(Type eventFireElement, Type terminationElement) { - // Nothing has been read so the buffer offset is at the start - offset = 0; + template InputStreamBuffer::InputStreamBuffer(Type event_fire_element, Type termination_element) + : m_event_fire_element(event_fire_element), + m_termination_element(termination_element) + { - // Set the event fire and termination elements - this -> eventFireElement = eventFireElement; - this -> terminationElement = terminationElement; } /** - * @details Destroys the InputStreamBuffer + * @breif Destroys the InputStreamBuffer + * * @tparam Type The type of data the stream is handling */ template InputStreamBuffer::~InputStreamBuffer() { @@ -254,68 +302,70 @@ namespace maxOS{ } /** - * @details Called when data is read from a stream. Adds the data to the buffer and checks if the event should be fired + * @breif Called when data is read from a stream. Adds the data to the buffer and checks if the event should be fired + * * @tparam Type - * @param readElement + * @param read_element */ - template void InputStreamBuffer::onStreamRead(Type readElement) { + template void InputStreamBuffer::on_stream_read(Type read_element) { - // If this element should fire an event - if(readElement == eventFireElement){ - // Fire the event by flushing the buffer + // flush the buffer if the event fire element is read + if(read_element == m_event_fire_element){ flush(); return; } - // If the offset is past the length of the buffer then flush the buffer - if(offset >= 10238){ + // Ensure the buffer is not full + if(m_offset >= 10238){ flush(); } - // Add the element to the buffer - buffer[offset++] = readElement; + // Add the element + m_buffer[m_offset++] = read_element; } /** - * @details Called when a stream has finished. Flushes the buffer if there is any data in it + * @breif Called when a stream has finished. Flushes the buffer if there is any data in it + * * @tparam Type The type of data the stream is handling * @param stream The stream that has finished */ - template void InputStreamBuffer::onEndOfStream(GenericInputStream *stream) { + template void InputStreamBuffer::on_end_of_stream(GenericInputStream *stream) { - // If data had been read before the stream ends then flush the buffer - if(offset > 0) + // flush the buffer if there is any data in it + if(m_offset > 0) flush(); - // Run the default end of stream event - InputStreamProcessor::onEndOfStream(stream); - + // Pass the event on to the handlers and remove the stream + InputStreamProcessor::on_end_of_stream(stream); } /** - * @details Flushes the buffer by adding the termination element and firing an on read event (NOTE: The buffer is not cleared after this just overwritten) + * @breif Flushes the buffer by adding the termination element and firing an on read event (NOTE: The buffer is not cleared after this just overwritten) + * * @tparam Type The type of data the stream is handling */ template void InputStreamBuffer::flush() { - // If there is no data in the buffer then return - if(offset == 0) + // Ensure the buffer is not empty + if(m_offset == 0) return; // Add the termination element to the buffer - buffer[offset] = terminationElement; + m_buffer[m_offset] = m_termination_element; // Fire the on read event - InputStreamProcessor::onStreamRead(buffer); + InputStreamProcessor::on_stream_read(m_buffer); // Reset the offset - offset = 0; + m_offset = 0; } /** - * @details Creates a new GenericInputStream + * @breif Creates a new GenericInputStream + * * @tparam Type The type of data the stream is handling */ template GenericInputStream::GenericInputStream() { @@ -323,67 +373,65 @@ namespace maxOS{ } /** - * @details Creates a new GenericInputStream and connects it to the inputStreamEventHandler + * @breif Creates a new GenericInputStream and connects it to the handler + * * @tparam Type The type of data the stream is handling - * @param inputStreamEventHandler The inputStreamEventHandler to handle the data + * @param input_stream_event_handler The handler to handle the data */ - template GenericInputStream::GenericInputStream(InputStreamEventHandler *inputStreamEventHandler) { - - // Connect the inputStreamEventHandler - connectInputStreamEventHandler(inputStreamEventHandler); + template GenericInputStream::GenericInputStream(InputStreamEventHandler *input_stream_event_handler) { + // Connect the handler + connect_input_stream_event_handler(input_stream_event_handler); } /** - * @details Destroys the GenericInputStream and disconnects all internetProtocolHandlers + * @breif Destroys the GenericInputStream and disconnects all handlers + * * @tparam Type The type of data the stream is handling */ template GenericInputStream::~GenericInputStream() { // Disconnect all handlers - while (!inputStreamEventHandlers.empty()) - disconnectInputStreamEventHandler(*(inputStreamEventHandlers.begin())); + while (!m_input_stream_event_handlers.empty()) + disconnect_input_stream_event_handler(*(m_input_stream_event_handlers.begin())); } /** - * @details Adds a inputStreamEventHandler to the list of internetProtocolHandlers + * @breif Adds a inputStreamEventHandler to the list of internetProtocolHandlers * @tparam Type The type of data the stream is handling - * @param inputStreamEventHandler The inputStreamEventHandler to add + * @param input_stream_event_handler The inputStreamEventHandler to add */ - template void GenericInputStream::connectInputStreamEventHandler(InputStreamEventHandler *inputStreamEventHandler) { + template void GenericInputStream::connect_input_stream_event_handler(InputStreamEventHandler *input_stream_event_handler) { - // Check if the inputStreamEventHandler is already connected - if(inputStreamEventHandlers.find(inputStreamEventHandler) != inputStreamEventHandlers.end()) + // Don't add the handler if it is already connected + if(m_input_stream_event_handlers.find(input_stream_event_handler) != m_input_stream_event_handlers.end()) return; - // Add the inputStreamEventHandler to the list of handlers - inputStreamEventHandlers.pushBack(inputStreamEventHandler); + // Add the handler + m_input_stream_event_handlers.push_back(input_stream_event_handler); } /** - * @details Removes a inputStreamEventHandler from the list of internetProtocolHandlers + * @breif Removes a handler from the list of handlers + * * @tparam Type The type of data the stream is handling - * @param inputStreamEventHandler The inputStreamEventHandler to remove + * @param input_stream_event_handler The handler to remove */ - template void GenericInputStream::disconnectInputStreamEventHandler(InputStreamEventHandler *inputStreamEventHandler) { + template void GenericInputStream::disconnect_input_stream_event_handler(InputStreamEventHandler *input_stream_event_handler) { - // Check if the inputStreamEventHandler is connected - if(inputStreamEventHandlers.find(inputStreamEventHandler) == inputStreamEventHandlers.end()) + // Don't remove the handler if it is not connected + if(m_input_stream_event_handlers.find(input_stream_event_handler) == m_input_stream_event_handlers.end()) return; - // Remove the inputStreamEventHandler from the list of handlers - inputStreamEventHandlers.erase(inputStreamEventHandler); + // Remove the handler + m_input_stream_event_handlers.erase(input_stream_event_handler); // Fire the end of stream event - inputStreamEventHandler -> onEndOfStream(this); + input_stream_event_handler->on_end_of_stream(this); } - - - } - } #endif //MAXOS_INPUTSTREAM_H diff --git a/kernel/include/common/map.h b/kernel/include/common/map.h index 2a7050c2..f2633937 100644 --- a/kernel/include/common/map.h +++ b/kernel/include/common/map.h @@ -12,19 +12,34 @@ namespace maxOS{ namespace common{ + /** + * @class MapIterationHandler + * @brief Handles iteration of a map + * + * @tparam Key The key type + * @tparam Value The value type + */ template class MapIterationHandler { public: MapIterationHandler(); ~MapIterationHandler(); - virtual void onRead(Key, Value); - virtual void onEndOfStream(); + + virtual void on_read(Key, Value); + virtual void on_end_of_stream(); }; + /** + * @class Map + * @brief A list of key-value pairs + * + * @tparam Key The key type + * @tparam Value The value type + */ template class Map { protected: - Vector > elements; + Vector> m_elements; public: typedef typename Vector >::iterator iterator; @@ -32,15 +47,15 @@ namespace maxOS{ Map(); ~Map(); - Value& operator[](Key key); + Value& operator[](Key); iterator begin(); iterator end(); - iterator find(Key element); + iterator find(Key); bool empty(); void clear(); - void insert(Key key, Value value); - void erase(Key key); + void insert(Key, Value); + void erase(Key); void iterate(MapIterationHandler* handler); void iterate(void callback(Key&, Value&)); @@ -48,23 +63,34 @@ namespace maxOS{ }; /// ______________ TEMPLATE IMPLEMENTATION ______________ - template void MapIterationHandler::onEndOfStream() { + template MapIterationHandler::MapIterationHandler() { } - template void MapIterationHandler::onRead(Key, Value) { + template MapIterationHandler::~MapIterationHandler() { } - template MapIterationHandler::~MapIterationHandler() { + /** + * @brief Called when the end of the stream is reached + * + * @tparam Key The key type + * @tparam Value The value type + */ + template void MapIterationHandler::on_end_of_stream() { } - template MapIterationHandler::MapIterationHandler() { + /** + * @brief Called when a key-value pair is read + * + * @tparam Key The key type + * @tparam Value The value type + */ + template void MapIterationHandler::on_read(Key, Value) { } - template Map::Map() { } @@ -73,20 +99,50 @@ namespace maxOS{ } + /** + * @brief Overloads the [] operator to return the value of the key + * + * @tparam Key The key type + * @tparam Value The value type + * @param key The key to search for + * @return The value of the key + */ template Value &Map::operator[](Key key) { // Return the value of the key (second item in the pair) return find(key) -> second; } + /** + * @brief Returns the beginning of the map + * + * @tparam Key The key type + * @tparam Value The value type + * @return The m_first_memory_chunk element in the map + */ template typename Map::iterator Map::begin() { - return elements.begin(); + return m_elements.begin(); } + /** + * @brief Returns the end of the map + * + * @tparam Key The key type + * @tparam Value The value type + * @return The last element in the map + */ template typename Map::iterator Map::end() { - return elements.end(); + return m_elements.end(); } + /** + * @brief Finds an element in the map based on the key + * + * @tparam Key The key type + * @tparam Value The value type + * @param element The key to search for + * @return The iterator of the element, or the end iterator if not found + */ template typename Map::iterator Map::find(Key element) { // Loop through the elements @@ -104,62 +160,101 @@ namespace maxOS{ } + /** + * @brief Returns whether the map is empty + * + * @tparam Key The key type + * @tparam Value The value type + * @return Whether the map is empty + */ template bool Map::empty() { - return elements.empty(); + return m_elements.empty(); } + /** + * @brief Removes all elements from the map + * + * @tparam Key The key type + * @tparam Value The value type + */ template void Map::clear() { - elements.clear(); + m_elements.clear(); } + /** + * @brief Updates the value of an element, or adds a new element if it does not exist + * + * @tparam Key The key type + * @tparam Value The value type + * @param key The key of the new element + * @param value The value of the new element + */ template void Map::insert(Key key, Value value) { // Find the element iterator it = find(key); - // If the element is found + // If the element is found then update the value if (it != end()) { - // Set the value of the element to the new value it -> second = value; } else { // Otherwise, add a new element - elements.pushBack(Pair(key, value)); + m_elements.push_back(Pair(key, value)); } } + /** + * @brief Removes an element from the map + * + * @tparam Key The key type + * @tparam Value The value type + * @param key The key of the element to remove + */ template void Map::erase(Key key) { // Find the element iterator it = find(key); - // If the element is found + // If the element is found then remove it if (it != end()) { - // Erase the element - elements.erase(it); + m_elements.erase(it); } } + /** + * @brief Iterates through the map and calls the handler + * + * @tparam Key The key type + * @tparam Value The value type + * @param handler The handler to call + */ template void Map::iterate(MapIterationHandler *handler) { // Loop through the elements - for (iterator it = begin(); it != end(); it++) { + for(auto& it : m_elements) { + // Call the handler - handler -> onRead(it -> first, it -> second); + handler->on_read(it.first, it.second); } // Call the handler - handler -> onEndOfStream(); + handler->on_end_of_stream(); } + /** + * @brief Iterates through the map and calls the callback + * + * @tparam Key The key type + * @tparam Value The value type + * @param callback The callback to call + */ template void Map::iterate(void (*callback)(Key &, Value &)) { - // Loop through the elements - for (iterator it = begin(); it != end(); it++) { - - // Call the callback - callback(it -> first, it -> second); + // Call the callback for each element + for(auto& it : m_elements) { + callback(it.first, it.second); } } } diff --git a/kernel/include/common/outputStream.h b/kernel/include/common/outputStream.h index 32a704cd..cd71e164 100644 --- a/kernel/include/common/outputStream.h +++ b/kernel/include/common/outputStream.h @@ -13,21 +13,31 @@ namespace maxOS{ namespace common{ + /** + * @class OutputStream + * @brief A stream that can be written to. + * + * @tparam Type The type of the elements that will be written to the stream. + */ template class GenericOutputStream : public InputStreamProcessor { public: GenericOutputStream(); ~GenericOutputStream(); - void onStreamRead(Type readElement); - void onEndOfStream(GenericInputStream* stream); + void on_stream_read(Type) override; + void on_end_of_stream(GenericInputStream*) override; - virtual void write(Type writeElement); + virtual void write(Type); virtual void close(); - virtual GenericOutputStream& operator << (Type writeElement); + virtual GenericOutputStream& operator << (Type); }; + /** + * @class OutputStream + * @brief A stream that strings can be written to. + */ class OutputStream : public GenericOutputStream { @@ -39,15 +49,15 @@ namespace maxOS{ virtual void carriageReturn(); virtual void clear(); - virtual void write(string stringToWrite); - virtual void writeChar(char charToWrite); - virtual void writeInt(int intToWrite); - virtual void writeHex(uint32_t hexToWrite); + virtual void write(string string_to_write) override; + virtual void write_char(char char_to_write); + virtual void write_int(int int_to_write); + virtual void write_hex(uint32_t hex_to_write); - OutputStream& operator << (int intToWrite); - OutputStream& operator << (uint32_t hexToWrite); - OutputStream& operator << (string stringToWrite); - OutputStream& operator << (char charToWrite); + OutputStream& operator << (string string_to_write) override; + OutputStream& operator << (int int_to_write); + OutputStream& operator << (uint32_t hex_to_write); + OutputStream& operator << (char char_to_write); }; @@ -55,7 +65,8 @@ namespace maxOS{ ///__________________________________________Templates__________________________________________________/// /** - * @details Constructor of the GenericOutputStream class. + * @brief Constructor of the GenericOutputStream class. + * * @tparam Type The type of the elements that will be written to the stream. */ template GenericOutputStream::GenericOutputStream() { @@ -63,7 +74,8 @@ namespace maxOS{ } /** - * @details Destructor of the GenericOutputStream class. + * @brief Destructor of the GenericOutputStream class. + * * @tparam Type The type of the elements that will be written to the stream. */ template GenericOutputStream::~GenericOutputStream() { @@ -71,52 +83,56 @@ namespace maxOS{ } /** - * @details This function is called when an element is read from the stream. + * @brief Writes the date that was read from the input stream to the output stream. + * * @tparam Type The type of the elements that will be written to the stream. - * @param readElement The element that was read from the stream. + * @param read_element The element that was read from the stream. */ - template void GenericOutputStream::onStreamRead(Type readElement) { + template void GenericOutputStream::on_stream_read(Type read_element) { // When something is read from the input stream, it is written to the output stream. - write(readElement); + write(read_element); - // Pass the element to any handlers. - for(typename Vector*>::iterator inputStreamEventHandler = this -> inputStreamEventHandlers.begin(); inputStreamEventHandler != this -> inputStreamEventHandlers.end(); ++inputStreamEventHandler) - (*inputStreamEventHandler)->onStreamRead(readElement); + // Pass the element to any handlers + for(auto& input_stream_event_handler : this ->m_input_stream_event_handlers) + input_stream_event_handler->on_stream_read(read_element); } /** - * @details This function is called when the end of the stream is reached. + * @brief Close the stream and remove it from the list of streams when the end of the stream is reached. + * * @tparam Type The type of the elements that will be written to the stream. * @param stream The stream that reached the end. */ - template void GenericOutputStream::onEndOfStream(GenericInputStream *stream) { + template void GenericOutputStream::on_end_of_stream(GenericInputStream *stream) { // Close the stream. close(); - // Pass the event to any handlers. - for(typename Vector*>::iterator inputStreamEventHandler = this -> inputStreamEventHandlers.begin(); inputStreamEventHandler != this -> inputStreamEventHandlers.end(); ++inputStreamEventHandler) - (*inputStreamEventHandler) -> onEndOfStream(stream); + // Pass the event to any handlers + for(auto& input_stream_event_handler : this ->m_input_stream_event_handlers) + input_stream_event_handler->on_end_of_stream(stream); - // Handle the event on this class - InputStreamProcessor::onEndOfStream(stream); + // Remove the stream from the list of streams. + InputStreamProcessor::on_end_of_stream(stream); } /** - * @details This function writes an element to the stream. + * @brief write an element to the stream. + * * @tparam Type The type of the elements that will be written to the stream. - * @param writeElement The element that will be written to the stream. + * @param write_element The element that will be written to the stream. */ - template void GenericOutputStream::write(Type writeElement) { + template void GenericOutputStream::write(Type write_element) { } /** - * @details This function closes the stream. + * @brief Close the stream. + * * @tparam Type The type of the elements that will be written to the stream. */ template void GenericOutputStream::close() { @@ -124,24 +140,20 @@ namespace maxOS{ } /** - * @details This function writes an element to the stream. + * @brief Overload the << operator to write an element to the stream. + * * @tparam Type The type of the elements that will be written to the stream. - * @param writeElement The element that will be written to the stream. - * @return The stream. + * @param write_element The element that will be written to the stream. + * @return The stream */ - template GenericOutputStream &GenericOutputStream::operator << (Type writeElement) { + template GenericOutputStream &GenericOutputStream::operator << (Type write_element) { - // Write the element to the stream. - write(writeElement); + // write the element to the stream. + write(write_element); // Return the stream. return *this; - } - } - } - - #endif //MAXOS_COMMON_OUTPUTSTREAM_H diff --git a/kernel/include/common/pair.h b/kernel/include/common/pair.h index 9f9a88dd..c0e385d3 100644 --- a/kernel/include/common/pair.h +++ b/kernel/include/common/pair.h @@ -9,6 +9,13 @@ namespace maxOS { namespace common { + /** + * @class Pair + * @brief A pair of two objects + * + * @tparam First The type of the m_first_memory_chunk object + * @tparam Second The type of the second object + */ template class Pair { public: First first; @@ -19,24 +26,21 @@ namespace maxOS { ~Pair(); }; - //_____________________________Implementation___________________________________________ + ///_____________________________Implementation___________________________________________/// template Pair::Pair() { } template Pair::Pair(First first, Second second) + : first(first), + second(second) { - this->first = first; - this->second = second; + } template Pair::~Pair() { } - - - //Note, The GUI fucked it self soley because pair was implmented inline ffs - } } diff --git a/kernel/include/common/rectangle.h b/kernel/include/common/rectangle.h index bef8f5a4..abee242e 100644 --- a/kernel/include/common/rectangle.h +++ b/kernel/include/common/rectangle.h @@ -14,75 +14,56 @@ namespace maxOS{ // A rectangle template for use in the GUI system template class Rectangle{ public: - Type left; - Type top; - Type width; - Type height; + Type left { 0 }; + Type top { 0 }; + Type width { 0 }; + Type height { 0 }; Rectangle(); Rectangle(Type left, Type top, Type width, Type height); ~Rectangle(); - bool intersects(const Rectangle& other); - Rectangle intersection(const Rectangle& other); - Vector > subtract(const Rectangle& other); - bool contains(const Rectangle& other); + bool intersects(const Rectangle&); + Rectangle intersection(const Rectangle&); + + Vector > subtract(const Rectangle&); + + bool contains(const Rectangle&); bool contains(Type x, Type y); }; ///_______________________________________________TEMPLATES_________________________________________________________________/// - /** - * @details A rectangle template for use in the GUI system - * - * @tparam Type Type of the rectangle - */ template Rectangle::Rectangle(){ - left = 0; - top = 0; - height = 0; - width = 0; } - /** - * @details A rectangle template for use in the GUI system - * - * @tparam Type The type of the rectangle - * @param left - * @param top - * @param width - * @param height - */ - template Rectangle::Rectangle(Type left, Type top, Type width, Type height){ - // If the width is negative, adjust the left + + template Rectangle::Rectangle(Type left, Type top, Type width, Type height) + : left(left), + top(top), + width(width), + height(height) + { + + // If the width is negative, move the left and make the width positive if(width < 0) { - left += width; // Add the width to the left, what this does is move the left to the right - width *= -1; // Multiply the width by -1, what this does is make the width positive + left += width; + width *= -1; } - // If the height is negative, adjust the top + // If the m_height is negative, move the top and make the height positive if(height < 0) { - top += height; // Add the height to the top, what this does is move the top down - height *= -1; // Multiply the height by -1, what this does is make the height positive + top += height; + height *= -1; } // Set the values this->left = left; - //this -> right = left + width; # The right is not needed, it can be calculated from the left and width this->top = top; - //this -> bottom = top + height; # The bottom is not needed, it can be calculated from the top and height - - this->width = width; - this->height = height; } - /** - * @details Destructor - * - * @tparam Type The type of the rectangle - */ template Rectangle::~Rectangle() { } @@ -116,7 +97,7 @@ namespace maxOS{ } /** - * @details Returns the intersection of this rectangle and another rectangle + * @details Returns a retangle that represents the intersection of this rectangle and another rectangle * * @tparam Type The type of the rectangle * @param other The other rectangle @@ -127,13 +108,13 @@ namespace maxOS{ if(!intersects(other)) return Rectangle(); - // Get the left and top of the intersection - Type left = this -> left > other.left ? this -> left : other.left; // Check if the left of this rectangle is greater than the left of the other rectangle, if it is, use the left of this rectangle, otherwise use the left of the other rectangle - Type top = this -> top > other.top ? this -> top : other.top; // Check if the top of this rectangle is greater than the top of the other rectangle, if it is, use the top of this rectangle, otherwise use the top of the other rectangle + // Get the left and top of the intersection using the maximum of the two + Type left = this -> left > other.left ? this -> left : other.left; + Type top = this -> top > other.top ? this -> top : other.top; - // Get the right and bottom of the intersection - Type right = this -> left + this -> width < other.left + other.width ? this -> left + this -> width : other.left + other.width; // Check if the right of this rectangle is less than the right of the other rectangle, if it is, use the right of this rectangle, otherwise use the right of the other rectangle - Type bottom = this -> top + this -> height < other.top + other.height ? this -> top + this -> height : other.top + other.height; // Check if the bottom of this rectangle is less than the bottom of the other rectangle, if it is, use the bottom of this rectangle, otherwise use the bottom of the other rectangle + // Get the right and bottom of the intersection using the minimum of the two + Type right = this -> left + this -> width < other.left + other.width ? this -> left + this -> width : other.left + other.width; + Type bottom = this -> top + this -> height < other.top + other.height ? this -> top + this -> height : other.top + other.height; // Return the intersection return Rectangle(left, top, right - left, bottom - top); @@ -151,10 +132,10 @@ namespace maxOS{ // Store the result rectangle Vector > result; - // If the rectangles don't intersect, return this rectangle + // Make sure the rectangles intersect if(!intersects(other)) { - result.pushBack(*this); + result.push_back(*this); return result; } @@ -163,34 +144,29 @@ namespace maxOS{ Type minRight = (left + width < other.left + other.width ? left + width : other.left + other.width); Type minBottom = (top + height < other.top + other.height ? top+height : other.top + other.height); + // Add the non intersecting rectangles to the result - // If the top of the other rectangle is above the top of this rectangle then this rectangle must be inside the other rectangle - if(top < other.top) - { - // Create a rectangle from the top of this rectangle to the top of the other rectangle (the block above the other rectangle) - result.pushBack(Rectangle(maxLeft, top, minRight - maxLeft, other.top - top)); - } + // Add non-overlapping region above if current top is less than other top + if (top < other.top) + result.push_back(Rectangle(maxLeft, top, minRight - maxLeft, + other.top - top)); - // If the left of this rectangle is to the left of the left of the other rectangle then this rectangle must be inside the other rectangle - if(left < other.left) - { - // Create a rectangle from the left of this rectangle to the left of the other rectangle (the block to the left of the other rectangle) - result.pushBack(Rectangle(left, top, other.left - left, height)); - } + // Add non-overlapping region to the left if current left is less than other left + if (left < other.left) + result.push_back( + Rectangle(left, top, other.left - left, height)); - // If the right of this rectangle is to the right of the right of the other rectangle then this rectangle must be inside the other rectangle - if(left +width > other.left + other.width) - { - // Create a rectangle from the right of the other rectangle to the right of this rectangle (the block to the right of the other rectangle) - result.pushBack(Rectangle(other.left + other.width, top, (left+width) - (other.left+other.width) + 1,height)); - } + // Add non-overlapping region to the right if current right is greater than other right + if (left + width > other.left + other.width) + result.push_back(Rectangle( + other.left + other.width, top, + (left + width) - (other.left + other.width) + 1, height)); - // If the bottom of this rectangle is below the bottom of the other rectangle then this rectangle must be inside the other rectangle - if(this -> top + this -> height > other.top + other.height) - { - // Create a rectangle from the bottom of the other rectangle to the bottom of this rectangle (the block below the other rectangle) - result.pushBack(Rectangle(maxLeft, minBottom, minRight-maxLeft, top+height-minBottom + 1)); - } + // Add non-overlapping region below if current bottom is greater than other bottom + if (this->top + this->height > other.top + other.height) + result.push_back(Rectangle(maxLeft, minBottom, + minRight - maxLeft, + top + height - minBottom + 1)); return result; } @@ -203,6 +179,7 @@ namespace maxOS{ * @return True if this rectangle contains the other rectangle, false otherwise */ template bool Rectangle::contains(const Rectangle& other){ + // If the other rectangle is to the left of this rectangle if(other.left + other.width <= left) return false; @@ -225,15 +202,16 @@ namespace maxOS{ /** - * @details Checks if this rectangle contains a point - * - * @tparam Type The type of the rectangle - * @param x The x coordinate of the point - * @param y The y coordinate of the point - * @return True if this rectangle contains the point, false otherwise - */ + * @details Checks if this rectangle contains a point + * + * @tparam Type The type of the rectangle + * @param x The x coordinate of the point + * @param y The y coordinate of the point + * @return True if this rectangle contains the point, false otherwise + */ template bool Rectangle::contains(Type x, Type y){ - // If the point is to the left of this rectangle + + // If the point is to the left of this rectangle if(x < left) return false; @@ -255,9 +233,5 @@ namespace maxOS{ } } - } - - - #endif //MAXOS_COMMON_RECTANGLE_H diff --git a/kernel/include/common/time.h b/kernel/include/common/time.h index dcdb988a..c53ad3fd 100644 --- a/kernel/include/common/time.h +++ b/kernel/include/common/time.h @@ -11,6 +11,9 @@ namespace maxOS{ namespace common{ + /** + * @struct Time + */ struct Time{ uint16_t year; diff --git a/kernel/include/common/vector.h b/kernel/include/common/vector.h index 33e5e0ed..186bac1c 100644 --- a/kernel/include/common/vector.h +++ b/kernel/include/common/vector.h @@ -11,22 +11,34 @@ namespace maxOS{ namespace common{ + /** + * @class VectorIterationHandler + * @brief Handles the iteration of a Vector providing read and end of stream functions + * + * @tparam Type Type of the Vector + */ template class VectorIterationHandler { public: VectorIterationHandler(); ~VectorIterationHandler(); - virtual void OnRead(Type); - virtual void OnEndOfStream(); - }; + virtual void on_read(Type); + virtual void on_end_of_stream(); + }; + /** + * @class Vector + * @brief Dynamically stores an array of elements + * + * @tparam Type Type of the Vector + */ template class Vector { protected: - Type elements[100]; // fake - currently max 100 elements - but the interface should be used already - uint32_t Size; - uint32_t MaxSize; + Type m_elements[100]; //Todo: make this dynamic + uint32_t m_size { 0 }; + uint32_t m_max_size { 100 }; public: typedef Type* iterator; @@ -35,194 +47,212 @@ namespace maxOS{ ~Vector(); Type& operator[](int index); + + bool empty(); uint32_t size(); + iterator begin(); iterator end(); - iterator find(Type element); - bool empty(); + iterator find(Type); + + iterator push_back(Type); + void pop_back(); + + iterator push_front(Type); + void pop_front(); - iterator pushBack(Type element); - void popBack(); - iterator pushFront(Type element); - void popFront(); - void erase(Type element); + void erase(Type); void erase(iterator position); void clear(); - void Iterate(VectorIterationHandler* vectorIterationHandler); + void iterate(VectorIterationHandler*); void Iterate(void callback(Type&)); }; - //______________________________________Implementation__________________________________________________ + ///______________________________________Implementation__________________________________________________ /** - * Base Template for VectorIterationHandler + * @brief Constructor for Vector + * * @tparam Type Type of the Vector */ - template - Vector::Vector() { - MaxSize = 100; - Size = 0; + template Vector::Vector() { + } /** - * Template for VectorIterationHandler - * @tparam Type Type of the Vector - * @param Size Size of the Vector - * @param element Element to fill the Vector with - */ - template - Vector::Vector(int Size, Type element) { - MaxSize = 100; + * @brief Constructor for Vector + * + * @tparam Type Type of the Vector + * @param Size Size of the Vector + * @param element Element to fill the Vector with + */ + template Vector::Vector(int Size, Type element) { - if (Size >= MaxSize) - Size = MaxSize; + // Make sure the size is not bigger than the max size + if (Size > m_max_size) + Size = m_max_size; - this->Size = Size; - for (iterator i = begin(); i != end(); i++) - *i = element; + // Fill the Vector with the element + for (int i = 0; i < Size; ++i) + m_elements[i] = element; + + // Set the size of the Vector + m_size = Size; } - template - Vector::~Vector() { + template Vector::~Vector() { } /** - * Operator [] for Vector + * @brief Overloads the [] operator to return the element at the index + * * @tparam Type Type of the Vector * @param index The index of the element * @return the element at the index */ - template - Type &Vector::operator[](int index) { - if (index <= Size) - return elements[index]; + template Type &Vector::operator[](int index) { + // If the index is in the Vector + if (index <= m_size) + return m_elements[index]; } /** - * Returns the size of the Vector - * @tparam Type Type of the Vector - * @return Size of the Vector + * @brief Returns the number of elements in the Vector + * + * @tparam Type Type of the Vector + * @return The size of the Vector */ - template - uint32_t Vector::size() { - return Size; + template uint32_t Vector::size() { + return m_size; } /** - * Returns the begin of the Vector - * @tparam Type Type of the Vector - * @return The begin of the Vector + * @brief Returns the m_first_memory_chunk element of the Vector + * + * @tparam Type Type of the Vector + * @return The m_first_memory_chunk element of the Vector */ - template - typename Vector::iterator Vector::begin() { - return &elements[0]; + template typename Vector::iterator Vector::begin() { + return &m_elements[0]; } /** - * Returns the end of the Vector - * @tparam Type Type of the Vector - * @return The end of the Vector + * @brief Returns the last element of the Vector + * + * @tparam Type Type of the Vector + * @return The last element of the Vector */ - template - typename Vector::iterator Vector::end() { - return &elements[0] + Size; - } + template typename Vector::iterator Vector::end() { + return &m_elements[0] + m_size; + } /** - * Finds an element in the Vector + * @brief Finds an element in the Vector and returns the iterator of the element + * * @tparam Type Type of the Vector * @param element The element to find - * @return The iterator of the element + * @return The iterator of the element or the end of the Vector if the element is not found */ - template - typename Vector::iterator Vector::find(Type element) { - for (iterator i = begin(); i != end(); ++i) // for each element in the Vector - if (*i == - element) // if the element is equal to the element we are looking for - return i; // return the iterator of the element - return end(); // else return the end of the Vector + template typename Vector::iterator Vector::find(Type element) { + + // Find the element + for (iterator i = begin(); i != end(); ++i) + if (*i == element) + return i; + + // The element must not be in the Vector + return end(); } /** - * Empty the Vector + * @brief Checks if the Vector is empty + * * @tparam Type Type of the Vector - * @return The iterator of the element + * @return True if the Vector is empty, false otherwise */ - template - bool Vector::empty() { + template bool Vector::empty() { return begin() == end(); } /** - * Pushes an element to the Vector (at the end) + * @brief Adds an element to the end of the vector and returns the iterator of the element + * * @tparam Type Type of the Vector - * @param element The element to push - - * @return The iterator of the element + * @param element The element to add + * @return The iterator of the element, if the Vector is full it returns the end of the Vector */ - template - typename Vector::iterator Vector::pushBack(Type element) { - if (Size >= MaxSize) // if the Vector is full - return end(); // return the end of the Vector - - elements[Size++] = element; // else add the element to the Vector - return end() - 1; // return the iterator of the element + template typename Vector::iterator Vector::push_back(Type element) { + // Return the end of the Vector if it is full + if (m_size >= m_max_size) + return end(); + + // Add the element to the Vector and return the iterator of the element + m_elements[m_size++] = element; + return end() - 1; } /** - * Removes an element from the Vector (at the end) + * @brief Removes the last element from the Vector * @tparam Type Type of the Vector */ - template - void Vector::popBack() { - if (Size > 0) // if the Vector is not empty - --Size; // remove the last element + template void Vector::pop_back() { + // Remove the last element from the Vector + if (m_size > 0) + --m_size; } /** - * Removes an element from the Vector (at the index) - * @tparam Type Type of the Vector - * @param element The element to remove - - * @return The iterator of the element + * @brief Adds an element to the front of the Vector and returns the iterator of the element + * + * @tparam Type Type of the Vector + * @param element The element to add + * @return The iterator of the element, if the Vector is full it returns the end of the Vector */ - template typename Vector::iterator Vector::pushFront(Type element) { + template typename Vector::iterator Vector::push_front(Type element) { // Make sure the Vector is not full - if (Size >= MaxSize) + if (m_size >= m_max_size) return end(); - // for each element in the Vector + // Move all elements one index to the right for (iterator i = end(); i > begin(); --i) - *i = *(i - 1); // move the element one index to the right + *i = *(i - 1); - elements[0] = element; // add the element to front of the Vector - ++Size; // increase the size of the Vector + // Add the element to the front of the Vector + m_elements[0] = element; + ++m_size; - return begin(); // return the iterator of the element + // Return the iterator of the element + return begin(); } /** - * Removes an element from the Vector (at the index) - * @tparam Type Type of the Vector - + * @brief Removes the m_first_memory_chunk element from the Vector + * + * @tparam Type Type of the Vector */ - template void Vector::popFront() { - if (Size > 0) //If the Vector is not empty - { - for (iterator i = begin() + 1; i != end(); ++i) // for each element in the Vector - *(i - 1) = *i; // move the element one index to the left - --Size; // decrease the size of the Vector - } + template void Vector::pop_front() { + + // Make sure the Vector is not empty + if (m_size == 0) + return; + + // Move all elements one index to the left + for (iterator i = begin(); i != end(); ++i) + *i = *(i + 1); + + // Decrease the size of the Vector + --m_size; } /** - * Removes an element from the Vector - * @tparam Type The type of the Vector + * @brief Removes all elements from the Vector that are equal to the element + * + * @tparam Type Type of the Vector * @param element The element to remove */ template void Vector::erase(Type element) { @@ -237,89 +267,92 @@ namespace maxOS{ ++hits; } else { - // if we have hits + // If there are hits move the element to the left if (hits > 0) - *(i - hits) = *i; // move the element to the left + *(i - hits) = *i; } } - Size -= hits; // decrease the size of the Vector + + // Decrease the size of the Vector + m_size -= hits; } /** - * Removes the element at the index + * @brief Removes the element at the m_position + * * @tparam Type The type of the Vector - * @param position The position of the element to remove + * @param position The m_position of the element to remove */ template void Vector::erase(typename Vector::iterator position) { - // element not in this vector + + // If the m_position is not in the Vector if (position < begin() || position >= end()) return; - // move all elements one index to the left + // Move all elements one index to the left for (++position; position != end(); ++position) *(position - 1) = *position; - // decrease the size of the Vector - --Size; + // Decrease the size of the Vector + --m_size; } /** - * Clears the Vector - * @tparam Type Type of the Vector + * @brief Removes all elements from the Vector + * + * @tparam Type Type of the Vector */ - template - void Vector::clear() { - Size = 0; + template void Vector::clear() { + m_size = 0; } - /** - * Iterator for Vector - * @tparam Type Type of the Vector - - * @param vectorIterationHandler The handler of the Vector + * @brief Iterates over the Vector and calls the OnRead function of the handler for each element + * + * @tparam Type Type of the Vector + * @param vector_iteration_handler The handler */ - template - void Vector::Iterate(VectorIterationHandler *vectorIterationHandler) { - // for each element in the Vector - for (iterator i = begin(); i != end(); ++i) - vectorIterationHandler -> OnRead(*i); // call the OnRead function of the handler - vectorIterationHandler -> OnEndOfStream(); // call the OnEndOfStream function of the handler + template void Vector::iterate(VectorIterationHandler *vector_iteration_handler) { + + // Call the OnRead function of the handler for each element + for(auto& element : m_elements) + vector_iteration_handler->on_read(element); + + // Call the OnEndOfStream function of the handler + vector_iteration_handler->on_end_of_stream(); } + /** - * Iterates over the Vector + * @brief Iterates over the Vector and calls the callback function for each element + * * @tparam Type Type of the Vector * @param callback The callback function */ - template - void Vector::Iterate(void callback(Type &)) { - for (iterator i = begin(); i != end(); ++i) // for each element in the Vector - callback(*i); // call the callback function + template void Vector::Iterate(void callback(Type &)) { + + // Call the callback function for each element + for(auto& element : m_elements) + callback(element); } - template - void VectorIterationHandler::OnEndOfStream() { + template VectorIterationHandler::VectorIterationHandler() { } - template - void VectorIterationHandler::OnRead(Type) { + template VectorIterationHandler::~VectorIterationHandler() { } - template - VectorIterationHandler::~VectorIterationHandler() { + template void VectorIterationHandler::on_end_of_stream() { } - template - VectorIterationHandler::VectorIterationHandler() { + template void VectorIterationHandler::on_read(Type) { } - } } diff --git a/kernel/include/drivers/ata.h b/kernel/include/drivers/ata.h index 9ee9a9f9..b361f912 100644 --- a/kernel/include/drivers/ata.h +++ b/kernel/include/drivers/ata.h @@ -13,38 +13,38 @@ namespace maxOS{ namespace drivers{ + /** + * @class AdvancedTechnologyAttachment + * @brief Driver for the ATA controller, handles the reading and writing of data to the hard drive + */ class AdvancedTechnologyAttachment{ protected: - hardwarecommunication::Port16Bit dataPort; - hardwarecommunication::Port8Bit errorPort; - hardwarecommunication::Port8Bit sectorCountPort; - hardwarecommunication::Port8Bit LBAlowPort; - hardwarecommunication::Port8Bit LBAmidPort; - hardwarecommunication::Port8Bit LBAHiPort; - hardwarecommunication::Port8Bit devicePort; - hardwarecommunication::Port8Bit commandPort; - hardwarecommunication::Port8Bit controlPort; - bool master; - uint16_t bytesPerSector; - - common::OutputStream* ataMessageStream; + hardwarecommunication::Port16Bit m_data_port; + hardwarecommunication::Port8Bit m_error_port; + hardwarecommunication::Port8Bit m_sector_count_port; + hardwarecommunication::Port8Bit m_LBA_low_port; + hardwarecommunication::Port8Bit m_LBA_mid_port; + hardwarecommunication::Port8Bit m_LBA_high_Port; + hardwarecommunication::Port8Bit m_device_port; + hardwarecommunication::Port8Bit m_command_port; + hardwarecommunication::Port8Bit m_control_port; + bool m_is_master; + uint16_t m_bytes_per_sector { 512 }; + + common::OutputStream* ata_message_stream; public: - AdvancedTechnologyAttachment(uint16_t portBase, bool master, common::OutputStream* ataMessageStream); + AdvancedTechnologyAttachment(uint16_t port_base, bool master, common::OutputStream* output_stream); ~AdvancedTechnologyAttachment(); - void Identify(); - void Read28(uint32_t sector, uint8_t* data, int count); - void Write28(uint32_t sector, uint8_t* data, int count); - void Flush(); //Flush Cache //TODO: See also vid 19 24:20 + void identify(); + void read_28(uint32_t sector, uint8_t* data, int count); + void write_28(uint32_t sector, uint8_t* data, int count); + void flush(); //TODO: See also vid 19 24:20 //TODO: Make into driver class - - }; - } - } #endif //MAXOS_DRIVERS_ATA_H diff --git a/kernel/include/drivers/clock/clock.h b/kernel/include/drivers/clock/clock.h index ecb1059f..7bf117c5 100644 --- a/kernel/include/drivers/clock/clock.h +++ b/kernel/include/drivers/clock/clock.h @@ -22,55 +22,68 @@ namespace maxOS { TIME }; + /** + * @class TimeEvent + * @brief Event that is triggered when the clock ticks, holds the current time + */ class TimeEvent : public common::Event{ public: common::Time* time; - TimeEvent(common::Time* time); + TimeEvent(common::Time*); ~TimeEvent(); }; + + /** + * @class ClockEventHandler + */ class ClockEventHandler : public common::EventHandler{ public: ClockEventHandler(); ~ClockEventHandler(); - common::Event* onEvent(common::Event* event); + common::Event* on_event(common::Event* event) override; - virtual void onTime(const common::Time& time); + virtual void on_time(const common::Time& time); }; + /** + * @class Clock + * @brief Driver for the CMOS Real Time Clock + */ class Clock: public Driver, public hardwarecommunication::InterruptHandler, public common::EventManager{ private: - volatile uint64_t ticks; // Ensure that the compiler does not optimize this variable out of the code (volatile) + + // Ensure that the compiler does not optimize this variable out of the code (volatile) + volatile uint64_t m_ticks; protected: - // Store all the event clockEventHandlers - common::Vector clockEventHandlers; - bool binaryCodedDecimalRepresentation; + + bool m_binary_coded_decimal_representation; // Ports - hardwarecommunication::Port8Bit dataPort; - hardwarecommunication::Port8Bit commandPort; + hardwarecommunication::Port8Bit m_data_port; + hardwarecommunication::Port8Bit m_command_port; // Time between events - uint16_t ticksBetweenEvents; - uint16_t ticksUntilNextEvent; + uint16_t m_ticks_between_events { 0 }; + uint16_t m_ticks_until_next_event { 1 }; // Other functions - void HandleInterrupt(); - uint8_t readHardwareClock(uint8_t address); - uint8_t binaryRepresentation(uint8_t number); + void handle_interrupt() final; + uint8_t read_hardware_clock(uint8_t address); + uint8_t binary_representation(uint8_t number); public: - Clock(hardwarecommunication::InterruptManager* interruptManager, uint16_t timeBetweenEvents = 10); + Clock(hardwarecommunication::InterruptManager* interrupt_manager, uint16_t time_between_events = 10); ~Clock(); - void activate(); + void activate() override; void delay(uint32_t milliseconds); - string getVendorName(); - string getDeviceName(); + string get_vendor_name() final; + string get_device_name() final; }; } diff --git a/kernel/include/drivers/console/console.h b/kernel/include/drivers/console/console.h index 51d2814d..ebd908da 100644 --- a/kernel/include/drivers/console/console.h +++ b/kernel/include/drivers/console/console.h @@ -34,76 +34,93 @@ namespace maxOS { White = 0x0F }; + /** + * @class Console + * @brief Abstract class for a console, allows for the printing of characters and strings with colours + */ class Console { - public: - Console(); - ~Console(); + public: + Console(); + ~Console(); - virtual uint16_t getWidth(); - virtual uint16_t getHeight(); + virtual uint16_t width(); + virtual uint16_t height(); - virtual void putChar(uint16_t x, uint16_t y, char c); - virtual char getChar(uint16_t x, uint16_t y); + virtual void put_character(uint16_t x, uint16_t y, char c); + virtual char get_character(uint16_t x, uint16_t y); - virtual void setForegroundColor(uint16_t x, uint16_t y, ConsoleColour foreground); - virtual void setBackgroundColor(uint16_t x, uint16_t y, ConsoleColour background); + virtual void set_foreground_color(uint16_t x, uint16_t y, ConsoleColour foreground); + virtual void set_background_color(uint16_t x, uint16_t y, ConsoleColour background); - virtual ConsoleColour getForegroundColor(uint16_t x, uint16_t y); - virtual ConsoleColour getBackgroundColor(uint16_t x, uint16_t y); + virtual ConsoleColour get_foreground_color(uint16_t x, uint16_t y); + virtual ConsoleColour get_background_color(uint16_t x, uint16_t y); - virtual void putChar(uint16_t x, uint16_t y, char c, ConsoleColour foreground, ConsoleColour background); - virtual void putString(uint16_t x, uint16_t y, string s, ConsoleColour foreground = LightGrey, ConsoleColour background = Black); - virtual void scrollUp(); - virtual void scrollUp(uint16_t left, uint16_t top, uint16_t width, uint16_t height, ConsoleColour foreground = LightGrey, ConsoleColour background = Black, char fill=' '); - virtual void clear(); - virtual void clear(uint16_t left, uint16_t top, uint16_t width, uint16_t height, ConsoleColour foreground = LightGrey, ConsoleColour background = Black, char fill=' '); - virtual void invertColors(uint16_t x, uint16_t y); + virtual void put_character(uint16_t x, uint16_t y, char c, ConsoleColour foreground, ConsoleColour background); + virtual void put_string(uint16_t x, uint16_t y, string s, ConsoleColour foreground = LightGrey, ConsoleColour background = Black); + + virtual void scroll_up(); + virtual void scroll_up(uint16_t left, uint16_t top, uint16_t width, uint16_t height, ConsoleColour foreground = LightGrey, ConsoleColour background = Black, char fill= ' '); + + virtual void clear(); + virtual void clear(uint16_t left, uint16_t top, uint16_t width, uint16_t height, ConsoleColour foreground = LightGrey, ConsoleColour background = Black, char fill=' '); + + virtual void invert_colors(uint16_t x, uint16_t y); + }; + /** + * @class ConsoleArea + * @brief A console that is a subsection of another console, limited by a width and height + */ class ConsoleArea : public Console { - protected: - Console* console; - uint16_t left; - uint16_t top; - uint16_t width; - uint16_t height; - public: - ConsoleArea(Console* console, uint16_t left, uint16_t top, uint16_t width, uint16_t height); - ConsoleArea(Console* console, uint16_t left, uint16_t top, uint16_t width, uint16_t height, ConsoleColour foreground, ConsoleColour background); - ~ConsoleArea(); - - uint16_t getWidth(); - uint16_t getHeight(); - - void putChar(uint16_t x, uint16_t y, char c); - void setForegroundColor(uint16_t x, uint16_t y, ConsoleColour foreground); - void setBackgroundColor(uint16_t x, uint16_t y, ConsoleColour background); - - char getChar(uint16_t x, uint16_t y); - ConsoleColour getForegroundColor(uint16_t x, uint16_t y); - ConsoleColour getBackgroundColor(uint16_t x, uint16_t y); + protected: + Console* m_console; + uint16_t m_left; + uint16_t m_top; + uint16_t m_width; + uint16_t m_height; + public: + ConsoleArea(Console* console, uint16_t left, uint16_t top, uint16_t width, uint16_t height); + ConsoleArea(Console* console, uint16_t left, uint16_t top, uint16_t width, uint16_t height, ConsoleColour foreground, ConsoleColour background); + ~ConsoleArea(); + + uint16_t width() override; + uint16_t height() override; + + void put_character(uint16_t x, uint16_t y, char c) override; + void set_foreground_color(uint16_t x, uint16_t y, ConsoleColour foreground) override; + void set_background_color(uint16_t x, uint16_t y, ConsoleColour background) override; + + char get_character(uint16_t x, uint16_t y) override; + ConsoleColour get_foreground_color(uint16_t x, uint16_t y) override; + ConsoleColour get_background_color(uint16_t x, uint16_t y) override; }; + /** + * @class ConsoleStream + * @brief A stream that can be used to write to a console + */ class ConsoleStream : public common::OutputStream { - protected: - Console* console; + protected: + Console* m_console; - ConsoleColour foreground; - ConsoleColour background; + ConsoleColour m_foreground; + ConsoleColour m_background; - public: - uint16_t cursorX; - uint16_t cursorY; + public: + uint16_t m_cursor_x { 0 }; + uint16_t m_cursor_y { 0 }; - ConsoleStream(Console* console); - ~ConsoleStream(); - void writeChar(char c); - void setCursor(uint16_t x, uint16_t y); - }; + ConsoleStream(Console*); + ~ConsoleStream(); + + void write_char(char c) override; + void set_cursor(uint16_t x, uint16_t y); + }; } } diff --git a/kernel/include/drivers/console/textmode.h b/kernel/include/drivers/console/textmode.h index 8d9286d1..8ddc2e5b 100644 --- a/kernel/include/drivers/console/textmode.h +++ b/kernel/include/drivers/console/textmode.h @@ -15,26 +15,29 @@ namespace maxOS{ namespace console { + /** + * @class TextModeConsole + * @brief Driver for the text mode console, handles the printing of characters and strings to the screen using VGA + */ class TextModeConsole : public Driver, public Console { + protected: + uint16_t* m_video_memory { (uint16_t*)0xB8000 }; public: TextModeConsole(); ~TextModeConsole(); - uint16_t getWidth(); - uint16_t getHeight(); - - void putChar(uint16_t x, uint16_t y, char c); - void setForegroundColor(uint16_t x, uint16_t y, ConsoleColour foreground); - void setBackgroundColor(uint16_t x, uint16_t y, ConsoleColour background); + uint16_t width() final; + uint16_t height() final; - char getChar(uint16_t x, uint16_t y); - ConsoleColour getForegroundColor(uint16_t x, uint16_t y); - ConsoleColour getBackgroundColor(uint16_t x, uint16_t y); + void put_character(uint16_t x, uint16_t y, char c) final; + void set_foreground_color(uint16_t x, uint16_t y, ConsoleColour) final; + void set_background_color(uint16_t x, uint16_t y, ConsoleColour) final; - protected: - uint16_t* videoMemory; + char get_character(uint16_t x, uint16_t y) final; + ConsoleColour get_foreground_color(uint16_t x, uint16_t y) final; + ConsoleColour get_background_color(uint16_t x, uint16_t y) final; }; } diff --git a/kernel/include/drivers/console/vesaboot.h b/kernel/include/drivers/console/vesaboot.h index 3ccf9b64..b8408ca6 100644 --- a/kernel/include/drivers/console/vesaboot.h +++ b/kernel/include/drivers/console/vesaboot.h @@ -16,33 +16,34 @@ namespace maxOS{ namespace console { + /** + * @class VESABootConsole + * @brief Driver for the VESA Console during boot, handles the printing of characters and strings to the screen using VESA + */ class VESABootConsole : public Driver, public Console { - public: - VESABootConsole(common::GraphicsContext* graphicsContext); - ~VESABootConsole(); + public: + VESABootConsole(common::GraphicsContext*); + ~VESABootConsole(); - uint16_t getWidth(); - uint16_t getHeight(); + uint16_t width() final; + uint16_t height() final; - void putChar(uint16_t x, uint16_t y, char c); - void setForegroundColor(uint16_t x, uint16_t y, ConsoleColour foreground); - void setBackgroundColor(uint16_t x, uint16_t y, ConsoleColour background); + void put_character(uint16_t x, uint16_t y, char) final; + void set_foreground_color(uint16_t x, uint16_t y, ConsoleColour) final; + void set_background_color(uint16_t x, uint16_t y, ConsoleColour) final; - char getChar(uint16_t x, uint16_t y); - ConsoleColour getForegroundColor(uint16_t x, uint16_t y); - ConsoleColour getBackgroundColor(uint16_t x, uint16_t y); + char get_character(uint16_t x, uint16_t y) final; + ConsoleColour get_foreground_color(uint16_t x, uint16_t y) final; + ConsoleColour get_background_color(uint16_t x, uint16_t y) final; - common::Colour consoleColourToVESA(ConsoleColour colour); + common::Colour console_colour_to_vesa(ConsoleColour); - // pointer to the video memory - uint16_t* videoMemory; - - protected: - - common::GraphicsContext* graphicsContext; - gui::AmigaFont font; + protected: + uint16_t* m_video_memory; + common::GraphicsContext* m_graphics_context; + gui::AmigaFont m_font; }; } diff --git a/kernel/include/drivers/driver.h b/kernel/include/drivers/driver.h index 0ab89701..9f937d7c 100644 --- a/kernel/include/drivers/driver.h +++ b/kernel/include/drivers/driver.h @@ -17,55 +17,72 @@ namespace maxOS namespace drivers { + /** + * @class Driver + * @brief base class for all drivers, handles the activation, deactivation, initialisation and reset of the driver as well as error messages and identifying the device + */ class Driver { protected: public: - common::OutputStream* driverMessageStream; + common::OutputStream* m_driver_message_stream; + Driver(common::OutputStream* driverMessageStream = 0); ~Driver(); - void errorMessage(string message); - void errorMessage(char charToWrite); - void errorMessage(int intToWrite); - void errorMessage(uint32_t hexToWrite); + void error_message(string message); + void error_message(char char_to_write); + void error_message(int int_to_write); + void error_message(uint32_t hex_to_write); virtual void activate(); virtual void deactivate(); virtual void initialise(); virtual uint32_t reset(); - virtual string getVendorName(); - virtual string getDeviceName(); + virtual string get_vendor_name(); + virtual string get_device_name(); }; //NOTE: Driver doesn't use the EventHandler class because it doesn't need to be connected to anything (May want to change this later) + /** + * @class DriverSelectorEventHandler + * @brief Event handler for the DriverSelector class, handles the event when a driver is selected + */ class DriverSelectorEventHandler { - public: - DriverSelectorEventHandler(); - ~DriverSelectorEventHandler(); - virtual void onDriverSelected(Driver* driver); + public: + DriverSelectorEventHandler(); + ~DriverSelectorEventHandler(); + virtual void on_driver_selected(Driver*); }; + /** + * @class DriverSelector + * @brief Selects the drivers to be used + */ class DriverSelector { - public: - DriverSelector(); - ~DriverSelector(); - virtual void selectDrivers(DriverSelectorEventHandler* handler, hardwarecommunication::InterruptManager* interruptManager, common::OutputStream* errorMessageStream); + public: + DriverSelector(); + ~DriverSelector(); + virtual void select_drivers(DriverSelectorEventHandler* handler, hardwarecommunication::InterruptManager* interruptManager, common::OutputStream* errorMessageStream); }; + /** + * @class DriverManager + * @brief Manages the drivers, handles the adding and removing of drivers + */ class DriverManager : public DriverSelectorEventHandler { - public: - common::Vector drivers; public: DriverManager(); ~DriverManager(); - void addDriver(Driver*); - void removeDriver(Driver*); - void onDriverSelected(Driver* driver); + void add_driver(Driver*); + void remove_driver(Driver*); + void on_driver_selected(Driver*) final; + + common::Vector drivers; }; } } diff --git a/kernel/include/drivers/ethernet/amd_am79c973.h b/kernel/include/drivers/ethernet/amd_am79c973.h index d2572b96..7f2ce0ba 100644 --- a/kernel/include/drivers/ethernet/amd_am79c973.h +++ b/kernel/include/drivers/ethernet/amd_am79c973.h @@ -20,6 +20,10 @@ namespace maxOS{ class amd_am79c973; + /** + * @class AMD AM79C973 + * @brief Driver for the AMD AM79C973 Ethernet Controller + */ class amd_am79c973 : public EthernetDriver, public hardwarecommunication::InterruptHandler{ struct InitializationBlock{ @@ -92,11 +96,11 @@ namespace maxOS{ void deactivate(); // Naming - string getVendorName(); - string getDeviceName(); + string get_vendor_name(); + string get_device_name(); //Override Interrupt default methods - void HandleInterrupt(); + void handle_interrupt(); //Ethernet Driver functions void DoSend(uint8_t* buffer, uint32_t size); diff --git a/kernel/include/drivers/ethernet/ethernet.h b/kernel/include/drivers/ethernet/ethernet.h index 75ce68df..f68faf8c 100644 --- a/kernel/include/drivers/ethernet/ethernet.h +++ b/kernel/include/drivers/ethernet/ethernet.h @@ -24,7 +24,10 @@ namespace maxOS{ DATA_RECEIVED }; - + /** + * @class BeforeSendEvent + * @brief Event that is triggered before data is sent, holds the buffer and size of the data + */ class BeforeSendEvent : public common::Event{ public: uint8_t* buffer; @@ -33,6 +36,10 @@ namespace maxOS{ ~BeforeSendEvent(); }; + /** + * @class DataSentEvent + * @brief Event that is triggered when data is sent, holds the buffer and size of the data + */ class DataSentEvent : public common::Event{ public: uint8_t* buffer; @@ -41,6 +48,10 @@ namespace maxOS{ ~DataSentEvent(); }; + /** + * @class DataReceivedEvent + * @brief Event that is triggered when data is received, holds the buffer and size of the data + */ class DataReceivedEvent : public common::Event{ public: uint8_t* buffer; @@ -49,20 +60,29 @@ namespace maxOS{ ~DataReceivedEvent(); }; + /** + * @class EthernetDriverEventHandler + * @brief Handles the events that are triggered by the Ethernet Driver + */ class EthernetDriverEventHandler : public common::EventHandler { public: EthernetDriverEventHandler(); ~EthernetDriverEventHandler(); - virtual common::Event* onEvent(common::Event* event); + virtual common::Event* + on_event(common::Event* event); virtual void BeforeSend(uint8_t* buffer, uint32_t size); virtual void DataSent(uint8_t* buffer, uint32_t size); virtual bool DataReceived(uint8_t* buffer, uint32_t size); }; - class EthernetDriver : public Driver, public common::EventManager + /** + * @class EthernetDriver + * @brief Driver for the Ethernet Controller, manages the sending and receiving of data, the mac address, and the events + */ + class EthernetDriver : public Driver, public common::EventManager { protected: virtual void DoSend(uint8_t* buffer, uint32_t size); diff --git a/kernel/include/drivers/ethernet/intel_i217.h b/kernel/include/drivers/ethernet/intel_i217.h index 1cfdf34c..a357ac2a 100644 --- a/kernel/include/drivers/ethernet/intel_i217.h +++ b/kernel/include/drivers/ethernet/intel_i217.h @@ -22,10 +22,12 @@ namespace maxOS{ namespace ethernet{ + /** + * @class Intel I217 + * @brief Driver for the Intel I217 Ethernet Controller + */ class intel_i217 : public EthernetDriver, public hardwarecommunication::InterruptHandler { - - struct receiveDescriptor { uint64_t bufferAddress; // The address of the receive buffer uint16_t length; // The length of the received frame @@ -85,17 +87,17 @@ namespace maxOS{ uint16_t currentSendBuffer; // The current send buffer - // Write Commands and read results From NICs either using MemIO or IO Ports + // write Commands and read results From NICs either using MemIO or IO Ports void Write(uint16_t address, uint32_t data); uint32_t Read(uint16_t address); //EPROM (Device Memory) bool epromPresent; // Whether or not the EPROM is present bool detectEEProm(); // Return true if EEProm exist, else it returns false and set the eerprom_existsdata member - uint32_t eepromRead( uint8_t addr); // Read 4 bytes from a specific EEProm Address + uint32_t eepromRead( uint8_t addr); // read 4 bytes from a specific EEProm Address - bool readMACAddress(); // Read MAC Address + bool readMACAddress(); // read MAC Address void receiveInit(); // Initialise receive descriptors an buffers void sendInit(); // Initialise transmit descriptors an buffers @@ -120,12 +122,12 @@ namespace maxOS{ void deactivate(); //Override Interrupt default methods - void HandleInterrupt(); + void handle_interrupt(); //Ethernet Driver functions - string getVendorName(); - string getDeviceName(); + string get_vendor_name(); + string get_device_name(); void DoSend(uint8_t* buffer, uint32_t size); uint64_t GetMediaAccessControlAddress(); diff --git a/kernel/include/drivers/ethernet/rawdatahandler.h b/kernel/include/drivers/ethernet/rawdatahandler.h index b439d92a..addf15fe 100644 --- a/kernel/include/drivers/ethernet/rawdatahandler.h +++ b/kernel/include/drivers/ethernet/rawdatahandler.h @@ -13,6 +13,10 @@ namespace maxOS { namespace ethernet { + /** + * @class RawDataHandler + * @brief Handles raw data received from the ethernet controller + */ class RawDataHandler { public: diff --git a/kernel/include/drivers/peripherals/keyboard.h b/kernel/include/drivers/peripherals/keyboard.h index c63afefb..d3bbbb0f 100644 --- a/kernel/include/drivers/peripherals/keyboard.h +++ b/kernel/include/drivers/peripherals/keyboard.h @@ -193,24 +193,27 @@ namespace maxOS }; + /** + * @class KeyboardState + * @brief Holds the state of the keyboard + */ class KeyboardState{ - public: - KeyboardState(); - ~KeyboardState(); - - // Left and Right - bool leftShift; - bool rightShift; - bool leftControl; - bool rightControl; - bool leftAlt; - bool rightAlt; - - // Other Stuff - bool capsLock; - bool numberPadLock; - bool scrollLock; - + public: + KeyboardState(); + ~KeyboardState(); + + // Left and Right + bool left_shift { false }; + bool right_shift { false }; + bool left_control { false }; + bool right_control { false }; + bool left_alt { false }; + bool right_alt { false }; + + // Other Stuff + bool caps_lock { false }; + bool number_pad_lock { false }; + bool scroll_lock { false }; }; enum KeyboardEvents{ @@ -218,198 +221,220 @@ namespace maxOS KEYUP }; + /** + * @class KeyUpEvent + * @brief Event that is triggered when a key is released + */ class KeyUpEvent : public common::Event{ public: - KeyUpEvent(KeyCode keyCode, KeyboardState keyboardState); + KeyUpEvent(KeyCode, KeyboardState); ~KeyUpEvent(); - KeyCode keyCode; - KeyboardState keyboardState; + KeyCode key_code; + KeyboardState keyboard_state; }; + /** + * @class KeyDownEvent + * @brief Event that is triggered when a key is pressed + */ class KeyDownEvent : public common::Event{ public: - KeyDownEvent(KeyCode keyCode, KeyboardState keyboardState); + KeyDownEvent(KeyCode, KeyboardState); ~KeyDownEvent(); - KeyCode keyCode; - KeyboardState keyboardState; + KeyCode key_code; + KeyboardState keyboard_state; }; + /** + * @class KeyboardEventHandler + * @brief Handles the events that are triggered by the Keyboard Driver + */ class KeyboardEventHandler : public common::EventHandler{ public: KeyboardEventHandler(); ~KeyboardEventHandler(); - virtual common::Event* onEvent(common::Event* event); + virtual common::Event* on_event(common::Event*); - virtual void onKeyDown(KeyCode keyDownCode, KeyboardState keyDownState); - virtual void onKeyUp(KeyCode keyUpCode, KeyboardState keyUpState); + virtual void on_key_down(KeyCode, KeyboardState); + virtual void on_key_up(KeyCode, KeyboardState); }; + /** + * @class KeyboardInterpreter + * @brief Interprets the scan codes from the keyboard + */ class KeyboardInterpreter : public common::InputStreamEventHandler, public common::EventManager{ - protected: - KeyboardState keyBoardState; + protected: + KeyboardState m_keyboard_state; - bool nextIsExtendedCode0; // Some keyboard codes are 2 bytes long - uint8_t currentExtendedCode1; - uint16_t extendedCode1Buffer; + bool m_next_is_extended_code_0 { false }; + uint8_t m_current_extended_code_1 { 0 }; + uint16_t m_extended_code_1_buffer { 0 }; - public: - KeyboardInterpreter(); - ~KeyboardInterpreter(); + public: + KeyboardInterpreter(); + ~KeyboardInterpreter(); - void onKeyRead(bool released, KeyboardState state, KeyCode keyCode); + void onKeyRead(bool, KeyboardState, KeyCode); }; + /** + * @class KeyboardInterpreterEN_US + * @brief Interprets the scan codes from the keyboard for the EN_US keyboard layout + */ class KeyboardInterpreterEN_US : public KeyboardInterpreter{ - public: - - enum KeyCodeEN_US { - // First Row - escape = 0x01, - f1 = 0x3B, - f2 = 0x3C, - f3 = 0x3D, - f4 = 0x3E, - f5 = 0x3F, - f6 = 0x40, - f7 = 0x41, - f8 = 0x42, - f9 = 0x43, - f10 = 0x44, - f11 = 0x57, - f12 = 0x58, - printScreen = 0x37, - scrollLock = 0x46, - pauseBreak = 0x45, - - // Second Row - squigglyLine = 0x29, - one = 0x02, - two = 0x03, - three = 0x04, - four = 0x05, - five = 0x06, - six = 0x07, - seven = 0x08, - eight = 0x09, - nine = 0x0A, - zero = 0x0B, - minus = 0x0C, - equals = 0x0D, - backspace = 0x0E, - insert = 0x52, - home = 0x47, - pageUp = 0x49, - numberPadLock = 0x45, - numberPadForwardSlash = 0x35, - numberPadMultiply = 0x37, - numberPadMinus = 0x4A, - - // Third Row - tab = 0x0F, - Q = 0x10, - W = 0x11, - E = 0x12, - R = 0x13, - T = 0x14, - Y = 0x15, - U = 0x16, - I = 0x17, - O = 0x18, - P = 0x19, - openSquareBracket = 0x1A, - closeSquareBracket = 0x1B, - backslash = 0x2B, - deleteKey = 0x53, - end = 0x4F, - pageDown = 0x51, - numberPadSeven = 0x47, - numberPadEight = 0x48, - numberPadNine = 0x49, - numberPadPlus = 0x4E, - - // Fourth Row - capsLock = 0x3A, - A = 0x1E, - S = 0x1F, - D = 0x20, - F = 0x21, - G = 0x22, - H = 0x23, - J = 0x24, - K = 0x25, - L = 0x26, - semicolon = 0x27, - apostrophe = 0x28, - enter = 0x1C, - numberPadFour = 0x4B, - numberPadFive = 0x4C, - numberPadSix = 0x4D, - - // Fifth Row - leftShift = 0x2A, - Z = 0x2C, - X = 0x2D, - C = 0x2E, - V = 0x2F, - B = 0x30, - N = 0x31, - M = 0x32, - comma = 0x33, - fullStop = 0x34, - forwardSlash = 0x35, - rightShift = 0x36, - upArrow = 0x48, - numberPadOne = 0x4F, - numberPadTwo = 0x50, - numberPadThree = 0x51, - numberPadEnter = 0x1C, - - // Sixth Row - leftControl = 0x1D, - leftOS = 0x5B, - leftAlt = 0x38, - space = 0x39, - rightAlt = 0x38, - function = 0x5D, - rightControl = 0x1D, - leftArrow = 0x4B, - downArrow = 0x50, - rightArrow = 0x4D, - numberPadZero = 0x52, - numberPadFullStop = 0x53 - }; - - KeyboardInterpreterEN_US(); - ~KeyboardInterpreterEN_US(); - - void onStreamRead(uint8_t scanCode); + public: + + enum KeyCodeEN_US { + // First Row + escape = 0x01, + f1 = 0x3B, + f2 = 0x3C, + f3 = 0x3D, + f4 = 0x3E, + f5 = 0x3F, + f6 = 0x40, + f7 = 0x41, + f8 = 0x42, + f9 = 0x43, + f10 = 0x44, + f11 = 0x57, + f12 = 0x58, + printScreen = 0x37, + scrollLock = 0x46, + pauseBreak = 0x45, + + // Second Row + squigglyLine = 0x29, + one = 0x02, + two = 0x03, + three = 0x04, + four = 0x05, + five = 0x06, + six = 0x07, + seven = 0x08, + eight = 0x09, + nine = 0x0A, + zero = 0x0B, + minus = 0x0C, + equals = 0x0D, + backspace = 0x0E, + insert = 0x52, + home = 0x47, + pageUp = 0x49, + numberPadLock = 0x45, + numberPadForwardSlash = 0x35, + numberPadMultiply = 0x37, + numberPadMinus = 0x4A, + + // Third Row + tab = 0x0F, + Q = 0x10, + W = 0x11, + E = 0x12, + R = 0x13, + T = 0x14, + Y = 0x15, + U = 0x16, + I = 0x17, + O = 0x18, + P = 0x19, + openSquareBracket = 0x1A, + closeSquareBracket = 0x1B, + backslash = 0x2B, + deleteKey = 0x53, + end = 0x4F, + pageDown = 0x51, + numberPadSeven = 0x47, + numberPadEight = 0x48, + numberPadNine = 0x49, + numberPadPlus = 0x4E, + + // Fourth Row + capsLock = 0x3A, + A = 0x1E, + S = 0x1F, + D = 0x20, + F = 0x21, + G = 0x22, + H = 0x23, + J = 0x24, + K = 0x25, + L = 0x26, + semicolon = 0x27, + apostrophe = 0x28, + enter = 0x1C, + numberPadFour = 0x4B, + numberPadFive = 0x4C, + numberPadSix = 0x4D, + + // Fifth Row + leftShift = 0x2A, + Z = 0x2C, + X = 0x2D, + C = 0x2E, + V = 0x2F, + B = 0x30, + N = 0x31, + M = 0x32, + comma = 0x33, + fullStop = 0x34, + forwardSlash = 0x35, + rightShift = 0x36, + upArrow = 0x48, + numberPadOne = 0x4F, + numberPadTwo = 0x50, + numberPadThree = 0x51, + numberPadEnter = 0x1C, + + // Sixth Row + leftControl = 0x1D, + leftOS = 0x5B, + leftAlt = 0x38, + space = 0x39, + rightAlt = 0x38, + function = 0x5D, + rightControl = 0x1D, + leftArrow = 0x4B, + downArrow = 0x50, + rightArrow = 0x4D, + numberPadZero = 0x52, + numberPadFullStop = 0x53 + }; + + KeyboardInterpreterEN_US(); + ~KeyboardInterpreterEN_US(); + + void on_stream_read(uint8_t scan_code) final; }; + /** + * @class KeyboardDriver + * @brief Driver for the Keyboard Controller, manages the events and the keyboard state + */ class KeyboardDriver : public hardwarecommunication::InterruptHandler, public Driver, public common::GenericInputStream{ - hardwarecommunication::Port8Bit dataPort; - hardwarecommunication::Port8Bit commandPort; + protected: + hardwarecommunication::Port8Bit m_data_port; + hardwarecommunication::Port8Bit m_command_port; - public: - KeyboardDriver(hardwarecommunication::InterruptManager *manager); - ~KeyboardDriver(); + public: + KeyboardDriver(hardwarecommunication::InterruptManager*); + ~KeyboardDriver(); - void HandleInterrupt(); + void handle_interrupt() final; - virtual void activate(); - string getDeviceName(); + void activate() final; + string get_device_name() final; }; - } - - } } diff --git a/kernel/include/drivers/peripherals/mouse.h b/kernel/include/drivers/peripherals/mouse.h index 525b8902..9359aca2 100644 --- a/kernel/include/drivers/peripherals/mouse.h +++ b/kernel/include/drivers/peripherals/mouse.h @@ -24,6 +24,10 @@ namespace maxOS { MOUSE_UP }; + /** + * @class MouseMoveEvent + * @brief Event that is triggered when the mouse moves, holds the x and y coordinates + */ class MouseMoveEvent : public common::Event{ public: int8_t x; @@ -32,50 +36,66 @@ namespace maxOS { ~MouseMoveEvent(); }; + /** + * @class MouseDownEvent + * @brief Event that is triggered when a mouse button is pressed, holds the button that was pressed + */ class MouseDownEvent : public common::Event{ public: uint8_t button; - MouseDownEvent(uint8_t button); + MouseDownEvent(uint8_t); ~MouseDownEvent(); }; + /** + * @class MouseUpEvent + * @brief Event that is triggered when a mouse button is released, holds the button that was released + */ class MouseUpEvent : public common::Event{ public: uint8_t button; - MouseUpEvent(uint8_t button); + MouseUpEvent(uint8_t); ~MouseUpEvent(); }; + /** + * @class MouseEventHandler + * @brief Handles events that are triggered by the mouse driver + */ class MouseEventHandler : public common::EventHandler{ public: MouseEventHandler(); ~MouseEventHandler(); - common::Event* onEvent(common::Event* event); + common::Event* + on_event(common::Event*) override; - virtual void onMouseDownEvent(uint8_t button); - virtual void onMouseUpEvent(uint8_t button); - virtual void onMouseMoveEvent(int8_t x, int8_t y); + virtual void on_mouse_down_event(uint8_t button); + virtual void on_mouse_up_event(uint8_t button); + virtual void on_mouse_move_event(int8_t x, int8_t y); }; - + /** + * @class MouseDriver + * @brief Driver for the PS/2 mouse, manages the mouse and triggers events when the mouse moves or a button is pressed + */ class MouseDriver : public hardwarecommunication::InterruptHandler, public Driver, public common::EventManager{ - hardwarecommunication::Port8Bit dataPort; - hardwarecommunication::Port8Bit commandPort; + hardwarecommunication::Port8Bit data_port; + hardwarecommunication::Port8Bit command_port; - void HandleInterrupt(); + void handle_interrupt(); uint8_t buffer[3]; - uint8_t offest; - uint8_t buttons; + uint8_t offset { 2 }; + uint8_t buttons { 0 }; public: MouseDriver(hardwarecommunication::InterruptManager *manager); ~MouseDriver(); - virtual void activate(); - string getDeviceName(); + void activate() final; + string get_device_name() final; }; } } diff --git a/kernel/include/drivers/video/vesa.h b/kernel/include/drivers/video/vesa.h index 09cfeb2e..b2ede889 100644 --- a/kernel/include/drivers/video/vesa.h +++ b/kernel/include/drivers/video/vesa.h @@ -12,7 +12,6 @@ #include #include -// Thanks to https://wiki.osdev.org/User:Omarrx024/VESA_Tutorial for the VESA documentation namespace maxOS { @@ -20,95 +19,35 @@ namespace maxOS { namespace video { - typedef struct vbe_info_structure { - char signature[4]; // must be "VESA" to indicate valid VBE support - uint16_t version; // VBE version; high byte is major version, low byte is minor version - uint32_t oem; // segment:offset pointer to OEM - uint32_t capabilities; // bitfield that describes card capabilities - uint32_t video_modes; // segment:offset pointer to list of supported video modes - uint16_t video_memory; // amount of video memory in 64KB blocks - uint16_t software_rev; // software revision - uint32_t vendor; // segment:offset to card vendor string - uint32_t product_name; // segment:offset to card model name - uint32_t product_rev; // segment:offset pointer to product revision - char reserved[222]; // reserved for future expansion - char oem_data[256]; // OEM BIOSes store their strings in this area - } __attribute__ ((packed)) vesa_control_info_t; - - typedef struct vbe_mode_info_structure { - uint16_t attributes; // deprecated, only bit 7 should be of interest to you, and it indicates the mode supports a linear frame buffer. - uint8_t window_a; // deprecated - uint8_t window_b; // deprecated - uint16_t granularity; // deprecated; used while calculating bank numbers - uint16_t window_size; - uint16_t segment_a; - uint16_t segment_b; - uint32_t win_func_ptr; // deprecated; used to switch banks from protected mode without returning to real mode - uint16_t pitch; // number of bytes per horizontal line - uint16_t width; // width in pixels - uint16_t height; // height in pixels - uint8_t w_char; // unused... - uint8_t y_char; // ... - uint8_t planes; - uint8_t bpp; // bits per pixel in this mode - uint8_t banks; // deprecated; total number of banks in this mode - uint8_t memory_model; - uint8_t bank_size; // deprecated; size of a bank, almost always 64 KB but may be 16 KB... - uint8_t image_pages; - uint8_t reserved0; - - uint8_t red_mask; - uint8_t red_position; - uint8_t green_mask; - uint8_t green_position; - uint8_t blue_mask; - uint8_t blue_position; - uint8_t reserved_mask; - uint8_t reserved_position; - uint8_t direct_color_attributes; - - uint32_t framebuffer; // physical address of the linear frame buffer; write here to draw to the screen - uint32_t off_screen_mem_off; - uint16_t off_screen_mem_size; // size of memory in the framebuffer but not being displayed on the screen - uint8_t reserved1[206]; - } __attribute__ ((packed)) vesa_mode_info_t; - - typedef struct vbe2_pmi_table { - uint16_t set_window; // offset in table for protected mode code for function 0x4F05 - uint16_t set_display_start; // offset in table for protected mode code for function 0x4F07 - uint16_t set_pallette; // offset in table for protected mode code for function 0x4F09 - } __attribute__ ((packed)) vbe2_pmi_table_t; - - class VideoElectronicsStandardsAssociationDriver : public VideoDriver { + /** + * @class VideoElectronicsStandardsAssociation + * @brief Driver for the VESA video controller, handles the rendering of pixels to the screen using VESA + */ + class VideoElectronicsStandardsAssociation : public VideoDriver { private: - vesa_control_info_t* vesaControlInfo; - vesa_mode_info_t* vesaModeInfo; - vbe2_pmi_table_t* vbe2PmiTable; - uint16_t vesaMode; - bool init(); protected: - bool internalSetMode( uint32_t width, uint32_t height, uint32_t colorDepth); + bool internal_set_mode(uint32_t width, uint32_t height, uint32_t) final; - void renderPixel32Bit( uint32_t x, uint32_t y, uint32_t colour); - uint32_t getRenderedPixel32Bit(uint32_t x, uint32_t y); + void render_pixel_32_bit( uint32_t x, uint32_t y, uint32_t colour) final; + uint32_t get_rendered_pixel_32_bit(uint32_t x, uint32_t y) final; - system::multiboot_info_t* multibootInfo; + system::multiboot_info_t* m_multiboot_info; - uint32_t* framebufferAddress; - uint8_t bpp; // bits per pixel in this mode - uint16_t pitch; // number of bytes per horizontal line + uint32_t* m_framebuffer_address; + uint8_t m_bpp; + uint16_t m_pitch; public: - VideoElectronicsStandardsAssociationDriver(system::multiboot_info_t* mb_info); - ~VideoElectronicsStandardsAssociationDriver(); + VideoElectronicsStandardsAssociation(system::multiboot_info_t* mb_info); + ~VideoElectronicsStandardsAssociation(); - bool supportsMode( uint32_t width, uint32_t height, uint32_t colorDepth); + bool supports_mode( uint32_t width, uint32_t height, uint32_t) final; - string getVendorName(); - string getDeviceName(); + string get_vendor_name() final; + string get_device_name() final; }; diff --git a/kernel/include/drivers/video/vga.h b/kernel/include/drivers/video/vga.h index 9ae68537..3db663cc 100644 --- a/kernel/include/drivers/video/vga.h +++ b/kernel/include/drivers/video/vga.h @@ -17,43 +17,41 @@ namespace maxOS{ namespace video{ + /** + * @class VideoGraphicsArray + * @brief Driver for the VGA graphics controller, handles the rendering of pixels to the screen + */ class VideoGraphicsArray : public VideoDriver{ protected: - uint8_t* FrameBufferSegment; - //-The CRT Controller (CRTC) is responsible for controlling the output of video data to the display monitor. - //-The graphics controller is responsible for managing the interface between CPU and video memory. - //-The sequencer manages the interface between the video data and RAMDAC. - - hardwarecommunication::Port8Bit miscPort; //Miscellaneous - hardwarecommunication::Port8Bit crtcIndexPort; //cathode ray tube controller (index) - hardwarecommunication::Port8Bit crtcDataPort; //cathode ray tube controller (data) - hardwarecommunication::Port8Bit sequenceIndexPort; //Sequence Index - hardwarecommunication::Port8Bit sequenceDataPort; //Sequence Data - hardwarecommunication::Port8Bit graphicsControllerIndexPort; //Graphics Controller Index - hardwarecommunication::Port8Bit graphicsControllerDataPort; //Graphics Controller Data - hardwarecommunication::Port8Bit attributeControllerIndexPort; //Attribute Controller Index - hardwarecommunication::Port8Bit attributeControllerReadPort; //Attribute Controller Read - hardwarecommunication::Port8Bit attributeControllerWritePort; //Attribute Controller Write - hardwarecommunication::Port8Bit attributeControllerResetPort; //Attribute Controller Reset - - void WriteRegisters(uint8_t* registers); //Send Initialization codes to corresponding port - uint8_t* GetFrameBufferSegment(); //Get offset for segment wanted to use - - bool internalSetMode(uint32_t width, uint32_t height, uint32_t colourDepth); - void renderPixel8Bit(uint32_t x, uint32_t y, uint8_t colour); - uint8_t getRenderedPixel8Bit(uint32_t x, uint32_t y); + hardwarecommunication::Port8Bit m_misc_port; + hardwarecommunication::Port8Bit m_crtc_index_port; + hardwarecommunication::Port8Bit crtc_data_port; + hardwarecommunication::Port8Bit m_sequence_index_port; + hardwarecommunication::Port8Bit m_sequence_data_port; + hardwarecommunication::Port8Bit m_graphics_controller_index_port; + hardwarecommunication::Port8Bit m_graphics_controller_data_port; + hardwarecommunication::Port8Bit m_attribute_controller_index_port; + hardwarecommunication::Port8Bit m_attribute_controller_read_port; + hardwarecommunication::Port8Bit m_attribute_controller_write_port; + hardwarecommunication::Port8Bit m_attribute_controller_reset_port; + + void write_registers(uint8_t* registers); + uint8_t* get_frame_buffer_segment(); + + bool internal_set_mode(uint32_t width, uint32_t height, uint32_t colour_depth) final; + void render_pixel_8_bit(uint32_t x, uint32_t y, uint8_t colour) final; + uint8_t get_rendered_pixel_8_bit(uint32_t x, uint32_t y) final; public: VideoGraphicsArray(); ~VideoGraphicsArray(); - string getVendorName(); - string getDeviceName(); + string get_vendor_name() final; + string get_device_name() final; - bool supportsMode(uint32_t width, uint32_t height, uint32_t colourDepth); - }; + bool supports_mode(uint32_t width, uint32_t height, uint32_t colour_depth) final; + }; } - } } diff --git a/kernel/include/drivers/video/video.h b/kernel/include/drivers/video/video.h index caecb2d5..1b18291c 100644 --- a/kernel/include/drivers/video/video.h +++ b/kernel/include/drivers/video/video.h @@ -15,18 +15,21 @@ namespace maxOS { namespace video { + /** + * @class VideoDriver + * @brief Driver for the video controller, handles the setting of the video mode + */ class VideoDriver : public Driver, public common::GraphicsContext { - protected: - virtual bool internalSetMode(uint32_t width, uint32_t height, uint32_t colorDepth); + protected: + virtual bool internal_set_mode(uint32_t width, uint32_t height, uint32_t color_depth); - public: - VideoDriver(); - ~VideoDriver(); + public: + VideoDriver(); + ~VideoDriver(); - virtual bool supportsMode(uint32_t width, uint32_t height, uint32_t colorDepth); - bool setMode(uint32_t width, uint32_t height, uint32_t colorDepth); - virtual bool setTextMode(); + virtual bool supports_mode(uint32_t width, uint32_t height, uint32_t color_depth); + bool set_mode(uint32_t width, uint32_t height, uint32_t colorDepth); }; } diff --git a/kernel/include/filesystem/fat32.h b/kernel/include/filesystem/fat32.h index daf9ffa1..98f36581 100644 --- a/kernel/include/filesystem/fat32.h +++ b/kernel/include/filesystem/fat32.h @@ -16,240 +16,65 @@ namespace maxOS{ namespace filesystem{ - struct BiosParameterBlock32{ - uint8_t jump[3]; - uint8_t OEMName[8]; - uint16_t bytesPerSector; - uint8_t sectorsPerCluster; - uint16_t reservedSectors; - uint8_t tableCopies; - uint16_t rootEntries; - uint16_t totalSectors16; - uint8_t mediaType; - uint16_t fatSectorCount; - uint16_t sectorsPerTrack; - uint16_t headCount; - uint32_t hiddenSectors; - uint32_t totalSectors32; - - uint32_t tableSize32; - uint16_t extendedFlags; - uint16_t fatVersion; - uint32_t rootCluster; - uint16_t fatInfo; - uint16_t backupSector; - uint8_t reserved0[12]; - uint8_t driveNumber; - uint8_t reserved1; - uint8_t bootSignature; - uint32_t volumeID; - uint8_t volumeLabel[11]; - uint8_t fileSystemType[8]; + uint8_t jump[3]; + uint8_t OEM_name[8]; + uint16_t bytes_per_sector; + uint8_t sectors_per_cluster; + uint16_t reserved_sectors; + uint8_t table_copies; + uint16_t root_entries; + uint16_t total_sectors_16; + uint8_t media_type; + uint16_t fat_sector_count; + uint16_t sectors_per_track; + uint16_t head_count; + uint32_t hidden_sectors; + uint32_t total_sectors_32; + + uint32_t table_size_32; + uint16_t extended_flags; + uint16_t fat_version; + uint32_t root_cluster; + uint16_t fat_info; + uint16_t backup_sector; + uint8_t reserved0[12]; + uint8_t drive_number; + uint8_t reserved_1; + uint8_t boot_signature; + uint32_t uint_32; + uint8_t volume_label[11]; + uint8_t file_system_type[8]; } __attribute__((packed)); struct DirectoryEntry{ - uint8_t name[8]; - uint8_t extension[3]; - uint8_t attributes; - uint8_t reserved; + uint8_t name[8]; + uint8_t extension[3]; + uint8_t attributes; + uint8_t reserved; - uint8_t creationTimeTenth; - uint16_t creationTime; - uint16_t creationDate; - uint16_t lastAccessDate; + uint8_t creation_time_tenth; + uint16_t creation_time; + uint16_t creation_date; + uint16_t last_access_date; - uint16_t firstClusterHigh; + uint16_t first_cluster_high; - uint16_t lastWriteTime; - uint16_t lastWriteDate; + uint16_t last_write_time; + uint16_t last_write_date; - uint16_t firstClusterLow; + uint16_t first_cluster_low; - uint32_t size; + uint32_t size; } __attribute__((packed)); - //A struct to hold the extra information about a directory entry - struct DirectoryEntryExtras{ - char longFileName[256]; - }; - - class FatDirectoryTraverser; - - class FatFileWriter : public FileWriter { - DirectoryEntry* fileInfo; - FatDirectoryTraverser* traverser; - uint32_t offsetPosition; - public: - FatFileWriter(FatDirectoryTraverser* parent, DirectoryEntry file); - ~FatFileWriter(); - - uint32_t Write(uint8_t *data, uint32_t size); - uint32_t Seek(uint32_t position, SeekType seek); - - bool Close(); - bool Flush(); - - uint32_t GetPosition(); - uint32_t GetFileSize(); - }; - - - - class FatFileReader : public FileReader{ - - private: - DirectoryEntry* fileInfo; - FatDirectoryTraverser* traverser; - uint32_t offsetPosition; - - public: - FatFileReader(FatDirectoryTraverser* parent, DirectoryEntry file); - ~FatFileReader(); - - uint32_t Read(uint8_t* data, uint32_t size); - uint32_t Seek(uint32_t position, SeekType seek); - - uint32_t GetPosition(); - uint32_t GetFileSize(); - - }; - - - - class FatFileEnumerator : public FileEnumerator{ - friend class FatFileReader; - friend class FatFileWriter; - - private: - FatDirectoryTraverser* traverser; - DirectoryEntry* fileInfo; - int index; - - FatFileReader* reader; - FatFileWriter* writer; - - public: - FatFileEnumerator(FatDirectoryTraverser* parent, DirectoryEntry directory, int id); - ~FatFileEnumerator(); - - string getFileName(); - string changeFileName(string newFileName); - - FileReader* getReader(); - FileWriter* getWriter(); - - bool hasNext(); - FileEnumerator* - next(); - - }; - - class FatDirectoryEnumerator : public DirectoryEnumerator{ - friend class FatDirectoryTraverser; - private: - FatDirectoryTraverser* traverser; - - int index; - - public: - FatDirectoryEnumerator(FatDirectoryTraverser* parent, DirectoryEntry directory, int id); - ~FatDirectoryEnumerator(); - - DirectoryEntry* directoryInfo; - - string getDirectoryName(); - string changeDirectoryName(string newDirectoryName); - - bool hasNext(); - DirectoryEnumerator* next(); - - }; - - class FatDirectoryTraverser : public DirectoryTraverser{ - friend class FatDirectoryEnumerator; - friend class FatFileEnumerator; - - private: - - DirectoryEntry tempDirent[16]; - common::Vector dirent; - common::Vector dirent_extras; - - common::OutputStream* fat32MessageStream; - - FatDirectoryEnumerator* currentDirectoryEnumerator; - uint32_t currentDirectoryIndex; - - - FatFileEnumerator* currentFileEnumerator; - uint32_t currentFileIndex; - - public: - drivers::AdvancedTechnologyAttachment* hd; - uint32_t dataStartSector; - uint32_t sectorsPrCluster; - uint32_t fatLocation; - uint32_t fatSize; - uint32_t directorySector; - uint32_t directoryCluster; - - FatDirectoryTraverser(drivers::AdvancedTechnologyAttachment* ataDevice, uint32_t directorySector, uint32_t dataStart, uint32_t clusterSectorCount, uint32_t fatLoc, uint32_t fat_size, common::OutputStream* fat32MessageStream); - ~FatDirectoryTraverser(); - - - void changeDirectory(FatDirectoryEnumerator* directory); - - void makeDirectory(string name); - void removeDirectory(string name); - - void makeFile(string name); - void removeFile(string name); - - void WriteDirectoryInfoChange(DirectoryEntry* entry); - - void UpdateDirectoryEntrysToDisk(); - void ReadEntrys(); - - FileEnumerator* getFileEnumerator(); - DirectoryEnumerator* getDirectoryEnumerator(); - - - }; - - class Fat32 : public FileSystem{ - private: - drivers::AdvancedTechnologyAttachment* drive; - uint32_t partOffset; - common::OutputStream* fat32MessageStream; - - FatDirectoryTraverser* currentTraverser; - - public: - Fat32(drivers::AdvancedTechnologyAttachment *hd, uint32_t partitionOffset, common::OutputStream* fat32MessageStream); - ~Fat32(); - - static uint32_t AllocateCluster(drivers::AdvancedTechnologyAttachment *hd, uint32_t currentCluster, uint32_t fatLocation, uint32_t fat_size); - static void DeallocateCluster(drivers::AdvancedTechnologyAttachment *hd, uint32_t firstCluster, uint32_t fatLocation, uint32_t fat_size); - - static void UpdateEntryInFat(drivers::AdvancedTechnologyAttachment *hd, uint32_t cluster, uint32_t newFatValue, uint32_t fatLocation); - - static bool IsValidFAT32Name(string name); - - DirectoryTraverser* getDirectoryTraverser(); - - - }; - - void ReadBiosBlock(drivers::AdvancedTechnologyAttachment *hd, uint32_t partitionOffset); - - } - + // TODO: Redo FAT32 + } } #endif //MAXOS_FILESYSTEM_FAT32_H diff --git a/kernel/include/filesystem/filesystem.h b/kernel/include/filesystem/filesystem.h index c8f7850d..a07c6be9 100644 --- a/kernel/include/filesystem/filesystem.h +++ b/kernel/include/filesystem/filesystem.h @@ -19,91 +19,8 @@ namespace maxOS{ SEEK_END }; - class FileWriter { - public: - FileWriter(); - ~FileWriter(); - - virtual uint32_t Write(uint8_t *data, uint32_t size); - virtual uint32_t Seek(uint32_t position, SeekType seek); - - virtual bool Close(); - virtual bool Flush(); - - virtual uint32_t GetPosition(); - virtual uint32_t GetFileSize(); - }; - - class FileReader{ - - public: - FileReader(); - ~FileReader(); - - virtual uint32_t Read(uint8_t* data, uint32_t size); - virtual uint32_t Seek(uint32_t position, SeekType seek); - - virtual uint32_t GetPosition(); - virtual uint32_t GetFileSize(); - - }; - - class FileEnumerator{ - - public: - FileEnumerator(); - ~FileEnumerator(); - - virtual string getFileName(); - virtual FileReader* getReader(); - virtual FileWriter* getWriter(); - - virtual bool hasNext(); - virtual FileEnumerator* next(); - - }; - - class DirectoryEnumerator{ - - public: - DirectoryEnumerator(); - ~DirectoryEnumerator(); - - virtual string getDirectoryName(); - - virtual bool hasNext(); - virtual DirectoryEnumerator* next(); - - }; - - class DirectoryTraverser{ - public: - - DirectoryTraverser(); - ~DirectoryTraverser(); - - virtual void changeDirectory(DirectoryEnumerator directory); - - virtual void makeDirectory(string name); - virtual void removeDirectory(string name); - - virtual void makeFile(string name); - virtual void removeFile(string name); - - virtual FileEnumerator* getFileEnumerator(); - virtual DirectoryEnumerator* getDirectoryEnumerator(); - - }; - - class FileSystem{ - - public: - FileSystem(); - ~FileSystem(); - - virtual DirectoryTraverser* getDirectoryTraverser(); - }; + // TODO: Redo this class } diff --git a/kernel/include/filesystem/msdospart.h b/kernel/include/filesystem/msdospart.h index 1e28ef62..254384bc 100644 --- a/kernel/include/filesystem/msdospart.h +++ b/kernel/include/filesystem/msdospart.h @@ -18,41 +18,43 @@ namespace maxOS{ uint8_t bootable; // 0x80 = bootable, 0x00 = not bootable - uint8_t startHead; // starting head on the disk - uint8_t startSector : 6; // starting sector on the disk - uint16_t startCylinder : 10; // starting cylinder on the disk + uint8_t startHead; + uint8_t startSector : 6; + uint16_t startCylinder : 10; - uint8_t partitionId; // partition type id + uint8_t partitionId; - uint8_t endHead; // ending head on the disk - uint8_t endSector : 6; // ending sector on the disk - uint16_t endCylinder : 10; // ending cylinder on the disk + uint8_t endHead; + uint8_t endSector : 6; + uint16_t endCylinder : 10; - uint32_t startLBA; // starting LBA on the disk - uint32_t length; // size of the partition in sectors + uint32_t startLBA; + uint32_t length; } __attribute__((packed)); struct MasterBootRecord{ - uint8_t bootloader[440]; // bootloader code - uint32_t diskSignature; // disk signature - uint16_t unused; // unused + uint8_t bootloader[440]; + uint32_t diskSignature; + uint16_t unused; - PartitionTableEntry primaryPartition[4]; // primary partitions + PartitionTableEntry primaryPartition[4]; - uint16_t magicNumber; // magic number + uint16_t magicNumber; } __attribute__((packed)); + /** + * @class MSDOSPartitionTable + * @brief Reads the partition table of the hard drive + */ class MSDOSPartitionTable{ public: - static void ReadPartitions(drivers::AdvancedTechnologyAttachment *hd); + static void read_partitions(drivers::AdvancedTechnologyAttachment *hd); }; - } - } #endif //MAXOS_FILESYSTEM_MSDOSPART_H diff --git a/kernel/include/gui/desktop.h b/kernel/include/gui/desktop.h index f9be8d9d..39595a70 100644 --- a/kernel/include/gui/desktop.h +++ b/kernel/include/gui/desktop.h @@ -15,23 +15,28 @@ namespace maxOS{ namespace gui{ + /** + * @class Desktop + * @brief The desktop that contains all the windows, handles the drawing of the screen and the mouse on every tick + */ class Desktop : public CompositeWidget, public drivers::peripherals::MouseEventHandler, public drivers::clock::ClockEventHandler{ //NTS: it is not a good idea to hardcode the mouse into the desktop as a tablet or touch screen device wont have a mouse cursor protected: - uint32_t mouseX; - uint32_t mouseY; + uint32_t m_mouse_x; + uint32_t m_mouse_y; - common::GraphicsContext* graphicsContext; - Widget* focussedWidget; - drivers::peripherals::MouseEventHandler* draggedWidget; + common::GraphicsContext* m_graphics_context; - void setFocus(Widget* widget); - void bringToFront(Widget* frontWidget); - void invertMouseCursor(); + Widget* m_focussed_widget { nullptr }; + drivers::peripherals::MouseEventHandler* m_dragged_widget { nullptr }; - common::Vector > invalidAreas; - void internalInvalidate(common::Rectangle& area, common::Vector >::iterator start, common::Vector >::iterator stop); - void drawSelf(common::GraphicsContext* gc, common::Rectangle& area); + void set_focus(Widget*) final; + void bring_to_front(Widget*) final; + void invert_mouse_cursor(); + + common::Vector > m_invalid_areas; + void internal_invalidate(common::Rectangle& area, common::Vector >::iterator start, common::Vector >::iterator stop); + void draw_self(common::GraphicsContext* gc, common::Rectangle& area); public: common::Colour colour; @@ -39,21 +44,21 @@ namespace maxOS{ Desktop(common::GraphicsContext* gc); ~Desktop(); - void addChild(Widget* childWidget); - void onTime(const common::Time& time); - void invalidate(common::Rectangle& area); + void add_child(Widget*) final; + void on_time(const common::Time& time) final; + void invalidate(common::Rectangle& area) final; - // Overrides mouse event handlers - void onMouseMoveEvent(int8_t x, int8_t y); - void onMouseDownEvent(uint8_t button); - void onMouseUpEvent(uint8_t button); + // Mouse Events + void on_mouse_move_event(int8_t x, int8_t y) final; + void on_mouse_down_event(uint8_t button) final; + void on_mouse_up_event(uint8_t button) final; - void onKeyDown(drivers::peripherals::KeyCode keyDownCode, drivers::peripherals::KeyboardState keyDownState); - void onKeyUp(drivers::peripherals::KeyCode keyUpCode, drivers::peripherals::KeyboardState keyUpState); + // Keyboard Events + void on_key_down(drivers::peripherals::KeyCode keyDownCode, drivers::peripherals::KeyboardState keyDownState) final; + void on_key_up(drivers::peripherals::KeyCode keyUpCode, drivers::peripherals::KeyboardState keyUpState) final; }; } - } #endif //MaxOS_GUI_DESKTOP_H diff --git a/kernel/include/gui/font.h b/kernel/include/gui/font.h index 2b820282..81c8a695 100644 --- a/kernel/include/gui/font.h +++ b/kernel/include/gui/font.h @@ -14,28 +14,32 @@ namespace maxOS{ namespace gui{ + /** + * @class Font + * @brief A class that can be used to draw text + */ class Font{ protected: - bool is8x8; + bool m_is_8_by_8; public: - uint16_t fontSize; - bool isBold; + uint16_t font_size { 8 }; - bool isItalic; - bool isUnderlined; - bool isStrikethrough; + bool is_bold { false }; + bool is_italic { false }; + bool is_underlined { false }; + bool is_strikethrough { false }; Font(); ~Font(); - virtual void drawText(int32_t x, int32_t y, common::Colour foregroundColour, common::Colour backgroundColour, common::GraphicsContext* context, string text); - virtual void drawText(int32_t x, int32_t y, common::Colour foregroundColour, common::Colour backgroundColour, common::GraphicsContext* context, string text, common::Rectangle limitArea); + virtual void draw_text(int32_t x, int32_t y, common::Colour foreground_colour, common::Colour background_colour, common::GraphicsContext *context, string text); + virtual void draw_text(int32_t x, int32_t y, common::Colour foreground_colour, common::Colour background_colour, common::GraphicsContext *context, string text, common::Rectangle limitArea); - virtual void getFont8x8(uint8_t (&font8x8)[2048]); + virtual void get_font_8_x_8(uint8_t (&font8x8)[2048]); - virtual uint32_t getTextHeight(string text); - virtual uint32_t getTextWidth(string text); + virtual uint32_t get_text_height(string); + virtual uint32_t get_text_width(string); }; @@ -45,7 +49,7 @@ namespace maxOS{ AmigaFont(); ~AmigaFont(); - virtual void getFont8x8(uint8_t (&font8x8)[2048]); + virtual void get_font_8_x_8(uint8_t (&font8x8)[2048]) final; }; } diff --git a/kernel/include/gui/widget.h b/kernel/include/gui/widget.h index 1ed97cfc..b31b9799 100644 --- a/kernel/include/gui/widget.h +++ b/kernel/include/gui/widget.h @@ -19,27 +19,28 @@ namespace maxOS{ namespace gui{ /** - * A widget is a graphical element that can be drawn on the screen. + * @class Widget + * @brief A graphical object that can be drawn on the screen */ class Widget : public drivers::peripherals::KeyboardEventHandler{ template friend class WidgetMoverResizer; friend class CompositeWidget; private: - common::Rectangle position; + common::Rectangle m_position; protected: - Widget* parent; - bool valid; + Widget* m_parent { nullptr }; + bool m_valid { false }; - virtual void setFocus(Widget* widget); - virtual void bringToFront(Widget* widget); + uint32_t m_min_width { 5 }; + uint32_t m_min_height { 5 }; - uint32_t minWidth; - uint32_t minHeight; + uint32_t m_max_width { 0x8FFFFFFF }; + uint32_t m_max_height { 0x8FFFFFFF }; - uint32_t maxWidth; - uint32_t maxHeight; + virtual void set_focus(Widget*); + virtual void bring_to_front(Widget*); public: @@ -52,40 +53,41 @@ namespace maxOS{ virtual void draw(common::GraphicsContext* gc, common::Rectangle& area); void invalidate(); virtual void invalidate(common::Rectangle& area); - virtual void addChild(Widget* child); + virtual void add_child(Widget* child); // Positioning functions - virtual common::Coordinates absoluteCoordinates(common::Coordinates coordinates); - virtual bool containsCoordinate(uint32_t x, uint32_t y); - common::Rectangle getPosition(); + virtual common::Coordinates absolute_coordinates(common::Coordinates coordinates); + virtual bool contains_coordinate(uint32_t x, uint32_t y); + common::Rectangle position(); void move(int32_t left, int32_t top); void resize(int32_t width, int32_t height); // Focus functions void focus(); - virtual void onFocus(); - virtual void onFocusLost(); - void bringToFront(); + virtual void on_focus(); + virtual void on_focus_lost(); + void bring_to_front(); // Mouse functions - virtual void onMouseEnterWidget(uint32_t toX, uint32_t toY); - virtual void onMouseLeaveWidget(uint32_t fromX, uint32_t fromY); - virtual void onMouseMoveWidget(uint32_t fromX, uint32_t fromY, uint32_t toX, uint32_t toY); - virtual drivers::peripherals::MouseEventHandler* onMouseButtonPressed(uint32_t x, uint32_t y, uint8_t button); - virtual void onMouseButtonReleased(uint32_t x, uint32_t y, uint8_t button); + virtual void on_mouse_enter_widget(uint32_t toX, uint32_t toY); + virtual void on_mouse_leave_widget(uint32_t fromX, uint32_t fromY); + virtual void on_mouse_move_widget(uint32_t fromX, uint32_t fromY, uint32_t toX, uint32_t toY); + virtual drivers::peripherals::MouseEventHandler* on_mouse_button_pressed(uint32_t x, uint32_t y, uint8_t button); + virtual void on_mouse_button_released(uint32_t x, uint32_t y, uint8_t button); }; /** - * A widget that can contain other widgets. + * @class CompositeWidget + * @brief A widget that can contain other widgets */ class CompositeWidget : public Widget{ protected: - common::Vector children; + common::Vector m_children; void draw(common::GraphicsContext* gc, common::Rectangle& area, common::Vector::iterator start); - virtual void drawSelf(common::GraphicsContext* gc, common::Rectangle& area); + virtual void draw_self(common::GraphicsContext* gc, common::Rectangle& area); public: @@ -96,22 +98,22 @@ namespace maxOS{ ~CompositeWidget(); // Drawing functions - virtual void draw(common::GraphicsContext* gc, common::Rectangle& area); - virtual void addChild(Widget* child); + virtual void draw(common::GraphicsContext* gc, common::Rectangle& area) override; + virtual void add_child(Widget* child) override; // Mouse functions - virtual void onMouseEnterWidget(uint32_t toX, uint32_t toY); - virtual void onMouseLeaveWidget(uint32_t fromX, uint32_t fromY); - virtual void onMouseMoveWidget(uint32_t fromX, uint32_t fromY, uint32_t toX, uint32_t toY); - virtual drivers::peripherals::MouseEventHandler* onMouseButtonPressed(uint32_t x, uint32_t y, uint8_t button); - virtual void onMouseButtonReleased(uint32_t x, uint32_t y, uint8_t button); - + virtual void on_mouse_enter_widget(uint32_t toX, uint32_t toY) override; + virtual void on_mouse_leave_widget(uint32_t fromX, uint32_t fromY) override; + virtual void on_mouse_move_widget(uint32_t fromX, uint32_t fromY, uint32_t toX, uint32_t toY) override; + virtual drivers::peripherals::MouseEventHandler* on_mouse_button_pressed(uint32_t x, uint32_t y, uint8_t button) override; + virtual void on_mouse_button_released(uint32_t x, uint32_t y, uint8_t button) override; }; /** - * A resizable widget. + * @class WidgetMoverResizer + * @brief A template class that allows you to move and resize a widget * * @tparam Left Left * @tparam Top Top @@ -125,7 +127,7 @@ namespace maxOS{ WidgetMoverResizer(Widget* widget); ~WidgetMoverResizer(); - void onMouseMoveEvent(int8_t x, int8_t y); + void on_mouse_move_event(int8_t x, int8_t y); }; @@ -150,8 +152,8 @@ namespace maxOS{ * * @tparam Left The left edge of the widget * @tparam Top The top edge of the widget - * @tparam Width The width of the widget - * @tparam Height The height of the widget + * @tparam Width The m_width of the widget + * @tparam Height The m_height of the widget * @param target The widget to move and resize */ template WidgetMoverResizer::WidgetMoverResizer(Widget* target) @@ -167,10 +169,10 @@ namespace maxOS{ /** * @details OnMouseMoved is called when the mouse is moved. Resizes and moves the widget when this happens. * - * @param x The x position of the mouse - * @param y The y position of the mouse + * @param x The x m_position of the mouse + * @param y The y m_position of the mouse */ - template void WidgetMoverResizer::onMouseMoveEvent(int8_t x, int8_t y) + template void WidgetMoverResizer::on_mouse_move_event(int8_t x, int8_t y) { Widget* targ = this->targettedWidget; @@ -178,17 +180,13 @@ namespace maxOS{ // If there is actually a size of the widget to change if(Left != 0 || Top != 0) // Move the widget to the left or right, and up or down - targ -> move(targ -> position.left + Left * x, targ -> position.top + Top * y); + targ -> move(targ ->m_position.left + Left * x, targ ->m_position.top + Top * y); // If there is actually a size of the widget to change if(Width != 0 || Height != 0) // Resize the widget to the left or right, and up or down - targ -> resize( targ -> position.width + Width*x, targ -> position.height + Height*y); + targ -> resize( targ ->m_position.width + Width*x, targ ->m_position.height + Height*y); } - } - - - } #endif //MaxOS_GUI_WIDGET_H diff --git a/kernel/include/gui/widgets/button.h b/kernel/include/gui/widgets/button.h index 449ffca4..78a89bb2 100644 --- a/kernel/include/gui/widgets/button.h +++ b/kernel/include/gui/widgets/button.h @@ -25,33 +25,49 @@ namespace maxOS { BUTTON_RELEASED }; + /** + * @class ButtonPressedEvent + * @brief Event that is triggered when a button is pressed + */ class ButtonPressedEvent : public common::Event{ - public: - ButtonPressedEvent(Button* source); - ~ButtonPressedEvent(); + public: + ButtonPressedEvent(Button*); + ~ButtonPressedEvent(); - Button* source; + Button* source; }; + /** + * @class ButtonReleasedEvent + * @brief Event that is triggered when a button is released + */ class ButtonReleasedEvent : public common::Event{ - public: - ButtonReleasedEvent(Button* source); - ~ButtonReleasedEvent(); + public: + ButtonReleasedEvent(Button*); + ~ButtonReleasedEvent(); - Button* source; + Button* source; }; + /** + * @class ButtonEventHandler + * @brief Handles button events + */ class ButtonEventHandler : public common::EventHandler{ - public: - ButtonEventHandler(); - ~ButtonEventHandler(); + public: + ButtonEventHandler(); + ~ButtonEventHandler(); - virtual common::Event* onEvent(common::Event* event); + virtual common::Event* on_event(common::Event*) override; - virtual void onButtonPressed(Button* source); - virtual void onButtonReleased(Button* source); + virtual void on_button_pressed(Button* source); + virtual void on_button_released(Button* source); }; + /** + * @class Button + * @brief A button widget, can be clicked + */ class Button : public Widget, public common::EventManager { public: @@ -59,17 +75,16 @@ namespace maxOS { ~Button(); // Widget Stuff - void draw(common::GraphicsContext* gc, common::Rectangle& area); - drivers::peripherals::MouseEventHandler* onMouseButtonPressed(uint32_t x, uint32_t y, uint8_t button); - void onMouseButtonReleased(uint32_t x, uint32_t y, uint8_t button); + void draw(common::GraphicsContext* gc, common::Rectangle& area) override; + drivers::peripherals::MouseEventHandler* on_mouse_button_pressed(uint32_t x, uint32_t y, uint8_t button) override; + void on_mouse_button_released(uint32_t x, uint32_t y, uint8_t button) override; // Button Stuff - common::Colour backgroundColour; - common::Colour foregroundColour; - common::Colour borderColour; + common::Colour background_colour; + common::Colour foreground_colour; + common::Colour border_colour; gui::AmigaFont font; string text; - }; } } diff --git a/kernel/include/gui/widgets/inputbox.h b/kernel/include/gui/widgets/inputbox.h index 19bd71ae..dba92f85 100644 --- a/kernel/include/gui/widgets/inputbox.h +++ b/kernel/include/gui/widgets/inputbox.h @@ -20,50 +20,62 @@ namespace maxOS{ INPUTBOX_TEXT_CHANGED }; + /** + * @class InputBoxTextChangedEvent + * @brief Event that is triggered when the text in an input box is changed + */ class InputBoxTextChangedEvent : public common::Event{ - public: - InputBoxTextChangedEvent(string newText); - ~InputBoxTextChangedEvent(); + public: + InputBoxTextChangedEvent(string); + ~InputBoxTextChangedEvent(); - string newText; + string new_text; }; + /** + * @class InputBoxEventHandler + * @brief Handles input box events + */ class InputBoxEventHandler : public common::EventHandler{ public: InputBoxEventHandler(); ~InputBoxEventHandler(); - virtual common::Event* onEvent(common::Event* event); + virtual common::Event* on_event(common::Event* event) override; - virtual void onInputBoxTextChanged(string newText); + virtual void on_input_box_text_changed(string); }; + /** + * @class InputBox + * @brief A box that can be used to input text + */ class InputBox : public Widget, public common::EventManager{ protected: - char widgetText[256]; // Replace with a buffer in memory later + char widget_text[256]; //TODO: Replace with a buffer in memory later public: InputBox(int32_t left, int32_t top, uint32_t width, uint32_t height); InputBox(int32_t left, int32_t top, uint32_t width, uint32_t height, string text); ~InputBox(); - void draw(common::GraphicsContext* gc, common::Rectangle& area); + void draw(common::GraphicsContext* gc, common::Rectangle& area) override; - void onFocus(); - void onFocusLost(); + void on_focus() override; + void on_focus_lost() override; - void onKeyDown(drivers::peripherals::KeyCode keyDownCode, drivers::peripherals::KeyboardState keyDownState); + void on_key_down(drivers::peripherals::KeyCode keyDownCode, drivers::peripherals::KeyboardState keyDownState) override; - void updateText(string newText); - string getText(); + void update_text(string); + string get_text(); // InputBox Variables - common::Colour backgroundColour; - common::Colour foregroundColour; - common::Colour borderColour; + common::Colour background_colour; + common::Colour foreground_colour; + common::Colour border_colour; gui::AmigaFont font; - uint32_t cursorPosition; + uint32_t cursor_position { 0 }; }; } diff --git a/kernel/include/gui/widgets/text.h b/kernel/include/gui/widgets/text.h index 21ea17d2..921c084c 100644 --- a/kernel/include/gui/widgets/text.h +++ b/kernel/include/gui/widgets/text.h @@ -15,24 +15,29 @@ namespace maxOS { namespace gui { namespace widgets{ + + /** + * @class Text + * @brief A box that can be used to display text + */ class Text : public Widget{ protected: - char widgetText[256]; + char m_widget_text[256]; //TODO: Replace with a buffer in memory later public: - //TODO: Redo so that it uses some generified font class + //TODO: Redo so that it uses some generified m_font class AmigaFont font; - common::Colour foregroundColour; - common::Colour backgroundColour; + common::Colour foreground_colour; + common::Colour background_colour; Text(int32_t left, int32_t top, uint32_t width, uint32_t height, string text); ~Text(); - void draw(common::GraphicsContext* gc, common::Rectangle& area); - void updateText(string newText); + void draw(common::GraphicsContext* gc, common::Rectangle& area) override; + void update_text(string); }; } diff --git a/kernel/include/gui/window.h b/kernel/include/gui/window.h index c5fd50e1..66831660 100644 --- a/kernel/include/gui/window.h +++ b/kernel/include/gui/window.h @@ -16,44 +16,38 @@ namespace maxOS{ class Window : public CompositeWidget{ protected: - widgets::Text title; + widgets::Text m_title; - // Resizers - WidgetMover windowWidgetMover; - WidgetMoverResizerTop windowWidgetMoverResizerTop; - WidgetMoverResizerBottom windowWidgetMoverResizerBottom; - WidgetMoverResizerLeft windowWidgetMoverResizerLeft; - WidgetMoverResizerRight windowWidgetMoverResizerRight; - WidgetMoverResizerTopLeft windowWidgetMoverResizerTopLeft; - WidgetMoverResizerTopRight windowWidgetMoverResizerTopRight; - WidgetMoverResizerBottomLeft windowWidgetMoverResizerBottomLeft; - WidgetMoverResizerBottomRight windowWidgetMoverResizerBottomRight; + // Resizes + WidgetMover m_mover; + WidgetMoverResizerTop m_resizer_top; + WidgetMoverResizerBottom m_resizer_bottom; + WidgetMoverResizerLeft m_resizer_left; + WidgetMoverResizerRight m_resizer_right; + WidgetMoverResizerTopLeft m_resizer_top_left; + WidgetMoverResizerTopRight m_resizer_top_right; + WidgetMoverResizerBottomLeft m_resizer_bottom_left; + WidgetMoverResizerBottomRight m_resizer_bottom_right; public: - uint8_t windowFrameThickness; - uint8_t windowTitleBarHeight; + uint8_t frame_thickness { 5 }; + uint8_t title_bar_height { 10 }; - common::Colour windowAreaColour; - common::Colour windowFrameColour; - common::Colour windowFrameBorderColour; + common::Colour area_colour; + common::Colour frame_colour; + common::Colour frame_border_colour; - Window(int32_t left, int32_t top, uint32_t width, uint32_t height, string titleText); - Window(Widget* containedWidget, string titleText); + Window(int32_t left, int32_t top, uint32_t width, uint32_t height, string title_text); + Window(Widget* containedWidget, string title_text); ~Window(); - void drawSelf(common::GraphicsContext* gc, common::Rectangle& area); - void addChild(Widget* child); - - drivers::peripherals::MouseEventHandler* onMouseButtonPressed(uint32_t x, uint32_t y, uint8_t button); - - + void draw_self(common::GraphicsContext* gc, common::Rectangle& area); + void add_child(Widget* child); + drivers::peripherals::MouseEventHandler* on_mouse_button_pressed(uint32_t x, uint32_t y, uint8_t button); }; - } - } - #endif //MaxOS_GUI_WINDOW_H diff --git a/kernel/include/hardwarecommunication/interrupts.h b/kernel/include/hardwarecommunication/interrupts.h index cc34177f..ffb02bc8 100644 --- a/kernel/include/hardwarecommunication/interrupts.h +++ b/kernel/include/hardwarecommunication/interrupts.h @@ -18,50 +18,54 @@ namespace maxOS { class InterruptManager; + /** + * @class InterruptHandler + * @brief Handles a certain interrupt number + */ class InterruptHandler { protected: - uint8_t interrupNumber; - InterruptManager *interruptManager; + uint8_t m_interrupt_number; + InterruptManager* m_interrupt_manager; - InterruptHandler(uint8_t interrupNumber, InterruptManager *interruptManager = 0); + InterruptHandler(uint8_t interrupt_number, InterruptManager*interrupt_manager = 0); ~InterruptHandler(); public: - virtual void HandleInterrupt(); + virtual void handle_interrupt(); }; + /** + * @class InterruptManager + * @brief Handles all interrupts and passes them to the correct handler + */ class InterruptManager : public common::InputStream { friend class InterruptHandler; protected: - static InterruptManager *ActiveInterruptManager; - static common::OutputStream* errorMessages; - uint16_t hardwareInterruptOffset; - InterruptHandler *interruptHandlers[256]; // Make vector? - ThreadManager* threadManager; + static InterruptManager* s_active_interrupt_manager; + static common::OutputStream* s_error_messages; + uint16_t m_hardware_interrupt_offset; + InterruptHandler* m_interrupt_handlers[256]; //TODO: Make vector? + system::ThreadManager* m_thread_manager; struct GateDescriptor { - uint16_t handlerAddressLowBits; - uint16_t gdt_codeSegmentSelector; - uint8_t reserved; - uint8_t access; - uint16_t handlerAddressHighBits; + uint16_t handler_address_low_bits; + uint16_t gdt_code_segment_selector; + uint8_t reserved; + uint8_t access; + uint16_t handler_address_high_bits; } __attribute__((packed)); - static GateDescriptor interruptDescriptorTable[256]; + static GateDescriptor s_interrupt_descriptor_table[256]; struct InterruptDescriptorTablePointer { uint16_t size; uint32_t base; } __attribute__((packed)); - static void SetInterruptDescriptorTableEntry(uint8_t interrupt, - uint16_t codeSegmentSelectorOffset, - void (*handler)(), - uint8_t DescriptorPrivilegeLevel, - uint8_t DescriptorType); + static void set_interrupt_descriptor_table_entry(uint8_t interrupt, uint16_t code_segment_selector_offset, void (*handler)(), uint8_t DescriptorPrivilegeLevel, uint8_t descriptor_type); static void InterruptIgnore(); @@ -121,26 +125,26 @@ namespace maxOS { static uint32_t HandleInterrupt(uint8_t interrupt, uint32_t esp); static uint32_t HandleInterruptRequest(uint32_t esp); - uint32_t DoHandleInterruptRequest(uint8_t interrupt, uint32_t esp); + uint32_t handle_interrupt_request(uint8_t interrupt, uint32_t esp); //PIC Cominunication - Port8BitSlow programmableInterruptControllerMasterCommandPort; - Port8BitSlow programmableInterruptControllerMasterDataPort; - Port8BitSlow programmableInterruptControllerSlaveCommandPort; - Port8BitSlow programmableInterruptControllerSlaveDataPort; + Port8BitSlow pic_master_command_port; + Port8BitSlow pic_master_data_port; + Port8BitSlow pic_slave_command_port; + Port8BitSlow pic_slave_data_port; public: - InterruptManager(uint16_t hardwareInterruptOffset, system::GlobalDescriptorTable *globalDescriptorTable, ThreadManager* threadManage, common::OutputStream* handler); + InterruptManager(uint16_t hardware_interrupt_offset, system::GlobalDescriptorTable*global_descriptor_table, system::ThreadManager* thread_manager, common::OutputStream* handler); ~InterruptManager(); - uint16_t HardwareInterruptOffset(); + uint16_t hardware_interrupt_offset(); - void setInterruptHandler(uint8_t interrupt, InterruptHandler *handler); - void removeInterruptHandler(uint8_t interrupt); + void set_interrupt_handler(uint8_t interrupt, InterruptHandler *handler); + void remove_interrupt_handler(uint8_t interrupt); - void Activate(); - void Deactivate(); + void activate(); + void deactivate(); }; } diff --git a/kernel/include/hardwarecommunication/pci.h b/kernel/include/hardwarecommunication/pci.h index 951f69f6..6daeabe0 100644 --- a/kernel/include/hardwarecommunication/pci.h +++ b/kernel/include/hardwarecommunication/pci.h @@ -22,24 +22,31 @@ namespace maxOS InputOutput = 1 }; + /** + * @class BaseAddressRegister + * @brief Used to store the base address register + */ class BaseAddressRegister{ public: - bool preFetchable; //If the memory is pre-fetchable - uint8_t* address; //The address of the register - uint32_t size; //The size of the register - BaseAddressRegisterType type; //The type of the register + bool pre_fetchable; + uint8_t* address; + uint32_t size; + BaseAddressRegisterType type; }; - //TODO: With USB could be a good idea to make a class for the device descriptor + /** + * @class PeripheralComponentInterconnectDeviceDescriptor + * @brief Stores information about a PCI device + */ class PeripheralComponentInterconnectDeviceDescriptor { public: - bool hasPortBase; - uint32_t portBase; //Port used for communication + bool has_port_base; + uint32_t port_base; //Port used for communication - bool hasMemoryBase; - uint32_t memoryBase; //Mem address used for communication + bool has_memory_base; + uint32_t memory_base; //Mem address used for communication uint32_t interrupt; //The interrupt @@ -47,8 +54,8 @@ namespace maxOS uint16_t device; uint16_t function; - uint16_t vendor_ID; - uint16_t device_ID; + uint16_t vendor_id; + uint16_t device_id; uint8_t class_id; uint8_t subclass_id; @@ -59,36 +66,40 @@ namespace maxOS PeripheralComponentInterconnectDeviceDescriptor(); ~PeripheralComponentInterconnectDeviceDescriptor(); - string getType(); + string get_type(); }; + /** + * @class PeripheralComponentInterconnectController + * @brief Handles the selecting and loading of drivers for PCI devices + */ class PeripheralComponentInterconnectController : public drivers::DriverSelector { - - // Ports - Port32Bit dataPort; - Port32Bit commandPort; - - // Debug - common::OutputStream* debugMessagesStream; - - // I/O - uint32_t Read(uint16_t bus, uint16_t device, uint16_t function, uint32_t registeroffset); - void Write(uint16_t bus, uint16_t device, uint16_t function, uint32_t registeroffset, uint32_t value); - - // Device - PeripheralComponentInterconnectDeviceDescriptor GetDeviceDescriptor(uint16_t bus, uint16_t device, uint16_t function); - BaseAddressRegister getBaseAddressRegister(uint16_t bus, uint16_t device, uint16_t function, uint16_t bar); // bar = 0-5 in case of header type 0 [or] bar = 0-1 in case of header type 1 - bool DeviceHasFunctions(uint16_t bus, uint16_t device); - - public: - PeripheralComponentInterconnectController(common::OutputStream* debugMessagesStream); - ~PeripheralComponentInterconnectController(); - - void selectDrivers(drivers::DriverSelectorEventHandler* handler, hardwarecommunication::InterruptManager* interruptManager, common::OutputStream* errorMessageStream); - drivers::Driver* GetDriver(PeripheralComponentInterconnectDeviceDescriptor dev, InterruptManager* interruptManager); - void listKnownDeivce(PeripheralComponentInterconnectDeviceDescriptor dev); + private: + // Ports + Port32Bit m_data_port; + Port32Bit m_command_port; + + // Debug + common::OutputStream* m_debug_messages_stream; + + // I/O + uint32_t read(uint16_t bus, uint16_t device, uint16_t function, uint32_t registeroffset); + void write(uint16_t bus, uint16_t device, uint16_t function, uint32_t registeroffset, uint32_t value); + + // Device + PeripheralComponentInterconnectDeviceDescriptor get_device_descriptor(uint16_t bus, uint16_t device, uint16_t function); + BaseAddressRegister get_base_address_register(uint16_t bus, uint16_t device, uint16_t function, uint16_t bar); + bool device_has_functions(uint16_t bus, uint16_t device); + + public: + PeripheralComponentInterconnectController(common::OutputStream*); + ~PeripheralComponentInterconnectController(); + + void select_drivers(drivers::DriverSelectorEventHandler *handler, hardwarecommunication::InterruptManager* interrupt_manager, common::OutputStream* error_message_stream); + drivers::Driver* get_driver(PeripheralComponentInterconnectDeviceDescriptor dev, InterruptManager* interrupt_manager); + void list_known_deivce(PeripheralComponentInterconnectDeviceDescriptor dev); }; } } diff --git a/kernel/include/hardwarecommunication/port.h b/kernel/include/hardwarecommunication/port.h index 0835c4f6..db0ab844 100644 --- a/kernel/include/hardwarecommunication/port.h +++ b/kernel/include/hardwarecommunication/port.h @@ -9,68 +9,69 @@ namespace maxOS { namespace hardwarecommunication { - //Base Class for ports + /** + * @class Port + * @brief base class for all ports + */ class Port { - protected: //Protected so that it cant be instantiated bc its purely virtual - uint16_t portnumber; + protected: + uint16_t m_port_number; - Port(uint16_t portnumber); + Port(uint16_t port_number); ~Port(); }; + /** + * @class Port8Bit + * @brief Handles 8 bit ports + */ class Port8Bit : public Port { public: - //Constructor / Deconstructor - Port8Bit(uint16_t portnumber); + Port8Bit(uint16_t port_number); ~Port8Bit(); - //Read / Write function - virtual void Write(uint8_t data); - - virtual uint8_t Read(); + virtual void write(uint8_t data); + virtual uint8_t read(); }; + /** + * @class Port8BitSlow + * @brief Handles 8 bit ports (slow) + */ class Port8BitSlow : public Port8Bit { public: - //Constructor / Deconstructor - Port8BitSlow(uint16_t portnumber); + Port8BitSlow(uint16_t port_number); ~Port8BitSlow(); - //Read / Write function - virtual void Write(uint8_t data); - //---Inherits read methods + virtual void write(uint8_t data) final; }; + /** + * @class Port16Bit + * @brief Handles 16 bit ports + */ class Port16Bit : public Port { public: - //Constructor / Deconstructor - Port16Bit(uint16_t portnumber); + Port16Bit(uint16_t port_number); ~Port16Bit(); - //Read / Write function - virtual void Write(uint16_t data); - - virtual uint16_t Read(); + virtual void write(uint16_t data); + virtual uint16_t read(); }; + /** + * @class Port32Bit + * @brief Handles 32 bit ports + */ class Port32Bit : public Port { public: - //Constructor / Deconstructor - Port32Bit(uint16_t portnumber); + Port32Bit(uint16_t port_number); ~Port32Bit(); - //Read / Write function - virtual void Write(uint32_t data); - - virtual uint32_t Read(); + virtual void write(uint32_t data); + virtual uint32_t read(); }; } } -#endif //MAX_OS_HARDWARECOMMUNICATION_PORT_H - -//NOTES -//1-protected : members can be used by objects of the derived classes but not by objects of the base class. -//2-virtual : if the base class and the derived class both have the same function [same name, same input parameters, same return type], then this function is overriden . So to make sure that when calling a member function from an object of the derived class , that this function called is the function that belongs to the derived class not to the base class , we use the virtual keyword to tell the compiler we want to resolve to the most derived class. -//3-static : static member functions can be called without creating an object for this class . -//4-inline : when code is compiled , a call to a function is replaced with the function's code rather than calling the function which improves performance . \ No newline at end of file +#endif //MAX_OS_HARDWARECOMMUNICATION_PORT_H \ No newline at end of file diff --git a/kernel/include/hardwarecommunication/serial.h b/kernel/include/hardwarecommunication/serial.h deleted file mode 100644 index d0756ac4..00000000 --- a/kernel/include/hardwarecommunication/serial.h +++ /dev/null @@ -1,124 +0,0 @@ -// -// Created by 98max on 11/12/2022. -// - -#ifndef MAXOS_HARDWARECOMMUNICATION_SERIAL_H -#define MAXOS_HARDWARECOMMUNICATION_SERIAL_H - -#include -#include -#include - -namespace maxOS{ - - namespace hardwarecommunication{ - - //Note: '_' is used to detect the end of the line, instead of \0 as is used at the start for colour codewords - class Colour{ - - public: - string defaultColour_fg = "\033[39m_"; - string defaultColour_bg = "\033[49m_"; - - string black_fg = "\033[30m_"; - string black_bg = "\033[40m_"; - - string dark_red_fg = "\033[31m_"; - string dark_red_bg = "\033[41m_"; - - string dark_green_fg = "\033[32m_"; - string dark_green_bg = "\033[42m_"; - - string dark_yellow_fg = "\033[33m_"; - string dark_yellow_bg = "\033[43m_"; - - string dark_blue_fg = "\033[34m_"; - string dark_blue_bg = "\033[44m_"; - - string dark_magenta_fg = "\033[35m_"; - string dark_magenta_bg = "\033[45m_"; - - string dark_cyan_fg = "\033[36m_"; - string dark_cyan_bg = "\033[46m_"; - - string dark_grey_fg = "\033[37m_"; - string dark_grey_bg = "\033[47m_"; - - string light_grey_fg = "\033[90m_"; - string light_grey_bg = "\033[100m_"; - - string red_fg = "\033[91m_"; - string red_bg = "\033[101m_"; - - string green_fg = "\033[92m_"; - string green_bg = "\033[102m_"; - - string yellow_fg = "\033[93m_"; - string yellow_bg = "\033[103m_"; - - string blue_fg = "\033[94m_"; - string blue_bg = "\033[104m_"; - - string magenta_fg = "\033[95m_"; - string magenta_bg = "\033[105m_"; - - string cyan_fg = "\033[96m_"; - string cyan_bg = "\033[106m_"; - - string white_fg = "\033[97m_"; - string white_bg = "\033[107m_"; - - - }; - - class Type{ - - public: - string bold = "\033[1m_"; - string italic = "\033[3m_"; - string underline = "\033[4m_"; - string strikethrough = "\033[9m_"; - string blink = "\033[5m_"; - string reverse = "\033[7m_"; - string hidden = "\033[8m_"; - string reset = "\033[0m_"; - string none = "_"; - - - }; - - class serial : public InterruptHandler { - private: - Port8Bit dataPort; - Port8Bit interruptEnableRegisterPort; - Port8Bit fifoCommandPort; - Port8Bit lineCommandPort; - Port8Bit modemCommandPort; - Port8Bit lineStatusPort; - Port8Bit modemStatusPort; - Port8Bit scratchPort; - - int receive(); - int isTransmitEmpty(); - void printHeader(string col, string type, string msg); - - public: - serial(InterruptManager* interruptManager); - ~serial(); - - void HandleInterrupt(); - - void Test(); - char Read(); - void Write(string str, int type = 0); - - - }; - - } - -} - - - -#endif //MAXOS_HARDWARECOMMUNICATION_SERIAL_H diff --git a/kernel/include/memory/memoryIO.h b/kernel/include/memory/memoryIO.h index c39862c0..9528f8cb 100644 --- a/kernel/include/memory/memoryIO.h +++ b/kernel/include/memory/memoryIO.h @@ -11,68 +11,64 @@ namespace maxOS{ namespace memory{ - //Base class for memory I/o + /** + * @class MemIO + * @brief base class for all memory IO + */ class MemIO { - protected: //Protected so that it cant be instantiated bc its purely virtual - uint64_t address; + protected: + uint32_t m_address; - MemIO(uint64_t address); + MemIO(uint32_t address); ~MemIO(); }; + /** + * @class MemIO8Bit + * @brief Handles 8 bit memory IO + */ class MemIO8Bit : public MemIO { public: - //Constructor / Deconstructor - MemIO8Bit(uint64_t address); + MemIO8Bit(uint32_t address); ~MemIO8Bit(); - //Read / Write function - virtual void Write(uint8_t data); - - virtual uint8_t Read(); + virtual void write(uint8_t data); + virtual uint8_t read(); }; class MemIO16Bit : public MemIO { public: - //Constructor / Deconstructor - MemIO16Bit(uint64_t address); + MemIO16Bit(uint32_t address); ~MemIO16Bit(); - //Read / Write function - virtual void Write(uint16_t data); - - virtual uint16_t Read(); + virtual void write(uint16_t data); + virtual uint16_t read(); }; class MemIO32Bit : public MemIO { public: - //Constructor / Deconstructor - MemIO32Bit(uint64_t address); + MemIO32Bit(uint32_t address); ~MemIO32Bit(); - //Read / Write function - virtual void Write(uint32_t data); - - virtual uint32_t Read(); + virtual void write(uint32_t data); + virtual uint32_t read(); }; class MemIO64Bit : public MemIO { public: - //Constructor / Deconstructor - MemIO64Bit(uint64_t address); + MemIO64Bit(uint32_t address); ~MemIO64Bit(); - //Read / Write function - virtual void Write(uint64_t data); - - virtual uint64_t Read(); + virtual void write(uint64_t data); + virtual uint64_t read(); }; - void* memcpy(void* destination, const void* source, uint32_t num); - - + static void* memcpy(void* destination, const void* source, uint32_t num); + static void* memset(void* ptr, int value, uint32_t num); + static void* memmove(void* destination, const void* source, uint32_t num); + static int memcmp(const void* ptr1, const void* ptr2, uint32_t num); } } diff --git a/kernel/include/memory/memorymanagement.h b/kernel/include/memory/memorymanagement.h index e9f10ad6..1fc257e5 100644 --- a/kernel/include/memory/memorymanagement.h +++ b/kernel/include/memory/memorymanagement.h @@ -22,55 +22,26 @@ namespace maxOS{ }; + /** + * @class MemoryManager + * @brief Handles memory allocation and deallocation + */ class MemoryManager{ - protected: - MemoryChunk* first; - - public: - static MemoryManager* activeMemoryManager; //Similar to how we have the active interrupt manager - - MemoryManager(size_t start, size_t size); - ~MemoryManager(); - - void* malloc(size_t size); - void free(void* pointer); - int getMemoryUsed(); - - template Type* Instantiate(uint32_t numberOfElements=1){ - Type* result = (Type*)malloc(sizeof(Type)*numberOfElements); - new (result) Type(); - return result; - } - - template Type* Instantiate(Parameter1 p1){ - Type* result = (Type*)malloc(sizeof(Type)); - new (result) Type(p1); - return result; - } - - template Type* Instantiate(Parameter1 p1, Parameter2 p2) { - Type* result = (Type*)malloc(sizeof(Type)); - new (result) Type(p1, p2); - return result; - } - - template Type* Instantiate(Parameter1 p1, Parameter2 p2, Parameter3 p3) { - Type* result = (Type*)malloc(sizeof(Type)); - new (result) Type(p1, p2, p3); - return result; - } - - template Type* Instantiate(Parameter1 p1, Parameter2 p2, Parameter3 p3, Parameter4 p4) { - Type* result = (Type*)malloc(sizeof(Type)); - new (result) Type(p1, p2, p3, p4); - return result; - } + protected: + MemoryChunk* m_first_memory_chunk; - }; - } + public: + static MemoryManager* s_active_memory_manager; + MemoryManager(size_t start, size_t size); + ~MemoryManager(); + void* malloc(size_t size); + void free(void* pointer); + int memory_used(); + }; + } } @@ -83,7 +54,7 @@ void* operator new[](size_t size); void* operator new(size_t size, void* pointer); void* operator new[](size_t size, void* pointer); -void operator delete(void* pointer); -void operator delete[](void* pointer); +void operator delete(void* pointer, size_t size); +void operator delete[](void* pointer, size_t size); #endif //MAXOS_SYSTEM_MEMORYMANAGEMENT_H diff --git a/kernel/include/net/ethernetframe.h b/kernel/include/net/ethernetframe.h index 5141a4e3..4e7df09b 100644 --- a/kernel/include/net/ethernetframe.h +++ b/kernel/include/net/ethernetframe.h @@ -50,7 +50,7 @@ namespace maxOS{ class EthernetFrameHandler : public drivers::ethernet::EthernetDriverEventHandler{ protected: - // A map of the handlers and the ethernet frame type they handle + // A map of the m_handlers and the ethernet frame type they handle common::Map frameHandlers; drivers::ethernet::EthernetDriver* ethernetDriver; diff --git a/kernel/include/net/tcp.h b/kernel/include/net/tcp.h index 6f23899c..a71fa87b 100644 --- a/kernel/include/net/tcp.h +++ b/kernel/include/net/tcp.h @@ -118,7 +118,8 @@ namespace maxOS{ TransmissionControlProtocolPayloadHandler(); ~TransmissionControlProtocolPayloadHandler(); - common::Event* onEvent(common::Event* event); + common::Event* + on_event(common::Event* event); virtual void handleTransmissionControlProtocolPayload(TransmissionControlProtocolSocket* socket, uint8_t* data, uint16_t size); virtual void Connected(TransmissionControlProtocolSocket* socket); diff --git a/kernel/include/net/udp.h b/kernel/include/net/udp.h index ded756a7..852ebe68 100644 --- a/kernel/include/net/udp.h +++ b/kernel/include/net/udp.h @@ -52,7 +52,8 @@ namespace maxOS UserDatagramProtocolPayloadHandler(); ~UserDatagramProtocolPayloadHandler(); - common::Event* onEvent(common::Event* event); + common::Event* + on_event(common::Event* event); virtual void handleUserDatagramProtocolMessage(UserDatagramProtocolSocket* socket, uint8_t* data, uint16_t size); diff --git a/kernel/include/system/gdt.h b/kernel/include/system/gdt.h index c50b66e9..37cede88 100644 --- a/kernel/include/system/gdt.h +++ b/kernel/include/system/gdt.h @@ -10,43 +10,51 @@ namespace maxOS { namespace system { - class GlobalDescriptorTable { - public: - class SegmentDescriptor { + + /** + * @class SegmentDescriptor + * @brief Stores data for the segment descriptors in the GDT + */ + class SegmentDescriptor { private: - uint16_t limit_lo; //Low Bytes of the pointer (Least Significant) - uint16_t base_lo; //Low Bytes of the pointer (Least Significant) - uint8_t base_hi; //One byte extension for the pointer - uint8_t type; //Excess Bytes - uint8_t flags_limit_hi; //High Bytes of the pointer (Most Significant) - uint8_t base_vhi; //High Bytes of the pointer (Most Significant) + uint16_t m_limit_lo; + uint16_t m_base_lo; + uint8_t m_base_hi; + uint8_t m_type; + uint8_t m_flags_limit_hi; + uint8_t m_base_vhi; + public: - SegmentDescriptor(uint32_t base, uint32_t limit, - uint8_t type); + SegmentDescriptor(uint32_t base, uint32_t limit, uint8_t type); - //Return Pointer and the limit - uint32_t Base(); + uint32_t base(); + uint32_t limit(); - uint32_t Limit(); + } __attribute__((packed)); - } __attribute__((packed)); //Tell GCC not to change any of the alignment in the structure. The packed attribute specifies that a variable or structure field should have the smallest possible alignment, one byte for a variable, and one bit for a field, unless you specify a larger value with the aligned attribute. - private: - SegmentDescriptor nullSegmentSelector; - SegmentDescriptor unusedSegmentSelector; - SegmentDescriptor codeSegmentSelector; - SegmentDescriptor dataSegmentSelector; - SegmentDescriptor taskStateSegmentSelector; + /** + * @class GlobalDescriptorTable + * @brief Sets up the GDT in the CPU + */ + class GlobalDescriptorTable { + + private: + SegmentDescriptor m_null_segment_selector; + SegmentDescriptor m_unused_segment_selector; + SegmentDescriptor m_code_segment_selector; + SegmentDescriptor m_data_segment_selector; + SegmentDescriptor m_task_state_segment_selector; - public: + public: - GlobalDescriptorTable(const multiboot_info& multibootHeader); - ~GlobalDescriptorTable(); + GlobalDescriptorTable(const multiboot_info& multiboot_header); + ~GlobalDescriptorTable(); - uint16_t CodeSegmentSelector(); - uint16_t DataSegmentSelector(); - uint16_t TaskStateSegmentSelector(); - }; + uint16_t code_segment_selector(); + uint16_t data_segment_selector(); + uint16_t task_state_segment_selector(); + }; } } diff --git a/kernel/include/system/multiboot.h b/kernel/include/system/multiboot.h index 583d5e7b..5c768ef7 100644 --- a/kernel/include/system/multiboot.h +++ b/kernel/include/system/multiboot.h @@ -111,14 +111,14 @@ namespace maxOS{ /* The above fields plus this one must equal 0 mod 2^32. */ multiboot_uint32_t checksum; - /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ + /* These are only m_valid if MULTIBOOT_AOUT_KLUDGE is set. */ multiboot_uint32_t header_addr; multiboot_uint32_t load_addr; multiboot_uint32_t load_end_addr; multiboot_uint32_t bss_end_addr; multiboot_uint32_t entry_addr; - /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */ + /* These are only m_valid if MULTIBOOT_VIDEO_MODE is set. */ multiboot_uint32_t mode_type; multiboot_uint32_t width; multiboot_uint32_t height; diff --git a/kernel/include/system/multitasking.h b/kernel/include/system/multitasking.h index 6039a535..ad206223 100644 --- a/kernel/include/system/multitasking.h +++ b/kernel/include/system/multitasking.h @@ -5,6 +5,7 @@ #ifndef MAXOS_SYSTEM_MULTITASKING_H #define MAXOS_SYSTEM_MULTITASKING_H +#include #include #include @@ -12,60 +13,57 @@ namespace maxOS{ namespace system{ - struct CPUState_Task - { - //Pushed by kernel in interuptstubs - - uint32_t eax; // Accumulating Register - uint32_t ebx; // Base Register - uint32_t ecx; // Counting Register - uint32_t edx; // Data Register - - uint32_t esi; // Stack Index - uint32_t edi; // Data Index - uint32_t ebp; // Stack Base Pointer - - //Elements that have been pushed so far - /* - uint32_t gs; - uint32_t fs; - uint32_t es; - uint32_t ds; - */ - uint32_t error; //One int for an error code - - uint32_t eip; // Instruction Pointer - uint32_t cs; // Code Segment - uint32_t eflags; // Flags - uint32_t esp; // Stack Pointer - uint32_t ss; // Stack Segment - } __attribute__((packed)); + struct CPUState { + //Pushed by kernel in interupt_stubs + + uint32_t eax; + uint32_t ebx; + uint32_t ecx; + uint32_t edx; + + uint32_t esi; + uint32_t edi; + uint32_t ebp; + uint32_t error; + uint32_t eip; + uint32_t cs; + uint32_t eflags; + uint32_t esp; + uint32_t ss; + } __attribute__((packed)); + + /** + * @class Task + * @brief A task that can be scheduled by the TaskManager + */ class Task { - friend class TaskManager; //Allow TaskManger class to acess private values of this class - private: - uint8_t stack[4096]; //Allocate 4kb for this tasks stack - CPUState_Task* cpuState; - public: - Task(system::GlobalDescriptorTable *gdt, void entrypoint()); - ~Task(); - bool killMe = false; + friend class TaskManager; + + private: + uint8_t m_stack[4096]; + CPUState * m_cpu_state; + public: + Task(system::GlobalDescriptorTable *gdt, void entrypoint()); + ~Task(); }; - + /** + * @class TaskManager + * @brief Manages the scheduling of m_tasks + */ class TaskManager { - private: - Task* tasks[256]; - int numTasks; - int currentTask; //Index of currently active task is used when the processor needs to go back to this task - public: - TaskManager(); - ~TaskManager(); - bool AddTask(Task* task); - CPUState_Task* Schedule(CPUState_Task* cpuState); //function that does the scheduling (round-robin [https://en.wikipedia.org/wiki/Round-robin_scheduling])s + private: + common::Vector m_tasks; + int m_current_task { -1 }; + public: + TaskManager(); + ~TaskManager(); + bool add_task(Task* task); + CPUState * schedule(CPUState * cpuState); }; } diff --git a/kernel/include/system/multithreading.h b/kernel/include/system/multithreading.h index 218d4bf1..4b4102d9 100644 --- a/kernel/include/system/multithreading.h +++ b/kernel/include/system/multithreading.h @@ -5,75 +5,51 @@ #ifndef MAXOS_SYSTEM_MULTITHREADING_H #define MAXOS_SYSTEM_MULTITHREADING_H +#include #include #include namespace maxOS{ - struct CPUState_Thread - { - uint32_t eax; - uint32_t ebx; - uint32_t ecx; - uint32_t edx; + namespace system{ - uint32_t esi; - uint32_t edi; - uint32_t ebp; + class Thread + { + friend class ThreadManager; + private: + uint8_t m_stack[4096]; + CPUState* m_cpu_state; + bool m_yield_status; + int m_tid; + public: + Thread(); + ~Thread(); - /* - uint32_t gs; - uint32_t fs; - uint32_t es; - uint32_t ds; - */ - uint32_t error; + void init(system::GlobalDescriptorTable *gdt, void entrypoint()); + }; - uint32_t eip; - uint32_t cs; - uint32_t eflags; - uint32_t esp; - uint32_t ss; - } __attribute__((packed)); + class ThreadManager + { + private: + // Vector for threads and stack + common::Vector m_threads; - class Thread - { - friend class ThreadManager; - private: - uint8_t stack[4096]; // 4 KiB - CPUState_Thread* cpustate; - bool yieldStatus; // if true, Thread will be yielded - int tid; // thread id - public: - Thread(system::GlobalDescriptorTable *gdt, void entrypoint()); - Thread(void entrypoint()); - void init(system::GlobalDescriptorTable *gdt, void entrypoint()); - ~Thread(); - }; + int m_current_thread; + system::GlobalDescriptorTable*m_gdt; + public: + ThreadManager(); + ThreadManager(system::GlobalDescriptorTable *gdt); + ~ThreadManager(); - class ThreadManager - { - private: - static uint8_t stack[256][5012]; - static Thread* Threads[256]; - static int numThreads; - static int currentThread; - static system::GlobalDescriptorTable *gdt; - public: - ThreadManager(); - ThreadManager(system::GlobalDescriptorTable *gdt); - ~ThreadManager(); - int CreateThread(void entrypoint()); - CPUState_Thread* Schedule(CPUState_Thread* cpustate); - bool TerminateThread(int tid); - bool JoinThreads(int other); - bool CheckThreads(int tid); - void YieldThreads(int tid); - }; + int create_thread(void entrypoint()); + CPUState*schedule(CPUState *cpu_state); + bool terminate_thread(int tid); + }; + } } #endif //MAXOS_SYSTEM_MULTITHREADING_H diff --git a/kernel/include/system/process.h b/kernel/include/system/process.h index 4282c7a4..9709a5ad 100644 --- a/kernel/include/system/process.h +++ b/kernel/include/system/process.h @@ -13,34 +13,10 @@ namespace maxOS{ class Process; - - class Process{ - friend class ProcessManager; - private: - ThreadManager* threadManager; - int mainThreadID; - int childThreads[6]; - int numChildThreads = 0; - - public: - void CreateChildThread(void entrypoint()); - void KillChildThread(int threadID); - void KillAllChildThreads(); - void RefreshProcess(); - void Kill(); - - void threadMain(void entrypoint(), Process* process); - - - - Process(void entrypoint(), ThreadManager* threadManager); - ~Process(); + // TODO: Re-work process class }; - } - - } #endif //MAXOS_PROCESS_H diff --git a/kernel/include/system/syscalls.h b/kernel/include/system/syscalls.h index d5921205..a64cd00d 100644 --- a/kernel/include/system/syscalls.h +++ b/kernel/include/system/syscalls.h @@ -14,10 +14,10 @@ namespace maxOS{ class SyscallHandler : hardwarecommunication::InterruptHandler{ public: - SyscallHandler(hardwarecommunication::InterruptManager* interruptManager, uint8_t interruptNumber); + SyscallHandler(hardwarecommunication::InterruptManager*interrupt_manager, uint8_t interrupt_number); ~SyscallHandler(); - virtual void HandleInterrupt(); + virtual void handle_interrupt(); }; diff --git a/kernel/src/common/colour.cpp b/kernel/src/common/colour.cpp index 2fdff188..fd30f6ab 100644 --- a/kernel/src/common/colour.cpp +++ b/kernel/src/common/colour.cpp @@ -8,33 +8,22 @@ using namespace maxOS::common; Colour::Colour() { - // Default to black - this -> red = 0; - this -> green = 0; - this -> blue = 0; - this -> alpha = 0; - } -Colour::Colour(uint8_t red, uint8_t green, uint8_t blue) { - - // Set the colours, no alpha - this -> red = red; - this -> green = green; - this -> blue = blue; - this -> alpha = 0; - +Colour::Colour(uint8_t red, uint8_t green, uint8_t blue) +: red(red), + green(green), + blue(blue) +{ } -Colour::Colour(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) { - - // Set the colours - this -> red = red; - this -> green = green; - this -> blue = blue; - this -> alpha = alpha; - +Colour::Colour(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) +: red(red), + green(green), + blue(blue), + alpha(alpha) +{ } diff --git a/kernel/src/common/graphicsContext.cpp b/kernel/src/common/graphicsContext.cpp index a00279b5..fe6e0416 100644 --- a/kernel/src/common/graphicsContext.cpp +++ b/kernel/src/common/graphicsContext.cpp @@ -6,86 +6,84 @@ using namespace maxOS::common; -GraphicsContext::GraphicsContext() { - width = 0; - height = 0; - colorDepth = 0; - mirrorYAxis = false; +GraphicsContext::GraphicsContext() +{ + // VirtualBox VGA palette - colourPallet[0x00] = Colour(0x00,0x00,0x00); // Black - colourPallet[0x01] = Colour(0x00,0x00,0xA8); // Duke Blue - colourPallet[0x02] = Colour(0x00,0xA8,0x00); // Islamic Green - colourPallet[0x03] = Colour(0x00,0xA8,0xA8); // Persian Green - colourPallet[0x04] = Colour(0xA8,0x00,0x00); // Dark Candy Apple Red - colourPallet[0x05] = Colour(0xA8,0x00,0xA8); // Heliotrope Magenta - - colourPallet[0x06] = Colour(0xA8,0xA8,0x00); // Light Gold - colourPallet[0x07] = Colour(0xA8,0xA8,0xA8); // Dark Gray (X11) - colourPallet[0x08] = Colour(0x00,0x00,0x57); // Cetacean Blue - colourPallet[0x09] = Colour(0x00,0x00,0xFF); // Blue - colourPallet[0x0A] = Colour(0x00,0xA8,0x57); // Green (Pigment) - colourPallet[0x0B] = Colour(0x00,0xA8,0xFF); // Vivid Cerulean - colourPallet[0x0C] = Colour(0xA8,0x00,0x57); // Jazzberry Jam - colourPallet[0x0D] = Colour(0xA8,0x00,0x57); // Jazzberry Jam - colourPallet[0x0E] = Colour(0xA8,0xA8,0x57); // Olive Green - colourPallet[0x0F] = Colour(0xA8,0xA8,0xFF); // Maximum Blue Purple - - colourPallet[0x10] = Colour(0x00,0x57,0x00); // Dark Green (X11) - colourPallet[0x11] = Colour(0x00,0x57,0xA8); // Cobalt Blue - colourPallet[0x12] = Colour(0x00,0xFF,0x00); // Electric Green - colourPallet[0x13] = Colour(0x00,0xFF,0xA8); // Medium Spring Green - colourPallet[0x14] = Colour(0xA8,0x57,0x00); // Windsor Tan - colourPallet[0x15] = Colour(0xA8,0x57,0xA8); // Purpureus - colourPallet[0x16] = Colour(0xA8,0xFF,0x00); // Spring Bud - colourPallet[0x17] = Colour(0xA8,0xFF,0xA8); // Mint Green - colourPallet[0x18] = Colour(0x00,0x57,0x57); // Midnight Green (Eagle Green) - colourPallet[0x19] = Colour(0x00,0x57,0xFF); // Blue (RYB) - colourPallet[0x1A] = Colour(0x00,0xFF,0x57); // Malachite - colourPallet[0x1B] = Colour(0x00,0xFF,0xFF); // Aqua - colourPallet[0x1C] = Colour(0xA8,0x57,0x57); // Middle Red Purple - colourPallet[0x1D] = Colour(0xA8,0x57,0xFF); // Lavender Indigo - colourPallet[0x1E] = Colour(0xA8,0xFF,0x57); // Olive Green - colourPallet[0x1F] = Colour(0xA8,0xFF,0xFF); // Celeste - - colourPallet[0x20] = Colour(0x57,0x00,0x00); // Blood Red - colourPallet[0x21] = Colour(0x57,0x00,0xA8); // Metallic Violet - colourPallet[0x22] = Colour(0x57,0xA8,0x00); // Kelly Green - colourPallet[0x23] = Colour(0x57,0xA8,0xA8); // Cadet Blue - colourPallet[0x24] = Colour(0xFF,0x00,0x00); // Red - colourPallet[0x25] = Colour(0xFF,0x00,0xA8); // Fashion Fuchsia - colourPallet[0x26] = Colour(0xFF,0xA8,0x00); // Chrome Yellow - colourPallet[0x27] = Colour(0xFF,0xA8,0xA8); // Light Salmon Pink - colourPallet[0x28] = Colour(0x57,0x00,0x57); // Imperial Purple - colourPallet[0x29] = Colour(0x57,0x00,0xFF); // Electric Indigo - colourPallet[0x2A] = Colour(0x57,0xA8,0x57); // Apple - colourPallet[0x2B] = Colour(0x57,0xA8,0xFF); // Blue Jeans - colourPallet[0x2C] = Colour(0xFF,0x00,0x57); // Folly - colourPallet[0x2D] = Colour(0xFF,0x00,0xFF); // Fuchsia - colourPallet[0x2E] = Colour(0xFF,0xA8,0x57); // Rajah - colourPallet[0x2F] = Colour(0xFF,0xA8,0xFF); // Rich Brilliant Lavender - - colourPallet[0x30] = Colour(0x57,0x57,0x00); // Dark Bronze (Coin) - colourPallet[0x31] = Colour(0x57,0x57,0xA8); // Liberty - colourPallet[0x32] = Colour(0x57,0xFF,0x00); // Chlorophyll Green - colourPallet[0x33] = Colour(0x57,0xFF,0xA8); // Medium Aquamarine - colourPallet[0x34] = Colour(0xFF,0x57,0x00); // Orange (Pantone) - colourPallet[0x35] = Colour(0xFF,0x57,0xA8); // Brilliant Rose - colourPallet[0x36] = Colour(0xFF,0xFF,0x00); // Yellow - colourPallet[0x37] = Colour(0xFF,0xFF,0xA8); // Calamansi - colourPallet[0x38] = Colour(0x57,0x57,0x57); // Davy's Grey - colourPallet[0x39] = Colour(0x57,0x57,0xFF); // Very Light Blue - colourPallet[0x3A] = Colour(0x57,0xFF,0x57); // Screamin' Green - colourPallet[0x3B] = Colour(0x57,0xFF,0xFF); // Electric Blue - colourPallet[0x3C] = Colour(0xFF,0x57,0x57); // Sunset Orange - colourPallet[0x3D] = Colour(0xFF,0x57,0xFF); // Shocking Pink (Crayola) - colourPallet[0x3E] = Colour(0xFF,0xFF,0x57); // Shocking Pink (Crayola) - colourPallet[0x3F] = Colour(0xFF,0xFF,0xFF); // White + m_colour_pallet[0x00] = Colour(0x00,0x00,0x00); // Black + m_colour_pallet[0x01] = Colour(0x00,0x00,0xA8); // Duke Blue + m_colour_pallet[0x02] = Colour(0x00,0xA8,0x00); // Islamic Green + m_colour_pallet[0x03] = Colour(0x00,0xA8,0xA8); // Persian Green + m_colour_pallet[0x04] = Colour(0xA8,0x00,0x00); // Dark Candy Apple Red + m_colour_pallet[0x05] = Colour(0xA8,0x00,0xA8); // Heliotrope Magenta + + m_colour_pallet[0x06] = Colour(0xA8,0xA8,0x00); // Light Gold + m_colour_pallet[0x07] = Colour(0xA8,0xA8,0xA8); // Dark Gray (X11) + m_colour_pallet[0x08] = Colour(0x00,0x00,0x57); // Cetacean Blue + m_colour_pallet[0x09] = Colour(0x00,0x00,0xFF); // Blue + m_colour_pallet[0x0A] = Colour(0x00,0xA8,0x57); // Green (Pigment) + m_colour_pallet[0x0B] = Colour(0x00,0xA8,0xFF); // Vivid Cerulean + m_colour_pallet[0x0C] = Colour(0xA8,0x00,0x57); // Jazzberry Jam + m_colour_pallet[0x0D] = Colour(0xA8,0x00,0x57); // Jazzberry Jam + m_colour_pallet[0x0E] = Colour(0xA8,0xA8,0x57); // Olive Green + m_colour_pallet[0x0F] = Colour(0xA8,0xA8,0xFF); // Maximum Blue Purple + + m_colour_pallet[0x10] = Colour(0x00,0x57,0x00); // Dark Green (X11) + m_colour_pallet[0x11] = Colour(0x00,0x57,0xA8); // Cobalt Blue + m_colour_pallet[0x12] = Colour(0x00,0xFF,0x00); // Electric Green + m_colour_pallet[0x13] = Colour(0x00,0xFF,0xA8); // Medium Spring Green + m_colour_pallet[0x14] = Colour(0xA8,0x57,0x00); // Windsor Tan + m_colour_pallet[0x15] = Colour(0xA8,0x57,0xA8); // Purpureus + m_colour_pallet[0x16] = Colour(0xA8,0xFF,0x00); // Spring Bud + m_colour_pallet[0x17] = Colour(0xA8,0xFF,0xA8); // Mint Green + m_colour_pallet[0x18] = Colour(0x00,0x57,0x57); // Midnight Green (Eagle Green) + m_colour_pallet[0x19] = Colour(0x00,0x57,0xFF); // Blue (RYB) + m_colour_pallet[0x1A] = Colour(0x00,0xFF,0x57); // Malachite + m_colour_pallet[0x1B] = Colour(0x00,0xFF,0xFF); // Aqua + m_colour_pallet[0x1C] = Colour(0xA8,0x57,0x57); // Middle Red Purple + m_colour_pallet[0x1D] = Colour(0xA8,0x57,0xFF); // Lavender Indigo + m_colour_pallet[0x1E] = Colour(0xA8,0xFF,0x57); // Olive Green + m_colour_pallet[0x1F] = Colour(0xA8,0xFF,0xFF); // Celeste + + m_colour_pallet[0x20] = Colour(0x57,0x00,0x00); // Blood Red + m_colour_pallet[0x21] = Colour(0x57,0x00,0xA8); // Metallic Violet + m_colour_pallet[0x22] = Colour(0x57,0xA8,0x00); // Kelly Green + m_colour_pallet[0x23] = Colour(0x57,0xA8,0xA8); // Cadet Blue + m_colour_pallet[0x24] = Colour(0xFF,0x00,0x00); // Red + m_colour_pallet[0x25] = Colour(0xFF,0x00,0xA8); // Fashion Fuchsia + m_colour_pallet[0x26] = Colour(0xFF,0xA8,0x00); // Chrome Yellow + m_colour_pallet[0x27] = Colour(0xFF,0xA8,0xA8); // Light Salmon Pink + m_colour_pallet[0x28] = Colour(0x57,0x00,0x57); // Imperial Purple + m_colour_pallet[0x29] = Colour(0x57,0x00,0xFF); // Electric Indigo + m_colour_pallet[0x2A] = Colour(0x57,0xA8,0x57); // Apple + m_colour_pallet[0x2B] = Colour(0x57,0xA8,0xFF); // Blue Jeans + m_colour_pallet[0x2C] = Colour(0xFF,0x00,0x57); // Folly + m_colour_pallet[0x2D] = Colour(0xFF,0x00,0xFF); // Fuchsia + m_colour_pallet[0x2E] = Colour(0xFF,0xA8,0x57); // Rajah + m_colour_pallet[0x2F] = Colour(0xFF,0xA8,0xFF); // Rich Brilliant Lavender + + m_colour_pallet[0x30] = Colour(0x57,0x57,0x00); // Dark Bronze (Coin) + m_colour_pallet[0x31] = Colour(0x57,0x57,0xA8); // Liberty + m_colour_pallet[0x32] = Colour(0x57,0xFF,0x00); // Chlorophyll Green + m_colour_pallet[0x33] = Colour(0x57,0xFF,0xA8); // Medium Aquamarine + m_colour_pallet[0x34] = Colour(0xFF,0x57,0x00); // Orange (Pantone) + m_colour_pallet[0x35] = Colour(0xFF,0x57,0xA8); // Brilliant Rose + m_colour_pallet[0x36] = Colour(0xFF,0xFF,0x00); // Yellow + m_colour_pallet[0x37] = Colour(0xFF,0xFF,0xA8); // Calamansi + m_colour_pallet[0x38] = Colour(0x57,0x57,0x57); // Davy's Grey + m_colour_pallet[0x39] = Colour(0x57,0x57,0xFF); // Very Light Blue + m_colour_pallet[0x3A] = Colour(0x57,0xFF,0x57); // Screamin' Green + m_colour_pallet[0x3B] = Colour(0x57,0xFF,0xFF); // Electric Blue + m_colour_pallet[0x3C] = Colour(0xFF,0x57,0x57); // Sunset Orange + m_colour_pallet[0x3D] = Colour(0xFF,0x57,0xFF); // Shocking Pink (Crayola) + m_colour_pallet[0x3E] = Colour(0xFF,0xFF,0x57); // Shocking Pink (Crayola) + m_colour_pallet[0x3F] = Colour(0xFF,0xFF,0xFF); // White // Set the rest of the palette to black - for(uint8_t colorCode = 255; colorCode >= 0x40; --colorCode) - colourPallet[colorCode] = Colour(0,0,0); + for(uint8_t color_code = 255; color_code >= 0x40; --color_code) + m_colour_pallet[color_code] = Colour(0,0,0); } @@ -95,27 +93,27 @@ GraphicsContext::~GraphicsContext() { } /** - * @details Renders a pixel to the screen, automatically uses the correct color depth + * @brief Renders a pixel to the screen based on the current color depth * * @param x The x coordinate of the pixel * @param y The y coordinate of the pixel * @param colour The colour of the pixel */ -void GraphicsContext::renderPixel(uint32_t x, uint32_t y, uint32_t colour) { +void GraphicsContext::render_pixel(uint32_t x, uint32_t y, uint32_t colour) { - // Call the correct putPixel function based on the color depth - switch (colorDepth) { + // Call the correct put_pixel function based on the color depth + switch (m_color_depth) { case 8: - renderPixel8Bit(x, y, colour); + render_pixel_8_bit(x, y, colour); break; case 16: - renderPixel16Bit(x, y, colour); + render_pixel_16_bit(x, y, colour); break; case 24: - renderPixel24Bit(x, y, colour); + render_pixel_24_bit(x, y, colour); break; case 32: - renderPixel32Bit(x, y, colour); + render_pixel_32_bit(x, y, colour); break; } @@ -123,123 +121,123 @@ void GraphicsContext::renderPixel(uint32_t x, uint32_t y, uint32_t colour) { } /** - * @details Renders a pixel to the screen using the 8 bit color depth + * @brief Renders a pixel to the screen using the 8 bit color depth * * @param x The x coordinate of the pixel * @param y The y coordinate of the pixel * @param colour The 8Bit colour of the pixel */ -void GraphicsContext::renderPixel8Bit(uint32_t x, uint32_t y, uint8_t colour) { +void GraphicsContext::render_pixel_8_bit(uint32_t x, uint32_t y, uint8_t colour) { } /** - * @details Renders a pixel to the screen using the 16 bit color depth + * @brief Renders a pixel to the screen using the 16 bit color depth * * @param x The x coordinate of the pixel * @param y The y coordinate of the pixel * @param colour The 16Bit colour of the pixel */ -void GraphicsContext::renderPixel16Bit(uint32_t x, uint32_t y, uint16_t colour) { +void GraphicsContext::render_pixel_16_bit(uint32_t x, uint32_t y, uint16_t colour) { } /** - * @details Renders a pixel to the screen using the 24 bit color depth + * @brief Renders a pixel to the screen using the 24 bit color depth * * @param x The x coordinate of the pixel * @param y The y coordinate of the pixel * @param colour The 24Bit colour of the pixel */ -void GraphicsContext::renderPixel24Bit(uint32_t x, uint32_t y, uint32_t colour) { +void GraphicsContext::render_pixel_24_bit(uint32_t x, uint32_t y, uint32_t colour) { } /** - * @details Renders a pixel to the screen using the 32 bit color depth + * @brief Renders a pixel to the screen using the 32 bit color depth * * @param x The x coordinate of the pixel * @param y The y coordinate of the pixel * @param colour The 32Bit colour of the pixel */ -void GraphicsContext::renderPixel32Bit(uint32_t x, uint32_t y, uint32_t colour) { +void GraphicsContext::render_pixel_32_bit(uint32_t x, uint32_t y, uint32_t colour) { } /** - * @details Gets the colour of a pixel on the screen, automatically uses the correct color depth + * @brief Gets the colour of a pixel on the screen, automatically uses the correct color depth * * @param x The x coordinate of the pixel * @param y The y coordinate of the pixel * @return The colour of the pixel */ -uint32_t GraphicsContext::getRenderedPixel(uint32_t x, uint32_t y) { - // Call the correct getPixel function based on the color depth - switch (colorDepth) { +uint32_t GraphicsContext::get_rendered_pixel(uint32_t x, uint32_t y) { + // Call the correct get_pixel function based on the color depth + switch (m_color_depth) { case 8: - return getRenderedPixel8Bit(x, y); + return get_rendered_pixel_8_bit(x, y); case 16: - return getRenderedPixel16Bit(x, y); + return get_rendered_pixel_16_bit(x, y); case 24: - return getRenderedPixel24Bit(x, y); + return get_rendered_pixel_24_bit(x, y); case 32: - return getRenderedPixel32Bit(x, y); + return get_rendered_pixel_32_bit(x, y); } } /** - * @details Gets the colour of a pixel on the screen using the 8 bit color depth + * @brief Gets the colour of a pixel on the screen using the 8 bit color depth * * @param x The x coordinate of the pixel * @param y The y coordinate of the pixel * @return The 8Bit colour of the pixel */ -uint8_t GraphicsContext::getRenderedPixel8Bit(uint32_t x, uint32_t y) { +uint8_t GraphicsContext::get_rendered_pixel_8_bit(uint32_t x, uint32_t y) { return 0; } /** - * @details Gets the colour of a pixel on the screen using the 16 bit color depth + * @brief Gets the colour of a pixel on the screen using the 16 bit color depth * * @param x The x coordinate of the pixel * @param y The y coordinate of the pixel * @return The 16Bit colour of the pixel */ -uint16_t GraphicsContext::getRenderedPixel16Bit(uint32_t x, uint32_t y) { +uint16_t GraphicsContext::get_rendered_pixel_16_bit(uint32_t x, uint32_t y) { return 0; } /** - * @details Gets the colour of a pixel on the screen using the 24 bit color depth + * @brief Gets the colour of a pixel on the screen using the 24 bit color depth * * @param x The x coordinate of the pixel * @param y The y coordinate of the pixel * @return The 24Bit colour of the pixel */ -uint32_t GraphicsContext::getRenderedPixel24Bit(uint32_t x, uint32_t y) { +uint32_t GraphicsContext::get_rendered_pixel_24_bit(uint32_t x, uint32_t y) { return 0; } /** - * @details Gets the colour of a pixel on the screen using the 32 bit color depth + * @brief Gets the colour of a pixel on the screen using the 32 bit color depth * * @param x The x coordinate of the pixel * @param y The y coordinate of the pixel * @return The 32Bit colour of the pixel */ -uint32_t GraphicsContext::getRenderedPixel32Bit(uint32_t x, uint32_t y) { +uint32_t GraphicsContext::get_rendered_pixel_32_bit(uint32_t x, uint32_t y) { return 0; } /** - * @details Converts a colour to an integer value based on the current color depth + * @brief Converts a colour to an integer value based on the current color depth * * @param colour The colour class to convert * @return The integer value of the colour */ -uint32_t GraphicsContext::colourToInt(Colour colour) { +uint32_t GraphicsContext::colour_to_int(Colour colour) { - switch(colorDepth) + switch(m_color_depth) { case 8: { @@ -247,7 +245,7 @@ uint32_t GraphicsContext::colourToInt(Colour colour) { int mindistance = 0xfffffff; for(uint32_t i = 0; i <= 255; ++i) { - Colour* c = &colourPallet[i]; + Colour* c = &m_colour_pallet[i]; int distance = ((int)colour.red-(int)c->red)*((int)colour.red-(int)c->red) +((int)colour.green-(int)c->green)*((int)colour.green-(int)c->green) @@ -276,12 +274,12 @@ uint32_t GraphicsContext::colourToInt(Colour colour) { default: case 32: { - uint32_t redHex = ((uint32_t)colour.red & 0xFF) << 16; - uint32_t greenHex = ((uint32_t)colour.green & 0xFF) << 8; - uint32_t blueHex = (uint32_t)colour.blue & 0xFF; - uint32_t alphaHex = ((uint32_t)colour.alpha & 0xFF) << 24; + uint32_t red_hex = ((uint32_t)colour.red & 0xFF) << 16; + uint32_t green_hex = ((uint32_t)colour.green & 0xFF) << 8; + uint32_t blue_hex = (uint32_t)colour.blue & 0xFF; + uint32_t alpha_hex = ((uint32_t)colour.alpha & 0xFF) << 24; - uint32_t hexValue = redHex | greenHex | blueHex | alphaHex; + uint32_t hexValue = red_hex | green_hex | blue_hex | alpha_hex; return hexValue; @@ -290,17 +288,18 @@ uint32_t GraphicsContext::colourToInt(Colour colour) { } /** - * @details Converts an integer value to a colour based on the current color depth + * @brief Converts an integer value to a colour based on the current color depth * * @param colour The integer value to convert * @return The colour class of the integer value */ -Colour GraphicsContext::intToColour(uint32_t colour) { - switch (colorDepth) { +Colour GraphicsContext::int_to_colour(uint32_t colour) { + switch (m_color_depth) { case 8: { - return colourPallet[colour & 0xFF]; //Mask off the top 24 bits and return the colour from the pallet (e.g. 0x00FF0000 -> 0x000000FF -> colourPallet[0xFF]) + // Return the colour from the palette + return m_colour_pallet[colour & 0xFF]; } case 16: @@ -308,9 +307,9 @@ Colour GraphicsContext::intToColour(uint32_t colour) { // 16-Bit Colour: 5 bits for red, 6 bits for green, 5 bits for blue (RRRRR,GGGGGG,BBBBB) Colour result; - result.red = (colour & 0xF800) >> 8; // Red, mask off the top 5 bits and shift right 8 bits (0000000000000000RRRRR000) - result.green = (colour & 0x07E0) >> 3; // Green, mask off the top 6 bits and shift right 3 bits (000000000000GGGGGG000000) - result.blue = (colour & 0x001F) << 3; // Blue, mask off the top 5 bits and shift left 3 bits (000000000000000000000BBBBB) + result.red = (colour & 0xF800) >> 8; + result.green = (colour & 0x07E0) >> 3; + result.blue = (colour & 0x001F) << 3; return result; } @@ -320,9 +319,9 @@ Colour GraphicsContext::intToColour(uint32_t colour) { // 24-Bit Colour: 8 bits for red, 8 bits for green, 8 bits for blue (RRRRRRRR,GGGGGGGG,BBBBBBBB) Colour result; - result.red = (colour & 0xFF0000) >> 16; // Red, mask off the top 8 bits and shift right 16 bits (RRRRRRRR0000000000000000) - result.green = (colour & 0x00FF00) >> 8; // Green, mask off the top 8 bits and shift right 8 bits (00000000GGGGGGGG00000000) - result.blue = (colour & 0x0000FF); // Blue, mask off the top 8 bits (0000000000000000BBBBBBBB) + result.red = (colour & 0xFF0000) >> 16; + result.green = (colour & 0x00FF00) >> 8; + result.blue = (colour & 0x0000FF); return result; } @@ -332,11 +331,11 @@ Colour GraphicsContext::intToColour(uint32_t colour) { { Colour result; - uint32_t hexValue = colour; - result.red = (hexValue >> 16) & 0xFF; - result.green = (hexValue >> 8) & 0xFF; - result.blue = hexValue & 0xFF; - result.alpha = (hexValue >> 24) & 0xFF; + uint32_t hex_value = colour; + result.red = (hex_value >> 16) & 0xFF; + result.green = (hex_value >> 8) & 0xFF; + result.blue = hex_value & 0xFF; + result.alpha = (hex_value >> 24) & 0xFF; return result; @@ -345,38 +344,38 @@ Colour GraphicsContext::intToColour(uint32_t colour) { } /** - * @details Gets the width of the screen + * @brief Gets the width of the screen * * @return The width of the screen */ -uint32_t GraphicsContext::getWidth() { - return width; +uint32_t GraphicsContext::get_width() { + return m_width; } /** - * @details Gets the height of the screen + * @brief Gets the height of the screen * * @return The height of the screen */ -uint32_t GraphicsContext::getHeight() { - return height; +uint32_t GraphicsContext::get_height() { + return m_height; } /** - * @details Renders a pixel to the screen + * @brief Renders a pixel to the screen (automatically converts the colour to an integer) * * @param x The x coordinate of the pixel * @param y The y coordinate of the pixel * @param colour The colour of the pixel */ -void GraphicsContext::putPixel(int32_t x, int32_t y, Colour colour) { +void GraphicsContext::put_pixel(int32_t x, int32_t y, Colour colour) { // Convert the colour to an integer and then print it - putPixel(x,y, colourToInt(colour)); + putPixel(x,y, colour_to_int(colour)); } /** - * @details Renders a pixel to the screen + * @brief Renders a pixel to the screen (automatically converts the colour to an integer), will not render the pixel if it is outside the screen * * @param x The x coordinate of the pixel * @param y The y coordinate of the pixel @@ -384,55 +383,55 @@ void GraphicsContext::putPixel(int32_t x, int32_t y, Colour colour) { */ void GraphicsContext::putPixel(int32_t x, int32_t y, int32_t colour) { - if (0 > x || (uint32_t)x >= width) { + if (0 > x || (uint32_t)x >= m_width) { return; } - // Check if the pixel is within the height of the screen - if (0 > y || (uint32_t) y >= height) { + // Check if the pixel is within the m_height of the screen + if (0 > y || (uint32_t) y >= m_height) { return; } // Render the pixel - renderPixel(x, mirrorYAxis ? height-y-1 : y, colour); + render_pixel(x, mirror_y_axis ? m_height - y - 1 : y, colour); } /** - * @details Gets the colour of a pixel + * @brief Gets the colour of a pixel, or returns black if the pixel is outside the screen * * @param x The x coordinate of the pixel * @param y The y coordinate of the pixel - * @return The colour of the pixel + * @return The colour of the pixel or black if the pixel is outside the screen */ -Colour GraphicsContext::getPixel(int32_t x, int32_t y) { +Colour GraphicsContext::get_pixel(int32_t x, int32_t y) { - // Check if the pixel is within the width of the screen - if (0 > x || (uint32_t)x >= width) { + // Check if the pixel is within the m_width of the screen + if (0 > x || (uint32_t)x >= m_width) { return Colour(0,0,0); } - // Check if the pixel is within the height of the screen - if (0 > y || (uint32_t) y >= height) { + // Check if the pixel is within the m_height of the screen + if (0 > y || (uint32_t) y >= m_height) { return Colour(0,0,0); } // Get the pixel and convert it to a colour - uint32_t translatedColor = getRenderedPixel(x, mirrorYAxis ? height-y-1 : y); - return intToColour(translatedColor); + uint32_t translated_color = get_rendered_pixel(x, mirror_y_axis ? m_height - y - 1 : y); + return int_to_colour(translated_color); } /** - * @details Inverts a pixel + * @brief Inverts a pixel * * @param x The x coordinate of the pixel * @param y The y coordinate of the pixel */ -void GraphicsContext::invertPixel(int32_t x, int32_t y) { +void GraphicsContext::invert_pixel(int32_t x, int32_t y) { // Get the pixel - Colour colour = getPixel(x,y); + Colour colour = get_pixel(x, y); // Invert the pixel colour.red = 255 - colour.red; @@ -440,85 +439,86 @@ void GraphicsContext::invertPixel(int32_t x, int32_t y) { colour.blue = 255 - colour.blue; // Render the pixel - putPixel(x,y,colour); + put_pixel(x, y, colour); } /** - * @details Draws a line on the screen + * @brief Draws a line on the screen * - * @param x0 The x coordinate of the first point - * @param y0 The y coordinate of the first point + * @param x0 The x coordinate of the m_first_memory_chunk point + * @param y0 The y coordinate of the m_first_memory_chunk point * @param x1 The x coordinate of the final point * @param y1 The y coordinate of the final point * @param colour The colour of the line */ -void GraphicsContext::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, Colour colour) { - drawLine(x0,y0,x1,y1,colourToInt(colour)); +void GraphicsContext::draw_line(int32_t x0, int32_t y0, int32_t x1, int32_t y1, Colour colour) { + drawLine(x0,y0,x1,y1, colour_to_int(colour)); } /** - * @details Draws a line on the screen + * @brief Draws a line on the screen * - * @param x0 The x coordinate of the first point - * @param y0 The y coordinate of the first point + * @param x0 The x coordinate of the m_first_memory_chunk point + * @param y0 The y coordinate of the m_first_memory_chunk point * @param x1 The x coordinate of the final point * @param y1 The y coordinate of the final point * @param colour The colour of the line */ void GraphicsContext::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t colour) { - // Store the minimum and maximum y values by checking which one is larger/smaller - bool y0IsSmaller = y0 < y1; - int32_t yMin = y0IsSmaller ? y0 : y1; - int32_t yMax = y0IsSmaller ? y1 : y0; + // Store the minimum and maximum y values + bool y_0_is_smaller = y0 < y1; + int32_t y_min = y_0_is_smaller ? y0 : y1; + int32_t y_max = y_0_is_smaller ? y1 : y0; - // If x1 is smaller than x0, reverse the points to draw from left to right + //Reverse the points to draw from left to right if(x1 < x0){ drawLine(x1,y1,x0,y0,colour); return; } - // If the line is vertical, draw it + // Vertical line if(x1 == x0) { // Force the line to be within the screen - if(yMin < 0) yMin = 0; - if((uint32_t)yMax >= height) yMax = height - 1; + if(y_min < 0) y_min = 0; + if((uint32_t)y_max >= m_height) + y_max = m_height - 1; - // Mirror the Y axis as directly calling putPixel will not do this - if(mirrorYAxis) + // Mirror the Y axis as directly calling put_pixel will not do this + if(mirror_y_axis) { - int32_t temp = yMax; - yMax = height - yMin - 1; - yMin = height - temp - 1; + int32_t temp = y_max; + y_max = m_height - y_min - 1; + y_min = m_height - temp - 1; } // Check that the line is within the screen - if (0 > x0 || (uint32_t) x0 >= width) { + if (0 > x0 || (uint32_t) x0 >= m_width) { return; } // Draw the line - for(int32_t y = yMin; y <= yMax; ++y) + for(int32_t y = y_min; y <= y_max; ++y) putPixel(x0, y, colour); return; } - // If the line is horizontal, draw it + // Horizontal line if(y1 == y0) { // Ensure the line is within the screen if(x0 < 0) x0 = 0; - if((uint32_t)x1 >= width) x1 = width-1; + if((uint32_t)x1 >= m_width) x1 = m_width -1; - // Mirror the Y axis as directly calling putPixel will not do this - if(mirrorYAxis) - y0 = height-y0-1; + // Mirror the Y axis as directly calling put_pixel will not do this + if(mirror_y_axis) + y0 = m_height -y0-1; // Check that the line is within the screen - if (0 > y0 || (uint32_t) y0 >= height) + if (0 > y0 || (uint32_t) y0 >= m_height) return; // Draw the line @@ -528,39 +528,30 @@ void GraphicsContext::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, u // If the line is not horizontal or vertical then it must be a diagonal line // Find the slope of the line - float slope = ((float)(y1-y0))/(x1-x0); // Change in y over change in x + float slope = ((float)(y1-y0))/(x1-x0); - // If the line is more horizontal than vertical, increment x by 1 and increment y by the slope + // A slope that is more horizontal should be drawn by incrementing x if(-1 <= slope && slope <= 1) { - // Start at minimum y and increment y by the slope float y = y0; - - // Start at minimum x and increment x by 1 for(int32_t x = x0; x <= x1; x++, y+=slope) putPixel(x, (int32_t)y, colour); } - // If the line is more vertical than horizontal, increment y by 1 and increment x by the inverse of the slope + // A slope that is more vertical should be drawn by incrementing y else { // Invert the slope slope = 1.0f/slope; - // Start at minimum x and increment x by the inverse of the slope float x = x0; - - // Start at minimum y and increment y by 1 - for(int32_t y = yMin; y <= yMax; x+=slope, y++) + for(int32_t y = y_min; y <= y_max; x+=slope, y++) putPixel((int32_t)x, y, colour); } - - - } /** - * @details Draws a rectangle on the screen + * @brief Draws a rectangle on the screen * * @param x0 The x coordinate of the top left corner * @param y0 The y coordinate of the top left corner @@ -568,13 +559,13 @@ void GraphicsContext::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, u * @param y1 The y coordinate of the bottom right corner * @param colour The colour of the rectangle */ -void GraphicsContext::drawRectangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, Colour colour) { - drawRectangle(x0,y0,x1,y1,colourToInt(colour)); +void GraphicsContext::draw_rectangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, Colour colour) { + draw_rectangle(x0, y0, x1, y1, colour_to_int(colour)); } /** - * @details Draws a rectangle on the screen + * @brief Draws a rectangle on the screen * * @param x0 The x coordinate of the top left corner * @param y0 The y coordinate of the top left corner @@ -582,7 +573,7 @@ void GraphicsContext::drawRectangle(int32_t x0, int32_t y0, int32_t x1, int32_t * @param y1 The y coordinate of the bottom right corner * @param colour The colour of the rectangle */ -void GraphicsContext::drawRectangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t colour) { +void GraphicsContext::draw_rectangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t colour) { // Ensure x and y 0 is smaller than x and y 1 --y0; @@ -597,7 +588,7 @@ void GraphicsContext::drawRectangle(int32_t x0, int32_t y0, int32_t x1, int32_t } /** - * @details Draws a rectangle on the screen, filled with a colour + * @brief Draws a rectangle on the screen, filled with a colour * * @param x0 The x coordinate of the top left corner * @param y0 The y coordinate of the top left corner @@ -605,12 +596,12 @@ void GraphicsContext::drawRectangle(int32_t x0, int32_t y0, int32_t x1, int32_t * @param y1 The y coordinate of the bottom right corner * @param colour The colour of the rectangle */ -void GraphicsContext::fillRectangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, Colour colour) { - fillRectangle(x0,y0,x1,y1,colourToInt(colour)); +void GraphicsContext::fill_rectangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, Colour colour) { + fill_rectangle(x0, y0, x1, y1, colour_to_int(colour)); } /** - * @details Draws a rectangle on the screen, filled with a colour + * @brief Draws a rectangle on the screen, filled with a colour * * @param x0 The x coordinate of the top left corner * @param y0 The y coordinate of the top left corner @@ -618,37 +609,38 @@ void GraphicsContext::fillRectangle(int32_t x0, int32_t y0, int32_t x1, int32_t * @param y1 The y coordinate of the bottom right corner * @param colour The colour of the rectangle */ -void GraphicsContext::fillRectangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t colour) { +void GraphicsContext::fill_rectangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t colour) { // Draw from left to right if(y1 < y0){ - fillRectangle(x1,y1,x0,y0,colour); + fill_rectangle(x1, y1, x0, y0, colour); return; } // Make sure the rectangle is within the height of the screen if(y0 < 0) y0 = 0; - if((uint32_t)y1 > height) y1 = height; + if((uint32_t)y1 > m_height) y1 = m_height; // Make sure the rectangle is within the width of the screen - bool x0IsSmaller = x0 < x1; - int32_t xMin = x0IsSmaller ? x0 : x1; - int32_t xMax = x0IsSmaller ? x1 : x0; + bool x_0_is_smaller = x0 < x1; + int32_t x_min = x_0_is_smaller ? x0 : x1; + int32_t x_max = x_0_is_smaller ? x1 : x0; - if(xMin < 0) xMin = 0; - if((uint32_t)xMax > width) xMax = width; + if(x_min < 0) x_min = 0; + if((uint32_t)x_max > m_width) + x_max = m_width; - // Mirror the Y axis as directly calling putPixel will not do this - if(mirrorYAxis) + // Mirror the Y axis as directly calling put_pixel will not do this + if(mirror_y_axis) { - uint32_t temp = y1; // Store the maximum y value - y1 = height - y0 - 1; // Set the maximum y value to the minimum y value - y0 = height - temp - 1; // Set the minimum y value to the maximum y value + uint32_t temp = y1; + y1 = m_height - y0 - 1; + y0 = m_height - temp - 1; } // Draw the rectangle for(int32_t y = y0; y < y1; ++y){ - for (int32_t x = xMin; x < xMax; ++x) { + for (int32_t x = x_min; x < x_max; ++x) { putPixel(x, y, colour); } } @@ -656,38 +648,37 @@ void GraphicsContext::fillRectangle(int32_t x0, int32_t y0, int32_t x1, int32_t } /** - * @details Draws a circle on the screen + * @brief Draws a circle on the screen * * @param x0 The x coordinate of the centre of the circle * @param y0 The y coordinate of the centre of the circle * @param radius The radius of the circle * @param colour The colour of the circle */ -void GraphicsContext::drawCircle(int32_t x0, int32_t y0, int32_t radius, Colour colour){ - drawCircle(x0,y0,radius,colourToInt(colour)); +void GraphicsContext::draw_circle(int32_t x0, int32_t y0, int32_t radius, Colour colour){ + draw_circle(x0, y0, radius, colour_to_int(colour)); } /** - * @details Draws a circle on the screen + * @brief Draws a circle on the screen * * @param x0 The x coordinate of the centre of the circle * @param y0 The y coordinate of the centre of the circle * @param radius The radius of the circle * @param colour The colour of the circle */ -void GraphicsContext::drawCircle(int32_t x0, int32_t y0, int32_t radius, uint32_t colour) { +void GraphicsContext::draw_circle(int32_t x0, int32_t y0, int32_t radius, uint32_t colour) { // Make sure the circle is with in the width and height of the screen if(x0 < 0) x0 = 0; - if((uint32_t)x0 > width) x0 = width; + if((uint32_t)x0 > m_width) x0 = m_width; if(y0 < 0) y0 = 0; - if((uint32_t)y0 > height) y0 = height; + if((uint32_t)y0 > m_height) y0 = m_height; - // Mirror the Y axis as directly calling putPixel will not do this - if(mirrorYAxis) - y0 = height-y0-1; + // Mirror the Y axis as directly calling put_pixel will not do this + if(mirror_y_axis) + y0 = m_height -y0-1; - // Draw the circle // Begin drawing at the left most point of the circle and draw a line to the right most point of the circle for(int32_t x = -radius; x <= radius; ++x){ @@ -705,20 +696,20 @@ void GraphicsContext::drawCircle(int32_t x0, int32_t y0, int32_t radius, uint32_ } /** - * @details Draws a circle on the screen, filled with a colour + * @brief Draws a circle on the screen, filled with a colour * * @param x0 The x coordinate of the centre of the circle * @param y0 The y coordinate of the centre of the circle * @param radius The radius of the circle * @param colour The colour of the circle */ -void GraphicsContext::fillCircle(int32_t x0, int32_t y0, int32_t radius, Colour colour) { - fillCircle(x0,y0,radius,colourToInt(colour)); +void GraphicsContext::fill_circle(int32_t x0, int32_t y0, int32_t radius, Colour colour) { + fillCircle(x0,y0,radius, colour_to_int(colour)); } /** - * @details Draws a circle on the screen, filled with a colour + * @brief Draws a circle on the screen, filled with a colour * * @param x0 The x coordinate of the centre of the circle * @param y0 The y coordinate of the centre of the circle @@ -729,13 +720,13 @@ void GraphicsContext::fillCircle(int32_t x0, int32_t y0, int32_t radius, uint32_ // Make sure the circle is with in the width and height of the screen if(x0 < 0) x0 = 0; - if((uint32_t)x0 > width) x0 = width; + if((uint32_t)x0 > m_width) x0 = m_width; if(y0 < 0) y0 = 0; - if((uint32_t)y0 > height) y0 = height; + if((uint32_t)y0 > m_height) y0 = m_height; - // Mirror the Y axis as directly calling putPixel will not do this - if(mirrorYAxis) - y0 = height-y0-1; + // Mirror the Y axis as directly calling put_pixel will not do this + if(mirror_y_axis) + y0 = m_height -y0-1; // Draw the circle @@ -750,5 +741,4 @@ void GraphicsContext::fillCircle(int32_t x0, int32_t y0, int32_t radius, uint32_ putPixel(x0+x,y0+y,colour); } } - } \ No newline at end of file diff --git a/kernel/src/common/inputStream.cpp b/kernel/src/common/inputStream.cpp index ab194e56..17545533 100644 --- a/kernel/src/common/inputStream.cpp +++ b/kernel/src/common/inputStream.cpp @@ -7,7 +7,8 @@ using namespace maxOS; using namespace maxOS::common; -InputStream::InputStream(InputStreamEventHandler *inputStreamEventHandler) -: GenericInputStream::GenericInputStream(inputStreamEventHandler) { +InputStream::InputStream(InputStreamEventHandler *input_stream_event_handler) +: GenericInputStream::GenericInputStream( + input_stream_event_handler) { } diff --git a/kernel/src/common/outputStream.cpp b/kernel/src/common/outputStream.cpp index b6b7c9a2..c84dac52 100644 --- a/kernel/src/common/outputStream.cpp +++ b/kernel/src/common/outputStream.cpp @@ -18,55 +18,55 @@ OutputStream::~OutputStream() { } /** - * @details Writes a newline to the output stream. + * @brief Writes a newline to the output stream. */ void OutputStream::lineFeed() { - // Write the text representation of a newline to the output stream. - writeChar('\n'); + // write the text representation of a newline to the output stream. + write_char('\n'); } /** - * @details Writes a carriage return to the output stream. + * @brief Writes a carriage return to the output stream. */ void OutputStream::carriageReturn() { - // Write the text representation of a carriage return to the output stream. - writeChar('\r'); + // write the text representation of a carriage return to the output stream. + write_char('\r'); } /** - * @details Clears the output stream. + * @brief Clears the output stream. */ void OutputStream::clear() { } /** - * @details Writes a string to the output stream. - * @param stringToWrite The string to write to the output stream. + * @brief Writes a string to the output stream. + * @param string_to_write The string to write to the output stream. */ -void OutputStream::write(string stringToWrite) { +void OutputStream::write(string string_to_write) { // Loop until broken while (true) { // Switch on the current character - switch (*stringToWrite) { + switch (*string_to_write) { // If the current character is a newline case '\n': - // Write a newline to the output stream + // write a newline to the output stream lineFeed(); break; // If the current character is a carriage return case '\r': - // Write a carriage return to the output stream + // write a carriage return to the output stream carriageReturn(); break; @@ -77,92 +77,92 @@ void OutputStream::write(string stringToWrite) { // If the current character is any other character default: - // Write the current character to the output stream - writeChar(*stringToWrite); + // write the current character to the output stream + write_char(*string_to_write); break; } // Increment the pointer to the next character - stringToWrite++; + string_to_write++; } } /** - * @details Writes a character to the output stream. - * @param charToWrite The character to write to the output stream. + * @brief Writes a character to the output stream. + * @param char_to_write The character to write to the output stream. */ -void OutputStream::writeChar(char charToWrite) { +void OutputStream::write_char(char char_to_write) { } /** - * @details Writes an integer to the output stream. - * @param intToWrite The integer to write to the output stream. + * @brief Writes an integer to the output stream. + * @param int_to_write The integer to write to the output stream. */ -void OutputStream::writeInt(int intToWrite) { +void OutputStream::write_int(int int_to_write) { // If the integer is 0 then write a 0 to the output stream and return as no more calculations are needed - if (intToWrite == 0) { - writeChar('0'); + if (int_to_write == 0) { + write_char('0'); return; } // Store the int to write in a temporary variable - int tempWriteInt = intToWrite; + int temp_write_int = int_to_write; // If the integer is negative then write a minus sign to the output stream and make the integer positive - bool isNegative = intToWrite <= 0; - if (isNegative) { - writeChar('-'); - tempWriteInt = -tempWriteInt; + bool is_negative = int_to_write <= 0; + if (is_negative) { + write_char('-'); + temp_write_int = -temp_write_int; } // Check how many digits the integer has by dividing it by 10 until it is 0 (rounded automatically) int digits = 0; - int temp = tempWriteInt; // Copy the value to avoid modifying the original + int temp = temp_write_int; // Copy the value to avoid modifying the original do { temp /= 10; digits++; } while (temp != 0); // Loop through each digit of the integer - for (int currentDigit = digits; currentDigit > 0; --currentDigit) { + for (int current_digit = digits; current_digit > 0; --current_digit) { // Calculate the divisor to extract the current digit int divisor = 1; - for (int i = 1; i < currentDigit; i++) { + for (int i = 1; i < current_digit; i++) { divisor *= 10; } // Calculate the current digit - int currentDigitValue = (tempWriteInt / divisor) % 10; + int current_digit_value = (temp_write_int / divisor) % 10; - // Write the current digit to the output stream - writeChar('0' + currentDigitValue); + // write the current digit to the output stream + write_char('0' + current_digit_value); } } /** - * @details Writes a hex to the output stream. + * @brief Writes a hex to the output stream. * @param writeHex The hex to write to the output stream. */ -void OutputStream::writeHex(uint32_t hexToWrite) { +void OutputStream::write_hex(uint32_t hex_to_write) { - // Write the hex prefix to the output stream + // write the hex prefix to the output stream write("0x"); // If the hex is 0 then write a 0 to the output stream and return as no more calculations are needed - if (hexToWrite == 0) { + if (hex_to_write == 0) { write("0"); return; } int length = 0; - unsigned int ibak = hexToWrite; + unsigned int ibak = hex_to_write; while(ibak > 0) { ibak /= 16; @@ -170,66 +170,66 @@ void OutputStream::writeHex(uint32_t hexToWrite) { } for(; length > 0; length--) { - ibak = hexToWrite; + ibak = hex_to_write; for(int j = 1; j < length; j++) ibak /= 16; const string Hex = "0123456789ABCDEF"; - writeChar(Hex[ibak % 16]); + write_char(Hex[ibak % 16]); } } /** - * @details Writes a interger to the output stream. - * @param intToWrite The integer to write to the output stream. + * @brief Writes a interger to the output stream. + * @param int_to_write The integer to write to the output stream. * @return The output stream. */ -OutputStream &OutputStream::operator << (int intToWrite) { +OutputStream &OutputStream::operator << (int int_to_write) { // Call the writeInt function to write the integer to the output stream - writeInt(intToWrite); + write_int(int_to_write); // Return the output stream return *this; } /** - * @details Writes a hexadecimal to the output stream. - * @param hexToWrite The hex to write to the output stream. + * @brief Writes a hexadecimal to the output stream. + * @param hex_to_write The hex to write to the output stream. * @return The output stream. */ -OutputStream &OutputStream::operator << (uint32_t hexToWrite) { +OutputStream &OutputStream::operator << (uint32_t hex_to_write) { - // Call the writeHex function to write the hex to the output stream - writeHex(hexToWrite); + // Call the write_hex function to write the hex to the output stream + write_hex(hex_to_write); // Return the output stream return *this; } /** - * @details Writes a string to the output stream. - * @param stringToWrite The string to write to the output stream. + * @brief Writes a string to the output stream. + * @param string_to_write The string to write to the output stream. * @return The output stream. */ -OutputStream &OutputStream::operator << (string stringToWrite) { +OutputStream &OutputStream::operator << (string string_to_write) { // Call the write function to write the string to the output stream - write(stringToWrite); + write(string_to_write); // Return the output stream return *this; } /** - * @details Writes a character to the output stream. - * @param charToWrite The character to write to the output stream. + * @brief Writes a character to the output stream. + * @param char_to_write The character to write to the output stream. * @return The output stream. */ -OutputStream &OutputStream::operator<<(char charToWrite) { +OutputStream &OutputStream::operator<<(char char_to_write) { // Call the writeChar function to write the character to the output stream - writeChar(charToWrite); + write_char(char_to_write); // Return the output stream return *this; diff --git a/kernel/src/drivers/ata.cpp b/kernel/src/drivers/ata.cpp index 681eb89c..b53fe98f 100644 --- a/kernel/src/drivers/ata.cpp +++ b/kernel/src/drivers/ata.cpp @@ -9,20 +9,20 @@ using namespace maxOS::common; using namespace maxOS::hardwarecommunication; using namespace maxOS::drivers; -AdvancedTechnologyAttachment::AdvancedTechnologyAttachment(uint16_t portBase, bool master, OutputStream* ataMessageStream) -: dataPort(portBase), - errorPort(portBase + 1), - sectorCountPort(portBase + 2), - LBAlowPort(portBase + 3), - LBAmidPort(portBase + 4), - LBAHiPort(portBase + 5), - devicePort(portBase + 6), - commandPort(portBase + 7), - controlPort(portBase + 0x206) +AdvancedTechnologyAttachment::AdvancedTechnologyAttachment(uint16_t port_base, bool master, OutputStream*output_stream) +: m_data_port(port_base), + m_error_port(port_base + 1), + m_sector_count_port(port_base + 2), + m_LBA_low_port(port_base + 3), + m_LBA_mid_port(port_base + 4), + m_LBA_high_Port(port_base + 5), + m_device_port(port_base + 6), + m_command_port(port_base + 7), + m_control_port(port_base + 0x206), + m_is_master(master), + ata_message_stream(output_stream) { - bytesPerSector = 512; - this -> master = master; - this -> ataMessageStream = ataMessageStream; + } AdvancedTechnologyAttachment::~AdvancedTechnologyAttachment() { @@ -30,226 +30,184 @@ AdvancedTechnologyAttachment::~AdvancedTechnologyAttachment() { } /** - * @details This function Identifiers the ATA device + * @brief Identify the ATA device */ -void AdvancedTechnologyAttachment::Identify() { - - devicePort.Write(master ? 0xA0 : 0xB0); //Select Device Master(0xA0) / Slave(0xB0) - controlPort.Write(0); //Clear HOB bit (HOB : Set this to read back the High Order Byte of the last LBA48 value sent to an IO port.) - - //Floating Bus check : First you select the master, then read in the value of the status register and then compare it with 0xFF (is an invalid status value). - devicePort.Write(0xA0); //Select Master (0xA0) - uint8_t status = commandPort.Read(); //Read Status - if(status == 0xFF){ //IF status is 0xFF then there is no device - ataMessageStream -> write("Invalid Status"); - return; //Return, beacuse if there is no master then there wont be a slave either - } - - devicePort.Write(master ? 0xA0 : 0xB0); //Select Device Master(0xA0) / Slave(0xB0) - sectorCountPort.Write(0); //Sector Doesn't Matter when Identifying so select sec 0 - LBAlowPort.Write(0); //Same here - LBAmidPort.Write(0); //Same here - LBAHiPort.Write(0); //Same here - commandPort.Write(0x0EC); //Command For Identifying - - status = commandPort.Read(); //Read Status - if(status == 0x00){ //IF status is 0x00 then there is no device - ataMessageStream -> write("No Device"); - return; //There is no slave/master - } - - //Can take a while for there to be an answer to the identify command, - while ( - ((status & 0x80) == 0x80) //Device is busy - && - ((status & 0x01) != 0x01) //There was an error - ) - { - status = commandPort.Read(); - } - - //Check for any errors - if(status & 0x01){ - - ataMessageStream -> write("ERROR"); - return; - - } - - //We are reading 2 bytes from data port so , it will be 256 , so total bytes read are 512 (512 is bytes per sector) - bool stopPrint = false; - for (uint16_t i = 0; i < 256; ++i) { - - uint16_t data = dataPort.Read(); - char *text = " \0"; - text[0] = (data >> 8) & 0xFF; - text[1] = data & 0xFF; - if(text[0] == 'K'){ - ataMessageStream -> write(text); - stopPrint = true; //Stop the messed up text from showing - } - - if(!stopPrint) ataMessageStream -> write(text); - - } - - +void AdvancedTechnologyAttachment::identify() { + + // Select the device (master or slave) + m_device_port.write(m_is_master ? 0xA0 : 0xB0); + + // Reset the HOB (High Order Byte) + m_control_port.write(0); + + // Check if the master is present + m_device_port.write(0xA0); + uint8_t status = m_command_port.read(); + if(status == 0xFF){ + ata_message_stream-> write("Invalid Status"); + return; + } + + // Select the device (master or slave) + m_device_port.write(m_is_master ? 0xA0 : 0xB0); + + // Clear the ports + m_sector_count_port.write(0); + m_LBA_low_port.write(0); + m_LBA_mid_port.write(0); + m_LBA_high_Port.write(0); + + // Send the identify command + m_command_port.write(0x0EC); + + // Check if the device is present + status = m_command_port.read(); + if(status == 0x00) + return; + + // Wait for the device to be ready or for an error to occur + while (((status & 0x80) == 0x80) && ((status & 0x01) != 0x01)) + status = m_command_port.read(); + + //Check for any errors + if(status & 0x01){ + ata_message_stream-> write("ERROR"); + return; + } + + // read the data and print it + for (uint16_t i = 0; i < 256; ++i) { + uint16_t data = m_data_port.read(); + char *text = " \0"; + text[0] = (data >> 8) & 0xFF; + text[1] = data & 0xFF; + ata_message_stream-> write(text); + } } /** - * @details This function reads a sector from the ATA device + * @brief read a sector from the ATA device * * @param sector The sector to read * @param data The data to read into * @param count The amount of data to read from that sector */ - -void AdvancedTechnologyAttachment::Read28(uint32_t sector, uint8_t* data, int count) +void AdvancedTechnologyAttachment::read_28(uint32_t sector, uint8_t* data, int count) { - //Dont Allow reading More then a sector - if(sector & 0xF0000000) - return; - if(count > bytesPerSector) + // Don't allow reading more then a sector + if(sector & 0xF0000000 || count > m_bytes_per_sector) return; - devicePort.Write((master ? 0xE0 : 0xF0) | ((sector & 0x0F000000) >> 24)); - errorPort.Write(0); - sectorCountPort.Write(1); - + // Select the device (master or slave) and reset it + m_device_port.write((m_is_master ? 0xE0 : 0xF0) | + ((sector & 0x0F000000) >> 24)); + m_error_port.write(0); + m_sector_count_port.write(1); - LBAlowPort.Write( sector & 0x000000FF ); //Split the sector into the port (put the low 8 bits ito this port) - LBAmidPort.Write( (sector & 0x0000FF00) >> 8); //Split the sector into the port (put the mid 8 bits ito this port) - LBAHiPort.Write( (sector & 0x00FF0000) >> 16); //Split the sector into the port (put the hi 8 bits ito this port) - commandPort.Write(0x20); //Command For Reading + // Split the sector into the ports + m_LBA_low_port.write(sector & 0x000000FF); + m_LBA_mid_port.write((sector & 0x0000FF00) >> 8); + m_LBA_high_Port.write((sector & 0x00FF0000) >> 16); + // Send the read command + m_command_port.write(0x20); + // Make sure the device is there + uint8_t status = m_command_port.read(); + if(status == 0x00) + return; - - uint8_t status = commandPort.Read(); //Read Status - if(status == 0x00){ //IF status is 0x00 then there is no device - ataMessageStream -> write("No Device"); - return; //There is no slave/master - } - - //Can take a while for the disk to be fully read - while(((status & 0x80) == 0x80) - && ((status & 0x01) != 0x01)) - status = commandPort.Read(); + // Wait for the device to be ready or for an error to occur + while(((status & 0x80) == 0x80) && ((status & 0x01) != 0x01)) + status = m_command_port.read(); //Check for any errors - if(status & 0x01){ + if(status & 0x01) return; - } - - //We are reading 2 bytes to the data port so , it will be 256 , so has to be incremented by 2 + // read the data and store it in the array for(uint16_t i = 0; i < count; i+= 2) { - uint16_t readData = dataPort.Read(); - - /* - string foo = " \0"; - foo[1] = (readData >> 8) & 0x00FF; - foo[0] = readData & 0x00FF; - printf(foo); - */ + uint16_t read_data = m_data_port.read(); - //Place into the data array - data[i] = readData & 0x00FF; + data[i] = read_data & 0x00FF; - //If we are not at the end of the array, place the next byte into the array as it is incremented by 2 each loop + // Place the next byte in the array if there is one if(i+1 < count) - data[i+1] = (readData >> 8) & 0x00FF; + data[i+1] = (read_data >> 8) & 0x00FF; } - //Hard Drive must have a full sector read, even if the data isnt the size of a full sector - for(uint16_t i = count + (count % 2); i < bytesPerSector; i+= 2) - dataPort.Read(); + // read the remaining bytes + for(uint16_t i = count + (count % 2); i < m_bytes_per_sector; i+= 2) + m_data_port.read(); } /** - * @details This function writes a sector to the ATA device + * @brief write to a sector on the ATA device * * @param sector The sector to write to * @param count The amount of data to write to that sector */ -void AdvancedTechnologyAttachment::Write28(uint32_t sector, uint8_t* data, int count){ +void AdvancedTechnologyAttachment::write_28(uint32_t sector, uint8_t* data, int count){ - //Don't Allow Writing More then a sector - if(sector > 0x0FFFFFFF) + // Don't allow writing more then a sector + if(sector > 0x0FFFFFFF || count > m_bytes_per_sector) return; - if(count > 512) - return; - + // Select the device (master or slave) and reset it + m_device_port.write(m_is_master ? 0xE0 + : 0xF0 | ((sector & 0x0F000000) >> 24)); + m_error_port.write(0); + m_sector_count_port.write(1); - devicePort.Write(master ? 0xE0 : 0xF0 | ((sector & 0x0F000000) >> 24) ); //Select Device Master(0xE0) / Slave(0xF0), and add spare bits - errorPort.Write(0); //Clear Previous Errors - sectorCountPort.Write(1); // For now only read/write a single sector TODO: Fix this + // Split the sector into the ports + m_LBA_low_port.write(sector & 0x000000FF); + m_LBA_mid_port.write((sector & 0x0000FF00) >> 8); + m_LBA_high_Port.write((sector & 0x00FF0000) >> 16); + // Send the write command + m_command_port.write(0x30); - LBAlowPort.Write( sector & 0x000000FF ); //Split the sector into the port (put the low 8 bits ito this port) - LBAmidPort.Write( (sector & 0x0000FF00) >> 8); //Split the sector into the port (put the mid 8 bits ito this port) - LBAHiPort.Write( (sector & 0x00FF0000) >> 16); //Split the sector into the port (put the hi 8 bits ito this port) - commandPort.Write(0x30); //Command For Writing + // write the data to the device + for (uint16_t i = 0; i < m_bytes_per_sector; i+= 2) { - ataMessageStream -> write("Writing to ATA: "); + uint16_t writeData = data[i]; + // Place the next byte in the array if there is one + if(i+1 < count) + writeData |= ((uint16_t)data[i+1]) << 8; - //We are write 2 bytes to the data port so , it will be 256 , so has to be incremented by 2 - for (uint16_t i = 0; i < bytesPerSector ; i+= 2) { - - uint16_t writeData = data[i]; //Get the i'th byte from the data - if(i+1 < count) //Check if next byte is there also - writeData |= ((uint16_t)data[i+1]) << 8; //Write that byte - dataPort.Write(writeData); //Write the data - char *text = " \0"; - text[1] = (writeData >> 8) & 0xFF; - text[0] = writeData & 0xFF; - - if(i < count) //Prevent random shit from throwing up on my screen - ataMessageStream -> write(text); + m_data_port.write(writeData); } - //Hard Drive must have a full sector written, even if the data isnt the size of a full sector - for(int i = count + (count%2); i < bytesPerSector; i += 2) //If count isnt an even number then it would have already had it's byte written - dataPort.Write(0x0000); - + // write the remaining bytes + for(int i = count + (count%2); i < m_bytes_per_sector; i += 2) + m_data_port.write(0x0000); } /** - * @details Flush the ATA device + * @brief Flush the cache of the ATA device */ -void AdvancedTechnologyAttachment::Flush() { +void AdvancedTechnologyAttachment::flush() { - devicePort.Write(master ? 0xE0 : 0xF0); //Select Device Master(0xE0) / Slave(0xF0) + // Select the device (master or slave) + m_device_port.write(m_is_master ? 0xE0 : 0xF0); - commandPort.Write(0xE7); //Command For Flushing + // Send the flush command + m_command_port.write(0xE7); - uint8_t status = commandPort.Read(); //Read Status - if(status == 0x00){ //IF status is 0x00 then there is no device - ataMessageStream -> write("No Device"); - return; //There is no slave/master - } + // Make sure the device is there + uint8_t status = m_command_port.read(); + if(status == 0x00) + return; - //Can take a while for there to be an answer to the flush command, - while ( - ((status & 0x80) == 0x80) //Device is busy - && - ((status & 0x01) != 0x01) //There was an error - ) - { - status = commandPort.Read(); - } - //Check for any errors - if(status & 0x01){ + // Wait for the device to be ready or for an error to occur + while (((status & 0x80) == 0x80) && ((status & 0x01) != 0x01)) + status = m_command_port.read(); - ataMessageStream -> write("ERROR"); - return; - - } + if(status & 0x01) + return; - //Flush complete } diff --git a/kernel/src/drivers/clock/clock.cpp b/kernel/src/drivers/clock/clock.cpp index 3ea67839..62373372 100644 --- a/kernel/src/drivers/clock/clock.cpp +++ b/kernel/src/drivers/clock/clock.cpp @@ -20,19 +20,19 @@ ClockEventHandler::~ClockEventHandler() { } /** - * @details Called when the clock ticks + * @brief Called when the clock ticks * @param time The current time * */ -void ClockEventHandler::onTime(const Time &time) { +void ClockEventHandler::on_time(common::Time const &time) { } -Event* ClockEventHandler::onEvent(Event* event) { +Event* ClockEventHandler::on_event(Event* event) { switch (event -> type) { case TIME: - onTime(*((TimeEvent*)event) -> time); + on_time(*((TimeEvent *)event)->time); break; default: @@ -46,21 +46,18 @@ Event* ClockEventHandler::onEvent(Event* event) { ///__Clock__ /** - * @details Constructor for the Clock class + * @brief Constructor for the Clock class * - * @param interruptManager The interrupt manager - * @param timeBetweenEvents The time between events in 10ths of a second + * @param interrupt_manager The interrupt manager + * @param time_between_events The time between events in 10ths of a second */ -Clock::Clock(InterruptManager *interruptManager, uint16_t timeBetweenEvents) +Clock::Clock(InterruptManager *interrupt_manager, uint16_t time_between_events) : Driver(), - InterruptHandler(interruptManager -> HardwareInterruptOffset(), interruptManager), - dataPort(0x71), - commandPort(0x70) + InterruptHandler(interrupt_manager->hardware_interrupt_offset(), interrupt_manager), + m_data_port(0x71), m_command_port(0x70), + m_ticks_between_events(time_between_events) { - // Set the default values - ticks = 0; - ticksBetweenEvents = timeBetweenEvents; - ticksUntilNextEvent = 1; + } Clock::~Clock() { @@ -68,139 +65,142 @@ Clock::~Clock() { } /** - * @details Handle the RTC interrupt, It increments the number of ticks and calls the event clockEventHandlers if the number of ticks is equal to the number of ticks between events - * @param esp The stack pointer + * @brief Handle the RTC interrupt, raising the clock event if enough time has passed + * */ -void Clock::HandleInterrupt() { +void Clock::handle_interrupt() { // Increment the number of ticks and decrement the number of ticks until the next event - ticks++; - ticksUntilNextEvent--; + m_ticks++; + m_ticks_until_next_event--; // If the number of ticks until the next event is not 0 then return - if(ticksUntilNextEvent != 0) + if(m_ticks_until_next_event != 0) return; // Otherwise, reset the number of ticks until the next event - ticksUntilNextEvent = ticksBetweenEvents; + m_ticks_until_next_event = m_ticks_between_events; // Create a time object Time time; - // Read the time from the hardware clock - time.year = binaryRepresentation(readHardwareClock(0x9)) + 2000; // Register 9 is the year - time.month = binaryRepresentation(readHardwareClock(0x8)); // Register 8 is the month - time.day = binaryRepresentation(readHardwareClock(0x7)); // Register 7 is the day - time.hour = binaryRepresentation(readHardwareClock(0x4)); // Register 4 is the hour - time.minute = binaryRepresentation(readHardwareClock(0x2)); // Register 2 is the minute - time.second = binaryRepresentation(readHardwareClock(0x0)); // Register 0 is the second + // read the time from the hardware clock + time.year = binary_representation(read_hardware_clock(0x9)) + 2000; // Register 9 is the year + time.month = binary_representation(read_hardware_clock(0x8)); // Register 8 is the month + time.day = binary_representation(read_hardware_clock(0x7)); // Register 7 is the day + time.hour = binary_representation(read_hardware_clock(0x4)); // Register 4 is the hour + time.minute = binary_representation(read_hardware_clock(0x2)); // Register 2 is the minute + time.second = binary_representation( +read_hardware_clock(0x0)); // Register 0 is the second //Raise the clock event TimeEvent* event = new TimeEvent(&time); - raiseEvent(event); + raise_event(event); //TODO: delete event; } /** - * @details read the current time from the hardware clock and return it + * @brief read the current time from the hardware clock and return it * * @param address The address of the register to read from * @return The value of the register */ -uint8_t Clock::readHardwareClock(uint8_t address) +uint8_t Clock::read_hardware_clock(uint8_t address) { - // Check if address is for a time or date register (address < 10), and disable updates to ensure accurate value is read. + // If the address is a time or date register, disable updates if(address < 10) { - // If the address is for a time or date register, disable updates - commandPort.Write(0xa); + m_command_port.write(0xa); // Wait until any updates are finished - while((dataPort.Read() & (1 << 7)) != 0) + while((m_data_port.read() & (1 << 7)) != 0) asm volatile("nop"); // execute the "nop" assembly instruction, which does nothing, but prevents the compiler from optimizing away the loop } - // Send the address to the hardware clock's command port - commandPort.Write(address); + // Send the address to the hardware clock + m_command_port.write(address); - // Read the value from the hardware clock's data port and return it - return dataPort.Read(); + // read the value from the hardware clock + return m_data_port.read(); } /** - * @details The binary representation of a number, if the binary coded decimal representation is used + * @brief The binary representation of a number + * * @param number The number to convert - * @return The binary representation of the number or the number itself if the binary coded decimal representation is not used + * @return The binary representation of the number if the binary coded decimal representation is used, otherwise the number */ -uint8_t Clock::binaryRepresentation(uint8_t number) { +uint8_t Clock::binary_representation(uint8_t number) { // If the binary coded decimal representation is not used, return the number - if(!binaryCodedDecimalRepresentation) + if(!m_binary_coded_decimal_representation) return number; // Otherwise, return the binary representation - return (number & 0xf) + ((number >> 4) & 0xf) * 10; // And the number with 0xf to get the last 4 bits, then shift it 4 bits to the right and do the same thing + return (number & 0xf) + ((number >> 4) & 0xf) * 10; } /** - * @details Activates the clock, reading the status register and setting the binary coded decimal representation flag + * @brief Activates the clock, setting the binary coded decimal representation flag */ void Clock::activate() { - // Read the status register - uint8_t status = readHardwareClock(0xb); + // read the status register + uint8_t status = read_hardware_clock(0xb); // If the fourth bit is 0 the binary coded decimal representation is used - bool useBinaryCodedDecimal = (status & 4) == 0; - + m_binary_coded_decimal_representation = (status & 4) == 0; // Convert status to binary // 00001011 = 0x0B (status as an example) // 00000100 = 0x04 (binary mask used to extract fourth bit) // 00000000 = 0x00 (result of bitwise AND operation with binary mask) // 00000000 == 0 (check if fourth bit is 0 to determine if BCD is used) - - - // If the binary coded decimal representation is used, set the binary coded decimal representation flag - binaryCodedDecimalRepresentation = useBinaryCodedDecimal; } /** - * @details Delays the program for a specified number of milliseconds (rounded to the nearest 100) by waiting for the number of ticks to equal the number of ticks until the delay is over + * @brief Delays the program for a specified number of milliseconds (rounded to the nearest 100) * * @param milliseconds How many milliseconds to delay the program for */ void Clock::delay(uint32_t milliseconds) { // Round the number of milliseconds to the nearest 100 - uint64_t roundedMilliseconds = ((milliseconds+99)/100); + uint64_t rounded_milliseconds = ((milliseconds+99)/100); // Calculate the number of ticks until the delay is over - uint64_t ticksUntilDelayIsOver = ticks + roundedMilliseconds; + uint64_t ticks_until_delay_is_over = m_ticks + rounded_milliseconds; // Wait until the number of ticks is equal to the number of ticks until the delay is over - while(ticks < ticksUntilDelayIsOver) + while(m_ticks < ticks_until_delay_is_over) asm volatile("nop"); // execute the "nop" assembly instruction, which does nothing, but prevents the compiler from optimizing away the loop } -string Clock::getVendorName() { +/** + * @brief Gets the name of the vendor + * @return The name of the vendor + */ +string Clock::get_vendor_name() { return "Generic"; } -string Clock::getDeviceName() { +/** + * @brief Gets the name of the device + * @return The name of the device + */ +string Clock::get_device_name() { return "Clock"; } - - TimeEvent::TimeEvent(Time* time) -:Event(ClockEvents::TIME) +:Event(ClockEvents::TIME), +time(time) { - this -> time = time; + } TimeEvent::~TimeEvent() { diff --git a/kernel/src/drivers/console/console.cpp b/kernel/src/drivers/console/console.cpp index 0ee7fb49..dd74c557 100644 --- a/kernel/src/drivers/console/console.cpp +++ b/kernel/src/drivers/console/console.cpp @@ -20,141 +20,150 @@ Console::~Console() { } /** - * Get the width of the console in characters + * @brief Get the width of the console in characters + * * @return The width of the console in characters */ -uint16_t Console::getWidth() { +uint16_t Console::width() { return 0; } /** - * Get the height of the console in characters + * @brief Get the height of the console in characters + * * @return The height of the console in characters */ -uint16_t Console::getHeight() { +uint16_t Console::height() { return 0; } /** - * Put a character on the console + * @brief Put a character on the console + * * @param x The x coordinate of the character * @param y The y coordinate of the character * @param c The character to put on the console */ -void Console::putChar(uint16_t x, uint16_t y, char c) { +void Console::put_character(uint16_t x, uint16_t y, char c) { } /** - * Set the foreground color of a character on the console + * @brief Set the foreground color of a character on the console + * * @param x The x coordinate of the character * @param y The y coordinate of the character * @param foreground The foreground color to set */ -void Console::setForegroundColor(uint16_t x, uint16_t y, ConsoleColour foreground) { +void Console::set_foreground_color(uint16_t x, uint16_t y, ConsoleColour foreground) { } /** - * Set the background color of a character on the console + * @brief Set the background color of a character on the console + * * @param x The x coordinate of the character * @param y The y coordinate of the character * @param background The background color to set */ -void Console::setBackgroundColor(uint16_t x, uint16_t y, ConsoleColour background) { +void Console::set_background_color(uint16_t x, uint16_t y, ConsoleColour background) { } /** - * Get the character at a given coordinate on the console + * @brief Get the character at a given coordinate on the console + * * @param x The x coordinate of the character * @param y The y coordinate of the character * @return The character at the given coordinate */ -char Console::getChar(uint16_t x, uint16_t y) { +char Console::get_character(uint16_t x, uint16_t y) { return ' '; } /** - * Get the background color of a character on the console + * @brief Get the background color of a character on the console + * * @param x The x coordinate of the character * @param y The y coordinate of the character * @return The background color of the character */ -ConsoleColour Console::getForegroundColor(uint16_t x, uint16_t y) { +ConsoleColour Console::get_foreground_color(uint16_t x, uint16_t y) { return Green; } /** - * Get the background color of a character on the console + * @brief Get the background color of a character on the console + * * @param x The x coordinate of the character * @param y The y coordinate of the character * @return The background color of the character */ -ConsoleColour Console::getBackgroundColor(uint16_t x, uint16_t y) { +ConsoleColour Console::get_background_color(uint16_t x, uint16_t y) { return Green; } /** - * Put a character on the console with a given foreground and background color + * @brief Put a character on the console with a given foreground and background color + * * @param x The x coordinate of the character * @param y The y coordinate of the character * @param c The character to put on the console * @param foreground The foreground color of the character * @param background The background color of the character */ -void Console::putChar(uint16_t x, uint16_t y, char c, ConsoleColour foreground, ConsoleColour background) { +void Console::put_character(uint16_t x, uint16_t y, char c, ConsoleColour foreground, ConsoleColour background) { // Set the colors of the character - setForegroundColor(x, y, foreground); - setBackgroundColor(x, y, background); + set_foreground_color(x, y, foreground); + set_background_color(x, y, background); // Put the character on the console - putChar(x, y, c); + put_character(x, y, c); } /** - * Put a string on the console + * @brief Put a string on the console + * * @param x The x coordinate of the string * @param y The y coordinate of the string * @param s The string to put on the console * @param foreground The foreground color of the string * @param background The background color of the string */ -void Console::putString(uint16_t x, uint16_t y, string s, ConsoleColour foreground, ConsoleColour background) { +void Console::put_string(uint16_t x, uint16_t y, string s, ConsoleColour foreground, ConsoleColour background) { // For each character in the string - for(const char* si = s; x < getWidth() && *si != '\0'; si++, x++) { + for(const char* si = s; x < width() && *si != '\0'; si++, x++) { // Put the character on the console - putChar(x,y,*si,foreground,background); - + put_character(x, y, *si, foreground, background); } - } /** - * Scroll the console up by 1 line + * @brief Scroll the console up by 1 line */ -void Console::scrollUp() { +void Console::scroll_up() { // Scroll the console up by 1 line - scrollUp(0, 0, getWidth(), getHeight()); + scroll_up(0, 0, width(), height()); } /** - * Scroll an area of the console up by 1 line + * @brief Scroll an area of the console up by 1 line + * * @param left The left coordinate of the area to scroll * @param top The top coordinate of the area to scroll - * @param width The width of the area to scroll - * @param height The height of the area to scroll + * @param width The m_width of the area to scroll + * @param height The m_height of the area to scroll * @param foreground The foreground color of the new line * @param background The background color of the new line * @param fill The character to fill the new line with */ -void Console::scrollUp(uint16_t left, uint16_t top, uint16_t width, uint16_t height, ConsoleColour foreground, ConsoleColour background, char fill) { +void Console::scroll_up(uint16_t left, uint16_t top, uint16_t width, uint16_t height, ConsoleColour foreground, ConsoleColour background, char fill) { // For each line in the area to scroll (except the last line) for(uint16_t y = top; y < top+height-1; y++){ @@ -163,18 +172,17 @@ void Console::scrollUp(uint16_t left, uint16_t top, uint16_t width, uint16_t hei for(uint16_t x = left; x < left+width; x++) { // Put the character from the line below - putChar(x, y, getChar(x, y+1), getForegroundColor(x, y+1), getBackgroundColor(x, y+1)); + put_character(x, y, get_character(x, y + 1), + get_foreground_color(x, y + 1), + get_background_color(x, y + 1)); } } - // For each character in the last line - for(uint16_t x = left; x < left+width; x++) { + // Fill the last line with the fill character + for(uint16_t x = left; x < left+width; x++) + put_character(x, top + height - 1, fill, foreground, background); - // Put the fill character - putChar(x, top+height-1, fill, foreground, background); - - } } /** @@ -183,45 +191,46 @@ void Console::scrollUp(uint16_t left, uint16_t top, uint16_t width, uint16_t hei void Console::clear() { // Clear the console - clear(0, 0, getWidth(), getHeight()); + clear(0, 0, width(), height()); } /** - * Clear an area of the console + * @brief Clear an area of the console + * * @param left The left coordinate of the area to clear * @param top The top coordinate of the area to clear - * @param width The width of the area to clear - * @param height The height of the area to clear + * @param width The m_width of the area to clear + * @param height The m_height of the area to clear * @param foreground The foreground color of the area * @param background The background color of the area * @param fill The character to fill the area with */ void Console::clear(uint16_t left, uint16_t top, uint16_t width, uint16_t height, ConsoleColour foreground, ConsoleColour background, char fill) { - // For each line in the area to clear + // Put the fill character in the areas for(uint16_t y = top; y < top+height; y++) for(uint16_t x = left; x < left+width; x++){ - // Put the fill character - putChar(x,y,fill,foreground,background); + put_character(x, y, fill, foreground, background); } } /** - * Invert the colors of a character on the console + * @brief Invert the colors of a character on the console + * * @param x The x coordinate of the character * @param y The y coordinate of the character */ -void Console::invertColors(uint16_t x, uint16_t y) { +void Console::invert_colors(uint16_t x, uint16_t y) { // Get the colors of the character - ConsoleColour foreground = getForegroundColor(x, y); - ConsoleColour background = getBackgroundColor(x, y); + ConsoleColour foreground = get_foreground_color(x, y); + ConsoleColour background = get_background_color(x, y); // Set the colors of the character - setForegroundColor(x, y, background); - setBackgroundColor(x, y, foreground); + set_foreground_color(x, y, background); + set_background_color(x, y, foreground); } @@ -229,20 +238,28 @@ void Console::invertColors(uint16_t x, uint16_t y) { ConsoleArea::ConsoleArea(Console *console, uint16_t left, uint16_t top, uint16_t width, uint16_t height) -: console(console), left(left), top(top), width(width), height(height) +: m_console(console), + m_left(left), + m_top(top), + m_width(width), + m_height(height) { } ConsoleArea::ConsoleArea(Console *console, uint16_t left, uint16_t top, uint16_t width, uint16_t height, ConsoleColour foreground, ConsoleColour background) - : console(console), left(left), top(top), width(width), height(height) +: m_console(console), + m_left(left), + m_top(top), + m_width(width), + m_height(height) { // Loop through the area setting the colors for(uint16_t y = top; y < top+height; y++) for(uint16_t x = left; x < left+width; x++){ - console->setForegroundColor(x,y,foreground); - console->setBackgroundColor(x,y,background); + console->set_foreground_color(x, y, foreground); + console->set_background_color(x, y, background); } } @@ -253,125 +270,134 @@ ConsoleArea::~ConsoleArea() { } /** - * Return the width of the console area + * @brief Return the width of the console area + * * @return The width of the console area */ -uint16_t ConsoleArea::getWidth() { - return width; +uint16_t ConsoleArea::width() { + return m_width; } /** - * Return the height of the console area + * @brief Return the height of the console area + * * @return The height of the console area */ -uint16_t ConsoleArea::getHeight() { - return height; +uint16_t ConsoleArea::height() { + return m_height; } /** - * Place a character on the console area if the coordinates are within the area + * @brief Place a character on the console area if the coordinates are within the area + * * @param x The x coordinate of the character * @param y The y coordinate of the character * @param c The character to put on the console */ -void ConsoleArea::putChar(uint16_t x, uint16_t y, char c) { +void ConsoleArea::put_character(uint16_t x, uint16_t y, char c) { // Make sure the coordinates are within the console area - if(x >= width || y >= height) + if(x >= m_width || y >= m_height) return; // Put the character on the console - console->putChar(left+x, top+y, c); + m_console->put_character(m_left + x, m_top + y, c); } /** - * Change the foreground color of a character on the console area if the coordinates are within the area + * @brief Change the foreground color of a character on the console area if the coordinates are within the area + * * @param x The x coordinate of the character * @param y The y coordinate of the character * @param foreground The foreground color of the character */ -void ConsoleArea::setForegroundColor(uint16_t x, uint16_t y, ConsoleColour foreground) { +void ConsoleArea::set_foreground_color(uint16_t x, uint16_t y, ConsoleColour foreground) { - // Make sure the coordinates are within the console area - if(x >= width || y >= height) - return; + // Make sure the coordinates are within the console area + if(x >= m_width || y >= m_height) + return; - // Set the foreground color of the character - console -> setForegroundColor(left + x, top + y, foreground); + // Set the foreground color of the character + m_console->set_foreground_color(m_left + x, m_top + y, foreground); } -void ConsoleArea::setBackgroundColor(uint16_t x, uint16_t y, ConsoleColour background) { +/** + * @brief Change the background color of a character on the console area if the coordinates are within the area + * + * @param x The x coordinate of the character + * @param y The y coordinate of the character + * @param background The background color of the character + */ +void ConsoleArea::set_background_color(uint16_t x, uint16_t y, ConsoleColour background) { // Make sure the coordinates are within the console area - if(x >= width || y >= height) + if(x >= m_width || y >= m_height) return; // Set the background color of the character - console -> setBackgroundColor(left + x, top + y, background); + m_console->set_background_color(m_left + x, m_top + y, background); } /** - * Return the character at the given coordinates if the coordinates are within the console area + * @brief Return the character at the given coordinates if the coordinates are within the console area + * * @param x The x coordinate of the character * @param y The y coordinate of the character * @return The character at the given coordinates, if the coordinates are within the console area otherwise " " */ -char ConsoleArea::getChar(uint16_t x, uint16_t y) { +char ConsoleArea::get_character(uint16_t x, uint16_t y) { // Make sure the coordinates are within the console area - if(x >= width || y >= height) + if(x >= m_width || y >= m_height) return ' '; // Return the character at the given coordinates - return console->getChar(left+x, top+y); + return m_console->get_character(m_left + x, m_top + y); } /** - * Return the foreground color of the character at the given coordinates if the coordinates are within the console area + * @brief Return the foreground color of the character at the given coordinates if the coordinates are within the console area + * * @param x The x coordinate of the character * @param y The y coordinate of the character * @return The foreground color of the character at the given coordinates, if the coordinates are within the console area otherwise ConsoleColour::LightGrey */ -ConsoleColour ConsoleArea::getForegroundColor(uint16_t x, uint16_t y) { +ConsoleColour ConsoleArea::get_foreground_color(uint16_t x, uint16_t y) { // Make sure the coordinates are within the console area - if(x >= width || y >= height) + if(x >= m_width || y >= m_height) return ConsoleColour::LightGrey; // Return the foreground color of the character at the given coordinates - return console->getForegroundColor(left+x, top+y); + return m_console->get_foreground_color(m_left + x, m_top + y); } /** - * Return the background color of the character at the given coordinates if the coordinates are within the console area + * @brief Return the background color of the character at the given coordinates if the coordinates are within the console area + * * @param x The x coordinate of the character * @param y The y coordinate of the character * @return The background color of the character at the given coordinates, if the coordinates are within the console area otherwise ConsoleColour::Black */ -ConsoleColour ConsoleArea::getBackgroundColor(uint16_t x, uint16_t y) { +ConsoleColour ConsoleArea::get_background_color(uint16_t x, uint16_t y) { // Make sure the coordinates are within the console area - if(x >= width || y >= height) + if(x >= m_width || y >= m_height) return ConsoleColour::Black; // Return the background color of the character at the given coordinates - return console->getBackgroundColor(left+x, top+y); + return m_console->get_background_color(m_left + x, m_top + y); } ///____ Console Stream ____/// -ConsoleStream::ConsoleStream(Console *console) { - - // Set the x and y coordinates to 0 - cursorX = 0; - cursorY = 0; - - // Set the console - this->console = console; +ConsoleStream::ConsoleStream(Console *console) +: m_console(console) +{ } @@ -380,25 +406,26 @@ ConsoleStream::~ConsoleStream() { } /** - * Write a character to the console stream + * @brief write a character to the console stream + * * @param c The character to write */ -void ConsoleStream::writeChar(char c) { +void ConsoleStream::write_char(char c) { // If the character placement is more than the width of the console go on a new line - if(cursorX >= console->getWidth()) { + if(m_cursor_x >= m_console->width()) { // Go to the start of the next line - cursorX = 0; + m_cursor_x = 0; // Increment the y coordinate but if it is more than the height of the console scroll the console - if(++cursorY >= console->getHeight()){ + if(++m_cursor_y >= m_console->height()){ // Scroll the console - console->scrollUp(); + m_console->scroll_up(); // Decrement the y coordinate - cursorY = console->getHeight()-1; + m_cursor_y = m_console->height()-1; } } @@ -407,13 +434,13 @@ void ConsoleStream::writeChar(char c) { // New line case '\n': // Increment the y coordinate but if it is more than the height of the console scroll the console - if(++cursorY >= console->getHeight()){ + if(++m_cursor_y >= m_console->height()){ // Scroll the console - console->scrollUp(); + m_console->scroll_up(); // Decrement the y coordinate - cursorY = console->getHeight()-1; + m_cursor_y = m_console->height()-1; } // don't break here, we want to go to the next case because of the \r @@ -421,7 +448,7 @@ void ConsoleStream::writeChar(char c) { // Carriage return case '\r': // Go to the start of the next line - cursorX = 0; + m_cursor_x = 0; break; // Null Terminator @@ -431,15 +458,15 @@ void ConsoleStream::writeChar(char c) { // Backspace case '\b': // Decrement the x coordinate - cursorX--; + m_cursor_x--; break; default: // Put the character on the console - console->putChar(cursorX, cursorY, c); + m_console->put_character(m_cursor_x, m_cursor_y, c); // Increment the x coordinate - cursorX++; + m_cursor_x++; break; } @@ -447,14 +474,14 @@ void ConsoleStream::writeChar(char c) { } /** - * Set the position of the cursor + * @brief Set the m_position of the cursor + * * @param x The x coordinate of the cursor * @param y The y coordinate of the cursor */ -void ConsoleStream::setCursor(uint16_t x, uint16_t y) { +void ConsoleStream::set_cursor(uint16_t x, uint16_t y) { // Set the x and y coordinates - cursorX = x; - cursorY = y; -} - + m_cursor_x = x; + m_cursor_y = y; +} \ No newline at end of file diff --git a/kernel/src/drivers/console/textmode.cpp b/kernel/src/drivers/console/textmode.cpp index 5e4f0b4b..1f69bbe9 100644 --- a/kernel/src/drivers/console/textmode.cpp +++ b/kernel/src/drivers/console/textmode.cpp @@ -11,8 +11,7 @@ using namespace maxOS::drivers::console; TextModeConsole::TextModeConsole() : Driver(), - Console(), - videoMemory((uint16_t*) 0xb8000) + Console() { } @@ -22,131 +21,144 @@ TextModeConsole::~TextModeConsole() } -uint16_t TextModeConsole::getWidth() +/** + * @brief Gets the width of the console + * + * @return The width of the console in characters + */ +uint16_t TextModeConsole::width() { return 80; } -uint16_t TextModeConsole::getHeight() +/** + * @brief Gets the height of the console + * + * @return The height of the console in characters + */ +uint16_t TextModeConsole::height() { return 25; } /** - * Places a character at the specified location + * @brief Places a character at the specified location if it is in bounds + * * @param x The x coordinate * @param y The y coordinate * @param c The character to place */ -void TextModeConsole::putChar(uint16_t x, uint16_t y, char c) { +void TextModeConsole::put_character(uint16_t x, uint16_t y, char c) { // If the coordinates are out of bounds, return - if(x >= getWidth() || y >= getHeight()) + if(x >= width() || y >= height()) return; // Calculate the offset - int offset = (y*getWidth() + x); + int offset = (y*width() + x); // Set the character at the offset, by masking the character with the current character (last 8 bits) - videoMemory[offset] = (videoMemory[offset] & 0xFF00) | (uint16_t)c; + m_video_memory[offset] = (m_video_memory[offset] & 0xFF00) | (uint16_t)c; } /** - * Sets the foreground color at the specified location + * @brief Sets the foreground color at the specified location + * * @param x The x coordinate * @param y The y coordinate * @param foreground The foreground color */ -void TextModeConsole::setForegroundColor(uint16_t x, uint16_t y, ConsoleColour foreground) { +void TextModeConsole::set_foreground_color(uint16_t x, uint16_t y, ConsoleColour foreground) { // If the coordinates are out of bounds, return - if(x >= getWidth() || y >= getHeight()) + if(x >= width() || y >= height()) return; // Calculate the offset - int offset = (y*getWidth() + x); + int offset = (y* width() + x); // Set the foreground color at the offset, by masking the foreground color with the current foreground color (bits 8-11) - videoMemory[offset] = (videoMemory[offset] & 0xF0FF) | ((uint16_t)foreground << 8); + m_video_memory[offset] = (m_video_memory[offset] & 0xF0FF) | ((uint16_t)foreground << 8); } /** - * Sets the background color at the specified location + * @brief Sets the background color at the specified location + * * @param x The x coordinate * @param y The y coordinate * @param background The background color */ -void TextModeConsole::setBackgroundColor(uint16_t x, uint16_t y, ConsoleColour background) { +void TextModeConsole::set_background_color(uint16_t x, uint16_t y, ConsoleColour background) { // If the coordinates are out of bounds, return - if(x >= getWidth() || y >= getHeight()) + if(x >= width() || y >= height()) return; // Calculate the offset - int offset = (y*getWidth() + x); + int offset = (y* width() + x); // Set the background color at the offset, by masking the background color with the current background color (bits 12-15) - videoMemory[offset] = (videoMemory[offset] & 0x0FFF) | ((uint16_t)background << 12); + m_video_memory[offset] = (m_video_memory[offset] & 0x0FFF) | ((uint16_t)background << 12); } /** - * Gets the character at the specified location + * @brief Gets the character at the specified location + * * @param x The x coordinate * @param y The y coordinate - * @return The character at the specified location + * @return The character at the specified location or a space if the coordinates are out of bounds */ -char TextModeConsole::getChar(uint16_t x, uint16_t y) { +char TextModeConsole::get_character(uint16_t x, uint16_t y) { // If the coordinates are out of bounds, return - if(x >= getWidth() || y >= getHeight()) + if(x >= width() || y >= height()) return ' '; // Calculate the offset - int offset = (y*getWidth() + x); + int offset = (y* width() + x); // Return the character at the offset, by masking the character with the current character (last 8 bits) - return (char)(videoMemory[offset] & 0x00FF); + return (char)(m_video_memory[offset] & 0x00FF); } /** - * Gets the foreground color at the specified location + * @brief Gets the foreground color at the specified location + * * @param x The x coordinate * @param y The y coordinate - * @return The foreground color at the specified location + * @return The foreground color at the specified location or white if the coordinates are out of bounds */ -ConsoleColour TextModeConsole::getForegroundColor(uint16_t x, uint16_t y) { +ConsoleColour TextModeConsole::get_foreground_color(uint16_t x, uint16_t y) { // If the coordinates are out of bounds, return - if(x >= getWidth() || y >= getHeight()) + if(x >= width() || y >= height()) return ConsoleColour::White; // Calculate the offset - int offset = (y*getWidth() + x); + int offset = (y* width() + x); // Return the foreground color at the offset, by masking the foreground color with the current foreground color (bits 8-11) - return (ConsoleColour)((videoMemory[offset] & 0x0F00) >> 8); + return (ConsoleColour)((m_video_memory[offset] & 0x0F00) >> 8); } /** - * Gets the background color at the specified location + * @brief Gets the background color at the specified location + * * @param x The x coordinate * @param y The y coordinate - * @return The background color at the specified location + * @return The background color at the specified location or black if the coordinates are out of bounds */ - ConsoleColour TextModeConsole::getBackgroundColor(uint16_t x, uint16_t y) { +ConsoleColour TextModeConsole::get_background_color(uint16_t x, uint16_t y) { // If the coordinates are out of bounds, return - if(x >= getWidth() || y >= getHeight()) + if(x >= width() || y >= height()) return ConsoleColour::Black; // Calculate the offset - int offset = (y*getWidth() + x); + int offset = (y* width() + x); // Return the background color at the offset, by masking the background color with the current background color (bits 12-15) - return (ConsoleColour)((videoMemory[offset] & 0xF000) >> 12); -} - - - + return (ConsoleColour)((m_video_memory[offset] & 0xF000) >> 12); +} \ No newline at end of file diff --git a/kernel/src/drivers/console/vesaboot.cpp b/kernel/src/drivers/console/vesaboot.cpp index f35cda7c..5f26b8d4 100644 --- a/kernel/src/drivers/console/vesaboot.cpp +++ b/kernel/src/drivers/console/vesaboot.cpp @@ -11,19 +11,16 @@ using namespace maxOS::memory; using namespace maxOS::drivers; using namespace maxOS::drivers::console; -VESABootConsole::VESABootConsole(GraphicsContext *graphicsContext) +VESABootConsole::VESABootConsole(GraphicsContext *graphics_context) : Driver(), - Console() + Console(), + m_graphics_context(graphics_context), + m_font(AmigaFont()) { - // Set the graphics context - this->graphicsContext = graphicsContext; - - // Set the font - this->font = AmigaFont(); - // Malloc the video memory - videoMemory = (uint16_t*)MemoryManager::activeMemoryManager->malloc(graphicsContext->getWidth() * graphicsContext->getHeight() * sizeof(uint16_t)); + m_video_memory = (uint16_t*)MemoryManager::s_active_memory_manager->malloc( + graphics_context->get_width() * graphics_context->get_height() * sizeof(uint16_t)); } VESABootConsole::~VESABootConsole() @@ -31,147 +28,166 @@ VESABootConsole::~VESABootConsole() } -uint16_t VESABootConsole::getWidth() +/** + * @brief Gets the width of the console + * + * @return The width of the console in characters + */ +uint16_t VESABootConsole::width() { - return graphicsContext->getWidth() / 8; // 8 pixels per character + return m_graphics_context->get_width() / 8; // 8 pixels per character } -uint16_t VESABootConsole::getHeight() +/** + * @brief Gets the height of the console + * + * @return The height of the console in characters + */ +uint16_t VESABootConsole::height() { - return graphicsContext->getHeight() / 9; // 9 pixels per character + return m_graphics_context->get_height() / 9; // 9 pixels per character } /** - * Places a character at the specified location + * @brief Places a character at the specified location + * * @param x The x coordinate * @param y The y coordinate * @param c The character to place */ -void VESABootConsole::putChar(uint16_t x, uint16_t y, char c) { +void VESABootConsole::put_character(uint16_t x, uint16_t y, char c) { // If the coordinates are out of bounds, return - if(x >= getWidth() || y >= getHeight()) + if(x >= width() || y >= height()) return; // Calculate the offset - int offset = (y*getWidth() + x); + int offset = (y* width() + x); // Set the character at the offset, by masking the character with the current character (last 8 bits) - videoMemory[offset] = (videoMemory[offset] & 0xFF00) | (uint16_t)c; + m_video_memory[offset] = (m_video_memory[offset] & 0xFF00) | (uint16_t)c; // Convert the char into a string char* s = " "; s[0] = c; - Colour foreground = consoleColourToVESA(getForegroundColor(x,y)); - Colour background = consoleColourToVESA(getBackgroundColor(x,y)); + Colour foreground = console_colour_to_vesa(get_foreground_color(x, y)); + Colour background = console_colour_to_vesa(get_background_color(x, y)); - // Use the font to draw the character - font.drawText(x*8, y*9, foreground, background, graphicsContext, s); + // Use the m_font to draw the character + m_font.draw_text(x * 8, y * 9, foreground, background, m_graphics_context, + s); } /** - * Sets the foreground color at the specified location + * @brief Sets the foreground color at the specified location + * * @param x The x coordinate * @param y The y coordinate * @param foreground The foreground color */ -void VESABootConsole::setForegroundColor(uint16_t x, uint16_t y, ConsoleColour foreground) { +void VESABootConsole::set_foreground_color(uint16_t x, uint16_t y, ConsoleColour foreground) { // If the coordinates are out of bounds, return - if(x >= getWidth() || y >= getHeight()) + if(x >= width() || y >= height()) return; // Calculate the offset - int offset = (y*getWidth() + x); + int offset = (y* width() + x); // Set the foreground color at the offset, by masking the foreground color with the current foreground color (bits 8-11) - videoMemory[offset] = (videoMemory[offset] & 0xF0FF) | ((uint16_t)foreground << 8); + m_video_memory[offset] = (m_video_memory[offset] & 0xF0FF) | ((uint16_t)foreground << 8); } /** - * Sets the background color at the specified location + * @brief Sets the background color at the specified location + * * @param x The x coordinate * @param y The y coordinate * @param background The background color */ -void VESABootConsole::setBackgroundColor(uint16_t x, uint16_t y, ConsoleColour background) { +void VESABootConsole::set_background_color(uint16_t x, uint16_t y, ConsoleColour background) { // If the coordinates are out of bounds, return - if(x >= getWidth() || y >= getHeight()) + if(x >= width() || y >= height()) return; // Calculate the offset - int offset = (y*getWidth() + x); + int offset = (y* width() + x); // Set the background color at the offset, by masking the background color with the current background color (bits 12-15) - videoMemory[offset] = (videoMemory[offset] & 0x0FFF) | ((uint16_t)background << 12); + m_video_memory[offset] = (m_video_memory[offset] & 0x0FFF) | ((uint16_t)background << 12); } /** - * Gets the character at the specified location + * @brief Gets the character at the specified location + * * @param x The x coordinate * @param y The y coordinate - * @return The character at the specified location + * @return The character at the specified location or a space if the coordinates are out of bounds */ -char VESABootConsole::getChar(uint16_t x, uint16_t y) { +char VESABootConsole::get_character(uint16_t x, uint16_t y) { // If the coordinates are out of bounds, return - if(x >= getWidth() || y >= getHeight()) + if(x >= width() || y >= height()) return ' '; // Calculate the offset - int offset = (y*getWidth() + x); + int offset = (y* width() + x); // Return the character at the offset, by masking the character with the current character (last 8 bits) - return (char)(videoMemory[offset] & 0x00FF); + return (char)(m_video_memory[offset] & 0x00FF); } /** - * Gets the foreground color at the specified location + * @brief Gets the foreground color at the specified location + * * @param x The x coordinate * @param y The y coordinate - * @return The foreground color at the specified location + * @return The foreground color at the specified location or white if the coordinates are out of bounds */ -ConsoleColour VESABootConsole::getForegroundColor(uint16_t x, uint16_t y) { +ConsoleColour VESABootConsole::get_foreground_color(uint16_t x, uint16_t y) { // If the coordinates are out of bounds, return - if(x >= getWidth() || y >= getHeight()) + if(x >= width() || y >= height()) return ConsoleColour::White; // Calculate the offset - int offset = (y*getWidth() + x); + int offset = (y* width() + x); // Return the foreground color at the offset, by masking the foreground color with the current foreground color (bits 8-11) - return (ConsoleColour)((videoMemory[offset] & 0x0F00) >> 8); + return (ConsoleColour)((m_video_memory[offset] & 0x0F00) >> 8); } /** - * Gets the background color at the specified location + * @brief Gets the background color at the specified location * @param x The x coordinate * @param y The y coordinate - * @return The background color at the specified location + * + * @return The background color at the specified location or black if the coordinates are out of bounds */ -ConsoleColour VESABootConsole::getBackgroundColor(uint16_t x, uint16_t y) { +ConsoleColour VESABootConsole::get_background_color(uint16_t x, uint16_t y) { // If the coordinates are out of bounds, return - if(x >= getWidth() || y >= getHeight()) + if(x >= width() || y >= height()) return ConsoleColour::Black; // Calculate the offset - int offset = (y*getWidth() + x); + int offset = (y* width() + x); // Return the background color at the offset, by masking the background color with the current background color (bits 12-15) - return (ConsoleColour)((videoMemory[offset] & 0xF000) >> 12); + return (ConsoleColour)((m_video_memory[offset] & 0xF000) >> 12); } - - - - -Colour VESABootConsole::consoleColourToVESA(ConsoleColour colour) { +/** + * @brief Converts a ConsoleColour to a Colour + * + * @param colour The ConsoleColour to convert + * @return The Colour + */ +Colour VESABootConsole::console_colour_to_vesa(ConsoleColour colour) { switch (colour) { case Black: @@ -222,6 +238,4 @@ Colour VESABootConsole::consoleColourToVESA(ConsoleColour colour) { case White: return Colour(255, 255, 255); } -} - - +} \ No newline at end of file diff --git a/kernel/src/drivers/driver.cpp b/kernel/src/drivers/driver.cpp index ab779d60..75388164 100644 --- a/kernel/src/drivers/driver.cpp +++ b/kernel/src/drivers/driver.cpp @@ -8,97 +8,113 @@ using namespace maxOS::common; using namespace maxOS::drivers; using namespace maxOS::memory; -Driver::Driver(OutputStream* driverMessageStream){ - - // Set the driver message stream - this -> driverMessageStream = driverMessageStream; +Driver::Driver(OutputStream* driverMessageStream) +: m_driver_message_stream(driverMessageStream) { }; Driver::~Driver(){ - this -> driverMessageStream = 0; + this ->m_driver_message_stream = 0; }; +/** + * @brief activate the driver + */ void Driver::activate(){ } +/** + * @brief deactivate the driver + */ void Driver::deactivate(){ } - +/** + * @brief Initialise the driver + */ void Driver::initialise() { } - +/** + * @brief Reset the driver + * + * @return How long in milliseconds it took to reset the driver + */ uint32_t Driver::reset(){ return 0; } /** - * @details This function writes a message to the driver message stream if it is not null - * @param message The message to write + * @brief write a message to the driver message stream if it is not null + * + * @param message The message to write */ -void Driver::errorMessage(string message) { +void Driver::error_message(string message) { - // Check if the driver message stream is not null - if( driverMessageStream != 0) { - // Write the message to the driver message stream - driverMessageStream -> write(message); - } + // If there is a driver message stream write the message to it + if(m_driver_message_stream != 0) + m_driver_message_stream-> write(message); } /** - * @details This function writes a character to the driver message stream if it is not null - * @param charToWrite The character to write + * @brief write a character to the driver message stream if it is not null + * + * @param char_to_write The character to write */ -void Driver::errorMessage(char charToWrite) { +void Driver::error_message(char char_to_write) { - // Check if the driver message stream is not null - if( driverMessageStream != 0) { - // Write the character to the driver message stream - driverMessageStream -> writeChar(charToWrite); - } + // If there is a driver message stream write the character to it + if(m_driver_message_stream != 0) + m_driver_message_stream-> write_char(char_to_write); } /** - * @details This function writes a int to the driver message stream if it is not null - * @param intToWrite The int to write + * @brief write an integer to the driver message stream if it is not null + * + * @param int_to_write The integer to write */ -void Driver::errorMessage(int intToWrite) { +void Driver::error_message(int int_to_write) { - // Check if the driver message stream is not null - if( driverMessageStream != 0) { - // Write the character to the driver message stream - driverMessageStream -> writeInt(intToWrite); - } + // If there is a driver message stream write the integer to it + if(m_driver_message_stream != 0) + m_driver_message_stream-> write_int(int_to_write); } /** - * @details This function writes a hex to the driver message stream if it is not null - * @param hexToWrite The hex to write + * @brief write a hex to the driver message stream if it is not null + * + * @param hex_to_write The hex to write */ -void Driver::errorMessage(uint32_t hexToWrite) { +void Driver::error_message(uint32_t hex_to_write) { - // Check if the driver message stream is not null - if( driverMessageStream != 0) { - // Write the character to the driver message stream - driverMessageStream -> writeHex(hexToWrite); - } + // If there is a driver message stream write the hex to it + if(m_driver_message_stream != 0) + m_driver_message_stream->write_hex(hex_to_write); } -string Driver::getVendorName() +/** + * @brief Get the vendor name of the driver + * + * @return The vendor name of the driver + */ +string Driver::get_vendor_name() { return "Generic"; } -string Driver::getDeviceName() +/** + * @brief Get the device name of the driver + * + * @return The device name of the driver + */ +string Driver::get_device_name() { return "Unknown Driver"; } @@ -112,10 +128,11 @@ DriverSelectorEventHandler::~DriverSelectorEventHandler() } /** - * @details This function is called when a driver is selected + * @brief This function is called when a driver is selected + * * @param driver The driver that was selected */ -void DriverSelectorEventHandler::onDriverSelected(Driver*) +void DriverSelectorEventHandler::on_driver_selected(Driver*) { } @@ -127,7 +144,10 @@ DriverSelector::~DriverSelector() { } -void DriverSelector::selectDrivers(DriverSelectorEventHandler*, hardwarecommunication::InterruptManager*, OutputStream*) +/** + * @brief Select the drivers + */ +void DriverSelector::select_drivers(DriverSelectorEventHandler*, hardwarecommunication::InterruptManager*, common::OutputStream *) { } @@ -137,40 +157,39 @@ DriverManager::DriverManager() { DriverManager::~DriverManager() { - // While there are still drivers in the driver vector - while (!drivers.empty()) { - - // Remove the driver - removeDriver(*drivers.begin()); - } + // Remove any drivers that are still attached + while (!drivers.empty()) + remove_driver(*drivers.begin()); } /** - * @details Adds a driver to the driver vector + * @brief Adds a driver to the manager + * * @param driver The driver to add */ -void DriverManager::addDriver(Driver* driver) { - drivers.pushBack(driver); +void DriverManager::add_driver(Driver* driver){ + drivers.push_back(driver); } /** - * @details Removes a driver from the driver vector + * @brief Removes a driver from the driver vector + * * @param driver The driver to remove */ -void DriverManager::removeDriver(Driver* driver) { +void DriverManager::remove_driver(Driver* driver) { - // Deactivate the driver + // deactivate the driver driver -> deactivate(); - // Remove the driver from the driver vector + // Remove the driver drivers.erase(driver); } /** - * @details When a driver is selected, add it to the driver vector + * @brief When a driver is selected add it to the manager */ -void DriverManager::onDriverSelected(Driver* driver) { - addDriver(driver); -} +void DriverManager::on_driver_selected(Driver* driver) { + add_driver(driver); +} \ No newline at end of file diff --git a/kernel/src/drivers/ethernet/amd_am79c973.cpp b/kernel/src/drivers/ethernet/amd_am79c973.cpp index 291bd67c..f59a1636 100644 --- a/kernel/src/drivers/ethernet/amd_am79c973.cpp +++ b/kernel/src/drivers/ethernet/amd_am79c973.cpp @@ -12,14 +12,14 @@ using namespace maxOS::hardwarecommunication; amd_am79c973::amd_am79c973(PeripheralComponentInterconnectDeviceDescriptor *dev, InterruptManager* interrupts, OutputStream *amdNetMessageStream) : EthernetDriver(amdNetMessageStream), - InterruptHandler(dev -> interrupt + interrupts -> HardwareInterruptOffset(), interrupts), - MACAddress0Port(dev -> portBase), - MACAddress2Port(dev -> portBase + 0x02), - MACAddress4Port(dev -> portBase + 0x04), - registerDataPort(dev -> portBase + 0x10), - registerAddressPort(dev -> portBase + 0x12), - resetPort(dev -> portBase + 0x14), - busControlRegisterDataPort(dev -> portBase + 0x16) + InterruptHandler(dev -> interrupt + interrupts->hardware_interrupt_offset(), interrupts), + MACAddress0Port(dev ->port_base), + MACAddress2Port(dev ->port_base + 0x02), + MACAddress4Port(dev ->port_base + 0x04), + registerDataPort(dev ->port_base + 0x10), + registerAddressPort(dev ->port_base + 0x12), + resetPort(dev ->port_base + 0x14), + busControlRegisterDataPort(dev ->port_base + 0x16) { // No active buffer at the start currentSendBuffer = 0; @@ -30,12 +30,12 @@ amd_am79c973::amd_am79c973(PeripheralComponentInterconnectDeviceDescriptor *dev, initDone = false; // Get the MAC adresses (split up in little endian order) - uint64_t MAC0 = MACAddress0Port.Read() % 256; - uint64_t MAC1 = MACAddress0Port.Read() / 256; - uint64_t MAC2 = MACAddress2Port.Read() % 256; - uint64_t MAC3 = MACAddress2Port.Read() / 256; - uint64_t MAC4 = MACAddress4Port.Read() % 256; - uint64_t MAC5 = MACAddress4Port.Read() / 256; + uint64_t MAC0 = MACAddress0Port.read() % 256; + uint64_t MAC1 = MACAddress0Port.read() / 256; + uint64_t MAC2 = MACAddress2Port.read() % 256; + uint64_t MAC3 = MACAddress2Port.read() / 256; + uint64_t MAC4 = MACAddress4Port.read() % 256; + uint64_t MAC5 = MACAddress4Port.read() / 256; // Combine MAC addresses into one 48 bit number ownMAC = MAC5 << 40 @@ -46,12 +46,12 @@ amd_am79c973::amd_am79c973(PeripheralComponentInterconnectDeviceDescriptor *dev, | MAC0; // Set the device to 32 bit mode - registerAddressPort.Write(20); // Tell device to write to register 20 - busControlRegisterDataPort.Write(0x102); // Write desired data + registerAddressPort.write(20); // Tell device to write to register 20 + busControlRegisterDataPort.write(0x102); // write desired data // Reset the stop bit (tell device it's not supposed to be reset now) - registerAddressPort.Write(0); // Tell device to write to register 0 - registerDataPort.Write(0x04); // Write desired data + registerAddressPort.write(0); // Tell device to write to register 0 + registerDataPort.write(0x04); // write desired data // Set the initialization block initBlock.mode = 0x0000; // Promiscuous mode = false ( promiscuous mode tells it to receive all packets, not just broadcasts and those for its own MAC address) @@ -89,10 +89,12 @@ amd_am79c973::amd_am79c973(PeripheralComponentInterconnectDeviceDescriptor *dev, } // Move initialization block into device - registerAddressPort.Write(1); // Tell device to write to register 1 - registerDataPort.Write( (uint32_t)(&initBlock) & 0xFFFF ); // Write address data - registerAddressPort.Write(2); // Tell device to write to register 2 - registerDataPort.Write( ((uint32_t)(&initBlock) >> 16) & 0xFFFF ); // Write shifted address data + registerAddressPort.write(1); // Tell device to write to register 1 + registerDataPort.write((uint32_t)(&initBlock) & + 0xFFFF); // write address data + registerAddressPort.write(2); // Tell device to write to register 2 + registerDataPort.write(((uint32_t)(&initBlock) >> 16) & + 0xFFFF); // write shifted address data } @@ -104,39 +106,40 @@ amd_am79c973::~amd_am79c973() /** - * @details This function activates the device and starts it (Runs when the driver-manger calls activateAll()) + * @brief This function activates the device and starts it (Runs when the driver-manger calls activateAll()) */ void amd_am79c973::activate() { initDone = false; // Set initDone to false - registerAddressPort.Write(0); // Tell device to write to register 0 - registerDataPort.Write(0x41); // Enable Interrupts and start the device + registerAddressPort.write(0); // Tell device to write to register 0 + registerDataPort.write(0x41); // Enable Interrupts and start the device while(!initDone); // Wait for initDone to be set to true + registerAddressPort.write(4); // Tell device to read from register 4 + uint32_t temp = registerDataPort.read(); // Get current data + registerAddressPort.write(4); // Tell device to write to register 4 + registerDataPort.write( + temp | + 0xC00); // Bitwise OR function on data (This automatically enlarges packets smaller than 64 bytes to that size and removes some relatively superfluous information from received packets.) - registerAddressPort.Write(4); // Tell device to read from register 4 - uint32_t temp = registerDataPort.Read(); // Get current data - - registerAddressPort.Write(4); // Tell device to write to register 4 - registerDataPort.Write(temp | 0xC00); // Bitwise OR function on data (This automatically enlarges packets smaller than 64 bytes to that size and removes some relatively superfluous information from received packets.) - - registerAddressPort.Write(0); // Tell device to write to register 0 - registerDataPort.Write(0x42); // Tell device that it is initialised and can begin operating + registerAddressPort.write(0); // Tell device to write to register 0 + registerDataPort.write( + 0x42); // Tell device that it is initialised and can begin operating active = true; // Set active to true } /** - * @details This function resets the device + * @brief This function resets the device * * @return The amount of ms to wait */ uint32_t amd_am79c973::reset() { - resetPort.Read(); - resetPort.Write(0); + resetPort.read(); + resetPort.write(0); return 10; // 10 means wait for 10ms } @@ -144,24 +147,28 @@ uint32_t amd_am79c973::reset() { /** - * @details This function handles the interrupt for the device + * @brief This function handles the interrupt for the device * * @param esp The stack pointer (where to return to) */ -void amd_am79c973::HandleInterrupt() { +void amd_am79c973::handle_interrupt() { // Similar to PIC, data needs to be read when a interrupt is sent, or it hangs - registerAddressPort.Write(0); // Tell device to read from register 0 - uint32_t temp = registerDataPort.Read(); // Get current data + registerAddressPort.write(0); // Tell device to read from register 0 + uint32_t temp = registerDataPort.read(); // Get current data // Note: Cant be switch case as multiple errors can occur at the same time // Errors - if((temp & 0x8000) == 0x8000) errorMessage("AMD am79c973 ERROR: "); - if((temp & 0x2000) == 0x2000) errorMessage("COLLISION ERROR\n"); - if((temp & 0x1000) == 0x1000) errorMessage("MISSED FRAME\n"); - if((temp & 0x0800) == 0x0800) errorMessage("MEMORY ERROR\n"); + if((temp & 0x8000) == 0x8000) + error_message("AMD am79c973 ERROR: "); + if((temp & 0x2000) == 0x2000) + error_message("COLLISION ERROR\n"); + if((temp & 0x1000) == 0x1000) + error_message("MISSED FRAME\n"); + if((temp & 0x0800) == 0x0800) + error_message("MEMORY ERROR\n"); // Responses @@ -170,8 +177,8 @@ void amd_am79c973::HandleInterrupt() { if((temp & 0x0100) == 0x0100) initDone = true;// // Reply that it was received - registerAddressPort.Write(0); // Tell device to write to register 0 - registerDataPort.Write(temp); // Tell device that the interrupt was received + registerAddressPort.write(0); // Tell device to write to register 0 + registerDataPort.write(temp); // Tell device that the interrupt was received } @@ -182,7 +189,7 @@ void amd_am79c973::HandleInterrupt() { // Furthermore, STP (Start of Packet, 0x02000000) and ENP (End of Packet, 0x01000000) should be set - this indicates that the data is not split up, but that it is a single Ethernet packet. // Furthermore, bits 12-15 must be set (0x0000F000, are probably reserved) and bits 0-11 are negative Size of the package. /** - * @details This function sends a package + * @brief This function sends a package * * @param buffer The buffer to send * @param size The size of the buffer @@ -192,7 +199,7 @@ void amd_am79c973::DoSend(uint8_t *buffer, uint32_t size) { while(!active); int sendDescriptor = currentSendBuffer; // Get where data has been written to - currentSendBuffer = (currentSendBuffer + 1) % 8; // Move send buffer to next send buffer (div by 8 so that it is cycled) (this allows for data to be sent from different tasks in parallel) + currentSendBuffer = (currentSendBuffer + 1) % 8; // Move send buffer to next send buffer (div by 8 so that it is cycled) (this allows for data to be sent from different m_tasks in parallel) if(size > 1518){ // If attempt to send more than 1518 bytes at once it will be too large size = 1518; // Discard all data after that (Generally if data is bigger than that at driver level then a higher up network layer must have made a mistake) @@ -215,9 +222,9 @@ void amd_am79c973::DoSend(uint8_t *buffer, uint32_t size) { sendBufferDescr[sendDescriptor].flags = 0x8300F000 // Encode the size of what is being sent | ((uint16_t)((-size) & 0xFFF));; - - registerAddressPort.Write(0); // Tell device to write to register 0 - registerDataPort.Write(0x48); // Tell device to send the data currently in the buffer + registerAddressPort.write(0); // Tell device to write to register 0 + registerDataPort.write( + 0x48); // Tell device to send the data currently in the buffer } void amd_am79c973::FetchDataReceived() @@ -236,7 +243,7 @@ void amd_am79c973::FetchDataReceived() FireDataReceived(buffer, size); //Pass data to handler } - recvBufferDescr[currentRecvBuffer].flags2 = 0; //Write that the data has been read and can now be used again + recvBufferDescr[currentRecvBuffer].flags2 = 0; //write that the data has been read and can now be used again recvBufferDescr[currentRecvBuffer].flags = 0x8000F7FF; //Clear the buffer } } @@ -267,7 +274,7 @@ void amd_am79c973::FetchDataSent() /** - * @details This function gets the MAC address + * @brief This function gets the MAC address * * @return The MAC address */ @@ -280,11 +287,11 @@ void amd_am79c973::deactivate() { } -string amd_am79c973::getVendorName() { +string amd_am79c973::get_vendor_name() { return "AMD"; } -string amd_am79c973::getDeviceName() { +string amd_am79c973::get_device_name() { return "PCnet-Fast III (Am79C973)"; } diff --git a/kernel/src/drivers/ethernet/ethernet.cpp b/kernel/src/drivers/ethernet/ethernet.cpp index b6cbef0c..442fbb15 100644 --- a/kernel/src/drivers/ethernet/ethernet.cpp +++ b/kernel/src/drivers/ethernet/ethernet.cpp @@ -34,7 +34,7 @@ void EthernetDriverEventHandler::DataSent(uint8_t*, uint32_t) { } -Event* EthernetDriverEventHandler::onEvent(Event *event) { +Event* EthernetDriverEventHandler::on_event(Event *event) { switch (event -> type) { @@ -47,7 +47,7 @@ Event* EthernetDriverEventHandler::onEvent(EventreturnValue.boolValue = DataReceived(((DataReceivedEvent*)event) -> buffer, ((DataReceivedEvent*)event) -> size); + event->return_value.boolValue = DataReceived(((DataReceivedEvent*)event) -> buffer, ((DataReceivedEvent*)event) -> size); break; default: @@ -71,7 +71,7 @@ EthernetDriver::~EthernetDriver() } /** - * @details Get the MAC address + * @brief Get the MAC address * * @return the MAC address */ @@ -81,63 +81,64 @@ MediaAccessControlAddress EthernetDriver::GetMediaAccessControlAddress() } /** - * @details Send data to the network via the driver backend + * @brief Send data to the network via the driver backend * * @param buffer The buffer to send * @param size The size of the buffer */ void EthernetDriver::Send(uint8_t* buffer, uint32_t size) { - driverMessageStream -> write("Sending: "); + m_driver_message_stream-> write("Sending: "); int displayType = 34; //What header to hide (Ethernet Header = 14, IP Header = 34, UDP = 42, TCP Header = 54, ARP = 42) for(int i = displayType; i < size; i++) { - driverMessageStream -> writeHex(buffer[i]); - driverMessageStream -> write(" "); + m_driver_message_stream->write_hex(buffer[i]); + m_driver_message_stream-> write(" "); } - driverMessageStream -> write("\n"); + m_driver_message_stream-> write("\n"); // Raise the event - raiseEvent(new BeforeSendEvent(buffer, size)); + raise_event(new BeforeSendEvent(buffer, size)); DoSend(buffer, size); } /** - * @details (Device Side) Send the data + * @brief (Device Side) Send the data */ void EthernetDriver::DoSend(uint8_t*, uint32_t) { } /** - * @details Handle the recieved data + * @brief Handle the recieved data * * @param buffer The buffer to handle * @param size The size of the buffer */ void EthernetDriver::FireDataReceived(uint8_t* buffer, uint32_t size) { - driverMessageStream -> write("Receiving: "); + m_driver_message_stream-> write("Receiving: "); //size = 64; int displayType = 34; //What header to hide (Ethernet Header = 14, IP Header = 34, UDP = 42, TCP Header = 54, ARP = 42) for(int i = displayType; i < size; i++) { - driverMessageStream -> writeHex(buffer[i]); - driverMessageStream -> write(" "); + m_driver_message_stream->write_hex(buffer[i]); + m_driver_message_stream-> write(" "); } - driverMessageStream -> write("\n"); + m_driver_message_stream-> write("\n"); // Raise the event - Vector*> values = raiseEvent(new DataReceivedEvent(buffer, size)); + Vector*> values = + raise_event(new DataReceivedEvent(buffer, size)); // Loop through the events for(typename Vector*>::iterator event = values.begin(); event != values.end(); ++event) { switch ((*event)->type) { case EthernetDriverEvents::DATA_RECEIVED: - if((*event)->returnValue.boolValue){ - driverMessageStream -> write("Sending back... \n"); + if((*event)->return_value.boolValue){ + m_driver_message_stream-> write("Sending back... \n"); Send(buffer, size); } break; @@ -146,26 +147,26 @@ void EthernetDriver::FireDataReceived(uint8_t* buffer, uint32_t size) break; } } - driverMessageStream -> write("DATA HANDLED\n"); + m_driver_message_stream-> write("DATA HANDLED\n"); } /** - * @details Send data + * @brief Send data * * @param buffer The buffer to send * @param size The size of the buffer */ void EthernetDriver::FireDataSent(uint8_t* buffer, uint32_t size) { - raiseEvent(new DataSentEvent(buffer, size)); + raise_event(new DataSentEvent(buffer, size)); } // if your mac address is e.g. 1c:6f:65:07:ad:1a (see output of ifconfig) // then you would call CreateMediaAccessControlAddress(0x1c, 0x6f, 0x65, 0x07, 0xad, 0x1a) /** - * @details Create a Media Access Control Address + * @brief Create a Media Access Control Address * - * @param digit1 The first digit + * @param digit1 The m_first_memory_chunk digit * @param digit2 The second digit * @param digit3 The third digit * @param digit4 The fourth digit diff --git a/kernel/src/drivers/ethernet/intel_i217.cpp b/kernel/src/drivers/ethernet/intel_i217.cpp index ad1ec2bc..e428b62a 100644 --- a/kernel/src/drivers/ethernet/intel_i217.cpp +++ b/kernel/src/drivers/ethernet/intel_i217.cpp @@ -24,7 +24,8 @@ using namespace memory; intel_i217::intel_i217(PeripheralComponentInterconnectDeviceDescriptor *deviceDescriptor, InterruptManager *interruptManager, OutputStream* intelNetMessageStream) : EthernetDriver(intelNetMessageStream), - InterruptHandler(deviceDescriptor->interrupt + interruptManager->HardwareInterruptOffset(), interruptManager) + InterruptHandler(deviceDescriptor->interrupt + + interruptManager->hardware_interrupt_offset(), interruptManager) { @@ -50,9 +51,9 @@ intel_i217::intel_i217(PeripheralComponentInterconnectDeviceDescriptor *deviceDe sendDescriptorTailRegister = 0x3818; // Get BAR0 type, io_base address and MMIO base address - bar_type = 1; // deviceDescriptor -> hasMemoryBase ? 0 : 1; //TODO: Fix memory mapping from PCI as it is unable to get MAC from memory - portBase = deviceDescriptor -> portBase; - //TODO: memBase = deviceDescriptor -> memoryBase; + bar_type = 1; // deviceDescriptor -> has_memory_base ? 0 : 1; //TODO: Fix memory mapping from PCI as it is unable to get MAC from memory + portBase = deviceDescriptor ->port_base; + //TODO: memBase = deviceDescriptor -> memory_base; initDone = false; active = false; @@ -69,7 +70,7 @@ intel_i217::intel_i217(PeripheralComponentInterconnectDeviceDescriptor *deviceDe }else{ - errorMessage("ERROR, INIT FAILED, MAC ADDRESS NOT FOUND"); + error_message("ERROR, INIT FAILED, MAC ADDRESS NOT FOUND"); while (true); } @@ -93,15 +94,15 @@ void intel_i217::Write(uint16_t address, uint32_t data) { if(bar_type == 0) { // If the base address register is memory mapped MemIO32Bit dataMem(memBase + address); // Create a 32 bit memory class at the address - dataMem.Write(data); // Write the data to the memory adress + dataMem.write(data); // write the data to the memory adress } else { Port32Bit commandPort(portBase); // Create a 32 bit port at the address Port32Bit dataPort(portBase + 4); // Create a 32 bit port at the address + 4 - commandPort.Write(address); // Write the address to the command port - dataPort.Write(data); // Write the data to the data port + commandPort.write(address); // write the address to the command port + dataPort.write(data); // write the data to the data port } @@ -114,15 +115,15 @@ uint32_t intel_i217::Read(uint16_t address) { if(bar_type == 0) { // If the base address register is memory mapped MemIO32Bit dataMem(memBase + address); // Create a 32 bit memory class at the address - return dataMem.Read(); // Read the data from the memory adress + return dataMem.read(); // read the data from the memory adress } else{ Port32Bit commandPort(portBase); // Create a 32 bit port at the address Port32Bit dataPort(portBase + 4); // Create a 32 bit port at the address + 4 - commandPort.Write(address); // Write the address to the command port - return dataPort.Read(); // Read the data from the data port + commandPort.write(address); // write the address to the command port + return dataPort.read(); // read the data from the data port } @@ -135,7 +136,7 @@ bool intel_i217::detectEEProm() { for(int i = 0; i < 1000 && ! epromPresent; i++) //Loop 1000 times or until the EEProm is detected { - val = Read( 0x0014); // Read the register + val = Read( 0x0014); // read the register if(val & 0x10) // If the EEProm is detected epromPresent = true; @@ -151,12 +152,12 @@ uint32_t intel_i217::eepromRead( uint8_t addr) uint32_t tmp = 0; // A temporary variable if ( epromPresent) // If the EEProm is detected { - Write( epromRegister, (1) | ((uint32_t)(addr) << 8) ); // Write the address to the register + Write( epromRegister, (1) | ((uint32_t)(addr) << 8) ); // write the address to the register while( !((tmp = Read(epromRegister)) & (1 << 4)) ); // Wait for the EEProm to be ready } else { - Write( epromRegister, (1) | ((uint32_t)(addr) << 2) ); // Write the address to the register + Write( epromRegister, (1) | ((uint32_t)(addr) << 2) ); // write the address to the register while( !((tmp = Read(epromRegister)) & (1 << 1)) ); // Wait for the EEProm to be ready } data = (uint16_t)((tmp >> 16) & 0xFFFF); // Get the data from the register @@ -168,15 +169,15 @@ bool intel_i217::readMACAddress() { { uint32_t temp; - temp = eepromRead(0); //Read the first 16 bits of the MAC address - macAddress[0] = temp &0xff; //Get the first 8 bits of the MAC address + temp = eepromRead(0); //read the m_first_memory_chunk 16 bits of the MAC address + macAddress[0] = temp &0xff; //Get the m_first_memory_chunk 8 bits of the MAC address macAddress[1] = temp >> 8; //Get the second 8 bits of the MAC address - temp = eepromRead( 1); //Read the second 16 bits of the MAC address + temp = eepromRead( 1); //read the second 16 bits of the MAC address macAddress[2] = temp &0xff; //Get the third 8 bits of the MAC address macAddress[3] = temp >> 8; //Get the fourth 8 bits of the MAC address - temp = eepromRead( 2); //Read the third 16 bits of the MAC address + temp = eepromRead( 2); //read the third 16 bits of the MAC address macAddress[4] = temp &0xff; //Get the fifth 8 bits of the MAC address macAddress[5] = temp >> 8; //Get the sixth 8 bits of the MAC address } @@ -202,21 +203,22 @@ void intel_i217::receiveInit() { uint8_t * ptr; //A pointer to the memory struct receiveDescriptor *descs; //A pointer to the receive descriptors - ptr = (uint8_t *)(MemoryManager::activeMemoryManager->malloc(sizeof(struct receiveDescriptor)*32 + 16)); //Allocate memory for the receive descriptors + ptr = (uint8_t *)(MemoryManager::s_active_memory_manager->malloc(sizeof(struct receiveDescriptor)*32 + 16)); //Allocate memory for the receive descriptors descs = (struct receiveDescriptor *)ptr; //Set the pointer to the receive descriptors for(int i = 0; i < 32; i++) { receiveDsrctrs[i] = (struct receiveDescriptor *)((uint8_t *)descs + i*16); - receiveDsrctrs[i] -> bufferAddress = (uint64_t)(uint8_t *)(MemoryManager::activeMemoryManager->malloc(8192 + 16)); + receiveDsrctrs[i] -> bufferAddress = (uint64_t)(uint8_t *)(MemoryManager::s_active_memory_manager + ->malloc(8192 + 16)); receiveDsrctrs[i] -> status = 0; } - //Write the send descriptor list address to the register + //write the send descriptor list address to the register Write(sendDescriptorLowRegister, (uint32_t)((uint64_t)ptr >> 32) ); Write(sendDescriptorHighRegister, (uint32_t)((uint64_t)ptr & 0xFFFFFFFF)); - //Write the recieve descriptor list address to the register + //write the recieve descriptor list address to the register Write(receiveDescriptorLowRegister, (uint64_t)ptr); Write(receiveDescriptorHighRegister, 0); @@ -246,7 +248,7 @@ void intel_i217::sendInit() { uint8_t * ptr; //A pointer to the memory struct sendDescriptor *descs; //A pointer to the send descriptors - ptr = (uint8_t *)(MemoryManager::activeMemoryManager->malloc(sizeof(struct sendDescriptor)*8 + 16)); //Allocate memory for the send descriptors + ptr = (uint8_t *)(MemoryManager::s_active_memory_manager->malloc(sizeof(struct sendDescriptor)*8 + 16)); //Allocate memory for the send descriptors descs = (struct sendDescriptor *)ptr; //Set the pointer to the send descriptors @@ -258,7 +260,7 @@ void intel_i217::sendInit() { sendDsrctrs[i] -> status = (1 << 0); // Descriptor Done } - //Write the send descriptor list address to the register + //write the send descriptor list address to the register Write(sendDescriptorHighRegister, (uint32_t)((uint64_t)ptr >> 32) ); Write(sendDescriptorLowRegister, (uint32_t)((uint64_t)ptr & 0xFFFFFFFF)); @@ -282,14 +284,14 @@ void intel_i217::sendInit() { // In the case of I217 (id = 0x0410) and 82577LM (id = 0x10EA) packets will not be sent if the TCTRL is not configured using the following bits. - // Write(sendControlRegister, 0b0110000000000111111000011111010); - //Write(0x0410, 0x0060200A); + // write(sendControlRegister, 0b0110000000000111111000011111010); + //write(0x0410, 0x0060200A); } void intel_i217::activate() { - driverMessageStream -> write("Activating Intel i217\n"); + m_driver_message_stream-> write("Activating Intel i217\n"); //Enable interrupts Write(interruptMaskRegister ,0x1F6DC); //Enable all interrupts @@ -303,25 +305,27 @@ void intel_i217::activate() { sendInit(); active = true; // Set active to true - driverMessageStream -> write("Intel i217 INIT DONE\n"); + m_driver_message_stream-> write("Intel i217 INIT DONE\n"); } -void intel_i217::HandleInterrupt() { +void intel_i217::handle_interrupt() { Write(interruptMaskRegister, 0x1); //Clear the interrupt or it will hang - uint32_t temp = Read(0xc0); //Read the interrupt status register + uint32_t temp = Read(0xc0); //read the interrupt status register - driverMessageStream -> write("Interrupt from INTEL i217"); + m_driver_message_stream-> write("Interrupt from INTEL i217"); - if(temp & 0x04) driverMessageStream -> write("INTEL i217 START LINK");//initDone = true; - if(temp & 0x10) driverMessageStream -> write("INTEL i217 GOOD THRESHOLD"); + if(temp & 0x04) + m_driver_message_stream-> write("INTEL i217 START LINK");//initDone = true; + if(temp & 0x10) + m_driver_message_stream-> write("INTEL i217 GOOD THRESHOLD"); if(temp & 0x80) FetchDataReceived(); } void intel_i217::FetchDataReceived() { - driverMessageStream -> write("Fetching data... "); + m_driver_message_stream-> write("Fetching data... "); uint16_t old_cur; bool got_packet = false; @@ -344,14 +348,14 @@ void intel_i217::FetchDataReceived() { old_cur = currentReceiveBuffer; //Save the current receive buffer currentReceiveBuffer = (currentReceiveBuffer + 1) % 32; //Increment the current receive buffer - Write(receiveDescriptorTailRegister, old_cur ); //Write the old current receive buffer to the tail register + Write(receiveDescriptorTailRegister, old_cur ); //write the old current receive buffer to the tail register } } void intel_i217::DoSend(uint8_t* buffer, uint32_t size) { - driverMessageStream -> write("Sending package... "); + m_driver_message_stream-> write("Sending package... "); while(!active); //Put params into send buffer @@ -368,16 +372,16 @@ void intel_i217::DoSend(uint8_t* buffer, uint32_t size) { uint8_t old_cur = currentSendBuffer; //Save the current send buffer currentSendBuffer = (currentSendBuffer + 1) % 8; //Increment the current send buffer - Write(sendDescriptorTailRegister, currentSendBuffer); //Write the current send buffer to the tail register + Write(sendDescriptorTailRegister, currentSendBuffer); //write the current send buffer to the tail register //Wait for the packet to be sent while(!(sendDsrctrs[old_cur]->status & 0xff)); - driverMessageStream -> write(" Done\n"); + m_driver_message_stream-> write(" Done\n"); } uint64_t intel_i217::GetMediaAccessControlAddress() { - driverMessageStream -> write("Getting MAC address... "); + m_driver_message_stream-> write("Getting MAC address... "); while(ownMAC == 0); return ownMAC; @@ -391,11 +395,11 @@ void intel_i217::deactivate() { Driver::deactivate(); } -string intel_i217::getVendorName() { +string intel_i217::get_vendor_name() { return "Intel"; } -string intel_i217::getDeviceName() { +string intel_i217::get_device_name() { return "E1000 (i217)"; } diff --git a/kernel/src/drivers/peripherals/keyboard.cpp b/kernel/src/drivers/peripherals/keyboard.cpp index e3f04f92..d28d3af5 100644 --- a/kernel/src/drivers/peripherals/keyboard.cpp +++ b/kernel/src/drivers/peripherals/keyboard.cpp @@ -23,24 +23,44 @@ KeyboardEventHandler::~KeyboardEventHandler() { }; -void KeyboardEventHandler::onKeyDown(KeyCode keyDownCode, KeyboardState keyDownState) +/** + * @brief Handle the key down event + * + * @param key_down_code The keycode of the key that was pressed + * @param key_down_state The state of the keyboard when the key was pressed + */ +void KeyboardEventHandler::on_key_down(KeyCode key_down_code, KeyboardState key_down_state) { } -void KeyboardEventHandler::onKeyUp(KeyCode keyUpCode, KeyboardState keyUpState) +/** + * @brief Handle the key up event + * + * @param key_up_code The keycode of the key that was released + * @param key_up_state The state of the keyboard when the key was released + */ +void KeyboardEventHandler::on_key_up(KeyCode key_up_code, KeyboardState key_up_state) { } -Event* KeyboardEventHandler::onEvent(Event *event) { +/** + * @brief Handle the trigger of an event + * + * @param event The event to handle + * @return The event that was passed with the data modified + */ +Event* KeyboardEventHandler::on_event(Event *event) { switch (event -> type) { case KeyboardEvents::KEYDOWN: - this->onKeyDown(((KeyDownEvent*)event)->keyCode, ((KeyDownEvent*)event)->keyboardState); + this->on_key_down(((KeyDownEvent *)event)->key_code, + ((KeyDownEvent *)event)->keyboard_state); break; case KeyboardEvents::KEYUP: - this->onKeyUp(((KeyUpEvent*)event)->keyCode, ((KeyUpEvent*)event)->keyboardState); + this->on_key_up(((KeyUpEvent *)event)->key_code, + ((KeyUpEvent *)event)->keyboard_state); break; default: @@ -48,7 +68,6 @@ Event* KeyboardEventHandler::onEvent(Event *even } return event; - } @@ -56,9 +75,9 @@ Event* KeyboardEventHandler::onEvent(Event *even ///___Driver___ KeyboardDriver::KeyboardDriver(InterruptManager* manager) - : InterruptHandler(0x21, manager), - dataPort(0x60), - commandPort(0x64) +: InterruptHandler(0x21, manager), + m_data_port(0x60), + m_command_port(0x64) { } KeyboardDriver::~KeyboardDriver(){ @@ -66,65 +85,55 @@ KeyboardDriver::~KeyboardDriver(){ } /** - * @details Activate the keyboard driver + * @brief activate the keyboard driver */ void KeyboardDriver::activate() { - while (commandPort.Read() & 0x1) //Wait for user to stop pressing key (this is for the start-up key eg.. hold 'F12' for boot menu or hold 'del' for bios ), The wait is needed as the keyboard controller won't send anymore characters until the buffer has been read - dataPort.Read(); - - commandPort.Write(0xAE); // Tell: PIC to send keyboard interrupt [or] tell keyboard to send interrupts to PIC - commandPort.Write(0x20); // Tell: get current state - uint8_t status = (dataPort.Read() | 1) & ~ 0x10; // Read current state then set rightmost bit to 1 becuase this will be the new state and clear the bit - commandPort.Write(0x60); // Tell: change current state - dataPort.Write(status); // Write back the current state - - dataPort.Write(0xF4); // Final Activation of keyboard - - //Keyboard Controller Commands : - // - //0xAE : Enable Keyboard - //0x20 : Read command byte , after that read the status from data port - //0x60 : Write command byte , after that change the state of the data port + + // Wait for user to stop pressing key (this is for the start-up key eg.. hold 'F12' for boot menu or hold 'del' for bios ) + while (m_command_port.read() & 0x1) + m_data_port.read(); + + // Enable keyboard interrupts + m_command_port.write(0xAE); + + // Get the current state of the keyboard + m_command_port.write(0x20); + uint8_t status = (m_data_port.read() | 1) & ~ 0x10; + + // Reset the keyboard + m_command_port.write(0x60); + m_data_port.write(status); + + // activate the keyboard + m_data_port.write(0xF4); } /** - * @details Handle the keyboard interrupt - * - * @param esp The stack pointer - * @return returns the passed esp + * @brief deactivate the keyboard driver */ -void KeyboardDriver::HandleInterrupt(){ +void KeyboardDriver::handle_interrupt(){ - // Read the scancode from the keyboard - uint8_t key = dataPort.Read(); //NOTE: The 8th bit is set to 1 if key is released and cleared to 0 if key is pressed + // read the scancode from the keyboard + uint8_t key = m_data_port.read(); - // Pass the scan code to the handlers - for(Vector*>::iterator streamEventHandler = inputStreamEventHandlers.begin(); streamEventHandler != inputStreamEventHandlers.end(); streamEventHandler++) - (*streamEventHandler)->onStreamRead(key); + // Pass the scan code to the m_handlers + for(auto& handler : this -> m_input_stream_event_handlers){ + handler -> on_stream_read(key); + } } -string KeyboardDriver::getDeviceName() { +/** + * @brief Get the device name + * @return The device name + */ +string KeyboardDriver::get_device_name() { return "Keyboard"; } ///___State___ -/** - * @details Initialise the keyboard stat with the default values being false - */ -KeyboardState::KeyboardState() { - - this -> leftShift = false; - this -> rightShift = false; - this -> leftControl = false; - this -> rightControl = false; - this -> leftAlt = false; - this -> rightAlt = false; - - this -> capsLock = false; - this -> numberPadLock = false; - this -> scrollLock = false; +KeyboardState::KeyboardState() { } @@ -138,31 +147,19 @@ KeyboardInterpreter::KeyboardInterpreter() : InputStreamEventHandler() { - // Extended codes are none by default - this -> nextIsExtendedCode0 = false; - this -> currentExtendedCode1 = 0; - this -> extendedCode1Buffer = 0; - } KeyboardInterpreter::~KeyboardInterpreter() { } -void KeyboardInterpreter::onKeyRead(bool released, KeyboardState state, KeyCode keyCode) { - - // Check if the key is released or pressed - if(released){ - - // Pass the release event to the handlers - raiseEvent(new KeyUpEvent(keyCode, state)); - - // Event handled - return; - } +void KeyboardInterpreter::onKeyRead(bool released, KeyboardState state, KeyCode key_code) { - // Pass the press event to the handlers - raiseEvent(new KeyDownEvent(keyCode, state)); + // Pass the key event to the handlers + if(released) + raise_event(new KeyUpEvent(key_code, state)); + else + raise_event(new KeyDownEvent(key_code, state)); } @@ -178,309 +175,342 @@ KeyboardInterpreterEN_US::~KeyboardInterpreterEN_US() { } -void KeyboardInterpreterEN_US::onStreamRead(uint8_t scanCode) { +void KeyboardInterpreterEN_US::on_stream_read(uint8_t scan_code) { - int keyType = 0; // Initialize keyType to 0 (0 represents a regular keypress) + // 0 is a regular key, 1 is an extended code, 2 is an extended code with e1CodeBuffer + int keyType = 0; - // Check if the key was released (bit 7 set) and certain conditions are met - bool released = (scanCode & 0x80) && (currentExtendedCode1 || (scanCode != 0xe1)) && (nextIsExtendedCode0 || (scanCode != 0xe0)); + // Check if the key was released + bool released = (scan_code & 0x80) && (m_current_extended_code_1 || (scan_code != 0xe1)) && (m_next_is_extended_code_0 || (scan_code != 0xe0)); - // If the key is released, clear bit 7 (make it a regular key) + // Clear the released bit if (released) - scanCode &= ~0x80; + scan_code &= ~0x80; - // If the scanCode is 0xe0, it indicates an extended code - if (scanCode == 0xe0) + // Set the e0Code flag to true + if (scan_code == 0xe0) { - nextIsExtendedCode0 = true; // Set the e0Code flag to true - return; + m_next_is_extended_code_0 = true; + return; } // If e0Code is true, set keyType to 1 and reset e0Code - if (nextIsExtendedCode0) + if (m_next_is_extended_code_0) { keyType = 1; - nextIsExtendedCode0 = false; + m_next_is_extended_code_0 = false; - // Check if the scanCode represents a shift key and return (fake shift) - if ((KeyboardInterpreterEN_US::KeyCodeEN_US)scanCode == KeyboardInterpreterEN_US::leftShift || (KeyboardInterpreterEN_US::KeyCodeEN_US)scanCode == KeyboardInterpreterEN_US::rightShift) + // Check if the scan_code represents a shift key and return (fake shift) + if ((KeyboardInterpreterEN_US::KeyCodeEN_US)scan_code == KeyboardInterpreterEN_US::leftShift || (KeyboardInterpreterEN_US::KeyCodeEN_US)scan_code == KeyboardInterpreterEN_US::rightShift) return; } - // If the scanCode is 0xe1, set the e1Code flag to 1 and return - if (scanCode == 0xe1) + // If the scan_code is 0xe1, set the e1Code flag to 1 and return + if (scan_code == 0xe1) { - currentExtendedCode1 = 1; - return; + m_current_extended_code_1 = 1; + return; } - // If e1Code is 1, set e1Code to 2, store the scanCode in e1CodeBuffer, and return - if (currentExtendedCode1 == 1) + // If e1Code is 1, set e1Code to 2, store the scan_code in e1CodeBuffer, and return + if (m_current_extended_code_1 == 1) { - currentExtendedCode1 = 2; - extendedCode1Buffer = scanCode; - return; + m_current_extended_code_1 = 2; + m_extended_code_1_buffer = scan_code; + return; } // If e1Code is 2, set keyType to 2, reset e1Code, and update e1CodeBuffer - if (currentExtendedCode1 == 2) + if (m_current_extended_code_1 == 2) { keyType = 2; - currentExtendedCode1 = 0; - extendedCode1Buffer |= (((uint16_t)scanCode) << 8); + m_current_extended_code_1 = 0; + m_extended_code_1_buffer |= (((uint16_t)scan_code) << 8); } - bool isShifting = this -> keyBoardState.leftShift || this -> keyBoardState.rightShift; - bool shouldBeUpperCase = isShifting != this -> keyBoardState.capsLock; + bool is_shifting = this ->m_keyboard_state.left_shift || this ->m_keyboard_state.right_shift; + bool should_be_upper_case = is_shifting != this ->m_keyboard_state.caps_lock; // TODO: Probabbly a better way to do this if(keyType == 0) - switch ((KeyCodeEN_US)scanCode) { + switch ((KeyCodeEN_US)scan_code) { // First row case KeyCodeEN_US::escape: - onKeyRead(released, this -> keyBoardState, KeyCode::escape); + onKeyRead(released, this ->m_keyboard_state, KeyCode::escape); break; case KeyCodeEN_US::f1: - onKeyRead(released, this -> keyBoardState, KeyCode::f1); + onKeyRead(released, this ->m_keyboard_state, KeyCode::f1); break; case KeyCodeEN_US::f2: - onKeyRead(released, this -> keyBoardState, KeyCode::f2); + onKeyRead(released, this ->m_keyboard_state, KeyCode::f2); break; case KeyCodeEN_US::f3: - onKeyRead(released, this -> keyBoardState, KeyCode::f3); + onKeyRead(released, this ->m_keyboard_state, KeyCode::f3); break; case KeyCodeEN_US::f4: - onKeyRead(released, this -> keyBoardState, KeyCode::f4); + onKeyRead(released, this ->m_keyboard_state, KeyCode::f4); break; case KeyCodeEN_US::f5: - onKeyRead(released, this -> keyBoardState, KeyCode::f5); + onKeyRead(released, this ->m_keyboard_state, KeyCode::f5); break; case KeyCodeEN_US::f6: - onKeyRead(released, this -> keyBoardState, KeyCode::f6); + onKeyRead(released, this ->m_keyboard_state, KeyCode::f6); break; case KeyCodeEN_US::f7: - onKeyRead(released, this -> keyBoardState, KeyCode::f7); + onKeyRead(released, this ->m_keyboard_state, KeyCode::f7); break; case KeyCodeEN_US::f8: - onKeyRead(released, this -> keyBoardState, KeyCode::f8); + onKeyRead(released, this ->m_keyboard_state, KeyCode::f8); break; case KeyCodeEN_US::f9: - onKeyRead(released, this -> keyBoardState, KeyCode::f9); + onKeyRead(released, this ->m_keyboard_state, KeyCode::f9); break; case KeyCodeEN_US::f10: - onKeyRead(released, this -> keyBoardState, KeyCode::f10); + onKeyRead(released, this ->m_keyboard_state, KeyCode::f10); break; case KeyCodeEN_US::f11: - onKeyRead(released, this -> keyBoardState, KeyCode::f11); + onKeyRead(released, this ->m_keyboard_state, KeyCode::f11); break; case KeyCodeEN_US::f12: - onKeyRead(released, this -> keyBoardState, KeyCode::f12); + onKeyRead(released, this ->m_keyboard_state, KeyCode::f12); break; case KeyCodeEN_US::printScreen: - onKeyRead(released, this -> keyBoardState, this -> keyBoardState.numberPadLock ? KeyCode::numberPadMultiply : KeyCode::printScreen); + onKeyRead(released, this ->m_keyboard_state, this ->m_keyboard_state.number_pad_lock + ? KeyCode::numberPadMultiply : KeyCode::printScreen); break; case KeyCodeEN_US::scrollLock: - onKeyRead(released, this -> keyBoardState, KeyCode::scrollLock); + onKeyRead(released, this ->m_keyboard_state, KeyCode::scrollLock); break; /* * TODO: Implement pause/break, it conflicts with numlock, I prefer numlock so that is why it is not implemented case KeyCodeEN_US::pauseBreak: - onKeyRead(released, this -> keyBoardState, KeyCode::pauseBreak); + onKeyRead(released, this -> m_keyboard_state, KeyCode::pauseBreak); break; */ // Second row case KeyCodeEN_US::squigglyLine: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::squigglyLine : KeyCode::slantedApostrophe); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::squigglyLine : KeyCode::slantedApostrophe); break; case KeyCodeEN_US::one: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::exclamationMark : KeyCode::one); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::exclamationMark : KeyCode::one); break; case KeyCodeEN_US::two: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::atSign: KeyCode::two); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::atSign: KeyCode::two); break; case KeyCodeEN_US::three: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::hash : KeyCode::three); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::hash : KeyCode::three); break; case KeyCodeEN_US::four: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::dollarSign : KeyCode::four); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::dollarSign : KeyCode::four); break; case KeyCodeEN_US::five: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::percentSign : KeyCode::five); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::percentSign : KeyCode::five); break; case KeyCodeEN_US::six: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::powerSign : KeyCode::six); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::powerSign : KeyCode::six); break; case KeyCodeEN_US::seven: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::andSign : KeyCode::seven); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::andSign : KeyCode::seven); break; case KeyCodeEN_US::eight: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::multiply : KeyCode::eight); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::multiply : KeyCode::eight); break; case KeyCodeEN_US::nine: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::openBracket : KeyCode::nine); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::openBracket : KeyCode::nine); break; case KeyCodeEN_US::zero: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::closeBracket : KeyCode::zero); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::closeBracket : KeyCode::zero); break; case KeyCodeEN_US::minus: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::underscore : KeyCode::minus); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::underscore : KeyCode::minus); break; case KeyCodeEN_US::equals: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::plus : KeyCode::equals); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::plus : KeyCode::equals); break; case KeyCodeEN_US::backspace: - onKeyRead(released, this -> keyBoardState, KeyCode::backspace); + onKeyRead(released, this ->m_keyboard_state, KeyCode::backspace); break; case KeyCodeEN_US::insert: - onKeyRead(released, this -> keyBoardState, this -> keyBoardState.numberPadLock ? KeyCode::numberPadZero : KeyCode::insert); + onKeyRead(released, this ->m_keyboard_state, this ->m_keyboard_state.number_pad_lock ? KeyCode::numberPadZero : KeyCode::insert); break; case KeyCodeEN_US::home: - onKeyRead(released, this -> keyBoardState, this -> keyBoardState.numberPadLock ? KeyCode::numberPadSeven : KeyCode::home); + onKeyRead(released, this ->m_keyboard_state, this ->m_keyboard_state.number_pad_lock + ? KeyCode::numberPadSeven : KeyCode::home); break; case KeyCodeEN_US::pageUp: - onKeyRead(released, this -> keyBoardState, this -> keyBoardState.numberPadLock ? KeyCode::numberPadNine : KeyCode::pageUp); + onKeyRead(released, this ->m_keyboard_state, this ->m_keyboard_state.number_pad_lock ? KeyCode::numberPadNine : KeyCode::pageUp); break; case KeyCodeEN_US::numberPadLock: // Ensure this is not a repeat if(!released){ - this -> keyBoardState.numberPadLock = !this -> keyBoardState.numberPadLock; + this ->m_keyboard_state.number_pad_lock = !this ->m_keyboard_state.number_pad_lock; } - onKeyRead(released, this -> keyBoardState, KeyCode::numberPadLock); + onKeyRead(released, this ->m_keyboard_state, KeyCode::numberPadLock); break; case KeyCodeEN_US::numberPadForwardSlash: // Check if number pad lock is on - if(this -> keyBoardState.numberPadLock){ - onKeyRead(released, this -> keyBoardState, KeyCode::numberPadForwardSlash); + if(this ->m_keyboard_state.number_pad_lock){ + onKeyRead(released, this ->m_keyboard_state, KeyCode::numberPadForwardSlash); }else{ // Normal Forward Slash - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::questionMark : KeyCode::forwardSlash); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::questionMark : KeyCode::forwardSlash); } break; // Number Pad Multiply is same as print screen case KeyCodeEN_US::numberPadMinus: - onKeyRead(released, this -> keyBoardState, KeyCode::numberPadMinus); + onKeyRead(released, this ->m_keyboard_state, KeyCode::numberPadMinus); break; // Third row case KeyCodeEN_US::tab: - onKeyRead(released, this -> keyBoardState, KeyCode::tab); + onKeyRead(released, this ->m_keyboard_state, KeyCode::tab); break; case KeyCodeEN_US::Q: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::Q : KeyCode::q); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::Q : KeyCode::q); break; case KeyCodeEN_US::W: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::W : KeyCode::w); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::W : KeyCode::w); break; case KeyCodeEN_US::E: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::E : KeyCode::e); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::E : KeyCode::e); break; case KeyCodeEN_US::R: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::R : KeyCode::r); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::R : KeyCode::r); break; case KeyCodeEN_US::T: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::T : KeyCode::t); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::T : KeyCode::t); break; case KeyCodeEN_US::Y: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::Y : KeyCode::y); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::Y : KeyCode::y); break; case KeyCodeEN_US::U: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::U : KeyCode::u); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::U : KeyCode::u); break; case KeyCodeEN_US::I: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::I : KeyCode::i); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::I : KeyCode::i); break; case KeyCodeEN_US::O: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::O : KeyCode::o); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::O : KeyCode::o); break; case KeyCodeEN_US::P: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::P : KeyCode::p); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::P : KeyCode::p); break; case KeyCodeEN_US::openSquareBracket: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::openCurlyBracket : KeyCode::openSquareBracket); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::openCurlyBracket : KeyCode::openSquareBracket); break; case KeyCodeEN_US::closeSquareBracket: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::closeCurlyBracket : KeyCode::closeSquareBracket); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::closeCurlyBracket : KeyCode::closeSquareBracket); break; case KeyCodeEN_US::backslash: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::lineThing : KeyCode::backslash); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::lineThing : KeyCode::backslash); break; case KeyCodeEN_US::deleteKey: - onKeyRead(released, this -> keyBoardState, this -> keyBoardState.numberPadLock ? KeyCode::numberPadFullStop : KeyCode::deleteKey); + onKeyRead(released, this ->m_keyboard_state, this ->m_keyboard_state.number_pad_lock + ? KeyCode::numberPadFullStop : KeyCode::deleteKey); break; case KeyCodeEN_US::end: - onKeyRead(released, this -> keyBoardState, this -> keyBoardState.numberPadLock ? KeyCode::numberPadOne : KeyCode::end); + onKeyRead(released, this ->m_keyboard_state, this ->m_keyboard_state.number_pad_lock ? KeyCode::numberPadOne : KeyCode::end); break; case KeyCodeEN_US::pageDown: - onKeyRead(released, this -> keyBoardState, this -> keyBoardState.numberPadLock ? KeyCode::numberPadThree : KeyCode::pageDown); + onKeyRead(released, this ->m_keyboard_state, this ->m_keyboard_state.number_pad_lock + ? KeyCode::numberPadThree : KeyCode::pageDown); break; // Number pad 7 is same as home case KeyCodeEN_US::numberPadEight: - onKeyRead(released, this -> keyBoardState, this -> keyBoardState.numberPadLock ? KeyCode::numberPadEight : KeyCode::upArrow); + onKeyRead(released, this ->m_keyboard_state, this ->m_keyboard_state.number_pad_lock + ? KeyCode::numberPadEight : KeyCode::upArrow); break; // Number pad 9 is same as page up case KeyCodeEN_US::numberPadPlus: - onKeyRead(released, this -> keyBoardState, KeyCode::numberPadPlus); + onKeyRead(released, this ->m_keyboard_state, KeyCode::numberPadPlus); break; // Fourth row @@ -488,116 +518,133 @@ void KeyboardInterpreterEN_US::onStreamRead(uint8_t scanCode) { case KeyCodeEN_US::capsLock: // Ensure this is not a repeat if(!released){ - this -> keyBoardState.capsLock = !this -> keyBoardState.capsLock; + this ->m_keyboard_state.caps_lock = !this ->m_keyboard_state.caps_lock; } - onKeyRead(released, this -> keyBoardState, KeyCode::capsLock); + onKeyRead(released, this ->m_keyboard_state, KeyCode::capsLock); break; case KeyCodeEN_US::A: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::A : KeyCode::a); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::A : KeyCode::a); break; case KeyCodeEN_US::S: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::S : KeyCode::s); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::S : KeyCode::s); break; case KeyCodeEN_US::D: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::D : KeyCode::d); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::D : KeyCode::d); break; case KeyCodeEN_US::F: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::F : KeyCode::f); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::F : KeyCode::f); break; case KeyCodeEN_US::G: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::G : KeyCode::g); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::G : KeyCode::g); break; case KeyCodeEN_US::H: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::H : KeyCode::h); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::H : KeyCode::h); break; case KeyCodeEN_US::J: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::J : KeyCode::j); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::J : KeyCode::j); break; case KeyCodeEN_US::K: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::K : KeyCode::k); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::K : KeyCode::k); break; case KeyCodeEN_US::L: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::L : KeyCode::l); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::L : KeyCode::l); break; case KeyCodeEN_US::semicolon: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::colon : KeyCode::semicolon); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::colon : KeyCode::semicolon); break; case KeyCodeEN_US::apostrophe: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::quotationMark : KeyCode::apostrophe); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::quotationMark : KeyCode::apostrophe); break; case KeyCodeEN_US::enter: - onKeyRead(released, this -> keyBoardState, this -> keyBoardState.numberPadLock ? KeyCode::numberPadEnter : KeyCode::enter); + onKeyRead(released, this ->m_keyboard_state, this ->m_keyboard_state.number_pad_lock + ? KeyCode::numberPadEnter : KeyCode::enter); break; case KeyCodeEN_US::numberPadFour: - onKeyRead(released, this -> keyBoardState, this -> keyBoardState.numberPadLock ? KeyCode::numberPadFour : KeyCode::leftArrow); + onKeyRead(released, this ->m_keyboard_state, this ->m_keyboard_state.number_pad_lock ? KeyCode::numberPadFour : KeyCode::leftArrow); break; case KeyCodeEN_US::numberPadFive: - onKeyRead(released, this -> keyBoardState, KeyCode::numberPadFive); + onKeyRead(released, this ->m_keyboard_state, KeyCode::numberPadFive); break; case KeyCodeEN_US::numberPadSix: - onKeyRead(released, this -> keyBoardState, this -> keyBoardState.numberPadLock ? KeyCode::numberPadSix : KeyCode::rightArrow); + onKeyRead(released, this ->m_keyboard_state, this ->m_keyboard_state.number_pad_lock ? KeyCode::numberPadSix : KeyCode::rightArrow); break; // Fifth row case KeyCodeEN_US::leftShift: - // Check if this is a repeat - if(!released){ - this -> keyBoardState.leftShift = !this -> keyBoardState.leftShift; - } - - onKeyRead(released, this -> keyBoardState, KeyCode::leftShift); + this ->m_keyboard_state.left_shift = !this ->m_keyboard_state.left_shift; + onKeyRead(released, this ->m_keyboard_state, KeyCode::leftShift); break; case KeyCodeEN_US::Z: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::Z : KeyCode::z); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::Z : KeyCode::z); break; case KeyCodeEN_US::X: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::X : KeyCode::x); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::X : KeyCode::x); break; case KeyCodeEN_US::C: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::C : KeyCode::c); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::C : KeyCode::c); break; case KeyCodeEN_US::V: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::V : KeyCode::v); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::V : KeyCode::v); break; case KeyCodeEN_US::B: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::B : KeyCode::b); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::B : KeyCode::b); break; case KeyCodeEN_US::N: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::N : KeyCode::n); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::N : KeyCode::n); break; case KeyCodeEN_US::M: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::M : KeyCode::m); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::M : KeyCode::m); break; case KeyCodeEN_US::comma: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::lessThan : KeyCode::comma); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::lessThan : KeyCode::comma); break; case KeyCodeEN_US::fullStop: - onKeyRead(released, this -> keyBoardState, shouldBeUpperCase ? KeyCode::greaterThan : KeyCode::fullStop); + onKeyRead(released, this ->m_keyboard_state, + should_be_upper_case ? KeyCode::greaterThan : KeyCode::fullStop); break; // Forward slash is same as number pad forward slash @@ -605,10 +652,10 @@ void KeyboardInterpreterEN_US::onStreamRead(uint8_t scanCode) { case KeyCodeEN_US::rightShift: // Check if this is a repeat if(!released){ - this -> keyBoardState.rightShift = !this -> keyBoardState.rightShift; + this ->m_keyboard_state.right_shift = !this ->m_keyboard_state.right_shift; } - onKeyRead(released, this -> keyBoardState, KeyCode::rightShift); + onKeyRead(released, this ->m_keyboard_state, KeyCode::rightShift); break; // Up Arrow is the same as number pad 8 @@ -616,7 +663,7 @@ void KeyboardInterpreterEN_US::onStreamRead(uint8_t scanCode) { // Number pad 1 is the same as end case KeyCodeEN_US::numberPadTwo: - onKeyRead(released, this -> keyBoardState, this -> keyBoardState.numberPadLock ? KeyCode::numberPadTwo : KeyCode::downArrow); + onKeyRead(released, this ->m_keyboard_state, this ->m_keyboard_state.number_pad_lock ? KeyCode::numberPadTwo : KeyCode::downArrow); break; // Number pad 3 is the same as page down @@ -627,29 +674,29 @@ void KeyboardInterpreterEN_US::onStreamRead(uint8_t scanCode) { case KeyCodeEN_US::leftControl: // Check if this is a repeat if(!released){ - this -> keyBoardState.leftControl = !this -> keyBoardState.leftControl; - this -> keyBoardState.rightControl = !this -> keyBoardState.rightControl; + this ->m_keyboard_state.left_control = !this ->m_keyboard_state.left_control; + this ->m_keyboard_state.right_control = !this ->m_keyboard_state.right_control; } - onKeyRead(released, this -> keyBoardState, KeyCode::leftControl); + onKeyRead(released, this ->m_keyboard_state, KeyCode::leftControl); break; case KeyCodeEN_US::leftOS: - onKeyRead(released, this -> keyBoardState, KeyCode::leftOS); + onKeyRead(released, this ->m_keyboard_state, KeyCode::leftOS); break; case KeyCodeEN_US::leftAlt: // Check if this is a repeat if(!released){ - this -> keyBoardState.leftAlt = !this -> keyBoardState.leftAlt; - this -> keyBoardState.rightAlt = !this -> keyBoardState.rightAlt; + this ->m_keyboard_state.left_alt = !this ->m_keyboard_state.left_alt; + this ->m_keyboard_state.right_alt = !this ->m_keyboard_state.right_alt; } - onKeyRead(released, this -> keyBoardState, KeyCode::leftAlt); + onKeyRead(released, this ->m_keyboard_state, KeyCode::leftAlt); break; case KeyCodeEN_US::space: - onKeyRead(released, this -> keyBoardState, KeyCode::space); + onKeyRead(released, this ->m_keyboard_state, KeyCode::space); break; // Right Alt is the same as left alt @@ -674,23 +721,23 @@ void KeyboardInterpreterEN_US::onStreamRead(uint8_t scanCode) { } KeyDownEvent::KeyDownEvent(KeyCode keyCode, KeyboardState keyboardState) -: Event(KeyboardEvents::KEYDOWN){ - this -> keyCode = keyCode; - this -> keyboardState = keyboardState; +: Event(KeyboardEvents::KEYDOWN), + key_code(keyCode), + keyboard_state(keyboardState) +{ } KeyDownEvent::~KeyDownEvent() { } -KeyUpEvent::KeyUpEvent(KeyCode keyCode, KeyboardState keyboardState) -: Event(KeyboardEvents::KEYUP){ - this -> keyCode = keyCode; - this -> keyboardState = keyboardState; +KeyUpEvent::KeyUpEvent(KeyCode key_code, KeyboardState keyboard_state) +: Event(KeyboardEvents::KEYUP), + key_code(key_code), + keyboard_state(keyboard_state) +{ } KeyUpEvent::~KeyUpEvent() { -} - - +} \ No newline at end of file diff --git a/kernel/src/drivers/peripherals/mouse.cpp b/kernel/src/drivers/peripherals/mouse.cpp index 1c9b048e..e492c1bb 100644 --- a/kernel/src/drivers/peripherals/mouse.cpp +++ b/kernel/src/drivers/peripherals/mouse.cpp @@ -17,22 +17,25 @@ MouseEventHandler::MouseEventHandler() { } /** - * @details This function is called when an event is triggered and calls the appropriate function + * @brief Handles the triggered event and calls the appropriate function * @param event The event that was triggered + * + * @return The event that was triggered with the modified data */ -Event* MouseEventHandler::onEvent(Event *event) { +Event* MouseEventHandler::on_event(Event *event) { switch (event->type){ case MOUSE_MOVE: - this->onMouseMoveEvent(((MouseMoveEvent*)event)->x, ((MouseMoveEvent*)event)->y); + this->on_mouse_move_event(((MouseMoveEvent *)event)->x, + ((MouseMoveEvent *)event)->y); break; case MOUSE_DOWN: - this->onMouseDownEvent(((MouseDownEvent*)event)->button); + this->on_mouse_down_event(((MouseDownEvent *)event)->button); break; case MOUSE_UP: - this->onMouseUpEvent(((MouseUpEvent*)event)->button); + this->on_mouse_up_event(((MouseUpEvent *)event)->button); break; } @@ -41,16 +44,31 @@ Event* MouseEventHandler::onEvent(Event *event) { return event; } - -void MouseEventHandler::onMouseDownEvent(uint8_t button){ +/** + * @brief Called when the mouse is pressed + * + * @param button The button that was pressed + */ +void MouseEventHandler::on_mouse_down_event(uint8_t button){ } -void MouseEventHandler::onMouseUpEvent(uint8_t button){ +/** + * @brief Called when the mouse is released + * + * @param button The button that was released + */ +void MouseEventHandler::on_mouse_up_event(uint8_t button){ } -void MouseEventHandler::onMouseMoveEvent(int8_t x, int8_t y){ +/** + * @brief Called when the mouse is moved + * + * @param x How much the mouse moved in the x direction + * @param y How much the mouse moved in the y direction + */ +void MouseEventHandler::on_mouse_move_event(int8_t x, int8_t y){ } @@ -61,86 +79,73 @@ MouseEventHandler::~MouseEventHandler() { ///__Driver__ MouseDriver::MouseDriver(InterruptManager* manager) - : InterruptHandler(0x2C, manager), //0x2C is mouse object, pass the manager paramerter to the base object - dataPort(0x60), - commandPort(0x64) +: InterruptHandler(0x2C, manager), + data_port(0x60), + command_port(0x64) { - offest = 2; - buttons = 0; + } MouseDriver::~MouseDriver(){ } /** - * @details Activate the mouse + * @brief activate the mouse */ void MouseDriver::activate() { + // Tell the PIC to start listening to the mouse + command_port.write(0xAB); + + // Get the current state of the mouse + command_port.write(0x20); + uint8_t status = (data_port.read() | 2); - commandPort.Write(0xAB); //Tell: PIC to send mouse interrupt [or] tell mouse to send interrupts to PIC - commandPort.Write(0x20); //Tell: get current state - uint8_t status = (dataPort.Read() | 2); //Read current state then set it to 2 becuase this will be the new state and clear the bit - commandPort.Write(0x60); //Tell: change current state - dataPort.Write(status); //Write back the current state + // write the new state + command_port.write(0x60); + data_port.write(status); - commandPort.Write(0xD4); //Forward commands - dataPort.Write(0xF4); //Final Activation of mouse - dataPort.Read(); + // activate the mouse + command_port.write(0xD4); + data_port.write(0xF4); + data_port.read(); - //Commands to the keyboard controller: (YES the keyboard) - //0xA8 | Activate mouse - //0xA7 | Deactivate mouse - //0x20 | Read command byte - //0x60 | Write command byte - //0xD4 | send the next command to the mouse instead of the keyboard - //Commands to the mouse controller: (Once forwarded) - //0xF4 | Tell the mouse to send data to the CPU , Enable Packet streaming when mouse is moved or clicked . - //0xF5 | Tell the mouse not to send any data to the CPU - //0xF6 | Reset mouse settings to default settings } /** - * @details Handle the mouse interrupt - * - * @param esp - * @return always returns esp - */ -void MouseDriver::HandleInterrupt(){ - - //The mouse triggers 3 interrupts , one for each byte . - //Byte 1 : Y overflow | X overflow | Y sign bit | X sign bit | Reserved (1) | Middle button pressed | Right button pressed | Left button pressed - //Byte 2 : X Movement since the last data packet. "delta X" value -- that is, it measures horizontal mouse movement, with left being negative. - //Byte 3 : Y Movement since the last data packet, "delta Y", with down (toward the user) being negative. + * @brief Handle the mouse interrupt - uint8_t status = commandPort.Read(); - if(!(status & 0x20)) //Only if the 6th bit of data is one then there is data to handle - return; //Otherwise don't bother handling this input + */ +void MouseDriver::handle_interrupt(){ + //Only if the 6th bit of data is one then there is data to handle + uint8_t status = command_port.read(); + if(!(status & 0x20)) + return; - buffer[offest] = dataPort.Read(); //Read mouse info into buffer - offest = (offest + 1) % 3; //Move through the offset + // read the data and store it in the buffer + buffer[offset] = data_port.read(); + offset = (offset + 1) % 3; - //If the mouse data transmission is incomplete (3rd piece of data isn't through) - if(offest != 0) + // If the mouse data transmission is incomplete (3rd piece of data isn't through) + if(offset != 0) return; - // If the mouse is moved (buffer 1 and 2 store x and y) + // If the mouse is moved (y-axis is inverted) if(buffer[1] != 0 || buffer[2] != 0) - raiseEvent(new MouseMoveEvent(buffer[1], -buffer[2])); // Flip the y axis + raise_event(new MouseMoveEvent(buffer[1], -buffer[2])); - //Detect button press for (int i = 0; i < 3; ++i) { - //Check if it's the same as the previous becuase if the current state of the buttons is not equal to the previous state of the buttons , then the button must have been pressed or released + // Check if the button state has changed if((buffer[0] & (0x1<(MouseEvents::MOUSE_UP) +: Event(MouseEvents::MOUSE_UP), + button(button) { - this->button = button; + } MouseUpEvent::~MouseUpEvent() { @@ -166,9 +177,9 @@ MouseUpEvent::~MouseUpEvent() { } MouseDownEvent::MouseDownEvent(uint8_t button) -: Event(MouseEvents::MOUSE_DOWN) +: Event(MouseEvents::MOUSE_DOWN), + button(button) { - this->button = button; } MouseDownEvent::~MouseDownEvent() { @@ -176,10 +187,10 @@ MouseDownEvent::~MouseDownEvent() { } MouseMoveEvent::MouseMoveEvent(int8_t x, int8_t y) -: Event(MouseEvents::MOUSE_MOVE) +: Event(MouseEvents::MOUSE_MOVE), + x(x), + y(y) { - this->x = x; - this->y = y; } MouseMoveEvent::~MouseMoveEvent() { diff --git a/kernel/src/drivers/video/vesa.cpp b/kernel/src/drivers/video/vesa.cpp index 1837c559..229fe699 100644 --- a/kernel/src/drivers/video/vesa.cpp +++ b/kernel/src/drivers/video/vesa.cpp @@ -10,26 +10,20 @@ using namespace maxOS::drivers::video; using namespace maxOS::memory; using namespace maxOS::system; -VideoElectronicsStandardsAssociationDriver::VideoElectronicsStandardsAssociationDriver(multiboot_info_t* mb_info) - : VideoDriver() +VideoElectronicsStandardsAssociation::VideoElectronicsStandardsAssociation(multiboot_info_t* mb_info) +: VideoDriver(), + m_multiboot_info(mb_info), + m_framebuffer_address((uint32_t*)mb_info->framebuffer_addr), + m_bpp(mb_info->framebuffer_bpp), + m_pitch(mb_info->framebuffer_pitch) { - - // Store the multiboot info - this->multibootInfo = mb_info; - - // Info from multiboot - this->framebufferAddress = (uint32_t*)multibootInfo->framebuffer_addr; - this->bpp = multibootInfo->framebuffer_bpp; - this->pitch = multibootInfo->framebuffer_pitch; - - } -VideoElectronicsStandardsAssociationDriver::~VideoElectronicsStandardsAssociationDriver(){ +VideoElectronicsStandardsAssociation::~VideoElectronicsStandardsAssociation(){ } -bool VideoElectronicsStandardsAssociationDriver::init() { +bool VideoElectronicsStandardsAssociation::init() { //Multiboot inits this for us return true; @@ -37,17 +31,17 @@ bool VideoElectronicsStandardsAssociationDriver::init() { /** * @brief Sets the mode of the VESA driver (TODO: List of modes) + * * @param width Width of the screen * @param height Height of the screen - * @param colorDepth Color depth of the screen + * @param color_depth Color depth of the screen * @return True if the mode was set successfully, false otherwise */ -bool VideoElectronicsStandardsAssociationDriver::internalSetMode(uint32_t width, uint32_t height, uint32_t colorDepth) { +bool VideoElectronicsStandardsAssociation::internal_set_mode(uint32_t width, uint32_t height, uint32_t color_depth) { // Check if the mode is supported - if(!supportsMode(width, height, colorDepth)) { - // Mode is not supported + if(!supports_mode(width, height, color_depth)) { return false; } @@ -65,15 +59,16 @@ bool VideoElectronicsStandardsAssociationDriver::internalSetMode(uint32_t width, /** * @brief Checks if the VESA driver supports the given mode - * @param width The width of the screen - * @param height The height of the screen - * @param colorDepth The color depth of the screen + * + * @param width The m_width of the screen + * @param height The m_height of the screen + * @param color_depth The color depth of the screen * @return */ -bool VideoElectronicsStandardsAssociationDriver::supportsMode(uint32_t width, uint32_t height, uint32_t colorDepth) { +bool VideoElectronicsStandardsAssociation::supports_mode(uint32_t width, uint32_t height, uint32_t color_depth) { // Check if the mode is supported - if(width == (int)multibootInfo->framebuffer_width && height == (int)multibootInfo->framebuffer_height && colorDepth == (int)multibootInfo->framebuffer_bpp) { + if(width == (int)m_multiboot_info->framebuffer_width && height == (int)m_multiboot_info->framebuffer_height && color_depth == (int)m_multiboot_info->framebuffer_bpp) { return true; } return false; @@ -81,32 +76,55 @@ bool VideoElectronicsStandardsAssociationDriver::supportsMode(uint32_t width, ui /** * @brief Renders a pixel on the screen in 32 bit mode + * * @param x The x coordinate of the pixel * @param y The y coordinate of the pixel * @param colour The 32bit colour of the pixel */ -void VideoElectronicsStandardsAssociationDriver::renderPixel32Bit(uint32_t x, uint32_t y, uint32_t colour) { +void VideoElectronicsStandardsAssociation::render_pixel_32_bit(uint32_t x, uint32_t y, uint32_t colour) { // Get the address of the pixel - uint32_t* pixelAddress = (uint32_t*)((uint8_t *)framebufferAddress + pitch * (y) + bpp * (x) / 8); + uint32_t*pixel_address = (uint32_t*)((uint8_t *)m_framebuffer_address + m_pitch * (y) + m_bpp * (x) / 8); // Set the pixel - *pixelAddress = colour; + *pixel_address = colour; } -uint32_t VideoElectronicsStandardsAssociationDriver::getRenderedPixel32Bit(uint32_t x, uint32_t y) { +/** + * @brief Gets the colour of a pixel on the screen in 32 bit mode + * + * @param x The x coordinate of the pixel + * @param y The y coordinate of the pixel + * @return The 32bit colour of the pixel + */ +uint32_t VideoElectronicsStandardsAssociation::get_rendered_pixel_32_bit(uint32_t x, uint32_t y) { + // Get the address of the pixel - uint32_t* pixelAddress = (uint32_t*)((uint8_t *)framebufferAddress + pitch * (y) + bpp * (x) / 8); + uint32_t*pixel_address = (uint32_t*)((uint8_t *)m_framebuffer_address + m_pitch * (y) + m_bpp * (x) / 8); - // Set the pixel - return *pixelAddress; // Return the colour of the pixel + // Return the pixel + return *pixel_address; } -string VideoElectronicsStandardsAssociationDriver::getVendorName() { +/** + * @brief Renders a pixel on the screen in 16 bit mode + * + * @param x The x coordinate of the pixel + * @param y The y coordinate of the pixel + * @param colour The 16bit colour of the pixel + */ +string VideoElectronicsStandardsAssociation::get_vendor_name() { return "NEC Home Electronics"; // Creator of the VESA standard } -string VideoElectronicsStandardsAssociationDriver::getDeviceName() { +/** + * @brief Gets the colour of a pixel on the screen in 16 bit mode + * + * @param x The x coordinate of the pixel + * @param y The y coordinate of the pixel + * @return The 16bit colour of the pixel + */ +string VideoElectronicsStandardsAssociation::get_device_name() { return "VESA compatible graphics card"; } diff --git a/kernel/src/drivers/video/vga.cpp b/kernel/src/drivers/video/vga.cpp index 10acd860..9cf5175c 100644 --- a/kernel/src/drivers/video/vga.cpp +++ b/kernel/src/drivers/video/vga.cpp @@ -12,17 +12,17 @@ using namespace maxOS::hardwarecommunication; // http://files.osdev.org/mirrors/geezer/osd/graphics/modes.c - helpful so thanks VideoGraphicsArray::VideoGraphicsArray() -:miscPort(0x3C2), - crtcIndexPort(0x3D4), - crtcDataPort(0x3D5), - sequenceIndexPort(0x3C4), - sequenceDataPort(0x3C5), - graphicsControllerIndexPort(0x3CE), - graphicsControllerDataPort(0x3CF), - attributeControllerIndexPort(0x3C0), - attributeControllerReadPort(0x3C1), - attributeControllerWritePort(0x3C0), - attributeControllerResetPort(0x3DA) +: m_misc_port(0x3C2), + m_crtc_index_port(0x3D4), + crtc_data_port(0x3D5), + m_sequence_index_port(0x3C4), + m_sequence_data_port(0x3C5), + m_graphics_controller_index_port(0x3CE), + m_graphics_controller_data_port(0x3CF), + m_attribute_controller_index_port(0x3C0), + m_attribute_controller_read_port(0x3C1), + m_attribute_controller_write_port(0x3C0), + m_attribute_controller_reset_port(0x3DA) { } @@ -31,79 +31,80 @@ VideoGraphicsArray::~VideoGraphicsArray() { } /** - * @details This function is used to write to the VGA registers. + * @brief This function is used to write to the VGA registers. * * @param registers The VGA registers to write to. */ -void VideoGraphicsArray::WriteRegisters(uint8_t* registers) +void VideoGraphicsArray::write_registers(uint8_t* registers) { - //MISC (1 val) - miscPort.Write(*(registers++)); //Get pointer to register, write first to misc, and increase pointer + // Move to the next register + m_misc_port.write(*(registers++)); - //SEQ (5 vals) + // Set the sequencer registers for (uint8_t i = 0; i < 5; i++ ) { - sequenceIndexPort.Write(i); //Tell where the data is to be written - sequenceDataPort.Write(*(registers++)); //Get pointer to register, first to sequence, and increase pointer + m_sequence_index_port.write(i); + m_sequence_data_port.write(*(registers++)); } - //Unlock CRTC controller (registers 0-7 of port 0x3D4 are write protected by the protect bit (bit 7 of index 0x11) so we must clear it to write to the registers .) - crtcIndexPort.Write(0x03); - crtcDataPort.Write(crtcDataPort.Read() | 0x80); //Set 0x03 (third's) first bit to 1 - crtcIndexPort.Write(0x11); - crtcDataPort.Write(crtcDataPort.Read() | ~0x80); //Set 0x11 (eleventh's) first bit to 0 + // Clear protection bit to enable writing to CR0-7 + m_crtc_index_port.write(0x03); + crtc_data_port.write(crtc_data_port.read() | 0x80); + m_crtc_index_port.write(0x11); + crtc_data_port.write(crtc_data_port.read() | ~0x80); - //Make sure that the unlock isn't overwritten - registers[0x03] = registers[0x03] | 0x80; //In the register 0x03 also set first 1 - registers[0x11] = registers[0x11] & ~0x80; //In the register 0x11 also set first 0 + // Ensure protection bit is set + registers[0x03] = registers[0x03] | 0x80; + registers[0x11] = registers[0x11] & ~0x80; - //CRTC (25 vals) + // write the CRTC registers for (uint8_t i = 0; i < 25; i++ ) { - crtcIndexPort.Write(i); //Tell where the data is to be written - crtcDataPort.Write(*(registers++)); //Get pointer to register, write to cathode thingy, and increase pointer + m_crtc_index_port.write(i); + crtc_data_port.write(*(registers++)); } - //GC (9 vals) + // write the graphics controller registers for(uint8_t i = 0; i < 9; i++) { - graphicsControllerIndexPort.Write(i); //Tell where the data is to be written - graphicsControllerDataPort.Write(*(registers++)); //Get pointer to register, write to graphics controller, and increase pointer + m_graphics_controller_index_port.write(i); + m_graphics_controller_data_port.write(*(registers++)); } - //AC (21 vals) + // write the attribute controller registers for(uint8_t i = 0; i < 21; i++) { - attributeControllerResetPort.Read(); //Reset the Controller - attributeControllerIndexPort.Write(i); //Tell where the data is to be written - attributeControllerWritePort.Write(*(registers++)); //Get pointer to register, write to attribute controller, and increase pointer + m_attribute_controller_reset_port.read(); + m_attribute_controller_index_port.write(i); + m_attribute_controller_write_port.write(*(registers++)); } - //Re-Lock CRTC and unblank display - attributeControllerResetPort.Read(); - attributeControllerIndexPort.Write(0x20); + // Re-Lock CRTC and unblank display + m_attribute_controller_reset_port.read(); + m_attribute_controller_index_port.write(0x20); } /** - * @details This function is used to get the maximum resolution of the VGA and colour depth. + * @brief Checks if the specified resolution is supported. * * @return True if the specified resolution is supported, otherwise false. */ -bool VideoGraphicsArray::supportsMode(uint32_t width, uint32_t height, uint32_t colourDepth) +bool VideoGraphicsArray::supports_mode(uint32_t width, uint32_t height, uint32_t colour_depth) { - return width == 320 && height == 200 && colourDepth == 8; + return width == 320 && height == 200 && colour_depth == 8; } /** - * @details This function is used to set the specified resolution and colour depth. + * @brief Set the resolution of the screen. * * @param width The width of the resolution. * @param height The height of the resolution. - * @param colourDepth The colour depth of the resolution. - * @return True if the specified resolution is supported, otherwise false. + * @param colour_depth The colour depth of the resolution. + * + * @return True if the card was able to set the resolution, otherwise false. */ -bool VideoGraphicsArray::internalSetMode(uint32_t width, uint32_t height, uint32_t colourDepth) +bool VideoGraphicsArray::internal_set_mode(uint32_t width, uint32_t height, uint32_t colour_depth) { - if(!supportsMode(width, height, colourDepth)) + if(!supports_mode(width, height, colour_depth)) return false; //Values from osdev / modes.c @@ -127,24 +128,25 @@ bool VideoGraphicsArray::internalSetMode(uint32_t width, uint32_t height, uint32 0x41, 0x00, 0x0F, 0x00, 0x00 }; - WriteRegisters(g_320x200x256); + write_registers(g_320x200x256); return true; } /** - * @details This function is used to get the framebuffer address. + * @brief This function is used to get the framebuffer address. * * @return The framebuffer address. */ -uint8_t* VideoGraphicsArray::GetFrameBufferSegment() +uint8_t* VideoGraphicsArray::get_frame_buffer_segment() { // Optimise so that dont have to read and write to the port every time return (uint8_t*)0xA0000; - //Read data from index number 6 - graphicsControllerIndexPort.Write(0x06); - uint8_t segmentNumber = graphicsControllerDataPort.Read() & (3<<2); //Shift by 2 as only intrested in bits 3 & 4 (& 3 so all the other bits are removed) + //read data from index number 6 + m_graphics_controller_index_port.write(0x06); + uint8_t segmentNumber = + m_graphics_controller_data_port.read() & (3<<2); //Shift by 2 as only intrested in bits 3 & 4 (& 3 so all the other bits are removed) switch(segmentNumber) { default: @@ -156,30 +158,52 @@ uint8_t* VideoGraphicsArray::GetFrameBufferSegment() } -//8 bit vga mode only has 256 colours. colorIndex selects which one to display /** - * @details This function is used to put a pixel on the screen. + * @brief Puts a 8 bit pixel on the screen. * * @param x The x coordinate of the pixel. * @param y The y coordinate of the pixel. * @param colour The colour of the pixel. */ -void VideoGraphicsArray::renderPixel8Bit(uint32_t x, uint32_t y, uint8_t colour){ +void VideoGraphicsArray::render_pixel_8_bit(uint32_t x, uint32_t y, uint8_t colour){ + + // Get the address of the pixel + uint8_t*pixel_address = get_frame_buffer_segment() + 320*y + x; - uint8_t* pixelAddress = GetFrameBufferSegment() + 320*y + x; // Get where to put the pixel in memory and x y pos - *pixelAddress = colour; // Set the colour of the pixel + // Set the pixel + *pixel_address = colour; } -uint8_t VideoGraphicsArray::getRenderedPixel8Bit(uint32_t x, uint32_t y) { - uint8_t* pixelAddress = GetFrameBufferSegment() + y*320 + x; // Get where the pixel is in memory and x y pos - return *pixelAddress; // Return the colour of the pixel +/** + * @brief Gets a 8 bit pixel from the screen. + * + * @param x The x coordinate of the pixel. + * @param y The y coordinate of the pixel. + * @return The colour of the pixel. + */ +uint8_t VideoGraphicsArray::get_rendered_pixel_8_bit(uint32_t x, uint32_t y) { + + // Get the address of the pixel + uint8_t*pixel_address = get_frame_buffer_segment() + 320*y + x; + + // Return the pixel + return *pixel_address; } -string VideoGraphicsArray::getVendorName() { +/** + * @brief Gets the name of the vendor. + * + * @return The name of the vendor. + */ +string VideoGraphicsArray::get_vendor_name() { return "IBM"; // VGA was made by IBM } -string VideoGraphicsArray::getDeviceName() { +/** + * @brief Gets the name of the device. + * + * @return The name of the device. + */ +string VideoGraphicsArray::get_device_name() { return "VGA compatible graphics card"; -} - +} \ No newline at end of file diff --git a/kernel/src/drivers/video/video.cpp b/kernel/src/drivers/video/video.cpp index 0c4ed3a3..edd5e0ce 100644 --- a/kernel/src/drivers/video/video.cpp +++ b/kernel/src/drivers/video/video.cpp @@ -18,33 +18,53 @@ VideoDriver::~VideoDriver() { } -bool VideoDriver::internalSetMode(uint32_t width, uint32_t height, uint32_t colorDepth) { +/** + * @brief Set the mode of the video driver + * + * @param width The width of the screen + * @param height The height of the screen + * @param color_depth The color depth of the screen + * @return true If the mode was set successfully false otherwise + */ +bool VideoDriver::internal_set_mode(uint32_t width, uint32_t height, uint32_t color_depth) { return false; } -bool VideoDriver::supportsMode(uint32_t width, uint32_t height, uint32_t colorDepth) { +/** + * @brief Check if the video driver supports a certain mode + * + * @param width The width of the screen + * @param height The height of the screen + * @param color_depth The color depth of the screen + * @return true If the mode is supported, false otherwise + */ +bool VideoDriver::supports_mode(uint32_t width, uint32_t height, uint32_t color_depth) { return false; } -bool VideoDriver::setMode(uint32_t width, uint32_t height, uint32_t colorDepth) { +/** + * @brief Set the mode of the video driver + * + * @param width The width of the screen + * @param height The height of the screen + * @param color_depth The color depth of the screen + * @return true If the mode was set successfully (and the screen was updated) false otherwise + */ +bool VideoDriver::set_mode(uint32_t width, uint32_t height, uint32_t colorDepth) { // Check if the mode is supported - if(!supportsMode(width, height, colorDepth)) + if(!supports_mode(width, height, colorDepth)) return false; // Set the mode - if(internalSetMode(width, height, colorDepth)) + if(internal_set_mode(width, height, colorDepth)) { - this -> width = width; - this -> height = height; - this -> colorDepth = colorDepth; + this -> m_width = width; + this -> m_height = height; + this -> m_color_depth = colorDepth; return true; } // If setting the mode failed, return false return false; -} - -bool VideoDriver::setTextMode() { - return false; } \ No newline at end of file diff --git a/kernel/src/filesystem/fat32.cpp b/kernel/src/filesystem/fat32.cpp index d725750b..5d7acfb0 100644 --- a/kernel/src/filesystem/fat32.cpp +++ b/kernel/src/filesystem/fat32.cpp @@ -9,1094 +9,3 @@ using namespace maxOS::common; using namespace maxOS::drivers; using namespace maxOS::filesystem; using namespace maxOS::memory; - -//TODO: Fix folders after lib not found error - -/** - * @details Intialize the FAT32 filesystem - * - * @param hd The hard disk to initialise the FAT32 filesystem on - * @param partitionOffset The offset of the partition to initialise the FAT32 filesystem on - */ -Fat32::Fat32(drivers::AdvancedTechnologyAttachment *hd, uint32_t partitionOffset, OutputStream* fat32MessageStream) { - - drive = hd; - partOffset = partitionOffset; - - // Set the message stream - this -> fat32MessageStream = fat32MessageStream; - - //Read the BIOS block from the first sector of the partition - BiosParameterBlock32 bpb; - hd->Read28(partitionOffset, (uint8_t*)&bpb, sizeof(BiosParameterBlock32)); - - //Read information from the BIOS block and store it in the global variables - uint32_t fatStart = partitionOffset + bpb.reservedSectors; //The FAT is located after the reserved sectors - uint32_t fatSize = bpb.tableSize32; - uint32_t dataStart = fatStart + fatSize*bpb.tableCopies; //The data is located after the FAT (which is fatSize * tableCopies sectors long) - uint32_t rootStart = dataStart + bpb.sectorsPerCluster*(bpb.rootCluster - 2); //rootCluster is offset 2 by default - - - FatDirectoryTraverser rootTraverser(hd, rootStart, dataStart, bpb.sectorsPerCluster, fatStart, fatSize, fat32MessageStream); - currentTraverser = &rootTraverser; - - -} - -Fat32::~Fat32() { - -} - -/** - * @details Get the current directory traverser - * - * @return The current directory traverser - */ -DirectoryTraverser* Fat32::getDirectoryTraverser() { - - return currentTraverser; - -} - -/** - * @details Allocate a new cluster in the FAT - * - * @param currentCluster The current cluster to allocate a new cluster after - * @param fatLocation The location of the FAT table - * @param fat_size The size of the FAT table - * @return The current directory traverser - */ -uint32_t Fat32::AllocateCluster(drivers::AdvancedTechnologyAttachment *hd, uint32_t currentCluster, uint32_t fatLocation, uint32_t fat_size){ - - //Find and store the first free cluster - uint32_t fatBuffer[512 / sizeof(uint32_t)]; //Create a buffer to store a sector of the FAT table - uint32_t nextFreeCluster = -1; - for (int sector = 0; sector < fat_size; ++sector) { //Loop the sectors of the FAT table - - hd -> Read28(fatLocation + sector, (uint8_t*)fatBuffer, sizeof(fatBuffer)); //Read the sector of the FAT table - for (int j = 0; j < 512 / sizeof(uint32_t); ++j) { //Loop through each entry in the sectort - - if(fatBuffer[j] == 0){ //Fat entries are available if it is 0x000000 - - nextFreeCluster = sector * (512 / sizeof(uint32_t)) + j; //Calculate the cluster number - break; - } - } - } - - //If there is no space left on the drive - if(nextFreeCluster == -1) return nextFreeCluster; //If there is no free clusters then return - - //Mark the next free cluster as used - UpdateEntryInFat(hd, nextFreeCluster, nextFreeCluster, fatLocation); - - //Mark the newly allocated cluster as the last cluster of the file - UpdateEntryInFat(hd, nextFreeCluster, 0x0FFFFFFF, fatLocation); - - //Modify the FAT table to update the last cluster to point to the new cluster - UpdateEntryInFat(hd, currentCluster, nextFreeCluster, fatLocation); - - return nextFreeCluster; -}; - - -/** - * @details Deallocates all clusters in a file - * - * @param hd pointer to the AdvancedTechnologyAttachment object representing the hard drive - * @param firstCluster The first cluster of the file to be deallocated - * @param fatLocation The location of the FAT table on the hard drive - * @param fat_size The size of the FAT table in sectors - */ -void Fat32::DeallocateCluster(drivers::AdvancedTechnologyAttachment *hd, uint32_t firstCluster, uint32_t fatLocation, uint32_t fat_size) { - - //Loop through all the clusters in the file - uint32_t nextCluster = firstCluster; - while (nextCluster != 0x0FFFFFFF) { - - //Read the current cluster's entry in the FAT - uint32_t fatBuffer[512 / sizeof(uint32_t)]; //Create a buffer to store a sector of the FAT table - uint32_t sector = nextCluster / (512 / sizeof(uint32_t)); //Calculate the sector of the FAT table - uint32_t offset = nextCluster % (512 / sizeof(uint32_t)); //Calculate the offset of the FAT table - hd -> Read28(fatLocation + sector, (uint8_t*)fatBuffer, sizeof(fatBuffer)); //Read the sector of the FAT table - - //Mark the current cluster as free - UpdateEntryInFat(hd, nextCluster, 0x00000000, fatLocation); - - //Get the next cluster in the file - nextCluster = fatBuffer[offset]; - } -} - -/** - * @details Update the entry in the FAT - * - * @param cluster The cluster to update - * @param newFatValue The new value to set the entry to - * @param fatLocation The location of the FAT table - */ -void Fat32::UpdateEntryInFat(drivers::AdvancedTechnologyAttachment *hd, uint32_t cluster, uint32_t newFatValue, uint32_t fatLocation){ - - uint32_t fatBuffer[512 / sizeof(uint32_t)]; - uint32_t sector = cluster / (512 / sizeof(uint32_t)); //Calculate the sector of the FAT table - uint32_t offset = cluster % (512 / sizeof(uint32_t)); //Calculate the offset of the FAT table - hd -> Read28(fatLocation + sector, (uint8_t*)fatBuffer, sizeof(fatBuffer)); //Read the sector of the FAT table - fatBuffer[offset] = newFatValue; //Set the entry to 0x0FFFFFFF - hd -> Write28(fatLocation + sector, (uint8_t*)fatBuffer, sizeof(fatBuffer)); //Write the changes to the disk //Write the sector of the FAT table - -}; - -/** - * @details Check if a string is a valid FAT32 name - * - * @param name Pointer to the char array to check - * @return true if the name is valid, false otherwise - */ -bool Fat32::IsValidFAT32Name(string name) { - - // Count the number of characters in the name - int len = 0; - while (name[len] != '\0') { - len++; - } - - // Check for length - if (len > 8) { - return false; - } - - // Check for invalid characters - for (int i = 0; i < len; i++) { - if (!((name[i] >= 'A' && name[i] <= 'Z') || (name[i] >= '0' && name[i] <= '9') || name[i] == ' ' || name[i] == '_' || name[i] == '^' || name[i] == '$' || name[i] == '~' || name[i] == '!' || name[i] == '#' || name[i] == '%' || name[i] == '&' || name[i] == '-' || name[i] == '{' || name[i] == '}' || name[i] == '@' || name[i] == '\'' || name[i] == '(' || name[i] == ')')) { - return false; - } - } - - return true; -} - -///__DirectoryTraverser__/// - -FatDirectoryTraverser::FatDirectoryTraverser(drivers::AdvancedTechnologyAttachment* ataDevice, uint32_t dirSec, uint32_t dataStart, uint32_t clusterSectorCount, uint32_t fatLoc, uint32_t fat_size, OutputStream* outStream) { - - //TODO: Add error checks - //TODO: File extensions - //TODO: Long file names - - //TODO: Fix bug that the physical drive doesnt get updated, probably has also got something to do with the reading error - //TODO: test cluster allocation, test directory/file renaming, test file/directory creation, test file/directory deletion, test directory entry updation - //TODO: File name string has to be 8 characters long (including spaces) for it to compare correctly - - hd = ataDevice; - - // Set the output stream - fat32MessageStream = outStream; - - //Set the data start and cluster sector count and fat location - dataStartSector = dataStart; - sectorsPrCluster = clusterSectorCount; - fatLocation = fatLoc; - directorySector = dirSec; - fatSize = fat_size; - - //Convert the directory sector into a cluster - directoryCluster = (directorySector - dataStartSector) / sectorsPrCluster + 2; - - //Read the directory entrys - ReadEntrys(); - - while (true); - - -} - -FatDirectoryTraverser::~FatDirectoryTraverser() { - -} - -void FatDirectoryTraverser::ReadEntrys(){ - - //Clear the array - dirent.clear(); - - //Clear the enumerators - currentFileEnumerator = 0; - currentDirectoryEnumerator = 0; - - //Directory reading loop - int index = 0; - uint32_t nextCluster = directoryCluster; - uint8_t fatBuffer[513]; - - //Read directory entries until the end of the cluster - while(true) { - - //Convert file cluster into a sector - uint32_t directoryReadSector = dataStartSector + sectorsPrCluster*(nextCluster - 2); //*Offset by 2 - int sectorOffset = 0; - - //Read the sectors in the cluster - while(true){ - - //Read the sector - hd -> Read28(directoryReadSector + sectorOffset, (uint8_t*)&tempDirent[0], 16*sizeof(DirectoryEntry)); //Read the directory entries - sectorOffset++; //Increment the sector offset - - //Loop through all the entries - for(int i = 0; i < 16; i++) { - //If the name is 0x00 then there are no more entries - if (tempDirent[i].name[0] == 0x00) { - return; - } - - //If the attribute is 0x0F then this is a long file name entry - if ((tempDirent[i].attributes & 0x0F) == 0x0F) { - continue; - } - - - //Store the directory entry in the dirent list - dirent.pushBack(tempDirent[i]); - - if(currentDirectoryEnumerator == 0 && (dirent[index].attributes & 0x10) == 0x10){ //If this is the first directory entry then set the current directory to this entry - currentDirectoryIndex = index; //Set the current directory index to the current entry - FatDirectoryEnumerator* dir = new FatDirectoryEnumerator(this, dirent[index], currentDirectoryIndex); //Create a new directory enumerator - currentDirectoryEnumerator = dir; //Set the current directory enumerator to the new directory enumerator - } - - if(currentFileEnumerator == 0 && (dirent[index].attributes & 0x10) != 0x10){ - currentFileIndex = index; - FatFileEnumerator* file = new FatFileEnumerator(this, dirent[index], currentFileIndex); - currentFileEnumerator = file; - } - - char* foo = " "; - for(int j = 0; j < 8; j++) - foo[j] = dirent[index].name[j]; - fat32MessageStream -> write(foo); - - index++; - } - - //If the next sector is in a different cluster then break - if (sectorOffset > sectorsPrCluster) - break; - } - - //Get the next cluster of the directory - uint32_t sector = nextCluster / (512 / sizeof(uint32_t)); //Calculate the sector of the FAT table - uint32_t offset = nextCluster % (512 / sizeof(uint32_t)); //Calculate the offset of the FAT table - - //Read the FAT sector for the current cluster - hd -> Read28(fatLocation + sector, fatBuffer, 512); - - //Set the next cluster to the next cluster in the FAT - nextCluster = ((uint32_t*)&fatBuffer)[offset] & 0x0FFFFFFF; - - //if the next cluster is 0, it means the end of the cluster chain - if (nextCluster == 0) { - break; - } - } -} - -/** - * @details Changes the current directory to the specified directory, re reads the directory entries - * - * @param directory The directory to change to - */ -void FatDirectoryTraverser::changeDirectory(FatDirectoryEnumerator* directory) { - - //Get the directory entry - DirectoryEntry* directoryEntry = directory -> directoryInfo; - - //Get the first sector of the directory - uint32_t newDirectoryCluster = ((uint32_t) directoryEntry -> firstClusterHigh << 16) //Shift the high cluster number 16 bits to the left - | directoryEntry -> firstClusterLow; //Add the low cluster number - - - //Set this to the directory sector - directoryCluster = newDirectoryCluster; - - //Re-read the directory entries - ReadEntrys(); - - -} - -void FatDirectoryTraverser::makeDirectory(string name) { - - //Check if the name is a valid FAT32 name - if(!Fat32::IsValidFAT32Name(name)) return; - - //Check if the name is already in use - for(int i = 0; i < 16; i++) { - if ((dirent[i].attributes & 0x0F) == 0x0F || (dirent[i].attributes & 0x10) != 0x10) //If the atrribute is 0x0F then this is a long file name entry, skip it. Or if its not a directory - continue; - - if (dirent[i].name[0] == 0x00) //If the name is 0x00 then there are no more entries - break; - - if (dirent[i].name[0] == 0xE5) //If the name is 0xE5 then the entry is free - continue; - - // if (strcmp(name, (string)dirent[i].name) == 0) { //If the name is the same as the parameter - // fat32MessageStream -> write("Name already in use"); - // return; - // } - } - - //Create a new directory entry with the name - DirectoryEntry newDir; //Directory entry to be added - newDir.attributes = 0x10; //Set the attributes to directory - newDir.size = 0; //Set the size to 0 - for(int i = 0; i < 8; i++) { //Set the name - newDir.name[i] = name[i]; - } - - //Allocate a cluster for the directory - uint32_t cluster = Fat32::AllocateCluster(hd, fatLocation, fatSize, sectorsPrCluster); - - //Convert the cluster into high and low for the directory entry - newDir.firstClusterHigh = (uint16_t)(cluster >> 16); - newDir.firstClusterLow = (uint16_t)(cluster & 0xFFFF); - - //Find the first free directory entry - for(int i = 0; i < 16; i++) { - if (dirent[i].name[0] == 0x00) { //If the name is 0x00 then there are no more entries - dirent[i] = newDir; //Set the directory entry to the new directory entry - break; - } - } - - //Write the directory entry to the disk - UpdateDirectoryEntrysToDisk(); - - //Create the "." and ".." directory entries - DirectoryEntry thisDir; //Directory entry for the "." directory, this points to the current directory - DirectoryEntry parentDir; //Directory entry for the ".." directory, this points to the parent directory - -} - -void FatDirectoryTraverser::removeDirectory(string name) { - int index = -1; - - //Loop through all the dirictory entrys - for(int i = 0; i < 16; i++) { - if ((dirent[i].attributes & 0x0F) == 0x0F || (dirent[i].attributes & 0x10) != 0x10) //If the atrribute is 0x0F then this is a long file name entry, skip it. Or if its not a directory - continue; - - if (dirent[i].name[0] == 0x00) //If the name is 0x00 then there are no more entries - break; - - if (dirent[i].name[0] == 0xE5) //If the name is 0xE5 then the entry is free - continue; - - // if (strcmp(name, (string)dirent[i].name) == 0) { //If the name is the same as the parameter - // dirent[i].name[0] = 0xE5; //Set the name to 0xE5 to indicate that the entry is free - // index = i; - // break; - // } - } - - //If the directory was not found - if(index == -1) { - fat32MessageStream -> write("Directory not found"); - return; - } - - //Get the first cluster of the directory - uint32_t cluster = (dirent[index].firstClusterHigh << 16) | dirent[index].firstClusterLow; - - //De allocate any clusters - Fat32::DeallocateCluster(hd, cluster, fatLocation, fatSize); - - //Write the directory entry to the disk - UpdateDirectoryEntrysToDisk(); -} - -void FatDirectoryTraverser::makeFile(string name) { - - //Check if the name is a valid FAT32 name - if(!Fat32::IsValidFAT32Name(name)) return; - - //Check if the name is already in use - for(int i = 0; i < 16; i++) { - if ((dirent[i].attributes & 0x0F) == 0x0F || (dirent[i].attributes & 0x10) == 0x10) //If the atrribute is 0x0F then this is a long file name entry, skip it. Or if its not a file - continue; - - if (dirent[i].name[0] == 0x00) //If the name is 0x00 then there are no more entries - break; - - if (dirent[i].name[0] == 0xE5) //If the name is 0xE5 then the entry is free - continue; - - // if (strcmp(name, (string)dirent[i].name) == 0) { //If the name is the same as the parameter - // fat32MessageStream -> write("Name already in use"); - // return; - // } - } - - //Create a new directory entry with the name - DirectoryEntry newFile; //Directory entry to be added - newFile.attributes = 0x20; //Set the attributes to file - newFile.size = 0; //Set the size to 0 - for(int i = 0; i < 8; i++) { //Set the name - newFile.name[i] = name[i]; - } - - //Allocate a cluster for the file - uint32_t cluster = Fat32::AllocateCluster(hd, fatLocation, fatSize, sectorsPrCluster); - - //Convert the cluster into high and low for the directory entry - newFile.firstClusterHigh = (uint16_t)(cluster >> 16); - newFile.firstClusterLow = (uint16_t)(cluster & 0xFFFF); - - //Find the first free directory entry - for(int i = 0; i < 16; i++) { - if (dirent[i].name[0] == 0x00) { //If the name is 0x00 then there are no more entries - dirent[i] = newFile; //Set the directory entry to the new directory entry - break; - } - } - - //Write the directory entry to the disk - UpdateDirectoryEntrysToDisk(); -} - -void FatDirectoryTraverser::removeFile(string name) { - int index = -1; - - //Loop through all the dirictory entrys - for(int i = 0; i < 16; i++) { - if ((dirent[i].attributes & 0x0F) == 0x0F || (dirent[i].attributes & 0x10) == 0x10) //If the atrribute is 0x0F then this is a long file name entry, skip it. Or if its not a file - continue; - - if (dirent[i].name[0] == 0x00) //If the name is 0x00 then there are no more entries - break; - - if (dirent[i].name[0] == 0xE5) //If the name is 0xE5 then the entry is free - continue; - - // if (strcmp(name, (string)dirent[i].name) == 0 ) { //If the name is the same as the parameter - // dirent[i].name[0] = 0xE5; //Set the name to 0xE5 to indicate that the entry is free - // index = i; - // break; - // } - } - - //If the file was not found - if(index == -1) { - fat32MessageStream -> write("File not found"); - return; - } - - //Get the first cluster of the directory - uint32_t cluster = (dirent[index].firstClusterHigh << 16) | dirent[index].firstClusterLow; - - //De allocate any clusters - Fat32::DeallocateCluster(hd, cluster, fatLocation, fatSize); - - //Write the directory entry to the disk - UpdateDirectoryEntrysToDisk(); -} - -FileEnumerator* FatDirectoryTraverser::getFileEnumerator() { - return currentFileEnumerator; -} - -DirectoryEnumerator* FatDirectoryTraverser::getDirectoryEnumerator() { - return currentDirectoryEnumerator; -} - -void FatDirectoryTraverser::WriteDirectoryInfoChange(DirectoryEntry* e) { - - DirectoryEntry entry = *e; - for (int i = 0; i < 16; ++i) { - - //Calculate the first cluster position in the FAT - uint32_t firstFileCluster = ((uint32_t) entry.firstClusterHigh << 16) //Shift the high cluster number 16 bits to the left - | entry.firstClusterLow; //Add the low cluster number - - uint32_t afirstFileCluster = ((uint32_t) dirent[i].firstClusterHigh << 16) //Shift the high cluster number 16 bits to the left - | dirent[i].firstClusterLow; //Add the low cluster number - - //Check if they are the same - if(firstFileCluster == afirstFileCluster){ - dirent[i] = entry; - break; - } - - } - - UpdateDirectoryEntrysToDisk(); - -} - -void FatDirectoryTraverser::UpdateDirectoryEntrysToDisk(){ - - //Directory reading loop - int index = 0; - uint32_t nextCluster = directoryCluster; - uint8_t fatBuffer[513]; - - //Write directory entries until the end of the cluster - while(true) { - - //Convert file cluster into a sector - uint32_t directoryReadSector = dataStartSector + sectorsPrCluster*(nextCluster - 2); //*Offset by 2 - int sectorOffset = 0; - - //Read the secotrs in the cluster - while(true){ - //Copy the directory entries to the tempBuffer - for(int i = 0; i < 16; i++) { - tempDirent[i] = dirent[index]; - index++; - } - - //Write a sectors worth of directory entries - hd -> Write28(directoryReadSector + sectorOffset, (uint8_t*)&tempDirent[0], 16*sizeof(DirectoryEntry)); //Read the directory entries - sectorOffset++; //Increment the sector offset - - - //If the next sector is in a different cluster then break - if (sectorOffset > sectorsPrCluster) - break; - } - - //Get the next cluster of the directory - uint32_t sector = nextCluster / (512 / sizeof(uint32_t)); //Calculate the sector of the FAT table - uint32_t offset = nextCluster % (512 / sizeof(uint32_t)); //Calculate the offset of the FAT table - - //Read the FAT sector for the current cluster - hd -> Read28(fatLocation + sector, fatBuffer, 512); - - //Set the next cluster to the next cluster in the FAT - nextCluster = ((uint32_t*)&fatBuffer)[offset] & 0x0FFFFFFF; - - //if the next cluster is 0, it means the end of the cluster chain - if (nextCluster == 0) { - break; - } - } - - //TODO: Expand the directory if there is not enough space - -} - -///__DirectoryEnumerator__/// - -FatDirectoryEnumerator::FatDirectoryEnumerator(FatDirectoryTraverser* parent, DirectoryEntry directory, int id) { - - //Set the directory entry - traverser = parent; - directoryInfo = &directory; - index = id; - - - - -} - -FatDirectoryEnumerator::~FatDirectoryEnumerator() { - -} - -/** - * @details Get the name of the directory - * - * @return The name of the directory - */ -string FatDirectoryEnumerator::getDirectoryName() { - char* foo = " "; - for (int j = 0; j < 8; j++) - foo[j] = directoryInfo -> name[j]; - - return foo; -} - -/** - * @details Change the name of the directory - * - * @param newDirectoryName The new name of the directory - * @return The old name of the directory - */ -string FatDirectoryEnumerator::changeDirectoryName(string newDirectoryName) { - - //Check if the new name is acceptable - if(!Fat32::IsValidFAT32Name(newDirectoryName)) return nullptr; - - //Write the new name into the directory entry - for (int i = 0; i < 8; i++) { - if (newDirectoryName[i] != '\0') { - directoryInfo -> name[i] = newDirectoryName[i]; - } else { - directoryInfo -> name[i] = ' '; - } - } - - //Save the changes to the disk - traverser -> WriteDirectoryInfoChange(directoryInfo); - - return newDirectoryName; -} - -/** - * @details Check if there is another directory in the parent directory - * - * @return True if there is another directory, false if not - */ -bool FatDirectoryEnumerator::hasNext() { - - return next() != 0; -} - -/** - * @details Get the next directory in the parent directory - * - * @return The next directory in the parent directory - */ -DirectoryEnumerator* FatDirectoryEnumerator::next() { - - for(int i = index+1; i < 16; i++) { - - //If the name is 0x00 then there are no more entries - if (traverser -> dirent[i].name[0] == 0x00) - break; - - //If the atrribute is 0x0F then this is a long file name entry, skip it. Or if it isnt a directory then skip it - if ((traverser -> dirent[i].attributes & 0x0F) == 0x0F || (traverser -> dirent[i].attributes & 0x10) != 0x10) - continue; - - FatDirectoryEnumerator* dir = new FatDirectoryEnumerator(traverser, traverser -> dirent[i], i); - return dir; - } - return 0; -} - -///__FileEnumerator__/// - -FatFileEnumerator::FatFileEnumerator(FatDirectoryTraverser* parent, DirectoryEntry file, int id) { - //Set the directory entry - traverser = parent; - fileInfo = &file; - index = id; - - //Create a new reader and writer - reader = new FatFileReader(parent,file); - writer = new FatFileWriter(parent,file); - - -} - -FatFileEnumerator::~FatFileEnumerator() { - -} - -/** - * @details Get the name of the file - * - * @return The name of the file - */ -string FatFileEnumerator::getFileName() { - char* foo = " "; - for (int j = 0; j < 8; j++) - foo[j] = fileInfo -> name[j]; - - return foo; -} - -/** - * @details Changes the name of the currently enumerated file - * - * @param newFileName The new filename - * @return The old filename - */ -string FatFileEnumerator::changeFileName(string newFileName) { - //Check if the new name is acceptable - if(!Fat32::IsValidFAT32Name(newFileName)) return nullptr; - - //Write the new name into the directory entry - for (int i = 0; i < 8; i++) { - if (newFileName[i] != '\0') { - fileInfo -> name[i] = newFileName[i]; - } else { - fileInfo -> name[i] = ' '; - } - } - //Save the changes to the disk - traverser -> WriteDirectoryInfoChange(fileInfo); - - return newFileName; -} - -/** - * @details Gets a reference to the current reader object - * - * @return The current reader object - */ -FileReader* FatFileEnumerator::getReader() { - return reader; -} - -/** - * @details Gets a reference to the current writer object - * - * @return The current writer object - */ -FileWriter* FatFileEnumerator::getWriter() { - return writer; -} - -/** - * @details Checks if there is a another file enumerater after this one - * - * @return True if there is another file, false if not - */ -bool FatFileEnumerator::hasNext() { - return next() != 0; -} - -/** - * @details Creates a new FatFileEnumerator object for the next file in the directory (Note: this is why you should store the return value in a varible and refernce that value instead of calling x -> next() -> doY(); ) - * - * @return The next file in the directory - */ -FileEnumerator* FatFileEnumerator::next() { - for(int i = index+1; i < 16; i++) { - - //If the name is 0x00 then there are no more entries - if (traverser -> dirent[i].name[0] == 0x00) - break; - - //If the atrribute is 0x0F then this is a long file name entry, skip it. Or if it is a directory then skip it - if ((traverser -> dirent[i].attributes & 0x0F) == 0x0F || (traverser -> dirent[i].attributes & 0x10) == 0x10) - continue; - - FatFileEnumerator* file = new FatFileEnumerator(traverser, traverser -> dirent[i], i); - return file; - } - return 0; -} - -///__FileReader__/// -FatFileReader::FatFileReader(FatDirectoryTraverser* parent, DirectoryEntry file) { - - fileInfo = &file; - traverser = parent; - -} - -FatFileReader::~FatFileReader() { - -} - -/** - * @details Read a number of bytes from the file - * - * @param data The buffer to read the data into - * @param size The number of bytes to read - * @return The number of bytes read. If this is less than size then the end of the file has been reached. - */ -uint32_t FatFileReader::Read(uint8_t *data, uint32_t size) { - - //TODO: fix performance issues - - //Read the first cluster of the file - uint32_t firstFileCluster = ((uint32_t) fileInfo -> firstClusterHigh << 16) //Shift the high cluster number 16 bits to the left - | fileInfo -> firstClusterLow; //Add the low cluster number - - - int32_t fSIZE = fileInfo -> size; - int32_t nextFileCluster = firstFileCluster; - uint8_t fileBuffer[513]; - uint8_t fatBuffer[513]; - - int dataOffset = 0; - int readPos = 0; - - while (fSIZE > 0){ - - //Convert file cluster into a sector - uint32_t fileSector = traverser -> dataStartSector + traverser -> sectorsPrCluster*(nextFileCluster - 2); //*Offset by 2 - int sectorOffset = 0; - - - //Loop the sectors of the file - for (; fSIZE > 0; fSIZE -= 512) { - - - traverser -> hd -> Read28(fileSector + sectorOffset, fileBuffer, 512); //Read the specified sector of the file - sectorOffset++; //Increment the sector offset - - - fileBuffer[fSIZE > 512 ? 512 : fSIZE = '\0']; //Add a null terminator to the end of the sector - - //Copy the sector into the data buffer - for (int i = 0; i < 512; i++) { - - readPos++; - - //Check that the data being read is after/at the position of the seeker cursor - if(readPos < offsetPosition){ - continue; - } - - //Increament the offset - offsetPosition++; - - //Check that the data buffer is not full / that the requested size has not been reached - if(dataOffset >= size) - return size; - - //Put the data into the data buffer - data[dataOffset] = fileBuffer[i]; - dataOffset++; - - } - - //If the next sector is in a different cluster then break - if (sectorOffset > traverser -> sectorsPrCluster) - break; - } - - - //Get the next cluster of the file - uint32_t fatSectorForCurrentCluster = nextFileCluster / (512 / sizeof(uint32_t)); //The FAT sector for the current cluster is the current cluster divided by the number of entries per sector - - //Read the FAT sector for the current cluster - traverser -> hd -> Read28(traverser -> fatLocation + fatSectorForCurrentCluster, fatBuffer, 512); - - //Get the offset of the current cluster in the FAT sector - uint32_t fatOffsetInSectorForCurrentCluster = nextFileCluster % (512/sizeof(uint32_t)); - - //Set the next cluster to the next cluster in the FAT - nextFileCluster = ((uint32_t*)&fatBuffer)[fatOffsetInSectorForCurrentCluster] & 0x0FFFFFFF; - } - - //If we get to here then the user requested to read more bytes then there are in the file - return dataOffset; -} - -/** - * @details Moves the file offset to a new position - * - * @param position The new position of the file offset - * @param seek The type of seek to perform. (SEEK_SET, offset = position) (SEEK_CUR, offset = offset + position) (SEEK_END, offset = fileSize + position) - * @return The new position of the file offset - */ -uint32_t FatFileReader::Seek(uint32_t position, SeekType seek) { - - switch (seek) { - case SEEK_SET: - offsetPosition = position; - break; - case SEEK_CUR: - offsetPosition += position; - break; - case SEEK_END: - offsetPosition = fileInfo -> size + position; - break; - default: - break; - } - - return offsetPosition; -} - -/** - * @details Get the current position of the file offset - * - * @return the current position of the file offset - */ -uint32_t FatFileReader::GetPosition() { - return offsetPosition; -} - -/** - * @details Get the size of the file - * - * @return the size of the file - */ -uint32_t FatFileReader::GetFileSize() { - return fileInfo -> size; -} - -///__FileWriter__/// - -//TODO: Implement - -FatFileWriter::FatFileWriter(FatDirectoryTraverser* parent, DirectoryEntry file) { - - //Initialise the file writer - fileInfo = &file; - traverser = parent; - offsetPosition = 0; -} - -FatFileWriter::~FatFileWriter() { - -} - -/** - * @details Writes data to a file starting at the current seek position and ending at the current seek position + size - * - * @param data The buffer to write the data from - * @param size The size that is to be written - * @return The number of bytes written, if this is less than size then then there is insufficient space on the disk - */ -uint32_t FatFileWriter::Write(uint8_t *data, uint32_t size) { - - - //TODO: Write larger then the size of the file (e.g. grow the file) - - //Read the first cluster of the file - uint32_t firstFileCluster = ((uint32_t) fileInfo -> firstClusterHigh << 16) //Shift the high cluster number 16 bits to the left - | fileInfo -> firstClusterLow; //Add the low cluster number - - - - int32_t fSIZE = fileInfo -> size; - int32_t nextFileCluster = firstFileCluster; - uint8_t fileBuffer[513]; - uint8_t fatBuffer[513]; - - int dataOffset = 0; - int writePos = 0; - - while (fSIZE > 0){ - - //Convert file cluster into a sector - uint32_t fileSector = traverser -> dataStartSector + traverser -> sectorsPrCluster*(nextFileCluster - 2); //*Offset by 2 - int sectorOffset = 0; - - - //Loop the sectors of the file - for (; fSIZE > 0; fSIZE -= 512) { - - //Check that the data will be writen at the offset/seek pos - if(writePos < offsetPosition){ - - ///If the data will not be written at the right place then read the sector and then begin writing after the offset - traverser -> hd -> Read28(fileSector + sectorOffset, fileBuffer, 512); //Read the specified sector of the file - - - } - sectorOffset++; - - //Copy the data buffer into the sector buffer - for (int i = 0; i < 512; i++) { - writePos++; - - //Check if it is a valid place to put data - if (writePos < offsetPosition) - continue; - - - //Increment the offset - offsetPosition++; - - //Check that the data buffer is not full / that the requested size has not been reached, if it is then write the data early and then - if (dataOffset >= size){ - traverser -> hd -> Write28(fileSector + sectorOffset, fileBuffer, i); //Write the sector to the disk - return size; - } - - //Put the data into the data buffer - fileBuffer[i] = data[dataOffset]; - dataOffset++; - } - - //Write the sector to the disk - traverser -> hd -> Write28(fileSector + sectorOffset, fileBuffer, 512); - - //If the next sector is in a different cluster then break - if (sectorOffset > traverser -> sectorsPrCluster) - break; - - }//_For end - - - - - //TODO: Test if it works - if(writePos >= fSIZE){ //If the data to be written is past the end of the file then we need to update the FAT table with new clusters for the data - - //Increase the file size by one cluster - uint32_t extendedFileSize = size - dataOffset; //The size of the file minus how much has already been written - if(extendedFileSize > traverser -> sectorsPrCluster * 512) //If the extended filesize is still bigger then the size of one cluster - extendedFileSize = traverser -> sectorsPrCluster * 512; //Then set the extended file size to the size of one cluster - fSIZE += extendedFileSize; //Increase the file size by the extended file size - fileInfo -> size += extendedFileSize; - - //Update the new size on disk - traverser -> WriteDirectoryInfoChange(fileInfo); - - //Set the next cluster to the next cluster in the FAT - nextFileCluster = Fat32::AllocateCluster(traverser -> hd, nextFileCluster, traverser -> fatLocation, traverser -> fatSize); - - //If there is no storage (free clusters) left on the partition - if(nextFileCluster == -1) return dataOffset; - } - else - { //Otherwise we can just check the FAT table for the next cluster and continue - - - //Get the next cluster of the file - uint32_t sector = nextFileCluster / (512 / sizeof(uint32_t)); //Calculate the sector of the FAT table - uint32_t offset = nextFileCluster % (512 / sizeof(uint32_t)); //Calculate the offset of the FAT table - - //Read the FAT sector for the current cluster - traverser -> hd -> Read28(traverser -> fatLocation + sector, fatBuffer, 512); - - //Set the next cluster to the next cluster in the FAT - nextFileCluster = ((uint32_t*)&fatBuffer)[offset ] & 0x0FFFFFFF; - - } - - } - - //If we get to here then the user requested to read more bytes than there are in the file - return dataOffset; -} - - - -uint32_t FatFileWriter::Seek(uint32_t position, SeekType seek) { - switch (seek) { - case SEEK_SET: - offsetPosition = position; - break; - case SEEK_CUR: - offsetPosition += position; - break; - case SEEK_END: - offsetPosition = fileInfo -> size + position; - break; - default: - break; - } - - return offsetPosition; -} - -bool FatFileWriter::Close() { - - //TODO: Implement - -} - -bool FatFileWriter::Flush() { - - //TODO: Implement - -} - -uint32_t FatFileWriter::GetPosition() { - return offsetPosition; -} - -uint32_t FatFileWriter::GetFileSize() { - return fileInfo -> size; -} diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp index 4b73d7f2..af5e2e62 100644 --- a/kernel/src/filesystem/filesystem.cpp +++ b/kernel/src/filesystem/filesystem.cpp @@ -7,328 +7,3 @@ using namespace maxOS; using namespace maxOS::filesystem; -///__FileSystem__/// - -FileSystem::FileSystem() { - //Base implementation: - //Create a new Directory Traverser and store it in the FileSystem object -} - -FileSystem::~FileSystem() { - -} - -DirectoryTraverser *FileSystem::getDirectoryTraverser() { - return nullptr; -} - -/** - * @details Get the directory traverser for the filesystem - * - * @return - */ - - -///__DirectoryTraverser__/// - -DirectoryTraverser::DirectoryTraverser() { - //A directory traverser provides a way to traverse a directory and get the files and subdirectories - //It allows to change what directory is being traversed - -} - -DirectoryTraverser::~DirectoryTraverser() { - -} - -/** - * @details Change what directory is being traversed - * - * @param directory the directory to traverse - */ -void DirectoryTraverser::changeDirectory(DirectoryEnumerator directory) { - - //e.g. change the current sector to the sector of the directory - //e.g. reset the directoryEnumerator and fileEnumerator - -} - -/** - * @details Creates a new directory - * - * @param name the name of the directory - */ -void DirectoryTraverser::makeDirectory(string name) { - -} - -/** - * @details Removes a directory and all its contents - * - * @param name the name of the directory to remove - */ -void DirectoryTraverser::removeDirectory(string name) { - -} - - - - -/** - * @details Gets the file enumerator for the current directory - * - * @return the file enumerator - */ -FileEnumerator* DirectoryTraverser::getFileEnumerator() { - return nullptr; -} - -/** - * @details Gets the directory enumerator for the current directory - * - * @return the directory enumerator - */ -DirectoryEnumerator* DirectoryTraverser::getDirectoryEnumerator() { - return nullptr; -} - -/** - * @details Creates a new file - * - * @param name the name of the file - */ -void DirectoryTraverser::makeFile(string name) { - -} - -/** - * @details Removes a file - * - * @param name the name of the file - */ -void DirectoryTraverser::removeFile(string name) { - -} - - -///__Directory Enumerator__/// - - -DirectoryEnumerator::DirectoryEnumerator() { - - //A directory enumerator provides a way to enumerate the directories in a directory - //It allows to get the name of the directory and to get the next directory - -} - -DirectoryEnumerator::~DirectoryEnumerator() { - -} - -/** - * @details Gets the name of the directory - * - * @return the name of the directory - */ -string DirectoryEnumerator::getDirectoryName() { - -} - -/** - * @details Checks if there is another directory - * - * @return true if there is another directory, false otherwise - */ -bool DirectoryEnumerator::hasNext() { - return false; -} - -/** - * @details Gets the next directoryEnumerator in this DirectoryTraverser - * - * @return the next directoryEnumerator - */ -DirectoryEnumerator* DirectoryEnumerator::next() { - return nullptr; -} - -///__FileEnumerator__/// - -FileEnumerator::FileEnumerator() { - //A file enumerator provides a way to enumerate the files in a directory - //It allows to get the name of the file, to get the reader and writer for the file and to get the next file -} - -FileEnumerator::~FileEnumerator() { - -} - -/** - * @details Gets the name of the current file - * - * @return the name of the file - */ -string FileEnumerator::getFileName() { - string a = "none"; - return a; -} - -/** - * @details Gets the reader for the current file - * - * @return the reader for the file - */ -FileReader* FileEnumerator::getReader() { - return nullptr; -} - -/** - * @details Gets the writer for the current file - * - * @return the writer for the file - */ -FileWriter* FileEnumerator::getWriter() { - return nullptr; -} - -/** - * @details Checks if there is another file - * - * @return true if there is another file, false otherwise - */ -bool FileEnumerator::hasNext() { - return false; -} - -/** - * @details Gets the next file in this DirectoryTraverser - * - * @return The next file - */ -FileEnumerator* FileEnumerator::next() { - return nullptr; -} - -///__FileReader__/// - -FileReader::FileReader() { - //A file reader provides a way to read from a file - //It allows to get the position in the file, to get the size of the file and to read from the file - -} - -FileReader::~FileReader() { - -} - -/** - * @details Reads from the file and stores the data in the buffer at the given position (default 0 + how many bytes has been read this fileEnumeration) - * - * @param data the data pointer to read into - * @param size the size of the data to read - * @return the amount of data read - */ -uint32_t FileReader::Read(uint8_t *data, uint32_t size) { - -} - -/** - * @details Moves the position in the file - * - * @param position how many bytes to move the position - * @param seek The type of seek to perform. (SEEK_SET, offset = position) (SEEK_CUR, offset = offset + position) (SEEK_END, offset = fileSize + position) - * @return the position in the file - */ -uint32_t FileReader::Seek(uint32_t position, SeekType seek) { - -} - -/** - * @details Gets the current position in the file - * - * @return the current position in the file - */ -uint32_t FileReader::GetPosition() { - return 0; -} - -/** - * @details Gets the size of the file - * - * @return the size of the file - */ -uint32_t FileReader::GetFileSize() { - return 0; -} - -///__FileWriter__/// - -FileWriter::FileWriter() { - //A file writer provides a way to write to a file - //It allows to get the position in the file, to get the size of the file and to write to the file - -} - -FileWriter::~FileWriter() { - -} - -/** - * @details Writes to the file at the given position (default 0 + how many bytes has been read this fileEnumeration) - * - * @param data the data pointer to write from - * @param size the size of the data to write - * @return the amount of data written - */ -uint32_t FileWriter::Write(uint8_t *data, uint32_t size) { - return 0; -} - -/** - * @details Moves the position in the file - * - * @param position the position to move to - * @param seek The type of seek to perform. (SEEK_SET, offset = position) (SEEK_CUR, offset = offset + position) (SEEK_END, offset = fileSize + position) - * @return how many bytes the position has been moved - */ -uint32_t FileWriter::Seek(uint32_t position, SeekType seek) { - return 0; -} - -/** - * @details Closes the current file - * - * @return True if the file was closed successfully, false otherwise - */ -bool FileWriter::Close() { - return false; -} - -/** - * @details Flushes the current file (writes all data to the disk) - * - * @return True if the file was flushed successfully, false otherwise - */ -bool FileWriter::Flush() { - return false; -} - -/** - * @details Gets the current position in the file - * - * @return the current position in the file - */ -uint32_t FileWriter::GetPosition() { - return 0; -} - -/** - * @details Gets the size of the file - * - * @return the size of the file - */ -uint32_t FileWriter::GetFileSize() { - return 0; -} - - diff --git a/kernel/src/filesystem/msdospart.cpp b/kernel/src/filesystem/msdospart.cpp index 701d39c6..79a836b4 100644 --- a/kernel/src/filesystem/msdospart.cpp +++ b/kernel/src/filesystem/msdospart.cpp @@ -10,40 +10,28 @@ using namespace maxOS::common; using namespace maxOS::filesystem; /** - * @details Read the partition table of a given hard disk + * @brief read the partition table of a given hard disk * * @param hd The hard disk to read the partition table from */ -void MSDOSPartitionTable::ReadPartitions(AdvancedTechnologyAttachment *hd) { +void MSDOSPartitionTable::read_partitions(drivers::AdvancedTechnologyAttachment *hd) { - MasterBootRecord masterBootRecord; // Create a MasterBootRecord object + // read the MBR from the hard disk + MasterBootRecord masterBootRecord; + hd -> read_28(0, (uint8_t *)&masterBootRecord, sizeof(MasterBootRecord)); - hd -> Read28(0, (uint8_t*)&masterBootRecord, sizeof(MasterBootRecord)); // Read the MasterBootRecord from the disk - - /* - printf("MBR: "); - for (int i = 446; i < 466 + 4*16; ++i) { //Loop through the MBR and print it - printfHex(((uint8_t*)&masterBootRecord)[i]); //Print the buffer at the current index - printf(" "); - } - printf("\n"); - */ - - if(masterBootRecord.magicNumber != 0xAA55){ // Check if the magic number is correct + // Check if the magic number is correct + if(masterBootRecord.magicNumber != 0xAA55) return; - } - for(int i = 0; i < 4; i++){ // Loop through the 4 primary partitions - - if(masterBootRecord.primaryPartition[i].partitionId == 0) continue; // If the partition id is 0, skip it + // Loop through the primary partitions + for(int i = 0; i < 4; i++){ - if(masterBootRecord.primaryPartition[i].bootable != 0x80) { // Check if the partition is bootable - //Not Bootable - } + if(masterBootRecord.primaryPartition[i].partitionId == 0) continue; // If the partition id is 0, skip it //TODO: Add a message stream - Fat32 fat32(hd, masterBootRecord.primaryPartition[i].startLBA, 0); // Create a Fat32 object + //TODO: Create a new FAT32 object } } diff --git a/kernel/src/gui/desktop.cpp b/kernel/src/gui/desktop.cpp index 12772fd4..14a8ac2d 100644 --- a/kernel/src/gui/desktop.cpp +++ b/kernel/src/gui/desktop.cpp @@ -10,32 +10,24 @@ using namespace maxOS::gui; using namespace maxOS::drivers::peripherals; /** - * @details Creates a new desktop with the given graphics context + * @brief Creates a new desktop with the given graphics context * * @param gc The graphics context to use */ Desktop::Desktop(GraphicsContext *gc) -: CompositeWidget(0,0,gc -> getWidth(), gc -> getHeight()), +: CompositeWidget(0,0, gc->get_width(), gc->get_height()), MouseEventHandler(), - ClockEventHandler() + ClockEventHandler(), + m_graphics_context(gc), + colour(Colour(0xA8, 0xA8, 0xA8)) { - // Dragged and focussed widget are null - draggedWidget = 0; - focussedWidget = 0; - - // Set the graphics context - graphicsContext = gc; - - // Set the mouse position to the center of the screen - mouseX = gc -> getWidth() / 2; - mouseY = gc -> getHeight() / 2; - - // Set the desktop colour - colour = Colour(0xA8, 0xA8, 0xA8); // Dark Gray (X11) + // Set the mouse m_position to the center of the screen + m_mouse_x = gc->get_width() / 2; + m_mouse_y = gc->get_height() / 2; // Draw the initial mouse cursor - invertMouseCursor(); + invert_mouse_cursor(); // Draw the desktop Widget::invalidate(); @@ -46,93 +38,76 @@ Desktop::~Desktop() { } /** - * @details Updates the currently focussed widget to be the given widget + * @brief Updates the currently focussed widget to be the given widget * * @param widget The widget that is now in focus */ -void Desktop::setFocus(Widget* widget) { - - // Check if there already was a focussed widget - if(this -> focussedWidget != 0){ - - // Send a focus lost event to the old focussed widget - this -> focussedWidget -> onFocusLost(); - - } +void Desktop::set_focus(Widget* widget) { - // Set the new focussed widget - this -> focussedWidget = widget; + // If there is a widget in focus then send a focus lost event to it + if(this ->m_focussed_widget != nullptr) + this->m_focussed_widget->on_focus_lost(); - // Send a focus gained event to the new focussed widget - this -> focussedWidget -> onFocus(); + // Focus the new widget and send a focus event to it + this ->m_focussed_widget = widget; + this->m_focussed_widget->on_focus(); } /** - * @details Brings the given widget to the front of the desktop + * @brief Brings the given widget to the front of the desktop * - * @param frontWidget The widget to bring to the front + * @param front_widget The widget to bring to the front */ -void Desktop::bringToFront(Widget* frontWidget) { - - /* - * 0x563200 - start = {elements = {0x563844, 0x563200, 0x563680, 0x56303c, 0x0 }, Size = 4, - erased = {elements = {0x563844, 0x563680, 0x56303c, 0x56303c, 0x0 }, Size = 3, - pushed front = {elements = {0x563200, 0x563844, 0x563680, 0x56303c, 0x0 }, Size = 4, - */ +void Desktop::bring_to_front(Widget*front_widget) { // Remove the widget from where ever it already is - children.erase(frontWidget); + m_children.erase(front_widget); // Add it back in the front - children.pushFront(frontWidget); + m_children.push_front(front_widget); } /** - * @details Draws the mouse cursor at the current mouse position by inverting the pixels (mouse is a plus sign) + * @brief Draws the mouse cursor at the current mouse m_position by inverting the pixels (mouse is a plus sign) */ -void Desktop::invertMouseCursor() { +void Desktop::invert_mouse_cursor() { //TODO: Get image drawing going and draw a proper mouse // Draw the horizontal line - for (int x = mouseX - 3; x <= mouseX + 3; ++x) { - graphicsContext->invertPixel(x, mouseY); + for (int x = m_mouse_x - 3; x <= m_mouse_x + 3; ++x) { + m_graphics_context->invert_pixel(x, m_mouse_y); } // Draw the vertical line - for (int y = mouseY - 3; y <= mouseY + 3; ++y) { - graphicsContext->invertPixel(mouseX, y); + for (int y = m_mouse_y - 3; y <= m_mouse_y + 3; ++y) { + m_graphics_context->invert_pixel(m_mouse_x, y); } } /** - * @details Goes through the passed areas and invalidates the areas that are covered by the given area + * @brief Goes through the passed areas and invalidates the areas that are covered by the given area * * @param area The area that is now invalid * @param start The start of the invalid areas * @param stop The end of the invalid areas */ -void Desktop::internalInvalidate(Rectangle &area, Vector>::iterator start, Vector>::iterator stop) { +void Desktop::internal_invalidate(common::Rectangle&area, Vector>::iterator start, Vector>::iterator stop) { // Loop through the invalid rectangles - for(Vector>::iterator invaildRect = start; invaildRect != stop; invaildRect++){ + for(Vector>::iterator invaild_rect = start; invaild_rect != stop; invaild_rect++){ // Check if the area intersects with the invalid rectangle - if(!area.intersects(*invaildRect)) + if(!area.intersects(*invaild_rect)) continue; // Get the parts of the area that are covered by the invalid rectangle - Vector> coveredAreas = area.subtract(*invaildRect); - - // Loop through the covered areas - for(Vector>::iterator coveredArea = coveredAreas.begin(); coveredArea != coveredAreas.end(); coveredArea++){ + Vector> coveredAreas = area.subtract(*invaild_rect); - // Invalidate the covered area - internalInvalidate(*coveredArea, invaildRect + 1, stop); - - } + // Invalidate the covered areas + for(Vector>::iterator coveredArea = coveredAreas.begin(); coveredArea != coveredAreas.end(); coveredArea++) + internal_invalidate(*coveredArea, invaild_rect + 1, stop); // The entire area will be invalidated by now return; @@ -140,128 +115,115 @@ void Desktop::internalInvalidate(Rectangle &area, Vector>::iterator vectorPosition = invalidAreas.pushBack(area); - - // If the position is the last item then the invalidation buffer is full - if(vectorPosition == invalidAreas.end()){ + Vector>::iterator vectorPosition = m_invalid_areas.push_back(area); - // Clear the invalid areas - invalidAreas.clear(); + // If the m_position is the last item then the invalidation buffer is full + if(vectorPosition == m_invalid_areas.end()){ - // Invalidate the whole desktop + // Invalidate the entire desktop + m_invalid_areas.clear(); Widget::invalidate(); } } /** - * @details Draws a certain area of the desktop + * @brief Draws a certain area of the desktop * * @param gc The graphics context to draw with * @param area The area to draw */ -void Desktop::drawSelf(common::GraphicsContext *gc, Rectangle &area) { +void Desktop::draw_self(common::GraphicsContext *gc, common::Rectangle &area) { //TODO: Draw a background image instead // Calculate the rectangle int32_t topCornerX = area.left; int32_t topCornerY = area.top; - int32_t bottomCornerX = area.left + area.width; int32_t bottomCornerY = area.top + area.height; // Draw the background, a rectangle the size of the desktop of the given colour - gc -> fillRectangle(topCornerX, topCornerY, bottomCornerX, bottomCornerY, colour); + gc->fill_rectangle(topCornerX, topCornerY, bottomCornerX, bottomCornerY, colour); } /** - * @details Adds a child widget to the desktop + * @brief Adds a child widget to the desktop * * @param widget The widget to add */ -void Desktop::addChild(Widget* childWidget) { +void Desktop::add_child(Widget*child_widget) { // Check if the new widget is under the mouse - bool underMouse = childWidget -> containsCoordinate(mouseX, mouseY); + bool underMouse = child_widget->contains_coordinate(m_mouse_x, m_mouse_y); - // If the mouse is over the new widget then send a mouse leave event to anything that used to be in this position - if(underMouse){ - - // Handle the mouse leaving this spot (as it has entered the new widget) - CompositeWidget::onMouseLeaveWidget(mouseX, mouseY); - } + // If the mouse is over the widget then send a mouse leave event to the child widget as it is no longer under the mouse + if(underMouse) + CompositeWidget::on_mouse_leave_widget(m_mouse_x, m_mouse_y); // Add the widget to the desktop - CompositeWidget::addChild(childWidget); + CompositeWidget::add_child(child_widget); // If the mouse is over the new widget then send a mouse enter event to the child widget - if(underMouse){ - CompositeWidget::onMouseEnterWidget(mouseX, mouseY); - } + if(underMouse) + CompositeWidget::on_mouse_enter_widget(m_mouse_x, m_mouse_y); } /** - * @details Redraws the desktop when a time event occurs + * @brief Redraws the desktop when a time event occurs * * @param time The time when the event occurred */ -void Desktop::onTime(const Time &time) { +void Desktop::on_time(common::Time const &time) { // Check if anything is invalid and needs to be redrawn - if(invalidAreas.empty()) + if(m_invalid_areas.empty()) return; // Erase the mouse cursor - invertMouseCursor(); + invert_mouse_cursor(); // Loop through the invalid areas - while (!invalidAreas.empty()) { + while (!m_invalid_areas.empty()) { - // Get the first invalid area - Rectangle invalidArea = *(invalidAreas.begin()); //get the pointer to the first element - - // Remove the area from the invalid areas - invalidAreas.popFront(); - - // Draw the area - draw(graphicsContext, invalidArea); + // Redraw the m_first_memory_chunk area + Rectangle invalidArea = *(m_invalid_areas.begin()); + m_invalid_areas.pop_front(); + draw(m_graphics_context, invalidArea); } // Can now draw the mouse cursor - invertMouseCursor(); + invert_mouse_cursor(); } /** - * @details Invalidate the given area of the desktop + * @brief Invalidate the given area of the desktop * * @param area The area that is now invalid */ void Desktop::invalidate(Rectangle &area) { // Invalidate the area - internalInvalidate(area, invalidAreas.begin(), invalidAreas.end()); + internal_invalidate(area, m_invalid_areas.begin(), m_invalid_areas.end()); } /** - * @details When the mouse moves on the desktop update the position of the mouse and redraw the cursor. Pass the event to the widget that the mouse is over + * @brief When the mouse moves on the desktop update the m_position of the mouse and redraw the cursor. Pass the event to the widget that the mouse is over * - * @param x The x position of the mouse - * @param y The y position of the mouse + * @param x The x m_position of the mouse + * @param y The y m_position of the mouse */ -void Desktop::onMouseMoveEvent(int8_t x, int8_t y) { - - // Store the position of the desktop for calculations - Rectangle desktopPosition = getPosition(); +void Desktop::on_mouse_move_event(int8_t x, int8_t y) { - // Calculate the position of the mouse on the desktop - int32_t newMouseX = mouseX + x; - int32_t newMouseY = mouseY + y; + // Calculate the m_position of the mouse on the desktop + Rectangle desktopPosition = position(); + int32_t newMouseX = m_mouse_x + x; + int32_t newMouseY = m_mouse_y + y; // Restrain the mouse to the desktop if(newMouseX < 0) newMouseX = 0; @@ -269,77 +231,72 @@ void Desktop::onMouseMoveEvent(int8_t x, int8_t y) { if(newMouseX > desktopPosition.width) newMouseX = desktopPosition.width - 1; if(newMouseY > desktopPosition.height) newMouseY = desktopPosition.height - 1; - // Remove the old cursor from the screen as it will be redrawn in the new position - invertMouseCursor(); + // Remove the old cursor from the screen as it will be redrawn in the new m_position + invert_mouse_cursor(); - // Check if the mouse is currently dragging a widget - if(draggedWidget != 0) - { - // Pass the mouse move event to the widget being dragged - draggedWidget -> onMouseMoveEvent(newMouseX - mouseX, newMouseY - mouseY); - } + // If a widget is being dragged then pass the event to it + if(m_dragged_widget != 0) + m_dragged_widget->on_mouse_move_event(newMouseX - m_mouse_x, newMouseY - m_mouse_y); // Handle the mouse moving event (pass it to the widget that the mouse is over) - CompositeWidget::onMouseMoveWidget(mouseX, mouseY, newMouseX, newMouseY); + CompositeWidget::on_mouse_move_widget(m_mouse_x, m_mouse_y, newMouseX, + newMouseY); - // Update the mouse position - mouseX = newMouseX; - mouseY = newMouseY; + // Update the mouse m_position + m_mouse_x = newMouseX; + m_mouse_y = newMouseY; // Draw the new cursor - invertMouseCursor(); + invert_mouse_cursor(); } /** - * @details When the mouse button is pressed pass the event to the widget that the mouse is over + * @brief When the mouse button is pressed pass the event to the widget that the mouse is over * * @param button The button that was pressed */ -void Desktop::onMouseDownEvent(uint8_t button) { +void Desktop::on_mouse_down_event(uint8_t button) { // The widget that handled the event becomes the widget being dragged - draggedWidget = CompositeWidget::onMouseButtonPressed(mouseX, mouseY, button); + m_dragged_widget = CompositeWidget::on_mouse_button_pressed(m_mouse_x, m_mouse_y, button); } /** - * @details When the mouse button is released pass the event to the widget that the mouse is over + * @brief When the mouse button is released pass the event to the widget that the mouse is over * * @param button The button that was released */ -void Desktop::onMouseUpEvent(uint8_t button) { +void Desktop::on_mouse_up_event(uint8_t button) { // Pass the event to the widget - CompositeWidget::onMouseButtonReleased(mouseX, mouseY, button); + CompositeWidget::on_mouse_button_released(m_mouse_x, m_mouse_y, button); // Dragging has stopped - draggedWidget = 0; + m_dragged_widget = 0; } /** - * @details When a key is pressed pass the event to the widget that is currently focussed + * @brief When a key is pressed pass the event to the widget that is currently focussed * @param keyDownCode The key that was pressed * @param keyDownState The state of the keyboard */ -void Desktop::onKeyDown(drivers::peripherals::KeyCode keyDownCode, drivers::peripherals::KeyboardState keyDownState) { +void Desktop::on_key_down(KeyCode keyDownCode, KeyboardState keyDownState) { // Pass the event to the widget that is in focus - if (focussedWidget != 0) { - focussedWidget -> onKeyDown(keyDownCode, keyDownState); - } + if (m_focussed_widget != 0) + m_focussed_widget->on_key_down(keyDownCode, keyDownState); } /** - * @details When a key is pressed pass the event to the widget that is currently focussed + * @brief When a key is pressed pass the event to the widget that is currently focussed * @param keyUpCode The key that was pressed * @param keyUpState The state of the keyboard */ -void Desktop::onKeyUp(drivers::peripherals::KeyCode keyUpCode, drivers::peripherals::KeyboardState keyUpState) { +void Desktop::on_key_up(KeyCode keyUpCode, KeyboardState keyUpState) { // Pass the event to the widget that is in focus - if (focussedWidget != 0) { - focussedWidget -> onKeyUp(keyUpCode, keyUpState); - } -} - + if (m_focussed_widget != 0) + m_focussed_widget->on_key_up(keyUpCode, keyUpState); +} \ No newline at end of file diff --git a/kernel/src/gui/font.cpp b/kernel/src/gui/font.cpp index ddbd2eae..e5200f8f 100644 --- a/kernel/src/gui/font.cpp +++ b/kernel/src/gui/font.cpp @@ -11,13 +11,6 @@ using namespace maxOS::gui; Font::Font() { - fontSize = 8; //TODO: Use this - - isBold = false; - isItalic = false; - isUnderlined = false; - isStrikethrough = false; - } Font::~Font() { @@ -25,84 +18,82 @@ Font::~Font() { } /** - * @details Write the entire text to the screen + * @brief write the entire text to the screen * @param x The x coordinate of the text * @param y The y coordinate of the text * @param context The graphics context to draw the text on * @param text The text to draw */ -void Font::drawText(int32_t x, int32_t y, Colour foregroundColour, Colour backgroundColour, GraphicsContext *context, string text) { +void Font::draw_text(int32_t x, int32_t y, common::Colour foreground_colour, + common::Colour background_colour, + common::GraphicsContext *context, string text) { // Calculate the rectangle of the text int32_t top = 0; int32_t left = 0; - uint32_t width = getTextWidth(text); - uint32_t height = getTextHeight(text); + uint32_t width = get_text_width(text); + uint32_t height = get_text_height(text); // Create the rectangle - Rectangle textArea(left, top, width, height); + Rectangle text_area(left, top, width, height); // Draw the text - drawText(x, y, foregroundColour, backgroundColour, context, text, textArea); + draw_text(x, y, foreground_colour, background_colour, context, text, text_area); } /** - * @details Write the entire text to the screen + * @brief write the entire text to the screen + * * @param x The x coordinate of the text * @param y The y coordinate of the text * @param context The graphics context to draw the text on * @param text The text to draw * @param limitArea The area of the text to draw */ -void Font::drawText(int32_t x, int32_t y, Colour foregroundColour, Colour backgroundColour, GraphicsContext *context, string text, Rectangle limitArea) { +void Font::draw_text(int32_t x, int32_t y, common::Colour foreground_colour, + common::Colour background_colour, + common::GraphicsContext *context, string text, + common::Rectangle limitArea) +{ - uint8_t font8x8[2048]; // Declare an array to hold the font data - getFont8x8(font8x8); // Get the font data + // Get the font + uint8_t font8x8[2048]; + get_font_8_x_8(font8x8); // Convert the colours - uint32_t foreground = context->colourToInt(foregroundColour); - uint32_t background = context->colourToInt(backgroundColour); + uint32_t foreground = context->colour_to_int(foreground_colour); + uint32_t background = context->colour_to_int(background_colour); // Ensure the area is within the actual area of the text if (limitArea.top < 0) { - - // Move the area down to fake the desired top and set the top to 0 limitArea.height += limitArea.top; limitArea.top = 0; } if (limitArea.left < 0) { - - // Move the area right to fake the desired left and set the left to 0 limitArea.width += limitArea.left; limitArea.left = 0; } - if (limitArea.top + limitArea.height > getTextHeight(text)) { + // Clamp the height and width max + if (limitArea.top + limitArea.height > get_text_height(text)) + limitArea.height = get_text_height(text) - limitArea.top; - // Set the height to the maximum height - limitArea.height = getTextHeight(text) - limitArea.top; - } - - if (limitArea.left + limitArea.width > getTextWidth(text)) { + if (limitArea.left + limitArea.width > get_text_width(text)) + limitArea.width = get_text_width(text) - limitArea.left; - // Set the width to the maximum width - limitArea.width = getTextWidth(text) - limitArea.left; - } // Calculate limits int32_t xLimit = limitArea.left + limitArea.width; int32_t yLimit = limitArea.top + limitArea.height; - // Draw the text from top to bottom for (int yBitMapOffset = limitArea.top; yBitMapOffset putPixel(x + xBitMapOffset, y + yBitMapOffset, foreground); @@ -110,7 +101,7 @@ void Font::drawText(int32_t x, int32_t y, Colour foregroundColour, Colour backgr } // If the y is the bottom then add an underline - if (isUnderlined && yBitMapOffset == yLimit - 1) { + if (is_underlined && yBitMapOffset == yLimit - 1) { // Draw the pixel context -> putPixel(x + xBitMapOffset, y + yBitMapOffset, foreground); @@ -120,7 +111,7 @@ void Font::drawText(int32_t x, int32_t y, Colour foregroundColour, Colour backgr //TODO: Bold, Italic // Get the character - uint8_t character = text[xBitMapOffset/8]; // Divide by 8 as each character is 8 pixels wide. + uint8_t character = text[xBitMapOffset/8]; // Check if this pixel is set or not bool set = font8x8[(uint16_t)character * 8 + yBitMapOffset] & (128 >> (xBitMapOffset % 8)); @@ -133,44 +124,43 @@ void Font::drawText(int32_t x, int32_t y, Colour foregroundColour, Colour backgr } /** - * @details Get the height of the text + * @brief Get the height of the text + * * @param text The text to get the height of * @return The height of the text */ -uint32_t Font::getTextHeight(string text) { +uint32_t Font::get_text_height(string text) { return 8; } /** - * @details Get the width of the text + * @brief Get the width of the text + * * @param text The text to get the width of * @return The width of the text */ -uint32_t Font::getTextWidth(string text) { +uint32_t Font::get_text_width(string text) { uint32_t length = 0; for(string c = (string)text; *c != '\0'; ++c) length++; return length*8; } -void Font::getFont8x8(uint8_t (&font8x8)[2048]) { +void Font::get_font_8_x_8(uint8_t (&font8x8)[2048]) { } - AmigaFont::AmigaFont() { - } AmigaFont::~AmigaFont() { - } -void AmigaFont::getFont8x8(uint8_t (&font8x8)[2048]) { uint8_t fontData[2048] = { +void AmigaFont::get_font_8_x_8(uint8_t (&font8x8)[2048]) { uint8_t fontData[2048] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E, 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E, @@ -432,5 +422,4 @@ void AmigaFont::getFont8x8(uint8_t (&font8x8)[2048]) { uint8_t fontData[2048] = for (int i = 0; i < 2048; ++i) { font8x8[i] = fontData[i]; } -} - +} \ No newline at end of file diff --git a/kernel/src/gui/widget.cpp b/kernel/src/gui/widget.cpp index ad5c3f9d..3d84aa1c 100644 --- a/kernel/src/gui/widget.cpp +++ b/kernel/src/gui/widget.cpp @@ -14,37 +14,13 @@ Widget::Widget() : KeyboardEventHandler() { - // No parent, not valid - parent = 0; - valid = false; - - // Set the minimum size to 5px - minWidth = 5; - minHeight = 5; - - // Set tne maximum size to the maximum value of a 32 bit integer - maxWidth = 0x8FFFFFFF; - maxHeight = 0x8FFFFFFF; - } Widget::Widget(int32_t left, int32_t top, uint32_t width, uint32_t height) : KeyboardEventHandler(), - position(left, top, width, height) + m_position(left, top, width, height) { - // No parent, not valid - parent = 0; - valid = false; - - // Set the minimum size to 5px - minWidth = 5; - minHeight = 5; - - // Set tne maximum size to the maximum value of a 32 bit integer - maxWidth = 0x8FFFFFFF; - maxHeight = 0x8FFFFFFF; - } @@ -53,7 +29,7 @@ Widget::~Widget(){ } /** - * @details Draw the widget on the screen + * @brief Draw the widget on the screen * * @param gc The graphics context to draw the widgets pixels on * @param area The area of the widget to draw @@ -63,15 +39,15 @@ void Widget::draw(GraphicsContext *gc, Rectangle &area) { } /** - * @details Invalidates the entire widget. This forces the widget to be redrawn on the next screen update + * @brief Invalidates the entire widget. This forces the widget to be redrawn on the next screen update */ void Widget::invalidate() { // Convert the relative coordinates to absolute coordinates - Coordinates absCoords = absoluteCoordinates(Coordinates(0,0)); + Coordinates coordinates = absolute_coordinates(Coordinates(0, 0)); // Create a rectangle with the absolute coordinates and the size of the widget - Rectangle invalidArea = Rectangle(absCoords.first, absCoords.second, position.width, position.height); + Rectangle invalidArea = Rectangle(coordinates.first, coordinates.second, m_position.width, m_position.height); // Invalidate the area invalidate(invalidArea); @@ -79,225 +55,221 @@ void Widget::invalidate() { } /** - * @details Invalidates a specific area of the widget. This forces that part of the screen to be redrawn on the next screen update + * @brief Invalidates a specific area of the widget. This forces that part of the screen to be redrawn on the next screen update * * @param area The area of the widget to invalidate */ void Widget::invalidate(Rectangle &area) { - // If the widget has a parent, invalidate the area relative to the parent - if(parent != 0){ - parent -> invalidate(area); - } - + // If the widget has a parent, invalidate the area of the parent + if(m_parent != 0) + m_parent->invalidate(area); } /** - * @details Set the parent of a widget to this widget, making it into a child + * @brief Set the parent of a widget to this widget, making it into a child * * @param child The child to add */ -void Widget::addChild(Widget *child) { +void Widget::add_child(Widget *child) { - // Set the parent of the child to this widget - child -> parent = this; + // Parent the child to this widget + child ->m_parent = this; } -Coordinates Widget::absoluteCoordinates(Coordinates coordinates) { +Coordinates Widget::absolute_coordinates(common::Coordinates coordinates) { - // If the widget has a parent, add the coordinates of the parent to the coordinates of the widget - if(parent != 0){ - return parent -> absoluteCoordinates(Coordinates(coordinates.first + position.left, coordinates.second + position.top)); - } + // Return the parents absolute coordinates + if(m_parent != 0) + return m_parent->absolute_coordinates(Coordinates(coordinates.first + m_position.left, coordinates.second + m_position.top)); - // If the widget has no parent, return the coordinates of the widget - return Coordinates(coordinates.first + position.left, coordinates.second + position.top); + // If the widget has no m_parent, return the coordinates of the widget + return Coordinates(coordinates.first + m_position.left, coordinates.second + m_position.top); } /** - * @details Check if the widget contains a specific coordinate + * @brief Check if the widget contains a specific coordinate * * @param x The x coordinate * @param y The y coordinate * @return True if the widget contains the coordinate, false if it does not */ -bool Widget::containsCoordinate(uint32_t x, uint32_t y) { +bool Widget::contains_coordinate(uint32_t x, uint32_t y) { // Check if the coordinates are within the bounds of the widget - return position.contains(x,y); + return m_position.contains(x,y); } /** - * @details Get the position of the widget + * @brief Get the position of the widget * * @return The position of the widget */ -Rectangle Widget::getPosition() { - return position; +Rectangle Widget::position() { + return m_position; } /** - * @details Set the position of the widget, and invalidate the old and new positions so they are redrawn + * @brief Set the position of the widget, and invalidate the old and new positions so they are redrawn * * @param left The new left position of the rectangle * @param top The new top position of the rectangle */ void Widget::move(int32_t left, int32_t top) { - // Widget is no longer valid as it needs to be redrawn somewhere else. This means the old position needs to be invalidated so the pixels behind this widget are redrawn + + // Invalidate the old position invalidate(); // Set the new position - position.left = left; - position.top = top; + m_position.left = left; + m_position.top = top; - // Widget is now valid so update the pixels in the new position + // Re draw the widget in the new position invalidate(); } /** - * @details Set the size of the widget, and invalidate the old and new positions so they are redrawn + * @brief Set the size of the widget, and invalidate the old and new positions so they are redrawn * - * @param width The new width of the rectangle - * @param height The new height of the rectangle + * @param width The new m_width of the rectangle + * @param height The new m_height of the rectangle */ void Widget::resize(int32_t width, int32_t height) { // Restrict the width and height to the minimum and maximum values - if(width < minWidth) width = minWidth; - if(height < minHeight) height = minHeight; - if(width > maxWidth) width = maxWidth; - if(height > maxHeight) height = maxHeight; + if(width < m_min_width) width = m_min_width; + if(height < m_min_height) height = m_min_height; + if(width > m_max_width) width = m_max_width; + if(height > m_max_height) height = m_max_height; // Store the old position, set the new position - Rectangle oldPosition = position; - position.width = width; - position.height = height; + Rectangle old_position = m_position; + m_position.width = width; + m_position.height = height; // Find the areas that need to be redrawn by subtracting the old position from the new position, and vice versa - Vector> invalidAreasOld = oldPosition.subtract(position); - Vector> invalidAreasNew = position.subtract(oldPosition); + Vector> invalid_areas_old = old_position.subtract(m_position); + Vector> invalid_areas_new = m_position.subtract(old_position); - // Right and Bottom require to be fully invalidated - if(position.width > oldPosition.width || position.height > oldPosition.height || oldPosition.width > position.width || oldPosition.height > position.height){ + // Right and Bottom require to be fully invalidated TODO: Fix this hack + if(m_position.width > old_position.width || m_position.height > old_position.height || old_position.width > m_position.width || old_position.height > m_position.height){ invalidate(); return; } - //Loop through the areas that need to be redrawn and invalidate them - for(int i = 0; i < invalidAreasOld.size(); i++){ - invalidate(invalidAreasOld[i]); - } + for(int i = 0; i < invalid_areas_old.size(); i++) + invalidate(invalid_areas_old[i]); + + for(int i = 0; i < invalid_areas_new.size(); i++) + invalidate(invalid_areas_new[i]); - for(int i = 0; i < invalidAreasNew.size(); i++){ - invalidate(invalidAreasNew[i]); - } } /** - * @details Set the current focuesd widget to be this widget + * @brief Set the current focused widget to be this widget */ void Widget::focus() { + // Set the focus the widget to this widget - setFocus(this); + set_focus(this); } /** - * @details Sets the widget that is currently focussed + * @brief Sets the widget that is currently focussed + * * @param widget The widget to set as focussed */ -void Widget::setFocus(Widget *widget) { +void Widget::set_focus(Widget *widget) { - // If the widget has a parent, set the focus of the parent to this widget - if(parent != 0){ - parent->setFocus(widget); - } + // Focus the parent to this widget + if(m_parent != 0) + m_parent->set_focus(widget); } /** - * @details Handles the event when the widget is focussed + * @brief Handles the event when the widget is focussed */ -void Widget::onFocus() { +void Widget::on_focus() { } /** - * @details Handles the event when the widget is unfocussed + * @brief Handles the event when the widget is unfocused */ -void Widget::onFocusLost() { +void Widget::on_focus_lost() { } /** - * @details Brings this widget to the front of the screen + * @brief Brings this widget to the front of the screen */ -void Widget::bringToFront() { +void Widget::bring_to_front() { // Bring this widget to the front of the screen - bringToFront(this); + bring_to_front(this); } /** - * @details Brings a specific widget to the front of the screen + * @brief Brings a specific widget to the front of the screen * * @param widget The widget to bring to the front */ -void Widget::bringToFront(Widget *widget) { +void Widget::bring_to_front(Widget *widget) { - // If the widget has a parent, bring the widget to the front of the parent - if(parent != 0){ - parent->bringToFront(widget); - } + // Bring the parent to the front of the screen + if(m_parent != 0) + m_parent->bring_to_front(widget); } /** - * @details Handles the event when the mouse is moved on to the widget + * @brief Handles the event when the mouse is moved on to the widget * * @param toX The x coordinate of the mouse * @param toY The y coordinate of the mouse */ -void Widget::onMouseEnterWidget(uint32_t toX, uint32_t toY) { +void Widget::on_mouse_enter_widget(uint32_t toX, uint32_t toY) { } /** - * @details Handles the event when the mouse is moved out of the widget + * @brief Handles the event when the mouse is moved out of the widget * * @param fromX The x coordinate of the mouse * @param fromY The y coordinate of the mouse */ -void Widget::onMouseLeaveWidget(uint32_t fromX, uint32_t fromY) { +void Widget::on_mouse_leave_widget(uint32_t fromX, uint32_t fromY) { } /** - * @details Handles the event when the mouse is moved over the widget + * @brief Handles the event when the mouse is moved over the widget * * @param fromX The x original coordinate of the mouse * @param fromY The y original coordinate of the mouse * @param toX The x new coordinate of the mouse * @param toY The y new coordinate of the mouse */ -void Widget::onMouseMoveWidget(uint32_t fromX, uint32_t fromY, uint32_t toX, uint32_t toY) { +void Widget::on_mouse_move_widget(uint32_t fromX, uint32_t fromY, uint32_t toX, uint32_t toY) { } /** - * @details Handles the event when the mouse is pressed on the widget + * @brief Handles the event when the mouse is pressed on the widget * * @param x The x coordinate of the mouse when it was pressed * @param y The y coordinate of the mouse when it was pressed * @param button The button that was pressed * @return nullptr */ -peripherals::MouseEventHandler* Widget::onMouseButtonPressed(uint32_t x, uint32_t y, uint8_t button) { +peripherals::MouseEventHandler* Widget::on_mouse_button_pressed(uint32_t x, uint32_t y, uint8_t button) { // Bring the widget to the front of the screen - bringToFront(); + bring_to_front(); // Focus the widget focus(); @@ -307,13 +279,13 @@ peripherals::MouseEventHandler* Widget::onMouseButtonPressed(uint32_t x, uint32_ } /** - * @details Handles the event when the mouse is released on the widget + * @brief Handles the event when the mouse is released on the widget * * @param x The x coordinate of the mouse when it was released * @param y The y coordinate of the mouse when it was released * @param button The button that was released */ -void Widget::onMouseButtonReleased(uint32_t x, uint32_t y, uint8_t button) { +void Widget::on_mouse_button_released(uint32_t x, uint32_t y, uint8_t button) { } @@ -334,20 +306,20 @@ CompositeWidget::~CompositeWidget() { } /** - * @details Draws a section of the widget and its children + * @brief Draws a section of the widget and its m_children * * @param gc The graphics context to draw to * @param area The area to draw */ void CompositeWidget::draw(GraphicsContext *gc, Rectangle &area) { - // Draw the widget with its children - draw(gc, area, children.begin()); + // Draw the widget with its m_children + draw(gc, area, m_children.begin()); } /** - * @details Draws a section of the widget and the children after a specific child + * @brief Draws a section of the widget and the m_children after a specific child * * @param gc The graphics context to draw to * @param area The area to draw @@ -358,38 +330,31 @@ void CompositeWidget::draw(GraphicsContext *gc, Rectangle &area, Vector // Draw the widget Widget::draw(gc, area); - // Get the comp widgets own are - Rectangle ownArea = getPosition(); + // Get the area of the widget + Rectangle own_area = position(); - // Loop through the children - for(Vector::iterator childWidget = start; childWidget != children.end(); childWidget++){ + //Note: has to use iterator as the start is not necessarily the m_first_memory_chunk child + for(Vector::iterator child_widget = start; child_widget != m_children.end(); child_widget++){ - // Get the position of the child - Rectangle childArea = (*childWidget)->getPosition(); + Rectangle child_area = (*child_widget)->position(); // Check if the child is in the area that needs to be redrawn - if(area.intersects(childArea)){ + if(area.intersects(child_area)){ // Get the area that needs to be redrawn - Rectangle redrawArea = area.intersection(childArea); + Rectangle rectangle = area.intersection(child_area); // Translate the area so that it is relative to the child - redrawArea.left -= childArea.left; - redrawArea.top -= childArea.top; + rectangle.left -= child_area.left; + rectangle.top -= child_area.top; // Draw the child - (*childWidget)->draw(gc, redrawArea); - - // Get what is left to draw (the area that is not covered by the child) - Vector> restDrawArea = area.subtract(childArea); + (*child_widget)->draw(gc, rectangle); - // Loop through the areas that need to be redrawn - for(Vector>::iterator restAreaPart = restDrawArea.begin(); restAreaPart != restDrawArea.end(); restAreaPart++){ - - // Call the draw function again with the part of the area, starting from the next child as the children up to this point have already been drawn - draw(gc, *restAreaPart, childWidget + 1); - - } + // Draw what is left of the area that needs to be redrawn + Vector> rest_draw_area = area.subtract(child_area); + for(Vector>::iterator rest_area_part = rest_draw_area.begin(); rest_area_part != rest_draw_area.end(); rest_area_part++) + draw(gc, *rest_area_part, child_widget + 1); // Return as the entire area has now been drawn return; @@ -397,56 +362,51 @@ void CompositeWidget::draw(GraphicsContext *gc, Rectangle &area, Vector } // Now draw the widget itself - drawSelf(gc, area); + draw_self(gc, area); } /** - * @details Draws the widget itself (should be overridden by the derived class) + * @brief Draws the widget itself (should be overridden by the derived class) * * @param gc The graphics context to draw to * @param area The area to draw */ -void CompositeWidget::drawSelf(GraphicsContext *gc, Rectangle &area) { +void CompositeWidget::draw_self(common::GraphicsContext *gc, common::Rectangle &area) { } /** - * @details Adds a child to the widget + * @brief Adds a child to the widget * * @param child The child to add */ -void CompositeWidget::addChild(Widget *child) { +void CompositeWidget::add_child(Widget *child) { - // Add the child to the list of children - children.pushBack(child); - - // Set the parent of the child to this widget - Widget::addChild(child); + // Store the child and parent the child to this widget + m_children.push_back(child); + Widget::add_child(child); } /** - * @details Passes the event to the child that the mouse is over. (Event handling should be done by the derived class) + * @brief Passes the event to the child that the mouse is over. (Event handling should be done by the derived class) * * @param toX The x coordinate of the mouse * @param toY The y coordinate of the mouse */ -void CompositeWidget::onMouseEnterWidget(uint32_t toX, uint32_t toY) { - - // Loop through the children - for(Vector::iterator childWidget = children.begin(); childWidget != children.end(); childWidget++){ +void CompositeWidget::on_mouse_enter_widget(uint32_t toX, uint32_t toY) { - // Get the position of the child - Rectangle childArea = (*childWidget)->getPosition(); + for(auto&child_widget : m_children){ // Check if the mouse is in the child - if(childArea.contains(toX, toY)){ + Rectangle child_area = child_widget->position(); + if(child_area.contains(toX, toY)){ // Get the position of the mouse relative to the child - uint32_t childX = toX - childArea.left; - uint32_t childY = toY - childArea.top; + uint32_t child_x = toX - child_area.left; + uint32_t child_y = toY - child_area.top; - // Call the child's onMouseEnterWidget function - (*childWidget)->onMouseEnterWidget(childX, childY); + // Call the child's on_mouse_enter_widget function + child_widget->on_mouse_enter_widget(child_x, child_y); // Break as the event has been handled break; @@ -455,145 +415,122 @@ void CompositeWidget::onMouseEnterWidget(uint32_t toX, uint32_t toY) { } /** - * @details Passes the event to the child that the mouse is over. (Event handling should be done by the derived class) + * @brief Passes the event to the child that the mouse is over. (Event handling should be done by the derived class) * * @param fromX The x coordinate of the mouse * @param fromY The y coordinate of the mouse */ -void CompositeWidget::onMouseLeaveWidget(uint32_t fromX, uint32_t fromY) { - // Loop through the children - for(Vector::iterator childWidget = children.begin(); childWidget != children.end(); childWidget++){ +void CompositeWidget::on_mouse_leave_widget(uint32_t fromX, uint32_t fromY) { - // Get the position of the child - Rectangle childArea = (*childWidget)->getPosition(); + for(auto&child_widget : m_children){ // Check if the mouse is in the child - if(childArea.contains(fromX, fromY)){ + Rectangle child_area = child_widget->position(); + if(child_area.contains(fromX, fromY)){ // Get the position of the mouse relative to the child - uint32_t childX = fromX - childArea.left; - uint32_t childY = fromY - childArea.top; + uint32_t child_x = fromX - child_area.left; + uint32_t child_y = fromY - child_area.top; - // Call the child's onMouseLeaveWidget function - (*childWidget)->onMouseLeaveWidget(childX, childY); + // Call the child's on_mouse_leave_widget function + child_widget->on_mouse_leave_widget(child_x, child_y); - // Break as the event has been handled + // Event has been handled break; } } } /** - * @details Passes the event to the child that the mouse is over, also generates a leave/enter event for children (Event handling should be done by the derived class) + * @brief Passes the event to the child that the mouse is over, also generates a leave/enter event for children * * @param fromX The x coordinate of the mouse * @param fromY The y coordinate of the mouse * @param toX The x coordinate of the mouse * @param toY The y coordinate of the mouse */ -void CompositeWidget::onMouseMoveWidget(uint32_t fromX, uint32_t fromY, uint32_t toX, uint32_t toY) { - - Widget* leftChild = nullptr; - Widget* enteredChild = nullptr; +void CompositeWidget::on_mouse_move_widget(uint32_t fromX, uint32_t fromY, uint32_t toX, uint32_t toY) { - // Loop through the children - for(Vector::iterator childWidget = children.begin(); childWidget != children.end(); childWidget++){ + Widget* left_child = nullptr; + Widget* entered_child = nullptr; - // Get the position of the child - Rectangle childArea = (*childWidget)->getPosition(); + for(auto&child_widget : m_children){ // Check if the mouse is in the child - bool mouseInFrom = childArea.contains(fromX, fromY); - bool mouseInTo = childArea.contains(toX, toY); + Rectangle child_area = child_widget->position(); + bool mouse_in_from = child_area.contains(fromX, fromY); + bool mouse_in_to = child_area.contains(toX, toY); // If the mouse started in the child - if(mouseInFrom){ - - // Check if the mouse moved out of the child - if(!mouseInTo){ + if(mouse_in_from){ - // The mouse started in the child but is now outside it so it must have left the child - leftChild = *childWidget; + // The mouse moved out of the child + if(!mouse_in_to){ + left_child = child_widget; continue; } - // This means the mouse is still in the child so pass the event to the child - (*childWidget)->onMouseMoveWidget(fromX, fromY, toX, toY); + // Mouse still in the child + child_widget->on_mouse_move_widget(fromX, fromY, toX, toY); }else{ - // Check if the mouse moved into the child - if(mouseInTo){ - // The mouse started outside the child but is now in it so it must have entered the child - enteredChild = *childWidget; - } - + // Mouse moved into the child + if(mouse_in_to) + entered_child = child_widget; } - // Pass the events to the children - if(leftChild != nullptr){ - leftChild->onMouseLeaveWidget(fromX, fromY); - } + // Pass the events to the child + if(left_child != nullptr) + left_child->on_mouse_leave_widget(fromX, fromY); - if(enteredChild != nullptr){ - enteredChild->onMouseEnterWidget(toX, toY); - } + if(entered_child != nullptr) + entered_child->on_mouse_enter_widget(toX, toY); } } /** - * @details Passes the event to the child that the mouse is over. (Event handling should be done by the derived class) + * @brief Passes the event to the child that the mouse is over. * * @param x The x coordinate of the mouse * @param y The y coordinate of the mouse * @param button The button that was pressed * @return The object that has the mouseEventHandler which handled the event */ -peripherals::MouseEventHandler *CompositeWidget::onMouseButtonPressed(uint32_t x, uint32_t y, uint8_t button) { - - MouseEventHandler* mouseEventHandler = 0; +peripherals::MouseEventHandler *CompositeWidget::on_mouse_button_pressed(uint32_t x, uint32_t y, uint8_t button) { - // Loop through the children - for(Vector::iterator childWidget = children.begin(); childWidget != children.end(); childWidget++){ + MouseEventHandler*mouse_event_handler = 0; - // If the mouse was clicked inside the child - if((*childWidget)->containsCoordinate(x, y)){ + for(auto&child_widget : m_children){ - // Pass the event to the child - mouseEventHandler = (*childWidget)->onMouseButtonPressed(x - (*childWidget)->position.left, y - (*childWidget)->position.top, button); - - // Break as the event has been handled + // Pass the event to the child + if(child_widget->contains_coordinate(x, y)){ + mouse_event_handler = child_widget -> on_mouse_button_pressed(x - child_widget->m_position.left, y - child_widget->m_position.top, button); break; } } - // Return the mouseEventHandler - return mouseEventHandler; + return mouse_event_handler; } /** - * @details Passes the event to the child that the mouse is over. (Event handling should be done by the derived class) + * @brief Passes the event to the child that the mouse is over. (Event handling should be done by the derived class) * * @param x The x coordinate of the mouse * @param y The y coordinate of the mouse * @param button The button that was released */ -void CompositeWidget::onMouseButtonReleased(uint32_t x, uint32_t y, uint8_t button) { +void CompositeWidget::on_mouse_button_released(uint32_t x, uint32_t y, uint8_t button) { - // Loop through the children - for(Vector::iterator childWidget = children.begin(); childWidget != children.end(); childWidget++){ + // Loop through the m_children + for(auto&child_widget : m_children){ - // If the mouse was clicked inside the child - if((*childWidget)->containsCoordinate(x, y)){ - - // Pass the event to the child - (*childWidget)->onMouseButtonReleased(x - (*childWidget)->position.left, y - (*childWidget)->position.top, button); - - // Break as the event has been handled + // Pass the event to the child + if(child_widget->contains_coordinate(x, y)){ + child_widget->on_mouse_button_released(x - child_widget->m_position.left, y - child_widget->m_position.top, button); break; } - } } diff --git a/kernel/src/gui/widgets/button.cpp b/kernel/src/gui/widgets/button.cpp index 9a2dac24..e9d8a624 100644 --- a/kernel/src/gui/widgets/button.cpp +++ b/kernel/src/gui/widgets/button.cpp @@ -21,43 +21,44 @@ ButtonEventHandler::~ButtonEventHandler() { } /** - * @details Handles the button events + * @brief Handles the button events + * * @param event The event to handle */ -Event* ButtonEventHandler::onEvent(Event *event) { +Event* ButtonEventHandler::on_event(Event *event) { // Check the event type switch (event -> type) { // Button pressed case BUTTON_PRESSED: - onButtonPressed(((ButtonPressedEvent*)event) -> source); + on_button_pressed(((ButtonPressedEvent *)event)->source); break; // Button released case BUTTON_RELEASED: - onButtonReleased(((ButtonReleasedEvent*)event) -> source); + on_button_released(((ButtonReleasedEvent *)event)->source); break; } - return event; - } /** - * @details Handles the button pressed event + * @brief Handles the button pressed event + * * @param source The source of the event */ -void ButtonEventHandler::onButtonPressed(Button *source) { +void ButtonEventHandler::on_button_pressed(Button *source) { } /** - * @details Handles the button released event + * @brief Handles the button released event + * * @param source The source of the event */ -void ButtonEventHandler::onButtonReleased(Button *source) { +void ButtonEventHandler::on_button_released(Button *source) { } @@ -66,14 +67,14 @@ void ButtonEventHandler::onButtonReleased(Button *source) { //// ___ Button ___ Button::Button(int32_t left, int32_t top, uint32_t width, uint32_t height, string text) -: Widget(left, top, width, height) +: Widget(left, top, width, height), + font(AmigaFont()), + text(text), + background_colour(Colour(0xFF, 0xFF, 0xFF)), + foreground_colour(Colour(0x00, 0x00, 0x00)), + border_colour(Colour(0x57, 0x57, 0x57)) { - // Set the default values - this -> font = AmigaFont(); - this -> text = text; - this -> backgroundColour = Colour(0xFF, 0xFF, 0xFF); - this -> foregroundColour = Colour(0x00, 0x00, 0x00); - this -> borderColour = Colour(0x57, 0x57, 0x57); + } Button::~Button() { @@ -81,7 +82,8 @@ Button::~Button() { } /** - * @details Draws the button + * @brief Draws the button + * * @param gc The graphics context to draw to * @param area The area to draw to */ @@ -90,16 +92,17 @@ void Button::draw(GraphicsContext *gc, Rectangle &area) { // Default Draw Operation Widget::draw(gc, area); - // Get the absolute position of the button - Coordinates buttonCoordinates = absoluteCoordinates(Coordinates(0,0)); - Rectangle buttonPosition = getPosition(); + // Get the absolute m_position of the button + Coordinates buttonCoordinates = absolute_coordinates(Coordinates(0, 0)); + Rectangle buttonPosition = position(); - // Get the x and y position of the button + // Get the x and y m_position of the button int32_t x = buttonCoordinates.first; int32_t y = buttonCoordinates.second; // Draw the background for the button - gc -> fillRectangle(x + area.left, y + area.top, x + area.left + area.width, y + area.top + area.height, backgroundColour); + gc->fill_rectangle(x + area.left, y + area.top, x + area.left + area.width, + y + area.top + area.height, background_colour); // Draw the border (TODO: Make a border class?? Window uses it too) @@ -107,79 +110,91 @@ void Button::draw(GraphicsContext *gc, Rectangle &area) { if(area.intersects(Rectangle(0,0,buttonPosition.width,1))){ // Start in the top left corner of the button and end in the top right corner - gc ->drawLine(x + area.left, y, x + area.left + area.width - 1, y,borderColour); + gc->draw_line(x + area.left, y, x + area.left + area.width - 1, y, + border_colour); } // Left Border if(area.intersects(Rectangle(0,0,1,buttonPosition.height))){ // Start in the top left corner and end in the bottom left corner - gc ->drawLine(x, y + area.top, x, y + area.top + area.height - 1,borderColour); + gc->draw_line(x, y + area.top, x, y + area.top + area.height - 1, + border_colour); } // Right Border if(area.intersects(Rectangle(0,buttonPosition.height - 1,buttonPosition.width,1))){ // Start in the top right corner and end in the bottom right corner - gc ->drawLine(x + area.left, y + buttonPosition.height - 1, x + area.left + area.width - 1, y + buttonPosition.height - 1,borderColour); + gc->draw_line(x + area.left, y + buttonPosition.height - 1, + x + area.left + area.width - 1, + y + buttonPosition.height - 1, border_colour); } // Bottom Border if(area.intersects(Rectangle(buttonPosition.width - 1,0,1,buttonPosition.height))){ // Start in the bottom left corner and end in the bottom right corner - gc ->drawLine(x + buttonPosition.width - 1, y + area.top, x + buttonPosition.width - 1, y + area.top + area.height - 1,borderColour); + gc->draw_line(x + buttonPosition.width - 1, y + area.top, + x + buttonPosition.width - 1, + y + area.top + area.height - 1, border_colour); } // Draw the text common::Rectangle textArea(area.left - 1, area.top - 1, area.width, area.height); - font.drawText(x + 1, y + 1, foregroundColour, backgroundColour, gc, text,textArea); + font.draw_text(x + 1, y + 1, foreground_colour, background_colour, gc, text, + textArea); } /** - * @details Handles the mouse button pressed event - * @param x The x position of the mouse - * @param y The y position of the mouse + * @brief Handles the mouse button pressed event + * + * @param x The x m_position of the mouse + * @param y The y m_position of the mouse * @param button The button that was pressed * @return The mouse event handler */ -MouseEventHandler* Button::onMouseButtonPressed(uint32_t x, uint32_t y, uint8_t button) { - // Raise the button pressed event - raiseEvent(new ButtonPressedEvent(this)); +MouseEventHandler* Button::on_mouse_button_pressed(uint32_t x, uint32_t y, uint8_t button) { + + // Raise the event + raise_event(new ButtonPressedEvent(this)); // Change the button colour - backgroundColour = Colour(0x57, 0x57, 0x57); + background_colour = Colour(0x57, 0x57, 0x57); Widget::invalidate(); // Pass the event on (that it was handled) - return Widget::onMouseButtonPressed(x, y, button); + return Widget::on_mouse_button_pressed(x, y, button); } /** - * @details Handles the mouse button released event - * @param x The x position of the mouse - * @param y The y position of the mouse + * @brief Handles the mouse button released event + * + * @param x The x m_position of the mouse + * @param y The y m_position of the mouse * @param button The button that was released */ -void Button::onMouseButtonReleased(uint32_t x, uint32_t y, uint8_t button) { +void Button::on_mouse_button_released(uint32_t x, uint32_t y, uint8_t button) { // Raise the button released event - raiseEvent(new ButtonReleasedEvent(this)); + raise_event(new ButtonReleasedEvent(this)); // Change the button colour - backgroundColour = Colour(0xFF, 0xFF, 0xFF); + background_colour = Colour(0xFF, 0xFF, 0xFF); Widget::invalidate(); // Pass the event on (that it was handled) - Widget::onMouseButtonReleased(x, y, button); + Widget::on_mouse_button_released(x, y, button); } /// ___ Event ___ ButtonReleasedEvent::ButtonReleasedEvent(Button *source) -: Event(ButtonEvents::BUTTON_RELEASED) { - this -> source = source; +: Event(ButtonEvents::BUTTON_RELEASED), + source(source) +{ + } ButtonReleasedEvent::~ButtonReleasedEvent() { @@ -187,10 +202,11 @@ ButtonReleasedEvent::~ButtonReleasedEvent() { } ButtonPressedEvent::ButtonPressedEvent(Button *source) -: Event(ButtonEvents::BUTTON_PRESSED) { - this -> source = source; +: Event(ButtonEvents::BUTTON_PRESSED), + source(source) +{ } ButtonPressedEvent::~ButtonPressedEvent() { -} +} \ No newline at end of file diff --git a/kernel/src/gui/widgets/inputbox.cpp b/kernel/src/gui/widgets/inputbox.cpp index 2617cf11..05e3c75b 100644 --- a/kernel/src/gui/widgets/inputbox.cpp +++ b/kernel/src/gui/widgets/inputbox.cpp @@ -20,53 +20,46 @@ InputBoxEventHandler::~InputBoxEventHandler() { } -Event* InputBoxEventHandler::onEvent(Event *event) { +Event* InputBoxEventHandler::on_event(Event *event) { switch (event->type) { case INPUTBOX_TEXT_CHANGED: - onInputBoxTextChanged(((InputBoxTextChangedEvent*)event)->newText); + on_input_box_text_changed(((InputBoxTextChangedEvent *)event)->new_text); break; } return event; } -void InputBoxEventHandler::onInputBoxTextChanged(string newText) { +void InputBoxEventHandler::on_input_box_text_changed(string new_text) { } /// ___ InputBox ___ /// InputBox::InputBox(int32_t left, int32_t top, uint32_t width, uint32_t height) -: Widget(left, top, width, height) +: Widget(left, top, width, height), + font(AmigaFont()), + background_colour(Colour(0xFF, 0xFF, 0xFF)), + foreground_colour(Colour(0x00, 0x00, 0x00)), + border_colour(Colour(0x57, 0x57, 0x57)) { - - // Set the defaults - this -> font = AmigaFont(); - cursorPosition = 0; - backgroundColour = Colour(0xFF, 0xFF, 0xFF); - foregroundColour = Colour(0x00, 0x00, 0x00); - borderColour = Colour(0x57, 0x57, 0x57); - // Clear the text buffer - widgetText[0] = '\0'; + widget_text[0] = '\0'; } InputBox::InputBox(int32_t left, int32_t top, uint32_t width, uint32_t height, string text) -: Widget(left, top, width, height) +: Widget(left, top, width, height), + font(AmigaFont()), + background_colour(Colour(0xFF, 0xFF, 0xFF)), + foreground_colour(Colour(0x00, 0x00, 0x00)), + border_colour(Colour(0x57, 0x57, 0x57)) { - // Set the defaults - this -> font = AmigaFont(); - cursorPosition = 0; - backgroundColour = Colour(0xFF, 0xFF, 0xFF); - foregroundColour = Colour(0x00, 0x00, 0x00); - borderColour = Colour(0x57, 0x57, 0x57); - // Clear the text buffer - widgetText[0] = '\0'; + widget_text[0] = '\0'; // Update the text - updateText(text); + update_text(text); } @@ -79,16 +72,17 @@ void InputBox::draw(GraphicsContext *gc, Rectangle &area) { // Default Draw Widget::draw(gc, area); - // Get the absolute position of the input box - Coordinates inputBoxCoordinates = absoluteCoordinates(Coordinates(0,0)); - Rectangle inputBoxPosition = getPosition(); + // Get the absolute m_position of the input box + Coordinates inputBoxCoordinates = absolute_coordinates(Coordinates(0, 0)); + Rectangle inputBoxPosition = position(); - // Get the x and y position of the input box + // Get the x and y m_position of the input box int32_t x = inputBoxCoordinates.first; int32_t y = inputBoxCoordinates.second; // Draw the background for the input box - gc -> fillRectangle(x + area.left, y + area.top, x + area.left + area.width, y + area.top + area.height, backgroundColour); + gc->fill_rectangle(x + area.left, y + area.top, x + area.left + area.width, + y + area.top + area.height, background_colour); // Draw the border (TODO: Make this a function because it is used in multiple places) @@ -96,82 +90,89 @@ void InputBox::draw(GraphicsContext *gc, Rectangle &area) { if(area.intersects(Rectangle(0,0,inputBoxPosition.width,1))){ // Start in the top left corner of the button and end in the top right corner - gc ->drawLine(x + area.left, y, x + area.left + area.width - 1, y,borderColour); + gc->draw_line(x + area.left, y, x + area.left + area.width - 1, y, + border_colour); } // Left Border if(area.intersects(Rectangle(0,0,1,inputBoxPosition.height))){ // Start in the top left corner and end in the bottom left corner - gc ->drawLine(x, y + area.top, x, y + area.top + area.height - 1,borderColour); + gc->draw_line(x, y + area.top, x, y + area.top + area.height - 1, + border_colour); } // Right Border if(area.intersects(Rectangle(0,inputBoxPosition.height - 1,inputBoxPosition.width,1))){ // Start in the top right corner and end in the bottom right corner - gc ->drawLine(x + area.left, y + inputBoxPosition.height - 1, x + area.left + area.width - 1, y + inputBoxPosition.height - 1,borderColour); + gc->draw_line(x + area.left, y + inputBoxPosition.height - 1, + x + area.left + area.width - 1, + y + inputBoxPosition.height - 1, border_colour); } // Bottom Border if(area.intersects(Rectangle(inputBoxPosition.width - 1,0,1,inputBoxPosition.height))){ // Start in the bottom left corner and end in the bottom right corner - gc ->drawLine(x + inputBoxPosition.width - 1, y + area.top, x + inputBoxPosition.width - 1, y + area.top + area.height - 1,borderColour); + gc->draw_line(x + inputBoxPosition.width - 1, y + area.top, + x + inputBoxPosition.width - 1, + y + area.top + area.height - 1, border_colour); } // Draw the text common::Rectangle textArea(area.left - 1, area.top - 1, area.width, area.height); - font.drawText(x + 1, y + 1, foregroundColour, backgroundColour, gc, &widgetText[0],textArea); + font.draw_text(x + 1, y + 1, foreground_colour, background_colour, gc, + &widget_text[0], textArea); } -void InputBox::onFocus() { +void InputBox::on_focus() { // Make the border black on focus - borderColour = Colour(0x00, 0x00, 0x00); + border_colour = Colour(0x00, 0x00, 0x00); invalidate(); } -void InputBox::onFocusLost() { +void InputBox::on_focus_lost() { // Reset the border colour - borderColour = Colour(0x57, 0x57, 0x57); + border_colour = Colour(0x57, 0x57, 0x57); invalidate(); } -void InputBox::onKeyDown(KeyCode keyDownCode, KeyboardState keyDownState) { +void InputBox::on_key_down(KeyCode keyDownCode, KeyboardState keyDownState) { // Handle the key press switch(keyDownCode) { case KeyCode::backspace: { - if(cursorPosition == 0) + if(cursor_position == 0) break; - cursorPosition--; + cursor_position--; // no break - we move the cursor to the left and use the code } case KeyCode::deleteKey: { // Move the text to the left - for(uint32_t i = cursorPosition; widgetText[i] != '\0'; ++i) - widgetText[i] = widgetText[i+1]; + for(uint32_t i = cursor_position; widget_text[i] != '\0'; ++i) + widget_text[i] = widget_text[i+1]; break; } case KeyCode::leftArrow: { // If the cursor is not at the beginning of the text, move it to the left - if(cursorPosition > 0) - cursorPosition--; + if(cursor_position > 0) + cursor_position--; break; } case KeyCode::rightArrow: { // If the cursor is not at the end of the text, move it to the right - if(widgetText[cursorPosition] != '\0') - cursorPosition++; + if(widget_text[cursor_position] != '\0') + cursor_position++; break; } default: @@ -181,23 +182,23 @@ void InputBox::onKeyDown(KeyCode keyDownCode, KeyboardState keyDownState) { if(31 < keyDownCode && keyDownCode < 127) { - uint32_t length = cursorPosition; + uint32_t length = cursor_position; // Find the length of the text buffer - while (widgetText[length] != '\0') { + while (widget_text[length] != '\0') { ++length; } // Shift elements to the right - while (length > cursorPosition) { - widgetText[length + 1] = widgetText[length]; + while (length > cursor_position) { + widget_text[length + 1] = widget_text[length]; --length; } // Insert the new character - widgetText[cursorPosition + 1] = widgetText[cursorPosition]; - widgetText[cursorPosition] = (uint8_t)keyDownCode; - cursorPosition++; + widget_text[cursor_position + 1] = widget_text[cursor_position]; + widget_text[cursor_position] = (uint8_t)keyDownCode; + cursor_position++; }else{ // Dont want to redraw the widget if nothing has changed @@ -212,46 +213,47 @@ void InputBox::onKeyDown(KeyCode keyDownCode, KeyboardState keyDownState) { // Fire the text changed event if(keyDownCode != KeyCode::leftArrow && keyDownCode != KeyCode::rightArrow) - raiseEvent(new InputBoxTextChangedEvent(&widgetText[0])); + raise_event(new InputBoxTextChangedEvent(&widget_text[0])); } -void InputBox::updateText(string newText) { +void InputBox::update_text(string new_text) { // Rewrite the text, start at the beginning - cursorPosition = 0; + cursor_position = 0; // Copy the new text into the widget text - for(char* c = (char*)newText, *buffer = &widgetText[0]; *c != '\0'; ++c, buffer++) + for(char* c = (char*)new_text, *buffer = &widget_text[0]; *c != '\0'; ++c, buffer++) { - // Update the cursor position and the buffer - cursorPosition++; + // Update the cursor m_position and the buffer + cursor_position++; *buffer = *c; } - // Write the null terminator - widgetText[cursorPosition] = '\0'; + // write the null terminator + widget_text[cursor_position] = '\0'; // Redraw the widget invalidate(); // Fire the text changed event - raiseEvent(new InputBoxTextChangedEvent(newText)); + raise_event(new InputBoxTextChangedEvent(new_text)); } -string InputBox::getText() { - return &widgetText[0]; +string InputBox::get_text() { + return &widget_text[0]; } /// ___ Events ___ /// -InputBoxTextChangedEvent::InputBoxTextChangedEvent(string newText) -: Event(INPUTBOX_TEXT_CHANGED) { - this->newText = newText; +InputBoxTextChangedEvent::InputBoxTextChangedEvent(string new_text) +: Event(INPUTBOX_TEXT_CHANGED), + new_text(new_text) +{ } InputBoxTextChangedEvent::~InputBoxTextChangedEvent() { -} +} \ No newline at end of file diff --git a/kernel/src/gui/widgets/text.cpp b/kernel/src/gui/widgets/text.cpp index 755fced6..000060ff 100644 --- a/kernel/src/gui/widgets/text.cpp +++ b/kernel/src/gui/widgets/text.cpp @@ -10,17 +10,13 @@ using namespace maxOS::gui; using namespace maxOS::gui::widgets; Text::Text(int32_t left, int32_t top, uint32_t width, uint32_t height, string text) -: Widget(left, top, width, height) +: Widget(left, top, width, height), + font(AmigaFont()), + foreground_colour(Colour(0,0,0)), + background_colour(Colour(255,255,255)) { - // Set the default font - this -> font = AmigaFont(); - // Set the text - updateText(text); - - // Set the default colours - foregroundColour = Colour(0,0,0); - backgroundColour = Colour(255,255,255); + update_text(text); } Text::~Text() { @@ -29,7 +25,7 @@ Text::~Text() { } /** - * @details Draw the text on the screen + * @brief Draw the text on the screen * * @param gc The graphics context to draw on * @param area The area of the text to draw @@ -39,37 +35,39 @@ void Text::draw(GraphicsContext *gc, Rectangle& area) { // Default Draw Operation Widget::draw(gc, area); - // Get the absolute position of the text - Coordinates textCoordinates = absoluteCoordinates(Coordinates(0,0)); - Rectangle textPosition = getPosition(); + // Get the absolute m_position of the text + Coordinates textCoordinates = absolute_coordinates(Coordinates(0, 0)); + Rectangle textPosition = position(); - // Get the x and y position of the text + // Get the x and y m_position of the text int32_t x = textCoordinates.first; int32_t y = textCoordinates.second; // Draw the background for the text (TODO: Might not need to do this as the background is drawn by the default draw operation) - gc -> fillRectangle(x+area.left, y+area.top, x+area.left+area.width, y+area.top+area.height, backgroundColour); + gc->fill_rectangle(x + area.left, y + area.top, x + area.left + area.width, + y + area.top + area.height, background_colour); // Draw the text - this ->font.drawText(x, y, foregroundColour, backgroundColour, gc, widgetText, area); + this->font.draw_text(x, y, foreground_colour, background_colour, gc, + m_widget_text, area); } /** - * @details Update the text of the widget - * @param newText The new text to display + * @brief Update the text of the widget + * @param new_text The new text to display */ -void Text::updateText(string newText) { +void Text::update_text(string new_text) { // Copy the new text into the widget by looping through the characters for(uint32_t i = 0; i < 1000; i++) { // Set the character - this -> widgetText[i] = newText[i]; + this ->m_widget_text[i] = new_text[i]; // Check if the end of the string has been reached - if(newText[i] == '\0') + if(new_text[i] == '\0') break; } diff --git a/kernel/src/gui/window.cpp b/kernel/src/gui/window.cpp index aac94daf..96170bc0 100644 --- a/kernel/src/gui/window.cpp +++ b/kernel/src/gui/window.cpp @@ -10,72 +10,63 @@ using namespace maxOS::common; using namespace maxOS::drivers; using namespace maxOS::drivers::peripherals; -Window::Window(int32_t left, int32_t top, uint32_t width, uint32_t height, string titleText) +Window::Window(int32_t left, int32_t top, uint32_t width, uint32_t height, string title_text) : CompositeWidget(left, top, width, height), -// Top at -10 for bar height, -5 for frame, + 2 for the border. Width is the width of the window minus the frame on each side. Height is the height of the title bar plus the frame on the top minus the border. - title(0, -(10 + 5) + 2, width - 2 * 5, 10 + 5 - 3, titleText), - windowWidgetMover(this), - windowWidgetMoverResizerTop(this), - windowWidgetMoverResizerBottom(this), - windowWidgetMoverResizerLeft(this), - windowWidgetMoverResizerRight(this), - windowWidgetMoverResizerTopLeft(this), - windowWidgetMoverResizerTopRight(this), - windowWidgetMoverResizerBottomLeft(this), - windowWidgetMoverResizerBottomRight(this) + m_title(0, -(10 + 5) + 2, width - 2 * 5, 10 + 5 - 3, title_text), + m_mover(this), + m_resizer_top(this), + m_resizer_bottom(this), + m_resizer_left(this), + m_resizer_right(this), + m_resizer_top_left(this), + m_resizer_top_right(this), + m_resizer_bottom_left(this), + m_resizer_bottom_right(this) { - // Set up the window border - windowFrameThickness = 5; - windowTitleBarHeight = 10; // Set the sizing - minWidth = 2 * windowFrameThickness; - minHeight = 2 * windowFrameThickness + windowTitleBarHeight; + m_min_width = 2 * frame_thickness; + m_min_height = 2 * frame_thickness + title_bar_height; // Set the colours - windowAreaColour = Colour(0xff, 0xff, 0xff); // White - windowFrameBorderColour = Colour(0x00, 0x00, 0x00); // Black - windowFrameColour = Colour(0x57,0x57,0x57); // Davy's Grey - title.foregroundColour = Colour(0xff, 0xff, 0xff); // White - title.backgroundColour = windowFrameColour; + area_colour = Colour(0xff, 0xff, 0xff); // White + frame_border_colour = Colour(0x00, 0x00, 0x00); // Black + frame_colour = Colour(0x57,0x57,0x57); // Davy's Grey + m_title.foreground_colour = Colour(0xff, 0xff, 0xff); // White + m_title.background_colour = frame_colour; // Add the title to the window - Window::addChild(&title); + Window::add_child(&m_title); } -Window::Window(Widget *containedWidget, string titleText) -// Width is the width of the contained widget plus the frame on each side and the border. Height is the height of the contained widget plus the frame on the top and bottom plus the height of the title bar plus the border. -: CompositeWidget(0, 0, containedWidget -> getPosition().width + 2 * 5 + 2, containedWidget->getPosition().height + 2 * 5 + 10 + 2), - title(0, -(10 + 5) + 2, containedWidget -> getPosition().width, 10 + 5 - 3, titleText), - windowWidgetMover(this), - windowWidgetMoverResizerTop(this), - windowWidgetMoverResizerLeft(this), - windowWidgetMoverResizerRight(this), - windowWidgetMoverResizerBottom(this), - windowWidgetMoverResizerTopLeft(this), - windowWidgetMoverResizerTopRight(this), - windowWidgetMoverResizerBottomLeft(this), - windowWidgetMoverResizerBottomRight(this) +Window::Window(Widget *containedWidget, string title_text) +: CompositeWidget(0, 0, containedWidget->position().width + 2 * 5 + 2, containedWidget->position().height + 2 * 5 + 10 + 2), + m_title(0, -(10 + 5) + 2, containedWidget->position().width, 10 + 5 - 3,title_text), + m_mover(this), + m_resizer_top(this), + m_resizer_left(this), + m_resizer_right(this), + m_resizer_bottom(this), + m_resizer_top_left(this), + m_resizer_top_right(this), + m_resizer_bottom_left(this), + m_resizer_bottom_right(this) { - // Set up the window border - windowFrameThickness = 5; - windowTitleBarHeight = 10; - // Set the sizing - minWidth = 2 * windowFrameThickness; - minHeight = 2 * windowFrameThickness + windowTitleBarHeight; + m_min_width = 2 * frame_thickness; + m_min_height = 2 * frame_thickness + title_bar_height; // Set the colours - windowAreaColour = Colour(0xff, 0xff, 0xff); // White - windowFrameBorderColour = Colour(0x00, 0x00, 0x00); // Black - windowFrameColour = Colour(0x57,0x57,0x57); // Davy's Grey - title.foregroundColour = Colour(0xff, 0xff, 0xff); // White - title.backgroundColour = windowFrameColour; + area_colour = Colour(0xff, 0xff, 0xff); // White + frame_border_colour = Colour(0x00, 0x00, 0x00); // Black + frame_colour = Colour(0x57,0x57,0x57); // Davy's Grey + m_title.foreground_colour = Colour(0xff, 0xff, 0xff); // White + m_title.background_colour = frame_colour; - // Add the title to the window - Window::addChild(&title); - Window::addChild(containedWidget); + // Add the m_title to the window + Window::add_child(&m_title); + Window::add_child(containedWidget); } @@ -84,151 +75,127 @@ Window::~Window() { } /** - * @details This function is called when a button is pressed. + * @brief Handles the mouse button being pressed. * * @param x The x coordinate of the mouse. * @param y The y coordinate of the mouse. * @param button The button that is pressed. */ -MouseEventHandler* Window::onMouseButtonPressed(uint32_t mouseX, uint32_t mouseY, uint8_t button){ +MouseEventHandler* Window::on_mouse_button_pressed(uint32_t mouseX, uint32_t mouseY, uint8_t button){ + + // Pass the mouse event to the children + maxOS::drivers::peripherals::MouseEventHandler* child_result = CompositeWidget::on_mouse_button_pressed(mouseX, mouseY, button); + Rectangle window_position = position(); - maxOS::drivers::peripherals::MouseEventHandler* childrenResult = CompositeWidget::onMouseButtonPressed(mouseX,mouseY,button); - Rectangle windowPosition = getPosition(); + // Bring the window to the front + bring_to_front(); - // Check if the mouse is in the frame - if(mouseX <= windowFrameThickness) // This means the mouse is in the left as the x position (relative to this object) has not passed the frame + if(mouseX <= frame_thickness) { - if(mouseY <= windowFrameThickness) // If y is also less than the frame thickness then the mouse is in the top left corner - return &windowWidgetMoverResizerTopLeft; + if(mouseY <= frame_thickness) + return &m_resizer_top_left; - else if(mouseY < windowPosition.height - windowFrameThickness) // If y is also greater than the height of the window minus the frame thickness then the mouse is above the bottom left corner - return &windowWidgetMoverResizerLeft; + else if(mouseY < window_position.height - frame_thickness) + return &m_resizer_left; - else // Otherwise it's in the bottom left corner - return &windowWidgetMoverResizerBottomLeft; + else + return &m_resizer_bottom_left; } - else if(mouseX < windowPosition.width - windowFrameThickness) // This means the mouse is in the middle as the x position (relative to this object) has passed the frame on the left but not the right + else if(mouseX < window_position.width - frame_thickness) { - if(mouseY <= windowFrameThickness) // If y is also less than the frame thickness then the mouse is in the top middle - return &windowWidgetMoverResizerTop; + if(mouseY <= frame_thickness) + return &m_resizer_top; - else if(mouseY < windowFrameThickness+windowTitleBarHeight) // If y less thant the frame thickness and the height of the title bar then the mouse is in the title bar - return &windowWidgetMover; + else if(mouseY < frame_thickness + title_bar_height) + return &m_mover; - else if(mouseY >= windowPosition.height-windowFrameThickness) // If y is also greater than the height of the window minus the frame thickness then the mouse is in the bottom - return &windowWidgetMoverResizerBottom; + else if(mouseY >= window_position.height - frame_thickness) + return &m_resizer_bottom; } else { - if(mouseY <= windowFrameThickness) // If y is also less than the frame thickness then the mouse is in the top right corner - return &windowWidgetMoverResizerTopRight; + if(mouseY <= frame_thickness) + return &m_resizer_top_right; - else if(mouseY < windowPosition.height-windowFrameThickness) // If y is also greater than the height of the window minus the frame thickness then the mouse is above the bottom right corner - return &windowWidgetMoverResizerRight; + else if(mouseY < window_position.height-frame_thickness) + return &m_resizer_right; - else // Otherwise its in the bottom right corner - return &windowWidgetMoverResizerBottomRight; + else + return &m_resizer_bottom_right; } - - return childrenResult; + return child_result; } /** - * @details This function draws the window. + * @brief Draws the window and its children. * * @param gc The graphics context to draw on. */ -void Window::drawSelf(common::GraphicsContext* gc, common::Rectangle& area){ +void Window::draw_self(common::GraphicsContext* gc, common::Rectangle& area){ // Get the positioning of the window - Coordinates windowAbsolutePosition = CompositeWidget::absoluteCoordinates(Coordinates(0,0)); - Rectangle windowPosition = this -> getPosition(); - int32_t windowX = windowAbsolutePosition.first; - int32_t windowY = windowAbsolutePosition.second; + Coordinates window_absolute_position = CompositeWidget::absolute_coordinates(Coordinates(0, 0)); + Rectangle windowPosition = this->position(); + int32_t window_x = window_absolute_position.first; + int32_t window_y = window_absolute_position.second; // Create an area for the window contents - Rectangle windowContentsArea(windowFrameThickness, windowFrameThickness + windowTitleBarHeight, windowPosition.width - 2 * windowFrameThickness, windowPosition.height - 2 * windowFrameThickness - windowTitleBarHeight); - - // Check if the window contents area is in the area to draw - if(windowContentsArea.intersects(area)){ + Rectangle window_contents_area( frame_thickness, frame_thickness + title_bar_height, windowPosition.width - 2 * frame_thickness, windowPosition.height - 2 * frame_thickness - title_bar_height); - // Get the parts of the window contents area that are in the area to draw - Rectangle windowContentsAreaToDraw = windowContentsArea.intersection(area); - - // Draw the window contents area (adding windowX and windowY to draw in the correct place) - gc -> fillRectangle(windowContentsAreaToDraw.left + windowX, windowContentsAreaToDraw.top + windowY, windowContentsAreaToDraw.left + windowContentsAreaToDraw.width + windowX, windowContentsAreaToDraw.top + windowContentsAreaToDraw.height + windowY, windowAreaColour); + // Draw the window contents if they are in the area to draw + if(window_contents_area.intersects(area)){ + Rectangle contents_drawable = window_contents_area.intersection(area); + gc->fill_rectangle(contents_drawable.left + window_x, contents_drawable.top + window_y, contents_drawable.left + contents_drawable.width + window_x, contents_drawable.top + contents_drawable.height + window_y,area_colour); } - // Draw the top of the window frame and the title bar (does not include left and right borders so start at windowFrameThickness and end at windowPosition.width - windowFrameThickness) - Rectangle windowFrameTopArea(windowFrameThickness, 0, windowPosition.width - 2 * windowFrameThickness, windowFrameThickness + windowTitleBarHeight); - if(windowFrameTopArea.intersects(area)){ - - // Get the parts of the window frame top area that are in the area to draw - Rectangle windowFrameTopAreaToDraw = windowFrameTopArea.intersection(area); - - // Draw the window frame top area (adding windowX and windowY to draw in the correct place) - gc -> fillRectangle(windowFrameTopAreaToDraw.left + windowX, windowFrameTopAreaToDraw.top + windowY, windowFrameTopAreaToDraw.left + windowFrameTopAreaToDraw.width + windowX, windowFrameTopAreaToDraw.top + windowFrameTopAreaToDraw.height + windowY, windowFrameColour); - + // Draw the frame if it is in the area to draw + Rectangle window_frame_top_area(frame_thickness, 0, windowPosition.width - 2 * frame_thickness,frame_thickness + title_bar_height); + if(window_frame_top_area.intersects(area)){ + Rectangle frame_drawable = window_frame_top_area.intersection(area); + gc->fill_rectangle(frame_drawable.left + window_x, frame_drawable.top + window_y, frame_drawable.left + frame_drawable.width + window_x, frame_drawable.top + frame_drawable.height + window_y, frame_colour); } - // Draw the bottom of the window frame (does not include left and right borders so start at windowFrameThickness and end at windowPosition.width - windowFrameThickness) - Rectangle windowFrameBottomArea(windowFrameThickness, windowPosition.height - windowFrameThickness, windowPosition.width - 2*windowFrameThickness, windowFrameThickness); - if(windowFrameBottomArea.intersects(area)){ - - // Get the parts of the window frame top area that are in the area to draw - Rectangle windowFrameBottomAreaToDraw = windowFrameBottomArea.intersection(area); - - // Draw the window frame top area (adding windowX and windowY to draw in the correct place) - gc -> fillRectangle(windowX + windowFrameBottomAreaToDraw.left, windowY + windowFrameBottomAreaToDraw.top, windowX + windowFrameBottomAreaToDraw.left + windowFrameBottomAreaToDraw.width, windowY + windowFrameBottomAreaToDraw.top + windowFrameBottomAreaToDraw.height, windowFrameColour); - + // Draw the bottom of the window frame + Rectangle window_frame_bottom_area(frame_thickness, windowPosition.height - frame_thickness, windowPosition.width - 2* frame_thickness, frame_thickness); + if(window_frame_bottom_area.intersects(area)){ + Rectangle bottom_drawable = window_frame_bottom_area.intersection(area); + gc->fill_rectangle(window_x + bottom_drawable.left, window_y + bottom_drawable.top, window_x + bottom_drawable.left + bottom_drawable.width, window_y + bottom_drawable.top + bottom_drawable.height, frame_colour); } // Draw the left of the window frame - Rectangle windowFrameLeftArea(0,0, windowFrameThickness, windowPosition.height); - if(windowFrameLeftArea.intersects(area)){ - - // Get the parts of the window frame top area that are in the area to draw - Rectangle windowFrameLeftAreaToDraw = windowFrameLeftArea.intersection(area); - - // Draw the window frame top area (adding windowX and windowY to draw in the correct place) - gc -> fillRectangle(windowX + windowFrameLeftAreaToDraw.left, windowY + windowFrameLeftAreaToDraw.top, windowX + windowFrameLeftAreaToDraw.left + windowFrameLeftAreaToDraw.width, windowY + windowFrameLeftAreaToDraw.top + windowFrameLeftAreaToDraw.height, windowFrameColour); - + Rectangle window_frame_left_area(0,0, frame_thickness, windowPosition.height); + if(window_frame_left_area.intersects(area)){ + Rectangle left_drawable = window_frame_left_area.intersection(area); + gc->fill_rectangle(window_x + left_drawable.left, window_y + left_drawable.top, window_x + left_drawable.left + left_drawable.width, window_y + left_drawable.top + left_drawable.height,frame_colour); } // Draw the right of the window frame - Rectangle windowFrameRightArea(windowPosition.width - windowFrameThickness, 0, windowFrameThickness, windowPosition.height); - if(windowFrameRightArea.intersects(area)){ - - // Get the parts of the window frame top area that are in the area to draw - Rectangle windowFrameRightAreaToDraw = windowFrameRightArea.intersection(area); - - // Draw the window frame top area (adding windowX and windowY to draw in the correct place) - gc -> fillRectangle(windowX + windowFrameRightAreaToDraw.left, windowY + windowFrameRightAreaToDraw.top, windowX + windowFrameRightAreaToDraw.left + windowFrameRightAreaToDraw.width, windowY + windowFrameRightAreaToDraw.top + windowFrameRightAreaToDraw.height, windowFrameColour); - + Rectangle window_frame_right_area(windowPosition.width - frame_thickness, 0, frame_thickness, windowPosition.height); + if(window_frame_right_area.intersects(area)){ + Rectangle right_drawable = window_frame_right_area.intersection(area); + gc->fill_rectangle(window_x + right_drawable.left, window_y + right_drawable.top, window_x + right_drawable.left + right_drawable.width, window_y + right_drawable.top + right_drawable.height, frame_colour); } } /** - * @details Adds a child to the window. + * @brief Adds a child to the window. * * @param child The child to add. */ -void Window::addChild(Widget *child) { +void Window::add_child(Widget *child) { // If there is a child to add if(child != 0){ - // Get the position of the child - Rectangle childPosition = child -> getPosition(); - - // Set the position of the child to be relative to the window frame and border - child -> move(childPosition.left + windowFrameThickness + 1, childPosition.top + windowFrameThickness + windowTitleBarHeight + 1); + // Change the position of the child to be inside the window contents + Rectangle childPosition = child->position(); + child -> move(childPosition.left + frame_thickness + 1, childPosition.top + frame_thickness + title_bar_height + 1); } // Add the child to the window - CompositeWidget::addChild(child); -} + CompositeWidget::add_child(child); +} \ No newline at end of file diff --git a/kernel/src/hardwarecommunication/interrupts.cpp b/kernel/src/hardwarecommunication/interrupts.cpp index 3717a934..af3c3442 100644 --- a/kernel/src/hardwarecommunication/interrupts.cpp +++ b/kernel/src/hardwarecommunication/interrupts.cpp @@ -11,36 +11,29 @@ using namespace maxOS::system; // Define the static variables -InterruptManager* InterruptManager::ActiveInterruptManager = 0; -OutputStream* InterruptManager::errorMessages = 0; -InterruptManager::GateDescriptor InterruptManager::interruptDescriptorTable[256]; +InterruptManager* InterruptManager::s_active_interrupt_manager = 0; +OutputStream* InterruptManager::s_error_messages = 0; +InterruptManager::GateDescriptor InterruptManager::s_interrupt_descriptor_table[256]; ///__Handler__ -InterruptHandler::InterruptHandler(uint8_t interrupNumber, InterruptManager *interruptManager){ - - //Store values given - this->interrupNumber = interrupNumber; - - if(interruptManager == 0) { - this->interruptManager = InterruptManager::ActiveInterruptManager; - } - - this->interruptManager = interruptManager; - +InterruptHandler::InterruptHandler(uint8_t interrupt_number, InterruptManager* interrupt_manager) +: m_interrupt_number(interrupt_number), + m_interrupt_manager(interrupt_manager) +{ // Set the handler in the array - this->interruptManager->setInterruptHandler(interrupNumber, this); + m_interrupt_manager->set_interrupt_handler(interrupt_number, this); } InterruptHandler::~InterruptHandler(){ // Unset the handler in the array - if(this->interruptManager != 0) - this->interruptManager->removeInterruptHandler(interrupNumber); + if(this->m_interrupt_manager != 0) + this->m_interrupt_manager->remove_interrupt_handler(m_interrupt_number); } -void InterruptHandler::HandleInterrupt() { +void InterruptHandler::handle_interrupt() { } @@ -48,172 +41,173 @@ void InterruptHandler::HandleInterrupt() { ///__Manger__ -/** - * @details This function is used to set an entry in the IDT - * - * @param interrupt Interrupt number - * @param CodeSegment Code segment - * @param handler Interrupt Handler - * @param DescriptorPrivilegeLevel Descriptor Privilege Level - * @param DescriptorType Descriptor Type - */ -void InterruptManager::SetInterruptDescriptorTableEntry(uint8_t interrupt, - uint16_t CodeSegment, - void (*handler)(), - uint8_t DescriptorPrivilegeLevel, - uint8_t DescriptorType) -{ - // address of pointer to code segment (relative to global descriptor table) - // and address of the handler (relative to segment) - interruptDescriptorTable[interrupt].handlerAddressLowBits = ((uint32_t) handler) & 0xFFFF; - interruptDescriptorTable[interrupt].handlerAddressHighBits = (((uint32_t) handler) >> 16) & 0xFFFF; - interruptDescriptorTable[interrupt].gdt_codeSegmentSelector = CodeSegment; - - const uint8_t IDT_DESC_PRESENT = 0x80; - interruptDescriptorTable[interrupt].access = IDT_DESC_PRESENT | ((DescriptorPrivilegeLevel & 3) << 5) | DescriptorType; //Combine constant with descriptor type and level. The level is shifted by 5 and only the last 3 bits are needed - interruptDescriptorTable[interrupt].reserved = 0; //Nothing needs to be reserved -} -InterruptManager::InterruptManager(uint16_t hardwareInterruptOffset, system::GlobalDescriptorTable* globalDescriptorTable,ThreadManager* threadManager, OutputStream* handler) - : common::InputStream(handler), - programmableInterruptControllerMasterCommandPort(0x20), - programmableInterruptControllerMasterDataPort(0x21), - programmableInterruptControllerSlaveCommandPort(0xA0), - programmableInterruptControllerSlaveDataPort(0xA1) +InterruptManager::InterruptManager(uint16_t hardware_interrupt_offset, system::GlobalDescriptorTable*global_descriptor_table,ThreadManager*thread_manager, OutputStream* handler) +: common::InputStream(handler), + pic_master_command_port(0x20), + pic_master_data_port(0x21), + pic_slave_command_port(0xA0), + pic_slave_data_port(0xA1), + m_thread_manager(thread_manager), + m_hardware_interrupt_offset(hardware_interrupt_offset) { - this->threadManager = threadManager; - this->hardwareInterruptOffset = hardwareInterruptOffset; - uint32_t CodeSegment = globalDescriptorTable->CodeSegmentSelector(); + uint32_t code_segment = global_descriptor_table->code_segment_selector(); - //Set all the entry's to Ignore so that the ones we don't specify aren't run as there won't be a handler for these and therefore would have caused a protection error + // By default ignore all interrupts so any un handled interrupts wont cause a fault const uint8_t IDT_INTERRUPT_GATE = 0xE; for(uint8_t i = 255; i > 0; --i) { - SetInterruptDescriptorTableEntry(i, CodeSegment, &InterruptIgnore, 0, IDT_INTERRUPT_GATE); //Set to ignore - interruptHandlers[i] = 0; //Set to no handler + set_interrupt_descriptor_table_entry(i, code_segment, &InterruptIgnore, 0, IDT_INTERRUPT_GATE); + m_interrupt_handlers[i] = 0; } - SetInterruptDescriptorTableEntry(0, CodeSegment, &InterruptIgnore, 0, IDT_INTERRUPT_GATE); //Set to ignore (for first in array) - interruptHandlers[0] = 0; //Set to no handler (for first in array) + + // First is also clear + set_interrupt_descriptor_table_entry(0, code_segment, &InterruptIgnore, 0,IDT_INTERRUPT_GATE); + m_interrupt_handlers[0] = 0; //Set Up the base interrupts - SetInterruptDescriptorTableEntry(0x00, CodeSegment, &HandleException0x00, 0, IDT_INTERRUPT_GATE); //Division by zero - SetInterruptDescriptorTableEntry(0x01, CodeSegment, &HandleException0x01, 0, IDT_INTERRUPT_GATE); //Single-step interrupt (see trap flag) - SetInterruptDescriptorTableEntry(0x02, CodeSegment, &HandleException0x02, 0, IDT_INTERRUPT_GATE); //NMI - SetInterruptDescriptorTableEntry(0x03, CodeSegment, &HandleException0x03, 0, IDT_INTERRUPT_GATE); //Breakpoint (which benefits from the shorter 0xCC encoding of INT 3) - SetInterruptDescriptorTableEntry(0x04, CodeSegment, &HandleException0x04, 0, IDT_INTERRUPT_GATE); //Overflow - SetInterruptDescriptorTableEntry(0x05, CodeSegment, &HandleException0x05, 0, IDT_INTERRUPT_GATE); //Bound Range Exceeded - SetInterruptDescriptorTableEntry(0x06, CodeSegment, &HandleException0x06, 0, IDT_INTERRUPT_GATE); //Invalid Opcode - SetInterruptDescriptorTableEntry(0x07, CodeSegment, &HandleException0x07, 0, IDT_INTERRUPT_GATE); //Coprocessor not available - SetInterruptDescriptorTableEntry(0x08, CodeSegment, &HandleException0x08, 0, IDT_INTERRUPT_GATE); //Double Fault - SetInterruptDescriptorTableEntry(0x09, CodeSegment, &HandleException0x09, 0, IDT_INTERRUPT_GATE); //Coprocessor Segment Overrun (386 or earlier only) - SetInterruptDescriptorTableEntry(0x0A, CodeSegment, &HandleException0x0A, 0, IDT_INTERRUPT_GATE); //Invalid Task State Segment - SetInterruptDescriptorTableEntry(0x0B, CodeSegment, &HandleException0x0B, 0, IDT_INTERRUPT_GATE); //Segment not present - SetInterruptDescriptorTableEntry(0x0C, CodeSegment, &HandleException0x0C, 0, IDT_INTERRUPT_GATE); //Stack Segment Fault - SetInterruptDescriptorTableEntry(0x0D, CodeSegment, &HandleException0x0D, 0, IDT_INTERRUPT_GATE); //General Protection Fault - SetInterruptDescriptorTableEntry(0x0E, CodeSegment, &HandleException0x0E, 0, IDT_INTERRUPT_GATE); //Page Fault - SetInterruptDescriptorTableEntry(0x0F, CodeSegment, &HandleException0x0F, 0, IDT_INTERRUPT_GATE); //reserved - SetInterruptDescriptorTableEntry(0x10, CodeSegment, &HandleException0x10, 0, IDT_INTERRUPT_GATE); //x87 Floating Point Exception - SetInterruptDescriptorTableEntry(0x11, CodeSegment, &HandleException0x11, 0, IDT_INTERRUPT_GATE); //Alignment Check - SetInterruptDescriptorTableEntry(0x12, CodeSegment, &HandleException0x12, 0, IDT_INTERRUPT_GATE); //Machine Check - SetInterruptDescriptorTableEntry(0x13, CodeSegment, &HandleException0x13, 0, IDT_INTERRUPT_GATE); //SIMD Floating-Point Exception - SetInterruptDescriptorTableEntry(0x14, CodeSegment, &HandleException0x14, 0, IDT_INTERRUPT_GATE); //Virtualization Exception - SetInterruptDescriptorTableEntry(0x15, CodeSegment, &HandleException0x15, 0, IDT_INTERRUPT_GATE); //Control Protection Exception - SetInterruptDescriptorTableEntry(0x16, CodeSegment, &HandleException0x16, 0, IDT_INTERRUPT_GATE); //reserved - SetInterruptDescriptorTableEntry(0x17, CodeSegment, &HandleException0x17, 0, IDT_INTERRUPT_GATE); //reserved - SetInterruptDescriptorTableEntry(0x18, CodeSegment, &HandleException0x18, 0, IDT_INTERRUPT_GATE); //reserved - SetInterruptDescriptorTableEntry(0x19, CodeSegment, &HandleException0x19, 0, IDT_INTERRUPT_GATE); //reserved - SetInterruptDescriptorTableEntry(0x1A, CodeSegment, &HandleException0x1A, 0, IDT_INTERRUPT_GATE); //reserved - SetInterruptDescriptorTableEntry(0x1B, CodeSegment, &HandleException0x1B, 0, IDT_INTERRUPT_GATE); //reserved - SetInterruptDescriptorTableEntry(0x1C, CodeSegment, &HandleException0x1C, 0, IDT_INTERRUPT_GATE); //reserved - SetInterruptDescriptorTableEntry(0x1D, CodeSegment, &HandleException0x1D, 0, IDT_INTERRUPT_GATE); //reserved - SetInterruptDescriptorTableEntry(0x1E, CodeSegment, &HandleException0x1E, 0, IDT_INTERRUPT_GATE); //reserved - SetInterruptDescriptorTableEntry(0x1F, CodeSegment, &HandleException0x1F, 0, IDT_INTERRUPT_GATE); //reserved - - - //Set up the hardware interrupts (offest by 0x20) //Ranges 0x20 - 0x30 - SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x00, CodeSegment, &HandleInterruptRequest0x00, 0, IDT_INTERRUPT_GATE); //0x20 - Default PIC interval / Timer - SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x01, CodeSegment, &HandleInterruptRequest0x01, 0, IDT_INTERRUPT_GATE); //0x21 - Keyboard - SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x02, CodeSegment, &HandleInterruptRequest0x02, 0, IDT_INTERRUPT_GATE); //0x22 - Cascade (used internally by the two PICs. never raised) - SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x03, CodeSegment, &HandleInterruptRequest0x03, 0, IDT_INTERRUPT_GATE); //0x23 - COM2, COM4 - SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x04, CodeSegment, &HandleInterruptRequest0x04, 0, IDT_INTERRUPT_GATE); //0x24 - COM1, COM3 - SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x05, CodeSegment, &HandleInterruptRequest0x05, 0, IDT_INTERRUPT_GATE); //0x25 - LPT2, LPT4 - SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x06, CodeSegment, &HandleInterruptRequest0x06, 0, IDT_INTERRUPT_GATE); //0x26 - LPT1 - SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x07, CodeSegment, &HandleInterruptRequest0x07, 0, IDT_INTERRUPT_GATE); //0x27 - Floppy Disk - SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x08, CodeSegment, &HandleInterruptRequest0x08, 0, IDT_INTERRUPT_GATE); //0x28 - CMOS Real Time Clock - SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x09, CodeSegment, &HandleInterruptRequest0x09, 0, IDT_INTERRUPT_GATE); //0x29 - Free for peripherals / legacy SCSI / NIC - SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x0A, CodeSegment, &HandleInterruptRequest0x0A, 0, IDT_INTERRUPT_GATE); //0x2A - Free for peripherals / SCSI / NIC - SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x0B, CodeSegment, &HandleInterruptRequest0x0B, 0, IDT_INTERRUPT_GATE); //0x2B - Free for peripherals / SCSI / NIC - SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x0C, CodeSegment, &HandleInterruptRequest0x0C, 0, IDT_INTERRUPT_GATE); //0x0C - Mouse - SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x0D, CodeSegment, &HandleInterruptRequest0x0D, 0, IDT_INTERRUPT_GATE); //0x2D - FPU / Coprocessor / Inter-processor - SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x0E, CodeSegment, &HandleInterruptRequest0x0E, 0, IDT_INTERRUPT_GATE); //0x2E - Primary ATA Hard Disk - SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x0F, CodeSegment, &HandleInterruptRequest0x0F, 0, IDT_INTERRUPT_GATE); //0x2F - Secondary ATA Hard Disk - - SetInterruptDescriptorTableEntry( 0x80, CodeSegment, &HandleInterruptRequest0x80, 0, IDT_INTERRUPT_GATE); //0x80 - Sys calls + set_interrupt_descriptor_table_entry(0x00, code_segment, &HandleException0x00, 0, IDT_INTERRUPT_GATE); //Division by zero + set_interrupt_descriptor_table_entry(0x01, code_segment, &HandleException0x01, 0, IDT_INTERRUPT_GATE); //Single-step interrupt (see trap flag) + set_interrupt_descriptor_table_entry(0x02, code_segment, &HandleException0x02, 0, IDT_INTERRUPT_GATE); //NMI + set_interrupt_descriptor_table_entry(0x03, code_segment, &HandleException0x03, 0, IDT_INTERRUPT_GATE); //Breakpoint (which benefits from the shorter 0xCC encoding of INT 3) + set_interrupt_descriptor_table_entry(0x04, code_segment, &HandleException0x04, 0, IDT_INTERRUPT_GATE); //Overflow + set_interrupt_descriptor_table_entry(0x05, code_segment, &HandleException0x05, 0, IDT_INTERRUPT_GATE); //Bound Range Exceeded + set_interrupt_descriptor_table_entry(0x06, code_segment, &HandleException0x06, 0, IDT_INTERRUPT_GATE); //Invalid Opcode + set_interrupt_descriptor_table_entry(0x07, code_segment, &HandleException0x07, 0, IDT_INTERRUPT_GATE); //Coprocessor not available + set_interrupt_descriptor_table_entry(0x08, code_segment, &HandleException0x08, 0, IDT_INTERRUPT_GATE); //Double Fault + set_interrupt_descriptor_table_entry(0x09, code_segment, &HandleException0x09, 0, IDT_INTERRUPT_GATE); //Coprocessor Segment Overrun (386 or earlier only) + set_interrupt_descriptor_table_entry(0x0A, code_segment, &HandleException0x0A, 0, IDT_INTERRUPT_GATE); //Invalid Task State Segment + set_interrupt_descriptor_table_entry(0x0B, code_segment, &HandleException0x0B, 0, IDT_INTERRUPT_GATE); //Segment not present + set_interrupt_descriptor_table_entry(0x0C, code_segment, &HandleException0x0C, 0, IDT_INTERRUPT_GATE); //Stack Segment Fault + set_interrupt_descriptor_table_entry(0x0D, code_segment, &HandleException0x0D, 0, IDT_INTERRUPT_GATE); //General Protection Fault + set_interrupt_descriptor_table_entry(0x0E, code_segment, &HandleException0x0E, 0, IDT_INTERRUPT_GATE); //Page Fault + set_interrupt_descriptor_table_entry(0x0F, code_segment, &HandleException0x0F, 0, IDT_INTERRUPT_GATE); //reserved + set_interrupt_descriptor_table_entry(0x10, code_segment, &HandleException0x10, 0, IDT_INTERRUPT_GATE); //x87 Floating Point Exception + set_interrupt_descriptor_table_entry(0x11, code_segment, &HandleException0x11, 0, IDT_INTERRUPT_GATE); //Alignment Check + set_interrupt_descriptor_table_entry(0x12, code_segment, &HandleException0x12, 0, IDT_INTERRUPT_GATE); //Machine Check + set_interrupt_descriptor_table_entry(0x13, code_segment, &HandleException0x13, 0, IDT_INTERRUPT_GATE); //SIMD Floating-Point Exception + set_interrupt_descriptor_table_entry(0x14, code_segment, &HandleException0x14, 0, IDT_INTERRUPT_GATE); //Virtualization Exception + set_interrupt_descriptor_table_entry(0x15, code_segment, &HandleException0x15, 0, IDT_INTERRUPT_GATE); //Control Protection Exception + set_interrupt_descriptor_table_entry(0x16, code_segment, &HandleException0x16, 0, IDT_INTERRUPT_GATE); //reserved + set_interrupt_descriptor_table_entry(0x17, code_segment, &HandleException0x17, 0, IDT_INTERRUPT_GATE); //reserved + set_interrupt_descriptor_table_entry(0x18, code_segment, &HandleException0x18, 0, IDT_INTERRUPT_GATE); //reserved + set_interrupt_descriptor_table_entry(0x19, code_segment, &HandleException0x19, 0, IDT_INTERRUPT_GATE); //reserved + set_interrupt_descriptor_table_entry(0x1A, code_segment, &HandleException0x1A, 0, IDT_INTERRUPT_GATE); //reserved + set_interrupt_descriptor_table_entry(0x1B, code_segment, &HandleException0x1B, 0, IDT_INTERRUPT_GATE); //reserved + set_interrupt_descriptor_table_entry(0x1C, code_segment, &HandleException0x1C, 0, IDT_INTERRUPT_GATE); //reserved + set_interrupt_descriptor_table_entry(0x1D, code_segment, &HandleException0x1D, 0, IDT_INTERRUPT_GATE); //reserved + set_interrupt_descriptor_table_entry(0x1E, code_segment, &HandleException0x1E, 0, IDT_INTERRUPT_GATE); //reserved + set_interrupt_descriptor_table_entry(0x1F, code_segment, &HandleException0x1F, 0, IDT_INTERRUPT_GATE); //reserved + + + //Set up the hardware interrupts (offset by 0x20) //Ranges 0x20 - 0x30 + set_interrupt_descriptor_table_entry(hardware_interrupt_offset + 0x00, code_segment, &HandleInterruptRequest0x00, 0, IDT_INTERRUPT_GATE); //0x20 - Default PIC interval / Timer + set_interrupt_descriptor_table_entry(hardware_interrupt_offset + 0x01, code_segment, &HandleInterruptRequest0x01, 0, IDT_INTERRUPT_GATE); //0x21 - Keyboard + set_interrupt_descriptor_table_entry(hardware_interrupt_offset + 0x02, code_segment, &HandleInterruptRequest0x02, 0, IDT_INTERRUPT_GATE); //0x22 - Cascade (used internally by the two PICs. never raised) + set_interrupt_descriptor_table_entry(hardware_interrupt_offset + 0x03, code_segment, &HandleInterruptRequest0x03, 0, IDT_INTERRUPT_GATE); //0x23 - COM2, COM4 + set_interrupt_descriptor_table_entry(hardware_interrupt_offset + 0x04, code_segment, &HandleInterruptRequest0x04, 0, IDT_INTERRUPT_GATE); //0x24 - COM1, COM3 + set_interrupt_descriptor_table_entry(hardware_interrupt_offset + 0x05, code_segment, &HandleInterruptRequest0x05, 0, IDT_INTERRUPT_GATE); //0x25 - LPT2, LPT4 + set_interrupt_descriptor_table_entry(hardware_interrupt_offset + 0x06, code_segment, &HandleInterruptRequest0x06, 0, IDT_INTERRUPT_GATE); //0x26 - LPT1 + set_interrupt_descriptor_table_entry(hardware_interrupt_offset + 0x07, code_segment, &HandleInterruptRequest0x07, 0, IDT_INTERRUPT_GATE); //0x27 - Floppy Disk + set_interrupt_descriptor_table_entry(hardware_interrupt_offset + 0x08, code_segment, &HandleInterruptRequest0x08, 0, IDT_INTERRUPT_GATE); //0x28 - CMOS Real Time Clock + set_interrupt_descriptor_table_entry(hardware_interrupt_offset + 0x09, code_segment, &HandleInterruptRequest0x09, 0, IDT_INTERRUPT_GATE); //0x29 - Free for peripherals / legacy SCSI / NIC + set_interrupt_descriptor_table_entry(hardware_interrupt_offset + 0x0A, code_segment, &HandleInterruptRequest0x0A, 0, IDT_INTERRUPT_GATE); //0x2A - Free for peripherals / SCSI / NIC + set_interrupt_descriptor_table_entry(hardware_interrupt_offset + 0x0B, code_segment, &HandleInterruptRequest0x0B, 0, IDT_INTERRUPT_GATE); //0x2B - Free for peripherals / SCSI / NIC + set_interrupt_descriptor_table_entry(hardware_interrupt_offset + 0x0C, code_segment, &HandleInterruptRequest0x0C, 0, IDT_INTERRUPT_GATE); //0x0C - Mouse + set_interrupt_descriptor_table_entry(hardware_interrupt_offset + 0x0D, code_segment, &HandleInterruptRequest0x0D, 0, IDT_INTERRUPT_GATE); //0x2D - FPU / Coprocessor / Inter-processor + set_interrupt_descriptor_table_entry(hardware_interrupt_offset + 0x0E, code_segment, &HandleInterruptRequest0x0E, 0, IDT_INTERRUPT_GATE); //0x2E - Primary ATA Hard Disk + set_interrupt_descriptor_table_entry(hardware_interrupt_offset + 0x0F, code_segment, &HandleInterruptRequest0x0F, 0, IDT_INTERRUPT_GATE); //0x2F - Secondary ATA Hard Disk + set_interrupt_descriptor_table_entry(hardware_interrupt_offset + 0x60, code_segment, &HandleInterruptRequest0x80, 0, IDT_INTERRUPT_GATE); //0x80 - Sys calls //Send Initialization Control Words - programmableInterruptControllerMasterCommandPort.Write(0x11); - programmableInterruptControllerSlaveCommandPort.Write(0x11); + pic_master_command_port.write(0x11); + pic_slave_command_port.write(0x11); - //Because the CPU uses interrupt 1 etc. , tell the PIC to add 0x20 to it (this is the remapping of hardware) - programmableInterruptControllerMasterDataPort.Write(hardwareInterruptOffset); - programmableInterruptControllerSlaveDataPort.Write(hardwareInterruptOffset+8); + // Remap the PIC to use the hardware interrupt offset + pic_master_data_port.write(hardware_interrupt_offset); + pic_slave_data_port.write(hardware_interrupt_offset + 8); //Tell PICs their roles - programmableInterruptControllerMasterDataPort.Write(0x04); //Master - programmableInterruptControllerSlaveDataPort.Write(0x02); //Slave + pic_master_data_port.write(0x04); //Master + pic_slave_data_port.write(0x02); //Slave //Tell PICS that they are in 8086 mode - programmableInterruptControllerMasterDataPort.Write(0x01); - programmableInterruptControllerSlaveDataPort.Write(0x01); + pic_master_data_port.write(0x01); + pic_slave_data_port.write(0x01); - //This represents the value in the Interrupt Mask Register (IMR), This enables interrupts - programmableInterruptControllerMasterDataPort.Write(0x00); - programmableInterruptControllerSlaveDataPort.Write(0x00); + // Clear the interrupt mask to enable all interrupts + pic_master_data_port.write(0x00); + pic_slave_data_port.write(0x00); //Tell the processor to use the IDT InterruptDescriptorTablePointer idt_pointer; idt_pointer.size = 256*sizeof(GateDescriptor) - 1; - idt_pointer.base = (uint32_t)interruptDescriptorTable; + idt_pointer.base = (uint32_t)s_interrupt_descriptor_table; asm volatile("lidt %0" : : "m" (idt_pointer)); }; InterruptManager::~InterruptManager() { - Deactivate(); + deactivate(); +} + + +/** + * @brief Sets an entry in the Interrupt Descriptor Table + * + * @param interrupt Interrupt number + * @param code_segment_selector_offset Code segment + * @param handler Interrupt Handler + * @param DescriptorPrivilegeLevel Descriptor Privilege Level + * @param descriptor_type Descriptor Type + */ +void InterruptManager::set_interrupt_descriptor_table_entry(uint8_t interrupt, uint16_t code_segment_selector_offset, void (*handler)(), uint8_t DescriptorPrivilegeLevel, uint8_t descriptor_type) +{ + // Store the handler function in the IDT + s_interrupt_descriptor_table[interrupt].handler_address_low_bits = ((uint32_t) handler) & 0xFFFF; + s_interrupt_descriptor_table[interrupt].handler_address_high_bits = (((uint32_t) handler) >> 16) & 0xFFFF; + s_interrupt_descriptor_table[interrupt].gdt_code_segment_selector = code_segment_selector_offset; + + // Set the access + const uint8_t IDT_DESC_PRESENT = 0x80; + s_interrupt_descriptor_table[interrupt].access = IDT_DESC_PRESENT | ((DescriptorPrivilegeLevel & 3) << 5) | descriptor_type; + s_interrupt_descriptor_table[interrupt].reserved = 0; } + /** - * @details This function activates the interrupt manager + * @brief Activates the interrupt manager and starts interrupts (also deactivates the current interrupt manager) */ -void InterruptManager::Activate() { +void InterruptManager::activate() { - if(ActiveInterruptManager != 0){ //There shouldn't be another interrupt manager, but for safety delete another ones. This is because the processor only has 1 IDT - ActiveInterruptManager->Deactivate(); - } + // Deactivate the current interrupt manager + if(s_active_interrupt_manager != 0) + s_active_interrupt_manager->deactivate(); - ActiveInterruptManager = this; - asm("sti"); //sti = start interrupts + // Set the current interrupt manager and start interrupts + s_active_interrupt_manager = this; + asm("sti"); } /** - * @details This function deactivates the interrupt manager + * @brief Deactivates the interrupt manager and stops interrupts */ -void InterruptManager::Deactivate() +void InterruptManager::deactivate() { - if(ActiveInterruptManager == this){ //Only if the active InterruptManger - ActiveInterruptManager = 0; - asm("cli"); //cli = clear interrupts - } - + // If this is the active interrupt manager, deactivate it and stop interrupts + if(s_active_interrupt_manager == this){ + s_active_interrupt_manager = 0; + asm("cli"); + } } /** - * @details This function passes the interrupt request on to the active interrupt manager + * @brief Handles the interrupt request by passing it to the interrupt manager * * @param interruptNumber The interrupt number * @param esp The stack pointer @@ -222,208 +216,117 @@ void InterruptManager::Deactivate() uint32_t InterruptManager::HandleInterrupt(uint8_t interrupt, uint32_t esp) { - if(ActiveInterruptManager != 0){ - return ActiveInterruptManager->DoHandleInterruptRequest(interrupt, esp); //Handle the interrupt in OOP mode instead of Static - } + // If there is an active interrupt manager, handle the interrupt + if(s_active_interrupt_manager != 0) + return s_active_interrupt_manager->handle_interrupt_request(interrupt, esp); + // CPU can continue return esp; } /** - * @details This function handles the interrupt request + * @brief Handles the interrupt request and runs the interrupt handler if there is one * * @param interruptNumber The interrupt number * @param esp The stack pointer * @return The stack pointer */ -uint32_t InterruptManager::DoHandleInterruptRequest(uint8_t interrupt, uint32_t esp) +uint32_t InterruptManager::handle_interrupt_request(uint8_t interrupt, uint32_t esp) { - if(interruptHandlers[interrupt] != 0){ //If it has a handler for it - interruptHandlers[interrupt]->HandleInterrupt(); //Run the handler - } - else{ - if(interrupt != 0x20){ //If not the timer interrupt - - switch (interrupt) { - - case 0x00: //Divide by zero - errorMessages->write("[ERROR] Divide by zero (int 0x00)"); - break; - - case 0x01: //Single step - errorMessages->write("[ERROR] Single step (int 0x01)"); - break; - - case 0x02: //Non maskable interrupt - errorMessages->write("[ERROR] Non maskable interrupt (int 0x02)"); - break; - - case 0x03: //Breakpoint - errorMessages->write("[ERROR] Breakpoint (int 0x03)"); - break; - - case 0x04: //Overflow - errorMessages->write("[ERROR] Overflow (int 0x04)"); - break; - - case 0x05: //Bounds check - errorMessages->write("[ERROR] Bounds check (int 0x05)"); - break; - - case 0x06: //Invalid opcode - errorMessages->write("[ERROR] Invalid opcode (int 0x06)"); - break; - - case 0x07: //Coprocessor not available - errorMessages->write("[ERROR] Coprocessor not available (int 0x07)"); - break; - - case 0x08: //Double fault - errorMessages->write("[ERROR] Double fault (int 0x08)"); - break; - - case 0x09: //Coprocessor segment overrun - errorMessages->write("[ERROR] Coprocessor segment overrun (int 0x09)"); - break; - - case 0x0A: //Invalid task state segment - errorMessages->write("[ERROR] Invalid TSS (int 0x0A)"); - break; - - case 0x0B: //Segment not present - errorMessages->write("[ERROR] Segment not present (int 0x0B)"); - break; - - case 0x0C: //Stack segment fault - errorMessages->write("[ERROR] Stack segment fault (int 0x0C)"); - break; - - case 0x0D: //General protection fault - errorMessages->write("[ERROR] General protection fault (int 0x0D)"); - while(true); - break; - - case 0x0E: //Page fault - errorMessages->write("[ERROR] Page fault (int 0x0E)"); - break; - - case 0x0F: //Reserved - errorMessages->write("[INFO] Reserved (int 0x0F)"); - break; - - case 0x10: //x87 FPU floating point error - errorMessages->write("[ERROR] x87 FPU floating point error (int 0x10)"); - break; - - case 0x11: //Alignment check - errorMessages->write("[INFO] Alignment check (int 0x11)"); - break; - - case 0x12: //Machine check - errorMessages->write("[INFO] Machine check (int 0x12)"); - break; - - case 0x13: //SIMD floating point exception - errorMessages->write("[ERROR] SIMD floating point exception (int 0x13)"); - break; - - case 0x14: //Virtualization exception - errorMessages->write("[ERROR] Virtualization exception (int 0x14)"); - break; - - case 0x15: //Reserved - errorMessages->write("[INFO] Reserved (int 0x15)"); - break; - - case 0x16: //Reserved - errorMessages->write("[INFO] Reserved (int 0x16)"); - break; - - case 0x17: //Reserved - errorMessages->write("[INFO] Reserved (int 0x17)"); - break; - - case 0x18: //Reserved - errorMessages->write("[INFO] Reserved (int 0x18)"); - break; - - case 0x19: //Reserved - errorMessages->write("[INFO] Reserved (int 0x19)"); - break; - - case 0x1A: //Reserved - errorMessages->write("[INFO] Reserved (int 0x1A)"); - break; - - case 0x1B: //Reserved - errorMessages->write("[INFO] Reserved (int 0x1B)"); - break; - - case 0x1C: //Reserved - errorMessages->write("[INFO] Reserved (int 0x1C)"); - break; - - case 0x1D: //Reserved - errorMessages->write("[INFO] Reserved (int 0x1D)"); - break; - - case 0x1E: //Reserved - errorMessages->write("[INFO] Reserved (int 0x1E)"); - break; - - case 0x1F: //Reserved - errorMessages->write("[INFO] Reserved (int 0x1F)"); - break; - + // If there is an interrupt handler, run it + if(m_interrupt_handlers[interrupt] != 0){ + m_interrupt_handlers[interrupt]->handle_interrupt(); + } + else if(interrupt != 0x20){ + + switch (interrupt) { + + case 0x00: s_error_messages->write("[ERROR] Divide by zero (int 0x00)"); break; + case 0x01: s_error_messages->write("[ERROR] Single-step interrupt (int 0x01)"); break; + case 0x02: s_error_messages->write("[ERROR] Non maskable interrupt (int 0x02)"); break; + case 0x03: s_error_messages->write("[ERROR] Breakpoint (int 0x03)"); break; + case 0x04: s_error_messages->write("[ERROR] Overflow (int 0x04)"); break; + case 0x05: s_error_messages->write("[ERROR] Bounds check (int 0x05)"); break; + case 0x06: s_error_messages->write("[ERROR] Invalid opcode (int 0x06)"); break; + case 0x07: s_error_messages->write("[ERROR] Coprocessor not available (int 0x07)"); break; + case 0x08: s_error_messages->write("[ERROR] Double fault (int 0x08)"); break; + case 0x09: s_error_messages->write("[ERROR] Coprocessor segment overrun (int 0x09)"); break; + case 0x0A: s_error_messages->write("[ERROR] Invalid TSS (int 0x0A)"); break; + case 0x0B: s_error_messages->write("[ERROR] Segment not present (int 0x0B)"); break; + case 0x0C: s_error_messages->write("[ERROR] Stack segment fault (int 0x0C)"); break; + case 0x0D: s_error_messages->write("[ERROR] General protection fault (int 0x0D)"); break; + case 0x0E: s_error_messages->write("[ERROR] Page fault (int 0x0E)"); break; + case 0x0F: s_error_messages->write("[INFO] Reserved (int 0x0F)"); break; + case 0x10: s_error_messages->write("[ERROR] x87 FPU floating point error (int 0x10)"); break; + case 0x11: s_error_messages->write("[INFO] Alignment check (int 0x11)"); break; + case 0x12: s_error_messages->write("[INFO] Machine check (int 0x12)"); break; + case 0x13: s_error_messages->write("[ERROR] SIMD floating point exception (int 0x13)"); break; + case 0x14: s_error_messages->write("[ERROR] Virtualization exception (int 0x14)"); break; + case 0x15: s_error_messages->write("[INFO] Reserved (int 0x15)"); break; + case 0x16: s_error_messages->write("[INFO] Reserved (int 0x16)"); break; + case 0x17: s_error_messages->write("[INFO] Reserved (int 0x17)"); break; + case 0x18: s_error_messages->write("[INFO] Reserved (int 0x18)"); break; + case 0x19: s_error_messages->write("[INFO] Reserved (int 0x19)"); break; + case 0x1A: s_error_messages->write("[INFO] Reserved (int 0x1A)"); break; + case 0x1B: s_error_messages->write("[INFO] Reserved (int 0x1B)"); break; + case 0x1C: s_error_messages->write("[INFO] Reserved (int 0x1C)"); break; + case 0x1D: s_error_messages->write("[INFO] Reserved (int 0x1D)"); break; + case 0x1E: s_error_messages->write("[INFO] Reserved (int 0x1E)"); break; + case 0x1F: s_error_messages->write("[INFO] Reserved (int 0x1F)"); break; + + default: + s_error_messages->write("UNHANDLED INTERRUPT 0x"); + s_error_messages->write_hex(interrupt); + s_error_messages->write(" "); + break; - default: - errorMessages->write("UNHANDLED INTERRUPT 0x"); - errorMessages->writeHex(interrupt); - errorMessages->write(" "); - break; - - } } } - //TODO: Cast CPUState and uin3t esp to same - - //Timer interrupt for tasks - if(interrupt == hardwareInterruptOffset) + //Timer interrupt for m_tasks + if(interrupt == m_hardware_interrupt_offset) { - esp = (uint32_t)threadManager->Schedule((CPUState_Thread*)esp); + esp = (uint32_t)m_thread_manager->schedule((CPUState*)esp); } // Acknowledge the interrupt (if it is a hardware interrupt) - if(hardwareInterruptOffset <= interrupt && interrupt < hardwareInterruptOffset+16) + if(m_hardware_interrupt_offset <= interrupt && interrupt < m_hardware_interrupt_offset +16) { - //Send Answer to tell PIC the interrupt was received - programmableInterruptControllerMasterCommandPort.Write(0x20); + pic_master_command_port.write(0x20); - //Answer the master always, but don't answer the slave unless the slave called the interrupt + // Answer the slave PIC if it was the one that sent the interrupt if(0x28 <= interrupt) - programmableInterruptControllerSlaveCommandPort.Write(0x20); + pic_slave_command_port.write(0x20); } - CPUState_Thread cpuStateThread = *((CPUState_Thread*)esp); - return esp; } /** - * @details This function returns the offset of the hardware interrupt + * @brief Returns the offset of the hardware interrupt * * @return The offset of the hardware interrupt */ -uint16_t InterruptManager::HardwareInterruptOffset() { - return hardwareInterruptOffset; +uint16_t InterruptManager::hardware_interrupt_offset() { + return m_hardware_interrupt_offset; } -void InterruptManager::setInterruptHandler(uint8_t interrupt, InterruptHandler *handler) { - interruptHandlers[interrupt] = handler; +/** + * @brief Sets the interrupt handler for the interrupt + * + * @param interrupt The interrupt number + * @param handler The interrupt handler + */ +void InterruptManager::set_interrupt_handler(uint8_t interrupt, InterruptHandler *handler) { + m_interrupt_handlers[interrupt] = handler; } -void InterruptManager::removeInterruptHandler(uint8_t interrupt) { - interruptHandlers[interrupt] = 0; -} +/** + * @brief Removes the interrupt handler for the interrupt + * + * @param interrupt The interrupt number + */ +void InterruptManager::remove_interrupt_handler(uint8_t interrupt) { + m_interrupt_handlers[interrupt] = 0; +} \ No newline at end of file diff --git a/kernel/src/hardwarecommunication/pci.cpp b/kernel/src/hardwarecommunication/pci.cpp index efabe467..7e10e555 100644 --- a/kernel/src/hardwarecommunication/pci.cpp +++ b/kernel/src/hardwarecommunication/pci.cpp @@ -24,7 +24,11 @@ PeripheralComponentInterconnectDeviceDescriptor::~PeripheralComponentInterconnec } -string PeripheralComponentInterconnectDeviceDescriptor::getType() { +/** + * @brief Get the type of the device + * @return Type of the device as a string (or Unknown if the type is not known) + */ +string PeripheralComponentInterconnectDeviceDescriptor::get_type() { switch (class_id) { case 0x00: return (subclass_id == 0x01) ? "VGA" : "Legacy"; @@ -35,9 +39,9 @@ string PeripheralComponentInterconnectDeviceDescriptor::getType() { case 0x06: return "SATA controller"; default: return "Storage"; } - case 0x02: return "Network"; // Network + case 0x02: return "Network"; case 0x03: return "Display"; - case 0x04: // Multimedia + case 0x04: switch(subclass_id) { case 0x00: return "Video"; @@ -45,7 +49,7 @@ string PeripheralComponentInterconnectDeviceDescriptor::getType() { case 0x03: return "Audio"; default: return "Multimedia"; } - case 0x06: // Bridges + case 0x06: switch(subclass_id) { case 0x00: return "Host bridge"; @@ -73,12 +77,12 @@ string PeripheralComponentInterconnectDeviceDescriptor::getType() { ///__CONTROLLER___ -PeripheralComponentInterconnectController::PeripheralComponentInterconnectController(OutputStream* debug) -: dataPort(0xCFC), //PCI Controller - commandPort(0xCF8) //PCI Controller - +PeripheralComponentInterconnectController::PeripheralComponentInterconnectController(OutputStream*stream) +: m_data_port(0xCFC), + m_command_port(0xCF8), + m_debug_messages_stream(stream) { - this->debugMessagesStream = debug; + } PeripheralComponentInterconnectController::~PeripheralComponentInterconnectController() { @@ -86,37 +90,32 @@ PeripheralComponentInterconnectController::~PeripheralComponentInterconnectContr } /** - * @details Read data from the PCI Controller + * @brief read data from the PCI Controller * * @param bus Bus number * @param device Device number * @param function Function number * @param registeroffset Register offset - * @return data from the PCI Controller + * @return data from the PCI Controller */ -uint32_t PeripheralComponentInterconnectController::Read(uint16_t bus, uint16_t device, uint16_t function, uint32_t registeroffset) { - //Structure of the address I / O port : - //31 | Enable bit - //30-24 | Reserved - //23-16 | Bus number - //15-11 | Device number - //10-8 | Function number - //7-0 | Register number , bit 0 and bit 1 are 0 - - uint32_t id = - 0x1 << 31 - | ((bus & 0xFF) << 16) - | ((device & 0x1F) << 11) - | ((function & 0x07) << 8) - | (registeroffset & 0xFC); //Cut off the last two bits of the number - commandPort.Write(id); //The ID is like the address of the port - uint32_t result = dataPort.Read(); +uint32_t PeripheralComponentInterconnectController::read(uint16_t bus, uint16_t device, uint16_t function, uint32_t registeroffset) { + + // Calculate the id + uint32_t id = 0x1 << 31 + | ((bus & 0xFF) << 16) + | ((device & 0x1F) << 11) + | ((function & 0x07) << 8) + | (registeroffset & 0xFC); + m_command_port.write(id); + + // read the data from the port + uint32_t result = m_data_port.read(); return result >> (8* (registeroffset % 4)); } /** - * @details Write data to the PCI Controller + * @brief write data to the PCI Controller * * @param bus Bus number * @param device Device number @@ -124,133 +123,134 @@ uint32_t PeripheralComponentInterconnectController::Read(uint16_t bus, uint16_t * @param registeroffset Register offset * @param value Value to write */ -void PeripheralComponentInterconnectController::Write(uint16_t bus, uint16_t device, uint16_t function, uint32_t registeroffset, uint32_t value) { - uint32_t id = - 0x1 << 31 - | ((bus & 0xFF) << 16) - | ((device & 0x1F) << 11) - | ((function & 0x07) << 8) - | (registeroffset & 0xFC); - commandPort.Write(id); - dataPort.Write(value); +void PeripheralComponentInterconnectController::write(uint16_t bus, uint16_t device, uint16_t function, uint32_t registeroffset, uint32_t value) { + + // Calculate the id + uint32_t id = 0x1 << 31 + | ((bus & 0xFF) << 16) + | ((device & 0x1F) << 11) + | ((function & 0x07) << 8) + | (registeroffset & 0xFC); + m_command_port.write(id); + + // write the data to the port + m_data_port.write(value); } /** - * @details Check if the device has a function + * @brief Check if the device has a function * * @param bus Bus number * @param device Device number * @return true if the device has a function */ -bool PeripheralComponentInterconnectController::DeviceHasFunctions(uint16_t bus, uint16_t device) { +bool PeripheralComponentInterconnectController::device_has_functions(uint16_t bus, uint16_t device) { - //0x0E - return Read(bus,device,0,0x0E) & (1<<7); //Read address, the 7th bit of it returns if there is a function + return read(bus, device, 0, 0x0E) & (1<<7); } /** - * @details Select the driver for the device + * @brief Select the driver for the device * * @param driverManager device driver manager - * @param interruptManager Interrupt manager + * @param interrupt_manager Interrupt manager * @return Driver for the device */ -void PeripheralComponentInterconnectController::selectDrivers(drivers::DriverSelectorEventHandler *handler, hardwarecommunication::InterruptManager *interruptManager, OutputStream *errorMessageStream) { +void PeripheralComponentInterconnectController::select_drivers(DriverSelectorEventHandler *handler, hardwarecommunication::InterruptManager *interrupt_manager, common::OutputStream *error_message_stream) +{ for (int bus = 0; bus < 8; ++bus) { - for (int device = 0; device < 32; ++device) { - int numFunctions = (DeviceHasFunctions(bus,device)) ? 8 : 1; + int numFunctions = (device_has_functions(bus, device)) ? 8 : 1; for (int function = 0; function < numFunctions; ++function) { - PeripheralComponentInterconnectDeviceDescriptor deviceDescriptor = GetDeviceDescriptor(bus, device, function); - //If there is no device then vendor ID is 0x0000, If the device is not ready to react then the vendor ID is 0x0001 - if(deviceDescriptor.vendor_ID == 0x0000 || deviceDescriptor.vendor_ID == 0x0001 || deviceDescriptor.vendor_ID == 0xFFFF){ + // Get the device descriptor, if the vendor id is 0x0000 or 0xFFFF, the device is not present/ready + PeripheralComponentInterconnectDeviceDescriptor deviceDescriptor = get_device_descriptor(bus, device, function); + if(deviceDescriptor.vendor_id == 0x0000 || deviceDescriptor.vendor_id == 0x0001 || deviceDescriptor.vendor_id == 0xFFFF) continue; - } + // Get port number for(int barNum = 5; barNum >= 0; barNum--){ - - BaseAddressRegister bar = getBaseAddressRegister(bus, device, function, barNum); - if(bar.address && (bar.type == InputOutput)){ - deviceDescriptor.portBase = (uint32_t)bar.address; - } + BaseAddressRegister bar = get_base_address_register(bus, device, function, barNum); + if(bar.address && (bar.type == InputOutput)) + deviceDescriptor.port_base = (uint32_t)bar.address; } - // Write to the debug stream - debugMessagesStream->write(deviceDescriptor.getType()); - debugMessagesStream->write(": "); + // write to the debug stream + m_debug_messages_stream->write(deviceDescriptor.get_type()); + m_debug_messages_stream->write(": "); - // Instantiate the driver and add it to the driver manager - Driver* driver = GetDriver(deviceDescriptor, interruptManager); + // Select the driver and print information about the device + Driver* driver = get_driver(deviceDescriptor, interrupt_manager); if(driver != 0){ - handler->onDriverSelected(driver); - debugMessagesStream->write(driver->getVendorName()); - debugMessagesStream->write(" "); - debugMessagesStream->write(driver->getDeviceName()); + handler->on_driver_selected(driver); + m_debug_messages_stream->write(driver->get_vendor_name()); + m_debug_messages_stream->write(" "); + m_debug_messages_stream->write(driver->get_device_name()); }else{ - listKnownDeivce(deviceDescriptor); + list_known_deivce(deviceDescriptor); } // New line - debugMessagesStream->write("\n"); + m_debug_messages_stream->write("\n"); } - } } - } /** - * @details Get the device descriptor + * @brief Get the device descriptor * * @param bus Bus number * @param device Device number * @param function Function number * @return Device descriptor */ -PeripheralComponentInterconnectDeviceDescriptor PeripheralComponentInterconnectController::GetDeviceDescriptor(uint16_t bus, uint16_t device, uint16_t function) { +PeripheralComponentInterconnectDeviceDescriptor PeripheralComponentInterconnectController::get_device_descriptor(uint16_t bus, uint16_t device, uint16_t function) { PeripheralComponentInterconnectDeviceDescriptor result; result.bus = bus; result.device = device; result.function = function; - result.vendor_ID = Read(bus, device, function, 0x00); - result.device_ID = Read(bus, device, function, 0x02); + result.vendor_id = read(bus, device, function, 0x00); + result.device_id = read(bus, device, function, 0x02); - result.class_id = Read(bus, device, function, 0x0B); - result.subclass_id = Read(bus, device, function, 0x0A); - result.interface_id = Read(bus, device, function, 0x09); + result.class_id = read(bus, device, function, 0x0B); + result.subclass_id = read(bus, device, function, 0x0A); + result.interface_id = read(bus, device, function, 0x09); - result.revision = Read(bus, device, function, 0x8); - result.interrupt = Read(bus, device, function, 0x3C); + result.revision = read(bus, device, function, 0x8); + result.interrupt = read(bus, device, function, 0x3C); return result; } /** - * @details Get the driver for the device + * @brief Get the driver for the device * * @param dev Device descriptor - * @param interruptManager Interrupt manager + * @param interrupt_manager Interrupt manager * @return Driver for the device, 0 if there is no driver */ -Driver* PeripheralComponentInterconnectController::GetDriver(PeripheralComponentInterconnectDeviceDescriptor dev, InterruptManager* interruptManager) { +Driver* PeripheralComponentInterconnectController::get_driver(PeripheralComponentInterconnectDeviceDescriptor dev, InterruptManager*interrupt_manager) { + + // Dont use new here, manually allocate memory instead Driver* driver = 0; - switch (dev.vendor_ID) + switch (dev.vendor_id) { case 0x1022: //AMD { - switch (dev.device_ID) + switch (dev.device_id) { case 0x2000: //am79c971 { - amd_am79c973* result = (amd_am79c973*)MemoryManager::activeMemoryManager ->malloc(sizeof(amd_am79c973)); - new (result) amd_am79c973(&dev, interruptManager); + amd_am79c973* result = (amd_am79c973*)MemoryManager::s_active_memory_manager + ->malloc(sizeof(amd_am79c973)); + new (result) amd_am79c973(&dev, interrupt_manager); return result; } @@ -261,13 +261,13 @@ Driver* PeripheralComponentInterconnectController::GetDriver(PeripheralComponent } case 0x8086: //Intel { - switch (dev.device_ID) + switch (dev.device_id) { case 0x100E: //i217 (Ethernet Controller) { - intel_i217* result = (intel_i217*)MemoryManager::activeMemoryManager ->malloc(sizeof(intel_i217)); - new (result) intel_i217(&dev, interruptManager); - + intel_i217* result = (intel_i217*)MemoryManager::s_active_memory_manager + ->malloc(sizeof(intel_i217)); + new (result) intel_i217(&dev, interrupt_manager); return result; } default: @@ -287,9 +287,8 @@ Driver* PeripheralComponentInterconnectController::GetDriver(PeripheralComponent { case 0x00: //VGA { - VideoGraphicsArray* result = (VideoGraphicsArray*)MemoryManager::activeMemoryManager ->malloc(sizeof(VideoGraphicsArray)); + VideoGraphicsArray* result = (VideoGraphicsArray*)MemoryManager::s_active_memory_manager->malloc(sizeof(VideoGraphicsArray)); new (result) VideoGraphicsArray(); - return result; } } @@ -301,20 +300,20 @@ Driver* PeripheralComponentInterconnectController::GetDriver(PeripheralComponent } -void PeripheralComponentInterconnectController::listKnownDeivce(PeripheralComponentInterconnectDeviceDescriptor dev) { - switch (dev.vendor_ID) +void PeripheralComponentInterconnectController::list_known_deivce(PeripheralComponentInterconnectDeviceDescriptor dev) { + switch (dev.vendor_id) { case 0x1022: { // The vendor is AMD - debugMessagesStream->write("AMD "); + m_debug_messages_stream->write("AMD "); // List the device - switch (dev.device_ID) + switch (dev.device_id) { default: - debugMessagesStream->writeHex(dev.device_ID); - break; + m_debug_messages_stream->write_hex(dev.device_id); + break; } break; } @@ -322,19 +321,19 @@ void PeripheralComponentInterconnectController::listKnownDeivce(PeripheralCompon case 0x106B: { // The vendor is Apple - debugMessagesStream->write("Apple "); + m_debug_messages_stream->write("Apple "); // List the device - switch (dev.device_ID) + switch (dev.device_id) { case 0x003F: { - debugMessagesStream->write("KeyLargo/Intrepid USB"); - break; + m_debug_messages_stream->write("KeyLargo/Intrepid USB"); + break; } default: - debugMessagesStream->writeHex(dev.device_ID); + m_debug_messages_stream->write_hex(dev.device_id); break; } break; @@ -343,15 +342,15 @@ void PeripheralComponentInterconnectController::listKnownDeivce(PeripheralCompon case 1234: { // The vendor is QEMU - debugMessagesStream->write("QEMU "); + m_debug_messages_stream->write("QEMU "); // List the device - switch (dev.device_ID) + switch (dev.device_id) { case 0x1111: { - debugMessagesStream->write("Virtual Video Controller"); + m_debug_messages_stream->write("Virtual Video Controller"); break; } } @@ -361,47 +360,47 @@ void PeripheralComponentInterconnectController::listKnownDeivce(PeripheralCompon case 0x8086: { // The vendor is Intel - debugMessagesStream->write("Intel "); + m_debug_messages_stream->write("Intel "); // List the device - switch (dev.device_ID) + switch (dev.device_id) { case 0x1237: { - debugMessagesStream->write("440FX"); + m_debug_messages_stream->write("440FX"); break; } case 0x2415: { - debugMessagesStream->write("AC'97"); + m_debug_messages_stream->write("AC'97"); break; } case 0x7000: { - debugMessagesStream->write("PIIX3"); + m_debug_messages_stream->write("PIIX3"); break; } case 0x7010: { - debugMessagesStream->write("PIIX4"); + m_debug_messages_stream->write("PIIX4"); break; } case 0x7111: { - debugMessagesStream->write("PIIX3"); + m_debug_messages_stream->write("PIIX3"); break; } case 0x7113: { - debugMessagesStream->write("PIIX4 ACPI"); + m_debug_messages_stream->write("PIIX4 ACPI"); break; } @@ -415,18 +414,18 @@ void PeripheralComponentInterconnectController::listKnownDeivce(PeripheralCompon case 0x80EE: { // The vendor is VirtualBox - debugMessagesStream->write("VirtualBox "); + m_debug_messages_stream->write("VirtualBox "); // List the device - switch (dev.device_ID) { + switch (dev.device_id) { case 0xBEEF: { - debugMessagesStream->write("Graphics Adapter"); + m_debug_messages_stream->write("Graphics Adapter"); break; } case 0xCAFE: { - debugMessagesStream->write("Guest Service"); + m_debug_messages_stream->write("Guest Service"); break; } } @@ -434,57 +433,44 @@ void PeripheralComponentInterconnectController::listKnownDeivce(PeripheralCompon } default: // Unknown - debugMessagesStream ->writeHex(dev.vendor_ID); - debugMessagesStream ->write(" "); - debugMessagesStream ->writeHex(dev.device_ID); - break; + m_debug_messages_stream->write_hex(dev.vendor_id); + m_debug_messages_stream->write(" "); + m_debug_messages_stream->write_hex(dev.device_id); + break; } } /** - * @details Get the base address register + * @brief Get the base address register * * @param bus Bus number * @param device Device number * @param function Function number - * @param barNum Base address register number - * @return Base address register + * @param barNum base address register number + * @return base address register */ -BaseAddressRegister PeripheralComponentInterconnectController::getBaseAddressRegister(uint16_t bus, uint16_t device, uint16_t function, uint16_t bar) { +BaseAddressRegister PeripheralComponentInterconnectController::get_base_address_register(uint16_t bus, uint16_t device, uint16_t function, uint16_t bar) { BaseAddressRegister result; // only types 0x00 (normal devices) and 0x01 (PCI-to-PCI bridges) are supported: - uint32_t headerType = Read(bus,device,function,0x0E); + uint32_t headerType = read(bus, device, function, 0x0E); if (headerType & 0x3F) return result; - uint32_t bar_value = Read(bus, device, function, 0x10 + 4*bar); // Get the offset of the base address register (Starts at 0x10) - result.type = (bar_value & 0x1) ? InputOutput : MemoryMapping; // Get the type of the base address register from the last bit (Input/Output or Memory Mapping) - result.address = (uint8_t*) (bar_value & ~0xF); // Get the address of the base address register (Mask the last 4 bits) - + // read the base address register + uint32_t bar_value = read(bus, device, function, 0x10 + 4 * bar); + result.type = (bar_value & 0x1) ? InputOutput : MemoryMapping; + result.address = (uint8_t*) (bar_value & ~0xF); - // Write all 1's to the register and read it back to get the size of the base address register - Write(bus, device, function, 0x10 + 4*bar, 0xFFFFFFF0 | result.type); - - // Read the size of the base address register - result.size = Read(bus, device, function, 0x10 + 4*bar); - result.size = (~result.size | 0xF) + 1; //Get the size of the base address register (Mask the last 4 bits) and add 1 + // read the size of the base address register + write(bus, device, function, 0x10 + 4 * bar, 0xFFFFFFF0 | result.type); + result.size = read(bus, device, function, 0x10 + 4 * bar); + result.size = (~result.size | 0xF) + 1; // Restore the original value of the base address register - Write(bus, device, function, 0x10 + 4*bar, bar_value); + write(bus, device, function, 0x10 + 4 * bar, bar_value); return result; -} - - - - - - - - - - - +} \ No newline at end of file diff --git a/kernel/src/hardwarecommunication/port.cpp b/kernel/src/hardwarecommunication/port.cpp index 65f98eca..83cd52e5 100644 --- a/kernel/src/hardwarecommunication/port.cpp +++ b/kernel/src/hardwarecommunication/port.cpp @@ -6,17 +6,17 @@ using namespace maxOS::hardwarecommunication; -Port::Port(uint16_t portnumber){ - this->portnumber = portnumber; +Port::Port(uint16_t port_number) +: m_port_number(port_number) +{ } + Port::~Port(){ } -//8 BIT (asm is b) - -Port8Bit::Port8Bit(uint16_t portnumber) -: Port(portnumber) +Port8Bit::Port8Bit(uint16_t port_number) +: Port(port_number) { } @@ -25,27 +25,27 @@ Port8Bit::~Port8Bit() { } /** - * @details Write a byte to the port (8Bit) + * @brief write a byte to the port * * @param data the byte to write */ -void Port8Bit::Write(uint8_t data){ - __asm__ volatile("outb %0, %1" : : "a" (data), "Nd" (portnumber)); //Nd--> d:The d register & N:Unsigned 8-bit integer constant +void Port8Bit::write(uint8_t data){ + __asm__ volatile("outb %0, %1" : : "a" (data), "Nd" (m_port_number)); } /** - * @details Read a byte from the port (8Bit) + * @brief read a byte from the port * * @return the byte read */ -uint8_t Port8Bit::Read(){ +uint8_t Port8Bit::read(){ uint8_t result; - __asm__ volatile("inb %1, %0" : "=a" (result) : "Nd" (portnumber)); + __asm__ volatile("inb %1, %0" : "=a" (result) : "Nd" (m_port_number)); return result; } -Port8BitSlow::Port8BitSlow(uint16_t portnumber) -: Port8Bit(portnumber) +Port8BitSlow::Port8BitSlow(uint16_t port_number) +: Port8Bit(port_number) { } @@ -54,20 +54,17 @@ Port8BitSlow::~Port8BitSlow() { } /** - * @details Write a byte to the port (8BitSlow) + * @brief write a byte to the port (slow) * * @param data the byte to write */ -void Port8BitSlow::Write(uint8_t data){ - __asm__ volatile("outb %0, %1\njmp 1f\n1: jmp 1f\n1:" : : "a" (data), "Nd" (portnumber)); +void Port8BitSlow::write(uint8_t data){ + __asm__ volatile("outb %0, %1\njmp 1f\n1: jmp 1f\n1:" : : "a" (data), "Nd" (m_port_number)); } - -//16 BIT (asm is w) - -Port16Bit::Port16Bit(uint16_t portnumber) - : Port(portnumber) +Port16Bit::Port16Bit(uint16_t port_number) +: Port(port_number) { } @@ -76,29 +73,28 @@ Port16Bit::~Port16Bit() { } /** - * @details Write a word to the port (16Bit) + * @brief write a word to the port * * @param data the word to write */ -void Port16Bit::Write(uint16_t data){ - __asm__ volatile("outw %0, %1" : : "a" (data), "Nd" (portnumber)); +void Port16Bit::write(uint16_t data){ + __asm__ volatile("outw %0, %1" : : "a" (data), "Nd" (m_port_number)); } /** - * @details Read a word from the port (16Bit) + * @brief read a word from the port * * @return the word read */ -uint16_t Port16Bit::Read(){ +uint16_t Port16Bit::read(){ uint16_t result; - __asm__ volatile("inw %1, %0" : "=a" (result) : "Nd" (portnumber)); + __asm__ volatile("inw %1, %0" : "=a" (result) : "Nd" (m_port_number)); return result; } -//32 BIT (asm is l) -Port32Bit::Port32Bit(uint16_t portnumber) - : Port(portnumber) +Port32Bit::Port32Bit(uint16_t port_number) +: Port(port_number) { } @@ -107,21 +103,21 @@ Port32Bit::~Port32Bit() { } /** - * @details Write a double word to the port (32Bit) + * @brief write a double word to the port (32Bit) * * @param data the double word to write */ -void Port32Bit::Write(uint32_t data){ - __asm__ volatile("outl %0, %1" : : "a" (data), "Nd" (portnumber)); +void Port32Bit::write(uint32_t data){ + __asm__ volatile("outl %0, %1" : : "a" (data), "Nd" (m_port_number)); } /** - * @details Read a double word from the port (32Bit) + * @brief read a double word from the port (32Bit) * * @return the double word read */ -uint32_t Port32Bit::Read(){ +uint32_t Port32Bit::read(){ uint32_t result; - __asm__ volatile("inl %1, %0" : "=a" (result) : "Nd" (portnumber)); + __asm__ volatile("inl %1, %0" : "=a" (result) : "Nd" (m_port_number)); return result; } \ No newline at end of file diff --git a/kernel/src/hardwarecommunication/serial.cpp b/kernel/src/hardwarecommunication/serial.cpp deleted file mode 100644 index 25dbeeab..00000000 --- a/kernel/src/hardwarecommunication/serial.cpp +++ /dev/null @@ -1,245 +0,0 @@ -// -// Created by 98max on 11/12/2022. -// - -#include "hardwarecommunication/serial.h" - -using namespace maxOS; -using namespace maxOS::common; -using namespace maxOS::hardwarecommunication; - - - -/** - * @details This function is the constructor for the serial port - */ -serial::serial(InterruptManager* interruptManager) -: InterruptHandler(interruptManager -> HardwareInterruptOffset() + 4, interruptManager), - dataPort(0x3f8), - interruptEnableRegisterPort(0x3f9), - fifoCommandPort(0x3fa), - lineCommandPort(0x3fb), - modemCommandPort(0x3fc), - lineStatusPort(0x3fd), - modemStatusPort(0x3fe), - scratchPort(0x3ff) - -{ - - //Initialise the serial port - interruptEnableRegisterPort.Write(0x00); //Disable all interrupts - lineCommandPort.Write(0x80); //Enable DLAB (set baud rate divisor) - interruptEnableRegisterPort.Write(0x03); //Set divisor to 3 (lo byte) 38400 baud - lineCommandPort.Write(0x03); // (hi byte) - lineCommandPort.Write(0x03); //8 bits, no parity, one stop bit - fifoCommandPort.Write(0xC7); //Enable FIFO, clear them, with 14-byte threshold - modemCommandPort.Write(0x0B); //IRQs enabled, RTS/DSR set - modemCommandPort.Write(0x1E); //Set in loopback mode, test the serial chip - interruptEnableRegisterPort.Write(0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte) - - - //Check if the serial port is working - if(interruptEnableRegisterPort.Read() != 0xAE){ - //HEL{ - } - - //Enable interrupts - interruptEnableRegisterPort.Write(0x02); //Enable interrupts - - //If the serial port is working set it in normal operation mode - modemCommandPort.Write(0x0F); - -} - -serial::~serial() { - -} - -/** - * @details This function checks if the serial port is ready to read data - */ -int serial::receive() { - //Check if the data is ready to be read - return lineStatusPort.Read() & 1; -} - -/** - * @details This function reads a byte from the serial port - * - * @return The byte read from the serial port - */ -char serial::Read() { - - //Wait until the data is ready to be read - while(receive() == 0); - - //Read the data - return dataPort.Read(); -} - -/** - * @details This function checks if the serial port is ready to write data - */ -int serial::isTransmitEmpty() { - - //Check if the transmit buffer is empty - return lineStatusPort.Read() & 0x20; - -} - -/** - * @details This function writes a header for the message - * - * @param col The color of the header - * @param type The type of the text - * @param msg The message - */ -void serial::printHeader(string col, string type, string msg){ - - char* message = new char[100]; - int pos = 0; - - message[pos++] = '['; - - //Colour - for(int i = 0; col[i] != '_'; ++i){ //Increment through each char as long as it's not the end symbol - message[pos++] = col[i]; - } - - //Type - for(int i = 0; type[i] != '_'; ++i){ //Increment through each char as long as it's not the end symbol - message[pos++] = type[i]; - } - - //Message - for(int i = 0; msg[i] != '\0'; ++i){ //Increment through each char as long as it's not the end symbol - message[pos++] = msg[i]; - } - - //Reset Colour - Colour col_r; - col = col_r.defaultColour_fg; - for(int i = 0; col[i] != '_'; ++i){ //Increment through each char as long as it's not the end symbol - message[pos++] = col[i]; - } - - //Reset Type - Type type_r; - type = type_r.reset; - for(int i = 0; type[i] != '_'; ++i){ //Increment through each char as long as it's not the end symbol - message[pos++] = type[i]; - } - - message[pos++] = ']'; - message[pos++] = ' '; - - for(int i = 0; i < pos; ++i){ //Increment through the message - while(isTransmitEmpty() == 0); //Wait until the transmit buffer is empty - dataPort.Write(message[i]); //Write the char to the serial port - } - -} - - -/** - * @details This function tests all the different messages that can be printed - */ -void serial::Test(){ - - Write("\n\n===- Testing serial port -===\n\n",-1); - - Write("Test_-1_NoHeader\n",-1); - Write("Test_0_Default\n",0); - Write("Test_1_Info\n",1); - Write("Test_2_Warning\n",2); - Write("Test_3_Error\n",3); - Write("Test_4_Fatal\n",4); - Write("Test_5_Success\n",5); - Write("Test_6_Debug\n",6); - Write("Test_7_Kernel\n",7); - Write("Test_8_Unknown\n",8); - - Write("\n\n===- Testing Complete -===\n\n",-1); - -} - -/** - * @details This function writes a message to the serial port - * - * @param str The message to be written - * @param type The type of the message 1 = info, 2 = warning, 3 = error, 4 = fatal, 5 = success, 6 = debug, 7 = kernel, 8 = unknown - */ -void serial::Write(string str, int type) { - Colour t_colour; - Type t_type; - - switch (type) { - - //Dont print header - case -1: - break; - - //Default - case 0: - printHeader(t_colour.defaultColour_fg, t_type.reset, "Message"); - break; - - //Info - case 1: - printHeader(t_colour.light_grey_fg, t_type.none, "Info"); - break; - - //Warning - case 2: - printHeader(t_colour.yellow_fg, t_type.none, "Warning"); - break; - - //Error - case 3: - printHeader(t_colour.red_fg, t_type.none, "Error"); - break; - - //Fatal Error - case 4: - printHeader(t_colour.dark_red_fg, t_type.bold, "Fatal Error"); - break; - - //Success - case 5: - printHeader(t_colour.green_fg, t_type.blink, "Success"); - break; - - //Debug - case 6: - printHeader(t_colour.magenta_fg, t_type.underline, "Debug"); - break; - - //Kernel - case 7: - printHeader(t_colour.cyan_fg, t_type.italic, "MaxOS"); - break; - - default: - printHeader(t_colour.defaultColour_fg, t_type.reset, "Unknown"); - break; - - } - - for(int i = 0; str[i] != '\0'; ++i){ //Increment through each char as long as it's not the end symbol - while(isTransmitEmpty() == 0); //Wait until the transmit buffer is empty - dataPort.Write(str[i]); //Write the char to the serial port - } - - - -} - -/** - * @details Read from the serial port when the interrupt is triggered - * - * @param esp The stack pointer - * @return The stack pointer (where the processor will go when the interrupt is finished) (always will be what is passed in) - */ -void serial::HandleInterrupt() { - //Handle reading from the serial port -} diff --git a/kernel/src/kernel.cpp b/kernel/src/kernel.cpp index 96abff0d..0de52b51 100644 --- a/kernel/src/kernel.cpp +++ b/kernel/src/kernel.cpp @@ -6,7 +6,6 @@ //Hardware com #include #include -#include //Drivers #include @@ -63,77 +62,6 @@ using namespace maxOS::system; using namespace maxOS::memory; using namespace maxOS::filesystem; - -#define ENABLE_GRAPHICS - -class KeyboardToStream : public KeyboardEventHandler -{ - OutputStream* stream; -public: - KeyboardToStream(OutputStream* stream) - { - this->stream = stream; - } - - void onKeyDown(drivers::peripherals::KeyCode keyDownCode, drivers::peripherals::KeyboardState keyDownState) - { - // If the key is a printable character, write it to the stream - if(31 < keyDownCode && keyDownCode < 127) - stream->writeChar((char)keyDownCode); - - // If it is a backspace, delete the last character - if(keyDownCode == KeyCode::backspace) - stream->write("\b \b"); - - // If it is a newline the prompt - if(keyDownCode == KeyCode::enter) - { - stream->write("\nMaxOS> "); - } - - } -}; - -class MouseToConsole: public MouseEventHandler{ - - Console* console; - int x; - int y; - uint8_t buttons; - -public: - MouseToConsole(Console* console) - { - this->console = console; - buttons = 0; - x = console->getWidth()*2; - y = console->getHeight()*2; - } - - - void onMouseMoveEvent(int8_t x, int8_t y) - { - - console->invertColors(this->x/4,this->y/4); - - this->x += x; - if(this->x < 0) - this->x = 0; - if(this->x >= console->getWidth()*4) - this->x = console->getWidth()*4-1; - - this->y += y; - if(this->y < 0) - this->y = 0; - if(this->y >= console->getHeight()*4) - this->y = console->getHeight()*4-1; - - console->invertColors(this->x/4,this->y/4); - } - - -}; - //Define what a constructor is typedef void (*constructor)(); @@ -146,33 +74,39 @@ extern "C" void callConstructors() (*i)(); //Call the constructor } -#pragma clang diagnostic ignored "-Wwritable-strings" - //TODO: Rewrite multiboot to use the one from the manual: https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Example-OS-code extern "C" void kernelMain(const multiboot_info& multibootHeader, uint32_t multiboot_magic) { - // Memory Management has to be set up first so that the video driver can use it + // Memory Management has to be set up m_first_memory_chunk so that the video driver can use it uint32_t memupper = multibootHeader.mem_upper; size_t heap = 10*1024*1024; //Start at 10MB size_t memSize = memupper*1024 - heap - 10*1024; //Convert memupper into MB, then subtract the hep and some padding MemoryManager memoryManager(heap, memSize); //Memory Mangement // Initialise the VESA Driver - VideoElectronicsStandardsAssociationDriver vesa((multiboot_info_t *)&multibootHeader); + VideoElectronicsStandardsAssociation vesa((multiboot_info_t *)&multibootHeader); VideoDriver* videoDriver = (VideoDriver*)&vesa; - videoDriver -> setMode((int)multibootHeader.framebuffer_width, (int)multibootHeader.framebuffer_height, (int)multibootHeader.framebuffer_bpp); + videoDriver->set_mode((int)multibootHeader.framebuffer_width, + (int)multibootHeader.framebuffer_height, + (int)multibootHeader.framebuffer_bpp); - //Initialise Console + // Initialise Console VESABootConsole console(&vesa); - //TextModeConsole console; console.clear(); - string logo = header_data; + // Check if the bootloader is m_valid + if (multiboot_magic != MULTIBOOT_BOOTLOADER_MAGIC) + { + console.put_string(0, 0, "Invalid bootloader", ConsoleColour::Red, + ConsoleColour::Black); + asm("hlt"); + } // Print the logo to center of the screen - uint32_t centerX = videoDriver->getWidth()/2; - uint32_t centerY = videoDriver->getHeight()/2; + string logo = header_data; + uint32_t centerX = videoDriver->get_width()/2; + uint32_t centerY = videoDriver->get_height()/2; for (int logoY = 0; logoY < logo_height; ++logoY) { for (int logoX = 0; logoX < logo_width; ++logoX) { @@ -183,39 +117,33 @@ extern "C" void kernelMain(const multiboot_info& multibootHeader, uint32_t multi LOGO_HEADER_PIXEL(logo, pixel); // Draw the pixel - videoDriver->putPixel(centerX - logo_width/2 + logoX, centerY - logo_height/2 + logoY, maxOS::common::Colour(pixel[0], pixel[1], pixel[2])); + videoDriver->put_pixel( + centerX - logo_width / 2 + logoX, + centerY - logo_height / 2 + logoY, + common::Colour(pixel[0], pixel[1], pixel[2])); } } // Make the header - ConsoleArea consoleHeader(&console, 0, 0, console.getWidth(), 1, ConsoleColour::Blue, ConsoleColour::LightGrey); + ConsoleArea consoleHeader(&console, 0, 0, console.width(), 1, ConsoleColour::Blue, ConsoleColour::LightGrey); ConsoleStream headerStream(&consoleHeader); headerStream << "Max OS v" << VERSION_STRING <<" [build " << BUILD_NUMBER << "]"; // Calc the length of the header - uint32_t headerLength = headerStream.cursorX; - uint32_t headerPadding = (console.getWidth() - headerLength)/2; - headerStream.setCursor(0,0); + uint32_t headerLength = headerStream.m_cursor_x; + uint32_t headerPadding = (console.width() - headerLength)/2; + headerStream.set_cursor(0, 0); - // Write the header + // write the header for(uint32_t i = 0; i < headerPadding; i++) headerStream << " "; headerStream << "Max OS v" << VERSION_STRING <<" [build " << BUILD_NUMBER << "]"; for(uint32_t i = 0; i < headerPadding; i++) headerStream << " "; // Make a main console area at the top of the screen - ConsoleArea mainConsoleArea(&console, 0, 1, console.getWidth(), console.getHeight(), ConsoleColour::DarkGrey, ConsoleColour::Black); + ConsoleArea mainConsoleArea(&console, 0, 1, console.width(), + console.height(), ConsoleColour::DarkGrey, ConsoleColour::Black); ConsoleStream cout(&mainConsoleArea); - // Make a null stream - ConsoleArea nullConsoleArea(&console, 0, 0, 0, 0); - ConsoleStream nullStream(&nullConsoleArea); - - // Check if the bootloader is valid - if (multiboot_magic != MULTIBOOT_BOOTLOADER_MAGIC) - { - cout << "Invalid bootloader \n"; - cout << "Got Magic: " << (uint32_t)multiboot_magic << ", Expected Magic: " << MULTIBOOT_BOOTLOADER_MAGIC; - return; - } + // Print the build info cout << "BUILD INFO: " << VERSION_NAME << " on " << BUILD_DATE.year << "-" << BUILD_DATE.month << "-" @@ -228,10 +156,10 @@ extern "C" void kernelMain(const multiboot_info& multibootHeader, uint32_t multi // Where the areas should start - uint32_t areaStart = cout.cursorY; + uint32_t areaStart = cout.m_cursor_y; // Make the system setup stream - ConsoleArea systemSetupHeader(&console, 0, areaStart, console.getWidth(), 1, ConsoleColour::LightGrey, ConsoleColour::Black); + ConsoleArea systemSetupHeader(&console, 0, areaStart, console.width(), 1, ConsoleColour::LightGrey, ConsoleColour::Black); ConsoleStream systemSetupHeaderStream(&systemSetupHeader); systemSetupHeaderStream << "Setting up system"; @@ -241,7 +169,7 @@ extern "C" void kernelMain(const multiboot_info& multibootHeader, uint32_t multi systemSetupHeaderStream << "."; // Print that the memory has been set up - cout << "Memory: " << (int)memoryManager.getMemoryUsed()/1000000 << "MB used, " << (int)memSize/1000000 << "MB available\n"; + cout << "Memory: " << (int)memoryManager.memory_used()/1000000 << "MB used, " << (int)memSize/1000000 << "MB available\n"; cout << "-- Set Up Memory Management\n"; systemSetupHeaderStream << "."; @@ -261,7 +189,7 @@ extern "C" void kernelMain(const multiboot_info& multibootHeader, uint32_t multi systemSetupHeaderStream << "[ DONE ]"; // Make the device setup stream - ConsoleArea deviceSetupHeader(&console, 0, cout.cursorY, console.getWidth(), 1, ConsoleColour::LightGrey, ConsoleColour::Black); + ConsoleArea deviceSetupHeader(&console, 0, cout.m_cursor_y, console.width(), 1, ConsoleColour::LightGrey, ConsoleColour::Black); ConsoleStream deviceSetupHeaderStream(&deviceSetupHeader); deviceSetupHeaderStream << "Setting up devices"; @@ -270,22 +198,20 @@ extern "C" void kernelMain(const multiboot_info& multibootHeader, uint32_t multi //Keyboard KeyboardDriver keyboard(&interrupts); KeyboardInterpreterEN_US keyboardInterpreter; - keyboard.connectInputStreamEventHandler(&keyboardInterpreter); - KeyboardToStream kbhandler(&cout); - //keyboardInterpreter.connectEventHandler(&kbhandler); - driverManager.addDriver(&keyboard); + keyboard.connect_input_stream_event_handler(&keyboardInterpreter); + driverManager.add_driver(&keyboard); cout << "-- Set Up Keyboard\n"; deviceSetupHeaderStream << "."; //Mouse MouseDriver mouse(&interrupts); - driverManager.addDriver(&mouse); + driverManager.add_driver(&mouse); cout << "-- Set Up Mouse\n"; deviceSetupHeaderStream << "."; //Clock Clock kernelClock(&interrupts, 1); - driverManager.addDriver(&kernelClock); + driverManager.add_driver(&kernelClock); cout << "-- Set Up Clock\n"; deviceSetupHeaderStream << "."; @@ -293,13 +219,15 @@ extern "C" void kernelMain(const multiboot_info& multibootHeader, uint32_t multi Vector driverSelectors; //Make the stream on the side for the PCI - ConsoleArea pciConsoleArea(&console, console.getWidth() - 45, areaStart+1, 45, console.getHeight()/2, ConsoleColour::DarkGrey, ConsoleColour::Black); + ConsoleArea pciConsoleArea(&console, console.width() - 45, areaStart+1, 45, console.height()/2, ConsoleColour::DarkGrey, ConsoleColour::Black); ConsoleStream pciConsoleStream(&pciConsoleArea); - console.putString(console.getWidth() - 45, areaStart, " PCI Devices ", ConsoleColour::LightGrey, ConsoleColour::Black); + console.put_string(console.width() - 45, areaStart, + " PCI Devices ", + ConsoleColour::LightGrey, ConsoleColour::Black); //PCI PeripheralComponentInterconnectController PCIController(&pciConsoleStream); - driverSelectors.pushBack(&PCIController); + driverSelectors.push_back(&PCIController); cout << "-- Set Up PCI\n"; deviceSetupHeaderStream << "."; @@ -314,7 +242,7 @@ extern "C" void kernelMain(const multiboot_info& multibootHeader, uint32_t multi for(Vector::iterator selector = driverSelectors.begin(); selector != driverSelectors.end(); selector++) { cout << "."; - (*selector)->selectDrivers(&driverManager, &interrupts, 0); + (*selector)->select_drivers(&driverManager, &interrupts, 0); } cout << " Found\n"; deviceSetupHeaderStream << "."; @@ -323,7 +251,7 @@ extern "C" void kernelMain(const multiboot_info& multibootHeader, uint32_t multi deviceSetupHeaderStream << "[ DONE ]"; // Make the activation stream - ConsoleArea activationHeader(&console, 0, cout.cursorY, console.getWidth(), 1, ConsoleColour::LightGrey, ConsoleColour::Black); + ConsoleArea activationHeader(&console, 0, cout.m_cursor_y, console.width(), 1, ConsoleColour::LightGrey, ConsoleColour::Black); ConsoleStream activationHeaderStream(&activationHeader); activationHeaderStream << "Initializing Hardware"; @@ -343,7 +271,7 @@ extern "C" void kernelMain(const multiboot_info& multibootHeader, uint32_t multi activationHeaderStream << "."; // Interrupts - interrupts.Activate(); + interrupts.activate(); kernelClock.delay(resetWaitTime); //Wait for the devices to reset (has to be done after interrupts are activated otherwise the clock interrupt wont trigger) cout << "-- Activated Interrupts\n"; activationHeaderStream << "."; @@ -358,7 +286,7 @@ extern "C" void kernelMain(const multiboot_info& multibootHeader, uint32_t multi cout << " Initialised\n"; activationHeaderStream << "."; - // Activate the drivers + // activate the drivers cout << "-- Activating Devices"; for(Vector::iterator driver = driverManager.drivers.begin(); driver != driverManager.drivers.end(); driver++) { @@ -372,19 +300,22 @@ extern "C" void kernelMain(const multiboot_info& multibootHeader, uint32_t multi activationHeaderStream << "[ DONE ]"; // Make the network setup stream - ConsoleArea networkSetupHeader(&console, 0, cout.cursorY, console.getWidth(), 1, ConsoleColour::LightGrey, ConsoleColour::Black); + ConsoleArea networkSetupHeader(&console, 0, cout.m_cursor_y, console.width(), 1, ConsoleColour::LightGrey, ConsoleColour::Black); ConsoleStream networkSetupHeaderStream(&networkSetupHeader); networkSetupHeaderStream << "Setting up network"; // Make the stream on the side for the network - ConsoleArea networkConsoleArea(&console, console.getWidth() - 40, 2 + console.getHeight()/2, 45, console.getHeight()/2, ConsoleColour::DarkGrey, ConsoleColour::Black); + ConsoleArea networkConsoleArea(&console, console.width() - 40, 2 + console.height()/2, 45, + console.height()/2, ConsoleColour::DarkGrey, ConsoleColour::Black); ConsoleStream networkConsoleStream(&networkConsoleArea); - console.putString(console.getWidth() - 40, 1 + console.getHeight()/2, " Network ", ConsoleColour::LightGrey, ConsoleColour::Black); + console.put_string(console.width() - 40, 1 + console.height() / 2, + " Network ", + ConsoleColour::LightGrey, ConsoleColour::Black); // Get the driver EthernetDriver* ethernetDriver = (EthernetDriver*)driverManager.drivers[4]; - ethernetDriver->driverMessageStream = &networkConsoleStream; - cout << "Got Ethernet Driver: " << ethernetDriver->getDeviceName() << "\n"; + ethernetDriver->m_driver_message_stream = &networkConsoleStream; + cout << "Got Ethernet Driver: " << ethernetDriver->get_device_name() << "\n"; networkSetupHeaderStream << "."; // Ethernet Frame Handler @@ -423,57 +354,11 @@ extern "C" void kernelMain(const multiboot_info& multibootHeader, uint32_t multi networkSetupHeaderStream << "[ DONE ]"; - // Run the network -//#define NETWORK -#ifdef NETWORK - - // TCPtoStream - class TCPtoStream: public TransmissionControlProtocolPayloadHandler{ - - ConsoleStream* stream; - public: - TCPtoStream(ConsoleStream* stream) - { - this->stream = stream; - } - ~TCPtoStream() - { - this->stream = nullptr; - } - - void handleTransmissionControlProtocolPayload(TransmissionControlProtocolSocket* socket, uint8_t* data, uint16_t payloadLength) - { - *stream << "TCP Payload Received: "; - for(uint16_t i = 0; i < payloadLength; i++) - { - *stream << data[i]; - } - *stream << "\n"; - } - - void Connected(TransmissionControlProtocolSocket* socket) - { - *stream << "TCP Connection Established\n"; - } - - void Disconnected(TransmissionControlProtocolSocket* socket) - { - *stream << "TCP Connection Closed\n"; - } - }; - cout << "Listening on TCP Port 1234\n"; - // Run in term before boot when using tcp.send : ncat -l 127.0.0.1 1234 - // Run in term after boot when using tcp.listen : ncat 127.0.0.1 1234 - -#endif - - -#define GUI #ifdef GUI Desktop desktop(videoDriver); - mouse.connectEventHandler(&desktop); - keyboardInterpreter.connectEventHandler(&desktop); - kernelClock.connectEventHandler(&desktop); + mouse.connect_event_handler(&desktop); + keyboardInterpreter.connect_event_handler(&desktop); + kernelClock.connect_event_handler(&desktop); Window testWindow(150,10, 200, 150, "Test Window"); widgets::InputBox testInputBox(10, 10, 150, 20, "test"); @@ -491,23 +376,22 @@ extern "C" void kernelMain(const multiboot_info& multibootHeader, uint32_t multi this->stream = nullptr; } - void onInputBoxTextChanged(string newText) + void on_input_box_text_changed(string newText) { *stream << "Input Box Changed: " << newText << "\n"; } }; InputBoxStream inputBoxStream(&cout); - testInputBox.connectEventHandler(&inputBoxStream); - testWindow.addChild(&testInputBox); - desktop.addChild(&testWindow); + testInputBox.connect_event_handler(&inputBoxStream); + testWindow.add_child(&testInputBox); + desktop.add_child(&testWindow); Window testWindow2(350,100, 200, 150, "Test Window 2"); - desktop.addChild(&testWindow2); + desktop.add_child(&testWindow2); #endif - // Loop forever + // Wait while (true); -} -#pragma clang diagnostic pop +} \ No newline at end of file diff --git a/kernel/src/memory/memoryIO.cpp b/kernel/src/memory/memoryIO.cpp index 167e734f..503d9d14 100644 --- a/kernel/src/memory/memoryIO.cpp +++ b/kernel/src/memory/memoryIO.cpp @@ -6,8 +6,9 @@ using namespace maxOS::memory; -MemIO::MemIO(uint64_t address) { - this->address = address; +MemIO::MemIO(uint32_t address) +: m_address(address) +{ } @@ -15,11 +16,8 @@ MemIO::~MemIO() { } - -// 8 BIT - -MemIO8Bit::MemIO8Bit(uint64_t address) - : MemIO(address) +MemIO8Bit::MemIO8Bit(uint32_t address) +: MemIO(address) { } @@ -28,28 +26,25 @@ MemIO8Bit::~MemIO8Bit() { } /** - * @details Writes data to the memory address + * @brief Writes data to the memory address * * @param data the data to write */ -void MemIO8Bit::Write(uint8_t data){ - (*((volatile uint8_t*)(address)))=(data); +void MemIO8Bit::write(uint8_t data){ + (*((volatile uint8_t*)(m_address)))=(data); } /** - * @details Reads data from the memory address + * @brief Reads data from the memory address * * @return the data read */ - -uint8_t MemIO8Bit::Read(){ - return *((volatile uint8_t*)(address)); +uint8_t MemIO8Bit::read(){ + return *((volatile uint8_t*)(m_address)); } -//16 BIT - -MemIO16Bit::MemIO16Bit(uint64_t address) - : MemIO(address) +MemIO16Bit::MemIO16Bit(uint32_t address) +: MemIO(address) { } @@ -58,27 +53,24 @@ MemIO16Bit::~MemIO16Bit() { } /** - * @details Writes data to the memory address + * @brief Writes data to the memory address * * @param data the data to write */ -void MemIO16Bit::Write(uint16_t data){ - (*((volatile uint16_t*)(address)))=(data); +void MemIO16Bit::write(uint16_t data){ + (*((volatile uint16_t*)(m_address)))=(data); } /** - * @details Reads data from the memory address + * @brief Reads data from the memory address * * @return the data read */ - -uint16_t MemIO16Bit::Read(){ - return *((volatile uint16_t*)(address)); +uint16_t MemIO16Bit::read(){ + return *((volatile uint16_t*)(m_address)); } -//32 BIT - -MemIO32Bit::MemIO32Bit(uint64_t address) +MemIO32Bit::MemIO32Bit(uint32_t address) : MemIO(address) { } @@ -88,27 +80,24 @@ MemIO32Bit::~MemIO32Bit() { } /** - * @details Writes data to the memory address + * @brief Writes data to the memory address * * @param data the data to write */ -void MemIO32Bit::Write(uint32_t data){ - (*((volatile uint32_t*)(address)))=(data); +void MemIO32Bit::write(uint32_t data){ + (*((volatile uint32_t*)(m_address)))=(data); } /** - * @details Reads data from the memory address + * @brief Reads data from the memory address * * @return the data read */ - -uint32_t MemIO32Bit::Read(){ - return *((volatile uint32_t*)(address)); +uint32_t MemIO32Bit::read(){ + return *((volatile uint32_t*)(m_address)); } -//64 BIT - -MemIO64Bit::MemIO64Bit(uint64_t address) +MemIO64Bit::MemIO64Bit(uint32_t address) : MemIO(address) { } @@ -118,25 +107,28 @@ MemIO64Bit::~MemIO64Bit() { } /** - * @details Writes data to the memory address + * @brief Writes data to the memory address * * @param data the data to write */ -void MemIO64Bit::Write(uint64_t data){ - (*((volatile uint64_t*)(address)))=(data); +void MemIO64Bit::write(uint64_t data){ + (*((volatile uint64_t*)(m_address)))=(data); } /** - * @details Reads data from the memory address + * @brief Reads data from the memory address * * @return the data read */ -uint64_t MemIO64Bit::Read(){ - return *((volatile uint64_t*)(address)); +uint64_t MemIO64Bit::read(){ + return *((volatile uint64_t*)(m_address)); } /** - * Memcpy from https://wiki.osdev.org/Meaty_Skeleton + * @brief Copies a block of memory from one location to another + * + * @see https://wiki.osdev.org/Meaty_Skeleton#memcpy.28.29 + * * @param destination The destination to copy to * @param source The source to copy from * @param num The number of bytes to copy @@ -150,3 +142,60 @@ void* maxOS::memory::memcpy(void* destination, const void* source, uint32_t num) dst[i] = src[i]; return destination; } + +/** + * @brief Fills a block of memory with a specified value + + * + * @param ptr The pointer to the block of memory + * @param value The value to fill the block of memory with + * @param num The number of bytes to fill + * @return The pointer to the block of memory + */ +void* maxOS::memory::memset(void* ptr, int value, uint32_t num) { + unsigned char* dst = (unsigned char*) ptr; + for (size_t i = 0; i < num; i++) + dst[i] = (unsigned char) value; + return ptr; +} + +/** + * @brief Copies a block of memory from one location to another + * + * @param destination The destination to copy to + * @param source The source to copy from + * @param num The number of bytes to copy + * @return The destination + */ +void* maxOS::memory::memmove(void* destination, const void* source, uint32_t num) { + unsigned char* dst = (unsigned char*) destination; + const unsigned char* src = (const unsigned char*) source; + if (dst < src) { + for (size_t i = 0; i < num; i++) + dst[i] = src[i]; + } else { + for (size_t i = num; i != 0; i--) + dst[i-1] = src[i-1]; + } + return destination; +} + +/** + * @brief Compares two blocks of memory + * + * @param ptr1 The m_first_memory_chunk block of memory + * @param ptr2 The second block of memory + * @param num The number of bytes to compare + * @return 0 if the blocks of memory are equal, -1 if ptr1 < ptr2, 1 if ptr1 > ptr2 + */ +int maxOS::memory::memcmp(const void* ptr1, const void* ptr2, uint32_t num) { + const unsigned char *p1 = (const unsigned char *)ptr1; + const unsigned char *p2 = (const unsigned char *)ptr2; + for (size_t i = 0; i < num; i++) { + if (p1[i] < p2[i]) + return -1; + if (p1[i] > p2[i]) + return 1; + } + return 0; +} \ No newline at end of file diff --git a/kernel/src/memory/memorymanagement.cpp b/kernel/src/memory/memorymanagement.cpp index e777c2d6..c1530949 100644 --- a/kernel/src/memory/memorymanagement.cpp +++ b/kernel/src/memory/memorymanagement.cpp @@ -7,35 +7,35 @@ using namespace maxOS; using namespace maxOS::memory; -MemoryManager* MemoryManager::activeMemoryManager = 0; +MemoryManager* MemoryManager::s_active_memory_manager = 0; -MemoryManager::MemoryManager(size_t start, size_t size) { +MemoryManager::MemoryManager(size_t start, size_t size) +{ - activeMemoryManager = this; + s_active_memory_manager = this; - //Prevent wirting outside the area that is allowed to write + //Prevent wiring outside the area that is allowed to write if(size < sizeof(MemoryChunk)){ - this -> first = 0; + this ->m_first_memory_chunk = 0; }else{ - this -> first = (MemoryChunk*)start; - first -> allocated = false; - first -> prev = 0; - first -> next = 0; - first -> size = size - sizeof(MemoryChunk); + this ->m_first_memory_chunk = (MemoryChunk*)start; + m_first_memory_chunk-> allocated = false; + m_first_memory_chunk-> prev = 0; + m_first_memory_chunk-> next = 0; + m_first_memory_chunk-> size = size - sizeof(MemoryChunk); } } MemoryManager::~MemoryManager() { - if(activeMemoryManager == this){ - activeMemoryManager = 0; - } + if(s_active_memory_manager == this) + s_active_memory_manager = 0; } /** - * @details Allocates a block of memory + * @brief Allocates a block of memory * * @param size size of the block * @return a pointer to the block, 0 if no block is available @@ -44,119 +44,101 @@ void* MemoryManager::malloc(size_t size) { MemoryChunk* result = 0; - //Common way of iterating through a linked list - for (MemoryChunk* chunk = first; chunk != 0 && result == 0; chunk = chunk->next) { //Iterate through the list of chunks - - if(chunk -> size > size && !chunk -> allocated){ //If the chunk is big enough and not being used + // Find the next free chunk that is big enough + for (MemoryChunk* chunk = m_first_memory_chunk; chunk != 0 && result == 0; chunk = chunk->next) { + if(chunk -> size > size && !chunk -> allocated) result = chunk; - } - } - if(result == 0){ + // If there is no free chunk then return 0 + if(result == 0) return 0; - } - - //The result must have been set to a memory chunk because it did not return - - if(result -> size < size + sizeof(MemoryChunk) + 1){ //Check if there is space for the new data and another memory chunk (for splitting). The + 1 is there so that the split chunk will actually have space for data, not just the header - //If there isn't space to split then there will just be a few bytes left over, not a problem - result -> allocated = true; - - }else{ - //If there is space then split the chunk - - MemoryChunk* temp = (MemoryChunk*)((size_t)result + sizeof(MemoryChunk) + size); //Add size memory chunk (header) and size of data to get to get the position of the next chunk + // If there is space to split the chunk + if(result -> size < size + sizeof(MemoryChunk) + 1) { + result->allocated = true; + return (void *)(((size_t)result) + sizeof(MemoryChunk)); + } - temp -> allocated = false; //Just created so wont be allocated - temp -> size = result->size - size - sizeof(MemoryChunk); //Get old size of the free chunk, take away the requested data and the header size - temp -> prev = result; //The previous is now the newly allocated chunk - temp -> next = result -> next; //The next pointer from the old chunk - if(temp -> next != 0){ //If there was something in front of this chunk - temp -> next -> prev = temp; //The chunk in front's previous pointer must be set to the newly split chunk - } + // Create a new chunk after the current one + MemoryChunk* temp = (MemoryChunk*)((size_t)result + sizeof(MemoryChunk) + size); - result->size = size; //The results new size is the requested data (excess has now been split off) - result->next = temp; //Point it to the split chunk - result -> allocated = true; + // Set the new chunk's properties and insert it into the linked list + temp -> allocated = false; + temp -> size = result->size - size - sizeof(MemoryChunk); + temp -> prev = result; + temp -> next = result -> next; - } + // If there is a chunk after the current one then set its previous to the new chunk + if(temp -> next != 0) + temp -> next -> prev = temp; - return (void*)(((size_t)result) + sizeof(MemoryChunk)); //Return the pointer to the newly allocated memory chunk - return result; + // Current chunk is now allocated and is pointing to the new chunk + result->size = size; + result -> allocated = true; + result->next = temp; + return (void*)(((size_t)result) + sizeof(MemoryChunk)); } /** - * @details Frees a block of memory + * @brief Frees a block of memory * * @param pointer A pointer to the block */ void MemoryManager::free(void *pointer) { - MemoryChunk* chunk = (MemoryChunk*)((size_t)pointer - sizeof(MemoryChunk)); //Subtract size of MemoryChunk as the pointer is seprate from the header + // Create a new free chunk + MemoryChunk* chunk = (MemoryChunk*)((size_t)pointer - sizeof(MemoryChunk)); + chunk -> allocated = false; - chunk -> allocated = false; //Chunk is now free + // If there is a free chunk before this chunk then merge them + if(chunk -> prev != 0 && !chunk -> prev -> allocated){ + // Increase the previous chunk's size and remove the current chunk from the linked list + chunk->prev->size += chunk->size + sizeof(MemoryChunk); + chunk -> prev -> next = chunk -> next; - //To merge you pretty much tell the chunk that is free that it has all this extra data and then move this pointer to the free chunk + // If there is a next chunk then ensure this chunk is removed from its linked list + if(chunk -> next != 0) + chunk -> next -> prev = chunk->prev; - //Merge the chunk behind - if(chunk -> prev != 0 && !chunk -> prev -> allocated){ //If there is a chunk behind this chunk and its free - - chunk -> prev -> next = chunk -> next; //Set the previous chunk next to the chunk in front of this (remove it from the backward linked list) - - chunk->prev->size += chunk->size + sizeof(MemoryChunk); //Add the size that has been freed and its header - - if(chunk -> next != 0){ //If there is a chunk infront of this chunk - - chunk -> next -> prev = chunk->prev; //Set the chunk in front of this chunk to the chunk behind this this (remove it from the forward linked list) - - } - - chunk = chunk -> prev; //Move the chunk pointer to the previous chunk + // Chunk is now the previous chunk + chunk = chunk -> prev; } - //Merge the chunk infront - if(chunk -> next != 0 && !chunk -> next -> allocated){ //If there is a chunk infront this chunk and its free - - chunk -> size += chunk -> next -> size + sizeof(MemoryChunk); //Add the size that has been freed and its header + // If there is a free chunk after this chunk then merge them + if(chunk -> next != 0 && !chunk -> next -> allocated){ + // Increase the current chunk's size and remove the next chunk from the linked list + chunk -> size += chunk -> next -> size + sizeof(MemoryChunk); chunk -> next = chunk -> next -> next; - if(chunk -> next != 0){ //If there is a chunk infront of this new chunk - - chunk -> next -> prev = chunk; //Set the chunk in front of this chunk to the chunk behind this this (remove it from the forward linked list) - - } - - + // Remove the just merged chunk from the linked list + if(chunk -> next != 0) + chunk -> next -> prev = chunk; } - - - } -int MemoryManager::getMemoryUsed() { +/** + * @brief Returns the amount of memory used + * @return The amount of memory used + */ +int MemoryManager::memory_used() { int result = 0; - for (MemoryChunk* chunk = first; chunk != 0; chunk = chunk->next) { //Iterate through the list of chunks - - if(chunk -> allocated){ //If the chunk is big enough and not being used + // Loop through all the chunks and add up the size of the allocated chunks + for (MemoryChunk* chunk = m_first_memory_chunk; chunk != 0; chunk = chunk->next) + if(chunk -> allocated) result += chunk -> size; - } - - } return result; - } @@ -166,29 +148,24 @@ int MemoryManager::getMemoryUsed() { void* operator new(size_t size){ - if(maxOS::memory::MemoryManager::activeMemoryManager != 0){ //Check if there is a memory manager - - return maxOS::memory::MemoryManager::activeMemoryManager -> malloc(size); - - } + // Use the memory manager to allocate the memory + if(maxOS::memory::MemoryManager::s_active_memory_manager != 0) + return maxOS::memory::MemoryManager::s_active_memory_manager-> malloc(size); return 0; } -void* operator new[](size_t size){ - - if(maxOS::memory::MemoryManager::activeMemoryManager != 0){ //Check if there is a memory manager - return maxOS::memory::MemoryManager::activeMemoryManager -> malloc(size); +void* operator new[](size_t size){ - } + // Use the memory manager to allocate the memory + if(maxOS::memory::MemoryManager::s_active_memory_manager != 0) + return maxOS::memory::MemoryManager::s_active_memory_manager-> malloc(size); return 0; } -//Placement New (see placement new operator) - void* operator new(size_t size, void* pointer){ return pointer; @@ -200,22 +177,19 @@ void* operator new[](size_t size, void* pointer){ } -void operator delete(void* pointer){ - - if(maxOS::memory::MemoryManager::activeMemoryManager != 0){ //Check if there is a memory manager +// NOTE: The size_t parameter is ignored, compiler was just complaining +void operator delete(void* pointer, size_t size){ - return maxOS::memory::MemoryManager::activeMemoryManager -> free(pointer); - - } + // Use the memory manager to free the memory + if(maxOS::memory::MemoryManager::s_active_memory_manager != 0) + return maxOS::memory::MemoryManager::s_active_memory_manager-> free(pointer); } -void operator delete[](void* pointer){ - - if(maxOS::memory::MemoryManager::activeMemoryManager != 0){ //Check if there is a memory manager +void operator delete[](void* pointer, size_t size){ - return maxOS::memory::MemoryManager::activeMemoryManager -> free(pointer); - - } + // Use the memory manager to free the memory + if(maxOS::memory::MemoryManager::s_active_memory_manager != 0) + return maxOS::memory::MemoryManager::s_active_memory_manager-> free(pointer); } \ No newline at end of file diff --git a/kernel/src/net/arp.cpp b/kernel/src/net/arp.cpp index d777e973..941d2a67 100644 --- a/kernel/src/net/arp.cpp +++ b/kernel/src/net/arp.cpp @@ -25,7 +25,7 @@ net::AddressResolutionProtocol::~AddressResolutionProtocol() { } /** - * @details Called when an ARP packet is received. + * @brief Called when an ARP packet is received. * * @param etherframePayload The payload of the ARP packet. * @param size The size of the ARP packet. @@ -82,7 +82,7 @@ bool AddressResolutionProtocol::handleEthernetFramePayload(uint8_t* etherframePa /** - * @details Request the MAC address of a given IP address. + * @brief Request the MAC address of a given IP address. * * @param IP_BE The IP address in BigEndian. */ @@ -112,7 +112,7 @@ void AddressResolutionProtocol::RequestMACAddress(InternetProtocolAddress addres /** - * @details Get the MAC address from an IP via ARP. + * @brief Get the MAC address from an IP via ARP. * * @param IP_BE The IP address to get the MAC address from. * @return The MAC address of the IP address. diff --git a/kernel/src/net/ethernetframe.cpp b/kernel/src/net/ethernetframe.cpp index 96b89884..1e102a9f 100644 --- a/kernel/src/net/ethernetframe.cpp +++ b/kernel/src/net/ethernetframe.cpp @@ -25,7 +25,7 @@ EthernetFramePayloadHandler::EthernetFramePayloadHandler(EthernetFrameHandler* f } /** - * @details Destroy the EtherFrameHandler:: EtherFrameHandler object, Removes it from the handler list + * @brief Destroy the EtherFrameHandler:: EtherFrameHandler object, Removes it from the handler list * */ EthernetFramePayloadHandler::~EthernetFramePayloadHandler() { @@ -40,7 +40,7 @@ bool EthernetFramePayloadHandler::handleEthernetframePayload(uint8_t* ethernetfr } /** - * @details Send an packet via the backend driver + * @brief Send an packet via the backend driver * * @param dstMAC the destination MAC address * @param data the data to send @@ -59,7 +59,7 @@ EthernetFrameHandler::EthernetFrameHandler(EthernetDriver* driver, OutputStream* this -> ethernetDriver = driver; this -> errorMessages = errorMessages; - driver ->connectEventHandler(this); + driver->connect_event_handler(this); } @@ -73,7 +73,7 @@ drivers::ethernet::MediaAccessControlAddress EthernetFrameHandler::getMAC() { /** - * @details Handle the received packet + * @brief Handle the received packet * * @param buffer the buffer with the received data * @param size the size of the received data @@ -114,7 +114,7 @@ bool EthernetFrameHandler::DataReceived(uint8_t* buffer, uint32_t size) { //If the handler is not found, print an error message errorMessages -> write("EFH: Unhandled ethernet frame type 0x"); - errorMessages -> writeHex(frame->type); + errorMessages->write_hex(frame->type); errorMessages -> write("\n"); } @@ -146,7 +146,7 @@ void EthernetFrameHandler::connectHandler(EthernetFramePayloadHandler *handler) } /** - * @details Send an packet via the backend driver + * @brief Send an packet via the backend driver * * @param dstMAC_BE the destination MAC address * @param etherType_BE the type of the protocol @@ -158,7 +158,7 @@ void EthernetFrameHandler::sendEthernetFrame(uint64_t destinationMAC, uint16_t f errorMessages->write("EFH: Sending frame..."); //Allocate memory for the buffer - uint8_t* buffer = (uint8_t*)MemoryManager::activeMemoryManager -> malloc(size + sizeof(EthernetFrameHeader)); + uint8_t* buffer = (uint8_t*)MemoryManager::s_active_memory_manager-> malloc(size + sizeof(EthernetFrameHeader)); EthernetFrameHeader* frame = (EthernetFrameHeader*)buffer; //Put data in the header @@ -177,5 +177,5 @@ void EthernetFrameHandler::sendEthernetFrame(uint64_t destinationMAC, uint16_t f //Free the buffer - MemoryManager::activeMemoryManager -> free(buffer); + MemoryManager::s_active_memory_manager-> free(buffer); } diff --git a/kernel/src/net/icmp.cpp b/kernel/src/net/icmp.cpp index f3fe3228..9db2419c 100644 --- a/kernel/src/net/icmp.cpp +++ b/kernel/src/net/icmp.cpp @@ -21,7 +21,7 @@ InternetControlMessageProtocol::~InternetControlMessageProtocol() { } /** - * @details Called by the InternetProtocolProvider when a new packet has arrived + * @brief Called by the InternetProtocolProvider when a new packet has arrived * * @param srcIP_BE The source IP address of the packet * @param dstIP_BE The destination IP address of the packet @@ -70,7 +70,7 @@ bool InternetControlMessageProtocol::handleInternetProtocolPayload(InternetProto } /** - * @details Sends an ICMP echo request to the specified IP address + * @brief Sends an ICMP echo request to the specified IP address * * @param ip_be The IP address to send the request to */ diff --git a/kernel/src/net/ipv4.cpp b/kernel/src/net/ipv4.cpp index bb41cb03..da3f28cd 100644 --- a/kernel/src/net/ipv4.cpp +++ b/kernel/src/net/ipv4.cpp @@ -54,7 +54,7 @@ InternetProtocolPayloadHandler::~InternetProtocolPayloadHandler() { } /** - * @details Called when an IP packet is received. (Deafult, does nothing, overide for use) + * @brief Called when an IP packet is received. (Deafult, does nothing, overide for use) * * @param srcIP_BE The source IP address. * @param dstIP_BE The destination IP address. @@ -70,7 +70,7 @@ bool InternetProtocolPayloadHandler::handleInternetProtocolPayload(maxOS::net::I } /** - * @details Sends an IP packet. + * @brief Sends an IP packet. * * @param dstIP_BE The destination IP address. * @param internetprotocolPayload The payload of the IP packet. @@ -104,7 +104,7 @@ InternetProtocolHandler::~InternetProtocolHandler() { } /** - * @details Called when an IP packet is received. + * @brief Called when an IP packet is received. * * @param etherframePayload The payload of the IP packet. * @param size The size of the IP packet. @@ -162,7 +162,7 @@ bool InternetProtocolHandler::handleEthernetframePayload(uint8_t* ethernetframeP /** - * @details Sends an IP packet. + * @brief Sends an IP packet. * * @param dstIP_BE The destination IP address. * @param protocol The protocol of the IP packet. @@ -171,7 +171,7 @@ bool InternetProtocolHandler::handleEthernetframePayload(uint8_t* ethernetframeP */ void InternetProtocolHandler::sendInternetProtocolPacket(uint32_t dstIP_BE, uint8_t protocol, uint8_t *data, uint32_t size) { - uint8_t* buffer = (uint8_t*)MemoryManager::activeMemoryManager -> malloc(sizeof(InternetProtocolV4Header) + size); //Allocate memory for the message + uint8_t* buffer = (uint8_t*)MemoryManager::s_active_memory_manager-> malloc(sizeof(InternetProtocolV4Header) + size); //Allocate memory for the message InternetProtocolV4Header *message = (InternetProtocolV4Header*)buffer; //Convert to struct for easier use message -> version = 4; //Set version @@ -208,11 +208,11 @@ void InternetProtocolHandler::sendInternetProtocolPacket(uint32_t dstIP_BE, uint //Send message frameHandler -> sendEthernetFrame(MAC, this -> handledType, buffer, size + sizeof(InternetProtocolV4Header)); //Send message - MemoryManager::activeMemoryManager->free(buffer); //Free memory + MemoryManager::s_active_memory_manager->free(buffer); //Free memory } /** - * @details Creates a checksum for the given data. + * @brief Creates a checksum for the given data. * * @param data The data to create a checksum for. * @param lengthInBytes The length of the data in bytes. diff --git a/kernel/src/net/tcp.cpp b/kernel/src/net/tcp.cpp index 6a559f94..93a41780 100644 --- a/kernel/src/net/tcp.cpp +++ b/kernel/src/net/tcp.cpp @@ -33,7 +33,7 @@ void TransmissionControlProtocolPayloadHandler::Disconnected(TransmissionControl } -Event* TransmissionControlProtocolPayloadHandler::onEvent(Event *event) { +Event* TransmissionControlProtocolPayloadHandler::on_event(Event *event) { switch (event -> type) { @@ -68,7 +68,7 @@ TransmissionControlProtocolSocket::~TransmissionControlProtocolSocket() { } /** - * @details Handle the TCP message (socket end) + * @brief Handle the TCP message (socket end) * * @param data The datah * @param size The size of the data @@ -77,13 +77,13 @@ TransmissionControlProtocolSocket::~TransmissionControlProtocolSocket() bool TransmissionControlProtocolSocket::handleTransmissionControlProtocolPayload(uint8_t* data, uint16_t size) { DataReceivedEvent* event = new DataReceivedEvent(this, data, size); - raiseEvent(event); - MemoryManager::activeMemoryManager->free(event); + raise_event(event); + MemoryManager::s_active_memory_manager->free(event); return true; } /** - * @details Send data over the socket + * @brief Send data over the socket * * @param data The data to send * @param size The size of the data @@ -98,7 +98,7 @@ void TransmissionControlProtocolSocket::Send(uint8_t* data, uint16_t size) } /** - * @details Disconnect the socket + * @brief Disconnect the socket */ void TransmissionControlProtocolSocket::Disconnect() { @@ -107,15 +107,15 @@ void TransmissionControlProtocolSocket::Disconnect() void TransmissionControlProtocolSocket::Disconnected() { DisconnectedEvent* event = new DisconnectedEvent(this); - raiseEvent(event); - MemoryManager::activeMemoryManager->free(event); + raise_event(event); + MemoryManager::s_active_memory_manager->free(event); } void TransmissionControlProtocolSocket::Connected() { ConnectedEvent* event = new ConnectedEvent(this); - raiseEvent(event); - MemoryManager::activeMemoryManager->free(event); + raise_event(event); + MemoryManager::s_active_memory_manager->free(event); } @@ -151,7 +151,7 @@ uint32_t bigEndian16(uint16_t x) } /** - * @details Handle the TCP message (provider end) + * @brief Handle the TCP message (provider end) * * @param srcIP_BE The source IP address * @param dstIP_BE The destination IP address @@ -378,7 +378,7 @@ bool TransmissionControlProtocolHandler::handleInternetProtocolPayload(InternetP } /** - * @details Send a packet (Throught the provider) + * @brief Send a packet (Throught the provider) * * @param socket The socket to send the packet from * @param data The data to send @@ -392,7 +392,7 @@ void TransmissionControlProtocolHandler::sendTransmissionControlProtocolPacket(T uint16_t lengthInclPHdr = totalLength + sizeof(TransmissionControlProtocolPseudoHeader); //Create a buffer for the packet - uint8_t* buffer = (uint8_t*)MemoryManager::activeMemoryManager -> malloc(lengthInclPHdr); + uint8_t* buffer = (uint8_t*)MemoryManager::s_active_memory_manager-> malloc(lengthInclPHdr); uint8_t* buffer2 = buffer + sizeof(TransmissionControlProtocolHeader) + sizeof(TransmissionControlProtocolPseudoHeader); //Create the headers @@ -437,11 +437,11 @@ void TransmissionControlProtocolHandler::sendTransmissionControlProtocolPacket(T //Send and then free the data Send(socket -> remoteIP, (uint8_t*)msg, totalLength); - MemoryManager::activeMemoryManager -> free(buffer); + MemoryManager::s_active_memory_manager-> free(buffer); } /** - * @details Connect to a remote host through the TCP protocol + * @brief Connect to a remote host through the TCP protocol * @param ip The IP of the remote host * @param port The port of the remote host * @return The socket that is connected to the remote host, 0 if it failed @@ -449,7 +449,7 @@ void TransmissionControlProtocolHandler::sendTransmissionControlProtocolPacket(T TransmissionControlProtocolSocket* TransmissionControlProtocolHandler::Connect(InternetProtocolAddress ip, TransmissionControlProtocolPort port) { //Create a new socket - TransmissionControlProtocolSocket* socket = (TransmissionControlProtocolSocket*)MemoryManager::activeMemoryManager -> malloc(sizeof(TransmissionControlProtocolSocket)); + TransmissionControlProtocolSocket* socket = (TransmissionControlProtocolSocket*)MemoryManager::s_active_memory_manager-> malloc(sizeof(TransmissionControlProtocolSocket)); //If there is space for the socket if(socket != 0) @@ -468,7 +468,7 @@ TransmissionControlProtocolSocket* TransmissionControlProtocolHandler::Connect(I socket -> localPort = ((socket -> localPort & 0xFF00)>>8) | ((socket -> localPort & 0x00FF) << 8); //Set the socket into the socket array and then set its state - sockets.pushBack(socket); + sockets.push_back(socket); socket -> state = SYN_SENT; //Dummy sequence number @@ -516,7 +516,7 @@ TransmissionControlProtocolSocket *TransmissionControlProtocolHandler::Connect(s } /** - * @details Begin the disconnect process + * @brief Begin the disconnect process * * @param socket The socket to disconnect */ @@ -529,7 +529,7 @@ void TransmissionControlProtocolHandler::Disconnect(TransmissionControlProtocolS } /** - * @details Begin listening on a port + * @brief Begin listening on a port * * @param port The port to listen on * @return The socket that will handle the connection @@ -537,7 +537,7 @@ void TransmissionControlProtocolHandler::Disconnect(TransmissionControlProtocolS TransmissionControlProtocolSocket* TransmissionControlProtocolHandler::Listen(uint16_t port) { //Create a new socket - TransmissionControlProtocolSocket* socket = (TransmissionControlProtocolSocket*)MemoryManager::activeMemoryManager -> malloc(sizeof(TransmissionControlProtocolSocket)); + TransmissionControlProtocolSocket* socket = (TransmissionControlProtocolSocket*)MemoryManager::s_active_memory_manager-> malloc(sizeof(TransmissionControlProtocolSocket)); //If there is space for the socket if(socket != 0) @@ -551,7 +551,7 @@ TransmissionControlProtocolSocket* TransmissionControlProtocolHandler::Listen(ui socket -> localPort = ((port & 0xFF00)>>8) | ((port & 0x00FF) << 8); //Add the socket to the socket array - sockets.pushBack(socket); + sockets.push_back(socket); } //Return the socket @@ -560,14 +560,14 @@ TransmissionControlProtocolSocket* TransmissionControlProtocolHandler::Listen(ui /** - * @details Bind a data handler to this socket + * @brief Bind a data handler to this socket * * @param socket The socket to bind the handler to * @param transmissionControlProtocolHandler The handler to bind */ void TransmissionControlProtocolHandler::Bind(TransmissionControlProtocolSocket* socket, TransmissionControlProtocolPayloadHandler* handler) { - socket ->connectEventHandler(handler); + socket->connect_event_handler(handler); } diff --git a/kernel/src/net/udp.cpp b/kernel/src/net/udp.cpp index e6437fa9..68c41074 100644 --- a/kernel/src/net/udp.cpp +++ b/kernel/src/net/udp.cpp @@ -19,7 +19,7 @@ void UserDatagramProtocolPayloadHandler::handleUserDatagramProtocolMessage(UserD } -Event* UserDatagramProtocolPayloadHandler::onEvent(Event *event) { +Event* UserDatagramProtocolPayloadHandler::on_event(Event *event) { switch (event -> type) { case UDP_DATA_RECEIVED: @@ -50,8 +50,8 @@ void UserDatagramProtocolSocket::handleUserDatagramProtocolPayload(uint8_t *data // Create the event UDPDataReceivedEvent* event = new UDPDataReceivedEvent(this, data, size); - raiseEvent(event); - MemoryManager::activeMemoryManager->free(event); + raise_event(event); + MemoryManager::s_active_memory_manager->free(event); } @@ -81,7 +81,7 @@ UserDatagramProtocolHandler::~UserDatagramProtocolHandler() { } /** - * @details Handle the recivement of an UDP packet + * @brief Handle the recivement of an UDP packet * * @param srcIP_BE The source IP address in big endian * @param dstIP_BE The destination IP address in big endian @@ -143,7 +143,7 @@ bool UserDatagramProtocolHandler::handleInternetProtocolPayload(InternetProtocol UserDatagramProtocolSocket *UserDatagramProtocolHandler::Connect(uint32_t ip, uint16_t port) { - UserDatagramProtocolSocket* socket = (UserDatagramProtocolSocket*)MemoryManager::activeMemoryManager -> malloc(sizeof(UserDatagramProtocolSocket)); //Allocate memory for the socket + UserDatagramProtocolSocket* socket = (UserDatagramProtocolSocket*)MemoryManager::s_active_memory_manager-> malloc(sizeof(UserDatagramProtocolSocket)); //Allocate memory for the socket if(socket != 0) //If the socket was created { @@ -156,7 +156,7 @@ UserDatagramProtocolSocket *UserDatagramProtocolHandler::Connect(uint32_t ip, ui socket -> localIP = internetProtocolHandler -> GetInternetProtocolAddress(); //IP that we will use to connect to the remote application socket -> userDatagramProtocolHandler = this; //Set the UDP handler - sockets.pushBack(socket); //Add the socket to the list of sockets + sockets.push_back(socket); //Add the socket to the list of sockets } return socket; //Return the socket @@ -197,14 +197,14 @@ UserDatagramProtocolSocket *UserDatagramProtocolHandler::Connect(string internet } /** - * @details Listens for incoming packets on the port + * @brief Listens for incoming packets on the port * * @param port The port to listen on * @return The socket that is listening */ UserDatagramProtocolSocket *UserDatagramProtocolHandler::Listen(uint16_t port) { - UserDatagramProtocolSocket* socket = (UserDatagramProtocolSocket*)MemoryManager::activeMemoryManager -> malloc(sizeof(UserDatagramProtocolSocket)); //Allocate memory for the socket + UserDatagramProtocolSocket* socket = (UserDatagramProtocolSocket*)MemoryManager::s_active_memory_manager-> malloc(sizeof(UserDatagramProtocolSocket)); //Allocate memory for the socket if(socket != 0) //If the socket was created { @@ -216,7 +216,7 @@ UserDatagramProtocolSocket *UserDatagramProtocolHandler::Listen(uint16_t port) { socket -> localIP = internetProtocolHandler -> GetInternetProtocolAddress(); //IP that we will use to connect to the remote application socket -> userDatagramProtocolHandler = this; //Set the UDP handler - sockets.pushBack(socket); //Add the socket to the list of sockets + sockets.push_back(socket); //Add the socket to the list of sockets } return socket; //Return the socket @@ -224,7 +224,7 @@ UserDatagramProtocolSocket *UserDatagramProtocolHandler::Listen(uint16_t port) { } /** - * @details Disconnects the socket from the remote IP and port + * @brief Disconnects the socket from the remote IP and port * * @param socket The socket to disconnect */ @@ -235,7 +235,7 @@ void UserDatagramProtocolHandler::Disconnect(UserDatagramProtocolSocket *socket) if((*currentSocket) == socket) //If the socket is the same as the socket that is being checked { sockets.erase(currentSocket); //Remove the socket from the list of sockets - MemoryManager::activeMemoryManager -> free(socket); //Free the socket + MemoryManager::s_active_memory_manager-> free(socket); //Free the socket break; //Break out of the loop } } @@ -243,7 +243,7 @@ void UserDatagramProtocolHandler::Disconnect(UserDatagramProtocolSocket *socket) } /** - * @details Sends a packet to the remote IP and port + * @brief Sends a packet to the remote IP and port * * @param socket The socket to send the packet from * @param data The data to send @@ -252,7 +252,7 @@ void UserDatagramProtocolHandler::Disconnect(UserDatagramProtocolSocket *socket) void UserDatagramProtocolHandler::Send(UserDatagramProtocolSocket *socket, uint8_t *data, uint16_t size) { uint16_t totalSize = sizeof(UserDatagramProtocolHeader) + size; //Get the total size of the packet - uint8_t* buffer = (uint8_t*)MemoryManager::activeMemoryManager->malloc(totalSize); //Allocate memory for the packet + uint8_t* buffer = (uint8_t*)MemoryManager::s_active_memory_manager->malloc(totalSize); //Allocate memory for the packet uint8_t* buffer2 = buffer + sizeof(UserDatagramProtocolHeader); //Get the buffer that will be used to store the data UserDatagramProtocolHeader* header = (UserDatagramProtocolHeader*)buffer; //Create the header of the packet @@ -278,19 +278,20 @@ void UserDatagramProtocolHandler::Send(UserDatagramProtocolSocket *socket, uint8 InternetProtocolPayloadHandler::Send(socket->remoteIP, buffer, totalSize); //Free the buffer - MemoryManager::activeMemoryManager->free(buffer); + MemoryManager::s_active_memory_manager->free(buffer); } /** - * @details Binds a handler to the socket + * @brief Binds a handler to the socket * * @param socket The socket to bind the handler to * @param userDatagramProtocolHandler The handler to bind */ void UserDatagramProtocolHandler::Bind(UserDatagramProtocolSocket *socket, UserDatagramProtocolPayloadHandler *userDatagramProtocolPayloadHandler) { - socket ->handlers.pushBack(userDatagramProtocolPayloadHandler); //Set the handler of the socket to the handler that was passed in + socket->m_handlers.push_back( + userDatagramProtocolPayloadHandler); //Set the handler of the socket to the handler that was passed in } diff --git a/kernel/src/system/gdt.cpp b/kernel/src/system/gdt.cpp index eecf44b0..9d8e354b 100644 --- a/kernel/src/system/gdt.cpp +++ b/kernel/src/system/gdt.cpp @@ -6,149 +6,137 @@ using namespace maxOS; using namespace maxOS::system; + /** - * @details Global Descriptor Table + * @brief Constructor for Segment Selector + * + * + * @param base base address + * @param limit limit + * @param flags Flags */ -GlobalDescriptorTable::GlobalDescriptorTable(const multiboot_info& multibootHeader) - : nullSegmentSelector(0, 0, 0), //Ignored - unusedSegmentSelector(0, 0, 0), //Ignored - codeSegmentSelector(0, 1024*multibootHeader.mem_upper, 0x9A), //0x9A Access for code - dataSegmentSelector(0, 1024*multibootHeader.mem_upper, 0x92), //0x92 Access flag for data - taskStateSegmentSelector(0, 1024*multibootHeader.mem_upper, 0) //Tasks - +SegmentDescriptor::SegmentDescriptor(uint32_t base, uint32_t limit, uint8_t type) { + uint8_t* target = (uint8_t*)this; //segment entry in GDT. + + if (limit <= 65536) + { + // 16-bit address space + target[6] = 0x40; + } + else + { + // 32-bit address space + if((limit & 0xFFF) != 0xFFF) + limit = (limit >> 12)-1; + else + limit = limit >> 12; - //Tell processor to use this table (8 bytes) - uint32_t gdt_t[2]; - gdt_t[0] = sizeof(GlobalDescriptorTable) << 16; //First and Second byte: The high bytes of the segment integer - gdt_t[1] = (uint32_t)this; //Last Four bytes: Tell processor the address of table - - asm volatile("lgdt (%0)": :"p" (((uint8_t *) gdt_t)+2)); //Pass it as an unsigned 8Bit int to assembly (p means push adress) + target[6] = 0xC0; + } -} + // Encode the limit + target[0] = limit & 0xFF; + target[1] = (limit >> 8) & 0xFF; + target[6] |= (limit >> 16) & 0xF; + // Encode the base + target[2] = base & 0xFF; + target[3] = (base >> 8) & 0xFF; + target[4] = (base >> 16) & 0xFF; + target[7] = (base >> 24) & 0xFF; -GlobalDescriptorTable::~GlobalDescriptorTable() -{ + // Type / Access Rights + target[5] = type; } - - /** - * @details Data Segment Selector + * @brief Look up the pointer * - * @return The data segment selector offset + * @return The pointer */ -uint16_t GlobalDescriptorTable::DataSegmentSelector() +uint32_t SegmentDescriptor::base() { - return (uint8_t*)&dataSegmentSelector - (uint8_t*)this; + uint8_t* target = (uint8_t*)this; + + uint32_t result = target[7]; + result = (result << 8) + target[4]; + result = (result << 8) + target[3]; + result = (result << 8) + target[2]; + + return result; } /** - * @details Code Segment Selector + * @brief Look up the limit * - * @return The code segment selector offset + * @return The limit */ -uint16_t GlobalDescriptorTable::CodeSegmentSelector() +uint32_t SegmentDescriptor::limit() { - return (uint8_t*)&codeSegmentSelector - (uint8_t*)this; + uint8_t* target = (uint8_t*)this; + + uint32_t result = target[6] & 0xF; + result = (result << 8) + target[1]; + result = (result << 8) + target[0]; + + if((target[6] & 0xC0) == 0xC0) + result = (result << 12) | 0xFFF; + + return result; } /** - * @details Task State Segment Selector - * - * @return The task state segment selector offset + * @brief Global Descriptor Table */ -uint16_t GlobalDescriptorTable::TaskStateSegmentSelector() +GlobalDescriptorTable::GlobalDescriptorTable(const multiboot_info&multiboot_header) +: m_null_segment_selector(0, 0, 0), m_unused_segment_selector(0, 0, 0), + m_code_segment_selector(0, 1024* multiboot_header.mem_upper, 0x9A), + m_data_segment_selector(0, 1024* multiboot_header.mem_upper, 0x92), + m_task_state_segment_selector(0, 1024* multiboot_header.mem_upper, 0) + { - return (uint8_t*)&taskStateSegmentSelector - (uint8_t*)this; + + // Create GDT + uint32_t gdt_t[2]; + gdt_t[0] = sizeof(GlobalDescriptorTable) << 16; + gdt_t[1] = (uint32_t)this; + + // Tell processor to use this table + asm volatile("lgdt (%0)": :"p" (((uint8_t *) gdt_t)+2)); + } -//Setup GDT for memory +GlobalDescriptorTable::~GlobalDescriptorTable() +{ +} + + /** - * @details Constructor for Segment Selector - * + * @brief Data Segment Selector * - * @param base Base address - * @param limit Limit - * @param flags Flags + * @return The data segment selector offset */ -GlobalDescriptorTable::SegmentDescriptor::SegmentDescriptor(uint32_t base, uint32_t limit, uint8_t type) +uint16_t GlobalDescriptorTable::data_segment_selector() { - uint8_t* target = (uint8_t*)this; //segment entry in GDT. - - if (limit <= 65536) - { - // 16-bit address space - target[6] = 0x40; - } - else - { - // 32-bit address space - // Now we have to squeeze the (32-bit) limit into 2.5 registers (20-bit). - // This is done by discarding the 12 least significant bits, but this - // is only legal, if they are all ==1, so they are implicitly still there - - // so if the last bits aren't all 1, we have to set them to 1, but this - // would increase the limit (cannot do that, because we might go beyond - // the physical limit or get overlap with other segments) so we have to - // compensate this by decreasing a higher bit (and might have up to - // 4095 wasted bytes behind the used memory) - - - if((limit & 0xFFF) != 0xFFF) - limit = (limit >> 12)-1; - else - limit = limit >> 12; - - target[6] = 0xC0; - } - - // Encode the limit - target[0] = limit & 0xFF; - target[1] = (limit >> 8) & 0xFF; - target[6] |= (limit >> 16) & 0xF; - - // Encode the base - target[2] = base & 0xFF; - target[3] = (base >> 8) & 0xFF; - target[4] = (base >> 16) & 0xFF; - target[7] = (base >> 24) & 0xFF; - - // Type / Access Rights - target[5] = type; + return (uint8_t*)&m_data_segment_selector - (uint8_t*)this; } + /** - * @details Look up the pointer + * @brief Code Segment Selector * - * @return The pointer + * @return The code segment selector offset */ -uint32_t GlobalDescriptorTable::SegmentDescriptor::Base() //To look up the pointer +uint16_t GlobalDescriptorTable::code_segment_selector() { - uint8_t* target = (uint8_t*)this; - - uint32_t result = target[7]; - result = (result << 8) + target[4]; - result = (result << 8) + target[3]; - result = (result << 8) + target[2]; - - return result; + return (uint8_t*)&m_code_segment_selector - (uint8_t*)this; } /** - * @details Look up the limit + * @brief Task State Segment Selector * - * @return The limit + * @return The task state segment selector offset */ -uint32_t GlobalDescriptorTable::SegmentDescriptor::Limit() +uint16_t GlobalDescriptorTable::task_state_segment_selector() { - uint8_t* target = (uint8_t*)this; - - uint32_t result = target[6] & 0xF; - result = (result << 8) + target[1]; - result = (result << 8) + target[0]; - - if((target[6] & 0xC0) == 0xC0) - result = (result << 12) | 0xFFF; - - return result; -} + return (uint8_t*)&m_task_state_segment_selector - (uint8_t*)this; +} \ No newline at end of file diff --git a/kernel/src/system/multitasking.cpp b/kernel/src/system/multitasking.cpp index abfd7f0c..714ea457 100644 --- a/kernel/src/system/multitasking.cpp +++ b/kernel/src/system/multitasking.cpp @@ -10,35 +10,26 @@ using namespace maxOS::system; ///__TASK__ Task::Task(GlobalDescriptorTable *gdt, void entrypoint()) { - // start of stack + size of stack - size of entry - cpuState = (CPUState_Task*)(stack + 4096 - sizeof(CPUState_Task)); - //Set phony entries - - cpuState -> eax = 0; - cpuState -> ebx = 0; - cpuState -> ecx = 0; - cpuState -> edx = 0; - cpuState -> esi = 0; - cpuState -> edi = 0; - cpuState -> ebp = 0; + //Set up stack + m_cpu_state = (CPUState *)(m_stack + 4096 - sizeof(CPUState)); - /* - cpuState -> gs = 0; - cpuState -> fs = 0; - cpuState -> es = 0; - cpuState -> ds = 0; - */ + //Set phony entries - //cpuState -> error = 0; + m_cpu_state-> eax = 0; + m_cpu_state-> ebx = 0; + m_cpu_state-> ecx = 0; + m_cpu_state-> edx = 0; - // cpuState -> esp = ; //commented out becuase its only for user space and different security levels + m_cpu_state-> esi = 0; + m_cpu_state-> edi = 0; + m_cpu_state-> ebp = 0; - cpuState -> eip = (uint32_t)entrypoint; // Instruction pointer is set to entry point (note: ignore error, it compiles) - cpuState -> cs = gdt->CodeSegmentSelector(); // Offset of the code segment - //state segment not used unless security - cpuState -> eflags = 0x202; + // Set up the function pointer + m_cpu_state-> eip = (uint32_t)entrypoint; + m_cpu_state-> cs = gdt->code_segment_selector(); + m_cpu_state-> eflags = 0x202; } Task::~Task() { @@ -49,10 +40,6 @@ Task::~Task() { TaskManager::TaskManager() { - //Default Values - numTasks = 0; - currentTask = -1; - } TaskManager::~TaskManager() { @@ -60,48 +47,38 @@ TaskManager::~TaskManager() { } /** - * @details Adds a task to the task manager + * @brief Adds a task to the task manager * * @param task The task to add */ -bool TaskManager::AddTask(Task *task) { +bool TaskManager::add_task(Task *task) { - if(numTasks >= 256){ //Array IS full - return false; - } - - tasks[numTasks++] = task; + m_tasks.push_back(task); return true; } /** - * @details Switches to the next task + * @brief Switches to the next task * * @param cpuState The current CPU state * @return The new CPU state */ -CPUState_Task *TaskManager::Schedule(CPUState_Task *cpuState) { - - if(numTasks <= 0){ //If there's no tasks yet - return cpuState; //Restore old cpu state - } +CPUState *TaskManager::schedule(CPUState *cpuState) { - if(currentTask >= 0){ - tasks[currentTask] -> cpuState = cpuState; //Restore the old value (put task back into list of tasks) - } + // If there's no tasks then don't schedule + if(m_tasks.size() <= 0) + return cpuState; - if(++currentTask >= numTasks){ //If current task exceeds size of tasks - currentTask %= numTasks; //Restart from beginning - } + // If there is a task running, save its state + if(m_current_task >= 0) + m_tasks[m_current_task] ->m_cpu_state = cpuState; - /* - if(tasks[currentTask] -> killMe){ - tasks[currentTask] = tasks[numTasks]; - numTasks - 1; - } - */ + // Switch to the next task (and loop back to the start if needed) + if(++m_current_task >= m_tasks.size()) + m_current_task %= m_tasks.size(); - return tasks[currentTask] -> cpuState; + // Start the next task + return m_tasks[m_current_task] ->m_cpu_state; -} +} \ No newline at end of file diff --git a/kernel/src/system/multithreading.cpp b/kernel/src/system/multithreading.cpp index 9a7f3fe1..4a5aee46 100644 --- a/kernel/src/system/multithreading.cpp +++ b/kernel/src/system/multithreading.cpp @@ -3,38 +3,38 @@ // #include -#define nullptr 0 - using namespace maxOS; using namespace maxOS::system; -int ThreadManager::numThreads = 0; -int ThreadManager::currentThread = -1; -Thread *ThreadManager::Threads[256] = {nullptr}; -GlobalDescriptorTable *ThreadManager::gdt; -uint8_t ThreadManager::stack[256][5012]; + +Thread::Thread() { + +} + +Thread::~Thread() +{ +} void Thread::init(GlobalDescriptorTable *gdt, void entrypoint()) { - cpustate = (CPUState_Thread *)(stack + 4096 - sizeof(CPUState_Thread)); - cpustate->eax = 0; - cpustate->ebx = 0; - cpustate->ecx = 0; - cpustate->edx = 0; + // Set up stack + m_cpu_state = (CPUState*)(m_stack + 4096 - sizeof(CPUState)); - cpustate->esi = 0; - cpustate->edi = 0; - cpustate->ebp = 0; + m_cpu_state->eax = 0; + m_cpu_state->ebx = 0; + m_cpu_state->ecx = 0; + m_cpu_state->edx = 0; - cpustate->eip = (uint32_t)entrypoint; // Set the entry point - cpustate->eflags = 0x202; // Interrupts enabled - yieldStatus = false; -} + m_cpu_state->esi = 0; + m_cpu_state->edi = 0; + m_cpu_state->ebp = 0; -Thread::~Thread() -{ + // Set up function pointer + m_cpu_state->eip = (uint32_t)entrypoint; + m_cpu_state->eflags = 0x202; + m_yield_status = false; } ThreadManager::ThreadManager() @@ -42,8 +42,7 @@ ThreadManager::ThreadManager() } ThreadManager::ThreadManager(GlobalDescriptorTable *gdt) -{ - this->gdt = gdt; +{ m_gdt = gdt; } ThreadManager::~ThreadManager() @@ -51,153 +50,77 @@ ThreadManager::~ThreadManager() } /** - * @details Add a thread to an empty place in the array + * @brief Add a thread to an empty place in the array * * @param Thread thread to add - * @return true if succesfully added + * @return true if successfully added * @return false if error */ -int ThreadManager::CreateThread(void entrypoint()) +int ThreadManager::create_thread(void entrypoint()) { - - if (numThreads >= 256) // if there are more than 256 threads, return false - return false; - - int i = 0; - while (i <= 256) // find an empty place in the array - { - if (Threads[i] == nullptr) // if the place is empty - { - Thread *th = (Thread *)(stack[i] + (5012 - sizeof(Thread))); // init space for thread - th->init(gdt, entrypoint); // init thread - th->tid = i; // set thread id - Threads[numThreads] = th; // add thread to array - Threads[numThreads]->cpustate->cs = gdt->CodeSegmentSelector(); // set code segment - numThreads++; // increment number of threads - return th->tid; // return thread id - } - - i++; // increment i - } - - return -1; // if no empty place was found, return -1 + // Create a new thread + Thread* new_thread = new Thread(); + new_thread -> init(m_gdt, entrypoint); + new_thread -> m_tid = m_threads.size(); + new_thread -> m_cpu_state -> cs = m_gdt-> code_segment_selector(); + + // Add the thread to the array + m_threads.push_back(new_thread); + return new_thread -> m_tid; } /** - * @details Schedules the next thread to be executed by checking its yieldsStatus. + * @brief Schedules the next thread to be executed by checking its yieldsStatus. * - * @param cpustate state - * @return CPUState_Thread* thread to be executed state + * @param cpu_state state + * @return CPUState* The state of the next thread to be executed */ -CPUState_Thread *ThreadManager::Schedule(CPUState_Thread* cpustate) +CPUState* ThreadManager::schedule(CPUState*cpu_state) { - if(cpustate -> eax == 37){ // if eax is 37, it means that the thread is being killed - TerminateThread(currentThread); // kill the thread - } - - if (numThreads <= 0) // if there are no threads, return cpustate - return cpustate; - - + // If the eax register is 37, terminate the thread + if(cpu_state-> eax == 37) + terminate_thread(m_current_thread); + // If there are no threads to schedule, return the current state + if (m_threads.size() <= 0 || m_threads[m_current_thread] == nullptr) + return cpu_state; + // Save the current state + m_threads[m_current_thread]->m_cpu_state = cpu_state; - if (currentThread >= 0 && Threads[currentThread] != nullptr) // if there is a current thread - Threads[currentThread++]->cpustate = cpustate; + // Switch to the next thread + if(++m_current_thread >= m_threads.size()) + m_current_thread %= m_threads.size(); - - - int i = currentThread; // set i to currentThread - - while (i < 256) - { - - if (i >= 0 && Threads[i] != nullptr) // if there is a thread in the array - { - - if (Threads[i]->yieldStatus) // if the thread is yielded - Threads[i]->yieldStatus = false; // set yieldStatus to false - else - { - currentThread = i; // set currentThread to i - return Threads[i] -> cpustate; // return the state of the thread - } - } - - i++; - if (i >= 256) // if i is greater than 256 - i = 0; + // If this thread is yielded then skip it + if(m_threads[m_current_thread]->m_yield_status){ + m_threads[m_current_thread]->m_yield_status = false; + return schedule(cpu_state); } - - return cpustate; + // Return the next thread's state + return m_threads[m_current_thread]->m_cpu_state; } /** - * @details Terminates a thread by removing it from an array by making its pointer nullptr + * @brief Terminates a thread * * @param tid thread id to terminate - * @return true if sucessfully terminated - * @return false if error + * @return true if successfully terminated thread or false if error */ -bool ThreadManager::TerminateThread(int tid) +bool ThreadManager::terminate_thread(int tid) { - // if tid is out of bounds, return false - if (tid < 0 || tid >= 256) - return false; - - // if there is no thread in the array, return false - if (Threads[tid] == nullptr) + // Check if the thread is actually running + if (tid < 0 || tid >= m_threads.size()) return false; - // Set the pointer to nullptr - Threads[tid] = nullptr; - numThreads--; - return true; -} - -/** - * @details Joins a thread by waiting to finish - * - * @param other thread to join - * @return true if succesfully joined - * @return false if error - */ -bool ThreadManager::JoinThreads(int other) -{ - //check if thread is already terminated or null - if (Threads[other] == nullptr) - return false; - if (Threads[other]->yieldStatus) - return false; + // Delete the thread + delete m_threads[tid]; - while (true) - { - if (Threads[other] == nullptr) - break; - } + // Erase the thread from the array + m_threads.erase(m_threads.begin() + tid); + // TODO: Thread ID needs to be updated return true; -} - -/** - * @details Makes yield status true of the current thread - * - */ -void ThreadManager::YieldThreads(int tid) -{ - Threads[tid]->yieldStatus = true; -} - -/** - * @details Checks if a thread is terminated - * - * @param tid thread id to check - * @return false if thread is terminated - */ -bool ThreadManager::CheckThreads(int tid) { - - return Threads[tid] == nullptr; - } \ No newline at end of file diff --git a/kernel/src/system/process.cpp b/kernel/src/system/process.cpp index cf429f2e..d7d06811 100644 --- a/kernel/src/system/process.cpp +++ b/kernel/src/system/process.cpp @@ -6,124 +6,3 @@ using namespace maxOS; using namespace maxOS::system; - - -Process::Process(void entrypoint(), ThreadManager* threadManager) { - - - //Create main thread - this -> threadManager = threadManager; - - - - - mainThreadID = threadManager -> CreateThread(entrypoint); - - //Clear child threads - for (int i = 0; i < 6; ++i) { - childThreads[i] = -1; - } - -} - -Process::~Process() { - - Kill(); - - -} - -void Process::threadMain(void entrypoint(), Process* process){ - entrypoint(); //Run the task - process -> Kill(); //Kill the process - -} - -/** - * @details Create a new thread, as a child of this process - * - * @param entrypoint Entry point of the thread - */ -void Process::CreateChildThread(void (*entrypoint)()) { - - RefreshProcess(); - if(numChildThreads < 6){ //If there is space for a new thread - for (int i = 0; i < 6; ++i) { //Loop through child threads - if(childThreads[numChildThreads] == -1){ //If the thread is empty - childThreads[numChildThreads] = threadManager -> CreateThread(entrypoint); //Create a new thread - numChildThreads++; //Increase the number of child threads - break; - } - } - } - -} - -/** - * @details Kill the process's child thread - * - * @param threadID ID of the thread to kill - */ -void Process::KillChildThread(int threadID) { - - for(int i = 0; i < numChildThreads; i++){ //Loop through child threads - if(childThreads[i] == -1) continue; //If the thread is empty, skip it - - if(childThreads[i] == threadID){ //If the thread is the one to kill - threadManager -> TerminateThread(threadID); //Kill the thread - childThreads[i] = -1; //Set the thread to empty - numChildThreads--; //Decrease the number of child threads - } - } - -} - -/** - * @details kill all the child threads - */ -void Process::KillAllChildThreads() { - - - - //Loop through child threads and kill them - for(int i = 0; i < numChildThreads; i++){ - - if(childThreads[i] == -1) continue; //If the thread is empty, skip it - - threadManager -> TerminateThread(childThreads[i]); - childThreads[i] = -1; - } - numChildThreads = 0; - - -} - -/** - * @details refresh the process, removing any empty child threads - */ -void Process::RefreshProcess() { - - //Loop through child threads and refresh them - for(int i = 0; i < numChildThreads; i++){ - if(childThreads[i] == -1) continue; //If the thread is empty, skip it - - if(!threadManager->CheckThreads(childThreads[i])){ //Check If thread still exists - childThreads[i] = -1; - numChildThreads--; - } - } - - -} - -/** - * @details Kill the process - */ -void Process::Kill() { - //Kill all child threads - KillAllChildThreads(); - - //Kill main thread - threadManager -> TerminateThread(mainThreadID); -} - diff --git a/kernel/src/system/syscalls.cpp b/kernel/src/system/syscalls.cpp index 06b1571e..cff5aa37 100644 --- a/kernel/src/system/syscalls.cpp +++ b/kernel/src/system/syscalls.cpp @@ -11,8 +11,8 @@ using namespace maxOS::system; ///__Handler__/// -SyscallHandler::SyscallHandler(InterruptManager* interruptManager, uint8_t InterruptNumber) - : InterruptHandler(InterruptNumber + interruptManager->HardwareInterruptOffset(), interruptManager) +SyscallHandler::SyscallHandler(InterruptManager*interrupt_manager, uint8_t interrupt_number) +: InterruptHandler(interrupt_number + interrupt_manager->hardware_interrupt_offset(), interrupt_manager) { } @@ -21,178 +21,14 @@ SyscallHandler::~SyscallHandler() } /** - * @details Handles the interrupt for a system call + * @brief Handles the interrupt for a system call * * @param esp The stack frame */ -void SyscallHandler::HandleInterrupt() +void SyscallHandler::handle_interrupt() { - // TODO: Get the CPU state from the stack frame + // TODO: Get the CPU state from the stack frame (maybe make a cpu driver to get the state) return; } -///__Syscall__/// - -/** - * @details terminate the calling process - * - * @param status The exit code - */ -void sys_exit(int status) -{ - asm("int $0x80" : : "a" (1), "b" (status)); //Call the interrupt, passing the syscall number and the argument -} - -/** - * @details creates a new process by duplicating the calling process. - The new process is referred to as the child process. The calling - process is referred to as the parent process. - - * @param cpu The CPU state of the calling process - */ -void sys_fork(CPUState_Thread* cpu) -{ - asm("int $0x80" : : "a" (2), "b" (cpu)); -} - -/** - * @details attempts to read up to count bytes from file descriptor fd - into the buffer starting at buf. - - * @param fd The file descriptor - * @param buf The buffer to read into - * @param count The number of bytes to read - * @return On success, the number of bytes read is returned (zero indicates - end of file), and the file position is advanced by this number. On error, -1 is returned - */ -size_t sys_read(unsigned int fd, char *buf, size_t count){ - - uint32_t data = 3; - asm volatile( "int $0x80" : "=a"(data) : "b"(fd), "c" (buf), "d" (count)); //Call the interrupt, passing the syscall number and the argument - return data; - - //https://man7.org/linux/man-pages/man2/read.2.html - -} - -/** - * @details attempts to write up to count bytes from the buffer starting - at buf to the file referred to by the file descriptor fd. - - * @param fd The file descriptor - * @param buf The buffer to write from - * @param count The number of bytes to write - * @return On success, the number of bytes written is returned (zero indicates nothing was written). On error, -1 is returned - */ -size_t sys_write(int fd, const void *buf, size_t count){ - - - uint32_t data = 4; - asm volatile( "int $0x80" : "=a"(data) : "b"(fd), "c" (buf), "d"(count)); //Call the interrupt, passing the syscall number and the argument - return data; - - //https://man7.org/linux/man-pages/man2/write.2.html - -} - -/** - * @details opens the file specified by pathname. If - the specified file does not exist, it may optionally (if O_CREAT - is specified in flags) be created by open(). - - * @param filename The file to open - * @param flags The flags to open the file with - * @param mode The mode to open the file with - * @return On success, these system calls return a nonnegative integer that is a file descriptor for the - newly opened file. On error, -1 is returned - */ -/* int sys_open(const char *pathname, int flags, mode_t mode){ - - asm("int $0x80" : : "a" (5), "b" (pathname), "c" (flags), "d" (mode)); - //TODO: Return the file descriptor - //https://man7.org/linux/man-pages/man2/open.2.html - -} */ - -/** - * @details closes a file descriptor, so that it no longer refers to any - file and may be reused. - - * @param fd The file descriptor to close - * @return On success, zero is returned. On error, -1 is returned - */ -int sys_close(int fd){ - - uint32_t data = 6; - asm volatile( "int $0x80" : "=a"(data) : "b"(fd)); //Call the interrupt, passing the syscall number and the argument - return data; - //https://man7.org/linux/man-pages/man2/close.2.html -} - -/** - * @details waits for a child process to stop or terminate. - * - * @param pid The process ID of the child process - * @param status The exit code of the child process - * @param options The options to wait with - * @return On success, returns the process ID of the child whose state has changed; if WNOHANG was - specified and one or more child(ren) specified by pid exist, but have not yet changed state, - then 0 is returned. On error, -1 is returned - */ -/* pid_t sys_waitpid(pid_t pid, int *status, int options) { - - uint32_t data = 7; - asm volatile( "int $0x80" : "=a"(data) : "b" (pid), "c" (status), "d" (options)); //Call the interrupt, passing the syscall number and the argument - return data; - //https://man7.org/linux/man-pages/man2/waitpid.2.html -} */ - -/** - * @ details equivalent to calling open() with flags - equal to O_CREAT|O_WRONLY|O_TRUNC. - - * @param pathname - * @param mode - * @return On success, these system calls return a nonnegative integer that is a file descriptor for the - newly opened file. On error, -1 is returned - */ -/* int sys_creat(const char *pathname, mode_t mode){ - - uint32_t data = 8; - asm volatile( "int $0x80" : "=a"(data) :"b" (pathname), "c" (mode)); - //TODO: Return the file descriptor - //https://man7.org/linux/man-pages/man2/open.2.html#:~:text=O_TRUNC%20is%20unspecified.-,creat,-()%0A%20%20%20%20%20%20%20A%20call -} */ - -/** - * @details creates a new link (also known as a hard link) to an - existing file. - - * @param oldpath The path to the existing file - * @param newpath The path to the new link - * @return On success, zero is returned. On error, -1 is returned - */ -int sys_link(const char *oldpath, const char *newpath){ - - uint32_t data = 9; - asm volatile( "int $0x80" : "=a"(data) : "b" (oldpath), "c" (newpath)); //Call the interrupt, passing the syscall number and the argument - return data; - //https://man7.org/linux/man-pages/man2/link.2.html -} - -/** - * @details deletes a name from the file system. If that name was the - last link to a file and no processes have the file open, the file - is deleted and the space it was using is made available for reuse. - - * @param pathname The path to the file to unlink - * @return On success, zero is returned. On error, -1 is returned - */ -int sys_unlink(const char *pathname){ - - uint32_t data = 10; - asm volatile( "int $0x80" : "=a"(data) : "b" (pathname)); //Call the interrupt, passing the syscall number and the argument - return data; - - //https://man7.org/linux/man-pages/man2/unlink.2.html -} \ No newline at end of file +// TODO: Implement the system calls \ No newline at end of file