1 /*
2 ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com)
3 **
4 **
5 ** This program is free software; you can redistribute it and/or
6 ** modify it under the terms of version 2 of the GNU Library General
7 ** Public License as published by the Free Software Foundation.
8 **
9 ** This program is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ** Library General Public License for more details. To obtain a
13 ** copy of the GNU Library General Public License, write to the Free
14 ** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 **
16 ** Any permitted reproduction of these routines, in whole or in part,
17 ** must bear this legend.
18 **
19 **
20 ** hercules.c
21 **
22 ** x86 Hercules (monochrome) debug output routines
23 ** $Id: hercules.c,v 1.4 2000/06/09 15:12:27 matt Exp $
24 */
25
26 #include <stdio.h>
27 #include <stdarg.h>
28 #include <string.h>
29
30 #if __DJGPP__
31 #include <go32.h>
32 #include <sys/farptr.h>
33 #endif /* __DJGPP__ */
34
35 #include "types.h"
36 #include "hercules.h"
37
38
39 #ifdef OSD_LOG
40
41 static int cx, cy; /* Position of printing cursor on 80x25 matrix */
42 static char style; /* Style of output, dark, bright, underlined, etc. */
43 static boolean output_enable; /* Used to "gate" output to monitor */
44 static uint16 *herc_video; /* Pointer to the monochrome video buffer */
45
46
47 /* Set the printing style */
herc_setstyle(char new_style)48 void herc_setstyle(char new_style)
49 {
50 style = new_style;
51 }
52
53 /* Enable output gate to the monitor */
herc_enable(void)54 void herc_enable(void)
55 {
56 output_enable = TRUE;
57 }
58
59 /* Disable output gate to the monitor */
herc_disable(void)60 void herc_disable(void)
61 {
62 output_enable = FALSE;
63 }
64
65 /* Scroll the display upward the requested number of lines */
herc_scroll(int num_lines)66 static void herc_scroll(int num_lines)
67 {
68 #ifdef __DJGPP__
69 char blank_line[HERC_BYTES_PER_LINE];
70 #endif /* __DJGPP__ */
71
72 if (FALSE == output_enable)
73 return;
74
75 #ifdef __DJGPP__
76 memset(blank_line, 0, HERC_BYTES_PER_LINE);
77 #endif /* __DJGPP__ */
78
79 while(num_lines-- > 0)
80 {
81 #ifdef __DJGPP__
82 movedata(_dos_ds, (unsigned) (herc_video + HERC_BYTES_PER_LINE / 2),
83 _dos_ds, (unsigned) herc_video, (HERC_ROWS - 1) * HERC_BYTES_PER_LINE);
84 #else
85 memmove(herc_video, herc_video + (HERC_BYTES_PER_LINE / 2),
86 (HERC_ROWS - 1) * HERC_BYTES_PER_LINE);
87 #endif /* __DJGPP__ */
88
89 /* Now blank out the last line */
90 #ifdef __DJGPP__
91 movedata(_my_ds(), (unsigned) blank_line,
92 _dos_ds, (unsigned) (herc_video + ((HERC_ROWS - 1) * HERC_BYTES_PER_LINE / 2)),
93 HERC_BYTES_PER_LINE);
94 #else
95 memset(herc_video + ((HERC_ROWS - 1) * HERC_BYTES_PER_LINE / 2), 0,
96 HERC_BYTES_PER_LINE);
97 #endif /* __DJGPP__ */
98 }
99 }
100
101 /* Print a line of text, wrapping, scrolling and interpreting newlines as needed */
herc_print(const char * string)102 void herc_print(const char *string)
103 {
104 int length, scroll;
105 uint16 character;
106
107 if (FALSE == output_enable)
108 return;
109
110 length = strlen(string);
111
112 /* Enter main loop and print each character */
113 while (length--)
114 {
115 character = *string++;
116
117 /* Test if this is a control character? */
118 if ('\n' == character)
119 {
120 cx = 0;
121
122 if (++cy >= HERC_ROWS)
123 {
124 scroll = cy - (HERC_ROWS - 1);
125 cy = (HERC_ROWS - 1);
126 herc_scroll(scroll);
127 }
128 }
129 else
130 {
131 /* Merge character and attribute */
132 character |= (uint16) (style << 8);
133
134 /* Display character */
135 #ifdef __DJGPP__
136 _farpokew(_dos_ds, (unsigned) (herc_video + ((cy * HERC_BYTES_PER_LINE / 2) + cx)), character);
137 #else
138 herc_video[(cy * HERC_BYTES_PER_LINE / 2) + cx] = character;
139 #endif /* __DJGPP__ */
140
141 /* Update cursor position */
142 if (++cx >= HERC_COLUMNS)
143 {
144 cx = 0;
145 /* Test for vertical scroll */
146 if (++cy >= HERC_ROWS)
147 {
148 scroll = cy - (HERC_ROWS - 1);
149 cy = (HERC_ROWS - 1);
150 herc_scroll(scroll);
151 }
152 }
153 }
154 }
155 }
156
herc_printf(const char * format,...)157 void herc_printf(const char *format, ...)
158 {
159 va_list ap;
160 char s[1024 + 1];
161
162 va_start(ap, format);
163 vsprintf(s, format, ap);
164 va_end(ap);
165 herc_print(s);
166 }
167
168 /* Clear the monochrome display */
herc_clear(void)169 void herc_clear(void)
170 {
171 #ifdef __DJGPP__
172 char *clear_buf;
173 #endif /* __DJGPP__ */
174
175 if (FALSE == output_enable)
176 return;
177
178 /* Clear the display */
179 #ifdef __DJGPP__
180 clear_buf = malloc(HERC_ROWS * HERC_BYTES_PER_LINE);
181 memset(clear_buf, 0, HERC_ROWS * HERC_BYTES_PER_LINE);
182 movedata(_my_ds(), (unsigned) clear_buf,
183 _dos_ds, (unsigned) herc_video, HERC_ROWS * HERC_BYTES_PER_LINE);
184
185 free(clear_buf);
186 #else
187 memset(herc_video, 0, HERC_ROWS * HERC_BYTES_PER_LINE);
188 #endif /* __DJGPP__ */
189
190 /* Reset the cursor */
191 cx = 0;
192 cy = 0;
193 }
194
195 /* Initialize the monochrome printing system */
herc_init(void)196 void herc_init(void)
197 {
198 /* Position cursor at (0,0) */
199 cx = 0;
200 cy = 0;
201 style = HERC_NORMAL;
202 output_enable = TRUE;
203 /* Pointer to the monochrome video buffer */
204 herc_video = (uint16 *) 0xB0000;
205 herc_clear();
206 }
207
208 #endif /* OSD_LOG */
209
210 /*
211 ** $Log: hercules.c,v $
212 ** Revision 1.4 2000/06/09 15:12:27 matt
213 ** initial revision
214 **
215 */
216