Annotation of uae/src/od-dos/video/vbe.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.