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

All times are UTC




Post new topic Reply to topic  [ 11 posts ] 
Author Message
 Post subject: High level macros
PostPosted: Sat Sep 14, 2013 3:33 pm 
Offline

Joined: Fri Nov 09, 2012 6:52 am
Posts: 16
Hi,

I'd like to let everyone here know about the macros I have been working on for high-level like coding with the 6502. My target is NES, so no 65c02 or better features are targeted. Maybe in the future they will be.

I've been working on and using these macros for some time. I use them often and they have been somewhat tested by others. Anyone who already uses ca65 will have no trouble giving them a try as only two files are needed and only one file needs to be included in your source module:
Code:
.include "ca65hl.h"


There is no library code and no memory used. The syntax is quite flexible, and logical structures can of course be nested as much as you would like. You can also create your own custom macros to work with the logical conditions, which act like boolean functions. The resulting code can look very high-level, but still maintains an almost 1:1 relationship to the underlying assembly in almost every case.

The only possible downside is that for very large projects it can be slow to build, but if you are utilizing that fact that ca65 has a linker, your code can (in my opinion, should) be separated into modules, which will eliminate this issue.

I am currently working on some sample code, and updating the wiki: https://www.assembla.com/spaces/ca65hl/wiki

Thanks!


Top
 Profile  
Reply with quote  
 Post subject: Re: High level macros
PostPosted: Sat Sep 14, 2013 6:49 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
I'm glad to see the interest in this growing! You're the fourth one here so far (that I know of) to be doing this-- or maybe third, since BitWise's aren't macros. He built the capability into his assembler so in that respect it's partly a compiler, not just an assembler; but the end result is the same. It also chooses which instructions to use based on whether a branch distance is outside the -128 to +127 range (which would be a really big program structure, but it can happen, especially with a CASE statement).

_________________
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  
 Post subject: Re: High level macros
PostPosted: Sat Sep 14, 2013 8:17 pm 
Offline
User avatar

Joined: Sat Sep 29, 2012 10:15 pm
Posts: 904
assemblia.com link is not working!

_________________
In theory, there is no difference between theory and practice. In practice, there is. ...Jan van de Snepscheut


Top
 Profile  
Reply with quote  
 Post subject: Re: High level macros
PostPosted: Sat Sep 14, 2013 8:21 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
It works for me. Maybe it was down briefly?

_________________
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  
 Post subject: Re: High level macros
PostPosted: Sat Sep 14, 2013 8:45 pm 
Offline

Joined: Fri Nov 09, 2012 6:52 am
Posts: 16
GARTHWILSON wrote:
I'm glad to see the interest in this growing!

:)
Quote:
It also chooses which instructions to use based on whether a branch distance is outside the -128 to +127 range (which would be a really big program structure, but it can happen, especially with a CASE statement).

ca65 will stop with an error if a branch is too far, at which time the user can add the macro directive setLongBranch + before the offending statement to invert all branch logic and use absolute jmp instructions. I plan to finish implementing a warning when you have a long branch where it is not needed, but that is not properly implemented at the moment.

Unfortunately (in this case), ca65 is a one pass assembler, and can't figure out if a branch is too far until it is too late to fix automatically with macro code.

I haven't really looked at adding a CASE, but I've looked at adding FOR, but am hesitant due to wanting to stick to a C like syntax, and the C FOR loop being more like a while <> do, meaning an inefficient jmp back to the top of the while to test the condition on the last iteration. I guess a FOR loop doesn't have to stick to that structure though.


Top
 Profile  
Reply with quote  
 Post subject: Re: High level macros
PostPosted: Sat Sep 14, 2013 10:20 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
Quote:
I haven't really looked at adding a CASE, but I've looked at adding FOR, but am hesitant due to wanting to stick to a C like syntax, and the C FOR loop being more like a while <> do, meaning an inefficient jmp back to the top of the while to test the condition on the last iteration. I guess a FOR loop doesn't have to stick to that structure though.

I modeled my structures mosly after Forth's standard ones (I say "standard" because Forth lets you make your own, in fact you can even define your own operators in Forth) but I figured BASIC's FOR...NEXT kind of syntax would be more readily accepted than Forth's simple but unusual DO...LOOP sytax (if you can even call it syntax, as Forth hardly has any syntax) by non-Forth-speaking people. In DO...LOOP, the internal compiled by DO only runs once, at the beginning of the loop, to prepare the stack, and then the internal compiled by LOOP (at the end of the loop) is what determines whether to go back to the top or not, similar to assembly language. The FOR...NEXT macros assemble the same thing you would do by hand, with for example:
Code:
    FOR_X 8, DOWN_TO, 0
        <loop contents>
        <actions, actions>
        <yada yada>
    NEXT_X

which assembles:
Code:
        LDX  #8
TOP:        <loop contents>
            <actions, actions>
            <yada yada>
        DEX
        BNE  TOP

The loop does not get run for the counter value equal to 0 like it would in BASIC, but it's a better transfer to/from assembly where we're subconsciously thinking of the DEX BNE here.

There are so many possible ways to do a FOR...LOOP in assembly thought that I originally thought it would not be feasible, so FOR...NEXT was added a long time after I did the others, and the FOR...NEXT macros are very long for the little code they lay down (which is usually only two or three bytes), because of the many options the macros have to sort out to decide what code to lay down.

I consider the CASE statement to be very valuable, but I have never run into a situation where I've had to nest CASE statements. CASE and my 16-bit FOR...NEXT (which is separate from FOR_X|FOR_Y...NEXT_X|NEXT_Y which are always 8-bit for 6502) are the only ones I have not made nestable.

_________________
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  
 Post subject: Re: High level macros
PostPosted: Mon Oct 14, 2013 4:03 pm 
Offline

Joined: Fri Nov 09, 2012 6:52 am
Posts: 16
My macros now feature support for parentheses in expressions! Although I am confident everything is working I would consider this untested, beta code.

https://www.assembla.com/code/ca65hl/git/nodes/devel

Following the same rules as the previous version, you can test 'expressions' that represent or result in a CPU flag being set/clear and branch appropriately. The latest code allows parentheses to create more complex logical conditions, as well as a negate operator that can distribute across parenthesis. The code generated aims to be efficient and will short circuit as soon as the outcome can be determined.

The only limitation is that all OR logic must be before all AND logic in the same parentheses set. ( Add parentheses to work around this.)

Some poor nonsensical examples:

Code:
 ; branch to label:
    * = 8000
   
    foo = $00
    bar = $01
    baz = $03
    myLabel = * + $50
   
    if ( ( foo >= #$03 && ! bar ) || ((zero && negative) || baz = #1)) goto myLabel

    ; code output:   
    8000   A5 00      LDA $00
    8002   C9 03      CMP #$03
    8004   90 04      BCC $800A
    8006   A5 01      LDA $01
    8008   F0 46      BEQ $8050
    800A   D0 02      BNE $800E
    800C   30 42      BMI $8050
    800E   A5 03      LDA $03
    8010   C9 01      CMP #$01
    8012   F0 3C      BEQ $8050

; if-endif ( else supported )

    * = 8000   
   
    foo = $00
    bar = $01
    baz = $03
   
    if (  !( bar & #$03 && baz == N set ) || (( V set || baz < #$10 ) || foo = #1) )
        nop
    endif

    ; code output:
    8000   A5 01      LDA $01
    8002   29 03      AND #$03
    8004   F0 12      BEQ $8018
    8006   A5 03      LDA $03
    8008   10 0E      BPL $8018
    800A   70 0C      BVS $8018
    800C   A5 03      LDA $03
    800E   C9 10      CMP #$10
    8010   90 06      BCC $8018
    8012   A5 00      LDA $00
    8014   C9 01      CMP #$01
    8016   D0 01      BNE $8019
    8018   EA         NOP
    8019


Top
 Profile  
Reply with quote  
 Post subject: Re: High level macros
PostPosted: Wed Oct 16, 2013 4:51 pm 
Offline

Joined: Fri Nov 09, 2012 6:52 am
Posts: 16
Implemented FOR; devel branch on assembla will be updated in the next few days.

http://i.imgur.com/KkUbyEA.png


Top
 Profile  
Reply with quote  
 Post subject: Re: High level macros
PostPosted: Wed Oct 16, 2013 6:44 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
with step size too. I didn't get that far on mine.

_________________
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  
 Post subject: Re: High level macros
PostPosted: Wed Oct 23, 2013 2:20 am 
Offline

Joined: Fri Nov 09, 2012 6:52 am
Posts: 16
FOR added to the devel branch: https://www.assembla.com/code/ca65hl/git/nodes/devel

I changed how it works from the first example I posted.

1)C-style of loop:
for ( <thing to do 1st>, <Flag to test - continue while true >, <stuff to do at end of loop> )

Example:

Code:
for ( x := #$3, not negative, dex )
; code
next

; more complex:

for ( x := foo, (x > #10) && (foo <> #1), dex:dex)
    ; some code
next



2) BASIC-style syntax:

This actually tries to optimize some, and will break if you mess with your counter register or variable without thinking:

Code:
for x := #$AA to #$10 step -3
    ;some code
next


It will loop until your counter hits the first invalid (for the loop) value. If possible it will skip CMP and use BPL/BMI or a lone BNE. 'step' can be omitted and a step of -1 or 1 decided on if possible. You can use variables rather than immediate values, but no optimizations are possible.


Top
 Profile  
Reply with quote  
 Post subject: Re: High level macros
PostPosted: Mon Nov 04, 2013 5:18 pm 
Offline

Joined: Fri Nov 09, 2012 6:52 am
Posts: 16
Hi,

It may need some polish, but I updated the documentation on the wiki for ca65hl:

https://www.assembla.com/spaces/ca65hl/wiki


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 11 posts ] 

All times are UTC


Who is online

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