git.y1.nz

gbdk-2020

GameBoy Development Kit
download: https://git.y1.nz/archives/gbdk.tar.gz
README | Files | Log | Refs | LICENSE

gbdk-lib/libc/asm/z80/divunsigned.s

      1 ;--------------------------------------------------------------------------
      2 ;  divunsigned.s
      3 ;
      4 ;  Copyright (C) 2000-2021, Michael Hope, Philipp Klaus Krause, Marco Bodrato
      5 ;
      6 ;  This library is free software; you can redistribute it and/or modify it
      7 ;  under the terms of the GNU General Public License as published by the
      8 ;  Free Software Foundation; either version 2, or (at your option) any
      9 ;  later version.
     10 ;
     11 ;  This library is distributed in the hope that it will be useful,
     12 ;  but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 ;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     14 ;  GNU General Public License for more details.
     15 ;
     16 ;  You should have received a copy of the GNU General Public License 
     17 ;  along with this library; see the file COPYING. If not, write to the
     18 ;  Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
     19 ;   MA 02110-1301, USA.
     20 ;
     21 ;  As a special exception, if you link this library with other files,
     22 ;  some of which are compiled with SDCC, to produce an executable,
     23 ;  this library does not by itself cause the resulting executable to
     24 ;  be covered by the GNU General Public License. This exception does
     25 ;  not however invalidate any other reasons why the executable file
     26 ;   might be covered by the GNU General Public License.
     27 ;--------------------------------------------------------------------------
     28 
     29         ;; Originally from GBDK by Pascal Felber.
     30 
     31 .area   _CODE
     32 
     33 .globl	__divuint
     34 .globl	__divuchar
     35 
     36 
     37 __divuchar:
     38 	ld	e, l
     39 	ld	l, a
     40 
     41         ;; Fall through
     42 __divu8::
     43         ld      h,#0x00
     44         ld      d,h
     45         ; Fall through to __divu16
     46 
     47         ;; unsigned 16-bit division
     48         ;;
     49         ;; Entry conditions
     50         ;;   HL = dividend
     51         ;;   DE = divisor
     52         ;;
     53         ;; Exit conditions
     54         ;;   DE = quotient
     55         ;;   HL = remainder
     56         ;;   carry = 0
     57         ;;   If divisor is 0, quotient is set to "infinity", i.e HL = 0xFFFF.
     58         ;;
     59         ;; Register used: AF,B,DE,HL
     60 __divuint:
     61 __divu16::
     62         ;; Two algorithms: one assumes divisor <2^7, the second
     63         ;; assumes divisor >=2^7; choose the applicable one.
     64         ld      a,e
     65         and     a,#0x80
     66         or      a,d
     67         jr      NZ,.morethan7bits
     68         ;; Both algorithms "rotate" 24 bits (H,L,A) but roles change.
     69 
     70         ;; unsigned 16/7-bit division
     71 .atmost7bits:
     72         ld      b,#16           ; bits in dividend and possible quotient
     73         ;; Carry cleared by AND/OR, this "0" bit will pass trough HL.[*]
     74         adc     hl,hl
     75 .dvloop7:
     76         ;; HL holds both dividend and quotient. While we shift a bit from
     77         ;;  MSB of dividend, we shift next bit of quotient in from carry.
     78         ;; A holds remainder.
     79         rla
     80 
     81         ;; If remainder is >= divisor, next bit of quotient is 1.  We try
     82         ;;  to compute the difference.
     83         sub     a,e
     84         jr      NC,.nodrop7     ; Jump if remainder is >= dividend
     85         add     a,e             ; Otherwise, restore remainder
     86         ;; The add above sets the carry, because sbc a,e did set it.
     87 .nodrop7:
     88         ccf                     ; Complement borrow so 1 indicates a
     89                                 ;  successful substraction (this is the
     90                                 ;  next bit of quotient)
     91         adc     hl,hl
     92         djnz    .dvloop7
     93         ;; Carry now contains the same value it contained before
     94         ;; entering .dvloop7[*]: "0" = valid result.
     95         ld      e,a             ; DE = remainder, HL = quotient
     96         ex	de, hl
     97         ret
     98 
     99 .morethan7bits:
    100         ld      b,#9            ; at most 9 bits in quotient.
    101         ld      a,l             ; precompute the first 7 shifts, by
    102         ld      l,h             ;  doing 8
    103         ld      h,#0
    104         rr      l               ;  undoing 1
    105 .dvloop:
    106         ;; Shift next bit of quotient into bit 0 of dividend
    107         ;; Shift next MSB of dividend into LSB of remainder
    108         ;; A holds both dividend and quotient. While we shift a bit from
    109         ;;  MSB of dividend, we shift next bit of quotient in from carry
    110         ;; HL holds remainder
    111         adc     hl,hl           ; HL < 2^(7+9), no carry, ever.
    112 
    113         ;; If remainder is >= divisor, next bit of quotient is 1. We try
    114         ;;  to compute the difference.
    115         sbc     hl,de
    116         jr      NC,.nodrop      ; Jump if remainder is >= dividend
    117         add     hl,de           ; Otherwise, restore remainder
    118 	;; The add above sets the carry, because sbc hl,de did set it.
    119 .nodrop:
    120         ccf                     ; Complement borrow so 1 indicates a
    121                                 ;  successful substraction (this is the
    122                                 ;  next bit of quotient)
    123         rla
    124         djnz    .dvloop
    125         ;; Take care of the ninth quotient bit! after the loop B=0.
    126         rl      b               ; BA = quotient
    127         ;; Carry now contains "0" = valid result.
    128         ld      d,b
    129         ld      e,a             ; DE = quotient, HL = remainder
    130         ret
    131 

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.