It is currently Fri Nov 24, 2017 1:29 pm

All times are UTC - 7 hours



Forum rules


Related:



Post new topic Reply to topic  [ 132 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7 ... 9  Next
Author Message
PostPosted: Tue Jan 20, 2015 6:10 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
Re: concerns over ldy #$00:

It's being assembled correctly, or was at the time of that post. You can clearly see the results being $A0 00 00 which is correct (16-bit load of $0000 into Y).

Once again (is this the 5th or 6th time? I've lost track) we're back at the need for generated assembly listings and why using an assembler that generates ones properly is important, especially when learning.

Furthermore, and I don't know why this isn't being discussed: forcing the size using .w does not guarantee that the code will function correctly. For example, telling someone to "just use .w" is just as error-prone (if not more so!) than letting the assembler make its own educated guess. For example, take this code (and I'll include the machine language for it because it's important here):

Code:
E2 20     sep #$20
          ;
          ; Programmer does something else here, using 8-bit accumulator, and forgets that it's 8-bit.
          ; Programmer has been taught "to use .w when referring to 16-bit values or addresses"
          ;
A9 00 00  lda.w #$0000
8D 28 EA  sta.w $ea28

But during run-time, this code gets executed as the following:

Code:
E2 20     sep #$20
A9 00     lda #$00
00 8D     brk $8d
28        plp
EA        nop

I don't think WLA DX is going to dynamically change the size of the operands ($00 vs. $00 00) if you do lda #$00 vs. lda #$0000 or even lda #0 (that's a good example of an ambiguous one) -- that's what using .b/w is for -- instead it (very likely) keys off of what the accumulator size is per SEP/REP. I'd check, but there's no way in hell I'm going to bother trying to use assembly listings in WLA DX after what I've experienced this past week.

TL;DR -- Listings generated by the assembler: important. Programmer understanding what their code does, and understanding the processor: equally as important. Forcing sizes using .b/w/l can result in bad learned behaviour. In other words: aren't sure if your code is generated correctly? Look at the listing. Aren't sure if it's executing correctly? Use a debugger. (And for those wondering how we used to debug code on the SNES during the early 90s when there was no such thing as an emulator -- we stared at our code until we found the bug. Really. At least on the IIGS we had GSBug which is still one of my favourite debuggers, only rivalled by SoftIce).


Top
 Profile  
 
PostPosted: Tue Jan 20, 2015 6:19 pm 
Offline

Joined: Fri Jul 04, 2014 9:31 pm
Posts: 801
I didn't mean to imply that it should be standard practice in all cases. For absolute or long addresses with small numerical values, it might be wise, because you know what addressing mode you want and the assembler is likely to screw it up.

But if you're using immediate values, yes, it's probably better to hold off on using length-forcing suffixes until it's clear you need them.


Top
 Profile  
 
PostPosted: Tue Jan 20, 2015 6:27 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
Nod, understood, and agreed. My post was mainly for psycopathicteen.

The issues here are compounded by the fact that WLA DX has awful documentation (both in organisation and grammar/phrasing), which just makes things even harder for someone new. I often brag about ORCA/M (Apple IIGS assembler) because its documentation is remarkably good (I can't tell you how many times during my IIGS days the docs saved me pain). Merlin 8/16's documentation (also Apple IIGS) is pretty good too. And so was x816s'.

All this makes me wonder if I could find Norman Yen (x816 author) and ask him to release the source for it so Win32 (rather than DOS) binaries could be built. It was written in Turbo Pascal, which could very easily be ported to C.


Top
 Profile  
 
PostPosted: Tue Jan 20, 2015 7:54 pm 
Offline
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3116
Location: Nacogdoches, Texas
koitsu wrote:
Espozo wrote:
Just wondering because, like I said, the loading and storing approach didn't work, I wonder, how does the table actually get loaded into ram? The table is 7 bytes long, so does it fill the register and 7 after it with information? How can the processor even hold the table if it can only hold 16 bits? (I'm sure my way of thinking things is way off.)

What do you think the loop in build_metasprite is for? I'm starting to get the impression someone gave you a bunch of code you don't understand (how it works). Did someone give you this code? If so, it might be better to discuss with them this type of question, since they're the author. This is exactly why taking code snippets from people + using them (without understanding them) is a Bad Practise(tm) (that's my opinion).


I don't remember exactly how the code came to be, but I know the answer lies in the SNES Programming Help thread. If I remember correctly, it's part of a much more complicated (and useful) code psychopathicteen wrote that I edited a bit for me. I don't know exactly what's going on, but I think I have a fairly good idea. (Accumulator should be 8 bit, and X and Y should be 16 bit.)

Code:
   ldy #$00      ;says 0 sprites have been made yet
   ldx #MetaspriteTable   ;where MetaspriteTable is in Bank0?
   sty YTemp      ;store y to YTemp
   stx XTemp      ;store x to XTemp
   jsr start_metasprite   ;jump to start_metasprite to build a metasprite

Code:
.BANK 0 SLOT 0
.ORG 0
.SECTION "MetaspriteCode"

start_metasprite:
   php      ;no clue
   rep #$10   ;prepares to make the accumulator 8bit by crearing the processor status bits?
   sep #$20   ;makes the accumulator 8bit?
   ldy YTemp   ;load #$00 into Y, as this offsets the Sprite Buffer and no sprites have been made yet
   ldx XTemp   ;the value of where the table starts is being loaded into X

build_metasprite:
   lda $00,x      ;I'm not sure why we are loading $00, (I looked in a memory editor and it is 0) but we are offseting $00 by X, to see where we are in the table
   beq metasprite_done   ;If the number in the table was 0, (designed to mean there are no more sprites in the metasprite) then jump to metasprite_done to jump back to the main code.
   inx         ;increase x by 1 to look at the next byte in the table (sprite x position)
   lda $00,x      ;we are offseting $00 by X, to see where we are in the table
   sta SpriteBuf1,y   ;storing the byte (for sprite y position) in SpriteBuf, offset by y (y gets incremented by 4 because each sprite has 4 bytes)
   inx         ;increase x by 1 to look at the next byte in the table (sprite y position)
   lda $00,x      ;we are offseting $00 by X, to see where we are in the table
   sta SpriteBuf1+1,y   ;storing the byte (for sprite y position) in SpriteBuf, offset by y (y gets incremented by 4 because each sprite has 4 bytes)
   inx         ;increase x by 1 to look at the next byte in the table (to see if there is another sprite in the metasprite)
   iny         ;y gets incremented by 4 because each sprite has 4 bytes
   iny
   iny
   iny
   bra build_metasprite   ;go back to build_metasprite to potentially build another sprite in the metasprite

metasprite_done:
   plp      ;no clue
   rts      ;jump back to the main code

.ENDS


I think the problem resides with the fact of how I'm storing X and Y when I jump to the metasprite building code and how I'm loading it when I get there, because like I said, if I just get rid of the storing and loading into XTemp and YTemp, it works fine. (X and Y are supposed to be 16 bit.)

