News: 11 March 2016 - Forum Rules

Author Topic: SNES architecture quirk?  (Read 6799 times)

Gideon Zhi

  • Discord Staff
  • Hero Member
  • *****
  • Posts: 3536
    • View Profile
    • Aeon Genesis
SNES architecture quirk?
« on: October 24, 2013, 04:45:23 am »
So one of the games I'm working on has compressed code, which is unpacked and executed from RAM. Most of this is text pointers, but I've uncovered a much more complex bit of code that needs some major retooling - in this case, tilemapping code. Rather than have to rebuild the compressed binary into the game every time I change the code, stuck the code at DBFA00 (lorom addr) in the game binary, and a JML $DBFA00 in the compressed binary. The JML gets loaded into RAM at $7E8D4C.

The issue is that while the code works in SNES9X, it's crashing the game in ZSNES and I don't have immediate access to that area of the game in BSNES.

Here's the code I wrote, with the original code commented out above it. Note that if I remove the comments at the top of the file, essentially replicating the original functionality just with the JML hooks, the code STILL crashes ZSNES, so it's not necessarily any of my actual code. My guess is that it's an architecture quirk with JMLs out of and back into RAM.

(Just as a bit of background, the text was originally 16-bit. My version is 8-bit with DTE support at A>=0x50. The adjustments to the tilemapping reflect that.)

Code: [Select]
lorom
;$7E/8D4C: B7 A0        LDA [$A0],Y [$7E:7A86]    A:75BE X:004B Y:0006 D:0200 DB:00 S:01FA P:envMXdizc HC:776 VC:239
;$7E/8D4E: C9 20        CMP #$20                  A:755D X:004B Y:0006 D:0200 DB:00 S:01FA P:envMXdizc HC:864 VC:239
;$7E/8D50: F0 31        BEQ $31 [$8D83]           A:755D X:004B Y:0006 D:0200 DB:00 S:01FA P:envMXdizC HC:920 VC:239
;$7E/8D52: 5A           PHY                       A:755D X:004B Y:0006 D:0200 DB:00 S:01FA P:envMXdizC HC:976 VC:239
;$7E/8D53: AD F2 0F     LDA $0FF2 [$00:0FF2]      A:755D X:004B Y:0006 D:0200 DB:00 S:01F9 P:envMXdizC HC:1038 VC:239
;$7E/8D56: EB           XBA                       A:7521 X:004B Y:0006 D:0200 DB:00 S:01F9 P:envMXdizC HC:1110 VC:239
;$7E/8D57: AD F9 0F     LDA $0FF9 [$00:0FF9]      A:2175 X:004B Y:0006 D:0200 DB:00 S:01F9 P:envMXdizC HC:1170 VC:239
;$7E/8D5A: C2 20        REP #$20                  A:2100 X:004B Y:0006 D:0200 DB:00 S:01F9 P:envMXdiZC HC:1242 VC:239
;$7E/8D5C: 87 3D        STA [$3D] [$7F:75BE]      A:2100 X:004B Y:0006 D:0200 DB:00 S:01F9 P:envmXdiZC HC:1328 VC:239
;$7E/8D5E: 1A           INC A                     A:2100 X:004B Y:0006 D:0200 DB:00 S:01F9 P:envmXdiZC HC:056 VC:240
;$7E/8D5F: A0 02        LDY #$02                  A:2101 X:004B Y:0006 D:0200 DB:00 S:01F9 P:envmXdizC HC:110 VC:240
;$7E/8D61: 97 3D        STA [$3D],Y [$7F:75C0]    A:2101 X:004B Y:0002 D:0200 DB:00 S:01F9 P:envmXdizC HC:190 VC:240
;$7E/8D63: 1A           INC A                     A:2101 X:004B Y:0002 D:0200 DB:00 S:01F9 P:envmXdizC HC:286 VC:240
;$7E/8D64: A0 40        LDY #$40                  A:2102 X:004B Y:0002 D:0200 DB:00 S:01F9 P:envmXdizC HC:340 VC:240
;$7E/8D66: 97 3D        STA [$3D],Y [$7F:75FE]    A:2102 X:004B Y:0040 D:0200 DB:00 S:01F9 P:envmXdizC HC:420 VC:240
;$7E/8D68: 1A           INC A                     A:2102 X:004B Y:0040 D:0200 DB:00 S:01F9 P:envmXdizC HC:516 VC:240
;$7E/8D69: A0 42        LDY #$42                  A:2103 X:004B Y:0040 D:0200 DB:00 S:01F9 P:envmXdizC HC:570 VC:240
;$7E/8D6B: 97 3D        STA [$3D],Y [$7F:7600]    A:2103 X:004B Y:0042 D:0200 DB:00 S:01F9 P:envmXdizC HC:650 VC:240
;$7E/8D6D: E2 20        SEP #$20                  A:2103 X:004B Y:0042 D:0200 DB:00 S:01F9 P:envmXdizC HC:746 VC:240
;$7E/8D6F: 1A           INC A                     A:2103 X:004B Y:0042 D:0200 DB:00 S:01F9 P:envMXdizC HC:808 VC:240
;$7E/8D70: 8D F9 0F     STA $0FF9 [$00:0FF9]      A:2104 X:004B Y:0042 D:0200 DB:00 S:01F9 P:envMXdizC HC:862 VC:240
;$7E/8D73: A5 3D        LDA $3D [$00:023D]        A:2104 X:004B Y:0042 D:0200 DB:00 S:01F9 P:envMXdizC HC:934 VC:240
;$7E/8D75: 18           CLC                       A:21BE X:004B Y:0042 D:0200 DB:00 S:01F9 P:eNvMXdizC HC:998 VC:240
;$7E/8D76: 69 04        ADC #$04                  A:21BE X:004B Y:0042 D:0200 DB:00 S:01F9 P:eNvMXdizc HC:1052 VC:240
;$7E/8D78: 90 02        BCC $02 [$8D7C]           A:21C2 X:004B Y:0042 D:0200 DB:00 S:01F9 P:eNvMXdizc HC:1108 VC:240
;$7E/8D7A: E6 3E        INC $3E [$00:023E]        A:2100 X:003F Y:0042 D:0200 DB:00 S:01F9 P:envMXdiZC HC:940 VC:244
;$7E/8D7C: 85 3D        STA $3D [$00:023D]        A:21C2 X:004B Y:0042 D:0200 DB:00 S:01F9 P:eNvMXdizc HC:1170 VC:240
;$7E/8D7E: 7A           PLY                       A:21C2 X:004B Y:0042 D:0200 DB:00 S:01F9 P:eNvMXdizc HC:1234 VC:240
;$7E/8D7F: C8           INY                       A:21C2 X:004B Y:0006 D:0200 DB:00 S:01FA P:envMXdizc HC:1302 VC:240
;$7E/8D80: C8           INY                       A:21C2 X:004B Y:0007 D:0200 DB:00 S:01FA P:envMXdizc HC:1356 VC:240
;$7E/8D81: 80 C9        BRA $C9 [$8D4C]           A:21C2 X:004B Y:0008 D:0200 DB:00 S:01FA P:envMXdizc HC:042 VC:241

org $DBFA00
  ;LDA [$A0],Y
  ;CMP #$20
  ;JMP $7E8D50

RomAddr:
  LDA [$A0],Y
  CMP #$50
  BCS TilemapDTE
  CMP #$20
  BNE TilemapRegular
  BRL Exit
 
TilemapDTE:
  PHY
  LDA $0FF2
  XBA
  LDA $0FF9
  REP #$20
  STA [$3D]
  INC A
  LDY #$40
  STA [$3D],Y
  INC A
  LDY #$02
  STA [$3D],Y
  INC A
  LDY #$42
  STA [$3D],Y
  SEP #$20
  INC A
  STA $0FF9
  LDA $3D
  CLC
  ADC #$04
  BCC $02
  INC $3D
  STA $3D
  PLY
  INY
  BRA RomAddr
 
TilemapRegular:
  PHY
  LDA $0FF2
  XBA
  LDA $0FF9
  REP #$20
  STA [$3D]
  INC A
  LDY #$40
  STA [$3D],Y
  SEP #$20
  INC A
  STA $0FF9
  LDA $3D
  CLC
  ADC #$02
  BCC $02
  INC $3D
  STA $3D
  PLY
  INY
  BRA RomAddr

Exit:
  JMP $7E8D83

assassin

  • Full Member
  • ***
  • Posts: 154
    • View Profile
    • My Barren Webpage
Re: SNES architecture quirk?
« Reply #1 on: October 24, 2013, 08:19:12 am »
- to be sure, it's not one of the games that needs special steps or packages to run with ZSNES in the first place, is it?
- i notice the commented out code will "INC $3E" if the addition to $3D overflows.  in contrast, the new code (in two spots) will "INC $3D".  that seems superfluous, with an "STA $3D" right after it.  is this intended?  yes, i realize it has nothing to do with crashing.
- following your theory about the dual JMLs, if you change the "JML $DBFA00" to "JSL $DBFA00", and the "JMP $7E8D83" to "RTL", will it run right?  alternatively, keep the "JML $DBFA00", and change the "JMP $7E8D83" to "PEA $8D82 / LDA #$7E / PHA / RTL" (err, i hope that pushing order is right).

lytron

  • Jr. Member
  • **
  • Posts: 58
    • View Profile
    • pantalytron.com
Re: SNES architecture quirk?
« Reply #2 on: October 24, 2013, 09:36:52 am »
Is a JMP with a 24-bit-address compiled correct? I only know it in combination with a JML, but it depends on which compiler you use.

denim

  • Jr. Member
  • **
  • Posts: 19
    • View Profile
Re: SNES architecture quirk?
« Reply #3 on: October 24, 2013, 12:08:00 pm »
Is a JMP with a 24-bit-address compiled correct? I only know it in combination with a JML, but it depends on which compiler you use.

Xkas 0.14 doesn't allow the use of JMP with 24-bit address. But maybe he is using another compiler.

Lenophis

  • Discord Staff
  • Hero Member
  • *****
  • Posts: 971
  • The return of the sombrero!
    • View Profile
    • Slick Productions
Re: SNES architecture quirk?
« Reply #4 on: October 24, 2013, 12:19:20 pm »
If xkas v0.14 won't let you use a legitimate SNES instruction, there's a problem. Good thing it works in 0.06. :p This sounds more like a Zsnes issue, though.


https://ff6randomizer.codeplex.com/ - Randomize your FF6 experience!

Gideon Zhi

  • Discord Staff
  • Hero Member
  • *****
  • Posts: 3536
    • View Profile
    • Aeon Genesis
Re: SNES architecture quirk?
« Reply #5 on: October 24, 2013, 02:36:31 pm »
- to be sure, it's not one of the games that needs special steps or packages to run with ZSNES in the first place, is it?
No. In fact, the reason I'm so concerned about this is that the original code works in ZSNES, it's just the new stuff that doesn't.

Quote
- i notice the commented out code will "INC $3E" if the addition to $3D overflows.  in contrast, the new code (in two spots) will "INC $3D".  that seems superfluous, with an "STA $3D" right after it.  is this intended?  yes, i realize it has nothing to do with crashing.
This is a typo, probably mostly arising from the fact that I wrote the code after midnight :p Thanks for pointing it out! (stupid 8-bit adders...)

Quote
- following your theory about the dual JMLs, if you change the "JML $DBFA00" to "JSL $DBFA00", and the "JMP $7E8D83" to "RTL", will it run right?  alternatively, keep the "JML $DBFA00", and change the "JMP $7E8D83" to "PEA $8D82 / LDA #$7E / PHA / RTL" (err, i hope that pushing order is right).

It still crashes in ZSNES if I use JSL, but it also still works right in SNES9X.

assassin

  • Full Member
  • ***
  • Posts: 154
    • View Profile
    • My Barren Webpage
Re: SNES architecture quirk?
« Reply #6 on: October 24, 2013, 03:11:55 pm »
- ZSNES has a debugger (sort of).  are you able to pinpoint at what instruction the game stops running in it?

-
Quote
The JML gets loaded into RAM at $7E8D4C.

how soon is this happening before the JML is executed?  maybe there's some (Z)SNES issue of it expecting a little wait for the RAM modify to be "recognized" before the new values there can be utilized.  i know nothing about SNES or ZSNES internals, and haven't heard of any "pre-fetching" here, so this is just a theory.  if you're running the JML very shortly after writing it, maybe put several NOPs in between the two acts.  (or more blatantly yet, a couple NOPs, a call to a dummy function in a far, non-RAM bank, that returns with RTL, and a couple more NOPs after return, _then_ execute the JML to RAM.)

try both of these countermeasures if you can, though the first step (ideally) is to glean what you can about the crash from ZSNES' debugger.  i say "ideally" because i've never been able to accomplish a damned thing in that debugger.

Gideon Zhi

  • Discord Staff
  • Hero Member
  • *****
  • Posts: 3536
    • View Profile
    • Aeon Genesis
Re: SNES architecture quirk?
« Reply #7 on: October 24, 2013, 03:27:53 pm »
- ZSNES has a debugger (sort of).  are you able to pinpoint at what instruction the game stops running in it?

try both of these countermeasures if you can, though the first step (ideally) is to glean what you can about the crash from ZSNES' debugger.  i say "ideally" because i've never been able to accomplish a damned thing in that debugger.

I can't even remember the last time I used ZSNES's debugger. I'm not even sure if ZSNES DOS works in Windows 7!

Any case, the JML goes loaded in a *long* time before it runs. It's part of the data that gets dumped into RAM when the game zones-in to this particular area, and there are about a dozen lines of dialog before that happening and the game running this particular display code.

Edit: Apparently, it works in ZSNES 1.50+ (I was testing the code using ZSNES 1.42). And since 1.42 doesn't have the debugger even if 1.50+ does, I can't test it any further, so. I guess that's the end of that? I'm going to have someone else test the game in bsnes to make sure it works.
« Last Edit: October 24, 2013, 03:35:48 pm by Gideon Zhi »

KingMike

  • Forum Moderator
  • Hero Member
  • *****
  • Posts: 7255
  • *sigh* A changed avatar. Big deal.
    • View Profile
Re: SNES architecture quirk?
« Reply #8 on: October 24, 2013, 08:18:28 pm »
Since ZSNES is the least accurate of the three, I'd have let it be broken as long as SNES9x supports it, and wait until I could test to that point in bsnes. Does the game have saving (in which case you could make a regular save in SNES9x then transplant to bsnes)?
"My watch says 30 chickens" Google, 2018

lytron

  • Jr. Member
  • **
  • Posts: 58
    • View Profile
    • pantalytron.com
Re: SNES architecture quirk?
« Reply #9 on: October 25, 2013, 07:33:36 am »
Code: [Select]
lorom
  LDA $3D
  CLC
  ADC #$04
  BCC $02
  INC $3D
  STA $3D

Just one short question: Does it make sense that you INC $3D right before you store the value in A in $3D? Doesn't it get replaced? Do you probably rather mean "INC A"?

EDIT: Sorry, just saw that you already were pointed to it.
« Last Edit: October 25, 2013, 08:55:33 am by lytron »

furrykef

  • Full Member
  • ***
  • Posts: 132
    • View Profile
Re: SNES architecture quirk?
« Reply #10 on: November 03, 2013, 07:13:47 pm »
Xkas 0.14 doesn't allow the use of JMP with 24-bit address. But maybe he is using another compiler.

Assemblers aren't compilers. Compilers translate high-level languages to another language (often assembly or pure object code). An assembler just provides a convenient human-readable syntax for binary code. (Of course, real assemblers usually also provide convenience features such as macros, but whatever.)

Bisqwit

  • Sr. Member
  • ****
  • Posts: 424
  • Polite, but politically incorrect.
    • View Profile
    • http://iki.fi/bisqwit/
Re: SNES architecture quirk?
« Reply #11 on: November 08, 2013, 11:42:01 pm »
The line between assemblers and compilers is rather narrow really, especially considering features such as jump size optimization, aligning and so on.
I would not pedantically uphold the difference. Although I wouldn't ever call a C++ compiler an assembler.