|
nedoPC.orgElectronics hobbyists community established in 2002 |
|
Author |
Message |
Sayman
Maniac
Joined: 05 Oct 2009 19:44 Posts: 223 Location: 212.164.105.5
|
Приветствую. На днях сидел ковырялся с утилитой форматирования. Нужна была процедура деления 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: ;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
| | | | |
процедура из викии CPC (причёсанная под sjasm/sjasmplus): | | | | Code: 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
| | | | |
|
18 Feb 2021 00:22 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22607 Location: Silicon Valley
|
b2m предложил ещё более быстрый и короткий вариант: https://zx-pk.ru/threads/32913-32-bit-delenie.html(переписка с 8080 из книги Гуртовцева, Гудыменко ): | | | | Code: DIV32: ld a,b ; DE = HLDE/BC, HL = HLDE%BC cpl ld b,a ld a,c cpl ld c,a inc bc xor a DIV321: add hl,hl rra ex de,hl add hl,hl ex de,hl jr nc, DIV320 inc hl DIV320: push hl add hl,bc jr nc, DIV322 rla DIV323: inc de inc sp inc sp add a, 10h jr nc, DIV321 ret DIV322: rla jr c, DIV323 pop hl add a, 10h jr nc, DIV321 ret
| | | | |
Я попробовал - не выходит получить выгоду от таких замен на z80-инструкции - выходит заметно больше кода который исполняется медленнее - так что лучше оставить как есть...
|
18 Feb 2021 02:17 |
|
|
b2m
Devil
Joined: 26 May 2003 06:57 Posts: 863
|
А если так: | | | | Code: DIV32: xor a ; DE = HLDE/BC, HL = HLDE%BC DIV321: ex de,hl add hl,hl ex de,hl adс hl,hl rra push hl ccf sbс hl,bc jr c, DIV322 rla DIV323: inc de inc sp inc sp add a, 10h jr nc, DIV321 ret DIV322: rla jr c, DIV323 pop hl add a, 10h jr nc, DIV321 ret
| | | | |
Если хочется ещё компактнее, можно три повторяющиеся команды конца цикла заменить на одну jr А ещё, можно чуть ускорить, если не делать push hl / inc sp / inc sp когда не надо. Тогда и rla / rra можно будет выкинуть, но за счёт дополнительной sbс hl,bc, конечно.
_________________Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
Last edited by b2m on 18 Feb 2021 05:52, edited 1 time in total.
|
18 Feb 2021 05:21 |
|
|
b2m
Devil
Joined: 26 May 2003 06:57 Posts: 863
|
Вот, даже проверял, вроде правильно: | | | | Code: DIV32: ld a,10h ; DE = HLDE/BC, HL = HLDE%BC DIV321: ex de,hl add hl,hl ex de,hl adс hl,hl jr c DIV322 push hl sbс hl,bc jr nc, DIV323 pop hl jr DIV325 DIV322: ccf sbс hl,bc jr DIV324 DIV323: inc sp inc sp DIV324: inc de DIV325: dec a jr nz, DIV321 ret
| | | | |
_________________Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
|
18 Feb 2021 05:39 |
|
|
b2m
Devil
Joined: 26 May 2003 06:57 Posts: 863
|
Кстати, если делитель и частное не превышают 32767 (например если используется арифметика со знаком и перед вызовом эти числа приводятся к положительным), то ветку DIV322 можно смело выкинуть.
_________________Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
|
18 Feb 2021 07:12 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22607 Location: Silicon Valley
|
чото там выше вперемешку русские c в мнемониках ассемблера - вот причесал: | | | | Code: DIV32MM: ; DE = HLDE/BC, HL = HLDE%BC ld a,10h DIV321MM: ex de,hl add hl,hl ex de,hl adc hl,hl jr c,DIV322MM push hl sbc hl,bc jr nc,DIV323MM pop hl jr DIV325MM DIV322MM: ccf sbc hl,bc jr DIV324MM DIV323MM: inc sp inc sp DIV324MM: inc de DIV325MM: dec a jr nz,DIV321MM ret
| | | | |
Воде работает
|
18 Feb 2021 10:46 |
|
|
b2m
Devil
Joined: 26 May 2003 06:57 Posts: 863
|
ivagor, как обычно, оптимизировал мой код | | | | Code: DIV32: ld a,10h ; DE = HLDE/BC, HL = HLDE%BC DIV321: ex de,hl add hl,hl ex de,hl adc hl,hl jr c, DIV322 sbc hl,bc jr nc, DIV323 add hl,bc jr DIV324 DIV322: ccf sbc hl,bc DIV323: inc de DIV324: dec a jr nz, DIV321 ret | | | | |
_________________Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
|
18 Feb 2021 10:50 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22607 Location: Silicon Valley
|
Дублирование в двух форумах не всегда синхронно - новая версия от b2m
|
18 Feb 2021 11:26 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22607 Location: Silicon Valley
|
Самая быстрая подпрограмма от b2m если делитель 15-битный апдейт: - - - Добавлено - - - 1162 тактов максимум - - - Добавлено - - - 209 байт
|
18 Feb 2021 12:36 |
|
|
Sayman
Maniac
Joined: 05 Oct 2009 19:44 Posts: 223 Location: 212.164.105.5
|
сам же и исправляю свой косяк - изначальная процедура на 2055тактов. последняя (через 1 пост вверх) 1456 тактов, но в каких диапазонах работает не известно, надо тоже проверять. на моих значениях работает вроде нормально. последняя процедура с 15битами обрезанная, не смотрел, т.к. не полный диапазон не интересен.
|
18 Feb 2021 21:03 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22607 Location: Silicon Valley
|
да - последний вариант для твоих целей неинтересен - из него надо деления со знаком сделать (убирать минус если есть, передавать в эту подпрограмму как 31-битное делимое и 15-битный делитель и потом возвращать знак обратно, если надо)
|
18 Feb 2021 23:00 |
|
|
Alekcandr
Doomed
Joined: 01 Oct 2007 10:30 Posts: 665 Location: Ukraine
|
Sayman, а в чем проблема? Взять готовую процедуру из исходников, которых пруд пруди. Тема избитая и 1000 раз проверенная. Ну, пусть на 100 тактов медлееееенней. Операция деления тяжелая, на 3.5Мгц всегда была не спешная, как и FAT16. Есть ведь много интересных штук, а тут опять изобретаем колесо. p.s. вот допустим. в MSX вложен один вайт в цикл M1. это минус 20% быстродействия. надо доработать? нет. как говорил один уважаемый программист на MSX - это не проблема, есть, много других интересных и не исследованных штук. возможно, математику имеет смысл дорабатывать под эксклюзивную штуку с особой заточкой. но вот так под универсал? если нужно очень. можно разделить задачу на несколько этапов деления (16/16 c остатком). это высший пилотаж. когда все основные штуки в программе работают. мопед не мой. еще подумавши. в целом не понятна задача. зачем 32 на 16. может возможно это упрастить? а когда не понятна задача, это капец во что может выльется
_________________Эмулятор OrionEXT:
http://www.orion-ext.narod.ru
|
20 Feb 2021 02:15 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22607 Location: Silicon Valley
|
просто оказалось, что процедуры деления, использованные в программах на Спринтере неработают нормально на всём диапазоне входных значений - вот и начался поиск новых решений, способных поделить то, что Сайману надо было поделить...
|
20 Feb 2021 12:41 |
|
|
Sayman
Maniac
Joined: 05 Oct 2009 19:44 Posts: 223 Location: 212.164.105.5
|
| | | | Alekcandr wrote: Sayman, а в чем проблема? Взять готовую процедуру из исходников, которых пруд пруди. Тема избитая и 1000 раз проверенная. Ну, пусть на 100 тактов медлееееенней. Операция деления тяжелая, на 3.5Мгц всегда была не спешная, как и FAT16. Есть ведь много интересных штук, а тут опять изобретаем колесо. p.s. вот допустим. в MSX вложен один вайт в цикл M1. это минус 20% быстродействия. надо доработать? нет. как говорил один уважаемый программист на MSX - это не проблема, есть, много других интересных и не исследованных штук. возможно, математику имеет смысл дорабатывать под эксклюзивную штуку с особой заточкой. но вот так под универсал? если нужно очень. можно разделить задачу на несколько этапов деления (16/16 c остатком). это высший пилотаж. когда все основные штуки в программе работают. мопед не мой. еще подумавши. в целом не понятна задача. зачем 32 на 16. может возможно это упрастить? а когда не понятна задача, это капец во что может выльется | | | | |
Если быть чуть более внимательным и прочитать первый пост. то сразу становится понятно, что процедура деления 16:16 для работы с дисками не подходит от слова совсем, если только ты не хочешь ограничить свою утилиту в 32мб . нумерация секторов - 28бит (поскольку LBA28). это явно не влезает в процедуру 16:16. Да и экономия не 100 такто, а как оказалось почти 3тыщи тактов. процедуры из исходников не рабочие. Кстати, файловая система FAT16 самая быстрая. я бьы не зназвал её не спешно. Она быстрее даже, чем FAT12 и намного быстрее, чем FAT32 в реалиях z80.
|
20 Feb 2021 22:33 |
|
|
Alekcandr
Doomed
Joined: 01 Oct 2007 10:30 Posts: 665 Location: Ukraine
|
Странно, что FAT16 быстрее FAT12. По моим данным это не так. Ну да ладно. Применительно к теме можно посмотреть исходники Nextor и как там реализуется математика применительно к FAT16. Функции деления 32/16 в чистом виде не нашел, может плохо искал.
_________________Эмулятор OrionEXT:
http://www.orion-ext.narod.ru
|
21 Feb 2021 02:43 |
|
|
Who is online |
Users browsing this forum: No registered users and 22 guests |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum
|
|