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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_34/] [or1ksim/] [peripheral/] [fb.c] - Diff between revs 1308 and 1350

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

Rev 1308 Rev 1350
/* fb.c -- Simple frame buffer
/* fb.c -- Simple frame buffer
   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 "config.h"
 
 
 
#ifdef HAVE_INTTYPES_H
 
#include <inttypes.h>
 
#endif
 
 
 
#include "port.h"
 
#include "arch.h"
#include "sim-config.h"
#include "sim-config.h"
#include "abstract.h"
#include "abstract.h"
#include "fb.h"
#include "fb.h"
#include "sched.h"
#include "sched.h"
 
 
#define FB_WRAP (512*1024)
#define FB_WRAP (512*1024)
 
 
static unsigned long pal[256];
static unsigned long pal[256];
static int fb_ctrl = 0;
static int fb_ctrl = 0;
static int fb_pic = 0;
static int fb_pic = 0;
static int fb_in_refresh = 1;
static int fb_in_refresh = 1;
static int fb_refresh_count = 0;
static int fb_refresh_count = 0;
static unsigned long fb_addr = 0;
static oraddr_t fb_addr = 0;
static unsigned long cam_addr = 0;
static oraddr_t cam_addr = 0;
static int camerax = 0, cameray = 0, camera_pos = 0;
static int camerax = 0, cameray = 0, camera_pos = 0;
 
 
static void change_buf_addr (unsigned long addr)
static void change_buf_addr (oraddr_t addr)
{
{
  fb_addr = addr;
  fb_addr = addr;
}
}
 
 
/* Write a register */
/* Write a register */
void fb_write32 (unsigned long addr, unsigned long value)
void fb_write32 (oraddr_t addr, uint32_t value)
{
{
  int a = (addr - config.fb.baseaddr);
  int a = (addr - config.fb.baseaddr);
  switch (a) {
  switch (a) {
    case FB_CTRL:    fb_ctrl = value; break;
    case FB_CTRL:    fb_ctrl = value; break;
    case FB_BUFADDR: change_buf_addr (value); break;
    case FB_BUFADDR: change_buf_addr (value); break;
    case FB_CAMBUFADDR: cam_addr = value; break;
    case FB_CAMBUFADDR: cam_addr = value; break;
    case FB_CAMPOSADDR: camera_pos = value;
    case FB_CAMPOSADDR: camera_pos = value;
                     camerax = value % FB_SIZEX;
                     camerax = value % FB_SIZEX;
                     cameray = value / FB_SIZEX;
                     cameray = value / FB_SIZEX;
                     break;
                     break;
    default:
    default:
      a -= FB_PAL;
      a -= FB_PAL;
      a /= 4;
      a /= 4;
      if (a < 0 || a >= 256) {
      if (a < 0 || a >= 256) {
        fprintf (stderr, "Write out of palette buffer (0x%08lx)!\n", addr);
        fprintf (stderr, "Write out of palette buffer (0x%"PRIxADDR")!\n", addr);
        runtime.sim.cont_run = 0;
        runtime.sim.cont_run = 0;
      } else pal[a] = value;
      } else pal[a] = value;
      break;
      break;
  }
  }
}
}
 
 
/* Read a register */
/* Read a register */
unsigned long fb_read32 (unsigned long addr)
oraddr_t fb_read32 (oraddr_t addr)
{
{
  int a = (addr - config.fb.baseaddr);
  int a = (addr - config.fb.baseaddr);
  switch (a) {
  switch (a) {
    case FB_CTRL:
    case FB_CTRL:
      return fb_ctrl & ~0xff000000| (fb_in_refresh ? 0x80000000 : 0) | ((unsigned long)(fb_refresh_count & 0x7f) << 24);
      return fb_ctrl & ~0xff000000| (fb_in_refresh ? 0x80000000 : 0) | ((unsigned long)(fb_refresh_count & 0x7f) << 24);
      break;
      break;
    case FB_BUFADDR: return fb_addr; break;
    case FB_BUFADDR: return fb_addr; break;
    case FB_CAMBUFADDR: return cam_addr; break;
    case FB_CAMBUFADDR: return cam_addr; break;
    case FB_CAMPOSADDR: return camera_pos; break;
    case FB_CAMPOSADDR: return camera_pos; break;
    default:
    default:
      a -= FB_PAL;
      a -= FB_PAL;
      a /= 4;
      a /= 4;
      if (a < 0 || a >= 256) {
      if (a < 0 || a >= 256) {
        fprintf (stderr, "Read out of palette buffer (0x%08lx)!\n", addr);
        fprintf (stderr, "Read out of palette buffer (0x%"PRIxADDR")!\n", addr);
        runtime.sim.cont_run = 0;
        runtime.sim.cont_run = 0;
        return 0;
        return 0;
      } else return pal[a];
      } else return pal[a];
  }
  }
}
}
 
 
/* define these also for big endian */
/* define these also for big endian */
#if __BIG_ENDIAN__
#if __BIG_ENDIAN__
#define CNV32(x) (\
#define CNV32(x) (\
     ((((x) >> 24) & 0xff) << 0)\
     ((((x) >> 24) & 0xff) << 0)\
   | ((((x) >> 16) & 0xff) << 8)\
   | ((((x) >> 16) & 0xff) << 8)\
   | ((((x) >> 8) & 0xff) << 16)\
   | ((((x) >> 8) & 0xff) << 16)\
   | ((((x) >> 0) & 0xff) << 24))
   | ((((x) >> 0) & 0xff) << 24))
#define CNV16(x) (\
#define CNV16(x) (\
     ((((x) >> 8) & 0xff) << 0)\
     ((((x) >> 8) & 0xff) << 0)\
   | ((((x) >> 0) & 0xff) << 8))
   | ((((x) >> 0) & 0xff) << 8))
#else
#else
#define CNV16(x) (x)
#define CNV16(x) (x)
#define CNV32(x) (x)
#define CNV32(x) (x)
#endif
#endif
 
 
/* Dumps a bmp file, based on current image */
/* Dumps a bmp file, based on current image */
static int fb_dump_image8 (char *filename)
static int fb_dump_image8 (char *filename)
{
{
  int sx = FB_SIZEX;
  int sx = FB_SIZEX;
  int sy = FB_SIZEY;
  int sy = FB_SIZEY;
  int i, x, y;
  int i, x, y;
  FILE *fo;
  FILE *fo;
 
 
  unsigned short int u16;
  unsigned short int u16;
  unsigned long int u32;
  unsigned long int u32;
 
 
  if (config.sim.verbose) PRINTF ("Creating %s...", filename);
  if (config.sim.verbose) PRINTF ("Creating %s...", filename);
  fo = fopen (filename, "wb+");
  fo = fopen (filename, "wb+");
  u16 = CNV16(19778); /* BM */
  u16 = CNV16(19778); /* BM */
  if (!fwrite (&u16, 2, 1, fo)) return 1;
  if (!fwrite (&u16, 2, 1, fo)) return 1;
  u32 = CNV32(14 + 40 + sx * sy + 1024); /* size */
  u32 = CNV32(14 + 40 + sx * sy + 1024); /* size */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  u32 = CNV32(0); /* reserved */
  u32 = CNV32(0); /* reserved */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  u32 = 14 + 40 + 1024; /* offset */
  u32 = 14 + 40 + 1024; /* offset */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
 
 
  u32 = CNV32(40); /* header size */
  u32 = CNV32(40); /* header size */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  u32 = CNV32(sx); /* width */
  u32 = CNV32(sx); /* width */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  u32 = CNV32(sy); /* height */
  u32 = CNV32(sy); /* height */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  u16 = CNV16(1);  /* planes */
  u16 = CNV16(1);  /* planes */
  if (!fwrite (&u16, 2, 1, fo)) return 1;
  if (!fwrite (&u16, 2, 1, fo)) return 1;
  u16 = CNV16(8);  /* bits */
  u16 = CNV16(8);  /* bits */
  if (!fwrite (&u16, 2, 1, fo)) return 1;
  if (!fwrite (&u16, 2, 1, fo)) return 1;
  u32 = CNV32(0);  /* compression */
  u32 = CNV32(0);  /* compression */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  u32 = CNV32(x * y); /* image size */
  u32 = CNV32(x * y); /* image size */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  u32 = CNV32(2835);  /* x resolution */
  u32 = CNV32(2835);  /* x resolution */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  u32 = CNV32(2835);  /* y resolution */
  u32 = CNV32(2835);  /* y resolution */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  u32 = CNV32(0);  /* ncolours = 0; should be generated */
  u32 = CNV32(0);  /* ncolours = 0; should be generated */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  u32 = CNV32(0);  /* important colours; all are important */
  u32 = CNV32(0);  /* important colours; all are important */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
 
 
  for (i = 0; i < 256; i++) {
  for (i = 0; i < 256; i++) {
    unsigned long val, d;
    unsigned long val, d;
    d = pal[i];
    d = pal[i];
#if 1
#if 1
    val = ((d >> 0) & 0x1f) << 3;   /* Blue */
    val = ((d >> 0) & 0x1f) << 3;   /* Blue */
    val |= ((d >> 5) & 0x3f) << 10;  /* Green */
    val |= ((d >> 5) & 0x3f) << 10;  /* Green */
    val |= ((d >> 11) & 0x1f) << 19; /* Red */
    val |= ((d >> 11) & 0x1f) << 19; /* Red */
#else 
#else 
    val = CNV32(pal[i]);
    val = CNV32(pal[i]);
#endif
#endif
    if (!fwrite (&val, 4, 1, fo)) return 1;
    if (!fwrite (&val, 4, 1, fo)) return 1;
  }
  }
 
 
  if (config.sim.verbose) PRINTF ("(%i,%i)", sx, sy);
  if (config.sim.verbose) PRINTF ("(%i,%i)", sx, sy);
  /* 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 - sx) % 4;
    int align = (4 - sx) % 4;
    int zero = CNV32(0);
    int zero = CNV32(0);
    int add;
    int add;
    while (align < 0) align += 4;
    while (align < 0) align += 4;
    for (x = 0; x < sx; x++) {
    for (x = 0; x < sx; x++) {
      add = (fb_addr & ~(FB_WRAP - 1)) | ((fb_addr + y * sx + x) & (FB_WRAP - 1));
      add = (fb_addr & ~(FB_WRAP - 1)) | ((fb_addr + y * sx + x) & (FB_WRAP - 1));
      fputc (evalsim_mem8 (add), fo);
      fputc (evalsim_mem8 (add), fo);
    }
    }
    if (align && !fwrite (&zero, align, 1, fo)) return 1;
    if (align && !fwrite (&zero, align, 1, fo)) return 1;
  }
  }
 
 
  if (config.sim.verbose) PRINTF ("DONE\n");
  if (config.sim.verbose) PRINTF ("DONE\n");
  fclose (fo);
  fclose (fo);
  return 0;
  return 0;
}
}
 
 
/* Dumps a bmp file, based on current image */
/* Dumps a bmp file, based on current image */
static int fb_dump_image24 (char *filename)
static int fb_dump_image24 (char *filename)
{
{
  int sx = FB_SIZEX;
  int sx = FB_SIZEX;
  int sy = FB_SIZEY;
  int sy = FB_SIZEY;
  int x, y;
  int x, y;
  FILE *fo;
  FILE *fo;
 
 
  unsigned short int u16;
  unsigned short int u16;
  unsigned long int u32;
  unsigned long int u32;
 
 
  if (config.sim.verbose) PRINTF ("Creating %s...", filename);
  if (config.sim.verbose) PRINTF ("Creating %s...", filename);
  fo = fopen (filename, "wb+");
  fo = fopen (filename, "wb+");
  u16 = CNV16(19778); /* BM */
  u16 = CNV16(19778); /* BM */
  if (!fwrite (&u16, 2, 1, fo)) return 1;
  if (!fwrite (&u16, 2, 1, fo)) return 1;
  u32 = CNV32(14 + 40 + sx * sy * 3); /* size */
  u32 = CNV32(14 + 40 + sx * sy * 3); /* size */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  u32 = CNV32(0); /* reserved */
  u32 = CNV32(0); /* reserved */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  u32 = 14 + 40; /* offset */
  u32 = 14 + 40; /* offset */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
 
 
  u32 = CNV32(40); /* header size */
  u32 = CNV32(40); /* header size */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  u32 = CNV32(sx); /* width */
  u32 = CNV32(sx); /* width */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  u32 = CNV32(sy); /* height */
  u32 = CNV32(sy); /* height */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  u16 = CNV16(1);  /* planes */
  u16 = CNV16(1);  /* planes */
  if (!fwrite (&u16, 2, 1, fo)) return 1;
  if (!fwrite (&u16, 2, 1, fo)) return 1;
  u16 = CNV16(24);  /* bits */
  u16 = CNV16(24);  /* bits */
  if (!fwrite (&u16, 2, 1, fo)) return 1;
  if (!fwrite (&u16, 2, 1, fo)) return 1;
  u32 = CNV32(0);  /* compression */
  u32 = CNV32(0);  /* compression */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  u32 = CNV32(x * y * 3); /* image size */
  u32 = CNV32(x * y * 3); /* image size */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  u32 = CNV32(2835);  /* x resolution */
  u32 = CNV32(2835);  /* x resolution */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  u32 = CNV32(2835);  /* y resolution */
  u32 = CNV32(2835);  /* y resolution */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  u32 = CNV32(0);  /* ncolours = 0; should be generated */
  u32 = CNV32(0);  /* ncolours = 0; should be generated */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  u32 = CNV32(0);  /* important colours; all are important */
  u32 = CNV32(0);  /* important colours; all are important */
  if (!fwrite (&u32, 4, 1, fo)) return 1;
  if (!fwrite (&u32, 4, 1, fo)) return 1;
 
 
  if (config.sim.verbose) PRINTF ("(%i,%i)", sx, sy);
  if (config.sim.verbose) PRINTF ("(%i,%i)", sx, sy);
  /* Data is stored upside down */
  /* Data is stored upside down */
  for (y = sy - 1; y >= 0; y--) {
  for (y = sy - 1; y >= 0; y--) {
    unsigned char line[FB_SIZEX][3];
    unsigned char line[FB_SIZEX][3];
    for (x = 0; x < sx; x++)
    for (x = 0; x < sx; x++)
      if (y >= cameray && x >= camerax && y < cameray + CAM_SIZEY && x < camerax + CAM_SIZEX) {
      if (y >= cameray && x >= camerax && y < cameray + CAM_SIZEY && x < camerax + CAM_SIZEX) {
        int add = (cam_addr + (x - camerax + (y - cameray) * CAM_SIZEX) * 2) ^ 2;
        int add = (cam_addr + (x - camerax + (y - cameray) * CAM_SIZEX) * 2) ^ 2;
        unsigned short d = evalsim_mem16 (add);
        unsigned short d = evalsim_mem16 (add);
        line[x][0] = ((d >> 0) & 0x1f) << 3;  /* Blue */
        line[x][0] = ((d >> 0) & 0x1f) << 3;  /* Blue */
        line[x][1] = ((d >> 5) & 0x3f) << 2;  /* Green */
        line[x][1] = ((d >> 5) & 0x3f) << 2;  /* Green */
        line[x][2] = ((d >> 11) & 0x1f) << 3; /* Red */
        line[x][2] = ((d >> 11) & 0x1f) << 3; /* Red */
      } else {
      } else {
        int add = (fb_addr & ~(FB_WRAP - 1)) | ((fb_addr + y * sx + x) & (FB_WRAP - 1));
        int add = (fb_addr & ~(FB_WRAP - 1)) | ((fb_addr + y * sx + x) & (FB_WRAP - 1));
        unsigned short d = pal[evalsim_mem8 (add)];
        unsigned short d = pal[evalsim_mem8 (add)];
        line[x][0] = ((d >> 0) & 0x1f) << 3;  /* Blue */
        line[x][0] = ((d >> 0) & 0x1f) << 3;  /* Blue */
        line[x][1] = ((d >> 5) & 0x3f) << 2;  /* Green */
        line[x][1] = ((d >> 5) & 0x3f) << 2;  /* Green */
        line[x][2] = ((d >> 11) & 0x1f) << 3; /* Red */
        line[x][2] = ((d >> 11) & 0x1f) << 3; /* Red */
      }
      }
    if(!fwrite (line, sizeof(line), 1, fo)) return 1;
    if(!fwrite (line, sizeof(line), 1, fo)) return 1;
  }
  }
 
 
  if (config.sim.verbose) PRINTF ("DONE\n");
  if (config.sim.verbose) PRINTF ("DONE\n");
  fclose (fo);
  fclose (fo);
  return 0;
  return 0;
}
}
 
 
void fb_job (int param)
void fb_job (int param)
{
{
  if (param) {
  if (param) {
    /* dump the image? */
    /* dump the image? */
    if (fb_ctrl & 1) {
    if (fb_ctrl & 1) {
      char temp[STR_SIZE];
      char temp[STR_SIZE];
      sprintf (temp, "%s%04i.bmp", &config.fb.filename[0], fb_pic);
      sprintf (temp, "%s%04i.bmp", &config.fb.filename[0], fb_pic);
      if (fb_ctrl & 2) fb_dump_image24 (temp);
      if (fb_ctrl & 2) fb_dump_image24 (temp);
      else fb_dump_image8 (temp);
      else fb_dump_image8 (temp);
      fb_pic++;
      fb_pic++;
    }
    }
    SCHED_ADD(fb_job, 0, runtime.sim.cycles + config.fb.refresh_rate - config.fb.refresh_rate / REFRESH_DIVIDER);
    SCHED_ADD(fb_job, 0, runtime.sim.cycles + config.fb.refresh_rate - config.fb.refresh_rate / REFRESH_DIVIDER);
    fb_in_refresh = 0;
    fb_in_refresh = 0;
  } else {
  } else {
    fb_refresh_count++;
    fb_refresh_count++;
    SCHED_ADD(fb_job, 1, runtime.sim.cycles + config.fb.refresh_rate / REFRESH_DIVIDER);
    SCHED_ADD(fb_job, 1, runtime.sim.cycles + config.fb.refresh_rate / REFRESH_DIVIDER);
 
 
  }
  }
}
}
 
 
/* Reset all VGAs */
/* Reset all VGAs */
void fb_reset ()
void fb_reset ()
{
{
  int i;
  int i;
 
 
  if (config.fb.enabled) {
  if (config.fb.enabled) {
    fb_pic = 0;
    fb_pic = 0;
    fb_addr = 0;
    fb_addr = 0;
    fb_ctrl = 0;
    fb_ctrl = 0;
 
 
    for (i = 0; i < 256; i++)
    for (i = 0; i < 256; i++)
      pal[i] = (i << 16) | (i << 8) | (i << 0);
      pal[i] = (i << 16) | (i << 8) | (i << 0);
 
 
    if (config.fb.baseaddr)
    if (config.fb.baseaddr)
      register_memoryarea(config.fb.baseaddr, FB_PAL + 256*4, 4, 0, fb_read32, fb_write32);
      register_memoryarea(config.fb.baseaddr, FB_PAL + 256*4, 4, 0, fb_read32, fb_write32);
    SCHED_ADD(fb_job, 0, runtime.sim.cycles + config.fb.refresh_rate);
    SCHED_ADD(fb_job, 0, runtime.sim.cycles + config.fb.refresh_rate);
  }
  }
}
}
 
 

powered by: WebSVN 2.1.0

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