How to divide the number of 16 bits by 2 in 6502 asm?

I want to split the number of 16 bits into two. My solution to the problem was lower

lda $17 ;set high byte ldx $32 ;set low byte divide: PHA ;push A to stack TXA ;X > A LSR ;divide low byte by 2 TAX ;A > X PLA ;pull A from stack LSR ;divide high byte by 2 BCC + ;C=0, skip PHA ;while C=1 TXA ;add $80 to the lsb ADC #$80 TAX PLA + +printDecimal $0400+120 

All the PHA/PLA tricks are related to the fact that my printDecimal macro reads MSB from A and LSB from X.

When I check alternatives online, I found 4 alternatives to my routine. But I did not understand.

 div2: LDA counter_hi ;Load the MSB ASL ;Copy the sign bit into C ROR counter_hi ;And back into the MSB ROR counter_lo ;Rotate the LSB as normal LDA counter_hi LDX counter_lo +printDecimal $0400+40 

How it works?

+5
source share
5 answers

Division by 2 (unsigned number) coincides with a shift of all bits by one position to the right. For example, the number 100 is in binary format:

 01100100 

Moving all positions to the right gives

 00110010 

which is a binary representation of 50.

The ROR command moves all positions to the right. The new byte MSB will be equal to the old value of the carry flag, and the new value of the carry flag will be equal to the old low byte of the byte.

If a 16-bit number is not specified, just shift the upper and lower bytes of the number to the right:

 LSR counter_hi ROR counter_lo 

LSR and ROR shift their argument to the right, but LSR makes MSB counter_hi 0 and shifts LSB counter_hi to the carry flag, while ROR makes MSB of counter_lo equal to the (old) LSB counter_hi.

If the number is signed, you need to save the sign bit and make sure that the sign bit of the new number is the same. This is what the first two commands of the code you quoted do. Please note that this works because the number is stored in two additions .

+8
source

It works like comments in say code;) In 6502, unfortunately, there is no arithmetic shift to the right, which would leave the sign bit intact. Therefore, it must be emulated. To do this, first, the character bit is extracted from the upper word. Please note that this is done using the battery, so the original value does not change. ROR used for a high word that rotates a 9-bit value obtained from the extension of an operand with a carry flag. Thus, the character bit that is currently in the CF will be rotated in the MSB, the remaining bits will be shifted to the right, and the LSB will be in the CF. This performed a signed division. The second ROR on the low word simply transfers the LSB from the upper word to the low word MSB and shifts the remaining parts to the right.

+4
source

If I remember correctly, ROR and ROL shift bits in the indicated direction, and the least significant bit (for ROR) and the most significant bit (for ROL) are moved to the Carry flag.

About 25 years have passed since I looked at any 6502, although not everything is very clear to me, but right away, as I thought it would be done.

Edit: In addition, in ROR and ROL, the existing state of the carry flag is transferred to the low / high bit of the battery.

+2
source

(Obviously, you know that the shift on the right by N bits is divided by 2 ^ N, and similarly, the shift on the left is shifted by 2)

From this link :

ASL puts the most important bit (MSB) hi byte counter_hi in the transfer register (so that the character is remembered when shifting - dividing by a positive integer (2) does not change the original character of our 16-bit number).

ROR counter_hi shifts counter_hi 1 bit to the right. Important:

The move is transferred to bit 7, and the original bit 0 is shifted to Carry.

which serves two purposes - to preserve the original character, and will also transmit LSB counter_hi for the second ROR

ROR counter_lo then does the same for the low byte. LSB counter_hi now shifted to MSB counter_lo

+2
source

I don’t remember all the instruction addressing modes, but maybe this is normal:

 LSR PHA TXA ROR TAX PLA 
+2
source

Source: https://habr.com/ru/post/1208673/


All Articles