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

📄 _pm.asm

📁 该源码是AT91rm9200的U-boot原代码。
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;****************************************************************************
;*
;*                  SciTech OS Portability Manager Library
;*
;*  ========================================================================
;*
;*    The contents of this file are subject to the SciTech MGL Public
;*    License Version 1.0 (the "License"); you may not use this file
;*    except in compliance with the License. You may obtain a copy of
;*    the License at http://www.scitechsoft.com/mgl-license.txt
;*
;*    Software distributed under the License is distributed on an
;*    "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
;*    implied. See the License for the specific language governing
;*    rights and limitations under the License.
;*
;*    The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
;*
;*    The Initial Developer of the Original Code is SciTech Software, Inc.
;*    All Rights Reserved.
;*
;*  ========================================================================
;*
;* Language:    80386 Assembler, TASM 4.0 or NASM
;* Environment: IBM PC Real mode and 16/32 bit protected mode
;*
;* Description: Low level assembly support for the PM library specific to
;*              MSDOS.
;*
;****************************************************************************

        IDEAL

include "scitech.mac"               ; Memory model macros

header      _pmdos                  ; Set up memory model

begdataseg  _pmdos

ifndef  flatmodel

struc   rmregs_s
ax          dw  ?
ax_high     dw  ?
bx          dw  ?
bx_high     dw  ?
cx          dw  ?
cx_high     dw  ?
dx          dw  ?
dx_high     dw  ?
si          dw  ?
si_high     dw  ?
di          dw  ?
di_high     dw  ?
cflag       dw  ?
cflag_high  dw  ?
ends    rmregs_s
RMREGS  = (rmregs_s PTR es:bx)

struc   rmsregs_s
es      dw  ?
cs      dw  ?
ss      dw  ?
ds      dw  ?
ends    rmsregs_s
RMSREGS = (rmsregs_s PTR es:bx)

endif   ; !flatmodel

ifdef flatmodel
    cextern _PM_savedDS,USHORT
    cextern _PM_VXD_off,UINT
    cextern _PM_VXD_sel,UINT
ifdef   DOS4GW
    cextern _PM_haveCauseWay,UINT
endif
endif
intel_id        db  "GenuineIntel"  ; Intel vendor ID

PMHELP_GETPDB       EQU 0026h
PMHELP_FLUSHTLB     EQU 0027h

enddataseg  _pmdos

P586

begcodeseg  _pmdos                  ; Start of code segment

ifndef  flatmodel

;----------------------------------------------------------------------------
; void PM_callRealMode(unsigned s,unsigned o, RMREGS *regs,
;   RMSREGS *sregs)
;----------------------------------------------------------------------------
; Calls a real mode procedure, loading the appropriate registers values
; from the passed in structures. Only the DS and ES register are loaded
; from the SREGS structure.
;----------------------------------------------------------------------------
cprocstart  PM_callRealMode

        ARG     s:WORD, o:WORD, regs:DWORD, sregs:DWORD

        LOCAL   addr:DWORD, bxVal:WORD, esVal:WORD, flags:WORD = LocalSize

        enter_c
        push    ds
        push    es

        mov     ax,[o]              ; Build the address to call in 'addr'
        mov     [WORD addr],ax
        mov     ax,[s]
        mov     [WORD addr+2],ax

        les     bx,[sregs]
        mov     ax,[RMSREGS.ds]
        mov     ds,ax               ; DS := passed in value
        mov     ax,[RMSREGS.es]
        mov     [esVal],ax
        les     bx,[regs]
        mov     ax,[RMREGS.bx]
        mov     [bxVal],ax
        mov     ax,[RMREGS.ax]      ; AX := passed in value
        mov     cx,[RMREGS.cx]      ; CX := passed in value
        mov     dx,[RMREGS.dx]      ; DX := passed in value
        mov     si,[RMREGS.si]      ; SI := passed in value
        mov     di,[RMREGS.di]      ; DI := passed in value
        push    bp
        push    [esVal]
        pop     es                  ; ES := passed in value
        mov     bx,[bxVal]          ; BX := passed in value

        call    [addr]              ; Call the specified routine

        pushf                       ; Save flags for later
        pop     [flags]

        pop     bp
        push    es
        pop     [esVal]
        push    bx
        pop     [bxVal]
        les     bx,[sregs]
        push    ds
        pop     [RMSREGS.ds]        ; Save value of DS
        push    [esVal]
        pop     [RMSREGS.es]        ; Save value of ES
        les     bx,[regs]
        mov     [RMREGS.ax],ax      ; Save value of AX
        mov     [RMREGS.cx],cx      ; Save value of CX
        mov     [RMREGS.dx],dx      ; Save value of DX
        mov     [RMREGS.si],si      ; Save value of SI
        mov     [RMREGS.di],di      ; Save value of DI
        mov     ax,[flags]          ; Return flags
        and     ax,1h               ; Isolate carry flag
        mov     [RMREGS.cflag],ax   ; Save carry flag status
        mov     ax,[bxVal]
        mov     [RMREGS.bx],ax      ; Save value of BX

        pop     es
        pop     ds
        leave_c
        ret

