symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/g364fb.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  * QEMU G364 framebuffer Emulator.
       
     3  *
       
     4  * Copyright (c) 2007-2008 Hervé Poussineau
       
     5  *
       
     6  * This program is free software; you can redistribute it and/or
       
     7  * modify it under the terms of the GNU General Public License as
       
     8  * published by the Free Software Foundation; either version 2 of
       
     9  * the License, or (at your option) any later version.
       
    10  *
       
    11  * This program is distributed in the hope that it will be useful,
       
    12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    14  * GNU General Public License for more details.
       
    15  *
       
    16  * You should have received a copy of the GNU General Public License
       
    17  * along with this program; if not, write to the Free Software
       
    18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
       
    19  * MA 02111-1307 USA
       
    20  */
       
    21 
       
    22 #include "hw.h"
       
    23 #include "mips.h"
       
    24 #include "console.h"
       
    25 #include "pixel_ops.h"
       
    26 
       
    27 //#define DEBUG_G364
       
    28 
       
    29 typedef struct G364State {
       
    30     unsigned int vram_size;
       
    31     uint8_t *vram_buffer;
       
    32     uint32_t ctla;
       
    33     uint8_t palette[256][3];
       
    34     /* display refresh support */
       
    35     DisplayState *ds;
       
    36     QEMUConsole *console;
       
    37     int graphic_mode;
       
    38     uint32_t scr_width, scr_height; /* in pixels */
       
    39 } G364State;
       
    40 
       
    41 /*
       
    42  * graphic modes
       
    43  */
       
    44 #define BPP 8
       
    45 #define PIXEL_WIDTH 8
       
    46 #include "g364fb_template.h"
       
    47 #undef BPP
       
    48 #undef PIXEL_WIDTH
       
    49 
       
    50 #define BPP 15
       
    51 #define PIXEL_WIDTH 16
       
    52 #include "g364fb_template.h"
       
    53 #undef BPP
       
    54 #undef PIXEL_WIDTH
       
    55 
       
    56 #define BPP 16
       
    57 #define PIXEL_WIDTH 16
       
    58 #include "g364fb_template.h"
       
    59 #undef BPP
       
    60 #undef PIXEL_WIDTH
       
    61 
       
    62 #define BPP 32
       
    63 #define PIXEL_WIDTH 32
       
    64 #include "g364fb_template.h"
       
    65 #undef BPP
       
    66 #undef PIXEL_WIDTH
       
    67 
       
    68 #define REG_DISPLAYX 0x0918
       
    69 #define REG_DISPLAYY 0x0940
       
    70 
       
    71 #define CTLA_FORCE_BLANK 0x400
       
    72 
       
    73 static void g364fb_draw_graphic(G364State *s, int full_update)
       
    74 {
       
    75     switch (ds_get_bits_per_pixel(s->ds)) {
       
    76         case 8:
       
    77             g364fb_draw_graphic8(s, full_update);
       
    78             break;
       
    79         case 15:
       
    80             g364fb_draw_graphic15(s, full_update);
       
    81             break;
       
    82         case 16:
       
    83             g364fb_draw_graphic16(s, full_update);
       
    84             break;
       
    85         case 32:
       
    86             g364fb_draw_graphic32(s, full_update);
       
    87             break;
       
    88         default:
       
    89             printf("g364fb: unknown depth %d\n", ds_get_bits_per_pixel(s->ds));
       
    90             return;
       
    91     }
       
    92 
       
    93     dpy_update(s->ds, 0, 0, s->scr_width, s->scr_height);
       
    94 }
       
    95 
       
    96 static void g364fb_draw_blank(G364State *s, int full_update)
       
    97 {
       
    98     int i, w;
       
    99     uint8_t *d;
       
   100 
       
   101     if (!full_update)
       
   102         return;
       
   103 
       
   104     w = s->scr_width * ((ds_get_bits_per_pixel(s->ds) + 7) >> 3);
       
   105     d = ds_get_data(s->ds);
       
   106     for(i = 0; i < s->scr_height; i++) {
       
   107         memset(d, 0, w);
       
   108         d += ds_get_linesize(s->ds);
       
   109     }
       
   110 
       
   111     dpy_update(s->ds, 0, 0, s->scr_width, s->scr_height);
       
   112 }
       
   113 
       
   114 #define GMODE_GRAPH 0
       
   115 #define GMODE_BLANK 1
       
   116 
       
   117 static void g364fb_update_display(void *opaque)
       
   118 {
       
   119     G364State *s = opaque;
       
   120     int full_update, graphic_mode;
       
   121 
       
   122     if (s->scr_width == 0 || s->scr_height == 0)
       
   123         return;
       
   124 
       
   125     if (s->ctla & CTLA_FORCE_BLANK)
       
   126         graphic_mode = GMODE_BLANK;
       
   127     else
       
   128         graphic_mode = GMODE_GRAPH;
       
   129     full_update = 0;
       
   130     if (graphic_mode != s->graphic_mode) {
       
   131         s->graphic_mode = graphic_mode;
       
   132         full_update = 1;
       
   133     }
       
   134     if (s->scr_width != ds_get_width(s->ds) || s->scr_height != ds_get_height(s->ds)) {
       
   135         qemu_console_resize(s->console, s->scr_width, s->scr_height);
       
   136         full_update = 1;
       
   137     }
       
   138     switch(graphic_mode) {
       
   139         case GMODE_GRAPH:
       
   140             g364fb_draw_graphic(s, full_update);
       
   141             break;
       
   142         case GMODE_BLANK:
       
   143         default:
       
   144             g364fb_draw_blank(s, full_update);
       
   145             break;
       
   146     }
       
   147 }
       
   148 
       
   149 /* force a full display refresh */
       
   150 static void g364fb_invalidate_display(void *opaque)
       
   151 {
       
   152     G364State *s = opaque;
       
   153     s->graphic_mode = -1; /* force full update */
       
   154 }
       
   155 
       
   156 static void g364fb_reset(void *opaque)
       
   157 {
       
   158     G364State *s = opaque;
       
   159 
       
   160     memset(s->palette, 0, sizeof(s->palette));
       
   161     s->scr_width = s->scr_height = 0;
       
   162     memset(s->vram_buffer, 0, s->vram_size);
       
   163     s->graphic_mode = -1; /* force full update */
       
   164 }
       
   165 
       
   166 static void g364fb_screen_dump(void *opaque, const char *filename)
       
   167 {
       
   168     G364State *s = opaque;
       
   169     int y, x;
       
   170     uint8_t index;
       
   171     uint8_t *data_buffer;
       
   172     FILE *f;
       
   173 
       
   174     f = fopen(filename, "wb");
       
   175     if (!f)
       
   176         return;
       
   177 
       
   178     data_buffer = s->vram_buffer;
       
   179     fprintf(f, "P6\n%d %d\n%d\n",
       
   180         s->scr_width, s->scr_height, 255);
       
   181     for(y = 0; y < s->scr_height; y++)
       
   182         for(x = 0; x < s->scr_width; x++, data_buffer++) {
       
   183             index = *data_buffer;
       
   184             fputc(s->palette[index][0], f);
       
   185             fputc(s->palette[index][1], f);
       
   186             fputc(s->palette[index][2], f);
       
   187         }
       
   188     fclose(f);
       
   189 }
       
   190 
       
   191 /* called for accesses to io ports */
       
   192 static uint32_t g364fb_ctrl_readb(void *opaque, target_phys_addr_t addr)
       
   193 {
       
   194     //G364State *s = opaque;
       
   195     uint32_t val;
       
   196 
       
   197     addr &= 0xffff;
       
   198 
       
   199     switch (addr) {
       
   200         default:
       
   201 #ifdef DEBUG_G364
       
   202             printf("g364fb/ctrl: invalid read at [" TARGET_FMT_lx "]\n", addr);
       
   203 #endif
       
   204             val = 0;
       
   205             break;
       
   206     }
       
   207 
       
   208 #ifdef DEBUG_G364
       
   209     printf("g364fb/ctrl: read 0x%02x at [" TARGET_FMT_lx "]\n", val, addr);
       
   210 #endif
       
   211 
       
   212     return val;
       
   213 }
       
   214 
       
   215 static uint32_t g364fb_ctrl_readw(void *opaque, target_phys_addr_t addr)
       
   216 {
       
   217     uint32_t v;
       
   218     v = g364fb_ctrl_readb(opaque, addr);
       
   219     v |= g364fb_ctrl_readb(opaque, addr + 1) << 8;
       
   220     return v;
       
   221 }
       
   222 
       
   223 static uint32_t g364fb_ctrl_readl(void *opaque, target_phys_addr_t addr)
       
   224 {
       
   225     uint32_t v;
       
   226     v = g364fb_ctrl_readb(opaque, addr);
       
   227     v |= g364fb_ctrl_readb(opaque, addr + 1) << 8;
       
   228     v |= g364fb_ctrl_readb(opaque, addr + 2) << 16;
       
   229     v |= g364fb_ctrl_readb(opaque, addr + 3) << 24;
       
   230     return v;
       
   231 }
       
   232 
       
   233 static void g364fb_ctrl_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
       
   234 {
       
   235     G364State *s = opaque;
       
   236 
       
   237     addr &= 0xffff;
       
   238 
       
   239 #ifdef DEBUG_G364
       
   240     printf("g364fb/ctrl: write 0x%02x at [" TARGET_FMT_lx "]\n", val, addr);
       
   241 #endif
       
   242 
       
   243     if (addr < 0x0800) {
       
   244         /* color palette */
       
   245         int idx = addr >> 3;
       
   246         int c = addr & 7;
       
   247         if (c < 3)
       
   248             s->palette[idx][c] = (uint8_t)val;
       
   249     } else {
       
   250         switch (addr) {
       
   251             case REG_DISPLAYX:
       
   252                 s->scr_width = (s->scr_width & 0xfffffc03) | (val << 2);
       
   253                 break;
       
   254             case REG_DISPLAYX + 1:
       
   255                 s->scr_width = (s->scr_width & 0xfffc03ff) | (val << 10);
       
   256                 break;
       
   257             case REG_DISPLAYY:
       
   258                 s->scr_height = (s->scr_height & 0xffffff80) | (val >> 1);
       
   259                 break;
       
   260             case REG_DISPLAYY + 1:
       
   261                 s->scr_height = (s->scr_height & 0xffff801f) | (val << 7);
       
   262                 break;
       
   263             default:
       
   264 #ifdef DEBUG_G364
       
   265                 printf("g364fb/ctrl: invalid write of 0x%02x at [" TARGET_FMT_lx "]\n", val, addr);
       
   266 #endif
       
   267                 break;
       
   268         }
       
   269     }
       
   270     s->graphic_mode = -1; /* force full update */
       
   271 }
       
   272 
       
   273 static void g364fb_ctrl_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
       
   274 {
       
   275     g364fb_ctrl_writeb(opaque, addr, val & 0xff);
       
   276     g364fb_ctrl_writeb(opaque, addr + 1, (val >> 8) & 0xff);
       
   277 }
       
   278 
       
   279 static void g364fb_ctrl_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
       
   280 {
       
   281     g364fb_ctrl_writeb(opaque, addr, val & 0xff);
       
   282     g364fb_ctrl_writeb(opaque, addr + 1, (val >> 8) & 0xff);
       
   283     g364fb_ctrl_writeb(opaque, addr + 2, (val >> 16) & 0xff);
       
   284     g364fb_ctrl_writeb(opaque, addr + 3, (val >> 24) & 0xff);
       
   285 }
       
   286 
       
   287 static CPUReadMemoryFunc *g364fb_ctrl_read[3] = {
       
   288     g364fb_ctrl_readb,
       
   289     g364fb_ctrl_readw,
       
   290     g364fb_ctrl_readl,
       
   291 };
       
   292 
       
   293 static CPUWriteMemoryFunc *g364fb_ctrl_write[3] = {
       
   294     g364fb_ctrl_writeb,
       
   295     g364fb_ctrl_writew,
       
   296     g364fb_ctrl_writel,
       
   297 };
       
   298 
       
   299 /* called for accesses to video ram */
       
   300 static uint32_t g364fb_mem_readb(void *opaque, target_phys_addr_t addr)
       
   301 {
       
   302     G364State *s = opaque;
       
   303 
       
   304     return s->vram_buffer[addr];
       
   305 }
       
   306 
       
   307 static uint32_t g364fb_mem_readw(void *opaque, target_phys_addr_t addr)
       
   308 {
       
   309     uint32_t v;
       
   310     v = g364fb_mem_readb(opaque, addr);
       
   311     v |= g364fb_mem_readb(opaque, addr + 1) << 8;
       
   312     return v;
       
   313 }
       
   314 
       
   315 static uint32_t g364fb_mem_readl(void *opaque, target_phys_addr_t addr)
       
   316 {
       
   317     uint32_t v;
       
   318     v = g364fb_mem_readb(opaque, addr);
       
   319     v |= g364fb_mem_readb(opaque, addr + 1) << 8;
       
   320     v |= g364fb_mem_readb(opaque, addr + 2) << 16;
       
   321     v |= g364fb_mem_readb(opaque, addr + 3) << 24;
       
   322     return v;
       
   323 }
       
   324 
       
   325 static void g364fb_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
       
   326 {
       
   327     G364State *s = opaque;
       
   328 
       
   329     s->vram_buffer[addr] = val;
       
   330 }
       
   331 
       
   332 static void g364fb_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
       
   333 {
       
   334     g364fb_mem_writeb(opaque, addr, val & 0xff);
       
   335     g364fb_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
       
   336 }
       
   337 
       
   338 static void g364fb_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
       
   339 {
       
   340     g364fb_mem_writeb(opaque, addr, val & 0xff);
       
   341     g364fb_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
       
   342     g364fb_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
       
   343     g364fb_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
       
   344 }
       
   345 
       
   346 static CPUReadMemoryFunc *g364fb_mem_read[3] = {
       
   347     g364fb_mem_readb,
       
   348     g364fb_mem_readw,
       
   349     g364fb_mem_readl,
       
   350 };
       
   351 
       
   352 static CPUWriteMemoryFunc *g364fb_mem_write[3] = {
       
   353     g364fb_mem_writeb,
       
   354     g364fb_mem_writew,
       
   355     g364fb_mem_writel,
       
   356 };
       
   357 
       
   358 int g364fb_mm_init(DisplayState *ds,
       
   359                    int vram_size, int it_shift,
       
   360                    target_phys_addr_t vram_base, target_phys_addr_t ctrl_base)
       
   361 {
       
   362     G364State *s;
       
   363     int io_vram, io_ctrl;
       
   364 
       
   365     s = qemu_mallocz(sizeof(G364State));
       
   366     if (!s)
       
   367         return -1;
       
   368 
       
   369     s->vram_size = vram_size;
       
   370     s->vram_buffer = qemu_mallocz(s->vram_size);
       
   371 
       
   372     qemu_register_reset(g364fb_reset, s);
       
   373     g364fb_reset(s);
       
   374 
       
   375     s->ds = ds;
       
   376 
       
   377     s->console = graphic_console_init(ds, g364fb_update_display,
       
   378                                       g364fb_invalidate_display,
       
   379                                       g364fb_screen_dump, NULL, s);
       
   380 
       
   381     io_vram = cpu_register_io_memory(0, g364fb_mem_read, g364fb_mem_write, s);
       
   382     cpu_register_physical_memory(vram_base, vram_size, io_vram);
       
   383 
       
   384     io_ctrl = cpu_register_io_memory(0, g364fb_ctrl_read, g364fb_ctrl_write, s);
       
   385     cpu_register_physical_memory(ctrl_base, 0x10000, io_ctrl);
       
   386 
       
   387     return 0;
       
   388 }