2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
11 BYTE CursorRow
, CursorCol
;
12 WORD ConsoleWidth
, ConsoleHeight
;
14 BOOLEAN
BiosInitialize()
18 HANDLE ConsoleOutput
= GetStdHandle(STD_OUTPUT_HANDLE
);
19 CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo
;
20 LPWORD IntVecTable
= (LPWORD
)((ULONG_PTR
)BaseAddress
);
21 LPBYTE BiosCode
= (LPBYTE
)((ULONG_PTR
)BaseAddress
+ TO_LINEAR(BIOS_SEGMENT
, 0));
23 /* Generate ISR stubs and fill the IVT */
24 for (i
= 0; i
< 256; i
++)
26 IntVecTable
[i
* 2] = Offset
;
27 IntVecTable
[i
* 2 + 1] = BIOS_SEGMENT
;
29 if (i
!= SPECIAL_INT_NUM
)
31 BiosCode
[Offset
++] = 0xFA; // cli
33 BiosCode
[Offset
++] = 0x6A; // push i
34 BiosCode
[Offset
++] = (BYTE
)i
;
36 BiosCode
[Offset
++] = 0xCD; // int SPECIAL_INT_NUM
37 BiosCode
[Offset
++] = SPECIAL_INT_NUM
;
39 BiosCode
[Offset
++] = 0x83; // add sp, 2
40 BiosCode
[Offset
++] = 0xC4;
41 BiosCode
[Offset
++] = 0x02;
44 BiosCode
[Offset
++] = 0xCF; // iret
47 /* Get the console buffer info */
48 if (!GetConsoleScreenBufferInfo(ConsoleOutput
, &ConsoleInfo
))
53 /* Set the initial cursor position and console size */
54 CursorCol
= ConsoleInfo
.dwCursorPosition
.X
;
55 CursorRow
= ConsoleInfo
.dwCursorPosition
.Y
;
56 ConsoleWidth
= ConsoleInfo
.dwSize
.X
;
57 ConsoleHeight
= ConsoleInfo
.dwSize
.Y
;
62 static COORD
BiosVideoAddressToCoord(ULONG Address
)
64 COORD Result
= {0, 0};
65 CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo
;
66 HANDLE ConsoleOutput
= GetStdHandle(STD_OUTPUT_HANDLE
);
68 if (!GetConsoleScreenBufferInfo(ConsoleOutput
, &ConsoleInfo
))
74 Result
.X
= ((Address
- CONSOLE_VIDEO_MEM_START
) >> 1) % ConsoleInfo
.dwSize
.X
;
75 Result
.Y
= ((Address
- CONSOLE_VIDEO_MEM_START
) >> 1) / ConsoleInfo
.dwSize
.X
;
80 VOID
BiosUpdateConsole(ULONG StartAddress
, ULONG EndAddress
)
85 HANDLE ConsoleOutput
= GetStdHandle(STD_OUTPUT_HANDLE
);
87 /* Loop through all the addresses */
88 for (i
= StartAddress
; i
< EndAddress
; i
++)
90 /* Get the coordinates */
91 Coordinates
= BiosVideoAddressToCoord(i
);
93 /* Check if this is a character byte or an attribute byte */
94 if ((i
- CONSOLE_VIDEO_MEM_START
) % 2 == 0)
96 /* This is a regular character */
97 FillConsoleOutputCharacterA(ConsoleOutput
,
98 *(PCHAR
)((ULONG_PTR
)BaseAddress
+ i
),
105 /* This is an attribute */
106 FillConsoleOutputAttribute(ConsoleOutput
,
107 *(PCHAR
)((ULONG_PTR
)BaseAddress
+ i
),
115 VOID
BiosUpdateVideoMemory(ULONG StartAddress
, ULONG EndAddress
)
121 HANDLE ConsoleOutput
= GetStdHandle(STD_OUTPUT_HANDLE
);
123 /* Loop through all the addresses */
124 for (i
= StartAddress
; i
< EndAddress
; i
++)
126 /* Get the coordinates */
127 Coordinates
= BiosVideoAddressToCoord(i
);
129 /* Check if this is a character byte or an attribute byte */
130 if ((i
- CONSOLE_VIDEO_MEM_START
) % 2 == 0)
132 /* This is a regular character */
133 ReadConsoleOutputCharacterA(ConsoleOutput
,
134 (LPSTR
)((ULONG_PTR
)BaseAddress
+ i
),
141 /* This is an attribute */
142 ReadConsoleOutputAttribute(ConsoleOutput
,
148 *(PCHAR
)((ULONG_PTR
)BaseAddress
+ i
) = LOBYTE(Attribute
);
153 VOID
BiosVideoService()
155 HANDLE ConsoleOutput
= GetStdHandle(STD_OUTPUT_HANDLE
);
157 BOOLEAN Invisible
= FALSE
;
159 CONSOLE_CURSOR_INFO CursorInfo
;
162 DWORD Eax
= EmulatorGetRegister(EMULATOR_REG_AX
);
163 DWORD Ecx
= EmulatorGetRegister(EMULATOR_REG_CX
);
164 DWORD Edx
= EmulatorGetRegister(EMULATOR_REG_DX
);
165 DWORD Ebx
= EmulatorGetRegister(EMULATOR_REG_BX
);
169 /* Set Text-Mode Cursor Shape */
172 /* Retrieve and validate the input */
173 Invisible
= ((HIBYTE(Ecx
) >> 5) & 0x03) ? TRUE
: FALSE
;
174 CursorHeight
= (HIBYTE(Ecx
) & 0x1F) - (LOBYTE(Ecx
) & 0x1F);
175 if (CursorHeight
< 1) CursorHeight
= 1;
176 if (CursorHeight
> 100) CursorHeight
= 100;
179 CursorInfo
.dwSize
= (CursorHeight
* 100) / CONSOLE_FONT_HEIGHT
;
180 CursorInfo
.bVisible
= !Invisible
;
181 SetConsoleCursorInfo(ConsoleOutput
, &CursorInfo
);
186 /* Set Cursor Position */
189 Position
.X
= LOBYTE(Edx
);
190 Position
.Y
= HIBYTE(Edx
);
192 SetConsoleCursorPosition(ConsoleOutput
, Position
);
196 /* Scroll Up/Down Window */
200 Rect
.Top
= HIBYTE(Ecx
);
201 Rect
.Left
= LOBYTE(Ecx
);
202 Rect
.Bottom
= HIBYTE(Edx
);
203 Rect
.Right
= LOBYTE(Edx
);
204 Character
.Char
.UnicodeChar
= L
' ';
205 Character
.Attributes
= HIBYTE(Ebx
);
206 Position
.X
= Rect
.Left
;
207 if (HIBYTE(Eax
) == 0x06) Position
.Y
= Rect
.Top
- LOBYTE(Eax
);
208 else Position
.Y
= Rect
.Top
+ LOBYTE(Eax
);
210 ScrollConsoleScreenBuffer(ConsoleOutput
,
218 /* Read Character And Attribute At Cursor Position */
224 /* Write Character And Attribute At Cursor Position */
230 /* Write Character Only At Cursor Position */