FORMAT/math.asm
2026-04-10 00:16:39 +10:00

215 lines
3.4 KiB
NASM

;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ MATH ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;----------------------------------------------------------------------;
IFUSED DIV_by_Shifts
; HL:DE / A => DE:BC, H=0, L - ®áâ â®ª
DIV_by_Shifts: LD C,A
DEC A
JR Z,.exit
;
AND E
LD B,A ; ®áâ â®ª
LD A,C
RRCA
.loop: SRL H
RR L
RR D
RR E
RRCA
JP NC,.loop
;
LD A,B
.exit: LD B,D
LD C,E
EX DE,HL
LD H,0
LD L,A
RET
ENDIF
;----------------------------------------------------------------------;
;-----------------------------------------------------------------------
; IN:
; DEBC, A
; OUT:
; HLIX = DEBC*A
DEBCxA: LD HL,0
LD IX,0
AND A
RET Z
;
.loop: ADD IX,BC
ADC HL,DE
JP C,STOP_ERROR ; ¤®å¥à 
;
DEC A
JR NZ,.loop
RET
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
AHL_RL_B: SLA L
RL H
RLA
JP C,STOP_ERROR
DJNZ AHL_RL_B
RET
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
AHL_RR_B: AND A
.loop: RRA
RR H
RR L
JP C,STOP_ERROR
DJNZ .loop
RET
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
;HLIX/BC -> HLIX remainder DE
HLIX_div_BC: EX DE,HL
; Negate BC to allow add instead of sbc
XOR A
; Need to set HL to 0 anyways, so save 2cc and a byte
LD H,A
LD L,A
SUB C
LD C,A
SBC A,A
SUB B
LD B,A
LD A,D
CALL .sub8
RLA
LD D,A
LD A,E
CALL .sub8
RLA
LD E,A
LD A,XH
CALL .sub8
RLA
LD XH,A
LD A,XL
CALL .sub8
RLA
LD XL,A
EX DE,HL
RET
;
.sub8: CALL .iter1
.iter1: CALL .iter2
.iter2: CALL .sub
.sub: RLA
ADC HL,HL
JR C,.skip
;
ADD HL,BC
RET C
;
SBC HL,BC
RET
;
.skip: ADD HL,BC
SCF
RET
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
; -> HLDE * BC. BC = á⥯¥­ì ¤¢®©ª¨
; <- AHLDE
; CF=1 - error
MUL32_POWER2: SRL B
RR C
LD A,B
OR C
RET Z
;
XOR A
.loop: EX DE,HL
ADD HL,HL
EX DE,HL
ADC HL,HL
ADC A,0
JP C,STOP_ERROR
;
SRL B
RR C
JR NC,.loop
;
;EX DE,HL
AND A
RET
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
; -> HL / DE. DE = á⥯¥­ì ¤¢®©ª¨
; <- A = HL / DE
; CF=1 - error
DIV16_POWER2: XOR A
.loop: INC A
SBC HL,DE
JR NC,.loop
DEC A
RET Z ; error: ¤¥«¨¬®¥ < ¤¥«¨â¥«ï
CCF
RET
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
MACRO DIV_RL
RL H
RLA
ADD A,C
JR C,.exit
SUB C
.exit:
ENDM
;
;Input: HLDE is numerator, A<129 is the divisor.
;Output: HLDE is quotient, A is remainder, C is negated
HLDE_Div_A: NEG
LD C,A
XOR A
CALL .div
LD B,H
LD H,L
CALL .div
LD L,H
LD H,D
CALL .div
LD D,H
LD H,E
CALL .div
LD E,H
LD H,B
RL E
RL D
ADC HL,HL
RET
;
.div: DIV_RL
DIV_RL
DIV_RL
DIV_RL
DIV_RL
DIV_RL
DIV_RL
RL H
RLA
ADD A,C
RET C
SUB C
RET
;-----------------------------------------------------------------------