It is currently Tue Sep 19, 2017 12:03 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 34 posts ]  Go to page Previous  1, 2, 3
Author Message
PostPosted: Tue Jul 25, 2017 7:01 am 
Offline
Formerly WheelInventor

Joined: Thu Apr 14, 2016 2:55 am
Posts: 852
Location: Gothenburg, Sweden
At lunch, i was trying to think of a solution that would automatically identify if a #stz is to be laid down directly after another, but i'm not familiar with TASS64 and not aware of a ca65 directive that'd be helpful.

Less elegantly, you could of course do it like this:

.macro name addr, anyArg
.ifp02 ;this is ca65:s check if target is 6502
.ifblank (anyArg) ;omitting anyArg is considered normal operation.
lda #0
sta addr
.else ;this is for saving cycles/bytes on the 6502 specifically
sta addr
.endif
.endif
[other processors go here, treat as normal]
.endm

call it like this:
name addr ; lays down lda + sta on 6502, stz on 65816
name addr foo ;lays down just sta on 6502, stz on 65816
name addr foo ;same

Rather than requiring a special value of anyArg, just having one there will tell the assembler to optimize the output for 6502 targets. It will behave, but requires you to know how to interface with the "optimization option", which will require proper commenting in return.


Alternately, you could make a call like this:

name addr1, addr2, addr3 (and so on)

And have a macro which will know how many iterations to run by the number of arguments, and lay down the proper opcodes for you automatically. That's better, but with the caveat that you have a maximum of iterations/arguments defined by how you wrote the macro. I think i'd go with that.

_________________
http://www.frankengraphics.com - personal NES blog


Top
 Profile  
 
PostPosted: Tue Jul 25, 2017 8:56 am 
Offline
User avatar

Joined: Sun Nov 09, 2008 9:18 pm
Posts: 979
Location: Pennsylvania, USA
tokumaru wrote:
I usually reserve a page of ROM for values $00-$ff, so if I wanted I could do the following to increment X by 4:

Code:
  lda ByteTable+4, x
  tax

This is a little faster than INX x4 (6 cycles vs. 8) while also occupying 4 bytes, but I definitely wouldn't use 256 bytes of ROM just for this. This table has many other uses though, such as simulating TXY ("ldy ByteTable, x") and TYX ("ldx ByteTable, y") instructions, in addition to the quick increments/decrements by constant numbers to index registers.

Many would consider this table a waste of space, but it has already made it possible for me to avoid temporary variables and also write slightly faster code in loops (thus saving a significant amount of cycles), by making the index registers more capable than usual.


What a neat tip! I don't mind wasting space, PRG is cheap compared to other things one can waste on the NES.


Top
 Profile  
 
PostPosted: Tue Jul 25, 2017 9:18 am 
Offline

Joined: Tue Feb 07, 2017 2:03 am
Posts: 232
passing in a list, and then size checking each item in the list would be the more complete way of doing it
Code:
IsParamDirectAddress .function i; i.e. $30 or $d020 not VIC_BACKCOL etc
.endf type(i) == bits

STZ .macro
    .for z = 0, z < len(\1), z = z + 1
        lda #0
        .proff
            .if IsParamDirectAddress(\1[z])
                .pron
                    sta \1[z]
                .proff
            .else
                .pron
                    sta (\1[z])+range(size(\1[z]))
                .proff
            .endif
        .pron
    .next
.endm
to which you then invoke it with #STZ ( myByte, myWord, otherByte ) Then it will output
Code:
lda #0
sta myByte
sta myWord
sta myWord+1
sta otherByte
sadly tass doesn't have a way to detect the current size of A or index in 65816 mode, so it can rep/sep as needed and assert that its in the right mode. So for 65816 extra macros that silently pass-though to the main on on 6502 are still needed. However such features are on the developers list of "to add", along with collapsible rep/seps . Once the optimiser pass is good enough that we can trust it to automatically handle optimisations or at least trivial cases, it could just remove the extra LDA #0 from doing repeated #STZ making the above moot ;)


Last edited by Oziphantom on Wed Jul 26, 2017 1:39 am, edited 1 time in total.

Top
 Profile  
 
PostPosted: Tue Jul 25, 2017 12:41 pm 
Offline
Formerly WheelInventor

Joined: Thu Apr 14, 2016 2:55 am
Posts: 852
Location: Gothenburg, Sweden
Not extending bytes to words, the thing i came up with was this:

Code:
.macro recurse_stz a1, a2, a3, a4, a5, a6, a7, a8
;------------------------------------------------------------
;Used inside macro mstz. Can also be called next after a mstz
;to wipe up to another 8 targets. 
;------------------------------------------------------------   
   .ifblank a1 ;if no arguments are left on the macros' pseudo-stack, exit.
      .exitmac
   .else
      .ifp02
         sta a1 ;NOTE! This assumes you've already set A to 0, persumably via .macro mstz
      .else ; assume a processor with opcode stz
         stz a1
   .endif
   recurse_stz a2, a3, a4, a5, a6, a7, a8   ;pipe all remaining arguments in a recursion: a2 -> a1, a3-> a2 and so on.   
.endm


.macro mstz addr1, addr2, addr3, addr4, addr5, addr5, addr6, addr7, addr8
;------------------------------------------------------------
;Description:
;Target agnostic STZ substitute. "mstz" stands for macro stz,
;to differentiate it from the opcode mnemonic "STZ".
;Behaviour:
;For 6502, it will lay down 1 LDA immediate,
;and n STAs where n is the number of given arguments (max 8).
;For anything else/undefined, it will lay down n STZ:s
;Affects:
;A in 6502 mode, none in any other mode.
;------------------------------------------------------------
   .if .paramcount = 0
      .warning  "mstz: No arguments were passed; macro ignored."
      .exitmac
   .endif
   .ifp02 ;6502 has no stz, so we need to load a #0 in preparation
      lda #0 ;NOTE! This affects the A register, unlike STZ
   .endif
   recurse_stz addr1, addr2, addr3, addr4, addr5, addr5, addr6, addr7, addr8
.endm


But even so, you could potentially run into worries - you must know that you don't need to keep whatever was in A when porting a block using this macro from 65816 to 6502. So i guess that proves your point about mermaids.

_________________
http://www.frankengraphics.com - personal NES blog


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

All times are UTC - 7 hours


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:  
Powered by phpBB® Forum Software © phpBB Group