Jump to content
IGNORED

Robot Zed 7800 first demo and progress


Sprybug

Recommended Posts

For those that don't know, I have had plans to port my new Atari 2600 homebrew, Robot Zed, to other consoles.  My first attempt at this is for the Atari 7800 using 7800Basic.  Over the past few weeks, I've learned how to scroll and get Zed to interact with the level, even jumping and shooting.  I've got a little working demo finished to show it off.  I also have first/rough drafts of 2 of the songs in RMT with Base Area, and Ice Zone.  I tried to include the RMT of Base Area into the program but the emulator hangs when it loads up, so I commented the RMT related stuff out for now until I figure out what's going wrong there.  I used RMTfix to get the start address at $4000 from the ROM code and yes I did set trackersupport RMT.  The compiler wouldn't allow me to set pokeysupport to just "on", it wanted me to pick an address for it to work, so I chose $450 with no change in result, and tried $800 with the same result.  So, if anyone can guide me through that so I can get these rocking tunes playing in the game, that'd be great!

 

The demo works with A7800 and the online Java emulator too.  It glitches with the ProSystem emulator, but from what I understand that emulator is less accurate and is no longer updated and supported, so it's best to stick with the better emulators.

 

Enjoy!

 

Test3.bas.a78

Test3.bas.bin

Edited by Sprybug
  • Like 11
Link to comment
Share on other sites

3 minutes ago, Karl G said:

Looks great so far! I would suggest also making the .a78 file generated bu 7800basic available when you share releases. This has a header that gives configuration/rom information to emulators and multicarts.

Thanks for the suggestion. I went back and added it to the original post.

  • Like 3
Link to comment
Share on other sites

Very nice start!

17 hours ago, Sprybug said:

[...] I tried to include the RMT of Base Area into the program but the emulator hangs when it loads up, so I commented the RMT related stuff out for now until I figure out what's going wrong there.  I used RMTfix to get the start address at $4000 from the ROM code and yes I did set trackersupport RMT.  The compiler wouldn't allow me to set pokeysupport to just "on", it wanted me to pick an address for it to work, so I chose $450 with no change in result, and tried $800 with the same result.  So, if anyone can guide me through that so I can get these rocking tunes playing in the game, that'd be great!

I think the problem mostly amounts to the fact that a7800 and js7800 only have mapper support for formats that have existed in the past, or are available formats for AA carts. 32k+ram@4000+pokey@450 isn't one of those. 7800basc is a bit looser, allowing you to mix-and-match some hardware, because i want it to be usable for anyone to create a test rom if they're developing new hardware. I don't have time to look it up just now, but there's a blurb in the 7800basic manual saying that it's on you to ensure the hardware combo you choose can produce carts. (or works in emulation)

 

My suggestion is to go for "set romsize 128kRAM" and "set pokeysupport $450', just like the rmtramdemo. That should work on the various modern emulators and flash carts - plus you're almost certainly going to need bankswitching for this game eventually. :)

  • Like 1
Link to comment
Share on other sites

5 hours ago, saxmeister said:

Great work! And this is your first stab at 7800basic?!?!? This will be a wonderful addition to the 7800. Welcome!!!

Yes, I've made 3 Atari 2600 homebrews with Batari BASIC.  The syntax is the same, just has a lot of added features for the 7800 that I needed to learn, and how things worked.  I wanted to cross platform my Atari 2600 homebrew of Robot Zed after finishing it, making it available on multiple platforms, while taking advantage of what each platform gives me.  The 7800 not only will let me have improved graphics, but a POKEY based soundtrack, and extra features and touches that I wanted to do with the original game that I just couldn't do on the 2600.

  • Like 2
Link to comment
Share on other sites

5 hours ago, RevEng said:

Very nice start!

I think the problem mostly amounts to the fact that a7800 and js7800 only have mapper support for formats that have existed in the past, or are available formats for AA carts. 32k+ram@4000+pokey@450 isn't one of those. 7800basc is a bit looser, allowing you to mix-and-match some hardware, because i want it to be usable for anyone to create a test rom if they're developing new hardware. I don't have time to look it up just now, but there's a blurb in the 7800basic manual saying that it's on you to ensure the hardware combo you choose can produce carts. (or works in emulation)

 

My suggestion is to go for "set romsize 128kRAM" and "set pokeysupport $450', just like the rmtramdemo. That should work on the various modern emulators and flash carts - plus you're almost certainly going to need bankswitching for this game eventually. :)

Thank you, Rev!  I will take a look at the example for sure.  I did change the romsize to 32kRAM, because I knew I'd need the extra ram for the music because of where it puts that info in RAM, but you are right.  I will need more than just 32K for sure.  I always start with the minimum until I see that it's time to add more, but with all these extra features, it's pretty much going to be a given.  I'll give the 128kRAM setting a go, and do some experimenting and get back to you.  Got a busy day today, but I'll see when I can give this a try.

  • Like 3
Link to comment
Share on other sites

On 10/23/2023 at 9:04 AM, RevEng said:

Very nice start!

I think the problem mostly amounts to the fact that a7800 and js7800 only have mapper support for formats that have existed in the past, or are available formats for AA carts. 32k+ram@4000+pokey@450 isn't one of those. 7800basc is a bit looser, allowing you to mix-and-match some hardware, because i want it to be usable for anyone to create a test rom if they're developing new hardware. I don't have time to look it up just now, but there's a blurb in the 7800basic manual saying that it's on you to ensure the hardware combo you choose can produce carts. (or works in emulation)

 

My suggestion is to go for "set romsize 128kRAM" and "set pokeysupport $450', just like the rmtramdemo. That should work on the various modern emulators and flash carts - plus you're almost certainly going to need bankswitching for this game eventually. :)

Hey Rev.  So I did a little playing around last night and today and noticed how much less space I have to work with in bank1 with a 128kRAM bankswitching scheme.  After loading in all my graphics for the first level, all the Robot Zed sprites, and other sprites I have made so far in the first bank, I've exceeded the ROM space in the first bank.  Is there a recommendation on how I should start organizing my banks, and what should be going where?  Thanks!

  • Like 1
Link to comment
Share on other sites

I should really write something up on this in the wiki :)

 

Atari's 7800 supergame bankswitching gives you 16k of rom that changes whenever you bankswitch (ephemeral banks), and another 16k of perma-rom. (the permanent, last bank in rom)

 

First rule - you need to keep anything that 7800basic needs for the current frame in either: the last bank, the active ephemeral bank. or ram. That goes for goes for graphics, level data, text strings, music data, etc. If you start using the interrupts (topscreenroutine, bottomscreenroutine, userinterrupt) they *need* to go in this last bank, or else bad things will happen when you bankswitch.

 

So you want to stick anything that's very shared in that last bank, be it data, code, or graphics. If there's something shared that can't fit in the last bank (data, code, graphics) you can stick copies of the same stuff into the ephemeral banks that that you plan to be switching between - even though that seems wasteful, this sort of duplication is normal.

 

For things that don't need to be shared, I like to break my banks down by game function. e.g. my title screen code and graphics go in one bank. I guess one way to judge this is if the code uses a different main loop than your game engine, it might be a good candidate for another bank. I also dedicate banks to large data structures that will be copied to ram (e.g. RMT music, level data) along with the routines that do the copying.

  • Like 3
Link to comment
Share on other sites

1 hour ago, RevEng said:

I should really write something up on this in the wiki :)

 

Atari's 7800 supergame bankswitching gives you 16k of rom that changes whenever you bankswitch (ephemeral banks), and another 16k of perma-rom. (the permanent, last bank in rom)

 

First rule - you need to keep anything that 7800basic needs for the current frame in either: the last bank, the active ephemeral bank. or ram. That goes for goes for graphics, level data, text strings, music data, etc. If you start using the interrupts (topscreenroutine, bottomscreenroutine, userinterrupt) they *need* to go in this last bank, or else bad things will happen when you bankswitch.

 

So you want to stick anything that's very shared in that last bank, be it data, code, or graphics. If there's something shared that can't fit in the last bank (data, code, graphics) you can stick copies of the same stuff into the ephemeral banks that that you plan to be switching between - even though that seems wasteful, this sort of duplication is normal.

 

For things that don't need to be shared, I like to break my banks down by game function. e.g. my title screen code and graphics go in one bank. I guess one way to judge this is if the code uses a different main loop than your game engine, it might be a good candidate for another bank. I also dedicate banks to large data structures that will be copied to ram (e.g. RMT music, level data) along with the routines that do the copying.

Looks like I'm going to have to do some more playing around.  How many banks do you get in a 128kRAM configuration?  What would be the last bank in this scheme?  I just may need to store all my graphics in the last bank.  There's going to be a lot of them.  These graphics I have made so far are just for the first level, all of Robot Zed's sprites, and the artillery sprites.  Haven't done any enemy or "effects" sprites yet, not to mention all the graphics for all of the other levels too.  This would mean I would have to do the incgraphics to load them in, in that last bank.  By doing so, would this mean that these graphics would be accessible by all the other banks?  Kind of like how Batari BASIC for the 2600 does it?

  • Like 1
Link to comment
Share on other sites

1 minute ago, Sprybug said:

Looks like I'm going to have to do some more playing around.  How many banks do you get in a 128kRAM configuration?  What would be the last bank in this scheme?

There are 8 banks in 128k. Like bB, 7800basic starts counting from bank 1, so bank 8 would be the last one. There's no real developer headaches if you want to start with 128k, but later decide you need to migrate to 256k, or 512k - literally you can just change the format and renumber your last bank.

 

1 minute ago, Sprybug said:

This would mean I would have to do the incgraphics to load them in, in that last bank.  By doing so, would this mean that these graphics would be accessible by all the other banks?  Kind of like how Batari BASIC for the 2600 does it?

Correct, and that's a good way to start. But you may find that last bank is just too small to hold everything you want to stick in it. If that happens, you may need to start splitting out map-specific graphics into ephemeral banks - maybe you'll have Base Area specific sprites in bank 2, and Ice Area specific sprites in bank 3, and make copies of the main loop in each.

 

I'm avoiding giving a solid design layout, because there isn't a one-size-fits-all layout. Start with your plan, but adjust the plan if you need to.

  • Like 2
Link to comment
Share on other sites

4 hours ago, RevEng said:

There are 8 banks in 128k. Like bB, 7800basic starts counting from bank 1, so bank 8 would be the last one. There's no real developer headaches if you want to start with 128k, but later decide you need to migrate to 256k, or 512k - literally you can just change the format and renumber your last bank.

 

Correct, and that's a good way to start. But you may find that last bank is just too small to hold everything you want to stick in it. If that happens, you may need to start splitting out map-specific graphics into ephemeral banks - maybe you'll have Base Area specific sprites in bank 2, and Ice Area specific sprites in bank 3, and make copies of the main loop in each.

 

I'm avoiding giving a solid design layout, because there isn't a one-size-fits-all layout. Start with your plan, but adjust the plan if you need to.

This was great info.  I shifted things around, put my map into RAM, and got the song playing!  Had to do a few other things, such as setting the Zed Sprite with a 2 zone range so Zed wouldn't be cut in half, since I put Zed's graphics in bank 8.  But it's working.  The Zed sprites alone took up 8K of bank 8, and the Base Zone graphics took up about another 8K in bank 1.  So I'm going to have to get real creative with it all somehow to make the graphics all work together when I add even more.  But this is a great start.  Here.  Have an update with music!

 

Robot_Zed_01.bas.a78

Robot_Zed_01.bas.bin

  • Like 6
Link to comment
Share on other sites

Depending on how much of the cart RAM you need you can use some of it as makeshift VRAM. It would be 4K for a 16 line block of graphics without the padding needed for objects shifted vertically so it's ideal for tilesets. You can then store your tile graphics in a different bank out of the way and copy the data over as needed.

  • Like 3
