完全仿orange‘s,不過我更喜歡nasm,遺憾的是僅僅做到了多個進程

rem auto.cmd
@echo off

nasm -fbin -o boot.bin boot.asm
dd if=boot.bin of=c.img seek=0 count=1
echo.
nasm -fbin -o loader.bin loader.asm
dd if=loader.bin of=c.img seek=1 count=20
echo.
nasm -fbin -o kernel.bin kernel.asm
dd if=kernel.bin of=c.img seek=21 count=8192
echo.

del c.img.lock

pause
; boot.asm

bits 16

start:
	cli
	mov ax, 0x7c0
	mov ds, ax
	
	mov dx, 0x1f2
	mov al, 20
	out dx, al
	
	mov dx, 0x1f3
	mov al, 1
	out dx, al
	mov dx, 0x1f4
	mov al, 0
	out dx, al
	mov dx, 0x1f5
	mov al, 0
	out dx, al
	mov dx, 0x1f6
	mov al, 0xe0
	out dx, al
	
	mov dx, 0x1f7
	mov al, 0x20
	out dx, al

	mov dx, 0x1f7
.1:
	in al, dx
	and al, 0x88
	cmp al, 0x08
	jnz .1
	
	mov cx, 20 * 256
	mov bx, 0x200
	mov dx, 0x1f0
.2:
	in ax, dx
	mov [bx], ax
	inc bx
	inc bx
	loop .2
	
	lgdt [gdtr]
	
	in al, 0x92
	or al, 0x2
	out 0x92, al
	
	mov eax, cr0
	or al, 0x1
	mov cr0, eax
	
	jmp dword 1 * 8 : 0
	
gdt_start:
	dq 0x0000_0000_0000_0000 ; 0 * 8
	dq 0x00cf_9a00_7e00_ffff ; 1 * 8
	dq 0x00cf_9200_7e00_ffff ; 2 * 8
	dq 0x00cf_920b_8000_ffff ; 3 * 8
	dq 0x00cf_9a00_0000_ffff ; 4 * 8
	dq 0x00cf_9200_0000_ffff ; 5 * 8
gdt_end:

gdtr:
	dw gdt_end - gdt_start - 1
	dd 0x7c00 + gdt_start
	
times 512 - 2 - ($ - $$) db 0
dw 0xaa55

; loader.asm
bits 32

start:
	mov ax, 3 * 8
	mov gs, ax
	mov ax, 2 * 8
	mov ds, ax
	mov ss, ax
	mov esp, stack_top
	
; 開闢棧空間
	sub esp, 20 * 4

;	call cls

;	xor ebx, ebx
;	mov byte [gs: ebx], 'P'
;	inc ebx
;	mov byte [gs: ebx], 0xc
;	inc ebx
	

	mov dword [esp + 0 * 4], 21
	mov dword [esp + 1 * 4], 8192
	mov dword [esp + 2 * 4], 0x100000
	call load_hd_to_mem
	
	
	mov dword [esp + 0 * 4], 0x7c00
	mov dword [esp + 1 * 4], 0
	mov dword [esp + 2 * 4], 0
	mov dword [esp + 3 * 4], 0
	mov dword [esp + 4 * 4], 0
	call create_descriptor	
	
	mov dword [esp + 0 * 4], 0x7c00
	mov dword [esp + 1 * 4], 1
	mov dword [esp + 2 * 4], 0x100000
	mov dword [esp + 3 * 4], 0x000fffff
	mov dword [esp + 4 * 4], 0x9a + 0xc000
	call create_descriptor

	mov dword [esp + 0 * 4], 0x7c00
	mov dword [esp + 1 * 4], 2
	mov dword [esp + 2 * 4], 0x100000
	mov dword [esp + 3 * 4], 0x000fffff
	mov dword [esp + 4 * 4], 0x92 + 0xc000
	call create_descriptor
	
	mov dword [esp + 0 * 4], 0x7c00
	mov dword [esp + 1 * 4], 3
	mov dword [esp + 2 * 4], 0xb8000
	mov dword [esp + 3 * 4], 0x00000fff
	mov dword [esp + 4 * 4], 0x92 + 0xc000
	call create_descriptor

	mov dword [esp + 0 * 4], 0x7c00
	mov dword [esp + 1 * 4], 4
	mov dword [esp + 2 * 4], 0
	mov dword [esp + 3 * 4], 0x000fffff
	mov dword [esp + 4 * 4], 0x9a + 0xc000
	call create_descriptor

	mov dword [esp + 0 * 4], 0x7c00
	mov dword [esp + 1 * 4], 5
	mov dword [esp + 2 * 4], 0
	mov dword [esp + 3 * 4], 0x000fffff
	mov dword [esp + 4 * 4], 0x92 + 0xc000
	call create_descriptor


;加載全局描述符表
	lgdt [gdtr]
	
	lidt [idtr]

;釋放預留的棧空間
	add esp, 20 * 4

;長跳入至內核開始處,即是0x100000開始的段	
	jmp dword 1 * 8 : 0

%include "syslib.asm" ;描述符填充函數所在的文件
	
stack_bottom:
	times 1024 db 0
stack_top: ;棧頂

gdtr: ;全局描述符表寄存器將從內存的此處加載全局描述符表的首地址和段限長
;這是一個6字節長度的數據結構,低兩個字節爲段限長,高四個字節爲描述表物理基地址
;因此全局描述符表最多 2^16 / 8個描述符,即8192個,(每個描述符長8個字節)
	dw 256 * 8 - 1
	dd 0x7c00 ;描述表的基地址定在了此處,也就覆蓋了引導扇區和加載程序
	
idtr:
	dw 256 * 8 - 1
	dd 0


; kernel.asm
bits 32

start:
	mov ax, 3 * 8
	mov gs, ax
	mov ax, 2 * 8
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov ss, ax
	mov esp, stack_top

	sub esp, 50 * 4

	call cls


;	call set_page

	call init_idt
	
	call init_8259
	call init_8254
	call init_rtc
	


	mov al, 1111_1000b ; only open clock interrupt
	out 0x21, al
	mov al, 1111_1110b
	out 0xa1, al



	call init_process
	
	add dword [process_table_point], 0 * 36 * 4
	
	call re_start

	add esp, 50 * 4
.loop:
	sub esp, 50 * 4


	
	hlt
	add esp, 50 * 4
	jmp .loop
	


align 4 * 1024
stack_bottom:
	times 4 * 1024 db 0
stack_top:

align 4096

page_dir_start:
	times 4096 db 0
page_dir_end:

PAGE_DIR_BASE equ 0x100000 + page_dir_start

page_table_start:
	times 8 * 4096 db 0
page_table_end:

PAGE_TABLE_BASE equ 0x100000 + page_table_start





;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%include "syslib.asm"


;;;;;process schedule;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

