Added upstream from http://ftp.icm.edu.pl/pub/loglan/
[loglan.git] / sources / int / graf / hercules.c
1      /* Loglan82 Compiler&Interpreter\r
2      Copyright (C) 1981-1993 Institute of Informatics, University of Warsaw\r
3      Copyright (C)  1993, 1994 LITA, Pau\r
4      \r
5      This program is free software; you can redistribute it and/or modify\r
6      it under the terms of the GNU General Public License as published by\r
7      the Free Software Foundation; either version 2 of the License, or\r
8      (at your option) any later version.\r
9      \r
10      This program is distributed in the hope that it will be useful,\r
11      but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13      GNU General Public License for more details.\r
14      \r
15 =======================================================================\r
16 */\r
17 \r
18 #include "graf.h"
19
20
21 #define bound(x,y)  ( x<0 || y<0 || x>719 || y>347 )
22
23
24 int pascal nocard( dummy )
25    void *dummy;
26 {
27    return 1;
28 }
29
30
31 #define index   0x3b4           /* 6845 ports */
32 #define data    0x3b5
33 #define mode    0x3b8           /* Herc ports */
34 #define status  0x3ba
35 #define config  0x3bf
36
37
38 static int cur_color;
39 static int cur_x;
40 static int cur_y;
41 static char *page_drawn;
42 static int page_drawn_no;
43 static int page_viewed;
44
45
46 #if WORD_32BIT
47 #define HERC_BASE 0xE00B0000UL
48 #define CHAR_BASE 0xE00FFA6EUL
49 #else
50 #define HERC_BASE 0xB0000000UL
51 #define CHAR_BASE 0xFFA6000EUL
52 #endif
53
54
55 static void set_page_drawn( page )
56    int page;
57 {
58    if( page == 0 || page == 1 )
59    {
60       page_drawn = (char *)( HERC_BASE + page * 0x8000);
61       page_drawn_no = page;
62    }
63 }
64
65
66 static void screen_off()
67 {
68    outportb( mode, '\0' );
69 }
70
71
72 static void set_page_viewed( page )
73    int page;
74 {
75    if( page == 0 )  outportb( mode, '\x0a' );
76    else
77    if( page == 1 )  outportb( mode, '\x8a' );
78    page_viewed = page;
79 }
80
81
82 static void clear_buffer( buf )
83    char *buf;
84 {
85    int i;
86    for( i=0; i<0x7fff; i++ )  buf[i] = '\0';
87 }
88
89
90 static void clear_gr_scr( page )
91    int page;
92 {
93    if( page_viewed == page )  screen_off();
94    clear_buffer( (char *)(HERC_BASE + page*0x8000) );
95    if( page_viewed == page )  set_page_viewed( page );
96 }
97
98
99 static int in_graphics=0;
100 void pascal gron( dummy )
101    int *dummy;
102 {
103    char i;
104    static char params[16] = {
105       '\x35', '\x2d', '\x2e', '\x07', '\x5b', '\x02',
106       '\x57', '\x57', '\x02', '\x03', '\x00', '\x00',
107       '\x00', '\x00', '\x00', '\x00'
108    };
109
110    if( in_graphics )  return;
111    in_graphics = 1;
112
113    atexit( groff );
114
115 /*
116    {
117       int i=0;
118       geninterrupt (0x11);
119       if (( AX & 0x30 ) == 0x30)
120          for (i=0; i<0x800; i++)
121             if (inportb(status) & 0x80)
122             {
123                i=-1;
124                break;
125             }
126       if( i != -1 )
127       {
128          fprintf( stderr, "This version runs only with HERCULES graphic card\n" );
129          exit( 1 );
130       }
131    }
132 */
133
134
135    outportb( config, 3 );                   /* allows both graphics pages */
136    screen_off();
137    for( i=0; i<sizeof(params); i++) {
138       outportb( index, i );
139       outportb( data, params[i] );
140    }
141    set_page_viewed( 0 );
142    set_page_drawn ( 0 );
143    clear_gr_scr( 1 );
144    clear_gr_scr( 0 );
145    cur_color=1;
146    cur_x=0;
147    cur_y=0;
148 }
149
150
151 void pascal groff()
152 {
153    char i;
154    static char params[16] = {
155       0x61, 0x50, 0x52, 0x0f, 0x19, 0x06,
156       0x19, 0x19, 0x02, 0x0d, 0x0b, 0x0c,
157       0x00, 0x00, 0x00, 0x00
158    };
159
160    if( !in_graphics )  return;
161    in_graphics = 0;
162
163    outportb( config, 0 );                       /* lock out graphics mode */
164    screen_off();
165    for( i=0; i<sizeof(params); i++) {
166       outportb( index, i );
167       outportb( data, params[i] );
168    }
169    outportb( mode, '\x28' );           /* enable blink and turn on screen */
170 }
171
172
173 void pascal hpage( nr, tryb, zeruj )
174    int *nr,*tryb,*zeruj;
175 {
176    if( *nr == 0 )
177    {
178       if( *zeruj )  clear_gr_scr( 0 );
179       if( *tryb ==  1 )  set_page_viewed( 0 );
180       if( *tryb == -1 )  set_page_viewed( 0 );
181    }
182    else
183    if( *nr == 1 )
184    {
185       if( *zeruj )  clear_gr_scr( 1 );
186       if( *tryb ==  1 )  set_page_viewed( 1 );
187       if( *tryb == -1 )  set_page_viewed( 1 );
188    }
189 }
190
191
192 void pascal video( buffer )
193    char *buffer;
194 {
195    page_drawn = buffer;
196    page_drawn_no = -1;
197 }
198
199
200 void pascal cls()
201 {
202    if( page_viewed == page_drawn_no )  clear_gr_scr( page_viewed );
203    else  clear_buffer( page_drawn );
204 }
205
206
207 void pascal point( col, row )
208    int *col,*row;
209 {
210    int x=*col, y=*row;
211    int byte_ofs;      /* offset within page for byte containing the point */
212    char mask;                            /* locates point within the byte */
213    if( bound( *col, *row ) )  return;
214    mask = 1 << (7 - (x % 8));
215    byte_ofs = 0x2000 * (y % 4) + 90 * (y/4) + (x/8);
216    if( cur_color == 1 )                                /* draw the point */
217       page_drawn[ byte_ofs ] |= mask;
218    else                                                /* erase the point */
219       page_drawn[ byte_ofs ] &= ~mask;
220    move( col, row );
221 }
222
223
224 void pascal move( col, row )
225    int *col,*row;
226 {
227    cur_x = *col;
228    cur_y = *row;
229 }
230
231
232 int pascal inxpos( dummy ) void *dummy; {  return cur_x;  }
233 int pascal inypos( dummy ) void *dummy; {  return cur_y;  }
234
235
236 int pascal inpix( col, row )
237    int *col,*row;
238 {
239    int x=*col, y=*row;
240    int byte_ofs;      /* offset within page for byte containing the point */
241    char mask;                            /* locates point within the byte */
242    if( bound( *col, *row ) )  return 0;
243    move( col, row );
244    mask = 1 << (7 - (x % 8));
245    byte_ofs = 0x2000 * (y % 4) + 90 * (y/4) + (x/8);
246    return !!( page_drawn[ byte_ofs ] & mask );
247 }
248
249
250 void pascal color( c )
251    int *c;
252 {
253    cur_color = *c;
254 }
255
256
257 void pascal intens( intensity )  int *intensity;  {}
258 void pascal pallet( palette   )  int *palette;    {}
259 void pascal border( color     )  int *color;      {}
260 void pascal style ( style_no  )  int *style_no;   {}
261 void pascal patern( p1,p2,p3,p4 ) int *p1,*p2,*p3,*p4; {}
262
263
264 static struct { int x,y,c; } stack[16];
265 static int stack_top=0;
266 void pascal pushxy()
267 {
268    stack[stack_top  ].x = cur_x;
269    stack[stack_top  ].y = cur_y;
270    stack[stack_top++].c = cur_color;
271 }
272 void pascal popxy()
273 {
274    cur_x     = stack[--stack_top].x;
275    cur_y     = stack[  stack_top].y;
276    cur_color = stack[  stack_top].c;
277 }
278
279
280 void pascal track ( x, y )  int *x,*y;  {}
281
282 static char *char_base = (char *)CHAR_BASE;
283 void pascal hascii( chrp )
284    int *chrp;
285 {
286    int i,j;
287    int chr = (*chrp) & 0x7F;
288    int x00 = inxpos(NULL);
289    int y00 = inypos(NULL);
290    pushxy();
291    if( chr == 0 )
292    {
293       int col = cur_color;
294       cur_color = 0;
295       for( i=x00; i<x00+8; i++ )  for( j=y00; j<y00+8; j++ )  point(&i,&j);
296       cur_color = col;
297    }
298    else
299    {
300       char *c = char_base + 8*chr;
301       for( i=x00; i<x00+8; i++ )  for( j=y00; j<y00+8; j++ )
302          if( !!( c[j-y00] & (0x80>>(i-x00)) ) )
303             point(&i,&j);
304    }
305    popxy();
306    if( chr != 0 )
307    {
308       x00 += 8;
309       move( &x00, &y00 );
310    }
311 }
312 void pascal hfont ( seg, ofs )  int *seg,*ofs;  {}
313 void pascal hfont8( seg, ofs )  int *seg,*ofs;  {}
314
315 \r