nedoPC.org

Electronics hobbyists community established in 2002
Atom Feed | View unanswered posts | View active topics It is currently 25 Apr 2024 09:31



Reply to topic  [ 204 posts ]  Go to page Previous  1 ... 6, 7, 8, 9, 10, 11, 12 ... 14  Next
Paguo-86PK - XXI BEK 
Author Message
Maniac
User avatar

Joined: 12 Apr 2011 20:43
Posts: 267
Location: Tashkent
Reply with quote
Вылизaл код, как мог…
Не знаю, имеются ли косяки. Но по подсчётам тактов баланс практически 1 в 1 и на 2 байта короче…
 Сбалансированный вариант
Code:
WRBYTE: PUSH    HL              ; 11    {{
        PUSH    BC              ; 11
        PUSH    DE              ; 11
        PUSH    AF              ; 11
        LD      A,080H          ; 7
        LD      (VT_57+8),A     ; 13
        LD      HL,00000H       ; 10
        ADD     HL,SP           ; 4
        EX      HL,DE           ; 4
        LD      L,C             ; 5
        LD      H,001H          ; 7
        LD      SP,HL           ; 5     }} = 99
WRBYTE1:POP     AF              ; 10    {{
        LD      A,L             ; 5
        RLCA                    ; 4
        CPL                     ; 4
        LD      (PC),A          ; 13    -- 36 vv 85 тактов от второго LD (PC),A
        LD      A,(KNS_WR)      ; 13
        LD      B,A             ; 5     }} = 54                                 :: x8 = 432
WRBYTE2:POP     AF              ; 10    {{
        DEC     B               ; 5
        JP      NZ,WRBYTE2      ; 10    }} = 25 * KNS_WR                        :: x8 = 200 * KNS_WR
        ADD     HL,HL           ; 4     {{
        SBC     A,A             ; 4
        AND     00EH            ; 7     -- 11 для компенсации на 275 тактов (99+176); 14 - на 315 тактов
        INC     A               ; 4
        LD      C,A             ; 5
        LD      A,H             ; 5
        LD      (PC),A          ; 13    -- 38 ^^ 85 тактов от первого LD (PC),A
        LD      A,(KNS_WR)      ; 13
        SUB     C               ; 4
        LD      B,A             ; 5     }} = 64                                 :: x8 = 480
WRBYTE3:POP     AF              ; 10    {{
        DEC     B               ; 5
        JP      P,WRBYTE3       ; 10    }} = 25 * KNS_WR : 25 * (KNS_WR - 14)   :: x8 = 200 * KNS_WR
        DEC     C               ; 5     {{
        JP      Z,WRBYTE1       ; 10    }} = 15                                 :: x8 = 120
        EX      HL,DE           ; 4     {{
        LD      SP,HL           ; 5
        LD      HL,VT_57+4      ; 10
        LD      (HL),0D0H       ; 11
        LD      (HL),76H        ; 11
        INC     HL              ; 5
        LD      (HL),23H        ; 77
        LD      (HL),49H        ; 11
        LD      A,27H           ; 7
        LD      (VG_75+1),A     ; 13
        LD      A,0E0H          ; 7
        LD      (VG_75+1),A     ; 13
        LD      L,8             ; 7
        LD      (HL),0A4H       ; 11
        POP     AF              ; 10
POPDBH: POP     DE              ; 10
        POP     BC              ; 10
        POP     HL              ; 10
        RET                     ; 10    }} = 176
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 92 bytes. Ticks: 275 + 133 + 25 x KNS_WR


Last edited by Paguo-86PK on 16 Feb 2020 18:53, edited 1 time in total.



16 Feb 2020 08:21
Profile WWW
Doomed
User avatar

Joined: 19 Feb 2017 03:46
Posts: 583
Location: Санкт-Петербург, Россия, третья планета от Солнца, галактика Млечный Путь
Reply with quote
Post 
Paguo-86PK wrote:
Вылизaл код, как мог
Столь большие усилия ради того, чтобы выиграть два байта - совершенно напрасные.

Во-первых, потому что два байта выигрываются совсем без усилий сразу же после первого взгляда на код.

 
Code:
WR_HL:  LD      C,H
        CALL    WRBYTE
        LD      C,L

if      $ ne RABADR + 0446H
        if1
        .printx * WRBYTE for emulator B2M need be at FC46 ! *
        endif
endif

WRBYTE: PUSH    HL
        PUSH    DE
        PUSH    BC
        PUSH    AF
        LD      A,80H
        LD      (VT_57+8),A
        LD      HL,0
        ADD     HL,SP           ; временно храним стек
        LD      SP,0            ; для регенерации
        LD      D,8
AFC58:  POP     AF
        LD      A,C
        RLCA
        LD      C,A
        LD      A,1
        XOR     C
        LD      (PC),A
        LD      A,(KNS_WR)
        LD      B,A
AFC66:  POP     AF
        DEC     B
        JP      NZ,AFC66
        LD      A,0             ; XOR A = LD A,B (в данном случае незачем)
        XOR     C
        LD      (PC),A
        DEC     D
        LD      A,(KNS_WR)
        JP      NZ,AFC7A
        SUB     14
AFC7A:  LD      B,A

AFC7B:  POP     AF            ; подъем стека на [рег.B] ячеек
        DEC     B
        JP      NZ,AFC7B
        INC     D
        DEC     D
        JP      NZ,AFC58

        LD      SP,HL
        LD      HL,VT_57+4
        LD      (HL),low SA     ; 0D0H
        LD      (HL),high SA    ; 076H
        INC     HL              ; VT_57+5
        LD      (HL),23H
        LD      (HL),49H
        LD      A,27H           ; start display commando
        LD      (VG_75+1),A     ; 001.sss.bb    001.001.11
        LD      A,0E0H          ; сброс счетчиков строк и знакомест ???
        LD      (VG_75+1),A
        LD      L,8
        LD      (HL),0A4H        ; VT_57+8
        POP     AF
POPREG: POP     BC
        POP     DE
        POP     HL
LD_BAK: RET

if      LD_BAK ne 0FCA4H
        if1
        .printx * Internal point 0FCA4H (need for emulator B2M) shifted ! *
        endif
endif

Первый байт выигрывается за счёт замены команды LD A,0 на команду XOR A или команду LD A,B. Второй байт выигрывается, если заметить, что регистр E свободен и в подпрограмме стоят почти подряд две команды LD A,(KNS_WR): вторая загрузка экономится, если после первой команды LD A,(KNS_WR) вставить команду LD E,A, а вместо второй загрузки поставить LD A,E, что два байта вместо трёх.

