Jump to content
Sign in to follow this  
jrok

Duplicate Kernels in multi-bank games?

Recommended Posts

I have a feeling this was answered before, but I've been searching for a good long while and can't find the appropriate thread.

 

From my understanding, the current version of bB stores the display kernel, the vblank and all of the player sprite graphics in the last bank of a bank-switched game, which puts an effective ceiling on amount of sprite data a bB game can have, regardless of the actual ROM size. But would it be possible to create a duplicate of the display kernel in more than one bank, then store additional graphics in it? For intance, in a 16k game, could a copy of the kernel be stored in both banks 3 and 4, with the remaining space used for sprite data? If that was possible, I'm assuming that such game would be structured such that Atari only had to address graphics in one bank at a time.

 

Thanks in advance,

Jarod.

Edited by jrok

Share this post


Link to post
Share on other sites
I have a feeling this was answered before, but I've been searching for a good long while and can't find the appropriate thread.

 

From my understanding, the current version of bB stores the display kernel, the vblank and all of the player sprite graphics in the last bank of a bank-switched game, which puts an effective ceiling on amount of sprite data a bB game can have, regardless of the actual ROM size. But would it be possible to create a duplicate of the display kernel in more than one bank, then store additional graphics in it? For intance, in a 16k game, could a copy of the kernel be stored in both banks 3 and 4, with the remaining space used for sprite data? If that was possible, I'm assuming that such game would be structured such that Atari only had to address graphics in one bank at a time.

 

Thanks in advance,

Jarod.

It does put an effective ceiling on the amount of *ROM*-based sprite data, but you could point the sprite graphics pointers at zero-page RAM or Superchip-RAM if you wanted.

 

Otherwise, yes, you could have a copy of the display kernel in multiple banks, as you suggested.

 

Michael

Share this post


Link to post
Share on other sites
I have a feeling this was answered before, but I've been searching for a good long while and can't find the appropriate thread.

 

From my understanding, the current version of bB stores the display kernel, the vblank and all of the player sprite graphics in the last bank of a bank-switched game, which puts an effective ceiling on amount of sprite data a bB game can have, regardless of the actual ROM size. But would it be possible to create a duplicate of the display kernel in more than one bank, then store additional graphics in it? For intance, in a 16k game, could a copy of the kernel be stored in both banks 3 and 4, with the remaining space used for sprite data? If that was possible, I'm assuming that such game would be structured such that Atari only had to address graphics in one bank at a time.

 

Thanks in advance,

Jarod.

It does put an effective ceiling on the amount of *ROM*-based sprite data, but you could point the sprite graphics pointers at zero-page RAM or Superchip-RAM if you wanted.

 

Otherwise, yes, you could have a copy of the display kernel in multiple banks, as you suggested.

 

Michael

 

Thanks Michael. If I wanted to go with a duplicate kernel, how would I go about implementing that in a way that 2600basic could parse? Could it be included as inline assembly? Also, how would one go about placing the sprite data into separate banks, since the default compilation automatically stores this in the last bank. Is there any documented example of such a program?

 

Jarod.

Share this post


Link to post
Share on other sites

If you modify the bat file to compile you bBasic code so that DASM generates a list file; I suspect you will find large ranges of bytes in the laast bank that are currently unused. This happens because the sprite graphics need to be position within pages of the ROM so that when indexed by the kernel code a page boundary is not crossed thus costing an extra CPU cycle and throwing the kerel timing off.

 

The large blank areas in ROM are generated by bBasic because it assumes that every sprite image must be able to have any vertical position on the screen. If in your game all your sprites have free range of the screen, then you are stuck with the large blank ROM areas.

 

If on the other hand sprites are confined to narrow vertical ranges of the screen (i.e. the top, or bottom) you can manually position them in ROM to optimize ROM usage. I have some handy macros to help do this, which I can post later tonight.

 

Cheers!

Rob

Share this post


Link to post
Share on other sites
If you modify the bat file to compile you bBasic code so that DASM generates a list file; I suspect you will find large ranges of bytes in the laast bank that are currently unused. This happens because the sprite graphics need to be position within pages of the ROM so that when indexed by the kernel code a page boundary is not crossed thus costing an extra CPU cycle and throwing the kerel timing off.

 

