Difference between revisions of "Z80:Advanced Math"
From Learn @ Cemetech
Jump to navigationJump to searchKermMartian (talk | contribs) |
KermMartian (talk | contribs) (Adjusted lowercase z80) |
||
Line 1: | Line 1: | ||
− | |||
− | |||
= Decimal Math = | = Decimal Math = | ||
Line 74: | Line 72: | ||
{{lowercase}} | {{lowercase}} | ||
− | [[Category: | + | [[Category:Z80 Assembly]] |
− | [[Category: | + | [[Category:Z80 Heaven]] |
Revision as of 21:04, 3 February 2016
Contents
Decimal Math
Addition/Subtraction
To do addition or subtraction on an integer of arbitrary size, we use ADC.
LD HL, (word1) ; Get least-significant word of word1 LD DE, (word2) ; Get least-significant word of word2 ADD HL, DE ; Add them LD (result), HL ; Store least-significant result LD HL, (dword1 + 2) ; Get most-significant word of word1 LD DE, (dword2 + 2) ; Get most-significant word of word2 ADC HL, DE ; Add them with the carry from the previous addition LD (result + 2), HL ; Store most-significant result RET word1: .DB $B3, $90, $12, $32 ; Each word is stored with the least-significant word2: .DB $F1, $15, $06, $B8 ; bytes first. You could just as easily have stored result: .DB $00, $00, $00, $00 ; them in big-endian, but because of how registers are ; loaded from RAM, it wouldn't work.
Multiplication
For multiplication, we could just add them in a DJNZ loop. But that is slow for multiplying big numbers. So we just do it like in base 10, where we multiply each digit separately.
.module DE_Times_A DE_Times_A: ; HL = DE ร— A LD HL, 0 ; Use HL to store the product LD B, 8 ; Eight bits to check _loop: RRCA ; Check least-significant bit of accumulator JR NC, _skip ; If zero, skip addition ADD HL, DE _skip: SLA E ; Shift DE one bit left RL D DJNZ _loop RET
Division
Division is also just like base-10 division as well. .module Div_HL_D Div_HL_D: ; HL = HL รท D, A = remainder
XOR A ; Clear upper eight bits of AHL LD B, 16 ; Sixteen bits in dividend
_loop:
ADD HL, HL ; Do a SLA HL RLA ; This moves the upper bits of the dividend into A JR C, _overflow CP D ; Check if we can subtract the divisor JR C, _skip ; Carry means D > A
_overflow:
SUB D ; Do subtraction for real this time INC L ; Set bit 0 of quotient
_skip:
DJNZ _loop RET
Exponentiation and Logarithms
Conclusion
For more info, see the TI-83 Asm in 28 Days, Day 15 (link below).
For ways to perform more accurate math (Floating Point), there are many prebuilt functions that operate on the OP operators. They can be found here.
Sources: