├── Bootloader
├── ExtendedOS
│ ├── img
│ │ └── MY_OS.bin
│ └── src
│ │ └── my_operating_system.asm
├── HelloWorld
│ ├── img
│ │ └── HelloWorld_OS.bin
│ └── src
│ │ └── hello_world.asm
├── HelloWorld_without_BIOS
│ ├── img
│ │ └── HelloWorld_withoutBIOS.bin
│ └── src
│ │ └── hello_world_without_bios.asm
└── Sample
│ └── set_caret_pos
│ └── set_caret_pos.asm
├── CPUInfo
├── asm
│ ├── cpuinfo.asm
│ └── cpuinfo_asm.png
└── cpu_info_c
│ ├── boot.s
│ ├── c_cpuinfo.png
│ ├── grub.cfg
│ ├── kernel.c
│ ├── kernel.h
│ ├── linker.ld
│ └── run.sh
├── GUI
├── ascii_chars
│ ├── ascii_chars_0_255.png
│ ├── boot.s
│ ├── grub.cfg
│ ├── kernel.c
│ ├── kernel.h
│ ├── linker.ld
│ ├── run.sh
│ ├── types.h
│ ├── utils.c
│ └── utils.h
├── box
│ ├── boot.s
│ ├── box_demo_kernel.png
│ ├── grub.cfg
│ ├── kernel.c
│ ├── kernel.h
│ ├── linker.ld
│ ├── run.sh
│ ├── types.h
│ ├── utils.c
│ └── utils.h
└── dosbox_gui
│ ├── boot.s
│ ├── dosbox_gui.png
│ ├── grub.cfg
│ ├── kernel.c
│ ├── kernel.h
│ ├── linker.ld
│ ├── run.sh
│ ├── types.h
│ ├── utils.c
│ └── utils.h
├── Global_Descriptor_Table
├── asm
│ └── gdt.asm
└── kernel_C
│ ├── boot.s
│ ├── gdt.c
│ ├── gdt.h
│ ├── grub.cfg
│ ├── kernel.c
│ ├── kernel.h
│ ├── linker.ld
│ ├── load_gdt.s
│ ├── run.sh
│ └── types.h
├── Graphics
└── Simple
│ ├── dda_line_draw
│ ├── img
│ │ ├── dda_line_draw.bin
│ │ └── dda_line_draw.png
│ └── src
│ │ └── dda.asm
│ ├── drawpixel
│ ├── img
│ │ ├── draw_pixel.bin
│ │ └── draw_pixels.png
│ └── src
│ │ └── drawpixel.asm
│ └── rectangle
│ ├── img
│ ├── rectangle.bin
│ └── rectangle.png
│ └── src
│ ├── Readme.txt
│ ├── dda.asm
│ ├── drawpixel.asm
│ └── rectangle.asm
├── Interrupt_Descriptor_Table
├── boot.s
├── gdt.c
├── gdt.h
├── grub.cfg
├── idt.c
├── idt.h
├── idt_demo.png
├── isr.c
├── isr.h
├── kernel.c
├── kernel.h
├── linker.ld
├── load_gdt.s
├── load_idt.s
├── run.sh
├── types.h
└── util.c
├── Kernel
├── Keyboard
│ ├── README.md
│ ├── ascii.jpg
│ ├── boot.s
│ ├── char.c
│ ├── char.h
│ ├── grub.cfg
│ ├── kernel.c
│ ├── kernel.h
│ ├── keyboard.h
│ ├── keyboard_demo.png
│ ├── keycodes.png
│ ├── linker.ld
│ ├── run.sh
│ ├── types.h
│ ├── utils.c
│ └── utils.h
├── Simple
│ ├── img
│ │ ├── kernel_1
│ │ │ └── MyOS.iso
│ │ └── kernel_2
│ │ │ └── MyOS.iso
│ └── src
│ │ ├── kernel_1
│ │ ├── boot.s
│ │ ├── grub.cfg
│ │ ├── kernel.c
│ │ ├── kernel.h
│ │ ├── linker.ld
│ │ └── run.sh
│ │ └── kernel_2
│ │ ├── boot.s
│ │ ├── grub.cfg
│ │ ├── kernel.c
│ │ ├── kernel.h
│ │ ├── linker.ld
│ │ └── run.sh
└── util.h
├── Pong-Game
├── bitmap.c
├── bitmap.h
├── boot.s
├── clean.sh
├── game_screenshots
│ ├── Pong_Game_Intro.png
│ ├── Pong_Game_Lose.png
│ └── Pong_Game_Play.png
├── grub.cfg
├── kernel.c
├── kernel.h
├── keyboard.h
├── linker.ld
├── pong.c
├── pong.h
├── run.sh
├── types.h
├── utils.c
├── utils.h
├── vga.c
└── vga.h
├── README.md
├── Tic-Tac-Toe
├── img
│ └── TicTacToe.iso
├── src
│ ├── boot.s
│ ├── box.c
│ ├── box.h
│ ├── grub.cfg
│ ├── kernel.c
│ ├── kernel.h
│ ├── keyboard.h
│ ├── linker.ld
│ ├── run.sh
│ ├── tic_tac_toe.c
│ ├── tic_tac_toe.h
│ ├── types.h
│ ├── utils.c
│ └── utils.h
└── tic_tac_toe.png
├── VGA
├── asm
│ ├── color_change.asm
│ ├── rotate_text.asm
│ └── vga_hello.asm
└── kernel_c
│ ├── Bitmap_Text
│ ├── bitmap.c
│ ├── bitmap.h
│ ├── boot.s
│ ├── grub.cfg
│ ├── kernel.c
│ ├── kernel.h
│ ├── keyboard.h
│ ├── linker.ld
│ ├── run.sh
│ ├── types.h
│ ├── vga.c
│ └── vga.h
│ ├── Bounce Rect
│ ├── boot.s
│ ├── grub.cfg
│ ├── kernel.c
│ ├── kernel.h
│ ├── keyboard.h
│ ├── linker.ld
│ ├── run.sh
│ ├── types.h
│ ├── vga.c
│ └── vga.h
│ ├── Reference
│ └── Intel OpenSource HD Graphics.pdf
│ ├── Simple
│ ├── boot.s
│ ├── grub.cfg
│ ├── kernel.c
│ ├── kernel.h
│ ├── linker.ld
│ └── run.sh
│ └── kernel_vga_output.png
└── x86 Calculator
├── README.md
├── asm
├── img
│ └── x86calc.bin
├── src
│ └── calc_x86.asm
└── x86calc_screenshot.png
└── kernel_c
├── img
└── x86_Calculator.iso
├── src
├── boot.s
├── char.c
├── char.h
├── grub.cfg
├── kernel.c
├── kernel.h
├── keyboard.h
├── linker.ld
├── run.sh
├── types.h
├── utils.c
└── utils.h
└── x86calculator_output.png
/Bootloader/ExtendedOS/img/MY_OS.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/Bootloader/ExtendedOS/img/MY_OS.bin
--------------------------------------------------------------------------------
/Bootloader/HelloWorld/img/HelloWorld_OS.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/Bootloader/HelloWorld/img/HelloWorld_OS.bin
--------------------------------------------------------------------------------
/Bootloader/HelloWorld/src/hello_world.asm:
--------------------------------------------------------------------------------
1 | [bits 16] ; tell assembler that working in real mode(16 bit mode)
2 | [org 0x7c00] ; organize from 0x7C00 memory location where BIOS will load us
3 |
4 |
5 | start: ; start label from where our code starts
6 |
7 |
8 | xor ax,ax ; set ax register to 0
9 | mov ds,ax ; set data segment(ds) to 0
10 | mov es,ax ; set extra segment(es) to 0
11 | mov bx,0x8000
12 |
13 |
14 | mov si, hello_world ; point hello_world to source index
15 | call print_string ; call print different color string function
16 |
17 |
18 |
19 | hello_world db 'Hello World!',13,0
20 |
21 |
22 | print_string:
23 | mov ah, 0x0E ; value to tell interrupt handler that take value from al & print it
24 |
25 | .repeat_next_char:
26 | lodsb ; get character from string
27 | cmp al, 0 ; cmp al with end of string
28 | je .done_print ; if char is zero, end of string
29 | int 0x10 ; otherwise, print it
30 | jmp .repeat_next_char ; jmp to .repeat_next_char if not 0
31 |
32 | .done_print:
33 | ret ;return
34 |
35 | times (510 - ($ - $$)) db 0x00 ;set 512 bytes for boot sector which are necessary
36 | dw 0xAA55 ; boot signature 0xAA & 0x55
37 |
38 |
39 |
--------------------------------------------------------------------------------
/Bootloader/HelloWorld_without_BIOS/img/HelloWorld_withoutBIOS.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/Bootloader/HelloWorld_without_BIOS/img/HelloWorld_withoutBIOS.bin
--------------------------------------------------------------------------------
/Bootloader/HelloWorld_without_BIOS/src/hello_world_without_bios.asm:
--------------------------------------------------------------------------------
1 | [bits 16] ; tell assembler that working in real mode(16 bit mode)
2 | [org 0x7c00] ; organize from 0x7C00 memory location where BIOS will load us
3 |
4 |
5 | start: ; start label from where our code starts
6 |
7 |
8 | xor ax,ax ; set ax register to 0
9 | mov ds,ax ; set data segment(ds) to 0
10 | mov es,ax ; set extra segment(es) to 0
11 | mov bx,0x8000
12 |
13 | ; get vga memory address and point set es to it
14 | mov dx, [VGA_MEM]
15 | mov es, dx
16 |
17 | call clear_screen
18 |
19 | mov si, hello_world
20 | call print_string
21 |
22 | ret
23 |
24 | print_string:
25 |
26 | .repeat_next_char:
27 | lodsb ; get character from string into al
28 | cmp al, 0 ; cmp al with end of string
29 | je .done_print ; if char is zero, end of string
30 |
31 | mov di, word[VGA_INDEX] ; otherwise, print it
32 | mov [es:di], al
33 | add word[VGA_INDEX], 2 ; increase VGA_INDEX by 2(for more see kernel code in C)
34 |
35 | jmp .repeat_next_char ; jmp to .repeat_next_char if not 0
36 |
37 | .done_print:
38 | ret
39 |
40 | ; clear screen just displays null characters
41 | clear_screen:
42 | ;set index to 0
43 | mov di, 0
44 |
45 | .clrloop:
46 | cmp di, word[MAX_VGA_INDEX]
47 | je .exit
48 |
49 | ; get null character into al
50 | mov al, 0
51 |
52 | ; put value of al into vga memory address
53 | mov [es:di], al
54 |
55 | ; increase di by 2 (2 bytes)
56 | add di, 2
57 | jmp .clrloop
58 |
59 | .exit:
60 | ret
61 |
62 | ;*********************************************
63 | ; declare data (for more see kernel code in C)
64 | VGA_MEM dw 0xB800
65 | MAX_VGA_INDEX dw 0xF9E ; 3998 in decimal
66 | VGA_INDEX dw 0x00
67 |
68 | hello_world db 'Hello World!',0
69 | ;*********************************************
70 |
71 |
72 | times (510 - ($ - $$)) db 0x00 ;set 512 bytes for boot sector which are necessary
73 | dw 0xAA55 ; boot signature 0xAA & 0x55
74 |
75 |
--------------------------------------------------------------------------------
/Bootloader/Sample/set_caret_pos/set_caret_pos.asm:
--------------------------------------------------------------------------------
1 | [bits 16]
2 | [org 0x7c00]
3 |
4 | _start:
5 |
6 | xor ax,ax
7 | mov ds,ax
8 | mov es,ax
9 | mov bx,0x8000
10 |
11 | mov al, 2 ; set font size, 1 or 0(big), 2(normal)
12 | mov ah, 0 ; clear the screen
13 | int 0x10 ; call video interrupt
14 |
15 |
16 | ;*********************************************************************
17 |
18 | ;set cursor to specific position on center of screen
19 | mov ah, 0x02 ; set register ah value to trigger BIOS for changing position,
20 | mov bh, 0x00
21 | ;(al already has 2 for font size(line 11))
22 | mov dl, 0x22 ; x co-ordinate
23 | mov dh, 0x0A ; y co-ordinate
24 | int 0x10
25 |
26 | mov si, str_demo
27 | call print_string
28 |
29 | ;*********************************************************************
30 |
31 |
32 | hlt
33 |
34 | str_demo db 'Hello World', 0
35 |
36 | print_string:
37 | mov ah, 0x0E ; value to tell interrupt handler that take value from al & print it
38 |
39 | .repeat_next_char:
40 | lodsb ; get character from string
41 | cmp al, 0 ; cmp al with end of string
42 | je .exit ; if char is zero, end of string
43 | int 0x10 ; otherwise, print it
44 | jmp .repeat_next_char ; jmp to .repeat_next_char if not 0
45 |
46 | .exit:
47 | ret
48 |
49 |
50 | ;**************************************************************
51 | ; boot loader magic number
52 | times (510 - ($ - $$)) db 0x00 ;set 512 bytes for boot sector which are necessary
53 | dw 0xAA55 ; boot signature 0xAA & 0x55
54 |
55 |
56 |
--------------------------------------------------------------------------------
/CPUInfo/asm/cpuinfo_asm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/CPUInfo/asm/cpuinfo_asm.png
--------------------------------------------------------------------------------
/CPUInfo/cpu_info_c/boot.s:
--------------------------------------------------------------------------------
1 | # set magic number to 0x1BADB002 to identified by bootloader
2 | .set MAGIC, 0x1BADB002
3 |
4 | # set flags to 0
5 | .set FLAGS, 0
6 |
7 | # set the checksum
8 | .set CHECKSUM, -(MAGIC + FLAGS)
9 |
10 | # set multiboot enabled
11 | .section .multiboot
12 |
13 | # define type to long for each data defined as above
14 | .long MAGIC
15 | .long FLAGS
16 | .long CHECKSUM
17 |
18 |
19 | # set the stack bottom
20 | stackBottom:
21 |
22 | # define the maximum size of stack to 1024 bytes
23 | .skip 1024
24 |
25 |
26 | # set the stack top which grows from higher to lower
27 | stackTop:
28 |
29 | .section .text
30 | .global _start
31 | .type _start, @function
32 |
33 |
34 | _start:
35 |
36 | # assign current stack pointer location to stackTop
37 | mov $stackTop, %esp
38 |
39 | # call the kernel main source
40 | call kernel_entry
41 |
42 | cli
43 |
44 |
45 | # put system in infinite loop
46 | hltLoop:
47 |
48 | hlt
49 | jmp hltLoop
50 |
51 | .size _start, . - _start
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/CPUInfo/cpu_info_c/c_cpuinfo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/CPUInfo/cpu_info_c/c_cpuinfo.png
--------------------------------------------------------------------------------
/CPUInfo/cpu_info_c/grub.cfg:
--------------------------------------------------------------------------------
1 | menuentry "MyOS" {
2 | multiboot /boot/MyOS.bin
3 | }
4 |
--------------------------------------------------------------------------------
/CPUInfo/cpu_info_c/kernel.h:
--------------------------------------------------------------------------------
1 | #ifndef KERNEL_H
2 | #define KERNEL_H
3 |
4 | typedef unsigned char uint8;
5 | typedef unsigned short uint16;
6 | typedef unsigned int uint32;
7 |
8 |
9 | #define VGA_ADDRESS 0xB8000
10 | #define BUFSIZE 2200
11 |
12 | uint16* vga_buffer;
13 |
14 | #define NULL 0
15 |
16 | enum vga_color {
17 | BLACK,
18 | BLUE,
19 | GREEN,
20 | CYAN,
21 | RED,
22 | MAGENTA,
23 | BROWN,
24 | GREY,
25 | DARK_GREY,
26 | BRIGHT_BLUE,
27 | BRIGHT_GREEN,
28 | BRIGHT_CYAN,
29 | BRIGHT_RED,
30 | BRIGHT_MAGENTA,
31 | YELLOW,
32 | WHITE,
33 | };
34 |
35 | #endif
36 |
--------------------------------------------------------------------------------
/CPUInfo/cpu_info_c/linker.ld:
--------------------------------------------------------------------------------
1 | /* entry point of our kernel */
2 | ENTRY(_start)
3 |
4 | SECTIONS
5 | {
6 | /* we need 1MB of space atleast */
7 | . = 1M;
8 |
9 | /* text section */
10 | .text BLOCK(4K) : ALIGN(4K)
11 | {
12 | *(.multiboot)
13 | *(.text)
14 | }
15 |
16 | /* read only data section */
17 | .rodata BLOCK(4K) : ALIGN(4K)
18 | {
19 | *(.rodata)
20 | }
21 |
22 | /* data section */
23 | .data BLOCK(4K) : ALIGN(4K)
24 | {
25 | *(.data)
26 | }
27 |
28 | /* bss section */
29 | .bss BLOCK(4K) : ALIGN(4K)
30 | {
31 | *(COMMON)
32 | *(.bss)
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/CPUInfo/cpu_info_c/run.sh:
--------------------------------------------------------------------------------
1 | #assemble boot.s file
2 | as --32 boot.s -o boot.o
3 |
4 | #compile kernel.c file
5 | gcc -m32 -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
6 |
7 | #linking the kernel with kernel.o and boot.o files
8 | ld -m elf_i386 -T linker.ld kernel.o boot.o -o MyOS.bin -nostdlib
9 |
10 | #check MyOS.bin file is x86 multiboot file or not
11 | grub-file --is-x86-multiboot MyOS.bin
12 |
13 | #building the iso file
14 | mkdir -p isodir/boot/grub
15 | cp MyOS.bin isodir/boot/MyOS.bin
16 | cp grub.cfg isodir/boot/grub/grub.cfg
17 | grub-mkrescue -o MyOS.iso isodir
18 |
19 | #run it in qemu
20 | qemu-system-x86_64 -cdrom MyOS.iso
21 |
--------------------------------------------------------------------------------
/GUI/ascii_chars/ascii_chars_0_255.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/GUI/ascii_chars/ascii_chars_0_255.png
--------------------------------------------------------------------------------
/GUI/ascii_chars/boot.s:
--------------------------------------------------------------------------------
1 | # set flags to 0
2 | .set FLAGS, 0
3 |
4 | # set magic number to 0x1BADB002 to identified by bootloader
5 | .set MAGIC, 0x1BADB002
6 |
7 | # set the checksum
8 | .set CHECKSUM, -(MAGIC + FLAGS)
9 |
10 | # set multiboot enabled
11 | .section .multiboot
12 |
13 | # define type to long for each data defined as above
14 | .long MAGIC
15 | .long FLAGS
16 | .long CHECKSUM
17 |
18 |
19 | # set the stack bottom
20 | stackBottom:
21 |
22 | # define the maximum size of stack to 512 bytes
23 | .skip 4096
24 |
25 |
26 | # set the stack top which grows from higher to lower
27 | stackTop:
28 |
29 | .section .text
30 | .global _start
31 | .type _start, @function
32 |
33 |
34 | _start:
35 |
36 |
37 | # assign current stack pointer location to stackTop
38 | mov $stackTop, %esp
39 |
40 | # call the kernel main function
41 | call kernel_entry
42 |
43 | cli
44 |
45 |
46 | # put system in infinite loop
47 | hltLoop:
48 |
49 | hlt
50 | jmp hltLoop
51 |
52 | .size _start, . - _start
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/GUI/ascii_chars/grub.cfg:
--------------------------------------------------------------------------------
1 | menuentry "MyOS" {
2 | multiboot /boot/MyOS.bin
3 | }
4 |
--------------------------------------------------------------------------------
/GUI/ascii_chars/kernel.c:
--------------------------------------------------------------------------------
1 | #include "kernel.h"
2 | #include "utils.h"
3 |
4 | uint32 vga_index;
5 | static uint32 next_line_index = 1;
6 | uint8 g_fore_color = WHITE, g_back_color = BLUE;
7 | int digit_ascii_codes[10] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
8 |
9 | /*
10 | this is same as we did in our assembly code for vga_print_char
11 |
12 | vga_print_char:
13 | mov di, word[VGA_INDEX]
14 | mov al, byte[VGA_CHAR]
15 |
16 | mov ah, byte[VGA_BACK_COLOR]
17 | sal ah, 4
18 | or ah, byte[VGA_FORE_COLOR]
19 |
20 | mov [es:di], ax
21 |
22 | ret
23 |
24 | */
25 | uint16 vga_entry(unsigned char ch, uint8 fore_color, uint8 back_color)
26 | {
27 | uint16 ax = 0;
28 | uint8 ah = 0, al = 0;
29 |
30 | ah = back_color;
31 | ah <<= 4;
32 | ah |= fore_color;
33 | ax = ah;
34 | ax <<= 8;
35 | al = ch;
36 | ax |= al;
37 |
38 | return ax;
39 | }
40 |
41 | void clear_vga_buffer(uint16 **buffer, uint8 fore_color, uint8 back_color)
42 | {
43 | uint32 i;
44 | for(i = 0; i < BUFSIZE; i++){
45 | (*buffer)[i] = vga_entry(NULL, fore_color, back_color);
46 | }
47 | next_line_index = 1;
48 | vga_index = 0;
49 | }
50 |
51 | void init_vga(uint8 fore_color, uint8 back_color)
52 | {
53 | vga_buffer = (uint16*)VGA_ADDRESS;
54 | clear_vga_buffer(&vga_buffer, fore_color, back_color);
55 | g_fore_color = fore_color;
56 | g_back_color = back_color;
57 | }
58 |
59 | void print_new_line()
60 | {
61 | if(next_line_index >= 55){
62 | next_line_index = 0;
63 | clear_vga_buffer(&vga_buffer, g_fore_color, g_back_color);
64 | }
65 | vga_index = 80*next_line_index;
66 | next_line_index++;
67 | }
68 |
69 | void print_char(char ch)
70 | {
71 | vga_buffer[vga_index] = vga_entry(ch, g_fore_color, g_back_color);
72 | vga_index++;
73 | }
74 |
75 | void print_string(char *str)
76 | {
77 | uint32 index = 0;
78 | while(str[index]){
79 | print_char(str[index]);
80 | index++;
81 | }
82 | }
83 |
84 | void print_int(int num)
85 | {
86 | char str_num[digit_count(num)+1];
87 | itoa(num, str_num);
88 | print_string(str_num);
89 | }
90 |
91 | void print_ascii_chars(uint8 fore_color, uint8 back_color)
92 | {
93 | uint32 i;
94 | uint16 ax = 0;
95 | uint8 ah = 0;
96 |
97 | for(i = 1; i < 254;i++){
98 | ax = 0;
99 | ah = back_color;
100 | ah <<= 4;
101 | ah |= fore_color;
102 | ax = ah;
103 | ax <<= 8;
104 | ax |= i;
105 |
106 | print_int(i);
107 | print_char(' ');
108 | print_char(ax);
109 | print_char(' ');
110 | }
111 | }
112 |
113 | void kernel_entry()
114 | {
115 | init_vga(WHITE, BLACK);
116 | print_ascii_chars(WHITE, BLACK);
117 | }
118 |
119 |
--------------------------------------------------------------------------------
/GUI/ascii_chars/kernel.h:
--------------------------------------------------------------------------------
1 | #ifndef KERNEL_H
2 | #define KERNEL_H
3 |
4 | #include "types.h"
5 |
6 | #define NULL 0
7 |
8 | #define VGA_ADDRESS 0xB8000
9 | #define BUFSIZE 2200
10 |
11 | uint16* vga_buffer;
12 |
13 | enum vga_color {
14 | BLACK,
15 | BLUE,
16 | GREEN,
17 | CYAN,
18 | RED,
19 | MAGENTA,
20 | BROWN,
21 | GREY,
22 | DARK_GREY,
23 | BRIGHT_BLUE,
24 | BRIGHT_GREEN,
25 | BRIGHT_CYAN,
26 | BRIGHT_RED,
27 | BRIGHT_MAGENTA,
28 | YELLOW,
29 | WHITE,
30 | };
31 |
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/GUI/ascii_chars/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 | }
40 |
41 | /* The compiler may produce other sections, by default it will put them in
42 | a segment with the same name. Simply add stuff here as needed. */
43 | }
44 |
--------------------------------------------------------------------------------
/GUI/ascii_chars/run.sh:
--------------------------------------------------------------------------------
1 | #assemble boot.s file
2 | as --32 boot.s -o boot.o
3 |
4 | #compile kernel.c file
5 | gcc -m32 -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
6 |
7 | gcc -m32 -c utils.c -o utils.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
8 |
9 | #linking the kernel with kernel.o and boot.o files
10 | ld -m elf_i386 -T linker.ld kernel.o utils.o boot.o -o MyOS.bin -nostdlib
11 |
12 | #check MyOS.bin file is x86 multiboot file or not
13 | grub-file --is-x86-multiboot MyOS.bin
14 |
15 | #building the iso file
16 | mkdir -p isodir/boot/grub
17 | cp MyOS.bin isodir/boot/MyOS.bin
18 | cp grub.cfg isodir/boot/grub/grub.cfg
19 | grub-mkrescue -o MyOS.iso isodir
20 |
21 | #run it in qemu
22 | qemu-system-x86_64 -cdrom MyOS.iso
23 |
--------------------------------------------------------------------------------
/GUI/ascii_chars/types.h:
--------------------------------------------------------------------------------
1 | #ifndef TYPES_H
2 | #define TYPES_H
3 |
4 | typedef unsigned char uint8;
5 | typedef unsigned short uint16;
6 | typedef unsigned int uint32;
7 |
8 | #endif
9 |
10 |
11 |
--------------------------------------------------------------------------------
/GUI/ascii_chars/utils.c:
--------------------------------------------------------------------------------
1 | #include "utils.h"
2 |
3 | uint32 strlen(const char* str)
4 | {
5 | uint32 length = 0;
6 | while(str[length])
7 | length++;
8 | return length;
9 | }
10 |
11 | uint32 digit_count(int num)
12 | {
13 | uint32 count = 0;
14 | if(num == 0)
15 | return 1;
16 | while(num > 0){
17 | count++;
18 | num = num/10;
19 | }
20 | return count;
21 | }
22 |
23 | void itoa(int num, char *number)
24 | {
25 | int dgcount = digit_count(num);
26 | int index = dgcount - 1;
27 | char x;
28 | if(num == 0 && dgcount == 1){
29 | number[0] = '0';
30 | number[1] = '\0';
31 | }else{
32 | while(num != 0){
33 | x = num % 10;
34 | number[index] = x + '0';
35 | index--;
36 | num = num / 10;
37 | }
38 | number[dgcount] = '\0';
39 | }
40 | }
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/GUI/ascii_chars/utils.h:
--------------------------------------------------------------------------------
1 | #ifndef UTILS_H
2 | #define UTILS_H
3 |
4 | #include "types.h"
5 |
6 | extern uint32 strlen(const char*);
7 | extern uint32 digit_count(int);
8 | extern void itoa(int, char *);
9 |
10 | #endif
11 |
12 |
--------------------------------------------------------------------------------
/GUI/box/boot.s:
--------------------------------------------------------------------------------
1 | # set flags to 0
2 | .set FLAGS, 0
3 |
4 | # set magic number to 0x1BADB002 to identified by bootloader
5 | .set MAGIC, 0x1BADB002
6 |
7 | # set the checksum
8 | .set CHECKSUM, -(MAGIC + FLAGS)
9 |
10 | # set multiboot enabled
11 | .section .multiboot
12 |
13 | # define type to long for each data defined as above
14 | .long MAGIC
15 | .long FLAGS
16 | .long CHECKSUM
17 |
18 |
19 | # set the stack bottom
20 | stackBottom:
21 |
22 | # define the maximum size of stack to 512 bytes
23 | .skip 4096
24 |
25 |
26 | # set the stack top which grows from higher to lower
27 | stackTop:
28 |
29 | .section .text
30 | .global _start
31 | .type _start, @function
32 |
33 |
34 | _start:
35 |
36 |
37 | # assign current stack pointer location to stackTop
38 | mov $stackTop, %esp
39 |
40 | # call the kernel main function
41 | call kernel_entry
42 |
43 | cli
44 |
45 |
46 | # put system in infinite loop
47 | hltLoop:
48 |
49 | hlt
50 | jmp hltLoop
51 |
52 | .size _start, . - _start
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/GUI/box/box_demo_kernel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/GUI/box/box_demo_kernel.png
--------------------------------------------------------------------------------
/GUI/box/grub.cfg:
--------------------------------------------------------------------------------
1 | menuentry "MyOS" {
2 | multiboot /boot/MyOS.bin
3 | }
4 |
--------------------------------------------------------------------------------
/GUI/box/kernel.c:
--------------------------------------------------------------------------------
1 | #include "kernel.h"
2 | #include "utils.h"
3 |
4 | uint32 vga_index;
5 | static uint32 next_line_index = 1;
6 | uint8 g_fore_color = WHITE, g_back_color = BLUE;
7 | int digit_ascii_codes[10] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
8 |
9 | uint16 vga_entry(unsigned char ch, uint8 fore_color, uint8 back_color)
10 | {
11 | uint16 ax = 0;
12 | uint8 ah = 0, al = 0;
13 |
14 | ah = back_color;
15 | ah <<= 4;
16 | ah |= fore_color;
17 | ax = ah;
18 | ax <<= 8;
19 | al = ch;
20 | ax |= al;
21 |
22 | return ax;
23 | }
24 |
25 | void clear_vga_buffer(uint16 **buffer, uint8 fore_color, uint8 back_color)
26 | {
27 | uint32 i;
28 | for(i = 0; i < BUFSIZE; i++){
29 | (*buffer)[i] = vga_entry(NULL, fore_color, back_color);
30 | }
31 | next_line_index = 1;
32 | vga_index = 0;
33 | }
34 |
35 | void init_vga(uint8 fore_color, uint8 back_color)
36 | {
37 | vga_buffer = (uint16*)VGA_ADDRESS;
38 | clear_vga_buffer(&vga_buffer, fore_color, back_color);
39 | g_fore_color = fore_color;
40 | g_back_color = back_color;
41 | }
42 |
43 | void print_new_line()
44 | {
45 | if(next_line_index >= 55){
46 | next_line_index = 0;
47 | clear_vga_buffer(&vga_buffer, g_fore_color, g_back_color);
48 | }
49 | vga_index = 80*next_line_index;
50 | next_line_index++;
51 | }
52 |
53 | void print_char(char ch)
54 | {
55 | vga_buffer[vga_index] = vga_entry(ch, g_fore_color, g_back_color);
56 | vga_index++;
57 | }
58 |
59 | void print_string(char *str)
60 | {
61 | uint32 index = 0;
62 | while(str[index]){
63 | print_char(str[index]);
64 | index++;
65 | }
66 | }
67 |
68 | void print_color_string(char *str, uint8 fore_color, uint8 back_color)
69 | {
70 | uint32 index = 0;
71 | uint8 fc, bc;
72 | fc = g_fore_color;
73 | bc = g_back_color;
74 | g_fore_color = fore_color;
75 | g_back_color = back_color;
76 | while(str[index]){
77 | print_char(str[index]);
78 | index++;
79 | }
80 | g_fore_color = fc;
81 | g_back_color = bc;
82 | }
83 |
84 | void print_int(int num)
85 | {
86 | char str_num[digit_count(num)+1];
87 | itoa(num, str_num);
88 | print_string(str_num);
89 | }
90 |
91 | uint16 get_box_draw_char(uint8 chn, uint8 fore_color, uint8 back_color)
92 | {
93 | uint16 ax = 0;
94 | uint8 ah = 0;
95 |
96 | ah = back_color;
97 | ah <<= 4;
98 | ah |= fore_color;
99 | ax = ah;
100 | ax <<= 8;
101 | ax |= chn;
102 |
103 | return ax;
104 | }
105 |
106 | void gotoxy(uint16 x, uint16 y)
107 | {
108 | vga_index = 80*y;
109 | vga_index += x;
110 | }
111 |
112 | void draw_generic_box(uint16 x, uint16 y,
113 | uint16 width, uint16 height,
114 | uint8 fore_color, uint8 back_color,
115 | uint8 topleft_ch,
116 | uint8 topbottom_ch,
117 | uint8 topright_ch,
118 | uint8 leftrightside_ch,
119 | uint8 bottomleft_ch,
120 | uint8 bottomright_ch)
121 | {
122 | uint32 i;
123 |
124 | //increase vga_index to x & y location
125 | vga_index = 80*y;
126 | vga_index += x;
127 |
128 | //draw top-left box character
129 | vga_buffer[vga_index] = get_box_draw_char(topleft_ch, fore_color, back_color);
130 |
131 | vga_index++;
132 | //draw box top characters, -
133 | for(i = 0; i < width; i++){
134 | vga_buffer[vga_index] = get_box_draw_char(topbottom_ch, fore_color, back_color);
135 | vga_index++;
136 | }
137 |
138 | //draw top-right box character
139 | vga_buffer[vga_index] = get_box_draw_char(topright_ch, fore_color, back_color);
140 |
141 | // increase y, for drawing next line
142 | y++;
143 | // goto next line
144 | vga_index = 80*y;
145 | vga_index += x;
146 |
147 | //draw left and right sides of box
148 | for(i = 0; i < height; i++){
149 | //draw left side character
150 | vga_buffer[vga_index] = get_box_draw_char(leftrightside_ch, fore_color, back_color);
151 | vga_index++;
152 | //increase vga_index to the width of box
153 | vga_index += width;
154 | //draw right side character
155 | vga_buffer[vga_index] = get_box_draw_char(leftrightside_ch, fore_color, back_color);
156 | //goto next line
157 | y++;
158 | vga_index = 80*y;
159 | vga_index += x;
160 | }
161 | //draw bottom-left box character
162 | vga_buffer[vga_index] = get_box_draw_char(bottomleft_ch, fore_color, back_color);
163 | vga_index++;
164 | //draw box bottom characters, -
165 | for(i = 0; i < width; i++){
166 | vga_buffer[vga_index] = get_box_draw_char(topbottom_ch, fore_color, back_color);
167 | vga_index++;
168 | }
169 | //draw bottom-right box character
170 | vga_buffer[vga_index] = get_box_draw_char(bottomright_ch, fore_color, back_color);
171 |
172 | vga_index = 0;
173 | }
174 |
175 | void draw_box(uint8 boxtype,
176 | uint16 x, uint16 y,
177 | uint16 width, uint16 height,
178 | uint8 fore_color, uint8 back_color)
179 | {
180 | switch(boxtype){
181 | case BOX_SINGLELINE :
182 | draw_generic_box(x, y, width, height,
183 | fore_color, back_color,
184 | 218, 196, 191, 179, 192, 217);
185 | break;
186 |
187 | case BOX_DOUBLELINE :
188 | draw_generic_box(x, y, width, height,
189 | fore_color, back_color,
190 | 201, 205, 187, 186, 200, 188);
191 | break;
192 | }
193 | }
194 |
195 | void fill_box(uint8 ch, uint16 x, uint16 y, uint16 width, uint16 height, uint8 color)
196 | {
197 | uint32 i,j;
198 |
199 | for(i = 0; i < height; i++){
200 | //increase vga_index to x & y location
201 | vga_index = 80*y;
202 | vga_index += x;
203 |
204 | for(j = 0; j < width; j++){
205 | vga_buffer[vga_index] = get_box_draw_char(ch, 0, color);
206 | vga_index++;
207 | }
208 | y++;
209 | }
210 | }
211 |
212 |
213 | void kernel_entry()
214 | {
215 | const char*str = "Box Demo";
216 |
217 | init_vga(WHITE, BLACK);
218 |
219 | gotoxy((VGA_MAX_WIDTH/2)-strlen(str), 1);
220 | print_color_string("Box Demo", WHITE, BLACK);
221 |
222 | draw_box(BOX_DOUBLELINE, 0, 0, BOX_MAX_WIDTH, BOX_MAX_HEIGHT, BRIGHT_GREEN, BLACK);
223 |
224 | draw_box(BOX_SINGLELINE, 5, 3, 20, 5, YELLOW, BLACK);
225 | gotoxy(10, 6);
226 | print_color_string("Hello World", BRIGHT_RED, BLACK);
227 |
228 | // NULL for only to fill colors, or provide any other character
229 | fill_box(NULL, 36, 5, 30, 10, RED);
230 |
231 | fill_box(1, 6, 16, 30, 4, GREEN);
232 | draw_box(BOX_DOUBLELINE, 6, 16, 28, 3, BLUE, GREEN);
233 |
234 | }
235 |
236 |
--------------------------------------------------------------------------------
/GUI/box/kernel.h:
--------------------------------------------------------------------------------
1 | #ifndef KERNEL_H
2 | #define KERNEL_H
3 |
4 | #include "types.h"
5 |
6 | #define NULL 0
7 |
8 | #define VGA_ADDRESS 0xB8000
9 | #define BUFSIZE 2200
10 |
11 | uint16* vga_buffer;
12 |
13 | #define VGA_MAX_WIDTH 80
14 | #define VGA_MAX_HEIGHT 25
15 |
16 | #define BOX_MAX_WIDTH 78
17 | #define BOX_MAX_HEIGHT 23
18 |
19 | #define BOX_SINGLELINE 1
20 | #define BOX_DOUBLELINE 2
21 |
22 | enum vga_color {
23 | BLACK,
24 | BLUE,
25 | GREEN,
26 | CYAN,
27 | RED,
28 | MAGENTA,
29 | BROWN,
30 | GREY,
31 | DARK_GREY,
32 | BRIGHT_BLUE,
33 | BRIGHT_GREEN,
34 | BRIGHT_CYAN,
35 | BRIGHT_RED,
36 | BRIGHT_MAGENTA,
37 | YELLOW,
38 | WHITE,
39 | };
40 |
41 |
42 | #endif
43 |
--------------------------------------------------------------------------------
/GUI/box/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 | }
40 |
41 | /* The compiler may produce other sections, by default it will put them in
42 | a segment with the same name. Simply add stuff here as needed. */
43 | }
44 |
--------------------------------------------------------------------------------
/GUI/box/run.sh:
--------------------------------------------------------------------------------
1 | #assemble boot.s file
2 | as --32 boot.s -o boot.o
3 |
4 | #compile kernel.c file
5 | gcc -m32 -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
6 |
7 | gcc -m32 -c utils.c -o utils.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
8 |
9 | #linking the kernel with kernel.o and boot.o files
10 | ld -m elf_i386 -T linker.ld kernel.o utils.o boot.o -o MyOS.bin -nostdlib
11 |
12 | #check MyOS.bin file is x86 multiboot file or not
13 | grub-file --is-x86-multiboot MyOS.bin
14 |
15 | #building the iso file
16 | mkdir -p isodir/boot/grub
17 | cp MyOS.bin isodir/boot/MyOS.bin
18 | cp grub.cfg isodir/boot/grub/grub.cfg
19 | grub-mkrescue -o MyOS.iso isodir
20 |
21 | #run it in qemu
22 | qemu-system-x86_64 -cdrom MyOS.iso
23 |
--------------------------------------------------------------------------------
/GUI/box/types.h:
--------------------------------------------------------------------------------
1 | #ifndef TYPES_H
2 | #define TYPES_H
3 |
4 | typedef unsigned char uint8;
5 | typedef unsigned short uint16;
6 | typedef unsigned int uint32;
7 |
8 | #endif
9 |
10 |
11 |
--------------------------------------------------------------------------------
/GUI/box/utils.c:
--------------------------------------------------------------------------------
1 | #include "utils.h"
2 |
3 | uint32 strlen(const char* str)
4 | {
5 | uint32 length = 0;
6 | while(str[length])
7 | length++;
8 | return length;
9 | }
10 |
11 | uint32 digit_count(int num)
12 | {
13 | uint32 count = 0;
14 | if(num == 0)
15 | return 1;
16 | while(num > 0){
17 | count++;
18 | num = num/10;
19 | }
20 | return count;
21 | }
22 |
23 | void itoa(int num, char *number)
24 | {
25 | int dgcount = digit_count(num);
26 | int index = dgcount - 1;
27 | char x;
28 | if(num == 0 && dgcount == 1){
29 | number[0] = '0';
30 | number[1] = '\0';
31 | }else{
32 | while(num != 0){
33 | x = num % 10;
34 | number[index] = x + '0';
35 | index--;
36 | num = num / 10;
37 | }
38 | number[dgcount] = '\0';
39 | }
40 | }
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/GUI/box/utils.h:
--------------------------------------------------------------------------------
1 | #ifndef UTILS_H
2 | #define UTILS_H
3 |
4 | #include "types.h"
5 |
6 | extern uint32 strlen(const char*);
7 | extern uint32 digit_count(int);
8 | extern void itoa(int, char *);
9 |
10 | #endif
11 |
12 |
--------------------------------------------------------------------------------
/GUI/dosbox_gui/boot.s:
--------------------------------------------------------------------------------
1 | # set flags to 0
2 | .set FLAGS, 0
3 |
4 | # set magic number to 0x1BADB002 to identified by bootloader
5 | .set MAGIC, 0x1BADB002
6 |
7 | # set the checksum
8 | .set CHECKSUM, -(MAGIC + FLAGS)
9 |
10 | # set multiboot enabled
11 | .section .multiboot
12 |
13 | # define type to long for each data defined as above
14 | .long MAGIC
15 | .long FLAGS
16 | .long CHECKSUM
17 |
18 |
19 | # set the stack bottom
20 | stackBottom:
21 |
22 | # define the maximum size of stack to 512 bytes
23 | .skip 4096
24 |
25 |
26 | # set the stack top which grows from higher to lower
27 | stackTop:
28 |
29 | .section .text
30 | .global _start
31 | .type _start, @function
32 |
33 |
34 | _start:
35 |
36 |
37 | # assign current stack pointer location to stackTop
38 | mov $stackTop, %esp
39 |
40 | # call the kernel main function
41 | call kernel_entry
42 |
43 | cli
44 |
45 |
46 | # put system in infinite loop
47 | hltLoop:
48 |
49 | hlt
50 | jmp hltLoop
51 |
52 | .size _start, . - _start
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/GUI/dosbox_gui/dosbox_gui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/GUI/dosbox_gui/dosbox_gui.png
--------------------------------------------------------------------------------
/GUI/dosbox_gui/grub.cfg:
--------------------------------------------------------------------------------
1 | menuentry "MyOS" {
2 | multiboot /boot/MyOS.bin
3 | }
4 |
--------------------------------------------------------------------------------
/GUI/dosbox_gui/kernel.h:
--------------------------------------------------------------------------------
1 | #ifndef KERNEL_H
2 | #define KERNEL_H
3 |
4 | #include "types.h"
5 |
6 | #define NULL 0
7 |
8 | #define VGA_ADDRESS 0xB8000
9 | #define BUFSIZE 2200
10 |
11 | uint16* vga_buffer;
12 |
13 | #define BOX_MAX_WIDTH 78
14 | #define BOX_MAX_HEIGHT 23
15 |
16 | #define BOX_SINGLELINE 1
17 | #define BOX_DOUBLELINE 2
18 |
19 | enum vga_color {
20 | BLACK,
21 | BLUE,
22 | GREEN,
23 | CYAN,
24 | RED,
25 | MAGENTA,
26 | BROWN,
27 | GREY,
28 | DARK_GREY,
29 | BRIGHT_BLUE,
30 | BRIGHT_GREEN,
31 | BRIGHT_CYAN,
32 | BRIGHT_RED,
33 | BRIGHT_MAGENTA,
34 | YELLOW,
35 | WHITE,
36 | };
37 |
38 |
39 | #endif
40 |
--------------------------------------------------------------------------------
/GUI/dosbox_gui/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 | }
40 |
41 | /* The compiler may produce other sections, by default it will put them in
42 | a segment with the same name. Simply add stuff here as needed. */
43 | }
44 |
--------------------------------------------------------------------------------
/GUI/dosbox_gui/run.sh:
--------------------------------------------------------------------------------
1 | #assemble boot.s file
2 | as --32 boot.s -o boot.o
3 |
4 | #compile kernel.c file
5 | gcc -m32 -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
6 |
7 | gcc -m32 -c utils.c -o utils.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
8 |
9 | #linking the kernel with kernel.o and boot.o files
10 | ld -m elf_i386 -T linker.ld kernel.o utils.o boot.o -o MyOS.bin -nostdlib
11 |
12 | #check MyOS.bin file is x86 multiboot file or not
13 | grub-file --is-x86-multiboot MyOS.bin
14 |
15 | #building the iso file
16 | mkdir -p isodir/boot/grub
17 | cp MyOS.bin isodir/boot/MyOS.bin
18 | cp grub.cfg isodir/boot/grub/grub.cfg
19 | grub-mkrescue -o MyOS.iso isodir
20 |
21 | #run it in qemu
22 | qemu-system-x86_64 -cdrom MyOS.iso
23 |
--------------------------------------------------------------------------------
/GUI/dosbox_gui/types.h:
--------------------------------------------------------------------------------
1 | #ifndef TYPES_H
2 | #define TYPES_H
3 |
4 | typedef unsigned char uint8;
5 | typedef unsigned short uint16;
6 | typedef unsigned int uint32;
7 |
8 | #endif
9 |
10 |
11 |
--------------------------------------------------------------------------------
/GUI/dosbox_gui/utils.c:
--------------------------------------------------------------------------------
1 | #include "utils.h"
2 |
3 | uint32 strlen(const char* str)
4 | {
5 | uint32 length = 0;
6 | while(str[length])
7 | length++;
8 | return length;
9 | }
10 |
11 | uint32 digit_count(int num)
12 | {
13 | uint32 count = 0;
14 | if(num == 0)
15 | return 1;
16 | while(num > 0){
17 | count++;
18 | num = num/10;
19 | }
20 | return count;
21 | }
22 |
23 | void itoa(int num, char *number)
24 | {
25 | int dgcount = digit_count(num);
26 | int index = dgcount - 1;
27 | char x;
28 | if(num == 0 && dgcount == 1){
29 | number[0] = '0';
30 | number[1] = '\0';
31 | }else{
32 | while(num != 0){
33 | x = num % 10;
34 | number[index] = x + '0';
35 | index--;
36 | num = num / 10;
37 | }
38 | number[dgcount] = '\0';
39 | }
40 | }
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/GUI/dosbox_gui/utils.h:
--------------------------------------------------------------------------------
1 | #ifndef UTILS_H
2 | #define UTILS_H
3 |
4 | #include "types.h"
5 |
6 | extern uint32 strlen(const char*);
7 | extern uint32 digit_count(int);
8 | extern void itoa(int, char *);
9 |
10 | #endif
11 |
12 |
--------------------------------------------------------------------------------
/Global_Descriptor_Table/asm/gdt.asm:
--------------------------------------------------------------------------------
1 | [bits 16]
2 | [org 0x7c00]
3 |
4 | kernel16_start:
5 |
6 | xor ax, ax
7 | mov ss, ax
8 | mov ds, ax
9 | mov es, ax
10 | mov fs, ax
11 | mov gs, ax
12 | mov sp, 0xfff
13 |
14 | cli
15 |
16 | lgdt[GDT_DESCRIPTOR]
17 |
18 | mov eax, cr0
19 | or eax, 1
20 | mov cr0, eax
21 |
22 | jmp CODE_SEGMENT:kernel32_start
23 |
24 |
25 | [bits 32]
26 |
27 | kernel32_start:
28 |
29 | mov ax, DATA_SEGMENT
30 | mov ds, ax
31 | mov es, ax
32 | mov fs, ax
33 | mov gs, ax
34 | mov ss, ax
35 |
36 | mov ebp, 0x0ffffff
37 | mov esp, ebp
38 |
39 | mov esi, hello_world
40 | call print_string
41 |
42 | .loopk:
43 | jmp .loopk
44 |
45 |
46 | print_string:
47 | pusha
48 | mov edx, VIDEO_MEMORY
49 | .loop:
50 | mov al, [esi]
51 | cmp al, 0
52 | je .exit
53 | mov ah, 0x0f
54 | mov [edx], ax
55 | add esi, 1
56 | add edx, 2
57 | jmp .loop
58 | .exit:
59 | popa
60 | ret
61 |
62 |
63 | ; Global Descriptor Table definition
64 |
65 | GDT_START:
66 |
67 | ; GDT null segment (2 dwords)
68 | GDT_NULL:
69 | dd 0x0
70 | dd 0x0
71 |
72 | ; GDT Code segment (2 dwords)
73 | GDT_CODE:
74 | dw 0xffff ; segment limit first 0-15 bits
75 | dw 0x0 ; base first 0-15 bits
76 | db 0x0 ; base 16-23 bits
77 | db 0x9a ; access byte
78 | db 11001111b ; high 4 bits (flags) low 4 bits (limit 4 last bits)(limit is 20 bit wide)
79 | db 0x0 ; base 24-31 bits
80 |
81 | ; GDT Data Segment (2 dwords)
82 | GDT_DATA:
83 | dw 0xffff ; segment limit first 0-15 bits
84 | dw 0x0 ; base first 0-15 bits
85 | db 0x0 ; base 16-23 bits
86 | db 0x92 ; access byte
87 | db 11001111b ; high 4 bits (flags) low 4 bits (limit 4 last bits)(limit is 20 bit wide)
88 | db 0x0 ; base 24-31 bits
89 |
90 | GDT_END:
91 |
92 | GDT_DESCRIPTOR:
93 | dw GDT_END - GDT_START
94 | dd GDT_START
95 |
96 | CODE_SEGMENT equ GDT_CODE + 4
97 | DATA_SEGMENT equ GDT_DATA + 4
98 |
99 |
100 | hello_world db 'HelloWorld', 0
101 |
102 | VIDEO_MEMORY equ 0xB8000
103 |
104 |
105 | times (510 - ($ - $$)) db 0x00
106 | dw 0AA55h
107 |
108 |
109 |
--------------------------------------------------------------------------------
/Global_Descriptor_Table/kernel_C/boot.s:
--------------------------------------------------------------------------------
1 | # set magic number to 0x1BADB002 to identified by bootloader
2 | .set MAGIC, 0x1BADB002
3 |
4 | # set flags to 0
5 | .set FLAGS, 0
6 |
7 | # set the checksum
8 | .set CHECKSUM, -(MAGIC + FLAGS)
9 |
10 | # set multiboot enabled
11 | .section .multiboot
12 |
13 | # define type to long for each data defined as above
14 | .long MAGIC
15 | .long FLAGS
16 | .long CHECKSUM
17 |
18 |
19 | # set the stack bottom
20 | stackBottom:
21 |
22 | # define the maximum size of stack to 512 bytes
23 | .skip 1024
24 |
25 |
26 | # set the stack top which grows from higher to lower
27 | stackTop:
28 |
29 | .section .text
30 | .global _start
31 | .type _start, @function
32 |
33 | _start:
34 |
35 | # assign current stack pointer location to stackTop
36 | mov $stackTop, %esp
37 |
38 | # call the kernel main source
39 | call kernel_entry
40 |
41 | cli
42 |
43 |
44 | # put system in infinite loop
45 | hltLoop:
46 |
47 | hlt
48 | jmp hltLoop
49 |
50 | .size _start, . - _start
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/Global_Descriptor_Table/kernel_C/gdt.c:
--------------------------------------------------------------------------------
1 | #include "gdt.h"
2 |
3 | struct GDT gdt_entries[3];
4 | struct GDT_PTR gdt_first;
5 |
6 | extern void load_gdt(struct GDT*);
7 |
8 | void init_gdt()
9 | {
10 | // set null segment
11 | gdt_entries[NULL_SEGMENT].segment_limit = 0;
12 | gdt_entries[NULL_SEGMENT].base_low = 0;
13 | gdt_entries[NULL_SEGMENT].base_middle = 0;
14 | gdt_entries[NULL_SEGMENT].access = 0;
15 | gdt_entries[NULL_SEGMENT].granularity = 0;
16 | gdt_entries[NULL_SEGMENT].base_high = 0;
17 |
18 | // set code segment
19 | gdt_entries[CODE_SEGMENT].segment_limit = 0xffff;
20 | gdt_entries[CODE_SEGMENT].base_low = 0;
21 | gdt_entries[CODE_SEGMENT].base_middle = 0;
22 | gdt_entries[CODE_SEGMENT].access = 0x9a;
23 | gdt_entries[CODE_SEGMENT].granularity = 0b11001111;
24 | gdt_entries[CODE_SEGMENT].base_high = 0;
25 |
26 | // set data segment
27 | gdt_entries[DATA_SEGMENT].segment_limit = 0xffff;
28 | gdt_entries[DATA_SEGMENT].base_low = 0;
29 | gdt_entries[DATA_SEGMENT].base_middle = 0;
30 | gdt_entries[DATA_SEGMENT].access = 0x92;
31 | gdt_entries[DATA_SEGMENT].granularity = 0b11001111;
32 | gdt_entries[DATA_SEGMENT].base_high = 0;
33 |
34 |
35 | gdt_first.limit_size = sizeof(gdt_entries) - 1;
36 | gdt_first.base_address = (struct GDT*)&gdt_entries;
37 |
38 | load_gdt((struct GDT*)&gdt_first);
39 |
40 | }
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/Global_Descriptor_Table/kernel_C/gdt.h:
--------------------------------------------------------------------------------
1 | #ifndef GDT_H
2 | #define GDT_H
3 |
4 | #include "types.h"
5 |
6 | #define NULL_SEGMENT 0
7 | #define CODE_SEGMENT 1
8 | #define DATA_SEGMENT 2
9 |
10 | struct GDT
11 | {
12 | uint16 segment_limit; // segment limit first 0-15 bits
13 | uint16 base_low; // base first 0-15 bits
14 | uint8 base_middle; // base 16-23 bits
15 | uint8 access; // access byte
16 | uint8 granularity; // high 4 bits (flags) low 4 bits (limit 4 last bits)(limit is 20 bit wide)
17 | uint8 base_high; // base 24-31 bits
18 | } __attribute__((packed));
19 |
20 |
21 | struct GDT_PTR
22 | {
23 | uint16 limit_size; // limit size of all GDT segments
24 | struct GDT* base_address; // base address of the first GDT segment
25 | } __attribute__((packed));
26 |
27 | extern struct GDT gdt_entries[3];
28 | extern struct GDT_PTR gdt_first;
29 |
30 | extern void init_gdt();
31 |
32 | #endif
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Global_Descriptor_Table/kernel_C/grub.cfg:
--------------------------------------------------------------------------------
1 | menuentry "MyOS" {
2 | multiboot /boot/MyOS.bin
3 | }
4 |
--------------------------------------------------------------------------------
/Global_Descriptor_Table/kernel_C/kernel.c:
--------------------------------------------------------------------------------
1 | #include "kernel.h"
2 | #include "types.h"
3 | #include "gdt.h"
4 |
5 | //index for video buffer array
6 | uint32 vga_index;
7 | //counter to store new lines
8 | static uint32 next_line_index = 1;
9 | //fore & back color values
10 | uint8 g_fore_color = WHITE, g_back_color = BLUE;
11 | //digit ascii code for printing integers
12 | int digit_ascii_codes[10] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
13 |
14 | /*
15 | 16 bit video buffer elements(register ax)
16 | 8 bits(ah) higher :
17 | lower 4 bits - forec olor
18 | higher 4 bits - back color
19 |
20 | 8 bits(al) lower :
21 | 8 bits : ASCII character to print
22 | */
23 | uint16 vga_entry(unsigned char ch, uint8 fore_color, uint8 back_color)
24 | {
25 | uint16 ax = 0;
26 | uint8 ah = 0, al = 0;
27 |
28 | ah = back_color;
29 | ah <<= 4;
30 | ah |= fore_color;
31 | ax = ah;
32 | ax <<= 8;
33 | al = ch;
34 | ax |= al;
35 |
36 | return ax;
37 | }
38 |
39 | //clear video buffer array
40 | void clear_vga_buffer(uint16 **buffer, uint8 fore_color, uint8 back_color)
41 | {
42 | uint32 i;
43 | for(i = 0; i < BUFSIZE; i++){
44 | (*buffer)[i] = vga_entry(NULL, fore_color, back_color);
45 | }
46 | next_line_index = 1;
47 | vga_index = 0;
48 | }
49 |
50 | //initialize vga buffer
51 | void init_vga(uint8 fore_color, uint8 back_color)
52 | {
53 | vga_buffer = (uint16*)VGA_ADDRESS;
54 | clear_vga_buffer(&vga_buffer, fore_color, back_color);
55 | g_fore_color = fore_color;
56 | g_back_color = back_color;
57 | }
58 |
59 | /*
60 | increase vga_index by width of row(80)
61 | */
62 | void print_new_line()
63 | {
64 | if(next_line_index >= 55){
65 | next_line_index = 0;
66 | clear_vga_buffer(&vga_buffer, g_fore_color, g_back_color);
67 | }
68 | vga_index = 80*next_line_index;
69 | next_line_index++;
70 | }
71 |
72 | //assign ascii character to video buffer
73 | void print_char(char ch)
74 | {
75 | vga_buffer[vga_index] = vga_entry(ch, g_fore_color, g_back_color);
76 | vga_index++;
77 | }
78 |
79 |
80 | uint32 strlen(const char* str)
81 | {
82 | uint32 length = 0;
83 | while(str[length])
84 | length++;
85 | return length;
86 | }
87 |
88 | uint32 digit_count(int num)
89 | {
90 | uint32 count = 0;
91 | if(num == 0)
92 | return 1;
93 | while(num > 0){
94 | count++;
95 | num = num/10;
96 | }
97 | return count;
98 | }
99 |
100 | void itoa(int num, char *number)
101 | {
102 | int dgcount = digit_count(num);
103 | int index = dgcount - 1;
104 | char x;
105 | if(num == 0 && dgcount == 1){
106 | number[0] = '0';
107 | number[1] = '\0';
108 | }else{
109 | while(num != 0){
110 | x = num % 10;
111 | number[index] = x + '0';
112 | index--;
113 | num = num / 10;
114 | }
115 | number[dgcount] = '\0';
116 | }
117 | }
118 |
119 | //print string by calling print_char
120 | void print_string(char *str)
121 | {
122 | uint32 index = 0;
123 | while(str[index]){
124 | print_char(str[index]);
125 | index++;
126 | }
127 | }
128 |
129 | //print int by converting it into string
130 | //& then printing string
131 | void print_int(int num)
132 | {
133 | char str_num[digit_count(num)+1];
134 | itoa(num, str_num);
135 | print_string(str_num);
136 | }
137 |
138 |
139 | void kernel_entry()
140 | {
141 | init_gdt();
142 |
143 | //first init vga with fore & back colors
144 | init_vga(WHITE, BLACK);
145 |
146 | print_string("Hello World!");
147 |
148 | }
149 |
150 |
151 |
152 |
--------------------------------------------------------------------------------
/Global_Descriptor_Table/kernel_C/kernel.h:
--------------------------------------------------------------------------------
1 | #ifndef KERNEL_H
2 | #define KERNEL_H
3 |
4 | #include "types.h"
5 |
6 | #define VGA_ADDRESS 0xB8000
7 | #define BUFSIZE 2200
8 |
9 | uint16* vga_buffer;
10 |
11 | #define NULL 0
12 |
13 | enum vga_color {
14 | BLACK,
15 | BLUE,
16 | GREEN,
17 | CYAN,
18 | RED,
19 | MAGENTA,
20 | BROWN,
21 | GREY,
22 | DARK_GREY,
23 | BRIGHT_BLUE,
24 | BRIGHT_GREEN,
25 | BRIGHT_CYAN,
26 | BRIGHT_RED,
27 | BRIGHT_MAGENTA,
28 | YELLOW,
29 | WHITE,
30 | };
31 |
32 | #endif
33 |
--------------------------------------------------------------------------------
/Global_Descriptor_Table/kernel_C/linker.ld:
--------------------------------------------------------------------------------
1 | /* entry point of our kernel */
2 | ENTRY(_start)
3 |
4 | SECTIONS
5 | {
6 | /* we need 1MB of space atleast */
7 | . = 1M;
8 |
9 | /* text section */
10 | .text BLOCK(4K) : ALIGN(4K)
11 | {
12 | *(.multiboot)
13 | *(.text)
14 | }
15 |
16 | /* read only data section */
17 | .rodata BLOCK(4K) : ALIGN(4K)
18 | {
19 | *(.rodata)
20 | }
21 |
22 | /* data section */
23 | .data BLOCK(4K) : ALIGN(4K)
24 | {
25 | *(.data)
26 | }
27 |
28 | /* bss section */
29 | .bss BLOCK(4K) : ALIGN(4K)
30 | {
31 | *(COMMON)
32 | *(.bss)
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/Global_Descriptor_Table/kernel_C/load_gdt.s:
--------------------------------------------------------------------------------
1 | .section .text
2 | .global load_gdt
3 |
4 | load_gdt:
5 | mov 4(%esp), %eax
6 | lgdt (%eax)
7 |
8 | mov $0x10, %eax
9 | mov %eax, %ds
10 | mov %eax, %es
11 | mov %eax, %fs
12 | mov %eax, %gs
13 | mov %eax, %ss
14 | jmp $0x8, $.long_jump
15 | .long_jump:
16 | ret
17 |
18 |
--------------------------------------------------------------------------------
/Global_Descriptor_Table/kernel_C/run.sh:
--------------------------------------------------------------------------------
1 | #assemble boot.s file
2 | as --32 boot.s -o boot.o
3 | as --32 load_gdt.s -o load_gdt.o
4 |
5 | #compile kernel.c file
6 | gcc -m32 -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
7 |
8 | #compile gdt.c file
9 | gcc -m32 -c gdt.c -o gdt.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
10 |
11 | #linking the kernel with kernel.o and boot.o files
12 | ld -m elf_i386 -T linker.ld kernel.o boot.o gdt.o load_gdt.o -o MyOS.bin -nostdlib
13 |
14 | #check MyOS.bin file is x86 multiboot file or not
15 | grub-file --is-x86-multiboot MyOS.bin
16 |
17 | #building the iso file
18 | mkdir -p isodir/boot/grub
19 | cp MyOS.bin isodir/boot/MyOS.bin
20 | cp grub.cfg isodir/boot/grub/grub.cfg
21 | grub-mkrescue -o MyOS.iso isodir
22 |
23 | #run it in qemu
24 | qemu-system-x86_64 -cdrom MyOS.iso
25 |
--------------------------------------------------------------------------------
/Global_Descriptor_Table/kernel_C/types.h:
--------------------------------------------------------------------------------
1 | #ifndef TYPES_H
2 | #define TYPES_H
3 |
4 | typedef unsigned char uint8;
5 | typedef unsigned short uint16;
6 | typedef unsigned int uint32;
7 | typedef signed char sint8;
8 | typedef signed short sint16;
9 | typedef signed int sint32;
10 | typedef uint8 byte;
11 | typedef uint16 word;
12 | typedef uint32 dword;
13 |
14 | #endif
15 |
16 |
--------------------------------------------------------------------------------
/Graphics/Simple/dda_line_draw/img/dda_line_draw.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/Graphics/Simple/dda_line_draw/img/dda_line_draw.bin
--------------------------------------------------------------------------------
/Graphics/Simple/dda_line_draw/img/dda_line_draw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/Graphics/Simple/dda_line_draw/img/dda_line_draw.png
--------------------------------------------------------------------------------
/Graphics/Simple/drawpixel/img/draw_pixel.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/Graphics/Simple/drawpixel/img/draw_pixel.bin
--------------------------------------------------------------------------------
/Graphics/Simple/drawpixel/img/draw_pixels.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/Graphics/Simple/drawpixel/img/draw_pixels.png
--------------------------------------------------------------------------------
/Graphics/Simple/drawpixel/src/drawpixel.asm:
--------------------------------------------------------------------------------
1 | ;****Graphics Pixel drawing algorithm****
2 |
3 | ;******************************************
4 | ; botloader code begin
5 |
6 | [bits 16] ; tell assembler that working in real mode(16 bit mode)
7 | [org 0x7c00] ; organize from 0x7C00 memory location where BIOS will load us
8 |
9 |
10 | start: ; start label from where our code starts
11 |
12 |
13 | xor ax,ax ; set ax register to 0
14 | mov ds,ax ; set data segment(ds) to 0
15 | mov es,ax ; set extra segment(es) to 0
16 |
17 | ;******************************************
18 | ; jumping from real mode to protected mode
19 | ; by using disk interrupt
20 | mov ah, 0x02 ; load second stage to memory
21 | mov al, 0x10 ; numbers of sectors to read into memory
22 | mov dl, 0x80 ; sector read from fixed/usb disk
23 | mov ch, 0 ; cylinder number
24 | mov dh, 0 ; head number
25 | mov cl, 2 ; sector number
26 | mov bx, _start ; load into es:bx segment :offset of buffer
27 | int 0x13 ; disk I/O interrupt
28 |
29 | ; before jumping clearing all interrupts
30 | cli
31 |
32 | ; jump to protected mode
33 | jmp _start ; jump to second stage
34 |
35 | times (510 - ($ - $$)) db 0x00 ;set 512 bytes for boot sector which are necessary
36 | dw 0xAA55 ; boot signature 0xAA & 0x55
37 |
38 |
39 | ; bootloader code end
40 |
41 | ;******************************************
42 | ; x86 code begin
43 |
44 | _start:
45 |
46 | main :
47 |
48 | ;******************************************
49 | ; set base pointer to heap
50 | ; and stack pointer to stack for functions and variables
51 | mov ebp, __HEAP__
52 | mov esp, __STACK__
53 |
54 | ;clear the screen
55 | mov ax,0x13
56 | int 0x10
57 |
58 | ; point extra segment register to the video memory address
59 | mov es, word[VGA_MEM]
60 |
61 | ;assign co-ordinates to X and YELLOW
62 | ;and color to PIXEL_COLOR
63 | ;call drawpixel procedure
64 | mov word[X],50
65 | mov word[Y],60
66 | mov ax, word[WHITE]
67 | mov word[PIXEL_COLOR], ax
68 | call drawpixel
69 |
70 | ;lets draw another pixels
71 | mov word[X],100
72 | mov word[Y],60
73 | mov ax, word[RED]
74 | mov word[PIXEL_COLOR], ax
75 | call drawpixel
76 |
77 | mov word[X],120
78 | mov word[Y],120
79 | mov ax, word[BRIGHT_CYAN]
80 | mov word[PIXEL_COLOR], ax
81 | call drawpixel
82 |
83 | mov word[X],140
84 | mov word[Y],30
85 | mov ax, word[YELLOW]
86 | mov word[PIXEL_COLOR], ax
87 | call drawpixel
88 |
89 | hlt
90 |
91 |
92 | ;draw a pixel at x,y location
93 | drawpixel :
94 |
95 | ;get x co-ordinate
96 | mov ax, word[X]
97 |
98 | ;get y co-ordinate
99 | mov bx, word[Y]
100 |
101 | ;clear destination index register for use as index in
102 | ;video memory pointed by es register
103 | xor di, di
104 |
105 | ;set y co-ordinate
106 | ;first increase video index by width of the current graphics mode(320*220)
107 | ;multiply index by y co-ordinate to set its location
108 | ;this is same as printing a new line in our kernel C code
109 | ;https://github.com/pritamzope/OS/tree/master/Kernel/Simple/src/kernel_3
110 | add di, word[WIDTH]
111 | imul di, bx
112 |
113 | ; set x co-ordinate by increasing index(di) by X value
114 | add di, ax
115 |
116 | ;get the color from PIXEL_COLOR memory
117 | mov ax, word[PIXEL_COLOR]
118 |
119 | ;plot the pixel with index(di) and pixel color(ax)
120 | mov [es:di], ax
121 |
122 | ret
123 |
124 |
125 | ;******************************************
126 | ; set the required disk space we need
127 | ; the size of image(.bin file size)
128 | times (4096 - ($ - $$)) db 0x00
129 |
130 | ;read only data section
131 | section .rodata
132 | __STACK__ dd 0x00FFFFFF
133 | __HEAP__ dd 0x00008C24
134 |
135 | ;video memory address
136 | ;for more see "Addressing details" section in following link
137 | ;https://en.wikipedia.org/wiki/Video_Graphics_Array
138 | ;In our kernel program we used 0xB8000 address
139 | VGA_MEM dw 0xA000
140 | WIDTH dw 320
141 | HEIGHT dw 219
142 |
143 | ;colors
144 | BLACK dw 0x00
145 | BLUE dw 0x01
146 | GREEN dw 0x02
147 | CYAN dw 0x03
148 | RED dw 0x04
149 | MAGENTA dw 0x05
150 | BROWN dw 0x06
151 | GRAY dw 0x07
152 | DARK_GRAY dw 0x08
153 | BRIGHT_BLUE dw 0x09
154 | BRIGHT_GREEN dw 0xA
155 | BRIGHT_CYAN dw 0xB
156 | BRIGHT_RED dw 0xC
157 | BRIGHT_MAGENTA dw 0xD
158 | YELLOW dw 0xE
159 | WHITE dw 0xF
160 |
161 | ;data section
162 | section .data
163 | X dd 0
164 | Y dd 0
165 | PIXEL_COLOR dw 0x0F
166 |
--------------------------------------------------------------------------------
/Graphics/Simple/rectangle/img/rectangle.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/Graphics/Simple/rectangle/img/rectangle.bin
--------------------------------------------------------------------------------
/Graphics/Simple/rectangle/img/rectangle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/Graphics/Simple/rectangle/img/rectangle.png
--------------------------------------------------------------------------------
/Graphics/Simple/rectangle/src/Readme.txt:
--------------------------------------------------------------------------------
1 | Just assemble the rectangle.asm source file
2 | dda.asm and drawpixel.asm files are included in rectangle.asm file.
3 |
4 | e.g:
5 | nasm -f bin rectangle.asm -o rectangle.bin
--------------------------------------------------------------------------------
/Graphics/Simple/rectangle/src/dda.asm:
--------------------------------------------------------------------------------
1 | ;****Digital Differential Analyzer(DDA) Line Drawing algorithm****
2 |
3 | drawline:
4 |
5 | ;calculate difference of x points
6 | mov ecx, dword[X2]
7 | sub ecx, dword[X1]
8 | mov dword[_DX], ecx
9 |
10 | ;calculate difference of y points
11 | mov ecx, dword[Y2]
12 | sub ecx, dword[Y1]
13 | mov dword[_DY], ecx
14 |
15 | ; check if Y1 & Y2 are equal
16 | mov eax, dword[Y1]
17 | mov ebx, dword[Y2]
18 | cmp eax, ebx
19 | je .y_equals
20 |
21 | ; check if X1 & X2 are equal
22 | mov eax, dword[X1]
23 | mov ebx, dword[X2]
24 | cmp eax, ebx
25 | je .x_equals
26 |
27 | ;check if _DX <= _DY
28 | mov ecx, dword[_DX]
29 | cmp ecx, dword[_DY]
30 | jle .dx_is_less
31 |
32 | .x_equals:
33 | ;is X1 & X2 are equal _STEP to _DY
34 | mov ecx, dword[_DY]
35 | mov dword[_STEP], ecx
36 |
37 | jmp .done
38 |
39 | .y_equals:
40 | ;if Y1 & Y2 are equal then goto next
41 |
42 | .dx_is_less:
43 | ;if _DX is greater than _DY or Y1 & Y2 are equal then
44 | ;set _STEP to _DX
45 | mov ecx, dword[_DX]
46 | mov dword[_STEP], ecx
47 |
48 | .done:
49 |
50 | ; _DX = _DX / _STEP
51 | xor edx, edx
52 | mov eax, dword[_DX]
53 | mov ebx, dword[_STEP]
54 | div ebx
55 | mov dword[_DX], eax
56 |
57 | ; _DY = _DY / _STEP
58 | xor edx, edx
59 | mov eax, dword[_DY]
60 | mov ebx, dword[_STEP]
61 | div ebx
62 | mov dword[_DY], eax
63 |
64 | ;set co-ordinate _X = X1
65 | mov eax, dword[X1]
66 | mov dword[_X], eax
67 |
68 | ;set co-ordinate _Y = Y1
69 | mov eax, dword[Y1]
70 | mov dword[_Y], eax
71 |
72 | ;set counter ecx to _STEP
73 | mov ecx, 0
74 |
75 | .line_loop:
76 |
77 | ;stop when ecx > _STEP
78 | cmp ecx, dword[_STEP]
79 | jg .exit
80 |
81 | ;get x co-ordinate
82 | mov eax, dword[_X]
83 |
84 | ;get y co-ordinate
85 | mov ebx, dword[_Y]
86 |
87 | ;clear destination index register for use as index in
88 | ;video memory pointed by es register
89 | xor di, di
90 |
91 | ;set y co-ordinate
92 | ;first increase video index by width of the current graphics mode(320*220)
93 | ;multiply index by y co-ordinate to set its location
94 | ;this is same as printing a new line in our kernel C code
95 | ;https://github.com/pritamzope/OS/tree/master/Kernel/Simple/src/kernel_3
96 | add di, word[VGA_WIDTH]
97 | imul di, bx
98 |
99 | ; set x co-ordinate by increasing index(di) by X value
100 | add di, ax
101 |
102 | ;get the color from PIXEL_COLOR memory
103 | mov ax, word[LINE_COLOR]
104 |
105 | ;plot the pixel with index(di) and pixel color(ax)
106 | mov [es:di], ax
107 |
108 | ;increase _X by _DX
109 | mov eax, dword[_X]
110 | add eax, dword[_DX]
111 | mov dword[_X], eax
112 |
113 | ;increase _Y by _DY
114 | mov eax, dword[_Y]
115 | add eax, dword[_DY]
116 | mov dword[_Y], eax
117 |
118 | ;increase _STEP
119 | inc ecx
120 |
121 | ;and continue loop
122 | jmp .line_loop
123 |
124 | .exit:
125 | ret
126 |
127 |
--------------------------------------------------------------------------------
/Graphics/Simple/rectangle/src/drawpixel.asm:
--------------------------------------------------------------------------------
1 | ;draw a pixel at x,y location
2 | drawpixel :
3 |
4 | ;get x co-ordinate
5 | mov ax, word[X_PIX]
6 |
7 | ;get y co-ordinate
8 | mov bx, word[Y_PIX]
9 |
10 | ;clear destination index register for use as index in
11 | ;video memory pointed by es register
12 | xor di, di
13 |
14 | ;set y co-ordinate
15 | ;first increase video index by width of the current graphics mode(320*220)
16 | ;multiply index by y co-ordinate to set its location
17 | ;this is same as printing a new line in our kernel C code
18 | ;https://github.com/pritamzope/OS/tree/master/Kernel/Simple/src/kernel_3
19 | add di, word[VGA_WIDTH]
20 | imul di, bx
21 |
22 | ; set x co-ordinate by increasing index(di) by X value
23 | add di, ax
24 |
25 | ;get the color from PIXEL_COLOR memory
26 | mov ax, word[PIXEL_COLOR]
27 |
28 | ;plot the pixel with index(di) and pixel color(ax)
29 | mov [es:di], ax
30 |
31 | ret
32 |
--------------------------------------------------------------------------------
/Interrupt_Descriptor_Table/boot.s:
--------------------------------------------------------------------------------
1 | # set magic number to 0x1BADB002 to identified by bootloader
2 | .set MAGIC, 0x1BADB002
3 |
4 | # set flags to 0
5 | .set FLAGS, 0
6 |
7 | # set the checksum
8 | .set CHECKSUM, -(MAGIC + FLAGS)
9 |
10 | # set multiboot enabled
11 | .section .multiboot
12 |
13 | # define type to long for each data defined as above
14 | .long MAGIC
15 | .long FLAGS
16 | .long CHECKSUM
17 |
18 |
19 | # set the stack bottom
20 | stackBottom:
21 |
22 | # define the maximum size of stack to 512 bytes
23 | .skip 1024
24 |
25 |
26 | # set the stack top which grows from higher to lower
27 | stackTop:
28 |
29 | .section .text
30 | .global _start
31 | .type _start, @function
32 |
33 | _start:
34 |
35 | # assign current stack pointer location to stackTop
36 | mov $stackTop, %esp
37 |
38 | # call the kernel main source
39 | call kernel_entry
40 |
41 | cli
42 |
43 |
44 | # put system in infinite loop
45 | hltLoop:
46 |
47 | hlt
48 | jmp hltLoop
49 |
50 | .size _start, . - _start
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/Interrupt_Descriptor_Table/gdt.c:
--------------------------------------------------------------------------------
1 | #include "gdt.h"
2 |
3 | struct GDT gdt_entries[3];
4 | struct GDT_PTR gdt_first;
5 |
6 | extern void load_gdt(struct GDT*);
7 |
8 | void init_gdt()
9 | {
10 | // set null segment
11 | gdt_entries[NULL_SEGMENT].segment_limit = 0;
12 | gdt_entries[NULL_SEGMENT].base_low = 0;
13 | gdt_entries[NULL_SEGMENT].base_middle = 0;
14 | gdt_entries[NULL_SEGMENT].access = 0;
15 | gdt_entries[NULL_SEGMENT].granularity = 0;
16 | gdt_entries[NULL_SEGMENT].base_high = 0;
17 |
18 | // set code segment
19 | gdt_entries[CODE_SEGMENT].segment_limit = 0xffff;
20 | gdt_entries[CODE_SEGMENT].base_low = 0;
21 | gdt_entries[CODE_SEGMENT].base_middle = 0;
22 | gdt_entries[CODE_SEGMENT].access = 0x9a;
23 | gdt_entries[CODE_SEGMENT].granularity = 0b11001111;
24 | gdt_entries[CODE_SEGMENT].base_high = 0;
25 |
26 | // set data segment
27 | gdt_entries[DATA_SEGMENT].segment_limit = 0xffff;
28 | gdt_entries[DATA_SEGMENT].base_low = 0;
29 | gdt_entries[DATA_SEGMENT].base_middle = 0;
30 | gdt_entries[DATA_SEGMENT].access = 0x92;
31 | gdt_entries[DATA_SEGMENT].granularity = 0b11001111;
32 | gdt_entries[DATA_SEGMENT].base_high = 0;
33 |
34 |
35 | gdt_first.limit_size = sizeof(gdt_entries) - 1;
36 | gdt_first.base_address = (struct GDT*)&gdt_entries;
37 |
38 | load_gdt((struct GDT*)&gdt_first);
39 |
40 | }
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/Interrupt_Descriptor_Table/gdt.h:
--------------------------------------------------------------------------------
1 | #ifndef GDT_H
2 | #define GDT_H
3 |
4 | #include "types.h"
5 |
6 | #define NULL_SEGMENT 0
7 | #define CODE_SEGMENT 1
8 | #define DATA_SEGMENT 2
9 |
10 | struct GDT
11 | {
12 | uint16 segment_limit; // segment limit first 0-15 bits
13 | uint16 base_low; // base first 0-15 bits
14 | uint8 base_middle; // base 16-23 bits
15 | uint8 access; // access byte
16 | uint8 granularity; // high 4 bits (flags) low 4 bits (limit 4 last bits)(limit is 20 bit wide)
17 | uint8 base_high; // base 24-31 bits
18 | } __attribute__((packed));
19 |
20 |
21 | struct GDT_PTR
22 | {
23 | uint16 limit_size; // limit size of all GDT segments
24 | struct GDT* base_address; // base address of the first GDT segment
25 | } __attribute__((packed));
26 |
27 | extern struct GDT gdt_entries[3];
28 | extern struct GDT_PTR gdt_first;
29 |
30 | extern void init_gdt();
31 |
32 | #endif
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Interrupt_Descriptor_Table/grub.cfg:
--------------------------------------------------------------------------------
1 | menuentry "MyOS" {
2 | multiboot /boot/MyOS.bin
3 | }
4 |
--------------------------------------------------------------------------------
/Interrupt_Descriptor_Table/idt.c:
--------------------------------------------------------------------------------
1 | #include "idt.h"
2 | #include "isr.h"
3 |
4 | struct IDT idt_entries[16];
5 | struct IDT_PTR idt_first;
6 |
7 | extern void load_idt(struct IDT*);
8 |
9 | void set_idt_gate(int intnum, uint32 isr)
10 | {
11 | idt_entries[intnum].base_low = isr & 0xffff;
12 | idt_entries[intnum].segment_selector = 0x08;
13 | idt_entries[intnum].zero = 0;
14 | idt_entries[intnum].type = 0x8E;
15 | idt_entries[intnum].base_high = (isr >> 16) & 0xffff;
16 | }
17 |
18 | void init_idt()
19 | {
20 | set_idt_gate(0, (uint32)isr_0);
21 | set_idt_gate(1, (uint32)isr_1);
22 | set_idt_gate(2, (uint32)isr_2);
23 | set_idt_gate(3, (uint32)isr_3);
24 | set_idt_gate(4, (uint32)isr_4);
25 | set_idt_gate(5, (uint32)isr_5);
26 | set_idt_gate(6, (uint32)isr_6);
27 | set_idt_gate(7, (uint32)isr_7);
28 | set_idt_gate(8, (uint32)isr_8);
29 | set_idt_gate(9, (uint32)isr_9);
30 | set_idt_gate(10, (uint32)isr_10);
31 | set_idt_gate(11, (uint32)isr_11);
32 | set_idt_gate(12, (uint32)isr_12);
33 | set_idt_gate(13, (uint32)isr_13);
34 | set_idt_gate(14, (uint32)isr_14);
35 | set_idt_gate(15, (uint32)isr_15);
36 |
37 | idt_first.limit_size = sizeof(idt_entries) - 1;
38 | idt_first.base_address = (struct IDT*)&idt_entries;
39 |
40 | load_idt((struct IDT*)&idt_first);
41 | }
42 |
43 |
--------------------------------------------------------------------------------
/Interrupt_Descriptor_Table/idt.h:
--------------------------------------------------------------------------------
1 | #ifndef IDT_H
2 | #define IDT_H
3 |
4 | #include "types.h"
5 |
6 | struct IDT
7 | {
8 | uint16 base_low; // lower 16 bits 0-15 of the address to jump to when this interrupt fires
9 | uint16 segment_selector; // code segment selector in GDT
10 | uint8 zero; // unused, always be zero
11 | uint8 type; // types trap, interrupt gates
12 | uint16 base_high; // upper 16 bits 16-31 of the address to jump to
13 | } __attribute__((packed));
14 |
15 |
16 | struct IDT_PTR
17 | {
18 | uint16 limit_size; // limit size of all IDT segments
19 | struct IDT* base_address; // base address of the first IDT segment
20 | } __attribute__((packed));
21 |
22 | extern struct IDT idt_entries[16];
23 | extern struct IDT_PTR idt_first;
24 |
25 | extern void init_idt();
26 |
27 | #endif
28 |
--------------------------------------------------------------------------------
/Interrupt_Descriptor_Table/idt_demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/Interrupt_Descriptor_Table/idt_demo.png
--------------------------------------------------------------------------------
/Interrupt_Descriptor_Table/isr.h:
--------------------------------------------------------------------------------
1 | #ifndef ISR_H
2 | #define ISR_H
3 |
4 | #include "types.h"
5 |
6 | struct registers
7 | {
8 | uint32 ds;
9 | uint32 edi, esi, ebp, esp, ebx, edx, ecx, eax; // pushed by pusha
10 | uint32 int_no, err_code; // interrupt number and error code
11 | uint32 eip, cs, eflags, useresp, ss; // pushed by the processor automatically
12 | };
13 |
14 | extern void isr_0();
15 | extern void isr_1();
16 | extern void isr_2();
17 | extern void isr_3();
18 | extern void isr_4();
19 | extern void isr_5();
20 | extern void isr_6();
21 | extern void isr_7();
22 | extern void isr_8();
23 | extern void isr_9();
24 | extern void isr_10();
25 | extern void isr_11();
26 | extern void isr_12();
27 | extern void isr_13();
28 | extern void isr_14();
29 | extern void isr_15();
30 |
31 | extern void common_isr_stub_handler();
32 | extern void isr_handler(struct registers);
33 |
34 | extern void isr_0_handler();
35 | extern void isr_1_handler();
36 | extern void isr_2_handler();
37 | extern void isr_3_handler();
38 | extern void isr_4_handler();
39 | extern void isr_5_handler();
40 | extern void isr_6_handler();
41 | extern void isr_7_handler();
42 | extern void isr_8_handler();
43 | extern void isr_9_handler();
44 | extern void isr_10_handler();
45 | extern void isr_11_handler();
46 | extern void isr_12_handler();
47 | extern void isr_13_handler();
48 | extern void isr_14_handler();
49 | extern void isr_15_handler();
50 |
51 | #endif
52 |
--------------------------------------------------------------------------------
/Interrupt_Descriptor_Table/kernel.c:
--------------------------------------------------------------------------------
1 | #include "kernel.h"
2 | #include "util.h"
3 | #include "types.h"
4 | #include "gdt.h"
5 | #include "idt.h"
6 |
7 | //index for video buffer array
8 | uint32 vga_index;
9 | //counter to store new lines
10 | static uint32 next_line_index = 1;
11 | //fore & back color values
12 | uint8 g_fore_color = WHITE, g_back_color = BLUE;
13 | //digit ascii code for printing integers
14 | int digit_ascii_codes[10] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
15 |
16 | /*
17 | 16 bit video buffer elements(register ax)
18 | 8 bits(ah) higher :
19 | lower 4 bits - forec olor
20 | higher 4 bits - back color
21 |
22 | 8 bits(al) lower :
23 | 8 bits : ASCII character to print
24 | */
25 | uint16 vga_entry(unsigned char ch, uint8 fore_color, uint8 back_color)
26 | {
27 | uint16 ax = 0;
28 | uint8 ah = 0, al = 0;
29 |
30 | ah = back_color;
31 | ah <<= 4;
32 | ah |= fore_color;
33 | ax = ah;
34 | ax <<= 8;
35 | al = ch;
36 | ax |= al;
37 |
38 | return ax;
39 | }
40 |
41 | //clear video buffer array
42 | void clear_vga_buffer(uint16 **buffer, uint8 fore_color, uint8 back_color)
43 | {
44 | uint32 i;
45 | for(i = 0; i < BUFSIZE; i++){
46 | (*buffer)[i] = vga_entry(NULL, fore_color, back_color);
47 | }
48 | next_line_index = 1;
49 | vga_index = 0;
50 | }
51 |
52 | //initialize vga buffer
53 | void init_vga(uint8 fore_color, uint8 back_color)
54 | {
55 | vga_buffer = (uint16*)VGA_ADDRESS;
56 | clear_vga_buffer(&vga_buffer, fore_color, back_color);
57 | g_fore_color = fore_color;
58 | g_back_color = back_color;
59 | }
60 |
61 | /*
62 | increase vga_index by width of row(80)
63 | */
64 | void print_new_line()
65 | {
66 | if(next_line_index >= 55){
67 | next_line_index = 0;
68 | clear_vga_buffer(&vga_buffer, g_fore_color, g_back_color);
69 | }
70 | vga_index = 80*next_line_index;
71 | next_line_index++;
72 | }
73 |
74 | //assign ascii character to video buffer
75 | void print_char(char ch)
76 | {
77 | vga_buffer[vga_index] = vga_entry(ch, g_fore_color, g_back_color);
78 | vga_index++;
79 | }
80 |
81 | //print string by calling print_char
82 | void print_string(char *str)
83 | {
84 | uint32 index = 0;
85 | while(str[index]){
86 | if(str[index] == '\n')
87 | print_new_line();
88 | else
89 | print_char(str[index]);
90 | index++;
91 | }
92 | }
93 |
94 | //print int by converting it into string
95 | //& then printing string
96 | void print_int(int num)
97 | {
98 | char str_num[digit_count(num)+1];
99 | itoa(num, str_num);
100 | print_string(str_num);
101 | }
102 |
103 |
104 | void kernel_entry()
105 | {
106 | init_gdt();
107 | init_idt();
108 |
109 | init_vga(WHITE, BLACK);
110 |
111 | // set values to registers and raise an interrupt with number
112 | asm volatile("\tmov $12345, %eax");
113 | asm volatile("\tint $0");
114 | asm volatile("\tint $1");
115 | asm volatile("\tint $2");
116 | asm volatile("\tint $3");
117 | asm volatile("\tint $4");
118 | asm volatile("\tint $5");
119 | asm volatile("\tint $6");
120 | asm volatile("\tint $7");
121 | asm volatile("\tint $8");
122 | asm volatile("\tint $9");
123 | asm volatile("\tint $10");
124 | asm volatile("\tint $11");
125 | asm volatile("\tint $12");
126 | asm volatile("\tint $13");
127 | asm volatile("\tint $14");
128 | asm volatile("\tint $15");
129 |
130 | }
131 |
132 |
133 |
134 |
--------------------------------------------------------------------------------
/Interrupt_Descriptor_Table/kernel.h:
--------------------------------------------------------------------------------
1 | #ifndef KERNEL_H
2 | #define KERNEL_H
3 |
4 | #include "types.h"
5 |
6 | #define VGA_ADDRESS 0xB8000
7 | #define BUFSIZE 2200
8 |
9 | uint16* vga_buffer;
10 |
11 | enum vga_color {
12 | BLACK,
13 | BLUE,
14 | GREEN,
15 | CYAN,
16 | RED,
17 | MAGENTA,
18 | BROWN,
19 | GREY,
20 | DARK_GREY,
21 | BRIGHT_BLUE,
22 | BRIGHT_GREEN,
23 | BRIGHT_CYAN,
24 | BRIGHT_RED,
25 | BRIGHT_MAGENTA,
26 | YELLOW,
27 | WHITE,
28 | };
29 |
30 | extern void print_new_line();
31 | extern void print_char(char);
32 | extern void print_string(char *);
33 | extern void print_int(int);
34 |
35 |
36 | #endif
37 |
--------------------------------------------------------------------------------
/Interrupt_Descriptor_Table/linker.ld:
--------------------------------------------------------------------------------
1 | /* entry point of our kernel */
2 | ENTRY(_start)
3 |
4 | SECTIONS
5 | {
6 | /* we need 1MB of space atleast */
7 | . = 1M;
8 |
9 | /* text section */
10 | .text BLOCK(4K) : ALIGN(4K)
11 | {
12 | *(.multiboot)
13 | *(.text)
14 | }
15 |
16 | /* read only data section */
17 | .rodata BLOCK(4K) : ALIGN(4K)
18 | {
19 | *(.rodata)
20 | }
21 |
22 | /* data section */
23 | .data BLOCK(4K) : ALIGN(4K)
24 | {
25 | *(.data)
26 | }
27 |
28 | /* bss section */
29 | .bss BLOCK(4K) : ALIGN(4K)
30 | {
31 | *(COMMON)
32 | *(.bss)
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/Interrupt_Descriptor_Table/load_gdt.s:
--------------------------------------------------------------------------------
1 | .section .text
2 | .global load_gdt
3 |
4 | load_gdt:
5 | mov 4(%esp), %eax
6 | lgdt (%eax)
7 |
8 | mov $0x10, %eax
9 | mov %eax, %ds
10 | mov %eax, %es
11 | mov %eax, %fs
12 | mov %eax, %gs
13 | mov %eax, %ss
14 | jmp $0x8, $.long_jump
15 | .long_jump:
16 | ret
17 |
--------------------------------------------------------------------------------
/Interrupt_Descriptor_Table/load_idt.s:
--------------------------------------------------------------------------------
1 | .section .text
2 | .global load_idt
3 |
4 | load_idt:
5 | mov 4(%esp), %eax
6 | lidt (%eax)
7 | ret
8 |
--------------------------------------------------------------------------------
/Interrupt_Descriptor_Table/run.sh:
--------------------------------------------------------------------------------
1 | #assemble boot.s file
2 | as --32 boot.s -o boot.o
3 | as --32 load_gdt.s -o load_gdt.o
4 | as --32 load_idt.s -o load_idt.o
5 |
6 | #compile kernel.c file
7 | gcc -m32 -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
8 |
9 | #compile util.c file
10 | gcc -m32 -c util.c -o util.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
11 |
12 | #compile gdt.c file
13 | gcc -m32 -c gdt.c -o gdt.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
14 |
15 | #compile idt.c file
16 | gcc -m32 -c idt.c -o idt.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
17 |
18 | #compile isr.c file
19 | gcc -m32 -c isr.c -o isr.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
20 |
21 | #linking the kernel with kernel.o and boot.o files
22 | ld -m elf_i386 -T linker.ld kernel.o util.o boot.o gdt.o load_gdt.o load_idt.o idt.o isr.o -o MyOS.bin -nostdlib
23 |
24 | #check MyOS.bin file is x86 multiboot file or not
25 | grub-file --is-x86-multiboot MyOS.bin
26 |
27 | #building the iso file
28 | mkdir -p isodir/boot/grub
29 | cp MyOS.bin isodir/boot/MyOS.bin
30 | cp grub.cfg isodir/boot/grub/grub.cfg
31 | grub-mkrescue -o MyOS.iso isodir
32 |
33 | #run it in qemu
34 | qemu-system-x86_64 -cdrom MyOS.iso
--------------------------------------------------------------------------------
/Interrupt_Descriptor_Table/types.h:
--------------------------------------------------------------------------------
1 | #ifndef TYPES_H
2 | #define TYPES_H
3 |
4 | #define NULL 0
5 |
6 | typedef unsigned char uint8;
7 | typedef unsigned short uint16;
8 | typedef unsigned int uint32;
9 | typedef signed char sint8;
10 | typedef signed short sint16;
11 | typedef signed int sint32;
12 | typedef uint8 byte;
13 | typedef uint16 word;
14 | typedef uint32 dword;
15 |
16 | #endif
17 |
18 |
--------------------------------------------------------------------------------
/Interrupt_Descriptor_Table/util.c:
--------------------------------------------------------------------------------
1 | #include "util.h"
2 |
3 | uint32 strlen(const char* str)
4 | {
5 | uint32 length = 0;
6 | while(str[length])
7 | length++;
8 | return length;
9 | }
10 |
11 | uint32 digit_count(int num)
12 | {
13 | uint32 count = 0;
14 | if(num == 0)
15 | return 1;
16 | while(num > 0){
17 | count++;
18 | num = num/10;
19 | }
20 | return count;
21 | }
22 |
23 | void itoa(int num, char *number)
24 | {
25 | int dgcount = digit_count(num);
26 | int index = dgcount - 1;
27 | char x;
28 | if(num == 0 && dgcount == 1){
29 | number[0] = '0';
30 | number[1] = '\0';
31 | }else{
32 | while(num != 0){
33 | x = num % 10;
34 | number[index] = x + '0';
35 | index--;
36 | num = num / 10;
37 | }
38 | number[dgcount] = '\0';
39 | }
40 | }
41 |
42 |
43 |
--------------------------------------------------------------------------------
/Kernel/Keyboard/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Kernel/Keyboard/ascii.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/Kernel/Keyboard/ascii.jpg
--------------------------------------------------------------------------------
/Kernel/Keyboard/boot.s:
--------------------------------------------------------------------------------
1 | # set flags to 0
2 | .set FLAGS, 0
3 |
4 | # set magic number to 0x1BADB002 to identified by bootloader
5 | .set MAGIC, 0x1BADB002
6 |
7 | # set the checksum
8 | .set CHECKSUM, -(MAGIC + FLAGS)
9 |
10 | # set multiboot enabled
11 | .section .multiboot
12 |
13 | # define type to long for each data defined as above
14 | .long MAGIC
15 | .long FLAGS
16 | .long CHECKSUM
17 |
18 |
19 | # set the stack bottom
20 | stackBottom:
21 |
22 | # define the maximum size of stack to 512 bytes
23 | .skip 4096
24 |
25 |
26 | # set the stack top which grows from higher to lower
27 | stackTop:
28 |
29 | .section .text
30 | .global _start
31 | .type _start, @function
32 |
33 |
34 | _start:
35 |
36 | # assign current stack pointer location to stackTop
37 | mov $stackTop, %esp
38 |
39 | # call the kernel main function
40 | call kernel_entry
41 |
42 | cli
43 |
44 |
45 | # put system in infinite loop
46 | hltLoop:
47 |
48 | hlt
49 | jmp hltLoop
50 |
51 | .size _start, . - _start
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/Kernel/Keyboard/char.c:
--------------------------------------------------------------------------------
1 | #include "char.h"
2 |
3 | char get_ascii_char(uint8 key_code)
4 | {
5 | switch(key_code){
6 | case KEY_A : return 'A';
7 | case KEY_B : return 'B';
8 | case KEY_C : return 'C';
9 | case KEY_D : return 'D';
10 | case KEY_E : return 'E';
11 | case KEY_F : return 'F';
12 | case KEY_G : return 'G';
13 | case KEY_H : return 'H';
14 | case KEY_I : return 'I';
15 | case KEY_J : return 'J';
16 | case KEY_K : return 'K';
17 | case KEY_L : return 'L';
18 | case KEY_M : return 'M';
19 | case KEY_N : return 'N';
20 | case KEY_O : return 'O';
21 | case KEY_P : return 'P';
22 | case KEY_Q : return 'Q';
23 | case KEY_R : return 'R';
24 | case KEY_S : return 'S';
25 | case KEY_T : return 'T';
26 | case KEY_U : return 'U';
27 | case KEY_V : return 'V';
28 | case KEY_W : return 'W';
29 | case KEY_X : return 'X';
30 | case KEY_Y : return 'Y';
31 | case KEY_Z : return 'Z';
32 | case KEY_1 : return '1';
33 | case KEY_2 : return '2';
34 | case KEY_3 : return '3';
35 | case KEY_4 : return '4';
36 | case KEY_5 : return '5';
37 | case KEY_6 : return '6';
38 | case KEY_7 : return '7';
39 | case KEY_8 : return '8';
40 | case KEY_9 : return '9';
41 | case KEY_0 : return '0';
42 | case KEY_MINUS : return '-';
43 | case KEY_EQUAL : return '=';
44 | case KEY_SQUARE_OPEN_BRACKET : return '[';
45 | case KEY_SQUARE_CLOSE_BRACKET : return ']';
46 | case KEY_SEMICOLON : return ';';
47 | case KEY_BACKSLASH : return '\\';
48 | case KEY_COMMA : return ',';
49 | case KEY_DOT : return '.';
50 | case KEY_FORESLHASH : return '/';
51 | case KEY_SPACE : return ' ';
52 | default : return 0;
53 | }
54 | }
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/Kernel/Keyboard/char.h:
--------------------------------------------------------------------------------
1 | #ifndef CHAR_H
2 | #define CHAR_H
3 |
4 | #include "types.h"
5 | #include "keyboard.h"
6 |
7 |
8 | extern char get_ascii_char(uint8);
9 |
10 | #endif
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Kernel/Keyboard/grub.cfg:
--------------------------------------------------------------------------------
1 | menuentry "MyOS" {
2 | multiboot /boot/MyOS.bin
3 | }
4 |
--------------------------------------------------------------------------------
/Kernel/Keyboard/kernel.c:
--------------------------------------------------------------------------------
1 | #include "kernel.h"
2 | #include "utils.h"
3 | #include "char.h"
4 |
5 | uint32 vga_index;
6 | static uint32 next_line_index = 1;
7 | uint8 g_fore_color = WHITE, g_back_color = BLUE;
8 | int digit_ascii_codes[10] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
9 |
10 | /*
11 | this is same as we did in our assembly code for vga_print_char
12 |
13 | vga_print_char:
14 | mov di, word[VGA_INDEX]
15 | mov al, byte[VGA_CHAR]
16 |
17 | mov ah, byte[VGA_BACK_COLOR]
18 | sal ah, 4
19 | or ah, byte[VGA_FORE_COLOR]
20 |
21 | mov [es:di], ax
22 |
23 | ret
24 |
25 | */
26 | uint16 vga_entry(unsigned char ch, uint8 fore_color, uint8 back_color)
27 | {
28 | uint16 ax = 0;
29 | uint8 ah = 0, al = 0;
30 |
31 | ah = back_color;
32 | ah <<= 4;
33 | ah |= fore_color;
34 | ax = ah;
35 | ax <<= 8;
36 | al = ch;
37 | ax |= al;
38 |
39 | return ax;
40 | }
41 |
42 | void clear_vga_buffer(uint16 **buffer, uint8 fore_color, uint8 back_color)
43 | {
44 | uint32 i;
45 | for(i = 0; i < BUFSIZE; i++){
46 | (*buffer)[i] = vga_entry(NULL, fore_color, back_color);
47 | }
48 | next_line_index = 1;
49 | vga_index = 0;
50 | }
51 |
52 | void init_vga(uint8 fore_color, uint8 back_color)
53 | {
54 | vga_buffer = (uint16*)VGA_ADDRESS;
55 | clear_vga_buffer(&vga_buffer, fore_color, back_color);
56 | g_fore_color = fore_color;
57 | g_back_color = back_color;
58 | }
59 |
60 | void print_new_line()
61 | {
62 | if(next_line_index >= 55){
63 | next_line_index = 0;
64 | clear_vga_buffer(&vga_buffer, g_fore_color, g_back_color);
65 | }
66 | vga_index = 80*next_line_index;
67 | next_line_index++;
68 | }
69 |
70 | void print_char(char ch)
71 | {
72 | vga_buffer[vga_index] = vga_entry(ch, g_fore_color, g_back_color);
73 | vga_index++;
74 | }
75 |
76 | void print_string(char *str)
77 | {
78 | uint32 index = 0;
79 | while(str[index]){
80 | print_char(str[index]);
81 | index++;
82 | }
83 | }
84 |
85 | void print_int(int num)
86 | {
87 | char str_num[digit_count(num)+1];
88 | itoa(num, str_num);
89 | print_string(str_num);
90 | }
91 |
92 | uint8 inb(uint16 port)
93 | {
94 | uint8 ret;
95 | asm volatile("inb %1, %0" : "=a"(ret) : "d"(port));
96 | return ret;
97 | }
98 |
99 | void outb(uint16 port, uint8 data)
100 | {
101 | asm volatile("outb %0, %1" : "=a"(data) : "d"(port));
102 | }
103 |
104 | char get_input_keycode()
105 | {
106 | char ch = 0;
107 | while((ch = inb(KEYBOARD_PORT)) != 0){
108 | if(ch > 0)
109 | return ch;
110 | }
111 | return ch;
112 | }
113 |
114 | /*
115 | keep the cpu busy for doing nothing(nop)
116 | so that io port will not be processed by cpu
117 | here timer can also be used, but lets do this in looping counter
118 | */
119 | void wait_for_io(uint32 timer_count)
120 | {
121 | while(1){
122 | asm volatile("nop");
123 | timer_count--;
124 | if(timer_count <= 0)
125 | break;
126 | }
127 | }
128 |
129 | void sleep(uint32 timer_count)
130 | {
131 | wait_for_io(timer_count);
132 | }
133 |
134 | void test_input()
135 | {
136 | char ch = 0;
137 | char keycode = 0;
138 | do{
139 | keycode = get_input_keycode();
140 | if(keycode == KEY_ENTER){
141 | print_new_line();
142 | }else{
143 | ch = get_ascii_char(keycode);
144 | print_char(ch);
145 | }
146 | sleep(0x02FFFFFF);
147 | }while(ch > 0);
148 | }
149 |
150 | void kernel_entry()
151 | {
152 | init_vga(WHITE, BLUE);
153 | print_string("Type here, one key per second, ENTER to go to next line");
154 | print_new_line();
155 | test_input();
156 |
157 | }
158 |
159 |
--------------------------------------------------------------------------------
/Kernel/Keyboard/kernel.h:
--------------------------------------------------------------------------------
1 | #ifndef KERNEL_H
2 | #define KERNEL_H
3 |
4 | #include "types.h"
5 |
6 | #define NULL 0
7 |
8 | #define VGA_ADDRESS 0xB8000
9 | #define BUFSIZE 2200
10 |
11 | uint16* vga_buffer;
12 |
13 | enum vga_color {
14 | BLACK,
15 | BLUE,
16 | GREEN,
17 | CYAN,
18 | RED,
19 | MAGENTA,
20 | BROWN,
21 | GREY,
22 | DARK_GREY,
23 | BRIGHT_BLUE,
24 | BRIGHT_GREEN,
25 | BRIGHT_CYAN,
26 | BRIGHT_RED,
27 | BRIGHT_MAGENTA,
28 | YELLOW,
29 | WHITE,
30 | };
31 |
32 |
33 | #include "keyboard.h"
34 |
35 |
36 | #endif
37 |
--------------------------------------------------------------------------------
/Kernel/Keyboard/keyboard.h:
--------------------------------------------------------------------------------
1 | #ifndef KEYBOARD_H
2 | #define KEYBOARD_H
3 |
4 | #define KEYBOARD_PORT 0x60
5 |
6 |
7 | #define KEY_A 0x1E
8 | #define KEY_B 0x30
9 | #define KEY_C 0x2E
10 | #define KEY_D 0x20
11 | #define KEY_E 0x12
12 | #define KEY_F 0x21
13 | #define KEY_G 0x22
14 | #define KEY_H 0x23
15 | #define KEY_I 0x17
16 | #define KEY_J 0x24
17 | #define KEY_K 0x25
18 | #define KEY_L 0x26
19 | #define KEY_M 0x32
20 | #define KEY_N 0x31
21 | #define KEY_O 0x18
22 | #define KEY_P 0x19
23 | #define KEY_Q 0x10
24 | #define KEY_R 0x13
25 | #define KEY_S 0x1F
26 | #define KEY_T 0x14
27 | #define KEY_U 0x16
28 | #define KEY_V 0x2F
29 | #define KEY_W 0x11
30 | #define KEY_X 0x2D
31 | #define KEY_Y 0x15
32 | #define KEY_Z 0x2C
33 | #define KEY_1 0x02
34 | #define KEY_2 0x03
35 | #define KEY_3 0x04
36 | #define KEY_4 0x05
37 | #define KEY_5 0x06
38 | #define KEY_6 0x07
39 | #define KEY_7 0x08
40 | #define KEY_8 0x09
41 | #define KEY_9 0x0A
42 | #define KEY_0 0x0B
43 | #define KEY_MINUS 0x0C
44 | #define KEY_EQUAL 0x0D
45 | #define KEY_SQUARE_OPEN_BRACKET 0x1A
46 | #define KEY_SQUARE_CLOSE_BRACKET 0x1B
47 | #define KEY_SEMICOLON 0x27
48 | #define KEY_BACKSLASH 0x2B
49 | #define KEY_COMMA 0x33
50 | #define KEY_DOT 0x34
51 | #define KEY_FORESLHASH 0x35
52 | #define KEY_F1 0x3B
53 | #define KEY_F2 0x3C
54 | #define KEY_F3 0x3D
55 | #define KEY_F4 0x3E
56 | #define KEY_F5 0x3F
57 | #define KEY_F6 0x40
58 | #define KEY_F7 0x41
59 | #define KEY_F8 0x42
60 | #define KEY_F9 0x43
61 | #define KEY_F10 0x44
62 | #define KEY_F11 0x85
63 | #define KEY_F12 0x86
64 | #define KEY_BACKSPACE 0x0E
65 | #define KEY_DELETE 0x53
66 | #define KEY_DOWN 0x50
67 | #define KEY_END 0x4F
68 | #define KEY_ENTER 0x1C
69 | #define KEY_ESC 0x01
70 | #define KEY_HOME 0x47
71 | #define KEY_INSERT 0x52
72 | #define KEY_KEYPAD_5 0x4C
73 | #define KEY_KEYPAD_MUL 0x37
74 | #define KEY_KEYPAD_Minus 0x4A
75 | #define KEY_KEYPAD_PLUS 0x4E
76 | #define KEY_KEYPAD_DIV 0x35
77 | #define KEY_LEFT 0x4B
78 | #define KEY_PAGE_DOWN 0x51
79 | #define KEY_PAGE_UP 0x49
80 | #define KEY_PRINT_SCREEN 0x37
81 | #define KEY_RIGHT 0x4D
82 | #define KEY_SPACE 0x39
83 | #define KEY_TAB 0x0F
84 | #define KEY_UP 0x48
85 |
86 |
87 | #endif
88 |
89 |
--------------------------------------------------------------------------------
/Kernel/Keyboard/keyboard_demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/Kernel/Keyboard/keyboard_demo.png
--------------------------------------------------------------------------------
/Kernel/Keyboard/keycodes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/Kernel/Keyboard/keycodes.png
--------------------------------------------------------------------------------
/Kernel/Keyboard/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 | }
40 |
41 | /* The compiler may produce other sections, by default it will put them in
42 | a segment with the same name. Simply add stuff here as needed. */
43 | }
44 |
--------------------------------------------------------------------------------
/Kernel/Keyboard/run.sh:
--------------------------------------------------------------------------------
1 | #assemble boot.s file
2 | as --32 boot.s -o boot.o
3 |
4 | #compile kernel.c file
5 | gcc -m32 -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
6 |
7 | gcc -m32 -c utils.c -o utils.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
8 |
9 | gcc -m32 -c char.c -o char.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
10 |
11 | #linking the kernel with kernel.o and boot.o files
12 | ld -m elf_i386 -T linker.ld kernel.o utils.o char.o boot.o -o MyOS.bin -nostdlib
13 |
14 | #check MyOS.bin file is x86 multiboot file or not
15 | grub-file --is-x86-multiboot MyOS.bin
16 |
17 | #building the iso file
18 | mkdir -p isodir/boot/grub
19 | cp MyOS.bin isodir/boot/MyOS.bin
20 | cp grub.cfg isodir/boot/grub/grub.cfg
21 | grub-mkrescue -o MyOS.iso isodir
22 |
23 | #run it in qemu
24 | qemu-system-x86_64 -cdrom MyOS.iso
25 |
--------------------------------------------------------------------------------
/Kernel/Keyboard/types.h:
--------------------------------------------------------------------------------
1 | #ifndef TYPES_H
2 | #define TYPES_H
3 |
4 | typedef unsigned char uint8;
5 | typedef unsigned short uint16;
6 | typedef unsigned int uint32;
7 |
8 | #endif
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Kernel/Keyboard/utils.c:
--------------------------------------------------------------------------------
1 | #include "utils.h"
2 |
3 | uint32 strlen(const char* str)
4 | {
5 | uint32 length = 0;
6 | while(str[length])
7 | length++;
8 | return length;
9 | }
10 |
11 | uint32 digit_count(int num)
12 | {
13 | uint32 count = 0;
14 | if(num == 0)
15 | return 1;
16 | while(num > 0){
17 | count++;
18 | num = num/10;
19 | }
20 | return count;
21 | }
22 |
23 | void itoa(int num, char *number)
24 | {
25 | int dgcount = digit_count(num);
26 | int index = dgcount - 1;
27 | char x;
28 | if(num == 0 && dgcount == 1){
29 | number[0] = '0';
30 | number[1] = '\0';
31 | }else{
32 | while(num != 0){
33 | x = num % 10;
34 | number[index] = x + '0';
35 | index--;
36 | num = num / 10;
37 | }
38 | number[dgcount] = '\0';
39 | }
40 | }
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/Kernel/Keyboard/utils.h:
--------------------------------------------------------------------------------
1 | #ifndef UTILS_H
2 | #define UTILS_H
3 |
4 | #include "types.h"
5 |
6 | extern uint32 strlen(const char*);
7 | extern uint32 digit_count(int);
8 | extern void itoa(int, char *);
9 |
10 | #endif
11 |
12 |
--------------------------------------------------------------------------------
/Kernel/Simple/img/kernel_1/MyOS.iso:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/Kernel/Simple/img/kernel_1/MyOS.iso
--------------------------------------------------------------------------------
/Kernel/Simple/img/kernel_2/MyOS.iso:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/Kernel/Simple/img/kernel_2/MyOS.iso
--------------------------------------------------------------------------------
/Kernel/Simple/src/kernel_1/boot.s:
--------------------------------------------------------------------------------
1 | # set magic number to 0x1BADB002 to identified by bootloader
2 | .set MAGIC, 0x1BADB002
3 |
4 | # set flags to 0
5 | .set FLAGS, 0
6 |
7 | # set the checksum
8 | .set CHECKSUM, -(MAGIC + FLAGS)
9 |
10 | # set multiboot enabled
11 | .section .multiboot
12 |
13 | # define type to long for each data defined as above
14 | .long MAGIC
15 | .long FLAGS
16 | .long CHECKSUM
17 |
18 |
19 | # set the stack bottom
20 | stackBottom:
21 |
22 | # define the maximum size of stack to 512 bytes
23 | .skip 1024
24 |
25 |
26 | # set the stack top which grows from higher to lower
27 | stackTop:
28 |
29 | .section .text
30 | .global _start
31 | .type _start, @function
32 |
33 |
34 | _start:
35 |
36 | # assign current stack pointer location to stackTop
37 | mov $stackTop, %esp
38 |
39 | # call the kernel main source
40 | call kernel_entry
41 |
42 | cli
43 |
44 |
45 | # put system in infinite loop
46 | hltLoop:
47 |
48 | hlt
49 | jmp hltLoop
50 |
51 | .size _start, . - _start
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/Kernel/Simple/src/kernel_1/grub.cfg:
--------------------------------------------------------------------------------
1 | menuentry "MyOS" {
2 | multiboot /boot/MyOS.bin
3 | }
4 |
--------------------------------------------------------------------------------
/Kernel/Simple/src/kernel_1/kernel.c:
--------------------------------------------------------------------------------
1 | #include "kernel.h"
2 |
3 | /*
4 | 16 bit video buffer elements(register ax)
5 | 8 bits(ah) higher :
6 | lower 4 bits - forec olor
7 | higher 4 bits - back color
8 |
9 | 8 bits(al) lower :
10 | 8 bits : ASCII character to print
11 | */
12 | uint16 vga_entry(unsigned char ch, uint8 fore_color, uint8 back_color)
13 | {
14 | uint16 ax = 0;
15 | uint8 ah = 0, al = 0;
16 |
17 | ah = back_color;
18 | ah <<= 4;
19 | ah |= fore_color;
20 | ax = ah;
21 | ax <<= 8;
22 | al = ch;
23 | ax |= al;
24 |
25 | return ax;
26 | }
27 |
28 | //clear video buffer array
29 | void clear_vga_buffer(uint16 **buffer, uint8 fore_color, uint8 back_color)
30 | {
31 | uint32 i;
32 | for(i = 0; i < BUFSIZE; i++){
33 | (*buffer)[i] = vga_entry(NULL, fore_color, back_color);
34 | }
35 | }
36 |
37 | //initialize vga buffer
38 | void init_vga(uint8 fore_color, uint8 back_color)
39 | {
40 | vga_buffer = (uint16*)VGA_ADDRESS; //point vga_buffer pointer to VGA_ADDRESS
41 | clear_vga_buffer(&vga_buffer, fore_color, back_color); //clear buffer
42 | }
43 |
44 | void kernel_entry()
45 | {
46 | //first init vga with fore & back colors
47 | init_vga(WHITE, BLACK);
48 |
49 | //assign each ASCII character to video buffer
50 | //you can change colors here
51 | vga_buffer[0] = vga_entry('H', WHITE, BLACK);
52 | vga_buffer[1] = vga_entry('e', WHITE, BLACK);
53 | vga_buffer[2] = vga_entry('l', WHITE, BLACK);
54 | vga_buffer[3] = vga_entry('l', WHITE, BLACK);
55 | vga_buffer[4] = vga_entry('o', WHITE, BLACK);
56 | vga_buffer[5] = vga_entry(' ', WHITE, BLACK);
57 | vga_buffer[6] = vga_entry('W', WHITE, BLACK);
58 | vga_buffer[7] = vga_entry('o', WHITE, BLACK);
59 | vga_buffer[8] = vga_entry('r', WHITE, BLACK);
60 | vga_buffer[9] = vga_entry('l', WHITE, BLACK);
61 | vga_buffer[10] = vga_entry('d', WHITE, BLACK);
62 | }
63 |
--------------------------------------------------------------------------------
/Kernel/Simple/src/kernel_1/kernel.h:
--------------------------------------------------------------------------------
1 | #ifndef KERNEL_H
2 | #define KERNEL_H
3 |
4 | typedef unsigned char uint8;
5 | typedef unsigned short uint16;
6 | typedef unsigned int uint32;
7 |
8 |
9 | #define VGA_ADDRESS 0xB8000
10 | #define BUFSIZE 2200
11 |
12 | uint16* vga_buffer;
13 |
14 | #define NULL 0
15 |
16 | enum vga_color {
17 | BLACK,
18 | BLUE,
19 | GREEN,
20 | CYAN,
21 | RED,
22 | MAGENTA,
23 | BROWN,
24 | GREY,
25 | DARK_GREY,
26 | BRIGHT_BLUE,
27 | BRIGHT_GREEN,
28 | BRIGHT_CYAN,
29 | BRIGHT_RED,
30 | BRIGHT_MAGENTA,
31 | YELLOW,
32 | WHITE,
33 | };
34 |
35 | #endif
--------------------------------------------------------------------------------
/Kernel/Simple/src/kernel_1/linker.ld:
--------------------------------------------------------------------------------
1 | /* entry point of our kernel */
2 | ENTRY(_start)
3 |
4 | SECTIONS
5 | {
6 | /* we need 1MB of space atleast */
7 | . = 1M;
8 |
9 | /* text section */
10 | .text BLOCK(4K) : ALIGN(4K)
11 | {
12 | *(.multiboot)
13 | *(.text)
14 | }
15 |
16 | /* read only data section */
17 | .rodata BLOCK(4K) : ALIGN(4K)
18 | {
19 | *(.rodata)
20 | }
21 |
22 | /* data section */
23 | .data BLOCK(4K) : ALIGN(4K)
24 | {
25 | *(.data)
26 | }
27 |
28 | /* bss section */
29 | .bss BLOCK(4K) : ALIGN(4K)
30 | {
31 | *(COMMON)
32 | *(.bss)
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/Kernel/Simple/src/kernel_1/run.sh:
--------------------------------------------------------------------------------
1 | #assemble boot.s file
2 | as --32 boot.s -o boot.o
3 |
4 | #compile kernel.c file
5 | gcc -m32 -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
6 |
7 | #linking the kernel with kernel.o and boot.o files
8 | ld -m elf_i386 -T linker.ld kernel.o boot.o -o MyOS.bin -nostdlib
9 |
10 | #check MyOS.bin file is x86 multiboot file or not
11 | grub-file --is-x86-multiboot MyOS.bin
12 |
13 | #building the iso file
14 | mkdir -p isodir/boot/grub
15 | cp MyOS.bin isodir/boot/MyOS.bin
16 | cp grub.cfg isodir/boot/grub/grub.cfg
17 | grub-mkrescue -o MyOS.iso isodir
18 |
19 | #run it in qemu
20 | qemu-system-x86_64 -cdrom MyOS.iso
21 |
--------------------------------------------------------------------------------
/Kernel/Simple/src/kernel_2/boot.s:
--------------------------------------------------------------------------------
1 | # set magic number to 0x1BADB002 to identified by bootloader
2 | .set MAGIC, 0x1BADB002
3 |
4 | # set flags to 0
5 | .set FLAGS, 0
6 |
7 | # set the checksum
8 | .set CHECKSUM, -(MAGIC + FLAGS)
9 |
10 | # set multiboot enabled
11 | .section .multiboot
12 |
13 | # define type to long for each data defined as above
14 | .long MAGIC
15 | .long FLAGS
16 | .long CHECKSUM
17 |
18 |
19 | # set the stack bottom
20 | stackBottom:
21 |
22 | # define the maximum size of stack to 512 bytes
23 | .skip 1024
24 |
25 |
26 | # set the stack top which grows from higher to lower
27 | stackTop:
28 |
29 | .section .text
30 | .global _start
31 | .type _start, @function
32 |
33 |
34 | _start:
35 |
36 | # assign current stack pointer location to stackTop
37 | mov $stackTop, %esp
38 |
39 | # call the kernel main source
40 | call kernel_entry
41 |
42 | cli
43 |
44 |
45 | # put system in infinite loop
46 | hltLoop:
47 |
48 | hlt
49 | jmp hltLoop
50 |
51 | .size _start, . - _start
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/Kernel/Simple/src/kernel_2/grub.cfg:
--------------------------------------------------------------------------------
1 | menuentry "MyOS" {
2 | multiboot /boot/MyOS.bin
3 | }
4 |
--------------------------------------------------------------------------------
/Kernel/Simple/src/kernel_2/kernel.c:
--------------------------------------------------------------------------------
1 | #include "kernel.h"
2 |
3 | //index for video buffer array
4 | uint32 vga_index;
5 | //counter to store new lines
6 | static uint32 next_line_index = 1;
7 | //fore & back color values
8 | uint8 g_fore_color = WHITE, g_back_color = BLUE;
9 | //digit ascii code for printing integers
10 | int digit_ascii_codes[10] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
11 |
12 | /*
13 | 16 bit video buffer elements(register ax)
14 | 8 bits(ah) higher :
15 | lower 4 bits - forec olor
16 | higher 4 bits - back color
17 |
18 | 8 bits(al) lower :
19 | 8 bits : ASCII character to print
20 | */
21 | uint16 vga_entry(unsigned char ch, uint8 fore_color, uint8 back_color)
22 | {
23 | uint16 ax = 0;
24 | uint8 ah = 0, al = 0;
25 |
26 | ah = back_color;
27 | ah <<= 4;
28 | ah |= fore_color;
29 | ax = ah;
30 | ax <<= 8;
31 | al = ch;
32 | ax |= al;
33 |
34 | return ax;
35 | }
36 |
37 | //clear video buffer array
38 | void clear_vga_buffer(uint16 **buffer, uint8 fore_color, uint8 back_color)
39 | {
40 | uint32 i;
41 | for(i = 0; i < BUFSIZE; i++){
42 | (*buffer)[i] = vga_entry(NULL, fore_color, back_color);
43 | }
44 | next_line_index = 1;
45 | vga_index = 0;
46 | }
47 |
48 | //initialize vga buffer
49 | void init_vga(uint8 fore_color, uint8 back_color)
50 | {
51 | vga_buffer = (uint16*)VGA_ADDRESS;
52 | clear_vga_buffer(&vga_buffer, fore_color, back_color);
53 | g_fore_color = fore_color;
54 | g_back_color = back_color;
55 | }
56 |
57 | /*
58 | increase vga_index by width of row(80)
59 | */
60 | void print_new_line()
61 | {
62 | if(next_line_index >= 55){
63 | next_line_index = 0;
64 | clear_vga_buffer(&vga_buffer, g_fore_color, g_back_color);
65 | }
66 | vga_index = 80*next_line_index;
67 | next_line_index++;
68 | }
69 |
70 | //assign ascii character to video buffer
71 | void print_char(char ch)
72 | {
73 | vga_buffer[vga_index] = vga_entry(ch, g_fore_color, g_back_color);
74 | vga_index++;
75 | }
76 |
77 |
78 | uint32 strlen(const char* str)
79 | {
80 | uint32 length = 0;
81 | while(str[length])
82 | length++;
83 | return length;
84 | }
85 |
86 | uint32 digit_count(int num)
87 | {
88 | uint32 count = 0;
89 | if(num == 0)
90 | return 1;
91 | while(num > 0){
92 | count++;
93 | num = num/10;
94 | }
95 | return count;
96 | }
97 |
98 | void itoa(int num, char *number)
99 | {
100 | int dgcount = digit_count(num);
101 | int index = dgcount - 1;
102 | char x;
103 | if(num == 0 && dgcount == 1){
104 | number[0] = '0';
105 | number[1] = '\0';
106 | }else{
107 | while(num != 0){
108 | x = num % 10;
109 | number[index] = x + '0';
110 | index--;
111 | num = num / 10;
112 | }
113 | number[dgcount] = '\0';
114 | }
115 | }
116 |
117 | //print string by calling print_char
118 | void print_string(char *str)
119 | {
120 | uint32 index = 0;
121 | while(str[index]){
122 | print_char(str[index]);
123 | index++;
124 | }
125 | }
126 |
127 | //print int by converting it into string
128 | //& then printing string
129 | void print_int(int num)
130 | {
131 | char str_num[digit_count(num)+1];
132 | itoa(num, str_num);
133 | print_string(str_num);
134 | }
135 |
136 |
137 | void kernel_entry()
138 | {
139 | //first init vga with fore & back colors
140 | init_vga(WHITE, BLACK);
141 |
142 | /*call above function to print something
143 | here to change the fore & back color
144 | assign g_fore_color & g_back_color to color values
145 | g_fore_color = BRIGHT_RED;
146 | */
147 | print_string("Hello World!");
148 | print_new_line();
149 | print_int(123456789);
150 | print_new_line();
151 | print_string("Goodbye World!");
152 |
153 | }
--------------------------------------------------------------------------------
/Kernel/Simple/src/kernel_2/kernel.h:
--------------------------------------------------------------------------------
1 | #ifndef KERNEL_H
2 | #define KERNEL_H
3 |
4 | typedef unsigned char uint8;
5 | typedef unsigned short uint16;
6 | typedef unsigned int uint32;
7 |
8 |
9 | #define VGA_ADDRESS 0xB8000
10 | #define BUFSIZE 2200
11 |
12 | uint16* vga_buffer;
13 |
14 | #define NULL 0
15 |
16 | enum vga_color {
17 | BLACK,
18 | BLUE,
19 | GREEN,
20 | CYAN,
21 | RED,
22 | MAGENTA,
23 | BROWN,
24 | GREY,
25 | DARK_GREY,
26 | BRIGHT_BLUE,
27 | BRIGHT_GREEN,
28 | BRIGHT_CYAN,
29 | BRIGHT_RED,
30 | BRIGHT_MAGENTA,
31 | YELLOW,
32 | WHITE,
33 | };
34 |
35 | #endif
36 |
--------------------------------------------------------------------------------
/Kernel/Simple/src/kernel_2/linker.ld:
--------------------------------------------------------------------------------
1 | /* entry point of our kernel */
2 | ENTRY(_start)
3 |
4 | SECTIONS
5 | {
6 | /* we need 1MB of space atleast */
7 | . = 1M;
8 |
9 | /* text section */
10 | .text BLOCK(4K) : ALIGN(4K)
11 | {
12 | *(.multiboot)
13 | *(.text)
14 | }
15 |
16 | /* read only data section */
17 | .rodata BLOCK(4K) : ALIGN(4K)
18 | {
19 | *(.rodata)
20 | }
21 |
22 | /* data section */
23 | .data BLOCK(4K) : ALIGN(4K)
24 | {
25 | *(.data)
26 | }
27 |
28 | /* bss section */
29 | .bss BLOCK(4K) : ALIGN(4K)
30 | {
31 | *(COMMON)
32 | *(.bss)
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/Kernel/Simple/src/kernel_2/run.sh:
--------------------------------------------------------------------------------
1 | #assemble boot.s file
2 | as --32 boot.s -o boot.o
3 |
4 | #compile kernel.c file
5 | gcc -m32 -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
6 |
7 | #linking the kernel with kernel.o and boot.o files
8 | ld -m elf_i386 -T linker.ld kernel.o boot.o -o MyOS.bin -nostdlib
9 |
10 | #check MyOS.bin file is x86 multiboot file or not
11 | grub-file --is-x86-multiboot MyOS.bin
12 |
13 | #building the iso file
14 | mkdir -p isodir/boot/grub
15 | cp MyOS.bin isodir/boot/MyOS.bin
16 | cp grub.cfg isodir/boot/grub/grub.cfg
17 | grub-mkrescue -o MyOS.iso isodir
18 |
19 | #run it in qemu
20 | qemu-system-x86_64 -cdrom MyOS.iso
21 |
--------------------------------------------------------------------------------
/Kernel/util.h:
--------------------------------------------------------------------------------
1 | #ifndef UTIL_H
2 | #define UTIL_H
3 |
4 | #include "types.h"
5 |
6 | extern uint32 strlen(const char*);
7 | extern uint32 digit_count(int);
8 | extern void itoa(int, char *);
9 |
10 | #endif
11 |
--------------------------------------------------------------------------------
/Pong-Game/bitmap.c:
--------------------------------------------------------------------------------
1 | #include "bitmap.h"
2 | #include "types.h"
3 | #include "vga.h"
4 |
5 |
6 | // 0 = no-pixel, 1 = pixel
7 |
8 | uint8 bitmaps_0_9[10][BITMAP_SIZE] = {
9 | // 0
10 | {0b01111110, 0b11000011, 0b11000111, 0b11001111,
11 | 0b11011011, 0b11110011, 0b11100011, 0b01111110},
12 |
13 | // 1
14 | {0b00011000, 0b00111000, 0b00111000, 0b00011000,
15 | 0b00011000, 0b00011000, 0b01111110, 0b01111110},
16 |
17 | // 2
18 | {0b00111100, 0b11100111, 0b00000111, 0b00000110,
19 | 0b00011110, 0b01111000, 0b11100011, 0b11111111},
20 |
21 | // 3
22 | {0b00111100, 0b11100111, 0b00000111, 0b00011100,
23 | 0b00000111, 0b00000111, 0b11100110, 0b00111100},
24 |
25 | // 4
26 | {0b00011100, 0b00111100, 0b01101100, 0b11001100,
27 | 0b11001100, 0b11111110, 0b00001100, 0b00011110},
28 |
29 | // 5
30 | {0b11111111, 0b11000000, 0b11111110, 0b00000111,
31 | 0b00000111, 0b00000111, 0b11000110, 0b01111110},
32 |
33 | // 6
34 | {0b00011100, 0b00110000, 0b01100000, 0b11000000,
35 | 0b11111110, 0b11000011, 0b11000011, 0b01111110},
36 |
37 | // 7
38 | {0b11111111, 0b11111111, 0b11000111, 0b00000111,
39 | 0b00001110, 0b00111000, 0b00111000, 0b00111000},
40 |
41 | // 8
42 | {0b01111110, 0b01111110, 0b11000011, 0b11000011,
43 | 0b01111110, 0b11000011, 0b11000011, 0b01111110},
44 |
45 | // 9
46 | {0b01111110, 0b11000011, 0b11000011, 0b01111111,
47 | 0b00000011, 0b00000111, 0b00001110, 0b01111100},
48 | };
49 |
50 |
51 | uint8 bitmaps_A_Z[26][BITMAP_SIZE] = {
52 | // A
53 | {0b00011000, 0b00111100, 0b01100110, 0b11000011,
54 | 0b11000011, 0b11111111, 0b11000011, 0b11000011},
55 |
56 | // B
57 | {0b11111100, 0b01100110, 0b01100110, 0b01111100,
58 | 0b01111100, 0b01100110, 0b01100110, 0b11111100},
59 |
60 | // C
61 | {0b00111110, 0b01100011, 0b11000000, 0b11000000,
62 | 0b11000000, 0b11000000, 0b01100011, 0b00111110},
63 |
64 | // D
65 | {0b11111100, 0b01100110, 0b01100011, 0b01100011,
66 | 0b01100011, 0b01100011, 0b01100110, 0b11111100},
67 |
68 | // E
69 | {0b11111111, 0b01100001, 0b01100000, 0b01100100,
70 | 0b01111100, 0b01100100, 0b01100001, 0b11111111},
71 |
72 | // F
73 | {0b11111111, 0b01100001, 0b01100000, 0b01100100,
74 | 0b01111100, 0b01100100, 0b01100000, 0b11110000},
75 |
76 | // G
77 | {0b00111110, 0b01100011, 0b11000000, 0b11000000,
78 | 0b11000111, 0b11100011, 0b01100011, 0b00111111},
79 |
80 | // H
81 | {0b11000011, 0b11000011, 0b11000011, 0b11000011,
82 | 0b11111111, 0b11000011, 0b11000011, 0b11000011},
83 |
84 | // I
85 | {0b01111110, 0b00011000, 0b00011000, 0b00011000,
86 | 0b00011000, 0b00011000, 0b00011000, 0b01111110},
87 |
88 | // J
89 | {0b00001111, 0b00000110, 0b00000110, 0b00000110,
90 | 0b00000110, 0b11000110, 0b11000110, 0b01111100},
91 |
92 | // K
93 | {0b11100011, 0b01100011, 0b01100110, 0b01101100,
94 | 0b01111000, 0b01101100, 0b01100110, 0b11100011},
95 |
96 | // L
97 | {0b11110000, 0b01100000, 0b01100000, 0b01100000,
98 | 0b01100000, 0b01100001, 0b01100011, 0b11111111},
99 |
100 | // M
101 | {0b11000011, 0b11100111, 0b11111111, 0b11111111,
102 | 0b11011011, 0b11000011, 0b11000011, 0b11000011},
103 |
104 | // N
105 | {0b11000011, 0b11100011, 0b11110011, 0b11011011,
106 | 0b11001111, 0b11000111, 0b11000011, 0b11000011},
107 |
108 | // O
109 | {0b00111100, 0b01100110, 0b11000011, 0b11000011,
110 | 0b11000011, 0b11000011, 0b01100110, 0b00111100},
111 |
112 | // P
113 | {0b11111110, 0b01100011, 0b01100011, 0b01100011,
114 | 0b01111110, 0b01100000, 0b01100000, 0b11110000},
115 |
116 | // Q
117 | {0b01111110, 0b11000011, 0b11000011, 0b11000011,
118 | 0b11000011, 0b11001111, 0b01111110, 0b00001111},
119 |
120 | // R
121 | {0b11111110, 0b01100011, 0b01100011, 0b01111110,
122 | 0b01101110, 0b01100110, 0b01100011, 0b11100011},
123 |
124 | // S
125 | {0b01111110, 0b11000011, 0b11100000, 0b01110000,
126 | 0b00011111, 0b00000011, 0b11000110, 0b01111100},
127 |
128 | // T
129 | {0b11111111, 0b10011001, 0b00011000, 0b00011000,
130 | 0b00011000, 0b00011000, 0b00011000, 0b00111100},
131 |
132 | // U
133 | {0b11000011, 0b11000011, 0b11000011, 0b11000011,
134 | 0b11000011, 0b11000011, 0b11000011, 0b11111111},
135 |
136 | // V
137 | {0b11000011, 0b11000011, 0b11000011, 0b11000011,
138 | 0b11000011, 0b11000011, 0b00111100, 0b00011000},
139 |
140 | // W
141 | {0b11000011, 0b11000011, 0b11000011, 0b11000011,
142 | 0b11011011, 0b11111111, 0b11100111, 0b11000011},
143 |
144 | // X
145 | {0b11000011, 0b11000011, 0b01100110, 0b01100110,
146 | 0b00111100, 0b00111100, 0b01100111, 0b11000011},
147 |
148 | // Y
149 | {0b11000011, 0b11000011, 0b11000011, 0b11000011,
150 | 0b01111110, 0b000011000, 0b00011000, 0b00111100},
151 |
152 | // Z
153 | {0b11111111, 0b11000011, 0b10000110, 0b00001100,
154 | 0b00011000, 0b00110001, 0b01100011, 0b11111111}
155 |
156 | };
157 |
158 | // putpixels of 0-9 bits from right-to-left
159 | void draw_num_bitmaps(uint16 index, uint16 x, uint16 y, uint8 color)
160 | {
161 | uint16 temp = 0, pix = 0;
162 |
163 | for(uint8 i = 0; i < BITMAP_SIZE; i++){
164 | temp = x;
165 | x += BITMAP_SIZE;
166 | pix = bitmaps_0_9[index][i];
167 | while(pix > 0){
168 | if(pix & 1){
169 | putpixel(x, y, color);
170 | }
171 | pix >>= 1;
172 | x--;
173 | }
174 | x = temp;
175 | y++;
176 | }
177 | }
178 |
179 | // putpixels of A-Z bits from right-to-left
180 | void draw_alpha_bitmaps(uint16 index, uint16 x, uint16 y, uint8 color)
181 | {
182 | uint16 temp = 0, pix = 0;
183 |
184 | for(uint8 i = 0; i < BITMAP_SIZE; i++){
185 | temp = x;
186 | x += BITMAP_SIZE;
187 | pix = bitmaps_A_Z[index][i];
188 | while(pix > 0){
189 | if(pix & 1){
190 | putpixel(x, y, color);
191 | }
192 | pix >>= 1;
193 | x--;
194 | }
195 | x = temp;
196 | y++;
197 | }
198 | }
199 |
200 | void draw_char(uint16 x, uint16 y, uint8 color, char ch)
201 | {
202 | if(ch >= '0' && ch <= '9'){
203 | draw_num_bitmaps(ch - '0', x, y, color);
204 | }else if(ch >= 'A' && ch <= 'Z'){
205 | draw_alpha_bitmaps((ch - '0') - 17, x, y, color);
206 | }
207 | }
208 |
209 | void draw_string(uint16 x, uint16 y, uint8 color, char *str)
210 | {
211 | uint32 index = 0;
212 |
213 | while(str[index]){
214 | draw_char(x, y, color, str[index]);
215 | x += BITMAP_SIZE + 1;
216 | index++;
217 | }
218 | }
219 |
220 |
--------------------------------------------------------------------------------
/Pong-Game/bitmap.h:
--------------------------------------------------------------------------------
1 | #ifndef BITMAP_H
2 | #define BITMAP_H
3 |
4 | #include "types.h"
5 |
6 | #define BITMAP_SIZE 8
7 |
8 | void draw_char(uint16 x, uint16 y, uint8 color, char ch);
9 | void draw_string(uint16 x, uint16 y, uint8 color, char *str);
10 |
11 | #endif
12 |
--------------------------------------------------------------------------------
/Pong-Game/boot.s:
--------------------------------------------------------------------------------
1 | # set magic number to 0x1BADB002 to identified by bootloader
2 | .set MAGIC, 0x1BADB002
3 |
4 | # set flags to 0
5 | .set FLAGS, 0
6 |
7 | # set the checksum
8 | .set CHECKSUM, -(MAGIC + FLAGS)
9 |
10 | # set multiboot enabled
11 | .section .multiboot
12 |
13 | # define type to long for each data defined as above
14 | .long MAGIC
15 | .long FLAGS
16 | .long CHECKSUM
17 |
18 |
19 | # set the stack bottom
20 | stackBottom:
21 |
22 | # define the maximum size of stack to 512 bytes
23 | .skip 1024
24 |
25 |
26 | # set the stack top which grows from higher to lower
27 | stackTop:
28 |
29 | .section .text
30 | .global _start
31 | .global load_gdt
32 | .type _start, @function
33 |
34 | load_gdt:
35 | mov 4(%esp), %eax
36 | lgdt (%eax)
37 |
38 | mov $0x10, %eax
39 | mov %eax, %ds
40 | mov %eax, %es
41 | mov %eax, %fs
42 | mov %eax, %gs
43 | mov %eax, %ss
44 | jmp $0x8, $.long_jump
45 | .long_jump:
46 | ret
47 |
48 |
49 | _start:
50 |
51 | # assign current stack pointer location to stackTop
52 | mov $stackTop, %esp
53 |
54 | # call the kernel main source
55 | call kernel_entry
56 |
57 | cli
58 |
59 |
60 | # put system in infinite loop
61 | hltLoop:
62 |
63 | hlt
64 | jmp hltLoop
65 |
66 | .size _start, . - _start
67 |
68 |
69 |
--------------------------------------------------------------------------------
/Pong-Game/clean.sh:
--------------------------------------------------------------------------------
1 | # clean all object files and folder but keep iso
2 | rm *.o
3 | rm -r isodir
4 | rm Pong_Game.bin
5 |
--------------------------------------------------------------------------------
/Pong-Game/game_screenshots/Pong_Game_Intro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/Pong-Game/game_screenshots/Pong_Game_Intro.png
--------------------------------------------------------------------------------
/Pong-Game/game_screenshots/Pong_Game_Lose.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/Pong-Game/game_screenshots/Pong_Game_Lose.png
--------------------------------------------------------------------------------
/Pong-Game/game_screenshots/Pong_Game_Play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/Pong-Game/game_screenshots/Pong_Game_Play.png
--------------------------------------------------------------------------------
/Pong-Game/grub.cfg:
--------------------------------------------------------------------------------
1 | menuentry "Pong Game" {
2 | multiboot /boot/Pong_Game.bin
3 | }
4 |
--------------------------------------------------------------------------------
/Pong-Game/kernel.c:
--------------------------------------------------------------------------------
1 | #include "kernel.h"
2 | #include "vga.h"
3 | #include "keyboard.h"
4 | #include "pong.h"
5 |
6 |
7 | uint8 inb(uint16 port)
8 | {
9 | uint8 data;
10 | asm volatile("inb %1, %0" : "=a"(data) : "Nd"(port));
11 | return data;
12 | }
13 |
14 | void outb(uint16 port, uint8 data)
15 | {
16 | asm volatile("outb %0, %1" : : "a"(data), "Nd"(port));
17 | }
18 |
19 | uint8 get_input_keycode()
20 | {
21 | uint8 keycode = 0;
22 | while((keycode = inb(KEYBOARD_PORT)) != 0){
23 | if(keycode > 0)
24 | return keycode;
25 | }
26 | return keycode;
27 | }
28 |
29 | /*
30 | keep the cpu busy for doing nothing(nop)
31 | so that io port will not be processed by cpu
32 | here timer can also be used, but lets do this in looping counter
33 | */
34 | void wait_for_io(uint32 timer_count)
35 | {
36 | while(1){
37 | asm volatile("nop");
38 | timer_count--;
39 | if(timer_count <= 0)
40 | break;
41 | }
42 | }
43 |
44 | void sleep(uint32 timer_count)
45 | {
46 | uint32 t = 0xeeeeef * timer_count;
47 | wait_for_io(t);
48 | }
49 |
50 |
51 | void kernel_entry()
52 | {
53 | init_vga();
54 | pong_game();
55 | }
56 |
57 |
58 |
--------------------------------------------------------------------------------
/Pong-Game/kernel.h:
--------------------------------------------------------------------------------
1 | #ifndef KERNEL_H
2 | #define KERNEL_H
3 |
4 | #include "types.h"
5 |
6 | #define NULL 0
7 |
8 | uint8 inb(uint16 port);
9 | void outb(uint16 port, uint8 data);
10 | uint8 get_input_keycode();
11 | void wait_for_io(uint32 timer_count);
12 | void sleep(uint32 timer_count);
13 |
14 |
15 | #endif
16 |
--------------------------------------------------------------------------------
/Pong-Game/keyboard.h:
--------------------------------------------------------------------------------
1 | #ifndef KEYBOARD_H
2 | #define KEYBOARD_H
3 |
4 | #define KEYBOARD_PORT 0x60
5 |
6 |
7 | #define KEY_A 0x1E
8 | #define KEY_B 0x30
9 | #define KEY_C 0x2E
10 | #define KEY_D 0x20
11 | #define KEY_E 0x12
12 | #define KEY_F 0x21
13 | #define KEY_G 0x22
14 | #define KEY_H 0x23
15 | #define KEY_I 0x17
16 | #define KEY_J 0x24
17 | #define KEY_K 0x25
18 | #define KEY_L 0x26
19 | #define KEY_M 0x32
20 | #define KEY_N 0x31
21 | #define KEY_O 0x18
22 | #define KEY_P 0x19
23 | #define KEY_Q 0x10
24 | #define KEY_R 0x13
25 | #define KEY_S 0x1F
26 | #define KEY_T 0x14
27 | #define KEY_U 0x16
28 | #define KEY_V 0x2F
29 | #define KEY_W 0x11
30 | #define KEY_X 0x2D
31 | #define KEY_Y 0x15
32 | #define KEY_Z 0x2C
33 | #define KEY_1 0x02
34 | #define KEY_2 0x03
35 | #define KEY_3 0x04
36 | #define KEY_4 0x05
37 | #define KEY_5 0x06
38 | #define KEY_6 0x07
39 | #define KEY_7 0x08
40 | #define KEY_8 0x09
41 | #define KEY_9 0x0A
42 | #define KEY_0 0x0B
43 | #define KEY_MINUS 0x0C
44 | #define KEY_EQUAL 0x0D
45 | #define KEY_SQUARE_OPEN_BRACKET 0x1A
46 | #define KEY_SQUARE_CLOSE_BRACKET 0x1B
47 | #define KEY_SEMICOLON 0x27
48 | #define KEY_BACKSLASH 0x2B
49 | #define KEY_COMMA 0x33
50 | #define KEY_DOT 0x34
51 | #define KEY_FORESLHASH 0x35
52 | #define KEY_F1 0x3B
53 | #define KEY_F2 0x3C
54 | #define KEY_F3 0x3D
55 | #define KEY_F4 0x3E
56 | #define KEY_F5 0x3F
57 | #define KEY_F6 0x40
58 | #define KEY_F7 0x41
59 | #define KEY_F8 0x42
60 | #define KEY_F9 0x43
61 | #define KEY_F10 0x44
62 | #define KEY_F11 0x85
63 | #define KEY_F12 0x86
64 | #define KEY_BACKSPACE 0x0E
65 | #define KEY_DELETE 0x53
66 | #define KEY_DOWN 0x50
67 | #define KEY_END 0x4F
68 | #define KEY_ENTER 0x1C
69 | #define KEY_ESC 0x01
70 | #define KEY_HOME 0x47
71 | #define KEY_INSERT 0x52
72 | #define KEY_KEYPAD_5 0x4C
73 | #define KEY_KEYPAD_MUL 0x37
74 | #define KEY_KEYPAD_Minus 0x4A
75 | #define KEY_KEYPAD_PLUS 0x4E
76 | #define KEY_KEYPAD_DIV 0x35
77 | #define KEY_LEFT 0x4B
78 | #define KEY_PAGE_DOWN 0x51
79 | #define KEY_PAGE_UP 0x49
80 | #define KEY_PRINT_SCREEN 0x37
81 | #define KEY_RIGHT 0x4D
82 | #define KEY_SPACE 0x39
83 | #define KEY_TAB 0x0F
84 | #define KEY_UP 0x48
85 |
86 |
87 | #endif
88 |
89 |
--------------------------------------------------------------------------------
/Pong-Game/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 | }
40 |
41 | /* The compiler may produce other sections, by default it will put them in
42 | a segment with the same name. Simply add stuff here as needed. */
43 | }
44 |
--------------------------------------------------------------------------------
/Pong-Game/pong.c:
--------------------------------------------------------------------------------
1 | #include "pong.h"
2 |
3 | // pads position y, will change on keys
4 | uint16 pad_pos_y = 2;
5 | // score counnt
6 | uint32 score_count = 0;
7 |
8 | // initialize game with into
9 | static void init_game()
10 | {
11 | uint8 b = 0;
12 |
13 | draw_string(120, 13, BRIGHT_CYAN, "PONG GAME");
14 | draw_rect(100, 4, 120, 25, BLUE);
15 | draw_string(10, 50, BRIGHT_MAGENTA, "HOW TO PLAY");
16 | draw_rect(2, 40, 235, 80, BROWN);
17 | draw_string(10, 70, BRIGHT_RED, "ARROW KEY UP");
18 | draw_string(30, 80, WHITE, "TO MOVE BOTH PADS UP");
19 | draw_string(10, 90, BRIGHT_RED, "ARROW KEY DOWN");
20 | draw_string(30, 100, WHITE, "TO MOVE BOTH PADS DOWN");
21 | draw_string(60, 160, BRIGHT_GREEN, "PRESS ENTER TO START");
22 | #ifdef VIRTUALBOX
23 | sleep(10);
24 | #endif
25 | while (1)
26 | {
27 | b = get_input_keycode();
28 | sleep(5);
29 | if (b == KEY_ENTER)
30 | break;
31 | b = 0;
32 | }
33 | clear_screen();
34 | }
35 |
36 | // update score count text
37 | static void update_score_count()
38 | {
39 | char str[32];
40 |
41 | itoa(score_count, str);
42 | draw_string(150, 2, WHITE, str);
43 | }
44 |
45 | // if lose then display final score & restart game
46 | static void lose()
47 | {
48 | uint8 b = 0;
49 | char str[32];
50 |
51 | itoa(score_count, str);
52 | clear_screen();
53 | draw_string(120, 15, BRIGHT_GREEN, "NICE PLAY");
54 | draw_string(125, 45, WHITE, "SCORE");
55 | draw_string(180, 45, WHITE, str);
56 | draw_string(45, 130, YELLOW, "PRESS ENTER TO PLAY AGAIN");
57 |
58 | #ifdef VIRTUALBOX
59 | sleep(10);
60 | #endif
61 | while (1)
62 | {
63 | b = get_input_keycode();
64 | sleep(5);
65 | if (b == KEY_ENTER)
66 | break;
67 | b = 0;
68 | }
69 | score_count = 0;
70 | clear_screen();
71 | pong_game();
72 | }
73 |
74 | // move both pads simultaneously on pressed keys
75 | void move_pads()
76 | {
77 | uint8 b;
78 |
79 | // draw both pads
80 | fill_rect(0, pad_pos_y, PAD_WIDTH, PAD_HEIGHT, YELLOW);
81 | fill_rect(PAD_POS_X, pad_pos_y, PAD_WIDTH, PAD_HEIGHT, YELLOW);
82 |
83 | b = get_input_keycode();
84 | // if down key pressed, move both pads down
85 | if (b == KEY_DOWN)
86 | {
87 | if (pad_pos_y < VGA_MAX_HEIGHT - PAD_HEIGHT)
88 | pad_pos_y = pad_pos_y + PAD_SPEED;
89 | fill_rect(0, pad_pos_y, PAD_WIDTH, PAD_HEIGHT, YELLOW);
90 | fill_rect(PAD_POS_X, pad_pos_y, PAD_WIDTH, PAD_HEIGHT, YELLOW);
91 | }
92 | // if up key pressed, move both pads up
93 | else if (b == KEY_UP)
94 | {
95 | if (pad_pos_y >= PAD_WIDTH)
96 | pad_pos_y = pad_pos_y - PAD_SPEED;
97 | fill_rect(0, pad_pos_y, PAD_WIDTH, PAD_HEIGHT, YELLOW);
98 | fill_rect(PAD_POS_X, pad_pos_y, PAD_WIDTH, PAD_HEIGHT, YELLOW);
99 | }
100 | #ifdef VIRTUALBOX
101 | sleep(1);
102 | #endif
103 | }
104 |
105 |
106 | void pong_game()
107 | {
108 | uint16 rect_pos_x = RECT_SIZE + 20;
109 | uint16 rect_pos_y = RECT_SIZE;
110 | uint16 rect_speed_x = RECT_SPEED_X;
111 | uint16 rect_speed_y = RECT_SPEED_Y;
112 |
113 | init_game();
114 |
115 | while (1)
116 | {
117 | // add speed values to positions
118 | rect_pos_x += rect_speed_x;
119 | rect_pos_y += rect_speed_y;
120 |
121 | // check if position x < left pad position x
122 | if (rect_pos_x - RECT_SIZE <= PAD_WIDTH + 1)
123 | {
124 | // if position of rect is not between left pad position,
125 | // then lose, bounced rect is not in y range of pad
126 | if ((rect_pos_y > 0 && rect_pos_y < pad_pos_y) ||
127 | (rect_pos_y <= VGA_MAX_HEIGHT && rect_pos_y > pad_pos_y + PAD_HEIGHT))
128 | {
129 | lose();
130 | }
131 | else
132 | {
133 | // set speed x to negative, means move opposite direction
134 | rect_speed_x = -rect_speed_x;
135 | // set position x to rect size
136 | rect_pos_x = PAD_WIDTH + RECT_SIZE;
137 | // increase score
138 | score_count++;
139 | }
140 | }
141 | // check if position x >= right pad position x
142 | else if (rect_pos_x + RECT_SIZE >= PAD_POS_X + RECT_SIZE - 1)
143 | {
144 | // in range of y pad position
145 | if ((rect_pos_y > 0 && rect_pos_y < pad_pos_y) ||
146 | (rect_pos_y <= VGA_MAX_HEIGHT && rect_pos_y > pad_pos_y + PAD_HEIGHT) ||
147 | (rect_pos_y + RECT_SIZE > 0 && rect_pos_y + RECT_SIZE < pad_pos_y))
148 | {
149 | lose();
150 | }
151 | else
152 | {
153 | // set speed x to negative, means move opposite direction
154 | rect_speed_x = -rect_speed_x;
155 | // set position x to minimum of pad position x - rect size
156 | rect_pos_x = PAD_POS_X - RECT_SIZE;
157 | // increase score
158 | score_count++;
159 | }
160 | }
161 |
162 | // change rect y position by checking boundries
163 | if (rect_pos_y - RECT_SIZE <= 0)
164 | {
165 | rect_speed_y = -rect_speed_y;
166 | rect_pos_y = RECT_SIZE;
167 | }
168 | else if(rect_pos_y + RECT_SIZE > VGA_MAX_HEIGHT + RECT_SIZE)
169 | {
170 | rect_speed_y = -rect_speed_y;
171 | rect_pos_y = VGA_MAX_HEIGHT - RECT_SIZE;
172 | }
173 |
174 | // clear screen for repaint
175 | clear_screen();
176 | // move pads on keys
177 | move_pads();
178 | // update score count
179 | update_score_count();
180 | // fill bounced rect
181 | fill_rect(rect_pos_x - RECT_SIZE, rect_pos_y - RECT_SIZE, RECT_SIZE, RECT_SIZE, WHITE);
182 | // change sleep value if running in VirtualBox or on bare metal
183 | sleep(1);
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/Pong-Game/pong.h:
--------------------------------------------------------------------------------
1 | #ifndef PONG_H
2 | #define PONG_H
3 |
4 | #include "kernel.h"
5 | #include "vga.h"
6 | #include "keyboard.h"
7 | #include "utils.h"
8 | #include "bitmap.h"
9 |
10 | /*
11 | if wants to run on qemu, uncomment following line,
12 | comment line #define VIRTUALBOX
13 | compile & run
14 | */
15 | //#define QEMU
16 |
17 | /*
18 | if wants to run on virtualbox, uncomment following line,
19 | comment line #define QEMU
20 | compile & run
21 | */
22 | #define VIRTUALBOX
23 |
24 |
25 | // size of bounced rectangle
26 | #define RECT_SIZE 6
27 |
28 | // speed of rectangle on qemu
29 | #ifdef QEMU
30 | #define RECT_SPEED_X 6
31 | #define RECT_SPEED_Y 6
32 | #endif
33 |
34 | // speed of rectangle on virtualbox
35 | #ifdef VIRTUALBOX
36 | #define RECT_SPEED_X 2
37 | #define RECT_SPEED_Y 2
38 | #endif
39 |
40 | // pad position, size & pads speeds
41 | #define PAD_POS_X VGA_MAX_WIDTH - PAD_WIDTH - 1
42 | #define PAD_WIDTH 6
43 | #define PAD_HEIGHT 50
44 |
45 | // pads speed on qemu
46 | #ifdef QEMU
47 | #define PAD_SPEED 20
48 | #endif
49 |
50 | // pads speed on virtualbox
51 | #ifdef VIRTUALBOX
52 | #define PAD_SPEED 6
53 | #endif
54 |
55 |
56 | void pong_game();
57 |
58 |
59 | #endif
60 |
--------------------------------------------------------------------------------
/Pong-Game/run.sh:
--------------------------------------------------------------------------------
1 | #assemble boot.s file
2 | as --32 boot.s -o boot.o
3 |
4 | #compile kernel.c file
5 | gcc -m32 -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
6 |
7 | #compile vga.c file
8 | gcc -m32 -c vga.c -o vga.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
9 |
10 | #compile bitmap.c file
11 | gcc -m32 -c bitmap.c -o bitmap.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
12 |
13 | #compile utils.c file
14 | gcc -m32 -c utils.c -o utils.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
15 |
16 | #compile pong.c file
17 | gcc -m32 -c pong.c -o pong.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
18 |
19 | #linking the kernel with object files
20 | ld -m elf_i386 -T linker.ld kernel.o vga.o boot.o bitmap.o utils.o pong.o -o Pong_Game.bin -nostdlib
21 |
22 | #check Pong_Game.bin file is x86 multiboot file or not
23 | grub-file --is-x86-multiboot Pong_Game.bin
24 |
25 | #building the iso file
26 | mkdir -p isodir/boot/grub
27 | cp Pong_Game.bin isodir/boot/Pong_Game.bin
28 | cp grub.cfg isodir/boot/grub/grub.cfg
29 | grub-mkrescue -o Pong_Game.iso isodir
30 |
31 | #run it in qemu
32 | qemu-system-x86_64 -cdrom Pong_Game.iso
33 |
--------------------------------------------------------------------------------
/Pong-Game/types.h:
--------------------------------------------------------------------------------
1 | #ifndef TYPES_H
2 | #define TYPES_H
3 |
4 | typedef unsigned char uint8;
5 | typedef unsigned short uint16;
6 | typedef unsigned int uint32;
7 |
8 | #endif
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Pong-Game/utils.c:
--------------------------------------------------------------------------------
1 | #include "utils.h"
2 |
3 | uint32 strlen(const char* str)
4 | {
5 | uint32 length = 0;
6 | while(str[length])
7 | length++;
8 | return length;
9 | }
10 |
11 | uint32 digit_count(int num)
12 | {
13 | uint32 count = 0;
14 | if(num == 0)
15 | return 1;
16 | while(num > 0){
17 | count++;
18 | num = num/10;
19 | }
20 | return count;
21 | }
22 |
23 | void itoa(int num, char *number)
24 | {
25 | int dgcount = digit_count(num);
26 | int index = dgcount - 1;
27 | char x;
28 | if(num == 0 && dgcount == 1){
29 | number[0] = '0';
30 | number[1] = '\0';
31 | }else{
32 | while(num != 0){
33 | x = num % 10;
34 | number[index] = x + '0';
35 | index--;
36 | num = num / 10;
37 | }
38 | number[dgcount] = '\0';
39 | }
40 | }
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/Pong-Game/utils.h:
--------------------------------------------------------------------------------
1 | #ifndef UTILS_H
2 | #define UTILS_H
3 |
4 | #include "types.h"
5 |
6 | #define TRUE 1
7 | #define FALSE 0
8 |
9 | extern uint32 strlen(const char*);
10 | extern uint32 digit_count(int);
11 | extern void itoa(int, char *);
12 |
13 | #endif
14 |
15 |
--------------------------------------------------------------------------------
/Pong-Game/vga.c:
--------------------------------------------------------------------------------
1 | #include "vga.h"
2 | #include "kernel.h"
3 |
4 | /*
5 | See Intel® OpenSource HD Graphics PRM pdf file
6 | for following defined data for each vga register
7 | and its explaination
8 | */
9 | static uint8 seq_data[5] = {0x03, 0x01, 0x0F, 0x00, 0x0E};
10 | static uint8 crtc_data[25] = {0x5F, 0x4F, 0x50, 0x82,
11 | 0x54, 0x80, 0xBF, 0x1F,
12 | 0x00, 0x41, 0x00, 0x00,
13 | 0x00, 0x00, 0x00, 0x00,
14 | 0x9C, 0x0E, 0x8F, 0x28,
15 | 0x40, 0x96, 0xB9, 0xA3,
16 | 0xFF};
17 |
18 | static uint8 gc_data[9] = {0x00, 0x00, 0x00, 0x00,
19 | 0x00, 0x40, 0x05, 0x0F,
20 | 0xFF};
21 |
22 | static uint8 ac_data[21] = {0x00, 0x01, 0x02, 0x03,
23 | 0x04, 0x05, 0x06, 0x07,
24 | 0x08, 0x09, 0x0A, 0x0B,
25 | 0x0C, 0x0D, 0x0E, 0x0F,
26 | 0x41, 0x00, 0x0F, 0x00,
27 | 0x00};
28 |
29 | void set_misc()
30 | {
31 | outb(VGA_MISC_WRITE, 0x63);
32 | }
33 |
34 | void set_seq()
35 | {
36 | // write sequence data to index of 0-4
37 | for(uint8 index = 0; index < 5; index++){
38 | // first set index
39 | outb(VGA_SEQ_INDEX, index);
40 | // write data at that index
41 | outb(VGA_SEQ_DATA, seq_data[index]);
42 | }
43 | }
44 |
45 | void set_crtc()
46 | {
47 | // write crtc data to index of 0-24
48 | for(uint8 index = 0; index < 25; index++){
49 | outb(VGA_CRTC_INDEX, index);
50 | outb(VGA_CRTC_DATA, crtc_data[index]);
51 | }
52 | }
53 |
54 | void set_gc()
55 | {
56 | // write gc data to index of 0-8
57 | for(uint8 index = 0; index < 9; index++){
58 | outb(VGA_GC_INDEX, index);
59 | outb(VGA_GC_DATA, gc_data[index]);
60 | }
61 | }
62 |
63 | void set_ac()
64 | {
65 | uint8 d;
66 | // write ac data to index of 0-20
67 | for(uint8 index = 0; index < 21; index++){
68 | outb(VGA_AC_INDEX, index);
69 | outb(VGA_AC_WRITE, ac_data[index]);
70 | }
71 | d = inb(VGA_INSTAT_READ);
72 | outb(VGA_AC_INDEX, d | 0x20);
73 | }
74 |
75 | void clear_screen()
76 | {
77 | for(uint32 index = 0; index < VGA_MAX; index++)
78 | vga_buffer[index] = 0;
79 | }
80 |
81 | void clear_color(uint8 color)
82 | {
83 | for(uint32 index = 0; index < VGA_MAX; index++)
84 | vga_buffer[index] = color;
85 | }
86 |
87 | void init_vga()
88 | {
89 | set_misc();
90 | set_seq();
91 | set_crtc();
92 | set_gc();
93 | set_ac();
94 |
95 | vga_buffer = (uint8*)VGA_ADDRESS;
96 |
97 | clear_screen();
98 | }
99 |
100 | void putpixel(uint16 x, uint16 y, uint8 color)
101 | {
102 | uint32 index = 0;
103 | index = 320 * y + x;
104 | if(index < VGA_MAX)
105 | vga_buffer[index] = color;
106 | }
107 |
108 | void draw_line(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint8 color)
109 | {
110 | if(y1 == y2){
111 | for(uint16 i = x1; i <= x2; i++)
112 | putpixel(i, y1, color);
113 | return;
114 | }
115 |
116 | if(x1 == x2){
117 | for(uint16 i = y1; i <= y2; i++){
118 | putpixel(x1, i, color);
119 | }
120 | return;
121 | }
122 | }
123 |
124 | void draw_rect(uint16 x, uint16 y, uint16 width, uint16 height, uint8 color)
125 | {
126 | draw_line(x, y, x, y + height, color);
127 | draw_line(x, y, x + width, y, color);
128 | draw_line(x + width, y, x + width, y + height, color);
129 | draw_line(x, y + height, x + width, y + height, color);
130 | }
131 |
132 | void fill_rect(uint16 x, uint16 y, uint16 width, uint16 height, uint8 color)
133 | {
134 | draw_line(x, y, x, y + height, color);
135 | draw_line(x, y, x + width, y, color);
136 | draw_line(x + width, y, x + width, y + height, color);
137 | draw_line(x, y + height, x + width, y + height, color);
138 | for(int i = y; i < y + height; i++){
139 | draw_line(x, i, x + width, i, color);
140 | }
141 | }
142 |
143 | void draw_bresenham_circle(int xc, int yc, int x, int y, uint8 color)
144 | {
145 | putpixel(xc+x, yc+y, color);
146 | putpixel(xc-x, yc+y, color);
147 | putpixel(xc+x, yc-y, color);
148 | putpixel(xc-x, yc-y, color);
149 | putpixel(xc+y, yc+x, color);
150 | putpixel(xc-y, yc+x, color);
151 | putpixel(xc+y, yc-x, color);
152 | putpixel(xc-y, yc-x, color);
153 | }
154 |
155 | void draw_circle(uint16 x, uint16 y, uint16 radius, uint8 color)
156 | {
157 | int x2 = 0, y2 = radius;
158 | int d = 3 - 2 * radius;
159 | draw_bresenham_circle(x, y, x2, y2, color);
160 | while(y2 >= x2){
161 | x2++;
162 | if(d > 0){
163 | y2--;
164 | d = d + 4 * (x2 - y2) + 10;
165 | }else{
166 | d = d + 4 * x2 + 6;
167 | }
168 | draw_bresenham_circle(x, y, x2, y2, color);
169 | }
170 | }
171 |
172 | void draw_diamond(uint16 x, uint16 y, uint16 radius, uint8 color)
173 | {
174 | uint16 x2 = 0, y2 = radius;
175 | uint16 d = 3 - 2 * radius;
176 | draw_bresenham_circle(x, y, x2, y2, color);
177 | while(y2 >= x2){
178 | x2++;
179 | if(d > 0){
180 | y2--;
181 | d = d + 4 * (x2 - y2) + 10;
182 | }else{
183 | d = d + 4 * x2 + 6;
184 | }
185 | draw_bresenham_circle(x, y, x2, y2, color);
186 | }
187 | }
188 |
189 |
--------------------------------------------------------------------------------
/Pong-Game/vga.h:
--------------------------------------------------------------------------------
1 | #ifndef VGA_H
2 | #define VGA_H
3 |
4 | #include "types.h"
5 |
6 | #define VGA_ADDRESS 0xA0000
7 | #define VGA_MAX 0xF9FF
8 | #define VGA_MAX_WIDTH 320
9 | #define VGA_MAX_HEIGHT 200
10 |
11 | uint8* vga_buffer;
12 |
13 | enum vga_color {
14 | BLACK,
15 | BLUE,
16 | GREEN,
17 | CYAN,
18 | RED,
19 | MAGENTA,
20 | BROWN,
21 | GREY,
22 | DARK_GREY,
23 | BRIGHT_BLUE,
24 | BRIGHT_GREEN,
25 | BRIGHT_CYAN,
26 | BRIGHT_RED,
27 | BRIGHT_MAGENTA,
28 | YELLOW,
29 | WHITE,
30 | };
31 |
32 | /* Attribute Controller Registers */
33 | #define VGA_AC_INDEX 0x3C0
34 | #define VGA_AC_READ 0x3C1
35 | #define VGA_AC_WRITE 0x3C0
36 |
37 | /*
38 | Miscellaneous Output
39 | */
40 | #define VGA_MISC_READ 0x3CC
41 | #define VGA_MISC_WRITE 0x3C2
42 |
43 | /* Sequencer Registers */
44 | #define VGA_SEQ_INDEX 0x3C4
45 | #define VGA_SEQ_DATA 0x3C5
46 |
47 | /* VGA Color Palette Registers */
48 | #define VGA_DAC_READ_INDEX 0x3C7
49 | #define VGA_DAC_WRITE_INDEX 0x3C8
50 | #define VGA_DAC_DATA 0x3C9
51 |
52 | /* Graphics Controller Registers */
53 | #define VGA_GC_INDEX 0x3CE
54 | #define VGA_GC_DATA 0x3CF
55 |
56 | /* CRT Controller Registers */
57 | #define VGA_CRTC_INDEX 0x3D4
58 | #define VGA_CRTC_DATA 0x3D5
59 |
60 | /* General Control and Status Registers */
61 | #define VGA_INSTAT_READ 0x3DA
62 |
63 | void init_vga();
64 | void clear_screen();
65 | void clear_color(uint8 color);
66 | void putpixel(uint16 x, uint16 y, uint8 color);
67 | void draw_line(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint8 color);
68 | void draw_rect(uint16 x, uint16 y, uint16 width, uint16 height, uint8 color);
69 | void fill_rect(uint16 x, uint16 y, uint16 width, uint16 height, uint8 color);
70 | void draw_circle(uint16 x, uint16 y, uint16 radius, uint8 color);
71 | void draw_diamond(uint16 x, uint16 y, uint16 radius, uint8 color);
72 |
73 | #endif
74 |
75 |
76 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SIMPLE-OS
2 |
3 | Simple Operating System programs starting from Bootloader in assembly to Kernel in C, and other programs like OS Calculator, Low Level Graphics etc.
4 |
5 | Bootloader contains simple 16 bit as well as 32 bit OS bootloader assembly programs.
6 |
7 | Kernel contains C programs for Simple HelloWorld, Keyboard I/O etc... and little bit assembly programs for low level operations.
8 |
9 | Global_Descriptor_Table contains code that sets up GDT in both x86 NASM Assembly and in C.
10 |
11 | Interrupt_Descriptor_Table contains code that sets up IDT in C with interrupt service routines.
12 |
13 | GUI contains graphics related programs in C for drawing boxes, DOSBox GUI etc.
14 |
15 | x86 Calculator contains an x86 calculator program capable to run on booting.
16 |
17 | Graphics contains simple low level pixels drawing, as well as objects such as Lines using DDA algorithm, Rectangles etc.
18 |
19 | VGA contains C kernel and assembly program for seeting up Video Graphics Array(VGA) and drawing some basic shapes by ploting pixels.
20 |
21 | Tic-Tac-Toe a simple tic-tac-toe DOS game with boxes.
22 |
23 | Pong-Game a simple Pong game using graphics.
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Tic-Tac-Toe/img/TicTacToe.iso:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/Tic-Tac-Toe/img/TicTacToe.iso
--------------------------------------------------------------------------------
/Tic-Tac-Toe/src/boot.s:
--------------------------------------------------------------------------------
1 | # set flags to 0
2 | .set FLAGS, 0
3 |
4 | # set magic number to 0x1BADB002 to identified by bootloader
5 | .set MAGIC, 0x1BADB002
6 |
7 | # set the checksum
8 | .set CHECKSUM, -(MAGIC + FLAGS)
9 |
10 | # set multiboot enabled
11 | .section .multiboot
12 |
13 | # define type to long for each data defined as above
14 | .long MAGIC
15 | .long FLAGS
16 | .long CHECKSUM
17 |
18 |
19 | # set the stack bottom
20 | stackBottom:
21 |
22 | # define the maximum size of stack to 512 bytes
23 | .skip 4096
24 |
25 |
26 | # set the stack top which grows from higher to lower
27 | stackTop:
28 |
29 | .section .text
30 | .global _start
31 | .type _start, @function
32 |
33 |
34 | _start:
35 |
36 |
37 | # assign current stack pointer location to stackTop
38 | mov $stackTop, %esp
39 |
40 | # call the kernel main function
41 | call kernel_entry
42 |
43 | cli
44 |
45 |
46 | # put system in infinite loop
47 | hltLoop:
48 |
49 | hlt
50 | jmp hltLoop
51 |
52 | .size _start, . - _start
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/Tic-Tac-Toe/src/box.c:
--------------------------------------------------------------------------------
1 | #include "kernel.h"
2 | #include "types.h"
3 | #include "utils.h"
4 | #include "box.h"
5 |
6 | uint16 get_box_draw_char(uint8 chn, uint8 fore_color, uint8 back_color)
7 | {
8 | uint16 ax = 0;
9 | uint8 ah = 0;
10 |
11 | ah = back_color;
12 | ah <<= 4;
13 | ah |= fore_color;
14 | ax = ah;
15 | ax <<= 8;
16 | ax |= chn;
17 |
18 | return ax;
19 | }
20 |
21 | void draw_generic_box(uint16 x, uint16 y,
22 | uint16 width, uint16 height,
23 | uint8 fore_color, uint8 back_color,
24 | uint8 topleft_ch,
25 | uint8 topbottom_ch,
26 | uint8 topright_ch,
27 | uint8 leftrightside_ch,
28 | uint8 bottomleft_ch,
29 | uint8 bottomright_ch)
30 | {
31 | uint32 i;
32 |
33 | //increase vga_index to x & y location
34 | vga_index = 80*y;
35 | vga_index += x;
36 |
37 | //draw top-left box character
38 | vga_buffer[vga_index] = get_box_draw_char(topleft_ch, fore_color, back_color);
39 |
40 | vga_index++;
41 | //draw box top characters, -
42 | for(i = 0; i < width; i++){
43 | vga_buffer[vga_index] = get_box_draw_char(topbottom_ch, fore_color, back_color);
44 | vga_index++;
45 | }
46 |
47 | //draw top-right box character
48 | vga_buffer[vga_index] = get_box_draw_char(topright_ch, fore_color, back_color);
49 |
50 | // increase y, for drawing next line
51 | y++;
52 | // goto next line
53 | vga_index = 80*y;
54 | vga_index += x;
55 |
56 | //draw left and right sides of box
57 | for(i = 0; i < height; i++){
58 | //draw left side character
59 | vga_buffer[vga_index] = get_box_draw_char(leftrightside_ch, fore_color, back_color);
60 | vga_index++;
61 | //increase vga_index to the width of box
62 | vga_index += width;
63 | //draw right side character
64 | vga_buffer[vga_index] = get_box_draw_char(leftrightside_ch, fore_color, back_color);
65 | //goto next line
66 | y++;
67 | vga_index = 80*y;
68 | vga_index += x;
69 | }
70 | //draw bottom-left box character
71 | vga_buffer[vga_index] = get_box_draw_char(bottomleft_ch, fore_color, back_color);
72 | vga_index++;
73 | //draw box bottom characters, -
74 | for(i = 0; i < width; i++){
75 | vga_buffer[vga_index] = get_box_draw_char(topbottom_ch, fore_color, back_color);
76 | vga_index++;
77 | }
78 | //draw bottom-right box character
79 | vga_buffer[vga_index] = get_box_draw_char(bottomright_ch, fore_color, back_color);
80 |
81 | vga_index = 0;
82 | }
83 |
84 | void draw_box(uint8 boxtype,
85 | uint16 x, uint16 y,
86 | uint16 width, uint16 height,
87 | uint8 fore_color, uint8 back_color)
88 | {
89 | switch(boxtype){
90 | case BOX_SINGLELINE :
91 | draw_generic_box(x, y, width, height,
92 | fore_color, back_color,
93 | 218, 196, 191, 179, 192, 217);
94 | break;
95 |
96 | case BOX_DOUBLELINE :
97 | draw_generic_box(x, y, width, height,
98 | fore_color, back_color,
99 | 201, 205, 187, 186, 200, 188);
100 | break;
101 | }
102 | }
103 |
104 | void fill_box(uint8 ch, uint16 x, uint16 y, uint16 width, uint16 height, uint8 color)
105 | {
106 | uint32 i,j;
107 |
108 | for(i = 0; i < height; i++){
109 | //increase vga_index to x & y location
110 | vga_index = 80*y;
111 | vga_index += x;
112 |
113 | for(j = 0; j < width; j++){
114 | vga_buffer[vga_index] = get_box_draw_char(ch, 0, color);
115 | vga_index++;
116 | }
117 | y++;
118 | }
119 | }
120 |
121 |
122 |
--------------------------------------------------------------------------------
/Tic-Tac-Toe/src/box.h:
--------------------------------------------------------------------------------
1 | #ifndef BOX_H
2 | #define BOX_H
3 |
4 | #include "types.h"
5 |
6 |
7 | #define BOX_MAX_WIDTH 78
8 | #define BOX_MAX_HEIGHT 23
9 |
10 | #define BOX_SINGLELINE 1
11 | #define BOX_DOUBLELINE 2
12 |
13 |
14 | extern void draw_generic_box(uint16, uint16, uint16, uint16,
15 | uint8, uint8, uint8, uint8,
16 | uint8, uint8, uint8, uint8);
17 |
18 | extern void draw_box(uint8, uint16, uint16, uint16, uint16,
19 | uint8, uint8);
20 |
21 | extern void fill_box(uint8, uint16, uint16, uint16, uint16, uint8);
22 |
23 |
24 | #endif
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Tic-Tac-Toe/src/grub.cfg:
--------------------------------------------------------------------------------
1 | menuentry "TicTacToe" {
2 | multiboot /boot/TicTacToe.bin
3 | }
4 |
--------------------------------------------------------------------------------
/Tic-Tac-Toe/src/kernel.c:
--------------------------------------------------------------------------------
1 | #include "kernel.h"
2 | #include "utils.h"
3 | #include "keyboard.h"
4 | #include "tic_tac_toe.h"
5 |
6 | uint32 vga_index;
7 | static uint32 next_line_index = 1;
8 | uint8 g_fore_color = WHITE, g_back_color = BLUE;
9 | int digit_ascii_codes[10] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
10 |
11 | uint16 vga_entry(unsigned char ch, uint8 fore_color, uint8 back_color)
12 | {
13 | uint16 ax = 0;
14 | uint8 ah = 0, al = 0;
15 |
16 | ah = back_color;
17 | ah <<= 4;
18 | ah |= fore_color;
19 | ax = ah;
20 | ax <<= 8;
21 | al = ch;
22 | ax |= al;
23 |
24 | return ax;
25 | }
26 |
27 | void clear_vga_buffer(uint16 **buffer, uint8 fore_color, uint8 back_color)
28 | {
29 | uint32 i;
30 | for(i = 0; i < BUFSIZE; i++){
31 | (*buffer)[i] = vga_entry(NULL, fore_color, back_color);
32 | }
33 | next_line_index = 1;
34 | vga_index = 0;
35 | }
36 |
37 | void init_vga(uint8 fore_color, uint8 back_color)
38 | {
39 | vga_buffer = (uint16*)VGA_ADDRESS;
40 | clear_vga_buffer(&vga_buffer, fore_color, back_color);
41 | g_fore_color = fore_color;
42 | g_back_color = back_color;
43 | }
44 |
45 | void clear_screen(uint8 fore_color, uint8 back_color)
46 | {
47 | clear_vga_buffer(&vga_buffer, fore_color, back_color);
48 | }
49 |
50 | void print_new_line()
51 | {
52 | if(next_line_index >= 55){
53 | next_line_index = 0;
54 | clear_vga_buffer(&vga_buffer, g_fore_color, g_back_color);
55 | }
56 | vga_index = 80*next_line_index;
57 | next_line_index++;
58 | }
59 |
60 | void print_char(char ch)
61 | {
62 | vga_buffer[vga_index] = vga_entry(ch, g_fore_color, g_back_color);
63 | vga_index++;
64 | }
65 |
66 | void print_string(char *str)
67 | {
68 | uint32 index = 0;
69 | while(str[index]){
70 | print_char(str[index]);
71 | index++;
72 | }
73 | }
74 |
75 | void print_color_string(char *str, uint8 fore_color, uint8 back_color)
76 | {
77 | uint32 index = 0;
78 | uint8 fc, bc;
79 | fc = g_fore_color;
80 | bc = g_back_color;
81 | g_fore_color = fore_color;
82 | g_back_color = back_color;
83 | while(str[index]){
84 | print_char(str[index]);
85 | index++;
86 | }
87 | g_fore_color = fc;
88 | g_back_color = bc;
89 | }
90 |
91 | void print_int(int num)
92 | {
93 | char str_num[digit_count(num)+1];
94 | itoa(num, str_num);
95 | print_string(str_num);
96 | }
97 |
98 | uint8 inb(uint16 port)
99 | {
100 | uint8 ret;
101 | asm volatile("inb %1, %0" : "=a"(ret) : "d"(port));
102 | return ret;
103 | }
104 |
105 | void outb(uint16 port, uint8 data)
106 | {
107 | asm volatile("outb %0, %1" : "=a"(data) : "d"(port));
108 | }
109 |
110 | byte get_input_keycode()
111 | {
112 | byte keycode = 0;
113 | while((keycode = inb(KEYBOARD_PORT)) != 0){
114 | if(keycode > 0)
115 | return keycode;
116 | }
117 | return keycode;
118 | }
119 |
120 | /*
121 | keep the cpu busy for doing nothing(nop)
122 | so that io port will not be processed by cpu
123 | here timer can also be used, but lets do this in looping counter
124 | */
125 | void wait_for_io(uint32 timer_count)
126 | {
127 | while(1){
128 | asm volatile("nop");
129 | timer_count--;
130 | if(timer_count <= 0)
131 | break;
132 | }
133 | }
134 |
135 | void sleep(uint32 timer_count)
136 | {
137 | wait_for_io(timer_count);
138 | }
139 |
140 | void gotoxy(uint16 x, uint16 y)
141 | {
142 | vga_index = 80*y;
143 | vga_index += x;
144 | }
145 |
146 | void kernel_entry()
147 | {
148 | byte ans = KEY_Y;
149 | init_vga(WHITE, BLACK);
150 |
151 | while(ans == KEY_Y){
152 | clear_screen(WHITE, BLACK);
153 | launch_game();
154 |
155 | sleep(0x04FFFFFF);
156 | clear_screen(WHITE, BLACK);
157 | print_string("Do you want to play again?(y/n) : ");
158 | ans = get_input_keycode();
159 | sleep(0x04FFFFFF);
160 | if(ans == KEY_Y){
161 | continue;
162 | }else if(ans == KEY_N){
163 | print_new_line();
164 | print_string("Thank you for playing!");
165 | break;
166 | }else{
167 | print_new_line();
168 | print_string("Invalid choice!");
169 | print_new_line();
170 | print_string("Exited ...");
171 | break;
172 | }
173 | }
174 | }
175 |
176 |
--------------------------------------------------------------------------------
/Tic-Tac-Toe/src/kernel.h:
--------------------------------------------------------------------------------
1 | #ifndef KERNEL_H
2 | #define KERNEL_H
3 |
4 | #include "types.h"
5 |
6 | #define NULL 0
7 |
8 | #define VGA_ADDRESS 0xB8000
9 | #define BUFSIZE 2200
10 |
11 | uint16* vga_buffer;
12 | extern uint32 vga_index;
13 |
14 | enum vga_color {
15 | BLACK,
16 | BLUE,
17 | GREEN,
18 | CYAN,
19 | RED,
20 | MAGENTA,
21 | BROWN,
22 | GREY,
23 | DARK_GREY,
24 | BRIGHT_BLUE,
25 | BRIGHT_GREEN,
26 | BRIGHT_CYAN,
27 | BRIGHT_RED,
28 | BRIGHT_MAGENTA,
29 | YELLOW,
30 | WHITE,
31 | };
32 |
33 | extern void clear_screen(uint8, uint8);
34 | extern void print_new_line();
35 | extern void print_char(char);
36 | extern void print_string(char *);
37 | extern void print_color_string(char *, uint8, uint8);
38 | extern void print_int(int);
39 | extern uint8 inb(uint16);
40 | extern void outb(uint16, uint8);
41 | extern byte get_input_keycode();
42 | extern void sleep(uint32);
43 | extern void gotoxy(uint16, uint16);
44 |
45 | #endif
46 |
--------------------------------------------------------------------------------
/Tic-Tac-Toe/src/keyboard.h:
--------------------------------------------------------------------------------
1 | #ifndef KEYBOARD_H
2 | #define KEYBOARD_H
3 |
4 | #define KEYBOARD_PORT 0x60
5 |
6 |
7 | #define KEY_A 0x1E
8 | #define KEY_B 0x30
9 | #define KEY_C 0x2E
10 | #define KEY_D 0x20
11 | #define KEY_E 0x12
12 | #define KEY_F 0x21
13 | #define KEY_G 0x22
14 | #define KEY_H 0x23
15 | #define KEY_I 0x17
16 | #define KEY_J 0x24
17 | #define KEY_K 0x25
18 | #define KEY_L 0x26
19 | #define KEY_M 0x32
20 | #define KEY_N 0x31
21 | #define KEY_O 0x18
22 | #define KEY_P 0x19
23 | #define KEY_Q 0x10
24 | #define KEY_R 0x13
25 | #define KEY_S 0x1F
26 | #define KEY_T 0x14
27 | #define KEY_U 0x16
28 | #define KEY_V 0x2F
29 | #define KEY_W 0x11
30 | #define KEY_X 0x2D
31 | #define KEY_Y 0x15
32 | #define KEY_Z 0x2C
33 | #define KEY_1 0x02
34 | #define KEY_2 0x03
35 | #define KEY_3 0x04
36 | #define KEY_4 0x05
37 | #define KEY_5 0x06
38 | #define KEY_6 0x07
39 | #define KEY_7 0x08
40 | #define KEY_8 0x09
41 | #define KEY_9 0x0A
42 | #define KEY_0 0x0B
43 | #define KEY_MINUS 0x0C
44 | #define KEY_EQUAL 0x0D
45 | #define KEY_SQUARE_OPEN_BRACKET 0x1A
46 | #define KEY_SQUARE_CLOSE_BRACKET 0x1B
47 | #define KEY_SEMICOLON 0x27
48 | #define KEY_BACKSLASH 0x2B
49 | #define KEY_COMMA 0x33
50 | #define KEY_DOT 0x34
51 | #define KEY_FORESLHASH 0x35
52 | #define KEY_F1 0x3B
53 | #define KEY_F2 0x3C
54 | #define KEY_F3 0x3D
55 | #define KEY_F4 0x3E
56 | #define KEY_F5 0x3F
57 | #define KEY_F6 0x40
58 | #define KEY_F7 0x41
59 | #define KEY_F8 0x42
60 | #define KEY_F9 0x43
61 | #define KEY_F10 0x44
62 | #define KEY_F11 0x85
63 | #define KEY_F12 0x86
64 | #define KEY_BACKSPACE 0x0E
65 | #define KEY_DELETE 0x53
66 | #define KEY_DOWN 0x50
67 | #define KEY_END 0x4F
68 | #define KEY_ENTER 0x1C
69 | #define KEY_ESC 0x01
70 | #define KEY_HOME 0x47
71 | #define KEY_INSERT 0x52
72 | #define KEY_KEYPAD_5 0x4C
73 | #define KEY_KEYPAD_MUL 0x37
74 | #define KEY_KEYPAD_Minus 0x4A
75 | #define KEY_KEYPAD_PLUS 0x4E
76 | #define KEY_KEYPAD_DIV 0x35
77 | #define KEY_LEFT 0x4B
78 | #define KEY_PAGE_DOWN 0x51
79 | #define KEY_PAGE_UP 0x49
80 | #define KEY_PRINT_SCREEN 0x37
81 | #define KEY_RIGHT 0x4D
82 | #define KEY_SPACE 0x39
83 | #define KEY_TAB 0x0F
84 | #define KEY_UP 0x48
85 |
86 |
87 | #endif
88 |
89 |
--------------------------------------------------------------------------------
/Tic-Tac-Toe/src/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 | }
40 |
41 | /* The compiler may produce other sections, by default it will put them in
42 | a segment with the same name. Simply add stuff here as needed. */
43 | }
44 |
--------------------------------------------------------------------------------
/Tic-Tac-Toe/src/run.sh:
--------------------------------------------------------------------------------
1 | #assemble boot.s file
2 | as --32 boot.s -o boot.o
3 |
4 | #compile kernel.c file
5 | gcc -m32 -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
6 |
7 | gcc -m32 -c utils.c -o utils.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
8 |
9 | gcc -m32 -c box.c -o box.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
10 |
11 | gcc -m32 -c tic_tac_toe.c -o tic_tac_toe.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
12 |
13 | #linking game files
14 | ld -m elf_i386 -T linker.ld boot.o kernel.o utils.o box.o tic_tac_toe.o -o TicTacToe.bin -nostdlib
15 |
16 | #check TicTacToe.bin file is x86 multiboot file or not
17 | grub-file --is-x86-multiboot TicTacToe.bin
18 |
19 | #building the iso file
20 | mkdir -p isodir/boot/grub
21 | cp TicTacToe.bin isodir/boot/TicTacToe.bin
22 | cp grub.cfg isodir/boot/grub/grub.cfg
23 | grub-mkrescue -o TicTacToe.iso isodir
24 |
25 | #run it in qemu
26 | qemu-system-x86_64 -cdrom TicTacToe.iso
27 |
--------------------------------------------------------------------------------
/Tic-Tac-Toe/src/tic_tac_toe.h:
--------------------------------------------------------------------------------
1 | #ifndef TIC_TAC_TOE_H
2 | #define TIC_TAC_TOE_H
3 |
4 | extern void launch_game();
5 |
6 |
7 | #endif
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Tic-Tac-Toe/src/types.h:
--------------------------------------------------------------------------------
1 | #ifndef TYPES_H
2 | #define TYPES_H
3 |
4 | typedef unsigned char uint8;
5 | typedef unsigned short uint16;
6 | typedef unsigned int uint32;
7 | typedef char byte;
8 | typedef int bool;
9 |
10 | #endif
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Tic-Tac-Toe/src/utils.c:
--------------------------------------------------------------------------------
1 | #include "utils.h"
2 |
3 | uint32 strlen(const char* str)
4 | {
5 | uint32 length = 0;
6 | while(str[length])
7 | length++;
8 | return length;
9 | }
10 |
11 | uint32 digit_count(int num)
12 | {
13 | uint32 count = 0;
14 | if(num == 0)
15 | return 1;
16 | while(num > 0){
17 | count++;
18 | num = num/10;
19 | }
20 | return count;
21 | }
22 |
23 | void itoa(int num, char *number)
24 | {
25 | int dgcount = digit_count(num);
26 | int index = dgcount - 1;
27 | char x;
28 | if(num == 0 && dgcount == 1){
29 | number[0] = '0';
30 | number[1] = '\0';
31 | }else{
32 | while(num != 0){
33 | x = num % 10;
34 | number[index] = x + '0';
35 | index--;
36 | num = num / 10;
37 | }
38 | number[dgcount] = '\0';
39 | }
40 | }
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/Tic-Tac-Toe/src/utils.h:
--------------------------------------------------------------------------------
1 | #ifndef UTILS_H
2 | #define UTILS_H
3 |
4 | #include "types.h"
5 |
6 | #define TRUE 1
7 | #define FALSE 0
8 |
9 | extern uint32 strlen(const char*);
10 | extern uint32 digit_count(int);
11 | extern void itoa(int, char *);
12 |
13 | #endif
14 |
15 |
--------------------------------------------------------------------------------
/Tic-Tac-Toe/tic_tac_toe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/Tic-Tac-Toe/tic_tac_toe.png
--------------------------------------------------------------------------------
/VGA/asm/color_change.asm:
--------------------------------------------------------------------------------
1 | [bits 16]
2 | [org 0x7c00]
3 |
4 | bootloader_entry:
5 | xor ax,ax
6 | mov ds,ax
7 | mov es,ax
8 |
9 | mov ah, 0x02
10 | mov al, 0x10
11 | mov dl, 0x80
12 | mov ch, 0
13 | mov dh, 0
14 | mov cl, 2
15 | mov bx, kernel_entry
16 | int 0x13
17 |
18 | cli
19 | cld
20 |
21 | jmp kernel_entry
22 |
23 | times (510 - ($ - $$)) db 0x00
24 | dw 0xAA55
25 |
26 |
27 | kernel_entry:
28 |
29 | call disable_cursor
30 |
31 | call load_vga
32 |
33 | ; clear screen with black background and white foreground
34 | mov byte[VGA_FORE_COLOR], 0xF
35 | mov byte[VGA_BACK_COLOR], 0x0
36 | call clear_screen
37 |
38 | mov si, msg_str
39 | call print_string
40 |
41 | call change_colors
42 |
43 | .exit:
44 |
45 | hlt
46 | ret
47 |
48 |
49 | change_colors:
50 | xor cx, cx
51 | mov cx, 0
52 |
53 | .loop:
54 | cmp cx, 0x10
55 | je .exit
56 |
57 | ; keyboard interrupt
58 | mov ax,0x00
59 | int 0x16
60 |
61 | mov word[VGA_BACK_COLOR], cx
62 | call clear_screen
63 |
64 | inc cx
65 | jmp .loop
66 |
67 | .exit:
68 | jmp change_colors
69 | ret
70 |
71 | print_string:
72 |
73 | .char_loop :
74 | lodsb
75 |
76 | cmp al, 0
77 | je .exit
78 |
79 | mov byte[VGA_CHAR], al
80 | call vga_print_char
81 |
82 | add word[VGA_INDEX], 2
83 |
84 | jmp .char_loop
85 |
86 | .exit:
87 | ret
88 |
89 |
90 | disable_cursor:
91 | mov ah, 0x01
92 | mov ch, 1
93 | mov cl, 0
94 | int 0x10
95 | ret
96 |
97 |
98 | load_vga:
99 | ; get vga memory address and point set es to it
100 | mov dx, [VGA_ADDRESS]
101 | mov es, dx
102 | ret
103 |
104 | vga_print_char:
105 | mov di, word[VGA_INDEX]
106 | mov al, byte[VGA_CHAR]
107 |
108 | mov ah, byte[VGA_BACK_COLOR]
109 | sal ah, 4
110 | or ah, byte[VGA_FORE_COLOR]
111 |
112 | mov [es:di], ax
113 |
114 | ret
115 |
116 |
117 | ; clear screen just displays null characters
118 | clear_screen:
119 | ;set index to 0
120 | mov di, 0
121 |
122 | .clrloop:
123 | cmp di, word[MAX_VGA_INDEX]
124 | jg .exit
125 |
126 | ; get null character into al
127 | mov al, 0
128 |
129 | mov ah, byte[VGA_BACK_COLOR]
130 | sal ah, 4
131 | or ah, byte[VGA_FORE_COLOR]
132 |
133 | ; put value of al into vga memory address
134 | mov [es:di], ax
135 |
136 | ; increase di by 2 (2 bytes)
137 | add di, 2
138 | jmp .clrloop
139 |
140 | .exit:
141 | mov word[VGA_INDEX], 0
142 | ret
143 |
144 |
145 | times (4096 - ($ - $$)) db 0x00
146 |
147 | section .data
148 | VGA_ADDRESS dw 0xB800
149 | MAX_VGA_INDEX dw 0xF9E ; 3998 in decimal
150 | VGA_INDEX dw 0
151 | VGA_CHAR db 0
152 | VGA_FORE_COLOR db 0xF
153 | VGA_BACK_COLOR db 0x0
154 |
155 | msg_str db 'Keep pressing any key to change color', 0
156 |
157 |
158 |
159 |
--------------------------------------------------------------------------------
/VGA/asm/rotate_text.asm:
--------------------------------------------------------------------------------
1 | [bits 16]
2 | [org 0x7c00]
3 |
4 | bootloader_entry:
5 | xor ax,ax
6 | mov ds,ax
7 | mov es,ax
8 |
9 | mov ah, 0x02
10 | mov al, 0x10
11 | mov dl, 0x80
12 | mov ch, 0
13 | mov dh, 0
14 | mov cl, 2
15 | mov bx, kernel_entry
16 | int 0x13
17 |
18 | cli
19 | cld
20 |
21 | jmp kernel_entry
22 |
23 | times (510 - ($ - $$)) db 0x00
24 | dw 0xAA55
25 |
26 |
27 | kernel_entry:
28 |
29 | call disable_cursor
30 |
31 | call load_vga
32 |
33 | ; clear screen with black background and white foreground
34 | mov byte[VGA_FORE_COLOR], 0xF
35 | mov byte[VGA_BACK_COLOR], 0x0
36 | call clear_screen
37 |
38 | call rotate
39 |
40 | hlt
41 | ret
42 |
43 | rotate:
44 | mov cx, 0
45 |
46 | .rotate_loop:
47 | cmp cx, word[MAX_VGA_INDEX]
48 | je .exit
49 |
50 | add word[VGA_INDEX], cx
51 |
52 | xor dx, dx
53 | mov dl, cl
54 | inc dl
55 | mov word[VGA_FORE_COLOR], dx
56 | mov word[VGA_BACK_COLOR], 0x0
57 | mov si, msg_str
58 | call print_string
59 |
60 | ; keyboard interrupt
61 | mov ax,0x00
62 | int 0x16
63 |
64 | mov word[VGA_FORE_COLOR], 0x0
65 | mov word[VGA_BACK_COLOR], 0x0
66 | call clear_screen
67 |
68 | add cx, 2
69 | jmp .rotate_loop
70 |
71 | .exit:
72 |
73 | ret
74 |
75 | print_string:
76 |
77 | .char_loop :
78 | lodsb
79 |
80 | cmp al, 0
81 | je .exit
82 |
83 | mov byte[VGA_CHAR], al
84 | call vga_print_char
85 |
86 | add word[VGA_INDEX], 2
87 |
88 | jmp .char_loop
89 |
90 | .exit:
91 | ret
92 |
93 |
94 | disable_cursor:
95 | mov ah, 0x01
96 | mov ch, 1
97 | mov cl, 0
98 | int 0x10
99 | ret
100 |
101 |
102 | load_vga:
103 | ; get vga memory address and point set es to it
104 | mov dx, [VGA_ADDRESS]
105 | mov es, dx
106 | ret
107 |
108 | vga_print_char:
109 | mov di, word[VGA_INDEX]
110 | mov al, byte[VGA_CHAR]
111 |
112 | mov ah, byte[VGA_BACK_COLOR]
113 | sal ah, 4
114 | or ah, byte[VGA_FORE_COLOR]
115 |
116 | mov [es:di], ax
117 |
118 | ret
119 |
120 |
121 | ; clear screen just displays null characters
122 | clear_screen:
123 | ;set index to 0
124 | mov di, 0
125 |
126 | .clrloop:
127 | cmp di, word[MAX_VGA_INDEX]
128 | jg .exit
129 |
130 | ; get null character into al
131 | mov al, 0
132 |
133 | mov ah, byte[VGA_BACK_COLOR]
134 | sal ah, 4
135 | or ah, byte[VGA_FORE_COLOR]
136 |
137 | ; put value of al into vga memory address
138 | mov [es:di], ax
139 |
140 | ; increase di by 2 (2 bytes)
141 | add di, 2
142 | jmp .clrloop
143 |
144 | .exit:
145 | mov word[VGA_INDEX], 0
146 | ret
147 |
148 |
149 | times (4096 - ($ - $$)) db 0x00
150 |
151 | section .data
152 | VGA_ADDRESS dw 0xB800
153 | MAX_VGA_INDEX dw 0xF9E ; 3998 in decimal
154 | VGA_INDEX dw 0
155 | VGA_CHAR db 0
156 | VGA_FORE_COLOR db 0xF
157 | VGA_BACK_COLOR db 0x0
158 |
159 | section .rodata
160 | msg_str db 'Hello', 0
161 |
162 |
163 |
164 |
--------------------------------------------------------------------------------
/VGA/asm/vga_hello.asm:
--------------------------------------------------------------------------------
1 | [bits 16]
2 | [org 0x7c00]
3 |
4 | bootloader_entry:
5 | xor ax,ax
6 | mov ds,ax
7 | mov es,ax
8 |
9 | mov ah, 0x02
10 | mov al, 0x10
11 | mov dl, 0x80
12 | mov ch, 0
13 | mov dh, 0
14 | mov cl, 2
15 | mov bx, kernel_entry
16 | int 0x13
17 |
18 | cli
19 | cld
20 |
21 | jmp kernel_entry
22 |
23 | times (510 - ($ - $$)) db 0x00
24 | dw 0xAA55
25 |
26 |
27 | kernel_entry:
28 |
29 | call disable_cursor
30 |
31 | call load_vga
32 |
33 | ; clear screen with black background and white foreground
34 | ; colors
35 | ;0x0 black
36 | ;0x1 blue
37 | ;0x2 green
38 | ;0x3 cyan
39 | ;0x4 red
40 | ;0x5 magenta
41 | ;0x6 brown
42 | ;0x7 gray
43 | ;0x8 dark gray
44 | ;0x9 bright blue
45 | ;0xA bright green
46 | ;0xB bright cyan
47 | ;0xC bright red
48 | ;0xD bright magenta
49 | ;0xE yellow
50 | ;0xF white
51 | mov byte[VGA_FORE_COLOR], 0xE
52 | mov byte[VGA_BACK_COLOR], 0x4
53 | call clear_screen
54 |
55 |
56 | ; increase VGA_INDEX to some 2 bytes amount
57 | ; so that it could lead to center of the screen
58 | add word[VGA_INDEX], 1824
59 |
60 | mov si, msg_str
61 | call print_string
62 |
63 |
64 | hlt
65 | ret
66 |
67 |
68 | print_string:
69 |
70 | .char_loop :
71 | lodsb
72 |
73 | cmp al, 0
74 | je .exit
75 |
76 | mov byte[VGA_CHAR], al
77 | call vga_print_char
78 |
79 | add word[VGA_INDEX], 2
80 |
81 | jmp .char_loop
82 |
83 | .exit:
84 | ret
85 |
86 |
87 | disable_cursor:
88 | mov ah, 0x01
89 | mov ch, 1
90 | mov cl, 0
91 | int 0x10
92 | ret
93 |
94 |
95 | load_vga:
96 | ; get vga memory address and point set es to it
97 | mov dx, [VGA_ADDRESS]
98 | mov es, dx
99 | ret
100 |
101 |
102 | vga_print_char:
103 | mov di, word[VGA_INDEX]
104 | mov al, byte[VGA_CHAR]
105 |
106 | ; 1 byte fore and back color
107 | ; high 4 bits : back color
108 | ; low 4 bits : fore color
109 |
110 | ; get back color
111 | mov ah, byte[VGA_BACK_COLOR]
112 | ; rotate it by 4 to left,
113 | ; for high 4 bits
114 | sal ah, 4
115 | ; oring with fore color value
116 | or ah, byte[VGA_FORE_COLOR]
117 |
118 | ; see kernel.c source, from Kernel folder
119 |
120 | mov [es:di], ax
121 |
122 | ret
123 |
124 |
125 | ; clear screen just displays null characters
126 | clear_screen:
127 | ;set index to 0
128 | mov di, 0
129 |
130 | .clrloop:
131 | cmp di, word[MAX_VGA_INDEX]
132 | jg .exit
133 |
134 | ; get null character into al
135 | mov al, 0
136 |
137 | mov ah, byte[VGA_BACK_COLOR]
138 | sal ah, 4
139 | or ah, byte[VGA_FORE_COLOR]
140 |
141 | ; put value of al into vga memory address
142 | mov [es:di], ax
143 |
144 | ; increase di by 2 (2 bytes)
145 | add di, 2
146 | jmp .clrloop
147 |
148 | .exit:
149 | mov word[VGA_INDEX], 0
150 | ret
151 |
152 |
153 | times (4096 - ($ - $$)) db 0x00
154 |
155 | section .data
156 | VGA_ADDRESS dw 0xB800
157 | MAX_VGA_INDEX dw 0xF9E ; 3998 in decimal
158 | VGA_INDEX dw 0
159 | VGA_CHAR db 0
160 | VGA_FORE_COLOR db 0xF
161 | VGA_BACK_COLOR db 0x0
162 |
163 | section .rodata
164 | msg_str db 'Hello World!', 0
165 |
166 |
167 |
168 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bitmap_Text/bitmap.c:
--------------------------------------------------------------------------------
1 | #include "bitmap.h"
2 | #include "types.h"
3 | #include "vga.h"
4 |
5 |
6 | // 0 = no-pixel, 1 = pixel
7 |
8 | uint8 bitmaps_0_9[10][BITMAP_SIZE] = {
9 | // 0
10 | {0b01111110, 0b11000011, 0b11000111, 0b11001111,
11 | 0b11011011, 0b11110011, 0b11100011, 0b01111110},
12 |
13 | // 1
14 | {0b00011000, 0b00111000, 0b00111000, 0b00011000,
15 | 0b00011000, 0b00011000, 0b01111110, 0b01111110},
16 |
17 | // 2
18 | {0b00111100, 0b11100111, 0b00000111, 0b00000110,
19 | 0b00011110, 0b01111000, 0b11100011, 0b11111111},
20 |
21 | // 3
22 | {0b00111100, 0b11100111, 0b00000111, 0b00011100,
23 | 0b00000111, 0b00000111, 0b11100110, 0b00111100},
24 |
25 | // 4
26 | {0b00011100, 0b00111100, 0b01101100, 0b11001100,
27 | 0b11001100, 0b11111110, 0b00001100, 0b00011110},
28 |
29 | // 5
30 | {0b11111111, 0b11000000, 0b11111110, 0b00000111,
31 | 0b00000111, 0b00000111, 0b11000110, 0b01111110},
32 |
33 | // 6
34 | {0b00011100, 0b00110000, 0b01100000, 0b11000000,
35 | 0b11111110, 0b11000011, 0b11000011, 0b01111110},
36 |
37 | // 7
38 | {0b11111111, 0b11111111, 0b11000111, 0b00000111,
39 | 0b00001110, 0b00111000, 0b00111000, 0b00111000},
40 |
41 | // 8
42 | {0b01111110, 0b01111110, 0b11000011, 0b11000011,
43 | 0b01111110, 0b11000011, 0b11000011, 0b01111110},
44 |
45 | // 9
46 | {0b01111110, 0b11000011, 0b11000011, 0b01111111,
47 | 0b00000011, 0b00000111, 0b00001110, 0b01111100},
48 | };
49 |
50 |
51 | uint8 bitmaps_A_Z[26][BITMAP_SIZE] = {
52 | // A
53 | {0b00011000, 0b00111100, 0b01100110, 0b11000011,
54 | 0b11000011, 0b11111111, 0b11000011, 0b11000011},
55 |
56 | // B
57 | {0b11111100, 0b01100110, 0b01100110, 0b01111100,
58 | 0b01111100, 0b01100110, 0b01100110, 0b11111100},
59 |
60 | // C
61 | {0b00111110, 0b01100011, 0b11000000, 0b11000000,
62 | 0b11000000, 0b11000000, 0b01100011, 0b00111110},
63 |
64 | // D
65 | {0b11111100, 0b01100110, 0b01100011, 0b01100011,
66 | 0b01100011, 0b01100011, 0b01100110, 0b11111100},
67 |
68 | // E
69 | {0b11111111, 0b01100001, 0b01100000, 0b01100100,
70 | 0b01111100, 0b01100100, 0b01100001, 0b11111111},
71 |
72 | // F
73 | {0b11111111, 0b01100001, 0b01100000, 0b01100100,
74 | 0b01111100, 0b01100100, 0b01100000, 0b11110000},
75 |
76 | // G
77 | {0b00111110, 0b01100011, 0b11000000, 0b11000000,
78 | 0b11000111, 0b11100011, 0b01100011, 0b00111111},
79 |
80 | // H
81 | {0b11000011, 0b11000011, 0b11000011, 0b11000011,
82 | 0b11111111, 0b11000011, 0b11000011, 0b11000011},
83 |
84 | // I
85 | {0b01111110, 0b00011000, 0b00011000, 0b00011000,
86 | 0b00011000, 0b00011000, 0b00011000, 0b01111110},
87 |
88 | // J
89 | {0b00001111, 0b00000110, 0b00000110, 0b00000110,
90 | 0b00000110, 0b11000110, 0b11000110, 0b01111100},
91 |
92 | // K
93 | {0b11100011, 0b01100011, 0b01100110, 0b01101100,
94 | 0b01111000, 0b01101100, 0b01100110, 0b11100011},
95 |
96 | // L
97 | {0b11110000, 0b01100000, 0b01100000, 0b01100000,
98 | 0b01100000, 0b01100001, 0b01100011, 0b11111111},
99 |
100 | // M
101 | {0b11000011, 0b11100111, 0b11111111, 0b11111111,
102 | 0b11011011, 0b11000011, 0b11000011, 0b11000011},
103 |
104 | // N
105 | {0b11000011, 0b11100011, 0b11110011, 0b11011011,
106 | 0b11001111, 0b11000111, 0b11000011, 0b11000011},
107 |
108 | // O
109 | {0b00111100, 0b01100110, 0b11000011, 0b11000011,
110 | 0b11000011, 0b11000011, 0b01100110, 0b00111100},
111 |
112 | // P
113 | {0b11111110, 0b01100011, 0b01100011, 0b01100011,
114 | 0b01111110, 0b01100000, 0b01100000, 0b11110000},
115 |
116 | // Q
117 | {0b01111110, 0b11000011, 0b11000011, 0b11000011,
118 | 0b11000011, 0b11001111, 0b01111110, 0b00001111},
119 |
120 | // R
121 | {0b11111110, 0b01100011, 0b01100011, 0b01111110,
122 | 0b01101110, 0b01100110, 0b01100011, 0b11100011},
123 |
124 | // S
125 | {0b01111110, 0b11000011, 0b11100000, 0b01110000,
126 | 0b00011111, 0b00000011, 0b11000110, 0b01111100},
127 |
128 | // T
129 | {0b11111111, 0b10011001, 0b00011000, 0b00011000,
130 | 0b00011000, 0b00011000, 0b00011000, 0b00111100},
131 |
132 | // U
133 | {0b11000011, 0b11000011, 0b11000011, 0b11000011,
134 | 0b11000011, 0b11000011, 0b11000011, 0b11111111},
135 |
136 | // V
137 | {0b11000011, 0b11000011, 0b11000011, 0b11000011,
138 | 0b11000011, 0b11000011, 0b00111100, 0b00011000},
139 |
140 | // W
141 | {0b11000011, 0b11000011, 0b11000011, 0b11000011,
142 | 0b11011011, 0b11111111, 0b11100111, 0b11000011},
143 |
144 | // X
145 | {0b11000011, 0b11000011, 0b01100110, 0b01100110,
146 | 0b00111100, 0b00111100, 0b01100111, 0b11000011},
147 |
148 | // Y
149 | {0b11000011, 0b11000011, 0b11000011, 0b11000011,
150 | 0b01111110, 0b000011000, 0b00011000, 0b00111100},
151 |
152 | // Z
153 | {0b11111111, 0b11000011, 0b10000110, 0b00001100,
154 | 0b00011000, 0b00110001, 0b01100011, 0b11111111}
155 |
156 | };
157 |
158 | // putpixels of 0-9 bits from right-to-left
159 | void draw_num_bitmaps(uint16 index, uint16 x, uint16 y, uint8 color)
160 | {
161 | uint16 temp = 0, pix = 0;
162 |
163 | for(uint8 i = 0; i < BITMAP_SIZE; i++){
164 | temp = x;
165 | x += BITMAP_SIZE;
166 | pix = bitmaps_0_9[index][i];
167 | while(pix > 0){
168 | if(pix & 1){
169 | putpixel(x, y, color);
170 | }
171 | pix >>= 1;
172 | x--;
173 | }
174 | x = temp;
175 | y++;
176 | }
177 | }
178 |
179 | // putpixels of A-Z bits from right-to-left
180 | void draw_alpha_bitmaps(uint16 index, uint16 x, uint16 y, uint8 color)
181 | {
182 | uint16 temp = 0, pix = 0;
183 |
184 | for(uint8 i = 0; i < BITMAP_SIZE; i++){
185 | temp = x;
186 | x += BITMAP_SIZE;
187 | pix = bitmaps_A_Z[index][i];
188 | while(pix > 0){
189 | if(pix & 1){
190 | putpixel(x, y, color);
191 | }
192 | pix >>= 1;
193 | x--;
194 | }
195 | x = temp;
196 | y++;
197 | }
198 | }
199 |
200 | void draw_char(uint16 x, uint16 y, uint8 color, char ch)
201 | {
202 | if(ch >= '0' && ch <= '9'){
203 | draw_num_bitmaps(ch - '0', x, y, color);
204 | }else if(ch >= 'A' && ch <= 'Z'){
205 | draw_alpha_bitmaps((ch - '0') - 17, x, y, color);
206 | }
207 | }
208 |
209 | void draw_string(uint16 x, uint16 y, uint8 color, char *str)
210 | {
211 | uint32 index = 0;
212 |
213 | while(str[index]){
214 | draw_char(x, y, color, str[index]);
215 | x += BITMAP_SIZE + 1;
216 | index++;
217 | }
218 | }
219 |
220 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bitmap_Text/bitmap.h:
--------------------------------------------------------------------------------
1 | #ifndef BITMAP_H
2 | #define BITMAP_H
3 |
4 | #include "types.h"
5 |
6 | #define BITMAP_SIZE 8
7 |
8 | void draw_char(uint16 x, uint16 y, uint8 color, char ch);
9 | void draw_string(uint16 x, uint16 y, uint8 color, char *str);
10 |
11 | #endif
12 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bitmap_Text/boot.s:
--------------------------------------------------------------------------------
1 | # set magic number to 0x1BADB002 to identified by bootloader
2 | .set MAGIC, 0x1BADB002
3 |
4 | # set flags to 0
5 | .set FLAGS, 0
6 |
7 | # set the checksum
8 | .set CHECKSUM, -(MAGIC + FLAGS)
9 |
10 | # set multiboot enabled
11 | .section .multiboot
12 |
13 | # define type to long for each data defined as above
14 | .long MAGIC
15 | .long FLAGS
16 | .long CHECKSUM
17 |
18 |
19 | # set the stack bottom
20 | stackBottom:
21 |
22 | # define the maximum size of stack to 512 bytes
23 | .skip 1024
24 |
25 |
26 | # set the stack top which grows from higher to lower
27 | stackTop:
28 |
29 | .section .text
30 | .global _start
31 | .global load_gdt
32 | .type _start, @function
33 |
34 | load_gdt:
35 | mov 4(%esp), %eax
36 | lgdt (%eax)
37 |
38 | mov $0x10, %eax
39 | mov %eax, %ds
40 | mov %eax, %es
41 | mov %eax, %fs
42 | mov %eax, %gs
43 | mov %eax, %ss
44 | jmp $0x8, $.long_jump
45 | .long_jump:
46 | ret
47 |
48 |
49 | _start:
50 |
51 | # assign current stack pointer location to stackTop
52 | mov $stackTop, %esp
53 |
54 | # call the kernel main source
55 | call kernel_entry
56 |
57 | cli
58 |
59 |
60 | # put system in infinite loop
61 | hltLoop:
62 |
63 | hlt
64 | jmp hltLoop
65 |
66 | .size _start, . - _start
67 |
68 |
69 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bitmap_Text/grub.cfg:
--------------------------------------------------------------------------------
1 | menuentry "MyOS" {
2 | multiboot /boot/MyOS.bin
3 | }
4 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bitmap_Text/kernel.c:
--------------------------------------------------------------------------------
1 | #include "kernel.h"
2 | #include "vga.h"
3 | #include "keyboard.h"
4 | #include "bitmap.h"
5 |
6 | uint8 inb(uint16 port)
7 | {
8 | uint8 data;
9 | asm volatile("inb %1, %0" : "=a"(data) : "Nd"(port));
10 | return data;
11 | }
12 |
13 | void outb(uint16 port, uint8 data)
14 | {
15 | asm volatile("outb %0, %1" : : "a"(data), "Nd"(port));
16 | }
17 |
18 |
19 | void kernel_entry()
20 | {
21 | init_vga();
22 |
23 | draw_string(0, 0, WHITE, "HELLO WORLD");
24 | }
25 |
26 |
27 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bitmap_Text/kernel.h:
--------------------------------------------------------------------------------
1 | #ifndef KERNEL_H
2 | #define KERNEL_H
3 |
4 | #include "types.h"
5 |
6 | #define NULL 0
7 |
8 | uint8 inb(uint16 port);
9 | void outb(uint16 port, uint8 data);
10 |
11 | #endif
12 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bitmap_Text/keyboard.h:
--------------------------------------------------------------------------------
1 | #ifndef KEYBOARD_H
2 | #define KEYBOARD_H
3 |
4 | #define KEYBOARD_PORT 0x60
5 |
6 |
7 | #define KEY_A 0x1E
8 | #define KEY_B 0x30
9 | #define KEY_C 0x2E
10 | #define KEY_D 0x20
11 | #define KEY_E 0x12
12 | #define KEY_F 0x21
13 | #define KEY_G 0x22
14 | #define KEY_H 0x23
15 | #define KEY_I 0x17
16 | #define KEY_J 0x24
17 | #define KEY_K 0x25
18 | #define KEY_L 0x26
19 | #define KEY_M 0x32
20 | #define KEY_N 0x31
21 | #define KEY_O 0x18
22 | #define KEY_P 0x19
23 | #define KEY_Q 0x10
24 | #define KEY_R 0x13
25 | #define KEY_S 0x1F
26 | #define KEY_T 0x14
27 | #define KEY_U 0x16
28 | #define KEY_V 0x2F
29 | #define KEY_W 0x11
30 | #define KEY_X 0x2D
31 | #define KEY_Y 0x15
32 | #define KEY_Z 0x2C
33 | #define KEY_1 0x02
34 | #define KEY_2 0x03
35 | #define KEY_3 0x04
36 | #define KEY_4 0x05
37 | #define KEY_5 0x06
38 | #define KEY_6 0x07
39 | #define KEY_7 0x08
40 | #define KEY_8 0x09
41 | #define KEY_9 0x0A
42 | #define KEY_0 0x0B
43 | #define KEY_MINUS 0x0C
44 | #define KEY_EQUAL 0x0D
45 | #define KEY_SQUARE_OPEN_BRACKET 0x1A
46 | #define KEY_SQUARE_CLOSE_BRACKET 0x1B
47 | #define KEY_SEMICOLON 0x27
48 | #define KEY_BACKSLASH 0x2B
49 | #define KEY_COMMA 0x33
50 | #define KEY_DOT 0x34
51 | #define KEY_FORESLHASH 0x35
52 | #define KEY_F1 0x3B
53 | #define KEY_F2 0x3C
54 | #define KEY_F3 0x3D
55 | #define KEY_F4 0x3E
56 | #define KEY_F5 0x3F
57 | #define KEY_F6 0x40
58 | #define KEY_F7 0x41
59 | #define KEY_F8 0x42
60 | #define KEY_F9 0x43
61 | #define KEY_F10 0x44
62 | #define KEY_F11 0x85
63 | #define KEY_F12 0x86
64 | #define KEY_BACKSPACE 0x0E
65 | #define KEY_DELETE 0x53
66 | #define KEY_DOWN 0x50
67 | #define KEY_END 0x4F
68 | #define KEY_ENTER 0x1C
69 | #define KEY_ESC 0x01
70 | #define KEY_HOME 0x47
71 | #define KEY_INSERT 0x52
72 | #define KEY_KEYPAD_5 0x4C
73 | #define KEY_KEYPAD_MUL 0x37
74 | #define KEY_KEYPAD_Minus 0x4A
75 | #define KEY_KEYPAD_PLUS 0x4E
76 | #define KEY_KEYPAD_DIV 0x35
77 | #define KEY_LEFT 0x4B
78 | #define KEY_PAGE_DOWN 0x51
79 | #define KEY_PAGE_UP 0x49
80 | #define KEY_PRINT_SCREEN 0x37
81 | #define KEY_RIGHT 0x4D
82 | #define KEY_SPACE 0x39
83 | #define KEY_TAB 0x0F
84 | #define KEY_UP 0x48
85 |
86 |
87 | #endif
88 |
89 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bitmap_Text/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 | }
40 |
41 | /* The compiler may produce other sections, by default it will put them in
42 | a segment with the same name. Simply add stuff here as needed. */
43 | }
44 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bitmap_Text/run.sh:
--------------------------------------------------------------------------------
1 | #assemble boot.s file
2 | as --32 boot.s -o boot.o
3 |
4 | #compile kernel.c file
5 | gcc -m32 -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
6 |
7 | #compile vga.c file
8 | gcc -m32 -c vga.c -o vga.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
9 |
10 | #compile bitmap.c file
11 | gcc -m32 -c bitmap.c -o bitmap.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
12 |
13 | #linking the kernel with kernel.o and boot.o files
14 | ld -m elf_i386 -T linker.ld kernel.o vga.o bitmap.o boot.o -o MyOS.bin -nostdlib
15 |
16 | #check MyOS.bin file is x86 multiboot file or not
17 | grub-file --is-x86-multiboot MyOS.bin
18 |
19 | #building the iso file
20 | mkdir -p isodir/boot/grub
21 | cp MyOS.bin isodir/boot/MyOS.bin
22 | cp grub.cfg isodir/boot/grub/grub.cfg
23 | grub-mkrescue -o MyOS.iso isodir
24 |
25 | #run it in qemu
26 | qemu-system-x86_64 -cdrom MyOS.iso
27 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bitmap_Text/types.h:
--------------------------------------------------------------------------------
1 | #ifndef TYPES_H
2 | #define TYPES_H
3 |
4 | typedef unsigned char uint8;
5 | typedef unsigned short uint16;
6 | typedef unsigned int uint32;
7 |
8 | #endif
9 |
10 |
11 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bitmap_Text/vga.c:
--------------------------------------------------------------------------------
1 | #include "vga.h"
2 | #include "kernel.h"
3 |
4 | /*
5 | See Intel® OpenSource HD Graphics PRM pdf file
6 | for following defined data for each vga register
7 | and its explaination
8 | */
9 | static uint8 seq_data[5] = {0x03, 0x01, 0x0F, 0x00, 0x0E};
10 | static uint8 crtc_data[25] = {0x5F, 0x4F, 0x50, 0x82,
11 | 0x54, 0x80, 0xBF, 0x1F,
12 | 0x00, 0x41, 0x00, 0x00,
13 | 0x00, 0x00, 0x00, 0x00,
14 | 0x9C, 0x0E, 0x8F, 0x28,
15 | 0x40, 0x96, 0xB9, 0xA3,
16 | 0xFF};
17 |
18 | static uint8 gc_data[9] = {0x00, 0x00, 0x00, 0x00,
19 | 0x00, 0x40, 0x05, 0x0F,
20 | 0xFF};
21 |
22 | static uint8 ac_data[21] = {0x00, 0x01, 0x02, 0x03,
23 | 0x04, 0x05, 0x06, 0x07,
24 | 0x08, 0x09, 0x0A, 0x0B,
25 | 0x0C, 0x0D, 0x0E, 0x0F,
26 | 0x41, 0x00, 0x0F, 0x00,
27 | 0x00};
28 |
29 | void set_misc()
30 | {
31 | outb(VGA_MISC_WRITE, 0x63);
32 | }
33 |
34 | void set_seq()
35 | {
36 | // write sequence data to index of 0-4
37 | for(uint8 index = 0; index < 5; index++){
38 | // first set index
39 | outb(VGA_SEQ_INDEX, index);
40 | // write data at that index
41 | outb(VGA_SEQ_DATA, seq_data[index]);
42 | }
43 | }
44 |
45 | void set_crtc()
46 | {
47 | // write crtc data to index of 0-24
48 | for(uint8 index = 0; index < 25; index++){
49 | outb(VGA_CRTC_INDEX, index);
50 | outb(VGA_CRTC_DATA, crtc_data[index]);
51 | }
52 | }
53 |
54 | void set_gc()
55 | {
56 | // write gc data to index of 0-8
57 | for(uint8 index = 0; index < 9; index++){
58 | outb(VGA_GC_INDEX, index);
59 | outb(VGA_GC_DATA, gc_data[index]);
60 | }
61 | }
62 |
63 | void set_ac()
64 | {
65 | uint8 d;
66 | // write ac data to index of 0-20
67 | for(uint8 index = 0; index < 21; index++){
68 | outb(VGA_AC_INDEX, index);
69 | outb(VGA_AC_WRITE, ac_data[index]);
70 | }
71 | d = inb(VGA_INSTAT_READ);
72 | outb(VGA_AC_INDEX, d | 0x20);
73 | }
74 |
75 | void clear_screen()
76 | {
77 | for(uint32 index = 0; index < VGA_MAX; index++)
78 | vga_buffer[index] = 0;
79 | }
80 |
81 | void clear_color(uint8 color)
82 | {
83 | for(uint32 index = 0; index < VGA_MAX; index++)
84 | vga_buffer[index] = color;
85 | }
86 |
87 | void init_vga()
88 | {
89 | set_misc();
90 | set_seq();
91 | set_crtc();
92 | set_gc();
93 | set_ac();
94 |
95 | vga_buffer = (uint8*)VGA_ADDRESS;
96 |
97 | clear_screen();
98 | }
99 |
100 | void putpixel(uint16 x, uint16 y, uint8 color)
101 | {
102 | uint32 index = 0;
103 | index = 320 * y + x;
104 | if(index < VGA_MAX)
105 | vga_buffer[index] = color;
106 | }
107 |
108 | void draw_line(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint8 color)
109 | {
110 | if(y1 == y2){
111 | for(uint16 i = x1; i <= x2; i++)
112 | putpixel(i, y1, color);
113 | return;
114 | }
115 |
116 | if(x1 == x2){
117 | for(uint16 i = y1; i <= y2; i++){
118 | putpixel(x1, i, color);
119 | }
120 | return;
121 | }
122 | }
123 |
124 | void draw_rect(uint16 x, uint16 y, uint16 width, uint16 height, uint8 color)
125 | {
126 | draw_line(x, y, x, y + height, color);
127 | draw_line(x, y, x + width, y, color);
128 | draw_line(x + width, y, x + width, y + height, color);
129 | draw_line(x, y + height, x + width, y + height, color);
130 | }
131 |
132 | void fill_rect(uint16 x, uint16 y, uint16 width, uint16 height, uint8 color)
133 | {
134 | draw_line(x, y, x, y + height, color);
135 | draw_line(x, y, x + width, y, color);
136 | draw_line(x + width, y, x + width, y + height, color);
137 | draw_line(x, y + height, x + width, y + height, color);
138 | for(int i = y; i < y + height; i++){
139 | draw_line(x, i, x + width, i, color);
140 | }
141 | }
142 |
143 | void draw_bresenham_circle(int xc, int yc, int x, int y, uint8 color)
144 | {
145 | putpixel(xc+x, yc+y, color);
146 | putpixel(xc-x, yc+y, color);
147 | putpixel(xc+x, yc-y, color);
148 | putpixel(xc-x, yc-y, color);
149 | putpixel(xc+y, yc+x, color);
150 | putpixel(xc-y, yc+x, color);
151 | putpixel(xc+y, yc-x, color);
152 | putpixel(xc-y, yc-x, color);
153 | }
154 |
155 | void draw_circle(uint16 x, uint16 y, uint16 radius, uint8 color)
156 | {
157 | int x2 = 0, y2 = radius;
158 | int d = 3 - 2 * radius;
159 | draw_bresenham_circle(x, y, x2, y2, color);
160 | while(y2 >= x2){
161 | x2++;
162 | if(d > 0){
163 | y2--;
164 | d = d + 4 * (x2 - y2) + 10;
165 | }else{
166 | d = d + 4 * x2 + 6;
167 | }
168 | draw_bresenham_circle(x, y, x2, y2, color);
169 | }
170 | }
171 |
172 | void draw_diamond(uint16 x, uint16 y, uint16 radius, uint8 color)
173 | {
174 | uint16 x2 = 0, y2 = radius;
175 | uint16 d = 3 - 2 * radius;
176 | draw_bresenham_circle(x, y, x2, y2, color);
177 | while(y2 >= x2){
178 | x2++;
179 | if(d > 0){
180 | y2--;
181 | d = d + 4 * (x2 - y2) + 10;
182 | }else{
183 | d = d + 4 * x2 + 6;
184 | }
185 | draw_bresenham_circle(x, y, x2, y2, color);
186 | }
187 | }
188 |
189 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bitmap_Text/vga.h:
--------------------------------------------------------------------------------
1 | #ifndef VGA_H
2 | #define VGA_H
3 |
4 | #include "types.h"
5 |
6 | #define VGA_ADDRESS 0xA0000
7 | #define VGA_MAX 0xF9FF
8 | #define VGA_MAX_WIDTH 320
9 | #define VGA_MAX_HEIGHT 200
10 |
11 | uint8* vga_buffer;
12 |
13 | enum vga_color {
14 | BLACK,
15 | BLUE,
16 | GREEN,
17 | CYAN,
18 | RED,
19 | MAGENTA,
20 | BROWN,
21 | GREY,
22 | DARK_GREY,
23 | BRIGHT_BLUE,
24 | BRIGHT_GREEN,
25 | BRIGHT_CYAN,
26 | BRIGHT_RED,
27 | BRIGHT_MAGENTA,
28 | YELLOW,
29 | WHITE,
30 | };
31 |
32 | /* Attribute Controller Registers */
33 | #define VGA_AC_INDEX 0x3C0
34 | #define VGA_AC_READ 0x3C1
35 | #define VGA_AC_WRITE 0x3C0
36 |
37 | /*
38 | Miscellaneous Output
39 | */
40 | #define VGA_MISC_READ 0x3CC
41 | #define VGA_MISC_WRITE 0x3C2
42 |
43 | /* Sequencer Registers */
44 | #define VGA_SEQ_INDEX 0x3C4
45 | #define VGA_SEQ_DATA 0x3C5
46 |
47 | /* VGA Color Palette Registers */
48 | #define VGA_DAC_READ_INDEX 0x3C7
49 | #define VGA_DAC_WRITE_INDEX 0x3C8
50 | #define VGA_DAC_DATA 0x3C9
51 |
52 | /* Graphics Controller Registers */
53 | #define VGA_GC_INDEX 0x3CE
54 | #define VGA_GC_DATA 0x3CF
55 |
56 | /* CRT Controller Registers */
57 | #define VGA_CRTC_INDEX 0x3D4
58 | #define VGA_CRTC_DATA 0x3D5
59 |
60 | /* General Control and Status Registers */
61 | #define VGA_INSTAT_READ 0x3DA
62 |
63 | void init_vga();
64 | void clear_screen();
65 | void clear_color(uint8 color);
66 | void putpixel(uint16 x, uint16 y, uint8 color);
67 | void draw_line(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint8 color);
68 | void draw_rect(uint16 x, uint16 y, uint16 width, uint16 height, uint8 color);
69 | void fill_rect(uint16 x, uint16 y, uint16 width, uint16 height, uint8 color);
70 | void draw_circle(uint16 x, uint16 y, uint16 radius, uint8 color);
71 | void draw_diamond(uint16 x, uint16 y, uint16 radius, uint8 color);
72 |
73 | #endif
74 |
75 |
76 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bounce Rect/boot.s:
--------------------------------------------------------------------------------
1 | # set magic number to 0x1BADB002 to identified by bootloader
2 | .set MAGIC, 0x1BADB002
3 |
4 | # set flags to 0
5 | .set FLAGS, 0
6 |
7 | # set the checksum
8 | .set CHECKSUM, -(MAGIC + FLAGS)
9 |
10 | # set multiboot enabled
11 | .section .multiboot
12 |
13 | # define type to long for each data defined as above
14 | .long MAGIC
15 | .long FLAGS
16 | .long CHECKSUM
17 |
18 |
19 | # set the stack bottom
20 | stackBottom:
21 |
22 | # define the maximum size of stack to 512 bytes
23 | .skip 1024
24 |
25 |
26 | # set the stack top which grows from higher to lower
27 | stackTop:
28 |
29 | .section .text
30 | .global _start
31 | .global load_gdt
32 | .type _start, @function
33 |
34 | load_gdt:
35 | mov 4(%esp), %eax
36 | lgdt (%eax)
37 |
38 | mov $0x10, %eax
39 | mov %eax, %ds
40 | mov %eax, %es
41 | mov %eax, %fs
42 | mov %eax, %gs
43 | mov %eax, %ss
44 | jmp $0x8, $.long_jump
45 | .long_jump:
46 | ret
47 |
48 |
49 | _start:
50 |
51 | # assign current stack pointer location to stackTop
52 | mov $stackTop, %esp
53 |
54 | # call the kernel main source
55 | call kernel_entry
56 |
57 | cli
58 |
59 |
60 | # put system in infinite loop
61 | hltLoop:
62 |
63 | hlt
64 | jmp hltLoop
65 |
66 | .size _start, . - _start
67 |
68 |
69 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bounce Rect/grub.cfg:
--------------------------------------------------------------------------------
1 | menuentry "MyOS" {
2 | multiboot /boot/MyOS.bin
3 | }
4 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bounce Rect/kernel.c:
--------------------------------------------------------------------------------
1 | #include "kernel.h"
2 | #include "vga.h"
3 | #include "keyboard.h"
4 |
5 | uint8 inb(uint16 port)
6 | {
7 | uint8 data;
8 | asm volatile("inb %1, %0" : "=a"(data) : "Nd"(port));
9 | return data;
10 | }
11 |
12 | void outb(uint16 port, uint8 data)
13 | {
14 | asm volatile("outb %0, %1" : : "a"(data), "Nd"(port));
15 | }
16 |
17 | uint8 get_input_keycode()
18 | {
19 | uint8 keycode = 0;
20 | while((keycode = inb(KEYBOARD_PORT)) != 0){
21 | if(keycode > 0)
22 | return keycode;
23 | }
24 | return keycode;
25 | }
26 |
27 | /*
28 | keep the cpu busy for doing nothing(nop)
29 | so that io port will not be processed by cpu
30 | here timer can also be used, but lets do this in looping counter
31 | */
32 | void wait_for_io(uint32 timer_count)
33 | {
34 | while(1){
35 | asm volatile("nop");
36 | timer_count--;
37 | if(timer_count <= 0)
38 | break;
39 | }
40 | }
41 |
42 | void sleep(uint32 timer_count)
43 | {
44 | uint32 t = 0xeeeeef * timer_count;
45 | wait_for_io(t);
46 | }
47 |
48 |
49 | void bounce_rect()
50 | {
51 | const uint16 rect_size = 10;
52 | uint16 rect_pos_x = rect_size;
53 | uint16 rect_pos_y = rect_size;
54 | uint16 rect_speed_x = 5;
55 | uint16 rect_speed_y = 5;
56 |
57 | while(1){
58 | // add speed values to positions
59 | rect_pos_x += rect_speed_x;
60 | rect_pos_y += rect_speed_y;
61 |
62 | // check if position x < 0
63 | if(rect_pos_x - rect_size < 0){
64 | // decrese added speed
65 | rect_speed_x = -rect_speed_x;
66 | // set position x to rect size
67 | rect_pos_x = rect_size;
68 | }else if(rect_pos_x + rect_size > VGA_MAX_WIDTH + rect_size){
69 | // check if position > VGA width + rect_size
70 | // decrese added speed
71 | rect_speed_x = -rect_speed_x;
72 | // set position x to minimum of VGA width rect size
73 | rect_pos_x = VGA_MAX_WIDTH - rect_size;
74 | }
75 |
76 | // same action for position y
77 | if(rect_pos_y - rect_size < 0){
78 | rect_speed_y = -rect_speed_y;
79 | rect_pos_y = rect_size;
80 | }else if(rect_pos_y + rect_size > VGA_MAX_HEIGHT + rect_size){
81 | rect_speed_y = -rect_speed_y;
82 | rect_pos_y = VGA_MAX_HEIGHT - rect_size;
83 | }
84 |
85 | // clear screen
86 | clear_screen();
87 | // fill rect
88 | fill_rect(rect_pos_x - rect_size, rect_pos_y - rect_size, rect_size, rect_size, WHITE);
89 | // change sleep value if running in VirtualBox or on bare metal
90 | sleep(1);
91 | }
92 | }
93 |
94 | void kernel_entry()
95 | {
96 | init_vga();
97 | bounce_rect();
98 | }
99 |
100 |
101 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bounce Rect/kernel.h:
--------------------------------------------------------------------------------
1 | #ifndef KERNEL_H
2 | #define KERNEL_H
3 |
4 | #include "types.h"
5 |
6 | #define NULL 0
7 |
8 | uint8 inb(uint16 port);
9 | void outb(uint16 port, uint8 data);
10 |
11 | #endif
12 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bounce Rect/keyboard.h:
--------------------------------------------------------------------------------
1 | #ifndef KEYBOARD_H
2 | #define KEYBOARD_H
3 |
4 | #define KEYBOARD_PORT 0x60
5 |
6 |
7 | #define KEY_A 0x1E
8 | #define KEY_B 0x30
9 | #define KEY_C 0x2E
10 | #define KEY_D 0x20
11 | #define KEY_E 0x12
12 | #define KEY_F 0x21
13 | #define KEY_G 0x22
14 | #define KEY_H 0x23
15 | #define KEY_I 0x17
16 | #define KEY_J 0x24
17 | #define KEY_K 0x25
18 | #define KEY_L 0x26
19 | #define KEY_M 0x32
20 | #define KEY_N 0x31
21 | #define KEY_O 0x18
22 | #define KEY_P 0x19
23 | #define KEY_Q 0x10
24 | #define KEY_R 0x13
25 | #define KEY_S 0x1F
26 | #define KEY_T 0x14
27 | #define KEY_U 0x16
28 | #define KEY_V 0x2F
29 | #define KEY_W 0x11
30 | #define KEY_X 0x2D
31 | #define KEY_Y 0x15
32 | #define KEY_Z 0x2C
33 | #define KEY_1 0x02
34 | #define KEY_2 0x03
35 | #define KEY_3 0x04
36 | #define KEY_4 0x05
37 | #define KEY_5 0x06
38 | #define KEY_6 0x07
39 | #define KEY_7 0x08
40 | #define KEY_8 0x09
41 | #define KEY_9 0x0A
42 | #define KEY_0 0x0B
43 | #define KEY_MINUS 0x0C
44 | #define KEY_EQUAL 0x0D
45 | #define KEY_SQUARE_OPEN_BRACKET 0x1A
46 | #define KEY_SQUARE_CLOSE_BRACKET 0x1B
47 | #define KEY_SEMICOLON 0x27
48 | #define KEY_BACKSLASH 0x2B
49 | #define KEY_COMMA 0x33
50 | #define KEY_DOT 0x34
51 | #define KEY_FORESLHASH 0x35
52 | #define KEY_F1 0x3B
53 | #define KEY_F2 0x3C
54 | #define KEY_F3 0x3D
55 | #define KEY_F4 0x3E
56 | #define KEY_F5 0x3F
57 | #define KEY_F6 0x40
58 | #define KEY_F7 0x41
59 | #define KEY_F8 0x42
60 | #define KEY_F9 0x43
61 | #define KEY_F10 0x44
62 | #define KEY_F11 0x85
63 | #define KEY_F12 0x86
64 | #define KEY_BACKSPACE 0x0E
65 | #define KEY_DELETE 0x53
66 | #define KEY_DOWN 0x50
67 | #define KEY_END 0x4F
68 | #define KEY_ENTER 0x1C
69 | #define KEY_ESC 0x01
70 | #define KEY_HOME 0x47
71 | #define KEY_INSERT 0x52
72 | #define KEY_KEYPAD_5 0x4C
73 | #define KEY_KEYPAD_MUL 0x37
74 | #define KEY_KEYPAD_Minus 0x4A
75 | #define KEY_KEYPAD_PLUS 0x4E
76 | #define KEY_KEYPAD_DIV 0x35
77 | #define KEY_LEFT 0x4B
78 | #define KEY_PAGE_DOWN 0x51
79 | #define KEY_PAGE_UP 0x49
80 | #define KEY_PRINT_SCREEN 0x37
81 | #define KEY_RIGHT 0x4D
82 | #define KEY_SPACE 0x39
83 | #define KEY_TAB 0x0F
84 | #define KEY_UP 0x48
85 |
86 |
87 | #endif
88 |
89 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bounce Rect/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 | }
40 |
41 | /* The compiler may produce other sections, by default it will put them in
42 | a segment with the same name. Simply add stuff here as needed. */
43 | }
44 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bounce Rect/run.sh:
--------------------------------------------------------------------------------
1 | #assemble boot.s file
2 | as --32 boot.s -o boot.o
3 |
4 | #compile kernel.c file
5 | gcc -m32 -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
6 |
7 | #compile vga.c file
8 | gcc -m32 -c vga.c -o vga.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
9 |
10 | #linking the kernel with kernel.o and boot.o files
11 | ld -m elf_i386 -T linker.ld kernel.o vga.o boot.o -o MyOS.bin -nostdlib
12 |
13 | #check MyOS.bin file is x86 multiboot file or not
14 | grub-file --is-x86-multiboot MyOS.bin
15 |
16 | #building the iso file
17 | mkdir -p isodir/boot/grub
18 | cp MyOS.bin isodir/boot/MyOS.bin
19 | cp grub.cfg isodir/boot/grub/grub.cfg
20 | grub-mkrescue -o MyOS.iso isodir
21 |
22 | #run it in qemu
23 | qemu-system-x86_64 -cdrom MyOS.iso
24 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bounce Rect/types.h:
--------------------------------------------------------------------------------
1 | #ifndef TYPES_H
2 | #define TYPES_H
3 |
4 | typedef unsigned char uint8;
5 | typedef unsigned short uint16;
6 | typedef unsigned int uint32;
7 |
8 | #endif
9 |
10 |
11 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bounce Rect/vga.c:
--------------------------------------------------------------------------------
1 | #include "vga.h"
2 | #include "kernel.h"
3 |
4 | /*
5 | See Intel® OpenSource HD Graphics PRM pdf file
6 | for following defined data for each vga register
7 | and its explaination
8 | */
9 | static uint8 seq_data[5] = {0x03, 0x01, 0x0F, 0x00, 0x0E};
10 | static uint8 crtc_data[25] = {0x5F, 0x4F, 0x50, 0x82,
11 | 0x54, 0x80, 0xBF, 0x1F,
12 | 0x00, 0x41, 0x00, 0x00,
13 | 0x00, 0x00, 0x00, 0x00,
14 | 0x9C, 0x0E, 0x8F, 0x28,
15 | 0x40, 0x96, 0xB9, 0xA3,
16 | 0xFF};
17 |
18 | static uint8 gc_data[9] = {0x00, 0x00, 0x00, 0x00,
19 | 0x00, 0x40, 0x05, 0x0F,
20 | 0xFF};
21 |
22 | static uint8 ac_data[21] = {0x00, 0x01, 0x02, 0x03,
23 | 0x04, 0x05, 0x06, 0x07,
24 | 0x08, 0x09, 0x0A, 0x0B,
25 | 0x0C, 0x0D, 0x0E, 0x0F,
26 | 0x41, 0x00, 0x0F, 0x00,
27 | 0x00};
28 |
29 | void set_misc()
30 | {
31 | outb(VGA_MISC_WRITE, 0x63);
32 | }
33 |
34 | void set_seq()
35 | {
36 | // write sequence data to index of 0-4
37 | for(uint8 index = 0; index < 5; index++){
38 | // first set index
39 | outb(VGA_SEQ_INDEX, index);
40 | // write data at that index
41 | outb(VGA_SEQ_DATA, seq_data[index]);
42 | }
43 | }
44 |
45 | void set_crtc()
46 | {
47 | // write crtc data to index of 0-24
48 | for(uint8 index = 0; index < 25; index++){
49 | outb(VGA_CRTC_INDEX, index);
50 | outb(VGA_CRTC_DATA, crtc_data[index]);
51 | }
52 | }
53 |
54 | void set_gc()
55 | {
56 | // write gc data to index of 0-8
57 | for(uint8 index = 0; index < 9; index++){
58 | outb(VGA_GC_INDEX, index);
59 | outb(VGA_GC_DATA, gc_data[index]);
60 | }
61 | }
62 |
63 | void set_ac()
64 | {
65 | uint8 d;
66 | // write ac data to index of 0-20
67 | for(uint8 index = 0; index < 21; index++){
68 | outb(VGA_AC_INDEX, index);
69 | outb(VGA_AC_WRITE, ac_data[index]);
70 | }
71 | d = inb(VGA_INSTAT_READ);
72 | outb(VGA_AC_INDEX, d | 0x20);
73 | }
74 |
75 | void clear_screen()
76 | {
77 | for(uint32 index = 0; index < VGA_MAX; index++)
78 | vga_buffer[index] = 0;
79 | }
80 |
81 | void clear_color(uint8 color)
82 | {
83 | for(uint32 index = 0; index < VGA_MAX; index++)
84 | vga_buffer[index] = color;
85 | }
86 |
87 | void init_vga()
88 | {
89 | set_misc();
90 | set_seq();
91 | set_crtc();
92 | set_gc();
93 | set_ac();
94 |
95 | vga_buffer = (uint8*)VGA_ADDRESS;
96 |
97 | clear_screen();
98 | }
99 |
100 | void putpixel(uint16 x, uint16 y, uint8 color)
101 | {
102 | uint32 index = 0;
103 | index = 320 * y + x;
104 | if(index < VGA_MAX)
105 | vga_buffer[index] = color;
106 | }
107 |
108 | void draw_line(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint8 color)
109 | {
110 | if(y1 == y2){
111 | for(uint16 i = x1; i <= x2; i++)
112 | putpixel(i, y1, color);
113 | return;
114 | }
115 |
116 | if(x1 == x2){
117 | for(uint16 i = y1; i <= y2; i++){
118 | putpixel(x1, i, color);
119 | }
120 | return;
121 | }
122 | }
123 |
124 | void draw_rect(uint16 x, uint16 y, uint16 width, uint16 height, uint8 color)
125 | {
126 | draw_line(x, y, x, y + height, color);
127 | draw_line(x, y, x + width, y, color);
128 | draw_line(x + width, y, x + width, y + height, color);
129 | draw_line(x, y + height, x + width, y + height, color);
130 | }
131 |
132 | void fill_rect(uint16 x, uint16 y, uint16 width, uint16 height, uint8 color)
133 | {
134 | draw_line(x, y, x, y + height, color);
135 | draw_line(x, y, x + width, y, color);
136 | draw_line(x + width, y, x + width, y + height, color);
137 | draw_line(x, y + height, x + width, y + height, color);
138 | for(int i = y; i < y + height; i++){
139 | draw_line(x, i, x + width, i, color);
140 | }
141 | }
142 |
143 | void draw_bresenham_circle(int xc, int yc, int x, int y, uint8 color)
144 | {
145 | putpixel(xc+x, yc+y, color);
146 | putpixel(xc-x, yc+y, color);
147 | putpixel(xc+x, yc-y, color);
148 | putpixel(xc-x, yc-y, color);
149 | putpixel(xc+y, yc+x, color);
150 | putpixel(xc-y, yc+x, color);
151 | putpixel(xc+y, yc-x, color);
152 | putpixel(xc-y, yc-x, color);
153 | }
154 |
155 | void draw_circle(uint16 x, uint16 y, uint16 radius, uint8 color)
156 | {
157 | int x2 = 0, y2 = radius;
158 | int d = 3 - 2 * radius;
159 | draw_bresenham_circle(x, y, x2, y2, color);
160 | while(y2 >= x2){
161 | x2++;
162 | if(d > 0){
163 | y2--;
164 | d = d + 4 * (x2 - y2) + 10;
165 | }else{
166 | d = d + 4 * x2 + 6;
167 | }
168 | draw_bresenham_circle(x, y, x2, y2, color);
169 | }
170 | }
171 |
172 | void draw_diamond(uint16 x, uint16 y, uint16 radius, uint8 color)
173 | {
174 | uint16 x2 = 0, y2 = radius;
175 | uint16 d = 3 - 2 * radius;
176 | draw_bresenham_circle(x, y, x2, y2, color);
177 | while(y2 >= x2){
178 | x2++;
179 | if(d > 0){
180 | y2--;
181 | d = d + 4 * (x2 - y2) + 10;
182 | }else{
183 | d = d + 4 * x2 + 6;
184 | }
185 | draw_bresenham_circle(x, y, x2, y2, color);
186 | }
187 | }
188 |
189 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Bounce Rect/vga.h:
--------------------------------------------------------------------------------
1 | #ifndef VGA_H
2 | #define VGA_H
3 |
4 | #include "types.h"
5 |
6 | #define VGA_ADDRESS 0xA0000
7 | #define VGA_MAX 0xF9FF
8 | #define VGA_MAX_WIDTH 320
9 | #define VGA_MAX_HEIGHT 200
10 |
11 | uint8* vga_buffer;
12 |
13 | enum vga_color {
14 | BLACK,
15 | BLUE,
16 | GREEN,
17 | CYAN,
18 | RED,
19 | MAGENTA,
20 | BROWN,
21 | GREY,
22 | DARK_GREY,
23 | BRIGHT_BLUE,
24 | BRIGHT_GREEN,
25 | BRIGHT_CYAN,
26 | BRIGHT_RED,
27 | BRIGHT_MAGENTA,
28 | YELLOW,
29 | WHITE,
30 | };
31 |
32 | /* Attribute Controller Registers */
33 | #define VGA_AC_INDEX 0x3C0
34 | #define VGA_AC_READ 0x3C1
35 | #define VGA_AC_WRITE 0x3C0
36 |
37 | /*
38 | Miscellaneous Output
39 | */
40 | #define VGA_MISC_READ 0x3CC
41 | #define VGA_MISC_WRITE 0x3C2
42 |
43 | /* Sequencer Registers */
44 | #define VGA_SEQ_INDEX 0x3C4
45 | #define VGA_SEQ_DATA 0x3C5
46 |
47 | /* VGA Color Palette Registers */
48 | #define VGA_DAC_READ_INDEX 0x3C7
49 | #define VGA_DAC_WRITE_INDEX 0x3C8
50 | #define VGA_DAC_DATA 0x3C9
51 |
52 | /* Graphics Controller Registers */
53 | #define VGA_GC_INDEX 0x3CE
54 | #define VGA_GC_DATA 0x3CF
55 |
56 | /* CRT Controller Registers */
57 | #define VGA_CRTC_INDEX 0x3D4
58 | #define VGA_CRTC_DATA 0x3D5
59 |
60 | /* General Control and Status Registers */
61 | #define VGA_INSTAT_READ 0x3DA
62 |
63 | void init_vga();
64 | void clear_screen();
65 | void clear_color(uint8 color);
66 | void putpixel(uint16 x, uint16 y, uint8 color);
67 | void draw_line(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint8 color);
68 | void draw_rect(uint16 x, uint16 y, uint16 width, uint16 height, uint8 color);
69 | void fill_rect(uint16 x, uint16 y, uint16 width, uint16 height, uint8 color);
70 | void draw_circle(uint16 x, uint16 y, uint16 radius, uint8 color);
71 | void draw_diamond(uint16 x, uint16 y, uint16 radius, uint8 color);
72 |
73 | #endif
74 |
75 |
76 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Reference/Intel OpenSource HD Graphics.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/VGA/kernel_c/Reference/Intel OpenSource HD Graphics.pdf
--------------------------------------------------------------------------------
/VGA/kernel_c/Simple/boot.s:
--------------------------------------------------------------------------------
1 | # set magic number to 0x1BADB002 to identified by bootloader
2 | .set MAGIC, 0x1BADB002
3 |
4 | # set flags to 0
5 | .set FLAGS, 0
6 |
7 | # set the checksum
8 | .set CHECKSUM, -(MAGIC + FLAGS)
9 |
10 | # set multiboot enabled
11 | .section .multiboot
12 |
13 | # define type to long for each data defined as above
14 | .long MAGIC
15 | .long FLAGS
16 | .long CHECKSUM
17 |
18 |
19 | # set the stack bottom
20 | stackBottom:
21 |
22 | # define the maximum size of stack to 512 bytes
23 | .skip 1024
24 |
25 |
26 | # set the stack top which grows from higher to lower
27 | stackTop:
28 |
29 | .section .text
30 | .global _start
31 | .global load_gdt
32 | .type _start, @function
33 |
34 | load_gdt:
35 | mov 4(%esp), %eax
36 | lgdt (%eax)
37 |
38 | mov $0x10, %eax
39 | mov %eax, %ds
40 | mov %eax, %es
41 | mov %eax, %fs
42 | mov %eax, %gs
43 | mov %eax, %ss
44 | jmp $0x8, $.long_jump
45 | .long_jump:
46 | ret
47 |
48 |
49 | _start:
50 |
51 | # assign current stack pointer location to stackTop
52 | mov $stackTop, %esp
53 |
54 | # call the kernel main source
55 | call kernel_entry
56 |
57 | cli
58 |
59 |
60 | # put system in infinite loop
61 | hltLoop:
62 |
63 | hlt
64 | jmp hltLoop
65 |
66 | .size _start, . - _start
67 |
68 |
69 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Simple/grub.cfg:
--------------------------------------------------------------------------------
1 | menuentry "MyOS" {
2 | multiboot /boot/MyOS.bin
3 | }
4 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Simple/kernel.c:
--------------------------------------------------------------------------------
1 | #include "kernel.h"
2 | #include "vga.h"
3 |
4 | uint8 inb(uint16 port)
5 | {
6 | uint8 data;
7 | asm volatile("inb %1, %0" : "=a"(data) : "Nd"(port));
8 | return data;
9 | }
10 |
11 | void outb(uint16 port, uint8 data)
12 | {
13 | asm volatile("outb %0, %1" : : "a"(data), "Nd"(port));
14 | }
15 |
16 | void kernel_entry()
17 | {
18 | init_vga();
19 | draw_rect(0, 0, VGA_MAX_WIDTH - 1, VGA_MAX_HEIGHT - 1, BRIGHT_GREEN);
20 | draw_rect(2, 2, 30, 30, YELLOW);
21 | draw_rect(VGA_MAX_WIDTH - 33, 2, 30, 30, YELLOW);
22 | draw_rect(2, VGA_MAX_HEIGHT - 33, 30, 30, YELLOW);
23 | draw_rect(VGA_MAX_WIDTH - 33, VGA_MAX_HEIGHT - 33, 30, 30, YELLOW);
24 | draw_diamond(16, 16, 10, BRIGHT_CYAN);
25 | draw_diamond(VGA_MAX_WIDTH - 18, 16, 10, BRIGHT_CYAN);
26 | draw_diamond(16, VGA_MAX_HEIGHT - 18, 10, BRIGHT_CYAN);
27 | draw_diamond(VGA_MAX_WIDTH - 18, VGA_MAX_HEIGHT - 18, 10, BRIGHT_CYAN);
28 |
29 | draw_line(VGA_MAX_WIDTH / 2, 0, VGA_MAX_WIDTH / 2, VGA_MAX_HEIGHT, BRIGHT_GREEN);
30 |
31 | for(uint16 i = 0; i < 50; i+=3){
32 | draw_circle(80, 100, 50-i, BRIGHT_RED);
33 | }
34 |
35 | for(uint16 i = 0; i < 50; i+=3){
36 | draw_diamond(240, 100, 50-i, BRIGHT_MAGENTA);
37 | }
38 |
39 | }
40 |
41 |
42 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Simple/kernel.h:
--------------------------------------------------------------------------------
1 | #ifndef KERNEL_H
2 | #define KERNEL_H
3 |
4 | #include "types.h"
5 |
6 | #define NULL 0
7 |
8 | extern uint8 inb(uint16 port);
9 | extern void outb(uint16 port, uint8 data);
10 |
11 | #endif
12 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Simple/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 | }
40 |
41 | /* The compiler may produce other sections, by default it will put them in
42 | a segment with the same name. Simply add stuff here as needed. */
43 | }
44 |
--------------------------------------------------------------------------------
/VGA/kernel_c/Simple/run.sh:
--------------------------------------------------------------------------------
1 | #assemble boot.s file
2 | as --32 boot.s -o boot.o
3 |
4 | #compile kernel.c file
5 | gcc -m32 -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
6 |
7 | #compile vga.c file
8 | gcc -m32 -c vga.c -o vga.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
9 |
10 | #linking the kernel with kernel.o and boot.o files
11 | ld -m elf_i386 -T linker.ld kernel.o vga.o boot.o -o MyOS.bin -nostdlib
12 |
13 | #check MyOS.bin file is x86 multiboot file or not
14 | grub-file --is-x86-multiboot MyOS.bin
15 |
16 | #building the iso file
17 | mkdir -p isodir/boot/grub
18 | cp MyOS.bin isodir/boot/MyOS.bin
19 | cp grub.cfg isodir/boot/grub/grub.cfg
20 | grub-mkrescue -o MyOS.iso isodir
21 |
22 | #run it in qemu
23 | qemu-system-x86_64 -cdrom MyOS.iso
24 |
--------------------------------------------------------------------------------
/VGA/kernel_c/kernel_vga_output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/VGA/kernel_c/kernel_vga_output.png
--------------------------------------------------------------------------------
/x86 Calculator/README.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/x86 Calculator/asm/img/x86calc.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/x86 Calculator/asm/img/x86calc.bin
--------------------------------------------------------------------------------
/x86 Calculator/asm/x86calc_screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/x86 Calculator/asm/x86calc_screenshot.png
--------------------------------------------------------------------------------
/x86 Calculator/kernel_c/img/x86_Calculator.iso:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/x86 Calculator/kernel_c/img/x86_Calculator.iso
--------------------------------------------------------------------------------
/x86 Calculator/kernel_c/src/boot.s:
--------------------------------------------------------------------------------
1 | # set flags to 0
2 | .set FLAGS, 0
3 |
4 | # set magic number to 0x1BADB002 to identified by bootloader
5 | .set MAGIC, 0x1BADB002
6 |
7 | # set the checksum
8 | .set CHECKSUM, -(MAGIC + FLAGS)
9 |
10 | # set multiboot enabled
11 | .section .multiboot
12 |
13 | # define type to long for each data defined as above
14 | .long MAGIC
15 | .long FLAGS
16 | .long CHECKSUM
17 |
18 |
19 | # set the stack bottom
20 | stackBottom:
21 |
22 | # define the maximum size of stack to 512 bytes
23 | .skip 4096
24 |
25 |
26 | # set the stack top which grows from higher to lower
27 | stackTop:
28 |
29 | .section .text
30 | .global _start
31 | .type _start, @function
32 |
33 |
34 | _start:
35 |
36 | # assign current stack pointer location to stackTop
37 | mov $stackTop, %esp
38 |
39 | # call the kernel main function
40 | call kernel_entry
41 |
42 | cli
43 |
44 |
45 | # put system in infinite loop
46 | hltLoop:
47 |
48 | hlt
49 | jmp hltLoop
50 |
51 | .size _start, . - _start
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/x86 Calculator/kernel_c/src/char.c:
--------------------------------------------------------------------------------
1 | #include "char.h"
2 |
3 | char get_ascii_char(uint8 key_code)
4 | {
5 | switch(key_code){
6 | case KEY_A : return 'A';
7 | case KEY_B : return 'B';
8 | case KEY_C : return 'C';
9 | case KEY_D : return 'D';
10 | case KEY_E : return 'E';
11 | case KEY_F : return 'F';
12 | case KEY_G : return 'G';
13 | case KEY_H : return 'H';
14 | case KEY_I : return 'I';
15 | case KEY_J : return 'J';
16 | case KEY_K : return 'K';
17 | case KEY_L : return 'L';
18 | case KEY_M : return 'M';
19 | case KEY_N : return 'N';
20 | case KEY_O : return 'O';
21 | case KEY_P : return 'P';
22 | case KEY_Q : return 'Q';
23 | case KEY_R : return 'R';
24 | case KEY_S : return 'S';
25 | case KEY_T : return 'T';
26 | case KEY_U : return 'U';
27 | case KEY_V : return 'V';
28 | case KEY_W : return 'W';
29 | case KEY_X : return 'X';
30 | case KEY_Y : return 'Y';
31 | case KEY_Z : return 'Z';
32 | case KEY_1 : return '1';
33 | case KEY_2 : return '2';
34 | case KEY_3 : return '3';
35 | case KEY_4 : return '4';
36 | case KEY_5 : return '5';
37 | case KEY_6 : return '6';
38 | case KEY_7 : return '7';
39 | case KEY_8 : return '8';
40 | case KEY_9 : return '9';
41 | case KEY_0 : return '0';
42 | case KEY_MINUS : return '-';
43 | case KEY_EQUAL : return '=';
44 | case KEY_SQUARE_OPEN_BRACKET : return '[';
45 | case KEY_SQUARE_CLOSE_BRACKET : return ']';
46 | case KEY_SEMICOLON : return ';';
47 | case KEY_BACKSLASH : return '\\';
48 | case KEY_COMMA : return ',';
49 | case KEY_DOT : return '.';
50 | case KEY_FORESLHASH : return '/';
51 | case KEY_SPACE : return ' ';
52 | default : return 0;
53 | }
54 | }
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/x86 Calculator/kernel_c/src/char.h:
--------------------------------------------------------------------------------
1 | #ifndef CHAR_H
2 | #define CHAR_H
3 |
4 | #include "types.h"
5 | #include "keyboard.h"
6 |
7 |
8 | extern char get_ascii_char(uint8);
9 |
10 | #endif
11 |
12 |
13 |
--------------------------------------------------------------------------------
/x86 Calculator/kernel_c/src/grub.cfg:
--------------------------------------------------------------------------------
1 | menuentry "x86 Calculator" {
2 | multiboot /boot/x86_calculator.bin
3 | }
4 |
--------------------------------------------------------------------------------
/x86 Calculator/kernel_c/src/kernel.h:
--------------------------------------------------------------------------------
1 | #ifndef KERNEL_H
2 | #define KERNEL_H
3 |
4 | #include "types.h"
5 |
6 | #define NULL 0
7 |
8 | #define VGA_ADDRESS 0xB8000
9 | #define BUFSIZE 2200
10 |
11 | uint16* vga_buffer;
12 |
13 | enum vga_color {
14 | BLACK,
15 | BLUE,
16 | GREEN,
17 | CYAN,
18 | RED,
19 | MAGENTA,
20 | BROWN,
21 | GREY,
22 | DARK_GREY,
23 | BRIGHT_BLUE,
24 | BRIGHT_GREEN,
25 | BRIGHT_CYAN,
26 | BRIGHT_RED,
27 | BRIGHT_MAGENTA,
28 | YELLOW,
29 | WHITE,
30 | };
31 |
32 |
33 | #include "keyboard.h"
34 |
35 |
36 | #endif
37 |
--------------------------------------------------------------------------------
/x86 Calculator/kernel_c/src/keyboard.h:
--------------------------------------------------------------------------------
1 | #ifndef KEYBOARD_H
2 | #define KEYBOARD_H
3 |
4 | #define KEYBOARD_PORT 0x60
5 |
6 |
7 | #define KEY_A 0x1E
8 | #define KEY_B 0x30
9 | #define KEY_C 0x2E
10 | #define KEY_D 0x20
11 | #define KEY_E 0x12
12 | #define KEY_F 0x21
13 | #define KEY_G 0x22
14 | #define KEY_H 0x23
15 | #define KEY_I 0x17
16 | #define KEY_J 0x24
17 | #define KEY_K 0x25
18 | #define KEY_L 0x26
19 | #define KEY_M 0x32
20 | #define KEY_N 0x31
21 | #define KEY_O 0x18
22 | #define KEY_P 0x19
23 | #define KEY_Q 0x10
24 | #define KEY_R 0x13
25 | #define KEY_S 0x1F
26 | #define KEY_T 0x14
27 | #define KEY_U 0x16
28 | #define KEY_V 0x2F
29 | #define KEY_W 0x11
30 | #define KEY_X 0x2D
31 | #define KEY_Y 0x15
32 | #define KEY_Z 0x2C
33 | #define KEY_1 0x02
34 | #define KEY_2 0x03
35 | #define KEY_3 0x04
36 | #define KEY_4 0x05
37 | #define KEY_5 0x06
38 | #define KEY_6 0x07
39 | #define KEY_7 0x08
40 | #define KEY_8 0x09
41 | #define KEY_9 0x0A
42 | #define KEY_0 0x0B
43 | #define KEY_MINUS 0x0C
44 | #define KEY_EQUAL 0x0D
45 | #define KEY_SQUARE_OPEN_BRACKET 0x1A
46 | #define KEY_SQUARE_CLOSE_BRACKET 0x1B
47 | #define KEY_SEMICOLON 0x27
48 | #define KEY_BACKSLASH 0x2B
49 | #define KEY_COMMA 0x33
50 | #define KEY_DOT 0x34
51 | #define KEY_FORESLHASH 0x35
52 | #define KEY_F1 0x3B
53 | #define KEY_F2 0x3C
54 | #define KEY_F3 0x3D
55 | #define KEY_F4 0x3E
56 | #define KEY_F5 0x3F
57 | #define KEY_F6 0x40
58 | #define KEY_F7 0x41
59 | #define KEY_F8 0x42
60 | #define KEY_F9 0x43
61 | #define KEY_F10 0x44
62 | #define KEY_F11 0x85
63 | #define KEY_F12 0x86
64 | #define KEY_BACKSPACE 0x0E
65 | #define KEY_DELETE 0x53
66 | #define KEY_DOWN 0x50
67 | #define KEY_END 0x4F
68 | #define KEY_ENTER 0x1C
69 | #define KEY_ESC 0x01
70 | #define KEY_HOME 0x47
71 | #define KEY_INSERT 0x52
72 | #define KEY_KEYPAD_5 0x4C
73 | #define KEY_KEYPAD_MUL 0x37
74 | #define KEY_KEYPAD_Minus 0x4A
75 | #define KEY_KEYPAD_PLUS 0x4E
76 | #define KEY_KEYPAD_DIV 0x35
77 | #define KEY_LEFT 0x4B
78 | #define KEY_PAGE_DOWN 0x51
79 | #define KEY_PAGE_UP 0x49
80 | #define KEY_PRINT_SCREEN 0x37
81 | #define KEY_RIGHT 0x4D
82 | #define KEY_SPACE 0x39
83 | #define KEY_TAB 0x0F
84 | #define KEY_UP 0x48
85 |
86 |
87 | #endif
88 |
89 |
--------------------------------------------------------------------------------
/x86 Calculator/kernel_c/src/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 | }
40 |
41 | /* The compiler may produce other sections, by default it will put them in
42 | a segment with the same name. Simply add stuff here as needed. */
43 | }
44 |
--------------------------------------------------------------------------------
/x86 Calculator/kernel_c/src/run.sh:
--------------------------------------------------------------------------------
1 | #assemble boot.s file
2 | as --32 boot.s -o boot.o
3 |
4 | #compile kernel.c file
5 | gcc -m32 -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
6 |
7 | gcc -m32 -c utils.c -o utils.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
8 |
9 | gcc -m32 -c char.c -o char.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
10 |
11 | #linking the kernel with kernel.o and boot.o files
12 | ld -m elf_i386 -T linker.ld kernel.o utils.o char.o boot.o -o x86_calculator.bin -nostdlib
13 |
14 | #check MyOS.bin file is x86 multiboot file or not
15 | grub-file --is-x86-multiboot x86_calculator.bin
16 |
17 | #building the iso file
18 | mkdir -p isodir/boot/grub
19 | cp x86_calculator.bin isodir/boot/x86_calculator.bin
20 | cp grub.cfg isodir/boot/grub/grub.cfg
21 | grub-mkrescue -o x86_Calculator.iso isodir
22 |
23 | #run it in qemu
24 | qemu-system-x86_64 -cdrom x86_Calculator.iso
25 |
--------------------------------------------------------------------------------
/x86 Calculator/kernel_c/src/types.h:
--------------------------------------------------------------------------------
1 | #ifndef TYPES_H
2 | #define TYPES_H
3 |
4 | typedef unsigned char uint8;
5 | typedef unsigned short uint16;
6 | typedef unsigned int uint32;
7 |
8 | #endif
9 |
10 |
11 |
--------------------------------------------------------------------------------
/x86 Calculator/kernel_c/src/utils.c:
--------------------------------------------------------------------------------
1 | #include "utils.h"
2 |
3 | uint32 strlen(const char* str)
4 | {
5 | uint32 length = 0;
6 | while(str[length])
7 | length++;
8 | return length;
9 | }
10 |
11 | uint32 digit_count(int num)
12 | {
13 | uint32 count = 0;
14 | if(num == 0)
15 | return 1;
16 | while(num > 0){
17 | count++;
18 | num = num/10;
19 | }
20 | return count;
21 | }
22 |
23 | void itoa(int num, char *number)
24 | {
25 | int dgcount = digit_count(num);
26 | int index = dgcount - 1;
27 | char x;
28 | if(num == 0 && dgcount == 1){
29 | number[0] = '0';
30 | number[1] = '\0';
31 | }else{
32 | while(num != 0){
33 | x = num % 10;
34 | number[index] = x + '0';
35 | index--;
36 | num = num / 10;
37 | }
38 | number[dgcount] = '\0';
39 | }
40 | }
41 |
42 | int atoi(char* s)
43 | {
44 | int len = strlen(s);
45 | int i = len - 1;
46 | int num = 0, pos = 1;
47 | while(i >= 0){
48 | num += (s[i] - '0') * pos;
49 | pos *= 10;
50 | i--;
51 | }
52 | return num;
53 | }
54 |
55 |
56 |
--------------------------------------------------------------------------------
/x86 Calculator/kernel_c/src/utils.h:
--------------------------------------------------------------------------------
1 | #ifndef UTILS_H
2 | #define UTILS_H
3 |
4 | #include "types.h"
5 |
6 | extern uint32 strlen(const char*);
7 | extern uint32 digit_count(int);
8 | extern void itoa(int, char *);
9 | extern int atoi(char*);
10 |
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/x86 Calculator/kernel_c/x86calculator_output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MainakRepositor/OS-Simple/40e2d3991ee7423e8bb39450c143be613bcf7a35/x86 Calculator/kernel_c/x86calculator_output.png
--------------------------------------------------------------------------------