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

All times are UTC




Post new topic Reply to topic  [ 26 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Wed Dec 15, 2021 7:08 pm 
Offline

Joined: Wed Dec 15, 2021 7:06 pm
Posts: 1
Hey, very much a noob to 6502 assembly. I'm working on something that should ideally be able to increment fully up from $4000 to $7fff, but obv 8 bit registers aren't enough. Is there any way to use both x and y registers for an address?


Top
 Profile  
Reply with quote  
PostPosted: Wed Dec 15, 2021 7:12 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
Welcome! I've seen X and Y used in a convention for passing parameters, but really an address can only live in one of two places: the instruction stream, and zero page. Oh, and the stack. Three places.

So, the normal scheme is to put the address in two consecutive zero page locations, use an appropriate indirect mode to use that pointer, and then to use the INC (or DEC) operations on zero page to increment and decrement. And, because these are 8 bit operations, you increment the low byte, and then detect overflow and increment the high byte if needed.


Top
 Profile  
Reply with quote  
PostPosted: Thu Dec 16, 2021 7:30 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8509
Location: Midwestern USA
Oman395 wrote:
Hey, very much a noob to 6502 assembly. I'm working on something that should ideally be able to increment fully up from $4000 to $7fff, but obv 8 bit registers aren't enough. Is there any way to use both x and y registers for an address?

.X and/or .Y can be used as an offset to a base address, but in themselves can't be used to form an address. As Ed noted, you need to use one of the indirect addressing modes, which involves page zero. Think of page zero as a set of (slightly slower) registers, a concept referred to as “addressable register architecture.”

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


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 17, 2021 3:20 pm 
Offline

Joined: Sun Nov 08, 2009 1:56 am
Posts: 411
Location: Minnesota
If all you want to do is count from $4000 to $7fff using just the X- and Y-registers, yes, you can do that. If you want to use one of those values to form an address you can use to read from or write to, no, there's no direct way to do that. No 6502 instruction uses the paired X- and Y-registers as an address for something the A-register is doing.

What you can do, as has been pointed out above, is put the value $4000 in a pair of consecutive zero page locations (lo-byte, hi-byte) and use it as the base address of an indirect instruction. Then you can increment that value as needed to reach higher and higher addresses. The slowest way to do that would be to increment the base address by one each time while holding X or Y constant. The faster way is to increment Y by one each time and increment the base address just once every 256 times.


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 17, 2021 6:21 pm 
Offline

Joined: Sun Sep 19, 2021 11:21 am
Posts: 41
Something like this will store $FF in memory locations $4000 to $7FFF...
Code:
; ? means the value of the memory location referenced.
; $10 holds low byte of address.
; $11 hold high byte of address.
     
         .ORG $200


         LDY #$00             ; Y = $00
         TYA                  ; A = $00
         STA $10              ; Memory location $10 = $00
         LDA #$40             ; A = $40
         STA $11              ; Memory location $11 = $40
loop1    LDA #$FF             ; A = $FF
loop2    STA ($10),Y          ; ?$11 * 256 + ?$10 + Y = A
         INY                  ; Y = Y + 1
         BNE loop2            ; Y <> 0 goto loop2
         INC $11              ; $11 = $11 + 1
         LDA $11              ; A = ?$11
         CMP #$80             ; A = $80
         BNE loop1            ; If yes goto loop1
         
         BRK                  ; End


Why can't I get this code to line up? :? <= Fixed!

Thank you, BigEd - tabs replaced by spaces and a little tinkering did it!


Last edited by DRG on Fri Dec 17, 2021 6:35 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 17, 2021 6:26 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
You need to use spaces, not tabs, I think. I usually do a lot of tweaking with the preview function - to get it right on the forum, which is what matters, and whatever it has to be in the text entry box.


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 17, 2021 7:03 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8509
Location: Midwestern USA
DRG wrote:
Something like this will store $FF in memory locations $4000 to $7FFF...

I'd do it this way:

Code:
; ? means the value of the memory location referenced.
; $10 holds low byte of address.
; $11 hold high byte of address.
;     
; Below executes in 180,813 clock cycles.
;
         .ORG $200
;
         LDA #$40             ; A = $40
         LDX #$80-$40         ; page counter (64 pages)
         LDY #$00             ; Y = $00
         STA $11              ; Memory location $11 = $40
         STY $10              ; Memory location $10 = $00
         LDA #$FF             ; A = $FF
;
loop     STA ($10),Y          ; ?$11 * 256 + ?$10 + Y = A
         INY                  ; Y = Y + 1
         BNE loop             ; Y <> 0 goto loop2
;
         INC $11              ; $11 = $11 + 1
         DEX                  ; page count = page count -1
         BNE loop             ; not done
;         
         BRK                  ; End

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


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 17, 2021 7:30 pm 
Offline

Joined: Sun Sep 19, 2021 11:21 am
Posts: 41
Just checked in the 6502 Simulator and mine was 118,131 clock cycles. But, that LDA/CMP pairing of mine seemed clumsy to me.

Just goes to show the OP that there are many way to skin a cat in 6502.


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 17, 2021 8:02 pm 
Offline

Joined: Fri Dec 21, 2018 1:05 am
Posts: 1120
Location: Albuquerque NM USA
I guess if you truly only want to use X and Y registers only, you can do it with self-modifying code where the base address of "STA $4000,x" is modified.

Am I banished from 6502.org forever for suggesting that? :twisted:
Bill


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 17, 2021 8:25 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
I don't do it often, but I wrote some self-modifying code today...


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 17, 2021 9:01 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8545
Location: Southern California
plasmo wrote:
I guess if you truly only want to use X and Y registers only, you can do it with self-modifying code where the base address of "STA $4000,x" is modified.

Am I banished from 6502.org forever for suggesting that? :twisted:
Bill

Not at all. The more I look, the more I think there is significant capability there that most of us have been neglecting.
http://wilsonminesco.com/SelfModCode/

_________________
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: Fri Dec 17, 2021 10:40 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 895
plasmo wrote:
Am I banished from 6502.org forever for suggesting that? :twisted:
Bill


Nope.
Here are some links for self modifying code in the Programming and Forth subforums.


Top
 Profile  
Reply with quote  
PostPosted: Sat Dec 18, 2021 5:53 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8509
Location: Midwestern USA
GARTHWILSON wrote:
plasmo wrote:
I guess if you truly only want to use X and Y registers only, you can do it with self-modifying code where the base address of "STA $4000,x" is modified.

Am I banished from 6502.org forever for suggesting that? :twisted:
Bill

Not at all. The more I look, the more I think there is significant capability there that most of us have been neglecting.
http://wilsonminesco.com/SelfModCode/

I have something like that in POC V1.3's SCSI driver. During the data-in and data-out bus phases, some code is copied from ROM to low RAM and self-modification sets the target address. It runs faster than using an indirect addressing mode.

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


Top
 Profile  
Reply with quote  
PostPosted: Sat Dec 18, 2021 10:00 am 
Offline

Joined: Sun Sep 19, 2021 11:21 am
Posts: 41
How bizarre! A self modifying code is what I actually thought of overnight having slept on it.

I thought this could actually be much closer aligned to the OP's, Oman395, original thoughts i.e. can an address "shared" between the X and Y registers be used to access memory.

In essence, the code below does what a "STA X:Y" instruction would do where X=lsb and Y=msb. The STA $1234 is just a sacrificial address to ensure the correct LDA instruction is generated by the assembler. Oh, and you couldn't run it in ROM!

Code:
         ; smc = self modifying code location.
         ; -> smc + 0 = $8D (LDA absolute from non-zero page address).
         ; -> smc + 1 = lsb of absolute address.
         ; -> smc + 2 = msb of absolute address.
         ;
         ; X holds the lsb of the address.
         ; Y holds the msb of the address.
         ;
         ; Acts as a pseudo "STA X:Y" instruction.
         
         .ORG $200

         LDX #$00      ; X = $00
         LDY #$40      ; Y = $40
         LDA #$FF      ; A = $FF
     
loopy    STY smc+2     ; Overwrite the msb
loopx    STX smc+1     ; Overwrite the lsb
smc      STA $1234     ; Absolute non-zeropage     
         INX           ; X = X + 1
         BNE loopx     ; X <> 0 goto loopx
         INY           ; Y = Y + 1
         CPY #$80      ; Does Y - $80 == 0
         BNE loopy     ; If yes goto loopy
         
         BRK           ; End


It takes longer (213,637 clock cycles) but, somehow, seems more elegant (IMHO).

I also worried what the reception to self modifying code would be - glad to see nothing is ruled out. :)

Such as code that has 64 lines of STA instructions (STA $4000,Y; STA $4100,Y; STA $4200,Y ... STA $7F00,Y). Much faster (2.55 times), but takes up more memory.


Top
 Profile  
Reply with quote  
PostPosted: Sat Dec 18, 2021 10:55 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8545
Location: Southern California
Taking advantage of SMC would be something like
Code:
      STZ  smc+1
      LDA  #$40
      STA  smc+2
      LDA  #$FF
     
smc:  STA  $1234     ; Absolute non-zeropage.   
      INC  smc+1     ; Incr ADL.
      BNE  smc       ; If it rolled over,
      INC  smc+2     ; then incr ADH also
      BPL  smc       ; Loop until ADH reaches $80.

_________________
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  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 26 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

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