1 /* #define STANDALONE_BIOS_VIDEO_TEST */
2 
3 /*
4  * BIOS video routines for GO32 version of TADS
5  *
6  * Modification History
7  *
8  * 22-Apr-95	dmb	Created.
9  *
10  */
11 #include <pc.h>
12 #include <dos.h>
13 #include <sys/farptr.h>
14 
15 #include "biosvid.h"
16 
17 static int Page, Cols = 80, Rows = 25, Color = 7, Bkgnd = 7, Mode;
18 static int Cstart, Cend;
19 
20 #ifdef STANDALONE_BIOS_VIDEO_TEST
21 
main(int argc,char ** argv)22 main(int argc, char **argv)
23 {
24 	int	i;
25 	char	s[80];
26 
27 	bios_video_init();
28 	bios_video_clear_region(0, Rows - 1, 0, Cols - 1);
29 	sprintf(s, "cols: %d   rows: %d   cursor = [%d, %d]", Cols, Rows, Cstart, Cend);
30 	bios_video_write_string_at_pos(6, 12, s);
31 	bios_video_set_cursor_position(5, 13);
32 	bios_video_write_char('!');
33 
34 	for (i = 0; i < 1000; i++) {
35 		bios_video_scroll_region(0, Rows - 1, 0, Cols - 1, 1);
36 		bios_video_scroll_region(0, Rows - 1, 0, Cols - 1, -1);
37 	}
38 }
39 #endif
40 
41 void
bios_video_get_screen_dimensions(int * x,int * y)42 bios_video_get_screen_dimensions(int *x, int *y)
43 {
44 	*x = Cols;
45 	*y = Rows;
46 }
47 
48 void
bios_video_set_bkgnd(int bkgnd)49 bios_video_set_bkgnd(int bkgnd)
50 {
51 	Bkgnd = bkgnd;
52 }
53 
54 void
bios_video_set_color(int color)55 bios_video_set_color(int color)
56 {
57 	Color = color;
58 }
59 
60 void
bios_video_init()61 bios_video_init()
62 {
63 	union REGS regs;
64 
65 	regs.h.ah = 15;
66 	int86(0x10, &regs, &regs);
67 	Mode = regs.h.al;
68 	Page = regs.h.bh;
69 
70 	/*
71 	 * If EGA or VGA, determine screen size.
72 	 * Otherwise, assume 80x25.
73 	 */
74 	if (bios_is_ega_or_vga()) {
75 		unsigned short s;
76 
77 		Rows = (int) _farpeekb(_go32_conventional_mem_selector(), 0x40*16 + 0x84) + 1;
78 		Cols = (int) _farpeekw(_go32_conventional_mem_selector(), 0x40*16 + 0x4a);
79 		s = (int) _farpeekw(_go32_conventional_mem_selector(), 0x40*16 + 0x60);
80 		Cstart = s >> 8;
81 		Cend = s & 0xFF;
82 	}
83 	else {
84 		Cstart = 6;
85 		Cend = 7;
86 		Cols = 80;
87 		Rows = 25;
88 	}
89 }
90 
91 int
bios_is_ega_or_vga()92 bios_is_ega_or_vga()
93 {
94 	union REGS regs;
95 
96 	regs.x.ax = 0x1a00;
97 	int86(0x10, &regs, &regs);
98 	if (regs.h.al == 0x1a) {
99 		switch (regs.h.bl) {
100 			case 4:	/* color EGA */
101 			case 5: /* mono EGA */
102 			case 7: /* mono VGA */
103 			case 8: /* color VGA */
104 				return 1;
105 			default:
106 				return 0;
107 		}
108 	}
109 
110 	regs.h.ah = 0x12;
111 	regs.h.bl = 0x10;
112 	int86(0x10, &regs, &regs);
113 	if (regs.h.bl != 0x10)
114 		return 1;
115 
116 	return 0;
117 }
118 
119 int
bios_video_monochrome()120 bios_video_monochrome()
121 {
122 	if (Mode == 7)
123 		return 1;
124 	else
125 		return 0;
126 }
127 
128 void
bios_video_set_cursor_shape(char start,char end)129 bios_video_set_cursor_shape(char start, char end)
130 {
131 	union REGS regs;
132 	regs.h.ah = 1;
133 	regs.h.ch = start;
134 	regs.h.cl = end;
135 	int86(0x10, &regs, &regs);
136 }
137 
138 /* write char to screen at current cursor pos and with current attr */
139 void
bios_video_write_char(char c)140 bios_video_write_char(char c)
141 {
142 	union REGS regs;
143 
144 	regs.h.ah = 9;
145 	regs.h.al = c;
146 	regs.h.bh = Page;
147 	regs.h.bl = Color;
148 	regs.x.cx = 1;
149 	int86(0x10, &regs, &regs);
150 }
151 
152 void
bios_video_write_string(char * s)153 bios_video_write_string(char *s)
154 {
155 	int	x, y;
156 
157 	bios_video_get_cursor_position(&x, &y);
158 	while (*s) {
159 		bios_video_set_cursor_position(x++, y);
160 		bios_video_write_char(*s++);
161 	}
162 }
163 
164 void
bios_video_write_string_at_pos(int x,int y,char * s)165 bios_video_write_string_at_pos(int x, int y, char *s)
166 {
167 	while (*s) {
168 		bios_video_set_cursor_position(x++, y);
169 		bios_video_write_char(*s++);
170 	}
171 }
172 
173 void
bios_video_set_cursor_position(int x,int y)174 bios_video_set_cursor_position(int x, int y)
175 {
176 	union REGS regs;
177 
178 	if (x >= Cols || y >= Rows)
179 		return;
180 
181 	regs.h.ah = 2;
182 	regs.h.bh = Page;
183 	regs.h.dh = y;
184 	regs.h.dl = x;
185 	regs.x.cx = 1;
186 	int86(0x10, &regs, &regs);
187 }
188 
189 void
bios_video_get_cursor_position(int * x,int * y)190 bios_video_get_cursor_position(int *x, int *y)
191 {
192 	union REGS regs;
193 
194 	regs.h.ah = 3;
195 	regs.h.bh = Page;
196 	int86(0x10, &regs, &regs);
197 	*x = (int) regs.h.dl;
198 	*y = (int) regs.h.dh;
199 }
200 
201 void
bios_video_scroll_region(int top,int bottom,int left,int right,int lines)202 bios_video_scroll_region(int top, int bottom, int left, int right, int lines)
203 {
204 	union REGS regs;
205 
206 	if (lines < 0) {
207 		/* scroll up --- delete lines */
208 		regs.h.ah = 6;
209 		regs.h.al = -lines;
210 		regs.h.bh = Bkgnd;
211 		regs.h.ch = top;
212 		regs.h.cl = left;
213 		regs.h.dh = bottom;
214 		regs.h.dl = right;
215 		int86(0x10, &regs, &regs);
216 	}
217 	else {
218 		/* scroll down --- insert lines */
219 		regs.h.ah = 7;
220 		regs.h.al = lines;
221 		regs.h.bh = Bkgnd;
222 		regs.h.ch = top;
223 		regs.h.cl = left;
224 		regs.h.dh = bottom;
225 		regs.h.dl = right;
226 		int86(0x10, &regs, &regs);
227 	}
228 }
229 
230 void
bios_video_clear_region(int top,int bottom,int left,int right)231 bios_video_clear_region(int top, int bottom, int left, int right)
232 {
233 	union REGS regs;
234 
235 	regs.h.ah = 6;
236 	regs.h.al = 0;
237 	regs.h.bh = Bkgnd;
238 	regs.h.ch = top;
239 	regs.h.cl = left;
240 	regs.h.dh = bottom;
241 	regs.h.dl = right;
242 	int86(0x10, &regs, &regs);
243 }
244 
245 void
bios_video_cursor_hide()246 bios_video_cursor_hide()
247 {
248 	bios_video_set_cursor_shape(Cend, Cstart);
249 }
250 
251 void
bios_video_cursor_show()252 bios_video_cursor_show()
253 {
254 	bios_video_set_cursor_shape(Cstart, Cend);
255 }
256 
257 int
bios_getchar()258 bios_getchar()
259 {
260 	union REGS regs;
261 
262 	regs.h.ah = 7;
263 	int86(0x21, &regs, &regs);
264 	return (int) regs.h.al;
265 }
266