деление 32-bit

23 views
Skip to first unread message

Vladimir Karpenko

unread,
Jul 19, 2003, 3:46:58 PM7/19/03
to
Hello Vasil
VI> Хаюшки All!

VI> У кого-нить есть пpоцедуpы деления для 32-х битных входных значений ?.
VI> Имею ввиду следующее: чтобы не "кpутить" 64-мя битами на выходе, заюзать
VI> две отдельные пpоцедуpы - одна для частного, дpугая для остатка.

VI> 32 / 32 = 32 частное
VI> 32 / 32 = 32 остаток

VI> Если кто занимался, поделитесь плиз.


Кода я делал spcrc, я использовал деление 32/8 вместо 32/32:)
Я пpосто одно 32х pазpалное число заменял на несколько 8ми pазаpдных!


[ZX][Sprinter registered developer][rw1p2][NedoPC]
Bye

Kirill Frolov

unread,
Jul 27, 2003, 2:27:42 PM7/27/03
to
Hемедленно нажми на RESET, Vasil Ivanov!

On Tue, 08 Jul 03 21:49:04 +0400, Vasil Ivanov wrote:

VI> У кого-нить есть пpоцедуpы деления для 32-х битных входных значений ?.
VI> Имею

VI> ввиду следующее: чтобы не "кpутить" 64-мя битами на выходе, заюзать


VI> две отдельные пpоцедуpы - одна для частного, дpугая для остатка.

VI> 32 / 32 = 32 частное
VI> 32 / 32 = 32 остаток

VI> Если кто занимался, поделитесь плиз.


ifused random
; Генератор случайных чисел, медленный
; (C) Kirill Frolov ~3000 takts.
; hl = random(0..<de) генерация числа в диапазоне
randn
push de
call rand
ex de, hl
pop bc
call mul
ex de, hl
ret
endif

ifused rand
randx dw 0, 0
; Получение случайного числа
; -> hl = случайное число 0..65535 ~2300 takts.
rand
; randx = randx*1103515245 + 12345)>>16) & 077777)
ld de, (randx+2)
ld bc, #4e6d
call mul
push hl
ld de, (randx)
ld bc, #41c6
call mul
pop de
add hl, de
push hl
ld de, (randx)
ld bc, #4e6d
call mul
ld bc, #3039
add hl, bc
ld (randx), hl
pop hl
adc hl, de
ld (randx+2), hl
ret
endif


ifused srand
; Установка генератора случайных чисел
; de = инициирующее значение
srand
ld (randx), de
ret
endif


ifused ldiv
ifndef ldiv
; Беззнаковое 32-разрядное деление
; функция состоит из двух частей:
; 1. 32-разрядное делимое и 16-разрядный
; делитель.
; 2. 32-раздядное делимое и 32-разрядный
; делитель.
; hl'hl = hl'hl / de'de
; de'de = hl'hl % de'de
ldiv
push hl
xor a
ld l, a
ld h, a
sub e
ld e, a
sbc a, d
sub e
ld d, a
exx
pop bc
ld a, 0
sbc a, e
ld e, a
sbc a, d ; de'de=0-divisor
sub e
ld d, a
and e
inc a ; Z=short divisor
push hl
ld hl, 0 ; hl'hl=reminder
exx
pop bc
ld a, b ; a,c,bc'=divident

jr nz, ldiv_long


; divisor = -00de
ld b, 8
rla
ldivs0
rl l
add hl, de
jr c, ldivs1
sbc hl, de
ldivs1 rla
djnz ldivs0

ld b, c
ld c, a
ld a, b
ld b, 8
rla
ldivs2
adc hl, hl
add hl, de
jr c, ldivs3
sbc hl, de
ldivs3 rla
djnz ldivs2
jr ldiv_long1


; divisor=-de'de
ldiv_long
call ldiv_8
ld b, c
ld c, a
ld a, b
call ldiv_8
ldiv_long1
exx
exa
ld a, b
exa
ld b, a
exa
exx
call ldiv_8
exx
exa
ld a, c
exa
ld c, a
exa
exx
call ldiv_8

; result=c,bc',a -> hl'hl
; reminder=hl'hl -> de'de

ex de, hl
ld l, a
ld a, c
exx
ex de, hl
ld h, a
ld l, b
ld a, c
exx
ld h, a
ret


; hl'hl=reminder
; de'de=divisor
; a=divident
ldiv_8
ld b, 8
rla
ldiv_8_0
adc hl, hl
exx
adc hl, hl
exx
add hl, de
exx
adc hl, de
exx
jr c, ldiv_8_1
sbc hl, de
exx
sbc hl, de
exx
ldiv_8_1
rla
djnz ldiv_8_0
ret

endif
endif

ifused div
ifndef div
; функция 16-разрядного беззнакового деления
; (C) Aleksey Malov aka Vivid
; little optimized by Vitaly Vidmirov
; hl = de/bc de = de%bc ~840 takts.
; hl = 0, de = de(dividend) if bc(divisor) == 0.
div
xor a ;меняем знак
sub c ; у делителя
ld c, a
sbc a, b
sub c
ld b, a
ld hl,0 ;обнулили новое делимое
ld a,d ;сначала двигаем
rla ;старший байт делимого
;t=18
; REPEAT 8
rl l ;
add hl,bc ;
jr c,$+4 ;8 раз
sbc hl,bc ;
rla ; t=8*45=360
rl l
add hl,bc
jr c,$+4
sbc hl,bc
rla
rl l
add hl,bc
jr c,$+4
sbc hl,bc
rla
rl l
add hl,bc
jr c,$+4
sbc hl,bc
rla
rl l
add hl,bc
jr c,$+4
sbc hl,bc
rla
rl l
add hl,bc
jr c,$+4
sbc hl,bc
rla
rl l
add hl,bc
jr c,$+4
sbc hl,bc
rla
rl l
add hl,bc
jr c,$+4
sbc hl,bc
rla
; ENDR

ld d,a ;ст. байт результата
ld a,e ;теперь двигаем
rla ;младший байт t=12

; REPEAT 8
adc hl,hl ;
add hl,bc ;
jr c,$+4 ;8 раз
sbc hl,bc ;
rla ; t=8*52=416
adc hl,hl
add hl,bc
jr c,$+4
sbc hl,bc
rla
adc hl,hl
add hl,bc
jr c,$+4
sbc hl,bc
rla
adc hl,hl
add hl,bc
jr c,$+4
sbc hl,bc
rla
adc hl,hl
add hl,bc
jr c,$+4
sbc hl,bc
rla
adc hl,hl
add hl,bc
jr c,$+4
sbc hl,bc
rla
adc hl,hl
add hl,bc
jr c,$+4
sbc hl,bc
rla
adc hl,hl
add hl,bc
jr c,$+4
sbc hl,bc
rla
; ENDR

ld e,a ;мл. байт результата
;hl-остаток от деления
;t=4
ex de, hl
ret
endif
endif

ifused lmul
ifndef lmul
; Беззнаковое умножение 32-разрядных
; чисел
; de'de,hl'hl=hl'hl*de'de
lmul
ld a, h
exa
ld a, l
exx
ld c, l
ld b, h
exa
exx ; bc'a'a=2-nd mult.

; hl'hl=production
; de'de=multiplicator
; a = 2-nd multiplicator

call lmul_8
push af
exx
push hl ; hi
exa
exx
push hl ; low
call lmul_8
push af
exx
push hl
ld a, c
exx
push hl
call lmul_8
push af
exx
push hl
ld a, b
exx
push hl
call lmul_8

; 76543210
;= DEdeHLhl
;0 aHLhl =
;1 BbcBC pop +
;2 bBCbc pop +
;3 bBCbc pop +

;0
exx
ld d, a
ld e, h
ld a, l
exx
ld d, a
ld e, h
ld a, l
ld hl, 0
exx
ld h, a
ld l, 0
;exx
;ld hl, 0
;1
;exx
pop bc
add hl, bc
exx
pop bc
ex de, hl
adc hl, bc
ex de, hl
exx
pop bc
ld a, b
adc a, e
ld e, a
adc a, d
sub e
ld d, a
exx
;2
pop bc
ld a, c
add a, h
ld h, a
ld a, b
exx
pop bc
adc a, l
ld l, a
ld a, c
adc a, h
ld h, a
ld a, b
exx
adc a, e
ld e, a
pop bc
ld a, b
adc a, d
ld d, a
exx
ld a, 0
adc a, e
ld e, a
adc a, d
sub e
ld d, a
exx
;3
pop bc
add hl, bc
exx
pop bc
adc hl, bc
exx
pop bc
ld a, b
adc a, e
ld e, a
adc a, d
sub e
ld d, a
exx
ld a, 0
adc a, e
ld e, a
adc a, d
sub e
ld d, a
exx
ret

