cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

divsigned.s (4070B)


      1;--------------------------------------------------------------------------
      2;  divsigned.s
      3;
      4;  Copyright (C) 2000-2021, Michael Hope, Philipp Klaus Krause
      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.area	_CODE
     30
     31.globl	__divsint
     32.globl	__divschar
     33
     34__divschar:
     35	ld	e, l
     36	ld	l, a
     37
     38__div8::
     39        ld      a, l            ; Sign extend
     40        rlca
     41        sbc     a,a
     42        ld      h, a
     43__div_signexte::
     44	ld      a, e            ; Sign extend
     45	rlca
     46	sbc     a, a
     47	ld      d, a
     48	; Fall through to __div16
     49
     50        ;; signed 16-bit division
     51        ;;
     52        ;; Entry conditions
     53        ;;   HL = dividend
     54        ;;   DE = divisor
     55        ;;
     56        ;; Exit conditions
     57        ;;   DE = quotient
     58        ;;   HL = remainder
     59        ;;
     60        ;; Register used: AF,B,DE,HL
     61__divsint:
     62__div16::
     63        ;; Determine sign of quotient by xor-ing high bytes of dividend
     64        ;;  and divisor. Quotient is positive if signs are the same, negative
     65        ;;  if signs are different
     66        ;; Remainder has same sign as dividend
     67        ld      a, h            ; Get high byte of dividend
     68        xor     a, d            ; Xor with high byte of divisor
     69        rla                     ; Sign of quotient goes into the carry
     70        ld      a, h            ; Get high byte of dividend
     71        push    af              ; Save sign of both quotient and reminder
     72
     73        ; Take absolute value of dividend
     74        rla
     75        jr      NC, .chkde      ; Jump if dividend is positive
     76        sub     a, a            ; Substract dividend from 0
     77        sub     a, l
     78        ld      l, a
     79        sbc     a, a            ; Propagate borrow (A=0xFF if borrow)
     80        sub     a, h
     81        ld      h, a
     82
     83        ; Take absolute value of divisor
     84.chkde:
     85        bit     7, d
     86        jr      Z, .dodiv       ; Jump if divisor is positive
     87        sub     a, a            ; Subtract divisor from 0
     88        sub     a, e
     89        ld      e, a
     90        sbc     a, a            ; Propagate borrow (A=0xFF if borrow)
     91        sub     a, d
     92        ld      d, a
     93
     94        ; Divide absolute values
     95.dodiv:
     96        call    __divu16
     97
     98.fix_quotient:
     99        ; Negate quotient if it is negative
    100        pop     af              ; recover sign of quotient
    101        ret	NC		; Jump if quotient is positive
    102        ld      b, a
    103        sub     a, a            ; Subtract quotient from 0
    104        sub     a, e
    105        ld      e, a
    106        sbc     a, a            ; Propagate borrow (A=0xFF if borrow)
    107        sub     a, d
    108        ld      d, a
    109        ld      a, b
    110	ret
    111
    112__get_remainder::
    113        ; Negate remainder if it is negative.
    114        rla
    115        ex	de, hl
    116        ret     NC              ; Return if remainder is positive
    117        sub     a, a            ; Subtract quotient from 0
    118        sub     a, e
    119        ld      e, a
    120        sbc     a, a            ; Propagate borrow (A=0xFF if borrow)
    121        sub     a, d
    122        ld      d, a
    123        ret
    124