/* * $Source: /cvs/cvsroot/d2x/unused/vga/vga.jas,v $ * $Revision: 1.1.1.2 $ * $Author: bradleyb $ * $Date: 2001-01-19 03:33:51 $ * * VGA library code * * $Log: not supported by cvs2svn $ * Revision 1.14 1996/01/02 18:00:51 matt * New parms for gr_init_screen * * Revision 1.13 1995/12/19 13:46:05 matt * Use symbolic constant for special 3dmax mode * * Revision 1.12 1995/12/13 18:03:03 matt * From JOHN: added code for special 3dbios mode * * Revision 1.11 1995/12/13 16:28:54 matt * Use more legal way of checking screen mode * * Revision 1.10 1995/11/28 10:30:22 matt * Added support for 1280x1024 * * Revision 1.9 1995/11/22 12:52:42 matt * Changed numeric literals to symbolic constants * * Revision 1.8 1995/11/16 12:00:17 jed * killed some prototype stuff * * Revision 1.7 1995/11/14 18:11:07 jed * added code to support linear frame buffering * * Revision 1.6 1995/08/30 21:11:26 matt * Added global containing current VGA mode * * Revision 1.5 1995/06/05 12:41:37 samir * Moved gr_palette_clear from gr.c to vga.c * * Revision 1.4 1995/05/31 10:54:26 matt * Added RCS header * * * */ #include #include #include #include #include #include #include "types.h" #include "mem.h" #include "error.h" #include "mono.h" // New for VGA Library. #include "gr.h" #include "vga.h" #include "palette.h" #include "grdef.h" #include "fxvesa.h" // Global Variables ----------------------------------------------------------- ubyte *vga_screen_addr = NULL; unsigned char * vga_video_memory = (unsigned char *)0xA0000; char vga_pal_default[768]; int vga_installed = 0; //extern int gr_palette_realized; int vga_prevent_palette_loading = 0; ubyte * pVideoMode = (volatile ubyte *)0x449; uword * pNumColumns = (volatile uword *)0x44a; ubyte * pNumRows = (volatile ubyte *)0x484; uword * pCharHeight = (volatile uword *)0x485; uword * pCursorPos = (volatile uword *)0x450; uword * pCursorType = (volatile uword *)0x460; uword * pTextMemory = (volatile uword *)0xb8000; ubyte saved_video_mode = 0; uword saved_num_columns = 0; ubyte saved_num_rows = 0; uword saved_char_height = 0; uword saved_cursor_pos = 0; uword saved_cursor_type = 0; ubyte saved_is_graphics = 0; uword * saved_video_memory = NULL; int cga_show_screen_info = 0; // VGA Functions -------------------------------------------------------------- ubyte vga_get_screen_mode( void ) { union REGS regs; regs.w.ax = 0x0f00; int386( 0x10, ®s, ®s ); return regs.w.ax & 0xff; } void vga_set_cellheight( ubyte height ) { ubyte temp; outp( 0x3d4, 9 ); temp = inp( 0x3d5 ); temp &= 0xE0; temp |= height; outp( 0x3d5, temp ); } void vga_set_linear() { outpw( 0x3c4, 0xE04 ); // enable chain4 mode outpw( 0x3d4, 0x4014 ); // turn on dword mode outpw( 0x3d4, 0xa317 ); // turn off byte mode } void vga_16_to_256() { outpw( 0x3ce, 0x4005 ); // set Shift reg to 1 inp( 0x3da ); // dummy input outp( 0x3c0, 0x30 ); outp( 0x3c0, 0x61 ); // turns on PCS & PCC inp( 0x3da ); // dummy input outp( 0x3c0, 0x33 ); outp( 0x3c0, 0 ); } void vga_turn_screen_off() { ubyte temp; temp = inp( 0x3da ); outp( 0x3c0, 0 ); } void vga_turn_screen_on() { ubyte temp; temp = inp( 0x3da ); outp( 0x3c0, 0x20 ); } void vga_set_misc_mode( uword mode ) { union REGS regs; regs.w.ax = mode; int386( 0x10, ®s, ®s ); } void gr_set_3dbios_mode( uint mode ) { union REGS regs; memset( ®s, 0, sizeof(regs) ); regs.w.ax = 0x4fd0; regs.w.bx = 0x3d00 | (mode & 0xff); int386( 0x10, ®s, ®s ); } void vga_set_text_25() { union REGS regs; regs.w.ax = 3; int386( 0x10, ®s, ®s ); } void vga_set_text_43() { union REGS regs; regs.w.ax = 0x1201; regs.w.bx = 0x30; int386( 0x10, ®s, ®s ); regs.w.ax = 3; int386( 0x10, ®s, ®s ); regs.w.ax = 0x1112; regs.w.bx = 0x0; int386( 0x10, ®s, ®s ); } void vga_set_text_50() { union REGS regs; regs.w.ax = 0x1202; regs.w.bx = 0x30; int386( 0x10, ®s, ®s ); regs.w.ax = 3; int386( 0x10, ®s, ®s ); regs.w.ax = 0x1112; regs.w.bx = 0x0; int386( 0x10, ®s, ®s ); } ubyte is_graphics_mode() { byte tmp; tmp = inp( 0x3DA ); // Reset flip-flip outp( 0x3C0, 0x30 ); // Select attr register 10 tmp = inp( 0x3C1 ); // Get graphics/text bit return tmp & 1; } int vga_save_mode() { int i; saved_video_mode = vga_get_screen_mode(); saved_num_columns = *pNumColumns; saved_num_rows = *pNumRows+1; saved_char_height = *pCharHeight; saved_cursor_pos = *pCursorPos; saved_cursor_type = *pCursorType; saved_is_graphics = is_graphics_mode(); if (saved_is_graphics==0) { MALLOC(saved_video_memory,uword, saved_num_columns*saved_num_rows ); for (i=0; i < saved_num_columns*saved_num_rows; i++ ) saved_video_memory[i] = pTextMemory[i]; } if (cga_show_screen_info ) { printf( "Current video mode 0x%x:\n", saved_video_mode ); if (saved_is_graphics) printf( "Graphics mode\n" ); else printf( "Text mode\n" ); printf( "( %d columns by %d rows)\n", saved_num_columns, saved_num_rows ); printf( "Char height is %d pixel rows\n", saved_char_height ); printf( "Cursor of type 0x%x is at (%d, %d)\n", saved_cursor_type, saved_cursor_pos & 0xFF, saved_cursor_pos >> 8 ); } return 0; } int isvga() { union REGS regs; regs.w.ax = 0x1a00; int386( 0x10, ®s, ®s ); if ( regs.h.al != 0x1a ) return 0; if ( (regs.h.bl==7) || (regs.h.bl==8)) return 1; return 0; } void vga_set_cursor_type( uword ctype ) { union REGS regs; regs.w.ax = 0x0100; regs.w.cx = ctype; int386( 0x10, ®s, ®s ); } void vga_enable_default_palette_loading() { union REGS regs; regs.w.ax = 0x1200; regs.w.bx = 0x31; int386( 0x10, ®s, ®s ); vga_prevent_palette_loading = 0; } void vga_disable_default_palette_loading() { union REGS regs; regs.w.ax = 0x1201; regs.w.bx = 0x31; int386( 0x10, ®s, ®s ); vga_prevent_palette_loading = 1; } void vga_set_cursor_position( uword position ) { union REGS regs; regs.w.ax = 0x0200; regs.w.bx = 0; regs.w.dx = position; int386( 0x10, ®s, ®s ); } void vga_restore_mode() { int i; if ( saved_video_mode == 3 ) { switch( saved_num_rows ) { case 43: vga_set_text_43(); break; case 50: vga_set_text_50(); break; default: vga_set_text_25(); break; } } else { vga_set_misc_mode(saved_video_mode); } if (saved_is_graphics==0) { for (i=0; i < saved_num_columns*saved_num_rows; i++ ) pTextMemory[i]=saved_video_memory[i]; vga_set_cursor_type( saved_cursor_type ); vga_set_cursor_position( saved_cursor_pos ); } } short vga_close() { if (vga_installed==1) { vga_installed = 0; vga_restore_mode(); if( saved_video_memory ) free(saved_video_memory); } return 0; } int LinearSVGABuffer=0; int vga_vesa_setmode( short mode ) { int retcode; if (VesaInit (mode)) // if there is an error with linear support { LinearSVGABuffer=1; return(0); } LinearSVGABuffer=0; retcode=gr_vesa_checkmode( mode ); // do the old banking way if ( retcode ) return retcode; return gr_vesa_setmodea( mode ); } int VGA_current_mode = SM_ORIGINAL; #define VIRGE #ifdef VIRGE extern int Virge_enabled; #endif short vga_set_mode(short mode) { int retcode; unsigned int w,h,t,data, r; LinearSVGABuffer=0; if (!vga_installed) return 1; #ifdef VIRGE Virge_enabled = 0; #endif switch(mode) { case SM_ORIGINAL: return 0; case SM_320x200C: if (!isvga()) return 1; vga_set_misc_mode(0x13); w = 320; r = 320; h = 200; t=BM_LINEAR; data = 0xA0000; break; case SM_640x400V: retcode = vga_vesa_setmode( 0x100 ); //gr_enable_default_palette_loading(); if (retcode !=0 ) return retcode; w = 640; r = 640; h = 400; t=BM_SVGA; data = 0; break; case SM_640x480V: retcode = vga_vesa_setmode( 0x101 ); //gr_enable_default_palette_loading(); if (retcode !=0 ) return retcode; w = 640; r = 640; h = 480; t=BM_SVGA; data = 0; break; case SM_800x600V: retcode = vga_vesa_setmode( 0x103 ); //gr_enable_default_palette_loading(); if (retcode !=0 ) return retcode; w = 800; r = 800; h = 600; t=BM_SVGA; data = 0; break; case SM_1024x768V: retcode = vga_vesa_setmode( 0x105 ); //gr_enable_default_palette_loading(); if (retcode !=0 ) return retcode; w = 1024; r = 1024; h = 768; t=BM_SVGA; data = 0; break; case SM_1280x1024V: retcode = vga_vesa_setmode( 0x107 ); //gr_enable_default_palette_loading(); if (retcode !=0 ) return retcode; w = 1280; r = 1280; h = 1024; t=BM_SVGA; data = 0; break; case SM_640x480V15: retcode = vga_vesa_setmode( 0x110 ); //gr_enable_default_palette_loading(); if (retcode !=0 ) return retcode; w = 640; r = 640*2; h=480; t=BM_SVGA15; data = 0; break; case SM_800x600V15: retcode = vga_vesa_setmode( 0x113 ); //gr_enable_default_palette_loading(); if (retcode !=0 ) return retcode; w = 800; r = 800*2; h=600; t=BM_SVGA15; data = 0; break; //super-special code for 3dmax high-res mode case SM_320x400_3DMAX: // 3dmax 320x400 if (!isvga()) return 1; gr_set_3dbios_mode(0x31); //w = 320; r = 320/4; h = 400; t=BM_MODEX; data = 0; w = 320; r = 320; h = 400; t=BM_SVGA; data = 0; break; //@@case 19: //@@ if (!isvga()) return 1; //@@ vga_set_misc_mode(0x13); //@@ vga_set_cellheight( 3 ); //@@ w = 320; r = 320; h = 200; t=BM_LINEAR; data = 0xA0000; //@@ break; //@@ //@@case 20: //@@ retcode = vga_vesa_setmode( 0x102 ); //@@ //gr_enable_default_palette_loading(); //@@ if (retcode !=0 ) return retcode; //@@ vga_16_to_256(); //@@ vga_set_linear(); //@@ //gr_set_cellheight( 1 ); //@@ gr_vesa_setlogical( 400 ); //@@ w = 400; r = 400; h = 600; t=BM_SVGA; data = 0; //@@ break; //@@ //@@case 21: //@@ if (!isvga()) return 1; //@@ vga_set_misc_mode(0xd); //@@ vga_16_to_256(); //@@ vga_set_linear(); //@@ //gr_set_cellheight( 3 ); //@@ w = 160; r = 160; h = 200; t=BM_LINEAR; data = 0xA0000; //@@ break; case SM_320x200U: case SM_320x240U: case SM_360x200U: case SM_360x240U: case SM_376x282U: case SM_320x400U: case SM_320x480U: case SM_360x400U: case SM_360x480U: case SM_360x360U: case SM_376x308U: case SM_376x564U: //mode X modes if (!isvga()) return 1; w = gr_modex_setmode( mode ); //gr_enable_default_palette_loading(); h = w & 0xffff; w = w >> 16; r = w / 4;t = BM_MODEX; data = 0; break; default: //unknown mode!!! Very bad!! Error("Unknown mode %d in vga_set_mode()",mode); } // if (vga_palette_realized && (vga_prevent_palette_loading==0)) // gr_pal_setblock( 0, 256, gr_palette); // return 0; VGA_current_mode = mode; if (LinearSVGABuffer) { mprintf ((0,"GREEEEAT!\n")); t=BM_LINEAR; vga_screen_addr=(ubyte *)VesaGetPtr(); } else vga_screen_addr=(ubyte *)0xa0000; gr_palette_clear(); return gr_init_screen( t,w,h,0,0,r,vga_screen_addr); } short vga_init() { // Only do this function once! if (vga_installed==1) return 1; if (gr_init_A0000()) return 10; vga_screen_addr = (ubyte *)0xa0000; //address in memory of screen // Save the current text screen mode if (vga_save_mode()==1) return 1; /* if (get_selector( &vga_fade_table, 256*GR_FADE_LEVELS, &vga_fade_table_selector )) Error( "Error allocating fade table selector!" ); if (get_selector( &vga_palette, 256*3, &vga_palette_selector )) Error( "Error allocating palette selector!" ); if (get_selector( &vga_inverse_table, 32*32*32, &vga_inverse_table_selector )) Error( "Error allocating inverse table selector!" ); */ // Set flags indicating that this is installed. gr_palette_clear(); vga_installed = 1; atexit(vga_close); return 0; } short vga_mode13_checkmode() { if (isvga()) return 0; else return 1; } // 0=Mode set OK // 1=No VGA adapter installed // 2=Program doesn't support this VESA granularity // 3=Monitor doesn't support that VESA mode.: // 4=Video card doesn't support that VESA mode. // 5=No VESA driver found. // 6=Bad Status after VESA call/ // 7=Not enough DOS memory to call VESA functions. // 8=Error using DPMI. // 9=Error setting logical line width. // 10=Error allocating selector for A0000h // 11=Not a valid mode support by gr.lib short vga_check_mode(short mode) { switch(mode) { case 19: case SM_320x200C: case SM_320x200U: case SM_320x240U: case SM_360x200U: case SM_360x240U: case SM_376x282U: case SM_320x400U: case SM_320x480U: case SM_360x400U: case SM_360x480U: case SM_360x360U: case SM_376x308U: case SM_376x564U: return vga_mode13_checkmode(); case SM_640x400V: return gr_vesa_checkmode( 0x100 ); case SM_640x480V: return gr_vesa_checkmode( 0x101 ); case SM_800x600V: return gr_vesa_checkmode( 0x103 ); case SM_1024x768V: return vga_vesa_setmode( 0x105 ); case SM_640x480V15: return vga_vesa_setmode( 0x110 ); case SM_800x600V15: return vga_vesa_setmode( 0x113 ); } return 11; }