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