123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- #include once <div32.asm>
- ;
- __DIVF16: ; 16.16 Fixed point Division (signed)
- ; DE.HL = Dividend, Stack Top = Divisor
- ; A = Dividend, B = Divisor => A / B
- lda z80_c ;- exx
- ldx z80_cp
- stx z80_c
- sta z80_cp
- lda z80_b
- ldx z80_bp
- stx z80_b
- sta z80_bp
- lda z80_e
- ldx z80_ep
- stx z80_e
- sta z80_ep
- lda z80_d
- ldx z80_dp
- stx z80_d
- sta z80_dp
- lda z80_l
- ldx z80_lp
- stx z80_l
- sta z80_lp
- lda z80_h
- ldx z80_hp
- stx z80_h
- sta z80_hp
- pla ;- pop hl ; return address
- sta z80_h
- pla
- sta z80_l
- pla ;- pop de ; low part
- sta z80_d
- pla
- sta z80_e
- tsx ;- ex (sp),hl ;- CALLEE Convention ; H'L'D'E' => Dividend
- lda $0103,x
- ldy z80_h
- sta z80_h
- tya
- sta $0103,x
- lda $0104,x
- ldy z80_l
- sta z80_l
- tya
- sta $104,x
- lda z80_e ;- ex de,hl ;- D'E'.H'L' Dividend
- ldx z80_l
- stx z80_e
- sta z80_l
- lda z80_d
- ldx z80_h
- stx z80_d
- sta z80_h
- __DIVF16START: ; FAST Entry: DEHL => Dividend, D'E'H'L' => Divisor
- lda z80_d ;- ld a,d ; Save sign
- sta z80_a
- ldx z80_ap ;- ex af,af'
- sta z80_ap
- txa
- lda z80_d ;- bit 7,d ; Negative?
- bit 7
- beq *+5 ;- call nz, __NEG32 ; Negates DEHL
- jsr __NEG32
- lda z80_c ;- exx ; Now works with D'E'.H'L'
- ldx z80_cp
- stx z80_c
- sta z80_cp
- lda z80_b
- ldx z80_bp
- stx z80_b
- sta z80_bp
- lda z80_e
- ldx z80_ep
- stx z80_e
- sta z80_ep
- lda z80_d
- ldx z80_dp
- stx z80_d
- sta z80_dp
- lda z80_l
- ldx z80_lp
- stx z80_l
- sta z80_lp
- lda z80_h
- ldx z80_hp
- stx z80_h
- sta z80_hp
- ldx z80_ap ;- ex af,af'
- sta z80_ap
- txa
- eor z80_d ;- xor d
- ldx z80_ap ;- ex af,af' ; Stores sign of the result for later
- sta z80_ap
- txa
- lda z80_d ;- bit 7,d ; Negative?
- bit 7
- beq *+5 ;- call nz, __NEG32
- jsr __NEG32
- lda z80_c ;- exx ; Now we have DE.HL => Dividend
- ldx z80_cp
- stx z80_c
- sta z80_cp
- lda z80_b
- ldx z80_bp
- stx z80_b
- sta z80_bp
- lda z80_e
- ldx z80_ep
- stx z80_e
- sta z80_ep
- lda z80_d
- ldx z80_dp
- stx z80_d
- sta z80_dp
- lda z80_l
- ldx z80_lp
- stx z80_l
- sta z80_lp
- lda z80_h
- ldx z80_hp
- stx z80_h
- sta z80_hp
- lda %16 ;- ld b,16
- sta z80_b
- __SHIFTALOOP:
- ; Tries to shift Dividend to the left
- lda z80_d ;- bit 7,d
- bit 7
- jne __SHIFTB ;- jp nz, __SHIFTB
- asl z80_l ;- add hl,hl
- rol z80_h
- lda z80_e ;- ex_de_hl
- ldx z80_l
- stx z80_e
- sta z80_l
- lda z80_d
- ldx z80_h
- stx z80_d
- sta z80_h
- ;- adc hl,hl
- lda z80_e ;- ex_de_hl
- ldx z80_l
- stx z80_e
- sta z80_l
- lda z80_d
- ldx z80_h
- stx z80_d
- sta z80_h
- ;- djnz __SHIFTALOOP
- jmp __DOF16_DIVRDY ;- jp __DOF16_DIVRDY
- __SHIFTB:
- ; Cannot shift Dividend more to the left, try to shift Divisor to the right
- lda z80_b ;- ld a,b
- sta z80_a
- lda z80_c ;- exx
- ldx z80_cp
- stx z80_c
- sta z80_cp
- lda z80_b
- ldx z80_bp
- stx z80_b
- sta z80_bp
- lda z80_e
- ldx z80_ep
- stx z80_e
- sta z80_ep
- lda z80_d
- ldx z80_dp
- stx z80_d
- sta z80_dp
- lda z80_l
- ldx z80_lp
- stx z80_l
- sta z80_lp
- lda z80_h
- ldx z80_hp
- stx z80_h
- sta z80_hp
- lda z80_a ;- ld b,a
- sta z80_b
- ; Divisor is in DEHL
- __SHIFTBLOOP:
- ;- bit 1, l
- jne __DOF16_DIVIDE ;- jp nz, __DOF16_DIVIDE
- ;- sra d
- ror z80_e ;- rr e
- ror z80_h ;- rr h
- ror z80_l ;- rr l
- dec z80_b ;- djnz __SHIFTBLOOP
- jne __SHIFTBLOOP
- __DOF16_DIVIDE:
- lda z80_b ;- ld a,b
- sta z80_a
- lda z80_c ;- exx
- ldx z80_cp
- stx z80_c
- sta z80_cp
- lda z80_b
- ldx z80_bp
- stx z80_b
- sta z80_bp
- lda z80_e
- ldx z80_ep
- stx z80_e
- sta z80_ep
- lda z80_d
- ldx z80_dp
- stx z80_d
- sta z80_dp
- lda z80_l
- ldx z80_lp
- stx z80_l
- sta z80_lp
- lda z80_h
- ldx z80_hp
- stx z80_h
- sta z80_hp
- lda z80_a ;- ld b,a
- sta z80_b
- __DOF16_DIVRDY:
- lda z80_c ;- exx
- ldx z80_cp
- stx z80_c
- sta z80_cp
- lda z80_b
- ldx z80_bp
- stx z80_b
- sta z80_bp
- lda z80_e
- ldx z80_ep
- stx z80_e
- sta z80_ep
- lda z80_d
- ldx z80_dp
- stx z80_d
- sta z80_dp
- lda z80_l
- ldx z80_lp
- stx z80_l
- sta z80_lp
- lda z80_h
- ldx z80_hp
- stx z80_h
- sta z80_hp
- lda z80_e ;- ex de,hl
- ldx z80_l
- stx z80_e
- sta z80_l
- lda z80_d
- ldx z80_h
- stx z80_d
- sta z80_h
- lda z80_c ;- push bc
- pha
- lda z80_b
- pha
- jsr __DIVU32START ;- call __DIVU32START
- pla ;- pop bc
- sta z80_b
- pla
- sta z80_c
- eor z80_a ;- xor a
- ora z80_b ;- or b
- jmp __ENDF16DIV ;- jp z,__ENDF16DIV
- __SHIFTCLOOP:
- asl z80_l ;- add hl,hl ; Shift DECIMAL PART << 1
- rol z80_h
- lda z80_e ;- ex_de_hl
- ldx z80_l
- stx z80_e
- sta z80_l
- lda z80_d
- ldx z80_h
- stx z80_d
- sta z80_h
- ;- adc hl,hl ; Shift INTEGER PART << 1 Plus Carry
- lda z80_e ;- ex_de_hl
- ldx z80_l
- stx z80_e
- sta z80_l
- lda z80_d
- ldx z80_h
- stx z80_d
- sta z80_h
- dec z80_b ;- djnz __SHIFTCLOOP
- jne __SHIFTCLOOP
- __ENDF16DIV: ; Put the sign on the result
- ldx z80_ap ;- ex af, af' ; Recovers sign
- sta z80_ap
- txa
- and #128 ;- and 128 ; positive?
- bne *+3 ;- ret z
- rts
- jcs __NEG32 ;- jp __NEG32 ; Negates DEHL and returns from there
|