Author Topic: DivAHLby10 Routine Check  (Read 3649 times)

0 Members and 1 Guest are viewing this topic.

Offline AssemblyBandit

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 374
  • Rating: +60/-1
  • ~AssemblyBandit~
    • View Profile
    • briandm82.com
DivAHLby10 Routine Check
« on: July 06, 2013, 06:23:54 am »
Here's a routine to divide AHL by 10. Just wondering if anyone could spot any potential problems with it. Particularly the inc L, should I inc HL to be safe?

Code: [Select]
DivAHLby10:
 ld d,a
 ld c,$0a
 sub a
 ld b,$18
DAHLLoop1:
 add hl,hl
 ld e,a
 ld a,d
 adc a,a
 ld d,a
 ld a,e
 rla
 cp c
 jr c,DAHLLoop2
 sub c
 inc l
DAHLLoop2:
 djnz DAHLLoop1
 ld e,a
 ld a,d
 ret

Offline jacobly

  • LV5 Advanced (Next: 300)
  • *****
  • Posts: 205
  • Rating: +161/-1
    • View Profile
Re: DivAHLby10 Routine Check
« Reply #1 on: July 06, 2013, 06:53:35 am »
Just wrote a program to brute force check the algorithm and it works perfectly as is. :)

Offline AssemblyBandit

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 374
  • Rating: +60/-1
  • ~AssemblyBandit~
    • View Profile
    • briandm82.com
Re: DivAHLby10 Routine Check
« Reply #2 on: July 06, 2013, 07:09:27 am »
Wow perfect, thanks! Brute force?! Can't argue with the results! How did you write it, on the calculator?

Offline Xeda112358

  • they/them
  • Moderator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 4704
  • Rating: +719/-6
  • Calc-u-lator, do doo doo do do do.
    • View Profile
Re: DivAHLby10 Routine Check
« Reply #3 on: July 06, 2013, 07:10:21 am »
Because you are using add hl,hl, bit 0 of HL is always 0 by the time you get to that, so you should be fine (as verified by jacobly :P) You might be able to get better speed by doing this, though:
Code: [Select]
DivAHLby10:
 ld d,a
 ld bc,$180a
 sub a
DAHLLoop1:
 add hl,hl
 rl d
 rla
 cp c
 jr c,DAHLLoop2
 sub c
 inc l
DAHLLoop2:
 djnz DAHLLoop1
 ld e,a
 ld a,d
 ret
E is the remainder, AHL is the quotient. It is 4 bytes smaller and 262 t-states faster :)

Offline AssemblyBandit

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 374
  • Rating: +60/-1
  • ~AssemblyBandit~
    • View Profile
    • briandm82.com
Re: DivAHLby10 Routine Check
« Reply #4 on: July 06, 2013, 07:22:06 am »
I should have known that it would have always been zero considering I basically just rotated it left  :banghead: Thanks for optimizing it, I put it into Buttonz. Just so you know, I just added some stuff to my divHlby10 routine and randomly checked, the registers I chose are arbitrary and can be changed if needed. I really care about the remainder though to display decimal, but you probably already knew that.

Offline Xeda112358

  • they/them
  • Moderator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 4704
  • Rating: +719/-6
  • Calc-u-lator, do doo doo do do do.
    • View Profile
Re: DivAHLby10 Routine Check
« Reply #5 on: July 06, 2013, 07:27:33 am »
Cool! If you have inputs as EHL, then the output will be A as the remainder and EHL as the result :
Code: [Select]
DivAHLby10:
 ld bc,$180a
 sub a
DAHLLoop1:
 add hl,hl
 rl d
 rla
 cp c
 jr c,DAHLLoop2
 sub c
 inc l
DAHLLoop2:
 djnz DAHLLoop1
 ret
That saves only 3 bytes and 12 cycles. If you want to squeeze a little more speed out of the routine without fully unrolling it, you can unrll the first 3 iterations since 3 bits will never be >=10 :
Code: [Select]
DivAHLby10:
 ld bc,$150a
 sub a
 add hl,hl \ rl d \ rla
 add hl,hl \ rl d \ rla
 add hl,hl \ rl d \ rla
DAHLLoop1:
 add hl,hl
 rl d
 rla
 cp c
 jr c,DAHLLoop2
 sub c
 inc l
DAHLLoop2:
 djnz DAHLLoop1
 ret
The cost is 12 bytes and you save only 87 cycles. I am trying to think of a better approach to get speed out of this.

EDIT: This routine gets a minimum of 966 tstates, average of 984.5, and max of 1002, making it almost 300 t-states faster at its slowest than the previous routine at its fastest. The downside is that it is 35 bytes, compared to the 15 it could be:
Code: [Select]
DivEHLby10:
;Inputs:
;     EHL
;Outputs:
;     EHL is the quotient
;     A is the remainder
;     D is not changed
;     BC is 10

 ld bc,$050a
 sub a

 sla e \ rla
 sla e \ rla
 sla e \ rla

 sla e \ rla
 cp c
 jr c,$+4
   sub c
   inc e
 djnz $-8

 ld b,16

 add hl,hl
 rla
 cp c
 jr c,$+4
 sub c
 inc l
 djnz $-7
 ret

Offline AssemblyBandit

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 374
  • Rating: +60/-1
  • ~AssemblyBandit~
    • View Profile
    • briandm82.com
Re: DivAHLby10 Routine Check
« Reply #6 on: July 15, 2013, 04:46:43 pm »
Thanks alot Xeda, now I know who to go to for code. That Pokemon Amber looks great!

Offline Xeda112358

  • they/them
  • Moderator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 4704
  • Rating: +719/-6
  • Calc-u-lator, do doo doo do do do.
    • View Profile
Re: DivAHLby10 Routine Check
« Reply #7 on: July 16, 2013, 09:41:24 am »
Thanks alot Xeda, now I know who to go to for code.
I'm still not at the level of Runer112, jacobly, or calc84maniac (to name a few :P). I definitely enjoy doing this kind of coding, though!
That Pokemon Amber looks great!
Thanks! Now if it can ever get finished...