XAsm - 6502 Cross Assembler

You need an actual VIC.

Moderator: Moderators

User avatar
Schlowski
NoMess!
Posts: 892
Joined: Tue Jun 08, 2004 12:20 pm

XAsm - 6502 Cross Assembler

Post by Schlowski »

As I wrote in another thread I have my own 2-pass 6502 macro assembler and as we now have this "Emulation and Cross Development" forum I thought I could share this tool.

http://www.stojalowski.de/files/XAsm_release.zip

Included are 2 versions, a commandline only version (XAsm.exe) and a version with a minimal(!) GUI (XAsm_Win.exe). I use the commandline version together with my favourite editor which makes for a nice development environment.

To show whats possible I include the sources for LCE and VPokerAsm.

Excerpt from MiniManual:

Code: Select all

Features:

- 2 pass assembler
- direct output for Commodore machines (binaries including load address)
- redefinable labels
- local labels
- macros with nesting 
- repeat loops with nesting and expression evaluation as loop counter
- conditional assembly based on values or defined/undefined labels
- illegal opcodes (as described in 6502-NMOS_extra_opcodes.htm)
- does everything I need :-)
- supports 6502, 6502 inkl. illegal opcodes and 65SC02 
A hopefully complete list of features can be read in MiniManual.txt.

Another nice feature me thinks is the output of cycles for each mnemonic in the listfiles:

Code: Select all

147B:                                 ; ----------------------------------------------------------------
147B:                                 ; Invert character
147B:                                 ; ----------------------------------------------------------------
147B: A0 07    [ 2 ]  InvChar       : ldy #7
147D: B1 14    [5/6]  InvC1         : lda ($14),y
147F: 49 FF    [ 2 ]                  eor #$ff
1481: 91 14    [6/7]                  sta ($14),y
1483: 88       [ 2 ]                  dey
1484: 10 F7    [2/3]                  bpl InvC1
1486: 60       [ 6 ]                  rts
[ 2 ] means 2 cycles
[2/3] means 2 cycles if branch not taken, 3 cycles if branch taken
[5/6] means 5 cycles, 6 cycles if page boundary is crossed

Of course we have some adjustments for branches over page boundaries:

Code: Select all

1FF0:                       * = $1FFA
1FF0:                       
1FF0:                       ; ---------------------------------------------------------------------
1FF0:                       ; test for cycle counting
1FF0:                       ; ---------------------------------------------------------------------
1FFA: A2 FF    [ 2 ]  Lab1: ldx     #$FF
1FFC: A9 01    [ 2 ]        lda     #1
1FFE: 8D 00 10 [ 4 ]        sta     $1000
2001: CA       [ 2 ]        dex
2002: D0 F6    [2/5]        bne     Lab1    ; 5 cycles if branch taken because of page boundary crossing!
2004: 60       [ 6 ]        rts
This makes cycle counting much easier.

I know, most of you are using DASM, but maybe this is of use for someone else...
KingTrode
Vic 20 Hobbyist
Posts: 133
Joined: Tue Apr 13, 2010 2:32 am

Post by KingTrode »

Thanks for making this available, new dev tools are always warmly welcomed by me :D

Downloaded, going to check it out later on/tomorrow
User avatar
nbla000
Salmon Run
Posts: 2582
Joined: Thu Oct 13, 2005 8:58 am
Location: Italy

Post by nbla000 »

Wow, a lot a new programs and tools this year for the Vic !!!

Very good work, I will try it at the first occasion.


About DASM, you are right, I use it for example but I'm using ACME for CBM-Filebrowser too, so it's just a syntax question but which may be the main reason to use your program ? except the pleasure of a new adventure of course :wink:
Mega-Cart: the cartridge you plug in once and for all.
User avatar
Schlowski
NoMess!
Posts: 892
Joined: Tue Jun 08, 2004 12:20 pm

Post by Schlowski »

@nbla000: I really don't know :-) I used to write my own 6502 assemblers since I had my first VIC and never got used to other assemblers, but I think this is no reason for anybody else... And I fear XAsm has no outstanding feature other assemblers do not offer, maybe beside the cycle count feature - but even here I'm not sure as I did not check other assemblers for that.

Ah, maybe this feature - generate complete Basic loader with data etc. from Source:

Code: Select all

.LOADER	DataTest.bas

* = 673
     
     JSR $CEFD ; CHKCOM, check for comma 
     JSR $D79E ; GETBYT, get byte into X 
     TXA  
     LDX #$00 ; counter 
LOOP:LSR 
     BCC NINC 
     INX 
NINC:BNE LOOP ; if A=0 this will exit, after INX it will be false 
     STX $FE ; store result back into ZP 
     RTS 
generates this:

Code: Select all

10 DATA 32,253,206,32,158,215,138,162
20 DATA 0,74,144,1,232,208,250,134
30 DATA 254,96
40 FORA=673TO690:READB:POKEA,B:NEXT
There's only one problem, this is pure ASCII - but with BasEdit.Net you can load and save this as a real PRG file.

Mmh, I should rework this feature a little bit so that it writes a real tokenized Basic file. Shouldn't be too difficult as it only requires a few tokens for DATA, FOR, TO, READ, POKE and NEXT and some line-number and linker-bytes glue...

And that's the main reason for these tools, they do what I want, I know (most of the time) how they do it and I can adjust everything as I feel the need to do. Sometimes I even take care of user wishes :wink:
Last edited by Schlowski on Tue May 04, 2010 4:32 pm, edited 1 time in total.
User avatar
Schlowski
NoMess!
Posts: 892
Joined: Tue Jun 08, 2004 12:20 pm

Post by Schlowski »

New version 3.3.8 uploaded
- .LOADER directive now generates true Commodore Basic file which can be LOADed and started with RUN without any further tricks.
User avatar
Wilson
Vic 20 Enthusiast
Posts: 190
Joined: Mon Sep 28, 2009 7:19 am
Location: Brooklyn, NY

Post by Wilson »

Wow, this is a very cool assembler! Lots of features. I know this sounds very trivial, but I like how labels don't have to be aligned on the far left. That always confuses me when I'm doing nested loops. :)

I've noticed that it will happily assemble some weird stuff though. For example:
INC "testsrcp2.a65" produces: INC $54

Also, while the assembler doesn't support modulo division, it will assemble LDA #5%2 to LDA #$00.

But that aside, this seems great!

Any chance of a Linux version? ;)
User avatar
Schlowski
NoMess!
Posts: 892
Joined: Tue Jun 08, 2004 12:20 pm

Post by Schlowski »

INC "testsrcp2.a65" produces: INC $54
That's because I try to be as versatile as possible, sometimes this misses the goal... Think of something like LDA #'A' to load the PETSCII-Value of 'A' into the accumulator. Or LDX #'Z'-5 or other calculations. Therefore constant string arguments will be treated as immediate values which sometimes leads to unexpected results.
The other problem it's easy to forget the . before some assembler directives, which in this case gives a total different result, instead of including a file it assembles the command...
Also, while the assembler doesn't support modulo division, it will assemble LDA #5%2 to LDA #$00.
Mmh, a modulo operator should be possible, I only have to be careful not to get confused between binary values starting with % and a modulo operation. But this should be handled properly by the evaluation routines anyway...

For a Linux version: Since it's written in Purebasic which has native Linux support this should be possible. Any volunteers?
User avatar
Schlowski
NoMess!
Posts: 892
Joined: Tue Jun 08, 2004 12:20 pm

Post by Schlowski »

New version 3.3.9 uploaded
- implemented modulo operator (%)
- added Linux executables
-- compiled under OpenSuse 11.1 2.6.27.29
---- XAsm_Linux is the commandline-version
---- XAsm_KDE is a GUI version

Modulo operator was alittle bit tricky, but now works as expected:

Code: Select all

0000: A9 01    [ 2 ]    lda     #11%2    ; modulo
0002: A9 00    [ 2 ]    lda     #10%2    ; modulo
0004: A9 03    [ 2 ]    lda     #%11      ; binary value
0006: A9 01    [ 2 ]    lda     #%1011%%10  ; modulo with binary values
KingTrode
Vic 20 Hobbyist
Posts: 133
Joined: Tue Apr 13, 2010 2:32 am

Post by KingTrode »

Thanks for the recent updates, new features always welcome.

I have recently updated my TextPad "Syntax Highlight" / "Tool Execute" to support XAsm and have spent the last day or so using it instead of DASM.

I must say I very impressed, it has some nice features - so much so that I'm putting DASM on the back burner for now and continue using XAsm.


Keep up the good work :D
User avatar
Schlowski
NoMess!
Posts: 892
Joined: Tue Jun 08, 2004 12:20 pm

Post by Schlowski »

Cool, a happy customer, so to say :-) If you have some ideas on how to enhance XAsm or miss a feature of DASM just ask, maybe it's easy to implement.

I use XAsm with UltraEdit the same way, with Syntax Highlighting and Assemble as a tool, output is captured by UltraEdit after assembly so I can see if everything was ok. Together with the project feature this is a complete development environment.
User avatar
Schlowski
NoMess!
Posts: 892
Joined: Tue Jun 08, 2004 12:20 pm

Post by Schlowski »

Mike showed me a little error in my cycle count:

Branches not taken require 2 cycles, branches taken 3 cycles, branches taken across page boundaries 4 cycles. XAsm reports 5 cycles for the latter one which is definately wrong. Will be corrected in the next version!

This was a mix up between different cycle counts in my 6502 reference book...
FD22
Vic 20 Hobbyist
Posts: 148
Joined: Mon Feb 15, 2010 12:31 pm

Post by FD22 »

Ah, just beat me to it. The confusion stems from the way the documentation (many and varied sources) for Branch instructions typically reads as "2 cycles (+1 if branch taken, +2 if branch taken over page boundary)".

Arguably, you can interpret this to mean 2+1+2 for a branch taken across a page boundary; but the additionals are actually an 'or', meaning 2+1 or 2+2 as opposed to 2+1+2.
User avatar
Schlowski
NoMess!
Posts: 892
Joined: Tue Jun 08, 2004 12:20 pm

Post by Schlowski »

In my case it was from the german version of "Programming the 6502" from Rodnay Zaks. There is simply a wrong footnote in the appendix concerning branches which states 2 cycles for a branch, add 2 if jump taken, add 3 if jump across page boundary.
In the separate description for each command it reads 2 cycles, +1 if jump taken, +2 if jump across page boundary, which is obviously the right description.
Unfortunately I took the wrong reference, but the table was much easier to read and implement than to read the description of each command page by page...

Anybody here with the original english version who can take a look at the Appendix D - Command set in hexadecimal with timings (or whatever it's called in the english version)?
KingTrode
Vic 20 Hobbyist
Posts: 133
Joined: Tue Apr 13, 2010 2:32 am

Post by KingTrode »

The one I have reads as follows:-

2 Cycles for branch instruction = n

Add 1 to n if branch in page

or

Add 2 to n if branch to another page

Hope this helps.
User avatar
Wilson
Vic 20 Enthusiast
Posts: 190
Joined: Mon Sep 28, 2009 7:19 am
Location: Brooklyn, NY

Post by Wilson »

That was fast! :shock:

Many thanks for the Linux version! I'll try it out tomorrow.
Post Reply