Jump to content
IGNORED

how to do this in assembler


Recommended Posts

hi

 

Assembler atari (atasm) can be separated into a number two, such that 2 is 23 in the register x, and 3 in the registry and?

 

Examples

 

Accumulator = 23, x = 2, y = 3

Accumulator = 45, x = 4, y = 5

Accumulator = 11, x = 1, y = 1

 

My level of assembly is very basic, and I can not think how to do that. If anyone has any idea or way of doing it.

 

greetings and thanks

Link to comment
Share on other sites

hi

 

Assembler atari (atasm) can be separated into a number two, such that 2 is 23 in the register x, and 3 in the registry and?

 

Examples

 

Accumulator = 23, x = 2, y = 3

Accumulator = 45, x = 4, y = 5

Accumulator = 11, x = 1, y = 1

 

My level of assembly is very basic, and I can not think how to do that. If anyone has any idea or way of doing it.

 

greetings and thanks

 

 

 

Well if you are working with hexadecimal representations(0-f), it is much easier than if you

are using decimal(0-9). With hexadecimal representation each digit is a representation of

4 bits so a byte is represented by two hexadecimal characters.

 

To get the right-sided digit you would AND with F.

To get the left side you would shift the bits right 4 times

 

right side:

lda #number

and #$0F

 

left side

lda #number

lsr

lsr

lsr

lsr

 

As I said this only applies to hex, and may not be the best solutions, good luck.

Link to comment
Share on other sites

Are you saying that you want to take the first digit in the accumulator and put it into the x register while at the same time putting the second digit from the accumulator into the y register?

yes

 

Well if you are working with hexadecimal representations(0-f), it is much easier than if you

are using decimal(0-9). With hexadecimal representation each digit is a representation of

4 bits so a byte is represented by two hexadecimal characters.

 

To get the right-sided digit you would AND with F.

To get the left side you would shift the bits right 4 times

 

right side:

lda #number

and #$0F

 

left side

lda #number

lsr

lsr

lsr

lsr

 

As I said this only applies to hex, and may not be the best solutions, good luck.

 

Thanks for the example, I am actually using hexadecimal numbers.

 

I need to ask if the battery is between 1 to 50, and each number placed in the big screen, for that I will use PLAYERS atari.

 

So to do 50 questions for each issue, it occurred to me to separate the two-digit number when you are.

 

	  LDX #$00
  LDY #$00
  LDA #$3F;63
  AND #$0F
  TAX
  LDA #$3F;63
  LSR
  LSR
  LSR
  LSR
  TAY

 

result

 

A: $40, X: $00 , Y:$03

 

missing a digit :?

 

 

greetings and thanks.

Edited by ascrnet
Link to comment
Share on other sites

To get the right-sided digit you would AND with F.

To get the left side you would shift the bits right 4 times

 

right side:

lda #number

and #$0F

 

left side

lda #number

lsr

lsr

lsr

lsr

 

As I said this only applies to hex, and may not be the best solutions, good luck.

 

More precisely, that solution works best for BCD values. In 65xx assembler, the instruction set includes an alternate way of handling additions and subtractions...via decimal mode. When active, base-16 hex values are treated as if they are base-10 decimal numbers...each 4-bit half (or nybble) holding a seperate digit.

 

hex...$09 + $01 = $0A

BCD...$09 + $01 = $10

 

 

If you invoke decimal mode by using SED, it remains active until you clear it with CLD. This mode only affects subsequent ADC's and SBC's.

Link to comment
Share on other sites

Hi ascrnet,

 

The project sounds interesting.

 

Hmm, You should be getting the same results that NRV has posted...

 

And just to clarify, with my example, using $3f (63 decimal)

you would end up with a $3 and an $f.

If you want to end up with a 6 and a 3, a different, more complex approach would be needed.

 

I wish I could be more help :(

 

Hope you figure it out.

(and thanks to Nukey Shay for the BCD clarification)

Link to comment
Share on other sites

Are you saying that you want to take the first digit in the accumulator and put it into the x register while at the same time putting the second digit from the accumulator into the y register?

yes

 

Well if you are working with hexadecimal representations(0-f), it is much easier than if you

are using decimal(0-9). With hexadecimal representation each digit is a representation of

4 bits so a byte is represented by two hexadecimal characters.

 

To get the right-sided digit you would AND with F.

To get the left side you would shift the bits right 4 times

 

right side:

lda #number

and #$0F

 

left side

lda #number

lsr

lsr

lsr

lsr

 

As I said this only applies to hex, and may not be the best solutions, good luck.

 

Thanks for the example, I am actually using hexadecimal numbers.

 

I need to ask if the battery is between 1 to 50, and each number placed in the big screen, for that I will use PLAYERS atari.

 

So to do 50 questions for each issue, it occurred to me to separate the two-digit number when you are.

 

	  LDX #$00
  LDY #$00
  LDA #$3F;63
  AND #$0F
  TAX
  LDA #$3F;63
  LSR
  LSR
  LSR
  LSR
  TAY

 

result

 

A: $40, X: $00 , Y:$03

 

missing a digit :?

 

 

greetings and thanks.

 

It's not surely whole code or register values are taken in wrong time, it's not possible after TAY instruction end up with accumulator NOT equal to Y register :)

Link to comment
Share on other sites

hi

 

The values from the bag's monitor atari800win, but this is what I tried with another program.

 

post-11721-1245177735_thumb.png

 

SHOW supposed to have the emulator Registo a, x, y, but in my program are not displayed well. So not well understood.

 

Now my question is like working with BCD numbers, you have to define something special to add and remove the digits?

 

greetings and thanks

Edited by ascrnet
Link to comment
Share on other sites

No special handling required...you just need to set decimal mode (SED) before changes (ADC/SBC), and clear decimal mode (CLD) when that has been done. When a variable has it's changes done via decimal mode, you can use the above method to get the numerical value for each nybble easily. Scoring for the majority of games out there use decimal mode in this manner, simply because it's that more efficient to split them up later for printing. No need to worry about the extended hex digits A-F, because decimal mode ignores them.

Link to comment
Share on other sites

No special handling required...you just need to set decimal mode (SED) before changes (ADC/SBC), and clear decimal mode (CLD) when that has been done. When a variable has it's changes done via decimal mode, you can use the above method to get the numerical value for each nybble easily. Scoring for the majority of games out there use decimal mode in this manner, simply because it's that more efficient to split them up later for printing. No need to worry about the extended hex digits A-F, because decimal mode ignores them.

Thanks for explanation Nukey Shay

 

Well then the BCD, and to add $ 04 + $ 04 + $ 02 = $ 10 then put the code if someone helps.

 

post-11721-1245210120_thumb.png

 

greetings and thanks

Edited by ascrnet
Link to comment
Share on other sites

No need to worry about the extended hex digits A-F, because decimal mode ignores them.

 

That's a bit of a misstatement. Decimal mode doesn't ignore A-F it fixes them

provided you're using BCD. but if (for example) you ADC immediate a non BCD

number and it may get it wrong (or it may not, which can be useful for binary to BCD

conversion)

Instructions other than ADC/SBC can result in non BCD values

 

Well then the BCD, and to add $ 04 + $ 04 + $ 02 = $ 10 then put the code if someone helps.

 

For future reference, instructions that set the value of A, X or Y and read-modify-write

instructions (INC/DEC memory) all set the Z and N flags

 

So, though there's nothing wrong with your code, it might be more usuall to write

it something like this:

 

   LDY #$03
  LDA #$00
  SED
  CLC
  JSR SUM



SUM
  ADC DATA-1,Y
  DEY			  ; sets the Z flag
  BNE SUM

  RTS

 

note it adds the numbers in reverse order now

Link to comment
Share on other sites

So, though there's nothing wrong with your code, it might be more usuall to write

it something like this:

 

   LDY #$03
  LDA #$00
  SED
  CLC
  JSR SUM



SUM
  ADC DATA-1,Y
  DEY			 ; sets the Z flag
  BNE SUM

  RTS

 

note it adds the numbers in reverse order now

 

Thanks bogax, but kept the numbers in the same order and it works.

	*= $600

  LDY #$03
  LDA #$00
  SED
  CLC
  JSR SUM
  BRK

SUM
  ADC DATA-1,Y
  DEY			 ; sets the Z flag
  BNE SUM
  RTS

DATA 
  .BYTE $04,$04,$03

 

to separate the numbers together, to take just one, I have to subtract (SBC), but as I get another?

 

greetings and thanks

Link to comment
Share on other sites

Thanks bogax, but kept the numbers in the same order and it works.

 

Yes, in this case it makes no difference

I was just pointing out that my loop doesn't work quite the same as yours

My loop works backwards through the data from higher addresses to lower addresses

and yours works forward from lower addresses to higher addresses

 

It's also possible to work forward though the data and still use the flags as set by

INY the code is just not quite as straight forward (as in easy to immediately understand)

I just thought it was more clear to do it the way I did

 

to separate the numbers together, to take just one, I have to subtract (SBC), but as I get another?

 

Assuming you are still talking about seperating the digits, the code you were already

given shoul work just fine (as far as I can see, if it didn't work, you must have done

something wrong)

 

The BCD byte is still just collection of bits the ADC/SBC instructions just treat them differently

AND and LSR don't treat them diferently

If you clear the decimal mode they'll be treated as straight binary by ADC/SBC

Link to comment
Share on other sites

hi

 

also works well.

 

	*= $600

  LDY #$03
  LDA #$00
  SED
  CLC
  JSR SUM
  JSR SEPARATE
  BRK

SUM
  ADC DATA-1,Y
  DEY			 ; sets the Z flag
  BNE SUM
  RTS


SEPARATE
  TAX
  AND #$0F
  TAY
  TXA
  LSR
  LSR
  LSR
  LSR
  RTS

DATA 
  .BYTE $04,$04,$20

 

 

Recently, the compiler is throwing me this warning when I add more lines of code to my game.

 

---------- atasm ----------
ATasm 1.06 beta (A mostly Mac65 compatible 6502 cross-assembler)
Pass 1: Success. (0 warnings)
Pass 2: 
In Demo.asm, line 147--
Error: Branch overflow! Target 130 bytes away.

Output completed (0 sec consumed)

 

DEX

CPX #1

line 147, BPL SCREEN :ponder:

 

greetings and thanks

Link to comment
Share on other sites

You've exceeded the conditional branch jumping distance. You need to do something like

 

DEX
CPX #1
bmi SkipIt
jmp SCREEN 
SkipIt:

 

To make a long conditional branch. Either that or refactor your code to get the conditional branches in range again.

 

If you delete a JSR not give me error :ponder:

Edited by ascrnet
Link to comment
Share on other sites

:lol: Thats because you've reduced the jump distance for the instruction into a range that can be encoded in the conditional branch instruction by the assembler.

But there are some logical order so you do not pass this? :ponder:

 

greetings and thanks

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...