init_process:
	enter
	pusha
	sub esp, 20 * 4

	mov dword [esp + 0 * 4], 0x7c00
	mov dword [esp + 1 * 4], 20
	mov dword [esp + 2 * 4], 0x100000 + tss_start
	mov dword [esp + 3 * 4], tss_end - tss_start + 1
	mov dword [esp + 4 * 4], 0x89	; task status segment
	call create_descriptor
	
	mov dword [tss_start + tss.ss0], 2 * 8
	mov word [tss_start + tss.iobase], tss_end - tss_start - 1
	
	mov ax, 20 * 8
	ltr ax



	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
				
	mov dword [esp + 0 * 4], 0x7c00
	mov dword [esp + 1 * 4], 21
	mov dword [esp + 2 * 4], 0x100000 + 0 * 36 * 4 + process_table_start + process_control.ldt
	mov dword [esp + 3 * 4], ldt_size * u64 - 1
	mov dword [esp + 4 * 4], 0x82	; locak descriptor
	call create_descriptor
	
	mov dword [esp + 0 * 4], 0x100000 + 0 * 36 * 4 +  process_table_start + process_control.ldt
	mov dword [esp + 1 * 4], 1 ; 第2個描述符,從0開始,第1個沒有用
	mov dword [esp + 2 * 4], 0x100000 ;任務代碼的首物理地址
	mov dword [esp + 3 * 4], 0xfffff ;任務的段長度
	mov dword [esp + 4 * 4], 0x9a + 0xc000 + 0x20 ;	0x9a:存在的可執行可讀代碼段
	call create_descriptor						  ; 0xc0:粒度爲4k, 使用32位地址及32位或8位操作數	

	mov dword [esp + 0 * 4], 0x100000 + 0 * 36 * 4 + process_table_start + process_control.ldt ;局部描述符表的首物理地址
	mov dword [esp + 1 * 4], 2 ; 第3個描述符,從0開始
	mov dword [esp + 2 * 4], 0x100000 ;和任務共用一個段
	mov dword [esp + 3 * 4], 0xfffff;因此數據段和代碼段使用相同的物理地址
	mov dword [esp + 4 * 4], 0x92 + 0xc000 + 0x20 ;	0x9a:存在的可讀可寫數據段
	call create_descriptor						  ; 0xc0:粒度爲4k, 段的上部界限爲4G
												  ; 0x20:DPL--描述符特權級爲1												  ; 0x20:DPL--描述符特權級爲1
												  
	mov dword [esp + 0 * 4], 0x100000 + 0 * 36 * 4 + process_table_start + process_control.ldt ;局部描述符表的首物理地址
	mov dword [esp + 1 * 4], 3 ; 第4個描述符,從0開始
	mov dword [esp + 2 * 4], 0xb8000 ;顯存段的起始地址
	mov dword [esp + 3 * 4], 0xfffff ; 段限長爲0xfff * 4k
	mov dword [esp + 4 * 4], 0x92 + 0xc000 + 0x20 ;	0x9a:存在的可讀可寫數據段
	call create_descriptor						  ; 0xc0:粒度爲4k, 段的上部界限爲4G
												  ; 0x20:DPL--描述符特權級爲1


	mov dword [process_table_start + process_control.ldt_sel], 21 * 8

	mov dword [process_table_start + process_stack.gs], 3 * 8 + 5
	mov dword [process_table_start + process_stack.fs], 2 * 8 + 5
	mov dword [process_table_start + process_stack.es], 2 * 8 + 5
	mov dword [process_table_start + process_stack.ss], 2 * 8 + 5
	mov dword [process_table_start + process_stack.ds], 2 * 8 + 5
	mov dword [process_table_start + process_stack.cs], 1 * 8 + 5
	mov dword [process_table_start + process_stack.eip], function1_start
	mov dword [process_table_start + process_stack.esp], task_or_user_stack_top
	mov dword [process_table_start + process_stack.eflags], 0x1202


	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
	mov edx, process_table_start + 1 * 36 * 4
	mov ecx, 2
	mov eax, 1
.1:	
	mov dword [esp + 0 * 4], 0x7c00
	
	mov ebx, 21
	add ebx, eax
	
	mov dword [esp + 1 * 4], ebx
	
	push eax
	push edx	
	xor edx, edx
	mov ebx, 36 * 4
	mul ebx
	mov ebx, 0x100000 + process_table_start + process_control.ldt	
	add ebx, eax
	pop edx
	pop eax
	
	mov dword [esp + 2 * 4], ebx
	mov dword [esp + 3 * 4], ldt_size * u64 - 1
	mov dword [esp + 4 * 4], 0x82	; locak descriptor
	call create_descriptor
	
	mov dword [esp + 0 * 4], ebx
	mov dword [esp + 1 * 4], 1 ; 第2個描述符,從0開始,第1個沒有用
	mov dword [esp + 2 * 4], 0x100000 ;任務代碼的首物理地址
	mov dword [esp + 3 * 4], 0xfffff ;任務的段長度
	mov dword [esp + 4 * 4], 0x9a + 0xc000 + 0x20 ;	0x9a:存在的可執行可讀代碼段
	call create_descriptor						  ; 0xc0:粒度爲4k, 使用32位地址及32位或8位操作數	

	mov dword [esp + 0 * 4], ebx ;局部描述符表的首物理地址
	mov dword [esp + 1 * 4], 2 ; 第3個描述符,從0開始
	mov dword [esp + 2 * 4], 0x100000 ;和任務共用一個段
	mov dword [esp + 3 * 4], 0xfffff;因此數據段和代碼段使用相同的物理地址
	mov dword [esp + 4 * 4], 0x92 + 0xc000 + 0x20 ;	0x9a:存在的可讀可寫數據段
	call create_descriptor						  ; 0xc0:粒度爲4k, 段的上部界限爲4G
												  ; 0x20:DPL--描述符特權級爲1												  ; 0x20:DPL--描述符特權級爲1
												  
	mov dword [esp + 0 * 4], ebx ;局部描述符表的首物理地址
	mov dword [esp + 1 * 4], 3 ; 第4個描述符,從0開始
	mov dword [esp + 2 * 4], 0xb8000 ;顯存段的起始地址
	mov dword [esp + 3 * 4], 0xfffff ; 段限長爲0xfff * 4k
	mov dword [esp + 4 * 4], 0x92 + 0xc000 + 0x20 ;	0x9a:存在的可讀可寫數據段
	call create_descriptor						  ; 0xc0:粒度爲4k, 段的上部界限爲4G
	
											  ; 0x20:DPL--描述符特權級爲1
	sub ebx, process_control.ldt + 0x100000
	mov edx, ebx
	
	mov ebx, 21
	add ebx, eax
	shl ebx, 3
	mov dword [edx + process_control.ldt_sel], ebx

	mov dword [edx + process_stack.gs], 3 * 8 + 5
	mov dword [edx + process_stack.fs], 2 * 8 + 5
	mov dword [edx + process_stack.es], 2 * 8 + 5
	mov dword [edx + process_stack.ss], 2 * 8 + 5
	mov dword [edx + process_stack.ds], 2 * 8 + 5
	mov dword [edx + process_stack.cs], 1 * 8 + 5

	mov dword [edx + process_stack.eflags], 0x1202
	
	
	mov esi, function_point
	mov ebx, eax
	shl ebx, 2
	add esi, ebx
	mov ebx, [esi]
	mov dword [edx + process_stack.eip], ebx
	
	mov esi, task_or_user_stack_top
	mov ebx, eax
	shl ebx, 9
	sub esi, ebx	
	mov dword [edx + process_stack.esp], esi
	
	inc eax
	dec ecx
	cmp ecx, 0
	jne .1



	mov edx, process_table_start + 3 * 36 * 4
	mov ecx, 3
	mov eax, 3
.2:	
	mov dword [esp + 0 * 4], 0x7c00
	
	mov ebx, 21
	add ebx, eax
	
	mov dword [esp + 1 * 4], ebx
	
	push eax
	push edx	
	xor edx, edx
	mov ebx, 36 * 4
	mul ebx
	mov ebx, 0x100000 + process_table_start + process_control.ldt	
	add ebx, eax
	pop edx
	pop eax
	
	mov dword [esp + 2 * 4], ebx
	mov dword [esp + 3 * 4], ldt_size * u64 - 1
	mov dword [esp + 4 * 4], 0x82	; locak descriptor
	call create_descriptor
	
	mov dword [esp + 0 * 4], ebx
	mov dword [esp + 1 * 4], 1 ; 第2個描述符,從0開始,第1個沒有用
	mov dword [esp + 2 * 4], 0x100000 ;任務代碼的首物理地址
	mov dword [esp + 3 * 4], 0xfffff ;任務的段長度
	mov dword [esp + 4 * 4], 0x9a + 0xc000 + 0x60 ;	0x9a:存在的可執行可讀代碼段
	call create_descriptor						  ; 0xc0:粒度爲4k, 使用32位地址及32位或8位操作數	

	mov dword [esp + 0 * 4], ebx ;局部描述符表的首物理地址
	mov dword [esp + 1 * 4], 2 ; 第3個描述符,從0開始
	mov dword [esp + 2 * 4], 0x100000 ;和任務共用一個段
	mov dword [esp + 3 * 4], 0xfffff;因此數據段和代碼段使用相同的物理地址
	mov dword [esp + 4 * 4], 0x92 + 0xc000 + 0x60 ;	0x9a:存在的可讀可寫數據段
	call create_descriptor						  ; 0xc0:粒度爲4k, 段的上部界限爲4G
												  ; 0x20:DPL--描述符特權級爲1												  ; 0x20:DPL--描述符特權級爲1
												  
	mov dword [esp + 0 * 4], ebx ;局部描述符表的首物理地址
	mov dword [esp + 1 * 4], 3 ; 第4個描述符,從0開始
	mov dword [esp + 2 * 4], 0xb8000 ;顯存段的起始地址
	mov dword [esp + 3 * 4], 0xfffff ; 段限長爲0xfff * 4k
	mov dword [esp + 4 * 4], 0x92 + 0xc000 + 0x60 ;	0x9a:存在的可讀可寫數據段
	call create_descriptor						  ; 0xc0:粒度爲4k, 段的上部界限爲4G
	
											  ; 0x20:DPL--描述符特權級爲1
	sub ebx, process_control.ldt + 0x100000
	mov edx, ebx
	
	mov ebx, 21
	add ebx, eax
	shl ebx, 3
	mov dword [edx + process_control.ldt_sel], ebx

	mov dword [edx + process_stack.gs], 3 * 8 + 7
	mov dword [edx + process_stack.fs], 2 * 8 + 7
	mov dword [edx + process_stack.es], 2 * 8 + 7
	mov dword [edx + process_stack.ss], 2 * 8 + 7
	mov dword [edx + process_stack.ds], 2 * 8 + 7
	mov dword [edx + process_stack.cs], 1 * 8 + 7

	mov dword [edx + process_stack.eflags], 0x1202
	
	
	mov esi, function_point
	mov ebx, eax
	shl ebx, 2
	add esi, ebx
	mov ebx, [esi]
	mov dword [edx + process_stack.eip], ebx
	
	mov esi, task_or_user_stack_top
	mov ebx, eax
	shl ebx, 9
	sub esi, ebx	
	mov dword [edx + process_stack.esp], esi
	
	inc eax
	dec ecx
	cmp ecx, 0
	jne .2



	add esp, 20 * 4
	popa
	leave
	ret


;	void set_page(void)
;	call set_page
set_page:
	enter
	pusha

	mov eax, PAGE_TABLE_BASE + 3
	mov edi, page_dir_start
	mov ecx, 1024
.1:
	stosd
	add eax, 0x1000
	loop .1

	mov eax, 0 + 3
	mov edi, page_table_start
	mov ecx, 8 * 1024
.2:
	stosd
	add eax, 0x1000
	loop .2
	
	mov eax, PAGE_DIR_BASE
	mov cr3, eax
	
	mov eax, cr0
	or eax, 0x80000000
	mov cr0 ,eax
	
	jmp short .page
.page:
	
	popa
	leave
	ret

;	int _add(int a, int b)
;	mov eax, [num1]
;	mov [esp + 0 * 4], eax
;	mov eax, [num2]
;	mov [esp + 1 * 4], eax
;	call _add
;	mov [result], eax	
_add:
	enter
	push_some
	
	mov eax, [ebp + 2 * 4]
	add eax, [ebp + 3 * 4]
	
	pop_some
	leave
	ret

;	void init_8259(void)
;	call init_8259
init_8259:
	enter
	pusha
	
	mov al, 0x11
	out 0x20, al
	
	out 0xa0, al
	
	mov al, 0x20
	out 0x21, al
	
	mov al, 0x28
	out 0xa1, al
	
	mov al, 0x4
	out 0x21, al
	
	mov al, 0x2
	out 0xa1, al
	
	mov al, 0x1
	out 0x21, al
	
	out 0xa1, al
	
	mov al, 0xff
	out 0x21, al
	
	out 0xa1, al
	
	popa
	leave
	ret

;	void init_8254(void)
;	call init_8254	
init_8254:
	enter
	pusha
	
	mov al, 0x34
	out 0x43, al
	mov al, 0x9c
	out 0x40, al
	mov al, 0x2e
	out 0x40, al
	
	popa
	leave
	ret

;	void init_rtc(void)
;	call init_rtc	
init_rtc:
	enter
	pusha
	
	mov al, 0xb
	or al, 0x80
	out 0x70, al
	mov al, 0x12
	out 0x71, al
	
	mov al, 0xc
	out 0x70, al
	in al, 0x71

	popa
	leave
	ret

;	void init_idt(void)
;	call init_idt
init_idt:
	enter
	pusha
	sub esp, 20 * 4

;	init exception in interrupt descriptor table
	xor eax, eax
	mov ebx, exception_table
	mov ecx, 17
	
.1:	
	mov esi, [ebx + eax * 4]
;	add esi, 0x100000
	mov dword [esp + 0 * 4], 0 ; interrupt descriptor table start
	mov dword [esp + 1 * 4], eax ; clock interrupt
	mov dword [esp + 2 * 4], 1 * 8 ; code segment select
	mov dword [esp + 3 * 4], 0x8e00 + 0x0000; interrupt gate
	mov dword [esp + 4 * 4], esi ; interrupt process program enter address
	call create_gate
	inc eax
	loop .1

;	init interrupt in interrupt descriptor table

	mov dword [esp + 0 * 4], 0 ; interrupt descriptor table start
	mov dword [esp + 1 * 4], 0x20 ; clock interrupt
	mov dword [esp + 2 * 4], 1 * 8 ; code segment select
	mov dword [esp + 3 * 4], 0x8e00 + 0x0000; interrupt gate
	mov dword [esp + 4 * 4], clock_int ;+ 0x100000; interrupt process program enter address
	call create_gate
	
	mov dword [esp + 0 * 4], 0 ; interrupt descriptor table start
	mov dword [esp + 1 * 4], 0x21 ; clock interrupt
	mov dword [esp + 2 * 4], 1 * 8 ; code segment select
	mov dword [esp + 3 * 4], 0x8e00 + 0x0000; interrupt gate
	mov dword [esp + 4 * 4], keyboard_int ;+ 0x100000; interrupt process program enter address
	call create_gate
	
	mov dword [esp + 0 * 4], 0 ; interrupt descriptor table start
	mov dword [esp + 1 * 4], 0x28 ; clock interrupt
	mov dword [esp + 2 * 4], 1 * 8 ; code segment select
	mov dword [esp + 3 * 4], 0x8e00 + 0x0000; interrupt gate
	mov dword [esp + 4 * 4], rtc_int ;+ 0x100000; interrupt process program enter address
	call create_gate
	
;	init other in interrupt descriptor table

	mov dword [esp + 0 * 4], 0 ; interrupt descriptor table start
	mov dword [esp + 1 * 4], 0x80 ; clock interrupt
	mov dword [esp + 2 * 4], 1 * 8 ; code segment select
	mov dword [esp + 3 * 4], 0x8e00 + 0x6000; interrupt gate
	mov dword [esp + 4 * 4], system_call ;+ 0x100000; interrupt process program enter address
	call create_gate

	
	add esp, 20 * 4
	popa
	leave
	ret


;;;;;system_call;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

align 32
system_call:
	interrupt_head .1

	mov edi, esp

	mov esp, stack_top

	jmp .2
.1:
	sti
	call [system_call_table + eax * 4]
	mov dword [edi + 11 * 4], eax
	cli
	jmp .re_start_re_enter

.2:
	sti
	call [system_call_table + eax * 4]
	mov dword [edi + 11 * 4], eax
	cli
	
interrupt_tail .re_start, .re_start_re_enter


align 32
system_call_table: dd system_get_ticks, my_cpuid


align 32

system_get_ticks: 
	enter
	push_some

	mov eax, [clock_count]
	
	pop_some
	leave
	ret

align 32

cpuid_data: dd 0, 0, 0, 0

my_cpuid: ;int my_cpuid(void)
	enter
	push_some

	mov eax, 0
	cpuid
	
	mov [cpuid_data + 0 * 4], ebx
	mov [cpuid_data + 1 * 4], edx	
	mov [cpuid_data + 2 * 4], ecx
	
	pop_some
	leave
	ret




; void cls(void)
; call cls
cls:
	enter
	pusha

	xor ebx, ebx
	mov al, ' '
	mov ah, 0xf
	mov ecx, 2000
.1:
	mov [gs: ebx], ax
	inc ebx
	inc ebx
	loop .1

	popa
	leave
	ret

; void print_c(char c, int colour)
;	mov dword [esp + 0 * 4], 'a'
;	mov dwrod [esp + 1 * 4], 0xf
;	call print_c
print_c: 
	enter
	pusha

	mov ebx, [cursor_pos]
	mov al, [ebp + 2 * 4]
	mov ah, [ebp + 3 * 4]
	mov [gs: ebx], ax
	inc ebx
	inc ebx
	mov [cursor_pos], ebx

	shr ebx, 1
	
;	mov al, 0xe
;	mov dx, 0x3d4
;	out dx, al
;	mov al, bh
;	mov dx, 0x3d5
;	out dx, al
	
;	mov al, 0xf
;	mov dx, 0x3d4
;	out dx, al
;	mov al, bl
;	mov dx, 0x3d5
;	out dx, al	
	
	popa
	leave
	ret


; int strlen(char* s)
;	mov dword [esp + 0 * 4], str
;	call strlen
;	return value in EAX
strlen: 
	enter
	push_some

	xor eax, eax
	mov ecx, 0xffff_ffff
	mov edi, [ebp + 2 * 4]
	repne
	scasb
	not ecx
	dec ecx
	mov eax, ecx
	
	pop_some
	leave
	ret

; void print_s(char* s, int colour)
;	mov dword [esp + 0 * 4], str
;	mov dword [esp + 1 * 4], 0xf
;	call print_s
print_s: 
	enter
	pusha

	mov ebx, [ebp + 2 * 4]
	mov dword [esp + 0 * 4], ebx
	call strlen
	mov ecx, eax
	mov ah, [ebp + 3 * 4]

.1:
	mov al, [ebx]
	inc ebx
	mov [esp + 0 * 4], al
	mov [esp + 1 * 4], ah
	call print_c
	loop .1
	
	popa
	leave
	ret

;	void print_s(char* s, int color, int pos)
;	mov dword [esp + 0 * 4], rtc_clock_str
;	mov dword [esp + 1 * 4], 0xe
;	mov dword [esp + 2 * 4], 24 * 80 * 2 + 0
;	call print_pos
print_pos:
	enter
	push_some
	
	sub esp, 30 * 4
	
	mov esi, [ebp + 2 * 4]
	
	mov [esp], esi
	call strlen
	mov ecx, eax
	
	mov ah, [ebp + 3 * 4]
	
	mov ebx, [ebp + 4 * 4]
	
.1:
	mov al, [esi]
	inc esi
	mov [gs:ebx], ax
	inc ebx
	inc ebx
	loop .1
		
	add esp, 30 * 4
	
	pop_some
	leave
	ret

;	unsigned char bcd_ascii(unsigned char)
;	mov al, [rtc_clock + 0]
;	mov [esp + 0 * 4], al
;	call bcd_ascii
bcd_ascii:
	enter
	push_some
	
	mov al, [ebp + 2 * 4]
	mov ah, al
	and ah, 00001111b
	add ah, '0'
	shr al, 4
	add al, '0'
	
	pop_some
	leave
	ret

;	void print_clock(void)
;	call print_clock
print_clock:
	enter
	pusha
	sub esp, 10 * 4
	
	mov al, [rtc_clock + 0]
	mov [esp + 0 * 4], al
	call bcd_ascii
	mov [rtc_clock_str + 0], al
	mov [rtc_clock_str + 1], ah
	
	mov al, [rtc_clock + 1]
	mov [esp + 0 * 4], al
	call bcd_ascii
	mov [rtc_clock_str + 3], al
	mov [rtc_clock_str + 4], ah
	
	mov al, [rtc_clock + 2]
	mov [esp + 0 * 4], al
	call bcd_ascii
	mov [rtc_clock_str + 6], al
	mov [rtc_clock_str + 7], ah
	
	mov dword [esp + 0 * 4], rtc_clock_str
	mov dword [esp + 1 * 4], 0xe
	mov dword [esp + 2 * 4], 3 * 80 * 2 + 26
	call print_pos

	add esp, 10 * 4
	popa
	leave
	ret

;	int _div(int* i, int n)
;	mov [esp + 0 * 4], ebx
;	mov [esp + 1 * 4], edx
;	call _div
_div:
	enter
	push_some
	
	xor edx, edx
	mov esi, [ebp + 2 * 4]
	mov eax, [esi]
	mov ebx, [ebp + 3 * 4]
	div ebx
	mov [esi], eax
	mov eax, edx
	
	pop_some
	leave
	ret

;	void itoa(int i, int n)
;	mov eax, [num1]
;	mov dword [esp + 0 * 4], eax
;	mov dword [esp + 1 * 4], 10
;	call itoa
;	display result	
;	mov dword [esp + 0 * 4], ascii_buf
;	mov dword [esp + 1 * 4], 0xc
;	call print_s	
itoa: 
	enter
	pusha	
	sub esp, 20 * 4
	
	mov esi, temp_buf
	mov edx, [ebp + 3 * 4]
	xor ecx, ecx
	
.1:	
	lea ebx, [ebp + 2 * 4]
	mov [esp + 0 * 4], ebx
	mov [esp + 1 * 4], edx
	call _div
	mov edi, number
	add edi, eax
	mov al, [edi]
	mov [esi], al
	inc esi
	inc ecx
	cmp dword [ebx], 0
	jne .1
	
	mov esi, temp_buf
	add esi, ecx
	mov edi, ascii_buf
.2:
	dec esi
	mov al, [esi]
	mov [edi], al
	inc edi
	loop .2

	mov byte [edi], 0
	
	add esp, 20 * 4	
	popa
	leave
	ret


;;;;;global_value;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

number: db '0123456789abcdef', 0
ascii_buf:
	times 32 db 0
temp_buf:
	times 32 db 0

cursor_pos: dd 0



num1: dd 20
num2: dd 30
result: dd 0


clock_count: dd 0
rtc_count: dd 0	
rtc_clock: dd 0, 0
rtc_clock_str: db '00:00:00', 0

;;;;;message_area;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
message_area:
str1: db 'Hello, World!', 0
clock_int_message: db 'Clock Interrupt...', 0
keyboard_int_message: db 'Keyboard Interrupt...', 0




;;;;;exception;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

