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

📄 _pm.asm

📁 AT91RM9200的完整启动代码:包括loader, boot及U-boot三部分均已编译通过!欢迎下载使用!
💻 ASM
📖 第 1 页 / 共 2 页
字号:

ifndef flatmodel
_PM_savedDS     dw  _DATA           ; Saved value of DS
endif

;----------------------------------------------------------------------------
; void PM_saveDS(void)
;----------------------------------------------------------------------------
; Save the value of DS into a section of the code segment, so that we can
; quickly load this value at a later date in the PM_loadDS() routine from
; inside interrupt handlers etc. The method to do this is different
; depending on the DOS extender being used.
;----------------------------------------------------------------------------
cprocstartdll16 PM_saveDS

ifdef flatmodel
        mov     [_PM_savedDS],ds    ; Store away in data segment
endif
        ret

cprocend

;----------------------------------------------------------------------------
; void PM_loadDS(void)
;----------------------------------------------------------------------------
; Routine to load the DS register with the default value for the current
; DOS extender. Only the DS register is loaded, not the ES register, so
; if you wish to call C code, you will need to also load the ES register
; in 32 bit protected mode.
;----------------------------------------------------------------------------
cprocstartdll16 PM_loadDS

        mov     ds,[cs:_PM_savedDS] ; We can access the proper DS through CS
        ret

cprocend

ifdef flatmodel

;----------------------------------------------------------------------------
; ibool DPMI_allocateCallback(void (*pmcode)(), void *rmregs, long *RMCB)
;----------------------------------------------------------------------------
cprocstart  _DPMI_allocateCallback

        ARG     pmcode:CPTR, rmregs:DPTR, RMCB:DPTR

        enter_c
        push    ds
        push    es

        push    cs
        pop     ds
        mov     esi,[pmcode]    ; DS:ESI -> protected mode code to call
        mov     edi,[rmregs]    ; ES:EDI -> real mode register buffer
        mov     ax,303h         ; AX := allocate realmode callback function
        int     31h
        mov     eax,0           ; Return failure!
        jc      @@Fail

        mov     eax,[RMCB]
        shl     ecx,16
        mov     cx,dx
        mov     [es:eax],ecx    ; Return real mode address
        mov     eax,1           ; Return success!

@@Fail: pop     es
        pop     ds
        leave_c
        ret

cprocend

;----------------------------------------------------------------------------
; void DPMI_freeCallback(long RMCB)
;----------------------------------------------------------------------------
cprocstart  _DPMI_freeCallback

        ARG     RMCB:ULONG

        enter_c

        mov     cx,[WORD RMCB+2]
        mov     dx,[WORD RMCB]  ; CX:DX := real mode callback
        mov     ax,304h
        int     31h

        leave_c
        ret

cprocend

endif

; Macro to delay briefly to ensure that enough time has elapsed between
; successive I/O accesses so that the device being accessed can respond
; to both accesses even on a very fast PC.

ifdef   USE_NASM
%macro  DELAY 0
        jmp     short $+2
        jmp     short $+2
        jmp     short $+2
%endmacro
%macro  IODELAYN 1
%rep    %1
        DELAY
%endrep
%endmacro
else
macro   DELAY
        jmp     short $+2
        jmp     short $+2
        jmp     short $+2
endm
macro   IODELAYN    N
    rept    N
        DELAY
    endm
endm
endif

;----------------------------------------------------------------------------
; uchar _PM_readCMOS(int index)
;----------------------------------------------------------------------------
; Read the value of a specific CMOS register. We do this with both
; normal interrupts and NMI disabled.
;----------------------------------------------------------------------------
cprocstart  _PM_readCMOS

        ARG     index:UINT

        push    _bp
        mov     _bp,_sp
        pushfd
        mov     al,[BYTE index]
        or      al,80h              ; Add disable NMI flag
        cli
        out     70h,al
        IODELAYN 5
        in      al,71h
        mov     ah,al
        xor     al,al
        IODELAYN 5
        out     70h,al              ; Re-enable NMI
        sti
        mov     al,ah               ; Return value in AL
        popfd
        pop     _bp
        ret

cprocend

;----------------------------------------------------------------------------
; void _PM_writeCMOS(int index,uchar value)
;----------------------------------------------------------------------------
; Read the value of a specific CMOS register. We do this with both
; normal interrupts and NMI disabled.
;----------------------------------------------------------------------------
cprocstart  _PM_writeCMOS

        ARG     index:UINT, value:UCHAR

        push    _bp
        mov     _bp,_sp
        pushfd
        mov     al,[BYTE index]
        or      al,80h              ; Add disable NMI flag
        cli
        out     70h,al
        IODELAYN 5
        mov     al,[value]
        out     71h,al
        xor     al,al
        IODELAYN 5
        out     70h,al              ; Re-enable NMI
        sti
        popfd
        pop     _bp
        ret

cprocend

ifdef   flatmodel

;----------------------------------------------------------------------------
; int _PM_pagingEnabled(void)
;----------------------------------------------------------------------------
; Returns 1 if paging is enabled, 0 if not or -1 if not at ring 0
;----------------------------------------------------------------------------
cprocstart  _PM_pagingEnabled

        mov     eax,-1
ifdef   DOS4GW
        mov     cx,cs
        and     ecx,3
        jz      @@Ring0
        cmp     [UINT _PM_haveCauseWay],0
        jnz     @@Ring0
        jmp     @@Exit

@@Ring0:
        mov     eax,cr0                 ; Load CR0
        shr     eax,31                  ; Isolate paging enabled bit
endif
@@Exit: ret

cprocend

;----------------------------------------------------------------------------
; _PM_getPDB - Return the Page Table Directory Base address
;----------------------------------------------------------------------------
cprocstart  _PM_getPDB

ifdef   DOS4GW
        mov     ax,cs
        and     eax,3
        jz      @@Ring0
        cmp     [UINT _PM_haveCauseWay],0
        jnz     @@Ring0
endif

; Call VxD if running at ring 3 in a DOS box

        cmp     [WORD _PM_VXD_sel],0
        jz      @@Fail
        mov     eax,PMHELP_GETPDB
ifdef   USE_NASM
        call    far dword [_PM_VXD_off]
else
        call    [FCPTR _PM_VXD_off]
endif
        ret

@@Ring0:
ifdef   DOS4GW
        mov     eax,cr3
        and     eax,0FFFFF000h
        ret
endif
@@Fail: xor     eax,eax
        ret

cprocend

;----------------------------------------------------------------------------
; PM_flushTLB - Flush the Translation Lookaside buffer
;----------------------------------------------------------------------------
cprocstart  PM_flushTLB

        mov     ax,cs
        and     eax,3
        jz      @@Ring0
ifdef   DOS4GW
        cmp     [UINT _PM_haveCauseWay],0
        jnz     @@Ring0
endif

; Call VxD if running at ring 3 in a DOS box

        cmp     [WORD _PM_VXD_sel],0
        jz      @@Fail
        mov     eax,PMHELP_FLUSHTLB
ifdef   USE_NASM
        call    far dword [_PM_VXD_off]
else
        call    [FCPTR _PM_VXD_off]
endif
        ret

@@Ring0:
ifdef   DOS4GW
        wbinvd                  ; Flush the CPU cache
        mov     eax,cr3
        mov     cr3,eax         ; Flush the TLB
endif
@@Fail: ret

cprocend

endif

;----------------------------------------------------------------------------
; void _PM_VxDCall(VXD_regs far *r,uint off,uint sel);
;----------------------------------------------------------------------------
cprocstart  _PM_VxDCall

        ARG     r:DPTR, off:UINT, sel:UINT

        enter_c

; Load all registers from the registers structure

        mov     ebx,[r]
        mov     eax,[ebx+0]
        mov     ecx,[ebx+8]
        mov     edx,[ebx+12]
        mov     esi,[ebx+16]
        mov     edi,[ebx+20]
        mov     ebx,[ebx+4]         ; Trashes BX structure pointer!

; Call the VxD entry point (on stack)

ifdef   USE_NASM
        call far dword [off]
else
        call    [FCPTR off]
endif

; Save all registers back in the structure

        push    ebx                 ; Push EBX onto stack for later
        mov     ebx,[r]
        mov     [ebx+0],eax
        mov     [ebx+8],ecx
        mov     [ebx+12],edx
        mov     [ebx+16],esi
        mov     [ebx+20],edi
        pop     [DWORD ebx+4]       ; Save value of EBX from stack

        leave_c
        ret

cprocend

endcodeseg  _pmdos

        END                     ; End of module

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -