6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Nov 23, 2024 12:57 pm

All times are UTC




Post new topic Reply to topic  [ 26 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Fri Nov 10, 2023 10:10 pm 
Offline

Joined: Fri Apr 28, 2023 5:16 am
Posts: 4
This was a good read, thank you to those who gave such well explained advice.

Allow me to ask a question: Like the OP, I dabble a bit with a simple project where I need to dynamically change memory addresses.

I want to print a series of characters on the screen starting with $0400 and ending with $07e7. To do that I have written four loops Right, down, left, up.

something like this

Code:
*=$1000
right:
lda #$d7 // petscii circle
sta $0400,x
inx
cpx #40 // max length of row.
bne right


That is not too hard, the X index stops at 40, but I struggle with the "down" bit

Code:
ldy #0
stx $1100
down:
lda #$d7 // petscii circle
sta $0400,x // X must increase 40 per cycle to print downwards in a line
lda $1100 //get the stored X value (should be 40 first pass)
adc #40
sta $1101 //
ldx $1100
iny
cpy #25 // with 25 rows this is the max
bne down



It works until x ($1100) reaches 255, then the x index flips because it has 8 bits only, and my whole little thing comes crashung down.

Could I change the routine so that I don't address $0400,x but increment the address itself that the petscii circle is stored to?


Top
 Profile  
Reply with quote  
PostPosted: Fri Nov 10, 2023 11:46 pm 
Offline
User avatar

Joined: Sat Jun 08, 2013 4:02 pm
Posts: 46
pistolhamster wrote:
It works until x ($1100) reaches 255, then the x index flips because it has 8 bits only, and my whole little thing comes crashung down.

Is that a typo or have you coined a neologism, a new word for flawed code, combining "crash" & "hung", much like hangry?

_________________
"I am endeavoring, ma'am, to create a mnemonic memory circuit... using stone knives and bearskins." -- Spock to Edith Keeler


Top
 Profile  
Reply with quote  
PostPosted: Sat Nov 11, 2023 12:51 am 
Offline

Joined: Fri Jul 09, 2021 10:12 pm
Posts: 741
Typically you would store the address in two consecutive bytes of page zero, and adjust them there by doing 16-bit adds or subtracts. Then to read or write the target memory location you set X or Y to zero and use indexed indirect addressing, i.e. (zpaddr,x) or (zpaddr),y.

However you can certainly use self-modifying code instead, if your code is in RAM. Garth linked to some examples of that upthread.

The case where self-modifying code doesn't work so well is where there are two or more instructions that all need to use the same address. There are some more complex techniques to cater for that a bit but it's simpler to just use indirect indexed addressing.


Top
 Profile  
Reply with quote  
PostPosted: Sat Nov 11, 2023 1:33 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8545
Location: Southern California
gfoot wrote:
Then to read or write the target memory location you set X or Y to zero and use indexed indirect addressing, i.e. (zpaddr,x) or (zpaddr),y.

On the 65c02, you can also do it without indexing, with:  ADC (ZP),  AND (ZP),  CMP (ZP),  EOR (ZP),  LDA (ZP),  ORA (ZP),  SBC (ZP),  and  STA (ZP).

_________________
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  
PostPosted: Sat Nov 11, 2023 8:35 am 
Offline

Joined: Fri Apr 28, 2023 5:16 am
Posts: 4
richardc64 wrote:
pistolhamster wrote:
It works until x ($1100) reaches 255, then the x index flips because it has 8 bits only, and my whole little thing comes crashung down.

Is that a typo or have you coined a neologism, a new word for flawed code, combining "crash" & "hung", much like hangry?


It would be an excellent example of serendipity. Alas, it was a typo. But yes, why not? "It crashung"


Top
 Profile  
Reply with quote  
PostPosted: Sun Nov 12, 2023 2:43 pm 
Offline

Joined: Fri Apr 28, 2023 5:16 am
Posts: 4
gfoot wrote:
Typically you would store the address in two consecutive bytes of page zero, and adjust them there by doing 16-bit adds or subtracts. Then to read or write the target memory location you set X or Y to zero and use indexed indirect addressing, i.e. (zpaddr,x) or (zpaddr),y.


Thanks, you put me on the track again. This is what I managed to write and test, I now have a nice column of petscii circles.

Code:
ldx #$27
ldy #$04
stx $60 // low byte address
sty $61 // high byte address
ldy #0 // counter
down:
    clc
    lda #81 //petscii circle
    sta ($60),y
    lda $60 // get low byte
    adc #40 // add 40 for next line
    sta $60 // store new value
    lda $61 // get high byte
    adc #0
    sta $61
    inx
    cpx #25 // max rows
    bne down


Top
 Profile  
Reply with quote  
PostPosted: Sun Nov 12, 2023 3:07 pm 
Offline

Joined: Fri Jul 09, 2021 10:12 pm
Posts: 741
pistolhamster wrote:
Thanks, you put me on the track again. This is what I managed to write and test, I now have a nice column of petscii circles.

Yes that's the idea. Note Garth's point that with a modern 65C02 you can also do it without using an index register.

Even on older CPUs you can also speed things up a little by swapping the roles of the Y register and the low byte of the address, i.e. $60. So you'd store zero at $60 and put the low byte of your target address into Y instead. This doesn't affect the function of the STA line, but it allows you to save a few cycles in the addition as now you can use TYA instead of LDA $60, and TAY instead of STA $60.


Top
 Profile  
Reply with quote  
PostPosted: Mon Nov 13, 2023 1:19 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8509
Location: Midwestern USA
Code:
ldx #$27
ldy #$04
stx $60 // low byte address
sty $61 // high byte address
ldx #25 ;rows
ldy #0 // counter
down:
    lda #81 //petscii circle
    sta ($60),y
    clc
    lda $60 // get low byte
    adc #40 // add 40 for next line
    sta $60 // store new value
    lda $61 // get high byte
    adc #0
    sta $61
    dex
    bne down ;more rows

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Wed Nov 15, 2023 9:09 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
gfoot wrote:
Even on older CPUs you can also speed things up a little by swapping the roles of the Y register and the low byte of the address, i.e. $60. So you'd store zero at $60 and put the low byte of your target address into Y instead. This doesn't affect the function of the STA line, but it allows you to save a few cycles in the addition as now you can use TYA instead of LDA $60, and TAY instead of STA $60.

Solid advice, every word. Shaved two bytes and ten cycles from the inner loop.
Code:
    ldy #$27
    ldx #$04
    stx $61     // high byte address
    ldx #0
    stx $60     // low byte address
    ldx #25     // counter
down:
    clc
down2:
    lda #81     // petscii circle
    sta ($60),y
    dex
    beq done
    tya         // get low byte
    adc #40     // add 40 for next line
    tay         // store new value
    bcc down2
    inc $61     // update high byte
    bcs down
done:

_________________
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)


Top
 Profile  
Reply with quote  
PostPosted: Wed Nov 15, 2023 8:49 pm 
Offline

Joined: Fri Apr 28, 2023 5:16 am
Posts: 4
gfoot wrote:
pistolhamster wrote:
Thanks, you put me on the track again. This is what I managed to write and test, I now have a nice column of petscii circles.

Yes that's the idea. Note Garth's point that with a modern 65C02 you can also do it without using an index register.

Even on older CPUs you can also speed things up a little by swapping the roles of the Y register and the low byte of the address, i.e. $60. So you'd store zero at $60 and put the low byte of your target address into Y instead. This doesn't affect the function of the STA line, but it allows you to save a few cycles in the addition as now you can use TYA instead of LDA $60, and TAY instead of STA $60.


Oh, that was a clever thing. Thank you.

IS the 65C02 the same as the WDC 65C02 that is still manufactured? I've seen that it will be the heart of the new Commander X16.


Top
 Profile  
Reply with quote  
PostPosted: Thu Nov 16, 2023 4:02 am 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
pistolhamster wrote:
IS the 65C02 the same as the WDC 65C02 that is still manufactured?
Yeah, pretty much... especially software-wise. Compared with C02's from Rockwell and CMD, for example, the current WDC product has a couple of new instructions, but they're ones you're unlikely to use -- STP and WAI. (And are you concerned about the hardware side of things? Briefly, the WDC chips can be run faster and they have some slight but important changes to the pinout; also the inputs no longer accept TTL voltage levels.)

-- Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


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

All times are UTC


Who is online

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