Mathematical procedures.
ZXNet echo conference «code.zx»
From Aleksey Malov → To All 4 April 2000
Greetings, All!
So, procedure number 1: quick division 16/16. To the one who can do it
speed up, it will be possible to erect a monument during his lifetime (at his expense). Acceleration
by replacing jr with jp is not considered, because winning/losing in
speed depends on the size of the arguments.
At the entrance:
de-divisible
bc divisor
Output:
de-quotient
hl-residue
divide ld a,b ;change
cpl ;
ld b,a ;sign
ld a,c ;
cpl;y
ldc,a ;
inc bc ;divisor t=30
ld hl,0 ;reset the new dividend to zero
ld a,d ;move first
rla ;high byte of dividend
;t=18
rl l ;┐
add hl,bc ;│
jr c,$+4 ;│8 times
sbc hl,bc ;│
rla ;┘ t=8*45=360
ld d,a ;st. result byte
ld a,e ;now move
rla ;low byte t=12
adc hl,hl ;┐
add hl,bc ;│
jr c,$+4 ;│8 times
sbc hl,bc ;│
rla ;┘ t=8*52=416
ld e,a ;ml. result byte
;hl-remainder of division
;t=4
Total:
30+18+360+12+416+4=840 cycles.
If the remainder is not needed, then the end of the process is
fools should look like this:
adc hl,hl ;┐
add hl,bc ;│
jr c,$+4 ;│7 times
sbc hl,bc ;│
rla ;┘ t=7*52=364
adc hl,hl ;
add hl,bc ;rla ;
ld e,a ; t=34
Total:
30+18+360+12+364+34=818 cycles.
P.S. If you divide by zero, then, as you would expect, the quotient
will be equal to zero, and the remainder will be equal to the dividend, i.e. in this regard, the procedure
there are no glitches.
;*************************
Procedure number 2: taking the square root of a register pair. Here
here we really need to erect a monument to someone who will speed up the procedure
at least for 1 beat. Acceleration by replacing jr with jp is not considered,
because gain/loss in speed depends on the size of the argument.
At the entrance:
hl-number from which to extract
square root
at the output:
a-square root of hl
sqrhl xor a ;zeroed a ;-)
ld de,64 ;this is required by the algorithm
; t=14
sla h ;take the two leftmost
adc a,a ;argument bit
sla h;
adc a,a ;
jr z,$+4 ;if they are not equal
dec a ;zero, then increase
inc d ;result
; t=39
sla h ;┐follow
adc a,a ;│extraction algorithm
sla h ;│square root
adc a,a ;│"column", only
sla d ;│
ld c,d ;│3 times
sli c ;│
cp c ;│
jr c,$+4 ;│
subc ;│
inc d ;┘ t=63*3=189
sla l ;┐do something similaradc a,a ;│operation with
sla l ;│low byte
adc a,a ;│argument
sla d ;│
ld c,d ;│2 times
sli c ;│
cp c ;│
jr c,$+4 ;│
subc ;│
inc d ;┘ t=63*2=126
ld h,a ;
or a ;cleared the carry flag
; t=8
sbc hl,de ;now we lack
jr nc,$+3 ;one register d for
add hl,de ;execute the last
ccf ;two cycles, will have to
rl d ;use more
add hl,hl ;slow operations
add hl,hl ;with register pairs
; t=67
sbc hl,de ;and last time
ccf ;perform calculations, not
ld a,d ;restoring hl
adc a,a ;in a-result
; t=27
Total:
14+39+189+126+8+67+27=470 cycles.
Procedure number 3: extracting the square root of a three-byte number.
Speeding up by replacing jr with jp is not considered, because winning/losing in
speed depends on the value of the argument.
At the entrance:
dhl=d*65536+hl - the number itself
Output:
hl - the same square root
sqrdhl xor a ;beginning of procedure
ld bc,64 ;almost the same
;previous
; t=14
sla d ;
adc a,a ;
sla d ;
adc a,a ; t=39
jr z,$+4 ;
dec a ;inc b ;
leaf d ;┐
adc a,a ;│
leaf d ;│
adc a,a ;│
page b ;│
ld e,b ;│3 times
slip and ;│
cp and ;│
jr c,$+4 ;│
sub and ;│
inc b ;┘ t=3*63=189
leaf h ;┐
adc a,a ;│
leaf h ;│
adc a,a ;│
page b ;│
ld e,b ;│2 times
slip and ;│
cp and ;│
jr c,$+4 ;│
sub and ;│
inc b ;┘ t=63*2=126
ld d,l ;
ld l,h ;
ld h,a ;change registers
or a ; t=16
sbc hl,bc;┐
jr nc,$+3;│
add hl,bc;│
ccf ;│2 times
rl b ;│
add hl,hl;│
add hl,hl;┘ t=67*2=134
ld l,h ;there is a suspicion that
ld h,0 ;this block and previous
ld c,b ;you can speed up a bit
ld b,h ;
rl h ;
ld a,d ; t=31
rla ;┐yes and this unit is mine
adc hl,hl;│dislike.
rla ;│very likely that
adc hl,hl;│it can be fine
sla c ;│accelerate. But how?
rl b ;│
ld d,b ;│
ld and c ;│3 times
slip and ;│
rl d ;│
sbc hl,of;│
jr nc,$+4;│
add hl,of;│
Dec c ;│
inc c ;┘ t=3*119=357 (!)
;horror! Think about how;speed up!
rla; this block is similar
adc hl,hl;previous with
rla ;small difference
adc hl,hl;at the end. It's done
ld d,b ;for the sake of promotion
ld e,c ;calculation speed
sla e;
rl d ;
sli e;
rl d ;
sbc hl,de;
ccf ; t=97
ld h,b ;
ld l,c ;
adc hl,hl;in hl - result
; t=23
Total:
14+39+189+126+16+134+31+357+97+23=1026.
;*******************
Well, and the procedure for calculating the address in attributes using coordinates in familiar places.
You can't do it faster if you don't use tables.
At the entrance:
d-y
e-x
Output:
hl-address in attributes
ld a,d
rrca
rrca
rrca
ld h,a
and #e0
or e
ld l,a
xor e
xor h
or #58
ld h,a
t=54 clock cycles.
I wish you health, happiness and creative Uzbeks.
Aleksey Malov aka VIVID/Brainwave.
From Vitaly Vidmirov → To Aleksey Malov 5 April 2000
I`m happy to meet you again, Aleksey!
last time (04 Apr 00 01:03:19) you talk about something
AM> So, procedure number 1: quick division 16/16. To those who can
AM> speed it up, it will be possible to erect a monument during his lifetime (at his expense).
AM> divide ld a,b ;change
AM> cpl ;
AM> ld b,a ;sign
AM> ld a,c ;
AM> cpl ;у
AM> ld c,a ;
AM> inc bc ;divisor t=30
immediately caught my eye
xor a
sub c
ldc,a
sbc a,b
sub c
ld b,a
30 -> 24.
I'll watch the rest when I have time. Don't forget that they exist
and other division algorithms...
catch my respects, Alexey