Jump to content
IGNORED

Atari Flashback Portable programming considerations


Karl G

Recommended Posts

I am splitting this topic from the AFP hacks topic, collecting information on how to code new projects to be compatible with the AFP.

 

Here's a list of what is known so far, mostly provided by Nukey:

Controllers/Switches:
The AFP has the equivalent of one joystick controller. Two player turn games would have to use the same joystick for each player.
The AFP has the console switches as buttons, an these can be repurposed for other functions in a game.
Overly frequent port polling (SWCHA/SWCHB) seems to cause issues
The color/bw switch does not keep its state, similar to the Atari 7800.
Emulation Limitations:
DPC+ is completely unsupported
code in VBLANK doesn't seem to work.
Mirrored RIOT addresses are not supported
Superchip RAM is not detected if it is zeroed out.
"Illegal" opcodes are not supported (except for DCP and SBX?)
Early HMOVE does not work
+1 cycle by branch over page does not work
For bB users (like me), the titlescreen kernel sadly does not work on the portable, either, but it shouldn't prevent the game from running.
Any other considerations that I have missed?
Nukey had a thought on how the AFP could be detected in code, but I'm afraid it flew over my head:
In that regard, the AFP should actually be detectable (just do a late PF write that has no effect on real hardware but DOES on the AFP, and check for a sprite collision positioned there)

 

Could anyone expand on this, or show a code sample that can test if it's running on the AFP?

  • Like 1
Link to comment
Share on other sites

I'm not sure if I should post this issue in this forum or the bB forum, but I am working on a game that seems like it should be compatible with the FBP, but isn't working there. It's written in batari basic using the standard kernel with 16k, no superchip RAM. I stripped out most of my code to try to find the cause, and discovered that it does work if everything is shoved into one bank, so it is definitely bankswitching-related. I was wondering if anyone could guess why the FBP isn't detecting the ROM correctly with bankswitching enabled? I couldn't find anything that I extracted from the other topic that seems to apply here. I'm attaching the basic source, the generated assembly, and the ROM of a stripped-down version that demonstrates the problem. Any advice would be much appreciated!

 

 

portable-fail.bas

portable-fail.bas.asm

portable-fail.bas.bin

Link to comment
Share on other sites

  • 2 weeks later...

I'm not sure if I should post this issue in this forum or the bB forum, but I am working on a game that seems like it should be compatible with the FBP, but isn't working there. It's written in batari basic using the standard kernel with 16k, no superchip RAM. I stripped out most of my code to try to find the cause, and discovered that it does work if everything is shoved into one bank, so it is definitely bankswitching-related. I was wondering if anyone could guess why the FBP isn't detecting the ROM correctly with bankswitching enabled? I couldn't find anything that I extracted from the other topic that seems to apply here. I'm attaching the basic source, the generated assembly, and the ROM of a stripped-down version that demonstrates the problem. Any advice would be much appreciated!

 

 

 

The Portable only detects banks that are mostly full, add ballast code (data statements or unused routines) to pad the banks that are lean.

Link to comment
Share on other sites

The Portable only detects banks that are mostly full, add ballast code (data statements or unused routines) to pad the banks that are lean.

 

Thanks! That is handy to know, but it doesn't seem to be the cause of my issue in this case. I completely filled up both banks with data that is all $FF, but I still have the same result. The "padded" version is attached. Any ideas?

 

 

portable-fail.bas

portable-fail.bas.asm

portable-fail.bas.bin

Link to comment
Share on other sites

 

Thanks! That is handy to know, but it doesn't seem to be the cause of my issue in this case. I completely filled up both banks with data that is all $FF, but I still have the same result. The "padded" version is attached. Any ideas?

 

 

You're welcome! :)

 

I took a look at the padded version. You can use any filler, $FF is only needed at the top of the banks to initialize superchip RAM.

 

Can't tell why this game isn't working. Maybe try compiling it with bB 1.0 to check if there is a compatibility issue with some of the new code. If you accidentally referenced a location instead of a value somewhere that could do it also, those are hard to find.

Link to comment
Share on other sites

I appreciate you looking at it. I know it's definitely related to bankswitching since I can get the same code to run when I compile it to 4K. Even a simple "hello world" example breaks when I make it 8K or larger, though. Good thought on the compiler version possibly making a difference. I should probably move the discussion over to the bB forum, anyway.

  • Like 1
Link to comment
Share on other sites

 

If it works on a 2600 then the problem is not on you, it's on the sloppy emulation in the portable.

 

True. :) Though I'm not always the most meticulous about counting my cycles at times. ;) I was trying to think if I had played Space Invaders on the FBP, so couldn't remember if it had a problem with that multi-sprite or not.

Edited by Jinroh
Link to comment
Share on other sites

I appreciate you looking at it. I know it's definitely related to bankswitching since I can get the same code to run when I compile it to 4K. Even a simple "hello world" example breaks when I make it 8K or larger, though. Good thought on the compiler version possibly making a difference. I should probably move the discussion over to the bB forum, anyway.

 

Using the 1.0 bB compiler from batari's site I was able to compile 8K superchip games (that were already nearly full in both banks) without having to make any changes at all but I didn't try 16k or other formats, possibly each one may have it's nuances.

 

There's been some speculation the portable also uses detection so it might have special handling for these.

 

I'll follow the other thread when you post it, curious what is keeping it from running.

 

Jinroh,

