URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [branches/] [stable_0_1_x/] [or1ksim/] [peripheral/] [fb.c] - Rev 647
Go to most recent revision | Compare with Previous | Blame | View Log
/* fb.c -- Simple frame buffer Copyright (C) 2001 Marko Mlinar, markom@opencores.org This file is part of OpenRISC 1000 Architectural Simulator. 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 Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <stdio.h> #include "sim-config.h" #include "abstract.h" #include "fb.h" static unsigned char buffer[FB_SIZEY * FB_SIZEX]; static unsigned long pal[256]; static int fb_pic; static int fb_cycles; /* Variable to screen buffer. */ struct dev_memarea *buf_area; static unsigned long fb_addr; /* Write a register */ void fb_buf_write8 (unsigned long addr, unsigned long value) { int a = addr - fb_addr; if (a < 0 || a >= FB_SIZEY * FB_SIZEX) { fprintf (stderr, "Write out of screen buffer (0x%08x)!\n", addr); cont_run = 0; } else buffer[a] = value; } /* Read a register */ unsigned long fb_buf_read8 (unsigned long addr) { int a = (addr - fb_addr); if (a < 0 || a >= FB_SIZEY * FB_SIZEX) { fprintf (stderr, "Read out of screen buffer (0x%08x)!\n", addr); cont_run = 0; return 0; } else return buffer[a]; } static void change_buf_addr (unsigned long addr) { unsigned long size_mask = bit_mask (FB_SIZEX * FB_SIZEY); unsigned long addr_mask = ~size_mask; buf_area->addr_mask = addr_mask; buf_area->addr_compare = addr & addr_mask; fb_addr = addr; } /* Write a register */ void fb_write32 (unsigned long addr, unsigned long value) { int a = (addr - config.fb.baseaddr); switch (a) { case FB_CTRL: break; case FB_BUFADDR: change_buf_addr (value); break; default: a -= FB_PAL; a /= 4; if (a < 0 || a >= 256) { fprintf (stderr, "Write out of palette buffer (0x%08x)!\n", addr); cont_run = 0; } else pal[a] = value; break; } } /* Read a register */ unsigned long fb_read32 (unsigned long addr) { int a = (addr - config.fb.baseaddr); switch (a) { case FB_CTRL: return 0; break; case FB_BUFADDR: return fb_addr; break; default: a -= FB_PAL; a /= 4; if (a < 0 || a >= 256) { fprintf (stderr, "Read out of palette buffer (0x%08x)!\n", addr); cont_run = 0; return 0; } else return pal[a]; } } /* define these also for big endian */ #define CNV16(x) (x) #define CNV32(x) (x) /* Dumps a bmp file, based on current image */ static int fb_dump_image (char *filename) { int sx = FB_SIZEX; int sy = FB_SIZEY; int i, x, y; FILE *fo; unsigned short int u16; unsigned long int u32; if (config.sim.verbose) printf ("Creating %s...", filename); fo = fopen (filename, "wb+"); u16 = CNV16(19778); /* BM */ if (!fwrite (&u16, 2, 1, fo)) return 1; u32 = CNV32(14 + 40 + sx * sy + 1024); /* size */ if (!fwrite (&u32, 4, 1, fo)) return 1; u32 = CNV32(0); /* reserved */ if (!fwrite (&u32, 4, 1, fo)) return 1; u32 = 14 + 40 + 1024; /* offset */ if (!fwrite (&u32, 4, 1, fo)) return 1; u32 = CNV32(40); /* header size */ if (!fwrite (&u32, 4, 1, fo)) return 1; u32 = CNV32(sx); /* width */ if (!fwrite (&u32, 4, 1, fo)) return 1; u32 = CNV32(sy); /* height */ if (!fwrite (&u32, 4, 1, fo)) return 1; u16 = CNV16(1); /* planes */ if (!fwrite (&u16, 2, 1, fo)) return 1; u16 = CNV16(8); /* bits */ if (!fwrite (&u16, 2, 1, fo)) return 1; u32 = CNV32(0); /* compression */ if (!fwrite (&u32, 4, 1, fo)) return 1; u32 = CNV32(x * y); /* image size */ if (!fwrite (&u32, 4, 1, fo)) return 1; u32 = CNV32(0); /* x resolution */ if (!fwrite (&u32, 4, 1, fo)) return 1; u32 = CNV32(0); /* y resolution */ if (!fwrite (&u32, 4, 1, fo)) return 1; u32 = CNV32(0); /* ncolours = 0; should be generated */ if (!fwrite (&u32, 4, 1, fo)) return 1; u32 = CNV32(0); /* important colours; all are important */ if (!fwrite (&u32, 4, 1, fo)) return 1; for (i = 0; i < 256; i++) { unsigned long val, d; d = pal[i]; val = ((d >> 12) & 0xf) << 0 + 4; /* Blue */ val |= ((d >> 8) & 0xf) << 8 + 4; /* Green */ val |= ((d >> 4) & 0xf) << 16 + 4; /* Red */ val = CNV32(pal[i]); if (!fwrite (&val, 4, 1, fo)) return 1; } if (config.sim.verbose) printf ("(%i,%i)", sx, sy); /* Data is stored upside down */ for (y = sy - 1; y >= 0; y--) { int align = (4 - sx) % 4; int zero = CNV32(0); while (align < 0) align += 4; for (x = 0; x < sx; x++) fputc (buffer[y * sx + x], fo); if (align && !fwrite (&zero, align, 1, fo)) return 1; } if (config.sim.verbose) printf ("DONE\n"); fclose (fo); return 0; } /* Reset all VGAs */ void fb_reset () { int i; if (config.fb.enabled) { fb_pic = 0; fb_cycles = 0; for (i = 0; i < 256; i++) pal[i] = (i << 16) | (i << 8) | (i << 0); register_memoryarea(config.fb.bufaddr, FB_SIZEX * FB_SIZEY, 1, fb_buf_read8, fb_buf_write8); buf_area = cur_area; if (config.fb.baseaddr) register_memoryarea(config.fb.baseaddr, FB_PAL + 256*4, 4, fb_read32, fb_write32); } } /* Handles one VGA clock */ void fb_clock () { /* dump the image? */ if (fb_cycles++ >= config.fb.refresh_rate) { char temp[STR_SIZE]; sprintf (temp, "%s%04i.bmp", &config.fb.filename[0], fb_pic); fb_dump_image (temp); fb_cycles = 0; fb_pic++; } }
Go to most recent revision | Compare with Previous | Blame | View Log