; hl'hl=0
; de'de=multiplicator
; a=2-nd multiplicator
lmul_8
ld hl, 0
exx
ld hl, 0
exx
ld b, 8
add a, a
jr lmul_8_2
lmul_8_0
add hl, hl
exx
adc hl, hl
exx
rla
lmul_8_2
jr nc, lmul_8_1
add hl, de
exx
adc hl, de
exx
adc a, 0
lmul_8_1
djnz lmul_8_0
ret

endif
endif


ifused mul
ifndef mul
; функция беззнакового умножения 16-разрядных чисел
; (C) Kirill Frolov
; idea by Vasil Ivanov
; dehl=de*bc ~730t.
mul
ld hl, 0
ld a, c
ld c, l ; 18

add a, a
jr nc, $+4
add hl, de
adc a, c ; 29
; REPEAT 7
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c ; 40*7 309
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c
; ENDR

ld c, a
push hl ; 0chl
ld hl, 0
ld a, b
ld b, l ; 33

add a, a
jr nc, $+4
add hl, de
add a, b ; 29
; REPEAT 7
add hl, hl
rla
jr nc, $+4
add hl, de
add a, b ; 40*7 309
add hl, hl
rla
jr nc, $+4
add hl, de
add a, b
add hl, hl
rla
jr nc, $+4
add hl, de
add a, b
add hl, hl
rla
jr nc, $+4
add hl, de
add a, b
add hl, hl
rla
jr nc, $+4
add hl, de
add a, b
add hl, hl
rla
jr nc, $+4
add hl, de
add a, b
add hl, hl
rla
jr nc, $+4
add hl, de
add a, b
; ENDR

; ahl0 + 0cde = hlde
pop de
ld b, l
ld l, h
ld h, a
ld a, d
add a, b
ld d, a
ld b, 0
adc hl, bc
ex de, hl ; 60

ret ; 729t.
endif
endif


ifused amul
ifndef amul
; функция 8-разрядного умножения с суммированием
; (C) Kirill Frolov
; hl = hl + a*de ~338 takts.
amul
add a, a
jr nc, $+4
add hl, de
adc a, c ; 39
;repeat 7
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c ; 40*7 309
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c
add hl, hl
rla
jr nc, $+4
add hl, de
adc a, c
;endr
ret
endif
endif


ifused sqrt
ifndef sqrt
; функция вычисления квадратного корня 16-разрядных чисел
; (C) Aleksey Malov aka Vivid
; a = sqrt(hl) ~470 takts.
sqrt
xor a ;обнулили a ;-)
ld de,64 ;этого требует алгоритм
; t=14
sla h ;берем два самых левых
adc a,a ;бита аргумента
sla h ;
adc a,a ;
jr z,$+4 ;если они не равны
dec a ;нулю, то увеличиваем
inc d ;результат
; t=39
; REPEAT 3
sla h ;далее следуем
adc a,a ;алгоритму извлечения
sla h ;квадратного корня
adc a,a ;"столбиком", только
sla d ;
ld c,d ;3 раза
sli c ;
cp c ;
jr c,$+4 ;
sub c ;
inc d ; t=63*3=189
sla h
adc a,a
sla h
adc a,a
sla d
ld c,d
sli c
cp c
jr c,$+4
sub c
inc d
sla h
adc a,a
sla h
adc a,a
sla d
ld c,d
sli c
cp c
jr c,$+4
sub c
inc d
; ENDR

; REPEAT 2
sla l ;проделываем похожую
adc a,a ;операцию с
sla l ;младшим байтом
adc a,a ;аргумента
sla d ;
ld c,d ;2 раза
sli c ;
cp c ;
jr c,$+4 ;
sub c ;
inc d ; t=63*2=126
sla l
adc a,a
sla l
adc a,a
sla d
ld c,d
sli c
cp c
jr c,$+4
sub c
inc d
; ENDR

ld h,a ;
or a ;обнулили флаг переноса
; t=8
sbc hl,de ;теперь нам не хватает
jr nc,$+3 ;одного регистра d для
add hl,de ;выполнения последних
ccf ;двух циклов, придется
rl d ;использовать более
add hl,hl ;медленные операции
add hl,hl ;с регистровыми парами
; t=67
sbc hl,de ;и последний раз
ccf ;выполняем расчеты, не
ld a,d ;восстанавливая hl
adc a,a ;в a-результат
; t=27
ret
endif
endif

ifused l2bcd
ifndef l2bcd
; de,hl -> c,d,e,h,l
l2bcd
exx
ld bc, #2000
ld l, c
ld h, c
ld e, l
ld d, h
l2bcd0
exx
add hl, hl
ex de, hl
adc hl, hl
ex de, hl
exx
ld a, l
adc a, a
daa
ld l, a
ld a, h
adc a, a
daa
ld h, a
ld a, e
adc a, a
daa
ld e, a
ld a, d
adc a, a
daa
ld d, a
ld a, c
adc a, a
daa
ld c, a
djnz l2bcd0
ret
endif
endif


ifused i2bcd
ifndef i2bcd
; функция переводит 16-разрядное беззнаковое
; двоичное число в двоично-десятичный формат
; (C) Kirill Frolov
; e,h,l = bin2bcd(hl) ~1330 takts.
i2bcd
ld bc, #1000
ld e, c
ld d, c
i2bcd0
add hl, hl
ld a, e
adc a, a
daa
ld e, a
ld a, d
adc a, a
daa
ld d, a
rl c
djnz i2bcd0 ; ~83 ~1328
ex de, hl
ld e, c
ret
endif
endif


ifndef htoa
ifused htoa
; a=0..FF, HL=str[3] -> hl=*0
htoa
push af
rra
rra
rra
rra
call nib2hex
pop af
nib2hex and #0f
cp #0a
sbc a, #69
daa
ld (hl), a
inc hl
ld (hl), 0
ret
endif
endif


ifused atow
ifndef atow
; hl=*str -> hl=num, de=*last+1,
; CF=1 error -> hl=*pos
atow
; skip all spaces
atow_sp
ld a, (hl)
call isspace
jr nz, atow_st
inc hl
jr atow_sp
atow_st
ld de, 0
ld a, (hl)
or a
scf
ret z
sub "0"
ret c
cp 9+1
jr c, atow_dig
scf
ret

atow0
ld a, (hl)
sub "0"
jr c, atow_ok
cp 9+1
jr nc, atow_ok
atow_dig
ex de, hl
call atowm10
ex de, hl
ret c ; overflow
inc hl
jr atow0

atowm10
add hl, hl
ret c
ld c, l
ld b, h
add hl, hl
ret c
add hl, hl
ret c
add hl, bc
ret c
ld c, a
ld b, 0
add hl, bc
ret

atow_ok
xor a
ex de, hl
ret

endif
endif

ifused wtoa
ifndef wtoa
; функция записывает 16-разрядное беззнаковое число
; в десятичном виде, ведущие нули отбрасываются.
; по адресу (hl) будет записано 5 цифр числа и
; символ с кодом 0 завершающий строку.
; (C) Kirill Frolov
; *hl = itoa(de) -> hl=указатель на завершающий 0.
wtoa
push hl
ex de, hl
call i2bcd
ld a, e
ex de, hl
pop hl

or a
jr nz, ltoa5
ld a, d
and #f0
jr nz, ltoa6
ld a, d
and #0f
jr nz, ltoa7
ld a, e
and #f0
jr nz, ltoa8
ld a, e
jr ltoa9
endif
endif


ifused ltoa
ifndef ltoa
; long de,bc -> string(hl[11])
; -> hl=*0
ltoa
; TODO check
push hl
ld l, c
ld h, b
call l2bcd
ex de, hl
ex (sp), hl
ld a, c
exa
ld a, c
pop bc

and #f0
jr nz, ltoa0
exa
and #0f
jr nz, ltoa1
ld a, b
and #f0
jr nz, ltoa2
ld a, b
and #0f
jr nz, ltoa3
ld a, c
and #f0
jr nz, ltoa4
ld a, c
and #0f
jr nz, ltoa5
ld a, d
and #f0
jr nz, ltoa6
ld a, d
and #0f
jr nz, ltoa7
ld a, e
and #f0
jr nz, ltoa8
ld a, e
jr ltoa9

; a,a',b,c,d,e
ltoa0
ld (hl), a
ld a, #33
rrd
inc hl
ltoa1
or #30
ld (hl), a
inc hl
ltoa2
ld (hl), b
ld a, #33
rrd
inc hl
ltoa3
or #30
ld (hl), a
inc hl
ltoa4
ld (hl), c
ld a, #33
rrd
inc hl
endif
endif
ifused ltoa5
; a,d, e
ltoa5
or #30
ld (hl), a
inc hl
ltoa6
ld (hl), d
ld a, #33
rrd
inc hl
ltoa7
or #30
ld (hl), a
inc hl
ltoa8
ld (hl), e
ld a, #33
rrd
inc hl
ltoa9
or #30
ld (hl), a

inc hl
ld (hl), 0
ret
endif

Reply all
Reply to author
Forward
0 new messages