OpenGL support under Cygwin/SDL
[btb/d2x.git] / arch / dos_vesa.c
1 /*
2  * $Source: /cvs/cvsroot/d2x/arch/dos_vesa.c,v $
3  * $Revision: 1.2 $
4  * $Author: bradleyb $
5  * $Date: 2001-01-29 13:35:08 $
6  *
7  * Dos VESA
8  *
9  * $Log: not supported by cvs2svn $
10  */
11
12 #ifdef HAVE_CONFIG_H
13 #include <conf.h>
14 #endif
15
16 #include <string.h>
17 #include "gr.h"
18 #include "grdef.h"
19 #include "u_dpmi.h"
20 #include "vesa.h"
21
22 #define SC_INDEX   0x3c4
23 #define CRTC_INDEX 0x3d4
24 #define CRTC_DATA  0x3d5
25
26 static int bankshift;
27 static int lastbank;
28
29 /* this comes from Allegro */
30 typedef struct vesa_mode_info
31 {
32    unsigned short ModeAttributes;
33    unsigned char  WinAAttributes;
34    unsigned char  WinBAttributes;
35    unsigned short WinGranularity;
36    unsigned short WinSize;
37    unsigned short WinASegment;
38    unsigned short WinBSegment;
39    unsigned long  WinFuncPtr;
40    unsigned short BytesPerScanLine;
41    unsigned short XResolution;
42    unsigned short YResolution;
43    unsigned char  XCharSize;
44    unsigned char  YCharSize;
45    unsigned char  NumberOfPlanes;
46    unsigned char  BitsPerPixel;
47    unsigned char  NumberOfBanks;
48    unsigned char  MemoryModel;
49    unsigned char  BankSize;
50    unsigned char  NumberOfImagePages;
51    unsigned char  Reserved_page;
52    unsigned char  RedMaskSize;
53    unsigned char  RedMaskPos;
54    unsigned char  GreenMaskSize;
55    unsigned char  GreenMaskPos;
56    unsigned char  BlueMaskSize;
57    unsigned char  BlueMaskPos;
58    unsigned char  ReservedMaskSize;
59    unsigned char  ReservedMaskPos;
60    unsigned char  DirectColorModeInfo;
61    unsigned long  PhysBasePtr;
62    unsigned long  OffScreenMemOffset;
63    unsigned short OffScreenMemSize;
64    unsigned char  Reserved[206];
65 } __attribute__ ((packed)) vesa_mode_info;
66
67
68 int gr_vesa_checkmode(int mode) {
69         int i;
70         dpmi_real_regs rregs;
71         vesa_mode_info *mode_info;
72
73         if (!(mode_info = dpmi_get_temp_low_buffer( 1024 )))
74             return 7;
75         rregs.eax = 0x4f01;
76         rregs.ecx = mode;
77         rregs.edi = DPMI_real_offset(mode_info);
78         rregs.es = DPMI_real_segment(mode_info);
79         dpmi_real_int386x( 0x10, &rregs );
80         if (rregs.eax != 0x4f)
81                 return 5; /* no vesa */
82         if (!(mode_info->ModeAttributes & 1))
83                 return 4; /* unsupported mode */
84
85         bankshift = 0;
86         i = mode_info->WinGranularity;
87         while (i < 64) {
88                 i <<= 1;
89                 bankshift++;
90         }
91         if (i != 64)
92                 return 2; /* incompatible window granularity */
93         return 0;
94 }
95
96 int gr_vesa_setmode(int mode) {
97     int ret;
98     lastbank = -1;
99     if ((ret = gr_vesa_checkmode(mode)))
100         return ret;
101     asm volatile("int $0x10" : "=a" (ret) : "a" (0x4f02), "b" (mode));
102     return (ret == 0x4f) ? 0 : 4;
103 }
104
105 inline void gr_vesa_setpage(int bank) {
106     if (bank != lastbank)
107         asm volatile("int $0x10"
108          : : "a" (0x4f05), "b" (0), "d" ((lastbank = bank) << bankshift));
109 }
110
111 void gr_vesa_incpage() {
112     gr_vesa_setpage(lastbank + 1);
113 }
114
115 void gr_vesa_setstart(int col, int row) {
116     asm volatile("int $0x10"
117      : : "a" (0x4f07), "b" (0), "c" (col), "d" (row));
118 }
119
120 int gr_vesa_setlogical(int line_width) {
121     int ret;
122     asm volatile("int $0x10"
123      : "=c" (ret) : "a" (0x4f07), "b" (0), "c" (line_width));
124     return ret;
125 }
126
127 void gr_vesa_scanline(int x1, int x2, int y, unsigned char color) {
128     int addr = (y * gr_var_bwidth) + x1;
129     int left = x2 - x1 + 1;
130     gr_vesa_setpage(addr >> 16);
131     addr &= 0xffff;
132     while (left) {
133         if (left > (65536 - addr)) {
134             left -= (65536 - addr);
135             memset(gr_video_memory + addr, color, 65536 - addr);
136             addr = 0;
137             gr_vesa_incpage();
138         } else {
139             memset(gr_video_memory + addr, color, left);
140             left = 0;
141         }
142     }
143 }
144
145 void gr_vesa_pixel(unsigned char color, unsigned int addr) {
146     gr_vesa_setpage(addr >> 16);
147     gr_video_memory[addr & 0xffff] = color;
148 }