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