It is currently Sat Nov 18, 2017 3:27 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 57 posts ]  Go to page 1, 2, 3, 4  Next
Author Message
 Post subject: IF macro for ca65
PostPosted: Mon Sep 03, 2012 1:38 am 
Offline
User avatar

Joined: Sun Jan 02, 2011 11:50 am
Posts: 522
I like NESHLA but it's too limiting, and so I moved on to ca65 for various reasons. The things I liked about NESHLA I figured I could do without or get close enough to the same functionality with macros. I decided to recreate the if functionality with macros and I think it is working well. If anyone is interested I'll post the code up somewhere. What I am able to do is stuff like:

Code:

if {carry set}
   ; do code
endif

;or

if {equal}
 ; blah blah
endif

if {less}
 ; blah blah
endif



It should work with any number of nested ifs and should be easy enough to add your own keywords.


Top
 Profile  
 
 Post subject: Re: IF macro for ca65
PostPosted: Mon Sep 03, 2012 7:08 am 
Offline
User avatar

Joined: Thu Jan 19, 2006 5:08 pm
Posts: 746
Location: Shelton, Washington.
Look at a 6502 manual, There are opcodes for specific operations like this!

They are Branching Instrucions!

EDIT:

IF Carry Set = BCS
IF Equal = BEQ
IF Less = BMI(?)

_________________
AKA SmilyMZX/AtariHacker.


Top
 Profile  
 
 Post subject: Re: IF macro for ca65
PostPosted: Mon Sep 03, 2012 7:58 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10112
Location: Rio de Janeiro - Brazil
I'm sure he knows that Hamtaro, since he made the macros and all (and the macros do translate to branch instructions when assembled). Assembly typically lacks indentation and logical blocks, so it's understandable that some people prefer to use macros to make things a little bit less low-level.


Top
 Profile  
 
 Post subject: Re: IF macro for ca65
PostPosted: Mon Sep 03, 2012 8:38 am 
Offline
User avatar

Joined: Sun Jan 02, 2011 11:50 am
Posts: 522
Hamtaro126 wrote:

IF Carry Set = BCS
IF Equal = BEQ
IF Less = BMI(?)


The macro would actually change carry set to BCC and equal to BNE since I want to enter the block of code if the flag is set.
In normal 6502 assembly Less is BCC, greater or equal is BCS (after a CMP instruction). That is how I implement it in the macro at least - NESHLA used the N flag >:(


Top
 Profile  
 
 Post subject: Re: IF macro for ca65
PostPosted: Mon Sep 03, 2012 9:46 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10112
Location: Rio de Janeiro - Brazil
Movax12 wrote:
NESHLA used the N flag >:(

Which is OK if you're dealing with signed numbers. The carry flag can be used for unsigned comparisons, while N and V should be used for signed numbers.


Top
 Profile  
 
 Post subject: Re: IF macro for ca65
PostPosted: Mon Sep 03, 2012 10:53 am 
Offline
User avatar

Joined: Sun Jan 02, 2011 11:50 am
Posts: 522
I think my brain would think about that better in terms of "is the result negative or not?" rather than less or greater, but I see your point.

So far I have:

Code:
; carry set
; carry clear
; no carry
; not carry
; C
; not C
; C set
; C clear
; less
; not less
; greater_equal
; not greater_equal
; zero
; zero clear
; zero set
; not zero
; equal
; not equal
; Z
; not Z
; Z set
; Z clear
; plus
; not plus
; positive
; not positive
; minus
; negative
; not minus
; not negative
; N
; not N
; N set
; N clear
; bit7
; bit7 set
; bit7 clear
; not bit7
; V
; overflow
; overflow set
; overflow clear
; not overflow
; V
; V set
; V clear
; not V
; bit6
; bit6 clear
; bit6 set
; not bit6


I'm not sure if I am implementing the macro as well as possible, but as long as I stick to the above formats I'm certain it will work. The code is here: http://sharetext.org/dDge


Top
 Profile  
 
 Post subject: Re: IF macro for ca65
PostPosted: Mon Sep 03, 2012 11:18 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19222
Location: NE Indiana, USA (NTSC)
tokumaru wrote:
The carry flag can be used for unsigned comparisons, while N and V should be used for signed numbers.

Is there a standard test on 6502 for whether unsigned + signed (e.g. position + change) has overflowed unsigned?

Would it be hard to make macros for greater, not greater, less_equal, not less_equal, that use a branch on Z that jumps over a branch on C?

Would "else" be hard?


Top
 Profile  
 
 Post subject: Re: IF macro for ca65
PostPosted: Mon Sep 03, 2012 11:25 am 
Offline
User avatar

Joined: Sun Jan 02, 2011 11:50 am
Posts: 522
tepples wrote:
Would it be hard to make macros for greater, not greater, less_equal, not less_equal, that use a branch on Z that jumps over a branch on C?


Not hard at all. It also wouldn't be hard to implement do-while loops, or repeat-until.

Quote:
Would "else" be hard?


I briefly thought about that, it might not be too hard.. I'll think about it.


Top
 Profile  
 
 Post subject: Re: IF macro for ca65
PostPosted: Tue Sep 04, 2012 12:00 am 
Offline
User avatar

Joined: Sun Jan 02, 2011 11:50 am
Posts: 522
So I was implementing ELSE and I realized that trying to track IF/ENDIF pairs with numbers and math doesn't work. It may work most of the time, but it doesn't work all the time. The only proper way to do it is a stack, and actually it's much easier.

So ELSE is working and IF / ENDIF should be 100% reliable as far as matching up the code blocks properly.

http://shorttext.com/f3qe4k


Top
 Profile  
 
 Post subject: Re: IF macro for ca65
PostPosted: Tue Sep 04, 2012 9:05 am 
Offline
User avatar

Joined: Sun Jan 02, 2011 11:50 am
Posts: 522
I added greater and not greater. I also made some the flag checks more restrictive, like a flag name (Z for example) has to be followed by 'set' or 'clear'. I may add a do while loop and get back to actually coding some 6502. If anyone uses this and needs the code to be relocatable, change the jmp in the else macro to clv/bvc.

http://pastebin.com/PKjw89u8
EDIT: small changes: http://pastebin.com/Hvfr4EQh


Top
 Profile  
 
 Post subject: Re: IF macro for ca65
PostPosted: Thu Sep 06, 2012 1:40 am 
Offline
User avatar

Joined: Sun Jan 02, 2011 11:50 am
Posts: 522
I've polished this up quite a bit, there is some information here: http://mynesdev.blogspot.ca/2012/09/ca6 ... acros.html

The expression evaluation code has gone from a huge pile of .IFs down to this:

Code:
.macro process_expression_FLAGS flagtest, flag, flagisset

; Find a value for which flag we are checking and return:
   
   _n_ .set  (  (.xmatch(.left(1, {flagtest}) , no)) .or (.xmatch(.left(1, {flagtest}) , not))  ) ; not or no prefix
   
   flag .set (.xmatch(.mid(_n_,1, {flagtest}) , C)) * 1 + (.xmatch(.mid(_n_,1, {flagtest}) , Z)) * 2 + (.xmatch(.mid(_n_,1,{flagtest}) , N)) * 3 + (.xmatch(.mid(_n_,1,{flagtest}) , V)) * 4 + (.xmatch(.mid(_n_,1,{flagtest}) , G)) * 5
   
   flag_set_default .set (.xmatch(.mid(_n_+1,1, {flagtest}), set)) * 1 + (.xmatch(.mid(_n_+1,1, {flagtest}), clear)) *  -1

   .ifnblank .mid(_n_+2,1, {flagtest}) ; user added clear or set, also accept 'do' from "while <exp> do" syntax
      invert_flag          .set .xmatch(.mid(_n_+2,1, {flagtest}), clear) *  -1  + .xmatch(.mid(_n_+2,1, {flagtest}), set) * 1 + .xmatch(.mid(_n_+2,1, {flagtest}), do) * 1
   .else
      invert_flag          .set 1 ; no clear or set added, that's okay make it a 1
   .endif
   invert_flag             .set invert_flag * (_n_ * -2 + 1)
   
   .if ( (flag = 0) .or (flag_set_default = 0) .or (invert_flag =0))
      .error "Unknow expression in flag test."
      .fatal ""
   .endif
   
    flagisset .set ((flag_set_default * invert_flag) > 0) ; This will always result in a negative or positive, positive being flag is being tested for
   
.endmacro


It's working well I think, I'll publish all the code soon.

Updated! I am done for now - I'm going to try to actually use it in code. Any feedback welcomed. Code is available at the blog link I posted.


Top
 Profile  
 
 Post subject: Re: IF macro for ca65
PostPosted: Thu Sep 27, 2012 2:12 pm 
Offline

Joined: Wed Mar 09, 2005 9:08 am
Posts: 348
I'm trying out your macro package, and it seems it can't handle local labels within the conditions like in the following snippet:

Code:
    cmp #JOY_A
    if equal
        jmp @Freeze
    endif

    cmp #JOY_B
    if equal
        jmp @Melt
    endif
    lda #0
    rts


Removing the '@' from my label names works fine. While I realize that your macros are supposed to reduce the need for local labels, it would be nice if it didn't disable their usage in this way. Do you think it would be possible to make your macro package support this?...


Top
 Profile  
 
 Post subject: Re: IF macro for ca65
PostPosted: Thu Sep 27, 2012 2:51 pm 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2981
Location: Tampere, Finland
Bananmos wrote:
Do you think it would be possible to make your macro package support this?...

As far as I know, it's not possible. The macros need to generate labels, and they'll always mess with the local (@) labels. I thought it might be possible to fix this by generating the label inside a scope, but looks like the @ labels don't care about scopes, so they'll get invalidated when any normal label comes. Then I thought it might be possible to generate the label using "foo = *" or "foo := *", but that also invalidates the local labels. As does "foo .set 123". That's all the possible workarounds I can think of...

P.S. Movax, why are you using .error followed by .fatal "", and not only .fatal?

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
 Post subject: Re: IF macro for ca65
PostPosted: Thu Sep 27, 2012 7:15 pm 
Offline
User avatar

Joined: Sun Jan 02, 2011 11:50 am
Posts: 522
.error outputs a line number with the string.
.fatal stops the assembly, but doesn't give a line number.

There are some minor issues with this too, but the worst error is if the branch is too far, ca65 won't tell you were the problem is in the main code, just in the macro. The branch generation could be changed to always use a jmp with a branch over and I've added an option to do that which isn't too complicated if anyone wants. It's too bad there is no way to decide if the branch is long or not in the macro code.

I don't see a way to use cheap local labels due to the generation of normal labels from the if macro(s)


Top
 Profile  
 
PostPosted: Fri Sep 28, 2012 5:03 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19222
Location: NE Indiana, USA (NTSC)
Is there a reason why you're not using macro-local labels?

I also have a bit of a problem with the Creative Commons license, which isn't really meant for code. One of the technicalities making it incompatible with some other licenses is the provision for requiring downstream users to remove credits. I'd have gone with this one.


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 3 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:  
Powered by phpBB® Forum Software © phpBB Group