[BASESRV][NTVDM][TESTVDD] Improve the FILE header section. Brought to you by Adam...
[reactos.git] / reactos / subsystems / mvdm / ntvdm / bios / bios32 / vbe.c
1 /*
2 * COPYRIGHT: GPLv2+ - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
4 * FILE: subsystems/mvdm/ntvdm/bios/bios32/vbe.c
5 * PURPOSE: VDM VESA BIOS Extensions (for the Cirrus CL-GD5434 emulated card)
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #define NDEBUG
12
13 #include "ntvdm.h"
14 #include "emulator.h"
15 #include "cpu/cpu.h"
16
17 #include "vbe.h"
18
19 #include "io.h"
20
21 /* PRIVATE VARIABLES **********************************************************/
22
23 static const VBE_MODE Modes[VBE_MODE_COUNT] = {
24 { 0x00, 0x00, NULL /* TODO */, NULL /* VGA */ },
25 { 0x01, 0x01, NULL /* TODO */, NULL /* VGA */ },
26 { 0x02, 0x02, NULL /* TODO */, NULL /* VGA */ },
27 { 0x03, 0x03, NULL /* TODO */, NULL /* VGA */ },
28 { 0x04, 0x04, NULL /* TODO */, NULL /* VGA */ },
29 { 0x05, 0x05, NULL /* TODO */, NULL /* VGA */ },
30 { 0x06, 0x06, NULL /* TODO */, NULL /* VGA */ },
31 { 0x07, 0x07, NULL /* TODO */, NULL /* VGA */ },
32 { 0x0D, 0x0D, NULL /* TODO */, NULL /* VGA */ },
33 { 0x0E, 0x0E, NULL /* TODO */, NULL /* VGA */ },
34 { 0x0F, 0x0F, NULL /* TODO */, NULL /* VGA */ },
35 { 0x10, 0x10, NULL /* TODO */, NULL /* VGA */ },
36 { 0x11, 0x11, NULL /* TODO */, NULL /* VGA */ },
37 { 0x12, 0x12, NULL /* TODO */, NULL /* VGA */ },
38 { 0x13, 0x13, NULL /* TODO */, NULL /* VGA */ },
39 { 0x14, 0xFFFF, NULL /* TODO */, NULL /* TODO */ },
40 { 0x54, 0x10A, NULL /* TODO */, NULL /* TODO */ },
41 { 0x55, 0x109, NULL /* TODO */, NULL /* TODO */ },
42 { 0x58, 0x102, NULL /* TODO */, NULL /* TODO */ },
43 { 0x5C, 0x103, NULL /* TODO */, NULL /* TODO */ },
44 { 0x5D, 0x104, NULL /* TODO */, NULL /* TODO */ },
45 { 0x5E, 0x100, NULL /* TODO */, NULL /* TODO */ },
46 { 0x5F, 0x101, NULL /* TODO */, NULL /* TODO */ },
47 { 0x60, 0x105, NULL /* TODO */, NULL /* TODO */ },
48 { 0x64, 0x111, NULL /* TODO */, NULL /* TODO */ },
49 { 0x65, 0x114, NULL /* TODO */, NULL /* TODO */ },
50 { 0x66, 0x110, NULL /* TODO */, NULL /* TODO */ },
51 { 0x67, 0x113, NULL /* TODO */, NULL /* TODO */ },
52 { 0x68, 0x116, NULL /* TODO */, NULL /* TODO */ },
53 { 0x69, 0x119, NULL /* TODO */, NULL /* TODO */ },
54 { 0x6C, 0x106, NULL /* TODO */, NULL /* TODO */ },
55 { 0x6D, 0x107, NULL /* TODO */, NULL /* TODO */ },
56 { 0x71, 0x112, NULL /* TODO */, NULL /* TODO */ },
57 { 0x72, 0xFFFF, NULL /* TODO */, NULL /* TODO */ },
58 { 0x73, 0xFFFF, NULL /* TODO */, NULL /* TODO */ },
59 { 0x74, 0x117, NULL /* TODO */, NULL /* TODO */ },
60 { 0x75, 0x11A, NULL /* TODO */, NULL /* TODO */ },
61 { 0x76, 0xFFFF, NULL /* TODO */, NULL /* TODO */ },
62 { 0x78, 0x115, NULL /* TODO */, NULL /* TODO */ },
63 { 0x79, 0x118, NULL /* TODO */, NULL /* TODO */ },
64 };
65
66 /* PUBLIC FUNCTIONS ***********************************************************/
67
68 VOID WINAPI VbeService(LPWORD Stack)
69 {
70 INT i;
71
72 switch (getAL())
73 {
74 /* Get VBE Information */
75 case 0x00:
76 {
77 VBE_INFORMATION Info;
78 PWORD Data = (PWORD)&Info;
79
80 /* Function recognized */
81 setAL(0x4F);
82
83 ZeroMemory(&Info, sizeof(VBE_INFORMATION));
84 Info.Signature = 'ASEV';
85 Info.Version = 0x0102;
86 Info.OemName = OEM_NAME_PTR;
87 Info.Capabilities = 0;
88 Info.ModeList = MAKELONG(LOWORD(getDI()
89 + FIELD_OFFSET(VBE_INFORMATION, ModeListBuffer)),
90 getES());
91 Info.VideoMemory = HIWORD(SVGA_BANK_SIZE * VGA_NUM_BANKS);
92
93 /* Fill the mode list */
94 for (i = 0; i < VBE_MODE_COUNT; i++)
95 {
96 /* Some modes don't have VESA numbers */
97 if (Modes[i].VesaNumber != 0xFFFF)
98 {
99 Info.ModeListBuffer[i] = Modes[i].VesaNumber;
100 }
101 }
102
103 Info.ModeListBuffer[VBE_MODE_COUNT] = 0xFFFF;
104
105 /* Copy the data to the caller */
106 for (i = 0; i < sizeof(VBE_INFORMATION) / sizeof(WORD); i++)
107 {
108 *(PWORD)SEG_OFF_TO_PTR(getES(), LOWORD(getDI() + i * 2)) = Data[i];
109 }
110
111 setAH(0);
112 break;
113 }
114
115 /* Get VBE Mode Information */
116 case 0x01:
117 {
118 WORD ModeNumber = getCX() & 0x1FF;
119 PWORD Data = NULL;
120
121 /* Function recognized */
122 setAL(0x4F);
123
124 /* Find the mode */
125 for (i = 0; i < VBE_MODE_COUNT; i++)
126 {
127 if ((!(ModeNumber & 0x100) && (ModeNumber == Modes[i].Number))
128 || ((ModeNumber & 0x100) && (ModeNumber == Modes[i].VesaNumber)))
129 {
130 Data = (PWORD)Modes[i].Info;
131
132 if (Data == NULL)
133 {
134 DPRINT1("WARNING: The mode information for mode %02X (%03X) is missing!\n",
135 Modes[i].Number,
136 Modes[i].VesaNumber);
137 }
138 }
139 }
140
141 if (Data == NULL)
142 {
143 /* Mode not found */
144 setAH(1);
145 break;
146 }
147
148 /* Clear the buffer */
149 for (i = 0; i < 128; i++)
150 {
151 *(PWORD)SEG_OFF_TO_PTR(getES(), LOWORD(getDI() + i * 2)) = 0;
152 }
153
154 /* Copy the data to the caller */
155 for (i = 0; i < sizeof(VBE_MODE_INFO) / sizeof(WORD); i++)
156 {
157 *(PWORD)SEG_OFF_TO_PTR(getES(), LOWORD(getDI() + i * 2)) = Data[i];
158 }
159
160 setAH(0);
161 break;
162 }
163
164 default:
165 {
166 DPRINT1("VESA BIOS Extensions function %02Xh NOT IMPLEMENTED!\n", getAL());
167 break;
168 }
169 }
170 }
171
172 BOOLEAN VbeInitialize(VOID)
173 {
174 BOOLEAN Success;
175 BYTE SeqIndex = IOReadB(VGA_SEQ_INDEX);
176
177 /* Store the OEM name */
178 strcpy(FAR_POINTER(OEM_NAME_PTR), OEM_NAME);
179
180 /* Unlock SVGA extensions on the card */
181 IOWriteB(VGA_SEQ_INDEX, SVGA_SEQ_UNLOCK_REG);
182 IOWriteB(VGA_SEQ_DATA, SVGA_SEQ_UNLOCKED);
183
184 /* Check if it worked */
185 Success = IOReadB(VGA_SEQ_DATA) == SVGA_SEQ_UNLOCKED;
186
187 IOWriteB(VGA_SEQ_INDEX, SeqIndex);
188 return Success;
189 }