/[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 148 - (show annotations)
Sun Aug 23 11:20:52 2009 UTC (10 years, 3 months ago) by Jede
File MIME type: text/plain
File size: 5419 byte(s)
Changement de zoom par l'interface
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_init()
56 {
57 int y;
58
59 /* Force a refresh the first time */
60 for (y = 0; y < VIDEO_HEIGHT; y++)
61 buf[y * (VIDEO_WIDTH + 1) + VIDEO_WIDTH] = 1;
62 frametouched = 1;
63
64 }
65
66
67
68 void render_frame (void)
69 {
70 unsigned bg;
71 unsigned fg;
72 int set;
73 int dheight;
74 int blink;
75 const unsigned char *chargen[2][2];
76
77 const unsigned char *mem = (const unsigned char *) Oric_Mem;
78 char *b;
79 const unsigned char *from[2];
80 int y;
81 int bottom; /* True iff y >= 200. In the last 24
82 scan lines, all rendering is done in
83 character mode. */
84
85 chargen[0][0] = mem + CHARSET0_TEXT;
86 chargen[0][1] = mem + CHARSET1_TEXT;
87 chargen[1][0] = mem + CHARSET0_HIRES;
88 chargen[1][1] = mem + CHARSET1_HIRES;
89 if (! initialised)
90 {
91 int y;
92
93 /* Force a refresh the first time */
94 for (y = 0; y < VIDEO_HEIGHT; y++)
95 buf[y * (VIDEO_WIDTH + 1) + VIDEO_WIDTH] = 1;
96 frametouched = 1;
97 hires = 0;
98 initialised = 1;
99 }
100
101 from[0] = mem + RAM_TEXT;
102 from[1] = mem + RAM_HIRES;
103
104 b = buf;
105 frametouched = 0;
106 for (y = 0; y < VIDEO_HEIGHT; y++)
107 {
108 int x;
109 int touched = 0;
110
111 bottom = (y >= 200);
112
113 /* Some attributes are reset at the beginning of every scan line */
114 bg = 0;
115 fg = 7;
116 set = 0;
117 dheight = 0;
118 blink = 0;
119
120 /* Render one line */
121 for (x = 0; x < TEXT_COLUMNS; x++)
122 {
123 unsigned char cell = (from[hires && ! bottom][x] & 0x7f);
124 int video_inverse = (from[hires && ! bottom][x] & 0x80);
125 unsigned char pattern;
126
127 /* "Parse" one cell */
128 if (cell >= 0x20)
129 {
130 if (hires && ! bottom)
131 {
132 pattern = (cell & 0x3f);
133 }
134 else
135 {
136 if (dheight)
137 pattern = chargen[hires && bottom][set]
138 [CHAR_HEIGHT * cell + (y / 2) % CHAR_HEIGHT];
139 else
140 pattern = chargen[hires && bottom][set]
141 [CHAR_HEIGHT * cell + y % CHAR_HEIGHT];
142 }
143 }
144 else
145 {
146 if ((cell & 0x78) == 0x00)
147 fg = (cell & (COLOURS - 1));
148 else if ((cell & 0x78) == 0x08)
149 {
150 set = !!(cell & 1);
151 dheight = (cell & 2);
152 blink = (cell & 4);
153 }
154 else if ((cell & 0x78) == 0x10)
155 bg = (cell & (COLOURS - 1));
156 else if ((cell & 0x78) == 0x18)
157 hires = !! (cell & 4);
158 pattern = 0;
159 }
160
161 /* Blinking : force everything to BG */
162 if (blink && framenum >= BLINK_HALF_PERIOD_F)
163 pattern = 0;
164
165 /* Render the cell (6 pixels in a row) */
166 if (video_inverse)
167 {
168 int bg_ = COLOURS - 1 - bg;
169 int fg_ = COLOURS - 1 - fg;
170 char pixel;
171
172 pixel=(pattern&0x20)?fg_:bg_; if(*b!=pixel){*b = pixel; touched=1;} b++;
173 pixel=(pattern&0x10)?fg_:bg_; if(*b!=pixel){*b = pixel; touched=1;} b++;
174 pixel=(pattern&0x08)?fg_:bg_; if(*b!=pixel){*b = pixel; touched=1;} b++;
175 pixel=(pattern&0x04)?fg_:bg_; if(*b!=pixel){*b = pixel; touched=1;} b++;
176 pixel=(pattern&0x02)?fg_:bg_; if(*b!=pixel){*b = pixel; touched=1;} b++;
177 pixel=(pattern&0x01)?fg_:bg_; if(*b!=pixel){*b = pixel; touched=1;} b++;
178 }
179 else
180 {
181 char pixel;
182
183 pixel=(pattern&0x20)?fg:bg; if(*b!=pixel){*b = pixel; touched=1;} b++;
184 pixel=(pattern&0x10)?fg:bg; if(*b!=pixel){*b = pixel; touched=1;} b++;
185 pixel=(pattern&0x08)?fg:bg; if(*b!=pixel){*b = pixel; touched=1;} b++;
186 pixel=(pattern&0x04)?fg:bg; if(*b!=pixel){*b = pixel; touched=1;} b++;
187 pixel=(pattern&0x02)?fg:bg; if(*b!=pixel){*b = pixel; touched=1;} b++;
188 pixel=(pattern&0x01)?fg:bg; if(*b!=pixel){*b = pixel; touched=1;} b++;
189 }
190 }
191
192 from[1] += x;
193 if (y % CHAR_HEIGHT == CHAR_HEIGHT - 1)
194 from[0] += x;
195
196 *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*/
197 if (touched)
198 frametouched = 1;
199 }
200
201 framenum++;
202 if (framenum >= 2 * BLINK_HALF_PERIOD_F)
203 framenum = 0;
204 }
205

  ViewVC Help
Powered by ViewVC 1.1.26