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