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