Link to comment
Share on other sites

2 hours ago, Karl G said:

Alternately, if the 1.5K of RAM you get without the extra RAM bank ends up being enough for you, you could always go with one of the other ROM sizes that always has two RON banks available at all times like 144K.

Unfortunately, I'll need the extra RAM to store the music data for the RMT player and to store the tileset data for the map, which can run anywhere from 4 to 8K in total depending on how big the song is.  Today, I tried putting the tilemap and the sprites that are not zed in the same bank that plots the map, sprites, and does a drawscreen, into a different bank (I used bank 3) that is called from the main routine (in bank 1), and the tilemap flickers like crazy.  Since each level is going to have its own tileset, I think the best way is to take that data and put it in the 8K of RAM that I have left, that is accessible by everything no matter what bank I happen to be in.  Would that work?  Would I have to do, for example in say bank 3, put in

 

  incgraphic gfx/Base_Area.png 160B 0 1 2 3 7 8 4 5 9 6

 

then later in the same bank as a routine to be called early from bank 1 before the main routine

 

copybaseareagraphics

  memcpy $6000 Base_Area 8192

  return otherbank

 

And then in bank 1 dimensions have something like

 

  dim levelgraphics=$6000

  

  

Edited by Sprybug
  • Like 2
Link to comment
Share on other sites

Because MARIA has to constantly read the graphics data as it draws the screen you have to have the correct bank switched in for the duration of the screen drawing. If you're calling drawscreen and then doing things outside the bank MARIA will start drawing whatever's at that spot in the bank. You could call drawwait to do nothing until the screen is finished drawing but then that's a lot of wasted time the CPU could be doing some stuff.


