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

📄 memfunc.asm

📁 访问32位PCI总线MEMORY的例程
💻 ASM
📖 第 1 页 / 共 4 页
字号:
            MOV     CX,DX
            MOV     AX,0801H
            INT     31H
        .ENDIF
        POP     DX
        POP     CX
        POP     BX
        POP     AX
@@END:
        RET

FREE_DEST_SEL ENDP

;********************************
;CPU動作モードチェック
;
;    入力    なし
;    出力    CY     1)動作できない
;    破壊    なし
;********************************
CHK_CPU_MODE	PROC C NEAR USES CX DX DS

	PUSH	CS
	PUSH	CS
	POP	DS
	POP	ES

    ASSUME  DS:CGROUP,ES:CGROUP

         MOV     [DSEL_CODE],CS

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

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

;         MOV     WORD PTR [DPMI_ENTRY],DI
;         MOV     WORD PTR [DPMI_ENTRY+2],ES
;         MOV     [DPMI_VER],DX
;         MOV     [ADRS_FLG],BX
;         MOV     [CPU_TYPE],CL
;         MOV     [PRVDT_SZ],SI
;
;         MOV     DX,ERROR_CPU
;         CMP     CL,3
;         JB      @@CANT_RUN         ;CPUが80386より前のものである
;
;         PUSH    DS
;         POP     ES
;    ASSUME  ES:CGROUP
;         TEST    SI,SI
;         JZ      @@NO_PRVDT
;         MOV     AH,48H             ;Memory Allocate
;         MOV     BX,SI              ;  for DPMI Private Data Segment
;         INT     21H                ;
;         MOV     DX,ERROR_MEMORY
;         JC      @@CANT_RUN         ; Jump if Memory can't allocate
;@@NO_PRVDT:
;         MOV     [PRVDT_SEG],AX       ;  AX=MCB
;         MOV     ES,[PRVDT_SEG]
;    ASSUME  ES:NOTHING
;         MOV     AX,0000H
;         CALL    [DPMI_ENTRY]
;         MOV     DX,ERROR_DPMI_PROT
;         JC      @@DPMI_CANT_RUN
;
;         PUSH    DS
;         POP     ES
;    ASSUME  ES:CGROUP
;         MOV     [DSEL_CODE],DS
;
;         MOV     AX,0400H
;         INT     31H
;         MOV     [DPMI_VER],AX
;         MOV     [MPIC_VECT_NO],DH
;         MOV     [SPIC_VECT_NO],DL
;
;         ; Allocate 3 descriptors
;         ;-------------------
;         MOV     AX,0
;         MOV     CX,3
;         INT     31H
;         JC      @@DPMI_FUNC_ERROR
;         MOV     BX,AX
;         MOV     [DATA_SEL],AX       ; Save base selector
;
;         ;Change DATA_SEL limit to max.
;         ;----------------------
;         PUSH    BX
;         MOV     CX,0FFFFH
;         MOV     DX,0FFFFH
;         MOV     AX,8
;         INT     31H
;         POP     BX
;         JC      @@DPMI_FUNC_ERROR
;
;         ;Change DATA_SEL access rigit.
;         ;----------------------
;         MOV     AX,9
;         MOV     CX,8093H
;         INT     31H
;         JC      @@DPMI_FUNC_ERROR
;
;         ;Get next selector value for SORC_SEL and DEST_SEL.
;         ;----------------------
;         MOV     AX,3
;         INT     31H
;         JC      @@CANT_RUN
;         MOV     BX,[DATA_SEL]
;         ADD     BX,AX
;         MOV     [SORC_SEL],BX
;         ADD     BX,AX
;         MOV     [DEST_SEL],BX
;
;         ;Tempolary change SORC_SEL limit to max.
;         ;----------------------
;         MOV     BX, [SORC_SEL]
;         MOV     AX,8
;         MOV     CX,-1
;         MOV     DX,-1
;         INT     31H
;         JC      @@DPMI_FUNC_ERROR
;
;         ;Change SORC_SEL access rigit.
;         ;----------------------
;         MOV     AX,9
;         MOV     CX,8093H
;         INT     31H
;         JC      @@DPMI_FUNC_ERROR
;
;         ;Tempolary change DEST_SEL limit to max.
;         ;----------------------
;         MOV     BX, [DEST_SEL]
;         MOV     AX,8
;         MOV     CX,-1
;         MOV     DX,-1
;         INT     31H
;         JC      @@DPMI_FUNC_ERROR
;
;         ;Change DEST_SEL access rigit.
;         ;----------------------
;         MOV     AX,9
;         MOV     CX,8093H
;         INT     31H
;         JC      @@DPMI_FUNC_ERROR
         PUSH    DS
         POP     ES
    ASSUME  ES:CGROUP
        MOV     DX,ERROR_DPMI_PROT
        OR      [FLAG],@DPMI
        STC
        RET

;VCPIをサポートするかチェック
;-----------------------
@@CHK_VCPI:

    ASSUME  ES:NOTHING
        PUSH    CS
        POP     ES
    ASSUME  ES:CGROUP

;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     @@CANT_RUN
        CMP     CL,'M'
        JNE     @@CANT_RUN

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

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

;VCPIが存在するか?
;-------------------------
        MOV     AX,0DE00H
        INT     67H
        MOV     DX,ERROR_DRV
        TEST    AH,AH
        JNZ     @@CANT_RUN      ;VCPI無し

    ;VCPI情報取得
    ;-------------------------
        MOV     AX,CS
        MOVZX   DX,AH
        SHL     AX,4
        SHR     DL,4
        ADD     AX,OFFSET CGROUP:PAGE_TBL_BUF+0FFFH
        ADC     DL,0
        AND     AX,0F000H
        MOV     WORD PTR [VCPI_PROTECT_TBL],AX
        MOV     BYTE PTR [VCPI_PROTECT_TBL+2],DL
        MOV     [DSEG_PAGE].BASE,AX
        MOV     [DSEG_PAGE].HIBASE,DL
        MOV     [DSEG_SORC].LIMIT,0FFFFH
        MOV     [DSEG_SORC].BASE,0
        MOV     [DSEG_SORC].HIBASE,40H
        MOV     [DSEG_DEST].LIMIT,0FFFFH
        MOV     [DSEG_DEST].BASE,0
        MOV     [DSEG_DEST].HIBASE,48H
        ;ページディレクトリエントリ作成
        ;------------------------
        PUSH    DX
        PUSH    AX
        POP     EAX
        MOV     EDX,EAX
        SHR     EDX,4
        MOV     ES,DX
    ASSUME  ES:NOTHING
        ADD     EAX,1007H

        MOV     DWORD PTR ES:[0],EAX
        MOV     BX,4
        ADD     EAX,1000H
        .REPEAT
            MOV     DWORD PTR ES:[BX],EAX
            ADD     BX,4
        .UNTIL !(BX & 0FFFH)

        ;ページテーブルエントリ作成
        ;------------------------
        MOV     EAX,00100007H
        MOV     BX,1000H
        .REPEAT
            MOV     DWORD PTR ES:[BX],EAX
            ADD     BX,4
        .UNTIL BX >=3000H

        MOV     DI,1000H
        MOV     SI,OFFSET CGROUP:VCPI_DESC
        MOV     AX,0DE01H
        INT     67H
        PUSH    CS
        POP     ES
    ASSUME  ES:CGROUP
        MOV     DX,ERROR_VCPI
        TEST    AH,AH
;        JNZ     @@CANT_RUN      ;取得できず

        MOV     [CODE_SEG],CS
        MOV     [VCPI_ENTRY],EBX
        OR      [FLAG],@VCPI

@@REAL_MODE:

    ASSUME  DS:CGROUP,ES:CGROUP
        CALL    MAKE_GDT
        CLC
        RET

@@DPMI_FUNC_ERROR:
        MOV     DX,ERROR_DPMI

@@DPMI_CANT_RUN:
	;Free Allocated Memory for DPMI
	;------------------
	MOV     ES,[PRVDT_SEG]
        MOV     AH,49H             ;Free Memory
        INT     21H

@@CANT_RUN:
        STC
        RET



CHK_CPU_MODE	ENDP