Carrot Kingdom plays awesome on the portable! :) The player sprite isn't as solid as it is on the full size consoles but I think that's because of the LCD.

  • Like 1
Link to comment
Share on other sites

Jinroh,

Carrot Kingdom plays awesome on the portable! :) The player sprite isn't as solid as it is on the full size consoles but I think that's because of the LCD.

 

Thanks! :) Yeah it doesn't play too badly, a few graphical glitches, but solid. Definitely the LCD isn't as forgiving as a CRT when it comes to flicker, AtGames needs to put a toggle for flicker like Stella, though they have other problems they should probably fix first. ;)

Link to comment
Share on other sites

 

Thanks! :) Yeah it doesn't play too badly, a few graphical glitches, but solid. Definitely the LCD isn't as forgiving as a CRT when it comes to flicker, AtGames needs to put a toggle for flicker like Stella, though they have other problems they should probably fix first. ;)

 

You're retriggering the sprites (multiple RESPx per line) here if I am not mistaken :) That's not what Space invaders does; it just uses all three copies to display six invaders total. Retriggering is pretty tricky to emulate correctly, so I am not surprised that the portable does not render it correctly.

Edited by DirtyHairy
Link to comment
Share on other sites

+1 cycle for branching over page breaks, and some "illegal" opcodes ARE supported. The video issues* was what lead to those false assumptions. But like anything here, what works in one game may not in another.

 

* The window of opportunity to rewrite any graphics registers mid-scanline is VERY short on the portable. Anything not cycle-exact is a potential problem. I've even had to tweak writes that were originally cycle-exact (it's goofy). The only way to know for sure is to try running the program to see if the emulator can deal with it.

 

The same goes for bankswitch mode detection...some work and others don't. Altering ones that don't slightly (such as filling RAM addresses with $FF or filling unused ROM areas with hotspot calls) *may* help the emulator to determine what it's supposed to be doing.

 

I have no theories to why VBLANK sometimes fails (migrating the screen downward), or why sprite positioning is so hit-and-miss (garbled scores...or worse problems like seen in Berzerk).

 

Hopefully, emulation in the next generation portable will be closer and these hacks can be abandoned.

  • Like 2
Link to comment
Share on other sites

The same goes for bankswitch mode detection...some work and others don't. Altering ones that don't slightly (such as filling RAM addresses with $FF or filling unused ROM areas with hotspot calls) *may* help the emulator to determine what it's supposed to be doing.

 

In my case, it was determined that filling my unused ROM areas with "ballast data" worked, but not when it was filled with $FF. It worked when a different arbitrary number was used ($37 in this case, as discovered by Mr SQL).

 

Agreed about hoping for a better emulator for the next iteration for the portable!

Link to comment
Share on other sites

  • 4 weeks later...

I've discovered this RESPx thing in Atari Flashback Portable while changing Atomchess to use venetian blinds.

 

It doesn't emulate the internal TIA counter for 160 clocks in order to reset outputting GRP0/GRP1.

 

It took me 2 days to understand it from the "TIA HW docs" but works as follows:

 

1. There is an internal TIA counter for players 0/1, it counts 160 clocks starting from where GRP0/GRP1 is displayed.

2. You can reset RESP0/RESP1 in the same line where player 0/1 is displayed BUT it will not show until the TIA counter counts down to zero.

3. This means the RESP0/RESP1 register doesn't do anything for single player copies moved to the left but works for moving to right in the next scanline.

 

This was the trick I finally used for Atomchess.

 

But as the Flashback doesn't have this counter, it generates ghost images of pieces at the right in the same scanline. It could be solved putting zeros in GRP0/GRP1 but currently I don't have enough cycles in display loop.

Link to comment
Share on other sites

This is about correct, but I would phrase things slightly differently: the counter counts from 0 to 159 (actually, it is 0 to 39 as the clock is divided by four) and is wired to a decode matrix. At certain counter states (which depend on the value of NUSIZ for players and missile), the decode matrix latches and rendering is triggered. For the first copy, the decode is at 156 (just before the real divide-by-four counter wraps). Strobing RESPx will cause the counter to wrap immediatelly after four more color clocks, but it will not trigger the decode, so you'll have to wait for another full scanline for the first copy to appear (for the sake of completeness, the actual counter state after a RESPx is slightly different during hblank). However, any other copies will appear on the first scanline after RESPx, too.

 

The same mechanism essentially also applies to the other sprites; however, for the ball, RESPBL also triggers a decode.

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

This is about correct, but I would phrase things slightly differently: the counter counts from 0 to 159 (actually, it is 0 to 39 as the clock is divided by four) and is wired to a decode matrix. At certain counter states (which depend on the value of NUSIZ for players and missile), the decode matrix latches and rendering is triggered. For the first copy, the decode is at 156 (just before the real divide-by-four counter wraps). Strobing RESPx will cause the counter to wrap immediatelly after four more color clocks, but it will not trigger the decode, so you'll have to wait for another full scanline for the first copy to appear (for the sake of completeness, the actual counter state after a RESPx is slightly different during hblank). However, any other copies will appear on the first scanline after RESPx, too.

 

The same mechanism essentially also applies to the other sprites; however, for the ball, RESPBL also triggers a decode.

 

Thanks! actually RESPx works easier with NUSIZ set up to multiple copies, because the 2nd and 3rd copy retrigger the display, this is used by various demos. But I needed it to work with a single copy because I'm using double-wide players.

Link to comment
Share on other sites

  • 1 year later...

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