Во-вторых, ради эмулятора EMU от b2m мы вообще не можем двигать вход WRBYTE и байт RET по адресу FCA4. Т.о изменять на 2 байта длину подпрограммы WRBYTE мы вообще не можем. Потому я в этой подпрограмме не менял ни байта. Кстати, ещё 3 байта освобождаются просто переносом подпрограммы WR_HL на место сразу перед меткой WRBYTE.

А в третьих, имело смысл оптимизировать подпрограмму WRBYTE и LDBYTE иначе. А именно, - взять алгоритм этой подпрограммы из монитора-3 ОРИОНА, где она вдвое короче. Подпрограммы мониторов в Микроше и РК86 излишне усложнены (про Микро-80 я просто не знаю, т.к не разбирался). Возможно это необходимость из-за низкой тактовой частоты процессора и ВГ75. В алгоритме сдвига входного и выходного байта при вводе/выводе задержка для последнего бита байта оказывается иной, чем для других битов. Алгоритм РК это выравнивает, а в ОРИОНЕ это не делается и качество ввода там ничуть не менее надёжное.

И у меня есть вопрос к авторам ПЗУ РК86. Зачем при выводе каждого байта перепрограммировать ПДП? На что тратится куча тактов и байтов. Ведь по одному байту не читают. Читают блоками байтов. Если ввести флаг настройки видео, то при первом вводе/выводе байта ПДП стопорится, экран гаснет, а регенерация ОЗУ поддерживается периодическими POP-ами. После ввода/вывода блока делается CALL PUSK_VG и работа ВТ57+ВГ75 по отображению восстанавливается. На этом экономится ~50 байтов.

Ещё у меня есть вопрос к железячникам, тем, кто разбирался в возможностях 580 ВТ57. Можно ли организовать на время магнитофонного ввода/вывода регенерацию динамического ОЗУ с помощью ПДП (может быть другого канала)? Примерно так как это делалось в IBM PC XT в 1982 году. Но (чтобы сохранить более-менее равномерный темп прогона) сделать закачку не одной сплошной пачки в 128 байт (что требовалось для регенерации DRAM 4116), а 32-х (или более) пачек размером по 4 или менее (если возможно) байтов. Метод МГ-ввода без гашения экрана в РК86 (в многоблочных защищённых от копирования кооперативных играх) и режим работы с дискетой достигнут установкой длины пачки в 4 байта (в оригинале 8 байт).

И ещё теоретически возможен ввод/вывод с регенерацией не с помощью POP-ов, а с помощью команд загрузки из ОЗУ с косвенной адресацией LD A,(RR). Это при включении команд LD и INC RR в петлю паузы. Я считаю, что это вполне возможно, потому, что в ленинградском мониторе Специалиста с пользой используя эти же временные задержки за время ввода/вывода всего одного байта (и даже со скоростью передачи втрое больше, чем в РК) успевалось выводить на экран 4 HEX-цифры, на что явно уходило больше, чем всего 256 команд LD и INC.


Last edited by barsik on 16 Feb 2020 18:52, edited 2 times in total.



16 Feb 2020 18:10
Profile
Maniac
User avatar

Joined: 12 Apr 2011 20:43
Posts: 267
Location: Tashkent
Reply with quote
barsik wrote:
Столь большие усилия ради того, чтобы выиграть два байта - совершенно напрасные.
Дажe ради эксперимента? :no:
barsik wrote:
Во-первых, потому что два байта выигрываются совсем без усилий сразу же после первого взгляда на код.
Интересно было просто переписать всё в своём стиле…
barsik wrote:
Во-вторых, ради эмулятора EMU от b2m мы вообще не можем двигать вход WRBYTE и байт RET по адресу FCA4. Т.о изменять на 2 байта длину подпрограммы WRBYTE мы вообще не можем. Потому я в этой подпрограмме не менял ни байта. Кстати, ещё 3 байта освобождаются просто переносом подпрограммы WR_HL на место сразу перед меткой WRBYTE.
А через конфиги никак не настраиваемо?
barsik wrote:
И у меня есть вопрос к авторам ПЗУ РК86.
Всегда мучался этим вопросом :lol:

P.S.: Тем не менее, моя подпрограмма хорошо сбалансирована. Но я не знаю, является ли дисбаланс оригинала самой логикой задачи?


16 Feb 2020 18:43
Profile WWW
Doomed
User avatar

Joined: 19 Feb 2017 03:46
Posts: 583
Location: Санкт-Петербург, Россия, третья планета от Солнца, галактика Млечный Путь
Reply with quote
Post 
Paguo-86PK wrote:
на 2 байта короче
Ещё в МГ-подпрограммах в ПЗУ РК байты выигрываются за счёт смены порядка PUSH-POP-ов. В ПЗУ РК есть два типа PUSH-POP-ов - один традиционный порядок - PUSH HL, DE, BC и извращённый - PUSH HL, BC, DE. Соответственно в таком же порядке есть две цепочки POP-ов. Сравнив последовательность PUSH-POP-ов в вашем варианте WRBYTE и моём, Вы увидите, что исправив извращённый порядок следования PUSH-ей на традиционный, я выиграл три байта, т.к тогда один вход POPREG и цепочка POP-ов для восстановления регистров только одна.
Paguo-86PK wrote:
barsik wrote:
ради эмулятора EMU от b2m мы вообще не можем двигать вход WRBYTE и байт RET по адресу FCA4.
А через конфиги никак не настраиваемо?
Да, в конце конфига EMU как раз и задаются эти два (с учётом LDBYTE четыре) адреса. Но пользователи эмуляторов настолько ленивы и некомпетентны, что ругались, плевались и проклинали разработчика при попытке использовать в эмуляторах существенно улучшенные мониторы РК/Ориона/Специалиста, в которых эти абсолютно нестандартные точки, естественно, сдвинуты (что нормально, т.к это не стандартизовано и программам не вредит). Потому что те, кто пользовался 8-ми разрядками 30 лет назад и обладали полнотой информации и разбирались в теме, уже практически все вымерли, а из современных пользователей серъёзных, грамотных пользователей эмуляторов единицы.

Мне несложно подгонять любые внутренние точки в мониторах РК/Ориона/Специалиста под требования не только некорректных (к стандартам входных точек ПЗУ) программ, но и к эмуляторам. Это просто выгоднее и удобнее, чем при каждом изменении (которых обычно тысячи) редактировать конфиг. Возникнет неудобство и породится ненужная путаница, если для каждой версии ПЗУ надо иметь свой конфиг.

В EMU80 отлавливаются только входные точки LDBYTE/WRBYTE, а в EMU отлавливаются не только входные точки, но и адреса выходных RET-ов. Это потому, что в этих эмуляторах одинаковый принцип определения начала МГ-обмена, но по разному определяется конец МГ-обмена (в EMU - по точке выхода из п/п-рамм, а в EMU80 по CALL CONIN).
Paguo-86PK wrote:
метка в исходнике: WRBYTE2
Ассемблеры CP/M используют только 6 символов в имени метки (остальные символы в метке писать можно, но они игнорируются). Это потому, что (чтобы шаг был 8 байтов) в таблицы меток, переменных и констант ассемблер заносит 6 байтов имени и 2 байта значения, что экономит расход ОЗУ и резко ускоряет сканирование. Потому две метки с именами WRBYTE2 и WRBYTE3 в родных ассеблерах (т.е тех, что в кодах Z80/КР580) дадут ошибку: "Двойное определение метки". И если это не исправить, то придётся использовать убогие самодельные ассемблеры, что любители 8-ми разрядок понаделали для Windows (в них число значащих символов в именах может быть большим).

Кстати, длинные имена только загромождают исходник, почти ничего не улучшая. Вполне "говорящие" имена можно иметь и в 6 символов. К тому же никто не мешает любителю длинных имен применять имена в 15 символов, лишь надо следить, чтобы первые 6 символов были уникальными.

PS. Насчёт того, чтобы сделать ввод/вывод с магнитофона без гашения экрана стоит попробовать (только в реале) задать число байтов в пачке ПДП минимальное и попробовать читать писать МГ-подпрограммами от Микро-80, Специалиста или ОРИОНА, поставив для начала максимально большую константу. Можно также попробовать формат MSX из ленинградского монитора Специалиста, т.к в этом формате есть больше времени между фронтами (потому при вводе с ленты там возможны "чудеса" типа считающего до нуля графического счётчика или рисовка картинки прямо в экран Специалиста в виде, как это рисуется при вводе в экран ZX).


16 Feb 2020 19:26
Profile
Doomed
User avatar

Joined: 19 Feb 2017 03:46
Posts: 583
Location: Санкт-Петербург, Россия, третья планета от Солнца, галактика Млечный Путь
Reply with quote
Post 
Если делать альтернативное ПЗУ для РК86 никак не заморачиваясь идеологией оригинального ПЗУ РК86, то можно выиграть намного больше байтов. Я это делал, когда писал ROM-BIOS для компьютера с нормальным текстовым адаптером (без ВГ75). И у меня в ту же РФ2 в 2 кб без проблем влезли не только все п/п-ммы ввода/вывода, но и RAM-монитор с более качественными директивами и проблем нехватки места вообще не было.

Драйвер вывода на экран в ПЗУ РК86 написан нетрадиционно. Авторы, видимо с целью ускорения, старались избежать вычислений экранных координат при выводе символа, что делается в драйверах всех остальных 8-ми разрядных компьютеров. Потому в ПЗУ РК нет вот такой типовой процедуры:

Code:
EKRAN   EQU     76D0H +3*78 +8

; Вход: L - H-координата
;       H - V-координата
;       C - код символа

SCREEN: LD      A,L
        LD      B,H
        INC     B
        LD      HL,EKRAN-78
        LD      DE,78
LOOP:   ADD     HL,DE
        DEC     B
        JP      NZ,LOOP
        CALL    AADDHL
        LD      (HL),C
        RET

AADDHL: ADD     A,L
        LD      L,A
        RET     NC
        INC     H
        RET
.
Хранится не только традиционная экранная коодината в виде POSX и POSY, но и хранится и, главное, динамически меняется экранный адрес для вывода следующего символа. После каждого вывода делается не только POSX++, но и EK_ADR++. Где раб.ячейка EK_ADR (7600) это адрес в экране где находится курсор и куда должен вставляться очередной символ. За счёт этого отпадает длительная вышеприведённая процедура расчёта экранной позиции (вместо неё в общем случае одна команда INC HL). Это ускоряет вывод.

Значение EK_ADR в ПЗУ ставится только при CLS и никогда не рассчитывается. Зато, если хоть раз внаглую изменить ячейки EK_ADR, то весь последующий вывод исказится. Внаглую игры меняют ячейки EK_ADR, чтобы подпрограммами F809/F818 вывести что-то вне основного экрана 64*25.

Кстати, вышеприведённый код я использовал когда-то, но его можно оптимизировать. Нужна лишь быстрая процедура умножения на 78 (со сдвигами).


Last edited by barsik on 17 Feb 2020 07:40, edited 1 time in total.



17 Feb 2020 06:45
Profile
Maniac
User avatar

Joined: 12 Apr 2011 20:43
Posts: 267
Location: Tashkent
Reply with quote
barsik wrote:
Если делать альтернативное ПЗУ для РК86 никак не заморачиваясь идеологией оригинального ПЗУ РК86, то можно выиграть намного больше байтов.
Нa Денди Mortal Kombat, Booger Man и Lion King написали сравнительно недавно, так как именно программно технологии стали продвинутее.
Давно вот парюсь с вопросом полной перетряски РК. Но, если трясти, то уж и дешифратор перерасключить, и память расширить до 48 Кб, и знакогенератор обновить…
barsik wrote:
Нужна лишь быстрая процедура умножения на 78 (со сдвигами).
Типа Mul78?
Code:
        PUSH    HL      ; 11
        LD      A,H     ;  5
        CPL             ;  4
        LD      E,A     ;  5
        LD      D,0FFH  ;  7
        INC     DE      ;  5
        PUSH    DE      ; 11
        LD      D,000H  ;  7
        LD      E,H     ;  5
        LD      H,D     ;  5
        LD      L,E     ;  5
        ADD     HL,HL   ;  4
        ADD     HL,HL   ;  4
        ADD     HL,DE   ;  4
        ADD     HL,HL   ;  4
        ADD     HL,HL   ;  4
        ADD     HL,HL   ;  4
        POP     DE      ; 10
        ADD     HL,DE   ;  4
        ADD     HL,HL   ;  4
        POP     DE      ; 10
        LD      D,000H  ;  7
        ADD     HL,DE   ;  4 = 133
Практика показала стабильный вывод текста и графики в окошках, но с заметными тормозами…

Если даже поиграть «каруселью регистров», выигрыш будет чуть ли ни вдвое:
Code:
        LD      D,000H  ;  7
        LD      E,H     ;  5
        LD      H,D     ;  5
        PUSH    HL      ; 11
        LD      L,E     ;  5
        ADD     HL,DE   ;  4
        ADD     HL,DE   ;  4
        LD      E,L     ;  5
        ADD     HL,HL   ;  4
        ADD     HL,DE   ;  4
        ADD     HL,HL   ;  4
        ADD     HL,HL   ;  4
        ADD     HL,DE   ;  4
        ADD     HL,HL   ;  4
        POP     DE      ; 10
        ADD     HL,DE   ;  4 = 84
Но скорости недостаточно…

Или снова откроем спор про неоптимальный вариант кода? :mrgreen:


Attachments:
File comment: Простейший цикл…
А вывод текста ещё тормознее!

Mul_78.zip [229 Bytes]
Downloaded 240 times
17 Feb 2020 07:35
Profile WWW
Doomed
User avatar

Joined: 19 Feb 2017 03:46
Posts: 583
Location: Санкт-Петербург, Россия, третья планета от Солнца, галактика Млечный Путь
Reply with quote
Post 
Есть небольшая неточность в арифметике - ADD HL,RR у КР580 выполняется за 10 тактов (11 тактов у Z80). В этой процедуре нас интересует в первую очередь размер в байтах, т.к про скорость и без того ясно, что сдвигами быстрее.

При умножении на фиксированное число можно использовать алгоритм со сдвигами. Но если число неудобное, плохо разлагается на сомножители кратные двойке, а второй сомножитель хоть и переменный, но небольшой, то сложение в цикле может быть выгоднее. Номер строки может быть от 0 до 24. Следовательно 24 сложения в цикле это всего ~600 тактов, т.е считая по средней эффективной частоте в 1.3 МГЦ, т.е при маш.периоде в 760 НС, в переводе на секунды - умножение циклическим сложением длится максимум 0.46 МСЕК.
Paguo-86PK wrote:
Или снова откроем спор про неоптимальный вариант кода?
Не получится, т.к читателям слишком сложно разбираться в представленных фрагментах, для лёгкого понимания которых нужны комментарии. В данном случае, чем разбираться в чужом непонятном алгоритме, проще написать свой вариант.


17 Feb 2020 10:29
Profile
Maniac
User avatar

Joined: 12 Apr 2011 20:43
Posts: 267
Location: Tashkent
Reply with quote
barsik wrote:
Есть небольшая неточность в арифметике - ADD HL,RR у КР580 выполняется за 10 тактов (11 тактов у Z80).
Oнлайн справочники вновь подвели :exclaim:
Да, в справочнике по z80 - 11 тактов :lol:
barsik wrote:
И вообще, если подумать, то на 78 умножать невыгодно и потому не надо. 78 сложений в цикле это более 1900 тактов, потому надо умножать не номер строки на 78, а наоборот 78 умножать на номер строки, который (0...24), а 24 сложения в цикле это уже всего ~600 тактов.
Можно и "в лоб" закодировать таблицу. Я так в ZX-Spectrum прокручивал пиксели спрайта без всяких циклов. :mrgreen:
Code:
MUL78:  ; HL = A * 78
        PUSH    DE
        LD      DE,78
        LD      HL,MUL78X
        CPL
        ADD     A,L
        LD      L,A
        CALL    MUL78Y
        POP     DE
        RET
MUL78Y: PUSH    HL
        LD      HL,0
        RET
        ADD     HL,DE
        ADD     HL,DE
        ...     ...
        ADD     HL,DE
MUL78X: ADD     HL,DE
        RET


17 Feb 2020 11:07
Profile WWW
Doomed
User avatar

Joined: 19 Feb 2017 03:46
Posts: 583
Location: Санкт-Петербург, Россия, третья планета от Солнца, галактика Млечный Путь
Reply with quote
Post 
Всё равно непонятно как получается умножение на 78. И RET посередине кода смущает. А табличный метод, хоть и тратит ~80 байтов (50 байт отнимает таблица), но зато выполняется всего за 40...50 маш.тактов.


17 Feb 2020 11:21
Profile
Maniac
User avatar

Joined: 12 Apr 2011 20:43
Posts: 267
Location: Tashkent
Reply with quote
barsik wrote:
Всё равно непонятно как получается умножение на 78. И RET посередине кода смущает. А табличный метод, хоть и тратит ~80 байтов (50 байт отнимает таблица), но зато выполняется всего за 40...50 маш.тактов.
Нa практике это самый тормозной метод. Запустите-ка :mrgreen:
А логику - отладчик откроет…
(Но в ZX-Spectrum прокручивать пиксели спрайтов так быстрее - всего 8 RLCA и прыжок на n-ый…)


Attachments:
Mul_78_ret.zip [244 Bytes]
Downloaded 233 times
17 Feb 2020 11:29
Profile WWW
Doomed
User avatar

Joined: 19 Feb 2017 03:46
Posts: 583
Location: Санкт-Петербург, Россия, третья планета от Солнца, галактика Млечный Путь
Reply with quote
Post 
Любому ясно как работает алгоритм с линейными ADD HL,DE, я сомневался лишь в числе загружаемом в HL перед вычитанием из него множителя. И не зря, - оказалось ошибка. Надо было загружать значение на 1 больше, чем метка с RET, а не на 1 меньшее.

Для ROM-BIOS неприемлемо ради экономии вместо цикла линейно ставить кучу ADD HL,DE, а вместо правильного вычитания числа из HL, применять сложение с обратным числом только регистра L, а не HL. Для ROM-BIOS, где идёт борьба за каждый байт, длинный линейный фрагмент кода не годится.

Это не самый тормозной вариант умножения на фиксированное число, т.к сложение HL и DE в цикле это ~600 маш.тактов. А здесь при умножении 78 на 25 (строк) максимальное число тактов на такое умножение будет в районе 300 машинных тактов. И ещё возникает возможность фатального улёта, если множитель окажется больше числа строк с ADD HL,DE.

Ниже исходник этой исправленной программки умножения на 78 с выводом результатов. Сама эта странслированная программка во вложении. Вот, что она выводит. А вывод этой программки нужен, чтобы заполнить табличку в алгоритме для табличного умножения, который хотя ещё более затратный по байтам, зато на порядок более быстрый. Для игр вероятно табличный метод самый лучший.

 
Code:
        .Z80
        aseg
        ORG     100H

RABADR  EQU     0
KS      EQU     02800H

HEX_A   EQU     0F815H
MCOUT   EQU     0F809H

; ----------------------------------------------

        defb    high RABADR,low RABADR
        defb    high (RABADR+LENGTH-1), low (RABADR+LENGTH-1)

        .phase  0

        CALL    CR
        XOR     A
LOOP:   PUSH    AF
        CALL    MULT78
        CALL    HEX_HL
        CALL    CR
        POP     AF
        INC     A
        CP      22
        JP      C,LOOP
        RET

; ----------------------------------------------

MULT78: LD      HL,MUL78X +1
        CPL
        ADD     A,L
        LD      L,A
        PUSH    HL
        LD      DE,78
        LD      HL,0
        RET

        rept    25
        ADD     HL,DE
        ENDM

MUL78X: RET

; ----------------------------------------------

HEX_HL: LD      A,H
        CALL    HEX_A
        LD      A,L
        JP      HEX_A

; ----------------------------------------------

CR:     LD      C,13
        CALL    MCOUT
        LD      C,10
        JP      MCOUT

; ----------------------------------------------

if      $ and 0FH ne 0
        rept    10H-($ and 0FH)
        defb    255
        endm
endif

LENGTH  EQU     $-RABADR

        .dephase

        defb    0, 0, 0E6H
        defb    high KS, low KS

        END
.


Attachments:
M78.rar [162 Bytes]
Downloaded 243 times
17 Feb 2020 18:01
Profile
Maniac
User avatar

Joined: 12 Apr 2011 20:43
Posts: 267
Location: Tashkent
Reply with quote
barsik wrote:
Любому ясно как работает алгоритм с линейными ADD HL,DE, я сомневался лишь в числе загружаемом в HL перед вычитанием из него множителя. И не зря, - оказалось ошибка. Надо было загружать значение на 1 больше, чем метка с RET, а не на 1 меньшее.
Кaк видите, много кода здесь у меня берётся прямо с потолка, пишется прямо здесь и имеет ошибки. :mrgreen:
Тот же линейный алгоритм с восемью RLCA в работе со спрайтами показывает скорость лучше, чем RLCA+DJNZ.
Вообще-то, при генерации звука для задержки с точностью в 1 такт именно линейные тупые таблицы подходят. Особенно, если комбинировать операции с разным требованием к тактам.
(Интересно было бы при вводе/выводе байта с магнитофона использовать задержку с точностью в 1 байт…)

Но, как ни крути, в предыдущей версии своих «Окошек» прошлых лет они показали себя как очень тормозные.
Потому, нативный вариант РК самый быстрый.
Но в нём можно было бы сократить число оперативных переменных, оставив только прямой указатель символа на экране и координату X: Обычная печать будет заключаться лишь в инкрементах. А по достижению границы строки нужно будет уже вычислить координату Y и произвести остальные манипуляции…
Про такой вариант я давно думаю.
(Для вычисления Y тупо отнимаем 78 пока не пересечём границу 77C2 - не так и много циклов…)
Есть ещё вариант с CRC, где все реквизиты печати сверяются с контрольной суммой и, в случае грубого внешнего вмешательства, вычисляются вновь. Что должно защитить от наглого поведения некоторых программ…

Тот же обмен с магнитофоном можно снабдить и вычислением контрольной суммы, так как алгоритм там крайне прост.
Тогда можно избавиться от паузы перед выводом большого файла и по завершению его ввода.
То есть, рабочие ячейки Монитора должны включать и ячейки CRC.

Буфер ввода директив так же можно выбросить и просто работать напрямую с экраном, как Вы предлагаете в редакторе…
Реквизиты видеобуфера нужно тоже хранить в рабочих ячейках, чтобы ВГ75/ВТ57 приложения не смели программировать сами, а всё делали легально - через Монитор.
Тогда и проблем с переключением формы курсора быть не должно.
Но это будет касаться только нашего софта, которого вообще ещё нет! :mrgreen:

В любом случае, общий ореол Монитора (своего) я как бы уже сформировал.
Осталось лишь накидать в блокноте общий план и взяться за него.

Искушения есть в плане многозадачности.
  • Стек приложениям Монитор выставляет сам
  • Запуск через «G<адрес1>,<адрес2>» для запуска двух программ
  • Диспетчер приложений быстро пересохраняет регистры задач
  • Операции с экраном/клавиатурой связаны с диспетчером задач
  • Периодически считываются флаги ВГ75 для фиксации конца кадра и организации, даже кривого, отсчёта времени
Теперь понимаете, почему я не выпиливаю директиву «X» и точку останова в «G»?
Их код, хоть и отдалённо, позволяет прикинуть объём алгоритма…
Ниже - код-пародия на две задачи… :mrgreen:

Ещё в 90-х статья заставила задуматься…
Хочу на практике проверить, на сколько будет затратно все команды ветвления на лету подменять на вызов диспетчера, чтобы приложение, даже без явного обращения к Монитору, исполнялось в режиме пассивной эмуляции…


Attachments:
File comment: Клавиша Tab переключает процессы
Внизу-справа - квадрат-индикатор процесса

twix.zip [352 Bytes]
Downloaded 261 times
17 Feb 2020 20:55
Profile WWW
Doomed
User avatar

Joined: 19 Feb 2017 03:46
Posts: 583
Location: Санкт-Петербург, Россия, третья планета от Солнца, галактика Млечный Путь
Reply with quote
Post 
Большинство из ваших планов улучшения ПЗУ я не понял, но не волнует. А вообще, чтобы не заморачиваться экономией байтов, надо делать ПЗУ размером в 4 кб (неважно двухстраничное с окном 2 кб или в виде сплошного ПЗУ F000...FFFF).
Paguo-86PK wrote:
Искушения есть в плане многозадачности
Некоторые услышав о многозадачности на РК86 начнут крутить пальцем у виска. Но ничто не мешает обсуждать методы введения многозадачности в РК. Особенно, если придумать для чего это надо и что полезного даст пользователю.

Понятно, что для архитектуры РК с доп.страницами ОЗУ по 32 кб легко ввести многозадачность. Но многозадачность не в том смысле, что программы работают одновременно, а в смысле, что можно запустить несколько программ и вручную прерывать их переключаясь на другую программу. Для этого достаточно дополнить п/п-мму ПЗУ F81B (которую вызывают все РК-программы) процедурой переключения на другую задачу. Для каждой задачи выделяется целая страница ОЗУ размером в 32 кб (со своим экраном, естественно).

Например, одновременно нажимаем <УС>, <СС> и <Fn>. По такому сочетанию переключается страница ОЗУ в адресах 0...7FFF и одновременно текущая программа. Теоретически, сколько в конкретном РК есть таких полубанок ОЗУ, столько РК-программ можно запустить.