;********************************
;GDT作成
;********************************
MAKE_GDT	PROC	NEAR

    ASSUME  DS:CGROUP,ES:CGROUP

;GDTテーブルの初期化
;------------------------
	;Stack Segment初期化
	;--------------------------
        MOV	AX,SS
	MOV	DL,AH
	SHL	AX,4
	SHR	DL,4
        MOV     [SSEG].BASE,AX
        MOV     [SSEG].HIBASE,DL

        ;Code Segmen初期化
        ;--------------------------
        MOV	AX,CS
        MOV	DL,AH
        SHL	AX,4
        SHR	DL,4
        ADD     WORD PTR [GDTR_PARA+2],AX
        ADC     BYTE PTR [GDTR_PARA+4],DL
        MOV     [CSEG16].BASE,AX
        MOV     [CSEG16].HIBASE,DL
        MOV     [DSEG].BASE,AX
        MOV     [DSEG].HIBASE,DL

;VCPI用
;----------------------
        ADD     [TSS_DESC].BASE,AX
        ADC     [TSS_DESC].HIBASE,DL

        ;VCPI プロテクトモード移行用テーブル初期化
        ;-------------------------
        ADD     WORD PTR [VCPI_PROTECT_TBL+4],AX
        ADC     BYTE PTR [VCPI_PROTECT_TBL+6],DL
        ADD     WORD PTR [VCPI_PROTECT_TBL+8],AX
        ADC     BYTE PTR [VCPI_PROTECT_TBL+10],DL

        RET

MAKE_GDT	ENDP

;********************************
;A20をOnにする
;********************************
A20_ON PROC NEAR

    ASSUME  DS:CGROUP,ES:CGROUP

        TEST    [FLAG],@DPMI
        JNZ     @@END

        PUSH    AX
        PUSH    BX
        PUSH    DS
        PUSH    ES

;A20が既にOnになっている場合は、何もしない
;---------------------
        XOR     AX,AX
        MOV     ES,AX
    ASSUME  ES:NOTHING
        DEC     AX
        MOV     DS,AX
    ASSUME  DS:NOTHING

        CLI
        MOV     AX,ES:[0]
        MOV     BX,DS:[10H]
        NOT     AX
        MOV     DS:[10H],AX
        CMP     AX,ES:[0]
        MOV     DS:[10H],BX
        STI
        JNE     @@A20_ON_END

        MOV     AX,4300H
        INT     2FH
        CMP     AH,80H
        JNE     @@A20_DIRECT

        XOR     BX,BX
        MOV     ES,BX
    ASSUME  ES:NOTHING
        MOV     AX,4310H
        INT     2FH
    ASSUME  ES:NOTHING
        MOV     AX,ES
        OR      AX,BX
        JZ      @@A20_DIRECT

;HIMEM.SYSを使用
;----------------------
@@USE_HIMEM:
        PUSH    CS
        PUSH    OFFSET CGROUP:@@RET_HIMEM
        PUSH    ES
        PUSH    BX
        MOV     AH,3
        RETF
@@RET_HIMEM:
        TEST    AX,AX
        JZ      @@A20_DIRECT

@@A20_ON_END:
        POP     ES
    ASSUME  ES:CGROUP
        POP     DS
    ASSUME  DS:CGROUP
        POP     BX
        POP     AX

@@END:
        RET


;直接制御
;------------------------
@@A20_DIRECT:
        CLI

@@WAIT_IBF1:
        IN      AL,64H
        TEST    AL,2
        JNZ     @@WAIT_IBF1
        MOV     AL,0D1H
        OUT     64H,AL

@@WAIT_IBF2:
        IN      AL,64H
        TEST    AL,2
        JNZ     @@WAIT_IBF2
        MOV     AL,0DFH
        OUT     60H,AL

;KBCが本当にコマンド処理終了するまで待つ
;---------------------------
    ;ダミーのコマンドを送信
    ;-------------------
@@WAIT_IBF3:
        IN      AL,64H
        TEST    AL,2
        JNZ     @@WAIT_IBF3
        MOV     AL,0FFH
        OUT     64H,AL
    ;ダミーのコマンドの処理が終わるのを待つ
    ;-------------------
@@WAIT_IBF4:
        IN      AL,64H
        TEST    AL,2
        JNZ     @@WAIT_IBF4

        STI
        POP     ES
    ASSUME  ES:CGROUP
        POP     DS
    ASSUME  DS:CGROUP
        POP     BX
        POP     AX
        RET

A20_ON ENDP


VCPI_PROTECT_TBL LABEL BYTE

        DW      CGROUP:PAGE_TBL_BUF,0   ;CR3
        DW      CGROUP:GDTR_PARA,0
        DW      CGROUP:IDTR_PARA,0
        DW      0                ;LDTR
        DW      TSS_SEL       ;TR
        DW      CGROUP:VCPI_ENTER_PROTECT,0,CSEL16

IDTR_PARA LABEL FWORD
        DW      3FFh
        DW      0,0

GDTR_PARA LABEL	FWORD
	DW	GDT_END-GDT-1	; LIMIT
	DW	CGROUP:GDT,0

DESC	STRUC

	LIMIT	DW	?
	BASE	DW	?
	HIBASE	DB	?
	ACCESS	DB	?
	HILIMIT	DB	?
	MSBASE	DB	?

DESC	ENDS

GDT	LABEL	BYTE
          DESC<>                               ;DUMMY
TSS_DESC  DESC<SIZE PROTECT_TSS-1,CGROUP:PROTECT_TSS,000h,89h,00h,000h> ;TSS
CSEG16    DESC<0FFFFH,0000h,000H,9BH,10H,000H> ;Code
DSEG      DESC<0FFFFH,0000h,000H,93H,10H,000H> ;Data(Code)
DSEG_SORC DESC<0FFFFH,0000h,000H,93H,9FH,000H> ;Source Data Area
DSEG_DEST DESC<0FFFFH,0000h,000H,93H,9FH,000H> ;Destination Data Area
DSEG_FFFF DESC<0FFFFH,0000h,000H,93H,10H,000H> ;Data First 64KB
DSEG_FULL DESC<0FFFFH,0000h,000H,93H,9FH,000H> ;Data Full
SSEG      DESC<0FFFFH,0000h,000H,93H,10H,000H> ;Stack
DSEG_PAGE DESC<03FFFH,0000h,000h,93h,10h,000h> ;Data Page Table
VCPI_DESC LABEL BYTE
          DESC<>                               ;VCPI Interface's Code Segment
          DESC<>                               ;for main control program
          DESC<>                               ;for main control program
GDT_END  LABEL   BYTE

TSS_SEL   EQU TSS_DESC-GDT
CSEL16    EQU CSEG16-GDT
DSEL      EQU DSEG-GDT
DSEL_SORC EQU DSEG_SORC-GDT
DSEL_DEST EQU DSEG_DEST-GDT
DSEL_FFFF EQU DSEG_FFFF-GDT
DSEL_FULL EQU DSEG_FULL-GDT
SSEL      EQU SSEG-GDT
DSEL_PAGE EQU DSEG_PAGE-GDT
CSEL_VCPI EQU VCPI_DESC-GDT

DPMI_ENTRY   DD   ?
DPMI_VER     DW   ?
ADRS_FLG     DW   ?
CPU_TYPE     DB   ?
PRVDT_SZ     DW   ?
PRVDT_SEG    DW   ?
SORC_SEL     DW   DSEL_SORC
DEST_SEL     DW   DSEL_DEST
DSEL_CODE    DW   ?
DATA_SEL     DW   0
VCPI_ENTRY   DD   ?
             DW   CSEL_VCPI
STACK_BAK    DW   ?
STACK_SEG    DW   ?
CODE_SEG     DW   ?
PAGE_SEG     DW   ?
MPIC_VECT_NO DB   8
SPIC_VECT_NO DB   70H

FLAG         DW   0
@DPMI        EQU 1 SHL 4   ;DPMIでメモリアクセス
@VCPI        EQU 1 SHL 5   ;VCPIでメモリアクセス

EMM_NAME DB    'EMMXXXX0',0

PROTECT_TSS   DD 26 DUP(?)
PAGE_TBL_BUF  DB 4096*4 DUP(?)


TEXT ENDS
     END

⌨️ 快捷键说明

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