2 * Copyright (c) 2001 The FreeBSD Project, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY The FreeBSD Project, Inc. AND CONTRIBUTORS
15 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
16 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL The FreeBSD Project, Inc. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * $FreeBSD: src/usr.bin/doscmd/video.c,v 1.5.2.1 2002/04/25 11:04:51 tg Exp $
27 * $DragonFly: src/usr.bin/doscmd/video.c,v 1.3 2003/10/04 20:36:43 hmp Exp $
30 #include <sys/types.h>
47 u_int8_t VGA_CRTC
[CRTC_Size
];
48 u_int8_t VGA_ATC
[ATC_Size
];
49 u_int8_t VGA_TSC
[TSC_Size
];
50 u_int8_t VGA_GDC
[GDC_Size
];
52 /* VGA status information */
53 u_int8_t vga_status
[64];
55 /* Table of supported video modes. */
56 vmode_t vmodelist
[] = {
57 {0x00, 0x17, TEXT
, 16, 8, 2, 0xb8000, FONT8x16
},
58 {0x01, 0x17, TEXT
, 16, 8, 2, 0xb8000, FONT8x16
},
59 {0x02, 0x18, TEXT
, 16, 8, 2, 0xb8000, FONT8x16
},
60 {0x03, 0x18, TEXT
, 16, 8, 2, 0xb8000, FONT8x16
},
61 {0x04, 0x04, GRAPHICS
, 4, 1, 0, 0xb8000, FONT8x8
},
62 {0x05, 0x05, GRAPHICS
, 4, 1, 0, 0xb8000, FONT8x8
},
63 {0x06, 0x06, GRAPHICS
, 2, 1, 0, 0xb8000, FONT8x8
},
64 {0x07, 0x19, TEXT
, 1, 8, 2, 0xb0000, FONT8x16
},
65 {0x08, 0x08, NOMODE
, 0, 0, 0, 0, 0},
66 {0x09, 0x09, NOMODE
, 0, 0, 0, 0, 0},
67 {0x0a, 0x0a, NOMODE
, 0, 0, 0, 0, 0},
68 {0x0b, 0x0b, NOMODE
, 0, 0, 0, 0, 0},
69 {0x0c, 0x0c, NOMODE
, 0, 0, 0, 0, 0},
70 {0x0d, 0x0d, GRAPHICS
, 16, 8, 0, 0xa0000, FONT8x8
},
71 {0x0e, 0x0e, GRAPHICS
, 16, 4, 0, 0xa0000, FONT8x8
},
72 {0x0f, 0x11, GRAPHICS
, 1, 2, 1, 0xa0000, FONT8x14
},
73 {0x10, 0x12, GRAPHICS
, 16, 2, 1, 0xa0000, FONT8x14
},
74 {0x11, 0x1a, GRAPHICS
, 2, 1, 3, 0xa0000, FONT8x16
},
75 {0x12, 0x1b, GRAPHICS
, 16, 1, 3, 0xa0000, FONT8x16
},
76 /* {0x13, 0x1c, GRAPHICS, 256, 1, 0, 0xa0000, FONT8x8}, */
79 #define NUMMODES (sizeof(vmodelist) / sizeof(vmode_t))
84 static void init_vga(void);
85 static u_int8_t
video_inb(int);
86 static void video_outb(int, u_int8_t
);
89 * Local types and variables
92 /* Save Table and assorted variables */
93 struct VideoSaveTable
{
94 u_short video_parameter_table
[2];
95 u_short parameter_dynamic_save_area
[2]; /* Not used */
96 u_short alphanumeric_character_set_override
[2]; /* Not used */
97 u_short graphics_character_set_override
[2]; /* Not used */
98 u_short secondary_save_table
[2]; /* Not used */
102 struct SecondaryVideoSaveTable
{
104 u_short display_combination_code_table
[2];
105 u_short alphanumeric_character_set_override
[2]; /* Not used */
106 u_short user_palette_profile_table
[2]; /* Not used */
110 struct VideoSaveTable
*vsp
;
111 struct SecondaryVideoSaveTable
*svsp
;
114 * Read and write the VGA port
117 /* Save the selected index register */
118 static u_int8_t crtc_index
, atc_index
, tsc_index
, gdc_index
;
119 /* Toggle between index and data on port ATC_WritePort */
120 static u_int8_t set_atc_index
= 1;
126 case CRTC_DataPortColor
:
127 return VGA_CRTC
[crtc_index
];
128 case CRTC_IndexPortColor
:
131 return VGA_ATC
[atc_index
];
133 return VGA_TSC
[tsc_index
];
137 return VGA_GDC
[gdc_index
];
140 case VGA_InputStatus1Port
:
142 VGA_InputStatus1
= (VGA_InputStatus1
+ 1) & 15;
143 return VGA_InputStatus1
;
150 video_outb(int port
, u_int8_t value
)
153 #define row (CursRow0)
154 #define col (CursCol0)
159 case CRTC_IndexPortColor
:
162 case CRTC_DataPortColor
:
163 VGA_CRTC
[crtc_index
] = value
;
164 switch (crtc_index
) {
165 case CRTC_CurLocHi
: /* Update cursor position in BIOS */
166 cp
= row
* DpyCols
+ col
;
172 case CRTC_CurLocLo
: /* Update cursor position in BIOS */
173 cp
= row
* DpyCols
+ col
;
180 debug(D_VIDEO
, "VGA: outb 0x%04x, 0x%02x at index 0x%02x\n",
181 port
, value
, crtc_index
);
184 case CRTC_IndexPortMono
: /* Not used */
186 case CRTC_DataPortMono
: /* Not used */
192 VGA_ATC
[atc_index
] = value
;
195 debug(D_VIDEO
, "VGA: outb 0x%04x, 0x%02x at index 0x%02x\n",
196 port
, value
, crtc_index
);
200 set_atc_index
= 1 - set_atc_index
;
206 VGA_TSC
[tsc_index
] = value
;
209 debug(D_VIDEO
, "VGA: outb 0x%04x, 0x%02x at index 0x%02x\n",
210 port
, value
, crtc_index
);
218 VGA_GDC
[gdc_index
] = value
;
222 debug(D_VIDEO
, "VGA: outb 0x%04x, 0x%02x at index 0x%02x\n",
223 port
, value
, crtc_index
);
230 debug(D_ALWAYS
, "VGA: Unknown port 0x%4x\n", port
);
242 /* If we are running under X, get a connection to the X server and create
243 an empty window of size (1, 1). It makes a couple of init functions a
248 /* Set VGA emulator to a sane state */
251 /* Initialize mode 3 (text, 80x25, 16 colors) */
255 /* Define all known I/O port handlers */
257 define_input_port_handler(CRTC_IndexPortColor
, video_inb
);
258 define_input_port_handler(CRTC_DataPortColor
, video_inb
);
259 define_input_port_handler(ATC_ReadPort
, video_inb
);
260 define_input_port_handler(TSC_IndexPort
, video_inb
);
261 define_input_port_handler(TSC_DataPort
, video_inb
);
262 define_input_port_handler(GDC_IndexPort
, video_inb
);
263 define_input_port_handler(GDC_DataPort
, video_inb
);
264 define_input_port_handler(VGA_InputStatus1Port
, video_inb
);
266 define_output_port_handler(CRTC_IndexPortColor
, video_outb
);
267 define_output_port_handler(CRTC_DataPortColor
, video_outb
);
268 define_output_port_handler(ATC_WritePort
, video_outb
);
269 define_output_port_handler(TSC_IndexPort
, video_outb
);
270 define_output_port_handler(TSC_DataPort
, video_outb
);
271 define_output_port_handler(GDC_IndexPort
, video_outb
);
272 define_output_port_handler(GDC_DataPort
, video_outb
);
275 redirect0
= isatty(0) == 0 || !xmode
;
276 redirect1
= isatty(1) == 0 || !xmode
;
277 redirect2
= isatty(2) == 0 || !xmode
;
283 video_bios_init(void)
292 * Put the Video Save Table Pointer @ C000:0000
293 * Put the Secondary Video Save Table Pointer @ C000:0020
294 * Put the Display Combination Code table @ C000:0040
295 * Put the Video Parameter table @ C000:1000 - C000:2FFF
297 BIOS_SaveTablePointer
= 0xC0000000;
299 vsp
= (struct VideoSaveTable
*)0xC0000L
;
300 memset(vsp
, 0, sizeof(struct VideoSaveTable
));
301 svsp
= (struct SecondaryVideoSaveTable
*)0xC0020L
;
303 vsp
->video_parameter_table
[0] = 0x1000;
304 vsp
->video_parameter_table
[1] = 0xC000;
306 vsp
->secondary_save_table
[0] = 0x0020;
307 vsp
->secondary_save_table
[1] = 0xC000;
309 svsp
->display_combination_code_table
[0] = 0x0040;
310 svsp
->display_combination_code_table
[1] = 0xC000;
312 p
= (u_char
*)0xC0040;
313 *p
++ = 2; /* Only support 2 combinations currently */
314 *p
++ = 1; /* Version # */
315 *p
++ = 8; /* We won't use more than type 8 */
316 *p
++ = 0; /* Reserved */
317 *p
++ = 0; *p
++ = 0; /* No Display No Display */
318 *p
++ = 0; *p
++ = 8; /* No Display VGA Color */
320 memcpy((void *)0xC1000, videoparams
, sizeof(videoparams
));
321 ivec
[0x1d] = 0xC0001000L
; /* Video Parameter Table */
323 ivec
[0x42] = ivec
[0x10]; /* Copy of video interrupt */
325 /* Put the current font at C000:3000; the pixels are copied in
326 'tty.c:load_font()'. */
327 ivec
[0x1f] = 0xC0003000L
;
328 ivec
[0x43] = 0xC0003000L
;
330 BIOSDATA
[0x8a] = 1; /* Index into DCC table */
332 vec
= insert_softint_trampoline();
334 register_callback(vec
, int10
, "int 10");
337 /* Initialize the VGA emulator
339 XXX This is not nearly finished right now.
346 /* Zero-fill 'dac_rgb' on allocation; the default (EGA) table has only
348 dac_rgb
= (struct dac_colors
*)calloc(256, sizeof(struct dac_colors
));
350 err(1, "Get memory for dac_rgb");
352 /* Copy the default DAC table to a working copy we can trash. */
353 for (i
= 0; i
< 64; i
++)
354 dac_rgb
[i
] = dac_default64
[i
]; /* Structure copy */
356 /* Point 'palette[]' to the Attribute Controller space. We will only use
357 the first 16 slots. */
360 /* Get memory for the video RAM and adjust the plane pointers. */
361 vram
= calloc(256 * 1024, 1); /* XXX */
363 warn("Could not get video memory; graphics modes not available.");
365 /* XXX There is probably a more efficient memory layout... */
367 vplane1
= vram
+ 0x10000;
368 vplane2
= vram
+ 0x20000;
369 vplane3
= vram
+ 0x30000;
371 VGA_InputStatus1
= 0;
375 * Initialize the requested video mode.
378 /* Indices into the video parameter table. We will use that array to
379 initialize the registers on startup and when the video mode changes. */
384 #define MiscOutput_Ofs 9
390 int idx
; /* Index into vmode */
391 int pidx
; /* Index into videoparams */
393 debug(D_VIDEO
, "VGA: Set video mode to 0x%02x\n", mode
);
395 idx
= find_vmode(mode
& 0x7f);
396 if (idx
== -1 || vmodelist
[idx
].type
== NOMODE
)
397 err(1, "Mode 0x%02x is not supported", mode
);
398 vmode
= vmodelist
[idx
];
399 pidx
= vmode
.paramindex
;
401 /* Preset VGA registers. */
402 memcpy(VGA_CRTC
, (u_int8_t
*)&videoparams
[pidx
][CRTC_Ofs
],
404 memcpy(VGA_ATC
, (u_int8_t
*)&videoparams
[pidx
][ATC_Ofs
],
406 /* Warning: the video parameter table does not contain the Sequencer's
407 Reset register. Its default value is 0x03.*/
408 VGA_TSC
[TSC_Reset
] = 0x03;
409 memcpy(VGA_TSC
+ 1, (u_int8_t
*)&videoparams
[pidx
][TSC_Ofs
],
410 sizeof(VGA_TSC
) - 1);
411 memcpy(VGA_GDC
, (u_int8_t
*)&videoparams
[pidx
][GDC_Ofs
],
413 VGA_MiscOutput
= videoparams
[pidx
][MiscOutput_Ofs
];
416 if ((VGA_ATC
[ATC_ModeCtrl
] & 1) == 1 && vmode
.type
== TEXT
)
417 err(1, "Text mode requested, but ATC switched to graphics mode!");
418 if ((VGA_ATC
[ATC_ModeCtrl
] & 1) == 0 && vmode
.type
== GRAPHICS
)
419 err(1, "Graphics mode requested, but ATC switched to text mode!");
421 VideoMode
= mode
& 0x7f;
422 DpyCols
= (u_int16_t
)videoparams
[pidx
][0];
423 DpyPageSize
= *(u_int16_t
*)&videoparams
[pidx
][3];
441 CursStart
= VGA_CRTC
[CRTC_CursStart
];
442 CursEnd
= VGA_CRTC
[CRTC_CursEnd
];
444 DpyRows
= videoparams
[pidx
][1];
445 CharHeight
= videoparams
[pidx
][2];
447 CRTCPort
= vmode
.numcolors
> 1 ? CRTC_IndexPortColor
: CRTC_IndexPortMono
;
448 NumColors
= vmode
.numcolors
;
449 NumPages
= vmode
.numpages
;
450 VertResolution
= vmode
.vrescode
;
451 vmem
= (u_int16_t
*)vmode
.vmemaddr
;
453 /* Copy VGA related BIOS variables from 'vga_status'. */
454 memcpy(&BIOS_VideoMode
, &VideoMode
, 33);
455 BIOS_DpyRows
= DpyRows
;
456 BIOS_CharHeight
= CharHeight
;
458 /* Load 'pixels[]' from default DAC values. */
462 xfont
= vmode
.fontname
;
465 /* Resize window if necessary. */
468 /* Mmap video memory for the graphics modes. Write access to 0xa0000 -
469 0xaffff will generate a T_PAGEFAULT trap in VM86 mode (aside: why not a
470 SIGSEGV?), which is handled in 'trap.c:sigbus()'. */
471 if (vmode
.type
== GRAPHICS
) {
472 vmem
= mmap((void *)0xa0000, 64 * 1024, PROT_NONE
,
473 MAP_ANON
| MAP_FIXED
| MAP_SHARED
, -1, 0);
475 fatal("Could not mmap() video memory");
477 /* Create an XImage to display the graphics screen. */
485 /* Initialize video memory with black background, white foreground */
487 for (i
= 0; i
< DpyPageSize
/ 2; ++i
)
494 /* Find the requested mode in the 'vmodelist' table. This function returns the
495 index into this table; we will also use the index for accessing the
496 'videoparams' array. */
497 int find_vmode(int mode
)
501 for (i
= 0; i
< NUMMODES
; i
++)
502 if (vmodelist
[i
].modenumber
== mode
)
508 /* Handle access to the graphics memory.
510 Simply changing the protection for the memory is not enough, unfortunately.
511 It would only work for the 256 color modes, where a memory byte contains
512 the color value of one pixel. The 16 color modes (and 4 color modes) make
513 use of four bit planes which overlay the first 64K of video memory. The
514 bits are distributed into these bit planes according to the GDC state, so
515 we will have to emulate the CPU instructions (see 'cpu.c:emu_instr()').
517 Handling the 256 color modes will be a bit easier, once we support those at
520 vmem_pageflt(struct sigframe
*sf
)
522 regcontext_t
*REGS
= (regcontext_t
*)(&sf
->sf_uc
.uc_mcontext
);
524 /* The ATC's Mode Control register tells us whether 4 or 8 color bits are
526 if (VGA_ATC
[ATC_ModeCtrl
] & (1 << 6)) {
527 /* 256 colors, allow writes; the protection will be set back to
528 PROT_READ at the next display update */
529 mprotect(vmem
, 64 * 1024, PROT_READ
| PROT_WRITE
);
533 /* There's no need to change the protection in the 16 color modes, we will
534 write to 'vram'. Just emulate the next instruction. */
535 return emu_instr(REGS
);
538 /* We need to keep track of the latches' contents.*/
539 static u_int8_t latch0
, latch1
, latch2
, latch3
;
541 /* Read a byte from the video memory. 'vga_read()' is called from
542 'cpu.c:read_byte()' and will emulate the VGA read modes. */
544 vga_read(u_int32_t addr
)
548 /* 'addr' lies between 0xa0000 and 0xaffff. */
549 dst
= addr
- 0xa0000;
552 latch0
= vplane0
[dst
];
553 latch1
= vplane1
[dst
];
554 latch2
= vplane2
[dst
];
555 latch3
= vplane3
[dst
];
557 /* Select read mode. */
558 if ((VGA_GDC
[GDC_Mode
] & 0x80) == 0)
559 /* Read Mode 0; return the byte from the selected bit plane. */
560 return vram
[dst
+ (VGA_GDC
[GDC_ReadMapSelect
] & 3) * 0x10000];
563 debug(D_ALWAYS
, "VGA: Read Mode 1 not implemented\n");
567 /* Write a byte to the video memory. 'vga_write()' is called from
568 'cpu.c:write_word()' and will emulate the VGA write modes. Not all four
569 modes are implemented yet, nor are the addressing modes (odd/even, chain4).
570 (NB: I think the latter will have to be done in 'tty_graphics_update()').
573 vga_write(u_int32_t addr
, u_int8_t val
)
576 u_int8_t c0
, c1
, c2
, c3
;
577 u_int8_t m0
, m1
, m2
, m3
;
583 debug(D_VIDEO
, "VGA: Write 0x%02x to 0x%x\n", val
, addr
);
584 debug(D_VIDEO
, " GDC: ");
585 for (i
= 0; i
< sizeof(VGA_GDC
); i
++)
586 debug(D_VIDEO
, "%02x ", VGA_GDC
[i
]);
587 debug(D_VIDEO
, "\n");
588 debug(D_VIDEO
, " TSC: ");
589 for (i
= 0; i
< sizeof(VGA_TSC
); i
++)
590 debug(D_VIDEO
, "%02x ", VGA_TSC
[i
]);
591 debug(D_VIDEO
, "\n");
594 /* 'addr' lies between 0xa0000 and 0xaffff. */
595 dst
= addr
- 0xa0000;
602 /* Select write mode. */
603 switch (VGA_GDC
[GDC_Mode
] & 3) {
605 mask
= VGA_GDC
[GDC_BitMask
];
607 if (VGA_GDC
[GDC_DataRotate
] & 7)
608 debug(D_ALWAYS
, "VGA: Data Rotate != 0\n");
610 /* Select function. */
611 switch (VGA_GDC
[GDC_DataRotate
] & 0x18) {
612 case 0x00: /* replace */
613 m0
= VGA_GDC
[GDC_SetReset
] & 1 ? mask
: 0x00;
614 m1
= VGA_GDC
[GDC_SetReset
] & 2 ? mask
: 0x00;
615 m2
= VGA_GDC
[GDC_SetReset
] & 4 ? mask
: 0x00;
616 m3
= VGA_GDC
[GDC_SetReset
] & 8 ? mask
: 0x00;
618 c0
= VGA_GDC
[GDC_EnableSetReset
] & 1 ? c0
& ~mask
: val
& ~mask
;
619 c1
= VGA_GDC
[GDC_EnableSetReset
] & 2 ? c1
& ~mask
: val
& ~mask
;
620 c2
= VGA_GDC
[GDC_EnableSetReset
] & 4 ? c2
& ~mask
: val
& ~mask
;
621 c3
= VGA_GDC
[GDC_EnableSetReset
] & 8 ? c3
& ~mask
: val
& ~mask
;
629 m0
= VGA_GDC
[GDC_SetReset
] & 1 ? 0xff : ~mask
;
630 m1
= VGA_GDC
[GDC_SetReset
] & 2 ? 0xff : ~mask
;
631 m2
= VGA_GDC
[GDC_SetReset
] & 4 ? 0xff : ~mask
;
632 m3
= VGA_GDC
[GDC_SetReset
] & 8 ? 0xff : ~mask
;
634 c0
= VGA_GDC
[GDC_EnableSetReset
] & 1 ? c0
& m0
: val
& m0
;
635 c1
= VGA_GDC
[GDC_EnableSetReset
] & 2 ? c1
& m1
: val
& m1
;
636 c2
= VGA_GDC
[GDC_EnableSetReset
] & 4 ? c2
& m2
: val
& m2
;
637 c3
= VGA_GDC
[GDC_EnableSetReset
] & 8 ? c3
& m3
: val
& m3
;
640 m0
= VGA_GDC
[GDC_SetReset
] & 1 ? mask
: 0x00;
641 m1
= VGA_GDC
[GDC_SetReset
] & 2 ? mask
: 0x00;
642 m2
= VGA_GDC
[GDC_SetReset
] & 4 ? mask
: 0x00;
643 m3
= VGA_GDC
[GDC_SetReset
] & 8 ? mask
: 0x00;
645 c0
= VGA_GDC
[GDC_EnableSetReset
] & 1 ? c0
| m0
: val
| m0
;
646 c1
= VGA_GDC
[GDC_EnableSetReset
] & 2 ? c1
| m1
: val
| m1
;
647 c2
= VGA_GDC
[GDC_EnableSetReset
] & 4 ? c2
| m2
: val
| m2
;
648 c3
= VGA_GDC
[GDC_EnableSetReset
] & 8 ? c3
| m3
: val
| m3
;
651 m0
= VGA_GDC
[GDC_SetReset
] & 1 ? mask
: 0x00;
652 m1
= VGA_GDC
[GDC_SetReset
] & 2 ? mask
: 0x00;
653 m2
= VGA_GDC
[GDC_SetReset
] & 4 ? mask
: 0x00;
654 m3
= VGA_GDC
[GDC_SetReset
] & 8 ? mask
: 0x00;
656 c0
= VGA_GDC
[GDC_EnableSetReset
] & 1 ? c0
^ m0
: val
^ m0
;
657 c1
= VGA_GDC
[GDC_EnableSetReset
] & 2 ? c1
^ m1
: val
^ m1
;
658 c2
= VGA_GDC
[GDC_EnableSetReset
] & 4 ? c2
^ m2
: val
^ m2
;
659 c3
= VGA_GDC
[GDC_EnableSetReset
] & 8 ? c3
^ m3
: val
^ m3
;
664 /* Just copy the latches' content to the desired destination
668 mask
= VGA_GDC
[GDC_BitMask
];
670 /* select function */
671 switch (VGA_GDC
[GDC_DataRotate
] & 0x18) {
672 case 0x00: /* replace */
673 m0
= (val
& 1 ? 0xff : 0x00) & mask
;
674 m1
= (val
& 2 ? 0xff : 0x00) & mask
;
675 m2
= (val
& 4 ? 0xff : 0x00) & mask
;
676 m3
= (val
& 8 ? 0xff : 0x00) & mask
;
689 m0
= (val
& 1 ? 0xff : 0x00) | ~mask
;
690 m1
= (val
& 2 ? 0xff : 0x00) | ~mask
;
691 m2
= (val
& 4 ? 0xff : 0x00) | ~mask
;
692 m3
= (val
& 8 ? 0xff : 0x00) | ~mask
;
700 m0
= (val
& 1 ? 0xff : 0x00) & mask
;
701 m1
= (val
& 2 ? 0xff : 0x00) & mask
;
702 m2
= (val
& 4 ? 0xff : 0x00) & mask
;
703 m3
= (val
& 8 ? 0xff : 0x00) & mask
;
711 m0
= (val
& 1 ? 0xff : 0x00) & mask
;
712 m1
= (val
& 2 ? 0xff : 0x00) & mask
;
713 m2
= (val
& 4 ? 0xff : 0x00) & mask
;
714 m3
= (val
& 8 ? 0xff : 0x00) & mask
;
725 debug(D_ALWAYS
, "VGA: Write Mode 3 not implemented\n");
729 /* Write back changed byte, depending on Map Mask register. */
730 if (VGA_TSC
[TSC_MapMask
] & 1)
732 if (VGA_TSC
[TSC_MapMask
] & 2)
734 if (VGA_TSC
[TSC_MapMask
] & 4)
736 if (VGA_TSC
[TSC_MapMask
] & 8)