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

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_2_0_rc2/] [or1ksim/] [peripheral/] [vga.c] - Diff between revs 1477 and 1484

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 1477 Rev 1484
/* vga.c -- Definition of types and structures for VGA/LCD
/* vga.c -- Definition of types and structures for VGA/LCD
   Copyright (C) 2001 Marko Mlinar, markom@opencores.org
   Copyright (C) 2001 Marko Mlinar, markom@opencores.org
 
 
This file is part of OpenRISC 1000 Architectural Simulator.
This file is part of OpenRISC 1000 Architectural Simulator.
 
 
This program is free software; you can redistribute it and/or modify
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
(at your option) any later version.
 
 
This program is distributed in the hope that it will be useful,
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public License for more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string.h>
 
 
#include "config.h"
#include "config.h"
 
 
#ifdef HAVE_INTTYPES_H
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#include <inttypes.h>
#endif
#endif
 
 
#include "port.h"
#include "port.h"
#include "arch.h"
#include "arch.h"
#include "sim-config.h"
#include "sim-config.h"
#include "vga.h"
#include "vga.h"
#include "abstract.h"
#include "abstract.h"
#include "sched.h"
#include "sched.h"
 
 
/* When this counter reaches config.vgas[].refresh_rate, a screenshot is taken and outputted */
/* When this counter reaches config.vgas[].refresh_rate, a screenshot is taken and outputted */
struct vga_state {
struct vga_state {
  int enabled;
  int enabled;
  int pics;
  int pics;
  unsigned long ctrl, stat, htim, vtim;
  unsigned long ctrl, stat, htim, vtim;
  int vbindex;
  int vbindex;
  unsigned long vbar[2];
  unsigned long vbar[2];
  unsigned hlen, vlen;
  unsigned hlen, vlen;
  int pindex;
  int pindex;
  unsigned long palette[2][256];
  unsigned long palette[2][256];
  oraddr_t baseaddr;
  oraddr_t baseaddr;
  int refresh_rate;
  int refresh_rate;
  int irq;
  int irq;
  char *filename;
  char *filename;
};
};
 
 
 
 
/* Write a register */
/* Write a register */
void vga_write32(oraddr_t addr, uint32_t value, void *dat)
void vga_write32(oraddr_t addr, uint32_t value, void *dat)
{
{
  struct vga_state *vga = dat;
  struct vga_state *vga = dat;
 
 
  addr -= vga->baseaddr;
  addr -= vga->baseaddr;
 
 
  switch (addr) {
  switch (addr) {
    case VGA_CTRL:  vga->ctrl = value; break;
    case VGA_CTRL:  vga->ctrl = value; break;
    case VGA_STAT:  vga->stat = value; break;
    case VGA_STAT:  vga->stat = value; break;
    case VGA_HTIM:  vga->htim = value; break;
    case VGA_HTIM:  vga->htim = value; break;
    case VGA_VTIM:  vga->vtim = value; break;
    case VGA_VTIM:  vga->vtim = value; break;
    case VGA_HVLEN: vga->hlen = (value >> 16) + 2; vga->hlen = (value & 0xffff) + 2; break;
    case VGA_HVLEN: vga->hlen = (value >> 16) + 2; vga->hlen = (value & 0xffff) + 2; break;
    case VGA_VBARA: vga->vbar[0] = value; break;
    case VGA_VBARA: vga->vbar[0] = value; break;
    case VGA_VBARB: vga->vbar[1] = value; break;
    case VGA_VBARB: vga->vbar[1] = value; break;
    default:
    default:
      if (addr >= VGA_CLUTA && addr < VGA_CLUTB) {
      if (addr >= VGA_CLUTA && addr < VGA_CLUTB) {
        vga->palette[0][addr - VGA_CLUTA] = value & 0x00ffffff;
        vga->palette[0][addr - VGA_CLUTA] = value & 0x00ffffff;
      } else if (addr >= VGA_CLUTB) {
      } else if (addr >= VGA_CLUTB) {
        vga->palette[1][addr - VGA_CLUTB] = value & 0x00ffffff;
        vga->palette[1][addr - VGA_CLUTB] = value & 0x00ffffff;
      } else {
      } else {
        fprintf( stderr, "vga_write32( 0x%"PRIxADDR", 0x%08"PRIx32" ): Out of range\n", addr + vga->baseaddr, value);
        fprintf( stderr, "vga_write32( 0x%"PRIxADDR", 0x%08"PRIx32" ): Out of range\n", addr + vga->baseaddr, value);
        return;
        return;
      }
      }
      break;
      break;
  }
  }
}
}
 
 
/* Read a register */
/* Read a register */
uint32_t vga_read32(oraddr_t addr, void *dat)
uint32_t vga_read32(oraddr_t addr, void *dat)
{
{
  struct vga_state *vga = dat;
  struct vga_state *vga = dat;
 
 
  addr -= vga->baseaddr;
  addr -= vga->baseaddr;
 
 
  switch (addr) {
  switch (addr) {
    case VGA_CTRL:  return vga->ctrl;
    case VGA_CTRL:  return vga->ctrl;
    case VGA_STAT:  return vga->stat;
    case VGA_STAT:  return vga->stat;
    case VGA_HTIM:  return vga->htim;
    case VGA_HTIM:  return vga->htim;
    case VGA_VTIM:  return vga->vtim;
    case VGA_VTIM:  return vga->vtim;
    case VGA_HVLEN: return ((vga->hlen - 2) << 16) | (vga->vlen - 2);
    case VGA_HVLEN: return ((vga->hlen - 2) << 16) | (vga->vlen - 2);
    case VGA_VBARA: return vga->vbar[0];
    case VGA_VBARA: return vga->vbar[0];
    case VGA_VBARB: return vga->vbar[1];
    case VGA_VBARB: return vga->vbar[1];
    default:
    default:
      if (addr >= VGA_CLUTA && addr < VGA_CLUTB) {
      if (addr >= VGA_CLUTA && addr < VGA_CLUTB) {
        return vga->palette[0][addr - VGA_CLUTA];
        return vga->palette[0][addr - VGA_CLUTA];
      } else if (addr >= VGA_CLUTB) {
      } else if (addr >= VGA_CLUTB) {
        return vga->palette[1][addr - VGA_CLUTB];
        return vga->palette[1][addr - VGA_CLUTB];
      } else {
      } else {
        fprintf( stderr, "vga_read32( 0x%"PRIxADDR" ): Out of range\n", addr);
        fprintf( stderr, "vga_read32( 0x%"PRIxADDR" ): Out of range\n", addr);
        return 0;
        return 0;
      }
      }
      break;
      break;
  }
  }
  return 0;
  return 0;
}
}
 
 
/* This code will only work on little endian machines */
/* This code will only work on little endian machines */
#ifdef __BIG_ENDIAN__
#ifdef __BIG_ENDIAN__
#warning Image dump not supported on big endian machines 
#warning Image dump not supported on big endian machines 
 
 
static int vga_dump_image (char *filename, struct vga_start *vga)
static int vga_dump_image (char *filename, struct vga_start *vga)
{
{
  return 1;
  return 1;
}
}
 
 
#else 
#else 
 
 
typedef struct {
typedef struct {
   unsigned short int type;                 /* Magic identifier            */
   unsigned short int type;                 /* Magic identifier            */
   unsigned int size;                       /* File size in bytes          */
   unsigned int size;                       /* File size in bytes          */
   unsigned short int reserved1, reserved2;
   unsigned short int reserved1, reserved2;
   unsigned int offset;                     /* Offset to image data, bytes */
   unsigned int offset;                     /* Offset to image data, bytes */
} BMP_HEADER;
} BMP_HEADER;
 
 
typedef struct {
typedef struct {
   unsigned int size;               /* Header size in bytes      */
   unsigned int size;               /* Header size in bytes      */
   int width,height;                /* Width and height of image */
   int width,height;                /* Width and height of image */
   unsigned short int planes;       /* Number of colour planes   */
   unsigned short int planes;       /* Number of colour planes   */
   unsigned short int bits;         /* Bits per pixel            */
   unsigned short int bits;         /* Bits per pixel            */
   unsigned int compression;        /* Compression type          */
   unsigned int compression;        /* Compression type          */
   unsigned int imagesize;          /* Image size in bytes       */
   unsigned int imagesize;          /* Image size in bytes       */
   int xresolution,yresolution;     /* Pixels per meter          */
   int xresolution,yresolution;     /* Pixels per meter          */
   unsigned int ncolours;           /* Number of colours         */
   unsigned int ncolours;           /* Number of colours         */
   unsigned int importantcolours;   /* Important colours         */
   unsigned int importantcolours;   /* Important colours         */
} INFOHEADER;
} INFOHEADER;
 
 
 
 
/* Dumps a bmp file, based on current image */
/* Dumps a bmp file, based on current image */
static int vga_dump_image (char *filename, struct vga_state *vga)
static int vga_dump_image (char *filename, struct vga_state *vga)
{
{
  int sx = vga->hlen;
  int sx = vga->hlen;
  int sy = vga->vlen;
  int sy = vga->vlen;
  int i, x, y;
  int i, x, y;
  int pc = vga->ctrl & VGA_CTRL_PC;
  int pc = vga->ctrl & VGA_CTRL_PC;
  int rbpp = vga->ctrl & VGA_CTRL_CD;
  int rbpp = vga->ctrl & VGA_CTRL_CD;
  int bpp = rbpp >> 8;
  int bpp = rbpp >> 8;
 
 
  BMP_HEADER bh;
  BMP_HEADER bh;
  INFOHEADER ih;
  INFOHEADER ih;
  FILE *fo;
  FILE *fo;
 
 
  if (!sx || !sy) return 1;
  if (!sx || !sy) return 1;
 
 
  /* 16bpp and 32 bpp will be converted to 24bpp */
  /* 16bpp and 32 bpp will be converted to 24bpp */
  if (bpp == 1 || bpp == 3) bpp = 2;
  if (bpp == 1 || bpp == 3) bpp = 2;
 
 
  bh.type = 19778; /* BM */
  bh.type = 19778; /* BM */
  bh.size = sizeof (BMP_HEADER) + sizeof (INFOHEADER) + sx * sy * (bpp * 4 + 4) + (pc ? 1024 : 0);
  bh.size = sizeof (BMP_HEADER) + sizeof (INFOHEADER) + sx * sy * (bpp * 4 + 4) + (pc ? 1024 : 0);
  bh.reserved1 = bh.reserved2 = 0;
  bh.reserved1 = bh.reserved2 = 0;
  bh.offset = sizeof (BMP_HEADER) + sizeof (INFOHEADER) + (pc ? 1024 : 0);
  bh.offset = sizeof (BMP_HEADER) + sizeof (INFOHEADER) + (pc ? 1024 : 0);
 
 
  ih.size = sizeof (INFOHEADER);
  ih.size = sizeof (INFOHEADER);
  ih.width = sx; ih.height = sy;
  ih.width = sx; ih.height = sy;
  ih.planes = 1; ih.bits = bpp * 4 + 4;
  ih.planes = 1; ih.bits = bpp * 4 + 4;
  ih.compression = 0; ih.imagesize = x * y * (bpp * 4 + 4);
  ih.compression = 0; ih.imagesize = x * y * (bpp * 4 + 4);
  ih.xresolution = ih.yresolution = 0;
  ih.xresolution = ih.yresolution = 0;
  ih.ncolours = 0; /* should be generated */
  ih.ncolours = 0; /* should be generated */
  ih.importantcolours = 0; /* all are important */
  ih.importantcolours = 0; /* all are important */
 
 
  fo = fopen (filename, "wb+");
  fo = fopen (filename, "wb+");
  if (!fwrite (&bh, sizeof (BMP_HEADER), 1, fo)) return 1;
  if (!fwrite (&bh, sizeof (BMP_HEADER), 1, fo)) return 1;
  if (!fwrite (&ih, sizeof (INFOHEADER), 1, fo)) return 1;
  if (!fwrite (&ih, sizeof (INFOHEADER), 1, fo)) return 1;
 
 
  if (pc) { /* Write palette? */
  if (pc) { /* Write palette? */
    for (i = 0; i < 256; i++) {
    for (i = 0; i < 256; i++) {
      unsigned long val, d;
      unsigned long val, d;
      d = vga->palette[vga->pindex][i];
      d = vga->palette[vga->pindex][i];
      val = (d >> 0) & 0xff;   /* Blue */
      val = (d >> 0) & 0xff;   /* Blue */
      val |= (d >> 8) & 0xff;  /* Green */
      val |= (d >> 8) & 0xff;  /* Green */
      val |= (d >> 16) & 0xff; /* Red */
      val |= (d >> 16) & 0xff; /* Red */
      if (!fwrite (&val, sizeof (val), 1, fo)) return 1;
      if (!fwrite (&val, sizeof (val), 1, fo)) return 1;
    }
    }
  }
  }
 
 
  /* Data is stored upside down */
  /* Data is stored upside down */
  for (y = sy - 1; y >= 0; y--) {
  for (y = sy - 1; y >= 0; y--) {
    int align = 4 - ((bpp + 1) * sx) % 4;
    int align = 4 - ((bpp + 1) * sx) % 4;
    int zero = 0;
    int zero = 0;
    for (x = 0; x < sx; x++) {
    for (x = 0; x < sx; x++) {
      unsigned long pixel = evalsim_mem32 (vga->vbar[vga->vbindex] + (y * sx + x) * (bpp + 1));
      int breakpoint;
 
      unsigned long pixel = eval_direct32 (vga->vbar[vga->vbindex] + (y * sx + x) * (bpp + 1), &breakpoint, 0, 0);
      if (!fwrite (&pixel, sizeof (pixel), 1, fo)) return 1;
      if (!fwrite (&pixel, sizeof (pixel), 1, fo)) return 1;
    }
    }
    if (!fwrite (&zero, align, 1, fo)) return 1;
    if (!fwrite (&zero, align, 1, fo)) return 1;
  }
  }
 
 
  fclose (fo);
  fclose (fo);
  return 0;
  return 0;
}
}
#endif /* !__BIG_ENDIAN__ */
#endif /* !__BIG_ENDIAN__ */
 
 
void vga_job (void *dat)
void vga_job (void *dat)
{
{
  struct vga_state *vga = dat;
  struct vga_state *vga = dat;
  /* dump the image? */
  /* dump the image? */
  char temp[STR_SIZE];
  char temp[STR_SIZE];
  sprintf (temp, "%s%04i.bmp", vga->filename, vga->pics++);
  sprintf (temp, "%s%04i.bmp", vga->filename, vga->pics++);
  vga_dump_image (temp, vga);
  vga_dump_image (temp, vga);
 
 
  SCHED_ADD(vga_job, dat, vga->refresh_rate);
  SCHED_ADD(vga_job, dat, vga->refresh_rate);
}
}
 
 
/* Reset all VGAs */
/* Reset all VGAs */
void vga_reset (void *dat)
void vga_reset (void *dat)
{
{
  struct vga_state *vga = dat;
  struct vga_state *vga = dat;
 
 
  int i;
  int i;
 
 
  /* Init palette */
  /* Init palette */
  for (i = 0; i < 256; i++)
  for (i = 0; i < 256; i++)
    vga->palette[0][i] = vga->palette[1][i] = 0;
    vga->palette[0][i] = vga->palette[1][i] = 0;
 
 
  vga->ctrl = vga->stat = vga->htim = vga->vtim = 0;
  vga->ctrl = vga->stat = vga->htim = vga->vtim = 0;
  vga->hlen = vga->vlen = 0;
  vga->hlen = vga->vlen = 0;
  vga->vbar[0] = vga->vbar[1] = 0;
  vga->vbar[0] = vga->vbar[1] = 0;
 
 
  /* Init screen dumping machine */
  /* Init screen dumping machine */
  vga->pics = 0;
  vga->pics = 0;
 
 
  vga->pindex = 0;
  vga->pindex = 0;
  vga->vbindex = 0;
  vga->vbindex = 0;
 
 
  SCHED_ADD(vga_job, dat, vga->refresh_rate);
  SCHED_ADD(vga_job, dat, vga->refresh_rate);
}
}
 
 
/*----------------------------------------------------[ VGA Configuration ]---*/
/*----------------------------------------------------[ VGA Configuration ]---*/
void vga_baseaddr(union param_val val, void *dat)
void vga_baseaddr(union param_val val, void *dat)
{
{
  struct vga_state *vga = dat;
  struct vga_state *vga = dat;
  vga->baseaddr = val.addr_val;
  vga->baseaddr = val.addr_val;
}
}
 
 
void vga_irq(union param_val val, void *dat)
void vga_irq(union param_val val, void *dat)
{
{
  struct vga_state *vga = dat;
  struct vga_state *vga = dat;
  vga->irq = val.int_val;
  vga->irq = val.int_val;
}
}
 
 
void vga_refresh_rate(union param_val val, void *dat)
void vga_refresh_rate(union param_val val, void *dat)
{
{
  struct vga_state *vga = dat;
  struct vga_state *vga = dat;
  vga->refresh_rate = val.int_val;
  vga->refresh_rate = val.int_val;
}
}
 
 
void vga_filename(union param_val val, void *dat)
void vga_filename(union param_val val, void *dat)
{
{
  struct vga_state *vga = dat;
  struct vga_state *vga = dat;
  if(!(vga->filename = strdup (val.str_val)));
  if(!(vga->filename = strdup (val.str_val)));
}
}
 
 
void vga_enabled(union param_val val, void *dat)
void vga_enabled(union param_val val, void *dat)
{
{
  struct vga_state *vga = dat;
  struct vga_state *vga = dat;
  vga->enabled = val.int_val;
  vga->enabled = val.int_val;
}
}
 
 
void *vga_sec_start(void)
void *vga_sec_start(void)
{
{
  struct vga_state *new = malloc(sizeof(struct vga_state));
  struct vga_state *new = malloc(sizeof(struct vga_state));
 
 
  if(!new) {
  if(!new) {
    fprintf(stderr, "Peripheral VGA: Run out of memory\n");
    fprintf(stderr, "Peripheral VGA: Run out of memory\n");
    exit(-1);
    exit(-1);
  }
  }
 
 
  new->baseaddr = 0;
  new->baseaddr = 0;
  new->enabled = 1;
  new->enabled = 1;
 
 
  return new;
  return new;
}
}
 
 
void vga_sec_end(void *dat)
void vga_sec_end(void *dat)
{
{
  struct vga_state *vga = dat;
  struct vga_state *vga = dat;
 
 
  if(!vga->enabled) {
  if(!vga->enabled) {
    free(dat);
    free(dat);
    return;
    return;
  }
  }
 
 
  if (vga->baseaddr)
  if (vga->baseaddr)
    register_memoryarea(vga->baseaddr, VGA_ADDR_SPACE, 4, 0, vga_read32, vga_write32, dat);
    register_memoryarea(vga->baseaddr, VGA_ADDR_SPACE, 4, 0, vga_read32, vga_write32, dat);
 
 
  reg_sim_reset(vga_reset, dat);
  reg_sim_reset(vga_reset, dat);
}
}
 
 
void reg_vga_sec(void)
void reg_vga_sec(void)
{
{
  struct config_section *sec = reg_config_sec("vga", vga_sec_start, vga_sec_end);
  struct config_section *sec = reg_config_sec("vga", vga_sec_start, vga_sec_end);
 
 
  reg_config_param(sec, "baseaddr", paramt_addr, vga_baseaddr);
  reg_config_param(sec, "baseaddr", paramt_addr, vga_baseaddr);
  reg_config_param(sec, "enabled", paramt_int, vga_enabled);
  reg_config_param(sec, "enabled", paramt_int, vga_enabled);
  reg_config_param(sec, "irq", paramt_int, vga_irq);
  reg_config_param(sec, "irq", paramt_int, vga_irq);
  reg_config_param(sec, "refresh_rate", paramt_int, vga_refresh_rate);
  reg_config_param(sec, "refresh_rate", paramt_int, vga_refresh_rate);
  reg_config_param(sec, "filename", paramt_str, vga_filename);
  reg_config_param(sec, "filename", paramt_str, vga_filename);
}
}
 
 

powered by: WebSVN 2.1.0

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