GP32 Mr.mirkos Sdk Replacement


Bug: example.dma_trippelbuffer never shows one frame.

Code:
  gp_SetView(framebuffer1);        	// Display of Screen 1
  gp_DMA0Memcopy(background,framebuffer3,320*240);  	// Clear Screen 3
  gp_DMA1Wait();            // wait until clear of sreen 3 is finish
  gp_SetFont8(30,100,13,"Iam Screen 2 ",0xF800,framebuffer2);	// Painting on Screen 2
  for (x=0;x<9000000;x++) x=x; 

  gp_SetView(framebuffer2);        	// Display of Screen 2
  gp_DMA1Memcopy(background,framebuffer1,320*240);  	// Clear Screen 1
  gp_DMA0Wait();            // wait until clear of sreen 3 is finish
  gp_SetFont8(30,110,13,"Iam Screen 3 ",0xF800,framebuffer3);	// Painting on Screen 3
  for (x=0;x<9000000;x++) x=x;
    
  gp_SetView(framebuffer3);        	// Display of Screen 3
  gp_DMA0Memcopy(background,framebuffer2,320*240);  	// Clear Screen 2
  gp_DMA1Wait();            // wait until clear of sreen 1 is finish
  gp_SetFont8(30,120,13,"Iam Screen 1 ",0xF800,framebuffer1);	// Painting on Screen 1
  for (x=0;x<9000000;x++) x=x;

  gp_SetView(framebuffer1);        	// Display of Screen 1
  gp_DMA1Memcopy(background,framebuffer3,320*240);  	// Clear Screen 3
  gp_DMA0Wait();            // wait until clear of sreen 3 is finish
  gp_SetFont8(30,100,13,"Iam Screen 2 ",0xF800,framebuffer2);	// Painting on Screen 2
  for (x=0;x<9000000;x++) x=x; 

  gp_SetView(framebuffer2);        	// Display of Screen 2
  gp_DMA0Memcopy(background,framebuffer1,320*240);  	// Clear Screen 1
  gp_DMA1Wait();            // wait until clear of sreen 3 is finish
  gp_SetFont8(30,110,13,"Iam Screen 3 ",0xF800,framebuffer3);	// Painting on Screen 3
  for (x=0;x<9000000;x++) x=x;

  gp_SetView(framebuffer3);        	// Display of Screen 3
  gp_DMA1Memcopy(background,framebuffer2,320*240);  	// Clear Screen 2
  gp_DMA0Wait();            // wait until clear of sreen 1 is finish
  gp_SetFont8(30,120,13,"Iam Screen 1 ",0xF800,framebuffer1);	// Painting on Screen 1
  for (x=0;x<9000000;x++) x=x;

should work fine. i will post an switch function later.


Note: This 'Bug' Takes only at high framerates effect. It causes from the point that the tribble buffer have to use two dma channels. dmaXWait always blend out one frame.
 
SDK 0.80 ready :)


- rewritten and changed most prototypes, for better "understanding"
- switched to newest zlib
- rewrote cpuclock part ( more clockrates, and better timing )
- rewrote grafik part ( you can now select your Framerate in Hz )
..ref=gp_initFramebuffer(framebuffer,16,85);
..sets the Refreshrate to 85 Hz
..ref returns the "real setted" refreshrate.
..so its now possible to programm very accurate scrolling
- The vsync is now 100% perfect, if you suffered from "flicky" display
..you can use:
..gp_setFramebuffer(framebuffer,1);
..1 = wait for vsync ( works 100% perfect )
- Soundpart gives correct sound on every cpuclock now ( hope so )
- and a looot more, read the pdf

http://mirkoroller.de/gp32
 
Tharo posted on May 10 2004 at 10:14 AM said:
Bug: example.dma_trippelbuffer never shows one frame.

