Просмотр полной версии : Мои эксперименты
Smalovsky
16.05.2021, 16:48
Мои эксперименты
https://dropmefiles.com/5mI4A
Экзешники в образе
Sprite - движение спрайта без буферирования(видно мелькание), Tile - вывод одиночного тайла, Tiles - вывод тайлов с прозрачностью, Tilescr - покрытие экрана тайлами, Tiletest - вывод 255 экранов замощенных тайлами( в среднем 4 экрана за секунду, время теста 63.5 секунды).
Подскажите, кто знает,на какой частоте работает Спринтер при запуске программ из ОС Естекс 10.5 МГц?
Т.к. SIMM работает на частоте 7МГц, то при выполнении программы из основного ОЗУ процессор вейтится, так что да, там будет примерно ~7,5-10,8МГц.
Тут есть измерения скорости выполнения кода в основной и быстрой памяти (кэш): https://t.me/zx_sprinter/14039
- - - Добавлено - - -
Так же режим Турбо может быть выключен пользователем - на реальном Спринтере по кнопке F12. Тогда частота процессора будет 3.5МГц.
Кстати, отличные результаты. Можно на код взглянуть? Возможно смогу что-то подсказать более детально.
RomanRom2
16.05.2021, 21:07
можно подключить fast-ram (на sram), тогда вейтится не будет при обращении к памяти.
это работает на реале только, в эмуляторе не реализовано.
Через аксель копировал? Или так - LDIR-ом?
Через аксель копировал? Или так - LDIR-ом?
такой спрайт поди не оправданно акселем выводить, +/- то же самое и получится
аксель может вертикальными отрезками копировать - используется тот же LDIR один раз, но копируются не байты, а целые отрезки - т.е. прямоугольник пикселов
Smalovsky
18.05.2021, 17:27
Продолжаю эксперименты
https://dropmefiles.com/rJCdM
Разбирался с двойной буферизацией. Результат тестировал на эмуляторе.
В образе диска следующие экзешники
Spbslw - демонстрация движения спрайта на медленной скорости с двойной буферизацией;
Sprite - движение спрайта без буферизации со средней скоростью;
Spriteb - движение спрайта с буферизацией на максимуме( 11 спрайтов выводится за 1/50 секунды с учётом восстановления фона).
Прошу потестировать на железе. На эмуляторе всё красиво.
Спрайты выводятся в формате Спектрум Некст( 227 цвет прозрачен + палитра Спектрум Некст).
Протестировал на моей плате Sp2000 производства 2002 года...
Smalovsky
30.05.2021, 14:51
Добил вывод тайловой карты. Теперь работающий прототип.
https://dropmefiles.com/6szoO
В архивеи сполняемые файлы
Maptest - тест вывода полноэкранного изображения тайлового слоя ( 255 экранов за минуту, 4.25 экрана в секунду. Это на эмуляторе. Интересно сколько на железе?);
ZXBMap - вывод 4 экранов по нажатию клавиши с буферированием;
ZXMap - вывод 4 экранов по нажатию клавиши без буферирования.
Вот что я заметил, при выводе с буферированием, смена экрана происходит мгновенно, и это как-то режет глаза, а вот без буферирования как-то волнообразно сверху в низ и более приятно для визуального восприятия.
Кто писал тайловые карты? Какое количество экранов за секунду кто получал?
Интересно, как Алон скролл для АТМ 2 делал?
https://www.youtube.com/watch?v=1tlW7kIxPyY
Это ж нереально. Разрешение 320 на 200 у экрана, цвет на каждый пиксель. Объёмы видеопамяти не маленькие.
Там ещё какой-то нечитабельный файл AM на дискете видится
Smalovsky
30.05.2021, 16:53
Там ещё какой-то нечитабельный файл AM на дискете видится
Ну, я ж на писи делаю образы дисков. Возможно, что-то случайно закинул. Не знаю что это. А экзешники Maptest, ZXBMap, ZXMap нормально запускаются? У Maptest на железе, не скажешь, какое время?
Ну, я ж на писи делаю образы дисков. Возможно, что-то случайно закинул. Не знаю что это. А экзешники Maptest, ZXBMap, ZXMap нормально запускаются? У Maptest на железе, не скажешь, какое время?
Да - нормально запускаются - чуть позже видосик сниму на телефон
А вообще если акселем копировать на экран, то весь экран копируется за 1.2 инта (т.е. в пределе 41 кадр в секунду) - вот код, который копирует из одной области видеопамяти в другую (можно сделать с нахлёстом, тогда будет типа скролл):
; display page was opened from the #C000 already
LD HL,#C000 ; Address of the beginning of a line of first screen
LD DE,#C180 ; Address of the beginning of a line of second screen
LD BC,#140 ; The width of the screen
DI ; Disable interrupt
LD D,D ; Switch the Accelerator to define block size mode
LD A,0 ; Set block size to 256 bytes
LD A,A ; Switch the Accelerator to copying a graphic data block mode
LDIR ; Copying
LD B,B ; Switch the Accelerator off
EI ; Enable interrupt
Smalovsky
31.05.2021, 19:09
Shaos, попробую акселератор,но у него есть недостаток - при копировании адреса из приемника в источник, адреса обоих возрастают. Это увеличивает расход памяти на хранение спрайтов, из-за невозможности их мирроринга, так как при копировании с инкреметом адресов невозможно копирование с зеркалированием цепочки байт. Если бы был ещё режим - инкремент адреса приёмника, декремент адреса источника, то расхода памяти для спрайтов можно было бы избежать.
Мне интересно как в игре TITD идёт работа со срайтами. Очень там гладко всё - уровень SNES. Где-то читал, что в этой игре есть модуль с прошивкой ФПГА на лету для ускорения спрайтового вывода. Мне нужен этот модуль и программный интерфейс к нему.
К сожалению информация по прошивке для Тхундера полностью утеряна (как и исходники) - насколько я знаю там была возможность крутить (скролить?) тайлы с точностью до 1 пиксела
Smalovsky
10.06.2021, 19:37
Я написал процедуру вывода тайла через ускоритель, так как тайловая карта строится последовательно по тайлам. Теперь время теста составляет 14 секунд, или 18.25 экранов в секунду.
Сделал образ диска с экзешными файлами:
SpMap - тест вывода 255 экранов на время;
Scroll - скролл карты с потайловым шагом.
Ссылка https://dropmefiles.com/IHCTU
Тестировал ещё потом вывод спрайтов без клиппинга. Вот такие результаты получил для спрайтов в 16 на 16 пикселей при их выводе за 1/50 секунду с учётом восстановления фона:
- Вывод спрайта программно с программным прозрачным цветом - около 17 спрайтов( как при прямом, так и при зеркальном выводе);
- Вывод спрайта программно с аппаратным прозрачным цветом - около 25 спрайтов при прямом выводе и 23 спрайта при зеркальном выводе ;
- Вывод спрайта акселератором с аппаратным прозрачным цветом - около 80 спрайтов.
При клиппировании эти результаты, однозначно, будут меньше, но я клиппирование ещё не проверял.
Недостаток вывода спрайтов акселератором - отсутствие зеркалирования. Но этот недостаток можно сгладить, если при запуске игры заранее сделать зеркальные копии спрайтов в памяти специальной процедурой.
RomanRom2
10.06.2021, 22:06
https://www.youtube.com/watch?v=9NOABKKpU1c&ab_channel=RomanKrupnin
Smalovsky
01.08.2021, 15:08
Shaos, если делать свой диспетчер прерываний для обработки нажатий клавиатуры, то этот пример кода для обработки нажатий на клавиатуре будет полезен?
http://sprinter8.org/blocks/z84c15/keyboard
Хочу сделать опрос клавиатуры в программе, но на своём диспетчере прерываний. От обычного спектрума процесс установки своей процедуры обработки прерывания чем-нибудь отличается на спринтере?
Справочная информация по прерываниям обычного спектрума https://zxpress.ru/article.php?id=1615
Shaos, если делать свой диспетчер прерываний для обработки нажатий клавиатуры, то этот пример кода для обработки нажатий на клавиатуре будет полезен?
http://sprinter8.org/blocks/z84c15/keyboard
Да, поможет. В принципе достаточно только второго листинга из статьи, п/п READ_KBD. Инициализацию порта делает DSS.
Хочу сделать опрос клавиатуры в программе, но на своём диспетчере прерываний. От обычного спектрума процесс установки своей процедуры обработки прерывания чем-нибудь отличается на спринтере?
Справочная информация по прерываниям обычного спектрума https://zxpress.ru/article.php?id=1615
Если хочешь сэкономить такты и не нужны функциональные клавиши и пр..., то можешь опрашивать спектрумовские порты клавиатуры - они доступны (в эмуляторе возможно потребуется добавить устройство Common Spectrum Keyboard).
Smalovsky
22.08.2021, 16:47
Начал писать движок игры. Тут такое дело возникло: выделяю в программе память, в конце программы освобождаю память, а в ОС по окончании программы нет выхода. Где я напутал?
Выделяю память так:
;сохранение старых значений страниц в окнах 0,1,3
IN A,(0x82)
LD (OldWin0Page),A
IN A,(0xa2)
LD (OldWin1Page),A
IN A,(0xE2)
LD (OldWin3Page),A
;выделение памяти
;для окон 0 и 3
;получение блока памяти на две страницы
ld b, 2
ld c,61
rst 0x10
ld (memblock),a; сохраним номер блока
;получим номера физических страниц в блоке
;в акк уже есть ном. блока
ld b, 0
ld c,196
call 15635
ld (Win0Page),a
ld a,(memblock)
ld b, 1
ld c,196
call 15635
ld (Win3Page),a
;отключение прерываний
di
ld a,i
ld (OldIREG),a
ld (OldSP),sp
;Установка новых значений страниц в окнах 0,1,3
Ld a,(Win0Page)
out (0x82),a
LD A,0x54; в 1 странице видеопамять
OUT (0xa2),A
Ld a,(Win3Page)
out (0xe2),a
;УСТАНАВЛИВАЕ СТЕК
ld sp,61000
Освобождаю память так:
di
ld a,(OldIREG)
ld i,a
im 1
;Установка старых значений страниц в окнах 0,1,3
Ld a,(OldWin0Page)
out (0x82),a
LD A,(OldWin1Page)
OUT (0xa2),A
Ld a,(OldWin3Page)
out (0xe2),a
;УСТАНАВЛИВАЕМ СТАРЫЙ СТЕК
ld sp,(OldSP)
;ei Включал прерывания - не помогло. В ОС нет выхода
;освобождаем память
ld a,(memblock)
ld c,62
rst 0x10
Вот исходный код во вложении( Пасмо ассемблер).75996
Скомпилированная программа:
https://dropmefiles.com/1IaUY
;получим номера физических страниц в блоке
;в акк уже есть ном. блока
ld b, 0
ld c,196
call 15635
Лучше пользоваться RST 8 для этого, там хоть и стоит заглушка, которая перенаправляет на #0008, но все же так быстрее и понятнее.
Что касается проблемы - с виду все норм, не заметил ничего критичного. Попробую подебажить - посмотрим.
Кстати, многие не знают, но в ZXMAK2 есть Debugger, который может здорово помочь в отладке!
Smalovsky
22.08.2021, 17:16
Что касается проблемы - с виду все норм, не заметил ничего критичного. Попробую подебажить - посмотрим.
Кстати, многие не знают, но в ZXMAK2 есть Debugger, который может здорово помочь в отладке!
Дебажил. На функции freemem (62),вроде, вываливается:
ld a,(memblock)
ld c,62
rst 0x10
Smalovsky
22.08.2021, 20:14
Решил проблему. Похоже, нумерация логических страниц в блоке с единицы...
Заменил номера страниц с 0 и 1 на 1 и 2 - заработал правильный выход в ОС.
нумерация страниц в блоке таки с нуля (0,1,2...)
а возврат в DSS у нас такой:
; Exit program
exit:
ld bc,0041h
rst 10h
либо RST 0 который вызывает тоже самое
- - - Updated - - -
и зачем SP переставлять вручную, если DSS при загрузке EXE всё равно ставит в тот SP который в хедере? и соответственно при выходе в DSS через 41h всё вернётся туда где было
Smalovsky
01.09.2021, 16:35
Хотел сделать обработку клавиатуры в прерывании через функцию ОС scankey. Вот так:
;здесь обработка клавиатуры
Ld a,(OldWin0Page); восстанавливаем системную страницу
out (0x82),a
ld a,0
ld (scankey),a
LD C,0x31 ;Функция опроса клавиатуры без ожидания
RST 0x10
JR Z,int2body1
ld a,d
and 127 ;убираем седьмой бит
ld (scankey),a
int2body1:
Ld a,(Win0Page)
out (0x82),a
Почему-то это не работало...
Пришлось писать обработку AT-клавиатуры самому. Вот код:
;Клавиатура
SerialChAData EQU #18 ;регистр данных канала A последовательного порта контроллера Z84
SerialChACtrl EQU #19 ;контролирующий регистр канала A последовательного порта контроллера Z84
kbMoveUp EQU 0x75 ;стрелка вверх
kbMoveDown EQU 0x72 ;стрелка вниз
kbMoveLeft EQU 0x6B ;стрелка влево
kbMoveRight EQU 0x74 ;стрелка вправо
kbEsc EQU 0x76 ;ескейп
target defb 0 ;код нажатой клавиши
scankey defb 0
pflag defb 0
eflag defb 0 ;флаг расширенных кодов
fflag defb 0 ;флаг заполнения буфера
;_____________________________
;обработчик прерывания
int2m:
di
push af
push bc
push de
push hl
ld a,(tick)
cp 2
jr nc, int2body
inc a
ld (tick),a
int2body:
;здесь обработка клавиатуры AT[ps/2 scan set 2]
keys:
ld a,(target) ; проверяем переменную со сканкодом нажатой клавиши
or a
jp nz, keystep2 ;если не ноль, то переходим к отлову отжатия клавиши
;иначе проверяем сканкод нажатой клавиши
call scan
ld d,a
ld a,(fflag) ;проверяем буфер клавиатуры по флагу заполнения
or a
jp z, player ;если пуст - выходим
ld a,d
cp 0xF0; ;клавиша отжата?
jr nz, keystep11 ;нет - проверяем на байт расширения
call scan; ;иначе, освождаем буфер и выходим
jp player
keystep11:
cp 0xE0; ;проверка на байт расширения
jr nz,keystep12 ;если нерасширенный код, то переходим на обработку нерасширенных кодов
call scan ;иначе, читаем буфер и сравниваем с
cp 0xF0 ;кодом отжатия расширенного кода
jr nz,keystep13 ;если не отжатие, то расширенный код, переходим на обработку расширенных кодов
call scan ;иначе, освобождаем буфер и выходим
jp player
keystep13:
ld (target),a ;запоминаем расширенный код
ld a,1
ld (eflag),a ;устанавливаем флаг расширенного кода и выходим
jp player
keystep12:
ld (target),a ;запоминаем нерасширенный код
xor a
ld (eflag),a ;сбрасываем флаг расширенного кода и выходим
jp player
keystep2:
ld a,(eflag) ;по флагу расширенных кодов определяем какое отжатие ловить
or a
jr z, keystep_for_F0 ;если флаг сброшен, ловим простое отжатие F0 нерасширенных кодов
;иначе, отлов расширенного отжатия EOFO расширенных кодов
call scan
ld d,a
ld a,(fflag)
or a
jp z, player ;буфер пуст? да - выход
ld a,d
cp 0xE0 ;расширенный код?
jr nz,F0compare ;нет - проверка на обычное отжатие
call scan ;иначе,читаем буфер
cp 0xF0 ;проверка на расширенное отжатие
jr nz, player ;если не расширренное отжатие, то освобождаем буфер и выход
call scan ;иначе, читаем расширенный код клавиши, которая была отжата
ld b,a
ld a,(target)
cp b ;сравниваем код отжатой клавиши с клавишей, которая была нажата
jr nz, player ;если коды не совпадают - выход
;ld (scankey),a
xor a
ld (target),a ;иначе, сбрасываем переменную для кода нажатой клавиши
ld (eflag),a ; и сбрасываем флаг расширенных кодов
jr player ;выход
F0compare:
cp 0xF0 ;обычное отжатие?
jr nz, player ;нет -выход
call scan ;да - освобождаем буфер и выход
jr player
;отлов F0 (обычного отжатия нерасширенных кодов)
keystep_for_F0:
call scan ;читаем буфер
ld d,a
ld a,(fflag)
or a
jp z, player ;если буфер пуст - выход
ld a,d
cp 0xF0 ;обычное отжатие?
jr nz, E0compare ;если нет - проверка расширенных кодов
call scan ;иначе, читаем код отжатой клавиши
ld b,a
ld a,(target)
cp b ;сравниваем код отжатой клавиши с клавишей, которая была нажата
jr nz, player ;если коды не совпадают - выход
;ld (scankey),a
xor a
ld (target),a ;иначе, сбрасываем переменную для кода нажатой клавиши
jr player ;выход
E0compare: ;отлов расширенных кодов для освобождения буфера
cp 0xE0 ;расширенный код?
jr nz, player ;если нет - выход
call scan ;иначе, читаем буфер
cp 0xF0 ;расширенное отжатие?
jr nz, player ;если нет - выход
call scan ;иначе, освобождаем буфер от кода отжатой клавиши и выход
jr player
;работа c плеером
player:
pop hl
pop de
pop bc
pop af
ei
reti
;_______________________________
scan:
;проверка есть ли данные от клавиатуры
IN a,(SerialChACtrl) ;бит0 = 0 - нет данных;бит0 = 1 - есть данные
and 1
ld (fflag),a
JR z,scanexit
;если данные есть
IN a,(SerialChAData)
scanexit:
ret
Работает. Программа реагирует на клавиши направлений(стрелки) и ескейп. В каждое отдельное прерывание работает только треть кода: либо фиксация в переменной кода нажатой клавиши, либо отлов отжатия F0, или отлов отжатия расширенного кода E0F0. Прошу потестить на реале, так как есть подозрение что эмулятор не пропускает клавиши PrintScreen и Pause\Break. Нужно проверить - нажатие этих клавиш не приведёт ли к отключению реакции на клавиши? Алгоритм обработки нажатий реагирует на обычные( однобайтовые коды нажатий и двубайтовые отпусканий) и расширенные( двубайтовые для нажатий и трёхбайтовые для отпусканий) коды, но не на дополнительные. Вот, нажатие ПринтСкрин и Паузы может привести к непредсказуемым результатам, так как они имеют дополнительные коды( 4-6 байт). Есть подозрение, что нажатие Паузы заблокирует клавиатуру.
Ссылка на образ диска https://dropmefiles.com/9jsV5
Может, кто приведёт пример более оптимального кода обработки нажатий клавиш клавиатуры? У меня слишком громоздкий получился.
Полезные ссылки по теме:
https://dvsav.ru/at-ps2-keyboard/
https://ru.wikipedia.org/wiki/%D0%A1%D0%BA%D0%B0%D0%BD-%D0%BA%D0%BE%D0%B4
Смотрел ещё исходники Клада от CHRV. Там обработчик совсем другой и для других целей( обработка нажатий нескольких клавиш). Мне не подойдёт.
в обработчике прерываний DSS лучше не вызывать
тем более клавишные подпрограммы - DSS ведь само по прерыванию инфу про кнопки берёт
говорят, что клавиатуру можно по ZX-спектрумовски читать даже в режиме Спринтера - я не пробовал, ну и там естественно без курсорных и расширенных клавиш будет...
Smalovsky
02.09.2021, 13:56
Shaos, мне бы кто на реале посмотрел тест клавитуры и отписался, клавиши ПринтСкрин и Пауза блокируют ли программу. Нужно стрелки понажимать чтоб квадратик подвигался, а затем нажать ПринтСкрин и Паузу в любом порядке, и затем снова стрелки. Эмулятор клавиши Принтскрин и Паузы не передаёт программе,поэтому я не знаю что будет на реале при нажатии этих клавиш.
Просто, если есть возможность, погоняй на реале, напиши на форум какой результат. Нужно узнать работают ли стрелки после нажатия клавиш ПринтСкрин и Пауза. Обработку клавиатуры я делаю для игры.
Образ диска https://dropmefiles.com/9jsV5
У меня сейчас Спринтер в разобранном виде (переезжает со стола в ПЦ-корпус) - может Сайман или RomanRom2 смогут позапускать
Smalovsky, проверил. после запуска нажал на стрелку вправо. кубик начал движение. как его остановить? при нажатии на esc реакции нет. кубик доезжает до (почти) границы экрана и всё зависает. кубик за собой оставляет какие то полоски, с шагом и возрастанием. потом после ребута запустил снова. нажал на курсор вниз. кубик поехал вниз. далее всё аналогично. реакции на pause или print screen никакой нет.
Не знаю почему у тебя не работает опрос на прерываниях.
У меня опрос клавиатуры нормально работал, я делал так:
Обработчик прерваний в конце вызывает RST #38 (досовский обработчик прерываний IM1):
Im2Handler:
di
push all
...
pop all
ei
rst #38
В коде проверка клавиатуры:
CheckKeys:
ld c,Dss.ScanKey
rst #10
ret z ;ничего не нажато
;определение нажатой кнопки
ret
Smalovsky
09.09.2021, 17:40
проверил. после запуска нажал на стрелку вправо. кубик начал движение. как его остановить? при нажатии на esc реакции нет. кубик доезжает до (почти) границы экрана и всё зависает.
Непонятно. В эмуляторе всё работает. Надо бы, что бы ещё кто на спринтере проверил.
кубик за собой оставляет какие то полоски, с шагом и возрастанием.
Это исправил.
Вот видео работы обновленной программы на эмуляторе( теперь уже спрайт двигается на фоне):
https://www.youtube.com/watch?v=-HQI-jKQ1fg&list=PLzrngP6uvMnY7jNMd2aAYEQEMN0VNNFgH&index=1
Возможно проблемы с клавиатурой в этом кусочке программы:
scan:
;проверка есть ли данные от клавиатуры
IN a,(SerialChACtrl) ;бит0 = 0 - нет данных;бит0 = 1 - есть данные
and 1
ld (fflag),a
JR z,scanexit
;если данные есть
IN a,(SerialChAData)
;вот тут возможно нужно что-то отправить в порт SerialChACtrl, что бы разрешить дальнейшую пересылку данных от клавиатуры
scanexit:
ret
Это надо разбираться с последовательным портом будет.
Программа для тестирования:
https://dropmefiles.com/4hFOg
Smalovsky
12.09.2021, 16:12
Повторю ссылку https://dropmefiles.com/4hFOg
У кого есть железный Спринтер, если есть возможность, протестируйте программу. Проверьте клавиши со стерлками, ескейп, принтскрин и паузу.
Мне не понятно, почему в эмуляторе программа работает, а на железе не хочет работать.
Только первую кнопку отрабатывает - сразу после запуска нажму вниз - едет вниз, а если нажму вправо - едет вправо и всё остальное игнорирует
P.S. По-моему проще 2К файл цеплять на форум как файл, а не грузить 1.4Мб образ дискеты...
Smalovsky
16.09.2021, 18:22
Shaos, спасибо за тестирование. Попробую в отладчике посмотреть работу с клавиатурой системных подпрограмм. Возможно, это поможет разобраться.
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot