Aus aktuellem Anlass hier ein paar Routinen zum Unsigned-Integer-Dividieren in Assembler. Wer sie gebrauchen kann, soll glücklich damit werden.
Code
- ; unsigned 16-bit integer division (16bit = 16bit / 16bit)
- ; define these addresses:
- ; numerator16u ; 16bit
- ; denominator16u ; 16bit
- ; remainder16u ; 16bit
- ; on entry:
- ; numerator16u = an unsigned 16-bit value
- ; denominator16u = an unsigned 16-bit value
- ; on exit:
- ; A, X corrupted
- ; Y = 0
- ; numerator16u = numerator16u DIV denominator16u
- ; denominator16u preserved
- ; remainder16u = numerator16u MOD denominator16u
- ; no stack space needed except for the return address
- divide16u_16u
- lda #0 ; clear remainder16u
- tax
- ldy #17 ; define bit counter
- ;clc ; current C does not matter - will vanish when done!
- bne ++ ; always
- ;--
- - rol remainder16u ; shift C to remainder's low bit
- rol remainder16u + 1
- sec
- lda remainder16u ; subtract denominator
- sbc denominator16u
- tax
- lda remainder16u + 1
- sbc denominator16u + 1
- bcc + ; if result is valid, write back
- ++ stx remainder16u
- sta remainder16u + 1
- ; C still has old value
- + rol numerator16u ; shift C to result's lowest bit
- rol numerator16u + 1 ; shift result's highest bit to C
- dey ; all steps done?
- bne -
- rts
Code
- ; unsigned 16-bit integer division (16bit = 16bit / 8bit)
- ; define these addresses:
- ; numerator16u ; 16bit
- ; denominator8u ; 8bit
- ; on entry:
- ; numerator16u = an unsigned 16-bit value
- ; denominator8u = an unsigned 8-bit value
- ; on exit:
- ; A corrupted
- ; X = remainder (numerator16u MOD denominator8u)
- ; Y = 0
- ; numerator16u = numerator16u DIV denominator8u
- ; denominator8u preserved
- ; no stack space needed except for the return address
- divide16u_8u
- ldx #0 ; clear remainder
- ldy #17 ; set bit counter
- ;clc ; C gets shifted into result, but in the end drops out again
- bne +
- ;--
- - txa ; get remainder
- rol
- tax
- sec
- sbc denominator8u
- bcc +
- tax ; sbc did not underflow, so use changed remainder
- ; carry holds result bit
- + rol numerator16u ; shift left
- rol numerator16u + 1
- dey ; all steps done ?
- bne -
- rts