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