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

📄 memfunc.asm

📁 访问32位PCI总线MEMORY的例程
💻 ASM
📖 第 1 页 / 共 4 页
字号:
@@vcpiLastFill:
	PUSH	EDI
	SHL	ECX, 2
	CALL	GET_DEST_SEL
	SHR	ECX, 2
	CLD
	REP	STOS DWORD PTR ES:[EDI]
	POP	EDI
	POP	ECX
	ADD	EDI, 40000H
	SUB	ECX, 40000H/4
	JA	@@vcpiLoopFill

@@success:
	CALL	LEAVE_PROTECT
	POP	AX
	POP	BX
	JMP	@@exit

@@error:
	POP	AX
	POP	BX
	XOR	AX, AX
	XOR	BX, BX
@@exit:
	RET

fillHimemLong_ ENDP

;********************************
;CPU動作モードチェック
;
;    入力    なし
;    出力    AX		0)Real Mode
;			1)VCPI Mode
;			2)DPMI Mode
;			-1)判定できず
;    破壊    なし
;********************************
getCpuMode_	PROC C NEAR PUBLIC USES BX CX DX DS ES

    ASSUME  DS:NOTHING,ES:NOTHING

;CPU動作モード判定
;------------------------
         SMSW    AX
         TEST    AL,1
         JZ      @@RealMode

;DPMIをサポートするかチェック
;-----------------------
         MOV     AX,1687H           ;DPMI Check
         INT     2FH                ;
    ASSUME  ES:NOTHING
         TEST    AX,AX
         JZ      @@DPMIMode

;VCPIをサポートするかチェック
;-----------------------
	;EMM386が存在するか?
	;-----------------------
        PUSH    DS
        XOR     AX,AX
        MOV     DS,AX
        MOV     DS,WORD PTR DS:[67H*4+2]
        MOV     AX,WORD PTR DS:[0AH]
        MOV     CL,BYTE PTR DS:[0AH+2]
        POP     DS
        MOV     DX,ERROR_EMM
        CMP     AX,'ME'
        JNE     @@CantRun
        CMP     CL,'M'
        JNE     @@CantRun

        MOV     AH,40H
        INT     67H
        MOV     DX,ERROR_EMM
        OR      AH,AH
        JNZ     @@CantRun

;@@@ File Handle方式は、EMSメモリ無しでEMM386を組み込んだ時、通用しない
;        MOV     DX,OFFSET CGROUP:EMM_NAME
;        MOV     AX,3D00H
;        INT     21H
;        JC      @@CantRun	;ファイルがない
;        MOV     BX,AX
;        MOV     AX,4400H
;        INT     21H
;        MOV     AX,DX
;        MOV     DX,ERROR_EMM
;        JC      @@CantRun
;        TEST    AX,80H
;        JZ      @@CantRun	;デバイスではない(ファイルである)
;;@@@ いらないかな?
;;        MOV     AX,4407H
;;        INT     21H
;;        JC      @@CantRun
;;        CMP     AL,0FFH
;;        JNE     @@CantRun	; BUSY状態
;;@@@
;        MOV     AH,3EH
;        INT     21H
;@@@

;VCPIが存在するか?
;-------------------------
        MOV     AX,0DE00H
        INT     67H
        MOV     DX,ERROR_DRV
        TEST    AH,AH
        JZ      @@VCPIMode
@@CantRun:
        MOV     AX, -1
	JMP	@@Exit

@@RealMode:
	MOV	AX, 0
	JMP	@@Exit
@@VCPIMode:
	MOV	AX, 1
	JMP	@@Exit
@@DPMIMode:
	MOV	AX, 2
@@Exit:
    ASSUME  DS:NOTHING,ES:NOTHING
        RET

getCpuMode_	ENDP

;**************************
;リアルモードに戻る
;
;       入力    なし
;       出力    なし
;       破壊    EAX,EDX
;**************************
LEAVE_PROTECT PROC C NEAR USES EAX EBX EDX

    ASSUME  DS:NOTHING,ES:NOTHING

        TEST    CS:[FLAG],@DPMI
        JNZ     @@DPMI

        TEST    CS:[FLAG],@VCPI
        JNZ     @@VCPI

        MOV     AX,DSEL_CODE
        MOV     DS,AX
    ASSUME  DS:NOTHING
        MOV     ES,AX
    ASSUME  ES:NOTHING
        MOV     EAX,CR0
        AND     AL,NOT 1
        MOV     CR0,EAX
        MOV     CS:[DSEL_CODE],CS
        STI
@@DPMI:
        MOV     AX,CS:[DSEL_CODE]
        MOV     ES,AX
    ASSUME  ES:CGROUP
        MOV     DS,AX
    ASSUME  DS:CGROUP
        RET

@@VCPI:
        MOV     EDX,ESP
        MOVZX   EAX,CS:[CODE_SEG]
        MOVZX   EBX,CS:[STACK_SEG]
        PUSH    EAX    ;GS
        PUSH    EAX    ;FS
        PUSH    EAX    ;DS
        PUSH    EAX    ;ES
        PUSH    EBX    ;SS
        PUSH    EDX    ;ESP
        PUSHFD         ;EFLAGS
        PUSH    EAX    ;CS
        MOV     AX,OFFSET CGROUP:@@RET_V86
        PUSH    EAX    ;EIP
        MOV     AX,DSEL_FULL
        MOV     DS,AX
    ASSUME  DS:NOTHING
        MOV     AX,0DE0CH
        CALL    FWORD PTR CS:[VCPI_ENTRY]
        JMP     $
@@RET_V86:
    ASSUME  DS:CGROUP,ES:CGROUP
        MOV     [DSEL_CODE],CS
        RET

LEAVE_PROTECT ENDP
;**************************
;プロテクトモードに移行
;
;       入力    なし
;       出力    CY	0)Success
;			1)Failure
;       破壊    なし
;**************************
ENTER_PROTECT PROC C NEAR USES EAX EBX ECX EDX ESI

	PUSH	CS
	PUSH	CS
	POP	DS
	POP	ES

    ASSUME  DS:CGROUP,ES:CGROUP

        TEST    [FLAG],@DPMI
        JNZ     @@DPMI

        CLI
        MOV     [DSEL_CODE],DSEL
        TEST    [FLAG],@VCPI
        JNZ     @@VCPI

        LGDT    [GDTR_PARA]
        MOV     EAX,CR0
        OR      AL,1	;CY=0
        MOV     CR0,EAX
@@DPMI:			;DPMI NOT SUPPORT
        RET

@@VCPI:
        MOV     [STACK_BAK],SP
	MOV	[STACK_SEG],SS
        XOR     EAX,EAX
        XOR     ESI,ESI
        MOV     AX,CS
        SHL     EAX,4
        MOV     SI,OFFSET CGROUP:VCPI_PROTECT_TBL
        ADD     ESI,EAX
        MOV     AX,0DE0CH
        INT     67H
        MOV     DX,ERROR_VCPI
	STC
	RET
VCPI_ENTER_PROTECT:
	MOV	AX,DSEL
	MOV	DS,AX
    ASSUME  DS:CGROUP
	MOV	ES,AX
    ASSUME  ES:CGROUP
	MOV	FS,AX
    ASSUME  FS:CGROUP
	MOV	GS,AX
    ASSUME  GS:CGROUP
	MOV	AX,SSEL
	MOV	SS,AX
    ASSUME  SS:CGROUP
        MOVZX   ESP,[STACK_BAK]

        MOV     [DSEG_SORC].BASE,0
        MOV     [DSEG_SORC].HIBASE,40H
        MOV     [DSEG_SORC].MSBASE,0

        MOV     [DSEG_DEST].BASE,0
        MOV     [DSEG_DEST].HIBASE,48H
        MOV     [DSEG_DEST].MSBASE,0
	CLC
        RET

ENTER_PROTECT ENDP

