OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [or1ksim/] [peripheral/] [vga.c] - Blame information for rev 1780

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 261 markom
/* vga.c -- Definition of types and structures for VGA/LCD
2 1748 jeremybenn
 
3 261 markom
   Copyright (C) 2001 Marko Mlinar, markom@opencores.org
4 1748 jeremybenn
   Copyright (C) 2008 Embecosm Limited
5 261 markom
 
6 1748 jeremybenn
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
7 261 markom
 
8 1748 jeremybenn
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
9 261 markom
 
10 1748 jeremybenn
   This program is free software; you can redistribute it and/or modify it
11
   under the terms of the GNU General Public License as published by the Free
12
   Software Foundation; either version 3 of the License, or (at your option)
13
   any later version.
14 261 markom
 
15 1748 jeremybenn
   This program is distributed in the hope that it will be useful, but WITHOUT
16
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18
   more details.
19 261 markom
 
20 1748 jeremybenn
   You should have received a copy of the GNU General Public License along
21
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
22 1350 nogj
 
23 1748 jeremybenn
/* This program is commented throughout in a fashion suitable for processing
24
   with Doxygen. */
25
 
26
 
27
/* Autoconf and/or portability configuration */
28 1350 nogj
#include "config.h"
29 1748 jeremybenn
#include "port.h"
30 1350 nogj
 
31 1748 jeremybenn
/* System includes */
32
#include <stdlib.h>
33
#include <stdio.h>
34 1350 nogj
 
35 1748 jeremybenn
/* Package includes */
36 1350 nogj
#include "arch.h"
37 645 markom
#include "sim-config.h"
38
#include "abstract.h"
39 805 markom
#include "sched.h"
40 1748 jeremybenn
#include "toplevel-support.h"
41 645 markom
 
42 1748 jeremybenn
 
43
#define VGA_CTRL        0x00    /* Control Register */
44
#define VGA_STAT        0x04    /* Status Register */
45
#define VGA_HTIM        0x08    /* Horizontal Timing Register */
46
#define VGA_VTIM        0x0c    /* Vertical Timing Register */
47
#define VGA_HVLEN       0x10    /* Horizontal and Vertical Length Register */
48
#define VGA_VBARA       0x14    /* Video Memory Base Address Register A */
49
#define VGA_VBARB       0x18    /* Video Memory Base Address Register B */
50
#define VGA_CLUTA       0x800
51
#define VGA_CLUTB       0xc00
52
#define VGA_MASK        0xfff
53
#define VGA_ADDR_SPACE  1024
54
 
55
 
56
/* List of implemented registers; all other are ignored.  */
57
 
58
/* Control Register */
59
#define VGA_CTRL_VEN    0x00000001      /* Video Enable */
60
#define VGA_CTRL_CD     0x00000300      /* Color Depth */
61
#define VGA_CTRL_PC     0x00000400      /* Pseudo Color */
62
 
63
/* Status Register */
64
/* Horiz. Timing Register */
65
/* Vert. Timing Register */
66
/* Horiz. and Vert. Length Register */
67
 
68 645 markom
/* When this counter reaches config.vgas[].refresh_rate, a screenshot is taken and outputted */
69 1748 jeremybenn
struct vga_state
70
{
71 1461 nogj
  int enabled;
72 645 markom
  int pics;
73
  unsigned long ctrl, stat, htim, vtim;
74
  int vbindex;
75
  unsigned long vbar[2];
76
  unsigned hlen, vlen;
77
  int pindex;
78
  unsigned long palette[2][256];
79 1368 nogj
  oraddr_t baseaddr;
80
  int refresh_rate;
81
  int irq;
82
  char *filename;
83
};
84 645 markom
 
85
 
86
/* Write a register */
87 1748 jeremybenn
void
88
vga_write32 (oraddr_t addr, uint32_t value, void *dat)
89 645 markom
{
90 1368 nogj
  struct vga_state *vga = dat;
91 645 markom
 
92 1748 jeremybenn
  switch (addr)
93
    {
94
    case VGA_CTRL:
95
      vga->ctrl = value;
96
      break;
97
    case VGA_STAT:
98
      vga->stat = value;
99
      break;
100
    case VGA_HTIM:
101
      vga->htim = value;
102
      break;
103
    case VGA_VTIM:
104
      vga->vtim = value;
105
      break;
106
    case VGA_HVLEN:
107
      vga->hlen = (value >> 16) + 2;
108
      vga->hlen = (value & 0xffff) + 2;
109
      break;
110
    case VGA_VBARA:
111
      vga->vbar[0] = value;
112
      break;
113
    case VGA_VBARB:
114
      vga->vbar[1] = value;
115
      break;
116 645 markom
    default:
117 1748 jeremybenn
      if (addr >= VGA_CLUTA && addr < VGA_CLUTB)
118
        {
119
          vga->palette[0][addr - VGA_CLUTA] = value & 0x00ffffff;
120
        }
121
      else if (addr >= VGA_CLUTB)
122
        {
123
          vga->palette[1][addr - VGA_CLUTB] = value & 0x00ffffff;
124
        }
125
      else
126
        {
127
          fprintf (stderr,
128
                   "vga_write32( 0x%" PRIxADDR ", 0x%08" PRIx32
129
                   " ): Out of range\n", addr + vga->baseaddr, value);
130
          return;
131
        }
132 645 markom
      break;
133 1748 jeremybenn
    }
134 645 markom
}
135
 
