Bitmap screen and Omega Race

Basic and Machine Language

Moderator: Moderators

User avatar
AndyH
Vic 20 Afficionado
Posts: 380
Joined: Thu Jun 17, 2004 5:51 am
Website: https://www.hewco.uk
Location: UK
Occupation: Developer

Bitmap screen and Omega Race

Post by AndyH »

I'm trying to get my head around creating a bitmap screen.

I found if I put the character address at $1000 and the screen at $1c00, I can get 19 x 20 characters (10 double height) before I run into the screen address. There are a few left over but not a full column before the screen starts.

I then looked at the size of the screen on Omega Race and can see this game has managed 20 x 20 characters. I can see it is setting the following:

  • $9002 = $94
  • $9005 = $FC

This is almost the same as my settings, but I've got a value of $13 in $9002 (bit 7 clear).

Omega race has bit 7 set which is part of the video matrix address according to the book, but where does that put the screen in memory?

Also, any ideas how Omega race gets that extra column? It looks like it is using all of the screen, eg: when the credits and text come up in the intro.

Any ideas (I'm a bit confused)?
--
AndyH
HEWCO | Vic 20 blog
DarwinNE
Vic 20 Devotee
Posts: 231
Joined: Tue Sep 04, 2018 2:40 am
Website: http://davbucci.chez-alice.fr
Location: Grenoble - France

Re: Bitmap screen and Omega Race

Post by DarwinNE »

I don't know if it can answer to your question, but I learnt (from Mike) that you can put both the screen and the character generator at $1000 and then skip the first characters that correspond to the memory used for the screen. Since you can't have more than 256 characters in the screen, if you skip the first 16 of them (16 pixel height), you remain with 240 characters available. 20x10 should be largely feasible (and even more than that).
User avatar
AndyH
Vic 20 Afficionado
Posts: 380
Joined: Thu Jun 17, 2004 5:51 am
Website: https://www.hewco.uk
Location: UK
Occupation: Developer

Re: Bitmap screen and Omega Race

Post by AndyH »

Thanks! I will give that a try.
--
AndyH
HEWCO | Vic 20 blog
User avatar
AndyH
Vic 20 Afficionado
Posts: 380
Joined: Thu Jun 17, 2004 5:51 am
Website: https://www.hewco.uk
Location: UK
Occupation: Developer

Re: Bitmap screen and Omega Race

Post by AndyH »

Brilliant, 21 x 22 characters (231 characters / 168 x 176 pixels) or 20 x 24 characters (all 240 characters / 160 x 192) are both working nicely. Many thanks!
--
AndyH
HEWCO | Vic 20 blog
User avatar
AndyH
Vic 20 Afficionado
Posts: 380
Joined: Thu Jun 17, 2004 5:51 am
Website: https://www.hewco.uk
Location: UK
Occupation: Developer

Re: Bitmap screen and Omega Race

Post by AndyH »

Here's the TRSE code if it is any use to others.

Code: Select all

program BitmapScreen;

var
	p1 : pointer; //zp
	
	@userdata "$1000" "$10F0" "SCREEN"
	@userdata "$1000" "$1FFF" "CHARACTER DATA"

@startblock $2000 code
	i,j,t, x,y : byte = 0;
	
	scr : array[ 23 ] of integer; // screen memory start addresses
	
	@define CHAR_ADDR	$1000		// character address
	@define SCR_ADDR	$1000
	
	@define SCR_WIDTH	20		//21  or  20
	@define SCR_HEIGHT	12		//11  or  12
	

procedure DisplaySetMode();
begin

	definescreen();
	poke(^$9003,0,(@SCR_HEIGHT<<1) | 1); 	// rows
	poke(^$9002,0, @SCR_WIDTH); 			// cols
	SCREEN_BG_COLOR := SCREEN_BG_BLACK;

	CreateAddressTable( scr, @SCR_ADDR, @SCR_WIDTH, 23 ); 
	SetCharsetLocation( @CHAR_ADDR );	
	SetScreenLocation( @SCR_ADDR );

end;

procedure DisplayDrawCharMap();
begin

	i := 16;
	for x:=0 to @SCR_WIDTH do  //19
		for y:=0 to @SCR_HEIGHT do
		begin
			screenmemory := addresstable(scr, 0, y,);
			screenmemory[x]:= i;
			i:=i+1;
		end;
		
end;

procedure DrawOnBitmap();
begin

	p1 := @CHAR_ADDR + (16*16);
	i:=31;
	t:=0;

	for x:=0 to @SCR_WIDTH do //19
	begin
	
		for y:=0 to (@SCR_HEIGHT * 16) do //176
		begin
		
			p1[0] := i;
			p1:=p1+1;
			t:=t+1;
			if (t=8) then
			begin
				t:=0;
				if i = 31 then i := 255 else i:=31;
			end;
			
			waitforraster(0); // slow it down

		end;

	end;

end;

 
begin

	DisplaySetMode();
	DisplayDrawCharMap();

	DrawOnBitmap();

	loop();

end.

--
AndyH
HEWCO | Vic 20 blog
User avatar
Mike
Herr VC
Posts: 4901
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Bitmap screen and Omega Race

Post by Mike »

Hi, Andy,

it's not quite clear to me, how the syntactic sugar of TRSE uses CreateAddressTable() in conjunction with 'addresstable' and 'scr' to address into the screen memory (and they aren't used in DrawOnBitmap() at all), but you should take into account, that you get a far easier addressing scheme with characters arranged in columns rather in rows. Even if the setup of the text screen is a little more complicated, that makes the difference between:

AD = 4352 + 192 * INT(X/8) + Y

and

AD = 4352 + 320 * INT(Y/16) + 16 * INT(X/8) + (YAND15)

the latter which definitely costs a lot more to calculate, especially given that 50% of the first expression gets its work done by the (),Y address mode of the 6502. :)

...

That being written, a thorough look into MINIGRAFIK and its assorted tools (like MINIPAINT, the batch suite, MINISKETCH, etc.) and games (like VICtoria Gold, Mah Jongg, etc.) is wholeheartedly recommended. :wink:
DarwinNE wrote:Since you can't have more than 256 characters in the screen, [...]
That's only a limit for bitmapped screens if you go by the data sheet. Witness tokra's and mine "New Frontiers in VIC-Hires-Graphics" series. :mrgreen:
User avatar
AndyH
Vic 20 Afficionado
Posts: 380
Joined: Thu Jun 17, 2004 5:51 am
Website: https://www.hewco.uk
Location: UK
Occupation: Developer

Re: Bitmap screen and Omega Race

Post by AndyH »

Thanks Mike. I will look into that. I'm in the experimentation phase and hoping I can use this in a future game. I enjoy figuring out a solution and acknowledge it might not be the most efficient, but it's easier to learn by doing than just reading about it for me. But that said, I really appreciate any advice from those who have already trodden the path and more experienced :) I was hoping you might comment as you always give very solid and knowledgeable answers.

My rationale for this first set up is that I thought that because double height characters are @A, BC, DE (each character on top of the other) that if I stack them vertically then calculating the Y starting position of something I want to draw is just a byte offset in the character memory. Then, if we stick with character aligned for the X position for a moment, I only need to know the address of the column to draw from then use the Y offset to get to the right place in memory.

AddressTable is something I added to TRSE to help with a traditional character display, but it can be used for anything where a lookup of sequential integers / addresses are required. So in that context, imagine your 22 x 23 character display, each integer (in TRSE this is a WORD - two bytes) in the address table is the start address of a Y position on the screen. As such I can get to any character address on the screen quite quickly with:

Code: Select all

screenmemory := addresstable( scr, 0, ypos );
screenmemory[ xpos ] := 1; // put an A character as xpos, ypos
This generates the following ASM:

Code: Select all

	lda ypos
	asl ; *2
	tax
	lda scr,x   ; Address of table lo
	ldy scr+1,x   ; Address of table hi
	
	sta screenmemory
	sty screenmemory+1

	lda #1
	ldy xpos
	sta (screenmemory),y
* The trade off with TRSE is that it makes writing and understanding code easier in some ways especially as your programs get larger, but it won't be as efficient as writing the ASM directly yourself - although you can jump into ASM code at any point and Nicolaas is constantly improving / optimising the output.


In my example code above, which is just a dump of what I got working as my first effort and can certainly be improved, just uses the address table to get the Y position to plot the double height characters in rows followed by columns.

So I could check that I am able to write to every block of 8 pixels on the screen, I have that DrawOnBitmap procedure. It's just a dirty bit of code for that purpose at the moment and it just goes down character memory starting from the 16th double character, and has a wait for VBL delay so I can see it drawing a simple pattern.

What I plan to do next is to create a routine to plot an 8x8 character image at any character aligned location on the screen. I will likely create another address table to specify where the start of a column (X position) is in memory for the character data and can use something like the following to know where to start drawing to:

Code: Select all

screenmemory := addresstable( charData, 0, xpos );
screenmemory[ ypos ] := 255; // put a line of pixels at xpos / ypos
Following that, for version 1, I will be looking to make a pre-shifting routine for character data I will use as sprites or want to plot at a non-character boundary and something that will draw that character with EOR. My sprites will be 8x8 or 8x16 (or any height for that matter). For version 2 I might dip into masks and images larger than 8 bits wide.

Hope that makes sense as to where I am going with this.
--
AndyH
HEWCO | Vic 20 blog
User avatar
AndyH
Vic 20 Afficionado
Posts: 380
Joined: Thu Jun 17, 2004 5:51 am
Website: https://www.hewco.uk
Location: UK
Occupation: Developer

