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

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

Parent Directory Parent Directory | Revision Log Revision Log


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


1 dbug 24 /*
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 Jede 90 *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 dbug 24 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