Jump to content

Photo

Sprites stuck on SuperCharger

SuperCharger sprites StarPath Arcadia Orange Juice

18 replies to this topic

#1 Mr SQL OFFLINE  

Mr SQL

    River Patroller

  • 2,096 posts

Posted Fri Jan 24, 2014 1:23 AM

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

 

Attached File  BreaksOnSC.bin   8.25KB   131 downloads

 

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?



#2 Mr SQL OFFLINE  

Mr SQL

    River Patroller

  • Topic Starter
  • 2,096 posts

Posted Fri Jan 24, 2014 10:05 AM

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

 



#3 batari OFFLINE  

batari

    )66]U('=I;B$*

  • 6,680 posts
  • begin 644 contest

Posted Sun Jan 26, 2014 2:27 AM

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?



#4 Mr SQL OFFLINE  

Mr SQL

    River Patroller

  • Topic Starter
  • 2,096 posts

Posted Sun Jan 26, 2014 3:59 PM

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! :)



#5 batari OFFLINE  

batari

    )66]U('=I;B$*

  • 6,680 posts
  • begin 644 contest

Posted Sun Jan 26, 2014 5:13 PM

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.



#6 Mr SQL OFFLINE  

Mr SQL

    River Patroller

  • Topic Starter
  • 2,096 posts

Posted Mon Jan 27, 2014 8:50 AM

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.      



#7 Gemintronic OFFLINE  

Gemintronic

    Jason S. - Lead Developer & CEO

  • 9,328 posts

Posted Mon Jan 27, 2014 9:08 AM

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 :)



#8 Mr SQL OFFLINE  

Mr SQL

    River Patroller

  • Topic Starter
  • 2,096 posts

Posted Mon Jan 27, 2014 10:38 AM

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.



#9 Eckhard Stolberg OFFLINE  

Eckhard Stolberg

    Dragonstomper

  • 957 posts
  • Location:Germany

Posted Tue Jan 28, 2014 12:44 PM

 

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?



#10 Mr SQL OFFLINE  

Mr SQL

    River Patroller

  • Topic Starter
  • 2,096 posts

Posted Wed Jan 29, 2014 12:03 PM

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: 

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



#11 Eckhard Stolberg OFFLINE  

Eckhard Stolberg

    Dragonstomper

  • 957 posts
  • Location:Germany

Posted Wed Jan 29, 2014 1:02 PM

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.



#12 Mr SQL OFFLINE  

Mr SQL

    River Patroller

  • Topic Starter
  • 2,096 posts

Posted Tue Feb 4, 2014 10:06 AM

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

 



#13 SpiceWare OFFLINE  

SpiceWare

    Draconian

  • 12,747 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Tue Feb 4, 2014 10:16 AM

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, Tue Feb 4, 2014 10:16 AM.


#14 Mr SQL OFFLINE  

Mr SQL

    River Patroller

  • Topic Starter
  • 2,096 posts

Posted Tue Feb 4, 2014 7:23 PM

 

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 :) 



#15 batari OFFLINE  

batari

    )66]U('=I;B$*

  • 6,680 posts
  • begin 644 contest

Posted Tue Feb 4, 2014 11:59 PM

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.

#16 Mr SQL OFFLINE  

Mr SQL

    River Patroller

  • Topic Starter
  • 2,096 posts

Posted Thu Feb 6, 2014 12:02 PM

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.



#17 batari OFFLINE  

batari

    )66]U('=I;B$*

  • 6,680 posts
  • begin 644 contest

Posted Thu Feb 6, 2014 6:03 PM

 

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.



#18 Eckhard Stolberg OFFLINE  

Eckhard Stolberg

    Dragonstomper

  • 957 posts
  • Location:Germany

Posted Fri Feb 7, 2014 3:46 PM

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.



#19 batari OFFLINE  

batari

    )66]U('=I;B$*

  • 6,680 posts
  • begin 644 contest

Posted Fri Feb 7, 2014 7:50 PM

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?







Also tagged with one or more of these keywords: SuperCharger, sprites, StarPath, Arcadia, Orange Juice

0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users