📄 memfunc.asm
字号:
@@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 + -