summaryrefslogtreecommitdiffstats
path: root/qemu/roms/openbios/drivers/vga_set_mode.c
blob: 339ad29662a79028a473805cd879b85736f11116 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
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);

}