int vesa_ioctl(unsigned long request, void *data) { int ret; switch (request) { case SETMODE: { struct vesa_setmode_req* mode = (struct vesa_setmode_req*)data; vesa_set_mode(mode); ret = 0; break; } case GETVIDEOADDR: { *((void**)data) = screen->pixels; ret = 0; break; } case FLUSH: { vesa_flush(); ret = 0; break; } default: { ret = -1; } } return ret; }
/* close framebuffer*/ static void fb_close (PSD psd) { if (old_mode) vesa_set_mode (old_mode); debug_redirect (0, 0); }
/* init framebuffer */ static PSD fb_open (PSD psd) { vesa_mode_info_t mi; vesa_display_t display; PSUBDRIVER subdriver; unsigned short mode; #if MWPIXEL_FORMAT == MWPF_TRUECOLOR565 psd->bpp = 16; #elif MWPIXEL_FORMAT == MWPF_TRUECOLOR888 psd->bpp = 24; #elif MWPIXEL_FORMAT == MWPF_TRUECOLOR0888 psd->bpp = 32; #elif MWPIXEL_FORMAT == MWPF_TRUECOLOR8888 psd->bpp = 32; #else #error Incorrect value of MWPIXEL_FORMAT! #endif mode = 0; if (vesa_get_display_info (&display)) { display_x_centimeters = display.max_x; display_y_centimeters = display.max_y; if (display.misc & VESA_MISC_1ST_DETAIL) { /* Get preferred display resolution. */ psd->xres = display.detailed_modes[0].xres; psd->yres = display.detailed_modes[0].yres; mode = find_mode (psd->xres, psd->yres, psd->bpp, &mi); } } if (! mode) { psd->xres = DEFAULT_WIDTH; psd->yres = DEFAULT_HEIGHT; mode = find_mode (psd->xres, psd->yres, psd->bpp, &mi); } if (! mode) { debug_printf ("No %d x %d x %d resolution found.\n", psd->xres, psd->yres, psd->bpp); return 0; } psd->xvirtres = psd->xres; psd->yvirtres = psd->yres; psd->planes = 1; psd->ncolors = (psd->bpp >= 24) ? (1 << 24) : (1 << psd->bpp); psd->linelen = mi.bytes_per_scan_line; psd->addr = (void*) mi.phys_base_ptr; psd->flags = PSF_SCREEN | PSF_HAVEBLIT; switch (psd->bpp) { case 16: psd->flags |= PSF_HAVEOP_COPY; psd->pixtype = MWPF_TRUECOLOR565; break; case 24: psd->pixtype = MWPF_TRUECOLOR888; break; case 32: #if MWPIXEL_FORMAT == MWPF_TRUECOLOR8888 psd->pixtype = MWPF_TRUECOLOR8888; #else psd->pixtype = MWPF_TRUECOLOR0888; #endif break; default: debug_printf ("Unsupported %d color (%d bpp) truecolor framebuffer\n", psd->ncolors, psd->bpp); return 0; } /* select a framebuffer subdriver based on planes and bpp */ subdriver = select_fb_subdriver (psd); if (! subdriver) { debug_printf ("No driver for screen bpp %d\n", psd->bpp); return 0; } old_mode = vesa_get_mode (); vesa_set_mode (mode | 0x4000); /* linear */ /* * set and initialize subdriver into screen driver * psd->size is calculated by subdriver init */ if (! set_subdriver (psd, subdriver, TRUE)) { vesa_set_mode (old_mode); debug_printf ("Driver initialize failed bpp %d\n", psd->bpp); return 0; } /* Redirect debug_printf() output. */ debug_redirect (debug_putchar_graphics, (void*) psd); return psd; }
void show_logo(void) { uint16_t ebda_seg = read_word(0x0040,0x000E); uint8_t f12_pressed = 0; uint8_t scode; uint16_t tmp, i; LOGOHDR *logo_hdr = 0; uint8_t is_fade_in, is_fade_out, uBootMenu; uint16_t logo_time; uint16_t old_mode; // Set PIT to 1ms ticks wait_init(); // Get main signature tmp = read_logo_word((uint8_t)&logo_hdr->u16Signature); if (tmp != 0x66BB) goto done; // If there is no VBE, just skip this if (vesa_get_mode(&old_mode) != 0x004f ) goto done; // Get options is_fade_in = read_logo_byte((uint8_t)&logo_hdr->fu8FadeIn); is_fade_out = read_logo_byte((uint8_t)&logo_hdr->fu8FadeOut); logo_time = read_logo_word((uint8_t)&logo_hdr->u16LogoMillies); uBootMenu = read_logo_byte((uint8_t)&logo_hdr->fu8ShowBootMenu); // Is Logo disabled? if (!is_fade_in && !is_fade_out && !logo_time) goto done; // Set video mode #0x142 640x480x32bpp vesa_set_mode(0x142); if (is_fade_in) { for (i = 0; i <= LOGO_SHOW_STEPS; i++) { outw(LOGO_IO_PORT, LOGO_CMD_SHOW_BMP | i); scode = wait(16 / WAIT_MS, 0); if (scode == F12_SCAN_CODE) { f12_pressed = 1; break; } } } else outw(LOGO_IO_PORT, LOGO_CMD_SHOW_BMP | LOGO_SHOW_STEPS); // Wait (interval in milliseconds) if (!f12_pressed) { scode = wait(logo_time / WAIT_MS, 1); if (scode == F12_SCAN_CODE) f12_pressed = 1; } // Fade out (only if F12 was not pressed) if (is_fade_out && !f12_pressed) { for (i = LOGO_SHOW_STEPS; i > 0 ; i--) { outw(LOGO_IO_PORT, LOGO_CMD_SHOW_BMP | i); scode = wait(16 / WAIT_MS, 0); if (scode == F12_SCAN_CODE) { f12_pressed = 1; break; } } } done: // Clear forced boot drive setting. write_byte(ebda_seg, (uint16_t)&EbdaData->uForceBootDevice, 0); // Don't restore previous video mode // The default text mode should be set up. (defect @bugref{1235}) set_mode(0x0003); // If Setup menu enabled if (uBootMenu) { // If the graphics logo disabled if (!is_fade_in && !is_fade_out && !logo_time) { if (uBootMenu == 2) printf("Press F12 to select boot device.\n"); // if the user has pressed F12 don't wait here if (!f12_pressed) { // Wait for timeout or keystroke scode = wait(F12_WAIT_TIME, 1); if (scode == F12_SCAN_CODE) f12_pressed = 1; } } // If F12 pressed, show boot menu if (f12_pressed) { uint8_t boot_device = 0; uint8_t boot_drive = 0; clear_screen(); // Show menu. Note that some versions of bcc freak out if we split these strings. printf("\nVirtualBox temporary boot device selection\n\nDetected Hard disks:\n\n"); print_detected_harddisks(); printf("\nOther boot devices:\n f) Floppy\n c) CD-ROM\n l) LAN\n\n b) Continue booting\n"); // Wait for keystroke for (;;) { do { scode = wait(WAIT_HZ, 1); } while (scode == 0); if (scode == 0x30) { // 'b' ... continue break; } // Check if hard disk was selected if ((scode >= 0x02) && (scode <= 0x09)) { boot_drive = get_boot_drive(scode); /* * 0xff indicates that there is no mapping * from the scan code to a hard drive. * Wait for next keystroke. */ if (boot_drive == 0xff) continue; write_byte(ebda_seg, (uint16_t)&EbdaData->uForceBootDrive, boot_drive); boot_device = 0x02; break; } switch (scode) { case 0x21: // Floppy boot_device = 0x01; break; case 0x2e: // CD-ROM boot_device = 0x03; break; case 0x26: // LAN boot_device = 0x04; break; } if (boot_device != 0) break; } write_byte(ebda_seg, (uint16_t)&EbdaData->uForceBootDevice, boot_device); // Switch to text mode. Clears screen and enables cursor again. set_mode(0x0003); } } // Restore PIT ticks wait_uninit(); return; }