📄 extras.asm
字号:
push acc ; push ZL0
mov XL, XH ; put XH in XL
lcall BMW ; multiply XH with (YH:YL)
mov b, Z0 ; save ZH0 in b register
pop Z0 ; recall ZL0
pop a ; restore ZL1 in accumulator
add a, b ; add ZH0 and ZL1
mov b, ZH1 ; save ZH1 in b register
mov Z1, a ; save result
pop a ; restore ZL2 in accumulator
addc a, b ; add ZH1 and ZL2 with carry from ZH0+ZL1
mov b, Z2 ; save ZH2 in b register
mov Z2, a ; save ZH1+ZL2+C in Z2
clr a ; clear accumulator
addc a, b ; add ZH2 with carry from ZH1+ZL2
mov Z3, a ; save result
ret ; done
mov a, X ; load X into accumulator
mov b, YL ; load Y low byte into b register
mul ab ; multiply
mov Z0, a ; save result low byte
push b ; push result high byte
; this byte needs to be added to the low
; byte of the product X*YH
mov a, X ; load X into accumulator
mov b, YH ; load Y high byte into b register
mul ab ; multiply
pop r0 ; recall X*YL high byte
add a, r0 ; add X*YL high byte and X*YH low byte
mov Z1, a ; save result
clr a ; clear accumulator
addc a, b ; a = b + carry flag
mov Z2, a ; save result
ret ; done
;====================================================================
; subroutine DIV16
; 16-Bit Unsigned Division
;
; input: internal registers XH, XL, YH, and YL hold the high and
; low bytes of the unsigned dividend and divisor.
; output: internal registers Z3 and Z2 hold high and low bytes of
; the quotient of Z=X竃. internal registers Z1 and Z0 hold
; the high and low bytes of the remainder. addressible bit
; ZOV is set if Y=0, i.e., the result is out of range.
;
; r1 and r0 store the high and low bytes of the partial
; remainder. r3 and r2 hold the partially computed quotient.
;
; calls: SUB16
; destroys: a, r0, r1, r2, r3, r7, flags
;====================================================================
DIV16:
mov a, YH ; get divisor high byte
orl a, YL ; OR with low byte
jnz div_OK ; divisor OK if not 0
setb ZOV ; else, overflow
ret
div_OK:
mov r1, XH ; store dividend in r1, r0
mov r0, XL
mov XH, #0 ; clear partial remainder
mov XL, #0
mov r3, #0 ; clear partial quotient
mov r2, #0
mov r7, #16 ; set loop count
div_loop:
clr C ; clear carry flag
mov a, r0 ; shift the highest bit of the dividend...
rlc a ; ... into...
mov r0, a
mov a, r1
rlc a
mov r1, a
mov a, XL ; ... the lowest bit of the partial ...
rlc a ; ... remainder
mov XL, a
mov a, XH
rlc a
mov XH, a
lcall SUB16 ; attempt to subtract to see if the...
; ... partial remainder is as large or...
; ... larger than the divisor.
mov C, ZOV ; get subtraction external barrow
cpl C ; complement external barrow
mov a, r3 ; add result bit to partial quotient
rrc a
mov r3, a
mov a, r2
rrc a
mov r2, a
djnz r7, div_loop
mov Z3, r3 ; put quotient in Z3, and Z2
mov Z2, r2
mov Z1, XH ; get remainder, saved before the...
mov Z0, XL ; last subtraction
clr ZOV ; divisor is not 0
ret ; done
;====================================================================
; subroutine DIV32
; 32-Bit Unsigned Division
;
; input: internal registers X3, X2, X1, and X0 hold the 32-bit
; unsigned dividend. similarly, internal registers Y1 and
; Y0 hold the high and low bytes of the unsigned divisor.
;
; output: internal registers Z5, Z4, Z3, and Z2 hold the 32-bit
; quotient of Z=X竃. internal registers Z1 and Z0 hold
; the high and low bytes of the remainder. addressible bit
; ZOV is set if Y=0, i.e., the result is out of range.
;
; internal registers PR3, PR2, PR1, and PR0 store the
; partial remainder. r5, r4, r3, and r2 hold the partially
; computed quotient.
;
; calls: SUB16
; destroys: a, r2, r3, r4, r5, r7, flags
;====================================================================
DIV32:
mov a, Y1 ; get divisor high byte
orl a, Y0 ; OR with low byte
jnz div32_OK ; divisor OK if not 0
setb ZOV ; else, overflow
ret
div32_OK:
mov Y2, #0 ; high 16 bits of Y is 0
mov Y3, #0
mov PR3, X3 ; store dividend
mov PR2, X2
mov PR1, X1
mov PR0, X0
mov X3, #0 ; clear partial remainder
mov X2, #0
mov X1, #0
mov X0, #0
mov r3, #0 ; clear partial quotient
mov r2, #0
mov r7, #32 ; set loop count
div32_loop:
clr C ; clear carry flag
mov a, PR0 ; shift the highest bit of the dividend...
rlc a ; ... into...
mov PR, a
mov a, PR1
rlc a
mov PR1, a
mov a, PR2
rlc a
mov PR2, a
mov a, PR3
rlc a
mov PR3, a
mov a, X0 ; ... the lowest bit of the partial ...
rlc a ; ... remainder
mov X0, a
mov a, X1
rlc a
mov X1, a
mov a, X2
rlc a
mov X2, a
mov a, X3
rlc a
mov X3, a
lcall SUB32 ; attempt to subtract to see if the...
; ... partial remainder is as large or...
; ... larger than the divisor.
mov C, ZOV ; get subtraction external barrow
cpl C ; complement external barrow
mov a, r5 ; add result bit to partial quotient
rrc a
mov r5, a
mov a, r4
rrc a
mov r4, a
mov a, r3
rrc a
mov r3, a
mov a, r2
rrc a
mov r2, a
djnz r7, div32_loop
mov Z5, r5 ; put quotient in Z3, and Z2
mov Z4, r4
mov Z3, r3
mov Z2, r2
mov Z1, X1 ; get remainder, saved before the...
mov Z0, X0 ; last subtraction
clr ZOV ; divisor is not 0
ret ; done
;====================================================================
; subroutine SADD16
; 16-Bit Signed (Two's Complement) addition
;
; input: internal registers XH, XL, YH, and YL hold the high and
; low bytes of the signed words in two's complement
; convension
; output: internal registers ZH and ZL hold high and low bytes of
; the signed word Z=X+Y. addressible bit ZOV is set if
; the result (Z) is out of range (-32768 to 32767)
; destroys: a, flags
;====================================================================
SADD16:
mov a, XL ; load X low byte into accumulator
add a, YL ; add Y low byte
mov ZL, a ; put result in Z low byte
mov a, XH ; load X high byte into accumulator
addc a, YH ; add Y high byte with the carry from low ...
; ... byte operation
mov ZH, a ; save result in Z high byte
mov C, OV ; get the overflow flag and ...
mov ZOV, C ; ... transfer to bit ZOV
ret ; done
;====================================================================
; subroutine SSUB16
; 16-Bit Signed (Two's Complement) subtraction
;
; input: internal registers XH, XL, YH, and YL hold the high and
; low bytes of the signed words in two's complement
; convension
; output: internal registers ZH and ZL hold high and low bytes of
; the signed word Z=X-Y. addressible bit ZOV is set if
; the result (Z) is out of range (-32768 to 32767)
; destroys: a, flags
;====================================================================
SSUB16:
mov a, XL ; load X low byte into accumulator
clr C ; clear carry flag
subb a, YL ; subract Y low byte
mov ZL, a ; put result in Z low byte
mov a, XH ; load X high byte into accumulator
subb a, YH ; subtract Y high byte with the barrow ...
; ... from low byte operation
mov ZH, a ; save result in Z high byte
mov C, OV ; get the overflow flag and ...
mov ZOV, C ; ... transfer to bit ZOV
ret ; done
;===============================================================
; subroutine SMUL16
; multiplication of signed 16-Bit words in the Absolute Value /
; Sign Bit format
;
; input: internal registers XH, XL and YH, YL hold the
; magnitudes of the two signed words to be multiplied.
; The addressible bits XS and YS are set if the
; corresponding number is negative.
; output: the absolute value of the result is placed in the 4
; internal registers named Z3, Z2, Z1, and Z0.
; Addressable bit ZS is set if the result is negative.
; calls: MUL16
; destroys: a
;================================================================
SMUL16:
lcall MUL16 ; multiply absolute values
mov C, XS ; get sign of X
xrl C, YS ; exor with the sign of Y
mov ZS, C ; save as sign of the result
ret
;===============================================================
; subroutine SDIV16
; division of signed 16-Bit words in the Absolute Value / Sign
; Bit format
;
; input: internal registers XAH, XAL and YAH, YAL hold the
; magnitudes of the two signed words. the addressable
; bits XS and YS are set if the corresponding number is
; negative.
; output: the absolute value of the result Z=X竃 is placed in
; the 4 internal registers named Z3, Z2, Z1, and Z0.
; addressable bit ZS is set if the result is negative,
; and ZOV is set if Y=0.
; calls: DIV16
; destroys: a
;================================================================
SDIV16:
lcall DIV16 ; multiply absolute values
mov C, XS ; get sign of X
xrl C, YS ; exor with the sign of Y
mov ZS, C ; save as sign of the result
ret
;===============================================================
; subroutine SDIV16
; division of signed 16-Bit words in the Absolute Value / Sign
; Bit format
;
; input: internal registers XH, XL and YH, YL hold the
; magnitudes of the two signed words. the addressable
; bits XS and YS are set if the corresponding number is
; negative.
; output: the absolute value of the result Z=X竃 is placed in
; the 4 internal registers named Z3, Z2, Z1, and Z0.
; addressable bit ZS is set if the result is negative,
; and ZOV is set if Y=0.
; calls: DIV16
; destroys: a
;================================================================
SDIV16:
lcall DIV16 ; multiply absolute values
mov C, XS ; get sign of X
xrl C, YS ; exor with the sign of Y
mov ZS, C ; save as sign of the result
ret
;====================================================================
; subroutine FMUL
; multiply two floating point numbers
;
; input: internal registers X2, X1, X0 and Y2, Y1, Y0 hold the
; two floating point numbers to be multiplied.
; output: the product Z = X
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -