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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_49/] [or1ksim/] [peripheral/] [vga.c] - Diff between revs 1350 and 1358

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

Rev 1350 Rev 1358
/* 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 "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 */
static struct {
static struct {
  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];
} vga[MAX_VGAS];
} vga[MAX_VGAS];
 
 
 
 
/* Write a register */
/* Write a register */
void vga_write32(oraddr_t addr, uint32_t value)
void vga_write32(oraddr_t addr, uint32_t value)
{
{
  int i, found = -1;
  int i, found = -1;
 
 
  /* Find which controller this is */
  /* Find which controller this is */
  for (i = 0; i < config.nvgas; i++ ) {
  for (i = 0; i < config.nvgas; i++ ) {
    if ((addr >= config.vgas[i].baseaddr) && (addr < config.vgas[i].baseaddr + VGA_ADDR_SPACE)) {
    if ((addr >= config.vgas[i].baseaddr) && (addr < config.vgas[i].baseaddr + VGA_ADDR_SPACE)) {
      found = i;
      found = i;
      break;
      break;
    }
    }
  }
  }
 
 
  if (found < 0) {
  if (found < 0) {
    fprintf( stderr, "vga_write32( 0x%"PRIxADDR" ): Out of range\n", addr);
    fprintf( stderr, "vga_write32( 0x%"PRIxADDR" ): Out of range\n", addr);
    runtime.sim.cont_run = 0;
    runtime.sim.cont_run = 0;
    return;
    return;
  }
  }
 
 
  addr -= config.vgas[found].baseaddr;
  addr -= config.vgas[found].baseaddr;
 
 
  switch (addr) {
  switch (addr) {
    case VGA_CTRL:  vga[found].ctrl = value; break;
    case VGA_CTRL:  vga[found].ctrl = value; break;
    case VGA_STAT:  vga[found].stat = value; break;
    case VGA_STAT:  vga[found].stat = value; break;
    case VGA_HTIM:  vga[found].htim = value; break;
    case VGA_HTIM:  vga[found].htim = value; break;
    case VGA_VTIM:  vga[found].vtim = value; break;
    case VGA_VTIM:  vga[found].vtim = value; break;
    case VGA_HVLEN: vga[found].hlen = (value >> 16) + 2; vga[found].hlen = (value & 0xffff) + 2; break;
    case VGA_HVLEN: vga[found].hlen = (value >> 16) + 2; vga[found].hlen = (value & 0xffff) + 2; break;
    case VGA_VBARA: vga[found].vbar[0] = value; break;
    case VGA_VBARA: vga[found].vbar[0] = value; break;
    case VGA_VBARB: vga[found].vbar[1] = value; break;
    case VGA_VBARB: vga[found].vbar[1] = value; break;
    default:
    default:
      if (addr >= VGA_CLUTA && addr < VGA_CLUTB) {
      if (addr >= VGA_CLUTA && addr < VGA_CLUTB) {
        vga[found].palette[0][addr - VGA_CLUTA] = value & 0x00ffffff;
        vga[found].palette[0][addr - VGA_CLUTA] = value & 0x00ffffff;
      } else if (addr >= VGA_CLUTB) {
      } else if (addr >= VGA_CLUTB) {
        vga[found].palette[1][addr - VGA_CLUTB] = value & 0x00ffffff;
        vga[found].palette[1][addr - VGA_CLUTB] = value & 0x00ffffff;
      } else {
      } else {
        fprintf( stderr, "vga_write32( 0x%"PRIxADDR", 0x%08"PRIx32" ): Out of range\n", addr + config.vgas[found].baseaddr, value);
        fprintf( stderr, "vga_write32( 0x%"PRIxADDR", 0x%08"PRIx32" ): Out of range\n", addr + config.vgas[found].baseaddr, value);
        runtime.sim.cont_run = 0;
        runtime.sim.cont_run = 0;
        return;
        return;
      }
      }
      break;
      break;
  }
  }
}
}
 
 
/* Read a register */
/* Read a register */
uint32_t vga_read32(oraddr_t addr)
uint32_t vga_read32(oraddr_t addr)
{
{
  int i, found = -1;
  int i, found = -1;
 
 
  /* Find which controller this is */
  /* Find which controller this is */
  for (i = 0; i < config.nvgas; i++ ) {
  for (i = 0; i < config.nvgas; i++ ) {
    if ((addr >= config.vgas[i].baseaddr) && (addr < config.vgas[i].baseaddr + VGA_ADDR_SPACE)) {
    if ((addr >= config.vgas[i].baseaddr) && (addr < config.vgas[i].baseaddr + VGA_ADDR_SPACE)) {
      found = i;
      found = i;
      break;
      break;
    }
    }
  }
  }
 
 
  if (found < 0) {
  if (found < 0) {
    fprintf( stderr, "vga_read32( 0x%"PRIxADDR" ): Out of range\n", addr);
    fprintf( stderr, "vga_read32( 0x%"PRIxADDR" ): Out of range\n", addr);
    runtime.sim.cont_run = 0;
    runtime.sim.cont_run = 0;
    return 0;
    return 0;
  }
  }
 
 
  addr -= config.vgas[found].baseaddr;
  addr -= config.vgas[found].baseaddr;
 
 
  switch (addr) {
  switch (addr) {
    case VGA_CTRL:  return vga[found].ctrl;
    case VGA_CTRL:  return vga[found].ctrl;
    case VGA_STAT:  return vga[found].stat;
    case VGA_STAT:  return vga[found].stat;
    case VGA_HTIM:  return vga[found].htim;
    case VGA_HTIM:  return vga[found].htim;
    case VGA_VTIM:  return vga[found].vtim;
    case VGA_VTIM:  return vga[found].vtim;
    case VGA_HVLEN: return ((vga[found].hlen - 2) << 16) | (vga[found].vlen - 2);
    case VGA_HVLEN: return ((vga[found].hlen - 2) << 16) | (vga[found].vlen - 2);
    case VGA_VBARA: return vga[found].vbar[0];
    case VGA_VBARA: return vga[found].vbar[0];
    case VGA_VBARB: return vga[found].vbar[1];
    case VGA_VBARB: return vga[found].vbar[1];
    default:
    default:
      if (addr >= VGA_CLUTA && addr < VGA_CLUTB) {
      if (addr >= VGA_CLUTA && addr < VGA_CLUTB) {
        return vga[found].palette[0][addr - VGA_CLUTA];
        return vga[found].palette[0][addr - VGA_CLUTA];
      } else if (addr >= VGA_CLUTB) {
      } else if (addr >= VGA_CLUTB) {
        return vga[found].palette[1][addr - VGA_CLUTB];
        return vga[found].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);
        runtime.sim.cont_run = 0;
        runtime.sim.cont_run = 0;
        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, int v)
static int vga_dump_image (char *filename, int v)
{
{
  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, int v)
static int vga_dump_image (char *filename, int v)
{
{
  int sx = vga[v].hlen;
  int sx = vga[v].hlen;
  int sy = vga[v].vlen;
  int sy = vga[v].vlen;
  int i, x, y;
  int i, x, y;
  int pc = vga[v].ctrl & VGA_CTRL_PC;
  int pc = vga[v].ctrl & VGA_CTRL_PC;
  int rbpp = vga[v].ctrl & VGA_CTRL_CD;
  int rbpp = vga[v].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;
  if (!sx || !sy) return;
 
 
  /* 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[v].palette[vga[v].pindex][i];
      d = vga[v].palette[vga[v].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[v].vbar[vga[v].vbindex] + (y * sx + x) * (bpp + 1));
      unsigned long pixel = evalsim_mem32 (vga[v].vbar[vga[v].vbindex] + (y * sx + x) * (bpp + 1));
      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 (int param)
void vga_job (int param)
{
{
  /* dump the image? */
  /* dump the image? */
  char temp[STR_SIZE];
  char temp[STR_SIZE];
  sprintf (temp, "%s%04i.bmp", config.vgas[param].filename, vga[param].pics++);
  sprintf (temp, "%s%04i.bmp", config.vgas[param].filename, vga[param].pics++);
  vga_dump_image (temp, param);
  vga_dump_image (temp, param);
 
 
  SCHED_ADD(vga_job, param, runtime.sim.cycles + config.vgas[param].refresh_rate);
  SCHED_ADD(vga_job, param, runtime.sim.cycles + config.vgas[param].refresh_rate);
}
}
 
 
/* Reset all VGAs */
/* Reset all VGAs */
void vga_reset ()
void vga_reset ()
{
{
  int i, j;
  int i, j;
  for (i = 0; i < config.nvgas; i++) {
  for (i = 0; i < config.nvgas; i++) {
 
 
    /* Init palette */
    /* Init palette */
    for (j = 0; j < 256; j++)
    for (j = 0; j < 256; j++)
      vga[i].palette[0][j] = vga[i].palette[1][j] = 0;
      vga[i].palette[0][j] = vga[i].palette[1][j] = 0;
 
 
    vga[i].ctrl = vga[i].stat = vga[i].htim = vga[i].vtim = 0;
    vga[i].ctrl = vga[i].stat = vga[i].htim = vga[i].vtim = 0;
    vga[i].hlen = vga[i].vlen = 0;
    vga[i].hlen = vga[i].vlen = 0;
    vga[i].vbar[0] = vga[i].vbar[1] = 0;
    vga[i].vbar[0] = vga[i].vbar[1] = 0;
 
 
    /* Init screen dumping machine */
    /* Init screen dumping machine */
    vga[i].pics = 0;
    vga[i].pics = 0;
 
 
    vga[i].pindex = 0;
    vga[i].pindex = 0;
    vga[i].vbindex = 0;
    vga[i].vbindex = 0;
 
 
    if (config.vgas[i].baseaddr)
    if (config.vgas[i].baseaddr)
      register_memoryarea(config.vgas[i].baseaddr, VGA_ADDR_SPACE, 4, 0, vga_read32, vga_write32);
      register_memoryarea(config.vgas[i].baseaddr, VGA_ADDR_SPACE, 4, 0, vga_read32, vga_write32);
    SCHED_ADD(vga_job, i, runtime.sim.cycles + config.vgas[i].refresh_rate);
    SCHED_ADD(vga_job, i, runtime.sim.cycles + config.vgas[i].refresh_rate);
  }
  }
}
}
 
 
 
/*----------------------------------------------------[ VGA Configuration ]---*/
 
void vga_nvgas(union param_val val, void *dat)
 
{
 
  if (val.int_val >= 0 && val.int_val < MAX_VGAS)
 
    config.nvgas = val.int_val;
 
  else
 
    CONFIG_ERROR("invalid number of devices.");
 
}
 
 
 
void vga_baseaddr(union param_val val, void *dat)
 
{
 
  if (current_device >= 0 && current_device < config.nvgas)
 
    config.vgas[current_device].baseaddr = val.addr_val;
 
  else
 
    CONFIG_ERROR("invalid device number.");
 
}
 
 
 
void vga_irq(union param_val val, void *dat)
 
{
 
  if (current_device >= 0 && current_device < config.nvgas)
 
    config.vgas[current_device].irq = val.int_val;
 
  else
 
    CONFIG_ERROR("invalid device number.");
 
}
 
 
 
void vga_refresh_rate(union param_val val, void *dat)
 
{
 
  if (current_device >= 0 && current_device < config.nvgas)
 
    config.vgas[current_device].refresh_rate = val.int_val;
 
  else
 
    CONFIG_ERROR("invalid device number.");
 
}
 
 
 
void vga_filename(union param_val val, void *dat)
 
{
 
  if (current_device >= 0 && current_device < config.nvgas)
 
    strcpy (config.vgas[current_device].filename, val.str_val);
 
  else
 
    CONFIG_ERROR("invalid device number.");
 
}
 
 
 
void reg_vga_sec(void)
 
{
 
  struct config_section *sec = reg_config_sec("vga", NULL, NULL);
 
 
 
  reg_config_param(sec, "nvgas", paramt_int, vga_nvgas);
 
  reg_config_param(sec, "device", paramt_int, change_device);
 
  reg_config_param(sec, "baseaddr", paramt_addr, vga_baseaddr);
 
  reg_config_param(sec, "irq", paramt_int, vga_irq);
 
  reg_config_param(sec, "refresh_rate", paramt_int, vga_refresh_rate);
 
  reg_config_param(sec, "filename", paramt_str, vga_filename);
 
  reg_config_param(sec, "enddevice", paramt_none, end_device);
 
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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