📄 kernel.asm
字号:
; SET VARIABLES
call set_variables
; STACK AND FDC
call stack_init
call fdc_init
; PALETTE FOR 320x200 and 640x480 16 col
cmp [0xfe0c],word 0x12
jne no_pal_vga
mov esi,boot_pal_vga
call boot_log
call paletteVGA
no_pal_vga:
cmp [0xfe0c],word 0x13
jne no_pal_ega
mov esi,boot_pal_ega
call boot_log
call palette320x200
no_pal_ega:
; LOAD DEFAULT SKIN
call load_default_skin
; MTRR'S
call enable_mtrr
; LOAD FIRST APPLICATION
mov [0x3000],dword 1
mov [0x3004],dword 1
mov [boot_application_load],byte 1
mov eax,firstapp
call start_application_fl
mov [boot_application_load],byte 0
cmp eax,2 ; if no first app found - halt
je first_app_found
cli
jmp $
boot_application_load: dd 0x0
first_app_found:
mov [0x3004],dword 2
mov [0x3000],dword 0
; START MULTITASKING
mov esi,boot_tasking
call boot_log
mov [0xe000],byte 1 ; multitasking enabled
; UNMASK ALL IRQ'S
mov esi,boot_allirqs
call boot_log
mov al,0 ; unmask all irq's
out 0xA1,al
out 0x21,al
mov ecx,32
ready_for_irqs:
mov al,0x20 ; ready for irqs
out 0x20,al
out 0xa0,al
loop ready_for_irqs ; flush the queue
sti
jmp $ ; wait here for timer to take control
; Fly :)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; MAIN OS LOOP ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
osloop:
call check_mouse_data
call draw_pointer
call check_menus
call check_scrolls
call checkbuttons
call checkwindows
call check_window_move_request
call checkmisc
call checkEgaCga
call stack_handler
call checkidle
jmp osloop
osloop_without_gui_response:
call check_mouse_data
call draw_pointer
call checkmisc
call checkEgaCga
call stack_handler
call checkidle
ret
checkidle:
pusha
cmp [check_idle_semaphore],0
jne no_idle_state
call change_task
mov eax,[idlemem]
mov ebx,[0xfdf0]
cmp eax,ebx
jnz idle_exit
call _rdtsc
mov ecx,eax
idle_loop:
hlt
cmp [check_idle_semaphore],0
jne idle_loop_exit
mov eax,[0xfdf0]
cmp ebx,eax
jz idle_loop
idle_loop_exit:
mov [idlemem],eax
call _rdtsc
sub eax,ecx
mov ebx,[idleuse]
add ebx,eax
mov [idleuse],ebx
popa
ret
idle_exit:
mov ebx,[0xfdf0]
mov [idlemem],ebx
call change_task
popa
ret
no_idle_state:
dec [check_idle_semaphore]
mov ebx,[0xfdf0]
mov [idlemem],ebx
call change_task
popa
ret
idlemem dd 0x0
idleuse dd 0x0
idleusesec dd 0x0
check_idle_semaphore dd 0x0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; INCLUDED SYSTEM FILES ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include "KERNEL32.INC"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; KERNEL FUNCTIONS ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
enable_mtrr:
pusha
cmp [0x2f0000+0x901c],byte 2
je no_mtrr
mov eax,[0xFE0C] ; if no LFB then no MTRR
test eax,0100000000000000b
jz no_mtrr
mov edx,[cpuid_1+3*4] ; edx - MTRR's supported ?
test edx,1000000000000b
jz no_mtrr
call find_empty_mtrr
cmp ecx,0
jz no_mtrr
mov esi,boot_mtrr ; 'setting mtrr'
call boot_log
mov edx,0x0 ; LFB , +8 M , write combine
mov eax,[0x2f9018]
or eax,1
wrmsr
inc ecx
mov edx,0xf
mov eax,0xff800800
wrmsr
mov ecx,0x2ff ; enable mtrr's
rdmsr
or eax,100000000000b ; set
wrmsr
no_mtrr:
popa
ret
setwindowdefaults:
pusha
xor eax,eax
mov ecx,0xc000
swdl:
inc eax
add ecx,2
mov [ecx+0x000],ax ; process no
mov [ecx+0x400],ax ; positions in stack
cmp ecx,0xc400-2 ; the more high, the more surface
jnz swdl
popa
ret
find_empty_mtrr: ; 8 pairs checked
mov ecx,0x201-2
mtrr_find:
add ecx,2
cmp ecx,0x200+8*2
jge no_free_mtrr
rdmsr
test eax,0x0800
jnz mtrr_find
dec ecx
ret
no_free_mtrr:
mov ecx,0
ret
reserve_irqs_ports:
pusha
mov [irq_owner+4*0],byte 1 ; timer
mov [irq_owner+4*1],byte 1 ; keyboard
mov [irq_owner+4*5],byte 1 ; sound blaster
mov [irq_owner+4*6],byte 1 ; floppy diskette
mov [irq_owner+4*13],byte 1 ; math co-pros
mov [irq_owner+4*14],byte 1 ; ide I
mov [irq_owner+4*15],byte 1 ; ide II
movzx eax,byte [0xf604] ; mouse irq
dec eax
add eax,mouseirqtable
movzx eax,byte [eax]
shl eax,2
mov [irq_owner+eax],byte 1
; RESERVE PORTS
mov edi,1 ; 0x00-0xff
mov [0x2d0000],edi
shl edi,4
mov [0x2d0000+edi+0],dword 1
mov [0x2d0000+edi+4],dword 0x0
mov [0x2d0000+edi+8],dword 0xff
cmp [0xf604],byte 2 ; com1 mouse -> 0x3f0-0x3ff
jne ripl1
inc dword [0x2d0000]
mov edi,[0x2d0000]
shl edi,4
mov [0x2d0000+edi+0],dword 1
mov [0x2d0000+edi+4],dword 0x3f0
mov [0x2d0000+edi+8],dword 0x3ff
ripl1:
cmp [0xf604],byte 3 ; com2 mouse -> 0x2f0-0x2ff
jne ripl2
inc dword [0x2d0000]
mov edi,[0x2d0000]
shl edi,4
mov [0x2d0000+edi+0],dword 1
mov [0x2d0000+edi+4],dword 0x2f0
mov [0x2d0000+edi+8],dword 0x2ff
ripl2:
popa
ret
mouseirqtable db 12 ; ps2
db 4 ; com1
db 3 ; com2
setirqreadports:
mov [irq12read+0],dword 0x60 + 0x01000000 ; read port 0x60 , byte
mov [irq12read+4],dword 0 ; end of port list
mov [irq04read+0],dword 0x3f8 + 0x01000000 ; read port 0x3f8 , byte
mov [irq04read+4],dword 0 ; end of port list
mov [irq03read+0],dword 0x2f8 + 0x01000000 ; read port 0x2f8 , byte
mov [irq03read+4],dword 0 ; end of port list
ret
process_number dd 0x1
novesachecksum dd 0x0
set_variables:
mov ecx,0x100 ; flush port 0x60
.fl60: in al,0x60
loop .fl60
mov [0xfcff],byte 0 ; mouse buffer
mov [0xf400],byte 0 ; keyboard buffer
mov [0xf500],byte 0 ; button buffer
mov [0xfb0a],dword 100*65536+100 ; mouse x/y
mov byte [SB16_Status],0 ; Minazzi Paolo
mov [0x400000-12],dword 1 ; tiled background
mov [0xfe88],dword 0x2C0000 ; address of button list
ret
align 4
sys_outport:
mov edi,ebx ; separate flag for read / write
and ebx,65535
mov ecx,[0x2d0000]
test ecx,ecx
jne sopl8
mov [esp+36],dword 1
ret
sopl8:
mov edx,[0x3010]
mov edx,[edx+0x4]
and ebx,65535
cld
sopl1:
mov esi,ecx
shl esi,4
add esi,0x2d0000
cmp edx,[esi+0]
jne sopl2
cmp ebx,[esi+4]
jb sopl2
cmp ebx,[esi+8]
jg sopl2
jmp sopl3
sopl2:
dec ecx
jnz sopl1
mov [esp+36],dword 1
ret
sopl3:
test edi,0x80000000 ; read ?
jnz sopl4
mov dx,bx ; write
out dx,al
mov [esp+36],dword 0
ret
sopl4:
mov dx,bx ; read
in al,dx
and eax,0xff
mov [esp+36],dword 0
mov [esp+24],eax
ret
checkscreenpixel:
mov esi,[0x3004]
inc esi
sciloop:
cmp esi,2
jbe scic3
dec esi
movzx edi,word [esi*2+0xc400]
shl edi,5
add edi,window_data
cmp [edi+4],ebx ; y start
jbe sci2
jmp sciloop
sci2:
cmp [edi+0],eax ; x start
jbe sci1
jmp sciloop
sci1:
mov ecx,[edi+0]
mov edx,[edi+4]
add ecx,[edi+8]
add edx,[edi+12]
cmp eax,ecx
jbe sci3
jmp sciloop
sci3:
cmp ebx,edx
jbe sci4
jmp sciloop
sci4:
movzx ecx,word [esi*2+0xc400] ; process of pixel
; check that the process has a rectangle window
mov edx,ecx
shl edx,8
add edx,0x80000+0x80
cmp [edx],dword 0
je rect_shaped
rand_shaped:
pusha
sub eax,[edi+0]
sub ebx,[edi+4]
push ecx
mov ecx,[edx+4]
shr eax,cl
shr ebx,cl
mov esi,[edi+8]
add esi,1
shr esi,cl
imul ebx,esi
add eax,ebx
add eax,[edx]
pop ecx
mov edx,ecx
shl edx,5
add eax,[edx+0x3000+0x10]
cmp [eax],byte 1
je rand_window_pixel
popa
jmp sciloop
rand_window_pixel:
popa
rect_shaped:
shl ecx,5
add ecx,0x3000
movzx ecx,byte [ecx+0xe] ; screen id of process
ret
scic3:
mov ecx,1 ; os pixel
ret
calculatescreen:
; eax x start
; ebx y start
; ecx x end
; edx y end
pusha
push eax
csp1:
push ecx
push edx
push eax
push ebx
call checkscreenpixel
mov eax,[0xfe00]
inc eax
imul eax,dword [esp+0]
add eax,[esp+4]
mov [eax+0x400000],cl
pop ebx
pop eax
pop edx
pop ecx
inc eax
cmp eax,ecx
jbe csp1
mov eax,[esp]
inc ebx
cmp ebx,edx
jbe csp1
pop eax
popa
ret
setscreen:
; eax x start
; ebx y start
; ecx x end
; edx y end
pusha
push esi
push eax
csp11:
push eax
push ebx
push ecx
push edx
mov esi,eax
mov eax,[0xfe00]
inc eax
mul ebx
add eax,esi
add eax,0x400000
mov cl,[esp+20]
mov [eax],cl
pop edx
pop ecx
pop ebx
pop eax
inc eax
cmp eax,ecx
jbe csp11
mov eax,[esp]
inc ebx
cmp ebx,edx
jbe csp11
add esp,8
popa
ret
align 4
sys_sb16:
cmp word [sb16],word 0
jnz sb16l1
mov [esp+36],dword 1
ret
sb16l1:
mov [esp+36],dword 0
cmp eax,1 ; set volume - main
jnz sb16l2
mov dx,word [sb16]
add dx,4
mov al,0x22
out dx,al
mov esi,1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -