diff options
Diffstat (limited to 'qemu/roms/openbios/drivers/vga_set_mode.c')
-rw-r--r-- | qemu/roms/openbios/drivers/vga_set_mode.c | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/qemu/roms/openbios/drivers/vga_set_mode.c b/qemu/roms/openbios/drivers/vga_set_mode.c new file mode 100644 index 000000000..339ad2966 --- /dev/null +++ b/qemu/roms/openbios/drivers/vga_set_mode.c @@ -0,0 +1,148 @@ +/* + * $Id$ + * $Source$ + * + * by + * Steve M. Gehlbach <steve@kesa.com> + * + * These routines set graphics mode and alpha mode + * for switching back and forth. + * + * Register settings are + * more or less as follows: + * + * Register Graphics Alpha + * 16 color + * ------------------------------------------------ + * GDC_MODE 0x00 0x10 + * GDC_MISC 0x05 0x0e + * SEQ_MEMORY_MODE 0x06 0x02 + * SEQ_PLANE_WRITE 0x0f 0x03 + * CRTC_CURSOR_START 0x20 0x00 + * CRTC_CURSOR_END 0x00 CHAR_HEIGHT-1 + * CRTC_MODE 0xe3 0xa3 + * CRTC_MAX_SCAN 0x40 0x40 | CHAR_HEIGHT-1 + * ATC_MODE 0x01 0x0c + * + */ + +#include "asm/io.h" +#include "vga.h" + +void vga_set_gmode (void) { + u8 byte; + + byte = read_att_b(ATC_MODE) & ~0x0f; + write_att(byte|0x1, ATC_MODE); +// +// display is off at this point + + byte = read_seq_b(SEQ_PLANE_WRITE) & ~0xf; + write_seq(byte|0xf,SEQ_PLANE_WRITE); // all planes + byte = read_seq_b(SEQ_MEMORY_MODE); + write_seq(byte|4,SEQ_MEMORY_MODE); + + byte = read_gra_b(GDC_MODE) & ~0x10; + write_gra(byte,GDC_MODE); + write_gra(0x05, GDC_MISC); + + write_crtc(0x20, CRTC_CURSOR_START); + write_crtc(0x00, CRTC_CURSOR_END); + byte = read_crtc_b(CRTC_MODE) & ~0xe0; + write_crtc(byte|0xe0, CRTC_MODE); + byte = read_crtc_b(CRTC_MAX_SCAN) & ~0x01f; + write_crtc(byte, CRTC_MAX_SCAN); + + byte = inb(MIS_R); // get 3c2 value by reading 3cc + outb(byte & ~0xc,MIS_W); // clear last bits to set 25Mhz clock and low page + + +// turn on display, disable access to attr palette + inb(IS1_RC); + outb(0x20, ATT_IW); +} + +void vga_set_amode (void) { + u8 byte; + write_att(0x0c, ATC_MODE); + + //reset palette to normal in the case it was changed + write_att(0x0, ATC_COLOR_PAGE); +// +// display is off at this point + + write_seq(0x3,SEQ_PLANE_WRITE); // planes 0 & 1 + byte = read_seq_b(SEQ_MEMORY_MODE) & ~0x04; + write_seq(byte,SEQ_MEMORY_MODE); + + byte = read_gra_b(GDC_MODE) & ~0x60; + write_gra(byte|0x10,GDC_MODE); + + write_gra(0x0e, GDC_MISC); + + write_crtc(0x00, CRTC_CURSOR_START); + write_crtc(CHAR_HEIGHT-1, CRTC_CURSOR_END); + + byte = read_crtc_b(CRTC_MODE) & ~0xe0; + write_crtc(byte|0xa0, CRTC_MODE); + byte = read_crtc_b(CRTC_MAX_SCAN) & ~0x01f; + write_crtc(byte | (CHAR_HEIGHT-1), CRTC_MAX_SCAN); + + +// turn on display, disable access to attr palette + inb(IS1_RC); + outb(0x20, ATT_IW); +} + +/* + * by Steve M. Gehlbach, Ph.D. <steve@kesa.com> + * + * vga_font_load loads a font into font memory. It + * assumes alpha mode has been set. + * + * The font load code follows technique used + * in the tiara project, which came from + * the Universal Talkware Boot Loader, + * http://www.talkware.net. + */ + +void vga_font_load(unsigned char *vidmem, const unsigned char *font, int height, int num_chars) { + +/* Note: the font table is 'height' long but the font storage area + * is 32 bytes long. + */ + + int i,j; + u8 byte; + + // set sequencer map 2, odd/even off + byte = read_seq_b(SEQ_PLANE_WRITE) & ~0xf; + write_seq(byte|4,SEQ_PLANE_WRITE); + byte = read_seq_b(SEQ_MEMORY_MODE); + write_seq(byte|4,SEQ_MEMORY_MODE); + + // select graphics map 2, odd/even off, map starts at 0xa0000 + write_gra(2,GDC_PLANE_READ); + byte = read_gra_b(GDC_MODE) & ~0x10; + write_gra(byte,GDC_MODE); + write_gra(0,GDC_MISC); + + for (i = 0 ; i < num_chars ; i++) { + for (j = 0 ; j < height ; j++) { + vidmem[i*32+j] = font[i*16+j]; + } + } + + // set sequencer back to maps 0,1, odd/even on + byte = read_seq_b(SEQ_PLANE_WRITE) & ~0xf; + write_seq(byte|3,SEQ_PLANE_WRITE); + byte = read_seq_b(SEQ_MEMORY_MODE) & ~0x4; + write_seq(byte,SEQ_MEMORY_MODE); + + // select graphics back to map 0,1, odd/even on + write_gra(0,GDC_PLANE_READ); + byte = read_gra_b(GDC_MODE); + write_gra(byte|0x10,GDC_MODE); + write_gra(0xe,GDC_MISC); + +} |