Re: Bitmap screen and Omega Race

Post by AndyH »

DarwinNE wrote: Fri Nov 01, 2019 4:21 pm I don't know if it can answer to your question, but I learnt (from Mike) that you can put both the screen and the character generator at $1000 and then skip the first characters that correspond to the memory used for the screen.
Oh, and BTW - many thanks to both of you for the above - I would never have thought of doing that!

I'm still wondering about what Omega Race is doing with that bit 7 in $9002 ( $94 ). Any ideas what address that sets?
--
AndyH
HEWCO | Vic 20 blog
User avatar
srowe
Vic 20 Scientist
Posts: 1356
Joined: Mon Jun 16, 2014 3:19 pm

Re: Bitmap screen and Omega Race

Post by srowe »

AndyH wrote: Sat Nov 02, 2019 5:11 am I'm still wondering about what Omega Race is doing with that bit 7 in $9002 ( $94 ). Any ideas what address that sets?
That bit controls VA9 of the screen address, combined with $FC in $9005 I make that a screen address of $1E00 and a character generator at $1200 (CPU addresses, VIC sees them at $3E00 and $3200 respectively).
User avatar
Mike
Herr VC
Posts: 4901
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Bitmap screen and Omega Race

Post by Mike »

srowe wrote: Sat Nov 02, 2019 6:11 amThat bit controls VA9 of the screen address, combined with $FC in $9005 I make that a screen address of $1E00 and a character generator at $1200 (CPU addresses, VIC sees them at $3E00 and $3200 respectively).
The character generator remains at $1000, bit 7 in $9002 only shifts text and colour RAM base by 1/2 KB.
User avatar
AndyH
Vic 20 Afficionado
Posts: 380
Joined: Thu Jun 17, 2004 5:51 am
Website: https://www.hewco.uk
Location: UK
Occupation: Developer

Re: Bitmap screen and Omega Race

Post by AndyH »

Ah, ok. I've also found a reference in a book that (if I understood it correctly) this bit has a bearing on the colour RAM address $9600 or $9400.
--
AndyH
HEWCO | Vic 20 blog
User avatar
srowe
Vic 20 Scientist
Posts: 1356
Joined: Mon Jun 16, 2014 3:19 pm

Re: Bitmap screen and Omega Race

Post by srowe »

AndyH wrote: Sat Nov 02, 2019 6:45 am Ah, ok. I've also found a reference in a book that (if I understood it correctly) this bit has a bearing on the colour RAM address $9600 or $9400.
Correct, it also affects the colour address, having it set makes that $9600.
User avatar
Mike
Herr VC
Posts: 4901
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Bitmap screen and Omega Race

Post by Mike »

Also note, that neither screen nor colour RAM are limited to 512 bytes. Especially, the colour RAM address wraps (back) to $9400 when it exceeds $97FF!
AndyH wrote:This generates the following ASM:

Code: Select all

	lda ypos
	asl ; *2
	tax
	lda scr,x   ; Address of table lo
	ldy scr+1,x   ; Address of table hi
	
	sta screenmemory
	sty screenmemory+1

	lda #1
	ldy xpos
	sta (screenmemory),y
That doesn't look too different from what I'd do in hand-written ASM. However, I'd pack the low- and high-bytes of the addresses into two distinct tables, which spares me the ASL instruction and allows me to load X directly from 'ypos' (see the BALLPING example here, $183B .. $184B). Also I only 'remember' LDY ABS,X exists when I *really* need it, I'd otherwise just go for the LDA LO_TABLE,X:STA ZP_PTR:LDA HI_TABLE,X:STA ZP_PTR+1 sequence.
User avatar
AndyH
Vic 20 Afficionado
Posts: 380
Joined: Thu Jun 17, 2004 5:51 am
Website: https://www.hewco.uk
Location: UK
Occupation: Developer

Re: Bitmap screen and Omega Race

Post by AndyH »

Good point, I'll add a Hi/Lo version for address table.
--
AndyH
HEWCO | Vic 20 blog
User avatar
AndyH
Vic 20 Afficionado
Posts: 380
Joined: Thu Jun 17, 2004 5:51 am
Website: https://www.hewco.uk
Location: UK
Occupation: Developer

Re: Bitmap screen and Omega Race

Post by AndyH »

A little update on my progress. I am about half way through the Turbo Rascal command set to bring a fast, easy to use bitmap mode to TRSE.

It supports:


20 x 24 (160 x 192 pixels) bitmap screen
Tiles - copy, or, eor, and drawing modes
Pre-shifted sprites - any size, or, eor, and drawing modes
Dots and blots - for particles, bullets etc
Horizontal scrolling
Text - full size or smaller supported
BCD numbers for scores etc
--
AndyH
HEWCO | Vic 20 blog
Post Reply