Revision 6f7e9aec hw/tcx.c

b/hw/tcx.c
1 1
/*
2
 * QEMU Sun4m System Emulator
2
 * QEMU TCX Frame buffer
3 3
 * 
4
 * Copyright (c) 2003-2004 Fabrice Bellard
4
 * Copyright (c) 2003-2005 Fabrice Bellard
5 5
 * 
6 6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 7
 * of this software and associated documentation files (the "Software"), to deal
......
25 25

  
26 26
#define MAXX 1024
27 27
#define MAXY 768
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
34
#define XSZ (8*80)
35
#define YSZ (24*11)
36
#define XOFF (MAXX-XSZ)
37
#define YOFF (MAXY-YSZ)
38
#else
39
#define XSZ MAXX
40
#define YSZ MAXY
41
#define XOFF 0
42
#define YOFF 0
43
#endif
28
#define TCX_DAC_NREGS 16
44 29

  
45 30
typedef struct TCXState {
46 31
    uint32_t addr;
47 32
    DisplayState *ds;
48 33
    uint8_t *vram;
49 34
    unsigned long vram_offset;
35
    uint16_t width, height;
50 36
    uint8_t r[256], g[256], b[256];
37
    uint8_t dac_index, dac_state;
51 38
} TCXState;
52 39

  
53 40
static void tcx_draw_line32(TCXState *s1, uint8_t *d, 
......
58 45

  
59 46
    for(x = 0; x < width; x++) {
60 47
	val = *s++;
61
	*d++ = s1->r[val];
62
	*d++ = s1->g[val];
63 48
	*d++ = s1->b[val];
49
	*d++ = s1->g[val];
50
	*d++ = s1->r[val];
64 51
	d++;
65 52
    }
66 53
}
......
73 60

  
74 61
    for(x = 0; x < width; x++) {
75 62
	val = *s++;
76
	*d++ = s1->r[val];
77
	*d++ = s1->g[val];
78 63
	*d++ = s1->b[val];
64
	*d++ = s1->g[val];
65
	*d++ = s1->r[val];
79 66
    }
80 67
}
81 68

  
......
104 91

  
105 92
    if (ts->ds->depth == 0)
106 93
	return;
107
    page = ts->vram_offset + YOFF*MAXX;
94
    page = ts->vram_offset;
108 95
    y_start = -1;
109 96
    page_min = 0x7fffffff;
110 97
    page_max = -1;
111 98
    d = ts->ds->data;
112
    s = ts->vram + YOFF*MAXX + XOFF;
99
    s = ts->vram;
113 100
    dd = ts->ds->linesize;
114 101
    ds = 1024;
115 102

  
......
128 115
	return;
129 116
    }
130 117
    
131
    for(y = 0; y < YSZ; y += 4, page += TARGET_PAGE_SIZE) {
118
    for(y = 0; y < ts->height; y += 4, page += TARGET_PAGE_SIZE) {
132 119
	if (cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG)) {
133 120
	    if (y_start < 0)
134 121
                y_start = y;
......
136 123
                page_min = page;
137 124
            if (page > page_max)
138 125
                page_max = page;
139
	    f(ts, d, s, XSZ);
126
	    f(ts, d, s, ts->width);
140 127
	    d += dd;
141 128
	    s += ds;
142
	    f(ts, d, s, XSZ);
129
	    f(ts, d, s, ts->width);
143 130
	    d += dd;
144 131
	    s += ds;
145
	    f(ts, d, s, XSZ);
132
	    f(ts, d, s, ts->width);
146 133
	    d += dd;
147 134
	    s += ds;
148
	    f(ts, d, s, XSZ);
135
	    f(ts, d, s, ts->width);
149 136
	    d += dd;
150 137
	    s += ds;
151 138
	} else {
152 139
            if (y_start >= 0) {
153 140
                /* flush to display */
154 141
                dpy_update(ts->ds, 0, y_start, 
155
                           XSZ, y - y_start);
142
                           ts->width, y - y_start);
156 143
                y_start = -1;
157 144
            }
158 145
	    d += dd * 4;
......
162 149
    if (y_start >= 0) {
163 150
	/* flush to display */
164 151
	dpy_update(ts->ds, 0, y_start, 
165
		   XSZ, y - y_start);
152
		   ts->width, y - y_start);
166 153
    }
167 154
    /* reset modified pages */
168 155
    if (page_max != -1) {
......
187 174
    
188 175
    qemu_put_be32s(f, (uint32_t *)&s->addr);
189 176
    qemu_put_be32s(f, (uint32_t *)&s->vram);
177
    qemu_put_be16s(f, (uint16_t *)&s->height);
178
    qemu_put_be16s(f, (uint16_t *)&s->width);
190 179
    qemu_put_buffer(f, s->r, 256);
191 180
    qemu_put_buffer(f, s->g, 256);
192 181
    qemu_put_buffer(f, s->b, 256);
182
    qemu_put_8s(f, &s->dac_index);
183
    qemu_put_8s(f, &s->dac_state);
193 184
}
194 185

  
195 186
static int tcx_load(QEMUFile *f, void *opaque, int version_id)
......
201 192

  
202 193
    qemu_get_be32s(f, (uint32_t *)&s->addr);
