/[qemu]/qemu/hw/tcx.c
ViewVC logotype

Diff of /qemu/hw/tcx.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.5 by bellard, Thu Feb 10 22:00:27 2005 UTC revision 1.6 by bellard, Sun Mar 13 09:43:36 2005 UTC
# Line 1  Line 1 
1  /*  /*
2   * QEMU Sun4m System Emulator   * QEMU TCX Frame buffer
3   *   *
4   * Copyright (c) 2003-2004 Fabrice Bellard   * Copyright (c) 2003-2005 Fabrice Bellard
5   *   *
6   * Permission is hereby granted, free of charge, to any person obtaining a copy   * 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   * of this software and associated documentation files (the "Software"), to deal
# Line 25  Line 25 
25    
26  #define MAXX 1024  #define MAXX 1024
27  #define MAXY 768  #define MAXY 768
28  /*  #define TCX_DAC_NREGS 16
  * Proll uses only small part of display, we need to switch to full  
  * display when we get linux framebuffer console or X11 running. For  
  * now it's just slower and awkward.  
 */  
 #if 1  
 #define XSZ (8*80)  
 #define YSZ (24*11)  
 #define XOFF (MAXX-XSZ)  
 #define YOFF (MAXY-YSZ)  
 #else  
 #define XSZ MAXX  
 #define YSZ MAXY  
 #define XOFF 0  
 #define YOFF 0  
 #endif  