Если же есть прерывания, то теоретически можно поиметь для драйвера мыши многозадачность в обычном смысле (т.е на прерываниях с разделением времени между задачами). Но увы, мышь нужна только в графической машине, где возможен GUI интерфейс, а для чисто текстовой машины GUI ещё никто не сделал. Потому разумно выкинуть РК86 с девятого этажа и заняться Специалистом (т.к Орион, Вектор, Корвет и др. - слишком сложные и менее привлекательные).
Paguo-86PK wrote:
реквизиты печати сверяются с контрольной суммой... Что должно защитить от наглого поведения некоторых программ
Непонятно от какого наглого поведения программ возможна защита. От обращения в нестандартные точки внутри ПЗУ F800 ничто не защитит кроме совместимости по внутренним точкам.
Paguo-86PK wrote:
Тогда можно избавиться от паузы перед выводом большого файла и по завершению его ввода.
А чем эти паузы кому-то мешают?
Paguo-86PK wrote:
Буфер ввода директив так же можно выбросить и просто работать напрямую с экраном
Да, это позволит в п/п-мме GETLIN с'экономить целых три байта за счёт исключения одной команды CALL COUT_C. При этом полезно переделать несколько игр и системных программ, что нагло вызывают п/п-мму GETLIN (F8EE) и некоторые из них, возможно, сдуру предполагают, что буфер ввода находится на 7633.


18 Feb 2020 00:20
Profile
Maniac
User avatar

Joined: 12 Apr 2011 20:43
Posts: 267
Location: Tashkent
Reply with quote
barsik wrote:
Большинство из ваших планов улучшения ПЗУ я не понял, но не волнует.
  • Директива «G» позволяет запустить основную и вспомогательную программы. В таком случае, тот же опрос клавиатуры активирует режим переключения между ними
  • Так как на обращение к подпрограммам опроса клавиатуры и печати на экран отводится существенный процент времени, можно опрашивать статус ВГ75 и вести отсчёт какого-то времени с какой-то точностью. А так как, в отличии от ZX-Spectrum, Сброс не обнуляет память, время можно худо-бедно отсчитывать беспрерывно, пусть и с погрешностями
  • Клавишам F1…F4 (в КР-03 - К1…К5) можно выделить одноимённые коды - 0xF1…0xF5. Та же Рус/Lat имеет же код EF… В сочетании с УС/СС можно расширить до F5…F8 и Табуляции дать код F9. Да и курсорные клавиши расширить, а то сильно не хватает тех же Delete/End/Insert для текста
  • Управление ПДП/ВГ75 проработать и унифицировать, выделив отдельные рабочие ячейки, чтобы приложение могло запросить Монитор сменить режим экрана. Тогда и форму курсора менять можно без срыва экрана, но только под нормальным софтом и нашим
  • В нижней части экрана отдельной функцией Монитора показывать подсказку с функциональными клавишами. Причём, сами клавиши, как и в DOS, могут предобрабатываться самим Монитором без сигнализирования приложению. Например, выводить снимок экрана в файл
  • Точки входа в основные подпрограммы можно размазать по всему ПЗУ с условием, что они должны иметь выровненные адреса. Например, F803 - FE00, F82D - FE40, F818 - FE80 и т.д…
barsik wrote:
А вообще, чтобы не заморачиваться экономией байтов, надо делать ПЗУ размером в 4 кб (неважно двухстраничное с окном 2 кб или в виде сплошного ПЗУ F000...FFFF).
Экономить всегда надо, пока мы есть!
(Поколение индусов с их искусством программирования Калькулятора весом в гигабайты нас не должно волновать!)
Мой КР-03 имеет 16 Кб! И это важно для меня, так как в перспективе придётся весь свой софт перегонять под 16 Кб…

Можно в ПЗУ сразу выделить зону POP-RET операций, чтобы все подпрограммы в конце выходили именно оттуда.
Можно даже и PUSH'ы оформить в подпрограмму и не беда, что придётся поплясать со стеком.
Главное - чтобы был план… :idea:
barsik wrote:
Некоторые услышав о многозадачности на РК86 начнут крутить пальцами у виска. Но ничто не мешает обсуждать методы введения многозадачности в РК. Особенно, если придумать для чего это надо и что полезного даст пользователю.
Ещё на Поиске под DOS 3.1 страдал тем, что выходя из среды Borland C в DOS-сеанс я справочник читал в Volcov Commander с примерами на Си по F4 и долго искал позицию, где остановился. Так как ни Copy-Paste тогда не существовало, ни Alt+Tab…
В пору было писать резидентный драйвер, чтобы по Print Screen экран копировал в файл, а потом в сочетании с Shift его отображал…

Это я к тому, что даже в тех же 32 Кб две задачи могут разделять один банк ОЗУ и экрана.
Совершенно незачем двум классическим программам РК работать одновременно…
barsik wrote:
Понятно, что для архитектуры РК с доп.страницами ОЗУ по 32 кб легко ввести многозадачность. Но многозадачность не в том смысле, что программы работают одновременно, а в смысле, что можно запустить несколько программ и вручную прерывать их переключаясь на другую программу. Для этого достаточно дополнить п/п-мму ПЗУ F81B (которую вызывают все РК-программы) процедурой переключения на другую задачу. Для каждой задачи выделяется своё окно ОЗУ в 32 кб (со своим экраном, естественно).
В своём примере я это и попытался сделать…
Клавиатура МС-7007 имеет достаточно клавиш, которые можно было бы перепрограммировать. В КР-03 некоторые затёрты и все выдают код Пробела.
(Кстати, сам «МС 0511 УКНЦ» у меня есть, но без БП. От современного БП он не запустился: Видимо на рынке лом уже был…)
barsik wrote:
Например, одновременно нажимаем <УС>, <СС> и <Fn>. По такому сочетанию переключается страница ОЗУ в адресах 0...7FFF. Теоретически, сколько в конкретном РК есть таких полубанок ОЗУ, столько РК-программ можно запустить.
Это всё хорошо. Но мы ещё с «Супер-РФ2» даже ещё не договорились! :mrgreen:
Потому, аппаратную сторону вопроса отложим пока в сторону :roll:
barsik wrote:
Но увы, мышь нужна только в графической машине, где возможен GUI интерфейс, а для чисто текстовой машины GUI ещё никто не сделал.
А как же тот же Volcov Commander, где мышь - всего лишь оранжевый атрибут на текстовом экране?
А как же Scream Tracker с текстовым режимом, где указатель мыши - всего лишь символы с оперативной перерисовкой?
Когда изучал премудрости программирования псевдографики в DOS, свой знакогенератор тоже делал с узорными рамками и мышкой…
Да, в РК такое провернуть тяжелее. Но, если решать в лоб, можно знакогенератор разбить на 48 страниц, где по сигналу отображения курсора включается нужная страница. Можно курсор позиционировать с точностью до пикселя! :mrgreen:

И Вы здесь - лукавите! :ewink:
Для РК мышь таки была с резисторами/1006ВИ1-таймером и даже драйвер для Бейсика!
А в центральных пунктах милиции в СССР (я выше уже писал) терминалы снабжались световыми перьями…
barsik wrote:
Непонятно от какого наглого поведения программ возможна защита. От обращения в нестандартные точки внутри ПЗУ F800 ничто не защитит кроме совместимости по внутренним точкам.
Игра КСОНИКС для отображения в нижней части экрана строки статуса нагло вписывает адрес в ячейки 7600/7601.
Монитор мог бы проверять целостность своих ячеек от внешней модификации особой подпрограммой…
barsik wrote:
А чем эти паузы кому-то мешают?
Через процедуру вывода байтов и так проходит весь файл. Не так и дорого по тактам будет организовать накопление контрольной суммы отдельными служебными ячейками…
barsik wrote:
Да, это позволит в п/п-мме GETLIN с'экономить целых три байта за счёт исключения одной команды CALL COUT_C. При этом полезно переделать несколько игр и системных программ, что нагло вызывают п/п-мму GETLIN (F8EE) и некоторые из них, возможно, сдуру предполагают, что буфер ввода находится на 7633.
Мы оба запутались в трёх соснах! :lol:
С одной стороны - обсуждали вариант Монитора без обратной совместимости.
С другой стороны - вопросы совместимости выскакивают как пузыри на новых обоях!

Немного теории
В эпоху восьмибитников никто не волновался про выравнивание указателей. Тогда как уже в 8086 16-битное слово рекомендовали в памяти хранить по чётным адресам, так как нечётные невыровненные требуют лишних тактов и могут заползать на соседние сегменты. С технологиями MMX/SSE всё стало ещё строже и хороший программист должен выравнивать адреса до 16 байтов. Хотя в последних процессорах это уже не актуально, но ради приличия - рекомендуется.

В РАДИО-86РК с выравниванием адресов вообще беда.
Указатель стека - изначально 76CF, тогда как PUSH использует предекремент и ячейка 76CF никогда не используется. Это безобразие я всегда хотел исправить, но из-за совместимости с программами с автозапуском пока ничего не трогал.
Те же константы скорости ввода-вывода (762F), граница ОЗУ (7631), буфер строки (7633) и «G»-адрес запуска (7627) - всё сбито.
С одной стороны, это доказывает Вашу правоту, что Монитор авторы писали не голым дампом: В ассемблере кое-как накидали карту рабочих ячеек.
С другой стороны, тут то и полезно разбираться в дампах и бить код ровнее. Что я пытаюсь делать по мере своей квалификации бинариста… :mrgreen:

P.S.: А прокрутка экрана через стек - не универсальна: К «окошкам» тяжело применить! :roll:
У меня через стек прокрутилось 44 полных кадров - за минуту.
Через мою оконную прокрутку 78×30 того же объёма - за 112 секунд.
Разница - менее, чем в 2 два через 1320 (30×44) символов 0A.
Так как грязная разница - даже не в полные 2 раза, то метод сомнительный для оконных операций.
Только для игр :exclaim:
Честно - я ожидал большего! :roll: Может мой алгоритм не так оптимален? Тогда поделитесь своим! :wink:
P.P.S.: Горизонтальная прокрутка легче:
Code:
REP: LD  SP,076D0H
     LD  DE,2340
LOOP:EX  HL,(SP)
     INC SP
     DEC DE
     INC D
     DEC D
     JP  P,LOOP
     JP  REP


Attachments:
File comment: Кстати…
Прокрутка экрана стеком - не так уж производительна, но сложна и не гибка

SpScroll.zip [207 Bytes]
Downloaded 247 times
18 Feb 2020 05:26
Profile WWW
Doomed
User avatar

Joined: 19 Feb 2017 03:46
Posts: 583
Location: Санкт-Петербург, Россия, третья планета от Солнца, галактика Млечный Путь
Reply with quote
Post 
Paguo-86PK wrote:
Мой КР-03 имеет 16 Кб! И это важно для меня, так как в перспективе придётся весь свой софт перегонять под 16 Кб
Что ваш основной принцип: мазохизм во всём?

Я сделал ОЗУ 32К сразу же как отладил РК, потратив на выкусывание 155 ЛА3 и запайку на её место 555 ЛА9 менее 15 минут. Какой смысл тратить многие сотни часов неинтересного труда на программное решение, если есть в тысячу раз менее трудоёмкое аппаратное?
Paguo-86PK wrote:
Клавиатура МС-7007 имеет достаточно клавиш, которые можно было бы перепрограммировать.
У меня тоже есть пара новых MS7007 (с отрезанным шлейфом, надо припаивать к метализации на плёнке проводки легкоплавким сплавом Розе или Вуда). Но увы, существующие эмуляторы РК86 не поддерживают MS7007.

Кстати, MS7007 конечно на порядок лучше, чем калькуляторные кнопки ВМ-16, но против писишной клавиатуры эргономика у них слабая (слишком малый ход клавиш, нет провала при нажатии), а главное, - пластмасса клавиш некачественная - всего за два года интенсивной эксплуатации клавиши истираются (надписи исчезают). Я истёр на ОРИОНЕ две такие клавиатуры.

