summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile32
-rw-r--r--basic.s24
-rw-r--r--bootsect.s54
-rw-r--r--kernel.s290
-rw-r--r--reader.c49
-rw-r--r--yotlibc/Makefile18
-rw-r--r--yotlibc/bccfunc.s9
-rw-r--r--yotlibc/char_in.s12
-rw-r--r--yotlibc/char_vga.s141
-rw-r--r--yotlibc/char_vhl.c149
-rw-r--r--yotlibc/str_in.c279
-rw-r--r--yotlibc/str_out.s98
-rw-r--r--yotlibc/yotlibc.h153
-rw-r--r--yotlibc/yotlibc.txt140
14 files changed, 1448 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..e81343c
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,32 @@
+
+.PHONY: all clean run
+
+all: floppy.img
+
+floppy.img: 55aa bootsect kernel reader
+ 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=reader of=$@ bs=512 seek=9 conv=notrunc
+
+bootsect: bootsect.s basic.s
+ nasm -f bin $< -o $@
+kernel: kernel.o
+ ld86 -T 0x0000 -d kernel.o -o kernel
+reader: reader.o yotlibc/yotlibc.a
+ ld86 -T 0x0000 -d reader.o yotlibc/yotlibc.a -o reader
+
+kernel.o: kernel.s
+ nasm -f as86 $< -o $@
+reader.o: reader.c
+ bcc -ansi -Mc -Iyotlibc -c $< -o $@
+
+55aa:
+ echo "0000000: 55aa" | xxd -r > $@
+
+run: floppy.img
+ qemu-kvm -fda floppy.img $(QARG)
+
+clean:
+ rm -f bootsect kernel kernel.o 55aa reader reader.o floppy.img
diff --git a/basic.s b/basic.s
new file mode 100644
index 0000000..5f14ecb
--- /dev/null
+++ b/basic.s
@@ -0,0 +1,24 @@
+putcharhex: ; bl=argument
+ pusha
+ mov ah, 0x0e
+ mov al, bl
+ and al, 0xf0
+ shr al, 4
+ call fourbit2hex
+ int 0x10
+ mov al, bl
+ and al, 0x0f
+ call fourbit2hex
+ int 0x10
+ popa
+ ret
+fourbit2hex: ; al=argument=result
+ cmp al, 10
+ jae fourbit2hex_alpha
+ add al, '0'
+ ret
+fourbit2hex_alpha:
+ add al, 'A'
+ sub al, 10
+ ret
+
diff --git a/bootsect.s b/bootsect.s
new file mode 100644
index 0000000..5e24681
--- /dev/null
+++ b/bootsect.s
@@ -0,0 +1,54 @@
+ org 0x7c00 ; boot sector
+
+entry:
+ ; now loading from disk
+ mov cx, 3 ; retry count
+ mov ax, 0x0000
+ mov ds, ax
+ mov ax, 0x9050
+ mov es, ax ; set es, the destination
+ mov bx, 0
+loaddisk:
+ mov si, cx
+ mov ah, 0x02 ; function: read disk sectors
+ mov al, 8 ; sector count
+ mov dh, 0 ; head
+ mov dl, 0 ; drive number
+ mov ch, 0 ; track
+ mov cl, 2 ; sector offset
+ int 0x13
+ jnc loadok
+ mov bl, al
+ call putcharhex
+ mov cx, si
+ loop loaddisk
+
+ ; load failed
+ mov ah, 0x0e
+ mov al, 'X'
+ int 0x10
+ jmp $
+
+ ; load OK
+loadok:
+ mov ah, 0x0e
+ mov al, 'P'
+ int 0x10
+ mov al, 'R'
+ int 0x10
+ mov al, 'E'
+ int 0x10
+ mov al, 'Y'
+ int 0x10
+ mov al, 'O'
+ int 0x10
+ mov al, 'T'
+ int 0x10
+ mov ax, 0x9050
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+ db 0xEA
+ dd 0x90500000
+
+%include "basic.s"
diff --git a/kernel.s b/kernel.s
new file mode 100644
index 0000000..da018d1
--- /dev/null
+++ b/kernel.s
@@ -0,0 +1,290 @@
+ global _main
+
+_main:
+ mov sp, 0x3ffe
+;--------------------------------------------------
+set_environment:
+ xor ax, ax
+ push es
+ mov es, ax
+ db 0xE8
+ add al, [bx+si]
+ db 0xEB
+ db 0x05
+ pop ax
+ sub sp, 2
+ ret
+;--------------------------------------------------
+do_memory_control:
+ add ax, 0x17
+ cli
+ mov [es:0x140], ax
+ mov [es:0x142], cs
+ sti
+ jmp do_memory_control_end
+ mov ax, 0x5301
+ xor bx, bx
+ int 0x15
+ mov ax, 0x530E
+ xor bx, bx
+ mov cx, 0x0102
+ int 0x15
+ mov ax, 0x5307
+ mov bx, 0x0001
+ mov cx, 0x0003
+ int 0x15
+ iret
+do_memory_control_end:
+ pop es
+;--------------------------------------------------
+set_keyboard:
+ xor ax, ax
+ push es
+ mov es, ax
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ db 0xE8
+ add al, [bx+si]
+ db 0xEB
+ db 0x05
+ pop ax
+ sub sp, 2
+ ret
+ add ax, 0x2C
+ cli
+ mov si, [es:0x24]
+ mov di, [es:0x26]
+ mov [es:0x324], si
+ mov [es:0x326], di
+ mov [es:0x24], ax
+ mov [es:0x26], cs
+ sti
+ jmp near set_keyboard_end
+
+code_for_scancode:
+ push ax
+ push bx
+ push es
+ mov ax, 0x40
+ mov es, ax
+
+ mov bx, 0x0007
+ mov ah, 0x0E
+ mov al, '['
+ int 0x10
+
+ mov bx, 0x0007
+ mov ah, 0x0E
+ mov ax, [es:0x1A]
+ call putint
+
+ mov bx, 0x0007
+ mov ah, 0x0E
+ mov al, ','
+ int 0x10
+
+ mov ax, [es:0x1C]
+ mov dx, ax
+ call putint
+
+
+ mov bx, 0x0007
+ mov ah, 0x0E
+ mov al, ']'
+ int 0x10
+
+ pop es
+ pop bx
+ pop ax
+ int 0xC9
+ iret
+set_keyboard_end:
+ pop es
+;--------------------------------------------------
+load_bin_from_floppy:
+ xor ax, ax
+ mov ax, 0x0050
+ mov es, ax
+ mov bx, 0x0000
+ ; start loading
+ mov si, cx
+ mov ah, 0x02 ; function: read disk sectors
+ mov al, 8 ; sector count
+ mov dh, 0 ; head
+ mov dl, 0 ; drive number
+ mov ch, 0 ; track
+ mov cl, 10 ; sector offset
+ int 0x13
+ jc load_bin_failed
+;--------------------------------------------------
+view_loader_message:
+ mov ah, 0x0e
+ mov al, ':'
+ mov bx, 0x0007
+ int 0x10
+ mov al, 0x0d
+ int 0x10
+ mov al, 0x0a
+ int 0x10
+;--------------------------------------------------
+fake_loader:
+ db 0xE8
+ add al, [bx+si]
+ db 0xEB
+ db 0x05
+ db 0x58
+;--------------------------------------------------
+virtual_device:
+ db 0x83
+ in al, dx
+ db 0x02
+ ret
+;--------------------------------------------------
+real_loader:
+ jmp near very_very_far_func
+ jmp program_exit
+;--------------------------------------------------
+load_bin_failed:
+ mov dx, 0
+ mov ds, dx
+ mov es, dx
+ xor ah, al
+ call putint
+ jmp _main
+;--------------------------------------------------
+program_exit:
+ mov bx, cs
+ mov ds, bx
+ mov es, bx
+ mov ss, bx
+ mov si, 0x3FFE
+ mov sp, [si]
+ mov dx, ax
+; pop dx
+; call char_vga_setbios
+
+ mov bx, 0x0007
+ mov ah, 0x0E
+ mov al, 0x0D
+ int 0x10
+ mov al, 0x0A
+ int 0x10
+
+ mov bx, 0x0007
+ mov ah, 0x0E
+ mov al, 'E'
+ int 0x10
+ mov al, 'x'
+ int 0x10
+ mov al, 'i'
+ int 0x10
+ mov al, 't'
+ int 0x10
+ mov al, ' '
+ int 0x10
+ mov al, 'C'
+ int 0x10
+ mov al, 'o'
+ int 0x10
+ mov al, 'd'
+ int 0x10
+ mov al, 'e'
+ int 0x10
+ mov al, ':'
+ int 0x10
+ mov al, ' '
+ int 0x10
+
+ mov ax, dx
+ call putint
+
+; mov ax, dx
+; call putint
+
+; mov ax, dx
+; call putint
+
+ int 0x10
+ db 0xEB, 0xFE
+ jmp _main
+;--------------------------------------------------
+putint: ; ax=argument
+ pusha
+ mov di, 0 ; dest index
+ mov si, 10 ; divisor, ax=dividend
+
+ putint_divloop:
+ mov dx, 0 ; clear upper bits
+ div si
+ add dx, '0'
+ mov byte [putintbuf+di], dl
+ inc di
+ cmp ax, 0
+ ja putint_divloop
+
+ mov ah, 0x0e
+ mov bx, 0x0007
+
+ putint_print:
+ dec di
+ mov al, byte [putintbuf+di]
+ int 0x10
+ cmp di, 0
+ ja putint_print
+
+ popa
+ ret
+;--------------------------------------------------
+very_very_far_func:
+; call char_vga_savebios
+; push dx
+ mov si, 0x3FFE
+ mov [si], sp
+
+ mov bx, 0x0050
+ mov ds, bx
+ mov es, bx
+ mov ss, bx
+ mov bx, 0xFFFF
+ mov si, bx
+ mov dx, 0xFFF8
+ mov sp, dx
+ mov bp, dx
+
+ mov [si-0x0001], cs
+ add ax, 0x0A
+ mov [si-0x0003], ax
+ mov dl, 0xFA
+ mov [si-0x0007], dx
+ mov dl, 0x5A
+ mov [si-0x0005], dl
+ mov dl, 0xCB
+ mov [si-0x0004], dl
+
+ jmp 0x0050:0x0000
+;--------------------------------------------------
+char_vga_setbios:
+ mov cx, bx ; preserve bx
+ mov ah, 0x0f
+ int 0x10 ; bh is set by int 0x10, ah=0x0f
+ mov ah, 0x02
+ int 0x10
+ mov bx, cx ; restore bx
+ ret
+
+char_vga_savebios:
+ mov cx, bx ; preserve bx
+ mov ah, 0x0f
+ int 0x10 ; bh is set by int 0x10, ah=0x0f
+ mov ah, 0x03
+ int 0x10
+ mov bx, cx ; restore bx
+ ret
+
+putintbuf: times 5 db 0
diff --git a/reader.c b/reader.c
new file mode 100644
index 0000000..7b30c1f
--- /dev/null
+++ b/reader.c
@@ -0,0 +1,49 @@
+#include <yotlibc.h>
+
+short rval = 8;
+short abc[100];
+int main(void){
+ XYCOORD xys;
+ short k;
+ extern int char_vga_cursor_x;
+ extern int char_vga_cursor_y;
+ int i;
+// xys.x = 1;
+// xys.y = 1;
+// chv_set_cursor(&xys);
+// char_vga_tobios();
+// putint(char_vga_cursor_x);
+// putint(char_vga_cursor_y);
+ chv_init_cursor();
+ chv_memwrite(5, 4);
+ xys.y = 23;
+ xys.x = 4;
+ chv_set_cursor(&xys);
+ putint(char_vga_cursor_y);
+ for(i=0; i<9; i++){
+ chv_putchar('F');
+ }
+ chv_sync_cursor();
+ yotrl(abc, "", 99);
+ putstr(abc);
+// chv_putchar_color('A', CHV_COLORPAIR(CHV_COLOR_GREEN, CHV_COLOR_GRAY));
+// chv_backspace();
+// chv_scroll(25);
+// chv_clear();
+// chv_reset_cursor();
+// chv_sync_cursor();
+// chv_putchar('A');
+// char_vga_tobios();
+// putint(22);
+// putint(chv_memread(5));
+// putstr("PPP");
+ //putstr("KKK:");
+ /*while(1){
+ int a = getch();
+ a = GETCH_SCANCODE(a);
+ putcharhex(a);
+ }
+ putint(getstr(abc, 10));
+ putstr(abc);*/
+ return 0xFFFD;
+}
diff --git a/yotlibc/Makefile b/yotlibc/Makefile
new file mode 100644
index 0000000..ebdc45c
--- /dev/null
+++ b/yotlibc/Makefile
@@ -0,0 +1,18 @@
+
+.PHONY: all clean
+.SUFFIXES: .c.o .s.o
+
+OBJ=bccfunc.o str_out.o char_in.o str_in.o char_vga.o char_vhl.o
+
+all: yotlibc.a
+
+yotlibc.a: $(OBJ)
+ ar86 rc $@ $(OBJ)
+
+.s.o:
+ nasm -f as86 $< -o $@
+.c.o:
+ bcc -ansi -Mc -c $< -o $@
+
+clean:
+ rm -f yotlibc.a $(OBJ)
diff --git a/yotlibc/bccfunc.s b/yotlibc/bccfunc.s
new file mode 100644
index 0000000..3060428
--- /dev/null
+++ b/yotlibc/bccfunc.s
@@ -0,0 +1,9 @@
+; 專門給 bcc 用的,我不知道為什麼它會缺基本功能
+
+global imod
+
+imod:
+ cwd
+ idiv bx
+ mov ax,dx
+ ret
diff --git a/yotlibc/char_in.s b/yotlibc/char_in.s
new file mode 100644
index 0000000..03fb29d
--- /dev/null
+++ b/yotlibc/char_in.s
@@ -0,0 +1,12 @@
+global _getch
+global getch
+
+_getch:
+ push bp
+ mov bp, sp
+ mov ah, 0x0
+ int 0x16
+ mov sp, bp
+ pop bp
+ ret
+
diff --git a/yotlibc/char_vga.s b/yotlibc/char_vga.s
new file mode 100644
index 0000000..6ac1c20
--- /dev/null
+++ b/yotlibc/char_vga.s
@@ -0,0 +1,141 @@
+global _char_vga_get_cursor
+global _char_vga_set_cursor
+global _char_vga_tobios
+global _char_vga_frombios
+global _char_vga_memread ; NOT A FUNCTION!
+global _char_vga_memwrite ; NOT A FUNCTION!
+global _char_vga_cursor_x
+global _char_vga_cursor_y
+
+global _chv_memread
+global _chv_memwrite
+
+_char_vga_cursor_x: dw 0
+_char_vga_cursor_y: dw 0
+
+_char_vga_get_cursor:
+ push bp
+ mov bp, sp
+ xor cx, cx ; 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 ax, cx ; set return value
+
+ mov sp, bp
+ pop bp
+ ret
+
+
+_char_vga_set_cursor:
+ push bp
+ mov bp, sp
+ mov cx, [bp+4] ; 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 sp, bp
+ pop bp
+ ret
+
+_char_vga_tobios:
+ push bp
+ mov bp, sp
+
+ mov cx, bx ; preserve bx
+
+ mov ah, 0x0f
+ int 0x10 ; bh is set by int 0x10, ah=0x0f
+ mov dl, [_char_vga_cursor_x]
+ mov dh, [_char_vga_cursor_y]
+ mov ah, 0x02
+ int 0x10
+
+ mov bx, cx ; restore bx
+
+ mov sp, bp
+ pop bp
+ ret
+
+_char_vga_frombios:
+ push bp
+ mov bp, sp
+
+ mov cx, bx ; preserve bx
+
+ mov ah, 0x0f
+ int 0x10 ; bh is set by int 0x10, ah=0x0f
+ mov [_char_vga_cursor_x], dl
+ mov [_char_vga_cursor_y], dh
+ mov ah, 0x03
+ int 0x10
+
+ mov bx, cx ; restore bx
+
+ mov sp, bp
+ pop bp
+ ret
+
+_char_vga_memread: ; al=result, bx=addr
+ mov dx, 0xb800
+ mov fs, dx
+ mov al, [fs:bx]
+ ret
+
+_char_vga_memwrite: ; al=value, bx=addr
+ mov dx, 0xb800
+ mov fs, dx
+ mov [fs:bx], al
+ ret
+
+_chv_memread:
+ push bp
+ mov bp,sp
+
+ mov bx, [bp+4]
+ call _char_vga_memread
+ xor ah, ah
+
+ mov sp, bp
+ pop bp
+ ret
+
+_chv_memwrite:
+ push bp
+ mov bp,sp
+
+ mov bx, [bp+4]
+ mov al, [bp+6]
+ call _char_vga_memwrite
+
+ mov sp, bp
+ pop bp
+ ret
diff --git a/yotlibc/char_vhl.c b/yotlibc/char_vhl.c
new file mode 100644
index 0000000..2cab8db
--- /dev/null
+++ b/yotlibc/char_vhl.c
@@ -0,0 +1,149 @@
+/* char_vhl = char VGA high level function */
+
+#include "yotlibc.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)
+ 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_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/yotlibc/str_in.c b/yotlibc/str_in.c
new file mode 100644
index 0000000..529b7ab
--- /dev/null
+++ b/yotlibc/str_in.c
@@ -0,0 +1,279 @@
+#include "yotlibc.h"
+
+int getstr(dest, maxlen)
+ char* dest;
+ int maxlen;
+{
+ int c, cascii, cscan;
+ int i = 0, j;
+ extern int char_vga_cursor_x;
+ extern int char_vga_cursor_y;
+
+ chv_init_cursor();
+
+ for(;;){
+ c = getch();
+ cascii = GETCH_ASCII(c);
+ cscan = GETCH_SCANCODE(c);
+ if(cascii >= 32 && cascii < 128){
+ if(i < maxlen){
+ dest[i++] = cascii;
+ chv_putchar(cascii);
+ chv_sync_cursor();
+ }
+ }else{
+ switch(cscan){
+ case KEYDOWN_SCANCODE_ENTER:
+ dest[i++] = '\0';
+ char_vga_cursor_y++;
+ char_vga_cursor_x = 0;
+ chv_sync_cursor();
+ char_vga_tobios();
+ return i;
+ case KEYDOWN_SCANCODE_BS:
+ if(i <= 0){
+ continue;
+ }
+ dest[i--] = '\0';
+ chv_backspace();
+ chv_sync_cursor();
+ break;
+ case KEYDOWN_SCANCODE_ESC:
+ chv_move_cursor(-i);
+ for(j=0; j<i; j++){
+ chv_putchar(' ');
+ }
+ chv_move_cursor(-i);
+ chv_sync_cursor();
+ i = 0, dest[0] = '\0';
+ break;
+
+ }
+ }
+ }
+ return 0;
+}
+
+int yotrl(dest, init, maxlen)
+ char* dest;
+ char* init;
+ int maxlen;
+{
+ int c, cascii, cscan;
+ int pos = 0, nowlen = 0, i;
+ char* ip;
+ int blank;
+ char prechar;
+ extern int char_vga_cursor_x;
+ extern int char_vga_cursor_y;
+ XYCOORD xy;
+
+ chv_init_cursor();
+
+ if(init != NULL){
+ for(i=0; i<maxlen && init[i] != '\0'; i++){
+ dest[i] = init[i];
+ }
+ dest[i] = '\0';
+ pos = i, nowlen = i;
+ for(ip = dest; *ip != '\0'; ip++){
+ chv_putchar(*ip);
+ }
+ }
+
+ chv_sync_cursor();
+
+ for(;;){
+ c = getch();
+ cascii = GETCH_ASCII(c);
+ cscan = GETCH_SCANCODE(c);
+ /* 判斷規則:正常輸入 -> scan code -> ASCII code 控制鍵 */
+ if(cascii >= 32 && cascii < 128){
+ if(nowlen + 1 <= maxlen){
+ if(pos == nowlen){
+ dest[pos++] = cascii;
+ nowlen++;
+ chv_putchar(cascii);
+ chv_sync_cursor();
+ }else{
+ xy.x = char_vga_cursor_x;
+ xy.y = char_vga_cursor_y;
+ for(i=nowlen; i>pos; i--){
+ dest[i] = dest[i-1];
+ }
+ dest[pos] = cascii;
+ chv_putchar(cascii);
+ nowlen++, pos++;
+ for(i=pos; i<nowlen; i++){
+ chv_putchar(dest[i]);
+ }
+ char_vga_cursor_x = xy.x;
+ char_vga_cursor_y = xy.y;
+ chv_movenext_cursor();
+ chv_sync_cursor();
+ }
+ }
+ }else{
+ switch(cscan){
+ case KEYDOWN_SCANCODE_ENTER:
+ dest[nowlen++] = '\0';
+ char_vga_cursor_y++;
+ char_vga_cursor_x = 0;
+ chv_sync_cursor();
+ char_vga_tobios();
+ return nowlen;
+ case KEYDOWN_SCANCODE_LEFT:
+ if(pos > 0){
+ pos--;
+ chv_moveprev_cursor();
+ chv_sync_cursor();
+ }
+ continue;
+ case KEYDOWN_SCANCODE_RIGHT:
+ if(pos < nowlen){
+ pos++;
+ chv_movenext_cursor();
+ chv_sync_cursor();
+ }
+ continue;
+ case KEYDOWN_SCANCODE_BS:
+ if(pos <= 0){
+ continue;
+ }
+ if(pos == nowlen){
+ dest[pos--] = '\0';
+ nowlen--;
+ chv_backspace();
+ chv_sync_cursor();
+ }else{
+ chv_moveprev_cursor();
+ xy.x = char_vga_cursor_x;
+ xy.y = char_vga_cursor_y;
+ for(i=pos; i<nowlen; i++){
+ dest[i-1] = dest[i];
+ }
+ pos--, nowlen--;
+ for(i=pos; i<nowlen; i++){
+ chv_putchar(dest[i]);
+ }
+ chv_putchar(' ');
+ char_vga_cursor_x = xy.x;
+ char_vga_cursor_y = xy.y;
+ chv_sync_cursor();
+ }
+ continue;
+ case KEYDOWN_SCANCODE_DELETE:
+ if(pos >= nowlen){
+ continue;
+ }
+ xy.x = char_vga_cursor_x;
+ xy.y = char_vga_cursor_y;
+ for(i=pos; i<nowlen; i++){
+ dest[i] = dest[i+1];
+ }
+ nowlen--;
+ for(i=pos; i<nowlen; i++){
+ chv_putchar(dest[i]);
+ }
+ chv_putchar(' ');
+ char_vga_cursor_x = xy.x;
+ char_vga_cursor_y = xy.y;
+ chv_sync_cursor();
+ continue;
+ case KEYDOWN_SCANCODE_HOME:
+ cascii = 1; /* 與 Ctrl+A 相同*/
+ break;
+ case KEYDOWN_SCANCODE_END:
+ cascii = 5; /* 與 Ctrl+E 相同 */
+ break;
+ case KEYDOWN_SCANCODE_ESC:
+ cascii = 3; /* 與 Ctrl+C 相同 */
+ break;
+ }
+
+ switch(cascii){
+ case 1: /* Ctrl+A */
+ chv_move_cursor(-pos);
+ chv_sync_cursor();
+ pos = 0;
+ break;
+ case 3: /* Ctrl+C */
+ chv_move_cursor(-pos);
+ for(i=0; i<nowlen; i++){
+ chv_putchar(' ');
+ }
+ chv_move_cursor(-nowlen);
+ chv_sync_cursor();
+ nowlen = 0, pos = 0;
+ break;
+ case 5: /* Ctrl+E */
+ chv_move_cursor(nowlen - pos);
+ chv_sync_cursor();
+ pos = nowlen;
+ break;
+ case 11: /* Ctrl+K */
+ blank = nowlen - pos;
+ xy.x = char_vga_cursor_x;
+ xy.y = char_vga_cursor_y;
+ for(i=0; i<blank; i++){
+ chv_putchar(' ');
+ }
+ nowlen = pos;
+ char_vga_cursor_x = xy.x;
+ char_vga_cursor_y = xy.y;
+ chv_sync_cursor();
+ break;
+ case 21: /* Ctrl+U */
+ blank = pos;
+ for(i=pos; i<nowlen; i++){
+ dest[i-blank] = dest[i];
+ }
+ chv_move_cursor(-pos);
+ xy.x = char_vga_cursor_x;
+ xy.y = char_vga_cursor_y;
+ pos = 0;
+ nowlen -= blank;
+ for(i=0; i<nowlen; i++){
+ chv_putchar(dest[i]);
+ }
+ for(i=0; i<blank; i++){
+ chv_putchar(' ');
+ }
+ char_vga_cursor_x = xy.x;
+ char_vga_cursor_y = xy.y;
+ chv_sync_cursor();
+ break;
+ case 23: /* Ctrl+W */
+ if(pos == 0){
+ break;
+ }
+ for(i=pos-1; i>=0 && dest[i] == ' '; i--);
+ for(; i>=0 && dest[i] != ' '; i--);
+ i++;
+ blank = pos - i;
+ if(i < blank){
+ i = blank;
+ }
+ for(i=pos; i<nowlen; i++){
+ dest[i-blank] = dest[i];
+ }
+ pos -= blank;
+ nowlen -= blank;
+ chv_move_cursor(-blank);
+ xy.x = char_vga_cursor_x;
+ xy.y = char_vga_cursor_y;
+ for(i=pos; i<nowlen; i++){
+ chv_putchar(dest[i]);
+ }
+ for(i=0; i<blank; i++){
+ chv_putchar(' ');
+ }
+ char_vga_cursor_x = xy.x;
+ char_vga_cursor_y = xy.y;
+ chv_sync_cursor();
+ break;
+ }
+ }
+ }
+ return 0;
+}
diff --git a/yotlibc/str_out.s b/yotlibc/str_out.s
new file mode 100644
index 0000000..202d808
--- /dev/null
+++ b/yotlibc/str_out.s
@@ -0,0 +1,98 @@
+global _putint
+global putcharhex
+global _putcharhex
+global putstr
+global _putstr
+
+_putint:
+ push bp
+ mov bp, sp
+ mov ax, word [bp+4] ; ax=argument
+ sub sp, 8 ; 5 bytes - printing buffer
+ pusha
+ mov di, -1 ; dest index
+ mov si, 10 ; divisor, ax=dividend
+putint_divloop:
+ mov dx, 0 ; clear upper bits
+ div si
+ add dx, '0'
+ mov byte [bp+di], dl
+ dec di
+ cmp ax, 0
+ ja putint_divloop
+
+ mov ah, 0x0e
+ mov bx, 0x0007
+putint_print:
+ inc di
+ mov al, byte [bp+di]
+ int 0x10
+ cmp di, -1
+ jl putint_print
+
+ popa
+ mov sp, bp
+ pop bp
+ ret
+
+
+_putcharhex:
+ push bp
+ mov bp, sp
+ mov cl, byte [bp+4]
+ call putcharhex
+ mov sp, bp
+ pop bp
+ ret
+
+putcharhex: ; cl=argument
+ mov dx, bx ; preserve bx
+ mov ah, 0x0e
+ mov bx, 0x0007
+ mov al, cl
+ and al, 0xf0
+ shr al, 4
+ call fourbit2hex
+ int 0x10
+ mov al, cl
+ and al, 0x0f
+ call fourbit2hex
+ int 0x10
+ mov bx, dx ; restore bx
+ ret
+
+fourbit2hex: ; al=argument=result
+ cmp al, 10
+ jae fourbit2hex_alpha
+ add al, '0'
+ ret
+fourbit2hex_alpha:
+ add al, 'A' - 10
+ ret
+
+
+_putstr:
+ push bp
+ mov bp, sp
+ mov dx, word [bp+4]
+ call putstr
+ mov sp, bp
+ pop bp
+ ret
+
+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
+
diff --git a/yotlibc/yotlibc.h b/yotlibc/yotlibc.h
new file mode 100644
index 0000000..1d9e5ca
--- /dev/null
+++ b/yotlibc/yotlibc.h
@@ -0,0 +1,153 @@
+#ifndef YOT_OS_LIBC16
+#define YOT_OS_LIBC16
+
+#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
+
+#define exit(globalvar) \
+ asm "mov sp, bp"; \
+ asm "mov ax, [_" #globalvar "]" ; \
+ asm "pop bp"; \
+ asm "retf"
+
+/* str_out.s */
+void putint(unsigned short); /* 以 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_putchar(int);
+void chv_putchar_color(int, int);
+void chv_backspace(void);
+void chv_clear(void);
+void chv_scroll(int);
+char chv_memread(int);
+void chv_memwrite(int, char);
+
+#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);
+void char_vga_frombios(void);
+void char_vga_tobios(void);
+
+/* 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);
+/* 讀入一行的函式
+ * ARG1 = 要存到哪裡
+ * ARG2 = 最多可以讀多長('\0' 不計入,但要自行保留空間)
+ * RVAL = 實際讀了幾個字 */
+
+int yotrl(char*, const char*, int);
+/* 同上,但是是進階版 */
+
+#endif
+
diff --git a/yotlibc/yotlibc.txt b/yotlibc/yotlibc.txt
new file mode 100644
index 0000000..3e27cfc
--- /dev/null
+++ b/yotlibc/yotlibc.txt
@@ -0,0 +1,140 @@
+
+1 基本功能
+
+-- 插斷: int 0x50: 關機. (好像不是yotlibc XD")
+-- Macro: void exit(全域變數) 取消.
+
+
+2 輸出(透過 BIOS)
+
+-- Function: void putint(unsigned short 數字)
+ 以 10 進位顯示一個 16-bit 無號整數
+
+-- Function: void putcharhex(char 位元組)
+ 以 16 進位顯示一個位元組的值
+
+-- Function: void putstr(const char* 字串)
+ 顯示字串(不會自動加上 '\n')
+
+
+3 讀入一個按鍵
+
+-- Function: int getch(void)
+ 等待使用者按鍵,回傳按鍵的 scan code 與 ASCII code
+
+-- Macro: int GETCH_SCANCODE(int 按鍵值)
+ 取出 getch() 回傳值的 scan code 部份
+
+-- Macro: int GETCH_ASCII(int 按鍵值)
+ 取出 getch() 回傳值的 ASCII code 部份
+
+
+4 螢幕輸出控制(除了部份與 BIOS 相容的函式外,這些函式並不依賴 BIOS)
+
+-- Data Type: XYCOORD
+ 儲存座標
+
+-- Macro: int CHAR_VGA_POSITION(int x, int y)
+ 將 x 與 y 座標轉成單一整數
+
+-- Macro: int CHAR_VGA_GETX(int n)
+ 將轉為單一整數後的座標的 x 部份取出
+
+-- Macro: int CHAR_VGA_GETY(int n)
+ 將轉為單一整數後的座標的 y 部份取出
+
+-- Constant: int CHAR_VGA_SCREENX
+ 定義螢幕行數
+
+-- Constant: int CHAR_VGA_SCREENY
+ 定義螢幕列數
+
+-- Constant: int CHAR_VGA_SCREENSIZE
+ 定義螢幕總字數
+
+-- Constant: int CHAR_VGA_MMIOSIZE
+ VGA memory-mapped I/O 在記憶體中佔的總位元組數
+
+-- Macro: int CHV_COLORPAIR(int 前景, int 背景)
+ 產生前景、背景顏色對數值
+
+-- Variable: int char_vga_cursor_x
+ 儲存目前游標位置的 x 座標
+
+-- Variable: int char_vga_cursor_y
+ 儲存目前游標位置的 y 座標
+
+-- Function: void chv_init_cursor(void)
+ 將目前游標位址存入全域變數
+ 第一次使用或是使用其他類型函式(包含 BIOS 或是 put 開頭的函式)變游標位址
+ 時,必須先執行這個函式
+
+-- Function: void chv_sync_cursor(void)
+ 執行游標移動。所有游標移動函式(chv_set_cursor、chv_set_cursor_direct、
+ chv_reset_cursor 除外)只會更改變數值,必須執行此函式才會真正移動游標
+
+-- Function: void chv_reset_cursor(void)
+ 將游標移回左上角
+
+-- Function: void chv_get_cursor(XYCOORD* 回傳的位址)
+ 透過 I/O 取得游標位址
+
+-- Function: void chv_set_cursor(XYCOORD* 要設定的位址)
+ 立即移動游標
+
+-- Function: void chv_set_cursor_direct(int x, int y)
+ 同上,只是不需要準備一個 struct
+
+-- Function: void chv_movenext_cursor(void)
+ 游標移到後一格,換行、螢幕捲動的問題會自動處理
+
+-- Function: void chv_moveprev_cursor(void)
+ 游標移到前一格,行的問題會自動處理
+
+-- Function: void chv_move_cursor(int 格子數量)
+ 游標大量向後移動(指定負數可向前移動)
+
+-- Function: void chv_putchar(int 字元)
+ 顯示一個字元(游標自動後移)
+
+-- Function: void chv_putchar_color(int 字元, int 顏色)
+ 同上,多了指定顏色的功能
+
+-- Function: void chv_backspace(void)
+ 清除目前所在位置的字元並倒退一格
+
+-- Function: void chv_clear(void)
+ 清空整個螢幕
+
+-- Function: void chv_scroll(int 行數)
+ 螢幕捲動
+
+-- Function: char chv_memread(int 位置)
+ 自 0xB8000+位置 讀回一個位元組
+
+-- Function: void chv_memwrite(int 位置, char 字元)
+ 向 0xB8000+位置 寫入一個位元組
+
+-- Macro: void chv_screen_write_char(int 位置, int 字元)
+ 替換此位置的字元
+
+-- Macro: void chv_screen_write_color(int 位置, int 顏色)
+ 替換此位置字元的顏色
+
+-- Function: void char_vga_get_cursor(void)
+ void char_vga_set_cursor(int 位置)
+ 內部運作的函式,我不多做解釋
+
+-- Function: void char_vga_frombios(void)
+ 透過 BIOS 讀回目前游標位置
+
+-- Function: void char_vga_tobios(void)
+ 透過 BIOS 移動目前游標位置
+
+
+5 字串輸入
+
+-- Function: int getstr(char* 字串, int 字串最大長度)
+ ARG1 = 要存到哪裡
+ ARG2 = 最多可以讀多長('\0' 不計入,但要自行保留空間)
+ RVAL = 實際讀了幾個字