Code:
  gp_SetView(framebuffer1);        	// Display of Screen 1
  gp_DMA0Memcopy(background,framebuffer3,320*240);  	// Clear Screen 3
  gp_DMA1Wait();            // wait until clear of sreen 3 is finish
  gp_SetFont8(30,100,13,"Iam Screen 2 ",0xF800,framebuffer2);	// Painting on Screen 2
  for (x=0;x<9000000;x++) x=x; 

  gp_SetView(framebuffer2);        	// Display of Screen 2
  gp_DMA1Memcopy(background,framebuffer1,320*240);  	// Clear Screen 1
  gp_DMA0Wait();            // wait until clear of sreen 3 is finish
  gp_SetFont8(30,110,13,"Iam Screen 3 ",0xF800,framebuffer3);	// Painting on Screen 3
  for (x=0;x<9000000;x++) x=x;
    
  gp_SetView(framebuffer3);        	// Display of Screen 3
  gp_DMA0Memcopy(background,framebuffer2,320*240);  	// Clear Screen 2
  gp_DMA1Wait();            // wait until clear of sreen 1 is finish
  gp_SetFont8(30,120,13,"Iam Screen 1 ",0xF800,framebuffer1);	// Painting on Screen 1
  for (x=0;x<9000000;x++) x=x;

  gp_SetView(framebuffer1);        	// Display of Screen 1
  gp_DMA1Memcopy(background,framebuffer3,320*240);  	// Clear Screen 3
  gp_DMA0Wait();            // wait until clear of sreen 3 is finish
  gp_SetFont8(30,100,13,"Iam Screen 2 ",0xF800,framebuffer2);	// Painting on Screen 2
  for (x=0;x<9000000;x++) x=x; 

  gp_SetView(framebuffer2);        	// Display of Screen 2
  gp_DMA0Memcopy(background,framebuffer1,320*240);  	// Clear Screen 1
  gp_DMA1Wait();            // wait until clear of sreen 3 is finish
  gp_SetFont8(30,110,13,"Iam Screen 3 ",0xF800,framebuffer3);	// Painting on Screen 3
  for (x=0;x<9000000;x++) x=x;

  gp_SetView(framebuffer3);        	// Display of Screen 3
  gp_DMA1Memcopy(background,framebuffer2,320*240);  	// Clear Screen 2
  gp_DMA0Wait();            // wait until clear of sreen 1 is finish
  gp_SetFont8(30,120,13,"Iam Screen 1 ",0xF800,framebuffer1);	// Painting on Screen 1
  for (x=0;x<9000000;x++) x=x;

should work fine. i will post an switch function later.


Note: This 'Bug' Takes only at high framerates effect. It causes from the point that the tribble buffer have to use two dma channels. dmaXWait always blend out one frame.
if its not too mutch trouble, can you use the new SDK080, and
post your work again ?
I will add it then ( with your name ) in my 081 release..

You can ( for example ) now use 4 DMA channels at once :) ( if youre not using sound at the same time )
 
Last edited by a moderator:
Im working on some smart x-buffer functions that alows the user to generate so much buffers as the user want.

I will publish the alpha blend function then, too.



For your dma functions i wish an global flag that shows "if sound used or not??" so that it is possible to make some choices.
 
Tharo posted on May 10 2004 at 11:54 AM said:
Im working on some smart x-buffer functions that alows the user to generate so much buffers as the user want.

I will publish the alpha blend function then, too.



For your dma functions i wish an global flag that shows "if sound used or not??" so that it is possible to make some choices.
yeh, i can create a

char gp_checkSound()

returns 1 on DMA 2,3 is in use
returns 0 on DMA 0,1,2,3 is free for use.

what about the sprite format, should i change the header for your
alpha blend ?

its now :

typedef struct {
char magic[4];
u16 x;
u16 y;
} SHEADER;

should we add one or two u16 here ?
 
Last edited by a moderator:
Hmm. That function would be great.

Yes you can add one char for the alpha value. its only 5 bit long (more makes no sense -.-)

But i will defenitive make an functions that works with alpha maps, too. This is an easier way to make blend animations.
 
Tharo posted on May 10 2004 at 01:56 PM said:
Hmm. That function would be great.

Yes you can add one char for the alpha value. its only 5 bit long (more makes no sense -.-)

But i will defenitive make an functions that works with alpha maps, too. This is an easier way to make blend animations.
typedef struct {
char magic[4];
u16 x;
u16 y;
u16 alpha;
} SHEADER;

so the header is now 10 bytes long, easy to remember for me :)
 
Last edited by a moderator:
Tharo posted on May 10 2004 at 03:51 PM said:
Alpha should be a pointer, then.
use
u16 alpha
as a value, not a pointer, you can use only the 5 Bit you need,
but
(suggestion)
how a bout 1 alpha channel, supporting RGB ?
So its possible to effect only R or only G elements ?

but please dont use a pointer, it makes the thing, later for the
user to difficult.
 
