From 196633c670e0558c87acc83888e1fd41019328b0 Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Wed, 18 Nov 2009 08:11:22 +0000 Subject: [PATCH] Initial version Committed on the Free edition of March Hare Software CVSNT Server. Upgrade to CVS Suite for more features and support: http://march-hare.com/cvsnt/ git-svn-id: http://moon:8086/svn/vhdl/trunk@664 cc03376c-175c-47c8-b038-4cd826a8556b --- lib/CPUs/MIPS/bsp/examples/mips_gfx.c | 506 ++++++++++++++++++++++++++ lib/CPUs/MIPS/bsp/examples/mips_gfx.h | 60 +++ 2 files changed, 566 insertions(+) create mode 100644 lib/CPUs/MIPS/bsp/examples/mips_gfx.c create mode 100644 lib/CPUs/MIPS/bsp/examples/mips_gfx.h diff --git a/lib/CPUs/MIPS/bsp/examples/mips_gfx.c b/lib/CPUs/MIPS/bsp/examples/mips_gfx.c new file mode 100644 index 0000000..185c749 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/mips_gfx.c @@ -0,0 +1,506 @@ +#include +#include +#include +#include "libsys.h" +#include "mips_gfx.h" + +// ------------------------------------------------------------- +// Functions +// ------------------------------------------------------------- +void __gfx_block_set_8(UINT32* pDst, UINT32 value) +{ + __asm__ volatile + ( + "sw %[value], 0(%[pDst])\n" + "sw %[value], 4(%[pDst])\n" + "sw %[value], 8(%[pDst])\n" + "sw %[value], 12(%[pDst])\n" + "sw %[value], 16(%[pDst])\n" + "sw %[value], 20(%[pDst])\n" + "sw %[value], 24(%[pDst])\n" + "sw %[value], 28(%[pDst])\n" + : + : [pDst] "r" (pDst), [value] "r" (value) + ); +} + +void __gfx_block_copy_8(UINT32* pDst, UINT32* pSrc) +{ + __asm__ volatile + ( + ".set noreorder\n" + ".set nomacro\n" + "lw $s0, 0(%[pSrc])\n" + "lw $s1, 4(%[pSrc])\n" + "sw $s0, 0(%[pDst])\n" + "lw $s0, 8(%[pSrc])\n" + "sw $s1, 4(%[pDst])\n" + "lw $s1, 12(%[pSrc])\n" + "sw $s0, 8(%[pDst])\n" + "lw $s0, 16(%[pSrc])\n" + "sw $s1, 12(%[pDst])\n" + "lw $s1, 20(%[pSrc])\n" + "sw $s0, 16(%[pDst])\n" + "lw $s0, 24(%[pSrc])\n" + "sw $s1, 20(%[pDst])\n" + "lw $s1, 28(%[pSrc])\n" + "sw $s0, 24(%[pDst])\n" + "sw $s1, 28(%[pDst])\n" + ".set macro\n" + ".set reorder\n" + : + : [pDst] "r" (pDst), [pSrc] "r" (pSrc) + : "s0", "s1" + ); +} + +void __gfx_copy_32(UINT32* pDst, UINT32* pSrc, UINT32 nblocks) +{ + while (nblocks) + { + __gfx_block_copy_8(pDst, pSrc); + pDst += 8; + pSrc += 8; + nblocks--; + } + +} + +void GFX_DirtyRectSetClean(buf_t *pBuf) +{ + pBuf->rect.xmin = pBuf->w; + pBuf->rect.xmax = 0; + pBuf->rect.ymin = pBuf->h; + pBuf->rect.ymax = 0; + pBuf->is_dirty = 0; +} + +void GFX_DirtyRectInit(buf_t *pBuf, UINT32 w, UINT32 h) +{ + pBuf->w = w; + pBuf->h = h; + GFX_DirtyRectSetClean(pBuf); +} + +void GFX_DirtyRectUpdate(buf_t *pBuf, UINT32 xmin, UINT32 xmax, UINT32 ymin, UINT32 ymax) +{ + + if (xmin < pBuf->rect.xmin) + { + pBuf->is_dirty = 1; + pBuf->rect.xmin = xmin; + } + + if (xmax > pBuf->rect.xmax) + { + pBuf->is_dirty = 1; + pBuf->rect.xmax = xmax; + } + + if (ymin < pBuf->rect.ymin) + { + pBuf->is_dirty = 1; + pBuf->rect.ymin = ymin; + } + + if (ymax > pBuf->rect.ymax) + { + pBuf->is_dirty = 1; + pBuf->rect.ymax = ymax; + } + + if (pBuf->is_dirty && ((pBuf->rect.xmax-pBuf->rect.xmin)%8)) + pBuf->rect.xmax = pBuf->rect.xmin + ((pBuf->rect.xmax-pBuf->rect.xmin)/8 + 1) * 8; // Make len_x multiple of 8 + +} + +void GFX_DirtyRectCopy(buf_t *pBuf) +{ + UINT32 xmin, xmax, ymin, ymax, x, y; + UINT32 *pDst, *pDst_end; + UINT32 *pSrc, *pSrc_end; + + xmin = pBuf->rect.xmin; + xmax = pBuf->rect.xmax; + + ymin = pBuf->rect.ymin; + ymax = pBuf->rect.ymax; + + ymin *= pBuf->w; + ymax *= pBuf->w; + + if (!((xmax-xmin)%8)) + { + for (y=ymin; y < ymax; y += pBuf->w) + { + pSrc = &pBuf->pLast->pFB[xmin + y]; + pSrc_end = &pBuf->pLast->pFB[xmax + y]; + pDst = &pBuf->pFB[xmin + y]; + pDst_end = &pBuf->pFB[xmax + y]; + while(pDst < pDst_end) + { + __gfx_block_copy_8(pDst, pSrc); + pDst += 8; + pSrc += 8; + } + } + return; + } + +// fprintf(stderr, "GFX_DirtyRectCopy(): Slow copy!\n"); + for (y=ymin; y < ymax; y += pBuf->w) + { + for (x=xmin; x < xmax; x++) + { + pBuf->pFB[x + y] = pBuf->pLast->pFB[x + y]; + } + } +} + +void GFX_init(gfx_t *pObj) +{ + UINT32 volatile *pVGA_ctrl = (UINT32*)SYS_VGA_CTRL; + UINT32 volatile *pVGA_moffs_0 = (UINT32*)SYS_VGA_FB_FRONT; + UINT32 volatile *pVGA_moffs_1 = (UINT32*)SYS_VGA_FB_BACK; + + int i; + buf_t *pBuf; + UINT32 w, h, fps; + + *pVGA_ctrl &= ~SYS_VGA_BIT_MSTEN; + + w = Screen_get_resx(); + h = Screen_get_resy(); + fps = Screen_get_fps(); + + printf("VGA screen = %d x %d @ %d fps\n", w, h, fps); + + pObj->w = w; + pObj->h = h; + + // Init buffers + pObj->pBuf = (buf_t*)calloc(1, sizeof(buf_t)); + pBuf = pObj->pBuf; + pBuf->pFB = (UINT32*)calloc((w+8) * h, sizeof(UINT32)); // w+8 because of dirty rectangle 8 byte min. x-size + for (i=1; i < GFX_NUM_FRAME_BUFFERS; i++) + { + + pBuf->pNext = (buf_t*)calloc(1, sizeof(buf_t)); + pBuf->pNext->pLast = pBuf; + pBuf = pBuf->pNext; + pBuf->pFB = (UINT32*)calloc((w+8) * h, sizeof(UINT32)); // w+8 because of dirty rectangle 8 byte min. x-size + } + pObj->pBuf->pLast = pBuf; + pBuf->pNext = pObj->pBuf; + + pBuf = pObj->pBuf; + for (i=0; i < GFX_NUM_FRAME_BUFFERS; i++) + { + GFX_DirtyRectInit(pBuf, w, h); + +// fprintf(stderr, "pBuf = %08X, pLast = %08X, pNext = %08X\n", pBuf, pBuf->pLast, pBuf->pNext); + pBuf = pBuf->pNext; + } + + *pVGA_moffs_0 = (UINT32)pObj->pBuf->pLast->pFB; + *pVGA_moffs_1 = (UINT32)pObj->pBuf->pLast->pFB; + *pVGA_ctrl |= SYS_VGA_BIT_MSTEN; + + +} + +void GFX_set_background(gfx_t *pObj, UINT32 *pImage, UINT32 image_nx, UINT32 image_ny, UINT32 image_scale_x, UINT32 image_scale_y) +{ + + UINT32 off_x, off_y; + UINT32 i, j; + UINT32 *pScr, *pImg; + buf_t *pBuf; + + if (!pImage) + return; + + off_x = (pObj->w-(image_scale_x*image_nx))/2; + off_y = (pObj->h-(image_scale_y*image_ny))/2; + + pBuf = pObj->pBuf; + + pScr = ((UINT32*)pBuf->pFB) + pObj->w*off_y + off_x; + pImg = pImage; + + for (i=0; i < image_ny*image_nx; i += 8) + { + __gfx_block_copy_8(pScr, pImg); + pScr += 8; + pImg += 8; + } + + do + { + GFX_DirtyRectUpdate(pBuf, 0, pObj->w, 0, pObj->h); + pBuf = pBuf->pNext; + + } while(pBuf != pObj->pBuf); + + +} + +void GFX_frame(gfx_t *pObj, UINT32 sync_mode) +{ + UINT32 volatile *pVGA_moffs_0 = (UINT32*)SYS_VGA_FB_FRONT; + + // Wait until back buffer becomes front + if (sync_mode == GFX_FRAME_SYNC) + { + while(*pVGA_moffs_0 == (UINT32)pObj->pBuf->pFB); + } + + GFX_copy_front2back(pObj); + +} + +void GFX_show(gfx_t *pObj) +{ + UINT32 volatile *pVGA_moffs_1 = (UINT32*)SYS_VGA_FB_BACK; + + *pVGA_moffs_1 = (UINT32)pObj->pBuf->pFB; + pObj->pBuf = pObj->pBuf->pNext; + +} + +void GFX_copy_front2back(gfx_t *pObj) +{ + buf_t *pBuf; + + pBuf = pObj->pBuf; + + // Lopp over all frame buffers, except front buffer + while(pBuf != pObj->pBuf->pLast) + { + if (pBuf->is_dirty) + { +// fprintf(stderr, "Dirty rect [%08X]: w=%d, h=%d\n", (int)pBuf, pBuf->rect.xmax - pBuf->rect.xmin, pBuf->rect.ymax - pBuf->rect.ymin); + GFX_DirtyRectCopy(pBuf); + GFX_DirtyRectSetClean(pBuf); + } + pBuf = pBuf->pNext; + } +} + +void GFX_copy_back2front(gfx_t *pObj) +{ +} + +void GFX_get_FB_front(gfx_t *pObj, UINT32 **ppFB) +{ + *ppFB = pObj->pBuf->pLast->pFB; +} + +void box_create(box_t *pObj, UINT32 w, UINT32 h) +{ + pObj->pSave = malloc(w*h*sizeof(UINT32)); + pObj->w = w; + pObj->h = h; +} + +void GFX_save(gfx_t *pObj, box_t *pBox, UINT32 posx, UINT32 posy) +{ + UINT32 xmin, xmax, ymin, ymax, x, y; + UINT32 *pFB, *pFB_end, *pSave; + + xmin = posx; + xmax = pBox->w + posx; + if (xmax > pObj->w) + xmax = pObj->w; + + ymin = pObj->w*posy; + ymax = pBox->h + posy; + if (ymax > pObj->h) + ymax = pObj->h; + + ymax *= pObj->w; + pSave = pBox->pSave; + + if (!((xmax-xmin)%8)) + { + for (y=ymin; y < ymax; y += pObj->w) + { + pFB = &pObj->pBuf->pFB[xmin + y]; + pFB_end = &pObj->pBuf->pFB[xmax + y]; + while(pFB < pFB_end) + { + __gfx_block_copy_8(pSave, pFB); + pFB += 8; + pSave += 8; + } + } + return; + } + +// fprintf(stderr, "GFX_save(): Slow copy!\n"); + for (y=ymin; y < ymax; y += pObj->w) + { + for (x=xmin; x < xmax; x++) + { + *(pSave++) = pObj->pBuf->pFB[x + y]; + } + } +} + +void GFX_restore(gfx_t *pObj, box_t *pBox, UINT32 posx, UINT32 posy) +{ + UINT32 xmin, xmax, ymin, ymax, x, y; + UINT32 *pFB, *pFB_end, *pSave; + buf_t *pBuf; + + xmin = posx; + xmax = pBox->w + posx; + if (xmax > pObj->w) + xmax = pObj->w; + + ymin = posy; + ymax = pBox->h + posy; + if (ymax > pObj->h) + ymax = pObj->h; + + pBuf = pObj->pBuf->pNext; + + // Lopp over all frame buffers, except current back buffer + while(pBuf != pObj->pBuf) + { + GFX_DirtyRectUpdate(pBuf, xmin, xmax, ymin, ymax); + pBuf = pBuf->pNext; + + } + pBuf = pObj->pBuf; + + ymin *= pObj->w; + ymax *= pObj->w; + pSave = pBox->pSave; + + if (!((xmax-xmin)%8)) + { + for (y=ymin; y < ymax; y += pObj->w) + { + pFB = &pBuf->pFB[xmin + y]; + pFB_end = &pBuf->pFB[xmax + y]; + while(pFB < pFB_end) + { + __gfx_block_copy_8(pFB, pSave); + pFB += 8; + pSave += 8; + } + } + return; + } + +// fprintf(stderr, "GFX_restore(): Slow copy!\n"); + for (y=ymin; y < ymax; y += pObj->w) + { + for (x=xmin; x < xmax; x++) + { + pBuf->pFB[x + y] = *(pSave++); + } + } +} + +void GFX_box_draw(gfx_t *pObj, box_t *pBox, UINT32 posx, UINT32 posy, UINT32 color) +{ + UINT32 xmin, xmax, ymin, ymax, x, y; + UINT32 *pFB, *pFB_end; + buf_t *pBuf; + + xmin = posx; + xmax = pBox->w + posx; + if (xmax > pObj->w) + xmax = pObj->w; + + ymin = posy; + ymax = pBox->h + posy; + if (ymax > pObj->h) + ymax = pObj->h; + + pBuf = pObj->pBuf->pNext; + + // Lopp over all frame buffers, except current back buffer + while(pBuf != pObj->pBuf) + { + GFX_DirtyRectUpdate(pBuf, xmin, xmax, ymin, ymax); + pBuf = pBuf->pNext; + + } + pBuf = pObj->pBuf; + + ymin *= pObj->w; + ymax *= pObj->w; + + if (!((xmax-xmin)%8)) + { + for (y=ymin; y < ymax; y += pObj->w) + { + pFB = &pBuf->pFB[xmin + y]; + pFB_end = &pBuf->pFB[xmax + y]; + while(pFB < pFB_end) + { + __gfx_block_set_8(pFB, color); + pFB += 8; + } + } + return; + } + +// fprintf(stderr, "GFX_box_draw(): Slow copy!\n"); + for (y=ymin; y < ymax; y += pObj->w) + { + for (x=xmin; x < xmax; x++) + { + pBuf->pFB[x + y] = color; + } + } +} + +void GFX_box_draw_direct(gfx_t *pObj, box_t *pBox, UINT32 posx, UINT32 posy, UINT32 color) +{ + UINT32 xmin, xmax, ymin, ymax, x, y; + UINT32 *pFB, *pFB_end; + buf_t *pBuf; + + pBuf = pObj->pBuf->pLast; + + xmin = posx; + xmax = pBox->w + posx; + if (xmax > pObj->w) + xmax = pObj->w; + + ymin = posy; + ymax = pBox->h + posy; + if (ymax > pObj->h) + ymax = pObj->h; + + ymin *= pObj->w; + ymax *= pObj->w; + + if (!((xmax-xmin)%8)) + { + for (y=ymin; y < ymax; y += pObj->w) + { + pFB = &pBuf->pFB[xmin + y]; + pFB_end = &pBuf->pFB[xmax + y]; + while(pFB < pFB_end) + { + __gfx_block_set_8(pFB, color); + pFB += 8; + } + } + return; + } + +// fprintf(stderr, "GFX_box_draw_direct(): Slow copy!\n"); + for (y=ymin; y < ymax; y += pObj->w) + { + for (x=xmin; x < xmax; x++) + { + pBuf->pFB[x + y] = color; + } + } +} diff --git a/lib/CPUs/MIPS/bsp/examples/mips_gfx.h b/lib/CPUs/MIPS/bsp/examples/mips_gfx.h new file mode 100644 index 0000000..2ebcdb4 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/mips_gfx.h @@ -0,0 +1,60 @@ +#ifndef GFX_H +#define GFX_H + +#include "libsys.h" + +#define GFX_NUM_FRAME_BUFFERS 2 +#define GFX_FRAME_NOSYNC 0 +#define GFX_FRAME_SYNC 1 + +// ------------------------------------------------------------- +// Types +// ------------------------------------------------------------- +typedef struct _sbox_t +{ + UINT32 w, h; + UINT32 *pSave; +} box_t; + +typedef struct _srect_t +{ + UINT32 xmin, xmax; + UINT32 ymin, ymax; +} rect_t; + +typedef struct _sbuf_t +{ + UINT32 *pFB; + struct _sbuf_t *pNext; + struct _sbuf_t *pLast; + UINT32 is_dirty; + rect_t rect; + UINT32 w, h; +} buf_t; + +typedef struct _sgfx_t +{ + UINT32 w, h; + buf_t *pBuf; + UINT32 *pBG; + +} gfx_t; + +// ------------------------------------------------------------- +// Functions +// ------------------------------------------------------------- +void __gfx_block_set_8(UINT32* pDst, UINT32 value); +void __gfx_block_copy_8(UINT32* pDst, UINT32* pSrc); +void __gfx_copy_32(UINT32* pDst, UINT32* pSrc, UINT32 nblocks); +void GFX_init(gfx_t *pObj); +void GFX_frame(gfx_t *pObj, UINT32 sync_mode); +void GFX_show(gfx_t *pObj); +void GFX_copy_front2back(gfx_t *pObj); +void GFX_copy_back2front(gfx_t *pObj); +void GFX_get_FB_front(gfx_t *pObj, UINT32 **ppFB); +void box_create(box_t *pObj, UINT32 w, UINT32 h); +void GFX_save(gfx_t *pObj, box_t *pBox, UINT32 posx, UINT32 posy); +void GFX_restore(gfx_t *pObj, box_t *pBox, UINT32 posx, UINT32 posy); +void GFX_box_draw(gfx_t *pObj, box_t *pBox, UINT32 posx, UINT32 posy, UINT32 color); + +#endif // GFX_H