The large blank areas in ROM are generated by bBasic because it assumes that every sprite image must be able to have any vertical position on the screen. If in your game all your sprites have free range of the screen, then you are stuck with the large blank ROM areas.

 

If on the other hand sprites are confined to narrow vertical ranges of the screen (i.e. the top, or bottom) you can manually position them in ROM to optimize ROM usage. I have some handy macros to help do this, which I can post later tonight.

 

Cheers!

Rob

This issue only affects the multisprite kernel (at least in the manner described here.) The issue is bB has no knowledge of actual sprite addresses (that's determined by DASM.) So bB simply places assembler directives to place around 90 bytes of zeros in each page containing sprite data, which could amount to a lot of space.

 

In the standard kernel, you might save space by rearranging the location of sprites in the code. The issue is still one of page-wrapping, but limiting the vertical position on the screen will not help. The savings in the standard kernel will be smaller, and only significant if there are many large sprites. In the standard kernel, sprites may be placed anywhere in a page, but the sprites themselves may not wrap.

 

Those batch files sound very useful - I probably could have used them in Gingerbread Man (if you had developed them before its release, that is.)

 

As for a multi-bank kernel, I have thought about that in the past, and it could be done, but bB would need some modifications. It would also require you to call one kernel or another - For example, you would need two separate drawscreen commands (I'd say drawscreen(x) to call a particular kernel) and sprites would belong to a particular kernel (i.e. you could not use sprites from multiple kernels on a single frame.) I will think about this some more tonight.

Share this post


Link to post
Share on other sites
If your bB game is getting that advanced, perhaps it's time to learn assembly :ponder:

 

Needing a larger amount of sprite data does not necessarily mean "more advanced."

 

As for a multi-bank kernel, I have thought about that in the past, and it could be done, but bB would need some modifications. It would also require you to call one kernel or another - For example, you would need two separate drawscreen commands (I'd say drawscreen(x) to call a particular kernel) and sprites would belong to a particular kernel (i.e. you could not use sprites from multiple kernels on a single frame.) I will think about this some more tonight.

 

That would be extremely useful. I would be able to completely finish my project eden game with that modification. Would it require any sacrifices in variables or cycles?

 

Would this also mean that the last bank could contain no kernel or sprite graphics, so it could be completely dedicated to vblank, or would vblank also be duplicated in every bank?

Edited by MausGames

Share this post


Link to post
Share on other sites
This issue only affects the multisprite kernel (at least in the manner described here.) The issue is bB has no knowledge of actual sprite addresses (that's determined by DASM.) So bB simply places assembler directives to place around 90 bytes of zeros in each page containing sprite data, which could amount to a lot of space.

 

In the standard kernel, you might save space by rearranging the location of sprites in the code. The issue is still one of page-wrapping, but limiting the vertical position on the screen will not help. The savings in the standard kernel will be smaller, and only significant if there are many large sprites. In the standard kernel, sprites may be placed anywhere in a page, but the sprites themselves may not wrap.

 

Those batch files sound very useful - I probably could have used them in Gingerbread Man (if you had developed them before its release, that is.)

 

As for a multi-bank kernel, I have thought about that in the past, and it could be done, but bB would need some modifications. It would also require you to call one kernel or another - For example, you would need two separate drawscreen commands (I'd say drawscreen(x) to call a particular kernel) and sprites would belong to a particular kernel (i.e. you could not use sprites from multiple kernels on a single frame.) I will think about this some more tonight.

 

Ah! Interesting to know the differences between the multisprite kernel and the normal one. I have been using the multisprite kernel exclusively so I was ignorant.

 

Here is the macro I created using the generated bBasic assembly code as a basis. I included an example of its usage. I can't guarantee it is 100% correct. Also you need to manually sort the sprites to get optimal ROM usage.

		asm
  ; Create a handy macro that matches the way bBasic allocates ROM space for
  ; sprite image data.
  ;
  ; usage SPRITE_ALLOC y h  (h = image height, y = sprite's max y pos on screen)
MAC	SPRITE_ALLOC
.MAX_Y_POS		SET {1}
.HEIGHT			SET {2}
.MIN_PAGE_OFFSET SET (.MAX_Y_POS + .HEIGHT)
	if	(<*) > (<(*+.HEIGHT))
		repeat	($100-<*)
	   		.byte	0
		repend
	endif
	if	(<*) < .MIN_PAGE_OFFSET
		repeat	(.MIN_PAGE_OFFSET-<*)
	   		.byte	0
		repend
	endif
ENDM
end	

asm
; ---------------------
; Title Screen Sprites:
; ---------------------
SPRITE_ALLOC 43, Image_LetterG_Hgt
Image_LetterG:
.byte	0
.byte	%01111110
.byte	%11100111
.byte	%11000011
.byte	%11001111
.byte	%11000000
.byte	%11100111
.byte	%01111110
Image_LetterG_Hgt = * - Image_LetterG + 1

SPRITE_ALLOC 47, Image_LetterF_Hgt
Image_LetterF:
.byte	0
.byte	%11000000
.byte	%11000000
.byte	%11000000
.byte	%11111100
.byte	%11000000
.byte	%11000000
.byte	%11111111
Image_LetterF_Hgt = * - Image_LetterF + 1

SPRITE_ALLOC 52, Image_LetterO_Hgt
Image_LetterO:
.byte	0
.byte	%01111110
.byte	%11100111
.byte	%11000011
.byte	%11000011
.byte	%11000011
.byte	%11100111
.byte	%01111110
Image_LetterO_Hgt = * - Image_LetterO + 1

SPRITE_ALLOC 56, Image_LetterE_Hgt
Image_LetterE:
.byte	0
.byte	%11111111
.byte	%11000000
.byte	%11000000
.byte	%11111100
.byte	%11000000
.byte	%11000000
.byte	%11111111
Image_LetterE_Hgt = * - Image_LetterE + 1

SPRITE_ALLOC 61, Image_LetterM_Hgt
Image_LetterM:
.byte	0
.byte	%11000011
.byte	%11000011
.byte	%11011011
.byte	%11111111
.byte	%11100111
.byte	%11000011
.byte	%10000001
Image_LetterM_Hgt = * - Image_LetterM + 1

SPRITE_ALLOC 65, Image_LetterA_Hgt
Image_LetterA:
.byte	0
.byte	%11000011
.byte	%11000011
.byte	%11000011
.byte	%11111111
.byte	%11000011
.byte	%11100111
.byte	%01111110
Image_LetterA_Hgt = * - Image_LetterA + 1

SPRITE_ALLOC 70, Image_LetterN_Hgt
Image_LetterN:
.byte 	0
.byte 	%11000011
.byte 	%11000111
.byte 	%11001111
.byte 	%11011011
.byte 	%11110011
.byte 	%11100011
.byte 	%11000011
Image_LetterN_Hgt = * - Image_LetterN + 1
end

 

It should be noted that I have completely bypassed the standard bB way for setting a sprite image. So you have to use code like this to set the sprite image pointers:

	rem * Title Screen
_COLUP1 = $2F
COLUP2 = $3F
COLUP3 = $4F
COLUP4 = $5F
COLUP5 = $6F

player1x = 30
player2x = 50
player3x = 80
player4x = 110
player5x = 130

player1y = 70
player2y = 61
player3y = 52
player4y = 43
player5y = 34

asm
LDA #<Image_LetterN
STA player1pointerlo
LDA #>Image_LetterN
STA player1pointerhi
LDA #Image_LetterN_Hgt
STA player1height
end

asm
LDA #<Image_LetterM
STA player2pointerlo
LDA #>Image_LetterM
STA player2pointerhi
LDA #Image_LetterM_Hgt
STA player2height
end

asm
LDA #<Image_LetterO
STA player3pointerlo
LDA #>Image_LetterO
STA player3pointerhi
LDA #Image_LetterO_Hgt
STA player3height
end

asm
LDA #<Image_LetterG
STA player4pointerlo
LDA #>Image_LetterG
STA player4pointerhi
LDA #Image_LetterG_Hgt
STA player4height
end

asm
LDA #<Image_LetterM
STA player5pointerlo
LDA #>Image_LetterM
STA player5pointerhi
LDA #Image_LetterM_Hgt
STA player5height
end
return thisbank

 

It should be fairly easy to wrap that asm code into a macro.

 

Rob

Share this post


Link to post
Share on other sites
If your bB game is getting that advanced, perhaps it's time to learn assembly :ponder:

 

Needing a larger amount of sprite data does not necessarily mean "more advanced."

True, but it is one of the indicators.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...