Last edited by a moderator:
So i need 5 bit per pixel ^^
Alpha sould be a pointer to the alpha mask of the picture. Or we need an complete different picture format ..

and an very good skilled photoshop or png compatible morph tool.

I got the X-Screen to work. 10-Buffered games are neet ;). I made an DMA and an non dma version. The non dma version is about 4 times quicker.
We (the irc channel and i) dont know excatly where the problem with DMA is, but it seems to be difficult to fix it. Its not the fault of DMA*WAIT() ... without this command its still terrible slow.


Code:
#include <stdio.h>      // beide für "printf"
#include <stdarg.h>
#include "gp32.h"

// DEFINES
#define BUFFERS 5  	// How deep do we buffer the screen?

// GOBALS
u16 *framebuffer[BUFFERS];  // unsere buffer
u16 *background;    // background
char swapper=0;    	// swap variable

// Externals
extern unsigned char cute[];


//---------------------------------------------------------------------------------------------------
// Printf emulation.
void wt_printf(int x, int y, int color, u16* screen, const char *a_fmtstr, ...) { 
    va_list argptr;
    char buffer[256]; 
	int len;

    va_start(argptr, a_fmtstr); 
    vsprintf(buffer, a_fmtstr, argptr); 
    va_end(argptr);

	for(len=0; buffer[len]!='\0'; ++len) len=len;

	gp_drawString(x, y, len, buffer, color, screen);
}
//---------------------------------------------------------------------------------------------------


void wt_initLayers(void) {
	int i;
  // Real Framebuffers
	for(i=0; i<2; i++) framebuffer[i] = (u16*) (FRAMEBUFFER + (320*240*2*i));
  // DMA Framebuffers
	for(i=2; i<BUFFERS; i++) framebuffer[i] = (u16*) malloc (320*240*2);

	background  = (u16*) malloc (320*240*2);
}

u16* wt_flip() {
	u8 future;
  //Zeige das JETZTIGE Bild an.
	gp_setFramebuffer(framebuffer[swapper], 1);
  //Setze das NEUE Bild
	if(++swapper==BUFFERS) swapper=0;

  //Berechne das NÄCHSTE Bild
	if((swapper+1)==BUFFERS) future = 0;
	else future=swapper+1;
	memcpy(framebuffer[future], background, 320*240*2);

  //Gib das NEUE Bild zurück
	return framebuffer[swapper];
}


int main() {
	u16 *screen;  // Buffer den wir gerade benutzen

	wt_initLayers();
	gp_setCpuspeed(66);
	gp_initFramebuffer(framebuffer[0], 16, 100);
	gp_initButton();
 
	gp_drawSpriteHT((short*)cute, 0, 0, background, 0x8340);
  
	while (1) {
  screen = wt_flip();

  wt_printf(8, 8, 0xF800, screen, "Iam Screen %i/%i", (swapper+1), BUFFERS);
  if(gp_getButton() & BA) gp_Reset();
	}
	
}
 
It seems that this is the new Header Format now:

typedef struct {
char magic[4];
u16 x;
u16 y;
u8 version;
u8 reserved
} SHEADER;


version flags:

bit 0-4
1=u16 RGB Data RRRRRGGG GGBB BBB-
2=u16 GBR Data uuhm, i forgot -.-
3=u16 RGB Data + Alpha Mask RRRR RGGG GGBB BBB-
A -333 3322 2221 1111
4=u32 ARGB Data ---- ---- ---A AAAA RRR RGGG GGBB BBB-
5=u32 RGAB Data ---- --RR RRR- ---- GGG GAAA AABB BBB-

bit 5
rotated data or not rotated


I for myself thing it is strongly recomed to save this infomations into the header. The speed diference between thoos data types is extremly hight when you use alot of alpha blending.
 
Okay, we now use a new Sprite Format, i update bmp2raw to fit the new spect soon.
Also Tharo release a Alphablending soon, working with this new Sprite format.


Code:
typedef struct {
 char magic[4];
 u16 size_x;
 u16 size_y;
 u8 info;
 u8 data;    
} SHEADER;

info :[0-4]   00000 RGB 16 Format RRRRRGGGGGBBBBB0   normal sprite data
              00001 reserved 
              00010 ARGB Data ---- ---- ---A AAAA RRRR RGGG GGBB BBB-
              00011 free for you ...
              11111  "

