Jump to content

Recommended Posts

13 hours ago, bsteux said:

No, unfortunately the doc is still missing. I'm currently refactoring the examples. In the process, I'll try to add some docs and explanation. In the meantime, don't hesitate to ask for help.

Thanks. I've been trying to modify the example_tiled2.c example to use my own 8x16 square tiles (160P mode), but trying to add my own tiles gives some unexpected results. And I'm not sure I exported my tiles properly using sprites7800. Or did I take the wrong approach? Note that I am not interested in sparse tiling, regular tiling works well for me.

Edited by l12n
On 10/15/2024 at 5:39 AM, bsteux said:

No, unfortunately the doc is still missing. I'm currently refactoring the examples. In the process, I'll try to add some docs and explanation. In the meantime, don't hesitate to ask for help.

My next question would be around sprites: what's the best way to dynamically determine the sprite to draw when calling multisprite_display_sprite (e.g. use different versions of the sprite when a character walks)? I looked at the include files and found a bunch of sprite functions (BTW what's the downside of multisprite_display_sprite_fast vs multisprite_display_sprite?) but nothing which takes an offset inside the sprite sheet.

I tried declaring an array of pointers containing my_sprite, my_sprite+32, my_sprite+64, etc. but the compiler doesn't seem to like this.

On 10/17/2024 at 6:14 AM, l12n said:

My next question would be around sprites: what's the best way to dynamically determine the sprite to draw when calling multisprite_display_sprite (e.g. use different versions of the sprite when a character walks)? I looked at the include files and found a bunch of sprite functions (BTW what's the downside of multisprite_display_sprite_fast vs multisprite_display_sprite?) but nothing which takes an offset inside the sprite sheet.

I tried declaring an array of pointers containing my_sprite, my_sprite+32, my_sprite+64, etc. but the compiler doesn't seem to like this.

To set the sprite to draw in sequence, one way is to use a simple pointer with offset, like in example_shmup.c (lines 530+, used to display the exhaust animation) :

                char *gfxptr;
                i = exhaust_state - 10;
                gfxptr = exhaust1 + i;
                x = spaceship_xpos + 4;
                multisprite_display_sprite_ex(x, y, gfxptr, 1, 3, 0);

or an array of pointers, like in example_RType2.c (line 130 + lines 489+, used to display the shield in front of RType ship) :

...
const char *R9_shield_sequence[] = {satellite1, satellite2, satellite3, satellite4};
...
        if (display_shield) {
            R9_shield_counter2++;
            if (R9_shield_counter2 == 5) {
                R9_shield_counter2 = 0;
                R9_shield_counter1++;
                if (R9_shield_counter1 == 4) R9_shield_counter1 = 0;
            }
            gfx = R9_shield_sequence[X = R9_shield_counter1];
            multisprite_display_sprite_ex(x, y, gfx, 4, 0, 1);
        }

 

BTW, the downside of using sprite_fast versions of macro instead of sprite or sprite_ex versions it that there is no memory boundary check for fast versions. If you add up too many sprites on the same display list, the _fast version will result in glitches/crash, while the usual function will just not display the sprite.

 

  • Like 1

@bsteux my next question would not be about the API but the build process. Just like the 7800basic, cc7800 generates a 8k/16k/32k binary but the .a78 is a few extra bytes larger (I assume it contains the 7800 header). Is there a way to generate a cart exactly 16386 / 32768 / ... bytes large? This matters if someone wants to burn the cart into an EEPROM. I notice some games such as Joust are exactly 32Kb large.

6 hours ago, l12n said:

@bsteux my next question would not be about the API but the build process. Just like the 7800basic, cc7800 generates a 8k/16k/32k binary but the .a78 is a few extra bytes larger (I assume it contains the 7800 header). Is there a way to generate a cart exactly 16386 / 32768 / ... bytes large? This matters if someone wants to burn the cart into an EEPROM. I notice some games such as Joust are exactly 32Kb large.

I strongly recommend to use the 7800AsmDevKit (from @RevEng at https://7800.8bitdev.org/index.php/7800AsmDevKit).

In this kit, you will not only find a suitable `dasm` executable (to be used with cc7800), but also '7800header` which has a nice strip option to save a headerless bin file ready to burn.

  • Like 2
9 hours ago, l12n said:

Are you saying that, when burning an EEPROM, one should burn a .bin file and not a .a78 file?

This is correct. 

 

The *.a78 files are designated as *.bin files with a header attached just before the ROM code for emulators and some flash cartridges to understand how to handle the binary data.

 

The *.bin files is only the ROM code designed to be burned to hardware cartridges that direct how the data is presented to the console.

  • Like 1
38 minutes ago, Trebor said:

This is correct. 

 

The *.a78 files are designated as *.bin files with a header attached just before the ROM code for emulators and some flash cartridges to understand how to handle the binary data.

 

The *.bin files is only the ROM code designed to be burned to hardware cartridges that direct how the data is presented to the console.

Good to know, thanks a lot for the explanation. Trying to burn a test 7800 app to an EEPROM with someone who has an EEPROM burner but we haven't found yet how to make it work.

33 minutes ago, l12n said:

Trying to burn a test 7800 app to an EEPROM with someone who has an EEPROM burner but we haven't found yet how to make it work.

If it is for an NTSC console, a proper encryption signature must be present.  When an Atari NTSC 7800 system starts up, the BIOS performs a mathematical algorithm using the data in the cartridge and the encryption key.

 

If this algorithm yields a valid result, the system is locked into 7800 mode and the cartridge is executed.

 

If the algorithm fails, the system is locked into 2600 mode and the cartridge is executed.

 

The aforementioned 7800AsmDevKit contains the program 7800sign to manage this feature.

The first mistake I made trying to create a cart was that the 7800 needs additional logic for generating the OE signal for the cart. You cannot connect an eeprom directly to the address bus and data bus and keep is active all the time. Only addresses intended for the cart should activate the read.

44 minutes ago, karri said:

The first mistake I made trying to create a cart was that the 7800 needs additional logic for generating the OE signal for the cart. You cannot connect an eeprom directly to the address bus and data bus and keep is active all the time. Only addresses intended for the cart should activate the read.

Would you have any resource explaining all this and how to flash a 7800 binary to an EEPROM?

27 minutes ago, l12n said:

Would you have any resource explaining all this and how to flash a 7800 binary to an EEPROM?

Basically to create a 48k cart you need to use a NOR gate. Monitor address pins A15 and A14. If they are both 0 then don't activate the ROM.

 

Here is a schematics of a small multicart I am releasing at eJagfest. It has two connectors. One is for the Lynx and the other is for the 7800. I happen to have a Lynx ROM burner so by setting the switch to 8 I can burn 512k to the cart. By turning the switch between 0..7 I can play 8 different games on the 7800.

A7800.svg

 

For flashing 512k to the ROM I use Lynx Joey flasher from BENNVENN.

 

The user interface of the Joey flasher is simple. When you plug it in your USB it opens a folder. Just drag the plain ROM image and it burns it on the flash rom on the cart. The process takes about 5s.

 

But. To use it like this you need the special firmware on the Joey cart that has the RAW mode supported.

 

If you want to flash a 48k binary to a 64k rom you need to flash 16k of 0xff to the bottom. And then 48k of 7800 data to the remaining 48k.

 

I hope this makes sense.

 

A much easier way is to use Otaku-flash that contains a Pico that emulates the rom and the electronics.

5 minutes ago, karri said:

Basically to create a 48k cart you need to use a NOR gate. Monitor address pins A15 and A14. If they are both 0 then don't activate the ROM

We are trying to burn a 16Kb cart. But it seems like one needs to create custom electronics around the EEPROM (and we're getting outside of the original cc7800 topic ;-)

  • Like 1
3 hours ago, l12n said:

We are trying to burn a 16Kb cart. But it seems like one needs to create custom electronics around the EEPROM (and we're getting outside of the original cc7800 topic ;-)

True. For a 16k cart you just need an inverter. A15 -> inverter -> OE*

On 10/25/2024 at 6:54 AM, l12n said:

Back to cc7800 @bsteux it seems like multisprite_set_charbase(tiles) is a no-op. Whatever argument that I pass, tiling_init() is always taking the first graphical asset defined in memory.

`multisprite_set_charbase(tiles)` is not a no-op. It sets the 8-bits CHARBASE register of Maria, as defined by :

#define multisprite_set_charbase(ptr) *CHARBASE = (ptr) >> 8;

As it uses only the higher byte of the parameter, you will not notice any difference when setting it to 0xA000 or 0xA080 for instance. This is due to the way Maria handles graphics. As it's a 8-bit chip, it builds the gfx effective address by combining (CHARBASE + line offset) for the higher byte, and the tile number as the lower byte. This means that the tiles gfx must start at a page boundary (multiple of 256 address) and must be scattered (i.e. the next line of each tile should be 256 bytes away). To make sure that these constraints are enforced, do insert your "tiles_gfx.h" first (before any other gfx) and make sure to use the `scattered` keyword to let `cc7800` generate the right layout (obvisouly, `sprites7800` does generate scattered gfxs...).

  • 1 month later...

@bsteux FYI, I added QuadTari support to my game (built using cc7800), and I had to tweak `joystick_init()`as it enables 2-button mode which is incompatible with the QuadTari. Also, the buttons need to be read differently with the QuadTari (you have to look at INPT4 and INPT5, which works even in a normal mode). I have some simple cc7800 code to read the QuadTari if you're interested.

  • Like 2
On 12/2/2024 at 5:44 AM, l12n said:

@bsteux FYI, I added QuadTari support to my game (built using cc7800), and I had to tweak `joystick_init()`as it enables 2-button mode which is incompatible with the QuadTari. Also, the buttons need to be read differently with the QuadTari (you have to look at INPT4 and INPT5, which works even in a normal mode). I have some simple cc7800 code to read the QuadTari if you're interested.

Yes, thanks, that would be a good addition to cc7800 headers collection. Would it be OK for you to share a quadtari.h header via this forum (if possible along with an example of use), or through Github Pull Request ?

I'm currently working on a refactoring of cc7800 (I'm currently updating all the examples to fit with the latest version of headers), that should be published in the week to come...

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