Jump to content
IGNORED

Sprites stuck on SuperCharger


Mr SQL

Recommended Posts

The sprites are sticking on the SuperCharger... anyone have an idea what's different?

 

BreaksOnSC.bin

 

The code runs fine on Stella and on the Harmony but when I run it on the SuperCharger the sprites get stuck.

 

I'm guessing there may be an "environment variable" (register) I'm not setting that is pre-configured when Stella or the Harmony runs a SuperCharger game?

Link to comment
Share on other sites

post-30777-0-69598200-1390578953_thumb.jpg

Found it! :) Was pretty interesting; there is indeed an "environment variable" not being set:

 

The bug is in both Stella and the Harmony firmware for emulating the SuperCharger which made it tough to find; I check my builds regularly in the emulator and semi-regularly on real hardware but I had been taking a shortcut and using the Harmony in the Parlour with the Vader as real hardware instead of the Junior in the basement with the SuperCharger.

 

Turns out I was playing Clu and had to use Tron to find the bug (Tron is a trace program that you write). Does anyone else ever code with Tron instead of using the debugger in Stella?

 

This is an example where you have to use Tron because you can't use the debugger - there's no 6502 Assembly code to debug in Stella when the bug is in Stella!

 

The game I am working on is running inside the ASDK Framework like DodgeIt PA in my signature, only it's using the SuperCharger version.

 

As a fun programming discussion/exercise, would anyone else like to try finding this bug with Tron or any other method (I'd be curious to see)? I can provide the commented asm for anyone who is interested.

 

I will share details on the bug presently so Stella and the Harmony firmware can be patched for better compability with the Starpath SuperCharger and the ASDK SuperCharger Gold Edition :)

 

Also curious if the Kroc and the Cuttle have this bug if someone could try the binary on them; you should see the sprites vibrating like they are stuck in molasses instead of moving all over the screen if they emulate the SuperCharger correctly.

 

Link to comment
Share on other sites

The Kroc doesn't do Supercharger. But as for the CC, I would guess it works, since the CC is based on Supercharger hardware.

 

There are a few things that I didn't bother implementing in Harmony. I vaguely recall some register where you can adjust the write delay from its normal 5 bus transistions, which doesn't seem useful for anything - is this it? It's also possible in SC to turn off the power to the ROM chip, which isn't possible to do in Harmony (and serves no practical function from a programming perspective, anyway.) There's also the issue of the BIOS. Neither Stella or Harmony use the "real" BIOS due to copyright reasons, so if you're relying on its contents (other than jump vectors for multiloads or something) then you will always find differences there.

 

Can you tell us a little about the nature of this bug, and what you did to trigger it?

Link to comment
Share on other sites

The Kroc doesn't do Supercharger. But as for the CC, I would guess it works, since the CC is based on Supercharger hardware.

 

There are a few things that I didn't bother implementing in Harmony. I vaguely recall some register where you can adjust the write delay from its normal 5 bus transistions, which doesn't seem useful for anything - is this it? It's also possible in SC to turn off the power to the ROM chip, which isn't possible to do in Harmony (and serves no practical function from a programming perspective, anyway.) There's also the issue of the BIOS. Neither Stella or Harmony use the "real" BIOS due to copyright reasons, so if you're relying on its contents (other than jump vectors for multiloads or something) then you will always find differences there.

 

Can you tell us a little about the nature of this bug, and what you did to trigger it?

bAtari,

it happens when bank switching; the Accumulator is not getting set on the Harmony and in Stella, but it is strangely getting set on the SuperCharger.

 

It turns out when you switch from bank 3/1 to bank 3/2 on the SC the contents of the registers are preserved (at least the Accumulator and Y) but when you switch from bank 3/2 to bank 3/1 the Accumulator contents get changed; it is seeded with a non binary value (overwrote my binary return).

 

I can't see any reason the Accumulator should get seeded from switching banks on the SC (and in one direction only!) but it does.

 

I'm updating the SuperCharger Edition of the ASDK to account for it. This bug shouldn't stop any SuperCharger games from being able to run on the Harmony or in Stella, but I think it would be good to fix for Developers.

 

