annotate vbe.c @ 0:cbded07e50d8 default tip

*: initial commit here's a simple VBE thing. It's intended to be able to work pretty much anywhere, but I don't really have anything to test VBE 1.0 with (and i'm not entirely sure if this code works in the first place) it's balls simple, no BS, and ONLY works with DJGPP.
author Paper <paper@tflc.us>
date Sat, 02 Aug 2025 12:55:21 -0400
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
1 /**
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
2 * VBE.C -- interface into VESA BIOS extensions from DJGPP-compiled
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
3 * MS-DOS programs.
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
4 *
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
5 * Copyright (c) 2025 Paper
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
6 *
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
8 * of this software and associated documentation files (the "Software"), to deal
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
9 * in the Software without restriction, including without limitation the rights
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
11 * copies of the Software, and to permit persons to whom the Software is
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
12 * furnished to do so, subject to the following conditions:
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
13 *
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
14 * The above copyright notice and this permission notice shall be included in all
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
15 * copies or substantial portions of the Software.
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
16 *
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
23 * SOFTWARE.
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
24 **/
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
25
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
26 #include <stdio.h>
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
27 #include <stdint.h>
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
28 #include <dpmi.h>
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
29 #include <go32.h>
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
30 #include <sys/farptr.h>
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
31 #include <stdlib.h>
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
32 #include <string.h>
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
33 #include <inttypes.h>
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
34 #include <dos.h>
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
35
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
36 #include "vbe.h"
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
37
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
38 /* pack all structures */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
39 #pragma pack(push, 1)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
40
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
41 struct VbeInfoBlock {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
42 char VbeSignature[4];
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
43 uint16_t VbeVersion;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
44 uint16_t OemStringPtr[2];
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
45 uint8_t Capabilities[4];
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
46 uint16_t VideoModePtr[2];
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
47 uint16_t TotalMemory; /* in units of 64kB blocks */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
48 uint8_t Reserved[492];
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
49 };
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
50
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
51 struct VbeModeInfoBlock {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
52 uint16_t Attributes; /* deprecated */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
53 uint8_t WindowA; /* deprecated */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
54 uint8_t WindowB; /* deprecated */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
55 uint16_t Granularity; /* deprecated */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
56 uint16_t WindowSize;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
57 uint16_t SegmentA;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
58 uint16_t SegmentB;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
59 uint32_t WinFuncPtr; /* deprecated */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
60 uint16_t Pitch; /* bytes per horizontal line */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
61
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
62 /* --- OPTIONAL UNTIL VBE 1.2 */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
63 uint16_t Width; /* in pixels */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
64 uint16_t Height; /* in pixels */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
65 uint8_t WChar; /* unused */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
66 uint8_t YChar; /* unused */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
67 uint8_t Planes;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
68 uint8_t BitsPerPixel;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
69 uint8_t Banks; /* deprecated */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
70 uint8_t MemoryModel;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
71 uint8_t BankSize; /* deprecated, almost always 64kB but maybe 16kB */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
72 uint8_t ImagePages;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
73 uint8_t Reserved0[1];
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
74
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
75 /* Direct color fields */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
76 uint8_t RedMask;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
77 uint8_t RedPosition;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
78 uint8_t GreenMask;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
79 uint8_t GreenPosition;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
80 uint8_t BlueMask;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
81 uint8_t BluePosition;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
82 uint8_t ReservedMask;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
83 uint8_t ReservedPosition;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
84 uint8_t DirectColorAttributes;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
85
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
86 /* --- OPTIONAL UNTIL VBE 2.0 */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
87 uint32_t Framebuffer; /* physical address of the linear framebuffer */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
88
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
89 uint8_t Reserved1[6];
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
90
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
91 /* --- OPTIONAL UNTIL VBE 3.0 */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
92 uint16_t LinBytesPerScanLine; /* bytes per scan line for linear modes */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
93 uint8_t BnkNumberOfImagePages; /* number of images for banked modes */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
94 uint8_t LinNumberOfImagePages; /* number of images for linear modes */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
95 uint8_t LinRedMaskSize; /* size of direct color red mask (linear modes) */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
96 uint8_t LinRedFieldPosition; /* bit position of lsb of red mask (linear modes) */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
97 uint8_t LinGreenMaskSize; /* size of direct color green mask (linear modes) */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
98 uint8_t LinGreenFieldPosition; /* bit position of lsb of green mask (linear modes) */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
99 uint8_t LinBlueMaskSize; /* size of direct color blue mask (linear modes) */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
100 uint8_t LinBlueFieldPosition; /* bit position of lsb of blue mask (linear modes) */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
101 uint8_t LinRsvdMaskSize; /* size of direct color reserved mask (linear modes) */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
102 uint8_t LinRsvdFieldPosition; /* bit position of lsb of reserved mask (linear modes) */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
103 uint32_t MaxPixelClock; /* maximum pixel clock (in Hz) for graphics mode */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
104
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
105 uint8_t Reserved2[189];
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
106 };
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
107
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
108 #pragma pack(pop)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
109
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
110 #define VMI_ATTRIBUTE_HARDWARE 0x01
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
111 #define VMI_ATTRIBUTE_RESERVED 0x02 /* only relevant for VBE < 1.2 */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
112 #define VMI_ATTRIBUTE_TTY 0x04
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
113 #define VMI_ATTRIBUTE_COLOR 0x08
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
114 #define VMI_ATTRIBUTE_GRAPHICS 0x10
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
115 #define VMI_ATTRIBUTE_VGACOMPAT 0x20
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
116 #define VMI_ATTRIBUTE_VGAWINMEM 0x40
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
117 #define VMI_ATTRIBUTE_LINEARBUFFER 0x80 /* linear framebuffer */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
118 #define VMI_ATTRIBUTE_DOUBLESCAN 0x100 /* ? */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
119 #define VMI_ATTRIBUTE_INTERLACE 0x200
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
120 #define VMI_ATTRIBUTE_TRIPLEBUF 0x400
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
121 #define VMI_ATTRIBUTE_STEREOSCOPIC 0x800 /* huh? 3D?? */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
122
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
123 /* check if a selection of attributes is enabled */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
124 #define VMI_ATTRIBUTE(x, a) (((x) & (a)) == (a))
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
125
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
126 #define MIN(a, b) ((a)<(b)?(a):(b))
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
127
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
128 #define VBE_FARPTR(x) (((x)[1] * 16) + (x)[0])
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
129
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
130 /* ------------------------------------------------------------------------ */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
131 /* this code is kind of a mess, sorry... */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
132
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
133 /* loosely based off the information on the osdev wiki,
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
134 * thanks a lot!
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
135 *
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
136 * this function is a thin wrapper around real-mode
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
137 * VESA routines. `id` is the identifier that goes into
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
138 * the AX register, and `ptr` and `s` are the pointer and
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
139 * size the resulting structure is supposed to be.
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
140 * `cx`, is obviously the "cx" register. this only needs
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
141 * to be provided if the underlying function requires it. */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
142 static int vesa_get_block(uint16_t id, uint16_t cx, void *ptr, size_t s)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
143 {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
144 __dpmi_regs r;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
145 long dosbuf;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
146 size_t c;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
147
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
148 /* use the conventional memory transfer buffer */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
149 dosbuf = (__tb & 0xFFFFF);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
150
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
151 /* zero-initialize */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
152 for (c = 0; c < s; c++)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
153 _farpokeb(_dos_ds, dosbuf + c, 0);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
154
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
155 /* this isn't necessary for functions other than
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
156 * 0x4F00, but I suppose it won't hurt. */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
157 dosmemput("VBE2", 4, dosbuf);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
158
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
159 r.x.ax = id;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
160 r.x.cx = cx;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
161 r.x.di = dosbuf & 0xF;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
162 r.x.es = (dosbuf >> 4) & 0xFFFF;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
163 __dpmi_int(0x10, &r);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
164
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
165 /* high byte is the result code,
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
166 * low byte must always be 0x4F */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
167 if (r.x.ax != 0x004F)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
168 return -1;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
169
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
170 /* copy the resulting data into our structure */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
171 dosmemget(dosbuf, s, ptr);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
172
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
173 return 0;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
174 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
175
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
176 static int vesa_get_info(struct VbeInfoBlock *block)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
177 {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
178 if (vesa_get_block(0x4F00, 0, block, sizeof(*block)) != 0)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
179 return -1;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
180
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
181 if (memcmp(block->VbeSignature, "VESA", 4) != 0)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
182 return -1;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
183
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
184 return 0;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
185 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
186
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
187 /* This could probably be a public API. I just don't care enough. :) */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
188
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
189 typedef void (*vesa_video_mode_cb_spec)(uint16_t mode,
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
190 struct VbeModeInfoBlock *pvmi, void *userdata);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
191
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
192 static int vesa_enum_video_modes(const struct VbeInfoBlock *pvbe,
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
193 vesa_video_mode_cb_spec cb, void *userdata)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
194 {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
195 struct VbeModeInfoBlock vmi;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
196 uint16_t mode;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
197 uint32_t ptr;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
198
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
199 for (ptr = VBE_FARPTR(pvbe->VideoModePtr); /* nothing */; ptr += 2) {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
200 mode = _farpeekw(_dos_ds, ptr);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
201 if (mode == 0xFFFF)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
202 break; /* end marker */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
203
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
204 if (vesa_get_block(0x4F01, mode, &vmi, sizeof(vmi)) != 0)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
205 continue; /* ...? */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
206
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
207 cb(mode, &vmi, userdata);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
208 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
209
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
210 return 0;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
211 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
212
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
213 struct vesa_best_mode_info {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
214 uint16_t width;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
215 uint16_t height;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
216
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
217 /* video mode score; higher is better */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
218 int16_t score;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
219 /* video mode */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
220 uint16_t mode;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
221 struct VbeModeInfoBlock vmi;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
222 };
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
223
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
224 static void vesa_best_mode_cb(uint16_t mode, struct VbeModeInfoBlock *pvmi,
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
225 void *userdata)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
226 {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
227 struct vesa_best_mode_info *info = userdata;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
228 int16_t score = 0;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
229
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
230 /* need a graphics mode. linear framebuffer is optional ;)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
231 * we also need the "extended" bits that were optional in VBE <1.2.
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
232 * newer versions require that this bit be 1, so... */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
233 if (!VMI_ATTRIBUTE(pvmi->Attributes, VMI_ATTRIBUTE_RESERVED|VMI_ATTRIBUTE_COLOR|VMI_ATTRIBUTE_GRAPHICS|VMI_ATTRIBUTE_HARDWARE))
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
234 return;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
235
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
236 /* put significant emphasis on resolution, then
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
237 * prefer higher bpp if available. */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
238 if (!(pvmi->Width % info->width))
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
239 score += 16 / (pvmi->Width / info->width);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
240
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
241 if (!(pvmi->Height % info->height))
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
242 score += 16 / (pvmi->Width / info->width);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
243
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
244 score += (pvmi->BitsPerPixel / 8);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
245
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
246 if (score > info->score) {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
247 info->score = score;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
248 info->mode = mode;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
249 memcpy(&info->vmi, pvmi, sizeof(info->vmi));
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
250 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
251 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
252
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
253 static int vesa_find_best_mode(struct VbeInfoBlock *vbe, uint16_t width,
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
254 uint16_t height, uint16_t *pmode, struct VbeModeInfoBlock *pvmi)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
255 {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
256 struct vesa_best_mode_info bmi = {0};
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
257
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
258 /* start at non-zero, so we always get at least one valid video mode
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
259 * (that is, if the video card actually gives us any) */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
260 bmi.width = width;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
261 bmi.height = height;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
262 bmi.score = -1;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
263
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
264 vesa_enum_video_modes(vbe, vesa_best_mode_cb, &bmi);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
265
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
266 if (bmi.score == -1)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
267 return -1;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
268
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
269 *pmode = bmi.mode;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
270 memcpy(pvmi, &bmi.vmi, sizeof(*pvmi));
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
271
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
272 return 0;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
273 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
274
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
275 static int vesa_set_mode(uint16_t mode)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
276 {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
277 __dpmi_regs r;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
278
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
279 r.x.ax = 0x4F02;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
280 r.x.bx = mode;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
281
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
282 __dpmi_int(0x10, &r);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
283
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
284 if (r.x.ax != 0x004F)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
285 return -1;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
286
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
287 return 0;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
288 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
289
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
290 static int vesa_set_bank(int bank_number)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
291 {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
292 __dpmi_regs r;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
293
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
294 r.x.ax = 0x4F05;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
295 r.x.bx = 0;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
296 r.x.dx = bank_number;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
297
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
298 __dpmi_int(0x10, &r);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
299
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
300 if (r.x.ax != 0x004F)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
301 return -1;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
302
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
303 return 0;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
304 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
305
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
306 /* ------------------------------------------------------------------------ */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
307 /* plain VGA stuff for resetting the video mode */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
308
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
309 static void vga_set_mode(uint8_t mode)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
310 {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
311 __dpmi_regs r;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
312
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
313 r.h.ah = 0x00;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
314 r.h.al = mode;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
315
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
316 __dpmi_int(0x10, &r);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
317 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
318
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
319 /* ------------------------------------------------------------------------ */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
320 /* public functions and structures */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
321
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
322 static int vesa_init_fb(struct vbe *vbe, uint16_t mode, uint32_t fb_address)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
323 {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
324 /* since we're running from protected mode, we have to allocate
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
325 * a logical address that maps to the physical framebuffer. */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
326 __dpmi_meminfo mi;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
327
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
328 return -1;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
329
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
330 if (vesa_set_mode(mode | 0x4000) != 0)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
331 return -1;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
332
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
333 mi.address = fb_address;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
334 mi.size = vbe->size;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
335
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
336 if (__dpmi_physical_address_mapping(&mi) != 0)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
337 return -1;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
338
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
339 vbe->blit.fb.selector = __dpmi_allocate_ldt_descriptors(1);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
340 if (vbe->blit.fb.selector == -1)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
341 return -1;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
342
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
343 if (__dpmi_set_segment_base_address(vbe->blit.fb.selector, mi.address) != 0)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
344 return -1;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
345
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
346 if (__dpmi_set_segment_limit(vbe->blit.fb.selector, mi.size - 1) != 0)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
347 return -1;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
348
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
349 vbe->blit.fb.address = mi.address;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
350
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
351 return 0;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
352 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
353
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
354 int vbe_init(struct vbe *vbe, uint16_t width, uint16_t height)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
355 {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
356 struct VbeInfoBlock vib;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
357 struct VbeModeInfoBlock vmi;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
358 uint16_t mode;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
359
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
360 memset(vbe, 0, sizeof(*vbe));
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
361
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
362 if (vesa_get_info(&vib) != 0)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
363 return -1;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
364
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
365 if (vesa_find_best_mode(&vib, width, height, &mode, &vmi) != 0)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
366 return -1;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
367
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
368 /* I'm fairly sure this can be 15, for 5R-5G-5B. Whatever. :) */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
369 if (vmi.BitsPerPixel % 8)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
370 return -1;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
371
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
372 vbe->width = vmi.Width;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
373 vbe->height = vmi.Height;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
374 vbe->pitch = vmi.Pitch;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
375 vbe->bpp = (vmi.BitsPerPixel / 8);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
376
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
377 vbe->size = (vbe->pitch * vbe->height * vbe->bpp);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
378
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
379 if (VMI_ATTRIBUTE(vmi.Attributes, VMI_ATTRIBUTE_LINEARBUFFER)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
380 && !vesa_init_fb(vbe, mode, vmi.Framebuffer)) {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
381 vbe->blit_type = VBE_BLIT_FRAMEBUFFER;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
382 } else if (!vesa_set_mode(mode)) {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
383 vbe->blit_type = VBE_BLIT_BANKS;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
384
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
385 vbe->blit.banks.size = vmi.WindowSize * 1024;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
386 vbe->blit.banks.granularity = vmi.Granularity * 1024;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
387 } else {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
388 return -1;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
389 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
390
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
391 return 0;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
392 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
393
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
394 static inline __attribute__((__always_inline__)) void farcpy(int selector,
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
395 uint32_t offset, const void *ptr, uint32_t size)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
396 {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
397 if (!size)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
398 return; /* LOL */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
399
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
400 /* do the bulk of the copying with longs */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
401 while (size >= 4) {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
402 _farpokel(selector, offset, *(const uint32_t *)ptr);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
403 ptr = (const char *)ptr + 4;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
404 offset += 4;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
405 size -= 4;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
406 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
407
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
408 /* now, copy any remaining bytes. */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
409 while (size > 0) {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
410 _farpokeb(selector, offset, *(const uint8_t *)ptr);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
411 ptr = (const char *)ptr + 1;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
412 offset++;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
413 size--;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
414 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
415 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
416
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
417 void vbe_blit(struct vbe *vbe, const void *ptr)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
418 {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
419 switch (vbe->blit_type) {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
420 case VBE_BLIT_FRAMEBUFFER: {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
421 farcpy(vbe->blit.fb.selector, 0, ptr, vbe->size);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
422 break;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
423 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
424 case VBE_BLIT_BANKS: {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
425 const uint32_t bank_size = vbe->blit.banks.size;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
426 const uint32_t bank_granularity = vbe->blit.banks.granularity;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
427 int bank_number = 0;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
428 int todo = vbe->size;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
429
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
430 while (todo > 0) {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
431 int copy_size;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
432
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
433 /* select the appropriate bank */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
434 vesa_set_bank(bank_number);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
435
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
436 /* how much can we copy in one go? */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
437 copy_size = MIN(todo, bank_size);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
438
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
439 /* copy a bank of data to the screen */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
440 dosmemput(ptr, copy_size, 0xA0000);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
441
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
442 /* move on to the next bank of data */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
443 todo -= copy_size;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
444 ptr = (const char *)ptr + copy_size;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
445 bank_number += (bank_size / bank_granularity);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
446 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
447 break;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
448 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
449 default:
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
450 /* nope ? */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
451 break;
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
452 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
453 }
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
454
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
455 void vbe_quit(struct vbe *vbe)
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
456 {
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
457 /* reset VGA mode to DOS text mode */
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
458 vga_set_mode(0x03);
cbded07e50d8 *: initial commit
Paper <paper@tflc.us>
parents:
diff changeset
459 }