Skip to content

Add VGA Graphics #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Sep 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .gdbinit
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ define view_realmode
end

define view_kernelmode
set $CS_BASE = 0x10000
set $DS_BASE = 0x10000
set $SS_BASE = 0x10000
set $CS_BASE = 0x0C000
set $DS_BASE = 0x0C000
set $SS_BASE = 0x0C000
symbol-file build/kernel/core.elf
clayout
end
Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,10 @@ include $(SRC_KERNEL)/process/Makefile.mk
include $(SRC_KERNEL)/syscall/Makefile.mk

include $(SRC_DRIVERS)/disk/Makefile.mk
include $(SRC_DRIVERS)/display/Makefile.mk
include $(SRC_DRIVERS)/keyboard/Makefile.mk
include $(SRC_DRIVERS)/pic/Makefile.mk
include $(SRC_DRIVERS)/display/Makefile.mk
include $(SRC_DRIVERS)/display/vga/Makefile.mk

include $(SRC_DIR)/fs/Makefile.mk
include $(SRC_DIR)/memmgr/tables/Makefile.mk
Expand Down
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@ The screenshots can be located as `Artifacts` under completed run on [Actions/CI
![image](https://user-images.githubusercontent.com/9819066/119272271-12b67700-bbfd-11eb-8036-1466d39ebe8e.png) | ![image](https://user-images.githubusercontent.com/9819066/129453488-1950ca70-25cc-4801-842f-b25ea88ab25f.png)


Simple Shell | TicTacToe Game
--------------| ------------------
![image](https://user-images.githubusercontent.com/9819066/132112726-75f4fa66-9708-4011-9ce2-a4731fc08e11.png) | ![image](https://user-images.githubusercontent.com/9819066/129463802-d9a0bc77-74eb-4438-b553-e1439ada95a1.png)
Simple Shell | cat
--------------| ------
![image](https://user-images.githubusercontent.com/9819066/132931063-21868d2e-4e55-4a25-843d-9a6a9d1830f6.png) | ![image](https://user-images.githubusercontent.com/9819066/132112873-f47c8588-1e23-4c4e-9237-a9783c70defb.png)

fork() | cat
----------------|------
![image](https://user-images.githubusercontent.com/9819066/132112808-72ba7691-5f18-4631-b95d-fa52a63d2f38.png) | ![image](https://user-images.githubusercontent.com/9819066/132112873-f47c8588-1e23-4c4e-9237-a9783c70defb.png)
fork() | TicTacToe game
----------------|---------------
![image](https://user-images.githubusercontent.com/9819066/132112808-72ba7691-5f18-4631-b95d-fa52a63d2f38.png) | ![image](https://user-images.githubusercontent.com/9819066/129463802-d9a0bc77-74eb-4438-b553-e1439ada95a1.png)

| pingpong game |
| ------------- |
| ![image](https://user-images.githubusercontent.com/9819066/132931019-eee2deca-ed31-4f7a-88ac-1d7754e7683e.png) |


### Boot OS
Expand Down
8 changes: 8 additions & 0 deletions include/fuzzy/drivers/display/vga/graphics.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once

#include <stddef.h>

int graphics_set_mode(uint8_t video_mode);
uint8_t graphics_get_mode();

int graphics_write_320x200x256(int user_ds, uint8_t *__us_buffer);
1 change: 1 addition & 0 deletions include/fuzzy/kernel/process/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ void process_scheduler(int *_e_ip, int *_e_cs, int *_e_sp, int *_e_ss);
// user space <-> kernel space data transfer helper
extern void syscall_strncpy_user_to_kernel(int user_ds, char *src_es_address, char *dest_ds_address, size_t size);
extern void syscall_strncpy_kernel_to_user(int user_ds, char *dest_address, char *src_address, size_t size);
// assumes size is multiple of 4
extern void kernel_memncpy_absolute(int dst_ds, char *dst_address, int src_ds, char *src_address, size_t size);

// operations
Expand Down
3 changes: 3 additions & 0 deletions include/fuzzy/kernel/syscall/graphics.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once

int syscall_4_graphics(int operation, int a1, int a2, int a3, int user_ds);
3 changes: 3 additions & 0 deletions include/fuzzy/kernel/syscall/keyboard.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once

int syscall_0_keyboard(int operation,int a1,int a2,int a3, int user_ds);
4 changes: 3 additions & 1 deletion include/fuzzy/memmgr/layout.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#pragma once

// START_ENSURE_SAME_layout_asm
#define MEMORY_APP_SIZE 0x20000
#define MEMORY_APP_SIZE 0x200000
#define STACKINIT_APP (MEMORY_APP_SIZE-4)
#define MEMORY_REALLIBRARY_DATA_ADDRESS 0x70000
#define MEMORY_REALLIBRARY_DATA_SIZE 0x10000
#define MEMORY_VGA_GRAPHICS_ADDRESS 0xA0000
#define MEMORY_VGA_GRAPHICS_SIZE 0x10000

// END_ENSURE_SAME_layout_asm

Expand Down
2 changes: 1 addition & 1 deletion include/fuzzy/real_mode/client.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#pragma once

int real_mode_client(int eax, int ebx, int ecx, int edx, int es);
int real_mode_client(int int_num, int eax, int ebx, int ecx, int edx, int es);
2 changes: 2 additions & 0 deletions src/drivers/disk/disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ static int load_sector_via_reallibrary_data(
int sector_index = lba%63 + 1;
// https://en.wikipedia.org/wiki/INT_13H#INT_13h_AH=02h:_Read_Sectors_From_Drive
real_mode_client(
0x13, // interrupt number
(0x02<<8) | count,
es_address,
((cylinder_head>>2)&0xFFC0) | (sector_index),
Expand All @@ -28,6 +29,7 @@ static int load_sector_via_reallibrary_data(
);
// https://en.wikipedia.org/wiki/INT_13H#INT_13h_AH=01h:_Get_Status_of_Last_Drive_Operation
int eax = real_mode_client(
0x13, // interrupt number
(0x01<<8),
0,
0,
Expand Down
2 changes: 0 additions & 2 deletions src/drivers/display/text_mode_vga.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,6 @@ void io_low_scroll_screen(char count, unsigned char color,
void io_low_put_char(char c, unsigned char color) {
_low_put_char(c,color, location_xy);
buffer[location_xy]=(((unsigned short)color)<<8)|c;
// slows down char printing but good enough for now.
io_low_flush();
}

void io_low_flush() {
Expand Down
13 changes: 13 additions & 0 deletions src/drivers/display/vga/Makefile.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

$(SELF_BUILD_DIR)/%.o: $(SELF_SRC_DIR)/%.c $(BUILD_USR_INCLUDE_ALL)
mkdir -p $(dir $@)
$(KERNEL_CC) -c -o $@ \
$<

$(SELF_BUILD_DIR)/%_asm.o: $(SELF_SRC_DIR)/%.asm
mkdir -p $(dir $@)
nasm -o $@ -f elf32 $<

$(SELF_BUILD_DIR)/libvga_graphics: $(SELF_BUILD_ALL_C) $(SELF_BUILD_ALL_ASM)
ar rc $@ $^

45 changes: 45 additions & 0 deletions src/drivers/display/vga/graphics.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include<fuzzy/drivers/display/vga/graphics.h>
#include<fuzzy/kernel/process/process.h>
#include<fuzzy/memmgr/tables/gdt.h>
#include<fuzzy/memmgr/layout.h>
#include<fuzzy/real_mode/client.h>

#include <stddef.h>

int graphics_set_mode(uint8_t video_mode) {
// https://en.wikipedia.org/wiki/INT_10H
int eax = real_mode_client(
0x10, // interrupt number
(0x00<<8) | video_mode, // set video mode
0, // do not care
0, // do not care
0, // do not care
0 // do not care
);
return 0;
}

uint8_t graphics_get_mode() {
// https://en.wikipedia.org/wiki/INT_10H
int eax = real_mode_client(
0x10, // interrupt number
(0x0F<<8), // get video mode
0, // do not care
0, // do not care
0, // do not care
0 // do not care
);
// active page ignored
return eax&0xFF;
}

int graphics_write_320x200x256(int user_ds, uint8_t *__us_buffer) {
const int size = 320*200*1;
kernel_memncpy_absolute(
GDT_ABS32_DS, // dst ds
MEMORY_VGA_GRAPHICS_ADDRESS, // dst address
user_ds, // src ds
__us_buffer, // src address
size);
return 0;
}
7 changes: 7 additions & 0 deletions src/drivers/keyboard/keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,13 @@ char keyboard_get_key_pressed_poll() {
return c;
}

int keyboard_get_kbhit() {
for (int i = 0; !keyboard_scanner_ascii_is_available() && i < 100; i++) {
keyboard_scanner_step();
}
return keyboard_scanner_ascii_is_available()>0;
}

void keyboard_init() {
unsigned char original_colors = get_color_fgbg();
sleep_mini(3000000);
Expand Down
1 change: 1 addition & 0 deletions src/drivers/keyboard/keyboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ void keyboard_init();

char keyboard_get_key_pressed_blocking();
char keyboard_get_key_pressed_poll();
int keyboard_get_kbhit();
1 change: 1 addition & 0 deletions src/kernel/Makefile.mk
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ $(kernel_core).elf: $(SELF_BUILD_DIR)/core_asm.o \
$(BUILD_DRIVERS)/pic/libpic \
$(BUILD_LIB_UTILS)/libutils \
$(BUILD_DRIVERS)/display/libtm_vga \
$(BUILD_DRIVERS)/display/vga/libvga_graphics \
$(BUILD_LIB_DS)/libds \
$(BUILD_DRIVERS)/disk/libdisk \
$(BUILD_DIR)/real_mode/librealmodeclient \
Expand Down
4 changes: 3 additions & 1 deletion src/kernel/process/process.asm
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ global kernel_memncpy_absolute
ret

kernel_memncpy_absolute:
; assumes count is multiple of 4
push ebp
mov ebp, esp
; callee save register
Expand All @@ -69,13 +70,14 @@ global kernel_memncpy_absolute
push es

mov ecx, [ebp + 0x18] ; count
shr ecx, 2 ; count/4
mov esi, [ebp + 0x14] ; src_loc
mov ds, [ebp + 0x10] ; src_ds
mov edi, [ebp + 0x0C] ; dest_loc
mov es, [ebp + 0x08] ; dest_ds

; strcpy
rep movsb
rep movsd ; move double word

pop es
pop ds
Expand Down
49 changes: 49 additions & 0 deletions src/kernel/syscall/graphics.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include <fuzzy/kernel/syscall/graphics.h>
#include <fuzzy/drivers/display/vga/graphics.h>
#include <fuzzy/memmgr/tables/gdt.h>
#include <graphics.h>

static int _graphics_prev_mode = -1;


static int _graphics_init() {
if(_graphics_prev_mode!=-1) {
// already in graphics mode
return -1;
}
_graphics_prev_mode = graphics_get_mode();
int err = graphics_set_mode(GRAPHIC_MODE_320x200x256);
return err;
}

static int _graphics_close() {
if(_graphics_prev_mode==-1) {
// not in graphics mode
return -1;
}
int err = graphics_set_mode(_graphics_prev_mode);
// flush text screen
flush_screen();
_graphics_prev_mode = -1;
return err;
}

static int _graphics_copybuffer(int user_ds, void *_us_buffer) {
uint8_t ARR[10][10];
for(int i=0;i<10;i++)for(int j=0;j<10;j++) {
ARR[i][j] = WHITE;
}
return graphics_write_320x200x256(user_ds, _us_buffer);
}

int syscall_4_graphics(int operation, int a1, int a2, int a3, int user_ds) {
switch (operation) {
case SYSCALL_GRAPHICS_INITGRAPH:
return _graphics_init();
case SYSCALL_GRAPHICS_CLOSEGRAPH:
return _graphics_close();
case SYSCALL_GRAPHICS_COPYBUFFER:
return _graphics_copybuffer(user_ds, (void *)a1);
}
return -1;
}
21 changes: 21 additions & 0 deletions src/kernel/syscall/keyboard.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include <fuzzy/kernel/syscall/keyboard.h>

#include <conio.h>

static int _keyboard_getch() {
return keyboard_get_key_pressed_poll();
}

static int _keyboard_kbhit() {
return keyboard_get_kbhit();
}

int syscall_0_keyboard(int operation,int a1,int a2,int a3, int user_ds) {
switch (operation) {
case SYSCALL_KEYBOARD_SUB_GETCH:
return _keyboard_getch();
case SYSCALL_KEYBOARD_SUB_KBHIT:
return _keyboard_kbhit();
}
return -1;
}
9 changes: 4 additions & 5 deletions src/kernel/syscall/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include <fuzzy/kernel/process/process.h>
#include <fuzzy/kernel/syscall/file_handler.h>
#include <fuzzy/kernel/syscall/console.h>
#include <fuzzy/kernel/syscall/graphics.h>
#include <fuzzy/kernel/syscall/keyboard.h>
#include <fuzzy/kernel/syscall/syscall.h>

#include <sys/syscall.h>
Expand All @@ -13,19 +15,16 @@

int SYSCALL_TABLE[SYSCALL_SIZE];

int syscall_0_keyboard_getch(int a0,int a1,int a2,int a3, int user_ds) {
return keyboard_get_key_pressed_poll();
}

extern int interrupt_handler_0x32_syscall_handler();

void interrupt_register_0x32_syscall() {
print_log("Registering syscalls.");
populate_idt_entry_32bit(IDT_SYSCALL, (unsigned int)interrupt_handler_0x32_syscall_handler, 0, 1);
SYSCALL_TABLE[SYSCALL_KEYBOARD]=syscall_0_keyboard_getch;
SYSCALL_TABLE[SYSCALL_KEYBOARD]=syscall_0_keyboard;
SYSCALL_TABLE[SYSCALL_PROCESS]=syscall_1_process;
SYSCALL_TABLE[SYSCALL_FILE_OP]=syscall_2_file_handler;
SYSCALL_TABLE[SYSCALL_CONSOLE]=syscall_3_console;
SYSCALL_TABLE[SYSCALL_GRAPHICS]=syscall_4_graphics;
}

int syscall_selector(int id, int arg0, int arg1, int arg2, int arg3, int user_ds) {
Expand Down
15 changes: 9 additions & 6 deletions src/real_mode/client.asm
Original file line number Diff line number Diff line change
Expand Up @@ -40,27 +40,30 @@ global real_mode_client
; push all value to be poped in real mode
mov ecx, 0
mov esi, ebp
mov ebx, [ds:esi + 0x18] ; (arg4:es)
mov ebx, [ds:esi + 28] ; (arg5:es)

push ecx ; realmode: ds
push ebx ; realmode: es
push ecx ; realmode: fs
push ecx ; realmode: gs

mov eax, [ds:esi + 0x8] ; (arg0:eax)
mov ebx, [ds:esi + 0xc] ; (arg1:ebx)
mov ecx, [ds:esi + 0x10] ; (arg2:ecx)
mov edx, [ds:esi + 0x14] ; (arg3:edx)
mov eax, [ds:esi + 12] ; (arg1:eax)
mov ebx, [ds:esi + 16] ; (arg2:ebx)
mov ecx, [ds:esi + 20] ; (arg3:ecx)
mov edx, [ds:esi + 24] ; (arg4:edx)

push eax ; realmode: ax
push ebx ; realmode: bx
push ecx ; realmode: cx
push edx ; realmode: dx

mov eax, [ds:esi + 8] ; (arg0:interrupt)
push eax

; Note: Make sure these line have IP representable
; in 2 bytes.
call GDT_ABS16_CS:0x7E00 ; execute_0x13_enter_real_mode
add esp, 32
add esp, 36

; revert back to original stack
pop ebx
Expand Down
Loading