Agree most of the BIOS isn't needed, very cool you have implemented support for multi-loads on the Harmony! :)

Link to comment
Share on other sites

I've looked at where you switch from those banks. It appears you are switching out the bank you are running in! You're not supposed to do that :)

 

My guess is that the Supercharger doesn't switch fast enough to fetch the next instruction, even if both banks contain the same data.

Link to comment
Share on other sites

I've looked at where you switch from those banks. It appears you are switching out the bank you are running in! You're not supposed to do that :)

 

My guess is that the Supercharger doesn't switch fast enough to fetch the next instruction, even if both banks contain the same data.

 

Yes the ASDK is using the same switchboard at the top of both switched banks (1&II) as the CBS RAM version. I am planning to replace it with a single switchboard in bank 3 to save space but it shouldn't make a difference (just confirmed this by making the call from bank 3 instead).

 

I'm going to test your theory to see if it's somehow missing the next instruction it's supposed to find after bankswitching (it was an RTS) and falling through to call the next routine in the switchboard - that would definitely change the accumulator and waste a lot of cycles...

 

Update: tested it by replacing my reload instruction with an equally weighted dummy instruction - still have vibrating sprites on the SuperCharger but works fine on the Harmony and in Stella - the SuperCharger insists on setting the contents of the Accumulator when switching from banks 3/2 to 3/1.

Link to comment
Share on other sites

DISCLAIMER: I no not what I speak.

 

Does the SuperCharger read its base routines (like for swapping tapes) from ROM or is it copied to RAM? I'm just wondering if those routines are copied to RAM that means they could be optimized/altered to free a byte or two for bank switching use..

 

Again, I don't fully understand bank switching technology so the above could be based on several false premises :)

Link to comment
Share on other sites

DISCLAIMER: I no not what I speak.

 

Does the SuperCharger read its base routines (like for swapping tapes) from ROM or is it copied to RAM? I'm just wondering if those routines are copied to RAM that means they could be optimized/altered to free a byte or two for bank switching use..

 

Again, I don't fully understand bank switching technology so the above could be based on several false premises :)

 

Loon,

great question! :) The SuperCharger reads it's routines from ROM and handles the ROM as a 4th memory bank in addition to the three 2k RAM/ROM banks.

 

We can't modify the ROM in the SuperCharger, and the portion that handles bankswitching (or some ideosyncracy of the SuperCharger hardware itself) appears to change the contents of the Accumulator when switching from 3/2 to 3/1.

 

With Stella and the Harmony firmware, this portion of the ROM was necessarily rewritten and is also interfacing with phantom hardware code; since the issue surfaces only in Stella and on the Harmony I think it must be in one of these areas.

Link to comment
Share on other sites

 

We can't modify the ROM in the SuperCharger, and the portion that handles bankswitching (or some ideosyncracy of the SuperCharger hardware itself) appears to change the contents of the Accumulator when switching from 3/2 to 3/1.

The only way to change the content of the registers in the 6502 is by running code on the 6502 that does this. But since the SC BIOS code isn't used for bankswitching, and the ROM bank isn't even mapped into the VCSs address space at the time of the switch, it must be your code that changes the accumulator.

 

If batari's theory is correct, and the SC isn't ready to serve the opcode for the RTS instruction right after the bankswitch, you might not nessessarily get an equal replacement, like you tested his theory with. If the the SC doesn't drive the data bus at the time of the instruction fetch, you'd probably get $00, which is BRK, or $FF, which is ISB absolute,X. Since ISB is a combination of INC and SBC it would definitely change the accumator. Or maybe you's get the value that was last on the data bus, which would be the value that the CMP $FFF8 instruction reads from address $FFF8.

 

Another theory might be a difference in the write pulse delay value which is part of the SC control register. The Stella emulator and the Harmony cart don't use this value for anything, but maybe on a real SC this value has some influence on how fast the SC could switch it's banks after a write to the control register?

Link to comment
Share on other sites

The only way to change the content of the registers in the 6502 is by running code on the 6502 that does this. But since the SC BIOS code isn't used for bankswitching, and the ROM bank isn't even mapped into the VCSs address space at the time of the switch, it must be your code that changes the accumulator.

 

