📄 klib386.s.cpp
字号:
08438
08439 _port_write_byte:
08440 cld
08441 push esi
08442 push ds
08443 mov ecx, FLAT_DS_SELECTOR
08444 mov ds, cx
08445 mov edx, PW_ARGS_B(esp)
08446 mov esi, PW_ARGS_B+4(esp)
08447 mov ecx, PW_ARGS_B+4+4(esp)
08448 rep
08449 outsb
08450 pop ds
08451 pop esi
08452 ret
08453
08454
08455 !*===========================================================================*
08456 !* lock *
08457 !*===========================================================================*
08458 ! PUBLIC void lock();
08459 ! Disable CPU interrupts.
08460
08461 .align 16
08462 _lock:
08463 cli ! disable interrupts
08464 ret
08465
08466
08467 !*===========================================================================*
08468 !* unlock *
08469 !*===========================================================================*
08470 ! PUBLIC void unlock();
08471 ! Enable CPU interrupts.
08472
08473 .align 16
08474 _unlock:
08475 sti
08476 ret
08477
08478
08479 !*==========================================================================*
08480 !* enable_irq *
08481 !*==========================================================================*/
08482 ! PUBLIC void enable_irq(unsigned irq)
08483 ! Enable an interrupt request line by clearing an 8259 bit.
08484 ! Equivalent code for irq < 8:
08485 ! out_byte(INT_CTLMASK, in_byte(INT_CTLMASK) & ~(1 << irq));
08486
08487 .align 16
08488 _enable_irq:
08489 mov ecx, 4(esp) ! irq
08490 pushf
08491 cli
08492 movb ah, ~1
08493 rolb ah, cl ! ah = ~(1 << (irq % 8))
08494 cmpb cl, 8
08495 jae enable_8 ! enable irq >= 8 at the slave 8259
08496 enable_0:
08497 inb INT_CTLMASK
08498 andb al, ah
08499 outb INT_CTLMASK ! clear bit at master 8259
08500 popf
08501 ret
08502 .align 4
08503 enable_8:
08504 inb INT2_CTLMASK
08505 andb al, ah
08506 outb INT2_CTLMASK ! clear bit at slave 8259
08507 popf
08508 ret
08509
08510
08511 !*==========================================================================*
08512 !* disable_irq *
08513 !*==========================================================================*/
08514 ! PUBLIC int disable_irq(unsigned irq)
08515 ! Disable an interrupt request line by setting an 8259 bit.
08516 ! Equivalent code for irq < 8:
08517 ! out_byte(INT_CTLMASK, in_byte(INT_CTLMASK) | (1 << irq));
08518 ! Returns true iff the interrupt was not already disabled.
08519
08520 .align 16
08521 _disable_irq:
08522 mov ecx, 4(esp) ! irq
08523 pushf
08524 cli
08525 movb ah, 1
08526 rolb ah, cl ! ah = (1 << (irq % 8))
08527 cmpb cl, 8
08528 jae disable_8 ! disable irq >= 8 at the slave 8259
08529 disable_0:
08530 inb INT_CTLMASK
08531 testb al, ah
08532 jnz dis_already ! already disabled?
08533 orb al, ah
08534 outb INT_CTLMASK ! set bit at master 8259
08535 popf
08536 mov eax, 1 ! disabled by this function
08537 ret
08538 disable_8:
08539 inb INT2_CTLMASK
08540 testb al, ah
08541 jnz dis_already ! already disabled?
08542 orb al, ah
08543 outb INT2_CTLMASK ! set bit at slave 8259
08544 popf
08545 mov eax, 1 ! disabled by this function
08546 ret
08547 dis_already:
08548 popf
08549 xor eax, eax ! already disabled
08550 ret
08551
08552
08553 !*===========================================================================*
08554 !* phys_copy *
08555 !*===========================================================================*
08556 ! PUBLIC void phys_copy(phys_bytes source, phys_bytes destination,
08557 ! phys_bytes bytecount);
08558 ! Copy a block of physical memory.
08559
08560 PC_ARGS = 4 + 4 + 4 + 4 ! 4 + 4 + 4
08561 ! es edi esi eip src dst len
08562
08563 .align 16
08564 _phys_copy:
08565 cld
08566 push esi
08567 push edi
08568 push es
08569
08570 mov eax, FLAT_DS_SELECTOR
08571 mov es, ax
08572
08573 mov esi, PC_ARGS(esp)
08574 mov edi, PC_ARGS+4(esp)
08575 mov eax, PC_ARGS+4+4(esp)
08576
08577 cmp eax, 10 ! avoid align overhead for small counts
08578 jb pc_small
08579 mov ecx, esi ! align source, hope target is too
08580 neg ecx
08581 and ecx, 3 ! count for alignment
08582 sub eax, ecx
08583 rep
08584 eseg movsb
08585 mov ecx, eax
08586 shr ecx, 2 ! count of dwords
08587 rep
08588 eseg movs
08589 and eax, 3
08590 pc_small:
08591 xchg ecx, eax ! remainder
08592 rep
08593 eseg movsb
08594
08595 pop es
08596 pop edi
08597 pop esi
08598 ret
08599
08600
08601 !*===========================================================================*
08602 !* mem_rdw *
08603 !*===========================================================================*
08604 ! PUBLIC u16_t mem_rdw(U16_t segment, u16_t *offset);
08605 ! Load and return word at far pointer segment:offset.
08606
08607 .align 16
08608 _mem_rdw:
08609 mov cx, ds
08610 mov ds, 4(esp) ! segment
08611 mov eax, 4+4(esp) ! offset
08612 movzx eax, (eax) ! word to return
08613 mov ds, cx
08614 ret
08615
08616
08617 !*===========================================================================*
08618 !* reset *
08619 !*===========================================================================*
08620 ! PUBLIC void reset();
08621 ! Reset the system by loading IDT with offset 0 and interrupting.
08622
08623 _reset:
08624 lidt (idt_zero)
08625 int 3 ! anything goes, the 386 will not like it
08626 .sect .data
08627 idt_zero: .data4 0, 0
08628 .sect .text
08629
08630
08631 !*===========================================================================*
08632 !* mem_vid_copy *
08633 !*===========================================================================*
08634 ! PUBLIC void mem_vid_copy(u16 *src, unsigned dst, unsigned count);
08635 !
08636 ! Copy count characters from kernel memory to video memory. Src, dst and
08637 ! count are character (word) based video offsets and counts. If src is null
08638 ! then screen memory is blanked by filling it with blank_color.
08639
08640 MVC_ARGS = 4 + 4 + 4 + 4 ! 4 + 4 + 4
08641 ! es edi esi eip src dst ct
08642
08643 _mem_vid_copy:
08644 push esi
08645 push edi
08646 push es
08647 mov esi, MVC_ARGS(esp) ! source
08648 mov edi, MVC_ARGS+4(esp) ! destination
08649 mov edx, MVC_ARGS+4+4(esp) ! count
08650 mov es, (_vid_seg) ! destination is video segment
08651 cld ! make sure direction is up
08652 mvc_loop:
08653 and edi, (_vid_mask) ! wrap address
08654 mov ecx, edx ! one chunk to copy
08655 mov eax, (_vid_size)
08656 sub eax, edi
08657 cmp ecx, eax
08658 jbe 0f
08659 mov ecx, eax ! ecx = min(ecx, vid_size - edi)
08660 0: sub edx, ecx ! count -= ecx
08661 shl edi, 1 ! byte address
08662 test esi, esi ! source == 0 means blank the screen
08663 jz mvc_blank
08664 mvc_copy:
08665 rep ! copy words to video memory
08666 o16 movs
08667 jmp mvc_test
08668 mvc_blank:
08669 mov eax, (_blank_color) ! ax = blanking character
08670 rep
08671 o16 stos ! copy blanks to video memory
08672 !jmp mvc_test
08673 mvc_test:
08674 shr edi, 1 ! word addresses
08675 test edx, edx
08676 jnz mvc_loop
08677 mvc_done:
08678 pop es
08679 pop edi
08680 pop esi
08681 ret
08682
08683
08684 !*===========================================================================*
08685 !* vid_vid_copy *
08686 !*===========================================================================*
08687 ! PUBLIC void vid_vid_copy(unsigned src, unsigned dst, unsigned count);
08688 !
08689 ! Copy count characters from video memory to video memory. Handle overlap.
08690 ! Used for scrolling, line or character insertion and deletion. Src, dst
08691 ! and count are character (word) based video offsets and counts.
08692
08693 VVC_ARGS = 4 + 4 + 4 + 4 ! 4 + 4 + 4
08694 ! es edi esi eip src dst ct
08695
08696 _vid_vid_copy:
08697 push esi
08698 push edi
08699 push es
08700 mov esi, VVC_ARGS(esp) ! source
08701 mov edi, VVC_ARGS+4(esp) ! destination
08702 mov edx, VVC_ARGS+4+4(esp) ! count
08703 mov es, (_vid_seg) ! use video segment
08704 cmp esi, edi ! copy up or down?
08705 jb vvc_down
08706 vvc_up:
08707 cld ! direction is up
08708 vvc_uploop:
08709 and esi, (_vid_mask) ! wrap addresses
08710 and edi, (_vid_mask)
08711 mov ecx, edx ! one chunk to copy
08712 mov eax, (_vid_size)
08713 sub eax, esi
08714 cmp ecx, eax
08715 jbe 0f
08716 mov ecx, eax ! ecx = min(ecx, vid_size - esi)
08717 0: mov eax, (_vid_size)
08718 sub eax, edi
08719 cmp ecx, eax
08720 jbe 0f
08721 mov ecx, eax ! ecx = min(ecx, vid_size - edi)
08722 0: sub edx, ecx ! count -= ecx
08723 shl esi, 1
08724 shl edi, 1 ! byte addresses
08725 rep
08726 eseg o16 movs ! copy video words
08727 shr esi, 1
08728 shr edi, 1 ! word addresses
08729 test edx, edx
08730 jnz vvc_uploop ! again?
08731 jmp vvc_done
08732 vvc_down:
08733 std ! direction is down
08734 lea esi, -1(esi)(edx*1) ! start copying at the top
08735 lea edi, -1(edi)(edx*1)
08736 vvc_downloop:
08737 and esi, (_vid_mask) ! wrap addresses
08738 and edi, (_vid_mask)
08739 mov ecx, edx ! one chunk to copy
08740 lea eax, 1(esi)
08741 cmp ecx, eax
08742 jbe 0f
08743 mov ecx, eax ! ecx = min(ecx, esi + 1)
08744 0: lea eax, 1(edi)
08745 cmp ecx, eax
08746 jbe 0f
08747 mov ecx, eax ! ecx = min(ecx, edi + 1)
08748 0: sub edx, ecx ! count -= ecx
08749 shl esi, 1
08750 shl edi, 1 ! byte addresses
08751 rep
08752 eseg o16 movs ! copy video words
08753 shr esi, 1
08754 shr edi, 1 ! word addresses
08755 test edx, edx
08756 jnz vvc_downloop ! again?
08757 cld ! C compiler expect up
08758 !jmp vvc_done
08759 vvc_done:
08760 pop es
08761 pop edi
08762 pop esi
08763 ret
08764
08765
08766 !*===========================================================================*
08767 !* level0 *
08768 !*===========================================================================*
08769 ! PUBLIC void level0(void (*func)(void))
08770 ! Call a function at permission level 0. This allows kernel tasks to do
08771 ! things that are only possible at the most privileged CPU level.
08772 !
08773 _level0:
08774 mov eax, 4(esp)
08775 mov (_level0_func), eax
08776 int LEVEL0_VECTOR
08777 ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -