; Flat Real Mode Initializer -
; A tiny ASM app to initialize the undocumented x86 addressing
; Copyright (C) 1999 by Louis P. Santill n
; Parts taken from bootsector code of Jeff Weeks, John Fine, and
; Flat Real Mode demonstration code of ASM Gems
; This program is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License
; as published by the Free Software Foundation; either version 2
; of the License, or (at your option) any later version.
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to
; the Free Software Foundation, Inc.
; 59 Temple Place
; Suite 330
; Boston, MA 02111-1307
; USA
[BITS 16]
[ORG 0x100]
JMP main
detectEMM:
MOV SI, detectingEMMString
CALL puts
PUSH ES
MOV AX, 0
MOV ES, AX
MOV BX, 0x91
MOV CX, [ ES : BX ]
MOV AX, [ ES : BX + 2 ]
MOV ES, AX
MOV BX, CX
ADD BX, 0x000A
MOV AX, [ ES : BX ]
CMP AX, [ EMMDeviceNameCMPString ]
JNE detectEMM@@
MOV AX, [ ES : BX + 2 ]
CMP AX, [ EMMDeviceNameCMPString + 2 ]
JNE detectEMM@@
MOV AX, [ ES : BX + 4 ]
CMP AX, [ EMMDeviceNameCMPString + 4 ]
JNE detectEMM@@
MOV AX, [ ES : BX + 6 ]
CMP AX, [ EMMDeviceNameCMPString + 6 ]
JNE detectEMM@@
POP ES
MOV AH, getEMMVersion
INT EMMint
JMP detectEMM00
detectEMM@@:
POP ES
MOV SI, checked
CALL puts
MOV SI, NWLN
CALL puts
MOV BYTE [ EMMflag ], EMMnotInstalled
JMP detectEMM01
detectEMM00:
; EMM is install...we should not continue
PUSH AX
MOV SI, unChecked
CALL puts
MOV SI, EMMVersionString
CALL puts
POP AX
AND AL, 0xF0
MOV CL, 4
SHR AX, CL
CALL puti
MOV SI, EMMVersionXString
CALL puts
MOV BYTE [ EMMflag ], 0
detectEMM01:
RET
;///////////////////////////////////////////////////////////////////////
detectXMM:
MOV SI, detectXMMString
CALL puts
MOV AX, 0x4300
INT 0x2F
CMP AL, 0x80
JE detectXMM00
MOV BYTE [ XMMflag ], XMMnotInstalled
MOV SI, unChecked
CALL puts
MOV SI, XMMnotInstalledString
CALL puts
JMP detectXMM@@
detectXMM00:
PUSH DX
PUSH BX
PUSH AX
MOV SI, checked
CALL puts
MOV SI, XMMVersionString
CALL puts
POP AX
PUSH AX
AND AH, 0x0F
MOV AL, AH
CALL puti
MOV SI, dotString
CALL puts
POP AX
PUSH AX
AND AL, 0xF0
MOV CL, 4
SHR AL, CL
CALL puti
POP AX
AND AX, 0x000F
CALL puti
MOV SI, NWLN
CALL puts
MOV SI, useXMMString
CALL puts
; Still need to add HMA detection (DX) and internal revision (BX) check
POP BX
POP DX
detectXMM@@:
RET
;///////////////////////////////////////////////////////////////////////
detectCPU:
MOV SI, check286Plus
CALL puts
PUSHF
XOR AH, AH
PUSH AX
POPF
PUSHF
POP AX
AND AH, 0xF0
CMP AH, 0xF0
; < 286 check
JE detectCPU01
MOV SI, unChecked
CALL puts
MOV SI, check386Plus
CALL puts
MOV AH, 0xF0
PUSH AX
POPF
PUSHF
POP AX
AND AH, 0xF0
; 386 check
JZ detectCPU00
MOV BYTE [ CPUflag ], found386Flag
MOV SI, checked
CALL puts
MOV SI, found386Plus
CALL puts
JMP detectCPU02
detectCPU00
MOV BYTE [ CPUflag ], 2
MOV SI, unChecked
CALL puts
MOV SI, found286Plus
CALL puts
detectCPU01:
MOV SI, unChecked
CALL puts
MOV SI, foundSub286
CALL puts
detectCPU02:
POPF
RET
;///////////////////////////////////////////////////////////////////////
puts:
LODSB
OR AL, AL
JZ puts00
MOV AH, 0x0E
MOV BX, 0x0007
INT 0x10
JMP puts
puts00:
RET
;///////////////////////////////////////////////////////////////////////
initFlatRealMode:
CLI
PUSH DS
PUSH ES
PUSH FS
PUSH GS
XOR EAX, EAX
MOV AX, DS
SHL EAX, 4
ADD [ GDT + 2 ], EAX
LGDT [ GDT ]
MOV EAX, CR0
INC AX
MOV CR0, EAX
MOV BX, flatdata
MOV DS, BX
MOV ES, BX
MOV FS, BX
MOV GS, BX
DEC AX
MOV CR0, EAX
POP GS
POP FS
POP ES
POP DS
STI
RET
;//////////////////////////////////////////////////////////////////////
puti:
ADD AL, '0'
MOV AH, 0x0E
MOV BX, 0x0007
INT 0x10
RET
;//////////////////////////////////////////////////////////////////////
enableA20:
MOV AL, 0xD1
OUT 0x64, AL
CALL A20Wait
MOV AL, 0xDF
OUT 0x60, AL
CALL A20Wait
MOV AL, 0xFF
OUT 0x64, AL
CALL A20Wait
RET
A20Wait:
IN AL, 0x64
JMP A20Wait00
A20Wait00:
AND AL, 2
JNZ A20Wait
RET
;//////////////////////////////////////////////////////////////////////
%define ENDL 13, 10
%define EOS 0
NWLN DB ENDL, EOS
%define version 'v0.0pre2'
;///////////////////////////////////////////////////////////////////////
introMessage DB 'FreeDOS Flat Real Mode Initializer ', version, ENDL
DB 'GPL Copyright (C) 1999, Louis P. Santillan', ENDL
DB ENDL
DB EOS
;//////////////////////////////////////////////////////////////////////
checked DB 0xFB, ']...', EOS
unChecked DB ' ]', ENDL, EOS
dotString DB '.', EOS
;//////////////////////////////////////////////////////////////////////
GDT DW 0xF, GDT, 0, 0, 0xFFFF, 0, 0x9200, 0x8F
flatdata EQU 8
;//////////////////////////////////////////////////////////////////////
initializingFRMString DB 'Entering Flat Real Mode [', EOS
FRMInitializedString DB 'Flat Real Mode has been entered', ENDL, EOS
FRMInitOK DB 'EMM Check Passed...', ENDL
DB ' Flat Real Mode can only be entered when an EMM is '
DB 'not installed', ENDL
DB ENDL, EOS
;//////////////////////////////////////////////////////////////////////
getEMMVersion EQU 0x46
EMMnotInstalled EQU -1
EMMint EQU 0x67
detectingEMMString DB 'EMM Installed [', EOS
EMMVersionString DB 'EMM version/generation: ', EOS
EMMVersionXString DB '.x', ENDL, EOS
EMMflag DB 0
; Device name read as 4 words
EMMDeviceNameCMPString DB 'EMMXXXX0'
yesEMMError DB ' Exiting with EMM running...', ENDL
DB ' Flat Real Mode cannot be entered when an EMM is running'
DB ENDL, EOS
;//////////////////////////////////////////////////////////////////////
detectXMMString DB 'XMM Installed [', EOS
getXMMVersion EQU 0x4300
XMMint EQU 0x2F
XMMnotInstalled EQU 0
XMMnotInstalledString DB ' An XMM is not installed...you must use '
DB 'your own allocation/de-allocation', ENDL
DB ' methods', ENDL
DB ENDL, EOS
XMMVersionString DB 'XMM Version ', EOS
XMMflag DB XMMnotInstalled
useXMMString DB ' You should use XMM for allocation & de-allocation'
DB ENDL
DB ENDL
DB EOS
;//////////////////////////////////////////////////////////////////////
enableA20String DB 'Enabling A20 Line of MMU [', EOS
A20EnabledString DB 'A20 Line of MMU has been ENABLED', ENDL
DB ENDL, EOS
;//////////////////////////////////////////////////////////////////////
check286Plus DB 'Checking for 286+ CPU [', EOS
found286Plus DB 'A 286+ CPU has been found', ENDL
DB ENDL, EOS
found286Flag EQU 2
foundSub286 DB 'A sub-286 CPU has been found', ENDL
DB ENDL, EOS
check386Plus DB 'Checking for 386+ CPU [', EOS
found386Plus DB 'A 386+ CPU has been found', ENDL
DB ENDL, EOS
found386Flag EQU 3
CPUflag DB 0
;//////////////////////////////////////////////////////////////////////
getKey:
PUSH AX
XOR AH, AH
INT 0x16
POP AX
RET
;//////////////////////////////////////////////////////////////////////
main:
MOV SI, introMessage
CALL puts
CALL detectEMM
CMP BYTE [ EMMflag ], EMMnotInstalled
JE main00
MOV SI, FRMInitOK
CALL puts
CALL detectXMM
CMP BYTE [ XMMflag ], 0
JE main00z
CALL detectCPU
CMP BYTE [ CPUflag ], found386Flag
JE main00z
MOV AL, 0
JMP main01
main00z:
MOV SI, enableA20String
CALL puts
CALL enableA20
MOV SI, checked
CALL puts
MOV SI, A20EnabledString
CALL puts
MOV SI, initializingFRMString
CALL puts
CALL initFlatRealMode
MOV SI, checked
CALL puts
MOV SI, FRMInitializedString
CALL puts
MOV AL, 0
JMP main01
main00:
MOV SI, yesEMMError
CALL puts
MOV AL, -1
main01:
MOV AH, 0x4C
INT 0x21