/[projet1]/public/pc/emulators/caloric/src/ula.c
Defence Force logotype

Contents of /public/pc/emulators/caloric/src/ula.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 90 - (show annotations)
Thu May 28 16:33:09 2009 UTC (10 years, 3 months ago) by Jede
File MIME type: text/plain
File size: 5198 byte(s)


1 /*
2 * ula.c - emulate the ULA (video)
3 * AYM 2002-08-21
4 */
5
6 /*
7 This file is copyright André Majorel 2002-2004.
8
9 This program is free software; you can redistribute it and/or modify it under
10 the terms of version 2 of the GNU General Public License as published by the
11 Free Software Foundation.
12
13 This program is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along with
18 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 Place, Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22
23 #include <stddef.h>
24
25 #include "caloric.h"
26
27
28 char buf[(VIDEO_WIDTH + 1) * VIDEO_HEIGHT];
29 /* Each cell contains the pixel colour
30 (0 through 7). The 241st column is a
31 boolean that says whether this
32 scanline has changed since the last
33 time. The boolean is embedded in the
34 buffer in the hope of keeping the
35 cache miss rate down (as all writes
36 occur in the same area).
37
38 This array is not static because
39 it's needed by the X11 rendering
40 function and the screenshot
41 function. */
42
43 int frametouched;
44
45 int hires = 0; /* The ULA powers up in text mode. Not
46 static because config.c needs it. */
47
48 int initialised = 0; /* Internal use */
49
50 int framenum = 0; /* Frame counter (for blinking) */
51
52 #define BLINK_HALF_PERIOD_F 32 /* Half period of blinking in frames */
53
54
55 void render_frame (void)
56 {
57 unsigned bg;
58 unsigned fg;
59 int set;
60 int dheight;
61 int blink;
62 const unsigned char *chargen[2][2];
63
64 const unsigned char *mem = (const unsigned char *) Oric_Mem;
65 char *b;
66 const unsigned char *from[2];
67 int y;
68 int bottom; /* True iff y >= 200. In the last 24
69 scan lines, all rendering is done in
70 character mode. */
71
72 chargen[0][0] = mem + CHARSET0_TEXT;
73 chargen[0][1] = mem + CHARSET1_TEXT;
74 chargen[1][0] = mem + CHARSET0_HIRES;
75 chargen[1][1] = mem + CHARSET1_HIRES;
76 if (! initialised)
77 {
78 int y;
79
80 /* Force a refresh the first time */
81 for (y = 0; y < VIDEO_HEIGHT; y++)
82 buf[y * (VIDEO_WIDTH + 1) + VIDEO_WIDTH] = 1;
83 frametouched = 1;
84 hires = 0;
85 initialised = 1;
86 }
87
88 from[0] = mem + RAM_TEXT;
89 from[1] = mem + RAM_HIRES;
90
91 b = buf;
92 frametouched = 0;
93 for (y = 0; y < VIDEO_HEIGHT; y++)
94 {
95 int x;
96 int touched = 0;
97
98 bottom = (y >= 200);
99
100 /* Some attributes are reset at the beginning of every scan line */
101 bg = 0;
102 fg = 7;
103 set = 0;
104 dheight = 0;
105 blink = 0;
106
107 /* Render one line */
108 for (x = 0; x < TEXT_COLUMNS; x++)
109 {
110 unsigned char cell = (from[hires && ! bottom][x] & 0x7f);
111 int video_inverse = (from[hires && ! bottom][x] & 0x80);
112 unsigned char pattern;
113
114 /* "Parse" one cell */
115 if (cell >= 0x20)
116 {
117 if (hires && ! bottom)
118 {
119 pattern = (cell & 0x3f);
120 }
121 else
122 {
123 if (dheight)
124 pattern = chargen[hires && bottom][set]
125 [CHAR_HEIGHT * cell + (y / 2) % CHAR_HEIGHT];
126 else
127 pattern = chargen[hires && bottom][set]
128 [CHAR_HEIGHT * cell + y % CHAR_HEIGHT];
129 }
130 }
131 else
132 {
133 if ((cell & 0x78) == 0x00)
134 fg = (cell & (COLOURS - 1));
135 else if ((cell & 0x78) == 0x08)
136 {
137 set = !!(cell & 1);
138 dheight = (cell & 2);
139 blink = (cell & 4);
140 }
141 else if ((cell & 0x78) == 0x10)
142 bg = (cell & (COLOURS - 1));
143 else if ((cell & 0x78) == 0x18)
144 hires = !! (cell & 4);
145 pattern = 0;
146 }
147
148 /* Blinking : force everything to BG */
149 if (blink && framenum >= BLINK_HALF_PERIOD_F)
150 pattern = 0;
151
152 /* Render the cell (6 pixels in a row) */
153 if (video_inverse)
154 {
155 int bg_ = COLOURS - 1 - bg;
156 int fg_ = COLOURS - 1 - fg;
157 char pixel;
158
159 pixel=(pattern&0x20)?fg_:bg_; if(*b!=pixel){*b = pixel; touched=1;} b++;
160 pixel=(pattern&0x10)?fg_:bg_; if(*b!=pixel){*b = pixel; touched=1;} b++;
161 pixel=(pattern&0x08)?fg_:bg_; if(*b!=pixel){*b = pixel; touched=1;} b++;
162 pixel=(pattern&0x04)?fg_:bg_; if(*b!=pixel){*b = pixel; touched=1;} b++;
163 pixel=(pattern&0x02)?fg_:bg_; if(*b!=pixel){*b = pixel; touched=1;} b++;
164 pixel=(pattern&0x01)?fg_:bg_; if(*b!=pixel){*b = pixel; touched=1;} b++;
165 }
166 else
167 {
168 char pixel;
169
170 pixel=(pattern&0x20)?fg:bg; if(*b!=pixel){*b = pixel; touched=1;} b++;
171 pixel=(pattern&0x10)?fg:bg; if(*b!=pixel){*b = pixel; touched=1;} b++;
172 pixel=(pattern&0x08)?fg:bg; if(*b!=pixel){*b = pixel; touched=1;} b++;
173 pixel=(pattern&0x04)?fg:bg; if(*b!=pixel){*b = pixel; touched=1;} b++;
174 pixel=(pattern&0x02)?fg:bg; if(*b!=pixel){*b = pixel; touched=1;} b++;
175 pixel=(pattern&0x01)?fg:bg; if(*b!=pixel){*b = pixel; touched=1;} b++;
176 }
177 }
178
179 from[1] += x;
180 if (y % CHAR_HEIGHT == CHAR_HEIGHT - 1)
181 from[0] += x;
182
183 *b++ = (char) touched; /* KLUDGEy eh ? -> comment from Jede : it put a flag at the end of the line -> touched=1 then the line has changed*/
184 if (touched)
185 frametouched = 1;
186 }
187
188 framenum++;
189 if (framenum >= 2 * BLINK_HALF_PERIOD_F)
190 framenum = 0;
191 }
192

  ViewVC Help
Powered by ViewVC 1.1.26