203 194
    qemu_get_be32s(f, (uint32_t *)&s->vram);
195
    qemu_get_be16s(f, (uint16_t *)&s->height);
196
    qemu_get_be16s(f, (uint16_t *)&s->width);
204 197
    qemu_get_buffer(f, s->r, 256);
205 198
    qemu_get_buffer(f, s->g, 256);
206 199
    qemu_get_buffer(f, s->b, 256);
200
    qemu_get_8s(f, &s->dac_index);
201
    qemu_get_8s(f, &s->dac_state);
207 202
    return 0;
208 203
}
209 204

  
......
219 214
    memset(s->vram, 0, MAXX*MAXY);
220 215
    cpu_physical_memory_reset_dirty(s->vram_offset, s->vram_offset + MAXX*MAXY,
221 216
                                    VGA_DIRTY_FLAG);
217
    s->dac_index = 0;
218
    s->dac_state = 0;
219
}
220

  
221
static uint32_t tcx_dac_readl(void *opaque, target_phys_addr_t addr)
222
{
223
    return 0;
224
}
225

  
226
static void tcx_dac_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
227
{
228
    TCXState *s = opaque;
229
    uint32_t saddr;
230

  
231
    saddr = (addr & (TCX_DAC_NREGS - 1)) >> 2;
232
    switch (saddr) {
233
    case 0:
234
	s->dac_index = val >> 24;
235
	s->dac_state = 0;
236
	break;
237
    case 1:
238
	switch (s->dac_state) {
239
	case 0:
240
	    s->r[s->dac_index] = val >> 24;
241
	    s->dac_state++;
242
	    break;
243
	case 1:
244
	    s->g[s->dac_index] = val >> 24;
245
	    s->dac_state++;
246
	    break;
247
	case 2:
248
	    s->b[s->dac_index] = val >> 24;
249
	default:
250
	    s->dac_state = 0;
251
	    break;
252
	}
253
	break;
254
    default:
255
	break;
256
    }
257
    return;
222 258
}
223 259

  
260
static CPUReadMemoryFunc *tcx_dac_read[3] = {
261
    tcx_dac_readl,
262
    tcx_dac_readl,
263
    tcx_dac_readl,
264
};
265

  
266
static CPUWriteMemoryFunc *tcx_dac_write[3] = {
267
    tcx_dac_writel,
268
    tcx_dac_writel,
269
    tcx_dac_writel,
270
};
271

  
224 272
void *tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base,
225
	      unsigned long vram_offset, int vram_size)
273
	       unsigned long vram_offset, int vram_size, int width, int height)
226 274
{
227 275
    TCXState *s;
276
    int io_memory;
228 277

  
229 278
    s = qemu_mallocz(sizeof(TCXState));
230 279
    if (!s)
......
233 282
    s->addr = addr;
234 283
    s->vram = vram_base;
235 284
    s->vram_offset = vram_offset;
285
    s->width = width;
286
    s->height = height;
236 287

  
237
    cpu_register_physical_memory(addr, vram_size, vram_offset);
288
    cpu_register_physical_memory(addr + 0x800000, vram_size, vram_offset);
289
    io_memory = cpu_register_io_memory(0, tcx_dac_read, tcx_dac_write, s);
290
    cpu_register_physical_memory(addr + 0x200000, TCX_DAC_NREGS, io_memory);
238 291

  
239 292
    register_savevm("tcx", addr, 1, tcx_save, tcx_load, s);
240 293
    qemu_register_reset(tcx_reset, s);
241 294
    tcx_reset(s);
242
    dpy_resize(s->ds, XSZ, YSZ);
295
    dpy_resize(s->ds, width, height);
243 296
    return s;
244 297
}
245 298

  
......
253 306
    f = fopen(filename, "wb");
254 307
    if (!f)
255 308
        return;
256
    fprintf(f, "P6\n%d %d\n%d\n", XSZ, YSZ, 255);
257
    d1 = s->vram + YOFF*MAXX + XOFF;
258
    for(y = 0; y < YSZ; y++) {
309
    fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);
310
    d1 = s->vram;
311
    for(y = 0; y < s->height; y++) {
259 312
        d = d1;
260
        for(x = 0; x < XSZ; x++) {
313
        for(x = 0; x < s->width; x++) {
261 314
            v = *d;
262 315
            fputc(s->r[v], f);
263 316
            fputc(s->g[v], f);

Also available in: Unified diff