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