;**************************
;DEST_SELのBASE AddressとLimitを変更
;
;       入力    ESI     Base address
;               ECX     Limit
;       出力    DS:ESI  先頭アドレス
;               CY      0)セグメント取得成功
;                       1)セグメント取得失敗
;       破壊    なし
;**************************
GET_SORC_SEL PROC NEAR

    ASSUME  DS:NOTHING,ES:NOTHING

        PUSH    CS:[DSEL_CODE]
        POP     DS
    ASSUME  DS:CGROUP

        TEST    [FLAG],@DPMI
        JNZ     @@DPMI

        TEST    [FLAG],@VCPI
        JNZ     @@VCPI

        PUSH    EAX
        MOV     EAX,ESI
        MOV     [DSEG_SORC].BASE,AX
        SHR     EAX,16
        MOV     [DSEG_SORC].HIBASE,AL
        MOV     [DSEG_SORC].MSBASE,AH

        XOR     ESI,ESI
        MOV     DS,[SORC_SEL]
    ASSUME  DS:NOTHING
        POP     EAX
        RET

;-----------------------
; VCPIでは、256KB分だけ割り当てる
;-----------------------
@@VCPI:

    ASSUME  DS:CGROUP

        PUSH    EAX
        PUSH    BX
        MOV     AX,DSEL_PAGE
        MOV     DS,AX
    ASSUME  DS:NOTHING
        MOV     EAX,ESI
        AND     AX,0F000H
        OR      AL,7
        MOV     BX, 2000H
        .REPEAT
            MOV     DS:[BX],EAX
            ADD     EAX,1000H
            ADD     BX,4
        .UNTIL BX>(2000H+4*(64+1)-1)

        MOV     DS,CS:[SORC_SEL]
    ASSUME  DS:NOTHING
        AND     ESI,0FFFH
	MOV	EAX, DWORD PTR CS:[VCPI_PROTECT_TBL]
	MOV	CR3, EAX	;Flush TLB cache
        POP     BX
        POP     EAX
        RET

@@DPMI:

    ASSUME  DS:CGROUP

        PUSH    AX
        PUSH    BX
        PUSH    ECX
        PUSH    DX
        PUSH    DI

        ;指定物理メモリを割り当てる
        ;-----------------
        PUSH    ECX
        PUSH    ESI
        POP     CX
        POP     BX
        POP     DI
        POP     SI
        MOV     AX,800H
        INT     31H
        .IF !CARRY?
            ;指定物理メモリを割り当てたアドレスをセグメントに設定する
            ;---------------------
            MOV     DX,CX
            MOV     CX,BX
            MOV     BX,[SORC_SEL]
            MOV     AX,7
            INT     31H
            .IF CARRY?
                PUSH    ESI
                POP     CX
                POP     BX
                MOV     AX,801H
                INT     31H
                STC
            .ELSE
                MOV     DS,BX
            ASSUME  DS:NOTHING
                XOR     ESI,ESI
            .ENDIF
        .ENDIF
        POP     DI
        POP     DX
        POP     ECX
        POP     BX
        POP     AX
        RET

GET_SORC_SEL ENDP

;**************************
;DEST_SELのBASE AddressとLimitを変更
;
;       入力    EDI     Base address
;               ECX     Limit size
;       出力    ES:EDI  先頭アドレス
;               CY      0)セグメント取得成功
;                       1)セグメント取得失敗
;       破壊    なし
;**************************
GET_DEST_SEL PROC NEAR

    ASSUME  DS:NOTHING,ES:NOTHING

        PUSH    CS:[DSEL_CODE]
        POP     ES
    ASSUME  ES:CGROUP

        TEST    ES:[FLAG],@DPMI
        JNZ     @@DPMI

        TEST    ES:[FLAG],@VCPI
        JNZ     @@VCPI

        PUSH    EAX
        MOV     EAX,EDI
        MOV     ES:[DSEG_DEST].BASE,AX
        SHR     EAX,16
        MOV     ES:[DSEG_DEST].HIBASE,AL
        MOV     ES:[DSEG_DEST].MSBASE,AH

        XOR     EDI,EDI
        MOV     ES,ES:[DEST_SEL]
    ASSUME  ES:NOTHING
        POP     EAX
        RET

