dasm-assembler / dasm Goto Github PK
View Code? Open in Web Editor NEWMacro assembler with support for several 8-bit microprocessors
Home Page: https://dasm-assembler.github.io/
License: GNU General Public License v2.0
Macro assembler with support for several 8-bit microprocessors
Home Page: https://dasm-assembler.github.io/
License: GNU General Public License v2.0
../dasm/bin/dasm ./chess.asm -l./chess.lst -f3 -s./chess.sym -o./chess.bin || (echo "mycommand failed $?"; exit 1)
end brace required
end brace required
OK, in which one of my 30+ files are those errors occurring?!!
In fact I'm pretty sure they are because I have pseudocode in commented out code (#if 0), which bugs the hell out of me, because I don't believe the parser should be doing anything but looking for ENDIF (and possiblly nested IF but I'm still out to lunch on that one).
Anyway, there we go - somewhere in "do not assemble this" pseudo-code I obviously have a start brace (a "{" presumably) and there's no matching close one.
PITA to find, and also a PITA having the parser parse it in the first place.
So, I'd like
a) Have the filename and line of the start brace reported, so it's easy to locate
b) provide a way to specify "non-parsed" blocks of text (for example, for comments)
Would be really nice to have unicode in labels!
As macros are effectively a text substitution 'engine', I would expect to be able to take any block of code, put it inside a macro, instantiate the macro, and it should work as before.
jmp there
there
Replace with
MAC gogo
jmp there
ENDM
gogo
there
That should all work fine.
The problem is, if 'there' is a local label. Then it doesn't work.
It's because, I think, macros have this local 'SUBROUTINE' scope.
The reason it's super inconvenient is that you can't include a local branch as a destination in a macro, for example...
CHECK_TIMER .exit
.exit
That will fail, of course, because of the local label. I don't think this is ideal, or correct, behaviour.
And it's super-inconvenient, as it makes it impossible to use locals inside macros.
I don't know if/what this might break if 'fixed', but I thought I'd post the issue for discussion.
Hi! Nice to see some new development on an old project of mine! I just recently heard about it so I had a look.
It seems you lost the project history though. I just happen to have converted the svn history from sourceforge to git at https://gitlab.com/Rhialto/dasm-dillon . Since the original svn structure is a bit weird (and definitely nonstandard), the result reflects that. Would you be interested in replaying your changes on top of the history? Maybe we could re-arrange things a bit first, so that it makes more sense for the future.
The SUBROUTINE pseudo-op allows the definition of "local" labels. It's very useful.
However, it does not seem to "survive" being embedded in a macro.
processor 6502
org $1000
MAC TEST
SUBROUTINE
ENDM
.exit
SUBROUTINE ; disable this line to get an error
TEST
jmp .exit
.exit
In the above test code, the ".exit" is defined twice as a local label. The jmp would be expected to hit the second instance, as SUBROUTINE defines a local-label boundary just after the first ".exit". The above code assembles OK.
BUT, if you disable that SUBROUTINE just under the first ".exit", then we have a macro (TEST) which also declares "SUBROUTINE". This does not work - the line is not so much ignored, I think but perhaps the macro is automatically de-scoping local levels/labels at the ENDM? Just a guess.
It would be INCREDIBLY USEFUL to me to have SUBROUTINE working inside macros, and allow me to define the start of local scope with it, which survives outside the macro itself.
Dasm does not delete the binary output file automatically when there are assembly problems. This may lead to successful builds with wrong binary data lurking around. Extra measures have to be taken to remove this wrong intermediate results.
If an assmbly has some severe errors the already created intermediate binary output file should be removed by dasm before its exit.
We need to add a precompiled 64-bit dasm download for MacOS, as the new catalina variant of the OS no longer runs 32 bit apps.
Trying to use dv.w
works for my only if passed value is < 256 :
plop EQM .. + 1
dv.b plop $ab, $12
dv.w plop $ab, $12
dv.w plop $abcd, $1234
gives:
189 f249 plop EQM .. + 1
[...]
196 f24d ac 13 dv.v plop $ab, $12
197 f24f ac 13 dv.v plop $ab, $12
copperbar.a (198): error: Value in 'dv 43982' must be <$100.
copperbar.a (198): error: Value in 'dv 4661' must be <$100.
198 f251 ce 35 dv.v plop $abcd, $1234
Using: DASM 2.20.13 release
.byte 256
This results in 00 being placed in the output binary.
In other words, the low byte is used.
I believe this statement should be flagged as an error 'value out of range' or something like that.
For example, if you have
.byte $FFFF
You end up with just one $FF in the output, not two as you might (wrongly) expect.
Hi. I use DASM as the intermediate compiler under XC=BASIC mainly because of its very flexible macro syntax. A feature that I miss a lot is support for anonymous labels (+, -) like in ACME for example. Are you planning to implement something similar? Thanks.
If you assemble with -T1
, the resulting .sym file has a lot of labels duplicate but with different values. Since the file size is about identical, I suppose something goes wrong when sorting.
Consider adding Ben Coombe's bitmap changes, as listed in the PATCHES file...
From: Ben Combee [mailto:[email protected]] On Behalf Of Ben Combee
Sent: Thursday, February 28, 2008 8:56 AM
To: [email protected]
Subject: Bitmap format patch for DASM
Hi, Andrew... I just started up a 2600 project of my own, and I've done
a few local modifications to the DASM source -- most are to make it
compile without warnings in CodeWarrior for Windows, but I also added a
new integer representation inspired by some of the disassemblies I've
seen. I call it bitmap format, and instead of a leading %, you use a
leading | followed by dots and Xs. A trailing | is allowed, but not
required. Here's an example.
PfDataStart
.byte |..XXX...|
.byte |....X...|
.byte |X..XX..X|
.byte |.XX..XXX|
.byte |.XX..XXX|
.byte |X..XX..X|
.byte |....X...|
.byte |..XXX...|
PfDataEnd
I find it easier to visualize the bitmaps in the code using this format,
as 0's and 1's aren't that distinctive.
Here's the code change made to exp.c. I added this new function just
before pushbin():
char *pushbitmap(char *str)
{
long val = 0;
while (*str == '.' || *str == 'X') {
val = (val << 1) | (*str == 'X');
++str;
}
if (*str == '|') {
++str;
}
stackarg(val, 0, NULL);
return str;
}
Then I modified the case statement around line 314:
case '|': /* 13: | 11: || */
if (str[1] == '.' || str[1] == 'X')
{
str = pushbitmap(str+1);
}
else if (str[1] == '|')
{
doop((opfunc_t)op_oror, 11);
str += 2;
}
else
{
doop((opfunc_t)op_or, 13);
++str;
}
break;
I'd be glad to send the other changes, but they're mostly just adding
"static" in front of local functions and cleaning up some loops that
used a ";" to do nothing into using "{ }" instead (it tells the compiler
that you intended on the empty action rather than just using a semicolon
accidentally by habit.
Sometimes when you've made a special kind of coding mistake in your asm-code, dasm does never return from assembling. It seems to be locked up, running in an endless loop. It has to be terminated by pressing Ctrl-C. The user gets no clue where the error is located. Unfortunately I can't reproduce the error anymore, but I've had this problem in the past. I addressed it and I have a solution/bugfix already done.
If you experience the same behaviour, please write a testcase (put that asm file to the test folder).
Line 702 in b6b90fa
Would be really useful to expose the current iteration counter in REPEAT/REPEND loops.
I know it's do-able with bracketing SET/increment statements, for example...
.TEMP SET 0
REPEAT 3
.byte .TEMP
.TEMP SET .TEMP + 1
REPEND
If it were easy in the code, then something like...
REPEAT 3
.byte @ ; where @ is the current repeat loop #
REPEND
If you miss a trailing bracket on indirect,y addressing, the assembler does not flag an error, and instead assembles as absolute,y.
251 00d8 a0 47 ldy #PIECE_SHAPE_SIZE-1
252 00da b9 a4 00 .copy lda (__psb,y
253 00dd 99 a6 00 sta __pieceShapeBuffer,y
254 00e0 88 dey
255 00e1 10 f7 bpl .copy
On the line with .copy label -- missing close bracket, yet no warning/error generated.
Also, incorrect code generated :).
on OpenBSD, gmake is needed to run the Makefiles, but the rules refer to "make" which uses the native make instead, and doesn't work.
diff --git a/Makefile b/Makefile
index a8bd768..9bab1b1 100644
--- a/Makefile
+++ b/Makefile
@@ -38,13 +38,13 @@ install: build
test: build
echo "Running tests..."
(cd test; make; cd ..)
(cd test; $(MAKE); cd ..)
echo "Tests were run, but testing is not fully automated yet."
echo "In other words, don't rely on what you saw too much."
build:
(cd src; make; cd ..)
(cd src; $(MAKE); cd ..)
mkdir -p bin
cp src/dasm bin/dasm
cp src/ftohex bin/ftohex
@@ -115,6 +115,6 @@ beta:
clean:
(cd src; make clean; cd ..)
(cd test; make clean; cd ..)
(cd src; $(MAKE) clean; cd ..)
(cd test; $(MAKE) clean; cd ..)
-rm -rf dasm-beta-*.tar.gz bin/
diff --git a/test/Makefile b/test/Makefile
index a36eb2c..1a3f585 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -5,7 +5,7 @@ DASM=../bin/dasm
FTOHEX=../bin/ftohex
test:
(cd atari2600; make test; cd ..)
(cd atari2600; $(MAKE) test; cd ..)
./run_tests.sh
%.bin: %.asm
@@ -15,5 +15,5 @@ test:
clean:
(cd atari2600; make clean; cd ..)
(cd atari2600; $(MAKE) clean; cd ..)
rm -rf *.bin *.hex *.list.txt
The following code does not assemble:
CHECK = 0
MAC TEST
.byte {1}
IF CHECK > 0
.byte {2}
ENDIF
ENDM
ORG $f000
TEST 1
testmac.asm (12): error: Not enough args passed to Macro.
Unrecoverable error(s) in pass, aborting assembly!
Complete.
It seems like the CHECK
condition is not evaluated before checking the number of parameters required by the macro.
I think it would be helpful to query the current pass number.
I have some checking macros (e.g. for code and data alignment) which often fail in the first passes and abort assembly. But in the final pass they would pass.
It would be even better if ERR (or a new pseudo op) would only stop assembling in the last pass.
The following will not assemble, throwing an "Unknown mnemonic" error...
LABEL =10
The problem is, a space is required after the =. I'm not so sure that this should throw an error, and perhaps it's an easy fix.
Using a file extension with the -o
option in Windows 10 Powershell returns a fatal error.
Example:
dasm cleanmem.asm -f3 -v0 -ocart.bin
returns Fatal assembly error: Check command-line format.
Issue does not exist when .bin
is omitted, or when dasm is run from command prompt instead.
.byte "|8 17#|7 #17*#|6 #3*13 3*#|6 #2*5 $3 $5 2*#|6 #*2 $14 *#|6 #*10 2#2 $2 *#-2#|6 #*9 #2 #4 *2#2 #|4#2 #*6 $2 #3 #3 *#3 #|#2 2#-#*9 #4 2#@#4 #|2#2 3#*3 $5 #12 #|-2#2 2#*7 $#14 #|2 2#2 #*-$6 #3 .#5 .#2 #|3 4#*8 #3 2#3 #-2#2 #|5 2#*5 $2 #-2.9 2.#|6 #2*-$5 #-2.-#2 #2 #-2.#|6 #3*7 #3 7#2 #|5 3#10*#10 #|4 #3 21#|4 #2 2#-#2 #5 #2 #-#2 #|4 4#2 3#7 3#2 2#"
The above causes a segfault. I suspect it's any long lines like this, but that's the actual line where I found the issue. Normally easy enough to avoid - but...
a) the code is auto-generated so a pain to have to break into multiple lines
b) in my actual use-case, the string is passed to a macro. However the above .byte as a stand-alone will trigger the segfault. But requiring the one string to pass to the macro is why I can't easily split lines.
b) DASM should not segfault under any circumstances! If the line's too long, then say so!
The following code fails with to compile on windows, with both x86 and x64,with build from commit a3e6790
processor 6502
InMemoryCodeLength equ InMemoryCodeEnd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Variables segment
seg.u Variables
org $80
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Code segment
seg Code
org $1000
; ---- modified code-> copied to memory ----------------
Start
nop
InMemoryCodeEnd
nop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Epilogue
org $fffc
.word Start ; reset vector
.word Start ; BRK vector
MAC SOME_MACRO
nop
ENDM
dasm.exe rainbow.a -obuild/o.bin -lbuild/o.lst -sbuild/o.sym -f3
rainbow.a (38): error: Macro "some_macro" defintion is repeated.
Unrecoverable error(s) in pass, aborting assembly!
Complete.
In addition to the typo (defintion -> definition), what is orth noting is :
InMemoryCodeLength equ InMemoryCodeEnd
, the code compiles (though the error message is about duplicated macro which is abviously not duplicated)Macros have some erroneous behaviour...
MAC test
.byte 0
ENDM
MAC Test
.byte 1
ENDM
MAC TEST
.byte 2
ENDM
TEST
The above example will generate a '.byte 0' - and ALL of the macro names in the output listing are converted to lowercase - but the use (at the bottom) is left as-is. I think this is a potential issue, as labels elsewhere in the code are case-sensitive.
The issue: macro names are converted to lowercase. One wonders why.
The second issue: re-use of a macro name with different case is not reported,
The third issue: only the first use of a (case insensitive) macro name is actually used.
When you try to assemble files under Windows which contain Linux line feeds, DASM frequently fails. Especially the REPEAT pseudo-op seems to be affected.
Perhaps a bad idea, but I'm using dasm
to write a program for the MC6800. 6803 code is backwards compatible with 6800's documented instructions, so I thought it'd be a safe thing to do.
However, I just encountered a problem:
JSR $0040
On a 6800, this would use extended addressing, since there's no direct (zero-page) JSR there, so it would be assembled into $BD $0040
. The 6803 does have a direct JSR instruction though, and dasm
will obviously use it, creating code that's not compatible with 6800.
In this specific case, it's even worse. The opcode for direct JSR on 6803 is $9D
, which on the 6800 was an undocumented opcode: The mythical "halt and catch fire"!
Anyway, my actual question is this: I realize dasm
doesn't support 6800 and that maybe I should use something else, but is there a way to force it to use extended addressing in cases like this, without simply inputting the raw bytes?
Split to a new issue from issue #29
Forward references to macros are not allowed. They generate an assembly error (undefined mnemonic). It would be nice to allow forward references, but in any case, the error is suppressed under some circumstances which can be confusing...
If you have a forward-reference to a macro, then yes you get an error with details. But if you trigger a 2nd pass of the assembler by having a forward label reference TOO, then you don't get the error details. Sample code shows this in action. Enable/comment out the "jmp" and you get the two variants.
; Unknown mnemonic/macro
processor 6502
ORG $1000
jmp .forward
lda #1
TEST
lda #1
MAC TEST
lda #2
ENDM
.forward
; EOF
Output with the "jmp" enabled...
boo@Andrews-MacBook-Pro chess % ../dasm/bin/dasm ./test.asm -f3 -o./test.bin
Unrecoverable error(s) in pass, aborting assembly!
Complete.
Output with the "jmp" disabled...
boo@Andrews-MacBook-Pro chess % ../dasm/bin/dasm ./test.asm -f3 -o./test.bin
./test.asm (10): error: Unknown Mnemonic 'TEST'.
Unrecoverable error(s) in pass, aborting assembly!
Complete.
If you try to assemble this (no ORG given)...:
.byte 0
...you get the following output:
1 events requiring another assembler pass.
- Obscure reason - to be documented :)
Fatal assembly error: Source is not resolvable.
Hi,
I have some self modifying code. Since I need to copy it to ram, I put some label in ROM, and then add the difference between position of the code in the rom and the position where I copy it in ram.
I hoped to calculate the position of the code where it will be in RAM like this :
Col7_1 equ InMemoryCode + _col7_1 - _InMemoryCode
Where _col_7_1
is a label in the code in ROM, _InMemoryCode
the label at the beginning of the code when it's compiled in the ROM, and InMemoryCode
a label at the place where the code is copied in RAM.
Unfortunately, this doesn't work. If I try to inc Col7_1
, I get this error on a subsequent line :
Rainbow.a (94): error: Label mismatch...
--> BackToRom f096
Rainbow.a (99): error: Label mismatch...
--> 8.waittimer f09d
If I replace the -
with a +
in the definition of Col7_1
, it works (but with wrong value calculated of course).
The following definition works :
InMemoryCodeLength equ _InMemoryCodeEnd - _InMemoryCode
_InMemoryCode is $f000
InMemoryCode is $0083 (or $83 ? I do a ds InMemoryCodeLength
in the variable segment)
I would be happy to share the code f it helps, but would prefer to share it privately.
I'm getting a crash in 2.20.13 (compiled locally) on assembling a large program.
Running on MacOS.
Symptoms are I add code/data (as include files), it crashes. Remove it, it's happy.
Doesn't really matter what the code is, it seems. In this case it's data statements.
Here's the error...
../dasm/bin/dasm ./chess.asm -l./chess.lst -f3 -s./chess.sym -o./chess.bin || (echo "mycommand failed $?"; exit 1)
/bin/sh: line 1: 85600 Illegal instruction: 4 ../dasm/bin/dasm ./chess.asm -l./chess.lst -f3 -s./chess.sym -o./chess.bin
mycommand failed 132
I have tried with the precompiled MacOS 64-bit version, and that exhibits slightly different behaviour -- it simply never returns. But no error.
Not sure quite how to track this down - I would prefer not to upload many megabytes of code for testing.
I'd like to have the dasm error output changed to a "standard" format. In particular,
https://www.gnu.org/prep/standards/html_node/Errors.html
The reason is that this would make the output compatible with IDEs which parse output during a build to detect errors and allow hot-linking directly to the file/line where the error occurs. Currently dasm appears to be using (at least) the following, which is close but not quite standard....
file (line): error message
I also haven't checked to see if ALL errors/warnings follow the "standard"...
Although this does not generate an error, I think it should.
I have a double-# in the immediate....
; immediate
processor 6502
org $1000
lda ##0 ; should be an error?
Does not seem to complain, and binary is as expected.
I'd prefer to see this flagged - but at the very least perhaps worth a check of the code to make sure it's not doing anything unexpected with this strange format.
Typically old assemblers use dollar '$' sign as prefix for hexadecimal numbers. This causes problems when using on command line in shell scripts or in Makefiles since the dollar sign is the prefix for an environment variable in those contexts. Therefore it would be a nice feature is dasm would understand '0x' as a valid prefix for hexadecimal numbers.
As long as this is not supported dasm throws an segmentation fault when given in a define on the command line i.e.
dasm anysource.asm -DRAMSTART=0x60
The result is a segmentation fault and the user will not know the reason for the error.
Currently parameters are passed as strings without any option to operate on them. The following enhancements would be very useful:
There's a bit of an issue with the #if directive
I ran across a case where I had pseudo-code inside an #if 0
my way of doing an extended comment, basically.
But if the pseudocode also contains the word 'if' (note, not #if) then the preprocessor actually processes it. I think the preprocessor should ignore EVERYTHING inside an "#if 0" except for #endif
Test code...
processor 6502
org $1000
#if 0
some pseudocode
if this works properly, we should see code!
#endif
lda #1 ; does not get assembled
;eof
Assemble it and you don't get the "lda #1" generated, as dasm thinks its inside the #if 0
I would like to see dasm treat redefinition of a macro as an ERR
Failing that, there should be a warning.
It's a silent failure mode otherwise, where code you think is executing actually isn't... because the macro you are modifying is being shadowed by another of the same name.
It would be nice if the labels in the .sym file would contain bank information. That would make debugging of bank-switched files in Stella much easier.
Maybe one could add some pseudo-op (like SUBROUTINE) which defines the start of a new bank. And then generate a .sym file which outputs the bank too.
At https://dasm-assembler.github.io/
the link to "documentation" goes 404
I've recently gotten DASM to compile into a Web Assembly (WASM) module.
The process required no changes to the DASM source code. (Congrats on that, BTW), a tiny amount of glue-code and some minor changes to the Makefiles.
I'm planning on tying this into a 6502 emulator as well.
Are you interested in having any of these changes back upstream?
This could be the base for anything from a CodePen style demo page to an Atari 2600 IDE.
Trailing commas in a data declaration line seems to effectively add a 0 value.
E.g. this code:
PF0Table ; table 0
.byte #%10000000,
.byte #%10000000,
.byte #%10000000,
.byte #%11000000,
(...)
will generate 8 bytes.
This is not expected. You would expect an error from dasm, or maybe have dasm ignore it.
processor hd6303
org $ff60
aim 10,10
Dasm generates 71,0a instead of 71,0a,0a
https://www.jaapsch.net/psion/mcmnemnm.htm
I think aim should be coded as the following:
aim #$80, $17 ;71 80 17
aim #$80, 0,x ;61 80 00
I was trying to learn a bit about how a particular pseudo-op worked, and ended up with a very simple test-case which causes dasm to segfault. I am of the opinion that even if the code is "stupid", dasm should report an error, not crash :)
; segfault
str set ""
str eqm str + "\nAAAAA"
echo str
; EOF
Here's the result...
boo@Andrews-MacBook-Pro Chess % ../dasm/bin/dasm ./test.asm -o./test.bin
zsh: segmentation fault ../dasm/bin/dasm ./test.asm -o./test.bin
It would be super-dooper-cool if DASM had an option to include a comment on each line in the listing file, giving cycle counts for the instructions on that line. Also, perhaps a few embedded directives to start cycle count @ value, give the sum so far, hints for loops/branches, etc.
In the test folder there are files for 'false-positive' testcases that are also added to the list of normal testcases.
A testcase should either fail or succeed not both.
processor hd6303
org $0
jsr test
test
bra test
Can you please help me why is it wrong?
fwref.asm (7): error: Label mismatch...
--> test 0003Unrecoverable error(s) in pass, aborting assembly!
Complete.
the comments to enumeration ADDRESS_MODES in file asm.h seem to be misleading to me. Only the symbols
AM_IMP, AM_IMM8, AM_IMM16, AM_BYTEADR, AM_0X and AM_0Y have (for me) reasonable correct comments. The others seem to be shifted or swapped.
I came across this when I tried to extend the address modi.
the run_test.sh script does not check for the errorlevel of dasm. It parses the listing file instead. Some testcases may succeed even if they ar supposed to fail.
The script should evaluate the return code (errorlevel) from dasm-process.
Modern development environments are able to do syntax-highlighting. It would be nice if dasm could understand also
'ifndef' and 'macro'. Also in order to be more compatible to the output/formatting of some other assemblers and disassemblers it would be nice to have these two reserved words recognized.
I only found the latest documentation in the source code. IMO it should be part of the releases (too).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.