Page 2 of 2
Re: Simple 8bit division routine
Posted: Sun Dec 20, 2020 10:13 am
by BigEd
Interesting - thanks for investigating. Perhaps a single check for size and then incrementing would be a good bandaid.
Re: Simple 8bit division routine
Posted: Sun Dec 20, 2020 3:26 pm
by barrym95838
And sometimes a decent approximation is more than adequate for the job at hand. I like it.
Re: Simple 8bit division routine
Posted: Sun Dec 20, 2020 4:13 pm
by Chromatix
Here's an alternative form of the log function:
Code: Select all
8BIT_LOG2:
; Count leading zeroes
LDX #8
SEC
: DEX
ROL A
BCC :-
; Insert 3-bit LZ count at top of remainder
STX tmp
LSR tmp
ROR A
LSR tmp
ROR A
LSR tmp
ROR A
; Result in A, clobbered X
RTS
Re: Simple 8bit division routine
Posted: Sun Dec 20, 2020 6:08 pm
by Chromatix
And here's an attempt at an antilog function, mostly just reversing the steps of the logarithm function.
Code: Select all
8b_AntiLog2:
; Extract 3-bit LZ count into X
STZ tmp
ASL A
ROL tmp
ASL A
ROL tmp
ASL A
ROL tmp
LDX tmp
; Shift mantissa down
BEQ :++
: LSR A
DEX
BNE :-
; Round up - result in A, clobbered X
: ADC #0
RTS
Re: Simple 8bit division routine
Posted: Mon Dec 21, 2020 3:24 am
by barrym95838
The worst areas were approximately $4E-$6D where adding one count to all these would generally improve accuracy, and $99-$DC where adding two counts would generally improve accuracy.
Well, eight more bytes and eight more cycles isn't so bad, if you squint a little:
Code: Select all
...
cmp #$4E
adc #0
cmp #$99
adc #0
rts
... although, that's gonna push $DD and above a bit higher than you want (I didn't actually run your code, so I don't know for sure).
@Chromatix: does your algorithm provide similar results to Garth's (sorry, feeling a bit lazy here tonight)?
Re: Simple 8bit division routine
Posted: Mon Dec 21, 2020 10:38 am
by GARTHWILSON
Here's my effort at an 8-bit inverse LOG2 function. Input and output are in the accumulator.
Code: Select all
ALOG2: TAY ; (We'll need the input again later.)
AND #1FH ; Look at only the fractional part; but
ORA #20H ; it excludes the 1st '1', so add it.
ASL A ; Now scoot it to the left end to init.
ASL A
STA OUTPUT
TYA ; Get the original input back again.
loop: ADC # 00100000B ; (Note that C is already clear.) Add
BCS end ; 1 to the exponent part until it carries.
LSR OUTPUT ; As long as it doesn't carry, shift over
BRA loop ; and see if you can do it again.
end: LDA OUTPUT
RTS
;-------------
Because of truncation errors in the LOG2 --> ALOG2 cycle, many of the outputs are less than the input (where ideally they'd be identical).
1 to $3F were correct.
From $40 to $7F, every second one was one count low.
From $80 to $FF, it went $80, 80, 80, 80, 84, 84, 84, 84, 8C, 8C, 8C, 8C, 90, 90 [...] F8, F8, F8, F8, FC, FC, FC, and FC.
Re: Simple 8bit division routine
Posted: Tue Dec 22, 2020 10:42 am
by Chromatix
@Chromatix: does your algorithm provide similar results to Garth's (sorry, feeling a bit lazy here tonight)?
The log function should produce exactly the same results, except that it also handles a zero input cleanly (outputting zero as the nearest representation of -Inf). I think there is also a way to improve its accuracy during the right-shifting stage.
The antilog function has a bug, which I need to fix - serves me right for doing it last thing at night without testing…