6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Wed May 08, 2024 9:49 pm

All times are UTC




Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: 6502 assembler for 6502?
PostPosted: Sat Aug 12, 2023 7:27 pm 
Offline
User avatar

Joined: Fri Feb 17, 2023 11:59 pm
Posts: 163
Location: Lviv, Ukraine
I'm wondering if there are any implementations of 6502 assemblers written in 6502 assembly itself (alternatively, written for CC65) that support common features like labels. Basically, a program that can be given string as an input and produce machine code as a result.

_________________
/Andrew

deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD


Top
 Profile  
Reply with quote  
PostPosted: Sat Aug 12, 2023 7:50 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1405
Location: Scotland
I'm sure there are many - back in the day (c1980) I used something called TED II+ on the Apple II for example...

And of-course there's the one built into BBC Basic ...

Assembler ROMs for the AIM-65...

And I'm sure many many more..

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Sat Aug 12, 2023 8:26 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8177
Location: Midwestern USA
and3rson wrote:
I'm wondering if there are any implementations of 6502 assemblers written in 6502 assembly itself (alternatively, written for CC65) that support common features like labels. Basically, a program that can be given string as an input and produce machine code as a result.

Commodore’s MADS (C-64) and HCD65 (C-128) packages were full-featured assemblers written in 6502 assembly language.  HCD65 emitted an object file in MOS Technology symbolic format (similar to Motorola S-record format), which was then submitted to a linker to produce the final binary.  As I recall, the linker made it possible to relocate the resulting binary to an entirely different starting address, with static address references being fixed up.  That feature made it possible to develop code that could run on the stack.

I don’t know if the source code for either is available.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Sat Aug 12, 2023 9:59 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1373
I used the Commodore MADS package on the C64 for many years back in the 80's. I did a lot of code using that package. Overall a nice setup with an editor and dos wedge. The real bottleneck was the Commodore disk drive... initially using a 1541 and later a 1581 which did improve the performance.

On another note, Richard Leary's DOS/65 has an assembler (written in 6502 assembly) that runs on the 6502 and uses DOS/65 for file I/O. The entire source is available as well. I've used this quite a bit recently for testing of my recent DOS/65 3.20 version. It's a good 2-pass assembler, but it only supports the original NMOS 6502 instructions/addressing modes.

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Sun Aug 13, 2023 12:42 am 
Offline
User avatar

Joined: Fri Aug 03, 2018 8:52 am
Posts: 746
Location: Germany
it would be amazing if it were possible to compile the cc65 utlities with itself, so you could have a native C compiler, Assembler, and Linker. but i think 64k is simply not enough to run any of them natively.

of course another option is to write something yourself (either in C or directly in assembly), though that arguably takes more effort than porting something existing.


Top
 Profile  
Reply with quote  
PostPosted: Sun Aug 13, 2023 5:52 am 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 683
Location: Potsdam, DE
Back in the day I used an in memory assembler (an EPROM on the expansion board) for the Tangerine Microtan 65. TANSOFT, I think. That and some other options here: http://www.microtan.ukpc.net/pageAssemblers.html

I also used - mostly for development SBCs - Avocet running under CP/M on a z80 machine to generate binaries.

Neil


Top
 Profile  
Reply with quote  
PostPosted: Sun Aug 13, 2023 6:02 am 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1405
Location: Scotland
Proxy wrote:
it would be amazing if it were possible to compile the cc65 utlities with itself, so you could have a native C compiler, Assembler, and Linker. but i think 64k is simply not enough to run any of them natively.


I did try - I gave it one-shot and failed miserably. It's just not going to work...


Proxy wrote:
of course another option is to write something yourself (either in C or directly in assembly), though that arguably takes more effort than porting something existing.


It might be nice to make it modular enough to work on other systems, but that could be quite hard when it comes to filing system interfacing. Also things like I have started on an assembler myself, but it's in BCPL, so not much use to anyone other than me, really... If it's written in ASM on another system then it might limit who can actually assemble it in the first instance and so on...

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Sun Aug 13, 2023 8:03 am 
Offline
User avatar

Joined: Fri Aug 03, 2018 8:52 am
Posts: 746
Location: Germany
you don't really need a file system if the assembler works like a BASIC interpreter and includes it's own editor, with optional LOAD and SAVE commands that the user can implement themself.


Top
 Profile  
