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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [peripheral/] [fb.c] - Diff between revs 19 and 224

Only display areas with differences | Details | Blame | View Log

Rev 19 Rev 224
/* 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
   Copyright (C) 2008 Embecosm Limited
   Copyright (C) 2008 Embecosm Limited
 
 
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
 
 
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
 
 
   This program is free software; you can redistribute it and/or modify it
   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 the Free
   under the terms of the GNU General Public License as published by the Free
   Software Foundation; either version 3 of the License, or (at your option)
   Software Foundation; either version 3 of the License, or (at your option)
   any later version.
   any later version.
 
 
   This program is distributed in the hope that it will be useful, but WITHOUT
   This program is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
   more details.
 
 
   You should have received a copy of the GNU General Public License along
   You should have received a copy of the GNU General Public License along
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
/* This program is commented throughout in a fashion suitable for processing
/* This program is commented throughout in a fashion suitable for processing
   with Doxygen. */
   with Doxygen. */
 
 
 
 
/* Autoconf and/or portability configuration */
/* Autoconf and/or portability configuration */
#include "config.h"
#include "config.h"
#include "port.h"
#include "port.h"
 
 
/* System includes */
/* System includes */
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
 
 
/* Package includes */
/* Package includes */
#include "arch.h"
#include "arch.h"
#include "sim-config.h"
#include "sim-config.h"
#include "abstract.h"
#include "abstract.h"
#include "sched.h"
#include "sched.h"
#include "toplevel-support.h"
#include "toplevel-support.h"
 
 
 
 
#define FB_SIZEX           640
#define FB_SIZEX           640
#define FB_SIZEY           480
#define FB_SIZEY           480
 
 
#define CAM_SIZEX          352
#define CAM_SIZEX          352
#define CAM_SIZEY          288
#define CAM_SIZEY          288
 
 
/*! Relative amount of time spent in refresh */
/*! Relative amount of time spent in refresh */
#define REFRESH_DIVIDER     20
#define REFRESH_DIVIDER     20
 
 
#define FB_CTRL            0x0000
#define FB_CTRL            0x0000
#define FB_BUFADDR         0x0004
#define FB_BUFADDR         0x0004
#define FB_CAMBUFADDR      0x0008
#define FB_CAMBUFADDR      0x0008
#define FB_CAMPOSADDR      0x000c
#define FB_CAMPOSADDR      0x000c
#define FB_PAL             0x0400
#define FB_PAL             0x0400
 
 
#define FB_WRAP (512*1024)
#define FB_WRAP (512*1024)
 
 
struct fb_state
struct fb_state
{
{
  int enabled;
  int enabled;
  unsigned long pal[256];
  unsigned long pal[256];
  int ctrl;
  int ctrl;
  int pic;
  int pic;
  int in_refresh;
  int in_refresh;
  int refresh_count;
  int refresh_count;
  oraddr_t addr;
  oraddr_t addr;
  oraddr_t cam_addr;
  oraddr_t cam_addr;
  int camerax;
  int camerax;
  int cameray;
  int cameray;
  int camera_pos;
  int camera_pos;
  oraddr_t baseaddr;
  oraddr_t baseaddr;
  int refresh;
  int refresh;
  int refresh_rate;
  int refresh_rate;
  char *filename;
  char *filename;
};
};
 
 
static void
static void
change_buf_addr (struct fb_state *fb, oraddr_t addr)
change_buf_addr (struct fb_state *fb, oraddr_t addr)
{
{
  fb->addr = addr;
  fb->addr = addr;
}
}
 
 
/* Write a register */
/* Write a register */
static void
static void
fb_write32 (oraddr_t addr, uint32_t value, void *dat)
fb_write32 (oraddr_t addr, uint32_t value, void *dat)
{
{
  struct fb_state *fb = dat;
  struct fb_state *fb = dat;
 
 
  switch (addr)
  switch (addr)
    {
    {
    case FB_CTRL:
    case FB_CTRL:
      fb->ctrl = value;
      fb->ctrl = value;
      break;
      break;
    case FB_BUFADDR:
    case FB_BUFADDR:
      change_buf_addr (fb, value);
      change_buf_addr (fb, value);
      break;
      break;
    case FB_CAMBUFADDR:
    case FB_CAMBUFADDR:
      fb->cam_addr = value;
      fb->cam_addr = value;
      break;
      break;
    case FB_CAMPOSADDR:
    case FB_CAMPOSADDR:
      fb->camera_pos = value;
      fb->camera_pos = value;
      fb->camerax = value % FB_SIZEX;
      fb->camerax = value % FB_SIZEX;
      fb->cameray = value / FB_SIZEX;
      fb->cameray = value / FB_SIZEX;
      break;
      break;
    default:
    default:
      addr -= FB_PAL;
      addr -= FB_PAL;
      addr /= 4;
      addr /= 4;
      if (addr < 0 || addr >= 256)
      if (addr < 0 || addr >= 256)
        {
        {
          fprintf (stderr, "Write out of palette buffer (0x%" PRIxADDR ")!\n",
          fprintf (stderr, "Write out of palette buffer (0x%" PRIxADDR ")!\n",
                   addr);
                   addr);
        }
        }
      else
      else
        fb->pal[addr] = value;
        fb->pal[addr] = value;
      break;
      break;
    }
    }
}
}
 
 
/* Read a register */
/* Read a register */
static oraddr_t
static oraddr_t
fb_read32 (oraddr_t addr, void *dat)
fb_read32 (oraddr_t addr, void *dat)
{
{
  struct fb_state *fb = dat;
  struct fb_state *fb = dat;
 
 
  switch (addr)
  switch (addr)
    {
    {
    case FB_CTRL:
    case FB_CTRL:
      return (fb->ctrl & ~0xff000000) | (fb->
      return (fb->ctrl & ~0xff000000) | (fb->
                                         in_refresh ? 0x80000000 : 0) |
                                         in_refresh ? 0x80000000 : 0) |
        ((unsigned long) (fb->refresh_count & 0x7f) << 24);
        ((unsigned long) (fb->refresh_count & 0x7f) << 24);
      break;
      break;
    case FB_BUFADDR:
    case FB_BUFADDR:
      return fb->addr;
      return fb->addr;
      break;
      break;
    case FB_CAMBUFADDR:
    case FB_CAMBUFADDR:
      return fb->cam_addr;
      return fb->cam_addr;
      break;
      break;
    case FB_CAMPOSADDR:
    case FB_CAMPOSADDR:
      return fb->camera_pos;
      return fb->camera_pos;
      break;
      break;
    default:
    default:
      addr -= FB_PAL;
      addr -= FB_PAL;
      addr /= 4;
      addr /= 4;
      if (addr < 0 || addr >= 256)
      if (addr < 0 || addr >= 256)
        {
        {
          fprintf (stderr, "Read out of palette buffer (0x%" PRIxADDR ")!\n",
          fprintf (stderr, "Read out of palette buffer (0x%" PRIxADDR ")!\n",
                   addr);
                   addr);
          return 0;
          return 0;
        }
        }
      else
      else
        return fb->pal[addr];
        return fb->pal[addr];
    }
    }
}
}
 
 
/* 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
static int
fb_dump_image8 (struct fb_state *fb, char *filename)
fb_dump_image8 (struct fb_state *fb, char *filename)
{
{
  int sx = FB_SIZEX;
  int sx = FB_SIZEX;
  int sy = FB_SIZEY;
  int sy = FB_SIZEY;
  int i, x = 0, y = 0;
  int i, x = 0, y = 0;
  FILE *fo;
  FILE *fo;
 
 
  unsigned short int u16;
  unsigned short int u16;
  unsigned long int u32;
  unsigned long int u32;
 
 
  if (config.sim.verbose)
  if (config.sim.verbose)
    PRINTF ("Creating %s...", filename);
    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))
  if (!fwrite (&u16, 2, 1, fo))
    return 1;
    return 1;
  u32 = CNV32 (14 + 40 + sx * sy + 1024);       /* size */
  u32 = CNV32 (14 + 40 + sx * sy + 1024);       /* size */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
  u32 = CNV32 (0);               /* reserved */
  u32 = CNV32 (0);               /* reserved */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
  u32 = 14 + 40 + 1024;         /* offset */
  u32 = 14 + 40 + 1024;         /* offset */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
 
 
  u32 = CNV32 (40);             /* header size */
  u32 = CNV32 (40);             /* header size */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
  u32 = CNV32 (sx);             /* width */
  u32 = CNV32 (sx);             /* width */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
  u32 = CNV32 (sy);             /* height */
  u32 = CNV32 (sy);             /* height */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
  u16 = CNV16 (1);              /* planes */
  u16 = CNV16 (1);              /* planes */
  if (!fwrite (&u16, 2, 1, fo))
  if (!fwrite (&u16, 2, 1, fo))
    return 1;
    return 1;
  u16 = CNV16 (8);              /* bits */
  u16 = CNV16 (8);              /* bits */
  if (!fwrite (&u16, 2, 1, fo))
  if (!fwrite (&u16, 2, 1, fo))
    return 1;
    return 1;
  u32 = CNV32 (0);               /* compression */
  u32 = CNV32 (0);               /* compression */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
  u32 = CNV32 (x * y);          /* image size */
  u32 = CNV32 (x * y);          /* image size */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
  u32 = CNV32 (2835);           /* x resolution */
  u32 = CNV32 (2835);           /* x resolution */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
  u32 = CNV32 (2835);           /* y resolution */
  u32 = CNV32 (2835);           /* y resolution */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
  u32 = CNV32 (0);               /* ncolours = 0; should be generated */
  u32 = CNV32 (0);               /* ncolours = 0; should be generated */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
  u32 = CNV32 (0);               /* important colours; all are important */
  u32 = CNV32 (0);               /* important colours; all are important */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
 
 
  for (i = 0; i < 256; i++)
  for (i = 0; i < 256; i++)
    {
    {
      unsigned long val, d;
      unsigned long val, d;
      d = fb->pal[i];
      d = fb->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))
      if (!fwrite (&val, 4, 1, fo))
        return 1;
        return 1;
    }
    }
 
 
  if (config.sim.verbose)
  if (config.sim.verbose)
    PRINTF ("(%i,%i)", sx, sy);
    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)
      while (align < 0)
        align += 4;
        align += 4;
      for (x = 0; x < sx; x++)
      for (x = 0; x < sx; x++)
        {
        {
          add =
          add =
            (fb->
            (fb->
             addr & ~(FB_WRAP - 1)) | ((fb->addr + y * sx + x) & (FB_WRAP -
             addr & ~(FB_WRAP - 1)) | ((fb->addr + y * sx + x) & (FB_WRAP -
                                                                  1));
                                                                  1));
          fputc (eval_direct8 (add, 0, 0), fo);
          fputc (eval_direct8 (add, 0, 0), fo);
        }
        }
      if (align && !fwrite (&zero, align, 1, fo))
      if (align && !fwrite (&zero, align, 1, fo))
        return 1;
        return 1;
    }
    }
 
 
  if (config.sim.verbose)
  if (config.sim.verbose)
    PRINTF ("DONE\n");
    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
static int
fb_dump_image24 (struct fb_state *fb, char *filename)
fb_dump_image24 (struct fb_state *fb, char *filename)
{
{
  int sx = FB_SIZEX;
  int sx = FB_SIZEX;
  int sy = FB_SIZEY;
  int sy = FB_SIZEY;
  int x = 0, y = 0;
  int x = 0, y = 0;
  FILE *fo;
  FILE *fo;
 
 
  unsigned short int u16;
  unsigned short int u16;
  unsigned long int u32;
  unsigned long int u32;
 
 
  if (config.sim.verbose)
  if (config.sim.verbose)
    PRINTF ("Creating %s...", filename);
    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))
  if (!fwrite (&u16, 2, 1, fo))
    return 1;
    return 1;
  u32 = CNV32 (14 + 40 + sx * sy * 3);  /* size */
  u32 = CNV32 (14 + 40 + sx * sy * 3);  /* size */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
  u32 = CNV32 (0);               /* reserved */
  u32 = CNV32 (0);               /* reserved */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
  u32 = 14 + 40;                /* offset */
  u32 = 14 + 40;                /* offset */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
 
 
  u32 = CNV32 (40);             /* header size */
  u32 = CNV32 (40);             /* header size */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
  u32 = CNV32 (sx);             /* width */
  u32 = CNV32 (sx);             /* width */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
  u32 = CNV32 (sy);             /* height */
  u32 = CNV32 (sy);             /* height */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
  u16 = CNV16 (1);              /* planes */
  u16 = CNV16 (1);              /* planes */
  if (!fwrite (&u16, 2, 1, fo))
  if (!fwrite (&u16, 2, 1, fo))
    return 1;
    return 1;
  u16 = CNV16 (24);             /* bits */
  u16 = CNV16 (24);             /* bits */
  if (!fwrite (&u16, 2, 1, fo))
  if (!fwrite (&u16, 2, 1, fo))
    return 1;
    return 1;
  u32 = CNV32 (0);               /* compression */
  u32 = CNV32 (0);               /* compression */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
  u32 = CNV32 (x * y * 3);      /* image size */
  u32 = CNV32 (x * y * 3);      /* image size */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
  u32 = CNV32 (2835);           /* x resolution */
  u32 = CNV32 (2835);           /* x resolution */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
  u32 = CNV32 (2835);           /* y resolution */
  u32 = CNV32 (2835);           /* y resolution */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
  u32 = CNV32 (0);               /* ncolours = 0; should be generated */
  u32 = CNV32 (0);               /* ncolours = 0; should be generated */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
  u32 = CNV32 (0);               /* important colours; all are important */
  u32 = CNV32 (0);               /* important colours; all are important */
  if (!fwrite (&u32, 4, 1, fo))
  if (!fwrite (&u32, 4, 1, fo))
    return 1;
    return 1;
 
 
  if (config.sim.verbose)
  if (config.sim.verbose)
    PRINTF ("(%i,%i)", sx, sy);
    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 >= fb->cameray && x >= fb->camerax
        if (y >= fb->cameray && x >= fb->camerax
            && y < fb->cameray + CAM_SIZEY && x < fb->camerax + CAM_SIZEX)
            && y < fb->cameray + CAM_SIZEY && x < fb->camerax + CAM_SIZEX)
          {
          {
            int add =
            int add =
              (fb->cam_addr +
              (fb->cam_addr +
               (x - fb->camerax + (y - fb->cameray) * CAM_SIZEX) * 2) ^ 2;
               (x - fb->camerax + (y - fb->cameray) * CAM_SIZEX) * 2) ^ 2;
            unsigned short d = eval_direct16 (add, 0, 0);
            unsigned short d = eval_direct16 (add, 0, 0);
            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 =
            int add =
              (fb->
              (fb->
               addr & ~(FB_WRAP - 1)) | ((fb->addr + y * sx + x) & (FB_WRAP -
               addr & ~(FB_WRAP - 1)) | ((fb->addr + y * sx + x) & (FB_WRAP -
                                                                    1));
                                                                    1));
            unsigned short d = fb->pal[eval_direct8 (add, 0, 0)];
            unsigned short d = fb->pal[eval_direct8 (add, 0, 0)];
            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))
      if (!fwrite (line, sizeof (line), 1, fo))
        return 1;
        return 1;
    }
    }
 
 
  if (config.sim.verbose)
  if (config.sim.verbose)
    PRINTF ("DONE\n");
    PRINTF ("DONE\n");
  fclose (fo);
  fclose (fo);
  return 0;
  return 0;
}
}
 
 
static void
static void
fb_job (void *dat)
fb_job (void *dat)
{
{
  struct fb_state *fb = dat;
  struct fb_state *fb = dat;
 
 
  if (fb->refresh)
  if (fb->refresh)
    {
    {
      /* 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", fb->filename, fb->pic);
          sprintf (temp, "%s%04i.bmp", fb->filename, fb->pic);
          if (fb->ctrl & 2)
          if (fb->ctrl & 2)
            fb_dump_image24 (fb, temp);
            fb_dump_image24 (fb, temp);
          else
          else
            fb_dump_image8 (fb, temp);
            fb_dump_image8 (fb, temp);
          fb->pic++;
          fb->pic++;
        }
        }
      SCHED_ADD (fb_job, dat, fb->refresh_rate / REFRESH_DIVIDER);
      SCHED_ADD (fb_job, dat, fb->refresh_rate / REFRESH_DIVIDER);
      fb->in_refresh = 0;
      fb->in_refresh = 0;
      fb->refresh = 0;
      fb->refresh = 0;
    }
    }
  else
  else
    {
    {
      fb->refresh_count++;
      fb->refresh_count++;
      fb->refresh = 1;
      fb->refresh = 1;
      SCHED_ADD (fb_job, dat, fb->refresh_rate / REFRESH_DIVIDER);
      SCHED_ADD (fb_job, dat, fb->refresh_rate / REFRESH_DIVIDER);
    }
    }
}
}
 
 
/* Reset all FBs */
/* Reset all FBs */
static void
static void
fb_reset (void *dat)
fb_reset (void *dat)
{
{
  struct fb_state *fb = dat;
  struct fb_state *fb = dat;
  int i;
  int i;
 
 
  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++)
    fb->pal[i] = (i << 16) | (i << 8) | (i << 0);
    fb->pal[i] = (i << 16) | (i << 8) | (i << 0);
 
 
  SCHED_ADD (fb_job, dat, fb->refresh_rate);
  SCHED_ADD (fb_job, dat, fb->refresh_rate);
  fb->refresh = 0;
  fb->refresh = 0;
}
}
 
 
/*-----------------------------------------------------[ FB configuration ]---*/
/*-----------------------------------------------------[ FB configuration ]---*/
static void
static void
fb_enabled (union param_val val, void *dat)
fb_enabled (union param_val val, void *dat)
{
{
  struct fb_state *fb = dat;
  struct fb_state *fb = dat;
  fb->enabled = val.int_val;
  fb->enabled = val.int_val;
}
}
 
 
 
 
static void
static void
fb_baseaddr (union param_val val, void *dat)
fb_baseaddr (union param_val val, void *dat)
{
{
  struct fb_state *fb = dat;
  struct fb_state *fb = dat;
  fb->baseaddr = val.addr_val;
  fb->baseaddr = val.addr_val;
}
}
 
 
 
 
static void
static void
fb_refresh_rate (union param_val val, void *dat)
fb_refresh_rate (union param_val val, void *dat)
{
{
  struct fb_state *fb = dat;
  struct fb_state *fb = dat;
  fb->refresh_rate = val.int_val;
  fb->refresh_rate = val.int_val;
}
}
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Set the frame buffer output file
/*!Set the frame buffer output file
 
 
   Free any previously allocated value.
   Free any previously allocated value.
 
 
   @param[in] val  The value to use
   @param[in] val  The value to use
   @param[in] dat  The config data structure                                 */
   @param[in] dat  The config data structure                                 */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void
fb_filename (union param_val  val,
fb_filename (union param_val  val,
             void            *dat)
             void            *dat)
{
{
  struct fb_state *fb = dat;
  struct fb_state *fb = dat;
 
 
  if (NULL != fb->filename)
  if (NULL != fb->filename)
    {
    {
      free (fb->filename);
      free (fb->filename);
      fb->filename = NULL;
      fb->filename = NULL;
    }
    }
 
 
  if (!(fb->filename = strdup (val.str_val)))
  if (!(fb->filename = strdup (val.str_val)))
    {
    {
      fprintf (stderr, "Peripheral FB: Run out of memory\n");
      fprintf (stderr, "Peripheral FB: Run out of memory\n");
      exit (-1);
      exit (-1);
    }
    }
}       /* fb_filename() */
}       /* fb_filename() */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Initialize a new frame buffer configuration
/*!Initialize a new frame buffer configuration
 
 
   ALL parameters are set explicitly to default values.                      */
   ALL parameters are set explicitly to default values.                      */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void *
static void *
fb_sec_start ()
fb_sec_start ()
{
{
  struct fb_state *new = malloc (sizeof (struct fb_state));
  struct fb_state *new = malloc (sizeof (struct fb_state));
 
 
  if (!new)
  if (!new)
    {
    {
      fprintf (stderr, "Peripheral FB: Run out of memory\n");
      fprintf (stderr, "Peripheral FB: Run out of memory\n");
      exit (-1);
      exit (-1);
    }
    }
 
 
  new->enabled       = 1;
  new->enabled       = 1;
  new->baseaddr      = 0;
  new->baseaddr      = 0;
  new->refresh_rate  = 1000000000000ULL / 50ULL / config.sim.clkcycle_ps;
  new->refresh_rate  = 1000000000000ULL / 50ULL / config.sim.clkcycle_ps;
  new->filename      = strdup ("fb_out");
  new->filename      = strdup ("fb_out");
 
 
  new->ctrl          = 0;
  new->ctrl          = 0;
  new->pic           = 0;
  new->pic           = 0;
  new->in_refresh    = 1;
  new->in_refresh    = 1;
  new->refresh_count = 0;
  new->refresh_count = 0;
  new->addr          = 0;
  new->addr          = 0;
  new->cam_addr      = 0;
  new->cam_addr      = 0;
  new->camerax       = 0;
  new->camerax       = 0;
  new->cameray       = 0;
  new->cameray       = 0;
  new->camera_pos    = 0;
  new->camera_pos    = 0;
 
 
  return new;
  return new;
 
 
}       /* fb_sec_start() */
}       /* fb_sec_start() */
 
 
 
 
static void
static void
fb_sec_end (void *dat)
fb_sec_end (void *dat)
{
{
  struct fb_state *fb = dat;
  struct fb_state *fb = dat;
  struct mem_ops ops;
  struct mem_ops ops;
 
 
  if (!fb->enabled)
  if (!fb->enabled)
    {
    {
      free (fb->filename);
      free (fb->filename);
      free (fb);
      free (fb);
      return;
      return;
    }
    }
 
 
  memset (&ops, 0, sizeof (struct mem_ops));
  memset (&ops, 0, sizeof (struct mem_ops));
 
 
  ops.readfunc32 = fb_read32;
  ops.readfunc32 = fb_read32;
  ops.writefunc32 = fb_write32;
  ops.writefunc32 = fb_write32;
  ops.write_dat32 = dat;
  ops.write_dat32 = dat;
  ops.read_dat32 = dat;
  ops.read_dat32 = dat;
 
 
  /* FIXME: Correct delay? */
  /* FIXME: Correct delay? */
  ops.delayr = 2;
  ops.delayr = 2;
  ops.delayw = 2;
  ops.delayw = 2;
 
 
  reg_mem_area (fb->baseaddr, FB_PAL + 256 * 4, 0, &ops);
  reg_mem_area (fb->baseaddr, FB_PAL + 256 * 4, 0, &ops);
 
 
  reg_sim_reset (fb_reset, dat);
  reg_sim_reset (fb_reset, dat);
}
}
 
 
void
void
reg_fb_sec ()
reg_fb_sec ()
{
{
  struct config_section *sec =
  struct config_section *sec =
    reg_config_sec ("fb", fb_sec_start, fb_sec_end);
    reg_config_sec ("fb", fb_sec_start, fb_sec_end);
 
 
  reg_config_param (sec, "baseaddr", paramt_addr, fb_baseaddr);
  reg_config_param (sec, "baseaddr",     PARAMT_ADDR, fb_baseaddr);
  reg_config_param (sec, "enabled", paramt_int, fb_enabled);
  reg_config_param (sec, "enabled",      PARAMT_INT,  fb_enabled);
  reg_config_param (sec, "refresh_rate", paramt_int, fb_refresh_rate);
  reg_config_param (sec, "refresh_rate", PARAMT_INT,  fb_refresh_rate);
  reg_config_param (sec, "txfile", paramt_str, fb_filename);
  reg_config_param (sec, "txfile",       PARAMT_STR,  fb_filename);
  reg_config_param (sec, "filename", paramt_str, fb_filename);
  reg_config_param (sec, "filename",     PARAMT_STR,  fb_filename);
}
}
 
 

powered by: WebSVN 2.1.0

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