Hi,
I'm not really using Assembler but I can show you how I did double buffering using TurboRascal (TRSE). Maybe it helps:
(A) Memory setup
I used $1000 and $1e00 as screen addr1/2 to switch between. The colour address is $9400 and $9600
The charset location is at $1800, and 192 chars are sufficient for me
(B) Variables:
currentBank 0=screen1, 1=screen2
time: Timer for counting the frames
framestatus: indicate if the update of tiles are finished
raster: rasterline (different for PAL/NTSC)
(C) VBL Raster interrupt
Explanation: The interrupt is separated into 4 parts depending on frameStatus and time
frameStatus := 1 -> start cycle set by GameLoop
frameStatus := 0 -> cycle is finished
time in cycle
time = 0: Switch bank depending on current bank
time = 1: Copy all data from bank to another
time = 2: cycle is finished and frameStatus = 0
Code: Select all
interrupt vbl();
begin
StartIRQ(0);
UpdateSound();
if(frameStatus = 1) then begin
if(time = 0) then begin
SwitchBank();
end
else if(time = 1 and currentBank = 0) then begin
copyHalfScreen(^@SCREEN_ADDR1, ^@SCREEN_ADDR2, 10,0,0);
copyHalfScreen(^@COLOR_ADDR1, ^@COLOR_ADDR2, 10,0,0);
end
else if(time = 1 and currentBank = 1) then begin
copyHalfScreen(^@SCREEN_ADDR2, ^@SCREEN_ADDR1, 10,0,0);
copyHalfScreen(^@COLOR_ADDR2, ^@COLOR_ADDR1, 10,0,0);
end;
end;
if(time = 2) then begin
frameStatus := 0;
end;
if(time < 4) then inc(time)
else if(frameStatus = 1) then begin
time:=0;
end;
closeIRQ();
end;
(D) Game loop example
Only Update the game objects that are hidden after the interrupt cycle is done. If finished set framestatus =1 to start new cycle
Code: Select all
while(state = @STATE_PLAY) do begin
ReadJoy1();
waitnoraster(0);
if(frameStatus = 0) then begin
Update();
Animate();
CycleWater();
frameStatus := 1;
end;
end;
(E) Update Example
While doing an update use the correct screenmemory
Code: Select all
if(currentBank = 1) then screenmemory := scr1[y+1] else screenmemory := scr2[y+1];
screenmemory[x]:=c;
Note scr1 is a pointer to the screen location, same need to be done for the color ram
(F) Switch Bank function
Code: Select all
procedure SwitchBank();
begin
if (currentBank = 0) then
begin
VICCR5 := $fe;
VICCR2 := VICCR2 | $80;
currentBank := 1;
end
else
begin
VICCR5 := $ce;
VICCR2 := VICCR2 & $7F;
currentBank := 0;
end;
end;
(G) Start VBL interrupt
Code: Select all
// PAL=121, NTSC=107
if (HSCROLL_REGISTER = 12) then raster := 121 else raster := 107;
VIARasterIRQ(vbl(), raster, 0);
Hope this helps...