Jump to content
IGNORED

7800basic beta, the release thread


RevEng

Recommended Posts

When I compiled one of my projects recently. I started running into " Origin Reverse-indexed" and tracked it down. Appears an ORG $A000 in the .ASM is the cause I am limiting the program to use a 32K ROM for now. I did notice there still empty gaps in the .BIN file. Are there any commands/options in the 7800 Basic to move ROM area blocks, lets say less is needed to graphic images/data and more is needed for the program?

Edited by peteym5
Link to comment
Share on other sites

The 7800 has some requirements on where graphics are positioned in memory. (technically you can loosen those requirements, but it would force you to waste even more memory) 2k/4k graphics blocks are located at 4k/8k boundaries. (depending on the zone height)

 

This results in islands of space that you're probably not using in your game. Check out the dmahole command.

Link to comment
Share on other sites

OK, I see how DMAhole works by examining the ASM file. It can move some programming and or data into these DMA holes. It is exactly what I do with the 8-bit when I need to start a table at a top of a page (every 256 bytes) or 8k bank. If the page or bank is not all used up, I place some small pieces of data there. What I probably will do is insert a dmahole routine before a start of a routine or data table. Now this dmahole 0 is after the org $A000, and can I assume dmahole 1 will place something after the org $B000?

    dmahole 0
    asm
check_bits
   .byte 1,2,4,8,16,32,64,128
my_table
   .byte 0,1,2,3,4,5,6,7,8,9
   .byte 0,1,2,3,4,5,6,7,8,9
   .byte 0,1,2,3,4,5,6,7,8,9
   .byte 0,1,2,3,4,5,6,7,8,9
   .byte 0,1,2,3,4,5,6,7,8,9
   .byte 0,1,2,3,4,5,6,7,8,9
   .byte 0,1,2,3,4,5,6,7,8,9
   .byte 0,1,2,3,4,5,6,7,8,9     
end
Edited by peteym5
Link to comment
Share on other sites

If you have a zone-height of 16 and dmahole 0 is at $A000, then dmahole 1 will be at $B000.

If you have a zone-height of 8, and dmahole 0 is at $A000, then dmahole 1 will be at $A800.

 

If it helps, the compiler calls out exactly where it's putting dmahole 0, dmahole 1, etc., in addition to the graphics block locations.

Link to comment
Share on other sites

I am wondering if there are any 7800 emulators made or in development with debug mode? Also I change a line in the 7800bas.bat file to look like this

dasm "%~f1.asm" -I"%bas7800dir%"/includes -f3 -l"%~f1.txt" -o"%~f1.bin" | 7800filter 

Adding -l"%~f1.txt" allows anyone to look at the assembly code and look at what memory locations stuff is store on the cartridge. Could let people see how much room they had in DMA holes, if they can mode a block a data or not.

Edited by peteym5
Link to comment
Share on other sites

Sorry, probably just reading comprehension issues caused by posting soon after I woke up, although looks like you edited your post while I was typing as well. :)

 

I've generally been able to hunt down bugs just from using the line numbers given by 7800basic + the .asm file all the same. Most often the actual bugs occur before those things flagged by the compiler however.

Link to comment
Share on other sites

I discovered I have to do a compile every time I have make small modifications. If I make some massive modifications and get that "--- Unresolved Symbol List" error that does not show which symbol it cannot find. Can spend hours trying to track it down. However MADS Assembler does show where the error is occurring and can make a label fine. Have to see if either MADS can assemble an ASM geared toward DASM or can DASM also generate a label file. However I am figuring out tricks to help track down compiler errors faster now.

 

One other thing, a few 4 player games that will using 4 paddle controllers have been proposed to me. Noticed a few titles have not been ported to the 7800 and we may fill in those gaps.

Edited by peteym5
Link to comment
Share on other sites

  • 1 month later...

Took a while of tinkering with Tiled 1.0.3, but finally managed to make it generate plotmapfiles compatible with 7800basic. Having not used the program before, plus the way their online help is set up, made it look like embedding tilesets was removed. And indeed there's one location in the menus (where their online help indicates how to embed stuff - what to check) that has the embed checkmark grayed out.

 

Apparently you need to add a tileset to your map, and as you're adding it, mark it to be embedded right away. Not a good idea to press the tiny "embed" button after you've linked an external .tsx file as things start looking confusing with two copies of the tileset appearing. And when tiled goes to save the file at that point it likes to play around with the order of the tile sets unless they're embedded when they're initially added.

 

