1 /*
2  * $Id$
3  * $Source$
4  *
5  *  by
6  *  Steve M. Gehlbach <steve@kesa.com>
7  *
8  *  These routines set graphics mode and alpha mode
9  *  for switching back and forth.
10  *
11  *  Register settings are
12  *  more or less as follows:
13  *
14  *  Register             Graphics      Alpha
15  *                       16 color
16  *  ------------------------------------------------
17  *  GDC_MODE              0x00          0x10
18  *  GDC_MISC              0x05          0x0e
19  *  SEQ_MEMORY_MODE       0x06          0x02
20  *  SEQ_PLANE_WRITE       0x0f          0x03
21  *  CRTC_CURSOR_START     0x20          0x00
22  *  CRTC_CURSOR_END       0x00          CHAR_HEIGHT-1
23  *  CRTC_MODE             0xe3          0xa3
24  *  CRTC_MAX_SCAN         0x40          0x40 | CHAR_HEIGHT-1
25  *  ATC_MODE              0x01          0x0c
26  *
27  */
28 
29 #include "asm/io.h"
30 #include "vga.h"
31 
vga_set_gmode(void)32 void vga_set_gmode (void) {
33 	u8 byte;
34 
35 	byte = read_att_b(ATC_MODE) & ~0x0f;
36 	write_att(byte|0x1, ATC_MODE);
37 //
38 // display is off at this point
39 
40 	byte = read_seq_b(SEQ_PLANE_WRITE) & ~0xf;
41 	write_seq(byte|0xf,SEQ_PLANE_WRITE); // all planes
42 	byte = read_seq_b(SEQ_MEMORY_MODE);
43 	write_seq(byte|4,SEQ_MEMORY_MODE);
44 
45 	byte = read_gra_b(GDC_MODE) & ~0x10;
46 	write_gra(byte,GDC_MODE);
47 	write_gra(0x05, GDC_MISC);
48 
49 	write_crtc(0x20, CRTC_CURSOR_START);
50 	write_crtc(0x00, CRTC_CURSOR_END);
51 	byte = read_crtc_b(CRTC_MODE) & ~0xe0;
52 	write_crtc(byte|0xe0, CRTC_MODE);
53 	byte = read_crtc_b(CRTC_MAX_SCAN) & ~0x01f;
54 	write_crtc(byte, CRTC_MAX_SCAN);
55 
56 	byte = inb(MIS_R); // get 3c2 value by reading 3cc
57 	outb(byte & ~0xc,MIS_W); // clear last bits to set 25Mhz clock and low page
58 
59 
60 // turn on display, disable access to attr palette
61 	inb(IS1_RC);
62 	outb(0x20, ATT_IW);
63 }
64 
vga_set_amode(void)65 void vga_set_amode (void) {
66 	u8 byte;
67 	write_att(0x0c, ATC_MODE);
68 
69 	//reset palette to normal in the case it was changed
70 	write_att(0x0, ATC_COLOR_PAGE);
71 //
72 // display is off at this point
73 
74 	write_seq(0x3,SEQ_PLANE_WRITE); // planes 0 & 1
75 	byte = read_seq_b(SEQ_MEMORY_MODE) & ~0x04;
76 	write_seq(byte,SEQ_MEMORY_MODE);
77 
78 	byte = read_gra_b(GDC_MODE) & ~0x60;
79 	write_gra(byte|0x10,GDC_MODE);
80 
81 	write_gra(0x0e, GDC_MISC);
82 
83 	write_crtc(0x00, CRTC_CURSOR_START);
84 	write_crtc(CHAR_HEIGHT-1, CRTC_CURSOR_END);
85 
86 	byte = read_crtc_b(CRTC_MODE) & ~0xe0;
87 	write_crtc(byte|0xa0, CRTC_MODE);
88 	byte = read_crtc_b(CRTC_MAX_SCAN) & ~0x01f;
89 	write_crtc(byte | (CHAR_HEIGHT-1), CRTC_MAX_SCAN);
90 
91 
92 // turn on display, disable access to attr palette
93 	inb(IS1_RC);
94 	outb(0x20, ATT_IW);
95 }
96 
97 /*
98  * by Steve M. Gehlbach, Ph.D. <steve@kesa.com>
99  *
100  * vga_font_load loads a font into font memory.  It
101  * assumes alpha mode has been set.
102  *
103  * The font load code follows technique used
104  * in the tiara project, which came from
105  * the Universal Talkware Boot Loader,
106  * http://www.talkware.net.
107  */
108 
vga_font_load(unsigned char * vidmem,const unsigned char * font,int height,int num_chars)109 void vga_font_load(unsigned char *vidmem, const unsigned char *font, int height, int num_chars) {
110 
111 /* Note: the font table is 'height' long but the font storage area
112  * is 32 bytes long.
113  */
114 
115 	int i,j;
116 	u8 byte;
117 
118 	// set sequencer map 2, odd/even off
119 	byte = read_seq_b(SEQ_PLANE_WRITE) & ~0xf;
120 	write_seq(byte|4,SEQ_PLANE_WRITE);
121 	byte = read_seq_b(SEQ_MEMORY_MODE);
122 	write_seq(byte|4,SEQ_MEMORY_MODE);
123 
124 	// select graphics map 2, odd/even off, map starts at 0xa0000
125 	write_gra(2,GDC_PLANE_READ);
126 	byte = read_gra_b(GDC_MODE) & ~0x10;
127 	write_gra(byte,GDC_MODE);
128 	write_gra(0,GDC_MISC);
129 
130 	for (i = 0 ; i < num_chars ; i++) {
131 		for (j = 0 ; j < height ; j++) {
132 			vidmem[i*32+j] = font[i*16+j];
133 		}
134 	}
135 
136 	// set sequencer back to maps 0,1, odd/even on
137 	byte = read_seq_b(SEQ_PLANE_WRITE) & ~0xf;
138 	write_seq(byte|3,SEQ_PLANE_WRITE);
139 	byte = read_seq_b(SEQ_MEMORY_MODE) & ~0x4;
140 	write_seq(byte,SEQ_MEMORY_MODE);
141 
142 	// select graphics back to map 0,1, odd/even on
143 	write_gra(0,GDC_PLANE_READ);
144 	byte = read_gra_b(GDC_MODE);
145 	write_gra(byte|0x10,GDC_MODE);
146 	write_gra(0xe,GDC_MISC);
147 
148 }
149