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

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: 
1.1.1.2 ! root      796: int SetMode(int ModeNumber, int Linear, int Debug) {
1.1       root      797:     _go32_dpmi_registers IntRegs;
                    798: 
                    799:     switch(InternalModeList[ModeNumber].ControlType) {
                    800:        case TVBE:
1.1.1.2 ! root      801:            if (Debug) printf ("Using VESA BIOS.\n");
1.1       root      802:            IntRegs.x.ax = 0x4F02;
                    803:            if (ModeList[ModeNumber].ModeType == T16) {
                    804:                if (Linear)
                    805:                    return(0);
                    806:                IntRegs.x.bx = InternalModeList[ModeNumber].OriginalModeNumber;
                    807:                ModeList[ModeNumber].ChangeBank = NULL_ChangeBank;
                    808:                ModeList[ModeNumber].PutLine = PutLineVGA16;
                    809:            } else if (Linear) {
                    810:                if (!ModeList[ModeNumber].HasLinear)
                    811:                    return(0);
                    812:                IntRegs.x.bx = InternalModeList[ModeNumber].OriginalModeNumber | (1<<14);
                    813:                ModeList[ModeNumber].ChangeBank = NULL_ChangeBank;
                    814:                ModeList[ModeNumber].PutLine = PutLineLinear;
                    815:            } else {
                    816:                if (!ModeList[ModeNumber].HasWindow)
                    817:                    return(0);
                    818:                IntRegs.x.bx = InternalModeList[ModeNumber].OriginalModeNumber;
                    819:                if (HasProtectedModeInterface) {
1.1.1.2 ! root      820:                    if (Debug) printf ("Using Protected Mode Bank Switch Function.\n");
1.1       root      821:                    ModeList[ModeNumber].ChangeBank = VBE_ChangeBankProtectMode;
                    822:                } else if ((InternalModeList[ModeNumber].WinFuncPtrSegment != 0) && (InternalModeList[ModeNumber].WinFuncPtrOffset != 0)) {
1.1.1.2 ! root      823:                    if (Debug) printf ("Using Real Mode Bank Switch Function.\n");
1.1       root      824:                    ModeList[ModeNumber].ChangeBank = VBE_ChangeBankRealMode;
                    825:                } else {
1.1.1.2 ! root      826:                    if (Debug) printf ("Using Real Mode Bank Switch Interrupt Function.\n");
1.1       root      827:                    ModeList[ModeNumber].ChangeBank = VBE_ChangeBankRealInterrupt;
                    828:                }
                    829:                ModeList[ModeNumber].PutLine = PutLineBanked;
                    830:            }
                    831:            IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0;
                    832:            _go32_dpmi_simulate_int(0x10, &IntRegs);
                    833:            break;
                    834:        case TVGA:
1.1.1.2 ! root      835:            if (Debug) printf ("Using normal VGA.\n");
1.1       root      836:            IntRegs.h.ah = 0x00;
                    837:            IntRegs.h.al = InternalModeList[ModeNumber].OriginalModeNumber;
                    838:            IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0;
                    839:            _go32_dpmi_simulate_int(0x10, &IntRegs);
                    840:            ModeList[ModeNumber].ChangeBank = NULL_ChangeBank;
                    841:            if (ModeList[ModeNumber].ModeType == T16)
                    842:                ModeList[ModeNumber].PutLine = PutLineVGA16;
                    843:            else
                    844:                ModeList[ModeNumber].PutLine = PutLineLinear;
                    845:            break;
                    846:        case TModeX:
1.1.1.2 ! root      847:            if (Debug) printf ("Using VGA Mode X.\n");
1.1       root      848:            SetModeX(InternalModeList[ModeNumber].OriginalModeNumber);
                    849:            ModeList[ModeNumber].ChangeBank = NULL_ChangeBank;
                    850:            ModeList[ModeNumber].PutLine = PutLineVGAX;
                    851:            break;
                    852:     }
                    853:     CurrentMode = ModeList[ModeNumber];
                    854:     CurrentInternalMode = InternalModeList[ModeNumber];
                    855:     RestoreOldVGAMode = 1;
                    856:     MapVideoMemory();
                    857:     return(1);
                    858: }
                    859: 
                    860: void SetModeX(int ModeNumber) {
                    861:     _go32_dpmi_registers IntRegs;
                    862:     int i;
                    863:     char cleared[320];
                    864: 
                    865:     IntRegs.h.ah = 0x00;
                    866:     IntRegs.h.al = 0x13;
                    867:     IntRegs.x.ss = IntRegs.x.sp = IntRegs.x.flags = 0;
                    868:     _go32_dpmi_simulate_int(0x10, &IntRegs);
                    869:     for (i=0; i<320; i++)
                    870:        cleared[i] = 0;
                    871:     outportw(0x3c4, 0x604);
                    872:     if (ModeNumber == 1) {
                    873:        outportw(0x3c4, 0x0100);
                    874:        outportb(0x3c2, 0x00e3);
                    875:        outportw(0x3c4, 0x0300);
                    876:        outportw(0x3d4, 0x2c11);
                    877:        outportw(0x3d4, 0x5f00);
                    878:        outportw(0x3d4, 0x4f01);
                    879:        outportw(0x3d4, 0x5002);
                    880:        outportw(0x3d4, 0x8203);
                    881:        outportw(0x3d4, 0x5404);
                    882:        outportw(0x3d4, 0x8005);
                    883:        outportw(0x3d4, 0x0d06);
                    884:        outportw(0x3d4, 0x3e07);
                    885:        outportw(0x3d4, 0x0008);
                    886:        outportw(0x3d4, 0x4109);
                    887:        outportw(0x3d4, 0x000a);
                    888:        outportw(0x3d4, 0x000b);
                    889:        outportw(0x3d4, 0x000c);
                    890:        outportw(0x3d4, 0x000d);
                    891:        outportw(0x3d4, 0x000e);
                    892:        outportw(0x3d4, 0x000f);
                    893:        outportw(0x3d4, 0xea10);
                    894:        outportw(0x3d4, 0xac11);
                    895:        outportw(0x3d4, 0xdf12);
                    896:        outportw(0x3d4, 0x2813);
                    897:        outportw(0x3d4, 0x0014);
                    898:        outportw(0x3d4, 0xe715);
                    899:        outportw(0x3d4, 0x0616);
                    900:        outportw(0x3d4, 0xe317);
                    901:        for (i=0; i<240; i++)
                    902:            PutLineVGAX(cleared, i);
                    903:     } else {
                    904:        outportw(0x3d4, 0x0e11);
                    905:        outportw(0x3d4, 0x5f00);
                    906:        outportw(0x3d4, 0x4f01);
                    907:        outportw(0x3d4, 0x5002);
                    908:        outportw(0x3d4, 0x8203);
                    909:        outportw(0x3d4, 0x5404);
                    910:        outportw(0x3d4, 0x8005);
                    911:        outportw(0x3d4, 0xbf06);
                    912:        outportw(0x3d4, 0x1f07);
                    913:        outportw(0x3d4, 0x0008);
                    914:        outportw(0x3d4, 0x4009);
                    915:        outportw(0x3d4, 0x000a);
                    916:        outportw(0x3d4, 0x000b);
                    917:        outportw(0x3d4, 0x000c);
                    918:        outportw(0x3d4, 0x000d);
                    919:        outportw(0x3d4, 0x000e);
                    920:        outportw(0x3d4, 0x000f);
                    921:        outportw(0x3d4, 0x9c10);
                    922:        outportw(0x3d4, 0x8e11);
                    923:        outportw(0x3d4, 0x8f12);
                    924:        outportw(0x3d4, 0x2813);
                    925:        outportw(0x3d4, 0x0014);
                    926:        outportw(0x3d4, 0x9615);
                    927:        outportw(0x3d4, 0xb916);
                    928:        outportw(0x3d4, 0xe317);
                    929:        for (i=0; i<400; i++)
                    930:            PutLineVGAX(cleared, i);
                    931:     }
                    932: }
                    933: 
                    934: void MapVideoMemory(void) {
                    935:     int Amont, AlignedAmont;
                    936:     unsigned int PhysicalPosition;
                    937:     char *NearPosition, *AlignedBufferPtr;
                    938: 
                    939:     if ((!CanMapBuffer) || (CurrentMode.MappedAddress != NULL))
                    940:        return;
                    941:     if ((CurrentMode.HasLinear) && (CurrentMode.ChangeBank == NULL_ChangeBank)) {
                    942:        Amont = CurrentMode.LinearSize;
                    943:        PhysicalPosition = CurrentInternalMode.LinearPosition;
                    944:        NearPosition = malloc(CurrentMode.LinearMappingSize);
                    945:     } else if (CurrentMode.HasWindow) {
                    946:        Amont = CurrentMode.WindowSize;
                    947:        PhysicalPosition = CurrentInternalMode.WindowPosition;
                    948:        NearPosition = malloc(CurrentMode.WindowMappingSize);
                    949:     } else
                    950:        return;
                    951:     if (NearPosition == NULL)
                    952:        return;
                    953:     AlignedBufferPtr = (char *) ALIGN(NearPosition);
                    954:     AlignedAmont = ALIGN(Amont);
                    955:     if (__djgpp_map_physical_memory(AlignedBufferPtr, AlignedAmont, PhysicalPosition)) {
                    956:        free(NearPosition);
                    957:        CurrentMode.MappedAddress = NULL;
                    958:     } else
                    959:        CurrentMode.MappedAddress = AlignedBufferPtr;
                    960: }

unix.superglobalmegacorp.com

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