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>
9 /* INCLUDES *******************************************************************/
16 /* PRIVATE VARIABLES **********************************************************/
18 static BYTE CursorRow
, CursorCol
;
19 static WORD ConsoleWidth
, ConsoleHeight
;
21 /* PRIVATE FUNCTIONS **********************************************************/
23 static COORD
BiosVideoAddressToCoord(ULONG Address
)
25 COORD Result
= {0, 0};
26 CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo
;
27 HANDLE ConsoleOutput
= GetStdHandle(STD_OUTPUT_HANDLE
);
29 if (!GetConsoleScreenBufferInfo(ConsoleOutput
, &ConsoleInfo
))
35 Result
.X
= ((Address
- CONSOLE_VIDEO_MEM_START
) >> 1) % ConsoleInfo
.dwSize
.X
;
36 Result
.Y
= ((Address
- CONSOLE_VIDEO_MEM_START
) >> 1) / ConsoleInfo
.dwSize
.X
;
41 /* PUBLIC FUNCTIONS ***********************************************************/
43 BOOLEAN
BiosInitialize()
47 HANDLE ConsoleOutput
= GetStdHandle(STD_OUTPUT_HANDLE
);
48 CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo
;
49 LPWORD IntVecTable
= (LPWORD
)((ULONG_PTR
)BaseAddress
);
50 LPBYTE BiosCode
= (LPBYTE
)((ULONG_PTR
)BaseAddress
+ TO_LINEAR(BIOS_SEGMENT
, 0));
52 /* Generate ISR stubs and fill the IVT */
53 for (i
= 0; i
< 256; i
++)
55 IntVecTable
[i
* 2] = Offset
;
56 IntVecTable
[i
* 2 + 1] = BIOS_SEGMENT
;
58 if (i
!= SPECIAL_INT_NUM
)
60 BiosCode
[Offset
++] = 0xFA; // cli
62 BiosCode
[Offset
++] = 0x6A; // push i
63 BiosCode
[Offset
++] = (BYTE
)i
;
65 BiosCode
[Offset
++] = 0xCD; // int SPECIAL_INT_NUM
66 BiosCode
[Offset
++] = SPECIAL_INT_NUM
;
68 BiosCode
[Offset
++] = 0x83; // add sp, 2
69 BiosCode
[Offset
++] = 0xC4;
70 BiosCode
[Offset
++] = 0x02;
73 BiosCode
[Offset
++] = 0xCF; // iret
76 /* Get the console buffer info */
77 if (!GetConsoleScreenBufferInfo(ConsoleOutput
, &ConsoleInfo
))
82 /* Set the initial cursor position and console size */
83 CursorCol
= ConsoleInfo
.dwCursorPosition
.X
;
84 CursorRow
= ConsoleInfo
.dwCursorPosition
.Y
;
85 ConsoleWidth
= ConsoleInfo
.dwSize
.X
;
86 ConsoleHeight
= ConsoleInfo
.dwSize
.Y
;
88 /* Initialize the PIC */
89 PicWriteCommand(PIC_MASTER_CMD
, PIC_ICW1
| PIC_ICW1_ICW4
);
90 PicWriteCommand(PIC_SLAVE_CMD
, PIC_ICW1
| PIC_ICW1_ICW4
);
92 /* Set the interrupt offsets */
93 PicWriteData(PIC_MASTER_DATA
, BIOS_PIC_MASTER_INT
);
94 PicWriteData(PIC_SLAVE_DATA
, BIOS_PIC_SLAVE_INT
);
96 /* Tell the master PIC there is a slave at IRQ 2 */
97 PicWriteData(PIC_MASTER_DATA
, 1 << 2);
98 PicWriteData(PIC_SLAVE_DATA
, 2);
100 /* Make sure the PIC is in 8086 mode */
101 PicWriteData(PIC_MASTER_DATA
, PIC_ICW4_8086
);
102 PicWriteData(PIC_SLAVE_DATA
, PIC_ICW4_8086
);
104 /* Clear the masks for both PICs */
105 PicWriteData(PIC_MASTER_DATA
, 0x00);
106 PicWriteData(PIC_SLAVE_DATA
, 0x00);
108 PitWriteCommand(0x34);
109 PitWriteData(0, 0x00);
110 PitWriteData(0, 0x00);
115 VOID
BiosUpdateConsole(ULONG StartAddress
, ULONG EndAddress
)
120 HANDLE ConsoleOutput
= GetStdHandle(STD_OUTPUT_HANDLE
);
122 /* Loop through all the addresses */
123 for (i
= StartAddress
; i
< EndAddress
; i
++)
125 /* Get the coordinates */
126 Coordinates
= BiosVideoAddressToCoord(i
);
128 /* Check if this is a character byte or an attribute byte */
129 if ((i
- CONSOLE_VIDEO_MEM_START
) % 2 == 0)
131 /* This is a regular character */
132 FillConsoleOutputCharacterA(ConsoleOutput
,
133 *(PCHAR
)((ULONG_PTR
)BaseAddress
+ i
),
140 /* This is an attribute */
141 FillConsoleOutputAttribute(ConsoleOutput
,
142 *(PCHAR
)((ULONG_PTR
)BaseAddress
+ i
),
150 VOID
BiosUpdateVideoMemory(ULONG StartAddress
, ULONG EndAddress
)
156 HANDLE ConsoleOutput
= GetStdHandle(STD_OUTPUT_HANDLE
);
158 /* Loop through all the addresses */
159 for (i
= StartAddress
; i
< EndAddress
; i
++)
161 /* Get the coordinates */
162 Coordinates
= BiosVideoAddressToCoord(i
);
164 /* Check if this is a character byte or an attribute byte */
165 if ((i
- CONSOLE_VIDEO_MEM_START
) % 2 == 0)
167 /* This is a regular character */
168 ReadConsoleOutputCharacterA(ConsoleOutput
,
169 (LPSTR
)((ULONG_PTR
)BaseAddress
+ i
),
176 /* This is an attribute */
177 ReadConsoleOutputAttribute(ConsoleOutput
,
183 *(PCHAR
)((ULONG_PTR
)BaseAddress
+ i
) = LOBYTE(Attribute
);
188 VOID
BiosVideoService()
190 HANDLE ConsoleOutput
= GetStdHandle(STD_OUTPUT_HANDLE
);
192 BOOLEAN Invisible
= FALSE
;
194 CONSOLE_CURSOR_INFO CursorInfo
;
197 DWORD Eax
= EmulatorGetRegister(EMULATOR_REG_AX
);
198 DWORD Ecx
= EmulatorGetRegister(EMULATOR_REG_CX
);
199 DWORD Edx
= EmulatorGetRegister(EMULATOR_REG_DX
);
200 DWORD Ebx
= EmulatorGetRegister(EMULATOR_REG_BX
);
204 /* Set Text-Mode Cursor Shape */
207 /* Retrieve and validate the input */
208 Invisible
= ((HIBYTE(Ecx
) >> 5) & 0x03) ? TRUE
: FALSE
;
209 CursorHeight
= (HIBYTE(Ecx
) & 0x1F) - (LOBYTE(Ecx
) & 0x1F);
210 if (CursorHeight
< 1) CursorHeight
= 1;
211 if (CursorHeight
> 100) CursorHeight
= 100;
214 CursorInfo
.dwSize
= (CursorHeight
* 100) / CONSOLE_FONT_HEIGHT
;
215 CursorInfo
.bVisible
= !Invisible
;
216 SetConsoleCursorInfo(ConsoleOutput
, &CursorInfo
);
221 /* Set Cursor Position */
224 Position
.X
= LOBYTE(Edx
);
225 Position
.Y
= HIBYTE(Edx
);
227 SetConsoleCursorPosition(ConsoleOutput
, Position
);
231 /* Scroll Up/Down Window */
235 Rect
.Top
= HIBYTE(Ecx
);
236 Rect
.Left
= LOBYTE(Ecx
);
237 Rect
.Bottom
= HIBYTE(Edx
);
238 Rect
.Right
= LOBYTE(Edx
);
239 Character
.Char
.UnicodeChar
= L
' ';
240 Character
.Attributes
= HIBYTE(Ebx
);
241 Position
.X
= Rect
.Left
;
242 if (HIBYTE(Eax
) == 0x06) Position
.Y
= Rect
.Top
- LOBYTE(Eax
);
243 else Position
.Y
= Rect
.Top
+ LOBYTE(Eax
);
245 ScrollConsoleScreenBuffer(ConsoleOutput
,
253 /* Read Character And Attribute At Cursor Position */
259 /* Write Character And Attribute At Cursor Position */
265 /* Write Character Only At Cursor Position */
273 VOID
BiosHandleIrq(BYTE IrqNumber
)
275 PicWriteCommand(PIC_MASTER_CMD
, PIC_OCW2_EOI
);