diff options
author | lantw44 <lantw44@gmail.com> | 2013-01-21 02:16:51 +0800 |
---|---|---|
committer | lantw44 <lantw44@gmail.com> | 2013-01-21 02:16:51 +0800 |
commit | e80b7d7b9ceabc86154715d3332aebce3a60f1fe (patch) | |
tree | 5d15230e2594494a797b9c2da6d560a26d6d219d | |
parent | 21f4b645319848112fd62b0bb5019d98f8e4a741 (diff) | |
download | yotos-e80b7d7b9ceabc86154715d3332aebce3a60f1fe.tar yotos-e80b7d7b9ceabc86154715d3332aebce3a60f1fe.tar.gz yotos-e80b7d7b9ceabc86154715d3332aebce3a60f1fe.tar.bz2 yotos-e80b7d7b9ceabc86154715d3332aebce3a60f1fe.tar.lz yotos-e80b7d7b9ceabc86154715d3332aebce3a60f1fe.tar.xz yotos-e80b7d7b9ceabc86154715d3332aebce3a60f1fe.tar.zst yotos-e80b7d7b9ceabc86154715d3332aebce3a60f1fe.zip |
加入尚未完成的保護模式切換功能
-rw-r--r-- | Makefile | 61 | ||||
-rw-r--r-- | pmgdt.s | 133 | ||||
-rw-r--r-- | pmint.c | 46 | ||||
-rw-r--r-- | pmkern.s | 332 | ||||
-rw-r--r-- | yotk32/Makefile | 22 | ||||
-rw-r--r-- | yotk32/char_vga.s | 60 | ||||
-rw-r--r-- | yotk32/char_vhl.c | 158 | ||||
-rw-r--r-- | yotk32/str_out.c | 29 | ||||
-rw-r--r-- | yotk32/strbasic.c | 74 | ||||
-rw-r--r-- | yotk32/yotk32.h | 154 | ||||
-rw-r--r-- | yotsh.c | 32 |
11 files changed, 1077 insertions, 24 deletions
@@ -2,16 +2,26 @@ .PHONY: all clean run .SUFFIXES: .c.o .s.o +FDIMAGE=floppy.img +BINARY=bootsect 55aa kernel yotsh reader while1 pmboot pmkern +YOT16_LIBC=yotlibc/yotlibc.a +YOT32_KLIB=yotk32/yotk32.a + +QEMU=qemu-kvm +RM=rm -f + all: floppy.img -floppy.img: 55aa bootsect kernel yotsh reader while1 +floppy.img: $(BINARY) dd if=/dev/zero of=$@ bs=512 count=2880 dd if=55aa of=$@ bs=1 count=2 seek=510 conv=notrunc dd if=bootsect of=$@ conv=notrunc - dd if=kernel of=$@ bs=512 seek=1 conv=notrunc - dd if=yotsh of=$@ bs=512 seek=32 conv=notrunc - dd if=while1 of=$@ bs=512 seek=72 conv=notrunc - dd if=reader of=$@ bs=512 seek=73 conv=notrunc + dd if=kernel of=$@ bs=512 seek=1 conv=notrunc + dd if=yotsh of=$@ bs=512 seek=32 conv=notrunc + dd if=while1 of=$@ bs=512 seek=72 conv=notrunc + dd if=reader of=$@ bs=512 seek=73 conv=notrunc + dd if=pmboot of=$@ bs=512 seek=100 conv=notrunc + dd if=pmkern of=$@ bs=512 seek=101 conv=notrunc .c.o: bcc -ansi -Mc -Iyotlibc -c $< -o $@ @@ -20,25 +30,40 @@ floppy.img: 55aa bootsect kernel yotsh reader while1 bootsect: bootsect.s basic.s nasm -f bin $< -o $@ +55aa: + echo "0000000: 55aa" | xxd -r > $@ kernel: kernel.o - ld86 -T 0x0000 -d kernel.o -o kernel + ld86 -T 0x0000 -d $^ -o $@ -yotsh: yotsh.o yotlibc/yotlibc.a - ld86 -T 0x0000 -d yotsh.o yotlibc/yotlibc.a -o yotsh -reader: reader.o yotlibc/yotlibc.a - ld86 -T 0x0000 -d reader.o yotlibc/yotlibc.a -o reader -while1: while1.o yotlibc/yotlibc.a - ld86 -T 0x0000 -d while1.o yotlibc/yotlibc.a -o while1 +yotsh: yotsh.o $(YOT16_LIBC) + ld86 -T 0x0000 -d $^ -o $@ +reader: reader.o $(YOT16_LIBC) + ld86 -T 0x0000 -d $^ -o $@ +while1: while1.o $(YOT16_LIBC) + ld86 -T 0x0000 -d $^ -o $@ + +pmboot: pmgdt.s + nasm -f bin -dload_offset=0x80500 -dpmkernel=0x80700 $< -o $@ +pmkern: pmkern.o pmint.o $(YOT32_KLIB) + ld -melf_i386 -Ttext 0x80700 $^ --oformat binary -o $@ + +pmkern.o: pmkern.s + nasm -f elf32 $< -o $@ +pmint.o: pmint.c + gcc -m32 -masm=intel -ffreestanding -fleading-underscore \ + -Iyotk32 -c $< -o $@ -55aa: - echo "0000000: 55aa" | xxd -r > $@ -yotlibc/yotlibc.a: +$(YOT16_LIBC): $(MAKE) -C yotlibc +$(YOT32_KLIB): + $(MAKE) -C yotk32 run: floppy.img - qemu-kvm -fda floppy.img $(QARG) + $(QEMU) -fda $(FDIMAGE) $(QARG) clean: - rm -f bootsect kernel kernel.o reader.o while1.o \ - 55aa yotsh yotsh.o floppy.img + $(RM) $(FDIMAGE) $(BINARY) kernel.o reader.o while1.o yotsh.o \ + pmkern.o pmint.o + $(MAKE) -C yotlibc clean + $(MAKE) -C yotk32 clean @@ -0,0 +1,133 @@ +global _main +global _pm_bootstrap +global gdt_start +global gdt_null +global gdt_code +global gdt_data +global gdt_user_code +global gdt_user_data +global gdt_end +global gdt_descriptor + +[bits 16] + +_main: +_pm_bootstrap: + mov dx, msg_title + call putstr + mov dx, msg_ldgdt + call putstr + + cli + lgdt [gdt_descriptor] + + in al, 0x92 + or al, 2 + out 0x92, al + + mov eax, cr0 + or eax, 0x1 + mov cr0, eax + + jmp dword CODE_SEGMENT:pmkernel + +msg_title: db 13, 10, 'YOTOS protected mode loader', 13, 10, 0 +msg_ldgdt: db 'Loading Global Descriptor Table (GDT)... ', 0 + +putstr: ; dx=argument + mov cx, bx ; we must preserve bx +putstr_start: + mov bx, dx ; [dx] is not a effective address + mov al, byte [bx] + test al, al + jz putstr_end + mov ah, 0x0e + mov bx, 0x0007 + int 0x10 + inc dx + jmp putstr_start +putstr_end: + mov bx, cx + ret + + + +; GDT entry + + +gdt_start: + +gdt_null: ; null descriptor + dd 0x00 + dd 0x00 + +gdt_code: ; code segment descriptor + dw 0xffff ; segment limit (bits 0-15) + dw 0x0 ; base (bits 0-15) + db 0x0 ; base (bits 16-23) + + db 10011010b ; (present) 1, + ; (privilege) 00, + ; (descriptor type) 1, + ; type = + ; (code) 1, + ; (conforming) 0, + ; (readable) 1, + ; (accessed) 0 + + db 11001111b ; (granularity) 1, + ; (32-bit default) 1, + ; (64-bit segment) 0, + ; (AVL) 0, + ; segment limit (bits 16-19) + + db 0x0 ; base (bits 24-31) + +gdt_data: ; data segment descriptor + dw 0xffff ; segment limit (bits 0-15) + dw 0x0 ; base (bits 0-15) + db 0x0 ; base (bits 16-23) + + db 10010010b ; (present) 1, + ; (privilege) 00, + ; (descriptor type) 1, + ; type = + ; (code) 0, + ; (expand down) 0, + ; (writable) 1, + ; (accessed) 0 + + db 11001111b ; (granularity) 1, + ; (32-bit default) 1, + ; (64-bit segment) 0, + ; (AVL) 0, + ; segment limit (bits 16-19) + + db 0x0 ; base (bits 24-31) + +gdt_user_code: ; user mode code segment descriptor + dw 0xffff + dw 0x0 + db 0x0 + db 11111010b + db 11001111b + db 0x0 + +gdt_user_data: ; user mode data segment descriptor + dw 0xfff + dw 0x0 + db 0x0 + db 11110010b + db 11001111b + db 0x0 + +gdt_end: + +gdt_descriptor: + dw gdt_end - gdt_start - 1 + dd load_offset + gdt_start + +CODE_SEGMENT equ gdt_code - gdt_start +DATA_SEGMENT equ gdt_data - gdt_start + + @@ -0,0 +1,46 @@ +#include <yotk32.h> + +typedef struct registers +{ + long ds; + long edi, esi, ebp, esp, ebx, edx, ecx, eax; + long int_no, err_code; + long eip, cs, eflags, useresp, ss; +} registers_t; + + +void int_isr_handler(registers_t regs){ + chv_putchar(regs.int_no); + chv_sync_cursor(); +} + +void timer_sleep_msg(void){ + static int count = 0; + count++; + if(count % 100 == 0){ + putstr("..."); + putint(count / 100); + chv_sync_cursor(); + } +} + +void int_irq_handler(registers_t regs){ + asm(".intel_syntax noprefix\n"); + + if(regs.int_no > 31 + 8){ /* Send reset signal to slave PIC (PIC2) */ + asm volatile( + "mov dx, 0xA0\n" + "mov al, 0x20\n" + "out dx, al"); + } + + /* Send reset signal to master PIC (PIC1) */ + asm volatile( + "mov dx, 0x20\n" + "mov al, 0x20\n" + "out dx, al"); + + if(regs.int_no == 32){ /* IRQ0 == Timer */ + timer_sleep_msg(); + } +} diff --git a/pmkern.s b/pmkern.s new file mode 100644 index 0000000..da53094 --- /dev/null +++ b/pmkern.s @@ -0,0 +1,332 @@ +extern _putstr +extern _chv_next_line +extern _chv_init_cursor +extern _chv_putchar +extern _chv_sync_cursor +extern _chv_next_line +extern _int_isr_handler +extern _int_irq_handler + +global _start +global _pm_init +global idt_start +global idt_end +global idt_descriptor + +CODE_SEGMENT equ 0x08 ; gdt_code - gdt_start +DATA_SEGMENT equ 0x10 ; gdt_data - gdt_start +USER_CODE_SEGMENT equ 0x18 ; gdt_user_code - gdt_start +USER_DATA_SEGMENT equ 0x20 ; gdt_user_data - gdt_start + +[bits 32] + +%macro ISR_NOERRCODE 1 + global _int_isr_%1 + _int_isr_%1: + cli + push byte 0 + push byte %1 + jmp _int_isr_common +%endmacro + +%macro ISR_ERRCODE 1 + global _int_isr_%1 + _int_isr_%1: + cli + push byte %1 + jmp _int_isr_common +%endmacro + +%macro IDT_ISR_ENTRY 1 + mov eax, _int_isr_%1 + mov word [ebx], ax + mov word [ebx+2], CODE_SEGMENT + mov byte [ebx+4], 0 + mov byte [ebx+5], 0x80 | 14 + mov eax, _int_isr_%1 + shr eax, 16 + mov word [ebx+6], ax + add ebx, 8 +%endmacro + +%macro IRQ 2 + global _int_irq_%1 + _int_irq_%1: + cli + push byte 0 + push byte %2 + jmp _int_irq_common +%endmacro + +%macro IDT_IRQ_ENTRY 1 + mov eax, _int_irq_%1 + mov word [ebx], ax + mov word [ebx+2], CODE_SEGMENT + mov byte [ebx+4], 0 + mov byte [ebx+5], 0x80 | 14 + mov eax, _int_irq_%1 + shr eax, 16 + mov word [ebx+6], ax + add ebx, 8 +%endmacro + + +_start: +_pm_init: + mov ax, DATA_SEGMENT + mov ds, ax + mov ss, ax + mov es, ax + mov fs, ax + mov gs, ax + + mov ebp, 0x90500 + mov esp, ebp + + call _chv_init_cursor + + call _chv_next_line + push msg_ldidt + call _putstr + add esp, 4 + call _chv_sync_cursor + + ; Create IDT entry + mov ebx, idt_start + +%assign intcount 0 +%rep 32 + IDT_ISR_ENTRY intcount +%assign intcount intcount+1 +%endrep + +%assign intcount 0 +%rep 16 + IDT_IRQ_ENTRY intcount +%assign intcount intcount+1 +%endrep + + ; Load IDT descriptor + lidt [idt_descriptor] + + ; ========== IDT OK ========== + + call _chv_next_line + push msg_remap_irq + call _putstr + add esp, 4 + call _chv_sync_cursor + + sub esp, 2 + + ; Save masks + mov dx, 0x21 ; PIC1 + in al, dx + mov byte [esp], al + + mov dx, 0xA1 ; PIC1 + in al, dx + mov byte [esp+1], al + + ; Initialize two PICs + mov dx, 0x20 ; PIC1 + mov al, 0x11 + out dx, al + + mov dx, 0xA0 ; PIC2 + mov al, 0x11 + out dx, al + + ; Set vector offset + mov dx, 0x21 ; PIC1 + mov al, 0x20 ; IRQ 0 -> INT 0x20 + out dx, al + + mov dx, 0xA1 ; PIC2 + mov al, 0x28 ; IRQ 8 -> INT 0x28 + out dx, al + + ; Master/Slave PIC + mov dx, 0x21 ; PIC1 + mov al, 0x04 ; there is a slave PIC at IRQ2 (0000 0100) + out dx, al + + mov dx, 0xA1 ; PIC2 + mov al, 0x02 ; tell Slave PIC its cascade identity (0000 0010) + out dx, al + + ; Set 8086/88 mode + mov dx, 0x21 ; PIC1 + mov al, 0x01 + out dx, al + + mov dx, 0xA1 ; PIC2 + mov al, 0x01 + out dx, al + + ; Restore mask + mov dx, 0x21 ; PIC1 + mov al, byte [esp] + out dx, al + + mov dx, 0xA1 ; PIC2 + mov al, byte [esp+1] + out dx, al + + add esp, 2 + + ; ========== IRQ remap OK ========== + + sti + + call _chv_next_line + call _chv_next_line + push msg_pmkernel + call _putstr + add esp, 4 + call _chv_next_line + call _chv_next_line + call _chv_sync_cursor + +sleep_forever: + call _chv_next_line + push msg_sleep_forever + call _putstr + add esp, 4 + call _chv_sync_cursor + + ; Set timer + mov dx, 0x43 ; timer command port + mov al, 0x36 + out dx, al + + mov ax, 11932 + mov dx, 0x40 + + out dx, al + mov ah, al + out dx, al + +jump_forever: + hlt + hlt + hlt + hlt + hlt + jmp jump_forever + + +msg_ldidt: db 'Loading Interrupt Descriptor Table (IDT)... ', 0 +msg_remap_irq: db 'Remapping Interrupt requests (IRQ)... ', 0 +msg_pmkernel: db 'OK, YOT OS protected mode kernel is started', 0 +msg_sleep_forever: db 'No instruction available - sleep forever', 0 + +idt_start: + times 256 dq 0 +idt_end: + +idt_descriptor: + dw idt_end - idt_start - 1 + dd idt_start + +ISR_NOERRCODE 0 +ISR_NOERRCODE 1 +ISR_NOERRCODE 2 +ISR_NOERRCODE 3 +ISR_NOERRCODE 4 +ISR_NOERRCODE 5 +ISR_NOERRCODE 6 +ISR_NOERRCODE 7 +ISR_ERRCODE 8 +ISR_NOERRCODE 9 +ISR_ERRCODE 10 +ISR_ERRCODE 11 +ISR_ERRCODE 12 +ISR_ERRCODE 13 +ISR_ERRCODE 14 +ISR_NOERRCODE 15 +ISR_NOERRCODE 16 +ISR_NOERRCODE 17 +ISR_NOERRCODE 18 +ISR_NOERRCODE 19 +ISR_NOERRCODE 20 +ISR_NOERRCODE 21 +ISR_NOERRCODE 22 +ISR_NOERRCODE 23 +ISR_NOERRCODE 24 +ISR_NOERRCODE 25 +ISR_NOERRCODE 26 +ISR_NOERRCODE 27 +ISR_NOERRCODE 28 +ISR_NOERRCODE 29 +ISR_NOERRCODE 30 +ISR_NOERRCODE 31 + +IRQ 0, 32 +IRQ 1, 33 +IRQ 2, 34 +IRQ 3, 35 +IRQ 4, 36 +IRQ 5, 37 +IRQ 6, 38 +IRQ 7, 39 +IRQ 8, 40 +IRQ 9, 41 +IRQ 10, 42 +IRQ 11, 43 +IRQ 12, 44 +IRQ 13, 45 +IRQ 14, 46 +IRQ 15, 47 + + +_int_isr_common: + pushad + + mov ax, ds + push eax + + mov ax, DATA_SEGMENT + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + call _int_isr_handler + + pop eax + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + popad + + add esp, 8 + sti + iret + +_int_irq_common: + pushad + + mov ax, ds + push eax + + mov ax, DATA_SEGMENT + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + call _int_irq_handler + + pop eax + mov ds, ax + mov es, ax + mov fs, ax + mov fs, ax + + popad + add esp, 8 + sti + iret diff --git a/yotk32/Makefile b/yotk32/Makefile new file mode 100644 index 0000000..b077324 --- /dev/null +++ b/yotk32/Makefile @@ -0,0 +1,22 @@ + +.PHONY: all clean +.SUFFIXES: .c.o .s.o + +# some 32-bit function not implemented +#OBJ=str_out.o char_in.o str_in.o char_vga.o char_vhl.o strbasic.o + +OBJ=str_out.o char_vga.o char_vhl.o strbasic.o +LIB=yotk32.a + +all: $(LIB) + +$(LIB): $(OBJ) + ar rcs $@ $(OBJ) + +.s.o: + nasm -f elf $< -o $@ +.c.o: + gcc -m32 -ffreestanding -fleading-underscore -c $< -o $@ + +clean: + rm -f $(LIB) $(OBJ) diff --git a/yotk32/char_vga.s b/yotk32/char_vga.s new file mode 100644 index 0000000..3352146 --- /dev/null +++ b/yotk32/char_vga.s @@ -0,0 +1,60 @@ +global _char_vga_get_cursor +global _char_vga_set_cursor +global _char_vga_cursor_x +global _char_vga_cursor_y + +_char_vga_cursor_x: dd 0 +_char_vga_cursor_y: dd 0 + +_char_vga_get_cursor: + push ebp + mov ebp, esp + xor ecx, ecx ; cx=result + + mov dx, 0x3D4 + mov al, 0x0E + out dx, al ; read high byte + + mov dx, 0x3D5 + in al, dx + mov ch, al + + mov dx, 0x3D4 + mov al, 0x0F + out dx, al ; read low byte + + mov dx, 0x3D5 + in al, dx + mov cl, al + + mov eax, ecx ; set return value + + mov esp, ebp + pop ebp + ret + + +_char_vga_set_cursor: + push ebp + mov ebp, esp + mov ecx, [ebp+8] ; cx=argument + + mov dx, 0x3D4 + mov al, 0x0E + out dx, al ; send high byte + + mov dx, 0x3D5 + mov al, ch + out dx, al + + mov dx, 0x3D4 + mov al, 0x0F + out dx, al ; send low byte + + mov dx, 0x3D5 + mov al, cl + out dx, al + + mov esp, ebp + pop ebp + ret diff --git a/yotk32/char_vhl.c b/yotk32/char_vhl.c new file mode 100644 index 0000000..e02f2b1 --- /dev/null +++ b/yotk32/char_vhl.c @@ -0,0 +1,158 @@ +/* char_vhl = char VGA high level function */ + +#include "yotk32.h" + +extern int char_vga_cursor_x; +extern int char_vga_cursor_y; + +void chv_init_cursor(void){ + int curpos = char_vga_get_cursor(); + char_vga_cursor_x = CHAR_VGA_GETX(curpos); + char_vga_cursor_y = CHAR_VGA_GETY(curpos); +} + +void chv_get_cursor(xycoord) + XYCOORD* xycoord; +{ + chv_init_cursor(); + xycoord->x = char_vga_cursor_x; + xycoord->y = char_vga_cursor_y; +} + +void chv_set_cursor(xycoord) + const XYCOORD* xycoord; +{ + char_vga_cursor_x = xycoord->x; + char_vga_cursor_y = xycoord->y; + char_vga_set_cursor( + CHAR_VGA_POSITION(char_vga_cursor_x, char_vga_cursor_y)); +} + +void chv_set_cursor_direct(x, y) + int x; + int y; +{ + char_vga_cursor_x = x; + char_vga_cursor_y = y; + char_vga_set_cursor( + CHAR_VGA_POSITION(char_vga_cursor_x, char_vga_cursor_y)); +} + +void chv_sync_cursor(void){ + char_vga_set_cursor( + CHAR_VGA_POSITION(char_vga_cursor_x, char_vga_cursor_y)); +} + +void chv_reset_cursor(void){ + chv_set_cursor_direct(0, 0); +} + +void chv_movenext_cursor(void){ + if(++char_vga_cursor_x >= CHAR_VGA_SCREENX){ + char_vga_cursor_x -= CHAR_VGA_SCREENX; + char_vga_cursor_y++; + } + if(char_vga_cursor_y >= CHAR_VGA_SCREENY){ + char_vga_cursor_y = CHAR_VGA_SCREENY; + chv_scroll(1); + } +} + +void chv_moveprev_cursor(void){ + if(--char_vga_cursor_x < 0){ + char_vga_cursor_x += CHAR_VGA_SCREENX; + char_vga_cursor_y--; + } + if(char_vga_cursor_y < 0){ + char_vga_cursor_y = 0; + } +} + +void chv_move_cursor(count) + int count; +{ + int n; + n = CHAR_VGA_POSITION(char_vga_cursor_x, char_vga_cursor_y) + count; + char_vga_cursor_x = CHAR_VGA_GETX(n); + char_vga_cursor_y = CHAR_VGA_GETY(n); + if(char_vga_cursor_x > CHAR_VGA_SCREENX){ + char_vga_cursor_x = CHAR_VGA_SCREENX - 1; + }else if(char_vga_cursor_x < 0){ + char_vga_cursor_x = 0; + } + if(char_vga_cursor_y > CHAR_VGA_SCREENY){ + char_vga_cursor_y = CHAR_VGA_SCREENY - 1; + }else if(char_vga_cursor_y < 0){ + char_vga_cursor_y = 0; + } +} + +void chv_next_line(void){ + if(++char_vga_cursor_y >= CHAR_VGA_SCREENY){ + char_vga_cursor_y--; + chv_scroll(1); + char_vga_cursor_y++; + } + char_vga_cursor_x = 0; +} + +void chv_putchar(c) + int c; +{ + chv_memwrite( + CHAR_VGA_POSITION(char_vga_cursor_x, char_vga_cursor_y) * 2, c); + chv_movenext_cursor(); +} + +void chv_putchar_color(c, color) + int c; + int color; +{ + int pos = CHAR_VGA_POSITION(char_vga_cursor_x, char_vga_cursor_y) * 2; + chv_memwrite(pos++, c); + chv_memwrite(pos, color); + chv_movenext_cursor(); +} + +void chv_backspace(void){ + chv_moveprev_cursor(); + chv_memwrite( + CHAR_VGA_POSITION(char_vga_cursor_x, char_vga_cursor_y) * 2, ' '); +} + +void chv_clear(void){ + int i; + XYCOORD xycoord; + chv_memwrite(0, 'A'); + for(i=0; i< CHAR_VGA_MMIOSIZE; ){ + chv_memwrite(i++, ' '); + chv_memwrite(i++, CHV_COLORPAIR( + CHV_COLOR_LIGHT_GRAY, CHV_COLOR_BLACK)); + } +} + +void chv_scroll(line) + int line; +{ + int c, i; + int src, dest; + if(line > 0){ + src = line * CHAR_VGA_SCREENX * 2; + for(dest = 0; dest < CHAR_VGA_MMIOSIZE && src < CHAR_VGA_MMIOSIZE; + dest++, src++){ + c = chv_memread(src); + chv_memwrite(dest, c); + } + for(; dest < CHAR_VGA_MMIOSIZE; ){ + chv_memwrite(dest++, ' '); + chv_memwrite(dest++, CHV_COLORPAIR( + CHV_COLOR_LIGHT_GRAY, CHV_COLOR_BLACK)); + } + char_vga_cursor_y -= line; + if(char_vga_cursor_y < 0){ + char_vga_cursor_y = 0; + chv_sync_cursor(); + } + } +} + diff --git a/yotk32/str_out.c b/yotk32/str_out.c new file mode 100644 index 0000000..ada10e5 --- /dev/null +++ b/yotk32/str_out.c @@ -0,0 +1,29 @@ +#include "yotk32.h" + +void putint(unsigned long toprint){ + char printbuf[12]; + int i = 0; + do{ + printbuf[i] = toprint % 10 + '0'; + toprint /= 10; + i++; + }while(toprint > 0); + for(i--; i>=0; i--){ + chv_putchar(printbuf[i]); + } +} + +void putcharhex(char c){ + char clist[] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F'}; + + chv_putchar(clist[((c & 0xF0) >> 4)]); + chv_putchar(clist[(c & 0x0F)]); +} + +void putstr(const char* s){ + for(; *s; s++){ + chv_putchar(*s); + } +} diff --git a/yotk32/strbasic.c b/yotk32/strbasic.c new file mode 100644 index 0000000..25c039c --- /dev/null +++ b/yotk32/strbasic.c @@ -0,0 +1,74 @@ +#include "yotk32.h" + +int strcmp(s1, s2) + const char* s1; + const char* s2; +{ + char* str1; + char* str2; + if((*s1 | *s2) && (!*s1 || !*s2)){ + if(*s1){ + return 1; + }else{ + return -1; + } + } + for(str1=(char*)s1, str2=(char*)s2; + *str1 != '\0' && *str2 != '\0'; str1++, str2++){ + if(*str1 > *str2){ + return 2; + }else if(*str1 < *str2){ + return -2; + } + } + if(*str1 != '\0'){ + return 3; + } + if(*str2 != '\0'){ + return -3; + } + return 0; +} + +int strtos(str, store) + const char* str; + unsigned int* store; +{ + unsigned int result = 0; + bool ishex = false; + if(*str == '0' && (*(str+1) == 'x' || *(str+1) == 'X')){ + str += 2; + ishex = true; + } + for(; *str != '\0'; str++){ + if(*str >= '0' && *str <= '9'){ + if(ishex){ + result <<= 4; + result += *str - '0'; + }else{ + result *= 10; + result += *str - '0'; + } + }else if(*str >= 'A' && *str <= 'F'){ + if(ishex){ + result <<= 4; + result += *str - 'A' + 10; + }else{ + return 0; + } + }else if(*str >= 'a' && *str <= 'f'){ + if(ishex){ + result <<= 4; + result += *str - 'a' + 10; + }else{ + return 0; + } + }else if(*str == ' ' || *str == '\t' || *str == '\n'){ + break; + }else{ + return 0; /* Failed */ + } + } + *store = result; + return 1; /* OK */ +} diff --git a/yotk32/yotk32.h b/yotk32/yotk32.h new file mode 100644 index 0000000..289b7ee --- /dev/null +++ b/yotk32/yotk32.h @@ -0,0 +1,154 @@ +#ifndef YOT_OS_KERNEL32_LIB +#define YOT_OS_KERNEL32_LIB + +#ifndef NULL +#define NULL ((char*)0) +#endif + +#ifndef EOF +#define EOF (-1) +#endif + +#ifndef bool +#define bool char +#endif + +#ifndef true +#define true 1 +#endif + +#ifndef false +#define false 0 +#endif + +/* str_out.s */ +void putint(unsigned long); /* 以 10 進位顯示一個 word (unsigned) */ +void putcharhex(char); /* 以 16 進位顯示一個 byte */ +void putstr(const char*); /* 顯示一個字串,'\0' 是結束 */ + +/* char_in.s */ +#define GETCH_SCANCODE(code16) (((code16) & 0xff00) >> 8) +#define GETCH_ASCII(code16) ((code16) & 0x00ff) +int getch(void); + +/* char_vga.s + char_vhl.c */ +#define CHAR_VGA_POSITION(x,y) (((y)*80)+(x)) +#define CHAR_VGA_GETX(n) ((n)%80) +#define CHAR_VGA_GETY(n) ((n)/80) +#define CHAR_VGA_SCREENX 80 +#define CHAR_VGA_SCREENY 25 +#define CHAR_VGA_SCREENSIZE ((CHAR_VGA_SCREENX)*(CHAR_VGA_SCREENY)) +#define CHAR_VGA_MMIOSIZE ((CHAR_VGA_SCREENSIZE)*2) + +#define CHV_COLORPAIR(fg,bg) ((fg) | ((bg) << 4)) +#define CHV_COLOR_BLACK 0 +#define CHV_COLOR_BLUE 1 +#define CHV_COLOR_GREEN 2 +#define CHV_COLOR_CYAN 3 +#define CHV_COLOR_RED 4 +#define CHV_COLOR_MAGENTA 5 +#define CHV_COLOR_BROWN 6 +#define CHV_COLOR_LIGHT_GRAY 7 +#define CHV_COLOR_GRAY 8 +#define CHV_COLOR_LIGHT_BLUE 9 +#define CHV_COLOR_LIGHT_GREEN 10 +#define CHV_COLOR_LIGHT_CYAN 11 +#define CHV_COLOR_LIGHT_RED 12 +#define CHV_COLOR_LIGHT_MAGNETA 13 +#define CHV_COLOR_LIGHT_BROWN 14 +#define CHV_COLOR_WHITE 15 + +typedef struct char_vga_position{ + int x, y; +} XYCOORD; + +void chv_init_cursor(void); +void chv_sync_cursor(void); +void chv_reset_cursor(void); +void chv_get_cursor(XYCOORD*); +void chv_set_cursor(const XYCOORD*); +void chv_set_cursor_direct(int, int); +void chv_movenext_cursor(void); +void chv_moveprev_cursor(void); +void chv_move_cursor(int); +void chv_next_line(void); +void chv_putchar(int); +void chv_putchar_color(int, int); +void chv_backspace(void); +void chv_clear(void); +void chv_scroll(int); + +#define chv_memread(position) \ + (*((char*)((0xb8000)+(position)))) +#define chv_memwrite(position,byte) \ + ((*((char*)((0xb8000)+(position)))) = (byte)) + +#define chv_screen_write_char(position,character) \ + chv_memwrite(((position)*2), (character)) +#define chv_screen_write_color(position,color) \ + chv_memwrite(((position)*2+1), (color)) + +int char_vga_get_cursor(void); +void char_vga_set_cursor(int); + +/* keyboard scan codes */ +#define KEYDOWN_SCANCODE_ESC 0x01 +#define KEYDOWN_SCANCODE_BS 0x0e +#define KEYDOWN_SCANCODE_TAB 0x0f +#define KEYDOWN_SCANCODE_ENTER 0x1c +#define KEYDOWN_SCANCODE_CTRL 0x1d +#define KEYDOWN_SCANCODE_LEFT_SHIFT 0x2a +#define KEYDOWN_SCANCODE_RIGHT_SHIFT 0x36 +#define KEYDOWN_SCANCODE_PRINT_SCREEN 0x37 +#define KEYDOWN_SCANCODE_ALT 0x38 +#define KEYDOWN_SCANCODE_SPACE 0x39 +#define KEYDOWN_SCANCODE_CAPS_LOCK 0x3a +#define KEYDOWN_SCANCODE_FUNCTION(n) (0x3a+(n)) /* F1 ~ F10,其他不適用 */ +#define KEYDOWN_SCANCODE_NUM_LOCK 0x45 +#define KEYDOWN_SCANCODE_SCROLL_LOCK 0x46 +#define KEYDOWN_SCANCODE_HOME 0x47 +#define KEYDOWN_SCANCODE_UP 0x48 +#define KEYDOWN_SCANCODE_PAGE_UP 0x49 +#define KEYDOWN_SCANCODE_LEFT 0x4b +#define KEYDOWN_SCANCODE_RIGHT 0x4d +#define KEYDOWN_SCANCODE_END 0x4f +#define KEYDOWN_SCANCODE_DOWN 0x50 +#define KEYDOWN_SCANCODE_PAGE_DOWN 0x51 +#define KEYDOWN_SCANCODE_INSERT 0x52 +#define KEYDOWN_SCANCODE_DELETE 0x53 + +/* keypad */ +#define KEYDOWN_SCANCODE_KEYPAD_ENTER 0x1c +#define KEYDOWN_SCANCODE_KEYPAD_SLASH 0x35 +#define KEYDOWN_SCANCODE_KEYPAD_STAR 0x37 +#define KEYDOWN_SCANCODE_KEYPAD_7 0x47 +#define KEYDOWN_SCANCODE_KEYPAD_8 0x48 +#define KEYDOWN_SCANCODE_KEYPAD_9 0x49 +#define KEYDOWN_SCANCODE_KEYPAD_MINUS 0x4a +#define KEYDOWN_SCANCODE_KEYPAD_4 0x4b +#define KEYDOWN_SCANCODE_KEYPAD_5 0x4c +#define KEYDOWN_SCANCODE_KEYPAD_6 0x4d +#define KEYDOWN_SCANCODE_KEYPAD_ADD 0x4e +#define KEYDOWN_SCANCODE_KEYPAD_1 0x4f +#define KEYDOWN_SCANCODE_KEYPAD_2 0x50 +#define KEYDOWN_SCANCODE_KEYPAD_3 0x51 +#define KEYDOWN_SCANCODE_KEYPAD_0 0x52 +#define KEYDOWN_SCANCODE_KEYPAD_DOT 0x53 + +/* str_in.c */ +int getstr(char*, int, int); +/* 讀入一行的函式 + * ARG1 = 要存到哪裡 + * ARG2 = 最多可以讀多長('\0' 不計入,但要自行保留空間) + * RVAL = 實際讀了幾個字 */ + +int yotrl(char*, const char*, int, int); +/* 同上,但是是進階版 */ + + +/* strbasic.c */ +int strcmp(const char*, const char*); +int strtos(const char*, unsigned int*); + +#endif + @@ -199,9 +199,29 @@ int main(){ }else if(!strcmp(argcopy, "reboot")){ cp1 = 0; asm "int 0x51"; - }else if(!strcmp(argcopy, "reload")){ + }else if(!strcmp(argcopy, "reload") || + !strcmp(argcopy, "reload2") || + !strcmp(argcopy, "yot16") || + !strcmp(argcopy, "yotrm")){ cp1=0; return 0; + }else if(!strcmp(argcopy, "yot32") || + !strcmp(argcopy, "yotpm") || + !strcmp(argcopy, "protect")){ + putstr( + "WARNING: You cannot run any real mode program " + "unless rebooting!\r\n" + "Do you want to switch to protected mode ? [no] "); + yotrl(cmdline, NULL, 3, 7); + if(!strcmp(cmdline, "yes")){ + return (3 << 12) | 101; + }else{ + if(cmdline[0] == 'y' || cmdline[0] == 'Y'){ + putstr("You should type `yes\'.\r\n"); + }else{ + putstr("Not confirmed.\r\n"); + } + } }else if(!strcmp(argcopy, "loadgarbage")){ cp1=0; return 74; @@ -211,10 +231,6 @@ int main(){ }else if(!strcmp(argcopy, "loadstupid")){ cp1=0; return 73; - }else if(!strcmp(argcopy, "reload2")){ - cp1=0; - /*envsave(env,sizeof(env));*/ - return 0; }else if(!strcmp(argcopy, "clear") || !strcmp(argcopy, "cls")){ chv_clear(); @@ -247,6 +263,8 @@ int main(){ putstr("Syntax: reboot\r\n"); }else if(!strcmp(cp2, "reload")){ putstr("Syntax: reload\r\n"); + }else if(!strcmp(cp2, "yot32")){ + putstr("Syntax: yot32\r\n"); }else if(!strcmp(cp2, "loadgarbage") || !strcmp(cp2, "loadstupid") || !strcmp(cp2, "loadnull")){ @@ -276,7 +294,9 @@ int main(){ "\r\n reboot " "Reboot the computer" "\r\n reload " - "Reload ??" + "Reload the shell" + "\r\n yot32 " + "Switch to protected mode" "\r\n loadgarbage " "Display some garbage to screen" "\r\n loadstupid " |