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