| #include <common.h> |
| #include "x86emu/x86emu.h" |
| #include "../bios_emulator/glue.h" |
| #include "vesa_code.h" |
| #include "memio.h" |
| #include "misc_utils.h" |
| #include "vesa.h" |
| |
| #define EMULATOR_STRAP_OFFSET 0x30000 |
| #define EMULATOR_STACK_OFFSET 0x20000 |
| #define EMULATOR_VESA_OFFSET 0x40000 |
| #define EMULATOR_BIOS_OFFSET 0xC0000 |
| |
| extern pci_dev_t video_dev; |
| |
| typedef short WORD; |
| typedef unsigned char BYTE; |
| typedef unsigned long DWORD; |
| |
| struct MODEINFO { |
| // Mandatory information for all VBE revision |
| WORD modeattributes; // Mode attributes |
| BYTE winaattributes; // Window A attributes |
| BYTE winbattributes; // Window B attributes |
| WORD wingranularity; // Window granularity |
| WORD winsize; // Window size |
| WORD winasegment; // Window A start segment |
| WORD winbsegment; // Window B start segment |
| DWORD winfuncptr; // pointer to window function |
| WORD bytesperscanline; // Bytes per scan line |
| |
| // Mandatory information for VBE 1.2 and above |
| WORD xresolution; // Horizontal resolution in pixel or chars |
| WORD yresolution; // Vertical resolution in pixel or chars |
| BYTE xcharsize; // Character cell width in pixel |
| BYTE ycharsize; // Character cell height in pixel |
| BYTE numberofplanes; // Number of memory planes |
| BYTE bitsperpixel; // Bits per pixel |
| BYTE numberofbanks; // Number of banks |
| BYTE memorymodel; // Memory model type |
| BYTE banksize; // Bank size in KB |
| BYTE numberofimagepages; // Number of images |
| BYTE reserved1; // Reserved for page function |
| |
| // Direct Color fields (required for direct/6 and YUV/7 memory models) |
| BYTE redmasksize; // Size of direct color red mask in bits |
| BYTE redfieldposition; // Bit position of lsb of red bask |
| BYTE greenmasksize; // Size of direct color green mask in bits |
| BYTE greenfieldposition; // Bit position of lsb of green bask |
| BYTE bluemasksize; // Size of direct color blue mask in bits |
| BYTE bluefieldposition; // Bit position of lsb of blue bask |
| BYTE rsvdmasksize; // Size of direct color reserved mask in bits |
| BYTE rsvdfieldposition; // Bit position of lsb of reserved bask |
| BYTE directcolormodeinfo; // Direct color mode attributes |
| |
| // Mandatory information for VBE 2.0 and above |
| DWORD physbaseptr; // Physical address for flat frame buffer |
| DWORD offscreenmemoffset; // Pointer to start of off screen memory |
| WORD offscreenmemsize; // Amount of off screen memory in 1Kb units |
| char reserved2[206]; // Remainder of ModeInfoBlock |
| } __attribute__((packed)); |
| |
| /* WARNING: Must be kept in line with the OS 4 bootloader. */ |
| |
| #define SWAPWORD(x) mi->x = (WORD)read_word_little(&(mi->x)) |
| #define SWAPLONG(x) mi->x = (DWORD)read_long_little(&(mi->x)) |
| |
| unsigned short makemask(int bits, int shift) |
| { |
| unsigned short mask = 0; |
| while (bits) |
| { |
| bits--; |
| mask = mask << 1; |
| mask = mask | 1; |
| } |
| |
| if (shift) mask = mask << shift; |
| return mask; |
| } |
| |
| #define PRFBI(x) printf("%s = %ld (%lx)\n", #x, (unsigned long)fbi->x, (unsigned long)fbi->x) |
| |
| void fill_fbi(struct MODEINFO *mi, struct FrameBufferInfo *fbi) |
| { |
| int i; |
| unsigned char *a; |
| |
| fbi->BaseAddress = (void *)mi->physbaseptr; |
| fbi->XSize = mi->xresolution; |
| fbi->YSize = mi->yresolution; |
| fbi->BitsPerPixel = mi->bitsperpixel; |
| fbi->Modulo = mi->bytesperscanline; |
| |
| fbi->RedMask = makemask(mi->redmasksize, 8-mi->redmasksize); |
| fbi->RedShift = mi->redfieldposition; |
| |
| fbi->GreenMask = makemask(mi->greenmasksize, 8-mi->greenmasksize); |
| fbi->GreenShift = mi->greenfieldposition; |
| |
| fbi->BlueMask = makemask(mi->bluemasksize, 8-mi->bluemasksize); |
| fbi->BlueShift = mi->bluefieldposition; |
| |
| |
| #if 0 |
| PRFBI(BaseAddress); |
| PRFBI(XSize); |
| PRFBI(YSize); |
| PRFBI(BitsPerPixel); |
| PRFBI(Modulo); |
| PRFBI(RedMask); |
| PRFBI(RedShift); |
| PRFBI(GreenMask); |
| PRFBI(GreenShift); |
| PRFBI(BlueMask); |
| PRFBI(BlueShift); |
| #endif |
| |
| #if 0 |
| a = (unsigned char *)mi->physbaseptr; |
| if (!a) return; |
| |
| i = mi->bytesperscanline * mi->yresolution; |
| while (i) |
| { |
| *a = 0; |
| i--; |
| a++; |
| } |
| #endif |
| } |
| |
| void swap_modeinfo(struct MODEINFO *mi) |
| { |
| SWAPWORD(modeattributes); |
| SWAPWORD(wingranularity); |
| SWAPWORD(winsize); |
| SWAPWORD(winasegment); |
| SWAPWORD(winbsegment); |
| SWAPLONG(winfuncptr); |
| SWAPWORD(bytesperscanline); |
| SWAPWORD(xresolution); |
| SWAPWORD(yresolution); |
| SWAPLONG(physbaseptr); |
| SWAPLONG(offscreenmemoffset); |
| SWAPWORD(offscreenmemsize); |
| } |
| |
| #define PRF(x) printf("%s = %ld (%lx)\n", #x, (unsigned long)mi->x, (unsigned long)mi->x) |
| |
| void print_modeinfo(struct MODEINFO *mi) |
| { |
| #if 0 |
| PRF(modeattributes); |
| PRF(winaattributes); |
| PRF(winbattributes); |
| PRF(wingranularity); |
| PRF(winsize); |
| PRF(winasegment); |
| PRF(winbsegment); |
| PRF(winfuncptr); |
| PRF(bytesperscanline); |
| PRF(xresolution); |
| PRF(yresolution); |
| PRF(xcharsize); |
| PRF(ycharsize); |
| PRF(numberofplanes); |
| PRF(bitsperpixel); |
| PRF(numberofbanks); |
| PRF(memorymodel); |
| PRF(banksize); |
| PRF(numberofimagepages); |
| PRF(redmasksize); |
| PRF(redfieldposition); |
| PRF(greenmasksize); |
| PRF(greenfieldposition); |
| PRF(bluemasksize); |
| PRF(bluefieldposition); |
| PRF(directcolormodeinfo); |
| PRF(physbaseptr); |
| PRF(offscreenmemoffset); |
| PRF(offscreenmemsize); |
| #endif |
| } |
| |
| void *set_vesa_mode(int mode) |
| { |
| u8 *strap; |
| int i; |
| struct MODEINFO *mi = (struct MODEINFO *)(M.mem_base + EMULATOR_VESA_OFFSET); |
| |
| char *s; |
| |
| code[4] = (unsigned char)mode; |
| code[20] = (unsigned char)mode; |
| |
| // Execution starts here |
| M.x86.R_CS = SEG(EMULATOR_STRAP_OFFSET); |
| M.x86.R_IP = OFF(EMULATOR_STRAP_OFFSET); |
| |
| // Stack at top of ram |
| M.x86.R_SS = SEG(EMULATOR_STACK_OFFSET); |
| M.x86.R_SP = OFF(EMULATOR_STACK_OFFSET); |
| |
| strap = (u8*)M.mem_base + EMULATOR_STRAP_OFFSET; |
| for (i=0; i<code_COUNT; i++) |
| { |
| *strap++ = code[i]; |
| } |
| |
| disable_interrupts(); |
| X86EMU_exec(); |
| enable_interrupts(); |
| |
| swap_modeinfo(mi); |
| |
| fbi = (struct FrameBufferInfo *)(malloc(sizeof(struct FrameBufferInfo))); |
| if (fbi) fill_fbi(mi,fbi); |
| |
| return fbi; |
| } |