Advertisement
verz

Sqrt16 - Z80

Aug 5th, 2019
591
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;
  2. ;   Sqrt16
  3. ;
  4. ;     Sqrt16: Integer Square Root of input + remainder
  5. ;       input:    2 bytes in _square
  6. ;       output:   1 bytes in _sqrt,     result
  7. ;                 2 bytes in M+3,       remainder
  8. ;
  9. ;   HL is loaded with _square value at the beginning, and the results are put in memory at the end
  10. ;   it can easily be changed to enter and exit the values via registers directly
  11. ;
  12. ;   medium execution time: 250us on a 4MHz Z80; almost 4000 computed roots per sec
  13. ;
  14. ;   implements:
  15. ;        R= 0
  16. ;        M= N                               ;N= input
  17. ;        D= 2^7 (80h)                       ;D= 2^(p-1),  p= #bits(result) = #bits(input)/2
  18. ;        for n= 1 to 8                      ;for n= 1 to p
  19. ;        {
  20. ;            T= ((R+R+D) >> 1) << 8         ; T= (2R+D) << (p-1)
  21. ;            if (T <= M) then M=M-T: R=R+D
  22. ;            M= M << 1
  23. ;            D= D/2
  24. ;        }
  25.  
  26. _square .db 0,0,0,0
  27. _M4     .db 0
  28. _sqrt   .db 0
  29. ;_T     .db 0,0
  30. _M      = _square
  31. ;_D     .db 0
  32.    
  33. sqrt16
  34.     ld hl,(_square) ; hl=M; T exists just temporarily in a
  35.     ld de,00080h    ; d=R, e=D in last iteration (80h)
  36.     ld bc, 0740h    ; b is a counter, c=D
  37. loopsq16
  38.     jp c, _skp016
  39.    
  40.     ld a,h      ; M-T  (T>M)
  41.     sub c
  42.     sub d
  43.     jp m, _skp116   ; if "m" then M-T<0, so T>M
  44.     jp _s1
  45.    
  46. _skp016
  47.     ld a,h
  48.     sub c
  49.     sub d
  50. _s1 ld h,a      ; M=M-T
  51.  
  52.     ld a,c      ; R=R+D; (D must be doubled)
  53.     add a,c
  54.     add a,d
  55.     ld d,a
  56.    
  57. _skp116
  58.     srl c       ; D=D/2
  59.  
  60.     xor a
  61.     sla l       ; M=M*2
  62.     rl h
  63.  
  64.     djnz loopsq16
  65.  
  66. lastiter16      ; D=1   ; T+1=R  =>  M-T == M-R
  67.     jp c, _skp01
  68.    
  69.     ;or a       ; CY=0, but CY is not set here
  70.     sbc hl,de   ; M-T (T>M)
  71.     add hl,de   ; restore HL;   sbc+add: trick to do a 16bit compare
  72.     jp m,_skp11 ; if "m" then M-T<0, so T>M
  73. _skp01
  74.     or a        ; CY=0
  75.     sbc hl,de   ; M=M-T where T=<R><80h>=de
  76.    
  77.     inc d       ; R=R+D  =>  R=R+1
  78. _skp11
  79.     sla l
  80.     rl h
  81.     rl e
  82.  
  83.     ld (_square+2),hl   ; h is the low byte of the remainder
  84.     ld (_square+4),de   ; e is the high byte of the remainder (1 bit);   d is the result
  85.     ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement