├── .target ├── Kernal ├── drivers │ ├── ACPI.h │ ├── asmio.h │ ├── 0xb8000.h │ └── PS2.h ├── kmain.h ├── Kernal.depend ├── bmake.sh ├── Kernal.layout ├── Kernal.cbp ├── kmain.c └── bootstrap.s ├── GameOS.iso ├── link ├── boot.o ├── kernel.o ├── GameOS.bin └── linker.ld ├── Readme ├── GameOS.workspace ├── GameOS.workspace.layout ├── .gitattributes └── .gitignore /.target: -------------------------------------------------------------------------------- 1 | x86_64-elf 2 | -------------------------------------------------------------------------------- /Kernal/drivers/ACPI.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Kernal/kmain.h: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /GameOS.iso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getynge/GameOS/HEAD/GameOS.iso -------------------------------------------------------------------------------- /link/boot.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getynge/GameOS/HEAD/link/boot.o -------------------------------------------------------------------------------- /link/kernel.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getynge/GameOS/HEAD/link/kernel.o -------------------------------------------------------------------------------- /link/GameOS.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getynge/GameOS/HEAD/link/GameOS.bin -------------------------------------------------------------------------------- /Readme: -------------------------------------------------------------------------------- 1 | GameOS 2 | This project is an attempt to make an open source operating system 3 | optimized for gaming. -------------------------------------------------------------------------------- /Kernal/Kernal.depend: -------------------------------------------------------------------------------- 1 | # depslib dependency file v1.0 2 | 1387731393 source:c:\users\mike\google drive\gameos\kernal\kmain.c 3 | "kmain.h" 4 | 5 | 1387731324 c:\users\mike\google drive\gameos\kernal\kmain.h 6 | 7 | -------------------------------------------------------------------------------- /GameOS.workspace: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /GameOS.workspace.layout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Kernal/bmake.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | i586-elf-as ./bootstrap.s -o ../link/boot.o 3 | i586-elf-gcc -c ./kmain.c -o ../link/kernel.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra 4 | cd ../link/ 5 | i586-elf-gcc -T linker.ld -o GameOS.bin -ffreestanding -O2 -nostdlib boot.o kernel.o -lgcc 6 | cd .. 7 | rm isodir/boot/GameOS.bin 8 | cp ./link/GameOS.bin ./isodir/boot/GameOS.bin 9 | rm GameOS.iso 10 | grub-mkrescue -o GameOS.iso isodir 11 | -------------------------------------------------------------------------------- /Kernal/drivers/asmio.h: -------------------------------------------------------------------------------- 1 | #ifndef __H__ASMIO__H__ 2 | #define __H__ASMIO__H__ 3 | inline void hang(){ 4 | hang:; 5 | asm volatile ("cli;" 6 | "hlt;" 7 | : : ); 8 | goto hang; 9 | } 10 | inline uint8_t inportb(uint16_t port){ 11 | uint8_t ret; 12 | asm volatile ("inb %%dx,%%al":"=a" (ret):"d" (port)); 13 | return ret; 14 | } 15 | inline void outportb(uint16_t port, uint8_t value){ 16 | asm volatile ("outb %%al,%%dx": :"d" (port), "a" (value)); 17 | } 18 | inline uint32_t HighMemCNT(){ 19 | 20 | } 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /Kernal/Kernal.layout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /link/linker.ld: -------------------------------------------------------------------------------- 1 | /* The bootloader will look at this image and start execution at the symbol 2 | designated as the entry point. */ 3 | ENTRY(_start) 4 | 5 | /* Tell where the various sections of the object files will be put in the final 6 | kernel image. */ 7 | SECTIONS 8 | { 9 | /* Begin putting sections at 1 MiB, a conventional place for kernels to be 10 | loaded at by the bootloader. */ 11 | . = 1M; 12 | 13 | /* First put the multiboot header, as it is required to be put very early 14 | early in the image or the bootloader won't recognize the file format. 15 | Next we'll put the .text section. */ 16 | .text BLOCK(4K) : ALIGN(4K) 17 | { 18 | *(.multiboot) 19 | *(.text) 20 | } 21 | 22 | /* Read-only data. */ 23 | .rodata BLOCK(4K) : ALIGN(4K) 24 | { 25 | *(.rodata) 26 | } 27 | 28 | /* Read-write data (initialized) */ 29 | .data BLOCK(4K) : ALIGN(4K) 30 | { 31 | *(.data) 32 | } 33 | 34 | /* Read-write data (uninitialized) and stack */ 35 | .bss BLOCK(4K) : ALIGN(4K) 36 | { 37 | *(COMMON) 38 | *(.bss) 39 | *(.bootstrap_stack) 40 | } 41 | 42 | /* The compiler may produce other sections, by default it will put them in 43 | a segment with the same name. Simply add stuff here as needed. */ 44 | } 45 | -------------------------------------------------------------------------------- /Kernal/Kernal.cbp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 49 | 50 | -------------------------------------------------------------------------------- /Kernal/kmain.c: -------------------------------------------------------------------------------- 1 | #include "drivers/0xb8000.h" 2 | #include "drivers/PS2.h" 3 | uint32_t HMem; 4 | typedef struct MHeap{ 5 | struct MHeap * parent; 6 | struct MHeap * child; 7 | }MHeap; 8 | size_t strlen(const char * str){ 9 | size_t ret = 0; 10 | if(str != 0x0){ 11 | while(str[ret] != 0x0){ 12 | ret += 1; 13 | } 14 | } 15 | return ret; 16 | } 17 | void (*writestring)(const char * data); 18 | #if defined(__cplusplus) 19 | extern "C" 20 | #endif // defined 21 | int _kmain(){ 22 | VGA_TERMINAL_INIT(); 23 | outportb(PS2_CONTROLLER_STATE, PS2_DISABLE_FIRST_PORT); //disable ports for now to prevent writing to the input buffer when we don't want it 24 | outportb(PS2_CONTROLLER_STATE, PS2_DISABLE_SECOND_PORT); 25 | inportb(PS2_CONTROLLER_DATA); //flush the input buffer by reading it 26 | writestring = &VGA_TERMINAL_WRITESTRING; 27 | (*writestring)("kernel has booted without error\n"); 28 | (*writestring)("beginning debugging process\n"); 29 | PS2_CONTROLLER_INIT(); 30 | if(VGA_TERMINAL_BASE_IO == 0x3D4){ 31 | (*writestring)("BIOS base IO is 0x3D4\n"); 32 | }else{ 33 | (*writestring)("BIOS base port is not standard\n"); 34 | (*writestring)("Will use non-standard base port call\n"); 35 | } 36 | (*writestring)("debugging completed, no fatal errors detected\n"); 37 | (*writestring)("press ENTER to finish boot\n"); 38 | //char * cmd; //bytes 0x00100001 through 0x00100201 are reserved for command line arguments 39 | 40 | //cmd = (char*) 0x00100001; 41 | uint16_t curpos = 0; 42 | while(true){ 43 | uint8_t state = inportb(PS2_CONTROLLER_STATE); 44 | if(state & 0b00000001) 45 | { 46 | uint8_t key = inportb(PS2_CONTROLLER_DATA); 47 | inportb(PS2_CONTROLLER_DATA); 48 | char res = PS2_KEYBOARD_CODE_HANDLER(0x02, key); 49 | if(res == 0x0){ 50 | continue; 51 | } 52 | if(res == '\n' && debugflag == 0x1){ 53 | VGA_TERMINAL_CLEARBUFFER(); 54 | debugflag = 0; 55 | (*writestring)("sysrqterm>"); 56 | continue; 57 | } 58 | if(res == '\n'){ 59 | (*writestring)("\nsysrqterm>"); 60 | continue; 61 | } 62 | if(res != 0){ 63 | if(curpos < 512){ 64 | //cmd[curpos] = res; 65 | curpos += 1; 66 | VGA_TERMINAL_PUTCHAR(res); 67 | } 68 | } 69 | } 70 | } 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | 131 | # NuGet Packages Directory 132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 133 | #packages/ 134 | 135 | # Windows Azure Build Output 136 | csx 137 | *.build.csdef 138 | 139 | # Windows Store app package directory 140 | AppPackages/ 141 | 142 | # Others 143 | sql/ 144 | *.Cache 145 | ClientBin/ 146 | [Ss]tyle[Cc]op.* 147 | ~$* 148 | *~ 149 | *.dbmdl 150 | *.[Pp]ublish.xml 151 | *.pfx 152 | *.publishsettings 153 | 154 | # RIA/Silverlight projects 155 | Generated_Code/ 156 | 157 | # Backup & report files from converting an old project file to a newer 158 | # Visual Studio version. Backup files are not needed, because we have git ;-) 159 | _UpgradeReport_Files/ 160 | Backup*/ 161 | UpgradeLog*.XML 162 | UpgradeLog*.htm 163 | 164 | # SQL Server files 165 | App_Data/*.mdf 166 | App_Data/*.ldf 167 | 168 | ############# 169 | ## Windows detritus 170 | ############# 171 | 172 | # Windows image file caches 173 | Thumbs.db 174 | ehthumbs.db 175 | 176 | # Folder config file 177 | Desktop.ini 178 | 179 | # Recycle Bin used on file shares 180 | $RECYCLE.BIN/ 181 | 182 | # Mac crap 183 | .DS_Store 184 | 185 | 186 | ############# 187 | ## Python 188 | ############# 189 | 190 | *.py[co] 191 | 192 | # Packages 193 | *.egg 194 | *.egg-info 195 | dist/ 196 | build/ 197 | eggs/ 198 | parts/ 199 | var/ 200 | sdist/ 201 | develop-eggs/ 202 | .installed.cfg 203 | 204 | # Installer logs 205 | pip-log.txt 206 | 207 | # Unit test / coverage reports 208 | .coverage 209 | .tox 210 | 211 | #Translations 212 | *.mo 213 | 214 | #Mr Developer 215 | .mr.developer.cfg 216 | -------------------------------------------------------------------------------- /Kernal/bootstrap.s: -------------------------------------------------------------------------------- 1 | # Declare constants used for creating a multiboot header. 2 | .set ALIGN, 1<<0 # align loaded modules on page boundaries 3 | .set MEMINFO, 1<<1 # provide memory map 4 | .set FLAGS, ALIGN | MEMINFO # this is the Multiboot 'flag' field 5 | .set MAGIC, 0x1BADB002 # 'magic number' lets bootloader find the header 6 | .set CHECKSUM, -(MAGIC + FLAGS) # checksum of above, to prove we are multiboot 7 | 8 | # Declare a header as in the Multiboot Standard. We put this into a special 9 | # section so we can force the header to be in the start of the final program. 10 | # You don't need to understand all these details as it is just magic values that 11 | # is documented in the multiboot standard. The bootloader will search for this 12 | # magic sequence and recognize us as a multiboot kernel. 13 | .section .multiboot 14 | .align 4 15 | .long MAGIC 16 | .long FLAGS 17 | .long CHECKSUM 18 | 19 | # Currently the stack pointer register (esp) points at anything and using it may 20 | # cause massive harm. Instead, we'll provide our own stack. We will allocate 21 | # room for a small temporary stack by creating a symbol at the bottom of it, 22 | # then allocating 16384 bytes for it, and finally creating a symbol at the top. 23 | .section .bootstrap_stack 24 | stack_bottom: 25 | .skip 16384 # 16 KiB 26 | stack_top: 27 | 28 | # The linker script specifies _start as the entry point to the kernel and the 29 | # bootloader will jump to this position once the kernel has been loaded. It 30 | # doesn't make sense to return from this function as the bootloader is gone. 31 | .section .text 32 | .global _start 33 | .type _start, @function 34 | _start: 35 | # Welcome to kernel mode! We now have sufficient code for the bootloader to 36 | # load and run our operating system. It doesn't do anything interesting yet. 37 | # Perhaps we would like to call printf("Hello, World\n"). You should now 38 | # realize one of the profound truths about kernel mode: There is nothing 39 | # there unless you provide it yourself. There is no printf function. There 40 | # is no header. If you want a function, you will have to code it 41 | # yourself. And that is one of the best things about kernel development: 42 | # you get to make the entire system yourself. You have absolute and complete 43 | # power over the machine, there are no security restrictions, no safe 44 | # guards, no debugging mechanisms, there is nothing but what you build. 45 | 46 | # By now, you are perhaps tired of assembly language. You realize some 47 | # things simply cannot be done in C, such as making the multiboot header in 48 | # the right section and setting up the stack. However, you would like to 49 | # write the operating system in a higher level language, such as C or C++. 50 | # To that end, the next task is preparing the processor for execution of 51 | # such code. C doesn't expect much at this point and we only need to set up 52 | # a stack. Note that the processor is not fully initialized yet and stuff 53 | # such as floating point instructions are not available yet. 54 | 55 | # To set up a stack, we simply set the esp register to point to the top of 56 | # our stack (as it grows downwards). 57 | movl $stack_top, %esp 58 | 59 | # We are now ready to actually execute C code. We cannot embed that in an 60 | # assembly file, so we'll create a kernel.c file in a moment. In that file, 61 | # we'll create a C entry point called kernel_main and call it here. 62 | call _kmain 63 | 64 | # In case the function returns, we'll want to put the computer into an 65 | # infinite loop. To do that, we use the clear interrupt ('cli') instruction 66 | # to disable interrupts, the halt instruction ('hlt') to stop the CPU until 67 | # the next interrupt arrives, and jumping to the halt instruction if it ever 68 | # continues execution, just to be safe. We will create a local label rather 69 | # than real symbol and jump to there endlessly. 70 | cli 71 | hlt 72 | .Lhang: 73 | jmp .Lhang 74 | 75 | # Set the size of the _start symbol to the current location '.' minus its start. 76 | # This is useful when debugging or when you implement call tracing. 77 | .size _start, . - _start 78 | -------------------------------------------------------------------------------- /Kernal/drivers/0xb8000.h: -------------------------------------------------------------------------------- 1 | #ifndef __H__0XB8000__H__ 2 | #define __H__0XB8000__H__ 3 | #include 4 | #include 5 | #include 6 | #include "asmio.h" 7 | size_t strlen(const char * str); 8 | /* 9 | Hardware text mode colors 10 | */ 11 | typedef enum vga_color 12 | { 13 | COLOR_BLACK = 0, 14 | COLOR_BLUE = 1, 15 | COLOR_GREEN = 2, 16 | COLOR_CYAN = 3, 17 | COLOR_RED = 4, 18 | COLOR_MAGENTA = 5, 19 | COLOR_BROWN = 6, 20 | COLOR_LIGHT_GREY = 7, 21 | COLOR_DARK_GREY = 8, 22 | COLOR_LIGHT_BLUE = 9, 23 | COLOR_LIGHT_GREEN = 10, 24 | COLOR_LIGHT_CYAN = 11, 25 | COLOR_LIGHT_RED = 12, 26 | COLOR_LIGHT_MAGENTA = 13, 27 | COLOR_LIGHT_BROWN = 14, 28 | COLOR_WHITE = 15, 29 | }vga_color; 30 | uint8_t debugflag = 0x1; 31 | volatile uint16_t VGA_TERMINAL_BASE_IO; 32 | void VGA_TERMINAL_UPDATE_CURSOR(uint8_t row, uint8_t col){ 33 | uint16_t position = (row*80) + col; 34 | outportb(VGA_TERMINAL_BASE_IO, 0x0F); 35 | outportb((VGA_TERMINAL_BASE_IO+1), (uint8_t)(position&0xFF)); 36 | outportb(VGA_TERMINAL_BASE_IO, 0x0E); 37 | outportb((VGA_TERMINAL_BASE_IO+1), (uint8_t)((position>>8)&0xFF)); 38 | } 39 | uint8_t VGA_MAKE_COLOR(vga_color fg, vga_color bg){ 40 | return fg | bg << 4; 41 | } 42 | uint16_t VGA_MAKE_ENTRY(char c, uint8_t color){ 43 | uint16_t c16 = c; 44 | uint16_t color16 = color; 45 | return c16 | color16 << 8; 46 | } 47 | static const size_t VGA_WIDTH = 80; 48 | static const size_t VGA_HEIGHT = 24; 49 | size_t terminal_row; 50 | size_t terminal_column; 51 | uint8_t terminal_color; 52 | uint16_t* terminal_buffer; 53 | uint16_t* terminal_scroll_buffer; 54 | /** 55 | *Set the buffer location on which the next character will be placed. 56 | **/ 57 | void VGA_TERMINAL_SETPOS(uint8_t x, uint8_t y){ 58 | terminal_column = x; 59 | terminal_row = y; 60 | VGA_TERMINAL_UPDATE_CURSOR(y, x); 61 | } 62 | void VGA_TERMINAL_NEWLINE(){ 63 | VGA_TERMINAL_SETPOS(0, terminal_row+1); 64 | 65 | } 66 | /** 67 | Short for Horizontal Push, takes a whole line from the top of the primary buffer and moves it to the bottom of the 68 | scroll buffer, the entire scroll buffer is moved up one line before the content is pushed to it, and the 69 | entire primary buffer is moved up one line after the content is pushed to the scroll buffer. 70 | **/ 71 | void VGA_BUFFER_HPUSH(){ 72 | 73 | } 74 | /** 75 | short for Horizontal Pop, takes a whole line from the bottom of the scroll buffer and moves it to the top of the primary buffer, 76 | **/ 77 | void VGA_BUFFER_HPOP(){ 78 | 79 | } 80 | void VGA_TERMINAL_SCROLL(int8_t direction_and_distance){ 81 | ///If the sign bit is set, move up, if it is clear move down. 82 | if(direction_and_distance & (uint8_t) 0b10000000){ 83 | 84 | 85 | }else{ 86 | 87 | } 88 | } 89 | void VGA_TERMINAL_INIT() 90 | { 91 | 92 | terminal_row = 0; 93 | terminal_column = 0; 94 | terminal_color = VGA_MAKE_COLOR(COLOR_LIGHT_GREY, COLOR_BLACK); 95 | terminal_buffer = (uint16_t*) 0xB8000; 96 | uint8_t * BIO = (uint8_t*)0x0463; 97 | uint8_t * BIO2 = (uint8_t*)0x0464; 98 | uint8_t bio = *BIO; 99 | uint8_t bio2 = *BIO2; 100 | VGA_TERMINAL_BASE_IO = bio | (bio2<<8); 101 | for ( size_t y = 0; y < VGA_HEIGHT; y++ ) 102 | { 103 | for ( size_t x = 0; x < VGA_WIDTH; x++ ) 104 | { 105 | const size_t index = y * VGA_WIDTH + x; 106 | terminal_buffer[index] = VGA_MAKE_ENTRY(' ', terminal_color); 107 | } 108 | } 109 | } 110 | 111 | void VGA_TERMINAL_SETCOLOR(uint8_t color) 112 | { 113 | terminal_color = color; 114 | } 115 | 116 | void VGA_TERMINAL_PUT_ENTRY_AT(char c, uint8_t color, size_t x, size_t y) 117 | { 118 | const size_t index = y * VGA_WIDTH + x; 119 | terminal_buffer[index] = VGA_MAKE_ENTRY(c, color); 120 | } 121 | 122 | void VGA_TERMINAL_PUTCHAR(char c) 123 | { 124 | VGA_TERMINAL_PUT_ENTRY_AT(c, terminal_color, terminal_column, terminal_row); 125 | if ( ++terminal_column == VGA_WIDTH ) 126 | { 127 | terminal_column = 0; 128 | if ( ++terminal_row == VGA_HEIGHT ) 129 | { 130 | terminal_row = VGA_HEIGHT-1; 131 | 132 | } 133 | } 134 | VGA_TERMINAL_UPDATE_CURSOR(terminal_row, terminal_column); 135 | } 136 | void VGA_TERMINAL_CLEARBUFFER(){ 137 | for ( size_t y = 0; y < VGA_HEIGHT; y++ ) 138 | { 139 | for ( size_t x = 0; x < VGA_WIDTH; x++ ) 140 | { 141 | const size_t index = y * VGA_WIDTH + x; 142 | terminal_buffer[index] = 0x0; 143 | } 144 | } 145 | VGA_TERMINAL_SETPOS(0, 0); 146 | } 147 | void VGA_TERMINAL_WRITESTRING(const char* data) 148 | { 149 | size_t datalen = strlen(data); 150 | for ( size_t i = 0; i < datalen; i++ ) 151 | if(data[i] == '\n'){ 152 | VGA_TERMINAL_NEWLINE(); 153 | }else{ 154 | VGA_TERMINAL_PUTCHAR(data[i]); 155 | } 156 | } 157 | #endif 158 | -------------------------------------------------------------------------------- /Kernal/drivers/PS2.h: -------------------------------------------------------------------------------- 1 | #define PS2_READ_FROM_BYTE_0 0x20 2 | #define PS2_WRITE_TO_BYTE_0 0x60 3 | #define TEST_PS2_CONTROLLER 0xAA 4 | #define PS2_CONTROLLER_TEST_PASSED 0x55 5 | #include "asmio.h" 6 | #define PS2_SET_SCAN_CODE_SET 0xF0 7 | #define PS2_CONTROLLER_TEST_FAILED 0xFC 8 | #define PS2_ENABLE_FIRST_PORT 0xAE 9 | #define PS2_ENABLE_SECOND_PORT 0xA8 10 | #define PS2_DISABLE_FIRST_PORT 0xAD 11 | #define PS2_DISABLE_SECOND_PORT 0xA7 12 | #define PS2_IDENTIFY_DEVICE 0xF2 13 | #define PS2_TEST_FIRST_PORT 0xAB 14 | #define PS2_TEST_SECOND_PORT 0xA9 15 | #define PS2_PORT_TEST_PASSED 0x00 16 | #define PS2_PORT_CLOCK_LINE_STUCK_LOW 0x01 17 | #define PS2_PORT_CLOCK_LINE_STUCK_HIGH 0x02 18 | #define PS2_PORT_DATA_LINE_STUCK_LOW 0x03 19 | #define PS2_PORT_DATA_LINE_STUCK_HIGH 0x04 20 | const uint16_t PS2_CONTROLLER_STATE = 0x64; 21 | const uint16_t PS2_CONTROLLER_DATA = 0x60; 22 | uint8_t PS2_PORT_COUNT = 0; 23 | void (*writestring)(const char * data); 24 | inline void PS2_CONTROLLER_BUSY(){ 25 | while(!(inportb(PS2_CONTROLLER_STATE) & 0b00000001)){ 26 | (*writestring)("."); 27 | } 28 | return; 29 | } 30 | inline uint8_t PS2_READ_FROM_OFFSET(uint8_t offset){ 31 | uint8_t result = offset + 0x21; 32 | if(result > 0x3f){ 33 | result = 0x3f; 34 | } 35 | return result; 36 | } 37 | inline uint8_t PS2_WRITE_FROM_OFFSET(uint8_t offset){ 38 | uint8_t result = offset + 0x61; 39 | if(result > 0x7f){ 40 | result = 0x7f; 41 | } 42 | } 43 | void PS2_CONTROLLER_SELF_TEST(){ 44 | //clear the buffer to prevent incorrect test data 45 | inportb(PS2_CONTROLLER_DATA); 46 | (*writestring)("Performing PS/2 controller self test"); 47 | outportb(PS2_CONTROLLER_STATE, TEST_PS2_CONTROLLER); 48 | uint8_t result = 0; 49 | PS2_CONTROLLER_BUSY(); 50 | (*writestring)("\n"); 51 | result = inportb(PS2_CONTROLLER_DATA); 52 | if(result == PS2_CONTROLLER_TEST_PASSED){ 53 | (*writestring)("The PS/2 controller appears to be working"); 54 | }else if(result == PS2_CONTROLLER_TEST_PASSED){ 55 | (*writestring)("The PS/2 controller does not appear to be working\n"); 56 | (*writestring)("Will now halt..."); 57 | hang(); 58 | }else{ 59 | (*writestring)("The PS/2 controller did not return a valid code\n"); 60 | (*writestring)("Will now halt..."); 61 | hang(); 62 | } 63 | (*writestring)("\n"); 64 | } 65 | void PS2_PORT_TEST(){ 66 | inportb(PS2_CONTROLLER_DATA); 67 | outportb(PS2_CONTROLLER_STATE, PS2_TEST_FIRST_PORT); 68 | PS2_CONTROLLER_BUSY(); 69 | uint8_t result = inportb(PS2_CONTROLLER_DATA); 70 | if(result == PS2_PORT_TEST_PASSED){ 71 | (*writestring)("The first PS/2 port appears to be working\n"); 72 | }else{ 73 | (*writestring)("ERROR: PS/2 port test failed, will halt"); 74 | hang(); 75 | } 76 | result = 0x04; 77 | if(PS2_PORT_COUNT == 2){ 78 | inportb(PS2_CONTROLLER_DATA); 79 | outportb(PS2_CONTROLLER_STATE, PS2_TEST_SECOND_PORT); 80 | PS2_CONTROLLER_BUSY(); 81 | result = inportb(PS2_CONTROLLER_DATA); 82 | if(result == PS2_PORT_TEST_PASSED){ 83 | (*writestring)("The second PS/2 port appears to be working\n"); 84 | }else{ 85 | (*writestring)("ERROR: PS/2 port test failed, will halt"); 86 | hang(); 87 | } 88 | } 89 | } 90 | void PS2_CONTROLLER_INIT(){ 91 | PS2_CONTROLLER_SELF_TEST(); 92 | outportb(PS2_CONTROLLER_STATE, PS2_READ_FROM_BYTE_0); 93 | PS2_CONTROLLER_BUSY(); 94 | uint8_t configuration_byte = inportb(PS2_CONTROLLER_DATA); 95 | if(configuration_byte & 0b00100000){ 96 | PS2_PORT_COUNT = 2; 97 | (*writestring)("There are two PS/2 ports on this machine\n"); 98 | }else{ 99 | (*writestring)("There is one PS/2 port on this machine\n"); 100 | PS2_PORT_COUNT = 1; 101 | } 102 | configuration_byte = configuration_byte & 0b10111100; 103 | outportb(PS2_CONTROLLER_STATE, PS2_WRITE_TO_BYTE_0); 104 | outportb(PS2_CONTROLLER_DATA, configuration_byte); 105 | inportb(PS2_CONTROLLER_DATA); 106 | PS2_PORT_TEST(); 107 | outportb(PS2_CONTROLLER_STATE, PS2_ENABLE_FIRST_PORT); 108 | (*writestring)("PS/2 port one (assumed keyboard) has been enabled\n"); 109 | if(PS2_PORT_COUNT == 2){ 110 | outportb(PS2_CONTROLLER_STATE, PS2_ENABLE_SECOND_PORT); 111 | (*writestring)("PS/2 port two (assumed mouse) has been enabled\n"); 112 | } 113 | outportb(PS2_CONTROLLER_DATA, 0x02); 114 | outportb(PS2_CONTROLLER_DATA, PS2_SET_SCAN_CODE_SET); 115 | } 116 | /* 117 | switch case for keyboard input, in order from most frequent characters to least frequent 118 | This is in the English language, and this order directive does not include special characters 119 | */ 120 | char PS2_KEYBOARD_CODE_HANDLER(uint8_t mode, uint8_t code){ 121 | if(mode == 0x02){ 122 | switch(code){ 123 | case 0x24: 124 | return 'e'; 125 | case 0x2C: 126 | return 't'; 127 | case 0x1C: 128 | return 'a'; 129 | case 0x44: 130 | return 'o'; 131 | case 0x43: 132 | return 'i'; 133 | case 0x31: 134 | return 'n'; 135 | case 0x1B: 136 | return 's'; 137 | case 0x33: 138 | return 'h'; 139 | case 0x2D: 140 | return 'r'; 141 | case 0x23: 142 | return 'd'; 143 | case 0x4B: 144 | return 'l'; 145 | case 0x21: 146 | return 'c'; 147 | case 0x3C: 148 | return 'u'; 149 | case 0x3A: 150 | return 'm'; 151 | case 0x1D: 152 | return 'w'; 153 | case 0x2B: 154 | return 'f'; 155 | case 0x34: 156 | return 'g'; 157 | case 0x35: 158 | return 'y'; 159 | case 0x4D: 160 | return 'p'; 161 | case 0x32: 162 | return 'b'; 163 | case 0x2A: 164 | return 'v'; 165 | case 0x42: 166 | return 'k'; 167 | case 0x3B: 168 | return 'j'; 169 | case 0x22: 170 | return 'x'; 171 | case 0x15: 172 | return 'q'; 173 | case 0x1A: 174 | return 'z'; 175 | case 0x5A: 176 | return '\n'; 177 | case 0x54: 178 | return '['; 179 | case 0x5B: 180 | return ']'; 181 | case 0x5D: 182 | return '\\'; 183 | case 0x4C: 184 | return ';'; 185 | case 0x52: 186 | return '\''; 187 | case 0x41: 188 | return ','; 189 | case 0x49: 190 | return '.'; 191 | case 0x4A: 192 | return '/'; 193 | case 0x29: 194 | return ' '; 195 | default: 196 | return 0x0; 197 | } 198 | }else{ 199 | return 0x0; 200 | } 201 | } 202 | --------------------------------------------------------------------------------