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
GARTHWILSON wrote:
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
barrym95838 wrote:
@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…