|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * DOS VESA BIOS / VGA / Mode X graphics interface. ! 5: * ! 6: * (c) 1997 Gustavo Goedert ! 7: */ ! 8: ! 9: #include "sysconfig.h" ! 10: #include "sysdeps.h" ! 11: ! 12: #include <stdlib.h> ! 13: #include <dos.h> ! 14: #include <go32.h> ! 15: #include <dpmi.h> ! 16: #include <sys/farptr.h> ! 17: ! 18: #include "vbe.h" ! 19: ! 20: #define ALIGN(x) ((((int)(x)>>12)<<12)+4096) ! 21: #define PACKED __attribute__ ((packed)) ! 22: ! 23: /* externs in vbe.h */ ! 24: int NumberOfModes = 0; ! 25: T_ModeInfo *ModeList = NULL; ! 26: T_ModeInfo CurrentMode; ! 27: int CanMapBuffer = 0; ! 28: int CurrentBankNumber = 0; ! 29: /* end from vbe.h */ ! 30: ! 31: enum VBE_MemoryModels { ! 32: TextMode, CGA_Graphics, HerculesGraphics, Planar, ! 33: PackedPixel, ModeX, DirectColor, YUV ! 34: }; ! 35: ! 36: typedef struct { ! 37: char VbeSignature[4] PACKED; // = VBE2 ! 38: short VbeVersion PACKED; ! 39: char *OemStringPtr PACKED; ! 40: char Capabilities[4] PACKED; ! 41: unsigned int VideoModePtr PACKED; ! 42: short TotalMemory PACKED; ! 43: short OemSoftwareRev PACKED; ! 44: char *OemVendorNamePtr PACKED; ! 45: char *OemProductNamePtr PACKED; ! 46: char *OemProductRevPtr PACKED; ! 47: char Reserved[222] PACKED; ! 48: char OemData[256] PACKED; ! 49: } T_VBE_VbeInfoBlock; ! 50: ! 51: typedef struct { ! 52: // Mandatory information for all VBE revisions ! 53: short ModeAttributes PACKED; ! 54: char WinAAttributes PACKED; ! 55: char WinBAttributes PACKED; ! 56: short WinGranularity PACKED; ! 57: unsigned short WinSize PACKED; ! 58: unsigned short WinASegment PACKED; ! 59: unsigned short WinBSegment PACKED; ! 60: unsigned int WinFuncPtr PACKED; ! 61: short BytesPerScanLine PACKED; ! 62: // Mandatory information for VBE 1.2 and above ! 63: short XResolution PACKED; ! 64: short YResolution PACKED; ! 65: char XCharSize PACKED; ! 66: char YCharSize PACKED; ! 67: char NumberOfPlanes PACKED; ! 68: char BitsPerPixel PACKED; ! 69: char NumberOfBanks PACKED; ! 70: char MemoryModel PACKED; ! 71: char BankSize PACKED; ! 72: char NumberOfImagePages PACKED; ! 73: char ReservedA PACKED; // = 1 ! 74: // Direct Color fields (required for direct/6 and YUV/7 memory models) ! 75: char RedMaskSize PACKED; ! 76: char RedFieldPosition PACKED; ! 77: char GreenMaskSize PACKED; ! 78: char GreenFieldPosition PACKED; ! 79: char BlueMaskSize PACKED; ! 80: char BlueFieldPosition PACKED; ! 81: char RsvdMaskSize PACKED; ! 82: char RsvdFieldPosition PACKED; ! 83: char DirectColorModeInfo PACKED; ! 84: // Mandatory information for VBE 2.0 and above ! 85: unsigned int PhysBasePtr PACKED; ! 86: unsigned int OffScreenMemOffset PACKED; ! 87: short OffScreenMemSize PACKED; ! 88: char ReservedB[206] PACKED; ! 89: } T_VBE_ModeInfoBlock; ! 90: ! 91: typedef struct { ! 92: short SetWindowOffset PACKED; ! 93: short SetDisplayStartOffset PACKED; ! 94: short SetPrimaryPaletteDataOffset PACKED; ! 95: short PortsMemoryOffset PACKED; ! 96: } T_VBE_ProtectedModeInterface; ! 97: ! 98: typedef enum {TVBE, TVGA, TModeX} T_ControlType; ! 99: ! 100: typedef struct { ! 101: T_ModeType ModeType; ! 102: int OriginalModeNumber; ! 103: int ModeWidth, ModeHeight; ! 104: int BitsPerPixel, BitsPerColor; ! 105: int RedSize, RedPosition; ! 106: int GreenSize, GreenPosition; ! 107: int BlueSize, BluePosition; ! 108: } T_VBE_Table; ! 109: ! 110: typedef struct { ! 111: T_ControlType ControlType; ! 112: int OriginalModeNumber; ! 113: int WriteWindow; ! 114: int FastWinCalc; ! 115: int GranularityFix; ! 116: unsigned int WinMask1, WinMask2; ! 117: unsigned int WinFuncPtrSegment, WinFuncPtrOffset; ! 118: unsigned int WindowPosition, LinearPosition; ! 119: } T_ModeInternalInfo; ! 120: ! 121: T_ModeInfo VGA_InfoTable[7] = { ! 122: {T16, 320, 200, 8, 4, 0, 0, 0, 0, 0, 0, 40, 40, 0, 0, 0x10000, 0xa0000, 0, 0, 0, 0, NULL, NULL, NULL}, ! 123: {T16, 640, 200, 8, 4, 0, 0, 0, 0, 0, 0, 80, 80, 0, 0, 0x10000, 0xa0000, 0, 0, 0, 0, NULL, NULL, NULL}, ! 124: {T16, 640, 350, 8, 4, 0, 0, 0, 0, 0, 0, 80, 80, 0, 0, 0x10000, 0xa0000, 0, 0, 0, 0, NULL, NULL, NULL}, ! 125: {T16, 640, 480, 8, 4, 0, 0, 0, 0, 0, 0, 80, 80, 0, 0, 0x10000, 0xa0000, 0, 0, 0, 0, NULL, NULL, NULL}, ! 126: {T256, 320, 200, 8, 8, 0, 0, 0, 0, 0, 0, 320, 320, 1, 0x10000, 0x12000, 0xa0000, 1, 0x10000, 0x12000, 0xa0000, NULL, NULL, NULL}, ! 127: {T256, 320, 240, 8, 8, 0, 0, 0, 0, 0, 0, 80, 80, 0, 0, 0x10000, 0xa0000, 0, 0, 0, 0, NULL, NULL, NULL}, ! 128: {T256, 320, 400, 8, 8, 0, 0, 0, 0, 0, 0, 80, 80, 0, 0, 0x10000, 0xa0000, 0, 0, 0, 0, NULL, NULL, NULL} ! 129: /* {T256, 320, 480 ! 130: {T256, 360, 200 ! 131: {T256, 360, 400 ! 132: {T256, 360, 480*/ ! 133: }; ! 134: ! 135: T_ModeInternalInfo VGA_InternalInfoTable[7] = { ! 136: {TVGA, 0x0d, 0, 0, 0, 0, 0, 0, 0, 0xa0000, 0}, ! 137: {TVGA, 0x0e, 0, 0, 0, 0, 0, 0, 0, 0xa0000, 0}, ! 138: {TVGA, 0x10, 0, 0, 0, 0, 0, 0, 0, 0xa0000, 0}, ! 139: {TVGA, 0x12, 0, 0, 0, 0, 0, 0, 0, 0xa0000, 0}, ! 140: {TVGA, 0x13, 0, 0, 0, 0, 0, 0, 0, 0xa0000, 0xa0000}, ! 141: {TModeX, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0}, ! 142: {TModeX, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0} ! 143: /* {TModeX, 0x03 ! 144: {TModeX, 0x04 ! 145: {TModeX, 0x05 ! 146: {TModeX, 0x06*/ ! 147: }; ! 148: ! 149: T_VBE_Table VBE_Table[24] = { ! 150: {T16, 0x6a, 800, 600, 8, 4, 0, 0, 0, 0, 0, 0}, ! 151: {T256, 0x100, 640, 400, 8, 8, 0, 0, 0, 0, 0, 0}, ! 152: {T256, 0x101, 640, 480, 8, 8, 0, 0, 0, 0, 0, 0}, ! 153: {T16, 0x102, 800, 600, 8, 4, 0, 0, 0, 0, 0, 0}, ! 154: {T256, 0x103, 800, 600, 8, 8, 0, 0, 0, 0, 0, 0}, ! 155: {T16, 0x104, 1024, 768, 8, 4, 0, 0, 0, 0, 0, 0}, ! 156: {T256, 0x105, 1024, 768, 8, 8, 0, 0, 0, 0, 0, 0}, ! 157: {T16, 0x106, 1280, 1024, 8, 4, 0, 0, 0, 0, 0, 0}, ! 158: {T256, 0x107, 1280, 1024, 8, 8, 0, 0, 0, 0, 0, 0}, ! 159: {T32K, 0x10d, 320, 200, 16, 15, 5, 10, 5, 5, 5, 0}, ! 160: {T64K, 0x10e, 320, 200, 16, 16, 5, 11, 6, 5, 5, 0}, ! 161: {T16M, 0x10f, 320, 200, 24, 24, 8, 16, 8, 8, 8, 0}, ! 162: {T32K, 0x110, 640, 480, 16, 15, 5, 10, 5, 5, 5, 0}, ! 163: {T64K, 0x111, 640, 480, 16, 16, 5, 11, 6, 5, 5, 0}, ! 164: {T16M, 0x112, 640, 480, 24, 24, 8, 16, 8, 8, 8, 0}, ! 165: {T32K, 0x113, 800, 600, 16, 15, 5, 10, 5, 5, 5, 0}, ! 166: {T64K, 0x114, 800, 600, 16, 16, 5, 11, 6, 5, 5, 0}, ! 167: {T16M, 0x115, 800, 600, 24, 24, 8, 16, 8, 8, 8, 0}, ! 168: {T32K, 0x116, 1024, 768, 16, 15, 5, 10, 5, 5, 5, 0}, ! 169: {T64K, 0x117, 1024, 768, 16, 16, 5, 11, 6, 5, 5, 0}, ! 170: {T16M, 0x118, 1024, 768, 24, 24, 8, 16, 8, 8, 8, 0}, ! 171: {T32K, 0x119, 1280, 1024, 16, 15, 5, 10, 5, 5, 5, 0}, ! 172: {T64K, 0x11a, 1280, 1024, 16, 16, 5, 11, 6, 5, 5, 0}, ! 173: {T16M, 0x11b, 1280, 1024, 24, 24, 8, 16, 8, 8, 8, 0} ! 174: }; ! 175: ! 176: int HasVbe = 0; ! 177: int HasProtectedModeInterface = 0; ! 178: int RestoreOldVGAMode = 0, OldVGAMode; ! 179: ! 180: T_VBE_VbeInfoBlock VBE_VbeInfoBlock; ! 181: T_VBE_ModeInfoBlock VBE_ModeInfoBlock; ! 182: T_VBE_ProtectedModeInterface *VBE_ProtectedModeInterface; ! 183: short VBE_ModeList[512]; ! 184: unsigned int WinFuncPtrPM; ! 185: short *PortsMemory; ! 186: ! 187: T_ModeInternalInfo *InternalModeList = NULL; ! 188: T_ModeInternalInfo CurrentInternalMode; ! 189: char *LinearVgaBuffer, *AlignedLinearVgaBuffer; ! 190: ! 191: unsigned char PaletteData[768]; ! 192: _go32_dpmi_seginfo PaletteMem; ! 193: ! 194: int VBE_GetVbeInfoBlock(void); ! 195: int VBE_GetModeInfoBlock(int mode); ! 196: int VBE_GetProtectedModeInterface(void); ! 197: void VBE_ChangeBankRealInterrupt(int BankNumber); ! 198: void VBE_ChangeBankRealMode(int BankNumber); ! 199: void VBE_ChangeBankProtectMode(int BankNumber); ! 200: void NULL_ChangeBank(int BankNumber); ! 201: void PutLineLinear(char *addr, int target_y); ! 202: void PutLineBanked(char *addr, int target_y); ! 203: void PutLineVGA16(char *addr, int target_y); ! 204: void PutLineVGAX(char *addr, int target_y); ! 205: void InsertMode(T_ModeInfo *ModeInfo, T_ModeInternalInfo *ModeInternalInfo); ! 206: void SetModeX(int ModeNumber); ! 207: void MapVideoMemory(void); ! 208: ! 209: int VBE_GetVbeInfoBlock(void) { ! 210: _go32_dpmi_registers IntRegs; ! 211: ! 212: strncpy(VBE_VbeInfoBlock.VbeSignature, "VBE2", 4); ! 213: dosmemput(&VBE_VbeInfoBlock, sizeof(VBE_VbeInfoBlock), __tb); ! 214: IntRegs.x.ax = 0x4F00; ! 215: IntRegs.x.di = __tb & 0x0F; ! 216: IntRegs.x.es = (__tb >> 4) & 0xFFFF; ! 217: IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0; ! 218: _go32_dpmi_simulate_int(0x10, &IntRegs); ! 219: dosmemget(__tb, sizeof(VBE_VbeInfoBlock), &VBE_VbeInfoBlock); ! 220: return((IntRegs.x.ax == 0x004F) && (VBE_VbeInfoBlock.VbeVersion >= 0x0100)); ! 221: } ! 222: ! 223: int VBE_GetModeInfoBlock(int mode) { ! 224: _go32_dpmi_registers IntRegs; ! 225: ! 226: VBE_ModeInfoBlock.ReservedA = 1; ! 227: IntRegs.x.ax = 0x4F01; ! 228: IntRegs.x.cx = mode; ! 229: IntRegs.x.di = __tb & 0x0F; ! 230: IntRegs.x.es = (__tb >> 4) & 0xFFFF; ! 231: IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0; ! 232: _go32_dpmi_simulate_int(0x10, &IntRegs); ! 233: dosmemget(__tb, sizeof(VBE_ModeInfoBlock), &VBE_ModeInfoBlock); ! 234: return(IntRegs.x.ax == 0x004F); ! 235: } ! 236: ! 237: int VBE_GetProtectedModeInterface(void) { ! 238: _go32_dpmi_registers IntRegs; ! 239: ! 240: IntRegs.x.ax = 0x4F0A; ! 241: IntRegs.x.bx = 0x0000; ! 242: IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0; ! 243: _go32_dpmi_simulate_int(0x10, &IntRegs); ! 244: VBE_ProtectedModeInterface = (T_VBE_ProtectedModeInterface *) malloc(IntRegs.x.cx); ! 245: if (VBE_ProtectedModeInterface == NULL) ! 246: return(0); ! 247: dosmemget(IntRegs.x.es * 16 + IntRegs.x.di, IntRegs.x.cx, VBE_ProtectedModeInterface); ! 248: WinFuncPtrPM = (unsigned int) VBE_ProtectedModeInterface + VBE_ProtectedModeInterface->SetWindowOffset; ! 249: PortsMemory = (short *) VBE_ProtectedModeInterface + VBE_ProtectedModeInterface->PortsMemoryOffset; ! 250: return(IntRegs.x.ax == 0x004F); ! 251: } ! 252: ! 253: void VBE_ChangeBankRealInterrupt(int BankNumber) { ! 254: _go32_dpmi_registers IntRegs; ! 255: ! 256: IntRegs.x.ax = 0x4F05; ! 257: IntRegs.x.bx = CurrentInternalMode.WriteWindow; ! 258: IntRegs.x.dx = CurrentInternalMode.GranularityFix ? BankNumber * CurrentInternalMode.GranularityFix : BankNumber; ! 259: IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0; ! 260: _go32_dpmi_simulate_int(0x10, &IntRegs); ! 261: CurrentBankNumber = BankNumber; ! 262: } ! 263: ! 264: void VBE_ChangeBankRealMode(int BankNumber) { ! 265: _go32_dpmi_registers IntRegs; ! 266: ! 267: IntRegs.x.ax = 0x4F05; ! 268: IntRegs.x.bx = CurrentInternalMode.WriteWindow; ! 269: IntRegs.x.dx = CurrentInternalMode.GranularityFix ? BankNumber * CurrentInternalMode.GranularityFix : BankNumber; ! 270: IntRegs.x.cs = CurrentInternalMode.WinFuncPtrSegment; ! 271: IntRegs.x.ip = CurrentInternalMode.WinFuncPtrOffset; ! 272: IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0; ! 273: _go32_dpmi_simulate_fcall(&IntRegs); ! 274: CurrentBankNumber = BankNumber; ! 275: } ! 276: ! 277: void VBE_ChangeBankProtectMode(int BankNumber) { ! 278: int BNumber = CurrentInternalMode.GranularityFix ? BankNumber * CurrentInternalMode.GranularityFix : BankNumber; ! 279: ! 280: asm __volatile__ (" ! 281: push %%es ! 282: movw %0, %%es ! 283: call %1 ! 284: pop %%es ! 285: " ! 286: : ! 287: : "g" (_dos_ds), "r" (WinFuncPtrPM), "a" (0x4F05), "b" (CurrentInternalMode.WriteWindow), "d" (BNumber) ! 288: : "%ax", "%bx", "%dx", "cc", "memory" ! 289: ); ! 290: CurrentBankNumber = BankNumber; ! 291: _farsetsel(_dos_ds); ! 292: } ! 293: ! 294: void NULL_ChangeBank(int BankNumber) { ! 295: CurrentBankNumber = BankNumber; ! 296: } ! 297: ! 298: void PutLineLinear(char *addr, int target_y) { ! 299: unsigned int ptr; ! 300: ! 301: ptr = CurrentMode.LinearAddress + target_y * CurrentMode.LogicalLineLength; ! 302: asm __volatile__ (" ! 303: push %%es ! 304: cld ! 305: movw %0, %%es ! 306: shrl $2, %%ecx ! 307: rep ! 308: movsl ! 309: pop %%es ! 310: " ! 311: : ! 312: : "g" (_dos_ds), "S" (addr), "D" (ptr), "c" (CurrentMode.LineLength) ! 313: : "%esi", "%edi", "%ecx", "cc" ! 314: ); ! 315: } ! 316: ! 317: void PutLineBanked(char *addr, int target_y) { ! 318: unsigned int offs; ! 319: int page, pos, left; ! 320: char *ptr; ! 321: ! 322: offs = target_y * CurrentMode.LogicalLineLength; ! 323: if (CurrentInternalMode.FastWinCalc) { ! 324: page = offs >> CurrentInternalMode.WinMask1; ! 325: pos = offs & CurrentInternalMode.WinMask2; ! 326: } else { ! 327: page = offs / CurrentMode.WindowSize; ! 328: pos = offs % CurrentMode.WindowSize; ! 329: } ! 330: left = CurrentMode.WindowSize - pos; ! 331: ptr = (char *) CurrentMode.WindowAddress + pos; ! 332: if (page != CurrentBankNumber) ! 333: CurrentMode.ChangeBank(page); ! 334: if (left >= CurrentMode.LineLength) ! 335: asm __volatile__ (" ! 336: push %%es ! 337: cld ! 338: movw %0, %%es ! 339: shrl $2, %%ecx ! 340: rep ! 341: movsl ! 342: pop %%es ! 343: " ! 344: : ! 345: : "g" (_dos_ds), "S" (addr), "D" (ptr), "c" (CurrentMode.LineLength) ! 346: : "%esi", "%edi", "%ecx", "cc" ! 347: ); ! 348: else { ! 349: asm __volatile__ (" ! 350: push %%es ! 351: cld ! 352: movw %0, %%es ! 353: shrl $2, %%ecx ! 354: rep ! 355: movsl ! 356: pop %%es ! 357: " ! 358: : ! 359: : "g" (_dos_ds), "S" (addr), "D" (ptr), "c" (left) ! 360: : "%esi", "%edi", "%ecx", "cc" ! 361: ); ! 362: CurrentMode.ChangeBank(page+1); ! 363: asm __volatile__ (" ! 364: push %%es ! 365: cld ! 366: movw %0, %%es ! 367: addl %1, %%esi ! 368: subl %1, %%ecx ! 369: shrl $2, %%ecx ! 370: rep ! 371: movsl ! 372: pop %%es ! 373: " ! 374: : ! 375: : "g" (_dos_ds), "g" (left), "S" (addr), "D" (CurrentMode.WindowAddress), "c" (CurrentMode.LineLength) ! 376: : "%esi", "%edi", "%ecx", "cc" ! 377: ); ! 378: } ! 379: } ! 380: ! 381: void PutLineVGA16(char *addr, int target_y) { ! 382: unsigned int start, ptr; ! 383: int i; ! 384: UBYTE c; ! 385: ! 386: #if 0 ! 387: ptr = CurrentMode.WindowAddress + target_y * CurrentMode.LogicalLineLength; ! 388: outportw(0x3ce, 0x205); ! 389: outportw(0x3ce, 3); ! 390: for (i=0; i<CurrentMode.ModeWidth; i++) { ! 391: outportw(0x3ce, 1<<(((i&7)^7)+8)|8); ! 392: _farnspeekb(ptr+(i>>3)); ! 393: _farnspokeb(ptr+(i>>3), addr[i]); ! 394: } ! 395: #else ! 396: start = CurrentMode.WindowAddress + target_y * CurrentMode.LogicalLineLength; ! 397: ptr = start; ! 398: outportw(0x3c4, 0x802); ! 399: for (i=0; i<CurrentMode.ModeWidth; i+=8, ptr++) { ! 400: c = ((addr[i ]<<4)&128)|((addr[i+1]<<3)&64)|((addr[i+2]<<2)&32)|((addr[i+3]<<1)&16)| ! 401: ((addr[i+4] )&8 )|((addr[i+5]>>1)&4 )|((addr[i+6]>>2)&2 )|((addr[i+7]>>3)&1); ! 402: _farnspokeb(ptr, c); ! 403: } ! 404: ptr = start; ! 405: outportw(0x3c4, 0x402); ! 406: for (i=0; i<CurrentMode.ModeWidth; i+=8, ptr++) { ! 407: c = ((addr[i ]<<5)&128)|((addr[i+1]<<4)&64)|((addr[i+2]<<3)&32)|((addr[i+3]<<2)&16)| ! 408: ((addr[i+4]<<1)&8 )|((addr[i+5] )&4 )|((addr[i+6]>>1)&2 )|((addr[i+7]>>2)&1 ); ! 409: _farnspokeb(ptr, c); ! 410: } ! 411: ptr = start; ! 412: outportw(0x3c4, 0x202); ! 413: for (i=0; i<CurrentMode.ModeWidth; i+=8, ptr++) { ! 414: c = ((addr[i ]<<6)&128)|((addr[i+1]<<5)&64)|((addr[i+2]<<4)&32)|((addr[i+3]<<3)&16)| ! 415: ((addr[i+4]<<2)&8 )|((addr[i+5]<<1)&4 )|((addr[i+6] )&2 )|((addr[i+7]>>1)&1 ); ! 416: _farnspokeb(ptr, c); ! 417: } ! 418: ptr = start; ! 419: outportw(0x3c4, 0x102); ! 420: for (i=0; i<CurrentMode.ModeWidth; i+=8, ptr++) { ! 421: c = ((addr[i ]<<7)&128)|((addr[i+1]<<6)&64)|((addr[i+2]<<5)&32)|((addr[i+3]<<4)&16)| ! 422: ((addr[i+4]<<3)&8 )|((addr[i+5]<<2)&4 )|((addr[i+6]<<1)&2 )|((addr[i+7] )&1 ); ! 423: _farnspokeb(ptr, c); ! 424: } ! 425: #endif ! 426: } ! 427: ! 428: void PutLineVGAX(char *addr, int target_y) { ! 429: unsigned int start, ptr; ! 430: int i; ! 431: UBYTE c; ! 432: ! 433: start = CurrentMode.WindowAddress + target_y * CurrentMode.LogicalLineLength; ! 434: ptr = start; ! 435: outportw(0x3c4, 0x102); ! 436: for (i=0; i<CurrentMode.ModeWidth; i+=4, ptr++) ! 437: _farnspokeb(ptr, addr[i]); ! 438: ptr = start; ! 439: outportw(0x3c4, 0x202); ! 440: for (i=1; i<CurrentMode.ModeWidth; i+=4, ptr++) ! 441: _farnspokeb(ptr, addr[i]); ! 442: ptr = start; ! 443: outportw(0x3c4, 0x402); ! 444: for (i=2; i<CurrentMode.ModeWidth; i+=4, ptr++) ! 445: _farnspokeb(ptr, addr[i]); ! 446: ptr = start; ! 447: outportw(0x3c4, 0x802); ! 448: for (i=3; i<CurrentMode.ModeWidth; i+=4, ptr++) ! 449: _farnspokeb(ptr, addr[i]); ! 450: } ! 451: ! 452: void SetPalette(int Color, int Red, int Green, int Blue) { ! 453: _go32_dpmi_registers IntRegs; ! 454: ! 455: if (CurrentMode.ModeType == T16) { ! 456: IntRegs.h.ah = 0x10; ! 457: IntRegs.h.al = 0x00; ! 458: IntRegs.h.bh = Color; ! 459: IntRegs.h.bl = Color; ! 460: IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0; ! 461: _go32_dpmi_simulate_int(0x10, &IntRegs); ! 462: } ! 463: IntRegs.h.ah = 0x10; ! 464: IntRegs.h.al = 0x10; ! 465: IntRegs.x.bx = Color; ! 466: IntRegs.h.ch = Green; ! 467: IntRegs.h.cl = Blue; ! 468: IntRegs.h.dh = Red; ! 469: _go32_dpmi_simulate_int(0x10, &IntRegs); ! 470: DelayedSetPalette(Color, Red, Green, Blue); ! 471: } ! 472: ! 473: void DelayedSetPalette(int Color, int Red, int Green, int Blue) { ! 474: PaletteData[Color * 3 + 0] = Red; ! 475: PaletteData[Color * 3 + 1] = Green; ! 476: PaletteData[Color * 3 + 2] = Blue; ! 477: } ! 478: ! 479: void ViewPalette(int Color, int *Red, int *Green, int *Blue) { ! 480: *Red = PaletteData[Color * 3 + 0] << 2; ! 481: *Green = PaletteData[Color * 3 + 1] << 2; ! 482: *Blue = PaletteData[Color * 3 + 2] << 2; ! 483: } ! 484: ! 485: void LoadPalette(void) { ! 486: _go32_dpmi_registers IntRegs; ! 487: int i; ! 488: ! 489: dosmemput(PaletteData, 768, PaletteMem.rm_segment*16); ! 490: if (CurrentMode.ModeType == T16) { ! 491: for(i=0; i<16; i++) { ! 492: IntRegs.h.ah = 0x10; ! 493: IntRegs.h.al = 0x00; ! 494: IntRegs.h.bh = i; ! 495: IntRegs.h.bl = i; ! 496: IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0; ! 497: _go32_dpmi_simulate_int(0x10, &IntRegs); ! 498: } ! 499: } ! 500: IntRegs.h.ah = 0x10; ! 501: IntRegs.h.al = 0x12; ! 502: IntRegs.x.bx = 0; ! 503: if (CurrentMode.ModeType == T16) ! 504: IntRegs.x.cx = 16; ! 505: else ! 506: IntRegs.x.cx = 256; ! 507: IntRegs.x.es = PaletteMem.rm_segment; ! 508: IntRegs.x.dx = 0x0000; ! 509: IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0; ! 510: _go32_dpmi_simulate_int(0x10, &IntRegs); ! 511: } ! 512: ! 513: int InitGfxLib(void) { ! 514: static int GfxInicilized = 0; ! 515: _go32_dpmi_registers IntRegs; ! 516: __dpmi_meminfo MemoryInfo; ! 517: unsigned int DosMemPos; ! 518: int DiscartMode; ! 519: int i, j, TryList=1, CurrentList=0; ! 520: short ModeNumber; ! 521: T_ModeInfo ModeInfo; ! 522: T_ModeInternalInfo ModeInternalInfo; ! 523: ! 524: if (GfxInicilized) ! 525: return(1); ! 526: ! 527: /* Save Old VGA Mode */ ! 528: IntRegs.x.ax = 0x1C; ! 529: IntRegs.h.ah = 0x0F; ! 530: IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0; ! 531: _go32_dpmi_simulate_int(0x10, &IntRegs); ! 532: OldVGAMode = IntRegs.h.al; ! 533: ! 534: /* Allocate Palette Memory */ ! 535: PaletteMem.size = 48; ! 536: if (_go32_dpmi_allocate_dos_memory(&PaletteMem)) { ! 537: printf ("Can't allocate real mode memory for palette data.\n"); ! 538: return(0); ! 539: } ! 540: ! 541: /* Check for VBE */ ! 542: HasVbe = VBE_GetVbeInfoBlock(); ! 543: ! 544: /* Build ModeInfo Tables */ ! 545: if (HasVbe) { ! 546: printf ("VESA BIOS Extension version %d.%d found.\n", VBE_VbeInfoBlock.VbeVersion >> 8, VBE_VbeInfoBlock.VbeVersion & 0xFF); ! 547: if (VBE_VbeInfoBlock.VbeVersion >= 0x0200) ! 548: HasProtectedModeInterface = VBE_GetProtectedModeInterface(); ! 549: DosMemPos = (VBE_VbeInfoBlock.VideoModePtr >> 16) * 16 + ! 550: (VBE_VbeInfoBlock.VideoModePtr & 0xffff); ! 551: dosmemget(DosMemPos, 1024, VBE_ModeList); ! 552: VBE_ModeList[511] = -1; ! 553: i = 0; ! 554: while(1) { ! 555: if (TryList) { ! 556: ModeNumber = VBE_Table[CurrentList].OriginalModeNumber; ! 557: CurrentList++; ! 558: if (CurrentList == 25) ! 559: TryList = 0; ! 560: } else { ! 561: ModeNumber = VBE_ModeList[i]; ! 562: if (ModeNumber == -1) ! 563: break; ! 564: i++; ! 565: if ((ModeNumber == 0x6a) || ((ModeNumber >= 0x100) && (ModeNumber <= 0x107)) || ((ModeNumber >= 0x10d) && (ModeNumber <= 0x11b))) ! 566: continue; ! 567: } ! 568: if ((ModeNumber != (short)0x81ff) && VBE_GetModeInfoBlock(ModeNumber)) { ! 569: DiscartMode = 0; ! 570: if (!(VBE_ModeInfoBlock.ModeAttributes & 0x1)) ! 571: DiscartMode = 1; ! 572: ModeInternalInfo.OriginalModeNumber = ModeNumber; ! 573: ModeInternalInfo.ControlType = TVBE; ! 574: ModeInfo.RedSize = 0; ! 575: ModeInfo.RedPosition = 0; ! 576: ModeInfo.GreenSize = 0; ! 577: ModeInfo.GreenPosition = 0; ! 578: ModeInfo.BlueSize = 0; ! 579: ModeInfo.BluePosition = 0; ! 580: if (VBE_VbeInfoBlock.VbeVersion < 0x0102) { ! 581: if (VBE_ModeInfoBlock.ModeAttributes & 0x2) { ! 582: ModeInfo.ModeWidth = VBE_ModeInfoBlock.XResolution; ! 583: ModeInfo.ModeHeight = VBE_ModeInfoBlock.YResolution; ! 584: ModeInfo.BitsPerPixel = VBE_ModeInfoBlock.BitsPerPixel; ! 585: if (ModeInfo.BitsPerPixel == 15) ! 586: ModeInfo.BitsPerPixel = 16; ! 587: if (ModeInfo.BitsPerPixel == 4) { ! 588: ModeInfo.ModeType = T16; ! 589: ModeInfo.BitsPerPixel = 8; ! 590: ModeInfo.BitsPerColor = 4; ! 591: if (VBE_ModeInfoBlock.MemoryModel != Planar) ! 592: DiscartMode = 1; ! 593: } else if (ModeInfo.BitsPerPixel == 8) { ! 594: ModeInfo.ModeType = T256; ! 595: ModeInfo.BitsPerColor = 8; ! 596: if (VBE_ModeInfoBlock.MemoryModel != PackedPixel) ! 597: DiscartMode = 1; ! 598: } else if (ModeInfo.BitsPerPixel == 16) { ! 599: ModeInfo.ModeType = T32K; ! 600: ModeInfo.BitsPerColor = 15; ! 601: ModeInfo.RedSize = 5; ! 602: ModeInfo.RedPosition = 10; ! 603: ModeInfo.GreenSize = 5; ! 604: ModeInfo.GreenPosition = 5; ! 605: ModeInfo.BlueSize = 5; ! 606: ModeInfo.BluePosition = 0; ! 607: if (VBE_ModeInfoBlock.MemoryModel != PackedPixel) ! 608: DiscartMode = 1; ! 609: } else if ((ModeInfo.BitsPerPixel == 24) || (ModeInfo.BitsPerPixel == 32)) { ! 610: ModeInfo.ModeType = T16M; ! 611: ModeInfo.BitsPerColor = 24; ! 612: ModeInfo.RedSize = 8; ! 613: ModeInfo.RedPosition = 16; ! 614: ModeInfo.GreenSize = 8; ! 615: ModeInfo.GreenPosition = 8; ! 616: ModeInfo.BlueSize = 8; ! 617: ModeInfo.BluePosition = 0; ! 618: if (VBE_ModeInfoBlock.MemoryModel != PackedPixel) ! 619: DiscartMode = 1; ! 620: } else ! 621: DiscartMode = 1; ! 622: } else { ! 623: for (j = 0; j < 24; j++) { ! 624: if (VBE_Table[j].OriginalModeNumber == ModeInternalInfo.OriginalModeNumber) { ! 625: ModeInfo.ModeType = VBE_Table[j].ModeType; ! 626: ModeInfo.ModeWidth = VBE_Table[j].ModeWidth; ! 627: ModeInfo.ModeHeight = VBE_Table[j].ModeHeight; ! 628: ModeInfo.BitsPerPixel = VBE_Table[j].BitsPerPixel; ! 629: ModeInfo.BitsPerColor = VBE_Table[j].BitsPerColor; ! 630: ModeInfo.RedSize = VBE_Table[j].RedSize; ! 631: ModeInfo.RedPosition = VBE_Table[j].RedPosition; ! 632: ModeInfo.GreenSize = VBE_Table[j].GreenSize; ! 633: ModeInfo.GreenPosition = VBE_Table[j].GreenPosition; ! 634: ModeInfo.BlueSize = VBE_Table[j].BlueSize; ! 635: ModeInfo.BluePosition = VBE_Table[j].BluePosition; ! 636: break; ! 637: } ! 638: } ! 639: if (j == 24) ! 640: DiscartMode = 1; ! 641: } ! 642: } else { ! 643: ModeInfo.ModeWidth = VBE_ModeInfoBlock.XResolution; ! 644: ModeInfo.ModeHeight = VBE_ModeInfoBlock.YResolution; ! 645: ModeInfo.BitsPerPixel = VBE_ModeInfoBlock.BitsPerPixel; ! 646: if (ModeInfo.BitsPerPixel == 15) ! 647: ModeInfo.BitsPerPixel = 16; ! 648: if (ModeInfo.BitsPerPixel == 4) { ! 649: ModeInfo.ModeType = T16; ! 650: ModeInfo.BitsPerPixel = 8; ! 651: ModeInfo.BitsPerColor = 4; ! 652: if (VBE_ModeInfoBlock.MemoryModel != Planar) ! 653: DiscartMode = 1; ! 654: } else if (ModeInfo.BitsPerPixel == 8) { ! 655: ModeInfo.ModeType = T256; ! 656: ModeInfo.BitsPerColor = 8; ! 657: if (VBE_ModeInfoBlock.MemoryModel != PackedPixel) ! 658: DiscartMode = 1; ! 659: } else { ! 660: ModeInfo.RedSize = VBE_ModeInfoBlock.RedMaskSize; ! 661: ModeInfo.RedPosition = VBE_ModeInfoBlock.RedFieldPosition; ! 662: ModeInfo.GreenSize = VBE_ModeInfoBlock.GreenMaskSize; ! 663: ModeInfo.GreenPosition = VBE_ModeInfoBlock.GreenFieldPosition; ! 664: ModeInfo.BlueSize = VBE_ModeInfoBlock.BlueMaskSize; ! 665: ModeInfo.BluePosition = VBE_ModeInfoBlock.BlueFieldPosition; ! 666: ModeInfo.BitsPerColor = ModeInfo.RedSize + ModeInfo.GreenSize + ModeInfo.BlueSize; ! 667: if (ModeInfo.BitsPerColor == 15) { ! 668: ModeInfo.ModeType = T32K; ! 669: if (ModeInfo.BitsPerPixel != 16) ! 670: DiscartMode = 1; ! 671: } else if (ModeInfo.BitsPerColor == 16) { ! 672: ModeInfo.ModeType = T64K; ! 673: if (ModeInfo.BitsPerPixel != 16) ! 674: DiscartMode = 1; ! 675: } else if (ModeInfo.BitsPerColor == 24) { ! 676: ModeInfo.ModeType = T16M; ! 677: if ((ModeInfo.BitsPerPixel != 24) && (ModeInfo.BitsPerPixel != 32)) ! 678: DiscartMode = 1; ! 679: } else ! 680: DiscartMode = 1; ! 681: if (VBE_ModeInfoBlock.MemoryModel != DirectColor) ! 682: DiscartMode = 1; ! 683: } ! 684: } ! 685: ModeInfo.LineLength = (ModeInfo.BitsPerPixel >> 3) * ModeInfo.ModeWidth; ! 686: ModeInfo.LogicalLineLength = VBE_ModeInfoBlock.BytesPerScanLine; ! 687: ModeInfo.HasWindow = 0; ! 688: ModeInfo.HasLinear = 0; ! 689: if ((VBE_ModeInfoBlock.MemoryModel == PackedPixel) || (VBE_ModeInfoBlock.MemoryModel == DirectColor)) { ! 690: if (!(VBE_ModeInfoBlock.ModeAttributes & 0x40)) { ! 691: ModeInfo.HasWindow = 1; ! 692: if (VBE_ModeInfoBlock.WinFuncPtr != 0) { ! 693: ModeInternalInfo.WinFuncPtrSegment = VBE_ModeInfoBlock.WinFuncPtr >> 16; ! 694: ModeInternalInfo.WinFuncPtrOffset = VBE_ModeInfoBlock.WinFuncPtr & 0xffff; ! 695: } else { ! 696: ModeInternalInfo.WinFuncPtrSegment = 0; ! 697: ModeInternalInfo.WinFuncPtrOffset = 0; ! 698: } ! 699: ModeInfo.WindowSize = VBE_ModeInfoBlock.WinSize * 1024; ! 700: if ((VBE_ModeInfoBlock.WinAAttributes & 1) || (VBE_ModeInfoBlock.WinBAttributes & 1)) { ! 701: if ((!(VBE_ModeInfoBlock.WinBAttributes & 4)) || (VBE_ModeInfoBlock.WinAAttributes & 4)) { ! 702: ModeInternalInfo.WriteWindow = 0; ! 703: ModeInternalInfo.WindowPosition = ModeInfo.WindowAddress = VBE_ModeInfoBlock.WinASegment * 16; ! 704: } else { ! 705: ModeInternalInfo.WriteWindow = 1; ! 706: ModeInternalInfo.WindowPosition = ModeInfo.WindowAddress = VBE_ModeInfoBlock.WinBSegment * 16; ! 707: } ! 708: if (VBE_ModeInfoBlock.WinGranularity) { ! 709: ModeInternalInfo.GranularityFix = VBE_ModeInfoBlock.WinSize / VBE_ModeInfoBlock.WinGranularity; ! 710: if (ModeInternalInfo.GranularityFix == 1) ! 711: ModeInternalInfo.GranularityFix = 0; ! 712: } else ! 713: ModeInternalInfo.GranularityFix = 0; ! 714: } else ! 715: ModeInfo.WindowSize = ModeInfo.WindowAddress = ModeInternalInfo.GranularityFix = 0; ! 716: /* You never know... */ ! 717: if (ModeInfo.WindowSize == 0) ! 718: ModeInfo.WindowSize = 0x10000; ! 719: if (ModeInfo.WindowAddress == 0) ! 720: ModeInternalInfo.WindowPosition = ModeInfo.WindowAddress = 0xa0000; ! 721: ModeInternalInfo.FastWinCalc = 0; ! 722: for (j=1; j<32; j++) { ! 723: if (((unsigned int) 1<<j) == ModeInfo.WindowSize) { ! 724: ModeInternalInfo.FastWinCalc = 1; ! 725: ModeInternalInfo.WinMask1 = j; ! 726: ModeInternalInfo.WinMask2 = ModeInfo.WindowSize-1; ! 727: break; ! 728: } ! 729: } ! 730: ModeInfo.WindowMappingSize = ModeInfo.WindowSize + 0x2000; ! 731: } ! 732: if (VBE_ModeInfoBlock.ModeAttributes & 0x80) { ! 733: ModeInfo.HasLinear = 1; ! 734: ModeInternalInfo.LinearPosition = VBE_ModeInfoBlock.PhysBasePtr; ! 735: ModeInfo.LinearSize = ModeInfo.ModeHeight * ModeInfo.LogicalLineLength; ! 736: MemoryInfo.size = ModeInfo.LinearSize; ! 737: MemoryInfo.address = ModeInternalInfo.LinearPosition; ! 738: if (!__dpmi_physical_address_mapping(&MemoryInfo)) ! 739: ModeInfo.LinearAddress = MemoryInfo.address; ! 740: else ! 741: ModeInfo.LinearAddress = 0; ! 742: ModeInfo.LinearMappingSize = ModeInfo.LinearSize + 0x2000; ! 743: } ! 744: } ! 745: ModeInfo.ChangeBank = NULL; ! 746: ModeInfo.PutLine = NULL; ! 747: ModeInfo.MappedAddress = NULL; ! 748: if ((ModeInfo.ModeType == T16) && (ModeInfo.ModeHeight > 600)) //FIXME! not supported yeat ! 749: DiscartMode = 1; ! 750: if (!DiscartMode) ! 751: InsertMode(&ModeInfo, &ModeInternalInfo); ! 752: } ! 753: } ! 754: } ! 755: for (i = 0; i < 7; i++) ! 756: InsertMode(&VGA_InfoTable[i], &VGA_InternalInfoTable[i]); ! 757: ! 758: /* See if we can map */ ! 759: LinearVgaBuffer = malloc(0x11000); ! 760: if (LinearVgaBuffer != NULL) { ! 761: AlignedLinearVgaBuffer = (char *) ALIGN(LinearVgaBuffer); ! 762: if (!__djgpp_map_physical_memory(AlignedLinearVgaBuffer, 0x10000, 0xa0000)) ! 763: CanMapBuffer = 1; ! 764: } ! 765: ! 766: GfxInicilized = 1; ! 767: return(1); ! 768: } ! 769: ! 770: void CloseGfxLib(void) { ! 771: _go32_dpmi_registers IntRegs; ! 772: ! 773: if (RestoreOldVGAMode) { ! 774: IntRegs.x.ax = 0x1C; ! 775: IntRegs.h.ah = 0x00; ! 776: IntRegs.h.al = OldVGAMode; ! 777: IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0; ! 778: _go32_dpmi_simulate_int(0x10, &IntRegs); ! 779: } ! 780: _go32_dpmi_free_dos_memory(&PaletteMem); ! 781: } ! 782: ! 783: void InsertMode(T_ModeInfo *ModeInfo, T_ModeInternalInfo *ModeInternalInfo) { ! 784: if (NumberOfModes == 0) { ! 785: ModeList = malloc(sizeof(T_ModeInfo)); ! 786: InternalModeList = malloc(sizeof(T_ModeInternalInfo)); ! 787: } else { ! 788: ModeList = realloc(ModeList, sizeof(T_ModeInfo) * (NumberOfModes + 1)); ! 789: InternalModeList = realloc(InternalModeList, sizeof(T_ModeInternalInfo) * (NumberOfModes + 1)); ! 790: } ! 791: ModeList[NumberOfModes] = *ModeInfo; ! 792: InternalModeList[NumberOfModes] = *ModeInternalInfo; ! 793: NumberOfModes++; ! 794: } ! 795: ! 796: int SetMode(int ModeNumber, int Linear) { ! 797: _go32_dpmi_registers IntRegs; ! 798: static int FirstTime = 1; ! 799: ! 800: switch(InternalModeList[ModeNumber].ControlType) { ! 801: case TVBE: ! 802: if (FirstTime) printf ("Using VESA BIOS.\n"); ! 803: IntRegs.x.ax = 0x4F02; ! 804: if (ModeList[ModeNumber].ModeType == T16) { ! 805: if (Linear) ! 806: return(0); ! 807: IntRegs.x.bx = InternalModeList[ModeNumber].OriginalModeNumber; ! 808: ModeList[ModeNumber].ChangeBank = NULL_ChangeBank; ! 809: ModeList[ModeNumber].PutLine = PutLineVGA16; ! 810: } else if (Linear) { ! 811: if (!ModeList[ModeNumber].HasLinear) ! 812: return(0); ! 813: IntRegs.x.bx = InternalModeList[ModeNumber].OriginalModeNumber | (1<<14); ! 814: ModeList[ModeNumber].ChangeBank = NULL_ChangeBank; ! 815: ModeList[ModeNumber].PutLine = PutLineLinear; ! 816: } else { ! 817: if (!ModeList[ModeNumber].HasWindow) ! 818: return(0); ! 819: IntRegs.x.bx = InternalModeList[ModeNumber].OriginalModeNumber; ! 820: if (HasProtectedModeInterface) { ! 821: if (FirstTime) printf ("Using Protected Mode Bank Switch Function.\n"); ! 822: ModeList[ModeNumber].ChangeBank = VBE_ChangeBankProtectMode; ! 823: } else if ((InternalModeList[ModeNumber].WinFuncPtrSegment != 0) && (InternalModeList[ModeNumber].WinFuncPtrOffset != 0)) { ! 824: if (FirstTime) printf ("Using Real Mode Bank Switch Function.\n"); ! 825: ModeList[ModeNumber].ChangeBank = VBE_ChangeBankRealMode; ! 826: } else { ! 827: if (FirstTime) printf ("Using Real Mode Bank Switch Interrupt Function.\n"); ! 828: ModeList[ModeNumber].ChangeBank = VBE_ChangeBankRealInterrupt; ! 829: } ! 830: ModeList[ModeNumber].PutLine = PutLineBanked; ! 831: } ! 832: IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0; ! 833: _go32_dpmi_simulate_int(0x10, &IntRegs); ! 834: break; ! 835: case TVGA: ! 836: if (FirstTime) printf ("Using normal VGA.\n"); ! 837: IntRegs.h.ah = 0x00; ! 838: IntRegs.h.al = InternalModeList[ModeNumber].OriginalModeNumber; ! 839: IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0; ! 840: _go32_dpmi_simulate_int(0x10, &IntRegs); ! 841: ModeList[ModeNumber].ChangeBank = NULL_ChangeBank; ! 842: if (ModeList[ModeNumber].ModeType == T16) ! 843: ModeList[ModeNumber].PutLine = PutLineVGA16; ! 844: else ! 845: ModeList[ModeNumber].PutLine = PutLineLinear; ! 846: break; ! 847: case TModeX: ! 848: if (FirstTime) printf ("Using VGA Mode X.\n"); ! 849: SetModeX(InternalModeList[ModeNumber].OriginalModeNumber); ! 850: ModeList[ModeNumber].ChangeBank = NULL_ChangeBank; ! 851: ModeList[ModeNumber].PutLine = PutLineVGAX; ! 852: break; ! 853: } ! 854: CurrentMode = ModeList[ModeNumber]; ! 855: CurrentInternalMode = InternalModeList[ModeNumber]; ! 856: RestoreOldVGAMode = 1; ! 857: FirstTime = 0; ! 858: MapVideoMemory(); ! 859: return(1); ! 860: } ! 861: ! 862: void SetModeX(int ModeNumber) { ! 863: _go32_dpmi_registers IntRegs; ! 864: int i; ! 865: char cleared[320]; ! 866: ! 867: IntRegs.h.ah = 0x00; ! 868: IntRegs.h.al = 0x13; ! 869: IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0; ! 870: _go32_dpmi_simulate_int(0x10, &IntRegs); ! 871: for (i=0; i<320; i++) ! 872: cleared[i] = 0; ! 873: outportw(0x3c4, 0x604); ! 874: if (ModeNumber == 1) { ! 875: outportw(0x3c4, 0x0100); ! 876: outportb(0x3c2, 0x00e3); ! 877: outportw(0x3c4, 0x0300); ! 878: outportw(0x3d4, 0x2c11); ! 879: outportw(0x3d4, 0x5f00); ! 880: outportw(0x3d4, 0x4f01); ! 881: outportw(0x3d4, 0x5002); ! 882: outportw(0x3d4, 0x8203); ! 883: outportw(0x3d4, 0x5404); ! 884: outportw(0x3d4, 0x8005); ! 885: outportw(0x3d4, 0x0d06); ! 886: outportw(0x3d4, 0x3e07); ! 887: outportw(0x3d4, 0x0008); ! 888: outportw(0x3d4, 0x4109); ! 889: outportw(0x3d4, 0x000a); ! 890: outportw(0x3d4, 0x000b); ! 891: outportw(0x3d4, 0x000c); ! 892: outportw(0x3d4, 0x000d); ! 893: outportw(0x3d4, 0x000e); ! 894: outportw(0x3d4, 0x000f); ! 895: outportw(0x3d4, 0xea10); ! 896: outportw(0x3d4, 0xac11); ! 897: outportw(0x3d4, 0xdf12); ! 898: outportw(0x3d4, 0x2813); ! 899: outportw(0x3d4, 0x0014); ! 900: outportw(0x3d4, 0xe715); ! 901: outportw(0x3d4, 0x0616); ! 902: outportw(0x3d4, 0xe317); ! 903: for (i=0; i<240; i++) ! 904: PutLineVGAX(cleared, i); ! 905: } else { ! 906: outportw(0x3d4, 0x0e11); ! 907: outportw(0x3d4, 0x5f00); ! 908: outportw(0x3d4, 0x4f01); ! 909: outportw(0x3d4, 0x5002); ! 910: outportw(0x3d4, 0x8203); ! 911: outportw(0x3d4, 0x5404); ! 912: outportw(0x3d4, 0x8005); ! 913: outportw(0x3d4, 0xbf06); ! 914: outportw(0x3d4, 0x1f07); ! 915: outportw(0x3d4, 0x0008); ! 916: outportw(0x3d4, 0x4009); ! 917: outportw(0x3d4, 0x000a); ! 918: outportw(0x3d4, 0x000b); ! 919: outportw(0x3d4, 0x000c); ! 920: outportw(0x3d4, 0x000d); ! 921: outportw(0x3d4, 0x000e); ! 922: outportw(0x3d4, 0x000f); ! 923: outportw(0x3d4, 0x9c10); ! 924: outportw(0x3d4, 0x8e11); ! 925: outportw(0x3d4, 0x8f12); ! 926: outportw(0x3d4, 0x2813); ! 927: outportw(0x3d4, 0x0014); ! 928: outportw(0x3d4, 0x9615); ! 929: outportw(0x3d4, 0xb916); ! 930: outportw(0x3d4, 0xe317); ! 931: for (i=0; i<400; i++) ! 932: PutLineVGAX(cleared, i); ! 933: } ! 934: } ! 935: ! 936: void MapVideoMemory(void) { ! 937: int Amont, AlignedAmont; ! 938: unsigned int PhysicalPosition; ! 939: char *NearPosition, *AlignedBufferPtr; ! 940: ! 941: if ((!CanMapBuffer) || (CurrentMode.MappedAddress != NULL)) ! 942: return; ! 943: if ((CurrentMode.HasLinear) && (CurrentMode.ChangeBank == NULL_ChangeBank)) { ! 944: Amont = CurrentMode.LinearSize; ! 945: PhysicalPosition = CurrentInternalMode.LinearPosition; ! 946: NearPosition = malloc(CurrentMode.LinearMappingSize); ! 947: } else if (CurrentMode.HasWindow) { ! 948: Amont = CurrentMode.WindowSize; ! 949: PhysicalPosition = CurrentInternalMode.WindowPosition; ! 950: NearPosition = malloc(CurrentMode.WindowMappingSize); ! 951: } else ! 952: return; ! 953: if (NearPosition == NULL) ! 954: return; ! 955: AlignedBufferPtr = (char *) ALIGN(NearPosition); ! 956: AlignedAmont = ALIGN(Amont); ! 957: if (__djgpp_map_physical_memory(AlignedBufferPtr, AlignedAmont, PhysicalPosition)) { ! 958: free(NearPosition); ! 959: CurrentMode.MappedAddress = NULL; ! 960: } else ! 961: CurrentMode.MappedAddress = AlignedBufferPtr; ! 962: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.