Generic for loop

Building your first 6502-based project? We'll help you get started here.
User avatar
cjs
Posts: 759
Joined: 01 Dec 2018
Location: Tokyo, Japan
Contact:

Re: Generic for loop

Post by cjs »

BillO wrote:
x is never changed so why are you doing sta(scrLow,x)?...Would this not work more efficiently?

Code: Select all

           sta (scrLow)       ; put it on the screen
That addressing mode doesn't exist on the 6502. (At least, not in the NMOS version that the 2600 uses. Maybe they added it to some 65C02 variants.)

I find this reference useful for quickly looking up the addressing modes available for each instruction. (And what flags are set by each instruction, too.)
Curt J. Sampson - github.com/0cjs
Chromatix
Posts: 1462
Joined: 21 May 2018

Re: Generic for loop

Post by Chromatix »

Quote:
x is never changed so why are you doing sta(scrLow,x)?
I imagine it's because the NMOS 6502 core - which is what you'd get in a 2600 - doesn't have a non-indexed indirect addressing mode. You either get pre-indexed by X, or post-indexed by Y.

The approach by sark02 looks sound in principle, taking advantage of the index registers and the post-indexed addressing mode. I don't have time today to fettle the setup code around it, but the core is useful. Its one limitation is that it doesn't easily support a final inner loop of less than 256 bytes; you have to put the remainder portion in the first iteration. This may not matter in the end, though.
User avatar
BillO
Posts: 1038
Joined: 12 Dec 2008
Location: Canada

Re: Generic for loop

Post by BillO »

Okay, did some study on the responses, and thank you both for taking the time. I did leave the parenthesis in and may have conflated things a touch ...

So why not the use zero page addressing mode: sta scrLow ? scrLow is only a byte value, so will still refer to page 0. There should be little change, except for saving a few cycles using the zero page mode.

like:

Code: Select all

fill:      lda #3             ; set the color
           sta scrLow       ; put it on the screen
           inc scrLow         ; increment low byte
           bne fill           ; loop if not zero
           inc scrHigh        ; increment high byte
           lda scrHigh        ; load high byte
           cmp $03            ; compare high byte
           bne fill           ; != so increment low byte
           lda scrLow         ; load low byte
           cmp $02            ; compare low byte
           bne fill           ; != so increment low byte
     
end:       brk
Still trying to wrap my head around this, so pleae be patient...
Bill
sark02
Posts: 241
Joined: 10 Nov 2015

Re: Generic for loop

Post by sark02 »

sark02 wrote:

Code: Select all

L1:	
    sta ($20),y
    iny
    bne L1
    inc $21
    dex
    bpl L1
A quick addendum to my code:
Whereas sta (ind),y is 6 cycles, std abs,y is only 5, so if the loop can be in RAM rather than ROM, it can be modified to:

Code: Select all

L1:	
    sta $1234,y   ; $1234 patched at runtime
    iny
    bne L1
    inc L1+2      ; increment upper byte of STA address
    dex
    bpl L1
This uses (L1+2,L1+1) as the write address, as opposed to ($21,$20). Saves 1 cycle/iteration.
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Generic for loop

Post by barrym95838 »

I don't know if it's just the kooky way my brain works, but I think you can save some code space but get 'er done just as quickly if your application can tolerate filling from high to low (untested):

Code: Select all

; Fill X*256+Y bytes of memory with A, based
; at ($21,$20) ... don't try to exceed 33023 bytes!
; exit: Y=0, X=$FF, A and base pointer preserved
fill:
   pha
   txa
   clc
   adc $21
   sta $21
   pla
   cpy #0
   beq fill3
fill2:
   dey
   sta ($20),y
   bne fill2
fill3:
   dec $21
   dex
   bpl fill2
   inc $21
   rts
Last edited by barrym95838 on Thu Feb 13, 2020 5:48 am, edited 2 times in total.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
User avatar
cjs
Posts: 759
Joined: 01 Dec 2018
Location: Tokyo, Japan
Contact:

Re: Generic for loop

Post by cjs »

barrym95838 wrote:
I don't know if it's just the kooky way my brain works, but I think you can save some code space but get 'er done just as quickly if your application can tolerate filling from high to low....
Your brain works like a 6502! I guess that qualifies as "kooky...."

And yes, I've noticed this too. My bigint representation was initially little-endian, following the convention of the CPU. But I changed it to big-endian, going opposite the convention, specifically because on the 6502 you can save a CMP and perhaps more by counting down to zero rather than counting up to your target. A related technique is to use 1-based indexes for arrays rather than 0-based: the loop control is just DEY followed by BEQ done.
Curt J. Sampson - github.com/0cjs
sark02
Posts: 241
Joined: 10 Nov 2015

Re: Generic for loop

Post by sark02 »

barrym95838 wrote:
I don't know if it's just the kooky way my brain works, but I think you can save some code space but get 'er done just as quickly if your application can tolerate filling from high to low [...]
Nice one.
Post Reply