cprocend

endif

;----------------------------------------------------------------------------
; void PM_segread(PMSREGS *sregs)
;----------------------------------------------------------------------------
; Read the current value of all segment registers
;----------------------------------------------------------------------------
cprocstartdll16 PM_segread

        ARG     sregs:DPTR

        enter_c

        mov     ax,es
        _les    _si,[sregs]
        mov     [_ES _si],ax
        mov     [_ES _si+2],cs
        mov     [_ES _si+4],ss
        mov     [_ES _si+6],ds
        mov     [_ES _si+8],fs
        mov     [_ES _si+10],gs

        leave_c
        ret

cprocend

; Create a table of the 256 different interrupt calls that we can jump
; into

ifdef   USE_NASM

%assign intno 0

intTable:
%rep    256
        db      0CDh
        db      intno
%assign intno   intno + 1
        ret
        nop
%endrep

else

intno = 0

intTable:
        REPT    256
        db      0CDh
        db      intno
intno = intno + 1
        ret
        nop
        ENDM

endif

;----------------------------------------------------------------------------
; _PM_genInt    - Generate the appropriate interrupt
;----------------------------------------------------------------------------
cprocnear   _PM_genInt

        push    _ax                     ; Save _ax
        push    _bx                     ; Save _bx
ifdef flatmodel
        mov     ebx,[UINT esp+12]       ; EBX := interrupt number
else
        mov     bx,sp                   ; Make sure ESP is zeroed
        mov     bx,[UINT ss:bx+6]       ; BX := interrupt number
endif
        mov     _ax,offset intTable     ; Point to interrupt generation table
        shl     _bx,2                   ; _BX := index into table
        add     _ax,_bx                 ; _AX := pointer to interrupt code
ifdef flatmodel
        xchg    eax,[esp+4]             ; Restore eax, and set for int
else
        mov     bx,sp
        xchg    ax,[ss:bx+2]            ; Restore ax, and set for int
endif
        pop     _bx                     ; restore _bx
        ret

cprocend

;----------------------------------------------------------------------------
; int PM_int386x(int intno, PMREGS *in, PMREGS *out,PMSREGS *sregs)
;----------------------------------------------------------------------------
; Issues a software interrupt in protected mode. This routine has been
; written to allow user programs to load CS and DS with different values
; other than the default.
;----------------------------------------------------------------------------
cprocstartdll16 PM_int386x

        ARG     intno:UINT, inptr:DPTR, outptr:DPTR, sregs:DPTR

        LOCAL   flags:UINT, sv_ds:UINT, sv_esi:ULONG = LocalSize

        enter_c
        push    ds
        push    es                  ; Save segment registers
        push    fs
        push    gs

        _lds    _si,[sregs]         ; DS:_SI -> Load segment registers
        mov     es,[_si]
        mov     bx,[_si+6]
        mov     [sv_ds],_bx         ; Save value of user DS on stack
        mov     fs,[_si+8]
        mov     gs,[_si+10]

        _lds    _si,[inptr]         ; Load CPU registers
        mov     eax,[_si]
        mov     ebx,[_si+4]
        mov     ecx,[_si+8]
        mov     edx,[_si+12]
        mov     edi,[_si+20]
        mov     esi,[_si+16]

        push    ds                  ; Save value of DS
        push    _bp                 ; Some interrupts trash this!
        clc                         ; Generate the interrupt
        push    [UINT intno]
        mov     ds,[WORD sv_ds]     ; Set value of user's DS selector
        call    _PM_genInt
        pop     _bp                 ; Pop intno from stack (flags unchanged)
        pop     _bp                 ; Restore value of stack frame pointer
        pop     ds                  ; Restore value of DS

        pushf                       ; Save flags for later
        pop     [UINT flags]
        push    esi                 ; Save ESI for later
        pop     [DWORD sv_esi]
        push    ds                  ; Save DS for later
        pop     [UINT sv_ds]

        _lds    _si,[outptr]        ; Save CPU registers
        mov     [_si],eax
        mov     [_si+4],ebx
        mov     [_si+8],ecx
        mov     [_si+12],edx
        push    [DWORD sv_esi]
        pop     [DWORD _si+16]
        mov     [_si+20],edi

        mov     _bx,[flags]         ; Return flags
        and     ebx,1h              ; Isolate carry flag
        mov     [_si+24],ebx        ; Save carry flag status

        _lds    _si,[sregs]         ; Save segment registers
        mov     [_si],es
        mov     _bx,[sv_ds]
        mov     [_si+6],bx          ; Get returned DS from stack
        mov     [_si+8],fs
        mov     [_si+10],gs

        pop     gs                  ; Restore segment registers
        pop     fs
        pop     es
        pop     ds
        leave_c
        ret

cprocend

⌨️ 快捷键说明

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