Page 1 of 1

Wla's RAM handling totally broken?

Posted: Sun Apr 01, 2007 12:54 pm
by blargg
Currently I use .defines for addresses of variables in RAM:

Code: Select all

.define variable $10
Nevermind that wla seems to lack sane constant definitions of the form

Code: Select all

variable = $10
In ca65 and other assemblers, you just do

Code: Select all

.zeropage
variable: .byte 0

.code
lda variable ; uses zero-page addressing
... more code
and the assembler puts the variable at the next open address in zero page (or .bss for the rest of RAM). You can interleve these freely, allowing each source file to define its variables at the top without conflict with others.

I figured I'd try to use wla's .ramsection to define these. OK, slot 0 is RAM, slot 1 is ROM. Let's define some code, some variables, then more code:

Code: Select all

.memorymap
    defaultslot 1
    slotsize    $100
    slot    0   $200
    slot    1   $8000
.endme

.rombankmap
    bankstotal  1
    banksize    $100
    banks       1
.endro

; OK, some "code"
.bank 0 slot 1
    .byte $11,$22

; A variable
.RAMSECTION "1" slot 0
variable: db
.ends

; More "code"
.bank 0 slot 1
    .byte $33,$44
    .word variable
But wla for some reason inserts a zero byte in the ROM output!

Code: Select all

      vv What the hell is this inserted byte?
11 22 00 33 44 00 02 
               ^^^^^ Couldn't be this, which is at address $200
As you can see, it properly put variable at address $200, but inserted the zero byte in ROM at address $8002. OK, fine, I can accept a few zero bytes inserted at random places between routines. But when I try to use .ramsection for zero page variables, I get a linker error when using them (I'm using this for the SPC-700 CPU, but the same issues apply to the 6502):

Code: Select all

.memorymap
    defaultslot 1
    slotsize    $100
    slot    0   $000     ; address 0 now for zero page
    slot    1   $8000
.endme

.rombankmap
    bankstotal  1
    banksize    $100
    banks       1
.endro

.RAMSECTION "1" slot 0
variable: db
.ends

.bank 0 slot 1
	mov	a,variable ; same as lda variable (from zero page)
But the linker fails:

Code: Select all

test.a:19: FIX_REFERENCES: Too large distance (-32259 bytes from $8002 to
$200 "variable") for a 8bit reference.
This fixes it:

Code: Select all

mov a,<variable
This is insane to go through, when the assembler's job is to simplify things for you.

Posted: Sun Apr 01, 2007 1:16 pm
by Bananmos
I've already given my two cents on WLA. While it sports lots of neat features I'd like to see implemented in other assemblers, those are of no use when the basics don't work/are buggy.

Posted: Sun Apr 01, 2007 1:40 pm
by Bregalad
Note that you are supposed to put your code in ROM sections, wich you seems to forgot both times.
That zero byte is very weird, however, it don't seems it do this with me (unless is specify padding for various ROM sections).

Again, you're supposed to put your code into section and the output will by buggy and unpredictable if you don't (I know this is weird) because the assembler have absolutely no directive how to pad it.

The error you got with the SPC700 is very weird. I haven't tryed wla-spc700 yet, so I can't tell.
Since the SPC700 have only RAM and no ROM, I guess if you want to compile a .spc file you have to simulate a ROM secion inside the RAM (that will be RAM with known initial state), and then if you want to pass it in a real SNES ROM, you'll have to incbin the pseudo-ROM data and write it to the SPC700 at startup.

Posted: Sun Apr 01, 2007 1:56 pm
by blargg
Show me the code! :) Fix my example to properly use .ramsection without messing with the current ROM data being defined. i.e. it outputs a file witht he contents 11 22 33 44 00 02 ..

Posted: Sun Apr 01, 2007 2:02 pm
by Bregalad
I guess something like this would do.

Code: Select all

; OK, some "code"
.orga $8000      ;Not necessary in theory, but that doesn't hurt anyone
.section "1122" slot 1 FREE
.bank 0 slot 1
    .byte $11,$22
.ends

; A variable
.RAMSECTION "1" slot 0
variable: db
.ends

; More "code"
.section "3344" slot 1 FREE
.bank 0 slot 1
    .byte $33,$44
    .word variable
.ends

Posted: Sun Apr 01, 2007 5:21 pm
by blargg
Not working:

; (memory map from above)
.orga $8000      ;Not necessary in theory, but that doesn't hurt anyone
# DIRECTIVE_ERROR: .ORGA is outside the current SLOT.
.section "1122" slot 1 FREE
.bank 0 slot 1

OK, move .orga inside:

.section "1122" slot 1 FREE
# ERROR: Unknown symbol "slot".
.bank 0 slot 1
.orga $8000      ;Not necessary in theory, but that doesn't hurt anyone

OK, remove slot from sections:

.section "1122" FREE
.bank 0 slot 1
# LOGIC_ERROR: Section "1122" is open. Do not try to change the bank.

OK, put bank before section:

.bank 0 slot 1
.section "1122" FREE
.orga $8000      ;Not necessary in theory, but that doesn't hurt anyone
# DIRECTIVE_ERROR: You can't issue .ORGA inside a .SECTION.

OK, put .org before section

.bank 0 slot 1
.orga $8000      ;Not necessary in theory, but that doesn't hurt anyone
.section "1122" FREE
(wla crashes)

Remove the &(*&( org. Still crashes.

Oh, apparently there were some junk characters pasted from my web browser that obviously must crash an assembler (looks like the spaces after orga before the comment, ASCII 202 rather than 32). No way to avoid that. OK, clear those out:

Code: Select all

.memorymap
      defaultslot 1
      slotsize    $100
      slot  0     $000
      slot  1     $8000
.endme

.rombankmap
      bankstotal  1
      banksize    $100
      banks       1
.endro

.section "1" FREE 
      .byte $12
.ends

.RAMSECTION "2" slot 0 
variable:   db
variable2:  db
.ends 

.section "3" FREE
      .byte $34
      mov   a,variable2
      mov   a,<variable2
      .byte $56
.ends
This actually works somewhat:

34 E4 FE E4 01 56 12

Apparently it puts the "free" sections in reverse order. I guess there's some logic that I'm not getting. Unfortunately the first mov a turns into a *relative* offset or something to the variable (E4 FE, where the FE is some kind of offset), even though it's over $8000 bytes away and this CPU has no relative addressing mode like that. The second mov a,<variable2 works. Maybe that's better than .defines, though I'd hate to forget the < and silently get bad code. And what the hell is with having to name every section uniquely? So much busywork to do simple things. And given how many problems I encounter, I'm not very trusting that it won't screw up these RAM sections in some subtle way. Even NESASM shines in comparison to this.

Posted: Mon Apr 02, 2007 9:03 am
by Bregalad
Well, I often puts some related routines in a similar sections (like all the routines that does writes strings to PPU in the same seciton, etc..)
There is nothing wrong in naming them, as long as you can found name for your subroutines.
The FREE sections are sorted by their size before being copiled. In your example your section "1" is 1 byte long so it goes after the section "3" wich is 6 bytes long.

Aside of the ".w" needed for some opcode wich is a bit annoying at first, I have had NO bad issues with WLA at all, even trough, I've been using it for about 2 years. I don't know how you do to have so many problem in so few time. :wink:

NESASM wasn't too bad until you wanted to do some larger code than a plain NROM-128 programm (it also needed to have all variables declared manually).