If batari's theory is correct, and the SC isn't ready to serve the opcode for the RTS instruction right after the bankswitch, you might not nessessarily get an equal replacement, like you tested his theory with. If the the SC doesn't drive the data bus at the time of the instruction fetch, you'd probably get $00, which is BRK, or $FF, which is ISB absolute,X. Since ISB is a combination of INC and SBC it would definitely change the accumator. Or maybe you's get the value that was last on the data bus, which would be the value that the CMP $FFF8 instruction reads from address $FFF8.

 

Another theory might be a difference in the write pulse delay value which is part of the SC control register. The Stella emulator and the Harmony cart don't use this value for anything, but maybe on a real SC this value has some influence on how fast the SC could switch it's banks after a write to the control register?

 

Eckhard,

good points and interesting ideas; pehaps the SC serves up an instruction during the delay somehow I just can't see how it can be from my code, the call is pretty straight forward:

post-30777-0-60790100-1391017510_thumb.jpg

 

The purple routine in Bank2 does a "lda b" right before its RTS, loading the Accumulator from low RAM. On the SuperCharger hardware I have to reload it again after bankswitching from 3/2 to 3/1.

 

If you have a SuperCharger I can send you the source to try it out or just to look over but the Stella debugger can't help since it runs the code differently.

Link to comment
Share on other sites

If you have a SuperCharger I can send you the source to try it out or just to look over but the Stella debugger can't help since it runs the code differently.

Yes, I have a Supercharger and a Cuttle Cart to test your program on, so I could have a look at your code, if you want to.

 

Some things I noticed from your picture:

IIRC, writes to the SC control register happen immediately, so the NOPs shouldn't be necessary.

 

And the SC BIOS figures out the necessary write pulse delay value at startup and stores it together with the current bank configuration in address $80 when it passes control to the game. Since your game has problems on a real SC, maybe it might be worth a try to keep the topmost three bits of the byte intact instead of setting them always to zero, and ORA them into your bank configuration value before writing it to the SC control byte. Maybe this helps fixing your problem.

Link to comment
Share on other sites

post-30777-0-54517400-1391529794_thumb.jpg

Update for developers:

 

Awesome developer teamwork with Eckhard! :) We've determined how the "environment variable" (register) is being set differently by the SuperCharger hardware than Stella/Harmony's phantom hardware when bankswitching.

 

The hotspot for the phantom hardware returns a zero while the hotspot on the real hardware does not (probably 255).

 

Eckhard drilled into the code and found I was calling the function like this:

 

jsr getbitstatus
beq

 

The branch below the call relies on the implicit cmp #0 that occurs when the return value fom the function is loaded into the accumulator - this gets stored in the cc register which is what was being changed by the real Hardware!

 

The 0 returned by the phantom hardware functions as pass through for the implicit cmp #0 (because it just duplicates it) which does not change the "environment variable" (register) like the real Hardware does.

 

I will have an updated version of the SuperCharger ASDK out with the fix for the real Hardware presently - along with some other fixes and enhancements :)

 

I think it would be helpful to developers if Stella/Harmony were updated so that SuperCharger bankswitching (the byte for the hotspot) matches the real hardware.

 

  • Like 1
Link to comment
Share on other sites

I think it would be helpful to developers if Stella/Harmony were updated so that SuperCharger bankswitching (the byte for the hotspot) matches the real hardware.

 

stephena's very good about fixing issues like this, but you'll need to post about it here since he might never see this topic. He'll need an example program that works correctly on the SuperCharger but not in Stella.

 

Are you knowledgeable with C? If so you could download the source and fix it yourself, then submit the revisions to him. The files to change would most likely be:

  • stella/src/emucore/CartAR.cxx
  • stella/src/emucore/CartAR.hxx

