⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 klib386.s.cpp

📁 一个简单的操作系统minix的核心代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
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 + -