no_error_code:
	mov eax, [esp + 0 * 4] ; exception number
	mov ecx, [esp + 1 * 4] ; eip
	mov edx, [esp + 2 * 4] ; cs
	mov ebx, [esp + 3 * 4] ; eflags
	sub esp, 20 * 4
	shl eax, 2
	add eax, exception_msg_table
	mov edi, [eax]
	mov dword [esp + 0 * 4], edi
	mov dword [esp + 1 * 4], 0xc
	call print_s
	
	mov dword [esp + 0 * 4], ecx
	mov dword [esp + 1 * 4], 16
	call itoa
	
	mov dword [esp + 0 * 4], ascii_buf
	mov dword [esp + 1 * 4], 0x9
	call print_s

	mov dword [esp + 0 * 4], ' '
	mov dword [esp + 1 * 4], 0xf
	call print_c
	
	mov dword [esp + 0 * 4], edx
	mov dword [esp + 1 * 4], 16
	call itoa
	
	mov dword [esp + 0 * 4], ascii_buf
	mov dword [esp + 1 * 4], 0x9
	call print_s

	mov dword [esp + 0 * 4], ' '
	mov dword [esp + 1 * 4], 0xf
	call print_c
	
	mov dword [esp + 0 * 4], ebx
	mov dword [esp + 1 * 4], 16
	call itoa
	
	mov dword [esp + 0 * 4], ascii_buf
	mov dword [esp + 1 * 4], 0x9
	call print_s

	mov dword [esp + 0 * 4], ' '
	mov dword [esp + 1 * 4], 0xf
	call print_c

	add esp, 20 * 4
.1:
	hlt
	jmp .1	
		
error_code:
	mov eax, [esp + 0 * 4] ; exception number
	mov ecx, [esp + 1 * 4] ; error_code
	mov edx, [esp + 2 * 4] ; eip
	mov ebx, [esp + 3 * 4] ; cs
	mov esi, [esp + 4 * 4] ; eflags
	sub esp, 20 * 4
	shl eax, 2
	add eax, exception_msg_table
	mov edi, [eax]
	mov dword [esp + 0 * 4], edi
	mov dword [esp + 1 * 4], 0xc
	call print_s
	
	mov dword [esp + 0 * 4], ecx
	mov dword [esp + 1 * 4], 16
	call itoa
	
	mov dword [esp + 0 * 4], ascii_buf
	mov dword [esp + 1 * 4], 0x9
	call print_s

	mov dword [esp + 0 * 4], ' '
	mov dword [esp + 1 * 4], 0xf
	call print_c
	
	mov dword [esp + 0 * 4], edx
	mov dword [esp + 1 * 4], 16
	call itoa
	
	mov dword [esp + 0 * 4], ascii_buf
	mov dword [esp + 1 * 4], 0x9
	call print_s

	mov dword [esp + 0 * 4], ' '
	mov dword [esp + 1 * 4], 0xf
	call print_c
	
	mov dword [esp + 0 * 4], ebx
	mov dword [esp + 1 * 4], 16
	call itoa
	
	mov dword [esp + 0 * 4], ascii_buf
	mov dword [esp + 1 * 4], 0x9
	call print_s

	mov dword [esp + 0 * 4], ' '
	mov dword [esp + 1 * 4], 0xf
	call print_c

	mov dword [esp + 0 * 4], esi
	mov dword [esp + 1 * 4], 16
	call itoa
	
	mov dword [esp + 0 * 4], ascii_buf
	mov dword [esp + 1 * 4], 0x9
	call print_s

	mov dword [esp + 0 * 4], ' '
	mov dword [esp + 1 * 4], 0xf
	call print_c

	add esp, 20 * 4
.1:
	hlt
	jmp .1	

divide_error:
	push 0
	jmp no_error_code
	
debug:
	push 1
	jmp no_error_code
	
nmi:
	push 2
	jmp no_error_code
	
break_point:
	push 3
	jmp no_error_code
	
overflow:
	push 4
	jmp no_error_code
	
bound_check:
	push 5
	jmp no_error_code
	
invalid_instruction:
	push 6
	jmp no_error_code
	
device_not_available:
	push 7
	jmp no_error_code
	
double_fault:
	push 8
	jmp error_code
	
coprocessor_segment_overrun:
	push 9
	jmp no_error_code
	
invalid_tss:
	push 10
	jmp error_code
	
segment_not_present:
	push 11
	jmp error_code
	
stack_fault:
	push 12
	jmp error_code
	
general_protection:
	push 13
	jmp error_code
	
page_fault:
	push 14
	jmp error_code
	
reserved:
	push 15
.1:
	hlt
	jmp .1
	
coprocessor_error:
	push 16
	jmp no_error_code

align 32

exception_table:
	dd divide_error, debug, nmi, break_point, \
	overflow, bound_check, invalid_instruction, device_not_available, \
	double_fault, coprocessor_segment_overrun, invalid_tss, \
	segment_not_present, stack_fault, general_protection, \
	page_fault, reserved, coprocessor_error	
	
divide_error_msg: db "divide_error...#0:  ", 0
debug_msg: db "debug...#1:  ", 0
nmi_msg: db "nmi...#2:  ", 0
break_point_msg: db "break_point...#3:  ", 0
overflow_msg: db "overflow...#4:  ", 0
bound_check_msg: db "bound_check...#5:  ", 0
invalid_instruction_msg: db "invalid_instruction...#6:  ", 0
device_not_available_msg: db "device_not_available...#7:  ", 0
double_fault_msg: db "double_fault...#8:  ", 0 
coprocessor_segment_overrun_msg: db "coprocessor_segment_overrun...#9:  ", 0 
invalid_tss_msg: db "invalid_tss...#10:  ", 0
segment_not_present_msg: db "segment_not_present...#11:  ", 0
stack_fault_msg: db "stack_fault...#12:  ", 0
general_protection_msg: db "general_protection...#13:  ", 0
page_fault_msg: db "page_fault...#14:  ", 0
reserved_msg: db "reserved...#15:  ", 0 
coprocessor_error_msg: db "coprocessor_error...#16:  ", 0

exception_msg_table:
	dd divide_error_msg, debug_msg, nmi_msg, break_point_msg, \
	overflow_msg, bound_check_msg, invalid_instruction_msg, device_not_available_msg, \
	double_fault_msg, coprocessor_segment_overrun_msg, invalid_tss_msg, \
	segment_not_present_msg, stack_fault_msg, general_protection_msg, \
	page_fault_msg, reserved_msg, coprocessor_error_msg




;;;;;interrupt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 32


re_start:
	mov esp, [process_table_point]
	lldt [esp + process_control.ldt_sel]
	lea eax, [esp + 18 * 4]
	mov [tss_start + tss.esp0], eax

re_start_re_enter:
	dec dword [re_enter_flags]
	pop gs
	pop fs
	pop es
	pop ds
	popa
	add esp, 4
	iret

align 32

clock_int:
	interrupt_head .1

	mov esp, stack_top
	jmp .2
.1:	
	in al, 0x21
	or al, 0x01
	out 0x21, al
	
	mov al, 0x20
	out 0x20, al
	
	sti
	call clock_handler
	cli
	
	in al, 0x21
	and al, 0xfe
	out 0x21, al
	jmp .re_start_re_enter

.2:	
	in al, 0x21
	or al, 0x01
	out 0x21, al
	
	mov al, 0x20
	out 0x20, al
	
	sti
	call sche
	cli
	
	in al, 0x21
	and al, 0xfe
	out 0x21, al

interrupt_tail .re_start, .re_start_re_enter


delay: ; void delay(int times)
	enter
	pusha

	mov ecx, [ebp + 2 * 4]
.1:
	nop
	nop
	loop .1
	
	popa
	leave
	ret



re_enter_flags: dd 0



clock_handler:
	enter
	pusha

	inc dword [clock_count]

	call sche

	push dword 10
	push dword [clock_count]
	call itoa
	add esp, 2 * 4

	push dword  24 * 160  +  0	
	push dword  0xc
	push dword  ascii_buf
	call print_pos
	add esp, 3 * 4
	
	popa
	leave
	ret


sche:
	enter
	pusha

	add dword [process_table_point], 36 * 4
	cmp dword [process_table_point], process_table_start + 5 * 36 * 4
	jbe .1
	mov dword [process_table_point], process_table_start
.1:

	popa
	leave
	ret


align 32	
keyboard_int: 
	interrupt_head .1

	mov esp, stack_top
	jmp .2

.1:

	in al, 0x21
	or al, 0000_0100b
	out 0x21, al

	mov al, 0x20
	out 0x20, al
	
	sti
	call keyboard_handler
	cli
	
	in al, 0x21
	and al, 1111_1011b
	out 0x21, al
	
	jmp .re_start_re_enter

.2:
	in al, 0x21
	or al, 0000_0100b
	out 0x21, al

	mov al, 0x20
	out 0x20, al
	
	sti
	call keyboard_handler
	cli
	
	in al, 0x21
	and al, 1111_1011b
	out 0x21, al

interrupt_tail .re_start, .re_start_re_enter

make: dd 0

keyboard_handler:
	enter
	pusha

	xor eax, eax
	in al, 0x60
	
	cmp al, 0xe1
	je .end
	cmp al, 0xe0
	je .end	
	mov ah, al
	and ah, 0x80
	cmp ah, 0
	jnz .end
	mov dword [make], 1

	and eax, 0x7f
	mov ebx, eax
	shl eax, 1
	add ebx, eax
	xor eax, eax
	mov al, [key_map + ebx]

	
	push dword 0xf
	push dword eax
	call print_c
	add esp, 2 * 4
.end:
	
	popa
	leave
	ret


align 32
rtc_int: 
	interrupt_head .1

	mov esp, stack_top
	jmp .2
	
.1:

	in al, 0xa1
	or al, 0000_0001b
	out 0xa1, al

	mov al, 0x20
	out 0x20, al
	out 0xa0, al

	sti
	call rtc_handler
	cli

	in al, 0xa1
	and al, 1111_1110b
	out 0xa1, al
	
	jmp .re_start_re_enter
.2:
	in al, 0xa1
	or al, 0000_0001b
	out 0xa1, al

	mov al, 0x20
	out 0x20, al
	out 0xa0, al

	sti
	call rtc_handler
	cli

	in al, 0xa1
	and al, 1111_1110b
	out 0xa1, al
	
interrupt_tail .re_start, .re_start_re_enter

rtc_handler:
	enter
	pusha

.1:
;	mov al, 0x8a
;	out 0x70, al
;	in al, 0x71
;	test al, 0x80
;	jnz .1
	
	mov al, 4
	out 0x70, al
	in al, 0x71
	mov [rtc_clock + 0], al
	
	mov al, 2
	out 0x70, al
	in al, 0x71
	mov [rtc_clock + 1], al
	
	mov al, 0
	out 0x70, al
	in al, 0x71
	mov [rtc_clock + 2], al

	mov al, 0xc
	out 0x70, al
	in al, 0x71	

	inc dword [rtc_count]
	
	popa
	leave
	ret

;;;;;other_function;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

msg1: db 'TASK1:', 0
msg2: db 'TASK2:', 0
msg3: db 'TASK3:', 0
msg4: db 'U_TASK4:', 0
msg5: db 'U_TASK5:', 0
msg6: db 'U_TASK6:', 0

align 4 * 1024
;	void function1(void)
function1_start:
	enter
	pusha

	sub esp, 20 * 4
	mov dword [esp + 0 * 4], msg1
	mov dword [esp + 1 * 4], 0xc
	mov dword [esp + 2 * 4], 0 * 160  +  0
	call print_pos	

.1:
	
	mov eax, [clock_count]
	mov dword [esp + 0 * 4], eax
	mov dword [esp + 1 * 4], 10
	call itoa
	
	mov dword [esp + 0 * 4], ascii_buf
	mov dword [esp + 1 * 4], 0xa
	mov dword [esp + 2 * 4], 0 * 160  +  20
	call print_pos
	jmp .1
	
	add esp, 20 * 4
	popa
	leave
	ret
function1_end:


align 32
function2_start:
	enter
	pusha
	
	
	sub esp, 20 * 4
	
	mov dword [esp + 0 * 4], msg2
	mov dword [esp + 1 * 4], 0xc
	mov dword [esp + 2 * 4], 1 * 160  +  0
	call print_pos	

	
	mov byte [gs: 160 + 20], '0'
	mov byte [gs: 161 + 20], 0xb
.1:
	cmp byte [gs: 160 + 20], '9'
	ja .2
	inc byte [gs: 160 + 20]
	mov byte [gs: 161 + 20], 0xb
	jmp .1
.2:
	mov byte [gs: 160 + 20], '0'
	jmp .1

	add esp, 20 * 4
	popa
	leave
	ret
function2_end:



align 32
function3_start:
	enter
	pusha

	sub esp, 20 * 4


	mov dword [esp + 0 * 4], msg3
	mov dword [esp + 1 * 4], 0xc
	mov dword [esp + 2 * 4], 2 * 160  +  0
	call print_pos	
	
	mov byte [gs: 320 + 20], 'A'
	mov byte [gs: 321 + 20], 0xc
.1:
	cmp byte [gs: 320 + 20], 'Z'
	ja .2
	inc byte [gs: 320 + 20]
	mov byte [gs: 321 + 20], 0xc
	jmp .1
.2:
	mov byte [gs: 320 + 20], 'A'	
	jmp .1
	
	add esp, 20 * 4
	popa
	leave
	ret
function3_end:

align 32
function4_start:
	enter
	pusha


	sub esp, 20 * 4
	mov dword [esp + 0 * 4], msg4
	mov dword [esp + 1 * 4], 0xf
	mov dword [esp + 2 * 4], 3 * 160  +  0
	call print_pos

	mov eax, 1
	int 0x80
	
	mov dword [esp + 0 * 4], cpuid_data
	mov dword [esp + 1 * 4], 0xc
	mov dword [esp + 2 * 4], 3 * 160  + 80
	call print_pos

.1:
	call print_clock
	jmp .1
	add esp, 20 * 4
	popa
	leave
	ret
function4_end:



align 32
function5_start:
	enter
	pusha

	sub esp, 20 * 4

	mov dword [esp + 0 * 4], msg5
	mov dword [esp + 1 * 4], 0xf
	mov dword [esp + 2 * 4], 4 * 160  +  0
	call print_pos

	
.1:

	mov eax, 0
	int 0x80

	mov dword [esp + 0 * 4], eax
	mov dword [esp + 1 * 4], 10
	call itoa
	
	mov dword [esp + 0 * 4], ascii_buf
	mov dword [esp + 1 * 4], 0xd
	mov dword [esp + 2 * 4], 4 * 2 * 80 + 20
	call print_pos

	jmp .1
	
	add esp, 20 * 4
	popa
	leave
	ret
function5_end:



align 32
function6_start:
	enter
	pusha

	sub esp, 20 * 4
	mov dword [esp + 0 * 4], msg6
	mov dword [esp + 1 * 4], 0xf
	mov dword [esp + 2 * 4], 5 * 160  +  0
	call print_pos

	mov dword [esp + 0 * 4], '6'
	mov dword [esp + 1 * 4], 0xb
	call print_c

.1:
;	mov dword [esp + 0 * 4], 'M'
;	mov dword [esp + 1 * 4], 0x9
;	call print_c
	

	call my_delay

	
;	mov eax, 0
;	int 0x80

	mov eax, [rtc_count]
	mov dword [esp + 0 * 4], eax
	mov dword [esp + 1 * 4], 10
	call itoa
	
	mov dword [esp + 0 * 4], ascii_buf
	mov dword [esp + 1 * 4], 0x9
	mov dword [esp + 2 * 4], 5 * 2 * 80 + 40
	call print_pos

	jmp .1
	
	add esp, 20 * 4
	popa
	leave
	ret
function6_end:



function_point dd function1_start, function2_start, function3_start, function4_start, function5_start,\
				  function6_start

align 1024
task_or_user_stack_bottom:
	times 64 * 128 dd 0
task_or_user_stack_top:


align 4096
code_segment_test:
	nop
	retf



;;;;;about process;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

align 32

process_table_start:
	times 64 * 36 dd 0
process_table_end:

process_table_point: dd process_table_start

align 32

tss_start:
	times 1 * 26 dd 0
tss_end: 	

align 32

get_ticks: ; int get_ticks(void) ;int system_get_ticks(void)
;給系統調用get_ticks包裝一下 這個東西對於純彙編語言的系統似乎的多餘的
	enter
	push_some

	mov eax, 0
	int 0x80
	
	pop_some
	leave
	ret


align 32
my_delay:
	enter
	push_some

	sub esp, 1 * 4


	call get_ticks
	mov [esp], eax
	add dword [esp], 100
.1:	
	call get_ticks
	cmp eax, [esp]
	jbe .1
	
	mov eax, 1
	
	add esp, 1 * 4
	
	pop_some
	leave
	ret	
	

align 32	
key_map:
						  ; 0
						  
	db 0,		0,		0 ; 0x00 none
	db 0,		0,		0 ; 0x01 esc
	db '1',		'!',	0 ; 0x02 '1'
	db '2',		'@',	0 ; 0x03 '2'
	db '3',		'#',	0 ; 0x04 '3'
	db '4',		'$',	0 ; 0x05 '4'
	db '5',		'%',	0 ; 0x06 '5'
	db '6',		'^',	0 ; 0x07 '6'
	db '7',		'&',	0 ; 0x08 '7'
	db '8',		'*',	0 ; 0x09 '8'
	db '9',		'(',	0 ; 0x0a '9'
	db '0',		')',	0 ; 0x0b '0'
	db '-',		'_',	0 ; 0x0c '-'
	db '=',		'+',	0 ; 0x0d '='
	db 8,		8,		8 ; 0x0e backspace
	db 0,		0,		0 ; 0x0f tab
	
						  ; 1		
						  
	db 'q',		'Q',	0 ; 0x10 'q'
	db 'w',		'W',	0 ; 0x11 'w'
	db 'e',		'E',	0 ; 0x12 'e'
	db 'r',		'R',	0 ; 0x13 'r'
	db 't',		'T',	0 ; 0x14 't'
	db 'y',		'Y',	0 ; 0x15 'y'
	db 'u',		'U',	0 ; 0x16 'u'
	db 'i',		'I',	0 ; 0x17 'i'
	db 'o',		'O',	0 ; 0x18 'o'
	db 'p',		'P',	0 ; 0x19 'p'	
	db '[',		'{',	0 ; 0x1a 'i'
	db ']',		'}',	0 ; 0x1b 'o'
	db 0xa,		0,      0 ; 0x1c enter	
	db '[',		'{',	0 ; 0x1d ctrl
	db 'a',		'A',	0 ; 0x1e 'a'	
	db 's',		'S',	0 ; 0x1f 's'
	
						  ; 2		
							
	db 'd',		'D',	0 ; 0x20 'd'
	db 'f',		'F',	0 ; 0x21 'f'
	db 'g',		'G',	0 ; 0x22 'g'
	db 'h',		'H',	0 ; 0x23 'h'
	db 'j',		'J',	0 ; 0x24 'j'
	db 'k',		'K',	0 ; 0x25 'k'
	db 'l',		'L',	0 ; 0x26 'l'
	db ';',		':',	0 ; 0x27 ';'
	db "'",		'"',	0 ; 0x28 '\'
	db '`',		'~',	0 ; 0x29 '`'	
	db 0,		0,		0 ; 0x2a shift left
	db '\',		'|',	0 ; 0x2b 'o'	
	db 'z',		'Z',	0 ; 0x2c 'z'
	db 'x',		'X',	0 ; 0x2d 'x'	
	db 'c',		'C',	0 ; 0x2e 'c'
	db 'v',		'V',	0 ; 0x2f 'v'	
	
						  ; 3		
						  	
	db 'b',		'B',	0 ; 0x30 'b'
	db 'n',		'N',	0 ; 0x31 'n'
	db 'm',		'M',	0 ; 0x32 'm'
	db ',',		'<',	0 ; 0x33 ','
	db '.',		'>',	0 ; 0x34 '.'
	db '/',		'?',	0 ; 0x35 '/'
	db 0,		0,		0 ; 0x36 
	db 0,		0,		0 ; 0x37 
	db 0,		0,		0 ; 0x38 
	db ' ',		' ',	0 ; 0x39 	
	db 0,		0,		0 ; 0x3a 
	db 0,		0,		0 ; 0x3b 
	db 0,		0,		0 ; 0x3c 	
	db 0,		0,		0 ; 0x3d 
	db 0,		0,		0 ; 0x3e 	
	db 0,		0,		0 ; 0x3f 	
	
						  ; 4		
						  
	db 0,		0,		0 ; 0x40	
	db 0,		0,		0 ; 0x41
	db 0,		0,		0 ; 0x42 
	db 0,		0,		0 ; 0x43 	
	db 0,		0,		0 ; 0x44 
	db 0,		0,		0 ; 0x45 
	db 0,		0,		0 ; 0x46 	
	db 0,		0,		0 ; 0x47 
	db 0,		0,		0 ; 0x48 	
	db 0,		0,		0 ; 0x49	
	db 0,		0,		0 ; 0x4a 
	db 0,		0,		0 ; 0x4b 
	db 0,		0,		0 ; 0x4c 	
	db 0,		0,		0 ; 0x4d 
	db 0,		0,		0 ; 0x4e 	
	db 0,		0,		0 ; 0x4f	

							; 5
	db 0,		0,		0 ; 0x_0	
	db 0,		0,		0 ; 0x_1
	db 0,		0,		0 ; 0x_2 
	db 0,		0,		0 ; 0x_3 	
	db 0,		0,		0 ; 0x_4 
	db 0,		0,		0 ; 0x_5 
	db 0,		0,		0 ; 0x_6 	
	db 0,		0,		0 ; 0x_7 
	db 0,		0,		0 ; 0x_8 	
	db 0,		0,		0 ; 0x_9	
	db 0,		0,		0 ; 0x_a 
	db 0,		0,		0 ; 0x_b 
	db 0,		0,		0 ; 0x_c 	
	db 0,		0,		0 ; 0x_d 
	db 0,		0,		0 ; 0x_e 	
	db 0,		0,		0 ; 0x_f	

							; 6
	db 0,		0,		0 ; 0x_0	
	db 0,		0,		0 ; 0x_1
	db 0,		0,		0 ; 0x_2 
	db 0,		0,		0 ; 0x_3 	
	db 0,		0,		0 ; 0x_4 
	db 0,		0,		0 ; 0x_5 
	db 0,		0,		0 ; 0x_6 	
	db 0,		0,		0 ; 0x_7 
	db 0,		0,		0 ; 0x_8 	
	db 0,		0,		0 ; 0x_9	
	db 0,		0,		0 ; 0x_a 
	db 0,		0,		0 ; 0x_b 
	db 0,		0,		0 ; 0x_c 	
	db 0,		0,		0 ; 0x_d 
	db 0,		0,		0 ; 0x_e 	
	db 0,		0,		0 ; 0x_f

							; 7
	db 0,		0,		0 ; 0x_0	
	db 0,		0,		0 ; 0x_1
	db 0,		0,		0 ; 0x_2 
	db 0,		0,		0 ; 0x_3 	
	db 0,		0,		0 ; 0x_4 
	db 0,		0,		0 ; 0x_5 
	db 0,		0,		0 ; 0x_6 	
	db 0,		0,		0 ; 0x_7 
	db 0,		0,		0 ; 0x_8 	
	db 0,		0,		0 ; 0x_9	
	db 0,		0,		0 ; 0x_a 
	db 0,		0,		0 ; 0x_b 
	db 0,		0,		0 ; 0x_c 	
	db 0,		0,		0 ; 0x_d 
	db 0,		0,		0 ; 0x_e 	
	db 0,		0,		0 ; 0x_f	
; syslib.asm
%include "sysmacro.asm"

u8 equ 1
u16 equ 2
u32 equ 4
u64 equ 8

struc tss ; 26 double word
	.backlink resb u32
	.esp0 resb u32
	.ss0 resb u32
	.esp1 resb u32
	.ss1 resb u32
	.esp2 resb u32
	.ss2 resb u32
	.cr3 resb u32
	.eip resb u32
	.flags resb u32
	.eax resb u32
	.ecx resb u32
	.edx resb u32
	.ebx resb u32
	.esp resb u32
	.ebp resb u32
	.esi resb u32
	.edi resb u32
	.es resb u32
	.cs resb u32
	.ss resb u32
	.ds resb u32
	.fs resb u32
	.gs resb u32
	.ldt resb u32
	.trap resb u16
	.iobase resb u16
endstruc

struc process_stack
	.gs: resb u32	;	#0
	.fs: resb u32
	.es: resb u32
	.ds: resb u32
	.edi: resb u32
	.esi: resb u32
	.ebp: resb u32
	.kernel_esp: resb u32
	.ebx: resb u32
	.edx: resb u32
	.ecx: resb u32
	.eax: resb u32
	.retaddr: resb u32
	.eip: resb u32
	.cs: resb u32
	.eflags: resb u32
	.esp: resb u32
	.ss: resb u32	;	#17
endstruc

ldt_size equ 4

struc process_control ; 18 + 1 + 8 + 1 + 8 double word = 36
	.process_stack resb 18 * u32	; 18 double word
	.ldt_sel resb u32	; 1 double word
	.ldt resb ldt_size * u64	; 8 double word
	.pid resb u32	; 1 double word
	.process_name resb 32 * u8	; 8 double word
endstruc


; void create_descriptor(int table_start, int number, int base, int limit, int attrib)
; mov dword [esp + 0 * 4], 0x7c00
; mov dword [esp + 1 * 4], 1
; mov dword [esp + 2 * 4], 0x100000
; mov dword [esp + 3 * 4], 0x000fffff
; mov dword [esp + 4 * 4], 0x9a + 0xc000
; call create_descriptor

create_descriptor:
	enter
	pusha

	push ds
	mov ax, 5 * 8
	mov ds, ax

	mov word [ebx + 5], 0 	
	mov ebx, [ebp + 2 * 4]
	mov ecx, [ebp + 3 * 4]
	shl ecx, 3
	add ebx, ecx
	mov eax, [ebp + 5 * 4]
	mov [ebx], ax
	shr eax, 16
	and al, 0x0f
	mov [ebx + 6], al
	mov eax, [ebp + 4 * 4]
	mov ecx, eax
	and eax, 0x00ffffff
	mov [ebx + 2], eax
	shr ecx, 24
	mov [ebx + 7], cl
	mov ax, [ebp + 6 * 4]
	or [ebx + 5], ax

	pop ds
	popa
	leave
	ret
	
;	void create_gate(int table_start, int irq, int select, int attrib, int offset)
;	mov dword [esp + 0 * 4], 0x7c00 + 256 * 8 ; interrupt descriptor table start
;	mov dword [esp + 1 * 4], 0x20 ; clock interrupt
;	mov dword [esp + 2 * 4], 4 * 8 ; code segment select
;	mov dword [esp + 3 * 4], 0x8e00 + 0x0000; interrupt gate
;	mov dword [esp + 4 * 4], clock_int ; interrupt process program enter address
;	call create_gate
create_gate: 
	enter
	pusha

	push ds
	mov ax, 5 * 8
	mov ds, ax
	
	mov ebx, [ebp + 2 * 4]
	mov ecx, [ebp + 3 * 4]
	shl ecx, 3
	add ebx, ecx
	mov ax, [ebp + 4 * 4]
	mov [ebx + 2], ax
	mov ax, [ebp + 5 * 4]
	mov [ebx + 4], ax
	mov eax, [ebp + 6 * 4]
	mov [ebx + 0], ax
	shr eax, 16
	mov [ebx + 6], ax
	
	pop ds
	popa
	leave
	ret
	
;	void load_hd_to_mem(int sector_start, int sectors, int mem_start)
;	mov dword [esp + 0 * 4], 21 ; from 
;	mov dword [esp + 1 * 4], 8196 ; size
;	mov dword [esp + 2 * 4], 0x100000 ; memory start
;	call load_hd_to_mem
load_hd_to_mem:
	enter
	pusha

	push ds
	mov ax, 5 * 8
	mov ds, ax
	
	mov esi, [ebp + 2 * 4]
	mov ecx, [ebp + 3 * 4]
	mov ebx, [ebp + 4 * 4]

.readloop:	
	mov al, 1
	mov dx, 0x1f2
	out dx, al

	mov eax, esi
	mov dx, 0x1f3
	out dx, al
	shr eax, 8	
	mov dx, 0x1f4
	out dx, al
	shr eax, 8		
	mov dx, 0x1f5
	out dx, al
	shr eax, 8
	and al, 0x0f
	or al, 0xe0
	mov dx, 0x1f6
	out dx, al
	
	mov dx, 0x1f7
	mov al, 0x20
	out dx, al

	mov dx, 0x1f7
.1:
	in al, dx
	and al, 0x88
	cmp al, 0x08
	jnz .1

	push ecx
	mov ecx, 256
	mov dx, 0x1f0
.2:
	in ax, dx
	mov [ebx], ax
	inc ebx
	inc ebx
	loop .2
	pop ecx

	inc esi
	loop .readloop

	pop ds
	popa
	leave
	ret


	
	


; sysmacro.asm
%macro enter 0
	push ebp
	mov ebp, esp
%endmacro

%macro push_some 0
	push ecx
	push edx
	push ebx
	push esi
	push edi
%endmacro

%macro pop_some 0
	pop edi
	pop esi
	pop ebx
	pop edx
	pop ecx
%endmacro

%macro interrupt_head 1 ; bad select
	sub esp, 4
	pusha
	push ds
	push es
	push fs
	push gs

	mov dx, ss
	mov ds, dx
	mov es, dx

	inc dword [re_enter_flags]
	cmp dword [re_enter_flags], 0
	jne %1
%endmacro
	
%macro interrupt_tail 2 ; bad select
%1:
	mov esp, [process_table_point]
	lldt [esp + process_control.ldt_sel]
	lea eax, [esp + 18 * 4]
	mov [tss_start + tss.esp0], eax
%2:
	dec dword [re_enter_flags]
	pop gs
	pop fs
	pop es
	pop ds
	popa
	add esp, 4
	iret
%endmacro

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章