blob: 173dd4f7bd291eb05254a26a81e83c1a467e9e21 [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'Connor536129a2016-08-05 10:58:24 -040010#include "std/vga.h" // struct video_param_s
Kevin O'Connoraad3b692012-01-14 23:15:40 -050011#include "stdvga.h" // stdvga_find_mode
Kevin O'Connorfa9c66a2013-09-14 19:10:40 -040012#include "string.h" // memcpy_far
Kevin O'Connor2f2ec112016-08-05 11:14:58 -040013#include "vgabios.h" // SET_VGA
14#include "vgautil.h" // vgafont16
Kevin O'Connor1f2c3072009-05-06 23:35:59 -040015
Kevin O'Connor1f2c3072009-05-06 23:35:59 -040016
Kevin O'Connor5727c292009-05-16 17:29:32 -040017/****************************************************************
Kevin O'Connoraad3b692012-01-14 23:15:40 -050018 * Video mode register definitions
Kevin O'Connor5727c292009-05-16 17:29:32 -040019 ****************************************************************/
20
Kevin O'Connor1f2c3072009-05-06 23:35:59 -040021/* Mono */
Kevin O'Connor5727c292009-05-16 17:29:32 -040022static u8 palette0[] VAR16 = {
Kevin O'Connora959aa12009-05-25 00:12:18 -040023 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
24 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
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 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
28 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
29 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f,
30 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f,
31 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
32 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
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 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
36 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
37 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f,
38 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f
Kevin O'Connor1f2c3072009-05-06 23:35:59 -040039};
40
Kevin O'Connor5727c292009-05-16 17:29:32 -040041static u8 palette1[] VAR16 = {
Kevin O'Connora959aa12009-05-25 00:12:18 -040042 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 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
45 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
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 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
49 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
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 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
53 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
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,
56 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
57 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f
Kevin O'Connor1f2c3072009-05-06 23:35:59 -040058};
59
Kevin O'Connor5727c292009-05-16 17:29:32 -040060static u8 palette2[] VAR16 = {
Kevin O'Connora959aa12009-05-25 00:12:18 -040061 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
62 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x2a,0x00, 0x2a,0x2a,0x2a,
63 0x00,0x00,0x15, 0x00,0x00,0x3f, 0x00,0x2a,0x15, 0x00,0x2a,0x3f,
64 0x2a,0x00,0x15, 0x2a,0x00,0x3f, 0x2a,0x2a,0x15, 0x2a,0x2a,0x3f,
65 0x00,0x15,0x00, 0x00,0x15,0x2a, 0x00,0x3f,0x00, 0x00,0x3f,0x2a,
66 0x2a,0x15,0x00, 0x2a,0x15,0x2a, 0x2a,0x3f,0x00, 0x2a,0x3f,0x2a,
67 0x00,0x15,0x15, 0x00,0x15,0x3f, 0x00,0x3f,0x15, 0x00,0x3f,0x3f,
68 0x2a,0x15,0x15, 0x2a,0x15,0x3f, 0x2a,0x3f,0x15, 0x2a,0x3f,0x3f,
69 0x15,0x00,0x00, 0x15,0x00,0x2a, 0x15,0x2a,0x00, 0x15,0x2a,0x2a,
70 0x3f,0x00,0x00, 0x3f,0x00,0x2a, 0x3f,0x2a,0x00, 0x3f,0x2a,0x2a,
71 0x15,0x00,0x15, 0x15,0x00,0x3f, 0x15,0x2a,0x15, 0x15,0x2a,0x3f,
72 0x3f,0x00,0x15, 0x3f,0x00,0x3f, 0x3f,0x2a,0x15, 0x3f,0x2a,0x3f,
73 0x15,0x15,0x00, 0x15,0x15,0x2a, 0x15,0x3f,0x00, 0x15,0x3f,0x2a,
74 0x3f,0x15,0x00, 0x3f,0x15,0x2a, 0x3f,0x3f,0x00, 0x3f,0x3f,0x2a,
75 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
76 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f
Kevin O'Connor1f2c3072009-05-06 23:35:59 -040077};
78
Kevin O'Connor5727c292009-05-16 17:29:32 -040079static u8 palette3[] VAR16 = {
Kevin O'Connora959aa12009-05-25 00:12:18 -040080 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a,
81 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
82 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f,
83 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
84 0x00,0x00,0x00, 0x05,0x05,0x05, 0x08,0x08,0x08, 0x0b,0x0b,0x0b,
85 0x0e,0x0e,0x0e, 0x11,0x11,0x11, 0x14,0x14,0x14, 0x18,0x18,0x18,
86 0x1c,0x1c,0x1c, 0x20,0x20,0x20, 0x24,0x24,0x24, 0x28,0x28,0x28,
87 0x2d,0x2d,0x2d, 0x32,0x32,0x32, 0x38,0x38,0x38, 0x3f,0x3f,0x3f,
88 0x00,0x00,0x3f, 0x10,0x00,0x3f, 0x1f,0x00,0x3f, 0x2f,0x00,0x3f,
89 0x3f,0x00,0x3f, 0x3f,0x00,0x2f, 0x3f,0x00,0x1f, 0x3f,0x00,0x10,
90 0x3f,0x00,0x00, 0x3f,0x10,0x00, 0x3f,0x1f,0x00, 0x3f,0x2f,0x00,
91 0x3f,0x3f,0x00, 0x2f,0x3f,0x00, 0x1f,0x3f,0x00, 0x10,0x3f,0x00,
92 0x00,0x3f,0x00, 0x00,0x3f,0x10, 0x00,0x3f,0x1f, 0x00,0x3f,0x2f,
93 0x00,0x3f,0x3f, 0x00,0x2f,0x3f, 0x00,0x1f,0x3f, 0x00,0x10,0x3f,
94 0x1f,0x1f,0x3f, 0x27,0x1f,0x3f, 0x2f,0x1f,0x3f, 0x37,0x1f,0x3f,
95 0x3f,0x1f,0x3f, 0x3f,0x1f,0x37, 0x3f,0x1f,0x2f, 0x3f,0x1f,0x27,
Kevin O'Connor1f2c3072009-05-06 23:35:59 -040096
Kevin O'Connora959aa12009-05-25 00:12:18 -040097 0x3f,0x1f,0x1f, 0x3f,0x27,0x1f, 0x3f,0x2f,0x1f, 0x3f,0x37,0x1f,
98 0x3f,0x3f,0x1f, 0x37,0x3f,0x1f, 0x2f,0x3f,0x1f, 0x27,0x3f,0x1f,
99 0x1f,0x3f,0x1f, 0x1f,0x3f,0x27, 0x1f,0x3f,0x2f, 0x1f,0x3f,0x37,
100 0x1f,0x3f,0x3f, 0x1f,0x37,0x3f, 0x1f,0x2f,0x3f, 0x1f,0x27,0x3f,
101 0x2d,0x2d,0x3f, 0x31,0x2d,0x3f, 0x36,0x2d,0x3f, 0x3a,0x2d,0x3f,
102 0x3f,0x2d,0x3f, 0x3f,0x2d,0x3a, 0x3f,0x2d,0x36, 0x3f,0x2d,0x31,
103 0x3f,0x2d,0x2d, 0x3f,0x31,0x2d, 0x3f,0x36,0x2d, 0x3f,0x3a,0x2d,
104 0x3f,0x3f,0x2d, 0x3a,0x3f,0x2d, 0x36,0x3f,0x2d, 0x31,0x3f,0x2d,
105 0x2d,0x3f,0x2d, 0x2d,0x3f,0x31, 0x2d,0x3f,0x36, 0x2d,0x3f,0x3a,
106 0x2d,0x3f,0x3f, 0x2d,0x3a,0x3f, 0x2d,0x36,0x3f, 0x2d,0x31,0x3f,
107 0x00,0x00,0x1c, 0x07,0x00,0x1c, 0x0e,0x00,0x1c, 0x15,0x00,0x1c,
108 0x1c,0x00,0x1c, 0x1c,0x00,0x15, 0x1c,0x00,0x0e, 0x1c,0x00,0x07,
109 0x1c,0x00,0x00, 0x1c,0x07,0x00, 0x1c,0x0e,0x00, 0x1c,0x15,0x00,
110 0x1c,0x1c,0x00, 0x15,0x1c,0x00, 0x0e,0x1c,0x00, 0x07,0x1c,0x00,
111 0x00,0x1c,0x00, 0x00,0x1c,0x07, 0x00,0x1c,0x0e, 0x00,0x1c,0x15,
112 0x00,0x1c,0x1c, 0x00,0x15,0x1c, 0x00,0x0e,0x1c, 0x00,0x07,0x1c,
Kevin O'Connor1f2c3072009-05-06 23:35:59 -0400113
Kevin O'Connora959aa12009-05-25 00:12:18 -0400114 0x0e,0x0e,0x1c, 0x11,0x0e,0x1c, 0x15,0x0e,0x1c, 0x18,0x0e,0x1c,
115 0x1c,0x0e,0x1c, 0x1c,0x0e,0x18, 0x1c,0x0e,0x15, 0x1c,0x0e,0x11,
116 0x1c,0x0e,0x0e, 0x1c,0x11,0x0e, 0x1c,0x15,0x0e, 0x1c,0x18,0x0e,
117 0x1c,0x1c,0x0e, 0x18,0x1c,0x0e, 0x15,0x1c,0x0e, 0x11,0x1c,0x0e,
118 0x0e,0x1c,0x0e, 0x0e,0x1c,0x11, 0x0e,0x1c,0x15, 0x0e,0x1c,0x18,
119 0x0e,0x1c,0x1c, 0x0e,0x18,0x1c, 0x0e,0x15,0x1c, 0x0e,0x11,0x1c,
120 0x14,0x14,0x1c, 0x16,0x14,0x1c, 0x18,0x14,0x1c, 0x1a,0x14,0x1c,
121 0x1c,0x14,0x1c, 0x1c,0x14,0x1a, 0x1c,0x14,0x18, 0x1c,0x14,0x16,
122 0x1c,0x14,0x14, 0x1c,0x16,0x14, 0x1c,0x18,0x14, 0x1c,0x1a,0x14,
123 0x1c,0x1c,0x14, 0x1a,0x1c,0x14, 0x18,0x1c,0x14, 0x16,0x1c,0x14,
124 0x14,0x1c,0x14, 0x14,0x1c,0x16, 0x14,0x1c,0x18, 0x14,0x1c,0x1a,
125 0x14,0x1c,0x1c, 0x14,0x1a,0x1c, 0x14,0x18,0x1c, 0x14,0x16,0x1c,
126 0x00,0x00,0x10, 0x04,0x00,0x10, 0x08,0x00,0x10, 0x0c,0x00,0x10,
127 0x10,0x00,0x10, 0x10,0x00,0x0c, 0x10,0x00,0x08, 0x10,0x00,0x04,
128 0x10,0x00,0x00, 0x10,0x04,0x00, 0x10,0x08,0x00, 0x10,0x0c,0x00,
129 0x10,0x10,0x00, 0x0c,0x10,0x00, 0x08,0x10,0x00, 0x04,0x10,0x00,
Kevin O'Connor1f2c3072009-05-06 23:35:59 -0400130
Kevin O'Connora959aa12009-05-25 00:12:18 -0400131 0x00,0x10,0x00, 0x00,0x10,0x04, 0x00,0x10,0x08, 0x00,0x10,0x0c,
132 0x00,0x10,0x10, 0x00,0x0c,0x10, 0x00,0x08,0x10, 0x00,0x04,0x10,
133 0x08,0x08,0x10, 0x0a,0x08,0x10, 0x0c,0x08,0x10, 0x0e,0x08,0x10,
134 0x10,0x08,0x10, 0x10,0x08,0x0e, 0x10,0x08,0x0c, 0x10,0x08,0x0a,
135 0x10,0x08,0x08, 0x10,0x0a,0x08, 0x10,0x0c,0x08, 0x10,0x0e,0x08,
136 0x10,0x10,0x08, 0x0e,0x10,0x08, 0x0c,0x10,0x08, 0x0a,0x10,0x08,
137 0x08,0x10,0x08, 0x08,0x10,0x0a, 0x08,0x10,0x0c, 0x08,0x10,0x0e,
138 0x08,0x10,0x10, 0x08,0x0e,0x10, 0x08,0x0c,0x10, 0x08,0x0a,0x10,
139 0x0b,0x0b,0x10, 0x0c,0x0b,0x10, 0x0d,0x0b,0x10, 0x0f,0x0b,0x10,
140 0x10,0x0b,0x10, 0x10,0x0b,0x0f, 0x10,0x0b,0x0d, 0x10,0x0b,0x0c,
141 0x10,0x0b,0x0b, 0x10,0x0c,0x0b, 0x10,0x0d,0x0b, 0x10,0x0f,0x0b,
142 0x10,0x10,0x0b, 0x0f,0x10,0x0b, 0x0d,0x10,0x0b, 0x0c,0x10,0x0b,
143 0x0b,0x10,0x0b, 0x0b,0x10,0x0c, 0x0b,0x10,0x0d, 0x0b,0x10,0x0f,
144 0x0b,0x10,0x10, 0x0b,0x0f,0x10, 0x0b,0x0d,0x10, 0x0b,0x0c,0x10,
145 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
146 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00
Kevin O'Connor1f2c3072009-05-06 23:35:59 -0400147};
148
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500149static u8 sequ_01[] VAR16 = { 0x08, 0x03, 0x00, 0x02 };
150static u8 crtc_01[] VAR16 = {
151 0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
152 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
153 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3,
154 0xff };
155static u8 actl_01[] VAR16 = {
156 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
157 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
158 0x0c, 0x00, 0x0f, 0x08 };
159static u8 grdc_01[] VAR16 = {
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff };
161static u8 sequ_03[] VAR16 = { 0x00, 0x03, 0x00, 0x02 };
162static u8 crtc_03[] VAR16 = {
163 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
164 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
165 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
166 0xff };
167static u8 sequ_04[] VAR16 = { 0x09, 0x03, 0x00, 0x02 };
168static u8 crtc_04[] VAR16 = {
169 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f,
170 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2,
172 0xff };
173static u8 actl_04[] VAR16 = {
174 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07,
175 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
176 0x01, 0x00, 0x03, 0x00 };
177static u8 grdc_04[] VAR16 = {
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff };
179static u8 sequ_06[] VAR16 = { 0x01, 0x01, 0x00, 0x06 };
180static u8 crtc_06[] VAR16 = {
181 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
182 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2,
184 0xff };
185static u8 actl_06[] VAR16 = {
186 0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
187 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
188 0x01, 0x00, 0x01, 0x00 };
189static u8 grdc_06[] VAR16 = {
190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0f, 0xff };
191static u8 crtc_07[] VAR16 = {
192 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
193 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
194 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3,
195 0xff };
196static u8 actl_07[] VAR16 = {
197 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
198 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
199 0x0e, 0x00, 0x0f, 0x08 };
200static u8 grdc_07[] VAR16 = {
201 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff };
202static u8 sequ_0d[] VAR16 = { 0x09, 0x0f, 0x00, 0x06 };
203static u8 crtc_0d[] VAR16 = {
204 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f,
205 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
206 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3,
207 0xff };
208static u8 actl_0d[] VAR16 = {
209 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
210 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
211 0x01, 0x00, 0x0f, 0x00 };
212static u8 grdc_0d[] VAR16 = {
213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff };
214static u8 sequ_0e[] VAR16 = { 0x01, 0x0f, 0x00, 0x06 };
215static u8 crtc_0e[] VAR16 = {
216 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
217 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
218 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3,
219 0xff };
220static u8 crtc_0f[] VAR16 = {
221 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
222 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
223 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3,
224 0xff };
225static u8 actl_0f[] VAR16 = {
226 0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
227 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
228 0x01, 0x00, 0x01, 0x00 };
229static u8 actl_10[] VAR16 = {
230 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
231 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
232 0x01, 0x00, 0x0f, 0x00 };
233static u8 crtc_11[] VAR16 = {
234 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e,
235 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
236 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3,
237 0xff };
238static u8 actl_11[] VAR16 = {
239 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f,
240 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f,
241 0x01, 0x00, 0x0f, 0x00 };
242static u8 sequ_13[] VAR16 = { 0x01, 0x0f, 0x00, 0x0e };
243static u8 crtc_13[] VAR16 = {
244 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f,
245 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
246 0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3,
247 0xff };
248static u8 actl_13[] VAR16 = {
249 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
250 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
251 0x41, 0x00, 0x0f, 0x00 };
252static u8 grdc_13[] VAR16 = {
253 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff };
254static u8 crtc_6A[] VAR16 = {
255 0x7f, 0x63, 0x63, 0x83, 0x6b, 0x1b, 0x72, 0xf0,
256 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
257 0x59, 0x8d, 0x57, 0x32, 0x00, 0x57, 0x73, 0xe3,
258 0xff };
259
Kevin O'Connor5727c292009-05-16 17:29:32 -0400260#define PAL(x) x, sizeof(x)
Kevin O'Connor5727c292009-05-16 17:29:32 -0400261
Kevin O'Connorf98bbf02012-01-27 23:09:02 -0500262struct stdvga_mode_s {
263 u16 mode;
264 struct vgamode_s info;
265
266 u8 pelmask;
267 u8 *dac;
268 u16 dacsize;
269 u8 *sequ_regs;
270 u8 miscreg;
271 u8 *crtc_regs;
272 u8 *actl_regs;
273 u8 *grdc_regs;
274};
275
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500276static struct stdvga_mode_s vga_modes[] VAR16 = {
277 //mode { model tx ty bpp cw ch sstart }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500278 // pelm dac sequ misc crtc actl grdc
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500279 {0x00, { 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 {0x01, { MM_TEXT, 40, 25, 4, 9, 16, SEG_CTEXT }
Kevin O'Connord4398ad2012-01-01 12:32:53 -0500282 , 0xFF, PAL(palette2), sequ_01, 0x67, crtc_01, actl_01, grdc_01},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500283 {0x02, { 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 {0x03, { MM_TEXT, 80, 25, 4, 9, 16, SEG_CTEXT }
Kevin O'Connord4398ad2012-01-01 12:32:53 -0500286 , 0xFF, PAL(palette2), sequ_03, 0x67, crtc_03, actl_01, grdc_01},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500287 {0x04, { 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 {0x05, { MM_CGA, 320, 200, 2, 8, 8, SEG_CTEXT }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500290 , 0xFF, PAL(palette1), sequ_04, 0x63, crtc_04, actl_04, grdc_04},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500291 {0x06, { MM_CGA, 640, 200, 1, 8, 8, SEG_CTEXT }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500292 , 0xFF, PAL(palette1), sequ_06, 0x63, crtc_06, actl_06, grdc_06},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500293 {0x07, { MM_TEXT, 80, 25, 4, 9, 16, SEG_MTEXT }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500294 , 0xFF, PAL(palette0), sequ_03, 0x66, crtc_07, actl_07, grdc_07},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500295 {0x0D, { MM_PLANAR, 320, 200, 4, 8, 8, SEG_GRAPH }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500296 , 0xFF, PAL(palette1), sequ_0d, 0x63, crtc_0d, actl_0d, grdc_0d},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500297 {0x0E, { MM_PLANAR, 640, 200, 4, 8, 8, SEG_GRAPH }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500298 , 0xFF, PAL(palette1), sequ_0e, 0x63, crtc_0e, actl_0d, grdc_0d},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500299 {0x0F, { MM_PLANAR, 640, 350, 1, 8, 14, SEG_GRAPH }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500300 , 0xFF, PAL(palette0), sequ_0e, 0xa3, crtc_0f, actl_0f, grdc_0d},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500301 {0x10, { MM_PLANAR, 640, 350, 4, 8, 14, SEG_GRAPH }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500302 , 0xFF, PAL(palette2), sequ_0e, 0xa3, crtc_0f, actl_10, grdc_0d},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500303 {0x11, { MM_PLANAR, 640, 480, 1, 8, 16, SEG_GRAPH }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500304 , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_11, actl_11, grdc_0d},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500305 {0x12, { MM_PLANAR, 640, 480, 4, 8, 16, SEG_GRAPH }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500306 , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_11, actl_10, grdc_0d},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500307 {0x13, { MM_PACKED, 320, 200, 8, 8, 8, SEG_GRAPH }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500308 , 0xFF, PAL(palette3), sequ_13, 0x63, crtc_13, actl_13, grdc_13},
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500309 {0x6A, { MM_PLANAR, 800, 600, 4, 8, 16, SEG_GRAPH }
Kevin O'Connor0c7d4d02011-12-23 21:20:09 -0500310 , 0xFF, PAL(palette2), sequ_0e, 0xe3, crtc_6A, actl_10, grdc_0d},
Kevin O'Connor5727c292009-05-16 17:29:32 -0400311};
312
Kevin O'Connoraad3b692012-01-14 23:15:40 -0500313
314/****************************************************************
315 * Mode functions
316 ****************************************************************/
317
Kevin O'Connorf98bbf02012-01-27 23:09:02 -0500318static int
319is_stdvga_mode(struct vgamode_s *vmode_g)
Kevin O'Connore6bc4c12012-01-21 11:26:37 -0500320{
321 return (vmode_g >= &vga_modes[0].info
322 && vmode_g <= &vga_modes[ARRAY_SIZE(vga_modes)-1].info);
323}
324
Kevin O'Connor5727c292009-05-16 17:29:32 -0400325struct vgamode_s *
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500326stdvga_find_mode(int mode)
Kevin O'Connor5727c292009-05-16 17:29:32 -0400327{
328 int i;
329 for (i = 0; i < ARRAY_SIZE(vga_modes); i++) {
Kevin O'Connor10dff3d2012-01-09 19:19:44 -0500330 struct stdvga_mode_s *stdmode_g = &vga_modes[i];
331 if (GET_GLOBAL(stdmode_g->mode) == mode)
332 return &stdmode_g->info;
Kevin O'Connor5727c292009-05-16 17:29:32 -0400333 }
334 return NULL;
335}
Kevin O'Connoraad3b692012-01-14 23:15:40 -0500336
337void
Kevin O'Connorf98bbf02012-01-27 23:09:02 -0500338stdvga_list_modes(u16 seg, u16 *dest, u16 *last)
339{
Christian Gmeinera1a32832012-09-01 17:12:55 +0200340 int i;
Kevin O'Connor26209842014-02-11 17:36:56 -0500341 for (i = 0; i < ARRAY_SIZE(vga_modes) && dest < last; i++) {
Christian Gmeinera1a32832012-09-01 17:12:55 +0200342 struct stdvga_mode_s *stdmode_g = &vga_modes[i];
343 u16 mode = GET_GLOBAL(stdmode_g->mode);
344 if (mode == 0xffff)
345 continue;
346 SET_FARVAR(seg, *dest, mode);
347 dest++;
348 }
349
Kevin O'Connorf98bbf02012-01-27 23:09:02 -0500350 SET_FARVAR(seg, *dest, 0xffff);
351}
352
Kevin O'Connor536129a2016-08-05 10:58:24 -0400353static struct video_save_pointer_s video_save_pointer_table VAR16;
354
355static struct video_param_s video_param_table[29] VAR16;
356
Kevin O'Connorf98bbf02012-01-27 23:09:02 -0500357void
Kevin O'Connoraad3b692012-01-14 23:15:40 -0500358stdvga_build_video_param(void)
359{
Kevin O'Connor536129a2016-08-05 10:58:24 -0400360 SET_BDA(video_savetable
361 , SEGOFF(get_global_seg(), (u32)&video_save_pointer_table));
362 SET_VGA(video_save_pointer_table.videoparam
363 , SEGOFF(get_global_seg(), (u32)video_param_table));
364
Kevin O'Connoraad3b692012-01-14 23:15:40 -0500365 static u8 parammodes[] VAR16 = {
366 0, 0, 0, 0, 0x04, 0x05, 0x06, 0x07,
367 0, 0, 0, 0, 0, 0x0d, 0x0e, 0,
368 0, 0x0f, 0x10, 0, 0, 0, 0, 0x01,
369 0x03, 0x07, 0x11, 0x12, 0x13
370 };
371
372 int i;
373 for (i=0; i<ARRAY_SIZE(parammodes); i++) {
374 int mode = GET_GLOBAL(parammodes[i]);
375 if (! mode)
376 continue;
Kevin O'Connor63977902014-10-23 16:24:36 -0400377 struct video_param_s *vparam_g = &video_param_table[i];
Kevin O'Connoraad3b692012-01-14 23:15:40 -0500378 struct vgamode_s *vmode_g = stdvga_find_mode(mode);
379 if (!vmode_g)
380 continue;
381 int width = GET_GLOBAL(vmode_g->width);
382 int height = GET_GLOBAL(vmode_g->height);
383 u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
384 int cheight = GET_GLOBAL(vmode_g->cheight);
385 if (memmodel == MM_TEXT) {
386 SET_VGA(vparam_g->twidth, width);
387 SET_VGA(vparam_g->theightm1, height-1);
388 } else {
389 int cwidth = GET_GLOBAL(vmode_g->cwidth);
390 SET_VGA(vparam_g->twidth, width / cwidth);
391 SET_VGA(vparam_g->theightm1, (height / cheight) - 1);
392 }
393 SET_VGA(vparam_g->cheight, cheight);
394 SET_VGA(vparam_g->slength, calc_page_size(memmodel, width, height));
395 struct stdvga_mode_s *stdmode_g = container_of(
396 vmode_g, struct stdvga_mode_s, info);
397 memcpy_far(get_global_seg(), vparam_g->sequ_regs
398 , get_global_seg(), GET_GLOBAL(stdmode_g->sequ_regs)
399 , ARRAY_SIZE(vparam_g->sequ_regs));
400 SET_VGA(vparam_g->miscreg, GET_GLOBAL(stdmode_g->miscreg));
401 memcpy_far(get_global_seg(), vparam_g->crtc_regs
402 , get_global_seg(), GET_GLOBAL(stdmode_g->crtc_regs)
403 , ARRAY_SIZE(vparam_g->crtc_regs));
404 memcpy_far(get_global_seg(), vparam_g->actl_regs
405 , get_global_seg(), GET_GLOBAL(stdmode_g->actl_regs)
406 , ARRAY_SIZE(vparam_g->actl_regs));
407 memcpy_far(get_global_seg(), vparam_g->grdc_regs
408 , get_global_seg(), GET_GLOBAL(stdmode_g->grdc_regs)
409 , ARRAY_SIZE(vparam_g->grdc_regs));
410 }
Kevin O'Connor12900b12014-10-23 16:37:08 -0400411
412 // Fill available legacy modes in video_func_static table
413 u32 modes = 0;
414 for (i = 0; i < ARRAY_SIZE(vga_modes); i++) {
415 u16 mode = vga_modes[i].mode;
416 if (mode <= 0x13)
417 modes |= 1<<i;
418 }
419 SET_VGA(static_functionality.modes, modes);
Kevin O'Connoraad3b692012-01-14 23:15:40 -0500420}
Kevin O'Connor69b01cb2012-01-14 23:25:24 -0500421
422void
423stdvga_override_crtc(int mode, u8 *crtc)
424{
425 struct vgamode_s *vmode_g = stdvga_find_mode(mode);
426 if (!vmode_g)
427 return;
428 struct stdvga_mode_s *stdmode_g = container_of(
429 vmode_g, struct stdvga_mode_s, info);
430 SET_VGA(stdmode_g->crtc_regs, crtc);
431}
Kevin O'Connorf98bbf02012-01-27 23:09:02 -0500432
433static void
434clear_screen(struct vgamode_s *vmode_g)
435{
436 switch (GET_GLOBAL(vmode_g->memmodel)) {
437 case MM_TEXT:
438 memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0720, 32*1024);
439 break;
440 case MM_CGA:
441 memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 32*1024);
442 break;
443 default:
444 // XXX - old code gets/sets/restores sequ register 2 to 0xf -
445 // but it should always be 0xf anyway.
446 memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 64*1024);
447 }
448}
449
450int
451stdvga_set_mode(struct vgamode_s *vmode_g, int flags)
452{
453 if (! is_stdvga_mode(vmode_g)) {
454 warn_internalerror();
455 return -1;
456 }
457 struct stdvga_mode_s *stdmode_g = container_of(
458 vmode_g, struct stdvga_mode_s, info);
459
460 // if palette loading (bit 3 of modeset ctl = 0)
461 if (!(flags & MF_NOPALETTE)) { // Set the PEL mask
462 stdvga_pelmask_write(GET_GLOBAL(stdmode_g->pelmask));
463
464 // From which palette
465 u8 *palette_g = GET_GLOBAL(stdmode_g->dac);
466 u16 palsize = GET_GLOBAL(stdmode_g->dacsize) / 3;
467
468 // Always 256*3 values
469 stdvga_dac_write(get_global_seg(), palette_g, 0, palsize);
470 int i;
471 for (i = palsize; i < 0x0100; i++) {
472 static u8 rgb[3] VAR16;
473 stdvga_dac_write(get_global_seg(), rgb, i, 1);
474 }
475
476 if (flags & MF_GRAYSUM)
477 stdvga_perform_gray_scale_summing(0x00, 0x100);
478 }
479
480 // Set Attribute Ctl
481 u8 *regs = GET_GLOBAL(stdmode_g->actl_regs);
482 int i;
483 for (i = 0; i <= 0x13; i++)
484 stdvga_attr_write(i, GET_GLOBAL(regs[i]));
485 stdvga_attr_write(0x14, 0x00);
486
487 // Set Sequencer Ctl
488 stdvga_sequ_write(0x00, 0x03);
489 regs = GET_GLOBAL(stdmode_g->sequ_regs);
490 for (i = 1; i <= 4; i++)
491 stdvga_sequ_write(i, GET_GLOBAL(regs[i - 1]));
492
493 // Set Grafx Ctl
494 regs = GET_GLOBAL(stdmode_g->grdc_regs);
495 for (i = 0; i <= 8; i++)
496 stdvga_grdc_write(i, GET_GLOBAL(regs[i]));
497
498 // Set CRTC address VGA or MDA
499 u8 miscreg = GET_GLOBAL(stdmode_g->miscreg);
500 u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS;
501 if (!(miscreg & 1))
502 crtc_addr = VGAREG_MDA_CRTC_ADDRESS;
503
504 // Disable CRTC write protection
505 stdvga_crtc_write(crtc_addr, 0x11, 0x00);
506 // Set CRTC regs
507 regs = GET_GLOBAL(stdmode_g->crtc_regs);
508 for (i = 0; i <= 0x18; i++)
509 stdvga_crtc_write(crtc_addr, i, GET_GLOBAL(regs[i]));
510
511 // Set the misc register
512 stdvga_misc_write(miscreg);
513
514 // Enable video
515 stdvga_attrindex_write(0x20);
516
517 // Clear screen
518 if (!(flags & MF_NOCLEARMEM))
519 clear_screen(vmode_g);
520
521 // Write the fonts in memory
522 u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
523 if (memmodel == MM_TEXT)
524 stdvga_load_font(get_global_seg(), vgafont16, 0x100, 0, 0, 16);
525
526 return 0;
527}
Kevin O'Connor5b6936e2013-11-29 18:43:35 -0500528
529// Load the standard palette associated with 8bpp packed pixel vga modes.
530void
531stdvga_set_packed_palette(void)
532{
533 stdvga_dac_write(get_global_seg(), palette3, 0, sizeof(palette3) / 3);
534}