6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu Nov 21, 2024 4:20 pm

All times are UTC




Post new topic Reply to topic  [ 83 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next
Author Message
PostPosted: Wed Jun 21, 2017 7:12 pm 
Offline
User avatar

Joined: Mon May 25, 2015 2:25 pm
Posts: 690
Location: Gillies, Ontario, Canada
As I get closer to working on the full version of my Operating System (BMOS) and the incorporated Assembler (BMASM), I am considering options such as macros, formatting, etc.
I personally like the color scheme I currently have, which is much like Visual Studio, but will make this fully adjustable in the OS.

As for Assemblers, I am only familiar with the MacroAssembler by Michal Kowalski which I really enjoy using.
The only quirk I don' plan to use is that strange space before instructions thing.
I do plan to have the live help (press F1 over an instruction), and will add a lot more detail, such as cycles, examples, etc.
Another feature I plan to add is bookmarks in code, and scroll aware subroutines for easy traversing of long code.

My final IDE will probably be a mix of the following : Kowalski Assembler, AVR Studio, and Visual Studio.

To all those who enjoy writing 6502 code...
What other 6502 assemblers (PC or native) are considered popular?
Are there any "must have" features that you can't live without?
What's missing from your favorite assembler?

When I design BMASM, I am almost unlimited because of the design of Anvil-6502....

- I have a full 64K of program space to use for the OS / IDE
- The code is stored in its own 3.5MB of memory, accessible the Assembler
- The assembled program lives in its own sand-boxed 64K space away from the OS

Unlike a native 6502 assembler that has to do everything in some 32k of memory, I have no restrictions.
Also, my text and cursor routines are function calls in the FPGA "Chipset", so scrolling is highly responsive.
The 6502 still does most of the work though, and will also have to juggle a file system.

My next step in design will be to make a basic editor that can enter and run code directly.
Right now, I preload the source code into the SRAM.

Later.
Radical Brad


Top
 Profile  
Reply with quote  
PostPosted: Wed Jun 21, 2017 8:20 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
Oneironaut wrote:
To all those who enjoy writing 6502 code...
What other 6502 assemblers (PC or native) are considered popular?
Are there any "must have" features that you can't live without?
What's missing from your favorite assembler?

You could check out (and add to) the topic, "desirable assembler features." I found a way around the problem I initially wrote about. It's a jury rig, but it works.

I would add, don't require labels to start in column 1. If the editor has a "condensed" display mode which shows only the lines with something in column 1 to make it easier to find things you don't remember enough specifics to use the search feature, it's nice to be able to use the condensed mode and omit even lines with labels of only local interest which start in column 2 or later. If there's any difficulty positively identifying them as labels, they can be followed with a colon. I always put a colon after labels anyway, so a search for one goes right to it rather than wasting your time by first turning up a lot of references to the label.

I would also say don't require assembler directives (or pseudo-ops) to start with a dot, since that makes vertical alignment look messed up.

I have some other wish-list stuff elsewhere but it will take me a while to remember where. Basically, make it as flexible as possible, accommodating other users' styles and new things they might want to do that you haven't thought of yet. "Planning on the unknown" might sound self-contradicting, but it can be done somewhat effectively by making things as open as possible.

I have quite a list of 65xx assemblers at http://wilsonminesco.com/links.html#assem . Some of the lines go to further lists of assemblers. Most of them are free. I used the 2500AD assembler in the late 1980's up to about 1994, and then have been using the Cross-32 (C32) assembler since then. These two run under DOS. They weren't free, but seem to be much more powerful than what I usually see people on the forums using. The best free one I can think of at the moment might be Andrew Jacobs' As65. (I haven't used it, but it looks excellent.) I have a very compact macro assembler integrated with my Forth kernel on the workbench computer, but as flexible as it is in many ways, it's not suitable for assembling large projects. It's really just for assembling things like Forth primitives and runtimes and assembly-language ISRs, never more than one or two hundred lines, and typically a lot less; but because of it, I seldom need the PC-based assembler.

_________________
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: Thu Jun 22, 2017 1:48 am 
Offline

Joined: Tue Jul 24, 2012 2:27 am
Posts: 679
To my count, you have 76 command locations, unless some locations span more than 1 byte. You could consider putting those in zeropage, as many other platforms have "OS use" of zeropage in that size or larger.

I'm a big fan of ca65, which does the full segment/linker process of modern assemblers, and I use most of its features when I work on 6502 code. I find it much saner to lay out the memory map in segment definitions rather than have magic "*=$a000" commands buried around in the code. It's a very popular assembler, though somewhat controversial because of its relative complexity compared to more straight-line 1|2-pass assemblers.

While it has a pretty powerful preprocessor, one thing that I like is a proper metaprogramming language instead of just macros. I believe the Kick Assembler from the c64 community has more of a programming language driving the preprocessing than just macro tags, but I'm not sure about that. Any of the Lisp-based assemblers certainly have full a programming language available to preprocess or generate source code at assemble-time.

_________________
WFDis Interactive 6502 Disassembler
AcheronVM: A Reconfigurable 16-bit Virtual CPU for the 6502 Microprocessor


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 22, 2017 1:57 am 
Offline
User avatar

Joined: Mon May 25, 2015 2:25 pm
Posts: 690
Location: Gillies, Ontario, Canada
Thanks for the comments.

Garth, "condensed" mode sound interesting. Is that like "code folding"? AMOS (Amiga) had something like that where you could "zip up" a subrouting so just the header remained until you click on it. I think I will add that to my IDE.

White Flame, yes that's the count so far, but it will increase as I add more features to the chipset. I am 70% full on the Spartan6, and do intend to move to an Artix, so by the time my FPGA is filled, I will probably have double that many.

I think doing the full featured OS and IDE is going to be the largest part of this project for me.
The GPU programming took only days, and I have most of the PCB and plastic injection case done already as well.

It's been a great project to build so far except for the one long night were my text routines kept failing until I realized I had one cold solder joint on an SRAM!

Brad


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 22, 2017 2:00 am 
Offline
User avatar

Joined: Mon May 25, 2015 2:25 pm
Posts: 690
Location: Gillies, Ontario, Canada
Anvil-6502 says "Hello World"...

Image
https://youtu.be/81eEv91NQCw

Cheers!
Radical Brad


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 22, 2017 3:34 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
Oneironaut wrote:
Thanks for the comments.

Garth, "condensed" mode sound interesting. Is that like "code folding"? AMOS (Amiga) had something like that where you could "zip up" a subrouting [subroutine?] so just the header remained until you click on it. I think I will add that to my IDE.

I have mostly global labels starting in column 1, but occasionally also the ; for comments that I want to show in condensed mode. In my MultiEdit professional programmers' text editor, <Alt>F4 puts it into condensed mode, then you scroll to find what you want, and click or press return on the desired line, and condensed mode is exited and you go back to normal mode with that line in the middle of the screen. The editor has a bazillion features (and so does the popular UltraEdit); but you asked about assemblers.

White Flame wrote:
I'm a big fan of ca65, which does the full segment/linker process of modern assemblers,

The 2500AD assembler I mentioned used a linker, but once we got through the difficulty of making it work at all, we put the necessary commands in a batch file and forgot about it. It was I and one other engineer working on the project, and before long, it was just me. I never really understood the linker, just re-used the batch file and modified the file names for each project. The linker seems to be more for when you have a lot of people working on one software project; but I have only worked alone on software projects, since 1988 or so. Neither the C32 assembler I mentioned above nor my MPASM PIC assembler use a linker. They just output Intel Hex (or Mot S19 or whatever format you want) directly. I do of course use INCLude files and the INCL assembler directive which may be in a section of conditional assembly and include the file only if the conditions call for it.

White flame alluded to a 2-pass assembler, which reminds me: I would recommend making it take as many passes as necessary to get rid of all the phase errors. I had a trick I did one time that worked nicely but took many passes to get rid of the phase errors. I can't remember anymore what it was, but I'm sure it involved macros, probably in some sort of doubly linked list. The PC was fast enough that the little extra time for the 33 passes or whatever I was up to was a minor price to pay for the benefit of this trick.

The YouTube video is impressive.

_________________
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: Thu Jun 22, 2017 4:02 am 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
I was going to mention MAC/65 from the Atari.

It's novelties were you entered assembly much like you did BASIC -- with line numbers, and it kept it's assembly lines tokenized internally to reduce the memory foot print. I don't know its internal format, but you can easily see the machine instruction itself being the internal token, with a flag byte to distinguish pseudo instructions and macros and such.

Something like:
Code:
10 LDA #10
0A 00 01 A9 01 0A // 0A 00 as line number, 01 instruction flag, A9, 6502 for LDA #, 01 decimal value, 0A for '10'
20 LOOP LDA LAB1
14 00 02 01 01 AD 02 02 // 14 00 as line number, 02 label flag, $01 label number, text stored in a table, 01 instruction flag, AD, LDA ABS, 02 label flag, this is label #2

Don't put a lot of weight in to that, just making it up as I go, but you can see how it can make assembly easier (parsing is done at code entry, most of the instructions are pre-assembled), and reduce the memory footprint of the source in RAM.

One thing Atari BASIC did (I think) was when a line had a syntax error, it stored it directly as text. Only after parsing was it tokenized.

So, you got nice pretty listings without paying for a bunch of white space and such in memory. It was designed to do most everything in memory, on a 48K machine.
Code:
0010        LDA    #10
0020 LOOP   LDA    LAB1

The line numbers were just that -- line numbers used for editing. Not for labels like in BASIC. You used normal assembler labels. They just made line entry and editing easier.

Saving the tokenized version reduced disk space as well.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 22, 2017 7:12 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
Might be worth looking also at BeebAsm which is a BBC Micro-centric structured assembler, or at BBC Basic itself which allows intermingling of assembler in Basic, with all the features of that Basic (flow control, procedures, local variables.)
Quote:
BeebAsm is a 6502 assembler designed specially for developing assembler programs for the BBC Micro. It uses syntax reminiscent of BBC BASIC's built-in assembler, and is able to output its object code directly into emulator-ready DFS disc images.

(BBC Basic for a given machine - 6502, Z80, ARM, x86 - embeds an assembler for the appropriate CPU. Today's version of BBC Basic is here.)


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 22, 2017 2:39 pm 
Offline
User avatar

Joined: Mon May 25, 2015 2:25 pm
Posts: 690
Location: Gillies, Ontario, Canada
Thanks for the input.

So far I have taken a bit of an odd approach to how my source code is stored in SRAM.
Every line is exactly 128 bytes stored as Color (Byte1), Character (Byte2).
As the IDE draws source lines, it just renders 64 colored characters per line.
Instructions are always black and upper case, and comments are green.

Since I have almost 4MB free for the source code, this works just fine.
This method also makes scrolling and parsing text extremely fast.

I have no idea how to write an assembler, so I am probably doing things in a strange way.
Right now, I just parse the entire 4MB of text and seek out known instructions.
At that point, I seek jump labels and turn them back into addresses.
It then looks for clues as to what type of addressing is done on each instruction that supports modes.

As the entire 4MB is parsed, the 64K "EXE Segment" is written to.
Once done, the OS banks the 6502 to the EXE Segment, and the program runs.
I don't understand what is meant by "passes", but perhaps my lack of knowledge may be helping at this point!

I guess it's just an "Assembly Interpreter"!

I have no error checking at all right now, and only a small number of instructions.
I just add instructions as I use them. My Ball Demo only uses maybe 10 different instructions in total!

I can't stand pseudo-ops, and will have nothing like that in my IDE. I am a purist all the way!
Development of the full OS will certainly be a long and fun journey.

Cheers,
Brad


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 22, 2017 5:19 pm 
Offline
User avatar

Joined: Mon May 25, 2015 2:25 pm
Posts: 690
Location: Gillies, Ontario, Canada
Ah.. "one pass", "two pass" summed up very nicely right here...

https://stackoverflow.com/questions/10244422/how-is-2-pass-assembler-different-from-one-pass-assembler-in-resolving-the-futur

Most likely, my assembler will be multi-pass, and I am not talking about this...

https://cdn1.lockerdomecdn.com/uploads/24c9efcee2f2c6e2bd685265fb6621590fb1ce0137465073b1f5b758f2d5ebad_large

But seriously, why would anyone even consider a single pass assembler??
It takes the 6502 in my system a few seconds at best to read the entire 4MB of source code!
I will probably have 3 or 4 passes. One for ops, one for addresses, one for equa, one for comment formatting, etc.

Did you see how fast the 6502 assembled my ball demo in the video? It was executing before my finger was off the F12 key.
I can't imagine my assembler taking more than a few seconds even for 32,000 lines of richly commented code to run.
Perhaps the argument for a single pass assembler would be more relevant if I was coding for a PDP-1 system?

Brad


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 22, 2017 6:02 pm 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
Oneironaut wrote:
But seriously, why would anyone even consider a single pass assembler??

Abundant computing resources solve many ills and make obsolete many old techniques. When "passes" equate to writing working sets to very slow storage, a single pass has a lot of value over a multi pass system.

More complicated assemblers and instruction sets provide a need for more passes to make things more efficient. The 6502 is pretty simple, and in fact much can be done in one pass, with a little bit of back patching at the end. The only real ambiguity in the 6502 is essentially something like this:
Quote:
LDA LABEL

If LABEL = $1234, you will assemble AD 34 12. But if LABEL = $12, you assemble A5 12.

If your code looks like this:
Quote:
LABEL = $1234
LDA LABEL

Then there's no ambiguity -- when it's time to assemble the instruction, the assembler knows everything it needs to know.

Contrast to:
Quote:
LDA LABEL
LABEL = $12

Now, the assembler does not have enough information. Even worse, the decision it makes affects everything else, since if it assembles zero page, then all of the following code will be offset 1 than if it assembled as absolute.

So, you can see that to resolve this properly, you need to actually go through and reassemble everything past this statement to take in to account the change in the instruction size.

Worse, consider something like this:
Quote:
LDA LABEL
LABEL = *

Now, the value that needs to be assembled for the LDA depends on the value that ends up being assembled! This is where you get things like phase errors, when assumptions the assembler makes on earlier passes don't hold true on later passes.

Now, practically, the ZP issue isn't really a big issue, and most folks define things first, at the top, and simply never encounter this. Other times, the assembler may just edict that if it can't decide between ZP or ABS when it sees the instruction, it simply punts to ABS, and back fills later. LDA $0012 still does the same work as LDA $12, it just performs differently. Still other may have syntax that allows the developer to force the assemblers hand. My assembler does the edict thing, if you want ZP, define it early for it.

Finally, this is just one case, on a simple processor. Other processors are far more complicated.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 22, 2017 8:59 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
Oneironaut wrote:
I can't stand pseudo-ops, and will have nothing like that in my IDE. I am a purist all the way!

I'm not sure what you think they are. BDD uses that term for what I think are the same a assembler directives, which are rather necessary. For example, in
Code:
        BYTE  "Print this", 0

BYTE is an assembler directive, telling it to lay down the following bytes as data. It's not a mnemonic of a 6502 instruction. Other common ones are EQU (for setting equates, or constants which will be returned when their label is invoked), ORG (for setting the address origin where the following code will start), IF...ENDI for conditional assembly, ones for designating space for a variable or array, etc.. There may be one telling which processor you're using (NMOS versus CMOS, or '816), one for turning the generation of list code off and on, one for sending assembly-time messages to the screen to give warnings or whatever, and there's the whole field of macros without which I might have mostly abandoned assembly language a long time ago.

Two passes is enough in most cases. The first one starts the assembly process but has to leave a lot of operands blank because it has not encountered them yet to have actual numbers for them, and it goes building the table in that pass. By the second pass, it has all the information it needs to finish the job.

_________________
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: Thu Jun 22, 2017 9:46 pm 
Offline
User avatar

Joined: Mon May 25, 2015 2:25 pm
Posts: 690
Location: Gillies, Ontario, Canada
What I meant by Pseudo-Ops are fake instructions that some assemblers allow as legal instructions.
For instance, when I was learning ARM assembly, I found out that LDR is a fake instruction that most except.
This made my life difficult for a while, when I was counting cycles for a video app. LDR is made up of several real ops.
The old Atmel assembler had some of these as well.

Note sure if any 6502 assemblers try to do this, but I certainly would never add such a "feature" to mine.
If I wanted to wake up the "monkey in the black box", I would just program in C!

Brad


GARTHWILSON wrote:
Oneironaut wrote:
I can't stand pseudo-ops, and will have nothing like that in my IDE. I am a purist all the way!

I'm not sure what you think they are. BDD uses that term for what I think are the same a assembler directives, which are rather necessary. For example, in
Code:
        BYTE  "Print this", 0

BYTE is an assembler directive, telling it to lay down the following bytes as data. It's not a mnemonic of a 6502 instruction. Other common ones are EQU (for setting equates, or constants which will be returned when their label is invoked), ORG (for setting the address origin where the following code will start), IF...ENDI for conditional assembly, ones for designating space for a variable or array, etc.. There may be one telling which processor you're using (NMOS versus CMOS, or '816), one for turning the generation of list code off and on, one for sending assembly-time messages to the screen to give warnings or whatever, and there's the whole field of macros without which I might have mostly abandoned assembly language a long time ago.

Two passes is enough in most cases. The first one starts the assembly process but has to leave a lot of operands blank because it has not encountered them yet to have actual numbers for them, and it goes building the table in that pass. By the second pass, it has all the information it needs to finish the job.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 22, 2017 10:45 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
That just sounds like macros then; but although I'm a macro junkie, I've never used a macro I myself didn't write. I know what's in each macro and exactly what code it will lay down, but I don't have to look at the internal details every time I use one, and it makes the source code a lot more concise, even though looking at the resulting machine code wouldn't tell you if macros were used or not.

A simple one might be like
Code:
        COPY2  FOOBAR1, TO, FOOBAR2

and you know it will do exactly
Code:
        LDA  FOOBAR1
        STA  FOOBAR2
        LDA  FOOBAR1+1
        STA  FOOBAR2+1

_________________
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: Thu Jun 22, 2017 10:49 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8504
Location: Midwestern USA
whartung wrote:
Oneironaut wrote:
But seriously, why would anyone even consider a single pass assembler??

More complicated assemblers and instruction sets provide a need for more passes to make things more efficient.

The need for multiple assembler passes comes from having to resolve forward references of any kind, and has nothing to do with the complexity of the MPU or its instruction set.

The type of forward reference that arises when a zero (direct) page location is declared after the instruction that references it is avoidable, as you note. That is also the case for symbolic declarations of constants. However, most forward references are due to instructions whose operands refer to a yet-to-be-defined location in the source code. Such forward references cannot be avoided and can only be resolved by an assembler that makes a minimum of two passes through the source code, one pass to build and resolve the symbol table, and the other pass to generate the object code. Assembler authors who claim that their assemblers build and resolve the symbol table, and generate the object code in one pass are being disingenuous, since an instruction early in the source file that has a location that is defined later in the source file cannot be assembled until that later definition has been entered into the symbol table.

Something that occasionally pops up in assemblers is the "phase error" that Garth mentioned earlier. A phase error occurs when the attempt to use a label or symbol during the second pass results in an instruction size that is inconsistent with what the assembler calculated during the first pass. Forward references in zero page declarations are a common source of phase errors. Such errors can usually be resolved by an assembler that makes three or more passes through the source code. However, extra passes would not be necessary if the source file is correctly structured.

GARTHWILSON wrote:
Oneironaut wrote:
I can't stand pseudo-ops, and will have nothing like that in my IDE. I am a purist all the way!

I'm not sure what you think they are. BDD uses that term for what I think are the same as assembler directives, which are rather necessary.

The term "pseudo-op" is short for "pseudo-operation," which is a synonym for "assembler directive." I can't recall where I first heard that term, but it's been in my computing vocabulary for at least 40 years.

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


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 83 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next

All times are UTC


Who is online

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