;-----------------------
; VCPIでは、256KB分だけ割り当てる
;-----------------------
@@VCPI:

    ASSUME  ES:CGROUP

        PUSH    EAX
        PUSH    BX
        MOV     AX,DSEL_PAGE
        MOV     ES,AX
    ASSUME  DS:NOTHING
        MOV     EAX,EDI
        AND     AX,0F000H
        OR      AL,7
        MOV     BX, 2200H
        .REPEAT
            MOV     ES:[BX],EAX
            ADD     EAX,1000H
            ADD     BX,4
        .UNTIL BX>(2200H+4*(64+1)-1)

        MOV     ES,CS:[DEST_SEL]
    ASSUME  ES:NOTHING
        AND     EDI,0FFFH
	MOV	EAX, DWORD PTR CS:[VCPI_PROTECT_TBL]
	MOV	CR3, EAX	;Flush TLB cache
        POP     BX
        POP     EAX
        RET

@@DPMI:

    ASSUME  ES:CGROUP

        PUSH    AX
	PUSH	BX
        PUSH    ECX
	PUSH	DX
        PUSH    SI

        ;指定物理メモリを割り当てる
        ;-----------------
        PUSH    ECX
        PUSH    EDI
        POP     CX
        POP     BX
        POP     DI
        POP     SI
        MOV     AX,800H
        INT     31H
        .IF !CARRY?
            ;指定物理メモリを割り当てたアドレスをセグメントに設定する
            ;---------------------
            MOV     DX,CX
            MOV     CX,BX
            MOV     BX,[DEST_SEL]
            MOV     AX,7
            INT     31H
            .IF CARRY?
                PUSH    ESI
                POP     CX
                POP     BX
                MOV     AX,801H
                INT     31H
                STC
            .ELSE
                MOV     ES,BX
            ASSUME  ES:NOTHING
                XOR     EDI,EDI
            .ENDIF
        .ENDIF
        POP     SI
	POP	DX
        POP     ECX
	POP	BX
        POP     AX
        RET

GET_DEST_SEL ENDP

;**************************
;SORC_SELに割り当てたセレクタを開放
;
;       入力    なし
;       出力    なし
;       破壊    なし
;**************************
FREE_SORC_SEL PROC NEAR

    ASSUME  DS:NOTHING,ES:NOTHING

        TEST    CS:[FLAG],@DPMI
        JZ      @@END

;@@@ Win95のDPMIは Ver0.90でも 物理メモリ開放ファンクションが存在するらしいのでバージョンチェックは削除 @@@
;        CMP     CS:[DPMI_VER],100H
;        JB      @@END
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ;DPMI V1.00以上の場合は、割り当てた物理メモリを開放
   ;------------------------
        PUSH    AX
        PUSH    BX
        PUSH    CX
        PUSH    DX
        MOV     BX,CS:[SORC_SEL]
        MOV     AX,6
        INT     31H
        .IF !CARRY?
            MOV     BX,CX
            MOV     CX,DX
            MOV     AX,0801H
            INT     31H
        .ENDIF
        POP     DX
        POP     CX
        POP     BX
        POP     AX
@@END:
        RET

FREE_SORC_SEL ENDP

;**************************
;DEST_SELに割り当てたセレクタを開放
;
;       入力    なし
;       出力    なし
;       破壊    なし
;**************************
FREE_DEST_SEL PROC NEAR

    ASSUME  DS:NOTHING,ES:NOTHING

        TEST    CS:[FLAG],@DPMI
        JZ      @@END

;@@@ Win95のDPMIは Ver0.90でも 物理メモリ開放ファンクションが存在するらしいのでバージョンチェックは削除 @@@
;        CMP     CS:[DPMI_VER],100H
;        JB      @@END
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ;DPMI V1.00以上の場合は、割り当てた物理メモリを開放
   ;------------------------
        PUSH    AX
        PUSH    BX
        PUSH    CX
        PUSH    DX
        MOV     BX,CS:[DEST_SEL]
        MOV     AX,6
        INT     31H
        .IF !CARRY?
            MOV     BX,CX

⌨️ 快捷键说明

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