На днях сидел ковырялся с утилитой форматирования. Нужна была процедура деления 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
				