I have no idea why, but a code I am trying to make doesn't work. I think there is a problem with me loading values from a table using a 16bit accumulator, because the first value I'm loading is $FFFF and beq-ing it, and for some reason, it thinks it is 0 and branches when it is not supposed to. (Either that, or my code is just really messed up. ) I tried setting up the table like .DB $FF,$FF,$00,$00 (and so on) because WLA said I couldn't do .DB $FFFF,$0000.

You want .dw $ffff,$0000, by the way. That means "define word", and a word on 65816 is 16-bit. .dw means define-word, .db means define-byte.

I wouldn't be surprised if .db $ff,$ff caused the assembler to generate odd code when using 16-bit lda/etc. statements that reference them. Did you generate an assembly listing (I explained how to do this in another thread recently -- the procedure is the same but use wla-65816.exe for assembling of course) and see if the code being generated is what you expect?

I fixed the table, but sadly, it still doesn't work :(. Also, about the assembly listing, do you create it by writing -i between wla and the filename? Will it work with the wla.bat file?

You have to use -i as a flag to both the assembler and the linker. And of course it will work in a batch file -- there's nothing different about one of those compared to, say, doing it manually. I.e.:

Code:

wla-65816 -i -o %1.asm %1.objwlalink -i -vr temp.prj %1.fig

(Who uses FIG files in this day and age?!? Good lord, talk about an uncommon ROM format even back in the 90s...)

Also, could you at least give some relevant code bits/lines (and please reference the filename) where something like lda #$ffff / beq {label} is actually branching? (It should not -- ever. lda #$ffff would guarantee the zero flag in the CPU is not set, thus the beq would never happen). I have a feeling the lda statement you're using is actually loading a zero value from somewhere you're not expecting it, hence why the branch works.

There are 7 assembly-related files in this RAR, so being more specific would be quite helpful. I assume you know because you've run this through a debugger (ex. Geiger's SNES9x build with debugging) to see what the behaviour is.

