Statistics
| Branch: | Revision:

root / hw / tcx.c @ a8d3431a

History | View | Annotate | Download (6.3 kB)

1 420557e8 bellard
/*
2 420557e8 bellard
 * QEMU Sun4m System Emulator
3 420557e8 bellard
 * 
4 420557e8 bellard
 * Copyright (c) 2003-2004 Fabrice Bellard
5 420557e8 bellard
 * 
6 420557e8 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 420557e8 bellard
 * of this software and associated documentation files (the "Software"), to deal
8 420557e8 bellard
 * in the Software without restriction, including without limitation the rights
9 420557e8 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 420557e8 bellard
 * copies of the Software, and to permit persons to whom the Software is
11 420557e8 bellard
 * furnished to do so, subject to the following conditions:
12 420557e8 bellard
 *
13 420557e8 bellard
 * The above copyright notice and this permission notice shall be included in
14 420557e8 bellard
 * all copies or substantial portions of the Software.
15 420557e8 bellard
 *
16 420557e8 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 420557e8 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 420557e8 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 420557e8 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 420557e8 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 420557e8 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 420557e8 bellard
 * THE SOFTWARE.
23 420557e8 bellard
 */
24 420557e8 bellard
#include "vl.h"
25 420557e8 bellard
26 420557e8 bellard
#define MAXX 1024
27 420557e8 bellard
#define MAXY 768
28 e80cfcfc bellard
/*
29 e80cfcfc bellard
 * Proll uses only small part of display, we need to switch to full
30 e80cfcfc bellard
 * display when we get linux framebuffer console or X11 running. For
31 e80cfcfc bellard
 * now it's just slower and awkward.
32 e80cfcfc bellard
*/
33 e80cfcfc bellard
#if 1
34 420557e8 bellard
#define XSZ (8*80)
35 420557e8 bellard
#define YSZ (24*11)
36 420557e8 bellard
#define XOFF (MAXX-XSZ)
37 420557e8 bellard
#define YOFF (MAXY-YSZ)
38 e80cfcfc bellard
#else
39 e80cfcfc bellard
#define XSZ MAXX
40 e80cfcfc bellard
#define YSZ MAXY
41 e80cfcfc bellard
#define XOFF 0
42 e80cfcfc bellard
#define YOFF 0
43 e80cfcfc bellard
#endif
44 420557e8 bellard
45 420557e8 bellard
typedef struct TCXState {
46 8d5f07fa bellard
    uint32_t addr;
47 420557e8 bellard
    DisplayState *ds;
48 8d5f07fa bellard
    uint8_t *vram;
49 e80cfcfc bellard
    unsigned long vram_offset;
50 e80cfcfc bellard
    uint8_t r[256], g[256], b[256];
51 420557e8 bellard
} TCXState;
52 420557e8 bellard
53 e80cfcfc bellard
static void tcx_draw_line32(TCXState *s1, uint8_t *d, 
54 e80cfcfc bellard
                            const uint8_t *s, int width)
55 420557e8 bellard
{
56 e80cfcfc bellard
    int x;
57 e80cfcfc bellard
    uint8_t val;
58 e80cfcfc bellard
59 e80cfcfc bellard
    for(x = 0; x < width; x++) {
60 e80cfcfc bellard
        val = *s++;
61 e80cfcfc bellard
        *d++ = s1->r[val];
62 e80cfcfc bellard
        *d++ = s1->g[val];
63 e80cfcfc bellard
        *d++ = s1->b[val];
64 e80cfcfc bellard
        d++;
65 e80cfcfc bellard
    }
66 420557e8 bellard
}
67 420557e8 bellard
68 e80cfcfc bellard
static void tcx_draw_line24(TCXState *s1, uint8_t *d, 
69 e80cfcfc bellard
                            const uint8_t *s, int width)
