Find enclosed two programs; One is a VGA controller written in C. Switching modes is slow enough that it doesn't take high-speed code. The only thing that would be better in assembly is the routine to draw text up on the screen. The other is the system font from my laptop written in assembly. You need to compile both and link them together; I've included a 'main' which will put you in graphics mode (640x480x16) then draw the character set on the screen. Hit a key ( I used the bios for this ) and it will put you back in text mode and exit. My notebook has an LCD display; some of the register values for the CRT controller are different from Ferraro's list. In the vgaini program I have defined the symbol 'VGA' which selects the constants from Ferraro's list( 2nd Ed. Pg 318). If that doesn't work (it doesn't work on my system when returning to text mode) you can try undefining 'VGA' and defining the constant 'NOTEBOOK' to see if my notebook's constants are more realistic. If that doesn't work I have a program somewhere which will read the CRTC controller constants your system uses; you can examine them and make changes. I guess the hardware differences are why we have a BIOS. Regards, David -------------------------------VGAINI.C----------------------------------- /* VGAINI.C */ #include "dos.h" #include "memory.h" /* * Define this for my notebook */ /* #define NOTEBOOK */ /* * Define this for a normal VGA screen * Note: This picks constants out of Ferraro, I'm not sure if I've ever * tested them on normal VGA */ #define VGA /* Port addresses of control regs */ #define MISCOUTPUT 0x3c2 #define FEATURECONTROL 0x3da #define SEQUENCER 0x3c4 #define CRTC 0x03d4 #define GRAPHICS 0x3ce #define ATTRIBS 0x03c0 #define PELADDRESSWRITE 0x3c8 #define PELDATAREG 0x3c9 /* Number of regs on the various controllers */ #define MAXSEQ 5 #define MAXCRTC 0x19 #define MAXGRAPH 0x9 #define MAXATTRIB 0x015 /* Enable bit for the attribute controller */ #define ENABLEATTRIB 0x20 /* Mask to turn off register protection of some of the CRT regs */ #define NOPROT 0x7f /* Font and palette constants */ #define BYTESPERFONT 16 #define FONTENTRIES 256 #define PALETTELEN 64 /* Registers within controllers */ #define VREND 0x11 #define GRREGSETRESET 0 #define GRREGENABLESETRESET 1 #define SQREGMAPMASK 2 #define SQREGMEMORY 4 #define GRREGWRMODE 5 #define GRREGMISC 6 typedef unsigned char BYTE; /* External character font */ extern BYTE f8x16[]; /* Pointers into PC memory */ static BYTE far *biosmode = MK_FP(0x40,0x49); static BYTE far *FontBase = MK_FP(0xa000,0); static BYTE far *graphicsbase = MK_FP(0xa000,0); static BYTE far *textbase = MK_FP(0xb800,0); /* Variables used to save controller registers when mapping font mem in */ static BYTE oldgraphicsmode; static BYTE oldgraphicsmisc; static BYTE oldsqregmapmask; static BYTE oldsqregmemory; static BYTE theGraphicsMode = 0; /* Register set up for mode 3 */ static BYTE mode3[]= { 0x63,00,0x70,0x05, /* MISC OUTPUT, FEATURE CONTROL, two regs that are inputs */ 03,01,03,00,02, /* Sequencer */ #ifdef VGA 0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,0,0xc7,06,7,0,0,0,0x59,0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,0xff, /* CRT Controller */ #endif #ifdef NOTEBOOK 0x5f,0x4f,0x50,0x82,0x55,0x81,0x0bf,0x1f,0,0x4f,0xe,0x0f,0,0,7,0x80,0x9c,0xae,0x8f,0x28,0x1f,0x96,0xb9,0xa3,0xff, /* CRT Controller */ #endif 0,0,0,0,0,0x10,0xe,00,0xff, /* Graphics controller */ 0,1,2,3,4,5,6,7,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,8,0,0x0f,0,0 /* Attribute controller */ }; /* Register set up for mode 12 */ static BYTE mode12[] = { 0xe3,0,0x70,4, /* Misc Output, Feature Control, ETC */ 3,1,0xf,0,6, /* Sequencer */ #ifdef VGA 0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x3e,0,0x40,0,0,0,0,0,0x59,0xea,0x8c,0xdf,0x28,0,0xe7,4,0xe3,0xff, /* CRT Controller */ #endif #ifdef NOTEBOOK 0x5f,0x4f,0x50,0x82,0x54,0x80,0x0bf,0x3e,0,0x40,0xe,0xf,0,0,3,0x70,0xea,0xac,0xdf,0x28,0,0xe7,4,0xe3,0xff, /* CRT Controller */ #endif 0,0,0,0,0,40,5,0xf,0xff, /* Graphics Controller */ 0,1,2,3,4,5,0x14,7,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,1,0,0xf,0,0 /* Attribute Controller */ }; /* Default palette, the PC standard, entries 0-64 only */ static BYTE palette[PALETTELEN][3] = { { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x2a }, { 0x00, 0x2a, 0x00 }, { 0x00, 0x2a, 0x2a }, { 0x2a, 0x00, 0x00 }, { 0x2a, 0x00, 0x2a }, { 0x2a, 0x2a, 0x00 }, { 0x2a, 0x2a, 0x2a }, { 0x00, 0x00, 0x15 }, { 0x00, 0x00, 0x3f }, { 0x00, 0x2a, 0x15 }, { 0x00, 0x2a, 0x3f }, { 0x2a, 0x00, 0x15 }, { 0x2a, 0x00, 0x3f }, { 0x2a, 0x2a, 0x15 }, { 0x2a, 0x2a, 0x3f }, { 0x00, 0x15, 0x00 }, { 0x00, 0x15, 0x2a }, { 0x00, 0x3f, 0x00 }, { 0x00, 0x3f, 0x2a }, { 0x2a, 0x15, 0x00 }, { 0x2a, 0x15, 0x2a }, { 0x2a, 0x3f, 0x00 }, { 0x2a, 0x3f, 0x2a }, { 0x00, 0x15, 0x15 }, { 0x00, 0x15, 0x3f }, { 0x00, 0x3f, 0x15 }, { 0x00, 0x3f, 0x3f }, { 0x2a, 0x15, 0x15 }, { 0x2a, 0x15, 0x3f }, { 0x2a, 0x3f, 0x15 }, { 0x2a, 0x3f, 0x3f }, { 0x15, 0x00, 0x00 }, { 0x15, 0x00, 0x2a }, { 0x15, 0x2a, 0x00 }, { 0x15, 0x2a, 0x2a }, { 0x3f, 0x00, 0x00 }, { 0x3f, 0x00, 0x2a }, { 0x3f, 0x2a, 0x00 }, { 0x3f, 0x2a, 0x2a }, { 0x15, 0x00, 0x15 }, { 0x15, 0x00, 0x3f }, { 0x15, 0x2a, 0x15 }, { 0x15, 0x2a, 0x3f }, { 0x3f, 0x00, 0x15 }, { 0x3f, 0x00, 0x3f }, { 0x3f, 0x2a, 0x15 }, { 0x3f, 0x2a, 0x3f }, { 0x15, 0x15, 0x00 }, { 0x15, 0x15, 0x2a }, { 0x15, 0x3f, 0x00 }, { 0x15, 0x3f, 0x2a }, { 0x3f, 0x15, 0x00 }, { 0x3f, 0x15, 0x2a }, { 0x3f, 0x3f, 0x00 }, { 0x3f, 0x3f, 0x2a }, { 0x15, 0x15, 0x15 }, { 0x15, 0x15, 0x3f }, { 0x15, 0x3f, 0x15 }, { 0x15, 0x3f, 0x3f }, { 0x3f, 0x15, 0x15 }, { 0x3f, 0x15, 0x3f }, { 0x3f, 0x3f, 0x15 }, { 0x3f, 0x3f, 0x3f } }; /* Subroutine to write to a VGA controller port */ static void WriteVGA(int port, BYTE reg, BYTE value) { outportb(port,reg); outportb(port+1,value); } /* Read data from the VGA controller port */ static BYTE ReadVGA(int port, int reg) { outportb(port,reg); return(inportb(port+1)); } /* Subroutine outputs data to all the ports on a controller */ static void outregs(int port, int count, BYTE *table) { int i; for (i=0; i