6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu May 23, 2024 5:39 am

All times are UTC




Post new topic Reply to topic  [ 47 posts ]  Go to page Previous  1, 2, 3, 4  Next
Author Message
 Post subject:
PostPosted: Mon Nov 23, 2009 7:34 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8442
Location: Southern California
Quote:
The one instruction per line style came about because that's how you have to do it on IBM punch-cards (IBM S/360s, at least at the time, relied on which column something appeared in to indicate its purpose. Labels in column 0, mnemonics in column 8, operands in column 16, etc.).

Ah yes, I had forgotten that. The first time I wrote an assembler was to learn Forth on the HP-71 20 years ago. I did the same thing just to make it easier (or so I thought at the time).

Quote:
Quote:
Macros leave you in complete control and there is absolutely zero penalty in runtime speed or memory.

Not necessarily. A macro may well end up expanding to 16 or more bytes or significantly high-level constructs. Liberal use of such a macro, then, can significantly impact speed and/or memory, especially if looping is implicit.

Ok, maybe I should have said "normally," or "in most cases." After I wrote the above I did think of times you might use a less-than-perfect macro just because you already have it and didn't want to write another. (I'm not 100% innocent myself.)

It's also always possible for certain conditions to escape the programmer's attention, for example that
Code:
      IF_<condition>
         actions1
      ELSE
         actions2
      END_IF
      RTS

is not as efficient as
Code:
      IF_<condition>
         actions1
         RTS
      END_IF
      actions2    ; (the "else" code)
      RTS

because the branch put in by ELSE takes more time and memory than the extra RTS; or that a big CASE structure might not be nearly as efficient as a look-up table of execute addresses. The examples I gave were mostly just to get rid of gobs of labels and hide the jumps though, arriving at the very same output but from a more-readable source code. Obviously you need to know what's in your macros.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Nov 23, 2009 7:42 am 
Offline
User avatar

Joined: Tue Mar 02, 2004 8:55 am
Posts: 996
Location: Berkshire, UK
BigDumbDinosaur wrote:
BitWise wrote:
BigDumbDinosaur wrote:
I would not undertake this project at all if good, native-mode '816 assemblers that don't need work or are unnecessarily expensive (e.g, WDC's ProSDK) were available.

My assembler supports 6502, 65C02, 65816 and 65832. Its free and all you need is a Java runtime environment to run it. The same Java class zip should work on both Windows and Linux.

Might be worth trying before you start building.

You download link appears to be broken.

Works fine for me.

http://www.obelisk.demon.co.uk/6502/6502.zip

_________________
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Nov 24, 2009 6:08 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8191
Location: Midwestern USA
BitWise wrote:
My assembler supports 6502, 65C02, 65816 and 65832. Its free and all you need is a Java runtime environment to run it. The same Java class zip should work on both Windows and Linux.

Might be worth trying before you start building.
Quote:
Your download link appears to be broken.

Works fine for me.

http://www.obelisk.demon.co.uk/6502/6502.zip

Oh...I went to your site (www.obelisk.demon.co.uk), followed the links and that was where things broke. That is a different link. :)

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


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 24, 2009 6:09 am 
Offline

Joined: Sun Nov 08, 2009 1:56 am
Posts: 388
Location: Minnesota
GARTHWILSON wrote:

One thing I would really like that I have not seen in an assembler so far is to go beyond assembler variables (like EQUates that can be reassigned as many times as you want, which is nothing new), and also have assembler arrays and the ability to use a variable as a pointer into an array. What I would like to do with them is to make one or more stacks in the assembler so I can make assembly program structures in macros, without having to make sure assembler variables used by one structure don't step on those used by other ones that are nested.


The development version of the assembler I play with as a hobby doesn't have this specific ability, but it's possible to implement something like it by splicing and dicing strings. For the 6502 an IF..ENDIF might look like this:

Code:

     .macro IF_EQ
label_ctr = label_ctr + 1
]target$ = "_IF" str$(label_ctr)
]stack$ = ]stack$ ]target$
     .putbacks "bne " ]target$
    .endm

    .macro END_IF
]ndx = rindex(]stack$, "_IF")
    .putback mid$(]stack$, ]ndx)
]stack$ = mid$(]stack$, 1, ]ndx-1)
   .endm


The first macro creates, saves and uses a target label. The second retrieves, uses and discards that same label.

"putbacks" is a pseudo op that evaluates its argument as a string expression and then pushes the result back onto the input stream, so it becomes the next line the assembler sees. I implemented it specifically for the purpose of creating macros like these.

Because arbitrary string expressions are allowed it's possible to do this:

Code:
this$ = ".putbacks this$"
    .putbacks this$


but that loops only so many times before the assembler says "enough!" :)

I've created demo nesting IF..ELSE..ENDIF and WHILE..ENDWHILE "high-level structures" using macros like these. They can be pushed farther, though I'm not sure exactly how far.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Nov 24, 2009 6:23 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8191
Location: Midwestern USA
BitWise wrote:
BigDumbDinosaur wrote:
I would not undertake this project at all if good, native-mode '816 assemblers that don't need work or are unnecessarily expensive (e.g, WDC's ProSDK) were available.

My assembler supports 6502, 65C02, 65816 and 65832. Its free and all you need is a Java runtime environment to run it. The same Java class zip should work on both Windows and Linux.

Might be worth trying before you start building.

I took a look but didn't see everything I wanted. There's no obvious way to assemble tables that will work with "push/push/rts" program routing, reference the program counter or advance the program counter without generating code. Also, I may have missed it as I read the documentation, but I don't see an obvious way to have the assembler directly output to a Motorola S-record. Having to use a linker just to produce a simple program seems like an unnecessary extra step.

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


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Nov 24, 2009 7:39 am 
Offline
User avatar

Joined: Tue Mar 02, 2004 8:55 am
Posts: 996
Location: Berkshire, UK
BigDumbDinosaur wrote:
BitWise wrote:
BigDumbDinosaur wrote:
I would not undertake this project at all if good, native-mode '816 assemblers that don't need work or are unnecessarily expensive (e.g, WDC's ProSDK) were available.

My assembler supports 6502, 65C02, 65816 and 65832. Its free and all you need is a Java runtime environment to run it. The same Java class zip should work on both Windows and Linux.

Might be worth trying before you start building.

I took a look but didn't see everything I wanted. There's no obvious way to assemble tables that will work with "push/push/rts" program routing, reference the program counter or advance the program counter without generating code. Also, I may have missed it as I read the documentation, but I don't see an obvious way to have the assembler directly output to a Motorola S-record. Having to use a linker just to produce a simple program seems like an unnecessary extra step.

The assembler has .WORD and .BYTE directives to create data tables. Which you use depends on whether you want the address high and low bytes together or in separate tables.
Code:
FuncTable:
 .WORD Func1-1
 .WORD Func2-1

FuncHiTable:
 .BYTE HI (Func1-1)
 .BYTE HI (Func2-1)

FuncLoTable:
 .BYTE LO (Func1-1)
 .BYTE LO (Func2-1)


The program counter is referenced by a $ in an expression.
Code:
 BCC $+2


The directive .SPACE increase the program counter. Change the origin will work in absolute mode - will have to check relative mode.
Code:
SomeVar .SPACE 10

 
 NOP
 .ORG $+10
 NOP


You have to link to generate S19 but it only takes a split second and you can always create a make file for your project to automatically link after assembling.

_________________
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Nov 24, 2009 4:51 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8191
Location: Midwestern USA
BitWise wrote:
The assembler has .WORD and .BYTE directives to create data tables. Which you use depends on whether you want the address high and low bytes together or in separate tables.

The directive that is missing is .DBYTE <address>, which assembles <address> in big-endian order, producing a look-up table suitable for "push/push/rts" coding. .WORD assembles <address> in little-endian order.

Quote:
The program counter is referenced by a $ in an expression.

Code:
 BCC $+2

Completely non-standard. Using your assembler would mean editing many source files in which the directive *=*+n is used. Why deviate from the MOS Technology (and WDC) standards that were published years ago and used in all commercially developed assemblers? I don't mean to be critical, but the above are why I decided to create my own assembler, one that would be 100 percent MOS syntax compatible.

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


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Nov 24, 2009 6:25 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8442
Location: Southern California
Quote:
Completely non-standard. Using your assembler would mean editing many source files in which the directive *=*+n is used.

The $ is the only one I've ever heard of for this; so whether it's original or not, it seems standard to me. Is there an advantage to "*=*" other than that someone used it long ago? A text editor's search-and-replace feature would make very quick work of changing the source code over.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Nov 24, 2009 6:52 pm 
Offline
User avatar

Joined: Tue Mar 02, 2004 8:55 am
Posts: 996
Location: Berkshire, UK
I've seen *, $, ., and @ used in various 6502 assemblers over the years to represent the origin.

Thanks for bringing the .DBYTE directive to my attention. I'll add it to my implementation.

If BigDumbDinosaur is actually using the operating system his signature suggests he does then he has a complete arsenal of text processing tools at finger tips that can rearrange his code. 'sed' would make light work of replacing most of them.

_________________
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Nov 24, 2009 7:29 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8442
Location: Southern California
teamtempest, you got me excited for a minute, but I re-read my assembler's manual again (which I haven't looked at in a long time) and it just doesn't give any way to do that. I might still try to do the structure macros with variables (instead of a stack), although it won't be as neat, requiring a macro parameter, as well as care to avoid using the same variables for two or more nested structures.


and BitWise:
Quote:
I've seen *, $, .,

Ah yes, I forgot about the * .


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Nov 24, 2009 8:05 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10802
Location: England
Looking through the 6502 gcc posted on the other thread, I notice an interesting assembler feature mentioned:

Quote:
GCC02 outputs all conditional branches of the 6502 form Bcc as Jcc
instructions. The assembler is responsible for optimizing these to either a
single branch instruction or as a branch of the opposite condition over a
jump instruction.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Nov 25, 2009 6:00 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8191
Location: Midwestern USA
BitWise wrote:
I've seen *, $, ., and @ used in various 6502 assemblers over the years to represent the origin.

Thanks for bringing the .DBYTE directive to my attention. I'll add it to my implementation.

If BigDumbDinosaur is actually using the operating system his signature suggests he does then he has a complete arsenal of text processing tools at finger tips that can rearrange his code. 'sed' would make light work of replacing most of them.

As would awk and a few others. I do all my development on Linux (a dual Opteron box, no less). However, the idea is to not have to make wholesale source code edits to conform to non-standard assembler syntax.

BTW, the use of * to reference the program counter has existed since before the invention of the microprocessor. I recall seeing it in IBM 7094 assembly language programs in the 1960s (despite the availability of several high level language compilers, a surprising amount of assembly language was written for that machine).

The *=*+n idiom I can recall from the earliest 6502 assemblers. In fact, in Lance Leventhal's first edition of 6502 Assembly Language Programming, that device is illustrated. Commodore's MADS, which was a C64 implementation of the MOS Technology reference assembler from the late 1970s, used * to reference the program counter and *=*+n to advance it (*=*-n would cause an error, IICR). DevPak for the C-128 did likewise. WDC, whose founder was one of the architects of the original 6502 and one of the two authors of the assembly language syntax and mnemonics, also uses * as the program counter definition in their recommended assembler syntax and in their ProSDK.

Use of $ or @ to refer to the program counter gives rise to a potential ambiguity. In a standardized 6502 development environment, those symbols are used to represent base-16 and base-8 radices, respectively. * has no such meaning and thus can't be misunderstood as a radix. Why create an inherent interpretation conflict by deviating from an accepted standard?

My point to this diatribe is there is a long history behind the syntax found in compliant 65xx assemblers. As soon as one decides to deviate from the accepted standards, either because one wishes to be different, or because one isn't fully conversant with them, one succeeds in writing something that people like me who have been in this literally for decades aren't interested in using.

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


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Nov 25, 2009 2:14 pm 
Offline
User avatar

Joined: Tue Mar 02, 2004 8:55 am
Posts: 996
Location: Berkshire, UK
A couple of small tweaks and ...
Code:
Portable 65xx Assembler - V1.4 (2009-11-24)

                            ; A test for the Portable assembler with MOS compatibility
                           
        00000400          = BEGIN   =$0400
        000000FF          = STKBEG  =$FF
        00000000          = TEMP    =0
                           
                                            *=TEMP
000000                    : DCTR    *=*+2
000002                    : KEYNO   *=*+2
000004                    : NKEYS   *=*+1
                           
        0000A000          = VIAORB  =$A000
        0000A001          = VIAORA  =$A001
        0000A002          = VIAADDRB=$A002
        0000A003          = VIAADDRA=$A003
                           
        00000040          = DECPT   =%01000000
        000000FF          = ECODE   =$FF
                           
        0000000B          = GOKEY   =11
        0000000B          = KLAST   =11
                           
                                            *=$FFFC
                                           
00FFFC  0004              :                 .WORD   BEGIN
                                           
                                            *=BEGIN
                           
000400  A900              :                 LDA #0
000402  8D03A0            :                 STA VIAADDRA
000405  9A                :                 TXS
                           
                           
000406  9000              :                 BCC     *+2
                           
000408  0400              :                 .DBYTE  BEGIN
                                           
                                            .END

_________________
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Nov 25, 2009 4:15 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
GARTHWILSON wrote:
The $ is the only one I've ever heard of for this; so whether it's original or not, it seems standard to me. Is there an advantage to "*=*" other than that someone used it long ago? A text editor's search-and-replace feature would make very quick work of changing the source code over.


I have to concur with BDD here; I've only seen $ used once, and this was for a Commodore 128 assembler which included support for the Z-80. Note that $ is used as the current location pseudovariable on all 8080, Z-80, and 8085 assemblers. (It's not used much, if at all, on 8086 and later assemblers, due to the inherent relocatability of segments.) They chose $ over * to allow the use of the current location to be used in expressions containing multiplication. Intel hex notation (e.g., 0DEADBEEFH versus $DEADBEEF) was born of necessity here.

Note that using $ for the current location pseudovariable effectively precludes its use from identifying hexadecimal constants. While a sufficiently complicated parser can be made to detect isolated $ characters from prefix $ operators (absolutely requiring at least an LL-parser to do this), it opens up such errors as $1 being syntactically valid when you meant to type $+1. This is an amazingly common error to make on keyboards scanned at 60Hz (e.g., the C64's keyboard) if you're a fast typer like I am.

BDD, you're right that *=*-N was an error, primarily because MADS processed source listings sequentially, and wrote out blocks of code using sequential or PRG files (I forgot if it supported tape output, not ever having used a datasette with my C64). These files lacked random-access seek capability, so going backwards in the binary image was effectively forbidden by the DOS. The assembler design reflects this.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Nov 25, 2009 5:53 pm 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 995
Location: near Heidelberg, Germany
I think this:

BitWise wrote:
Code:

        00000400          = BEGIN   =$0400
...
                                            *=$FFFC
                                           
00FFFC  0004              :                 .WORD   BEGIN
                                           
                                            *=BEGIN


will only work for in-memory assemblers, as you jump backward in address space. Or what is the semantics when you write out the assembled result into a file?

André


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

All times are UTC


Who is online

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