На днях сидел ковырялся с утилитой форматирования. Нужна была процедура деления 32:16=16,16 (остаток). Решил позаимствовать процедуру из Flex Navigator, но оказалось, что процедура в командере не рабочая. Провёл несколько тестов, на больших или не ровных (с точки зрения HEX числа) значениях выдаёт всякую фигню. на мелких значениях более или менее работает.
Далее решил проверить сразу несколько процедур. Выбрал из FM, pq-dos и с просторов интернета.
По итогу рабочих процедур нашёл только 2. одна процедура из bdos`а PQ-DOS для Профи, вторая с викии CPC. Процедура из PQ-DOS жрёт около 4000 тактов (чуть больше). Процедура от CPC около 1200 - 1500, но занимает раза в 2 больше места. Провёл на них несколько тестов, обе дают корректные результаты. На CPC процедуре ещё отдельно и остатки протестировал.
размещаю обе процедуры тут, а в командерах требуется замена этих мат.процедур во избежание багов с файлами и ФС в целом!
процедура из PQ-DOS:
Code: Select all
;Input: HL:DE = Dividend, BC = Divisor, HL'= 0
;Output: HL:DE = Quotient, DE' = Remainder
div32_pqdos:
; exx
; push bc ;'
; push hl ;'
; exx
push bc
exx
pop bc ;'
ld hl,0
exx
ld b,32
.d32_1: add hl,hl
ex de,hl
adc hl,hl
ex de,hl
exx
adc hl,hl
or a
sbc hl,bc
jr nc,.d32_2
add hl,bc
exx
dec l
exx
.d32_2: exx
inc l
djnz .d32_1
exx
ex de,hl
; pop hl
; pop bc
exx
ret
Code: Select all
macro div_r
SLA E
RL D
ADC HL, HL
LD A, L
ADD A, C
LD A, H
ADC A, B
JR NC,.t2
ADD HL, BC
INC DE
.t2:
endm
macro div_e
SLA E
RL D
ADC HL, HL
JR C, .t1
LD A, L
ADD A, C
LD A, H
ADC A, B
JR NC, .t2
.t1: ADD HL, BC
INC DE
.t2:
endm
; BCDE = HLDE/BC, HL = HLDE%BC
;1171t
div32x16_cpc: DEC BC
LD A, B
CPL
LD B, A
LD A, C
CPL
LD C, A
ADD A, L
LD A, B
ADC A, H
JR NC, .DIV16
PUSH DE
EX DE, HL
LD HL, 0000
CALL .DIV32R
EX DE, HL
EX (SP), HL
EX DE, HL
CALL .DIV32E
POP BC
RET
.DIV16: CALL .DIV32E
LD BC, 0000
RET
; DE = HLDE/(-BC), HL = HLDE%(-BC), -BC < $8000
.DIV32R: CALL $+3
rept 8
div_r
endm
RET
; DE = HLDE/(-BC), HL = HLDE%(-BC)
.DIV32E: CALL $+3
rept 8
div_e
endm
RET