I'm an idiot (failure to create pong "bouncing" ball)

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post by Drew Sebastino »

tokumaru wrote:if it isn't, use the name of its scope.
So I use the name of its scope in conjunction with the" sub label", somehow? Doesn't it go before?

You know, since you seem to be knowledgeable in ca65, how would I put stuff, like "XPosition" underneath something like "ObjectTableSlot"? It kind of works like .res, although it's not global, but I don't remember how to do it. Also, is there a way to have it to where the size of "ObjectTableSlot" is automatically calculated?
User avatar
thefox
Posts: 3139
Joined: Mon Jan 03, 2005 10:36 am
Location: Tampere, Finland
Contact:

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post by thefox »

tokumaru wrote:IIRC, ca65 does this because it assumes you're going to define that label later, within the same scope it's being referenced, but then you don't, so an error occurs.
This should only be a problem if the value needs to be a compile-time constant (its size matters, or it's used in an .if statement, and so on.) I'm not really familiar with 65816, but if ca65 always assembles JML to a 4-byte instruction then it shouldn't be a problem. If it tries to automatically pick whether to use a 3 or 4 byte variant, then it might give an error there.

EDIT: Gave it a quick try in ca65:

Code: Select all

.p816
bar: nop
.proc xyzzy
    jml bar
.endproc
^ Assembles fine, as expected.

Code: Select all

.p816
.proc foo
    bar: nop
.endproc
.proc xyzzy
    jml bar
.endproc
^ Doesn't assemble, as expected.

Code: Select all

.p816
.proc foo
    bar: nop
    .proc xyzzy
        jml bar
    .endproc
.endproc
^ Also works.

Summa summarum: nothing out of ordinary here.
Last edited by thefox on Mon Jun 06, 2016 12:10 am, edited 1 time in total.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post by tokumaru »

I'm not particularly knowledgeable about ca65... But I've been able to build a framework using a subset of its features that I'm comfortable with. I did get the hang of scopes, but some of the quirks of single-pass assembly still take me by surprise.

I believe I already suggested you use .struct for things like the fields within object slots.
User avatar
koitsu
Posts: 4203
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post by koitsu »

thefox wrote:... I'm not really familiar with 65816, but if ca65 always assembles JML to a 4-byte instruction then it shouldn't be a problem. If it tries to automatically pick whether to use a 3 or 4 byte variant, then it might give an error there.
JML is a pseudo-op (or "alias") for JMP with an explicit 24-bit address. In other words: JML will always assemble to 4 bytes (1 opcode + 3 bytes for 24-bit address).
93143
Posts: 1371
Joined: Fri Jul 04, 2014 9:31 pm

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post by 93143 »

It seems from this page that JML can also be used as an indirect long jump with a 16-bit pointer as an operand.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post by Drew Sebastino »

Great. Now what is wrong. (The file actually assembles, it's just that it crashes)

Code: Select all

  rep #$30	;A=16, X/Y=16
  lda #.LOWORD(dummy)
  sta ObjectTable+Identity
  sep #$20	;A=8
  lda #.BANKBYTE(dummy)
  sta ObjectTable+Identity+2

Code: Select all

  rep #$30	; A=16, X/Y=16
object_identifier_loop:
  lda Identity
  bne continue_object_identifier_loop
  lda Identity+1
  beq next_object
  lda Identity
continue_object_identifier_loop:
  sta LongJumpLocation
  lda Identity+1
  sta LongJumpLocation+1
  jmp [LongJumpLocation]
next_object:
  rep #$30	; A=16, X/Y=16

Code: Select all

.proc dummy
  jmp object_identifier::next_object
Edit: I fixed some stuff, but it still doesn't work. :(
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post by Drew Sebastino »

I don't know why it just now occurred to me to check the listing file...

I don't think this is correct. Shouldn't there be 3 sets of "rr"?

Code: Select all

0003DDr 1  DC rr rr       jmp [LongJumpLocation]
I actually wrote "jmp dummy" and it worked perfectly, so this must be the problem.

It occurred to me to write "jml" to force the assembler to do 24 bit addressing, but it still assembled to be 16 bit. :(

Code: Select all

0003DDr 1  DC rr rr       jml [LongJumpLocation]
Is this a bug with ca65?
User avatar
nicklausw
Posts: 376
Joined: Sat Jan 03, 2015 5:58 pm
Location: ...
Contact:

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post by nicklausw »

Your config file is pointing to $808000 and so on for code and not $8000, right? (Or $800000 and $0000, can't remember).

EDIT: Wait, are you using a pointer to BSS for a location to jump to? Then it should assemble as 16-bit, so that's not the problem.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post by Drew Sebastino »

I wrote a whole big deal, and then I realized that I'm just being an idiot... It's 16 bit addressing to load the 24 bit number... I'm moving direct page and I don't think there's an absolute variant of this, so I guess this could be screwing it up? I think I'm just going to do the jsr thing.

I found out that you just found out what I did, nicklausw? I guess this isn't the problem, but the code starts at $008000.
User avatar
koitsu
Posts: 4203
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post by koitsu »

Espozo wrote:I don't know why it just now occurred to me to check the listing file...

I don't think this is correct. Shouldn't there be 3 sets of "rr"?

Code: Select all

0003DDr 1  DC rr rr       jmp [LongJumpLocation]
I actually wrote "jmp dummy" and it worked perfectly, so this must be the problem.

It occurred to me to write "jml" to force the assembler to do 24 bit addressing, but it still assembled to be 16 bit. :(

Code: Select all

0003DDr 1  DC rr rr       jml [LongJumpLocation]
Is this a bug with ca65?
No, the bug is in you. :-) You're using jml [Address]. The brackets here are important. This is asking for the addressing mode absolute indirect long, which assembles to opcode $DC (correct), and consists of 3 total bytes (i.e. 1 opcode byte, 2 operand bytes). This is **indirect** addressing, which means the full 24-bit address is what's stored in memory location LongJumpLocation (i.e. if LongJumpLocation = $1100, then byte at $1100 = low byte of address to jump to, byte at $1101 = high byte of address to jump to, byte at $1102 = bank byte of address to jump to). That probably isn't going to make any sense to you, so I'll rewrite it in code:

Code: Select all

LongJumpLocation .res 3   ; Needs to be in RAM or direct page

sep #$20
lda #$45
sta LongJumpLocation
lda #$23
sta LongJumpLocation+1
lda #$01
sta LongJumpLocation+2
jml [LongJumpLocation]   ; Will assemble to $DC {2-byte address of LongJumpLocation}
;
; This will end up jumping to $012345.
;
Now compare that to:

Code: Select all

LongJumpLocation = $6789ab

jml LongJumpLocation   ; Will assemble to $5C AB 89 67
;
; This will end up jump to $6789ab.
;
If you wanted an absolute 24-bit jump, you'd want jml LongJumpLocation. Whether or not you want indirect addressing depends on what you're trying to do and "how" you're using LongJumpLocation. There's no way any of us would know this.

As for the JMP vs. JML syntax: you can use the pseudo-op JML for two opcodes: either absolute long addressing (i.e. jml LongJumpLocation) or absolute indirect long addressing (i.e. jml [LongJumpLocation]). Both are considered acceptable.

I strongly urge you to go look at the WDC 65816 documentation - specifically PDF page 459 -- and look/read the opcode chart there very carefully.

There is no "absolute indirect long jump" that has a full 24-bit address in the operand list (i.e. a 4 byte instruction). Your choices are absolute long, or absolute indirect long.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post by Drew Sebastino »

Yeah, what you're describing seems to be what I figured out. I looked at the page in the 65816 book, but it didn't have anything except the different types of jumps.

To break it down...

"Absolute" means it's not affected by Direct Page, "Indirect" means that it's loading the value of the address from ram, and "Long" means 24 bit addressing (the address of where in ram the value is).

So, really, I don't even need to copy over the contents of "Identity". In fact, I think the problem is that I didn't write "a:" in front of "LongJumpLocation".

I'll try to fix this, and see if it'll work...

Edit: I now remembered as to why I did the "LongJumpLocation" instead of just "Identity", but then I remembered that the opcode is always absolute, so it didn't work.

However, I did write

Code: Select all

object_identifier_loop:
  lda Identity
  bne continue_object_identifier_loop
  lda Identity+1
  beq next_object
  lda Identity
continue_object_identifier_loop:
  sta a:LongJumpLocation
  lda Identity+1
  sta a:LongJumpLocation+1
  jml [LongJumpLocation]
next_object:
And I finally got it to run correctly. :D Thank you for tolerating me. :lol:
User avatar
koitsu
Posts: 4203
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post by koitsu »

Sure thing. And you're probably setting this somewhere else in your code, but: don't forget about a:LongJumpLocation+2 -- that'd hold the bank byte needed for the jml [LongJumpLocation] to be correct. It could be working by total chance right now.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post by Drew Sebastino »

Oh, the accumulator is in 16 bit mode, so it's fine if there's only 2 loads and stores. The middle byte is loaded and stored twice, but it's still faster than going to an 8 bit accumulator and then back. I try to do everything with a 16 bit accumulator, as it ends up being the most efficient in 90% of cases.
User avatar
koitsu
Posts: 4203
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post by koitsu »

Espozo wrote:Oh, the accumulator is in 16 bit mode, so it's fine if there's only 2 loads and stores. The middle byte is loaded and stored twice, but it's still faster than going to an 8 bit accumulator and then back. I try to do everything with a 16 bit accumulator, as it ends up being the most efficient in 90% of cases.
Ahh, smart and clever! For a moment I was wondering how this worked correctly, but I worked it out and you're absolutely right (the "middle byte" of the 24-bit address gets written twice). I was expecting to see things like Identity and Identity+2, not Identity+1. I'm one of those who switches register sizes fairly often, so you'll have to excuse me, haha :-)
Post Reply