7800basic now has a 'set dumpgraphics [address]' command to help with using RAM for graphics but I've not yet used it. What I've been doing is copying the graphics data from the compiled assembly. By storing it as raw data it can fit anywhere without 7800basic having to reserve specific chunks of the bank to be used for drawing (due to holey DMA and 7800basic having to assume your graphics won't always be zone-aligned).

I've included some code below based on what I've been doing that sticks tile graphics in $4000 - $4FFF. The first bit replaces the 'characterset' command so that we can manually set CHARBASE instead of giving it the name of some imported graphics. The second bit is a loop that copies 256 bytes of data for all 16 lines to that location. If we don't give it 256 bytes of data it'll just fill the rest with rubbish, but ideally the loop would be modified to only copy as much as you'd need.
 

	asm
	lda #$40 ;High byte of graphics address ($4000)
	sta sCHARBASE
	sta CHARBASE

	lda #%11100000 ;#%01100000 for 160B / 320C / 320D
	sta charactermode
end


 

tilesetCopy
	asm
	ldy #0
.tilesetCopyLoop ;Copy graphics from ROM to RAM
	
	lda tiles0,y
	sta $4000,y
	
	lda tiles1,y
	sta $4100,y
	
	lda tiles2,y
	sta $4200,y
	
	lda tiles3,y
	sta $4300,y
	
	lda tiles4,y
	sta $4400,y
	
	lda tiles5,y
	sta $4500,y
	
	lda tiles6,y
	sta $4600,y
	
	lda tiles7,y
	sta $4700,y
	
	lda tiles8,y
	sta $4800,y
	
	lda tiles9,y
	sta $4900,y
	
	lda tilesA,y
	sta $4A00,y
	
	lda tilesB,y
	sta $4B00,y
	
	lda tilesC,y
	sta $4C00,y
	
	lda tilesD,y
	sta $4D00,y
	
	lda tilesE,y
	sta $4E00,y
	
	lda tilesF,y
	sta $4F00,y
	
	dey
	bne .tilesetCopyLoop
end
	return otherbank
	
	asm
tiles0
	HEX 5555555555555555555555555555555555555555555555014055555555555555
	HEX 5555555555575557555755575557555755575557555755575557ffffffffffff
	HEX ffffffffffffffffffffffffffffaaaaaaaaaaaaaaaaaaaaaaaa000aaaaaaaaa
	HEX aaaaaaaaaaaaaaaaaaaaaaaaa000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
	HEX aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0000000000000000000000000000
	HEX 0000000000000000000000000000000000000000000000000000000000000000
	HEX 0000000000000000000000000000000000000000000000000000000000000000
	HEX 0000000000000000000000000000000000000000000000000000000000000000
	
tiles1
	HEX 65a9a96559656565656599a565a5a9959999996565659905505575fdfd755d75
	HEX 7575757555575557555755575557555755575557555755575557ffffffffffff
	HEX ffffffffffffffffffffffffffffaaaaaaaaaaaaaaaaaaaaaaaa00aaaaaaaaaa
	HEX aaaaaaaaaaaaaaaaaaaaaaaaaa00aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
	HEX aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0000000000000000000000000000
	HEX 0000000000000000000000000000000000000000000000000000000000000000
	HEX 0000000000000000000000000000000000000000000000000000000000000000
	HEX 0000000000000000000000000000000000000000000000000000000000000000
	
tiles2	
	HEX a9a9a9a959a9a965a9a999a9a9a9a995999999a9656599155455fdfdfdfd5dfd
	HEX fd75fdfd55575557555755575557555755575557555755575557ffffffffffff
	HEX ffffffffffffffffffffffffffffaaaaaaaaaaaaaaaaaaaaaaaa00aaaaaaaaaa
	HEX aaaaaaaaaaaaaaaaaaaaaaaaaa00aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
	HEX aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0000000000000000000000000000
	HEX 0000000000000000000000000000000000000000000000000000000000000000
	HEX 0000000000000000000000000000000000000000000000000000000000000000
	HEX 0000000000000000000000000000000000000000000000000000000000000000
	
tiles3	
	HEX 996595995999996599999999999995959999999965a9a9155455dd75d5dd5ddd
	HEX dd75dddd55575557555755575557555755575557555755575557ffffffffffff
	HEX ffffffffffffffffffffffffffffaaaaaaaaaaaaaaaaaaaaaaaa02aaaaaaaaaa
	HEX aaaaaaaaaaaaaaaaaaaaaaaaaa80aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
	HEX aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0000000000000000000000000000
	HEX 0000000000000000000000000000000000000000000000000000000000000000
	HEX 0000000000000000000000000000000000000000000000000000000000000000
	HEX 0000000000000000000000000000000000000000000000000000000000000000
	
etc...

 

Link to comment
Share on other sites

Thanks, Smitty.

 

I currently have 39 4x16 tilemap sprites for Base_Area with screen mode 160B, Doublewide on.  I noticed with your method there seems to be a limit of 16 total tilemap sprites.  Since using doublewide on a 160B, each sprite takes up 2 spots, so for example when I use Peekchar to see if he's running into a solid platform, that range is from 2-45, since each graphic number is in multiple of 2's, such as sprite 0 taking 0 & 1, the next sprite taking 2 & 3, etc.  I've tried my idea without success so far.  Keeps giving me compiler errors saying there's a parse error and unrecognized character "'" for some weird reason.  

However, I am very interested in this new command to see if it can work for me.  I don't see any documentation about it, so I don't know how I would implement it into the program.  Is there a thread somewhere that talks about it?

Edited by Sprybug
  • Like 1
Link to comment
Share on other sites

It's not 16 objects or anything like that, it's 16 lines so that it's effectively copying a 256x16 byte image into RAM. When you draw the graphics you're essentially giving it a horizontal offset from 0 to 255 into that image to start drawing from.

I'll always recommend the online copy of the documentation from here -
https://www.randomterrain.com/7800basic.html#set_dumpgraphics

Link to comment
Share on other sites

I've been trying to figure out the set dumpgraphics command, but the small amount of info there on the documentation doesn't feel complete.  I'm kind of confused on how it really is supposed to work and when and where you're supposed to do things.  From what I could guess, is that I would take my currently working Zed program, make a copy of it, so I can include the set dumpgraphics $4000 at the beginning, which I did.  It does create the files I was looking for.  Then in a whole new version of the program, don't put in set dumpgraohics $4000, and include the things that the examples are showing.  So in bank 1, which is my main bank I put 

 

  include dump_gfx_00.asm ; ** allow plot* commands to work
  gosub copymycharset bank3

 

Then in bank 3 I put

 

copymycharset
  memcpy $6000 .levelgraphics 4096
  return otherbank
levelgraphics
  incbin dump_gfx_00.bin

 

But when I do this, I get the error "Cannot open dump_gfx_00.asm7800.asm for reading"

 

.asm7800????  When it saves it saves it as dump_gfx_00.asm

 

The files are there after I run the first program that creates the files, but when I run my new program to load them in, not only do I get that compiler error, but the ASM and BIN files that were created before are just magically gone!  This is weird. 

 

Added Note:

A whole other extra thing to note from a previous attempt not using this method.

That error I got before with the 
parse error and unrecognized character "'"

with my method.  I accidentally still had it set for "batari BASIC" and when I discovered that, I switched it over to 7800basic, but my idea didn't work out as all the map graphics were corrupted.

Edited by Sprybug
  • Like 1
Link to comment
Share on other sites

@Sprybug Give me a bit and I'll give you an example that I've setup for RobotsRumble. Just need to strip it down to a single screen instead of the full level just to make it easier to follow.  It works great for all sorts of data and compression!

  • Like 2
Link to comment
Share on other sites

Ok - here is a base example:

builder.zip

 

There is a few things this example does:

 

Part 1: Compiling the 1.builder.78b file

  • During compile extracts the included gfx file(s) to binary. Note: you can include one or more gfx files (within the same gfx block)

Part 2: Running the 2.finalise.bat file (you can run form the command line or double-click In Windows)

  • Renames the dump_gfx_00.bin to planetearth2charset.bin
  • Uses the 'snip' tool to extract a tiled map and data tables to binary files
  • Uses the 'lz4raw file to compress the extracted binary files
  • Cleans up unrequired files

For next step to then including that with your games requires some additional steps.  Will try and put that together shortly.

 

I've added the additional compression and examples of some other additional functionality available not just the gfx dumping.  I've been able to reduce a largish map game I'm working on from 8 banks (3 screens including gfx for each, map and collision data per bank) down to 3.  A lot of modern c64 games uses compression and it's the next advancement for the 7800 community for mine.

 

Back soon! 

  • Like 2
Link to comment
Share on other sites

@mksmith  Thanks for all that!  I think what will help too is if I share my code so everyone can see what I am doing.

I'm using 160B for the maximum amount of colors I can use at one time.  I know with PlotMapFile you can get that on a 160A, but you lose support for offsetting your map coordinates, which is what I use to do the scrolling along with masking off the sides with solid black tiles.  This is why I use Plotmap instead, because you can easily employ scrolling using the x y and offset coordinates.  Since I know what the solid blocks are, I can use peekchar to determine what is solid and not, so I don't need a separate data table for the collisions.  Each section of a level is only 1280 bytes, so I'd be able to get a few full levels in just 1 bank.  Just my biggest problem is having all the graphics available at one time for the program to use.  I could try and squeeze all the level graphics into one tileset, but that will limit how many tiles I can use in one level, which is why I was looking into a way to get the tile graphics in RAM instead so I can copy a level's tile graphics into RAM depending on what level you're on, so they'll be always available for the MARIA to plot with no matter what bank I am in.  The last bank is where all of Robot Zed's sprites are in an 8K block, and I plan on putting all the enemy sprites in the other 8K still available.  The boss sprites will be in their own bank as the boss battle stuff I plan on putting all in its own bank, including all the code.

Here's my code so far. 

 

 

Robot_Zed_01.bas

 

  • Like 4
Link to comment
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.
Note: Your post will require moderator approval before it will be visible.

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...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...