📄 klib386.s
字号:
mov ecx, PR_ARGS_B+4+4(esp)
rep
insb
pop es
pop edi
ret
!*===========================================================================*
!* port_write *
!*===========================================================================*
! PUBLIC void port_write(port_t port, phys_bytes source, unsigned bytcount);
! Transfer data from memory to (hard disk controller) port.
PW_ARGS = 4 + 4 + 4 ! 4 + 4 + 4
! es edi eip port src len
.align 16
_port_write:
cld
push esi
push ds
mov ecx, FLAT_DS_SELECTOR
mov ds, cx
mov edx, PW_ARGS(esp) ! port to write to
mov esi, PW_ARGS+4(esp) ! source addr
mov ecx, PW_ARGS+4+4(esp) ! byte count
shr ecx, 1 ! word count
rep ! (hardware cannot handle dwords)
o16 outs ! write everything
pop ds
pop esi
ret
!*===========================================================================*
!* port_write_byte *
!*===========================================================================*
! PUBLIC void port_write_byte(port_t port, phys_bytes source,
! unsigned bytcount);
! Transfer data from memory to port.
PW_ARGS_B = 4 + 4 + 4 ! 4 + 4 + 4
! es edi eip port src len
_port_write_byte:
cld
push esi
push ds
mov ecx, FLAT_DS_SELECTOR
mov ds, cx
mov edx, PW_ARGS_B(esp)
mov esi, PW_ARGS_B+4(esp)
mov ecx, PW_ARGS_B+4+4(esp)
rep
outsb
pop ds
pop esi
ret
!*===========================================================================*
!* lock *
!*===========================================================================*
! PUBLIC void lock();
! Disable CPU interrupts.
.align 16
_lock:
cli ! disable interrupts
ret
!*===========================================================================*
!* unlock *
!*===========================================================================*
! PUBLIC void unlock();
! Enable CPU interrupts.
.align 16
_unlock:
sti
ret
!*==========================================================================*
!* enable_irq *
!*==========================================================================*/
! PUBLIC void enable_irq(unsigned irq)
! Enable an interrupt request line by clearing an 8259 bit.
! Equivalent code for irq < 8:
! out_byte(INT_CTLMASK, in_byte(INT_CTLMASK) & ~(1 << irq));
.align 16
_enable_irq:
mov ecx, 4(esp) ! irq
pushf
cli
movb ah, ~1
rolb ah, cl ! ah = ~(1 << (irq % 8))
cmpb cl, 8
jae enable_8 ! enable irq >= 8 at the slave 8259
enable_0:
inb INT_CTLMASK
andb al, ah
outb INT_CTLMASK ! clear bit at master 8259
popf
ret
.align 4
enable_8:
inb INT2_CTLMASK
andb al, ah
outb INT2_CTLMASK ! clear bit at slave 8259
popf
ret
!*==========================================================================*
!* disable_irq *
!*==========================================================================*/
! PUBLIC int disable_irq(unsigned irq)
! Disable an interrupt request line by setting an 8259 bit.
! Equivalent code for irq < 8:
! out_byte(INT_CTLMASK, in_byte(INT_CTLMASK) | (1 << irq));
! Returns true iff the interrupt was not already disabled.
.align 16
_disable_irq:
mov ecx, 4(esp) ! irq
pushf
cli
movb ah, 1
rolb ah, cl ! ah = (1 << (irq % 8))
cmpb cl, 8
jae disable_8 ! disable irq >= 8 at the slave 8259
disable_0:
inb INT_CTLMASK
testb al, ah
jnz dis_already ! already disabled?
orb al, ah
outb INT_CTLMASK ! set bit at master 8259
popf
mov eax, 1 ! disabled by this function
ret
disable_8:
inb INT2_CTLMASK
testb al, ah
jnz dis_already ! already disabled?
orb al, ah
outb INT2_CTLMASK ! set bit at slave 8259
popf
mov eax, 1 ! disabled by this function
ret
dis_already:
popf
xor eax, eax ! already disabled
ret
!*===========================================================================*
!* phys_copy *
!*===========================================================================*
! PUBLIC void phys_copy(phys_bytes source, phys_bytes destination,
! phys_bytes bytecount);
! Copy a block of physical memory.
PC_ARGS = 4 + 4 + 4 + 4 ! 4 + 4 + 4
! es edi esi eip src dst len
.align 16
_phys_copy:
cld
push esi
push edi
push es
mov eax, FLAT_DS_SELECTOR
mov es, ax
mov esi, PC_ARGS(esp)
mov edi, PC_ARGS+4(esp)
mov eax, PC_ARGS+4+4(esp)
cmp eax, 10 ! avoid align overhead for small counts
jb pc_small
mov ecx, esi ! align source, hope target is too
neg ecx
and ecx, 3 ! count for alignment
sub eax, ecx
rep
eseg movsb
mov ecx, eax
shr ecx, 2 ! count of dwords
rep
eseg movs
and eax, 3
pc_small:
xchg ecx, eax ! remainder
rep
eseg movsb
pop es
pop edi
pop esi
ret
!*===========================================================================*
!* mem_rdw *
!*===========================================================================*
! PUBLIC u16_t mem_rdw(U16_t segment, u16_t *offset);
! Load and return word at far pointer segment:offset.
.align 16
_mem_rdw:
mov cx, ds
mov ds, 4(esp) ! segment
mov eax, 4+4(esp) ! offset
movzx eax, (eax) ! word to return
mov ds, cx
ret
!*===========================================================================*
!* reset *
!*===========================================================================*
! PUBLIC void reset();
! Reset the system by loading IDT with offset 0 and interrupting.
_reset:
lidt (idt_zero)
int 3 ! anything goes, the 386 will not like it
.sect .data
idt_zero: .data4 0, 0
.sect .text
!*===========================================================================*
!* mem_vid_copy *
!*===========================================================================*
! PUBLIC void mem_vid_copy(u16 *src, unsigned dst, unsigned count);
!
! Copy count characters from kernel memory to video memory. Src, dst and
! count are character (word) based video offsets and counts. If src is null
! then screen memory is blanked by filling it with blank_color.
MVC_ARGS = 4 + 4 + 4 + 4 ! 4 + 4 + 4
! es edi esi eip src dst ct
_mem_vid_copy:
push esi
push edi
push es
mov esi, MVC_ARGS(esp) ! source
mov edi, MVC_ARGS+4(esp) ! destination
mov edx, MVC_ARGS+4+4(esp) ! count
mov es, (_vid_seg) ! destination is video segment
cld ! make sure direction is up
mvc_loop:
and edi, (_vid_mask) ! wrap address
mov ecx, edx ! one chunk to copy
mov eax, (_vid_size)
sub eax, edi
cmp ecx, eax
jbe 0f
mov ecx, eax ! ecx = min(ecx, vid_size - edi)
0: sub edx, ecx ! count -= ecx
shl edi, 1 ! byte address
test esi, esi ! source == 0 means blank the screen
jz mvc_blank
mvc_copy:
rep ! copy words to video memory
o16 movs
jmp mvc_test
mvc_blank:
mov eax, (_blank_color) ! ax = blanking character
rep
o16 stos ! copy blanks to video memory
!jmp mvc_test
mvc_test:
shr edi, 1 ! word addresses
test edx, edx
jnz mvc_loop
mvc_done:
pop es
pop edi
pop esi
ret
!*===========================================================================*
!* vid_vid_copy *
!*===========================================================================*
! PUBLIC void vid_vid_copy(unsigned src, unsigned dst, unsigned count);
!
! Copy count characters from video memory to video memory. Handle overlap.
! Used for scrolling, line or character insertion and deletion. Src, dst
! and count are character (word) based video offsets and counts.
VVC_ARGS = 4 + 4 + 4 + 4 ! 4 + 4 + 4
! es edi esi eip src dst ct
_vid_vid_copy:
push esi
push edi
push es
mov esi, VVC_ARGS(esp) ! source
mov edi, VVC_ARGS+4(esp) ! destination
mov edx, VVC_ARGS+4+4(esp) ! count
mov es, (_vid_seg) ! use video segment
cmp esi, edi ! copy up or down?
jb vvc_down
vvc_up:
cld ! direction is up
vvc_uploop:
and esi, (_vid_mask) ! wrap addresses
and edi, (_vid_mask)
mov ecx, edx ! one chunk to copy
mov eax, (_vid_size)
sub eax, esi
cmp ecx, eax
jbe 0f
mov ecx, eax ! ecx = min(ecx, vid_size - esi)
0: mov eax, (_vid_size)
sub eax, edi
cmp ecx, eax
jbe 0f
mov ecx, eax ! ecx = min(ecx, vid_size - edi)
0: sub edx, ecx ! count -= ecx
shl esi, 1
shl edi, 1 ! byte addresses
rep
eseg o16 movs ! copy video words
shr esi, 1
shr edi, 1 ! word addresses
test edx, edx
jnz vvc_uploop ! again?
jmp vvc_done
vvc_down:
std ! direction is down
lea esi, -1(esi)(edx*1) ! start copying at the top
lea edi, -1(edi)(edx*1)
vvc_downloop:
and esi, (_vid_mask) ! wrap addresses
and edi, (_vid_mask)
mov ecx, edx ! one chunk to copy
lea eax, 1(esi)
cmp ecx, eax
jbe 0f
mov ecx, eax ! ecx = min(ecx, esi + 1)
0: lea eax, 1(edi)
cmp ecx, eax
jbe 0f
mov ecx, eax ! ecx = min(ecx, edi + 1)
0: sub edx, ecx ! count -= ecx
shl esi, 1
shl edi, 1 ! byte addresses
rep
eseg o16 movs ! copy video words
shr esi, 1
shr edi, 1 ! word addresses
test edx, edx
jnz vvc_downloop ! again?
cld ! C compiler expect up
!jmp vvc_done
vvc_done:
pop es
pop edi
pop esi
ret
!*===========================================================================*
!* level0 *
!*===========================================================================*
! PUBLIC void level0(void (*func)(void))
! Call a function at permission level 0. This allows kernel tasks to do
! things that are only possible at the most privileged CPU level.
!
_level0:
mov eax, 4(esp)
mov (_level0_func), eax
int LEVEL0_VECTOR
ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -