Espozo wrote:
What?

What do you mean by "When you set the DP register all 1 byte addresses will be added to DP to form the effective address."? What are the "1 byte addresses?" How do I fix this particular problem?
Sorry about that, I was rushed for time.
Please read page 298 (Direct Page Addressing) of the
65c816 Programming Manual (PDF) for a diagram explaining what happens. Any load/store/cmp instruction that uses a single byte address is direct page.
You can check that by looking at the
.lst files and count the number of bytes they are using.
Code: Select all
000000r 1 .proc start_metasprite
000000r 1 0B phd
000001r 1 C2 30 rep #$30 ; A=16, X/Y=16
000003r 1 A4 rr ldy SpriteCount
000005r 1 A6 rr ldx MetaspriteTableOffset
000007r 1
000007r 1 A9 rr rr lda #ObjectTable
00000Ar 1 18 clc
00000Br 1 65 rr adc ObjectOffset
00000Dr 1 5B tcd
00000Er 1
00000Er 1 64 rr stz HFlipMask
000010r 1 A5 rr lda MetaspriteDirection
000012r 1 89 01 00 bit #$0001
000015r 1 F0 05 beq metasprite_loop
000017r 1 A9 FF FF lda #$FFFF
00001Ar 1 85 rr sta HFlipMask
00001Cr 1
You can see that the
SpriteCount,
MetaspriteTableOffset,
ObjectOffset,
HFlipMask,
MetaspriteDirection (and others) are using direct page addressing (1 byte addresses). Because you have set the DP register to something other than $0000, that value will be added to the address to form the effective one. This is probably causing some value in your object dataset to be overridden. When you read the same code through a trace logger you can see what I'm trying to explain.
Code: Select all
$00/80C0 0B PHD A:0000 X:8703 Y:0000 D:0000 DB:00 S:1FF9 P:envmxdiZC HC:0538 VC:231 FC:06 I:00
$00/80C1 C2 30 REP #$30 A:0000 X:8703 Y:0000 D:0000 DB:00 S:1FF7 P:envmxdiZC HC:0624 VC:231 FC:06 I:00
$00/80C3 A4 22 LDY $22 [$00:0022] A:0000 X:8703 Y:0000 D:0000 DB:00 S:1FF7 P:envmxdiZC HC:0662 VC:231 FC:06 I:00
$00/80C5 A6 14 LDX $14 [$00:0014] A:0000 X:8703 Y:0000 D:0000 DB:00 S:1FF7 P:envmxdiZC HC:0710 VC:231 FC:06 I:00
$00/80C7 A9 20 06 LDA #$0620 A:0000 X:8703 Y:0000 D:0000 DB:00 S:1FF7 P:eNvmxdizC HC:0758 VC:231 FC:06 I:00
$00/80CA 18 CLC A:0620 X:8703 Y:0000 D:0000 DB:00 S:1FF7 P:envmxdizC HC:0798 VC:231 FC:06 I:00
$00/80CB 65 26 ADC $26 [$00:0026] A:0620 X:8703 Y:0000 D:0000 DB:00 S:1FF7 P:envmxdizc HC:0828 VC:231 FC:06 I:00
$00/80CD 5B TCD A:0620 X:8703 Y:0000 D:0000 DB:00 S:1FF7 P:envmxdizc HC:0876 VC:231 FC:06 I:00
$00/80CE 64 1E STZ $1E [$00:063E] A:0620 X:8703 Y:0000 D:0620 DB:00 S:1FF7 P:envmxdizc HC:0906 VC:231 FC:06 I:00
$00/80D0 A5 16 LDA $16 [$00:0636] A:0620 X:8703 Y:0000 D:0620 DB:00 S:1FF7 P:envmxdizc HC:0960 VC:231 FC:06 I:00
$00/80D2 89 01 00 BIT #$0001 A:0000 X:8703 Y:0000 D:0620 DB:00 S:1FF7 P:envmxdiZc HC:1014 VC:231 FC:06 I:00
$00/80D5 F0 05 BEQ $05 [$80DC] A:0000 X:8703 Y:0000 D:0620 DB:00 S:1FF7 P:envmxdiZc HC:1054 VC:231 FC:06 I:00
$00/80DC C0 00 02 CPY #$0200 A:0000 X:8703 Y:0000 D:0620 DB:00 S:1FF7 P:envmxdiZc HC:1092 VC:231 FC:06 I:00
$00/80DF F0 67 BEQ $67 [$8148] A:0000 X:8703 Y:0000 D:0620 DB:00 S:1FF7 P:eNvmxdizc HC:1132 VC:231 FC:06 I:00
$00/80E1 29 FF 00 AND #$00FF A:0000 X:8703 Y:0000 D:0620 DB:00 S:1FF7 P:eNvmxdizc HC:1164 VC:231 FC:06 I:00
$00/80E4 99 01 02 STA $0201,y[$00:0201] A:0000 X:8703 Y:0000 D:0620 DB:00 S:1FF7 P:envmxdiZc HC:1204 VC:231 FC:06 I:00
$00/80E7 A5 1C LDA $1C [$00:063C] A:0000 X:8703 Y:0000 D:0620 DB:00 S:1FF7 P:envmxdiZc HC:1266 VC:231 FC:06 I:00
$00/80E9 F0 5D BEQ $5D [$8148] A:0000 X:8703 Y:0000 D:0620 DB:00 S:1FF7 P:envmxdiZc HC:1320 VC:231 FC:06 I:00
$00/8148 84 22 STY $22 [$00:0642] A:0000 X:8703 Y:0000 D:0620 DB:00 S:1FF7 P:envmxdiZc HC:1358 VC:231 FC:06 I:00
$00/814A 2B PLD A:0000 X:8703 Y:0000 D:0620 DB:00 S:1FF7 P:envmxdiZc HC:0048 VC:232 FC:06 I:00
$00/814B 60 RTS A:0000 X:8703 Y:0000 D:0000 DB:00 S:1FF9 P:envmxdiZc HC:0100 VC:232 FC:06 I:00
The effective address being read (the one in square braces) is the memory address being read for that instruction. In this case, your
lda MetaspriteDirection (line $00/80D0) is actually reading address $00:0636 instead of the correct address of $00:0016 allocated by ca65. Thus its reading the wrong value and branching incorrectly.
Espozo wrote:
Edit: I tried what I just suggested, and it still doesn't work.
MetaspriteDemoKoitsu.rar
I guess it still doesn't work because of problems #1 and #2 you said?
Yeah. You solved problem 2 (wrong address), now you need to solve problem 1 (using DP addressing for non-object variables).
You can fix this by either moving the variables Empty, MetaspriteTableOffset, MetaspriteDirection, MetaspritePalette, MetaspriteCharacterOffset, MetaspriteCount, HFlipMask, VFlipMask, SpriteCount, NewObjectRequest, ObjectOffset out of
.zeropage and into
.BSS and replacing their
.importzp/
.exportzp with
.import/
.export.
Or you can force absolute addressing on these variables with the
a: modifier.
Code: Select all
lda a:Empty,x ; 1st byte = sprite X position (value 0-255)
eor a:HFlipMask
clc
adc <XPosition
cmp #256
bcc sprite_x_not_out_of_bounds
cmp #65504
Personally I prefer the first, but you may need to do the second sometime in the future (I have with the NPC vs player interaction code).
I also recommend you place the object variables in a struct (like I mentioned in my previous post), it makes the code a lot easier to manage if you have separate code for heroes and objects.
(sorry about not making this clearer).
Mod edit (koitsu): I updated the URL for the 65816 manual; WDC moved this somewhat recently.