reserved: 5      reserved           
info: 6          0 Sprite is rotated  ( 90 deg )
                 1 Sprite is not rotated  
alphaenable: 7   0 Alpha disable
                 1 Alpha enabled
 
Helllooo.
The png2h tool (alpha) is released.

Commands:

Usage: png2h [-<options>] infile outfile
Options:
-h n Header Type. (0=None, 1=Mirko Header, 2=Mirko Header+), default=0
-r 0/1 Rotate the image data 90° in clock direction. default=0
-f n Data Structure inside the source file:
1=u16 RGB Data RRRR RGGG GGBB BBB-
4=u32 ARGB Data ---- ---- ---A AAAA RRRR RGGG GGBB BBB-
default=1


Right. For now it only supports two modes .. The other modes and source comes later in some weeks (promise)

It is a jar file so start it with something like "java -jar png2h". If you got problems to start the programm please post into this Thread so that i can fix it or write a good readme file.

The png2h was only tested at 21Bit images for now. Maybe the rotation 1 is wrong.

http://134.155.59.2/~ck/mirror/png2h.jar


okay. :ph34r: [edit]
Time for the code :)

Code:
// macro
#define RGB(x, y, z) ( (x) << 11 | (y) << 6 | (z) << 1 | (0) )
#define GETA(x) ( ((x) >> 16) & 0x1F )
#define GETR(x) ( ((x) >> 11) & 0x1F )
#define GETG(x) ( ((x) >> 6)  & 0x1F )
#define GETB(x) ( ((x) >> 1)  & 0x1F )

// Alpha table
 char __attribute__((__aligned__(4))) alpha_table[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
	0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 
	0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 
	0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 
	0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 
	0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 
	0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 
	0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 
	0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8, 9, 9, 
	0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 
	0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 
	0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 
	0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 
	0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 
	0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 
	0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 
	0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 
	0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 18, 
	0, 1, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 15, 15, 16, 17, 17, 18, 18, 19, 
	0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 15, 16, 17, 17, 18, 19, 19, 20, 
	0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20, 20, 21, 
	0, 1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 11, 12, 13, 13, 14, 15, 16, 16, 17, 18, 18, 19, 20, 21, 21, 22, 
	0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11, 12, 13, 13, 14, 15, 16, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23, 
	0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23, 24, 
	0, 1, 2, 2, 3, 4, 5, 6, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 23, 24, 25, 
	0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 13, 13, 14, 15, 16, 17, 18, 18, 19, 20, 21, 22, 23, 23, 24, 25, 26, 
	0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 23, 24, 24, 25, 26, 27, 
	0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 25, 26, 27, 28, 
	0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 22, 23, 24, 25, 26, 27, 28, 29, 
	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 
	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
};


//---------------------------------------------------------------------------------------------------
// Prints an Alpha transparent picture. ARGB, not rotated data, header 1
void gp_putARGBSprite(u32 *sprite, short put_x, short put_y, u16 *framebuffer) {
	int xx, tx, yy, ty, i;
	SHEADER *sheader;
	u16 dest, tmp=0;
	u32 color;
	u8 alpha;

	(u16*) sheader = sprite;

	i=0; 
	alpha=0;

	for (yy=0; yy<(sheader->x); yy++)
  for (xx=0; xx<(sheader->y); xx++) {
  	color = sprite[2+i++];
  	alpha = GETA(color);

  	if(alpha!=0) {
    tx = put_x+xx;
    ty = put_y+yy;

    if ( !((tx<0) || (tx>319) || (ty<0) || (ty>239)) ) {
    	//alpha = xx >> 1;  // xx / 2;
    	

    	if(alpha<31) {
      // Yes we have alpha. plz calc it.
      dest =*(framebuffer +(239-ty)+(240*tx) );
  
      u8 *upper = (u8*)((u32)alpha_table +(alpha*32));
      u8 *down = (u8*)((u32)alpha_table + ((31-alpha)*32));

      tmp = (upper[GETR(color)]+down[GETR(dest)]) << 11;
      tmp |= (upper[GETG(color)]+down[GETG(dest)]) << 6;
      tmp |= (upper[GETB(color)]+down[GETB(dest)]) << 1;

      *(framebuffer +(239-ty)+(240*tx) ) = tmp;
    	}
    	else {  	
      // No alpha. plz just blend it.
      *(framebuffer +(239-ty)+(240*tx) ) = color;
    	}
    }
  	}
  }
}


Kay kay kay. That is the first function. It is written in the mirko SDK Style.
What comes next?
- Optimized function. Needs ca. 25% of thoose functions time.
- An "alpha map" function for use with an seperate alpha mask. this alows alpha animations later in your game.


Feetback please. Maybe there still some bugs.
 
Hi !

I have a good idea for next version(s): How about the possibility to control the volume of played samples.

Like this:
gp_playSample(add_buffer, add_size, volume, add_copyflag)

For the volume it would be enough to use the size of a byte - The MIDI-Standard has volumes from 0 to 127 and it's enough.

Greetings

Tobias
 
ConsoleTom posted on May 19 2004 at 01:02 PM said:
Hi !

I have a good idea for next version(s): How about the possibility to control the volume of played samples.

Like this:
gp_playSample(add_buffer, add_size, volume, add_copyflag)

For the volume it would be enough to use the size of a byte - The MIDI-Standard has volumes from 0 to 127 and it's enough.

Greetings

Tobias
a good idear, i keep it in mind, for my new mixer...
 
Last edited by a moderator:
i found a bug in you grafik module...
in 8bpp the LCD's reg setting are wrong...
Code:
short gp_initFramebuffer(u32 addr,u16 bitmode,u16 refreshrate) {
         u16 CLKVAL=3;
         u32 GPHCLK = gp_getHCLK();
                {
                u16 BPPMODE = 12;     // default 16 Bit
                //u16 CLKVAL = 3;     // change in low clockrates
                u16 ENVID = 1;    
                u16 MMODE = 0;
                u16 PNRMODE = 3;
                //unsigned int GPHCLK = gp_getHCLK();

                switch (bitmode) {
                  //case 16 : BPPMODE=12; break;
                  case  8 : BPPMODE=11; break;
                  case  4 : BPPMODE=10; break;
                  case  2 : BPPMODE= 9; break;
                  case  1 : BPPMODE= 8; break;
                }
                
                // Try to get the correct CLKVAL for refreshrate
                if (refreshrate <  50) refreshrate = 50;
                if (refreshrate > 120) refreshrate =120;
                CLKVAL = (GPHCLK/(83385*2*refreshrate))-1;
                if (CLKVAL == 0) CLKVAL=1;
                refreshrate = GPHCLK / (83385*2*(CLKVAL+1));

         rLCDCON1 = (CLKVAL<<8) | (MMODE<<7) | (PNRMODE<<5) | (BPPMODE<<1) | (ENVID<<0);
                }
                {
                u16 LINEVAL = 320-1;
                u16 VBPD = 1;
                u16 VFPD = 2;
                u16 VSPW = 1;
         rLCDCON2 = 0;
         rLCDCON2 = (VBPD<<24) | (LINEVAL<<14) | (VFPD<<6) | (VSPW<<0);
                }
                {
                //u16 HBPD = 6;
                u16 HBPD = 2;
                //u16 HFPD = 2;
                u16 HFPD = 6;  
                u16 HOZVAL = 240-1;
         rLCDCON3 = 0;
         rLCDCON3 = (HBPD<<19) | (HOZVAL<<8) | (HFPD<<0);
                }
                {
                u16 ADDVAL = 0;
                u16 HSPW = 4;
                u16 MVAL = 0;  
                u16 PALADDEN = 0;
         rLCDCON4 = 0;
         rLCDCON4 = (PALADDEN<<24) | (ADDVAL<<16) | (MVAL<<8) | (HSPW<<0);
                }
                {
                u16 BSWP = 0;    
                u16 ENLEND = 0;
                //u16 HSTATUS = 2;
                u16 HWSWP = 1;   
                u16 INVENDLINE = 0;
                u16 INVVCLK = 1;
                u16 INVVD = 0;
                u16 INVVDEN = 0;
                u16 INVVFRAME = 1;
                u16 INVVLINE = 1;
                //u16 VSTATUS = 2;
                u16 RESERVED4 = 0;
                //if (bitmode<16) { BSWP=1;HWSWP=0; }
         rLCDCON5 = 0;
         rLCDCON5 = (INVVCLK<<10) | (INVVLINE<<9) | (INVVFRAME<<8) | (INVVD<<7) | (INVVDEN<<6) 
                               | (INVENDLINE<<4) | (ENLEND<<2) | (BSWP<<1) | (HWSWP<<0);
                }
                {
                u32 LCDBANK  = (unsigned int)addr >> 22;
                u32 LCDBASEU = ((unsigned int)addr & 0x3FFFFF) >> 1;
                u32 LCDBASEL = LCDBASEU + 320*(bitmode == 16 ? 240 : 120);
                u16 OFFSIZE = 0;
                //u16 PAGEWIDTH = 240;
                u16 PAGEWIDTH = bitmode == 16 ? 240 : 120;
         rLCDSADDR1 = 0;
         rLCDSADDR2 = 0;
         rLCDSADDR3 = 0;
         rLCDSADDR1 = (LCDBANK<<21) | (LCDBASEU<<0);
         rLCDSADDR2 = (LCDBASEL<<0);
         rLCDSADDR3 = (OFFSIZE<<11) | (PAGEWIDTH<<0);
                }
                rTPAL = 0;

return refreshrate;
}