There were a few other issues I had with getting it to work but those were code related in terms of making sure certain setup functions are in the code before adding graphics. Having the graphics added first mucks up the indices as 7800basic compiles.

 

If you plan on reusing the same tilesets for multiple screens I'd recommend saving a template of a blank screen after you've gotten the tilesets embedded properly.

 

I still recommend adding that CVS encoding for the map data though. Far more compact and has the potential for convenient quick edits/updates to a map from the file itself in a text editor. :)

  • Like 2
Link to comment
Share on other sites

  • 1 month later...

 

Hey everybody, body of mine sent me a link to 7800 Basic Site, Got a copy and I tried a few things, and tested it in the emulator. I came here looking for some information. I would like to do some conversions of something made from other systems and never done for 7800. First go with something simple like a Bowling game, then go with the harder stuff.

I would like to start designing the sprites for the bowler and the ball. I am thinking about using characters lane, gutter and markings. and maybe something going on the sides. Should I do the pins with characters or sprites?

 

 

 

Link to comment
Share on other sites

  • 1 month later...

Is there a difference between tiles and sprites "under the hood"? Does the presence or absence of a tiled background affect how many sprites may be displayed in a particular zone?

 

Is there a formula to determine the maximum number of sprites that may be displayed in a particular zone, given a particular graphics mode?

Link to comment
Share on other sites

The short answer is no, there's not really a difference between tiles and sprites, and a background does affect how many sprites can be displayed for a few reasons.

 

The longer answer is that everything the 7800 draws is defined by a 'display list' that defines things like the size and palette of the object. It also defines where the data for the graphics comes from and the only real difference between a 'tile' and a 'sprite' is that the DL for a 'tile' points at a tile map to see what to draw instead of just reading a big chunk of data.

 

The DL doesn't specify the Y location of the object as everything is aligned to the zone (rows of 8 or 16 pixels in 7800BASIC) so anytime a sprite is not aligned to a zone it is effectively drawn twice or more depending on how many zones are covered. Optimising this is why 7800BASIC has a distinction between sprites and banners.

 

Fortunately the 7800 doesn't really care how many things it has to draw on screen as it works a zone at a time. An amount of memory is set aside to hold a number of DLs and this defines how many objects can be drawn in a zone.

That doesn't mean there isn't a limit to what can be drawn on the screen however as the MARIA only has so much time to process everything, so ultimately there's a limit to the amount of bytes of data that can be read overall. This means if you draw a lot of large objects you'll run out of time and some things will not be drawn.

 

I can go into yet more detail but I'm currently on my phone.

  • Like 2
Link to comment
Share on other sites

Let me ramble a bit, and hopefully give you the right picture.

 

There are two things that can put a cap on the maximum number of sprites in any given zone...

 

The first limiting factor, is how much object memory you've allocated for that zone. 7800basic does the allocation behind the scenes, dividing up a large block of memory by the number of zones you're trying to display. This value gets reported during compile time. For Salvo, which uses a regular screen height and zones that are 16 lines tall, this is 31 objects per zone. It's worth mentioning that 7800basic can also be told to use a larger block of memory for display objects, if you have it. (would need to be XM or on-cart memory, realistically)

 

The second limiting factor, is how many raw bytes you're asking Maria to chew on with your display objects, because Maria has a limited time to render the scanline. (the rendering of the scanline is also known as DMA time, so often people refer to how many "dma cycles" an object takes to display.)

 

A sprite object is fairly simple - it has the start address of the graphics, and the byte width of the graphics. From there, getting all of the graphics bytes involved is easy enough for Maria.

 

A tile object is a bit more complicated - it has the "text" address, and the byte width of the text string, and then Maria has to add each of the text bytes the Character set address, before it can fetch the graphics bytes. So tiles take more DMA time than sprites.

 

So to answer your original question, tiles are different under the hood than sprites, and a tiled background definitely impacts the maximum number of sprites you can draw.

 

There isn't a simple formula to figure out maximum sprites, and the process is a bit involved. Any given scanline has about 402 Maria cycles available for DMA. Each sprite takes up 10 cycles, for Maria to read the object info, and an additional 3 cycles per graphics byte. Best case, that would mean about 30 1-byte sprites per zone, assuming no tile objects.

 

But it's also a bit more complicated when you look beyond just a single zone, because when a sprite straddles two zones, it's really two sprites.

 

