#include long GetVesaMode(); void SetVesaMode (short Mode); typedef unsigned char byte; #define smBW40 0x0000 #define smCO40 0x0001 // CGA } #define smBW80 0x0002 #define smCO80 0x0003 // CGA,EGA,VGA } #define smMONO 0x0007 // CGA,EGA,VGA } #define sm40x12 0x80 // VGA } #define sm40x14 0x81 // VGA } #define sm40x25 0x82 // CGA,EGA,VGA } #define sm40x30 0x83 // VGA } #define sm40x34 0x84 // VGA } #define sm40x43 0x85 // VGA } #define sm40x50 0x86 // VGA } #define sm40x60 0x87 // VGA } #define sm80x12 0x90 // VGA } #define sm80x14 0x91 // VGA } #define sm80x25 0x92 // VGA } #define sm80x30 0x93 // VGA } #define sm80x34 0x94 // VGA } #define sm80x43 0x95 // EGA,VGA } #define sm80x50 0x96 // VGA } #define sm80x60 0x97 // VGA } #define sm94x12 0xA0 // VGA } #define sm94x14 0xA1 // VGA } #define sm94x25 0xA2 // VGA } #define sm94x30 0xA3 // VGA } #define sm94x34 0xA4 // VGA } #define sm94x43 0xA5 // VGA } #define sm94x50 0xA6 // VGA } #define sm94x60 0xA7 // VGA } #define smNonStandard 0x00FF #define vga200ScanLines 0x00 #define vga350ScanLines 0x01 #define vga400ScanLines 0x02 #define vga480ScanLines 0x03 // DN specific } #define vgaFont16x8 0x0C #define vgaFont14x8 0x00 #define vgaFont8x8 0x04 #define vga40Cols 0x00 #define vga80Cols 0x20 #define vga94Cols 0x30 // DN specific } #define EquipmentOfs 0x0010 // Word } #define CrtColsOfs 0x044A // Byte } #define CrtRowsOfs 0x0484 // Byte } #define CrtCharOfs 0x0485 // Byte } #define CrtInfoOfs 0x0087 // Byte } #define CrtPSizOfs 0x044C // Word } byte vm40x12 = vga200ScanLines | vgaFont16x8 | vga40Cols; byte vm80x12 = vga200ScanLines | vgaFont16x8 | vga80Cols; byte vm94x12 = vga200ScanLines | vgaFont16x8 | vga94Cols; byte vm40x14 = vga200ScanLines | vgaFont14x8 | vga40Cols; byte vm80x14 = vga200ScanLines | vgaFont14x8 | vga80Cols; byte vm94x14 = vga200ScanLines | vgaFont14x8 | vga94Cols; byte vm40x25 = vga400ScanLines | vgaFont16x8 | vga40Cols; byte vm80x25 = vga400ScanLines | vgaFont16x8 | vga80Cols; byte vm94x25 = vga400ScanLines | vgaFont16x8 | vga94Cols; byte vm40x30 = vga480ScanLines | vgaFont16x8 | vga40Cols; byte vm80x30 = vga480ScanLines | vgaFont16x8 | vga80Cols; byte vm94x30 = vga480ScanLines | vgaFont16x8 | vga94Cols; byte vm40x34 = vga480ScanLines | vgaFont14x8 | vga40Cols; byte vm80x34 = vga480ScanLines | vgaFont14x8 | vga80Cols; byte vm94x34 = vga480ScanLines | vgaFont14x8 | vga94Cols; byte vm40x43 = vga350ScanLines | vgaFont8x8 | vga40Cols; byte vm80x43 = vga350ScanLines | vgaFont8x8 | vga80Cols; byte vm94x43 = vga350ScanLines | vgaFont8x8 | vga94Cols; byte vm40x50 = vga400ScanLines | vgaFont8x8 | vga40Cols; byte vm80x50 = vga400ScanLines | vgaFont8x8 | vga80Cols; byte vm94x50 = vga400ScanLines | vgaFont8x8 | vga94Cols; byte vm40x60 = vga480ScanLines | vgaFont8x8 | vga40Cols; byte vm80x60 = vga480ScanLines | vgaFont8x8 | vga80Cols; byte vm94x60 = vga480ScanLines | vgaFont8x8 | vga94Cols; enum TVideoType { vtUnknown=0, vtMONO, vtCGA, vtEGA, vtVGA, vtXGA, vtSVGA, vtVBE2 }; static struct rminfo { long EDI; long ESI; long EBP; long reserved_by_system; long EBX; long EDX; long ECX; long EAX; short flags; short ES,DS,FS,GS,IP,CS,SP,SS; } RMI; typedef struct { byte ID[4]; short XAttr; byte res[512]; }VideoInfo; byte VideoType=vtUnknown, ButtonCount = 0; short ScreenMode, ScreenWidth, ScreenHeight,CursorLines; byte HiResScreen, CheckSnow; byte *ScreenBuffer; void SetDNMode(byte Mode) { union REGS r; if(VideoType= vtVGA } { switch(Mode) { case sm40x12: SetVgaMode ( vm40x12, 40*256+12 ); break; case sm40x14: SetVgaMode ( vm40x14, 40*256+14 ); break; case sm40x25: SetVgaMode ( vm40x25, 40*256+25 ); break; case sm40x30: SetVgaMode ( vm40x30, 40*256+30 ); break; case sm40x34: SetVgaMode ( vm40x34, 40*256+34 ); break; case sm40x43: SetVgaMode ( vm40x43, 40*256+43 ); break; case sm40x50: SetVgaMode ( vm40x50, 40*256+50 ); break; case sm40x60: SetVgaMode ( vm40x60, 40*256+60 ); break; case sm80x12: SetVgaMode ( vm80x12, 80*256+12 ); break; case sm80x14: SetVgaMode ( vm80x14, 80*256+14 ); break; case sm80x25: SetVgaMode ( vm80x25, 80*256+25 ); break; case sm80x30: SetVgaMode ( vm80x30, 80*256+30 ); break; case sm80x34: SetVgaMode ( vm80x34, 80*256+34 ); break; case sm80x43: SetVgaMode ( vm80x43, 80*256+43 ); break; case sm80x50: SetVgaMode ( vm80x50, 80*256+50 ); break; case sm80x60: SetVgaMode ( vm80x60, 80*256+60 ); break; case sm94x12: SetVgaMode ( vm94x12, 94*256+12 ); break; case sm94x14: SetVgaMode ( vm94x14, 94*256+14 ); break; case sm94x25: SetVgaMode ( vm94x25, 94*256+25 ); break; case sm94x30: SetVgaMode ( vm94x30, 94*256+30 ); break; case sm94x34: SetVgaMode ( vm94x34, 94*256+34 ); break; case sm94x43: SetVgaMode ( vm94x43, 94*256+43 ); break; case sm94x50: SetVgaMode ( vm94x50, 94*256+50 ); break; case sm94x60: SetVgaMode ( vm94x60, 94*256+60 ); break; } } } void SetVgaMode (byte Flags,short Size) { byte temp,temp1,temp2; union REGS r; r.h.ah = 0x12; r.h.al = Flags&vga480ScanLines; if(r.h.al>=vga480ScanLines) r.h.al--; r.h.bl = 0x30; int386(0x10,&r,&r); r.h.ah = 0x00; r.h.al = Flags&vga94Cols; r.h.al>>=4; if(r.h.al!=(vga94Cols>>4)) r.h.al++; int386(0x10,&r,&r); r.h.ah = 0x11; r.h.al = Flags&vgaFont16x8; r.h.al>>=2; r.h.al+=r.h.ah; r.h.bl = 0x00; int386(0x10,&r,&r); _asm{CLI}; //----- VGA OFF ------------------------ outp(0x3C4,0); outp(0x3C5,1); outp(0x3D4,23); outp(0x3D5,0x7F&inp(0x3D5)); outp(0x3D4,17); outp(0x3D5,0x7F&inp(0x3D5)); //-------------------------------------- if((vga94Cols&Flags) == vga94Cols) { outp(0x3C2,(0xF3&inp(0x3CC))|0x04); outp(0x3C4,0x01); outp(0x3C5,0x01|inp(0x3C5)); outp(0x3D4,0x00); outp(0x3D5,0x6C); outp(0x3D4,0x01); outp(0x3D5,0x5D); outp(0x3D4,0x02); outp(0x3D5,0x5E); outp(0x3D4,0x03); outp(0x3D5,0x8F); outp(0x3D4,0x04); outp(0x3D5,0x62); outp(0x3D4,0x05); outp(0x3D5,0x8E); outp(0x3D4,0x13); outp(0x3D5,0x2F); inp(0x3DA); outp(0x3C0,0x13); outp(0x3C0,0x00); outp(0x3C0,0x20); outp(0x3C0,0x20); } if((vga480ScanLines&Flags) == vga480ScanLines) { outp(0x3C2,0xC0|inp(0x3CC)); outp(0x3D4,6); outp(0x3D5,11); outp(0x3D4,7); outp(0x3D5,62); outp(0x3D4,9); outp(0x3D5,79); outp(0x3D4,16); outp(0x3D5,234); outp(0x3D4,17); outp(0x3D5,140); outp(0x3D4,18); outp(0x3D5,223); outp(0x3D4,21); outp(0x3D5,231); outp(0x3D4,22); outp(0x3D5,4); } if((vgaFont16x8&Flags)==vgaFont8x8) temp2=temp= 8; if((vgaFont16x8&Flags)==vgaFont14x8) temp2=temp=14; if((vgaFont16x8&Flags)==vgaFont16x8) temp2=temp=16; //-----Char Height---------------------- outp(0x3D4,0x09); temp1=0xE0&inp(0x3D5); outp(0x3D5,(--temp)|temp1); outp(0x3D4,0x0A); if((--temp)>10) --temp; outp(0x3D5,temp); outp(0x3D4,0x0B); outp(0x3D5,++temp); //----- VGA ON ------------------------- outp(0x3D4,17); outp(0x3D5,0x80|inp(0x3D5)); outp(0x3D4,23); outp(0x3D5,0x80|inp(0x3D5)); outp(0x3C4,0); outp(0x3C5,3); //-------------------------------------- _asm{sti}; *(byte *)(CrtCharOfs)=temp2; temp=Size>>8; temp1=Size; *(byte *)(CrtColsOfs)=temp; *(byte *)(CrtRowsOfs)=temp1-1; *(short *)(CrtPSizOfs)=(temp*temp1)<<1; } short FixCrtMode(short Mode) { byte modes[]={smMONO,smCO40,smCO80,sm40x25,sm80x25,sm80x43,sm40x12,sm40x14,sm40x30,sm40x34,sm40x43, sm40x50,sm40x60,sm80x12,sm80x14,sm80x30,sm80x34,sm80x50,sm80x60,sm94x12,sm94x14,sm94x25, sm94x30,sm94x34,sm94x43,sm94x50,sm94x60}; byte i,i1; if(Mode<256) { if(VideoType>=vtVGA)i1=27; else if(VideoType>=vtEGA)i1=6; else i1=5; for(i=0;i0x7F) { Mode1=FixCrtMode(Mode); if(Mode1>0x7F) if(Mode1<0x100) SetDNMode(Mode1); else SetVesaMode(Mode1); else {r.h.ah = 0; r.h.al = Mode1; int386(0x10,&r,&r);} SetCrtData(); } printf("2: x - %d, y - %d\n",ScreenWidth,ScreenHeight); } void DetectVideoType() { union REGS r; if(VideoType!=vtUnknown) return; VideoType=vtMONO; r.x.eax = 0x0; int386(0x11,&r,&r); if((r.h.al&0x30)==0x30) return; VideoType=vtCGA; r.h.ah = 0x12; r.w.bx=0xFF10; int386(0x10,&r,&r); if(r.h.bh == 0xFF) return; VideoType=vtEGA; r.w.ax = 0x1C00; r.w.cx=0x7; int386(0x10,&r,&r); if(r.h.al!=0x1C) { r.w.ax = 0x1200; r.h.bl=0x32; int386(0x10,&r,&r); // VGA, MCGA, enable video addressing if(r.h.al!=0x12) return; } VideoType=vtVGA; DetectVesaType(); return; } typedef struct { byte row; byte col; byte mode; } infmod; infmod modes_vid[]= { {12,40,sm40x12}, {14,40,sm40x14}, {25,40,sm40x25}, {30,40,sm40x30}, {34,40,sm40x34}, {43,40,sm40x43}, {50,40,sm40x50}, {60,40,sm40x60}, {12,80,sm80x12}, {14,80,sm80x14}, {25,80,sm80x25}, {30,80,sm80x30}, {34,80,sm80x34}, {43,80,sm80x43}, {50,80,sm80x50}, {60,80,sm80x60}, {12,94,sm94x12}, {14,94,sm94x14}, {25,94,sm94x25}, {30,94,sm94x30}, {34,94,sm94x34}, {43,94,sm94x43}, {50,94,sm94x50}, {60,94,sm94x60}, }; byte GetCrtMode() { int i; long temp; union REGS r; byte ch_of,row_of,col_of; DetectVideoType(); if((temp=GetVesaMode())<0x100) temp&=0x7F; if(temp==0xFFFF){ r.h.ah = 0x0F; int386(0x10,&r,&r); temp=r.w.ax&0x7F;} ch_of = *(byte *)(CrtCharOfs); row_of= *(byte *)(CrtRowsOfs); col_of= *(byte *)(CrtColsOfs); if(temp<0x100) row_of++; for(i=0;i= vtSVGA) {RMI.EAX = 0x4F03; RMI.EDX = 0x4E;} else return(0); r.x.eax = 0x0300; r.h.bl = 0x10; r.h.bh = 0; r.w.cx = 0; sr.ds=sr.es=FP_SEG(&RMI); r.x.edi = FP_OFF(&RMI); int386x(0x31, &r, &r, &sr); if(RMI.EAX == RMI.EDX) return(RMI.EBX); return 0; }; void DetectVesaType() { union REGS r; struct SREGS sr; short selector, segment; VideoInfo *P; r.w.ax=0x0100; r.w.bx=(sizeof(VideoInfo)+15)>>4; int386(0x31,&r,&r); segment=r.w.ax; selector=r.w.dx; memset(&RMI,0,sizeof(RMI)); RMI.ES=segment; RMI.EAX=0x4E00; P=(VideoInfo *)(segment<<4); strcpy(P->ID,"QQQQ"); r.x.eax = 0x0300; r.h.bl = 0x10; r.h.bh = 0; r.w.cx = 0; sr.ds=sr.es=FP_SEG(&RMI); r.x.edi = FP_OFF(&RMI); int386x(0x31,&r,&r,&sr); if(!strncmp(P->ID,"VESA",4)) VideoType=vtXGA; else { RMI.ES=segment; RMI.EAX=0x4F00; r.x.eax = 0x0300; r.h.bl = 0x10; r.h.bh = 0; r.w.cx = 0; sr.es = FP_SEG(&RMI); r.x.edi = FP_OFF(&RMI); int386x(0x31, &r, &r, &sr); if(!strncmp(P->ID,"VESA",4)) { VideoType=vtSVGA; strcpy(P->ID,"VBE2"); RMI.ES=segment; RMI.EAX=0x4F00; r.x.eax = 0x0300; r.h.bl = 0x10; r.h.bh = 0; r.w.cx = 0; sr.es = FP_SEG(&RMI); r.x.edi = FP_OFF(&RMI); int386x(0x31, &r, &r, &sr); if(!strncmp(P->ID,"VESA",4)) VideoType=vtVBE2; } } r.w.ax=0x0101; r.w.dx=selector; int386(0x31,&r,&r); } void SetVesaMode (short Mode) { VideoInfo *P; union REGS r; struct SREGS sr; short selector, segment; if(VideoType==vtXGA) { r.w.ax=0x0100; r.w.bx=(sizeof(VideoInfo)+15)>>4; int386(0x31,&r,&r); segment=r.w.ax; selector=r.w.dx; memset(&RMI,0,sizeof(RMI)); P=(VideoInfo *)(segment<<4); RMI.ES=segment; RMI.EAX=0x4E02; RMI.EBX=Mode; r.x.eax = 0x0300; r.h.bl = 0x10; r.h.bh = 0; r.w.cx = 0; sr.ds=sr.es=FP_SEG(&RMI); r.x.edi=FP_OFF(&RMI); int386x(0x31,&r,&r,&sr); r.w.ax=0x0101; r.w.dx=selector; int386(0x31,&r,&r); } else if(VideoType==vtSVGA) { RMI.EAX=0x4F02; RMI.EBX=Mode; r.x.eax=0x0300; r.h.bl=0x10; r.h.bh=0; r.w.cx=0; sr.ds=sr.es=FP_SEG(&RMI); r.x.edi=FP_OFF(&RMI); int386x(0x31,&r,&r,&sr); } }