1 #include <common.h>
2 #include "x86emu/x86emu.h"
3 #include "../bios_emulator/glue.h"
4 #include "vesa_code.h"
5 #include "memio.h"
6 #include "misc_utils.h"
7 #include "vesa.h"
8
9 #define EMULATOR_STRAP_OFFSET 0x30000
10 #define EMULATOR_STACK_OFFSET 0x20000
11 #define EMULATOR_VESA_OFFSET 0x40000
12 #define EMULATOR_BIOS_OFFSET 0xC0000
13
14 extern pci_dev_t video_dev;
15
16 typedef short WORD;
17 typedef unsigned char BYTE;
18 typedef unsigned long DWORD;
19
20 struct MODEINFO {
21 // Mandatory information for all VBE revision
22 WORD modeattributes; // Mode attributes
23 BYTE winaattributes; // Window A attributes
24 BYTE winbattributes; // Window B attributes
25 WORD wingranularity; // Window granularity
26 WORD winsize; // Window size
27 WORD winasegment; // Window A start segment
28 WORD winbsegment; // Window B start segment
29 DWORD winfuncptr; // pointer to window function
30 WORD bytesperscanline; // Bytes per scan line
31
32 // Mandatory information for VBE 1.2 and above
33 WORD xresolution; // Horizontal resolution in pixel or chars
34 WORD yresolution; // Vertical resolution in pixel or chars
35 BYTE xcharsize; // Character cell width in pixel
36 BYTE ycharsize; // Character cell height in pixel
37 BYTE numberofplanes; // Number of memory planes
38 BYTE bitsperpixel; // Bits per pixel
39 BYTE numberofbanks; // Number of banks
40 BYTE memorymodel; // Memory model type
41 BYTE banksize; // Bank size in KB
42 BYTE numberofimagepages; // Number of images
43 BYTE reserved1; // Reserved for page function
44
45 // Direct Color fields (required for direct/6 and YUV/7 memory models)
46 BYTE redmasksize; // Size of direct color red mask in bits
47 BYTE redfieldposition; // Bit position of lsb of red bask
48 BYTE greenmasksize; // Size of direct color green mask in bits
49 BYTE greenfieldposition; // Bit position of lsb of green bask
50 BYTE bluemasksize; // Size of direct color blue mask in bits
51 BYTE bluefieldposition; // Bit position of lsb of blue bask
52 BYTE rsvdmasksize; // Size of direct color reserved mask in bits
53 BYTE rsvdfieldposition; // Bit position of lsb of reserved bask
54 BYTE directcolormodeinfo; // Direct color mode attributes
55
56 // Mandatory information for VBE 2.0 and above
57 DWORD physbaseptr; // Physical address for flat frame buffer
58 DWORD offscreenmemoffset; // Pointer to start of off screen memory
59 WORD offscreenmemsize; // Amount of off screen memory in 1Kb units
60 char reserved2[206]; // Remainder of ModeInfoBlock
61 } __attribute__((packed));
62
63 /* WARNING: Must be kept in line with the OS 4 bootloader. */
64
65 #define SWAPWORD(x) mi->x = (WORD)read_word_little(&(mi->x))
66 #define SWAPLONG(x) mi->x = (DWORD)read_long_little(&(mi->x))
67
makemask(int bits,int shift)68 unsigned short makemask(int bits, int shift)
69 {
70 unsigned short mask = 0;
71 while (bits)
72 {
73 bits--;
74 mask = mask << 1;
75 mask = mask | 1;
76 }
77
78 if (shift) mask = mask << shift;
79 return mask;
80 }
81
82 #define PRFBI(x) printf("%s = %ld (%lx)\n", #x, (unsigned long)fbi->x, (unsigned long)fbi->x)
83
fill_fbi(struct MODEINFO * mi,struct FrameBufferInfo * fbi)84 void fill_fbi(struct MODEINFO *mi, struct FrameBufferInfo *fbi)
85 {
86 int i;
87 unsigned char *a;
88
89 fbi->BaseAddress = (void *)mi->physbaseptr;
90 fbi->XSize = mi->xresolution;
91 fbi->YSize = mi->yresolution;
92 fbi->BitsPerPixel = mi->bitsperpixel;
93 fbi->Modulo = mi->bytesperscanline;
94
95 fbi->RedMask = makemask(mi->redmasksize, 8-mi->redmasksize);
96 fbi->RedShift = mi->redfieldposition;
97
98 fbi->GreenMask = makemask(mi->greenmasksize, 8-mi->greenmasksize);
99 fbi->GreenShift = mi->greenfieldposition;
100
101 fbi->BlueMask = makemask(mi->bluemasksize, 8-mi->bluemasksize);
102 fbi->BlueShift = mi->bluefieldposition;
103
104
105 #if 0
106 PRFBI(BaseAddress);
107 PRFBI(XSize);
108 PRFBI(YSize);
109 PRFBI(BitsPerPixel);
110 PRFBI(Modulo);
111 PRFBI(RedMask);
112 PRFBI(RedShift);
113 PRFBI(GreenMask);
114 PRFBI(GreenShift);
115 PRFBI(BlueMask);
116 PRFBI(BlueShift);
117 #endif
118
119 #if 0
120 a = (unsigned char *)mi->physbaseptr;
121 if (!a) return;
122
123 i = mi->bytesperscanline * mi->yresolution;
124 while (i)
125 {
126 *a = 0;
127 i--;
128 a++;
129 }
130 #endif
131 }
132
swap_modeinfo(struct MODEINFO * mi)133 void swap_modeinfo(struct MODEINFO *mi)
134 {
135 SWAPWORD(modeattributes);
136 SWAPWORD(wingranularity);
137 SWAPWORD(winsize);
138 SWAPWORD(winasegment);
139 SWAPWORD(winbsegment);
140 SWAPLONG(winfuncptr);
141 SWAPWORD(bytesperscanline);
142 SWAPWORD(xresolution);
143 SWAPWORD(yresolution);
144 SWAPLONG(physbaseptr);
145 SWAPLONG(offscreenmemoffset);
146 SWAPWORD(offscreenmemsize);
147 }
148
149 #define PRF(x) printf("%s = %ld (%lx)\n", #x, (unsigned long)mi->x, (unsigned long)mi->x)
150
print_modeinfo(struct MODEINFO * mi)151 void print_modeinfo(struct MODEINFO *mi)
152 {
153 #if 0
154 PRF(modeattributes);
155 PRF(winaattributes);
156 PRF(winbattributes);
157 PRF(wingranularity);
158 PRF(winsize);
159 PRF(winasegment);
160 PRF(winbsegment);
161 PRF(winfuncptr);
162 PRF(bytesperscanline);
163 PRF(xresolution);
164 PRF(yresolution);
165 PRF(xcharsize);
166 PRF(ycharsize);
167 PRF(numberofplanes);
168 PRF(bitsperpixel);
169 PRF(numberofbanks);
170 PRF(memorymodel);
171 PRF(banksize);
172 PRF(numberofimagepages);
173 PRF(redmasksize);
174 PRF(redfieldposition);
175 PRF(greenmasksize);
176 PRF(greenfieldposition);
177 PRF(bluemasksize);
178 PRF(bluefieldposition);
179 PRF(directcolormodeinfo);
180 PRF(physbaseptr);
181 PRF(offscreenmemoffset);
182 PRF(offscreenmemsize);
183 #endif
184 }
185
set_vesa_mode(int mode)186 void *set_vesa_mode(int mode)
187 {
188 u8 *strap;
189 int i;
190 struct MODEINFO *mi = (struct MODEINFO *)(M.mem_base + EMULATOR_VESA_OFFSET);
191
192 char *s;
193
194 code[4] = (unsigned char)mode;
195 code[20] = (unsigned char)mode;
196
197 // Execution starts here
198 M.x86.R_CS = SEG(EMULATOR_STRAP_OFFSET);
199 M.x86.R_IP = OFF(EMULATOR_STRAP_OFFSET);
200
201 // Stack at top of ram
202 M.x86.R_SS = SEG(EMULATOR_STACK_OFFSET);
203 M.x86.R_SP = OFF(EMULATOR_STACK_OFFSET);
204
205 strap = (u8*)M.mem_base + EMULATOR_STRAP_OFFSET;
206 for (i=0; i<code_COUNT; i++)
207 {
208 *strap++ = code[i];
209 }
210
211 disable_interrupts();
212 X86EMU_exec();
213 enable_interrupts();
214
215 swap_modeinfo(mi);
216
217 fbi = (struct FrameBufferInfo *)(malloc(sizeof(struct FrameBufferInfo)));
218 if (fbi) fill_fbi(mi,fbi);
219
220 return fbi;
221 }
222