(I know I'm probably frustrating you by this point...)


Top
 Profile  
 
PostPosted: Tue Jan 20, 2015 10:27 pm 
Offline

Joined: Wed May 19, 2010 6:12 pm
Posts: 2372
It looks like it should work. Post the latest ROM so I can trace it in a debugger and figure out what's wrong.


Top
 Profile  
 
PostPosted: Tue Jan 20, 2015 10:38 pm 
Offline
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3116
Location: Nacogdoches, Texas
Thank you. I'm literally dumbfounded. MetaspriteTest1 yields the correct result, while MetaspriteTest2 doesn't, which is the one that uses XTemp and YTemp. The metasprite routine for both is Metasprite and Metasprite2 respectively. If you have any questions, don't hesitate to ask.

Attachment:
MetaspriteDemo.rar [3.83 MiB]
Downloaded 192 times

Edit: I accidentally increased Y by one more than I should have in Metasprite2, so just get rid of one of them after you download it. It still doesn't work though...


Top
 Profile  
 
PostPosted: Wed Jan 21, 2015 12:01 am 
Offline

Joined: Wed May 19, 2010 6:12 pm
Posts: 2372
I just learned something new. WLA is a total piece of crap.

Quote:
0082ea ldy #$0000 A:0000 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V:230 H: 30
0082ed ldx #$8401 A:0000 X:0000 Y:0000 S:1fff D:0000 DB:00 nvMxdiZC V:230 H: 54
0082f0 sty $1808 [001808] A:0000 X:8401 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:230 H: 78
0082f3 stx $180a [00180a] A:0000 X:8401 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:230 H: 118
0082f6 jsr $820e [00820e] A:0000 X:8401 Y:0000 S:1fff D:0000 DB:00 NvMxdizC V:230 H: 158
00820e php A:0000 X:8401 Y:0000 S:1ffd D:0000 DB:00 NvMxdizC V:230 H: 204
00820f rep #$10 A:0000 X:8401 Y:0000 S:1ffc D:0000 DB:00 NvMxdizC V:230 H: 226
008211 sep #$20 A:0000 X:8401 Y:0000 S:1ffc D:0000 DB:00 NvMxdizC V:230 H: 248
008213 ldy $08 [000008] A:0000 X:8401 Y:0000 S:1ffc D:0000 DB:00 NvMxdizC V:230 H: 270
008215 ldx $0a [00000a] A:0000 X:8401 Y:0000 S:1ffc D:0000 DB:00 nvMxdiZC V:230 H: 302
008217 lda $00,x [000000] A:0000 X:0000 Y:0000 S:1ffc D:0000 DB:00 nvMxdiZC V:230 H: 334
008219 beq $822e [00822e] A:0000 X:0000 Y:0000 S:1ffc D:0000 DB:00 nvMxdiZC V:230 H: 364
00822e plp A:0000 X:0000 Y:0000 S:1ffc D:0000 DB:00 nvMxdiZC V:230 H: 386
00822f rts A:0000 X:0000 Y:0000 S:1ffd D:0000 DB:00 NvMxdizC V:230 H: 414


Top
 Profile  
 
PostPosted: Wed Jan 21, 2015 11:42 am 
Offline
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3116
Location: Nacogdoches, Texas
Wait a minute, did it load from the completely wrong register from what I stored in? Both were defined as XTemp and YTemp... I guess I'm not completely crazy after all! :roll: I guess this would explain how it got the number 0 and exited the routine. (I guess it's time to switch to a new assembler?)


Top
 Profile  
 
PostPosted: Wed Jan 21, 2015 12:38 pm 
Offline

Joined: Thu Aug 12, 2010 3:43 am
Posts: 1589
That's about as bad as that time I tried to use asmx and it somehow managed to rotate the order of the bytes in an entire 16 byte block (inevitably resulting in a crash for obvious reasons).


Top
 Profile  
 
PostPosted: Wed Jan 21, 2015 3:12 pm 
Offline

Joined: Thu Aug 28, 2008 1:17 am
Posts: 591
psycopathicteen wrote:
I just learned something new. WLA is a total piece of crap.

It's a secret to everybody.

_________________
__________________________
http://pcedev.wordpress.com


Top
 Profile  
 
PostPosted: Wed Jan 21, 2015 3:41 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
Espozo wrote:
Wait a minute, did it load from the completely wrong register from what I stored in? Both were defined as XTemp and YTemp... I guess I'm not completely crazy after all! :roll: I guess this would explain how it got the number 0 and exited the routine. (I guess it's time to switch to a new assembler?)

The root cause of the bug is unknown (I have a couple theories -- I'll spend a little time testing them out tonight), and I could do some testing to see what the heck is going on, but I'm choosing not to. Purely for educational purposes for you -- the code:

Code:
  rep #$10
  sep #$20
  ldy $180a
  ldx $1808

Should have assembled into:
Code:
C2 10     rep #$10
E2 20     sep #$20
AC 0A 18  ldy $180a
AE 08 18  ldx $1808

But instead the assembler somehow decided the index register size was 8-bit (I think?) and came out with this, silently discarding the upper byte of the address entirely, and thus chose to "optimise" by using direct page addresses:
Code:
C2 10     rep #$10
E2 20     sep #$20
A4 0A     ldy $0a     ; Effectively same as ldy $000a
A6 08     ldx $08     ; Effectively same as ldx $0008

I can tell it's using direct page because the opcodes+operands according to psychopathicteen's debugger output shows only 2 bytes used (if they were 16-bit absolute addresses, but wrong, they'd be 3 bytes).

Needless to say, $08 != $1808 and $0a != $180a. You didn't store your temporary values in direct page, you stored them in RAM (as the STX/STY lines clearly indicate), so the LDY/LDX statements here would result in incorrect values being loaded. Who knows what's in direct page at that point!

What's funny about all of this: this might explain why long, LONG ago, when I looked at some code someone wrote in WLA DX, I'd see what I considered "intermittent" usage of the .w modifier (meaning use at times where the assembler obviously should have gotten the right thing, thus was implied). That never sat well with me. Christ, I'm having horror flashbacks...


Top
 Profile  
 
PostPosted: Wed Jan 21, 2015 4:15 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19257
Location: NE Indiana, USA (NTSC)
[benefit-of-the-doubt]
Was there lda #$1800 tad beforehand? Perhaps it's attempting to track D the same way it tracks bits 5-4 of P.
[/benefit-of-the-doubt]


Top
 Profile  
 
PostPosted: Wed Jan 21, 2015 4:39 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
You mean tcd? Nope, no where in that code. What psychopathicteen posted here is what literally got run. And if there was a tcd (earlier in the program), it wouldn't explain why STY/STX used absolute addressing while LDY/LDX didn't (since neither used the .w to force 16-bit addresses).

Good theory/thinking nonetheless!


Top
 Profile  
 
PostPosted: Wed Jan 21, 2015 5:58 pm 
Offline
User avatar

Joined: Sat Jan 03, 2015 5:58 pm
Posts: 368
Location: ...
koitsu wrote:
nicklausw wrote:
Visual Studio and a bunch of other crap is needed. Don't use the binaries given on Ville's website, as those are somewhat outdated (and some bug fixes along with improvements have been made since then).

By the assumption that you're using Windows, here's my binaries. Fresh off GitHub. Made them last month as I recall.

EDIT: just remembered I also compiled them for Ubuntu, so I'll put those there aswell. Zip = windows, Tar = Ubuntu.

The Windows binaries you provide in the zip are native 64-bit binaries -- they will not work on 32-bit operating systems. This is unlike the "unofficial" binary builds which are 32-bit. I can't use these binaries (I do not run a 64-bit OS). There's really no reason (that I can think of) for native 64-bit binaries for WLA DX on Windows (on *IX it's a different situation, as not everyone's OSes have 32-bit compatibility shims; for example my FreeBSD boxes are all pure 64-bit with absolutely no 32-bit binary support). Windows 64-bit OSes provide 32-bit compatibility shims by default, so 32-bit is a better choice there for something non-memory-intensive like 65xxx assemblers.

The only reason I'm bothering to try your binaries is to see if the listing generation stuff has been fixed. "And some bug fixes along with improvements have been made since then" isn't precise enough -- this is exactly what a ChangeLog or commit history is for. I wouldn't need to try the binaries if I could see that + know exactly what commit and/or branch your binaries were based off of. :-)


Update: Decided to download the newest sources and try out a 32-bit distribution of cygwin to see if it could compile it. It did, and I'd like you to test these binaries out.


Attachments:
wla-dx-win32.zip [1.57 MiB]
Downloaded 69 times
Top
 Profile  
 
PostPosted: Wed Jan 21, 2015 6:05 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19257
Location: NE Indiana, USA (NTSC)
koitsu wrote:
You mean tcd?

Yes, a well-known synonym which I seem to remember came from WDC's datasheet. I use tad because it doesn't confuse "C" (BA) with "C" (bit 0 of P). Given the existence of xce (exchange carry with emulation); tcd looks like it could stand for "copy carry to decimal mode".

Is Cygwin needed, or would MinGW work as well? MinGW doesn't need quite as big of a C runtime DLL because it doesn't try to implement a huge swath of POSIX. Instead, it uses MSVC 6's DLL.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 132 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7 ... 9  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 7 guests


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

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group