summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlantw44 <lantw44@gmail.com>2013-01-21 02:16:51 +0800
committerlantw44 <lantw44@gmail.com>2013-01-21 02:16:51 +0800
commite80b7d7b9ceabc86154715d3332aebce3a60f1fe (patch)
tree5d15230e2594494a797b9c2da6d560a26d6d219d
parent21f4b645319848112fd62b0bb5019d98f8e4a741 (diff)
downloadyotos-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--Makefile61
-rw-r--r--pmgdt.s133
-rw-r--r--pmint.c46
-rw-r--r--pmkern.s332
-rw-r--r--yotk32/Makefile22
-rw-r--r--yotk32/char_vga.s60
-rw-r--r--yotk32/char_vhl.c158
-rw-r--r--yotk32/str_out.c29
-rw-r--r--yotk32/strbasic.c74
-rw-r--r--yotk32/yotk32.h154
-rw-r--r--yotsh.c32
11 files changed, 1077 insertions, 24 deletions
diff --git a/Makefile b/Makefile
index c0f9b70..d34f629 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/pmgdt.s b/pmgdt.s
new file mode 100644
index 0000000..4978871
--- /dev/null
+++ b/pmgdt.s
@@ -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
+
+
diff --git a/pmint.c b/pmint.c
new file mode 100644
index 0000000..752cec1
--- /dev/null
+++ b/pmint.c
@@ -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
+
diff --git a/yotsh.c b/yotsh.c
index f0f180d..5094ba7 100644
--- a/yotsh.c
+++ b/yotsh.c
@@ -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 "