blob: a97c85fe710dccead15c6e0537f09e1ce5c4eb00 [file] [log] [blame]
Kevin O'Connor4ad2d102012-01-14 23:20:05 -05001// Standard VGA mode information.
Kevin O'Connor1f2c3072009-05-06 23:35:59 -04002//
3// Copyright (C) 2009 Kevin O'Connor <kevin@koconnor.net>
4// Copyright (C) 2001-2008 the LGPL VGABios developers Team
5//
6// This file may be distributed under the terms of the GNU LGPLv3 license.
7
Kevin O'Connor5727c292009-05-16 17:29:32 -04008#include "biosvar.h" // GET_GLOBAL
Kevin O'Connor2d2fa312013-09-14 21:55:26 -04009#include "output.h" // warn_internalerror
Kevin O'Connoraad3b692012-01-14 23:15:40 -050010#include "stdvga.h" // stdvga_find_mode
Kevin O'Connorfa9c66a2013-09-14 19:10:40 -040011#include "string.h" // memcpy_far
Kevin O'Connor2d2fa312013-09-14 21:55:26 -040012#include "vgabios.h" // struct VideoParamTableEntry_s
Kevin O'Connor1f2c3072009-05-06 23:35:59 -040013
Kevin O'Connor1f2c3072009-05-06 23:35:59 -040014
Kevin O'Connor5727c292009-05-16 17:29:32 -040015/****************************************************************
Kevin O'Connoraad3b692012-01-14 23:15:40 -050016 * Video mode register definitions
Kevin O'Connor5727c292009-05-16 17:29:32 -040017 ****************************************************************/
18
Kevin O'Connor1f2c3072009-05-06 23:35:59 -040019/* Mono */
Kevin O'Connor5727c292009-05-16 17:29:32 -040020static u8 palette0[] VAR16 = {
Kevin O'Connora959aa12009-05-25 00:12:18 -040021 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
22 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
23 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
24 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
25 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
26 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
27 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f,
28 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f,
29 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
30 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
31 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
32 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
33 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
34 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
35 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f,
36 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f
Kevin O'Connor1f2c3072009-05-06 23:35:59 -040037};
38
Kevin O'Connor5727c292009-05-16 17:29:32 -040039static u8 palette1[] VAR16 = {
Kevin O'Connora959aa12009-05-25 00:12:18 -040040 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
41 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
42 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
43 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
44 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
45 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
46 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
47 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
48 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
49 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
50 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
51 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
52 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
53 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
54 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
55 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f
Kevin O'Connor1f2c3072009-05-06 23:35:59 -040056};
57
Kevin O'Connor5727c292009-05-16 17:29:32 -040058static u8 palette2[] VAR16 = {
Kevin O'Connora959aa12009-05-25 00:12:18 -040059 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
60 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x2a,0x00, 0x2a,0x2a,0x2a,
61 0x00,0x00,0x15, 0x00,0x00,0x3f, 0x00,0x2a,0x15, 0x00,0x2a,0x3f,
62 0x2a,0x00,0x15, 0x2a,0x00,0x3f, 0x2a,0x2a,0x15, 0x2a,0x2a,0x3f,
63 0x00,0x15,0x00, 0x00,0x15,0x2a, 0x00,0x3f,0x00, 0x00,0x3f,0x2a,
64 0x2a,0x15,0x00, 0x2a,0x15,0x2a, 0x2a,0x3f,0x00, 0x2a,0x3f,0x2a,
65 0x00,0x15,0x15, 0x00,0x15,0x3f, 0x00,0x3f,0x15, 0x00,0x3f,0x3f,
66 0x2a,0x15,0x15, 0x2a,0x15,0x3f, 0x2a,0x3f,0x15, 0x2a,0x3f,0x3f,
67 0x15,0x00,0x00, 0x15,0x00,0x2a, 0x15,0x2a,0x00, 0x15,0x2a,0x2a,
68 0x3f,0x00,0x00, 0x3f,0x00,0x2a, 0x3f,0x2a,0x00, 0x3f,0x2a,0x2a,
69 0x15,0x00,0x15, 0x15,0x00,0x3f, 0x15,0x2a,0x15, 0x15,0x2a,0x3f,
70 0x3f,0x00,0x15, 0x3f,0x00,0x3f, 0x3f,0x2a,0x15, 0x3f,0x2a,0x3f,
71 0x15,0x15,0x00, 0x15,0x15,0x2a, 0x15,0x3f,0x00, 0x15,0x3f,0x2a,
72 0x3f,0x15,0x00, 0x3f,0x15,0x2a, 0x3f,0x3f,0x00, 0x3f,0x3f,0x2a,
73 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
74 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f
Kevin O'Connor1f2c3072009-05-06 23:35:59 -040075};
76
Kevin O'Connor5727c292009-05-16 17:29:32 -040077static u8 palette3[] VAR16 = {
Kevin O'Connora959aa12009-05-25 00:12:18 -040078 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
79 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
80 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
81 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
82 0x00,0x00,0x00, 0x05,0x05,0x05, 0x08,0x08,0x08, 0x0b,0x0b,0x0b,
83 0x0e,0x0e,0x0e, 0x11,0x11,0x11, 0x14,0x14,0x14, 0x18,0x18,0x18,
84 0x1c,0x1c,0x1c, 0x20,0x20,0x20, 0x24,0x24,0x24, 0x28,0x28,0x28,
85 0x2d,0x2d,0x2d, 0x32,0x32,0x32, 0x38,0x38,0x38, 0x3f,0x3f,0x3f,
86 0x00,0x00,0x3f, 0x10,0x00,0x3f, 0x1f,0x00,0x3f, 0x2f,0x00,0x3f,
87 0x3f,0x00,0x3f, 0x3f,0x00,0x2f, 0x3f,0x00,0x1f, 0x3f,0x00,0x10,
88 0x3f,0x00,0x00, 0x3f,0x10,0x00, 0x3f,0x1f,0x00, 0x3f,0x2f,0x00,
89 0x3f,0x3f,0x00, 0x2f,0x3f,0x00, 0x1f,0x3f,0x00, 0x10,0x3f,0x00,
90 0x00,0x3f,0x00, 0x00,0x3f,0x10, 0x00,0x3f,0x1f, 0x00,0x3f,0x2f,
91 0x00,0x3f,0x3f, 0x00,0x2f,0x3f, 0x00,0x1f,0x3f, 0x00,0x10,0x3f,
92 0x1f,0x1f,0x3f, 0x27,0x1f,0x3f, 0x2f,0x1f,0x3f, 0x37,0x1f,0x3f,
93 0x3f,0x1f,0x3f, 0x3f,0x1f,0x37, 0x3f,0x1f,0x2f, 0x3f,0x1f,0x27,
Kevin O'Connor1f2c3072009-05-06 23:35:59 -040094
Kevin O'Connora959aa12009-05-25 00:12:18 -040095 0x3f,0x1f,0x1f, 0x3f,0x27,0x1f, 0x3f,0x2f,0x1f, 0x3f,0x37,0x1f,
96 0x3f,0x3f,0x1f, 0x37,0x3f,0x1f, 0x2f,0x3f,0x1f, 0x27,0x3f,0x1f,
97 0x1f,0x3f,0x1f, 0x1f,0x3f,0x27, 0x1f,0x3f,0x2f, 0x1f,0x3f,0x37,
98 0x1f,0x3f,0x3f, 0x1f,0x37,0x3f, 0x1f,0x2f,0x3f, 0x1f,0x27,0x3f,
99 0x2d,0x2d,0x3f, 0x31,0x2d,0x3f, 0x36,0x2d,0x3f, 0x3a,0x2d,0x3f,
100 0x3f,0x2d,0x3f, 0x3f,0x2d,0x3a, 0x3f,0x2d,0x36, 0x3f,0x2d,0x31,
101 0x3f,0x2d,0x2d, 0x3f,0x31,0x2d, 0x3f,0x36,0x2d, 0x3f,0x3a,0x2d,
102 0x3f,0x3f,0x2d, 0x3a,0x3f,0x2d, 0x36,0x3f,0x2d, 0x31,0x3f,0x2d,
103 0x2d,0x3f,0x2d, 0x2d,0x3f,0x31, 0x2d,0x3f,0x36, 0x2d,0x3f,0x3a,
104 0x2d,0x3f,0x3f, 0x2d,0x3a,0x3f, 0x2d,0x36,0x3f, 0x2d,0x31,0x3f,
105 0x00,0x00,0x1c, 0x07,0x00,0x1c, 0x0e,0x00,0x1c, 0x15,0x00,0x1c,
106 0x1c,0x00,0x1c, 0x1c,0x00,0x15, 0x1c,0x00,0x0e, 0x1c,0x00,0x07,
107 0x1c,0x00,0x00, 0x1c,0x07,0x00, 0x1c,0x0e,0x00, 0x1c,0x15,0x00,
108 0x1c,0x1c,0x00, 0x15,0x1c,0x00, 0x0e,0x1c,0x00, 0x07,0x1c,0x00,
109 0x00,0x1c,0x00, 0x00,0x1c,0x07, 0x00,0x1c,0x0e, 0x00,0x1c,0x15,
110 0x00,0x1c,0x1c, 0x00,0x15,0x1c, 0x00,0x0e,0x1c, 0x00,0x07,0x1c,
Kevin O'Connor1f2c3072009-05-06 23:35:59 -0400111
Kevin O'Connora959aa12009-05-25 00:12:18 -0400112 0x0e,0x0e,0x1c, 0x11,0x0e,0x1c, 0x15,0x0e,0x1c, 0x18,0x0e,0x1c,
113 0x1c,0x0e,0x1c, 0x1c,0x0e,0x18, 0x1c,0x0e,0x15, 0x1c,0x0e,0x11,
114 0x1c,0x0e,0x0e, 0x1c,0x11,0x0e, 0x1c,0x15,0x0e, 0x1c,0x18,0x0e,
115 0x1c,0x1c,0x0e, 0x18,0x1c,0x0e, 0x15,0x1c,0x0e, 0x11,0x1c,0x0e,
116 0x0e,0x1c,0x0e, 0x0e,0x1c,0x11, 0x0e,0x1c,0x15, 0x0e,0x1c,0x18,
117 0x0e,0x1c,0x1c, 0x0e,0x18,0x1c, 0x0e,0x15,0x1c, 0x0e,0x11,0x1c,
118 0x14,0x14,0x1c, 0x16,0x14,0x1c, 0x18,0x14,0x1c, 0x1a,0x14,0x1c,
119 0x1c,0x14,0x1c, 0x1c,0x14,0x1a, 0x1c,0x14,0x18, 0x1c,0x14,0x16,
120 0x1c,0x14,0x14, 0x1c,0x16,0x14, 0x1c,0x18,0x14, 0x1c,0x1a,0x14,
121 0x1c,0x1c,0x14, 0x1a,0x1c,0x14, 0x18,0x1c,0x14, 0x16,0x1c,0x14,
122 0x14,0x1c,0x14, 0x14,0x1c,0x16, 0x14,0x1c,0x18, 0x14,0x1c,0x1a,
123 0x14,0x1c,0x1c, 0x14,0x1a,0x1c, 0x14,0x18,0x1c, 0x14,0x16,0x1c,
124 0x00,0x00,0x10, 0x04,0x00,0x10, 0x08,0x00,0x10, 0x0c,0x00,0x10,
125 0x10,0x00,0x10, 0x10,0x00,0x0c, 0x10,0x00,0x08, 0x10,0x00,0x04,
126 0x10,0x00,0x00, 0x10,0x04,0x00, 0x10,0x08,0x00, 0x10,0x0c,0x00,
127 0x10,0x10,0x00, 0x0c,0x10,0x00, 0x08,0x10,0x00, 0x04,0x10,0x00,
Kevin O'Connor1f2c3072009-05-06 23:35:59 -0400128
Kevin O'Connora959aa12009-05-25 00:12:18 -0400129 0x00,0x10,0x00, 0x00,0x10,0x04, 0x00,0x10,0x08, 0x00,0x10,0x0c,
130 0x00,0x10,0x10, 0x00,0x0c,0x10, 0x00,0x08,0x10, 0x00,0x04,0x10,
131 0x08,0x08,0x10, 0x0a,0x08,0x10, 0x0c,0x08,0x10, 0x0e,0x08,0x10,
132 0x10,0x08,0x10, 0x10,0x08,0x0e, 0x10,0x08,0x0c, 0x10,0x08,0x0a,
133 0x10,0x08,0x08, 0x10,0x0a,0x08, 0x10,0x0c,0x08, 0x10,0x0e,0x08,
134 0x10,0x10,0x08, 0x0e,0x10,0x08, 0x0c,0x10,0x08, 0x0a,0x10,0x08,
135 0x08,0x10,0x08, 0x08,0x10,0x0a, 0x08,0x10,0x0c, 0x08,0x10,0x0e,
136 0x08,0x10,0x10, 0x08,0x0e,0x10, 0x08,0x0c,0x10, 0x08,0x0a,0x10,
137 0x0b,0x0b,0x10, 0x0c,0x0b,0x10, 0x0d,0x0b,0x10, 0x0f,0x0b,0x10,
138 0x10,0x0b,0x10, 0x10,0x0b,0x0f, 0x10,0x0b,0x0d, 0x10,0x0b,0x0c,
139 0x10,0x0b,0x0b, 0x10,0x0c,0x0b, 0x10,0x0d,0x0b, 0x10,0x0f,0x0b,
140 0x10,0x10,0x0b, 0x0f,0x10,0x0b, 0x0d,0x10,0x0b, 0x0c,0x10,0x0b,
141 0x0b,0x10,0x0b, 0x0b,0x10,0x0c, 0x0b,0x10,0x0d, 0x0b,0x10,0x0f,
142 0x0b,0x10,0x10, 0x0b,0x0f,0x10, 0x0b,0x0d,0x10, 0x0b,0x0c,0x10,
143 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
144 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00
Kevin O'Connor1f2c3072009-05-06 23:35:59 -0400145};
146
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500147static u8 sequ_01[] VAR16 = { 0x08, 0x03, 0x00, 0x02 };
148static u8 crtc_01[] VAR16 = {
149 0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
150 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
151 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3,
152 0xff };
153static u8 actl_01[] VAR16 = {
154 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
155 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
156 0x0c, 0x00, 0x0f, 0x08 };
157static u8 grdc_01[] VAR16 = {
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff };
159static u8 sequ_03[] VAR16 = { 0x00, 0x03, 0x00, 0x02 };
160static u8 crtc_03[] VAR16 = {
161 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
162 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
163 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
164 0xff };
165static u8 sequ_04[] VAR16 = { 0x09, 0x03, 0x00, 0x02 };
166static u8 crtc_04[] VAR16 = {
167 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f,
168 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2,
170 0xff };
171static u8 actl_04[] VAR16 = {
172 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07,
173 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
174 0x01, 0x00, 0x03, 0x00 };
175static u8 grdc_04[] VAR16 = {
176 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff };
177static u8 sequ_06[] VAR16 = { 0x01, 0x01, 0x00, 0x06 };
178static u8 crtc_06[] VAR16 = {
179 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
180 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2,
182 0xff };
183static u8 actl_06[] VAR16 = {
184 0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
185 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
186 0x01, 0x00, 0x01, 0x00 };
187static u8 grdc_06[] VAR16 = {
188 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0f, 0xff };
189static u8 crtc_07[] VAR16 = {
190 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
191 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
192 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3,
193 0xff };
194static u8 actl_07[] VAR16 = {
195 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
196 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
197 0x0e, 0x00, 0x0f, 0x08 };
198static u8 grdc_07[] VAR16 = {
199 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff };
200static u8 sequ_0d[] VAR16 = { 0x09, 0x0f, 0x00, 0x06 };
201static u8 crtc_0d[] VAR16 = {
202 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f,
203 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3,
205 0xff };
206static u8 actl_0d[] VAR16 = {
207 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
208 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
209 0x01, 0x00, 0x0f, 0x00 };
210static u8 grdc_0d[] VAR16 = {
211 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff };
212static u8 sequ_0e[] VAR16 = { 0x01, 0x0f, 0x00, 0x06 };
213static u8 crtc_0e[] VAR16 = {
214 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
215 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
216 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3,
217 0xff };
218static u8 crtc_0f[] VAR16 = {
219 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
220 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
221 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3,
222 0xff };
223static u8 actl_0f[] VAR16 = {
224 0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
225 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
226 0x01, 0x00, 0x01, 0x00 };
227static u8 actl_10[] VAR16 = {
228 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
229 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
230 0x01, 0x00, 0x0f, 0x00 };
231static u8 crtc_11[] VAR16 = {
232 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e,
233 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
234 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3,
235 0xff };
236static u8 actl_11[] VAR16 = {
237 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f,
238 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f,
239 0x01, 0x00, 0x0f, 0x00 };
240static u8 sequ_13[] VAR16 = { 0x01, 0x0f, 0x00, 0x0e };
241static u8 crtc_13[] VAR16 = {
242 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
243 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244 0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3,
245 0xff };
246static u8 actl_13[] VAR16 = {
247 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
248 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
249 0x41, 0x00, 0x0f, 0x00 };
250static u8 grdc_13[] VAR16 = {
251 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff };
252static u8 crtc_6A[] VAR16 = {
253 0x7f, 0x63, 0x63, 0x83, 0x6b, 0x1b, 0x72, 0xf0,
254 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
255 0x59, 0x8d, 0x57, 0x32, 0x00, 0x57, 0x73, 0xe3,
256 0xff };
257
Kevin O'Connor5727c292009-05-16 17:29:32 -0400258#define PAL(x) x, sizeof(x)
Kevin O'Connor5727c292009-05-16 17:29:32 -0400259
Kevin O'Connorf98bbf02012-01-27 23:09:02 -0500260struct stdvga_mode_s {
261 u16 mode;
262 struct vgamode_s info;
263
264 u8 pelmask;
265 u8 *dac;
266 u16 dacsize;
267 u8 *sequ_regs;
268 u8 miscreg;
269 u8 *crtc_regs;
270 u8 *actl_regs;
271 u8 *grdc_regs;
272};
273
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500274static struct stdvga_mode_s vga_modes[] VAR16 = {
275 //mode { model tx ty bpp cw ch sstart }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500276 // pelm dac sequ misc crtc actl grdc
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500277 {0x00, { MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT }
Kevin O'Connord4398ad2012-01-01 12:32:53 -0500278 , 0xFF, PAL(palette2), sequ_01, 0x67, crtc_01, actl_01, grdc_01},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500279 {0x01, { MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT }
Kevin O'Connord4398ad2012-01-01 12:32:53 -0500280 , 0xFF, PAL(palette2), sequ_01, 0x67, crtc_01, actl_01, grdc_01},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500281 {0x02, { MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT }
Kevin O'Connord4398ad2012-01-01 12:32:53 -0500282 , 0xFF, PAL(palette2), sequ_03, 0x67, crtc_03, actl_01, grdc_01},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500283 {0x03, { MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT }
Kevin O'Connord4398ad2012-01-01 12:32:53 -0500284 , 0xFF, PAL(palette2), sequ_03, 0x67, crtc_03, actl_01, grdc_01},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500285 {0x04, { MM_CGA, 320, 200, 2, 8, 8, SEG_CTEXT }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500286 , 0xFF, PAL(palette1), sequ_04, 0x63, crtc_04, actl_04, grdc_04},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500287 {0x05, { MM_CGA, 320, 200, 2, 8, 8, SEG_CTEXT }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500288 , 0xFF, PAL(palette1), sequ_04, 0x63, crtc_04, actl_04, grdc_04},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500289 {0x06, { MM_CGA, 640, 200, 1, 8, 8, SEG_CTEXT }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500290 , 0xFF, PAL(palette1), sequ_06, 0x63, crtc_06, actl_06, grdc_06},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500291 {0x07, { MM_TEXT, 80, 25, 4, 9, 16, SEG_MTEXT }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500292 , 0xFF, PAL(palette0), sequ_03, 0x66, crtc_07, actl_07, grdc_07},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500293 {0x0D, { MM_PLANAR, 320, 200, 4, 8, 8, SEG_GRAPH }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500294 , 0xFF, PAL(palette1), sequ_0d, 0x63, crtc_0d, actl_0d, grdc_0d},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500295 {0x0E, { MM_PLANAR, 640, 200, 4, 8, 8, SEG_GRAPH }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500296 , 0xFF, PAL(palette1), sequ_0e, 0x63, crtc_0e, actl_0d, grdc_0d},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500297 {0x0F, { MM_PLANAR, 640, 350, 1, 8, 14, SEG_GRAPH }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500298 , 0xFF, PAL(palette0), sequ_0e, 0xa3, crtc_0f, actl_0f, grdc_0d},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500299 {0x10, { MM_PLANAR, 640, 350, 4, 8, 14, SEG_GRAPH }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500300 , 0xFF, PAL(palette2), sequ_0e, 0xa3, crtc_0f, actl_10, grdc_0d},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500301 {0x11, { MM_PLANAR, 640, 480, 1, 8, 16, SEG_GRAPH }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500302 , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_11, actl_11, grdc_0d},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500303 {0x12, { MM_PLANAR, 640, 480, 4, 8, 16, SEG_GRAPH }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500304 , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_11, actl_10, grdc_0d},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500305 {0x13, { MM_PACKED, 320, 200, 8, 8, 8, SEG_GRAPH }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500306 , 0xFF, PAL(palette3), sequ_13, 0x63, crtc_13, actl_13, grdc_13},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500307 {0x6A, { MM_PLANAR, 800, 600, 4, 8, 16, SEG_GRAPH }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500308 , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_6A, actl_10, grdc_0d},
Kevin O'Connor5727c292009-05-16 17:29:32 -0400309};
310
Kevin O'Connoraad3b692012-01-14 23:15:40 -0500311
312/****************************************************************
313 * Mode functions
314 ****************************************************************/
315
Kevin O'Connorf98bbf02012-01-27 23:09:02 -0500316static int
317is_stdvga_mode(struct vgamode_s *vmode_g)
Kevin O'Connore6bc4c12012-01-21 11:26:37 -0500318{
319 return (vmode_g >= &vga_modes[0].info
320 && vmode_g <= &vga_modes[ARRAY_SIZE(vga_modes)-1].info);
321}
322
Kevin O'Connor5727c292009-05-16 17:29:32 -0400323struct vgamode_s *
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500324stdvga_find_mode(int mode)
Kevin O'Connor5727c292009-05-16 17:29:32 -0400325{
326 int i;
327 for (i = 0; i < ARRAY_SIZE(vga_modes); i++) {
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500328 struct stdvga_mode_s *stdmode_g = &vga_modes[i];
329 if (GET_GLOBAL(stdmode_g->mode) == mode)
330 return &stdmode_g->info;
Kevin O'Connor5727c292009-05-16 17:29:32 -0400331 }
332 return NULL;
333}
Kevin O'Connoraad3b692012-01-14 23:15:40 -0500334
335void
Kevin O'Connorf98bbf02012-01-27 23:09:02 -0500336stdvga_list_modes(u16 seg, u16 *dest, u16 *last)
337{
Christian Gmeinera1a32832012-09-01 17:12:55 +0200338 int i;
339 for (i = 0; i < ARRAY_SIZE(vga_modes); i++) {
340 struct stdvga_mode_s *stdmode_g = &vga_modes[i];
341 u16 mode = GET_GLOBAL(stdmode_g->mode);
342 if (mode == 0xffff)
343 continue;
344 SET_FARVAR(seg, *dest, mode);
345 dest++;
346 }
347
Kevin O'Connorf98bbf02012-01-27 23:09:02 -0500348 SET_FARVAR(seg, *dest, 0xffff);
349}
350
351void
Kevin O'Connoraad3b692012-01-14 23:15:40 -0500352stdvga_build_video_param(void)
353{
354 static u8 parammodes[] VAR16 = {
355 0, 0, 0, 0, 0x04, 0x05, 0x06, 0x07,
356 0, 0, 0, 0, 0, 0x0d, 0x0e, 0,
357 0, 0x0f, 0x10, 0, 0, 0, 0, 0x01,
358 0x03, 0x07, 0x11, 0x12, 0x13
359 };
360
361 int i;
362 for (i=0; i<ARRAY_SIZE(parammodes); i++) {
363 int mode = GET_GLOBAL(parammodes[i]);
364 if (! mode)
365 continue;
366 struct VideoParam_s *vparam_g = &video_param_table[i];
367 struct vgamode_s *vmode_g = stdvga_find_mode(mode);
368 if (!vmode_g)
369 continue;
370 int width = GET_GLOBAL(vmode_g->width);
371 int height = GET_GLOBAL(vmode_g->height);
372 u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
373 int cheight = GET_GLOBAL(vmode_g->cheight);
374 if (memmodel == MM_TEXT) {
375 SET_VGA(vparam_g->twidth, width);
376 SET_VGA(vparam_g->theightm1, height-1);
377 } else {
378 int cwidth = GET_GLOBAL(vmode_g->cwidth);
379 SET_VGA(vparam_g->twidth, width / cwidth);
380 SET_VGA(vparam_g->theightm1, (height / cheight) - 1);
381 }
382 SET_VGA(vparam_g->cheight, cheight);
383 SET_VGA(vparam_g->slength, calc_page_size(memmodel, width, height));
384 struct stdvga_mode_s *stdmode_g = container_of(
385 vmode_g, struct stdvga_mode_s, info);
386 memcpy_far(get_global_seg(), vparam_g->sequ_regs
387 , get_global_seg(), GET_GLOBAL(stdmode_g->sequ_regs)
388 , ARRAY_SIZE(vparam_g->sequ_regs));
389 SET_VGA(vparam_g->miscreg, GET_GLOBAL(stdmode_g->miscreg));
390 memcpy_far(get_global_seg(), vparam_g->crtc_regs
391 , get_global_seg(), GET_GLOBAL(stdmode_g->crtc_regs)
392 , ARRAY_SIZE(vparam_g->crtc_regs));
393 memcpy_far(get_global_seg(), vparam_g->actl_regs
394 , get_global_seg(), GET_GLOBAL(stdmode_g->actl_regs)
395 , ARRAY_SIZE(vparam_g->actl_regs));
396 memcpy_far(get_global_seg(), vparam_g->grdc_regs
397 , get_global_seg(), GET_GLOBAL(stdmode_g->grdc_regs)
398 , ARRAY_SIZE(vparam_g->grdc_regs));
399 }
400}
Kevin O'Connor69b01cb2012-01-14 23:25:24 -0500401
402void
403stdvga_override_crtc(int mode, u8 *crtc)
404{
405 struct vgamode_s *vmode_g = stdvga_find_mode(mode);
406 if (!vmode_g)
407 return;
408 struct stdvga_mode_s *stdmode_g = container_of(
409 vmode_g, struct stdvga_mode_s, info);
410 SET_VGA(stdmode_g->crtc_regs, crtc);
411}
Kevin O'Connorf98bbf02012-01-27 23:09:02 -0500412
413static void
414clear_screen(struct vgamode_s *vmode_g)
415{
416 switch (GET_GLOBAL(vmode_g->memmodel)) {
417 case MM_TEXT:
418 memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0720, 32*1024);
419 break;
420 case MM_CGA:
421 memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 32*1024);
422 break;
423 default:
424 // XXX - old code gets/sets/restores sequ register 2 to 0xf -
425 // but it should always be 0xf anyway.
426 memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 64*1024);
427 }
428}
429
430int
431stdvga_set_mode(struct vgamode_s *vmode_g, int flags)
432{
433 if (! is_stdvga_mode(vmode_g)) {
434 warn_internalerror();
435 return -1;
436 }
437 struct stdvga_mode_s *stdmode_g = container_of(
438 vmode_g, struct stdvga_mode_s, info);
439
440 // if palette loading (bit 3 of modeset ctl = 0)
441 if (!(flags & MF_NOPALETTE)) { // Set the PEL mask
442 stdvga_pelmask_write(GET_GLOBAL(stdmode_g->pelmask));
443
444 // From which palette
445 u8 *palette_g = GET_GLOBAL(stdmode_g->dac);
446 u16 palsize = GET_GLOBAL(stdmode_g->dacsize) / 3;
447
448 // Always 256*3 values
449 stdvga_dac_write(get_global_seg(), palette_g, 0, palsize);
450 int i;
451 for (i = palsize; i < 0x0100; i++) {
452 static u8 rgb[3] VAR16;
453 stdvga_dac_write(get_global_seg(), rgb, i, 1);
454 }
455
456 if (flags & MF_GRAYSUM)
457 stdvga_perform_gray_scale_summing(0x00, 0x100);
458 }
459
460 // Set Attribute Ctl
461 u8 *regs = GET_GLOBAL(stdmode_g->actl_regs);
462 int i;
463 for (i = 0; i <= 0x13; i++)
464 stdvga_attr_write(i, GET_GLOBAL(regs[i]));
465 stdvga_attr_write(0x14, 0x00);
466
467 // Set Sequencer Ctl
468 stdvga_sequ_write(0x00, 0x03);
469 regs = GET_GLOBAL(stdmode_g->sequ_regs);
470 for (i = 1; i <= 4; i++)
471 stdvga_sequ_write(i, GET_GLOBAL(regs[i - 1]));
472
473 // Set Grafx Ctl
474 regs = GET_GLOBAL(stdmode_g->grdc_regs);
475 for (i = 0; i <= 8; i++)
476 stdvga_grdc_write(i, GET_GLOBAL(regs[i]));
477
478 // Set CRTC address VGA or MDA
479 u8 miscreg = GET_GLOBAL(stdmode_g->miscreg);
480 u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS;
481 if (!(miscreg & 1))
482 crtc_addr = VGAREG_MDA_CRTC_ADDRESS;
483
484 // Disable CRTC write protection
485 stdvga_crtc_write(crtc_addr, 0x11, 0x00);
486 // Set CRTC regs
487 regs = GET_GLOBAL(stdmode_g->crtc_regs);
488 for (i = 0; i <= 0x18; i++)
489 stdvga_crtc_write(crtc_addr, i, GET_GLOBAL(regs[i]));
490
491 // Set the misc register
492 stdvga_misc_write(miscreg);
493
494 // Enable video
495 stdvga_attrindex_write(0x20);
496
497 // Clear screen
498 if (!(flags & MF_NOCLEARMEM))
499 clear_screen(vmode_g);
500
501 // Write the fonts in memory
502 u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
503 if (memmodel == MM_TEXT)
504 stdvga_load_font(get_global_seg(), vgafont16, 0x100, 0, 0, 16);
505
506 return 0;
507}
Kevin O'Connor5b6936e2013-11-29 18:43:35 -0500508
509// Load the standard palette associated with 8bpp packed pixel vga modes.
510void
511stdvga_set_packed_palette(void)
512{
513 stdvga_dac_write(get_global_seg(), palette3, 0, sizeof(palette3) / 3);
514}