70 e80cfcfc bellard
{
71 e80cfcfc bellard
    int x;
72 e80cfcfc bellard
    uint8_t val;
73 8d5f07fa bellard
74 e80cfcfc bellard
    for(x = 0; x < width; x++) {
75 e80cfcfc bellard
        val = *s++;
76 e80cfcfc bellard
        *d++ = s1->r[val];
77 e80cfcfc bellard
        *d++ = s1->g[val];
78 e80cfcfc bellard
        *d++ = s1->b[val];
79 e80cfcfc bellard
    }
80 e80cfcfc bellard
}
81 e80cfcfc bellard
82 e80cfcfc bellard
static void tcx_draw_line8(TCXState *s1, uint8_t *d, 
83 e80cfcfc bellard
                           const uint8_t *s, int width)
84 420557e8 bellard
{
85 e80cfcfc bellard
    int x;
86 e80cfcfc bellard
    uint8_t val;
87 e80cfcfc bellard
88 e80cfcfc bellard
    for(x = 0; x < width; x++) {
89 e80cfcfc bellard
        val = *s++;
90 e80cfcfc bellard
        /* XXX translate between palettes? */
91 e80cfcfc bellard
        *d++ = val;
92 420557e8 bellard
    }
93 420557e8 bellard
}
94 420557e8 bellard
95 e80cfcfc bellard
/* Fixed line length 1024 allows us to do nice tricks not possible on
96 e80cfcfc bellard
   VGA... */
97 e80cfcfc bellard
void tcx_update_display(void *opaque)
98 420557e8 bellard
{
99 e80cfcfc bellard
    TCXState *ts = opaque;
100 e80cfcfc bellard
    uint32_t page;
101 e80cfcfc bellard
    int y, page_min, page_max, y_start, dd, ds;
102 e80cfcfc bellard
    uint8_t *d, *s;
103 e80cfcfc bellard
    void (*f)(TCXState *s1, uint8_t *d, const uint8_t *s, int width);
104 e80cfcfc bellard
105 e80cfcfc bellard
    if (ts->ds->depth == 0)
106 e80cfcfc bellard
        return;
107 e80cfcfc bellard
    page = ts->vram_offset + YOFF*MAXX;
108 e80cfcfc bellard
    y_start = -1;
109 e80cfcfc bellard
    page_min = 0x7fffffff;
110 e80cfcfc bellard
    page_max = -1;
111 e80cfcfc bellard
    d = ts->ds->data;
112 e80cfcfc bellard
    s = ts->vram + YOFF*MAXX + XOFF;
113 e80cfcfc bellard
    dd = ts->ds->linesize;
114 e80cfcfc bellard
    ds = 1024;
115 e80cfcfc bellard
116 e80cfcfc bellard
    switch (ts->ds->depth) {
117 e80cfcfc bellard
    case 32:
118 e80cfcfc bellard
        f = tcx_draw_line32;
119 e80cfcfc bellard
        break;
120 e80cfcfc bellard
    case 24:
121 e80cfcfc bellard
        f = tcx_draw_line24;
122 e80cfcfc bellard
        break;
123 e80cfcfc bellard
    default:
124 e80cfcfc bellard
    case 8:
125 e80cfcfc bellard
        f = tcx_draw_line8;
126 e80cfcfc bellard
        break;
127 e80cfcfc bellard
    case 0:
128 e80cfcfc bellard
        return;
129 e80cfcfc bellard
    }
130 662f3c86 bellard
    
131 e80cfcfc bellard
    for(y = 0; y < YSZ; y += 4, page += TARGET_PAGE_SIZE) {
132 e80cfcfc bellard
        if (cpu_physical_memory_is_dirty(page)) {
133 e80cfcfc bellard
            if (y_start < 0)
134 e80cfcfc bellard
                y_start = y;
135 e80cfcfc bellard
            if (page < page_min)
136 e80cfcfc bellard
                page_min = page;
137 e80cfcfc bellard
            if (page > page_max)
138 e80cfcfc bellard
                page_max = page;
139 e80cfcfc bellard
            f(ts, d, s, XSZ);
140 e80cfcfc bellard
            d += dd;
141 e80cfcfc bellard
            s += ds;
142 e80cfcfc bellard
            f(ts, d, s, XSZ);
143 e80cfcfc bellard
            d += dd;
144 e80cfcfc bellard
            s += ds;
145 e80cfcfc bellard
            f(ts, d, s, XSZ);
146 e80cfcfc bellard
            d += dd;
147 e80cfcfc bellard
            s += ds;
148 e80cfcfc bellard
            f(ts, d, s, XSZ);
149 e80cfcfc bellard
            d += dd;
150 e80cfcfc bellard
            s += ds;
151 e80cfcfc bellard
        } else {
152 e80cfcfc bellard
            if (y_start >= 0) {
153 e80cfcfc bellard
                /* flush to display */
154 e80cfcfc bellard
                dpy_update(ts->ds, 0, y_start, 
155 e80cfcfc bellard
                           XSZ, y - y_start);
156 e80cfcfc bellard
                y_start = -1;
157 e80cfcfc bellard
            }
158 e80cfcfc bellard
            d += dd * 4;
159 e80cfcfc bellard
            s += ds * 4;
160 e80cfcfc bellard
        }
161 e80cfcfc bellard
    }
162 e80cfcfc bellard
    if (y_start >= 0) {
163 e80cfcfc bellard
        /* flush to display */
164 e80cfcfc bellard
        dpy_update(ts->ds, 0, y_start, 
165 e80cfcfc bellard
                   XSZ, y - y_start);
166 e80cfcfc bellard
    }
167 e80cfcfc bellard
    /* reset modified pages */
168 e80cfcfc bellard
    if (page_max != -1) {
169 e80cfcfc bellard
        cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE);
170 e80cfcfc bellard
    }