void gp_setFramebuffer(u32 addr,int vsync,int bitmode) {
                
                {
                u32 LCDBANK  = (unsigned int)addr >> 22;
                u32 LCDBASEU = ((unsigned int)addr & 0x3FFFFF) >> 1;
                u32 LCDBASEL = LCDBASEU + 320*(bitmode == 16 ? 240 : 120);
                u16 OFFSIZE = 0;
                u16 PAGEWIDTH = bitmode == 16 ? 240 : 120;
                //if (vsync) gp_waitVsync();
         rLCDSADDR1 = (LCDBANK<<21) | (LCDBASEU<<0);
         rLCDSADDR2 = (LCDBASEL<<0);
         rLCDSADDR3 = (OFFSIZE<<11) | (PAGEWIDTH<<0);
                if (vsync) gp_waitVsync();
                }

}
 
Hi all,

I'm new at GP32 developing, I was taking a look to some assembly files in Mr.Mirkos SDK and saw the 16bit screen clearing function. I realized it was using half-words to clear the buffer, but I think it would be faster to use words.

My proposed function:

gp_clearFramebuffer16:
// r0 = framebuffer
// r1 = color
orr r1, r1, r1, lsl #16 // getting ready for word filling hi-halfword(r1)=lo-halfword(r1)

mov r2, #(320*240*2) // r2 = bytes to be written

tst r0, #2 // check if word aligned
beq word_aligned

subs r2, r2, #4 // decrease byte counter
strh r1, [r0], #2 // fill first buffer's halfword, and assure it's now word aligned
strh r1, [r0, r2] // fill last buffer's halfword (buffer offset+(320*240*2)+2-4)=r1

word_aligned:


clear: str r1, [r0], #4 // clear two pixels, and increase r0 in 4 units
subs r2, r2, #4 // decrease byte counter (1 word = 4 bytes)
bne clear // continue till filling the buffer

bx lr // exit
 
Just a little thing I forget, add following line before the first routine instruction (orr r1, r1, r1, lsl #16), just after function name.

and r1,r1, #65535 // truncate r1 to a 16 bit vaule
 
bitrider posted on May 20 2004 at 02:10 PM said:
Hi all,

I'm new at GP32 developing, I was taking a look to some assembly files in Mr.Mirkos SDK and saw the 16bit screen clearing function. I realized it was using half-words to clear the buffer, but I think it would be faster to use words.

My proposed function:

gp_clearFramebuffer16:
// r0 = framebuffer
// r1 = color
orr r1, r1, r1, lsl #16 // getting ready for word filling hi-halfword(r1)=lo-halfword(r1)

mov r2, #(320*240*2) // r2 = bytes to be written

tst r0, #2 // check if word aligned
beq word_aligned

subs r2, r2, #4 // decrease byte counter
strh r1, [r0], #2 // fill first buffer's halfword, and assure it's now word aligned
strh r1, [r0, r2] // fill last buffer's halfword (buffer offset+(320*240*2)+2-4)=r1

word_aligned:


clear: str r1, [r0], #4 // clear two pixels, and increase r0 in 4 units
subs r2, r2, #4 // decrease byte counter (1 word = 4 bytes)
bne clear // continue till filling the buffer

bx lr // exit
A good idear using 2*16bit at once...

i change it, cant figure out if its faster, but it should... :)
 
Last edited by a moderator:
Back
Top