Потому подумываю о использовании имеющихся у меня нескольких дохлых плёночных PC-клавиатур. Речь не о конверторе интерфейса на Atmega, а о подключении клавиатуры в виде матрицы контактов. Для этого платка с интерфейсной паучиной снимается и проводки подпаиваются прямо к метализации на плёнке (я это делал, - секрет в том, что при пайке металлизированная плёнка кладётся на охлаждённый металл, используется легкоплавкий припой 100'C и кислотный жидкий флюс). Или можно попытаться отрезать печать от выводов интерфейсной паучины.
Paguo-86PK wrote:
мы ещё с «Супер-РФ2» даже ещё не договорились!
Тут я не договорная сторона. Меня «Супер-РФ2» не волнует. Для хранения файлов удобнее ROM-диск и я уже упоминал, что считаю, что страничное ПЗУ с окном 8 кб (E000...FFFF) намного полезнее. ROM-диск универсален (т.е подходит и для других машин), не требует вторжений и в вашем случае позволяет снять проблему нехватки объёма ПЗУ F800. Если все директивы сделать динамически загружаемыми из ROM-диска, то освободится более 1 кб объёма ПЗУ F800.
Paguo-86PK wrote:
barsik wrote:
для текстовой машины GUI ещё никто не сделал.
А как же тот же Volcov Commander... ?
Не путайте GUI с пиктограммами и указателем с обычным удобным текстовым интерфейсом, что применён в NC (и который поддерживала библиотека Turbo Vision от борландовских TP и TC).
Paguo-86PK wrote:
можно знакогенератор разбить на 48 страниц
Тут и один-то альтернативный фонт не пробить, куда уж там 48. И это противоречит вашему принципу: не вторгаемся в плату РК86 и из-за этого принципа до конца мучаемся с его недостатками. Т.е можно-то можно, но это уже скатывание в маниловщину, в пустые мечты далёкие от реальности. Вот прошить второй фонт в неиспользуемый второй килобайт РФ2 и припаять один проводок - это реально. Также реально воткнуть в панельку ПЗУ F800 вместо РФ2 импортную 2732 (у которой в том же корпусе DIP-24 целых 4 кб, у меня они есть, аж 3 штуки). Реальны только минимальные доработки, что легко может сделать каждый кто имеет электропаяльник.
Paguo-86PK wrote:
Для РК мышь таки была с резисторами/1006ВИ1-таймером и даже драйвер для Бейсика!
Какая же это мышь? Это демонстратор использования микросхемы 1006 ВИ1 в аналоговом джойстике.
Paguo-86PK wrote:
нагло вписывает адрес в ячейки 7600/7601. Монитор мог бы проверять целостность своих ячеек от внешней модификации особой подпрограммой…
А проще, если уж это так важно, найти те несколько программ, что лезут в ячейки и переделать их.
Paguo-86PK wrote:
В Радио-86РК с выравниванием адресов вообще беда
Не понятно о чём это и вряд-ли кто-то, кроме Вас, считает это бедой РК86. Реальной бедой РК86 все считают его предельно убогие изобразительные возможности (нет даже инверсии знакомест) и нехватку ОЗУ для работы DOS.
Paguo-86PK wrote:
Указатель стека - изначально 76CF, тогда как PUSH использует пре'декремент и ячейка 76CF никогда не используется. Это безобразие я всегда хотел исправить, но из-за совместимости с программами с автозапуском пока ничего не трогал.
А я и не знал, что где-то есть РК-программы с автозапуском, потому изменил стек на 76D0 и не парился. Но не ради выравнивания адресов, а из логики, - какой смысл терять ячейку впустую, хотя теоретически эту ячейку можно использовать как рабочую в программах.

Любопытно, что есть программы Специалиста и ОРИОНА, где в качестве флага использовали даже экранную ячейку BFFF (EFFF) в нижнем правом углу экрана. При записи туда числа 01 или 00 это практически незаметно (мерцает крошечная точка в углу никому не мешая). А в РК86 в качестве флагов пригодны 14*25+5*78=740 экранных ячеек, которые истрачены на программный бордюр (гашение по строкам и кадрам). В качестве флага ON пишем в эту экр.ячейку байт 20 или FF, а в качестве флага OFF пишем число 0. Т.к все эти три кода выводят пустое знакоместо, синхронизация не нарушается. Ещё есть свободные ячейки выше 7FF4, похоже их никто не использовал.
Paguo-86PK wrote:
Монитор авторы писали не голым дампом
В адресации портов разработчики РК ошиблись, но мазохизмом не болели.
Paguo-86PK wrote:
полезно разбираться в дампах и бить код ровнее
Нет. Полезнее вообще забыть о кодах и дампах, и даже об ассемблере и начать для 8-ми разрядок штамповать в огромном количестве и непревзойдённом качестве программы на Паскале или Си. Лучше трудозатраты тратить эффективно и на реально полезное. Я как раз потому и упоминал потребность в пригодном для реального использования текстовом редакторе размером до 2 кб, что они нужны для Паскаля, Си и Фортрана РК86.
Paguo-86PK wrote:
прокрутка экрана через стек - не универсальна: К «окошкам» тяжело применить! ... метод сомнительный для оконных операций
В ROM-BIOS ОРИОНА стандартизованы оконные параметры (хотя ROM-BIOS-ом вывод в окно поддержан неполноценно, только CLS-ом, а позиционированием и роликом нет). Но грамотные оконные драйверы поддерживают оконность полноценно и ролик в окне абсолютно не тормозит, хотя для графической машины он намного сложнее, чем для текстовой. Пример быстрого оконного ролика ОРИОНА (в цвете чуть сложнее):

 
Code:
HISCRN  EQU     0F3CFH  ; старший байт адреса    X+80H
WDTSCR  EQU     0F3D0H  ; ширина окна в байтах     dX
FRSTLN  EQU     0F3D4H  ; номер 1-й строки окна     Y
SCHIGH  EQU     0F3D5H  ; количество строк в окне  dY

ROLL:   PUSH    HL
        PUSH    DE
        PUSH    BC
        LD      A,(FRSTLN)
        ADD     A,A
        LD      C,A
        ADD     A,A
        ADD     A,A
        ADD     A,C
        ADD     A,10
        LD      C,A
        CALL    PRASCH
        LD      (TMP),A
       
        LD      (TMPSTK),SP
        LD      HL,(HISCRN)

ROLL1:  LD      L,C
        LD      SP,HL
        LD      A,C
        SUB     10
        LD      L,A
        LD      A,(TMP)
        CP      L
        JR      Z,ROLL3
ROLL2:
        rept    5
        POP     DE
        LD      (HL),E
        INC     L
        LD      (HL),D
        INC     L
        endm
       
        CP      L
        JR      NZ,ROLL2
ROLL3:
        LD      A,(INVERS)
ROLL4:
        rept    9
        LD      (HL),A
        INC     L
        endm
       
        LD      (HL),A
        INC     H
        DJNZ    ROLL1

        LD      SP,(TMPSTK)
        POP     BC
        POP     DE
        POP     HL
        RET

; Возвращает адрес начала символа в посл.строке окна

PRASCH: LD      A,(FRSTLN)
        LD      E,A          ; E - FRSTLN
        LD      A,(SCHIGH)
        ADD     A,E          ; A =FRSTLN+SCHIGH
        DEC     A
        ADD     A,A          ; *2
        LD      E,A          ; E=(FRSTLN+SCHIGH-1)*2
        ADD     A,A          ; *4
        ADD     A,A          ; *8
        ADD     A,E          ; *10*(FRSTLN+SCHIGH-1)
        RET
.

Paguo-86PK wrote:
Может мой алгоритм [ролика] не так оптимален? Тогда поделитесь своим!
Я не писал ролик стеком для РК (а только для ОРИОНА), тем более для окна. Для текстовой машины вообще никто в мире, видимо, не писал ролик стеком. Т.к для даже самой тормозной текстовой машины (это ZX80 или Галаксия) обычного LDIR с избытком достаточно. Возможно, что и у Вас проблем со скоростью нет, а их Вам создаёт неточный эмулятор. Тут поможет знание арифметики, считайте число тактов разных вариантов ролика.


18 Feb 2020 17:32
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 204 posts ]  Go to page Previous  1 ... 6, 7, 8, 9, 10, 11, 12 ... 14  Next

Who is online

Users browsing this forum: No registered users and 32 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

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.