8-bit Divide: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
m (spell check)
(Fix a couple bugs in the code (A wasn't zeroed before entering loop, and was missing a SEC instruction))
 
(3 intermediate revisions by 2 users not shown)
Line 1: Line 1:
The following code divide two 8-bit integers (range 0...255) and outputs a 16-bit result using only real calculation, no lookup table so the size of the code is very small.
The following code divide two 8-bit integers (range 0...255) and outputs a 16-bit result in fixed point 8.8 format. It is only using real calculations, no lookup table, thus the size of the code is very small.


<pre>
<pre>
Line 5: Line 5:
;by Bregalad
;by Bregalad
;Enter with A = Dividend, Y=Divisor
;Enter with A = Dividend, Y=Divisor
;Output with YA = (1/256)*(A/Y)
;Output with YX = (A/Y) << 8, A = remainder
Division
Division
sta Dvd ;Stores dividend
sta Dvd ;Stores dividend
sty Dvs ;Stores divisor
sty Dvs ;Stores divisor
lda #$00
lda #$00 ;A must be zero before entering the loop below.
sta Res ;Clear result
sta ResHi ;Clear result, setting up a ring counter
 
        ldy #$01        ;by initializing the result to $0001.
ldy #$10 ;The loop is for 16-bit result
        sty Res        ;When the 1 gets shifted out, we're done
- asl Dvd
- asl Dvd
rol A ;Shift divisor in 1 bit
rol A ;Shift in 1 bit of dividend
        bcs +          ;If carry is set, the dividend is already greater
cmp Dvs ;Check if fractional dividend is greater than divisor
cmp Dvs ;Check if fractional dividend is greater than divisor
bcc +
bcc ++
sbc Dvs ;Subtract (C is always set)
+ sbc Dvs ;Subtract (C is always set)
+ rol Res ;Shift result (1 if subtraction was done, 0 otherwise)
sec ;Necessary if we reached here via the `bcs +` above
rol Res2
++ rol Res ;Shift result (1 if subtraction was done, 0 otherwise)
dey
rol ResHi
bne -
bcc -
lda Res
ldx Res
ldy Res2
ldy ResHi
rts
rts
</pre>
</pre>


[[Category:Arithmetic]]
[[Category:Arithmetic]]

Latest revision as of 20:27, 21 January 2024

The following code divide two 8-bit integers (range 0...255) and outputs a 16-bit result in fixed point 8.8 format. It is only using real calculations, no lookup table, thus the size of the code is very small.

;8-bit divide
;by Bregalad
;Enter with A = Dividend, Y=Divisor
;Output with YX = (A/Y) << 8, A = remainder
Division
	sta Dvd		;Stores dividend
	sty Dvs		;Stores divisor
	lda #$00	;A must be zero before entering the loop below.
	sta ResHi	;Clear result, setting up a ring counter
        ldy #$01        ;by initializing the result to $0001.
        sty Res         ;When the 1 gets shifted out, we're done
-	asl Dvd
	rol A		;Shift in 1 bit of dividend
        bcs +           ;If carry is set, the dividend is already greater
	cmp Dvs		;Check if fractional dividend is greater than divisor
	bcc ++
+	sbc Dvs 	;Subtract (C is always set)
	sec		;Necessary if we reached here via the `bcs +` above
++	rol Res		;Shift result (1 if subtraction was done, 0 otherwise)
	rol ResHi
	bcc -
	ldx Res
	ldy ResHi
	rts