6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Oct 06, 2024 10:21 am

All times are UTC




Post new topic Reply to topic  [ 8 posts ] 
Author Message
PostPosted: Mon Nov 27, 2006 2:48 am 
Offline

Joined: Mon Nov 27, 2006 2:41 am
Posts: 4
If I recall the 6502 can't branch to an absolute address.

Is there any alternative to do something similar?


I have an input that changes between 0000-0011. If it's equal to 01 or 11 then I want the program to repeat. If the input is 00 then I want it to go to the next instruction.

Any ideas?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Nov 27, 2006 3:24 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8521
Location: Southern California
Just branch around a JMP instruction which immediately follows. To keep your code concise, make it a macro, like BCSlong, BNElong, etc..


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Nov 27, 2006 4:25 am 
Offline

Joined: Mon Nov 27, 2006 2:41 am
Posts: 4
GARTHWILSON wrote:
Just branch around a JMP instruction which immediately follows. To keep your code concise, make it a macro, like BCSlong, BNElong, etc..


Sorry I'm extremely new to this and not sure what you mean. I don't think I can macro anything as what I have only allows the op code and operand.


A simple example of what I want to do:

LDA AD 00 EO (Input that can be changing between 0001-0011 while it is running)
STA 8D 04 04 (Store it at that address)
***CHECK INPUT
***If input is 0 go to next instruction, If input is not 0 go back to the beginning
***Next instruction


Maybe you can help me on the next couple of instructions?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Nov 27, 2006 5:05 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8521
Location: Southern California
> as what I have only allows the op code and operand

Is that to say you don't have an assembler? I know there are some free ones available. Maybe someone else here can recommend one. I've used C32 from Universal Cross-Assemblers and the 2500AD assembler, but neither of those is free.

What you said can be done this way:
Code:
begin:  LDA  input_port
        STA  variable_addr
        BNE  begin

        <next instruction>

Note that the LDA has an implied compare-to-zero instruction built in, so you don't need your "***CHECK INPUT" line. The code segment above will take 10 clocks altogether (per loop) if the condition is not met, 11 if your variable is not in page 0. If that's all you wanted, you don't need the long branch to an absolute address.

Do you have a potential interrupt that might need the variable? If not, there's no point in storing it, because you won't get out of that loop until the value you fetched from the input port is 0 anyway. If the sequence you listed was an error and you only wanted to exit the loop if the value was not 0, then you could put the variable storage after the BNE so you'll get faster response when the condition is met. You could have for example,
Code:
begin:  LDA  input_port
        BEQ  begin
        STA  variable_addr

If the only thing you need the value for is to determine immediately what you'll do, you may not even need to store it, since the 6502 lets you test it multiple times against different values without destroying the starting value. (There are a lot more possibilities to do a lot with very few instructions but I'll stop there since you're new to this.)

The relative branch takes 2 clocks when the branch is not taken, and usually 3 if taken, but 4 if the branch is taken and a page boundary is crossed.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Nov 27, 2006 6:06 am 
Offline

Joined: Mon Nov 27, 2006 2:41 am
Posts: 4
GARTHWILSON wrote:
> as what I have only allows the op code and operand

Is that to say you don't have an assembler? I know there are some free ones available. Maybe someone else here can recommend one. I've used C32 from Universal Cross-Assemblers and the 2500AD assembler, but neither of those is free.

Unfortunately I don't have one but it won't be necessary for my mini project.

GARTHWILSON wrote:
What you said can be done this way:
Code:
begin:  LDA  input_port
        STA  variable_addr
        BNE  begin

        <next instruction>

Note that the LDA has an implied compare-to-zero instruction built in, so you don't need your "***CHECK INPUT" line. The code segment above will take 10 clocks altogether (per loop) if the condition is not met, 11 if your variable is not in page 0. If that's all you wanted, you don't need the long branch to an absolute address.


I did give that a try but I'm loading an "absolute address" into the accumulator which is the data input that i'm manually putting in so it didn't work because BNE requires a value to go back to check on a value if it's 0 or not. If I loaded the accumulator using the "immediate" code then there wouldn't be any problems but I need to load an absolute address for my input.

GARTHWILSON wrote:
Do you have a potential interrupt that might need the variable? If not, there's no point in storing it, because you won't get out of that loop until the value you fetched from the input port is 0 anyway. If the sequence you listed was an error and you only wanted to exit the loop if the value was not 0, then you could put the variable storage after the BNE so you'll get faster response when the condition is met. You could have for example,
Code:
begin:  LDA  input_port
        BEQ  begin
        STA  variable_addr

If the only thing you need the value for is to determine immediately what you'll do, you may not even need to store it, since the 6502 lets you test it multiple times against different values without destroying the starting value. (There are a lot more possibilities to do a lot with very few instructions but I'll stop there since you're new to this.)

The relative branch takes 2 clocks when the branch is not taken, and usually 3 if taken, but 4 if the branch is taken and a page boundary is crossed.

I'm not concerned about saving clocks so it's not an issue here. I want to exit the loop if it is equal to 0.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Nov 27, 2006 6:33 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8521
Location: Southern California
Quote:
I did give that a try but I'm loading an "absolute address" into the accumulator which is the data input that i'm manually putting in so it didn't work because BNE requires a value to go back to check on a value if it's 0 or not. If I loaded the accumulator using the "immediate" code then there wouldn't be any problems but I need to load an absolute address for my input.
Once the value is in the accumulator, it doesn't matter how you got it there or what addressing mode you used. BNE doesn't check the value anyway. All it does is branch or not branch based on the Z flag which was left either 1 or 0 by the LDA, again regardless of addressing mode. The comparison is done by the LDA, not the conditional branch instruction.
Quote:
I want to exit the loop if it is equal to 0.
Then note that your program won't ever find anything but 0 in the variable, unless there are interrupts running that watch it.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Nov 27, 2006 7:23 am 
Offline

Joined: Mon Nov 27, 2006 2:41 am
Posts: 4
GARTHWILSON wrote:
Quote:
I did give that a try but I'm loading an "absolute address" into the accumulator which is the data input that i'm manually putting in so it didn't work because BNE requires a value to go back to check on a value if it's 0 or not. If I loaded the accumulator using the "immediate" code then there wouldn't be any problems but I need to load an absolute address for my input.
Once the value is in the accumulator, it doesn't matter how you got it there or what addressing mode you used. BNE doesn't check the value anyway. All it does is branch or not branch based on the Z flag which was left either 1 or 0 by the LDA, again regardless of addressing mode. The comparison is done by the LDA, not the conditional branch instruction.
Quote:
I want to exit the loop if it is equal to 0.
Then note that your program won't ever find anything but 0 in the variable, unless there are interrupts running that watch it.


Got it!:D Thank you very much for all the information! Program working exactly how I want it. :D


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Nov 27, 2006 8:56 am 
Offline

Joined: Fri Jun 27, 2003 8:12 am
Posts: 618
Location: Meadowbrook
For a stack of compares, bne and beq, I used a jump table setup to absolutes.

_________________
"My biggest dream in life? Building black plywood Habitrails"


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC


Who is online

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