r/lib/kliba.asm

199 lines
4.7 KiB
NASM

; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; klib.asm
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Forrest Yu, 2005
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%include "sconst.inc"
; 导入全局变量
extern disp_pos
[SECTION .text]
; 导出函数
global disp_str
global disp_color_str
global out_byte
global in_byte
global enable_irq
global disable_irq
; ========================================================================
; void disp_str(char * info);
; ========================================================================
disp_str:
push ebp
mov ebp, esp
mov esi, [ebp + 8] ; pszInfo
mov edi, [disp_pos]
mov ah, 0Fh
.1:
lodsb
test al, al
jz .2
cmp al, 0Ah ; 是回车吗?
jnz .3
push eax
mov eax, edi
mov bl, 160
div bl
and eax, 0FFh
inc eax
mov bl, 160
mul bl
mov edi, eax
pop eax
jmp .1
.3:
mov [gs:edi], ax
add edi, 2
jmp .1
.2:
mov [disp_pos], edi
pop ebp
ret
; ========================================================================
; void disp_color_str(char * info, int color);
; ========================================================================
disp_color_str:
push ebp
mov ebp, esp
mov esi, [ebp + 8] ; pszInfo
mov edi, [disp_pos]
mov ah, [ebp + 12] ; color
.1:
lodsb
test al, al
jz .2
cmp al, 0Ah ; 是回车吗?
jnz .3
push eax
mov eax, edi
mov bl, 160
div bl
and eax, 0FFh
inc eax
mov bl, 160
mul bl
mov edi, eax
pop eax
jmp .1
.3:
mov [gs:edi], ax
add edi, 2
jmp .1
.2:
mov [disp_pos], edi
pop ebp
ret
; ========================================================================
; void out_byte(u16 port, u8 value);
; ========================================================================
out_byte:
mov edx, [esp + 4] ; port
mov al, [esp + 4 + 4] ; value
out dx, al
nop ; 一点延迟
nop
ret
; ========================================================================
; u8 in_byte(u16 port);
; ========================================================================
in_byte:
mov edx, [esp + 4] ; port
xor eax, eax
in al, dx
nop ; 一点延迟
nop
ret
; ========================================================================
; void disable_irq(int irq);
; ========================================================================
; Disable an interrupt request line by setting an 8259 bit.
; Equivalent code:
; if(irq < 8){
; out_byte(INT_M_CTLMASK, in_byte(INT_M_CTLMASK) | (1 << irq));
; }
; else{
; out_byte(INT_S_CTLMASK, in_byte(INT_S_CTLMASK) | (1 << irq));
; }
disable_irq:
mov ecx, [esp + 4] ; irq
pushf
cli
mov ah, 1
rol ah, cl ; ah = (1 << (irq % 8))
cmp cl, 8
jae disable_8 ; disable irq >= 8 at the slave 8259
disable_0:
in al, INT_M_CTLMASK
test al, ah
jnz dis_already ; already disabled?
or al, ah
out INT_M_CTLMASK, al ; set bit at master 8259
popf
mov eax, 1 ; disabled by this function
ret
disable_8:
in al, INT_S_CTLMASK
test al, ah
jnz dis_already ; already disabled?
or al, ah
out INT_S_CTLMASK, al ; set bit at slave 8259
popf
mov eax, 1 ; disabled by this function
ret
dis_already:
popf
xor eax, eax ; already disabled
ret
; ========================================================================
; void enable_irq(int irq);
; ========================================================================
; Enable an interrupt request line by clearing an 8259 bit.
; Equivalent code:
; if(irq < 8){
; out_byte(INT_M_CTLMASK, in_byte(INT_M_CTLMASK) & ~(1 << irq));
; }
; else{
; out_byte(INT_S_CTLMASK, in_byte(INT_S_CTLMASK) & ~(1 << irq));
; }
;
enable_irq:
mov ecx, [esp + 4] ; irq
pushf
cli
mov ah, ~1
rol ah, cl ; ah = ~(1 << (irq % 8))
cmp cl, 8
jae enable_8 ; enable irq >= 8 at the slave 8259
enable_0:
in al, INT_M_CTLMASK
and al, ah
out INT_M_CTLMASK, al ; clear bit at master 8259
popf
ret
enable_8:
in al, INT_S_CTLMASK
and al, ah
out INT_S_CTLMASK, al ; clear bit at slave 8259
popf
ret