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