#include <dos.h>
#define ASM __emit__
#define INT __int__
#define BYTE unsigned char
#define WORD unsigned int
#define DWORD unsigned long
void SetFS(void)
{
ASM(0xE8,0x00,0x00,0xEB,0x1F,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF);
ASM(0x00,0x00,0x00,0x9A,0x0F,0x00,0xFF,0xFF,0x00,0x00,0x00,0x92,0xCF,0x00,0x17,0x00);
ASM(0x00,0x00,0x00,0x00,0x5B,0x83,0xEB,0x03,0x1E,0x0E,0x1F,0x01,0x9F,0x56,0x00,0x01);
ASM(0x9F,0x5E,0x00,0x01,0x9F,0x68,0x00,0x01,0x9F,0x6D,0x00,0x01,0x9F,0x73,0x00,0x01);
ASM(0x9F,0x7A,0x00,0x01,0x9F,0x7F,0x00,0x01,0x9F,0x93,0x00,0x01,0x9F,0xA6,0x00,0x6A);
ASM(0x00,0x0E,0x66,0x58,0x2E,0xA3,0xA8,0x00,0x66,0xC1,0xE0,0x04,0x2E,0xA3,0x10,0x00);
ASM(0x66,0x50,0x66,0x50,0x58,0x58,0x2E,0xA2,0x12,0x00,0x2E,0x88,0x26,0x15,0x00,0x66);
ASM(0x58,0x66,0x05,0x06,0x00,0x00,0x00,0x66,0x2E,0xA3,0x20,0x00,0x0F,0x01,0x16,0x1E);
ASM(0x00,0xFA,0xE4,0x92,0x0C,0x02,0xE6,0x92,0x66,0x0F,0x20,0xC0,0x0C,0x01,0x66,0x0F);
ASM(0x22,0xC0,0xEA,0x97,0x00,0x08,0x00,0x6A,0x10,0x0F,0xA1,0x66,0x0F,0x20,0xC0,0x24);
ASM(0xFE,0x66,0x0F,0x22,0xC0,0xEA,0xAA,0x00,0x00,0x00,0xFB,0x1F);
}
void DisableA20(void)
{
ASM(0xFA,0xE4,0x92,0x24,0xFD,0xE6,0x92,0xFB);
}
BYTE ReadByte(DWORD adr)
{
adr = adr;
ASM(0x57,0x66,0x8B,0x7E,0x04,0x67,0x64,0x8A,0x07,0x5F);
}
void WriteByte(DWORD adr, BYTE val)
{
adr = adr;
val = val;
ASM(0x57,0x66,0x8B,0x7E,0x04,0x8A,0x46,0x08,0x67,0x64,0x88,0x07,0x5F);
}
/*
Assemble source file:
CODE SEGMENT
ASSUME CS:CODE
ORG 0100H
_SetFS:
START: CALL $ + 3
JMP MAIN
GDT DD 0,0
CSLL DW 0FFFFH
CSBL DW 0
CSBM DB 0
CSA DB 9AH
CSLH DB 0FH; 0CFH
CSBH DB 0
DSLL DW 0FFFFH
DSBL DW 0
DSBM DB 0
DSA DB 92H
DSLH DB 0FH; 0CFH
DSBH DB 0
VGDTR DW $ - GDT - 1
VBASE DD 0
; Get IP
MAIN: POP BX
SUB BX,3
PUSH DS
PUSH CS
POP DS
; redirection
ADD [BX + OFFSET $CSEG - OFFSET START],BX
ADD [BX + OFFSET $CSBL - OFFSET START],BX
ADD [BX + OFFSET $CSBM - OFFSET START],BX
ADD [BX + OFFSET $CSBH - OFFSET START],BX
ADD [BX + OFFSET $GDT - OFFSET START],BX
ADD [BX + OFFSET $VBASE - OFFSET START],BX
ADD [BX + OFFSET $VGDTR - OFFSET START],BX
ADD [BX + OFFSET $PSA - OFFSET START],BX
ADD [BX + OFFSET $RSA - OFFSET START],BX
DB 6AH,00H ; PUSH 00H
PUSH CS
DB 66H
POP AX ; POP EAX
DB 2EH,0A3H
$CSEG DW OFFSET CSEG - OFFSET START
; MOV WORD PTR CS:CSEG,AX
DB 66H
DB 0C1H,0E0H,04H ; SHL EAX,4
DB 2EH,0A3H
$CSBL DW OFFSET CSBL - OFFSET START
; MOV CSBL,AX
DB 66H
PUSH AX ; PUSH EAX
DB 66H
PUSH AX ; PUSH EAX
POP AX
POP AX
DB 2EH,0A2H
$CSBM DW OFFSET CSBM - OFFSET START
; MOV CSBM,AL
DB 2EH,88H,26H
$CSBH DW OFFSET CSBH - OFFSET START
; MOV CSBH,AH
DB 66H
POP AX ; POP EAX
DB 66H,05H
$GDT DW OFFSET GDT - OFFSET START
; ADD EAX,OFFSET GDT
DW 0
DB 66H
DB 2EH,0A3H
$VBASE DW OFFSET VBASE - OFFSET START
; MOV DWORD PTR VBASE,EAX
DB 0FH,01H,16H
$VGDTR DW OFFSET VGDTR - OFFSET START
; LGDT VGDTR
CLI
; Enable A20 line
IN AL,92H
OR AL,2
OUT 92H,AL
; Enter protect mode
DB 66H,0FH,20H,0C0H ; MOV EAX,CR0
OR AL,1
DB 66H,0FH,22H,0C0H ; MOV CR0,EAX
DB 0EAH
$PSA DW $ + 4 - OFFSET START
DW 8
; Modify FS
DB 6AH,10H ; PUSH 10H
DB 0FH,0A1H ; POP FS
; Exit protect mode
DB 66H,0FH,20H,0C0H ; MOV EAX,CR0
AND AL,0FEH
DB 66H,0FH,22H,0C0H ; MOV CR0,EAX
DB 0EAH
$RSA DW $ + 4 - OFFSET START
CSEG DW 0
STI
POP DS
_DisableA20:
CLI
IN AL,92H
AND AL,0FDH
OUT 92H,AL
STI
_ReadByte:
; adr -> EDI
DB 66H
MOV DI,[BP+4] ; MOV EDI,[BP+4]
DB 67H,64H
; return AL
MOV AL,[BX] ; MOV AL,FS:[EDI]
_WriteByte:
; adr -> EDI
DB 66H
MOV DI,[BP+4] ; MOV EDI,[BP+4]
; val -> AL
MOV AL,[BP+8]
DB 67H,64H
MOV [BX],AL ; MOV FS:[EDI],AL
CODE ENDS
END START
*/
// test:
void main(void)
{
DWORD adr = 0xA0000;
SetFS();
_AX = 0x4F02;
_BX = 0x0101;
INT(16);
while (adr < 0xB0000)
{
WriteByte(adr, 15);
adr++;
}
_AX = 0;
INT(22);
_AX = 3;
INT(16);
DisableA20();
}