2 #ifndef __DOSLIB_HW_VGA_VGA_H
3 #define __DOSLIB_HW_VGA_VGA_H
5 #include <hw/cpu/cpu.h>
9 typedef unsigned char *VGA_RAM_PTR;
10 typedef uint16_t *VGA_ALPHA_PTR;
12 typedef unsigned char far *VGA_RAM_PTR;
13 typedef uint16_t far *VGA_ALPHA_PTR;
17 #define VGA_IS_TANDY 0x02 /* Tandy/PCjr */
18 #define VGA_IS_HGC 0x04
19 #define VGA_IS_MCGA 0x08
20 #define VGA_IS_VGA 0x10
21 #define VGA_IS_EGA 0x20
22 #define VGA_IS_CGA 0x40
23 #define VGA_IS_MDA 0x80
24 #define VGA_IS_AMSTRAD 0x100
27 #define VGA_AC_ENABLE 0x20
29 /* graphics controller regs */
30 #define VGA_GC_DATA_ROTATE_OP_NONE (0 << 3)
31 #define VGA_GC_DATA_ROTATE_OP_AND (1 << 3)
32 #define VGA_GC_DATA_ROTATE_OP_OR (2 << 3)
33 #define VGA_GC_DATA_ROTATE_OP_XOR (3 << 3)
35 /* font manipulation vars */
36 #define VGA_EGA_BYTES_PER_CHAR_BITMAP 32
37 #define VGA_EGA_BYTES_PER_CHAR_BITMAP_SHIFT 5
39 /* EGA/VGA memory map bits */
41 VGA_MEMMAP_A0000_128K=0,
48 VGA_CGA_MODE_40WIDE=0,
49 VGA_CGA_MODE_80WIDE=0x01,
50 VGA_CGA_MODE_GRAPHICS=0x02,
52 VGA_CGA_MODE_VIDEO_ENABLE=0x08,
53 VGA_CGA_MODE_VIDEO_640=0x10,
54 VGA_CGA_MODE_NO_BLINKING=0x20
57 /* sequencer registers */
62 /* graphics controller registers */
64 VGA_GC_ENABLE_SET_RESET=0,
71 enum { /* CGA palette selection (320x200x4) */
72 VGA_CGA_PALETTE_GR_BR_RD=0,
73 VGA_CGA_PALETTE_CY_MA_WH=1
76 enum { /* color select (text=border color 320x200=background 640x200=foreground */
77 VGA_CGA_PALETTE_CS_BLUE=(1U << 0U),
78 VGA_CGA_PALETTE_CS_GREEN=(1U << 1U),
79 VGA_CGA_PALETTE_CS_RED=(1U << 2U),
80 VGA_CGA_PALETTE_CS_INTENSITY=(1U << 3U),
81 VGA_CGA_PALETTE_CS_ALT_INTENSITY=(1U << 4U)
84 extern VGA_RAM_PTR vga_graphics_ram;
85 extern VGA_RAM_PTR vga_graphics_ram_fence;
86 extern VGA_ALPHA_PTR vga_alpha_ram;
87 extern VGA_ALPHA_PTR vga_alpha_ram_fence;
89 extern uint32_t vga_clock_rates[4];
90 extern unsigned char vga_pos_x,vga_pos_y,vga_color;
91 extern unsigned char vga_width,vga_height;
92 extern unsigned char vga_alpha_mode;
93 extern unsigned char vga_hgc_type;
94 extern unsigned int vga_base_3x0;
95 extern unsigned long vga_ram_base;
96 extern unsigned long vga_ram_size;
97 extern unsigned char vga_stride;
98 extern unsigned short vga_flags;
99 extern unsigned char vga_9wide;
101 unsigned char int10_getmode();
102 void vga_write(const char *msg);
103 void int10_setmode(unsigned char mode);
104 void update_state_vga_memory_map_select(unsigned char c);
105 unsigned char vga_force_read(const VGA_RAM_PTR p);
106 void vga_force_write(VGA_RAM_PTR p,const unsigned char c);
107 void vga_force_write_w(VGA_ALPHA_PTR p,const unsigned short c);
109 void vga_sync_hw_cursor();
110 void vga_sync_bios_cursor();
111 void update_state_vga_memory_map_select(unsigned char c);
112 void vga_set_memory_map(unsigned char c);
113 void vga_bios_set_80x50_text();
114 void update_state_from_vga();
116 void vga_write_state_DEBUG(FILE *f);
117 void vga_relocate_crtc(unsigned char color);
118 void vga_switch_to_mono();
119 void vga_switch_to_color();
120 void vga_turn_on_hgc();
121 void vga_turn_off_hgc();
122 void vga_set_cga_palette_and_background(unsigned char pal,unsigned char color);
123 void vga_set_cga_mode(unsigned char b);
124 void vga_tandy_setpalette(unsigned char i,unsigned char c);
125 void vga_enable_256color_modex();
126 void vga_set_stride(unsigned int stride);
127 void vga_set_start_location(unsigned int offset);
128 void vga_set_ypan_sub(unsigned char c);
129 void vga_set_xpan(unsigned char c);
130 void vga_splitscreen(unsigned int v);
131 void vga_alpha_switch_to_font_plane();
132 void vga_alpha_switch_from_font_plane();
133 void vga_set_9wide(unsigned char en);
134 void vga_select_charset_a_b(unsigned short a,unsigned short b);
135 void vga_write_crtc_mode(struct vga_mode_params *p,unsigned int flags);
136 void vga_correct_crtc_mode(struct vga_mode_params *p);
137 void vga_read_crtc_mode(struct vga_mode_params *p);
139 #define VGA_WRITE_CRTC_MODE_NO_CLEAR_SYNC 0x0001
141 static inline unsigned char vga_read_CRTC(unsigned char i) {
142 outp(vga_base_3x0+4,i);
143 return inp(vga_base_3x0+5);
146 static inline unsigned char vga_read_GC(unsigned char i) {
151 static inline unsigned char vga_read_sequencer(unsigned char i) {
156 static inline void vga_write_sequencer(unsigned char i,unsigned char c) {
161 static inline void vga_write_GC(unsigned char i,unsigned char c) {
166 static inline void vga_write_CRTC(unsigned char i,unsigned char c) {
167 outp(vga_base_3x0+4,i);
168 outp(vga_base_3x0+5,c);
171 static inline void vga_write_color(unsigned char c) {
175 static inline void vga_read_PAL(unsigned char i,unsigned char *p,unsigned int count) {
178 while (count-- > 0) *p++ = inp(0x3C9);
181 static inline void vga_write_PAL(unsigned char i,unsigned char *p,unsigned int count) {
184 while (count-- > 0) outp(0x3C9,*p++);
187 /* NTS: VGA hardware treats bit 5 of the index as a "screen enable".
188 * When the caller is done reprogramming it is expected to or the index by VGA_AC_ENABLE */
189 static inline void vga_write_AC(unsigned char i,unsigned char c) {
190 inp(vga_base_3x0+0xA); /* reset flipflop */
193 inp(vga_base_3x0+0xA);
196 static inline unsigned char vga_read_AC(unsigned char i) {
199 /* NTS: Reading the palette registers must occur this way because
200 * an old S3 Virge DX card I have will misread the values
201 * when PAS=1 otherwise. */
203 inp(vga_base_3x0+0xA); /* reset latch */
204 outp(0x3C0,i&(~0x20)); /* index with PAS=0 */
206 inp(vga_base_3x0+0xA); /* reset latch */
207 outp(0x3C0,i|0x20); /* index with PAS=1 */
208 inp(vga_base_3x0+0xA); /* reset latch */
213 static inline void vga_AC_reenable_screen() {
214 inp(vga_base_3x0+0xA); /* reset flipflop */
216 inp(vga_base_3x0+0xA);
219 static inline void vga_palette_lseek(unsigned int i) {
223 static inline void vga_palette_write(unsigned char r,unsigned char g,unsigned char b) {
229 static inline unsigned char vga_in_vsync() {
230 unsigned int p = vga_base_3x0 + 0xA;
231 return (inp(p) & 0x8);
234 static inline void vga_wait_for_hsync() {
235 unsigned int p = vga_base_3x0 + 0xA;
236 while ((inp(p) & 0x1) == 0);
239 static inline void vga_wait_for_hsync_end() {
240 unsigned int p = vga_base_3x0 + 0xA;
241 while ((inp(p) & 0x1) != 0);
244 static inline void vga_wait_for_vsync() {
245 unsigned int p = vga_base_3x0 + 0xA;
246 while ((inp(p) & 0x8) == 0);
249 static inline void vga_wait_for_vsync_end() {
250 unsigned int p = vga_base_3x0 + 0xA;
251 while ((inp(p) & 0x8) != 0);
254 static inline unsigned char vga_AC_RGB_to_code(unsigned char r,unsigned char g,unsigned char b) {
255 return (((b>>1)&1)<<0)|(((g>>1)&1)<<1)|(((r>>1)&1)<<2)|
256 (((b>>0)&1)<<3)|(((g>>0)&1)<<4)|(((r>>0)&1)<<5);
259 #if defined(TARGET_WINDOWS) && TARGET_MSDOS == 32
260 /* we have to call the Win16 executable buffer */
262 # pragma aux int10_getmode = \
268 # pragma aux int10_setmode = \
275 /* Watcom loves to reorder memory I/O on us. So to avoid problems we just have to
276 * suck it up and write the VGA memory functions in assembly language where it can't
277 * reorder access. Keeping the I/O in order is very important if we're to make
278 * proper use of the VGA hardware latch */
279 #if TARGET_MSDOS == 32
280 #pragma aux vga_force_read = \
285 #pragma aux vga_force_write = \
289 #pragma aux vga_force_read = \
294 #pragma aux vga_force_write = \
297 #pragma aux vga_force_write_w = \
302 /* all video timing and mode related values.
303 * notice that other params like graphics controller settings aren't included here,
304 * since you can always set those up yourself without disturbing the video timing */
305 /* NTS: VGA standard hardware seems to be designed so that generally clock_div2=1
306 * means you divide the master clock by 2. But it also seems that this bit is
307 * ignored in 256-color modes and the VGA acts like it's always clear (NOT SET),
308 * timings are programmed as if 640x400, and pixels are doubled horizontally
309 * regardless of the bit. Despite all that, the general mode timing calculations
310 * work out correctly anyway. This is important to know, because it may affect
311 * your ability to correctly use this API for major mode changes between
312 * 256-color modes & other modes. */
313 struct vga_mode_params {
314 unsigned char clock_select:2; /* 0x3C2 Misc out reg bits 2-3 */
315 unsigned char hsync_neg:1; /* 0x3C2 bit 6 */
316 unsigned char vsync_neg:1; /* 0x3C2 bit 7 */
317 unsigned char clock9:1; /* sequencer[1] bit 0 */
318 unsigned char clock_div2:1; /* sequencer[1] bit 3 [divide master clock by 2] */
319 unsigned char word_mode:1; /* CRTC[0x17] bit 6 = WORD MODE */
320 unsigned char dword_mode:1; /* CRTC[0x14] bit 6 = DWORD MODE */
321 unsigned short horizontal_total; /* CRTC[0] -5 */
322 unsigned short horizontal_display_end; /* CRTC[1] -1 */
323 unsigned short horizontal_blank_start; /* CRTC[2] */
324 unsigned short horizontal_blank_end; /* CRTC[3] bit 0-4 & CRTC[5] bit 7 */
325 unsigned short horizontal_start_retrace;/* CRTC[4] */
326 unsigned short horizontal_end_retrace; /* CRTC[5] bit 0-4 */
327 unsigned char horizontal_start_delay_after_total; /* CRTC[3] bit 5-6 */
328 unsigned char horizontal_start_delay_after_retrace; /* CRTC[5] bit 5-6 */
329 unsigned short vertical_total; /* CRTC[6] and CRTC[7] bit 0 and CRTC[7] bit 5 -2 */
330 unsigned short vertical_start_retrace; /* CRTC[0x10] and CRTC[7] bit 2 and CRTC[7] bit 7 */
331 unsigned short vertical_end_retrace; /* CRTC[0x11] bit 0-3 */
332 unsigned char refresh_cycles_per_scanline; /* CRTC[0x11] bit 6 */
333 unsigned char inc_mem_addr_only_every_4th; /* CRTC[0x14] bit 5 */
334 unsigned short vertical_display_end; /* CRTC[0x12] and CRTC[7] bit 1 and CRTC[7] bit 6 */
335 unsigned short vertical_blank_start; /* CRTC[0x15] and CRTC[7] bit 3 */
336 unsigned short vertical_blank_end; /* CRTC[0x16] bit 0-7 */
337 unsigned char shift_load_rate:1; /* sequencer[1] bit 2 */
338 unsigned char shift4_enable:1; /* sequencer[1] bit 4 */
339 unsigned char address_wrap_select:1; /* CRTC[0x17] bit 5 */
340 unsigned char memaddr_div2:1; /* CRTC[0x17] bit 3 */
341 unsigned char scanline_div2:1; /* CRTC[0x17] bit 2 */
342 unsigned char map14:1; /* CRTC[0x17] bit 1 */
343 unsigned char map13:1; /* CRTC[0x17] bit 0 */
344 unsigned char scan_double:1; /* CRTC[0x09] bit 7 */
345 unsigned char max_scanline; /* CRTC[0x09] bit 4-0 */
346 unsigned char offset; /* CRTC[0x13] */
347 unsigned char sync_enable:1; /* CRTC[0x17] bit 7 */
350 #endif /* __DOSLIB_HW_VGA_VGA_H */