136
/* Read a register */
137 1748 jeremybenn
uint32_t
138
vga_read32 (oraddr_t addr, void *dat)
139 645 markom
{
140 1368 nogj
  struct vga_state *vga = dat;
141 645 markom
 
142 1748 jeremybenn
  switch (addr)
143
    {
144
    case VGA_CTRL:
145
      return vga->ctrl;
146
    case VGA_STAT:
147
      return vga->stat;
148
    case VGA_HTIM:
149
      return vga->htim;
150
    case VGA_VTIM:
151
      return vga->vtim;
152
    case VGA_HVLEN:
153
      return ((vga->hlen - 2) << 16) | (vga->vlen - 2);
154
    case VGA_VBARA:
155
      return vga->vbar[0];
156
    case VGA_VBARB:
157
      return vga->vbar[1];
158 645 markom
    default:
159 1748 jeremybenn
      if (addr >= VGA_CLUTA && addr < VGA_CLUTB)
160
        {
161
          return vga->palette[0][addr - VGA_CLUTA];
162
        }
163
      else if (addr >= VGA_CLUTB)
164
        {
165
          return vga->palette[1][addr - VGA_CLUTB];
166
        }
167
      else
168
        {
169
          fprintf (stderr, "vga_read32( 0x%" PRIxADDR " ): Out of range\n",
170
                   addr);
171
          return 0;
172
        }
173 645 markom
      break;
174 1748 jeremybenn
    }
175 645 markom
  return 0;
176
}
177
 
178
/* This code will only work on little endian machines */
179
#ifdef __BIG_ENDIAN__
180 1748 jeremybenn
#warning Image dump not supported on big endian machines
181 645 markom
 
182 1748 jeremybenn
static int
183
vga_dump_image (char *filename, struct vga_start *vga)
184 645 markom
{
185
  return 1;
186
}
187
 
188 1748 jeremybenn
#else
189 645 markom
 
190 1748 jeremybenn
typedef struct
191
{
192
  unsigned short int type;      /* Magic identifier            */
193
  unsigned int size;            /* File size in bytes          */
194
  unsigned short int reserved1, reserved2;
195
  unsigned int offset;          /* Offset to image data, bytes */
196 645 markom
} BMP_HEADER;
197
 
198 1748 jeremybenn
typedef struct
199
{
200
  unsigned int size;            /* Header size in bytes      */
201
  int width, height;            /* Width and height of image */
202
  unsigned short int planes;    /* Number of colour planes   */
203
  unsigned short int bits;      /* Bits per pixel            */
204
  unsigned int compression;     /* Compression type          */
205
  unsigned int imagesize;       /* Image size in bytes       */
206
  int xresolution, yresolution; /* Pixels per meter          */
207
  unsigned int ncolours;        /* Number of colours         */
208
  unsigned int importantcolours;        /* Important colours         */
209 645 markom
} INFOHEADER;
210
 
211
 
212
/* Dumps a bmp file, based on current image */
213 1748 jeremybenn
static int
214
vga_dump_image (char *filename, struct vga_state *vga)
215 645 markom
{
216 1368 nogj
  int sx = vga->hlen;
217
  int sy = vga->vlen;
218 1557 nogj
  int i, x = 0, y = 0;
219 1368 nogj
  int pc = vga->ctrl & VGA_CTRL_PC;
220
  int rbpp = vga->ctrl & VGA_CTRL_CD;
221 645 markom
  int bpp = rbpp >> 8;
222 1748 jeremybenn
 
223 645 markom
  BMP_HEADER bh;
224
  INFOHEADER ih;
225
  FILE *fo;
226
 
227 1748 jeremybenn
  if (!sx || !sy)
228
    return 1;
229 645 markom
 
230
  /* 16bpp and 32 bpp will be converted to 24bpp */
231 1748 jeremybenn
  if (bpp == 1 || bpp == 3)
232
    bpp = 2;
233
 
234
  bh.type = 19778;              /* BM */
235
  bh.size =
236
    sizeof (BMP_HEADER) + sizeof (INFOHEADER) + sx * sy * (bpp * 4 + 4) +
237
    (pc ? 1024 : 0);
238 645 markom
  bh.reserved1 = bh.reserved2 = 0;
239
  bh.offset = sizeof (BMP_HEADER) + sizeof (INFOHEADER) + (pc ? 1024 : 0);
240 1748 jeremybenn
 
241 645 markom
  ih.size = sizeof (INFOHEADER);
242 1748 jeremybenn
  ih.width = sx;
243
  ih.height = sy;
244
  ih.planes = 1;
245
  ih.bits = bpp * 4 + 4;
246
  ih.compression = 0;
247
  ih.imagesize = x * y * (bpp * 4 + 4);
248 645 markom
  ih.xresolution = ih.yresolution = 0;
249 1748 jeremybenn
  ih.ncolours = 0;               /* should be generated */
250
  ih.importantcolours = 0;       /* all are important */
251
 
252 645 markom
  fo = fopen (filename, "wb+");
253 1748 jeremybenn
  if (!fwrite (&bh, sizeof (BMP_HEADER), 1, fo))
254
    return 1;
255
  if (!fwrite (&ih, sizeof (INFOHEADER), 1, fo))
256
    return 1;
257
 
258
  if (pc)
259
    {                           /* Write palette? */
260
      for (i = 0; i < 256; i++)
261
        {
262
          unsigned long val, d;
263
          d = vga->palette[vga->pindex][i];
264
          val = (d >> 0) & 0xff; /* Blue */
265
          val |= (d >> 8) & 0xff;       /* Green */
266
          val |= (d >> 16) & 0xff;      /* Red */
267
          if (!fwrite (&val, sizeof (val), 1, fo))
268
            return 1;
269
        }
270 645 markom
    }
271 1748 jeremybenn
 
272 645 markom
  /* Data is stored upside down */
273 1748 jeremybenn
  for (y = sy - 1; y >= 0; y--)
274
    {
275
      int align = 4 - ((bpp + 1) * sx) % 4;
276
      int zero = 0;
277
      for (x = 0; x < sx; x++)
278
        {
279
          unsigned long pixel =
280
            eval_direct32 (vga->vbar[vga->vbindex] + (y * sx + x) * (bpp + 1),
281
                           0, 0);
282
          if (!fwrite (&pixel, sizeof (pixel), 1, fo))
283
            return 1;
284
        }
285
      if (!fwrite (&zero, align, 1, fo))
286
        return 1;
287 645 markom
    }
288 1748 jeremybenn
 
289 645 markom
  fclose (fo);
290
  return 0;
291
}
292
#endif /* !__BIG_ENDIAN__ */
293
 
294 1748 jeremybenn
void
295
vga_job (void *dat)
296 805 markom
{
297 1368 nogj
  struct vga_state *vga = dat;
298 805 markom
  /* dump the image? */
299
  char temp[STR_SIZE];
300 1368 nogj
  sprintf (temp, "%s%04i.bmp", vga->filename, vga->pics++);
301
  vga_dump_image (temp, vga);
302 1748 jeremybenn
 
303
  SCHED_ADD (vga_job, dat, vga->refresh_rate);
304 805 markom
}
305
 
306 645 markom
/* Reset all VGAs */
307 1748 jeremybenn
void
308
vga_reset (void *dat)
309 645 markom
{
310 1368 nogj
  struct vga_state *vga = dat;
311 645 markom
 
312 1368 nogj
  int i;
313 645 markom
 
314 1368 nogj
  /* Init palette */
315
  for (i = 0; i < 256; i++)
316
    vga->palette[0][i] = vga->palette[1][i] = 0;
317 645 markom
 
318 1368 nogj
  vga->ctrl = vga->stat = vga->htim = vga->vtim = 0;
319
  vga->hlen = vga->vlen = 0;
320
  vga->vbar[0] = vga->vbar[1] = 0;
321 1748 jeremybenn
 
322 1368 nogj
  /* Init screen dumping machine */
323
  vga->pics = 0;
324 645 markom
 
325 1368 nogj
  vga->pindex = 0;
326
  vga->vbindex = 0;
327
 
328 1748 jeremybenn
  SCHED_ADD (vga_job, dat, vga->refresh_rate);
329 645 markom
}
330 1358 nogj
 
331
/*----------------------------------------------------[ VGA Configuration ]---*/
332 1748 jeremybenn
static void
333
vga_enabled (union param_val val, void *dat)
334 1358 nogj
{
335 1368 nogj
  struct vga_state *vga = dat;
336 1748 jeremybenn
  vga->enabled = val.int_val;
337 1358 nogj
}
338
 
339 1748 jeremybenn
static void
340
vga_baseaddr (union param_val val, void *dat)
341 1358 nogj
{
342 1368 nogj
  struct vga_state *vga = dat;
343 1748 jeremybenn
  vga->baseaddr = val.addr_val;
344 1358 nogj
}
345
 
346 1748 jeremybenn
static void
347
vga_irq (union param_val val, void *dat)
348 1358 nogj
{
349 1368 nogj
  struct vga_state *vga = dat;
350 1748 jeremybenn
  vga->irq = val.int_val;
351 1358 nogj
}
352
 
353 1748 jeremybenn
static void
354
vga_refresh_rate (union param_val val, void *dat)
355 1358 nogj
{
356 1368 nogj
  struct vga_state *vga = dat;
357 1748 jeremybenn
  vga->refresh_rate = val.int_val;
358 1358 nogj
}
359
 
360 1748 jeremybenn
/*---------------------------------------------------------------------------*/
361
/*!Set the VGA output file
362
 
363
   Free any previously allocated value.
364
 
365
   @param[in] val  The value to use
366
   @param[in] dat  The config data structure                                 */
367
/*---------------------------------------------------------------------------*/
368
static void
369
vga_filename (union param_val  val,
370
              void            *dat)
371 1461 nogj
{
372
  struct vga_state *vga = dat;
373
 
374 1748 jeremybenn
  if (NULL != vga->filename)
375
    {
376
      free (vga->filename);
377
      vga->filename = NULL;
378
    }
379
 
380
  if (NULL == (vga->filename = strdup (val.str_val)))
381
    {
382
      fprintf (stderr, "ERROR: Out of memory\n");
383
      exit (-1);
384
    }
385
 
386
}       /* vga_filename() */
387
 
388
 
389
/*---------------------------------------------------------------------------*/
390
/*!Initialize a new VGA configuration
391
 
392
   ALL parameters are set explicitly to default values.                      */
393
/*---------------------------------------------------------------------------*/
394
static void *
395
vga_sec_start ()
396 1368 nogj
{
397 1748 jeremybenn
  struct vga_state *new = malloc (sizeof (struct vga_state));
398 1368 nogj
 
399 1748 jeremybenn
  if (!new)
400
    {
401
      fprintf (stderr, "Peripheral VGA: Run out of memory\n");
402
      exit (-1);
403
    }
404 1368 nogj
 
405 1748 jeremybenn
  new->enabled      = 1;
406
  new->baseaddr     = 0;
407
  new->irq          = 0;
408
  new->refresh_rate = 1000000000000ULL / 50ULL / config.sim.clkcycle_ps;
409
  new->filename     = strdup ("vga_out");
410 1368 nogj
 
411
  return new;
412
 
413 1748 jeremybenn
}       /* vga_sec_start() */
414
 
415
 
416
static void
417
vga_sec_end (void *dat)
418 1368 nogj
{
419
  struct vga_state *vga = dat;
420 1486 nogj
  struct mem_ops ops;
421 1748 jeremybenn
  if (!vga->enabled)
422
    {
423
      free (vga->filename);
424
      free (vga);
425
      return;
426
    }
427 1368 nogj
 
428 1748 jeremybenn
  memset (&ops, 0, sizeof (struct mem_ops));
429 1486 nogj
  ops.readfunc32 = vga_read32;
430
  ops.writefunc32 = vga_write32;
431
  ops.write_dat32 = dat;
432
  ops.read_dat32 = dat;
433
  /* FIXME: Correct delay? */
434
  ops.delayr = 2;
435
  ops.delayw = 2;
436 1748 jeremybenn
  reg_mem_area (vga->baseaddr, VGA_ADDR_SPACE, 0, &ops);
437
  reg_sim_reset (vga_reset, dat);
438
}
439 1486 nogj
 
440
 
441 1748 jeremybenn
/*---------------------------------------------------------------------------*/
442
/*!Create a new VGA configuration
443 1368 nogj
 
444 1748 jeremybenn
   ALL parameters are set explicitly to default values. Alternative naming for
445
   file parameter supported.                                                 */
446
/*---------------------------------------------------------------------------*/
447
void
448
reg_vga_sec ()
449 1358 nogj
{
450 1748 jeremybenn
  struct config_section *sec =
451
    reg_config_sec ("vga", vga_sec_start, vga_sec_end);
452 1358 nogj
 
453 1748 jeremybenn
  reg_config_param (sec, "baseaddr", paramt_addr, vga_baseaddr);
454
  reg_config_param (sec, "enabled", paramt_int, vga_enabled);
455
  reg_config_param (sec, "irq", paramt_int, vga_irq);
456
  reg_config_param (sec, "refresh_rate", paramt_int, vga_refresh_rate);
457
  reg_config_param (sec, "txfile", paramt_str, vga_filename);
458
  reg_config_param (sec, "filename", paramt_str, vga_filename);
459
 
460
}       /* reg_vga_sec() */
461
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.