diff --git a/boot/graphics.asm b/boot/graphics.asm index e69de29..63cb3fc 100644 --- a/boot/graphics.asm +++ b/boot/graphics.asm @@ -0,0 +1,36 @@ +global setjmp +; int setjmp(jmp_buf env); +setjmp: + mov ecx, [esp + 4] ; ecx = env + mov edx, [esp + 0] ; edx = ret addr + mov [ecx + 0], edx + mov [ecx + 4], ebx + mov [ecx + 8], esp + mov [ecx + 12], ebp + mov [ecx + 16], esi + mov [ecx + 20], edi + mov [ecx + 24], eax ; eax = trigblock()'s ret val + + xor eax, eax ; setjmp ret val = 0 + ret + +global longjmp +; void longjmp(jmp_buf env, int val) +longjmp: + + mov edx, [esp + 4] ; edx = env + mov eax, [esp + 8] ; eax = val + mov ecx, [edx + 0] ; ecx = setjmp()'s ret val + mov ebx, [edx + 4] + mov esp, [edx + 8] + mov ebp, [edx + 12] + mov esi, [edx + 16] + mov edi, [edx + 20] + + ; make sure longjmp's ret val not 0 + test eax, eax ; if eax == 0: + jnz .1 ; eax += 1 + inc eax ; else: goto lable 1 +.1: ; let longjmp's ret addr as setjmp's ret addr + mov [esp + 0], ecx ; ret addr = ecx = setjmp's next code + ret \ No newline at end of file diff --git a/build.py b/build.py index c714f87..d3cfb17 100644 --- a/build.py +++ b/build.py @@ -1,22 +1,16 @@ import os -gcc = '/i686_elf_tools/bin/i686-elf-gcc.exe -I include/ -std=gnu99 -ffreestanding -O2 -c -Wincompatible-pointer-types' +gcc = '/i686_elf_tools/bin/i686-elf-gcc.exe -std=gnu99 -I include/ -std=gnu99 -ffreestanding -O2 -c -Wincompatible-pointer-types' asm = '/i686_elf_tools/bin/i686-elf-as.exe' nasm = "nasm -f elf32" ld = '/i686_elf_tools/bin/i686-elf-ld.exe' - cd = os.getcwd() # 获取当前执行目录 'D:\CrashPowerDOS-main\' - out = "target" - - def clean(): - print("Clean target flolder") + print("Clean target folder") for file in os.listdir(cd + "\\target"): # 遍历指定文件夹下所有文件 os.remove(cd + "\\target\\" + file) return 0 - - def build_boot(): # 构建引导程序 print("Building boot source code...") status = True diff --git a/cpos.qcow2 b/cpos.qcow2 index 97c2d7e..ea72873 100644 Binary files a/cpos.qcow2 and b/cpos.qcow2 differ diff --git a/driver/acpi.c b/driver/acpi.c index 918891a..779fe56 100644 --- a/driver/acpi.c +++ b/driver/acpi.c @@ -4,6 +4,7 @@ #include "../include/io.h" #include "../include/isr.h" #include "../include/timer.h" +#include "../include/common.h" uint16_t SLP_TYPa; uint16_t SLP_TYPb; @@ -146,6 +147,46 @@ void power_off() { } } +static int AcpiPowerHandler(registers_t *irq) { + uint16_t status = io_in16((uint32_t) facp->PM1a_EVT_BLK); + // check if power button press + if (status & (1 << 8)) { + io_out16((uint32_t) facp->PM1a_EVT_BLK, status &= ~(1 << 8)); // clear bits + printf("Shutdown OS..."); + shutdown_kernel(); + return 0; + } + if (!facp->PM1b_EVT_BLK) + return -1; + // check if power button press + status = io_in16((uint32_t) facp->PM1b_EVT_BLK); + if (status & (1 << 8)) { + io_out16((uint32_t) facp->PM1b_EVT_BLK, status &= ~(1 << 8)); + printf("Shutdown OS..."); + shutdown_kernel(); + return 0; + } + return -1; +} + +static void AcpiPowerInit() { + uint32_t len = facp->PM1_EVT_LEN / 2; + uint32_t *PM1a_ENABLE_REG = facp->PM1a_EVT_BLK + len; + uint32_t *PM1b_ENABLE_REG = facp->PM1b_EVT_BLK + len; + + if (!facp) + return; + + io_out16((uint16_t)PM1a_ENABLE_REG, (uint8_t)(1 << 8)); + if (PM1b_ENABLE_REG) { + io_out16((uint16_t)PM1b_ENABLE_REG, (uint8_t)(1 << 8)); + } + + printf("ACPI : SCI_INT %08x\n",(uint8_t)facp->SCI_INT); + + register_interrupt_handler(facp->SCI_INT, AcpiPowerHandler); +} + int AcpiCheckHeader(void *ptr, uint8_t *sign) { uint8_t * bptr = ptr; uint32_t len = *(bptr + 4); @@ -278,5 +319,5 @@ void acpi_install() { AcpiSysInit(); acpi_enable_flag = !acpi_enable(); // power init - // AcpiPowerInit(); + AcpiPowerInit(); } \ No newline at end of file diff --git a/driver/keyboard.c b/driver/keyboard.c index ab1de30..2f68725 100644 --- a/driver/keyboard.c +++ b/driver/keyboard.c @@ -102,6 +102,8 @@ static void default_handle(uint32_t key,int release,char c){ if(c == 0) return 0; + if(key == 0x81) queue_push(key_char_queue,-5); + queue_push(key_char_queue,(char)c); } else { if(c == -1){ diff --git a/driver/vbe.c b/driver/vbe.c index c70ff26..1ef11b6 100644 --- a/driver/vbe.c +++ b/driver/vbe.c @@ -1,4 +1,5 @@ #include "../include/graphics.h" +#include "../include/io.h" unsigned int vesa_fb_width, vesa_fb_height, vesa_fb_bpp, vesa_fb_pitch; uint8_t *vesa_fb_addr; diff --git a/driver/vga.c b/driver/vga.c index fa06897..c07ac30 100644 --- a/driver/vga.c +++ b/driver/vga.c @@ -9,9 +9,9 @@ uint16_t *terminal_buffer; int status = 0; -static uint16_t cursor_x = 0, cursor_y = 0; // 光标位置 +uint16_t cursor_x = 0, cursor_y = 0; // 光标位置 -static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg) { +uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg) { return fg | bg << 4; } diff --git a/include/common.h b/include/common.h index 20a3334..bb26da9 100644 --- a/include/common.h +++ b/include/common.h @@ -1,7 +1,7 @@ #ifndef CRASHPOWEROS_COMMON_H #define CRASHPOWEROS_COMMON_H -#define OS_NAME "CrashPowerDOS" +#define OS_NAME "CoolPotOS" #define OS_VERSION "v0.2.4" #define LONG_MAX 9223372036854775807L diff --git a/include/cpp.h b/include/cpp.h new file mode 100644 index 0000000..702803f --- /dev/null +++ b/include/cpp.h @@ -0,0 +1,4 @@ +#ifndef CRASHPOWEROS_CPP_H +#define CRASHPOWEROS_CPP_H + +#endif diff --git a/include/date.h b/include/date.h index 7c7e03a..a764a02 100644 --- a/include/date.h +++ b/include/date.h @@ -2,5 +2,6 @@ #define CRASHPOWEROS_DATE_H int setup_date(); +void launch_date(); #endif //CRASHPOWEROS_DATE_H diff --git a/include/graphics.h b/include/graphics.h index fba1575..2b08a46 100644 --- a/include/graphics.h +++ b/include/graphics.h @@ -69,8 +69,17 @@ struct color_rgba { uint8_t a; }; +typedef struct { + unsigned short di, si, bp, sp, bx, dx, cx, ax; + unsigned short gs, fs, es, ds, eflags; +} regs16_t; + + + typedef struct color_rgba color_rgba; +uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg); + void vga_install(void); void vga_setcolor(uint8_t color); diff --git a/include/io.h b/include/io.h index 685f6c7..0cd3936 100644 --- a/include/io.h +++ b/include/io.h @@ -4,6 +4,27 @@ #include +struct tty { + int using1; // 使用标志 + void *vram; // 显存(也可以当做图层) + int x, y; // 目前的 x y 坐标 + int xsize, ysize; // x 坐标大小 y 坐标大小 + int Raw_y; // 换行次数 + int cur_moving; // 光标需要移动吗 + unsigned char color; // 颜色 + void (*putchar)(struct tty *res, int c); // putchar函数 + void (*MoveCursor)(struct tty *res, int x, int y); // MoveCursor函数 + void (*clear)(struct tty *res); // clear函数 + void (*screen_ne)(struct tty *res); // screen_ne函数 + void (*gotoxy)(struct tty *res, int x, int y); // gotoxy函数 + void (*print)(struct tty *res, const char *string); // print函数 + void (*Draw_Box)(struct tty *res, int x, int y, int x1, int y1, + unsigned char color); // Draw_Box函数 + int (*fifo_status)(struct tty *res); + int (*fifo_get)(struct tty *res); + unsigned int reserved[4]; // 保留项 +}; + void gdt_flush(uint32_t gdtr); void io_hlt(void); diff --git a/include/pcat.h b/include/pcat.h index b813978..475e035 100644 --- a/include/pcat.h +++ b/include/pcat.h @@ -5,9 +5,14 @@ #include "fat16.h" struct pcat_process{ - uint8_t is_e; + uint32_t line; + uint32_t chars; + uint32_t buf_x,buf_y; + uint32_t buffer_screen; + int keys; + struct File *file; }; -void pcat_launch(struct task_struct *father,struct File *file); +void pcat_launch(struct File *file); #endif diff --git a/kernel/kernel.c b/kernel/kernel.c index c416d36..61e38ac 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -70,7 +70,7 @@ void kernel_main(multiboot_t *multiboot) { clock_sleep(25); kernel_thread(setup_shell, NULL, "CPOS-Shell"); - if (!status) kernel_thread(setup_date, NULL, "CPOS-Date"); + launch_date(); for (;;) { io_hlt(); diff --git a/sysapp/date.c b/sysapp/date.c index 93b56fe..ee13ec6 100644 --- a/sysapp/date.c +++ b/sysapp/date.c @@ -6,6 +6,12 @@ extern uint16_t *terminal_buffer; extern uint8_t terminal_color; +int date_pid; + +void launch_date(){ + date_pid = kernel_thread(setup_date, NULL, "CPOS-Date"); +} + int setup_date(){ char* date_info; int i; diff --git a/sysapp/pcat.c b/sysapp/pcat.c index f52905b..a04d92a 100644 --- a/sysapp/pcat.c +++ b/sysapp/pcat.c @@ -1,40 +1,126 @@ #include "../include/pcat.h" +#include "../include/graphics.h" #include "../include/keyboard.h" -#include +#include "../include/date.h" +#include "../include/shell.h" +#include "../include/common.h" struct task_struct *father_pcat; struct pcat_process *this_process; uint32_t pid_pcat; extern KEY_STATUS *key_status; +extern uint16_t *terminal_buffer; +extern uint16_t cursor_x, cursor_y; // 光标位置 +extern int date_pid; -void pcat_key_listener(uint32_t key,int release,char c){ - +static void pcat_movcur(){ + cursor_x = this_process->buf_x; + cursor_y = this_process->buf_y; + move_cursor(); } -void start_pcat_thread(){ - this_process = (struct pcat_process*) kmalloc(sizeof(struct pcat_process)); - struct key_listener *listener = (struct key_listener*) kmalloc(sizeof(struct key_listener)); - listener->func = pcat_key_listener; - listener->func = 2; - add_listener(listener); - while (1){ - if(key_status->is_ctrl){ - if(this_process->is_e){ - kfree(this_process); - start_task(father_pcat); - task_kill(get_current()); +static void pcat_char(char c){ + uint16_t *location; + uint8_t attribute = vga_entry_color(VGA_COLOR_DARK_GREY,VGA_COLOR_BLACK); + if(c == '\n'){ + this_process->buf_y++; + this_process->buf_x = 0; + pcat_movcur(); + return; + } else if (c == 0x09) { + location = terminal_buffer + (this_process->buf_y * 80 + this_process->buf_x); + *location = ' ' | attribute; + this_process->buf_x = (this_process->buf_x + 8) & ~(8 - 1); + pcat_movcur(); + return; + } else if (c == '\b') { + if(this_process->buf_x){ + this_process->buf_x--; + location = terminal_buffer + (this_process->buf_y * 80 + this_process->buf_x); + *location = ' ' | attribute; + } else{ + if(this_process->buf_y){ + this_process->buf_y--; } } + char* cc = (char*) this_process->buffer_screen; + int i = (this_process->chars)--; + cc[i] = '\0'; + pcat_movcur(); + return; + } + vga_putentryat(c, attribute,this_process->buf_x,this_process->buf_y); + this_process->buf_x++; + if (this_process->buf_x >= 80) { + this_process->buf_x = 0; + this_process->buf_y++; + } + pcat_movcur(); + char* cc = (char*) this_process->buffer_screen; + int i = (this_process->chars)++; + cc[i] = c; +} +static void draw_string(const char *data){ + size_t size = strlen(data); + for (size_t i = 0; i < size; i++) + pcat_char(data[i]); +} + +static void draw_menu(){ + for (size_t x = 0; x < VGA_WIDTH; x++) { + vga_putentryat(' ',vga_entry_color(VGA_COLOR_BLACK,VGA_COLOR_LIGHT_GREY),x,(VGA_HEIGHT - 1)); } } -void pcat_launch(struct task_struct *father,struct File *file){ - father_pcat = father; - pid_pcat = kernel_thread(start_pcat_thread,NULL,"CPOS-PCAT"); - wait_task(father); - while (1){ - if(father->state != TASK_SLEEPING) break; +static int input_handler(){ + int index = 0; + char c; + while (1) { + c = getc(); + + if(c == 27){ + this_process->keys = 1; + return 0; + } + + if (c == '\b') { + if (index > 0) { + index--; + draw_string("\b \b"); + } + } else { + index++; + pcat_char(c); + } } +} + +static int check_exit(){ + return this_process->keys; +} + +void pcat_launch(struct File *file){ + vga_clear(); task_kill(date_pid); vga_clear(); + this_process = (struct pcat_process*) kmalloc(sizeof(struct pcat_process)); + this_process->buf_x = this_process->buf_y = 0; + this_process->line = 1; + this_process->chars = 0; + this_process->buffer_screen = (uint16_t) kmalloc(VGA_WIDTH * (VGA_HEIGHT - 1)); + this_process->file = file; + this_process->keys = 0; + + int pid = kernel_thread(input_handler,NULL,"CPOS-pcat"); + + while (1){ + if(check_exit()){ + break; + } + draw_menu(); + input_handler(); + } + task_kill(pid); + vga_clear(); + date_pid = kernel_thread(setup_date, NULL, "CPOS-Date"); } \ No newline at end of file diff --git a/sysapp/shell.c b/sysapp/shell.c index 1d184f1..bc9bd89 100644 --- a/sysapp/shell.c +++ b/sysapp/shell.c @@ -224,7 +224,7 @@ void cmd_pcat(int argc,char **argv){ file = open_file(argv[1]); } else file = create_file(argv[1]); - pcat_launch(get_current(),file); + pcat_launch(file); } void setup_shell(){ @@ -275,7 +275,7 @@ void setup_shell(){ else if (!strcmp("pcat", argv[0])) cmd_pcat(argc,argv); else if (!strcmp("help", argv[0]) || !strcmp("?", argv[0]) || !strcmp("h", argv[0])) { - vga_writestring("-=[\037CrashPowerShell Helper\036]=-\n"); + vga_writestring("-=[\037CoolPotShell Helper\036]=-\n"); vga_writestring("help ? h \032Print shell help info.\036\n"); vga_writestring("version \032Print os version.\036\n"); vga_writestring("echo \032Print message.\036\n"); diff --git a/util/base.cpp b/util/base.cpp new file mode 100644 index 0000000..3e5bbfa --- /dev/null +++ b/util/base.cpp @@ -0,0 +1,55 @@ +#include "../include/cpp.h" +#include +#include + +extern "C" uint32_t kmalloc(size_t); +extern "C" void kfree(void*); + +extern "C" void __cxa_pure_virtual() +{ + // Do nothing or print an error message. +} + +void *operator +new(size_t +size) +{ +return +(void*) kmalloc(size); +} + +void *operator +new[]( +size_t size +) +{ +return (void*)kmalloc(size); +} + +void operator + +delete(void *p, unsigned int size) { + kfree(p); +} + +void operator +delete[]( +void *p, +unsigned int size +) +{ +kfree(p); +} +void operator + +delete(void *p) { + kfree(p); +} + +void operator +delete[]( +void *p +) +{ +kfree(p); +}