171 420557e8 bellard
}
172 420557e8 bellard
173 e80cfcfc bellard
void tcx_invalidate_display(void *opaque)
174 420557e8 bellard
{
175 e80cfcfc bellard
    TCXState *s = opaque;
176 e80cfcfc bellard
    int i;
177 e80cfcfc bellard
178 e80cfcfc bellard
    for (i = 0; i < MAXX*MAXY; i += TARGET_PAGE_SIZE) {
179 e80cfcfc bellard
        cpu_physical_memory_set_dirty(s->vram_offset + i);
180 e80cfcfc bellard
    }
181 420557e8 bellard
}
182 420557e8 bellard
183 e80cfcfc bellard
static void tcx_save(QEMUFile *f, void *opaque)
184 420557e8 bellard
{
185 420557e8 bellard
    TCXState *s = opaque;
186 e80cfcfc bellard
    
187 e80cfcfc bellard
    qemu_put_be32s(f, (uint32_t *)&s->addr);
188 e80cfcfc bellard
    qemu_put_be32s(f, (uint32_t *)&s->vram);
189 e80cfcfc bellard
    qemu_put_buffer(f, s->r, 256);
190 e80cfcfc bellard
    qemu_put_buffer(f, s->g, 256);
191 e80cfcfc bellard
    qemu_put_buffer(f, s->b, 256);
192 420557e8 bellard
}
193 420557e8 bellard
194 e80cfcfc bellard
static int tcx_load(QEMUFile *f, void *opaque, int version_id)
195 420557e8 bellard
{
196 e80cfcfc bellard
    TCXState *s = opaque;
197 e80cfcfc bellard
    
198 e80cfcfc bellard
    if (version_id != 1)
199 e80cfcfc bellard
        return -EINVAL;
200 e80cfcfc bellard
201 e80cfcfc bellard
    qemu_get_be32s(f, (uint32_t *)&s->addr);
202 e80cfcfc bellard
    qemu_get_be32s(f, (uint32_t *)&s->vram);
203 e80cfcfc bellard
    qemu_get_buffer(f, s->r, 256);
204 e80cfcfc bellard
    qemu_get_buffer(f, s->g, 256);
205 e80cfcfc bellard
    qemu_get_buffer(f, s->b, 256);
206 e80cfcfc bellard
    return 0;
207 420557e8 bellard
}
208 420557e8 bellard
209 e80cfcfc bellard
static void tcx_reset(void *opaque)
210 420557e8 bellard
{
211 e80cfcfc bellard
    TCXState *s = opaque;
212 e80cfcfc bellard
213 e80cfcfc bellard
    /* Initialize palette */
214 e80cfcfc bellard
    memset(s->r, 0, 256);
215 e80cfcfc bellard
    memset(s->g, 0, 256);
216 e80cfcfc bellard
    memset(s->b, 0, 256);
217 e80cfcfc bellard
    s->r[255] = s->g[255] = s->b[255] = 255;
218 e80cfcfc bellard
    memset(s->vram, 0, MAXX*MAXY);
219 662f3c86 bellard
    cpu_physical_memory_reset_dirty(s->vram_offset, s->vram_offset + MAXX*MAXY);
220 420557e8 bellard
}
221 420557e8 bellard
222 e80cfcfc bellard
void *tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base,
223 e80cfcfc bellard
              unsigned long vram_offset, int vram_size)
224 420557e8 bellard
{
225 420557e8 bellard
    TCXState *s;
226 420557e8 bellard
227 420557e8 bellard
    s = qemu_mallocz(sizeof(TCXState));
228 420557e8 bellard
    if (!s)
229 e80cfcfc bellard
        return NULL;
230 420557e8 bellard
    s->ds = ds;
231 8d5f07fa bellard
    s->addr = addr;
232 e80cfcfc bellard
    s->vram = vram_base;
233 e80cfcfc bellard
    s->vram_offset = vram_offset;
234 e80cfcfc bellard
235 e80cfcfc bellard
    cpu_register_physical_memory(addr, vram_size, vram_offset);
236 e80cfcfc bellard
237 e80cfcfc bellard
    register_savevm("tcx", addr, 1, tcx_save, tcx_load, s);
238 e80cfcfc bellard
    qemu_register_reset(tcx_reset, s);
239 e80cfcfc bellard
    tcx_reset(s);
240 420557e8 bellard
    dpy_resize(s->ds, XSZ, YSZ);
241 e80cfcfc bellard
    return s;
242 420557e8 bellard
}
243 420557e8 bellard
244 e80cfcfc bellard
void tcx_screen_dump(void *opaque, const char *filename)
245 8d5f07fa bellard
{
246 e80cfcfc bellard
    TCXState *s = opaque;
247 8d5f07fa bellard
    FILE *f;
248 e80cfcfc bellard
    uint8_t *d, *d1, v;
249 8d5f07fa bellard
    int y, x;
250 8d5f07fa bellard
251 8d5f07fa bellard
    f = fopen(filename, "wb");
252 8d5f07fa bellard
    if (!f)
253 e80cfcfc bellard
        return;
254 e80cfcfc bellard
    fprintf(f, "P6\n%d %d\n%d\n", XSZ, YSZ, 255);
255 e80cfcfc bellard
    d1 = s->vram + YOFF*MAXX + XOFF;
256 8d5f07fa bellard
    for(y = 0; y < YSZ; y++) {
257 8d5f07fa bellard
        d = d1;
258 8d5f07fa bellard
        for(x = 0; x < XSZ; x++) {
259 8d5f07fa bellard
            v = *d;
260 e80cfcfc bellard
            fputc(s->r[v], f);
261 e80cfcfc bellard
            fputc(s->g[v], f);
262 e80cfcfc bellard
            fputc(s->b[v], f);
263 8d5f07fa bellard
            d++;
264 8d5f07fa bellard
        }
265 e80cfcfc bellard
        d1 += MAXX;
266 8d5f07fa bellard
    }
267 8d5f07fa bellard
    fclose(f);
268 8d5f07fa bellard
    return;
269 8d5f07fa bellard
}
270 8d5f07fa bellard
271 8d5f07fa bellard