/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Helpers for setting VGA modes in Linux. * * By George Foot, based on code by Marek Habersack. * * See readme.txt for copyright information. */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include "allegro.h" #if ((defined ALLEGRO_LINUX_VGA) && ((!defined ALLEGRO_WITH_MODULES) || (defined ALLEGRO_MODULE))) #include "allegro/internal/aintern.h" #include "allegro/platform/aintunix.h" #include "allegro/internal/aintvga.h" static MODE_REGISTERS mode13h = /* 320x200x8bpp NI */ { /* CRTC registers (24: 0-23) */ { 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3 }, /* Sequencer registers (5: 54-58) */ { 0x03, 0x01, 0x0F, 0x00, 0x0E }, /* ATC registers (21: 24-44) */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00, 0x0F, 0x00, 0x00 }, /* GC registers (9: 45-53) */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF }, /* misc (1: 59-59) */ 0x63, /* null pointer to extra register block; extra reg count */ NULL, 0, /* text font data */ NULL, NULL, /* flags */ 0L, /* palette (unused) */ { { 0 } } }; static MODE_REGISTERS mode10h = /* 640x350x4bpp NI */ { /* CRTC registers (24: 0-23) */ { 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x85, 0x5D, 0x28, 0x0F, 0x63, 0xBA, 0xE3 }, /* Sequencer registers (5: 54-58) */ { 0x03, 0x01, 0x0F, 0x00, 0x06 }, /* ATC registers (21: 24-44) */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x01, 0x00, 0x0F, 0x00, 0x00 }, /* GC registers (9: 45-53) */ { 0x00, 0x0F, 0x00, 0x20, 0x00, 0x00, 0x05, 0x0F, 0xFF }, /* misc (1: 59-59) */ 0xA3, /* null pointer to extra register block; extra reg count */ NULL, 0, /* text font data */ NULL, NULL, /* flags */ 0L, /* palette (unused) */ { { 0 } } }; static MODE_REGISTERS mode0Dh = /* 320x200x4bpp NI */ { /* CRTC registers (24: 0-23) */ { 0x2D, 0x27, 0x28, 0x90, 0x2B, 0x80, 0xBF, 0x1F, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x00, 0x96, 0xB9, 0xE3 }, /* Sequencer registers (5: 54-58) */ { 0x03, 0x09, 0x0F, 0x00, 0x06 }, /* ATC registers (21: 24-44) */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x01, 0x00, 0x0F, 0x00, 0x00 }, /* GC registers (9: 45-53) */ { 0x00, 0x0F, 0x00, 0x20, 0x00, 0x00, 0x05, 0x0F, 0xFF }, /* misc (1: 59-59) */ 0x63, /* null pointer to extra register block; extra reg count */ NULL, 0, /* text font data */ NULL, NULL, /* flags */ 0L, /* palette (unused) */ { { 0 } } }; static struct MAPPED_MEMORY vram = { 0xa0000, 0x10000, PROT_READ | PROT_WRITE, NULL }; /* _set_vga_mode: * Helper for the VGA and mode-X drivers to set a video mode. */ uintptr_t _set_vga_mode (int modenum) { MODE_REGISTERS *regs; if (!__al_linux_have_ioperms) { ustrzcpy (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("This driver needs root privileges")); return 0; } switch (modenum) { case 0x13: regs = &mode13h; break; case 0x10: regs = &mode10h; break; case 0x0D: regs = &mode0Dh; break; default: ustrzcpy (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Required VGA mode not supported")); return 0; } if (__al_linux_map_memory (&vram)) { ustrzcpy (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to map video memory")); return 0; } __al_linux_screen_off(); if (__al_linux_console_graphics()) { ustrzcpy (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Error setting VGA video mode")); __al_linux_screen_on(); __al_linux_unmap_memory (&vram); return 0; } __al_linux_save_text_mode(); __al_linux_set_vga_regs (regs); __al_linux_clear_vram(); __al_linux_screen_on(); return (unsigned long)vram.data; } /* _unset_vga_mode: * Helper for the VGA and mode-X drivers to unset the video mode. */ void _unset_vga_mode (void) { __al_linux_unmap_memory (&vram); __al_linux_screen_off(); __al_linux_restore_text_mode(); __al_linux_console_text(); __al_linux_screen_on(); } static MODE_REGISTERS gfx_regs; void _save_vga_mode (void) { __al_linux_screen_off(); get_palette (gfx_regs.palette.allegro); __al_linux_get_vga_regs (&gfx_regs); __al_linux_restore_text_mode(); __al_linux_console_text(); __al_linux_screen_on(); } void _restore_vga_mode (void) { __al_linux_screen_off(); __al_linux_save_text_mode(); __al_linux_console_graphics(); __al_linux_set_vga_regs (&gfx_regs); set_palette (gfx_regs.palette.allegro); __al_linux_screen_on(); } #endif /* if ((defined ALLEGRO_LINUX_VGA) && ... */