gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > Background Problems?

#51650 - lewisrevill - Mon Aug 22, 2005 6:19 pm

Hey guys

Im programming in Mode 4 and having trouble displaying my background. Its dispays ok but you can see it being drawn and i want it to be instant. I just using "Frontbuffer" and a loop to display a backround.h file. Please can you help - Thank you

#51657 - tepples - Mon Aug 22, 2005 7:54 pm

There are two frame buffers in mode 4. If you want something to appear instantly, you'll have to 1. draw your image to the buffer that you're not displaying and then 2. use the page bit in DISPCNT to switch to the image you just drew.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#51726 - headspin - Tue Aug 23, 2005 5:17 am

Use DMACopy() instead of a loop to get an instant display of the image.
_________________
Warhawk DS | Manic Miner: The Lost Levels | The Detective Game

#51744 - poslundc - Tue Aug 23, 2005 6:38 am

headspin wrote:
Use DMACopy() instead of a loop to get an instant display of the image.


How d'you figure?

Dan.

#51745 - yamaneko - Tue Aug 23, 2005 7:26 am

Macro for the bits seting:
#define DMA_ENABLE 0x80000000
#define DMA_INTERUPT_ENABLE 0x40000000
#define DMA_TIMEING_IMMEDIATE 0x00000000
#define DMA_TIMEING_VBLANK 0x10000000
#define DMA_TIMEING_HBLANK 0x20000000
#define DMA_TIMEING_SYNC_TO_DISPLAY 0x30000000
#define DMA_16 0x00000000
#define DMA_32 0x04000000
#define GAME_PACK 0x08000000
#define DMA_REPEATE 0x02000000
#define DMA_SOURCE_INCREMENT 0x00000000
#define DMA_SOURCE_DECREMENT 0x00800000
#define DMA_SOURCE_FIXED 0x01000000
#define DMA_DEST_INCREMENT 0x00000000
#define DMA_DEST_DECREMENT 0x00200000
#define DMA_DEST_FIXED 0x00400000
#define DMA_DEST_RELOAD 0x00600000

Some DMA register:
#define REG_DM3SAD *(volatile u32*)0x40000D4
#define REG_DM3SAD_L *(volatile u16*)0x40000D4
#define REG_DM3SAD_H *(volatile u16*)0x40000D6
#define REG_DM3DAD *(volatile u32*)0x40000D8
#define REG_DM3DAD_L *(volatile u16*)0x40000D8
#define REG_DM3DAD_H *(volatile u16*)0x40000DA
#define REG_DM3CNT *(volatile u32*)0x40000DC
#define REG_DM3CNT_L *(volatile u16*)0x40000DC
#define REG_DM3CNT_H *(volatile u16*)0x40000DE

The function:
#define DMACopy(src,dest,count)\
REG_DM3SAD = (u32)src;\
REG_DM3DAD = (u32)dest;\
REG_DM3CNT = count | DMA_ENABLE | DMA_TIMEING_IMMEDIATE | DMA_32;\
while(REG_DM3CNT_H & 0x8000);\

#51779 - strager - Tue Aug 23, 2005 1:07 pm

yamaneko wrote:
The function:
#define DMACopy(src,dest,count)\
REG_DM3SAD = (u32)src;\
REG_DM3DAD = (u32)dest;\
REG_DM3CNT = count | DMA_ENABLE | DMA_TIMEING_IMMEDIATE | DMA_32;\
while(REG_DM3CNT_H & 0x8000);\


Code:
#define DMACopy(src,dst,siz) { \
REG_DM3SAD = (u32)(src); \
REG_DM3DAD = (u32)(dst); \
REG_DM3CNT = ((siz) >> 1) | DMA_ENABLE | \
DMA_TIMING_IMMEDIATE | DMA_32; \
}

#define DMACopyWait(src,dst,siz) {
DMACopy(src, dst, siz); \
while(REG_DM3CNT & DMA_ENABLE) \
    /* Wait */ \
}


This copies an array of [siz] size from [src] to [dst]. [siz] is the actual array size in bytes (but only bits 1-15 are used).

Copy from your buffer to the display, with buffer swapping:
Code:
// VBlank code, should work (pseudo)
static u16 *back_buffer = (u16 *)(0x06000000);

// ...

DISP_CNT ^= BUFFER_FLIP; // Flip render buffer

DMACopy(my_display_buffer, back_buffer, 240 * 160); // Copy to the back buffer

back_buffer = (u16 *)((u32)back_buffer ^ 0x0000A000); // Set the new back buffer for the next VBlank

#51844 - lewisrevill - Tue Aug 23, 2005 10:51 pm

Hey guys ive tried that double buffer but when the backbuffer is displayed it has a section of the image messed up! Also it wasnt an instant transition! Could someone please display some code including registers for double buffering? Thanks

#51870 - yamaneko - Wed Aug 24, 2005 6:33 am

//Some register for the flip function
#define DISP_CR *(u16*)0x4000000
#define BACKBUFFER 0x10

//There are the diferent register of video memory
//All the time write in VideoBuffer!
u16 *VideoBuffer = (u16*)0x6000000;
u16 *VideoFrontBuffer = (u16*)0x6000000;
u16 *VideoBackBuffer = (u16*)0x600a000;


//Function for swap buffer
void Flip(){
if (DISP_CR & BACKBUFFER){
DISP_CR &= ~BACKBUFFER;
VideoBuffer = VideoBackBuffer;
}
else {
DISP_CR |= BACKBUFFER;
VideoBuffer = VideoFrontBuffer;
}
}


#define SCREEN_MOD4_SIZE32 9600//size(in long 240*160/4) of screen in mod4

//Main function
int main(void)
{
Flip();
DMACopy(your_src,VideoBuffer,SCREEN_MOD4_SIZE32);
}

#51971 - LOst? - Thu Aug 25, 2005 4:39 am

Wow, if I got this much help when I first came here, I would have made a game already, lol.
_________________
Exceptions are fun

#51976 - yamaneko - Thu Aug 25, 2005 6:16 am

Sorry Lost I was not here. :)
_________________
山猫