Jump to content
IGNORED

How do you index indirect addressing in a loop?


quohog

Recommended Posts

Hi! I'm curious how some of you would treat indirect addressing in a loop like I'm about to describe.

 

Every solution I can think of just feels clunky and I have a feeling there's an elegant way to do it just out of reach of my brain.

 

So. I originally wrote my sound manager unlooped, duplicating all code for voice 0 and voice 1, just to get it up and running quick. Now it's bigger and I want to save ROM by putting it into a loop that you run through twice with x = 0 and then 1. Simple, right? For readability sake, lets use a simple pretend version of it below. Say it the original code looked like this:

SoundManager subroutine

VOICE0:
    ldy note_index_0
    lda (notes_0),y
    sta AUDF0
VOICE1:
    ldy note_index_1
    lda (notes_1),y
    sta AUDF1
    rts

So then the LOOPED version would look like:

SoundManagerLooped subroutine

    ldx #1
VOICE_LOOP:
    lda note_index_0,x
    lda ????????????,y
    sta AUDF0,x
    dex
    bpl VOICE_LOOP
    rts

(My real sound manager is way more complicated so the looping saves more space than this, I swear. :D)

 

So can you see the part that's stumping me? The part with all the ???????? 


If note_index_0 and note_index_1 are both two-byte pointers into ROM, then I can't index note_index_0 with x to get the result. That will just point to the MSB of the same pointer. So I kind of want to multiply x by 2, but that doesn't seem worth the cycles. So right now I'm using a branch:

    cpx #0
    bne do_voice_1
    lda (notes_0),y
    jmp SET_NOTE
do_voice_1:
    lda (notes_1),y
SET_NOTE:
    sta AUDF0,x

But that makes me feel dirty and wasteful. And when I did it that way, I only shrunk my routine by 30%, when I was hoping to cut it in half. 

 

So is there just some simple answer using clever addressing modes? Or some change I can make to my layout of pointers?


I'm afraid the answer is going to be like when you go to the doctor and say, "Doc, my finger hurts when I bend it like this," and the doctor says, "Okay, so don't bend it like that." ?


Anyway, thanks for reading. Any suggestions are appreciated. :)
                
                        

Link to comment
Share on other sites

Sometimes a loop does not save bytes or save as many as you would like. Typically in your example people might try and do something like this:

 

    ldx #1
.loopVoices:
    ldy note_index,X
    lda (notes),y
    sta AUDF0,X
    dex
    bpl .loopVoices
    rts

To do that both notes for AUDF0 and AUDF1 must be close together and small enough to be indexed by just one pointer. While the loop itself saves 1 byte, the overhead removed for setting the other pointer will save a few more.

 

 

If the notes are small enough then you might as well align it to a page and use Absolute Y indexing instead of ZP Y.

    ldx #1
.loopVoices:
    ldy note_index,X
    lda Notes,y
    sta AUDF0,X
    dex
    bpl .loopVoices
    rts

Now the loop saves no bytes, but not setting a pointer does (and saves ram).

 

 

In general:

- Try and use the X register as much as possible for zeropage ram indexing, because it saves a byte over using Y.

- Look for opportunities to move rom around, so that a pointer doesn't have to be set at all.

- If a subroutine is only used once, put it inline instead.

  • Thanks 1
Link to comment
Share on other sites

9 hours ago, quohog said:

So right now I'm using a branch:


    cpx #0
    bne do_voice_1
    lda (notes_0),y
    jmp SET_NOTE
do_voice_1:
    lda (notes_1),y
SET_NOTE:
    sta AUDF0,x

But that makes me feel dirty and wasteful.

I'm doing almost the same thing in my own routine, but twice, because I put both (C+V) and (x+F) bytes in a single stream of data (as words instead of bytes), increasing Y register twice in a loop to read both. "x" would be a duration indicator using the upper 3 bits of the frecuency byte (not implemented yet).

 

6 hours ago, Andrew Davie said:

For this situation I'd use two blocks of code, like your original version.

Anything else looks ugly to me

Ouch! Well, it also looks ugly to me. I'll turn into two blocks and see how much better it looks. 

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...