Reply with quote  
PostPosted: Sun Aug 13, 2023 9:06 am 
Offline

Joined: Wed Jan 01, 2003 6:32 pm
Posts: 32
You might want to have a look at my assembler at https://github.com/Dietrich-L/CPM-65/tree/main/ASM
It is nativ, has MOS 6502 opcodes only and is very fast. No macros though.

The input is a text file, output is the assembled file and a label file. It is 6k in size and easy to port. However you need a file system to read the source file in 256 byte chunks and write the output files also in 256 byte chunks.

If you need any assistance, let me know.

Dietrich

_________________
My system: Elektor Junior Computer, GitHub https://github.com/Dietrich-L


Top
 Profile  
Reply with quote  
PostPosted: Sun Aug 13, 2023 3:45 pm 
Offline

Joined: Mon Sep 17, 2018 2:39 am
Posts: 133
Hi!

Proxy wrote:
you don't really need a file system if the assembler works like a BASIC interpreter and includes it's own editor, with optional LOAD and SAVE commands that the user can implement themself.

In the Atari 8-bit computers, two popular assemblers worked with this "BASIC like" editor: The original Atari Assembler Editor ( https://en.wikipedia.org/wiki/Atari_Assembler_Editor ) and the MAC/65 macro assembler ( https://en.wikipedia.org/wiki/MAC/65 ).

Source for the MAC/65 assembler is available, it is for the cartridge version that uses a bank-switched cart: https://atariwiki.org/wiki/Wiki.jsp?pag ... 651.011986 , it was used a lot because it tokenized the sources, making it very fast and allowing bigger sources.

There are a lot of assemblers for the Atari 8-bit, with and without support for macros and relocatable output. Some like Fast Assembler https://github.com/HolgerJanz/FastAssembler are still being updated today. Here is a little list (use google translate): http://atariki.krap.pl/index.php/Asembler

Have Fun!


Top
 Profile  
Reply with quote  
PostPosted: Mon Aug 14, 2023 4:46 am 
Offline

Joined: Fri Apr 15, 2016 1:03 am
Posts: 136
Another option is to run a 6502 assembler in FORTH hosted on a 6502.

If you're OK with a FORTHish syntax (to reuse the FORTH command line parsing) the assembler logic is straightforward.

Some 6502 implementations are
"typists assembler" in Tali FORTH,
& 6502 assembler in FIG FORTH.

Here is the console log of a 65816 example:
Code:
\ FORTHish assembler simple demo  ok
  ok
: UM*S ( u1 u2 -- ud ) \ start a subroutine (word) definition  compiled
  \ ud=u1*u2  simple multiply  compiled
  \ https://forth-standard.org/standard/core/UMTimes  compiled
  [ \ shift FORTH interpreter from compile to interpret state   ok
  0 ## lda, \ init product hi  ok
  2 d,x lsr,  \ initial shift u1  ok
  16 ## ldy, Begin,  \ for each u1 bit  ok
    IfCs,  ok
      clc, 0 d,x adc,  Then,  ok
    rora, 2 d,x ror,  \ shift right product & u1  ok
   dey, UntilEq,  ok
  0 d,x sta,  \ store product hi, product lo already in place  ok
  ]  \ shift FORTH interpreter from interpret to compile state  compiled
  ;  \ end the subroutine (word) definition  ok
  ok
SeeLatest  \ disassemble last word
04DB A90000     LDA #$0000 {' SInIndx0}
04DE 5602       LSR $02,x
04E0 A01000     LDY #$0010 {' SInIndx2}
04E3 9003       BCC $04E8 {UM*S+000D}
04E5 18         CLC
04E6 7500       ADC $00,x
04E8 6A         RORA
04E9 7602       ROR $02,x
04EB 88         DEY
04EC D0F5       BNE $04E3 {UM*S+0008}
04EE 9500       STA $00,x
04F0 60         RTS

 ok
  ok
1234 23456 UM*S D.  \ test the new subroutine 28944704  ok
  ok
  ok
: DUM/ModB ( uq_dividend ud_divisor -- ud_rem ud_quot )  \ unsigned divide 64/32=32,32  compiled
  [  ok
   8 d,x lda, LRefA @Word jsr,  8 d,x sta,  ok
  10 d,x lda, LRefA @Word jsr, 10 d,x sta,  ok
  inx, inx, inx, inx,  ok
  ' 2Swap jmp,  ok
  ok
 LDef @Word  ok
  asla, Tmp sta,  \ save dividend word & get next bit  ok
  16 ## ldy, Begin,  \ for each bit in word  ok
    6 d,x rol, 4 d,x rol, LRefR @8 bcs, \ rol dividend hi  ok
    6 d,x lda, 2 d,x cmp, 4 d,x lda, 0 d,x sbc, \ compare  ok
    IfCs,                                       \ if  ok
 LDef @8  ok
      6 d,x lda, 2 d,x sbc, 6 d,x sta,  \ subtract  ok
      4 d,x lda, 0 d,x sbc, 4 d,x sta,  ok
      sec, Then,  ok
    Tmp rol,  \ add bit to quotient word, get next dividend lo bit  ok
    dey, Untileq,  ok
  Tmp lda,  \ return quotient word  ok
  ] ;  ok
  ok
SeeLatest
04FC B508       LDA $08 {Tmp},x
04FE 201105     JSR $0511 {DUM/ModB+0015}
0501 9508       STA $08 {Tmp},x
0503 B50A       LDA $0A {Tmp+0002},x
0505 201105     JSR $0511 {DUM/ModB+0015}
0508 950A       STA $0A {Tmp+0002},x
050A E8         INX
050B E8         INX
050C E8         INX
050D E8         INX
050E 4CB08C     JMP $8CB0 {2Swap}
0511 0A         ASLA
0512 8508       STA $08 {Tmp}
0514 A01000     LDY #$0010 {' SInIndx2}
0517 3606       ROL $06,x
0519 3604       ROL $04,x
051B B00A       BCS $0527 {DUM/ModB+002B}
051D B506       LDA $06,x
051F D502       CMP $02,x
0521 B504       LDA $04,x
0523 F500       SBC $00,x
0525 900D       BCC $0534 {DUM/ModB+0038}
0527 B506       LDA $06,x
0529 F502       SBC $02,x
052B 9506       STA $06,x
052D B504       LDA $04,x
052F F500       SBC $00,x
0531 9504       STA $04,x
0533 38         SEC
0534 2608       ROL $08 {Tmp}
0536 88         DEY
0537 D0DE       BNE $0517 {DUM/ModB+001B}
0539 A508       LDA $08 {Tmp}
053B 60         RTS

 ok
  ok
$9abcdef0. $12345678. $98765432. DUM/ModB D.Hex Space D.Hex 1E9131AB 91430F8A ok
  ok


Top
 Profile  
Reply with quote  
PostPosted: Mon Aug 14, 2023 8:12 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8432
Location: Southern California
leepivonka wrote:
Another option is to run a 6502 assembler in FORTH hosted on a 6502.

I was going to let this topic run its course before mentioning this; but since you brought it up, I'll chime in now.

I have Forth resident in my workbench computer's ROM for very quick development of applications.  Like they say, you can get 90% of the performance with only 10% of the code in assembly language—provided it's the critical 10%.  ...Or is it 95% and 5%?  Whatever.  [1]  Anyway, there are many situations where I want to do some short piece in assembly language for maximum performance, so I took a couple of hours one evening and wrote myself an assembler years ago.  Later I improved it a bit, and I still have further improvements in mind; but it was quick to write in its original form, and takes very little memory.  It's single-pass, and Forth keeps addresses on the stack during assembly so forward references get filled in later in the assembly when the target is encountered.  A pleasant surprise I got after I wrote it is that since it's in Forth, macro capability was automatic—I didn't have to do anything to get it.  This assembler is not suitable for writing whole applications in assembly language, only primitives, subroutines, ISRs, runtimes, etc..

Quote:
If you're OK with a FORTHish syntax (to reuse the FORTH command line parsing) the assembler logic is straightforward.

I hate the RPN syntax of most Forth assemblers, so I made mine to be more normal, so you could have for example LDA# 7 , instead of 7 ## LDA .  (The comma is part of it.  It lays down the operand.  All the LDA# does is lay down the A9 op code.  It doesn't care if you even put an operand on it, which can be handy when you want to do self-modifying code where the operand itself is a variable, rather than a reference to a variable.)  So leepivonka's '816 first primitive above, UM*S, would be written as:

Code:
CODE  UM*S  ( u1 u2 -- ud )
      LDA#       0   ,
      LSR_DP,X   2  C,
      LDY#      10   ,       \ (I usually keep it in hex)
      HERE
         BCC 1$
             CLC
             ADC_DP,X  0  C,
 1$:     ROR_A
         ROR_DP,X   2  C,
         DEY
      BNE  GO_BACK
      STA_DP,X   0  C,
      GO_NEXT                \ Mine is not STC, which is
 \ ------------              \ why it's not RTS here.

No parsing is necessary.  The addressing mode is merged with the mnemonic, so you don't need a separate assembler vocabulary either, because for example assembly language's AND won't be confused with Forth's AND because in assembly language it's always AND#, AND_ZP, etc., never just AND.  You can put as many instructions on one line as you like.


[1]  The point is not that you can make the whole thing run 90% as fast as assembly, but rather that with a little assembly, you can get the speed-critical parts to perform as needed, while it doesn't matter for the rest.  "The rest" may be, for example, routines that scan and debounce a keypad, take care of auto key repeat delay and repeat speed, take in data or instructions on an RS-232 port and interpret them, etc..

An example from my own work is that I've had a machine-language ISR on my workbench computer playing back sampled aircraft audio at 24,000 samples per second while in Forth I was trying things by having the computer accept instructions as text over the RS-232 port and interpreting them.  The instructions could do things like change the sampling rate, move around in the recording, even modify the ISR on the fly.  So even though only a tiny percentage of it was not in Forth, I was producing the audio with 24,000 samples per second and doing other stuff at the same time, on my 5MHz workbench computer which was fast enough for it all.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Fri Aug 18, 2023 10:00 pm 
Offline
User avatar

Joined: Fri Feb 17, 2023 11:59 pm
Posts: 163
Location: Lviv, Ukraine
Dietrich - I'll try to use yours, looks very promising, thanks for sharing. I've tried writing my own in CC65, but it quickly went out of control and I've reached 8KB just with a simple tokenizer and mnemonic encoding. Not sure if my attempt is worth the time. Best case - I'll have an extremely simple and slow assembler that takes all my ROM... Here's my pitiful attempt: https://github.com/and3rson/6565 - though I'm probably going to abandon it. The only working part is tokenizer & mnemonic parsing.

Garth, leepivonka - Your FORTH stuff never ceases to amaze me, but I feel like I haven't yet reached the necessary state of mind to understand FORTH. :D I still appreciate your ideas, but I'll have to revisit them once I get better with FORTH.

Proxy - I too initially thought about compiling cc65 with cc65, however memory limitation is definitely going to be the tightest bottleneck, even with memory banking. (As I mentioned - in my case, even a bare minimum assembler that I wrote takes a lot of space, and I'm not yet even halfway through...)

_________________
/Andrew

deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD


Top
 Profile  
Reply with quote  
PostPosted: Thu Aug 24, 2023 5:10 am 
Offline

Joined: Fri Feb 12, 2021 10:17 pm
Posts: 34
There is also Krusader and the A1 Assembler, those are the two I use on my hombrew's.

I like both of these. Both support lables.

I modified the A1 assembler a to add load and save commands, which work with my SD card solution. If you like it there is a nice sb assembler which is it's desktop version. With that desktop version you can choose to compile to many formats, binaries, hex, and so on.

You can read about / download the A1 Assembler here: https://www.sbprojects.net/projects/apple1/a1asm.php

I intend but have not yet modified Krusader for save and load, though it is do-able and one of my projects on the back burner.

Krudaser 1.3 has the support for 65c02 op-codes. Though it can be ran from ram, the choice to go with it's built in version of wozmon, which is only slightly modified is also a nice option as that route will have you set up for breaks right from the get go. You can pick up Krusader here - https://github.com/st3fan/krusader

Good luck

_________________
Shaking out the dirty bits!

https://github.com/DonaldMoran


Top
 Profile  
Reply with quote  
PostPosted: Sat Aug 26, 2023 7:58 am 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 993
Location: near Heidelberg, Germany
Here's also @ASS that I wrote originally for the C64, using its BASIC editor to do the actual editing and file handling (overlays do work though) http://www.6502.org/users/andre/misc/index.html

Edit: I bootstrapped it with a copied assembler I got somewhere, until it was able to assemble itself. It's 4k in size. It does not do CMOS opcodes, and is not really documented. So, just for reference

_________________
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 14 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: