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
;
59 /* Initialize the PIC */
60 PicWriteCommand(PIC_MASTER_CMD
, PIC_ICW1
| PIC_ICW1_ICW4
);
61 PicWriteCommand(PIC_SLAVE_CMD
, PIC_ICW1
| PIC_ICW1_ICW4
);
63 /* Set the interrupt offsets */
64 PicWriteData(PIC_MASTER_DATA
, BIOS_PIC_MASTER_INT
);
65 PicWriteData(PIC_SLAVE_DATA
, BIOS_PIC_SLAVE_INT
);
67 /* Tell the master PIC there is a slave at IRQ 2 */
68 PicWriteData(PIC_MASTER_DATA
, 1 << 2);
69 PicWriteData(PIC_SLAVE_DATA
, 2);
71 /* Make sure the PIC is in 8086 mode */
72 PicWriteData(PIC_MASTER_DATA
, PIC_ICW4_8086
);
73 PicWriteData(PIC_SLAVE_DATA
, PIC_ICW4_8086
);
75 /* Clear the masks for both PICs */
76 PicWriteData(PIC_MASTER_DATA
, 0x00);
77 PicWriteData(PIC_SLAVE_DATA
, 0x00);
84 static COORD
BiosVideoAddressToCoord(ULONG Address
)
86 COORD Result
= {0, 0};
87 CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo
;
88 HANDLE ConsoleOutput
= GetStdHandle(STD_OUTPUT_HANDLE
);
90 if (!GetConsoleScreenBufferInfo(ConsoleOutput
, &ConsoleInfo
))
96 Result
.X
= ((Address
- CONSOLE_VIDEO_MEM_START
) >> 1) % ConsoleInfo
.dwSize
.X
;
97 Result
.Y
= ((Address
- CONSOLE_VIDEO_MEM_START
) >> 1) / ConsoleInfo
.dwSize
.X
;
102 VOID
BiosUpdateConsole(ULONG StartAddress
, ULONG EndAddress
)
107 HANDLE ConsoleOutput
= GetStdHandle(STD_OUTPUT_HANDLE
);
109 /* Loop through all the addresses */
110 for (i
= StartAddress
; i
< EndAddress
; i
++)
112 /* Get the coordinates */
113 Coordinates
= BiosVideoAddressToCoord(i
);
115 /* Check if this is a character byte or an attribute byte */
116 if ((i
- CONSOLE_VIDEO_MEM_START
) % 2 == 0)
118 /* This is a regular character */
119 FillConsoleOutputCharacterA(ConsoleOutput
,
120 *(PCHAR
)((ULONG_PTR
)BaseAddress
+ i
),
127 /* This is an attribute */
128 FillConsoleOutputAttribute(ConsoleOutput
,
129 *(PCHAR
)((ULONG_PTR
)BaseAddress
+ i
),
137 VOID
BiosUpdateVideoMemory(ULONG StartAddress
, ULONG EndAddress
)
143 HANDLE ConsoleOutput
= GetStdHandle(STD_OUTPUT_HANDLE
);
145 /* Loop through all the addresses */
146 for (i
= StartAddress
; i
< EndAddress
; i
++)
148 /* Get the coordinates */
149 Coordinates
= BiosVideoAddressToCoord(i
);
151 /* Check if this is a character byte or an attribute byte */
152 if ((i
- CONSOLE_VIDEO_MEM_START
) % 2 == 0)
154 /* This is a regular character */
155 ReadConsoleOutputCharacterA(ConsoleOutput
,
156 (LPSTR
)((ULONG_PTR
)BaseAddress
+ i
),
163 /* This is an attribute */
164 ReadConsoleOutputAttribute(ConsoleOutput
,
170 *(PCHAR
)((ULONG_PTR
)BaseAddress
+ i
) = LOBYTE(Attribute
);
175 VOID
BiosVideoService()
177 HANDLE ConsoleOutput
= GetStdHandle(STD_OUTPUT_HANDLE
);
179 BOOLEAN Invisible
= FALSE
;
181 CONSOLE_CURSOR_INFO CursorInfo
;
184 DWORD Eax
= EmulatorGetRegister(EMULATOR_REG_AX
);
185 DWORD Ecx
= EmulatorGetRegister(EMULATOR_REG_CX
);
186 DWORD Edx
= EmulatorGetRegister(EMULATOR_REG_DX
);
187 DWORD Ebx
= EmulatorGetRegister(EMULATOR_REG_BX
);
191 /* Set Text-Mode Cursor Shape */
194 /* Retrieve and validate the input */
195 Invisible
= ((HIBYTE(Ecx
) >> 5) & 0x03) ? TRUE
: FALSE
;
196 CursorHeight
= (HIBYTE(Ecx
) & 0x1F) - (LOBYTE(Ecx
) & 0x1F);
197 if (CursorHeight
< 1) CursorHeight
= 1;
198 if (CursorHeight
> 100) CursorHeight
= 100;
201 CursorInfo
.dwSize
= (CursorHeight
* 100) / CONSOLE_FONT_HEIGHT
;
202 CursorInfo
.bVisible
= !Invisible
;
203 SetConsoleCursorInfo(ConsoleOutput
, &CursorInfo
);
208 /* Set Cursor Position */
211 Position
.X
= LOBYTE(Edx
);
212 Position
.Y
= HIBYTE(Edx
);
214 SetConsoleCursorPosition(ConsoleOutput
, Position
);
218 /* Scroll Up/Down Window */
222 Rect
.Top
= HIBYTE(Ecx
);
223 Rect
.Left
= LOBYTE(Ecx
);
224 Rect
.Bottom
= HIBYTE(Edx
);
225 Rect
.Right
= LOBYTE(Edx
);
226 Character
.Char
.UnicodeChar
= L
' ';
227 Character
.Attributes
= HIBYTE(Ebx
);
228 Position
.X
= Rect
.Left
;
229 if (HIBYTE(Eax
) == 0x06) Position
.Y
= Rect
.Top
- LOBYTE(Eax
);
230 else Position
.Y
= Rect
.Top
+ LOBYTE(Eax
);
232 ScrollConsoleScreenBuffer(ConsoleOutput
,
240 /* Read Character And Attribute At Cursor Position */
246 /* Write Character And Attribute At Cursor Position */
252 /* Write Character Only At Cursor Position */
260 VOID
BiosHandleIrq(BYTE IrqNumber
)
262 PicWriteCommand(PIC_MASTER_CMD
, PIC_OCW2_EOI
);