29    
30  typedef struct TCXState {  typedef struct TCXState {
31      uint32_t addr;      uint32_t addr;
32      DisplayState *ds;      DisplayState *ds;
33      uint8_t *vram;      uint8_t *vram;
34      unsigned long vram_offset;      unsigned long vram_offset;
35        uint16_t width, height;
36      uint8_t r[256], g[256], b[256];      uint8_t r[256], g[256], b[256];
37        uint8_t dac_index, dac_state;
38  } TCXState;  } TCXState;
39    
40  static void tcx_draw_line32(TCXState *s1, uint8_t *d,  static void tcx_draw_line32(TCXState *s1, uint8_t *d,
# Line 58  static void tcx_draw_line32(TCXState *s1 Line 45  static void tcx_draw_line32(TCXState *s1
45    
46      for(x = 0; x < width; x++) {      for(x = 0; x < width; x++) {
47          val = *s++;          val = *s++;
         *d++ = s1->r[val];  
         *d++ = s1->g[val];  
48          *d++ = s1->b[val];          *d++ = s1->b[val];
49            *d++ = s1->g[val];
50            *d++ = s1->r[val];
51          d++;          d++;
52      }      }
53  }  }
# Line 73  static void tcx_draw_line24(TCXState *s1 Line 60  static void tcx_draw_line24(TCXState *s1
60    
61      for(x = 0; x < width; x++) {      for(x = 0; x < width; x++) {
62          val = *s++;          val = *s++;
         *d++ = s1->r[val];  
         *d++ = s1->g[val];  
63          *d++ = s1->b[val];          *d++ = s1->b[val];
64            *d++ = s1->g[val];
65            *d++ = s1->r[val];
66      }      }
67  }  }
68    
# Line 104  void tcx_update_display(void *opaque) Line 91  void tcx_update_display(void *opaque)
91    
92      if (ts->ds->depth == 0)      if (ts->ds->depth == 0)
93          return;          return;
94      page = ts->vram_offset + YOFF*MAXX;      page = ts->vram_offset;
95      y_start = -1;      y_start = -1;
96      page_min = 0x7fffffff;      page_min = 0x7fffffff;
97      page_max = -1;      page_max = -1;
98      d = ts->ds->data;      d = ts->ds->data;
99      s = ts->vram + YOFF*MAXX + XOFF;      s = ts->vram;
100      dd = ts->ds->linesize;      dd = ts->ds->linesize;
101      ds = 1024;      ds = 1024;
102    
# Line 128  void tcx_update_display(void *opaque) Line 115  void tcx_update_display(void *opaque)
115          return;          return;
116      }      }
117            
118      for(y = 0; y < YSZ; y += 4, page += TARGET_PAGE_SIZE) {      for(y = 0; y < ts->height; y += 4, page += TARGET_PAGE_SIZE) {
119          if (cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG)) {          if (cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG)) {
120              if (y_start < 0)              if (y_start < 0)
121                  y_start = y;                  y_start = y;
# Line 136  void tcx_update_display(void *opaque) Line 123  void tcx_update_display(void *opaque)
123                  page_min = page;                  page_min = page;
124              if (page > page_max)              if (page > page_max)
125                  page_max = page;                  page_max = page;
126              f(ts, d, s, XSZ);              f(ts, d, s, ts->width);
127              d += dd;              d += dd;
128              s += ds;              s += ds;
129              f(ts, d, s, XSZ);              f(ts, d, s, ts->width);
130              d += dd;              d += dd;
131              s += ds;              s += ds;
132              f(ts, d, s, XSZ);              f(ts, d, s, ts->width);
133              d += dd;              d += dd;
134              s += ds;              s += ds;
135              f(ts, d, s, XSZ);              f(ts, d, s, ts->width);
136              d += dd;              d += dd;
137              s += ds;              s += ds;
138          } else {          } else {
139              if (y_start >= 0) {              if (y_start >= 0) {
140                  /* flush to display */                  /* flush to display */
141                  dpy_update(ts->ds, 0, y_start,                  dpy_update(ts->ds, 0, y_start,
142                             XSZ, y - y_start);                             ts->width, y - y_start);
143                  y_start = -1;                  y_start = -1;
144              }              }
145              d += dd * 4;              d += dd * 4;
# Line 162  void tcx_update_display(void *opaque) Line 149  void tcx_update_display(void *opaque)
149      if (y_start >= 0) {      if (y_start >= 0) {
150          /* flush to display */          /* flush to display */
151          dpy_update(ts->ds, 0, y_start,          dpy_update(ts->ds, 0, y_start,
152                     XSZ, y - y_start);                     ts->width, y - y_start);
153      }      }
154      /* reset modified pages */      /* reset modified pages */
155      if (page_max != -1) {      if (page_max != -1) {
# Line 187  static void tcx_save(QEMUFile *f, void * Line 174  static void tcx_save(QEMUFile *f, void *
174            
175      qemu_put_be32s(f, (uint32_t *)&s->addr);      qemu_put_be32s(f, (uint32_t *)&s->addr);
176      qemu_put_be32s(f, (uint32_t *)&s->vram);      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);
179      qemu_put_buffer(f, s->r, 256);      qemu_put_buffer(f, s->r, 256);
180      qemu_put_buffer(f, s->g, 256);      qemu_put_buffer(f, s->g, 256);
181      qemu_put_buffer(f, s->b, 256);      qemu_put_buffer(f, s->b, 256);
182        qemu_put_8s(f, &s->dac_index);
183        qemu_put_8s(f, &s->dac_state);
184  }  }
185    
186  static int tcx_load(QEMUFile *f, void *opaque, int version_id)  static int tcx_load(QEMUFile *f, void *opaque, int version_id)
# Line 201  static int tcx_load(QEMUFile *f, void *o Line 192  static int tcx_load(QEMUFile *f, void *o
192    
193      qemu_get_be32s(f, (uint32_t *)&s->addr);      qemu_get_be32s(f, (uint32_t *)&s->addr);
194      qemu_get_be32s(f, (uint32_t *)&s->vram);      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);
197      qemu_get_buffer(f, s->r, 256);      qemu_get_buffer(f, s->r, 256);
198      qemu_get_buffer(f, s->g, 256);      qemu_get_buffer(f, s->g, 256);
199      qemu_get_buffer(f, s->b, 256);      qemu_get_buffer(f, s->b, 256);
200        qemu_get_8s(f, &s->dac_index);
201        qemu_get_8s(f, &s->dac_state);
202      return 0;      return 0;
203  }  }
204    
# Line 219  static void tcx_reset(void *opaque) Line 214  static void tcx_reset(void *opaque)
214      memset(s->vram, 0, MAXX*MAXY);      memset(s->vram, 0, MAXX*MAXY);
215      cpu_physical_memory_reset_dirty(s->vram_offset, s->vram_offset + MAXX*MAXY,      cpu_physical_memory_reset_dirty(s->vram_offset, s->vram_offset + MAXX*MAXY,
216                                      VGA_DIRTY_FLAG);                                      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;
258    }
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    
272  void *tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base,  void *tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base,
273                unsigned long vram_offset, int vram_size)                 unsigned long vram_offset, int vram_size, int width, int height)
274  {  {
275      TCXState *s;      TCXState *s;
276        int io_memory;
277    
278      s = qemu_mallocz(sizeof(TCXState));      s = qemu_mallocz(sizeof(TCXState));
279      if (!s)      if (!s)
# Line 233  void *tcx_init(DisplayState *ds, uint32_ Line 282  void *tcx_init(DisplayState *ds, uint32_
282      s->addr = addr;      s->addr = addr;
283      s->vram = vram_base;      s->vram = vram_base;
284      s->vram_offset = vram_offset;      s->vram_offset = vram_offset;
285        s->width = width;
286        s->height = height;
287    
288      cpu_register_physical_memory(addr, vram_size, vram_offset);      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);
291    
292      register_savevm("tcx", addr, 1, tcx_save, tcx_load, s);      register_savevm("tcx", addr, 1, tcx_save, tcx_load, s);
293      qemu_register_reset(tcx_reset, s);      qemu_register_reset(tcx_reset, s);
294      tcx_reset(s);      tcx_reset(s);
295      dpy_resize(s->ds, XSZ, YSZ);      dpy_resize(s->ds, width, height);
296      return s;      return s;
297  }  }
298    
# Line 253  void tcx_screen_dump(void *opaque, const Line 306  void tcx_screen_dump(void *opaque, const
306      f = fopen(filename, "wb");      f = fopen(filename, "wb");
307      if (!f)      if (!f)
308          return;          return;
309      fprintf(f, "P6\n%d %d\n%d\n", XSZ, YSZ, 255);      fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);
310      d1 = s->vram + YOFF*MAXX + XOFF;      d1 = s->vram;
311      for(y = 0; y < YSZ; y++) {      for(y = 0; y < s->height; y++) {
312          d = d1;          d = d1;
313          for(x = 0; x < XSZ; x++) {          for(x = 0; x < s->width; x++) {
314              v = *d;              v = *d;
315              fputc(s->r[v], f);              fputc(s->r[v], f);
316              fputc(s->g[v], f);              fputc(s->g[v], f);

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26