If you try to define the same memory location (using .org, .pad, or .align) more than once, ASM6 doesn't like it
how do you write code for memory banks, where each bank expects to be at the same location?
the only way I can see now would be to build each bank separately and .incbin them, but perhaps there is a better way?
You can use .base to move the PC around. For example, this makes two adjacent 8KB banks destined for the same location:
Code:
.align $2000
.base $c000
.. code ..
.align $2000
.base $c000
.. morecode ..
.align $2000
thanks I
just noticed the base command in the readme after checking it again
I'm trying to set up macros which can accept multiple parameters, but i'm getting unexpected actions
Code:
macro test (testvar, testvar2)
ifdef testvar
nop
endif
ifdef testvar2
nop
endif
endm
test
test $00
test $00 $00
gives me:
Code:
pass 1..
test.asm(14):test(2): Illegal instruction.
test.asm(15):test(2): Illegal instruction.
test.asm(15):test(5): Illegal instruction.
it seems like ifdef works if something isn't defined, but if the variable is defined, i get an illegal instruction. i'm guessing ASM6 doesn't like me using if def with macro variables, but is there a way to determine if a marco variable is used?
i also tried using "if testvar" but then i get an "unknown label" error when the label isn't defined
I see the problem. The listing shows this:
Code:
macro test (testvar, testvar2)
ifdef testvar
nop
endif
ifdef testvar2
nop
endif
endm
test
ifdef testvar
nop
endif
ifdef testvar2
nop
endif
test $00
ifdef $00
*** Illegal instruction.
nop
endif
ifdef testvar2
nop
endif
test $00 $00
ifdef $00
*** Illegal instruction.
nop
endif
ifdef $00
*** Illegal instruction.
nop
endif
testvars are replaced by $00 before they get to ifdef. I'll try to come up with a fix...
"Illegal instruction" isn't really an appropriate message for this either. Hrm.
if you made it so IFDEF returned true (and IFNDEF false) whenever it was passed a constant value, then it would work as expected inside of the macro definition
i don't know if that would mess up other stuff or be too much of a "hack" though.
an alternative might be to make
Code:
macro test (testvar)
ifdef testvar
nop
endif
endm
test TESTVALUE
replace itself with
Code:
macrovar_test_testvar = TESTVALUE
ifdef macrovar_test_testvar
nop
endif
you could also add a large random string or something to macrovar_test_testvar to ensure it's never going to be used in an actual program. the macrovar_test_testvar definition would only occur if the test macro was called with a parameter. if no parameter is used, then the definition isn't made and ifdef works correctly
edit: oh also, i don't know if this is a bug or not, but single quotes don't seem work with .include which is unexpected
is there a way to use expressions in macro calls?
Code:
macro setPPUCTRL (value)
lda v2000
and value
sta v2000
sta PPUCTRL
endm
setPPUCTRL #PPUCTRL_NTABLE_0 | PPUCTRL_HORIZONTAL | PPUCTRL_SPR_PTABLE_1 | PPUCTRL_BG_PTABLE_0 | PPUCTRL_SPR_8X8 | PPUCTRL_VBLANK_NMI_ON
gives me
"extra characters on line"
putting quotes around it
Code:
setPPUCTRL #(PPUCTRL_NTABLE_0 | PPUCTRL_HORIZONTAL | PPUCTRL_SPR_PTABLE_1 | PPUCTRL_BG_PTABLE_0 | PPUCTRL_SPR_8X8 | PPUCTRL_VBLANK_NMI_ON)
gives me
"Incomplete expression." and "Extra characters on line"
frantik wrote:
I'm trying to set up macros which can accept multiple parameters, but i'm getting unexpected actions
frantik wrote:
is there a way to use expressions in macro calls?
Both problems should be fixed now. Download it and give it a try.
I changed the macro syntax to be less ambiguous (no parentheses around arg list, and args must be comma separated).
yep, they're both working now
thanks! Now i can write a 'callfunction' macro which can take multiple parameters
Wow, so many changes to ASM6 lately... Well, it's good to know the program is evolving, as I like this assembler very much.
loopy wrote:
Both problems should be fixed now. Download it and give it a try.
I changed the macro syntax to be less ambiguous (no parentheses around arg list, and args must be comma separated).
Loopy, any reason you haven't integrated the ASM6 changes for other architectures (e.g. Mac) that someone posted a couple weeks ago?
EDIT: ah, by beneficii,
here.
Yes, his changes have been integrated with asm6 (mods to make asm6 portable to bigendian systems).
loopy wrote:
Yes, his changes have been integrated with asm6 (mods to make asm6 portable to bigendian systems).
Fantastic, then.
tokumaru wrote:
Wow, so many changes to ASM6 lately... Well, it's good to know the program is evolving
Are these changes backwards-compatible, or do they require changes to user code each time?
blargg wrote:
tokumaru wrote:
Wow, so many changes to ASM6 lately... Well, it's good to know the program is evolving
Are these changes backwards-compatible, or do they require changes to user code each time?
the changes to the macro code are not 100% backwards compatible because he make the syntax more strict. depending on your code you might have to update the macro calls
I dunno if this is even doable, but it would be awesome if macros could accept a block of code as a "virtual macro".. maybe something like this:
Code:
macro repeat times, {code}
stx times
- txa
pha
{code}
pla
tax
dex
bne -
endm
repeat 10
{
... code, 'n stuff ...
}
then it'd be super easy to create different kinds of control structures.
ideally multiple virtual macros could be passed. i'm just using the braces as an idea for syntax but they could be dropped in the macros definition probably. for the macro call, perhaps make a comma or newline before { acceptable?
Code:
macro FOR {init}, {test}, {incr}, {loopcode}
...
endm
FOR { ... } , { ... }, { ... }
{ ... }
This might be macro abuse, but you can get what you want by sticking code blocks in other macros.
Code:
macro stuff
nop
nop
nop
endm
macro repeat times, code
stx times
- txa
pha
code
pla
tax
dex
bne -
endm
repeat 5, stuff
well it's good to know you can pass a macro with a symbol .. that's about 1/2 of what I'm envisioning, and i can see it being useful
though it's still a bit cumbersome having to define and name the macro every time before the code which uses it. it would still be a cool feature if you could define a temporary macro without a name, but i don't know if that is something totally non-standard with assemblers or what
Code:
macro repeat n
lda #n
- pha
endm
macro repeat_end
pla
sec
sbc #1
bne -
endm
cool i will try that out.. i thought relative labels couldn't be used across macros but I dunno why i thought that.
one disadvantage to that method is that the ending macro doesn't have access to the starting macro's variables
ca65 allows one to pass arbitrary things to macros using { }. For example,
Code:
.macro foo arg
...
arg
...
.endm
foo {bar: .byte $12}
; expands to
...
bar: .byte $12
...
I doubt ca65 allows it, but asm6 could use an extended syntax that allows newlines in the { } string (and after a comma), allowing the original desired behavior, as long as a comma is inserted:
Code:
.macro repeat_n_times iter, body
lda #iter
...
body
...
.endm
repeat_n_times 10,
{
tax
sta table,x
}
This might pose some issues if the macro syntax allows empty arguments, where a comma at the end of a line would already mean simply that the last argument was empty. A workaround would be to write repeat_n_times 10,{ all on the same line, though forcing the
K&R brace style would be kind of annoying.
using the new macro variable ifdef/ifndef functionality for iNes header macro
Code:
macro iNES_header prg, chr, mapper1, mapper2
ifndef prg
prg = #$01
endif
ifndef chr
chr = #$01
endif
ifndef mapper1
mapper1 = #$00
endif
ifndef mapper2
mapper2 = #$00
endif
byte "NES",$1a
byte prg ; PRG-ROM block
byte chr ; CHR-ROM block
byte mapper1 ; mapper info
byte mapper2 ; mapper info
byte 0,0,0,0,0,0,0,0 ; pad header to 16 bytes
endm
; all of these are valid
iNES_header
iNES_header 01
iNES_header 01, 01, 10
; etc
ooo another bug/unexpected problem i ran into while trying to set up a vector macro
Code:
macro test testvar
byte testvar
endm
;works fine
test othervar
; gives "Recursive EQU not allowed."
test testvar
perhaps a workaround would be to add a random string to the macro variable names during one of the assembler passes? in the meantime it seems like it would be good coding practice to adopt some kind of macro variable naming scheme.. like @testvar or something similar..
edit: interestingly, this bug made me think of a way to pass code to variables, and code with spaces are possible with the new stricter syntax. it seems like it might not be that hard to extend the macro syntax to accept and pass line breaks as well
Code:
macro test macroabuse
macroabuse
endm
; both work
test word #$ffff
test nop
hey anybody know what compiler is used to compile ASM6?
frantik wrote:
hey anybody know what compiler is used to compile ASM6?
A C Compiler. The only I've seen it tested on is the GNU C Compiler, but ASM6 is meant to be cross-compatible.
i meant the specific one being used by Loopy.. so i don't have to worry about making some little changes which always seem to be required when moving from compiler to compiler
I'm going to try gcc from MiniGW.. hopefully it will work.
The asm6.exe I provide is compiled with MSVC6.
thanks
frantik wrote:
i meant the specific one being used by Loopy.. so i don't have to worry about making some little changes which always seem to be required when moving from compiler to compiler
I'm going to try gcc from MiniGW.. hopefully it will work.
Does it matter?
i just wanted to know which compiler to look into to have the easiest time compiling the source as is
got it to compile with VC studio.
I wanted to implement the {} syntax allowing multilines, but unfortunately I see that the program operates fundamentally on a line by line basis.. i was able to hack in something in the processfile function so that processline was passed multiple lines but it doesn''t work right at all of course.. the best error i got was "extra characters on line"
i think the best i can hope for now is to see if i can do something with a preprocessor
what is the difference between these two ways of defining variables?
Code:
xyz = $00
and
Code:
enum $000
xyz .byte 0
ende
it seems like LDA xyz would work the same either way
frantik wrote:
what is the difference between these two ways of defining variables?
The first way takes 1 line of code, the second way takes 3 lines.
They both do the same thing.
lol ok
so there's no difference at all?
this should work the same way in either case then?
Code:
LDA #>xyz
LDA #<xyz
thanks
frantik wrote:
what is the difference between these two ways of defining variables?
The second way is just more flexible. It might not make much of a difference if you have few variables, but what if you have dozens of them after xyz and you decide to make xyz a 16-bit variable instead of 8-bit? If you declared the variables the first way, you'll have to manually modify each one in order to make room for the extra byte of xyz. If you did it the second way, you could just change that ".byte 0" to ".byte 0, 0", ".dsb 2", or anything else that reserves 2 bytes, and all the other variables would automatically move 1 byte forward.
The second way is THE way to go if you plan on moving your variables around. I do that a lot, because as my programs grow I always feel the need to rearrange the variables in ways that make more sense (grouping similar variables and things like that).
yeah i can see why you would use each one, I just wasn't 100% sure if there was a technical difference. I mostly was asking because I want to set up certain variables in a header file to always be in the same location regardless of the program and it seemed like using = might be better than enum for a handful of variables
Quote:
Labels defined inside macros are local (visible only to that macro).
is it possible to add a second macro type which allows labels defined inside of macro to be visible?
kind of like an advanced multiline EQU?
Code:
replace function @functionName, @x
@functionName:
@x = 1
endreplace
function foo, bar
lda bar
rts
would convert to
Code:
foo:
bar = 1
lda bar
rts
I just found a bug in ASM6 that's bothering me a lot. If the labels start with the letter "a", I can't use them with instructions such as ASL and LSR (the error is "Extra characters on line").
It's probably because of the alternate syntax where you specify the accumulator as an operand even though it's implied, so the rest of the label's name is seen as "extra characters". This was driving me nuts, because I simply couldn't tell what was wrong with this specific variable.
Loopy, do you think you can fix this? For now I put "0+" before the label, but that's ugly as shit. And even though I could change the variable's name, it sucks that there's a letter we simply can't use as the first character.
tokumaru wrote:
I just found a bug in ASM6 that's bothering me a lot. If the labels start with the letter "a", I can't use them with instructions such as ASL and LSR (the error is "Extra characters on line").
It's probably because of the alternate syntax where you specify the accumulator as an operand even though it's implied, so the rest of the label's name is seen as "extra characters". This was driving me nuts, because I simply couldn't tell what was wrong with this specific variable.
Loopy, do you think you can fix this? For now I put "0+" before the label, but that's ugly as shit. And even though I could change the variable's name, it sucks that there's a letter we simply can't use as the first character.
The C(++) source is included in ASM6.ZIP, So anyone can fix it!
If you already know C(++), then you already know how to fix bugs/glitches in ASM6,
Yeah, I have the source, but I hate to mess with other people's programs. Even if I can find the exact location of the bug, I can't be sure I won't break something else by accident since I don't have a good understanding of the whole program.
tokumaru wrote:
Loopy, do you think you can fix this? For now I put "0+" before the label, but that's ugly as shit. And even though I could change the variable's name, it sucks that there's a letter we simply can't use as the first character.
Fixed.
And for a additional command, I would like to see:
Code:
.ASCIITBL
;Letters
"0"..."9" = $00
"A"..."Z" = $0A
;Times symbol
"x" = $29
;Space
$32 = $24
;Copyright
"c" = $df
.end
.org $8000
;Text (Data)
Hello:
.asc "HELLO WORLD"
like x816 and WLADX. Can you add it in the next version?
loopy wrote:
Fixed.
Cool! BTW, nice going with the local labels, that is a very welcomed feature.
Quick tip for OSX users:
If you're running Snow Leopard and have the latest Xcode tools installed, the latest version of GCC tries to build 64-bit by default which causes a run-time segmentation error with ASM6. Use the "-m32" option to force GCC to output a 32-bit version which works fine.