Oops... MetaspriteTest.asm is the main file, which jumps to Metasprite. (don't worry about all the other files.) The part where it jumps to Metasprite is under "InfiniteLoop" and the table is right near the end of MetaspriteTest. You're going to have to change .db to .dw and combine the two bytes together.

Don't hesitate to ask any questions. I appreciate you trying to help me.

Quote:

(Who uses FIG files in this day and age?!? Good lord, talk about an uncommon ROM format even back in the 90s...)

The .bat file. (I've honestly never heard of .fig files before.)

Edit: I just looked up and downloaded Snes9x debugger and wow does it look useful. (I currently use bsnes debugger)

This doesn't even make any sense no matter how you try to interpret it. All I've managed to determine is this: the assembler and/or linker (I don't know which) is outputting actual bytes that correlate with code of the actual program, but the lines it outputs do not correlate with the actual bytes shown -- e.g. assembler directives/pseudo-ops end up getting intermixed with actual assembly code.

$78 is sei, $18 is clc, $FB is xce. These are the first 3 instructions in InitSNES2.asm, so what the hell are they doing interspersed/intermixed with directives in MetaspriteTest.asm? I also noticed that each .asm file gets its own .lst file, except those ALSO look wrong! What this means is that this thing is designed completely wrong when it comes to use of .INCLUDE directives -- i.e. listing files cannot be reliably generated with this assembler.

Plain and simple: this assembler is a piece of shit. Who uses this thing?! Good god. It's no wonder nobody can get any programming done if the tools are in this kind of shape. x816 for DOS worked better than this.

I can tell this whole thing is solely focused around UNIX development environments, and reliance on actual GNU Makefiles. You know how I know that? Because there, you wouldn't be using .INCLUDE -- you'd have your Makefile reference every individual assembly file, and call wla-65816 on each one individually (i.e. 7 assembly files, 7 calls to wla-65816). I'm going to modify your wla.bat (heavily) to do this, to work around the obvious brokenness with listing file generation.

Plain and simple: this assembler is a piece of shit. Who uses this thing?! Good god. It's no wonder nobody can get any programming done if the tools are in this kind of shape. x816 for DOS worked better than this.

Are you referring to WLADX? What do you use then? Also, If I remember, the.bat file came with SNESstarterkit.

I can tell this whole thing is solely focused around UNIX development environments, and reliance on actual GNU Makefiles.

You don't need UNIX to run GNU makefiles. They run just fine in MSYS, a port of Bash, GNU Make, and GNU Coreutils to Windows.

One advantage of setting up a makefile (compared to a batch file that just reassembles everything all the time) is that if you change (say) an image file, Make will reconvert it to tiles, recompress it, reassemble the one source code file that contains an .incbin referencing the compressed tiles, and relink it. In large, complicated projects, this can save a lot of CPU and disk time over reconverting, recompressing, and reassembling everything in your project. This in turn means less time spent between Ctrl+R and the emulator opening, especially on an Atom netbook, though you can still force a full rebuild (make clean && make).

Quote:

You know how I know that? Because there, you wouldn't be using .INCLUDE -- you'd have your Makefile reference every individual assembly file, and call wla-65816 on each one individually (i.e. 7 assembly files, 7 calls to wla-65816).

The ca65 toolchain does the same thing, with ca65 generating .o files that ld65 combines into an executable .sfc, .nes, or whatever.

I'm not going to tell someone to install MSYS or Cygwin or other environments just to make a SNES ROM, Tepples. It's completely unnecessary and overkill. You should know better than to try and go that route with me. ;-)

My point stands: listing files with WLA DX are worthless if .INCLUDE is used anywhere.

I should note I tried separating this project up into how it "should" be done (using the project file correctly, assembling things as libraries, etc. then putting it all together during link-time) but gave up after repeatedly banging my head against a wall with this error message from the assembler: INTERNAL_PASS_1: A section must be open before any code/data can be accepted. (The file in question only contained code within .SECTION and .ENDS blocks (I even moved the macros into their own), so the message make no sense). The documentation is just as abysmal as it was the last time I looked at it (months ago).

I guess I'll say fuck listing files for now and I'll just go look at the thing in a real-time debugger and focus on the real problem.

I'm not going to tell someone to install MSYS or Cygwin or other environments just to make a SNES ROM, Tepples. It's completely unnecessary and overkill. You should know better than to try and go that route with me.

To be fair, you don't need any of those to use make (you just don't get *nix commands, but if your makefile doesn't use them then that doesn't matter - yes, that'd make sense with SNES development since you'll be using uncommon tools anyway). MinGW already comes with its own make (no, MSYS isn't needed), so one really could just take the make from MinGW (literally just one exe) and use that.

I guess one may want to distribute make on its own instead of telling people to get MinGW, but that'd work.

Okay, I haven't really sifted through the entire program/code to figure out what all is going on here, but let's talk about the code and what it's actually doing. First, MetaspriteTest.asm has this around label InfiniteLoop. Apologies for formatting mistakes, as this code uses hard tabs rather than spaces (but not consistently):

$8405 happens to be the 16-bit address (pre-calculated during assembly-time) of the memory location of MetaspriteTable. Let's start by asking: is that the correct address? Let's find out. And of course SNES9x won't let me copy/paste the Hex Editor portion... wonderful, so I get to type all of this in manually:

Your REP/SEP are in the wrong order. By doing REP #$10 / SEP #$30, you are setting 16-bit indexes, then setting 8-bit accumulator and 8-bit indexes. There are two ways to solve this, but one is wrong and the other is right. These are your options:

Code:

rep #$30 ; A=16, X/Y=16 sep #$20 ; A=8

Or:

Code:

sep #$30 ; A=8, X/Y=16 rep #$10 ; X/Y=16

Guess which one is the correct way? The first one. The 2nd one will introduce a horrible bug: you'll lose the upper byte of the X/Y index registers -- it'll be zeroed. This happens on the 65816 and ONLY with the index registers. You can swap between 16-bit and 8-bit accumulator without the full 16-bit contents being affected, but with indexes, upon going to 8-bit you lose the upper byte. In fact, that's happening with your code already. Look closely at the contents of X:

I should also point out here: you should not be using .dw $ffff,... like we discussed earlier. You are using an 8-bit accumulator, not a 16-bit accumulator (despite what you said earlier). And your build_metasprite routine is coded to use 8-bit accumulators as well. If you were to turn on 16-bit accumulator, your routine would break (look closely at where you're storing the results in SpriteBuf1 and what hard-coded math you're using there!).

I hope this has been a lesson in why having an assembler that generates proper/decent listings is VERY IMPORTANT. The fact WLA DX can't do this sanely/correctly is ridiculous.

I see other bugs in this program though, depending on how intelligent WLA DX is about knowing about addressing modes and banks, and when those crop up you're going to be crying big tears. Case in point: lda $0000,x right now is getting assembled into $b5 $00 (LDA directpage,X) because your MetaspriteTable data happens to be within the same bank as your the code that's running (in bank $00).

Eventually you're going to have to break outside of that (dealing with multiple banks); for example if MetaspriteTable was in a different bank (say bank $01 or $81 (same thing in this memory mode)), then the above code would be wrong and manifest itself by misbehaving in real-time: you'd be loading the wrong data: it'd be coming from bank $00 (where direct page is hard-coded to live) rather than where B was. In other words:

Code:

rep #$10 ldx #MetaspriteTable sep #$20 lda #$01 pha plb lda $0000,x

WLA DX may end up screwing you by optimising lda $0000,x into $b5 $00 (LDA directpage,X), rather than $ad $00 $00 (LDA absolute,X). The former would get you whatever bytes happened to be in bank $00 address $0000 + X, the latter would get you whatever bytes happened to be in bank $01 address $0000 + X.

The only way to "force" the assembler into knowing this is to use the .w modifier, i.e.:

Alternately you could use full 24-bit addressing ("long addressing") on all of your stuff that's not explicitly in direct page, through the .l (dot-ELL) modifier. Be aware that 24-bit addressing takes up 1 more byte, and takes 1 more cycle than absolute. This added cycle can add up real fast when doing loops, which is why before many loops you'll find people changing what B points to and then using absolute addressing.

Who is online

Users browsing this forum: No registered users and 5 guests

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum