Statistics
| Branch: | Revision:

root / hw / tcx.c @ 0443eaf6

History | View | Annotate | Download (6.4 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 0a962c02 bellard
        if (cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG)) {
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 0a962c02 bellard
        cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE,
170 0a962c02 bellard
                                        VGA_DIRTY_FLAG);
171 e80cfcfc bellard
    }
172 420557e8 bellard
}
173 420557e8 bellard
174 e80cfcfc bellard
void tcx_invalidate_display(void *opaque)
175 420557e8 bellard
{
176 e80cfcfc bellard
    TCXState *s = opaque;
177 e80cfcfc bellard
    int i;
178 e80cfcfc bellard
179 e80cfcfc bellard
    for (i = 0; i < MAXX*MAXY; i += TARGET_PAGE_SIZE) {
180 e80cfcfc bellard
        cpu_physical_memory_set_dirty(s->vram_offset + i);
181 e80cfcfc bellard
    }
182 420557e8 bellard
}
183 420557e8 bellard
184 e80cfcfc bellard
static void tcx_save(QEMUFile *f, void *opaque)
185 420557e8 bellard
{
186 420557e8 bellard
    TCXState *s = opaque;
187 e80cfcfc bellard
    
188 e80cfcfc bellard
    qemu_put_be32s(f, (uint32_t *)&s->addr);
189 e80cfcfc bellard
    qemu_put_be32s(f, (uint32_t *)&s->vram);
190 e80cfcfc bellard
    qemu_put_buffer(f, s->r, 256);
191 e80cfcfc bellard
    qemu_put_buffer(f, s->g, 256);
192 e80cfcfc bellard
    qemu_put_buffer(f, s->b, 256);
193 420557e8 bellard
}
194 420557e8 bellard
195 e80cfcfc bellard
static int tcx_load(QEMUFile *f, void *opaque, int version_id)
196 420557e8 bellard
{
197 e80cfcfc bellard
    TCXState *s = opaque;
198 e80cfcfc bellard
    
199 e80cfcfc bellard
    if (version_id != 1)
200 e80cfcfc bellard
        return -EINVAL;
201 e80cfcfc bellard
202 e80cfcfc bellard
    qemu_get_be32s(f, (uint32_t *)&s->addr);
203 e80cfcfc bellard
    qemu_get_be32s(f, (uint32_t *)&s->vram);
204 e80cfcfc bellard
    qemu_get_buffer(f, s->r, 256);
205 e80cfcfc bellard
    qemu_get_buffer(f, s->g, 256);
206 e80cfcfc bellard
    qemu_get_buffer(f, s->b, 256);
207 e80cfcfc bellard
    return 0;
208 420557e8 bellard
}
209 420557e8 bellard
210 e80cfcfc bellard
static void tcx_reset(void *opaque)
211 420557e8 bellard
{
212 e80cfcfc bellard
    TCXState *s = opaque;
213 e80cfcfc bellard
214 e80cfcfc bellard
    /* Initialize palette */
215 e80cfcfc bellard
    memset(s->r, 0, 256);
216 e80cfcfc bellard
    memset(s->g, 0, 256);
217 e80cfcfc bellard
    memset(s->b, 0, 256);
218 e80cfcfc bellard
    s->r[255] = s->g[255] = s->b[255] = 255;
219 e80cfcfc bellard
    memset(s->vram, 0, MAXX*MAXY);
220 0a962c02 bellard
    cpu_physical_memory_reset_dirty(s->vram_offset, s->vram_offset + MAXX*MAXY,
221 0a962c02 bellard
                                    VGA_DIRTY_FLAG);
222 420557e8 bellard
}
223 420557e8 bellard
224 e80cfcfc bellard
void *tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base,
225 e80cfcfc bellard
              unsigned long vram_offset, int vram_size)
226 420557e8 bellard
{
227 420557e8 bellard
    TCXState *s;
228 420557e8 bellard
229 420557e8 bellard
    s = qemu_mallocz(sizeof(TCXState));
230 420557e8 bellard
    if (!s)
231 e80cfcfc bellard
        return NULL;
232 420557e8 bellard
    s->ds = ds;
233 8d5f07fa bellard
    s->addr = addr;
234 e80cfcfc bellard
    s->vram = vram_base;
235 e80cfcfc bellard
    s->vram_offset = vram_offset;
236 e80cfcfc bellard
237 e80cfcfc bellard
    cpu_register_physical_memory(addr, vram_size, vram_offset);
238 e80cfcfc bellard
239 e80cfcfc bellard
    register_savevm("tcx", addr, 1, tcx_save, tcx_load, s);
240 e80cfcfc bellard
    qemu_register_reset(tcx_reset, s);
241 e80cfcfc bellard
    tcx_reset(s);
242 420557e8 bellard
    dpy_resize(s->ds, XSZ, YSZ);
243 e80cfcfc bellard
    return s;
244 420557e8 bellard
}
245 420557e8 bellard
246 e80cfcfc bellard
void tcx_screen_dump(void *opaque, const char *filename)
247 8d5f07fa bellard
{
248 e80cfcfc bellard
    TCXState *s = opaque;
249 8d5f07fa bellard
    FILE *f;
250 e80cfcfc bellard
    uint8_t *d, *d1, v;
251 8d5f07fa bellard
    int y, x;
252 8d5f07fa bellard
253 8d5f07fa bellard
    f = fopen(filename, "wb");
254 8d5f07fa bellard
    if (!f)
255 e80cfcfc bellard
        return;
256 e80cfcfc bellard
    fprintf(f, "P6\n%d %d\n%d\n", XSZ, YSZ, 255);
257 e80cfcfc bellard
    d1 = s->vram + YOFF*MAXX + XOFF;
258 8d5f07fa bellard
    for(y = 0; y < YSZ; y++) {
259 8d5f07fa bellard
        d = d1;
260 8d5f07fa bellard
        for(x = 0; x < XSZ; x++) {
261 8d5f07fa bellard
            v = *d;
262 e80cfcfc bellard
            fputc(s->r[v], f);
263 e80cfcfc bellard
            fputc(s->g[v], f);
264 e80cfcfc bellard
            fputc(s->b[v], f);
265 8d5f07fa bellard
            d++;
266 8d5f07fa bellard
        }
267 e80cfcfc bellard
        d1 += MAXX;
268 8d5f07fa bellard
    }
269 8d5f07fa bellard
    fclose(f);
270 8d5f07fa bellard
    return;
271 8d5f07fa bellard
}
272 8d5f07fa bellard
273 8d5f07fa bellard