Tables confusion

Discussion of hardware and software development for Super NES and Super Famicom. See the SNESdev wiki for more information.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
User avatar
andylatham82
Posts: 10
Joined: Tue Jul 11, 2017 10:20 am

Tables confusion

Post by andylatham82 »

Hi, I'm following the SNES development tutorial https://wiki.superfamicom.org/snes/show ... ial+Part+2 and have run into a problem that I can't solve. I'm hoping that someone here can help!

I'm trying to learn about tables. The tutorial gives the following example of using tables to change a value based upon the values in a table:

Code: Select all

Table:
	db $08,$1C,$24,$48          ; Table of timer values. Value can't go beyond #$FF unless in 16-bit mode.
	LDX $19                     ; Mario's power-up state.
	LDA Table,x                 ; Load the table, indexed by power-up ($19)
	STA $1490                   ; get the value into $1490.
	RTL                         ; Return
However when I try to build the program, I get the following error:
Pass 1...
gamecode.asm:35: ERROR: Unknown symbol "db".
I'm using wla-65816.exe to assemble my code, from which the above error is generated.

Does anyone know what the problem is?

Many thanks in advance!
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Tables confusion

Post by dougeff »

WLA seems to support the db directive...

http://www.villehelin.com/wla.txt

try it with a period before the db like .DB
nesdoug.com -- blog/tutorial on programming for the NES
93143
Posts: 1717
Joined: Fri Jul 04, 2014 9:31 pm

Re: Tables confusion

Post by 93143 »

I believe that's supposed to be .db rather than db.

EDIT: I made the classic beginner's error. Again.
Last edited by 93143 on Tue Jul 11, 2017 1:11 pm, edited 1 time in total.
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Tables confusion

Post by dougeff »

Also, you're reading way off the end of that table. The highest value you can use for X without getting code or garbage is $03. That's assuming the data bank register is set appropriately, which the use of rtl makes me nervous about.
I believe these are direct snippets of code from SMW.
nesdoug.com -- blog/tutorial on programming for the NES
niconii
Posts: 219
Joined: Sun Mar 27, 2016 7:56 pm

Re: Tables confusion

Post by niconii »

93143 wrote:The highest value you can use for X without getting code or garbage is $03.
They're loading X from address $19, not loading the literal number #$19.
User avatar
andylatham82
Posts: 10
Joined: Tue Jul 11, 2017 10:20 am

Re: Tables confusion

Post by andylatham82 »

Thanks for the responses guys. I'm new to any kind of assembly language, so this is really helpful.

I did try using .db rather than db and got an error saying that the value of the index I was trying to use was too high. The thing is that I was trying to load the index from address $19, which contains value #$00.

I'll post the exact error message when I get back onto the machine I was using tomorrow.
93143
Posts: 1717
Joined: Fri Jul 04, 2014 9:31 pm

Re: Tables confusion

Post by 93143 »

Nicole wrote:
93143 wrote:The highest value you can use for X without getting code or garbage is $03.
They're loading X from address $19, not loading the literal number #$19.
I just keep doing that.

andylatham82, you might want to take this as an object lesson. $19 and #$19 are not the same thing, and it is not at all difficult to generate bugs this way. I've done it multiple times, and I'm far from the only one.
User avatar
andylatham82
Posts: 10
Joined: Tue Jul 11, 2017 10:20 am

Re: Tables confusion

Post by andylatham82 »

93143 wrote:andylatham82, you might want to take this as an object lesson. $19 and #$19 are not the same thing, and it is not at all difficult to generate bugs this way. I've done it multiple times, and I'm far from the only one.
Ah yes this is one I've been keeping my eye on so far. No doubt I'll make plenty of such mistakes as I go on. I'm only at the most basic of levels at the moment, I'm looking forward to figuring out how to actually draw something on the screen!
93143
Posts: 1717
Joined: Fri Jul 04, 2014 9:31 pm

Re: Tables confusion

Post by 93143 »

Just to be very clear, the error here wasn't yours. It was mine - I misread your code.

Good luck with your efforts!
andylatham82 wrote:I did try using .db rather than db and got an error saying that the value of the index I was trying to use was too high. The thing is that I was trying to load the index from address $19, which contains value #$00.
Oh, right, we aren't done yet.

That sounds weird. The exact wording would be good, yes. The only thing I can think of is that the index register might be set to 16-bit mode, which would load two bytes rather than one. But that shouldn't cause an error; it should just load the wrong value...
User avatar
andylatham82
Posts: 10
Joined: Tue Jul 11, 2017 10:20 am

Re: Tables confusion

Post by andylatham82 »

Ok so I've changed my code to use .db instead of db and here's the error message I get when assembling (well I think it's actually while linking that the problem gets thrown up):
gamecode.asm:21: FIX_REFERENCES: Value ($8108) of "Table" is too much to be a 8bit value.
I have included my whole code below, but line 21 is this instruction:

LDA Table,x

In my code I have tried putting STZ $19 before using the table to make sure that the address I'm reading an index from is set to zero, and thus within the limits of the table.

Code: Select all

; TABLE EXAMPLE.
 
.include ".\SNESfiles\Header.inc"		; Include SNES header information.
.include ".\SNESfiles\Snes_Init.asm"	; Include SNES initialisation code.
 
; Needed to satisfy interrupt definition in "Header.inc".
VBlank:
RTI
 
.bank 0
.section "MainCode"

Start:					     ; Start of the program.

	Snes_Init			     ; Initialize the SNES. This resets the SNES to a known state.
   STZ $19                ; Ensure that the value of memory address $19 is zero.

Table:
	.db $08,$1C,$24,$48    ; Table of timer values. Value can't go beyond #$FF unless in 16-bit mode.
	;	 00  01  02  03
	LDX $19				    ; Mario's power-up state.
	LDA Table,x			   ; Load the table, indexed by power-up ($19)
	STA $1490				  ; get the value into $9.
	RTL					     ; Return

	
 
; Loop forever.
Forever:
	JMP Forever

.ends
93143
Posts: 1717
Joined: Fri Jul 04, 2014 9:31 pm

Re: Tables confusion

Post by 93143 »

Sounds like WLA is up to its old tricks again, picking the wrong opcode (B5 instead of BD) and complaining when it doesn't make sense. Try using lda.w instead of lda.
creaothceann
Posts: 611
Joined: Mon Jan 23, 2006 7:47 am
Location: Germany
Contact:

Re: Tables confusion

Post by creaothceann »

Even if the program compiles, wouldn't you have to jump over the .db bytes?

Code: Select all

Start:                                  ; program start
        SNES_Init                       ; initialize SNES
        STZ     $19                     ; memory address $19 = zero
        JMP     Table


TableData:
        ;        00   01   02   03
        .db     $08, $1C, $24, $48      ; Table of timer values. Value can't go beyond #$FF unless in 16-bit mode.


Table:
        LDX     $19                     ; Mario's power-up state
        LDA.W   TableData, X            ; Load the table, indexed by power-up ($19)
        STA     $1490                   ; get the value into $9.
        RTL                             ; return
My current setup:
Super Famicom ("2/1/3" SNS-CPU-GPM-02) → SCART → OSSC → StarTech USB3HDCAP → AmaRecTV 3.10
User avatar
andylatham82
Posts: 10
Joined: Tue Jul 11, 2017 10:20 am

Re: Tables confusion

Post by andylatham82 »

93143 wrote:Sounds like WLA is up to its old tricks again, picking the wrong opcode (B5 instead of BD) and complaining when it doesn't make sense. Try using lda.w instead of lda.
LDA.w has worked! I've no idea why though. And I don't know where the $8108 address comes from.
User avatar
andylatham82
Posts: 10
Joined: Tue Jul 11, 2017 10:20 am

Re: Tables confusion

Post by andylatham82 »

andylatham82 wrote:
93143 wrote:Sounds like WLA is up to its old tricks again, picking the wrong opcode (B5 instead of BD) and complaining when it doesn't make sense. Try using lda.w instead of lda.
LDA.w has worked! I've no idea why though. And I don't know where the $8108 address comes from.
Ah actually I see that $8108 is the address of the table itself. Is there a way to manage the creation of the table better so that it works with LDA instead of LDA.w?
93143
Posts: 1717
Joined: Fri Jul 04, 2014 9:31 pm

Re: Tables confusion

Post by 93143 »

creaothceann wrote:Even if the program compiles, wouldn't you have to jump over the .db bytes?
Excellent point. Otherwise the table will execute as code, namely (if I haven't screwed this up):

Code: Select all

php
trb $4824
which will corrupt the stack and then waste 6 cycles doing basically nothing (unless there's SRAM at $4824, in which case it will be corrupted too).

You might want to put the table in a separate section, or at least after the end of your code. I've done the 'jump over the table' trick myself, but it was in a test code I figured I was unlikely to reuse, so I cared more about not having to scroll around in the file than about performance or maintainability.
andylatham82 wrote:Ah actually I see that $8108 is the address of the table itself. Is there a way to manage the creation of the table better so that it works with LDA instead of LDA.w?
There's no need really. Using .w just tells WLA that you want to use the absolute-addressed version of the instruction, so it can use a full 16-bit operand. Using direct page would be slightly faster, but unless you want to figure out how to tell WLA to only use the bottom half of the label, you'd need to use page zero, and unless your data bank is a HiROM region (it shouldn't be), page zero is in shadow RAM, so you'd have to spend more effort loading the table into RAM at boot. Furthermore, you'd need to be sure the direct page register was pointing at page zero before using this subroutine, since in general it's not.

Less trouble to just use absolute addressing.

WLA DX is weird sometimes. Usually it gets this sort of thing right, but every now and then I run into a goofy error; more than once I've resorted to using .db statements to specify instructions directly in hex because WLA refused to assemble the code I wanted. This might just have been me not understanding how to force the assembler to work, and to be fair 65C816 code is a lot harder to assemble than 6502 code - not that that's relevant to this particular error...
Post Reply