The DMA times are in the DMA Timing appendix of the 7800 Software Guide.

 

One gotcha - it will probably be difficult to get 30 sprites plotted each frame, as it takes CPU time to plot each sprite. To do a large number of sprites (more than Salvo) it's probably necessary to use double buffering.

 

 

If your game idea supports it, you might also consider using pre-shifted tiles as objects. This is one traditional way to get a lot of moving on-screen objects, using relatively few resources. Serpentine does this for the snakes, and the game could probably run 10x it's current speed.

 

Hopefully there's something of use here, in my wall of text.

  • Like 3
Link to comment
Share on other sites

Thanks! I'm looking at an open-source falling block puzzle game called Vexed, originally for the Palm Pilot. It had 10 columns and 8 rows of blocks. I was picturing making them 16x16, which would work vertically, but I think that would actually translate to 20 sprites (8 width) rather than 10 in each zone? If so, I'm assuming that is too much. Some of these are empty spaces or immovable blocks, but it varies from level to level, and there could in theory be 10 blocks in one row.

 

Would the rancharmap sample be a good starting point for looking into the "pre-shifted tiles" approach?

Link to comment
Share on other sites

That would still count as 10 objects / sprites a zone as each object can be 32 bytes wide. In 160A mode each pixel is 2 bits so that's up to 128 pixels wide.

Assuming only one or two blocks are moving on screen at a time and the blocks stay where they are when they land you can do what a lot of games used to do and have a 'sprite' fall down the screen until it lines up with a 'tile' that pops in behind it.

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

Having a look at one clone of the game, I think it's important that the blocks are colored differently, so the matching pairs are as distinctive as possible.

 

So you'd either need tiles in one of the higher color modes (like 160B), or you can to implement the blocks as sprites. (which can each have a unique palette)

 

I'm assuming you'd use 160A mode here, with double-width text. I'd just go ahead with using sprites for blocks, using a tile background for the barriers and background. Double-buffering is an option, but you shouldn't need it. 10 sprite updates per frame is easily doable without it. Salvo works in the same graphics mode, and updates about 20 sprites per frame.

 

Each byte of sprite width (ie. 4x fat pixels in 160A) takes 3 DMA cycles. With a 160A double-wide tile background, the 402 DMA cycles we have gets cut down to 222 cycles. Dividing that by 16 DMA cycles per sprite (10 cycles for the display object parsing, 6 cycles for reading the 2 bytes of sprite gfx), gives a max of 13 sprites per zone.

 

I don't see anything technical standing in your way here. If you're aiming for other graphic modes, then I think another approach might be required.

  • Like 1
Link to comment
Share on other sites

Been having trouble with for loops.

 

Below's a quick sample program. When you try to compile it you receive the error:

 

"*** (16): ERROR, bad non-variable value
Compilation failed.

 

The line number it's referencing is the "next" line. The actual culprit appears to be the "step -1" however. As if I try to do a for loop with an increasing value (either with or without a step parameter) it compiles properly. Is there something I'm missing here?

  set doublewide on
  displaymode 160A
  set screenheight 224  
  set tv ntsc 

  dim CurrentBGC = $2200
  dim TargetBGC = $2300
  
  
  for z = 24 to 2 step -1
    y = CurrentBGC[z]
    if y > TargetBGC[z] then y = y - 1 : CurrentBGC[z] = y
  next
Link to comment
Share on other sites

Not sure. I'll have to take a look at it and see. This is an area of 7800basic that it inherited from bB, and I haven't been deeply into it.

 

In the meantime, I believe "step 255" should work fine and produce the intended result.

Link to comment
Share on other sites

Another question as I debug things in an experiment, can we dim variables with non-variable expressions?

 

In other words, can I use "dim mapzone2 = mapzone1+20" to make sure mapzone2 always starts exactly 20 bytes after mapzone1? Main advantage to doing this is to prevent needing to calculate the exact address values of every starting zone, which is why I'm trying to do it. just want to make sure this is how it's expected to work while I continue to look through my tangled web of code. :)

Link to comment
Share on other sites

  • 3 months later...
  • 2 weeks later...

I have a question ... is there anyway to copy a font from ROM to RAM and then make the character set pointer reference the RAM location?  I am thinking about making a font editor in interlaced modes that is executable from the emulator, and using a hex dump to dump the font data into a binary file which can be then inserted into an .asm or .bas file

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...