AR = Arcadia (Starpath's original company name).

Edited by SpiceWare
Link to comment
Share on other sites

 

stephena's very good about fixing issues like this, but you'll need to post about it here since he might never see this topic. He'll need an example program that works correctly on the SuperCharger but not in Stella.

 

Are you knowledgeable with C? If so you could download the source and fix it yourself, then submit the revisions to him. The files to change would most likely be:

  • stella/src/emucore/CartAR.cxx
  • stella/src/emucore/CartAR.hxx

AR = Arcadia (Starpath's original company name).

 

Thanks Spice I'll share the details on the Stella thread!

 

Stella is open source so Stephena can probably resource thousands of developers, maybe millions of them :)

Link to comment
Share on other sites

Thanks all for figuring this out. I looked at code but could not (though I did suspect the value read from the hotspot was not correct, I could not find anywhere where you used the flags as pointed out above.)

 

So what exactly needs to be changed? Does the hotspot always read $FF, or the contents of the current bank, or new bank, or something else? I can make it either, but I want to be sure of the exact behavior so it can be done right.

Link to comment
Share on other sites

Thanks all for figuring this out. I looked at code but could not (though I did suspect the value read from the hotspot was not correct, I could not find anywhere where you used the flags as pointed out above.)

 

So what exactly needs to be changed? Does the hotspot always read $FF, or the contents of the current bank, or new bank, or something else? I can make it either, but I want to be sure of the exact behavior so it can be done right.

 

You're welcome, great teamwork trying different ideas and analysing the code with you earlier as well!! :)

 

I will try loading the hotspot byte into COLUBK to confirm if it looks like $FF as Eckhard suspected; interesting idea that it could change depending upon which bank you're in. If the default value is not $FF when the static RAM is not initialised, perhaps it could even contain random data like the RIOT? I'll repeat this test a couple of times to see.

Link to comment
Share on other sites

 

You're welcome, great teamwork trying different ideas and analysing the code with you earlier as well!! :)

 

I will try loading the hotspot byte into COLUBK to confirm if it looks like $FF as Eckhard suspected; interesting idea that it could change depending upon which bank you're in. If the default value is not $FF when the static RAM is not initialised, perhaps it could even contain random data like the RIOT? I'll repeat this test a couple of times to see.

It looks like Stella and Harmony both reveal the byte that is "under" the hotspot, which actually is $00 in all three banks.

 

If the Supercharger does not drive the bus, you might expect $FF (which would be the last value on the bus - CMP $FFF8 will fetch $2C, $F8, $FF.) So it's worth trying $1FF8, for instance, to see if this is true. This behavior can be simulated easily enough in Stella and Harmony, and this is a good time for Harmony as a BIOS update is in the works.

Link to comment
Share on other sites

It looks like Stella and Harmony both reveal the byte that is "under" the hotspot, which actually is $00 in all three banks.

 

If the Supercharger does not drive the bus, you might expect $FF (which would be the last value on the bus - CMP $FFF8 will fetch $2C, $F8, $FF.) So it's worth trying $1FF8, for instance, to see if this is true. This behavior can be simulated easily enough in Stella and Harmony, and this is a good time for Harmony as a BIOS update is in the works.

It seems to be a bit more complicated than that. If I do

 

ldx #$09

cpx $f000,x

lda $fff8

 

I get the value that is at address $fff8. But if I do

 

ldx #$09

cpx $f000,x

nop

lda $fff8

 

the SC will do a write to the RAM at address $fff8 too, even when writing is disabled. Therefore the the LDA will return the newly written value most of the time. Sometimes some bits are not set though. I haven't figured out why yet. It might be that I was switching the RAM bank that is mapped into $fff8.

Link to comment
Share on other sites

It seems to be a bit more complicated than that. If I do

 

ldx #$09

cpx $f000,x

lda $fff8

 

I get the value that is at address $fff8. But if I do

 

ldx #$09

cpx $f000,x

nop

lda $fff8

 

the SC will do a write to the RAM at address $fff8 too, even when writing is disabled. Therefore the the LDA will return the newly written value most of the time. Sometimes some bits are not set though. I haven't figured out why yet. It might be that I was switching the RAM bank that is mapped into $fff8.

Interesting. I would guess that the 5-bus transition write is active, but accessing $1FF8 before the fifth transition will stifle the write. Does it happen when switching from a write to a read-enabled bank, a read to a write-emabled bank, or does it switch even when going between two read-only banks? What happens when going more than the 5 bus transitions?

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