PDA

Просмотр полной версии : Мои эксперименты



Smalovsky
16.05.2021, 16:48
Мои эксперименты
https://dropmefiles.com/5mI4A
Экзешники в образе
Sprite - движение спрайта без буферирования(видно мелькание), Tile - вывод одиночного тайла, Tiles - вывод тайлов с прозрачностью, Tilescr - покрытие экрана тайлами, Tiletest - вывод 255 экранов замощенных тайлами( в среднем 4 экрана за секунду, время теста 63.5 секунды).
Подскажите, кто знает,на какой частоте работает Спринтер при запуске программ из ОС Естекс 10.5 МГц?

Дмитрий
16.05.2021, 20:51
Т.к. SIMM работает на частоте 7МГц, то при выполнении программы из основного ОЗУ процессор вейтится, так что да, там будет примерно ~7,5-10,8МГц.
Тут есть измерения скорости выполнения кода в основной и быстрой памяти (кэш): https://t.me/zx_sprinter/14039

- - - Добавлено - - -

Так же режим Турбо может быть выключен пользователем - на реальном Спринтере по кнопке F12. Тогда частота процессора будет 3.5МГц.
Кстати, отличные результаты. Можно на код взглянуть? Возможно смогу что-то подсказать более детально.

RomanRom2
16.05.2021, 21:07
можно подключить fast-ram (на sram), тогда вейтится не будет при обращении к памяти.
это работает на реале только, в эмуляторе не реализовано.

Shaos
16.05.2021, 22:55
Через аксель копировал? Или так - LDIR-ом?

Дмитрий
16.05.2021, 23:15
Через аксель копировал? Или так - LDIR-ом?

такой спрайт поди не оправданно акселем выводить, +/- то же самое и получится

Shaos
17.05.2021, 00:54
аксель может вертикальными отрезками копировать - используется тот же LDIR один раз, но копируются не байты, а целые отрезки - т.е. прямоугольник пикселов

Smalovsky
18.05.2021, 17:27
Продолжаю эксперименты
https://dropmefiles.com/rJCdM
Разбирался с двойной буферизацией. Результат тестировал на эмуляторе.
В образе диска следующие экзешники
Spbslw - демонстрация движения спрайта на медленной скорости с двойной буферизацией;
Sprite - движение спрайта без буферизации со средней скоростью;
Spriteb - движение спрайта с буферизацией на максимуме( 11 спрайтов выводится за 1/50 секунды с учётом восстановления фона).
Прошу потестировать на железе. На эмуляторе всё красиво.
Спрайты выводятся в формате Спектрум Некст( 227 цвет прозрачен + палитра Спектрум Некст).

Shaos
19.05.2021, 04:57
Протестировал на моей плате 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 у экрана, цвет на каждый пиксель. Объёмы видеопамяти не маленькие.

Shaos
30.05.2021, 16:45
Там ещё какой-то нечитабельный файл AM на дискете видится

Smalovsky
30.05.2021, 16:53
Там ещё какой-то нечитабельный файл AM на дискете видится
Ну, я ж на писи делаю образы дисков. Возможно, что-то случайно закинул. Не знаю что это. А экзешники Maptest, ZXBMap, ZXMap нормально запускаются? У Maptest на железе, не скажешь, какое время?

Shaos
31.05.2021, 00:59
Ну, я ж на писи делаю образы дисков. Возможно, что-то случайно закинул. Не знаю что это. А экзешники 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. Где-то читал, что в этой игре есть модуль с прошивкой ФПГА на лету для ускорения спрайтового вывода. Мне нужен этот модуль и программный интерфейс к нему.

Shaos
31.05.2021, 22:26
К сожалению информация по прошивке для Тхундера полностью утеряна (как и исходники) - насколько я знаю там была возможность крутить (скролить?) тайлы с точностью до 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

Дмитрий
01.08.2021, 18:04
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

Дмитрий
22.08.2021, 17:04
;получим номера физических страниц в блоке
;в акк уже есть ном. блока
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 - заработал правильный выход в ОС.

Shaos
23.08.2021, 08:52
нумерация страниц в блоке таки с нуля (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. Там обработчик совсем другой и для других целей( обработка нажатий нескольких клавиш). Мне не подойдёт.

Shaos
01.09.2021, 20:10
в обработчике прерываний DSS лучше не вызывать
тем более клавишные подпрограммы - DSS ведь само по прерыванию инфу про кнопки берёт
говорят, что клавиатуру можно по ZX-спектрумовски читать даже в режиме Спринтера - я не пробовал, ну и там естественно без курсорных и расширенных клавиш будет...

Smalovsky
02.09.2021, 13:56
Shaos, мне бы кто на реале посмотрел тест клавитуры и отписался, клавиши ПринтСкрин и Пауза блокируют ли программу. Нужно стрелки понажимать чтоб квадратик подвигался, а затем нажать ПринтСкрин и Паузу в любом порядке, и затем снова стрелки. Эмулятор клавиши Принтскрин и Паузы не передаёт программе,поэтому я не знаю что будет на реале при нажатии этих клавиш.
Просто, если есть возможность, погоняй на реале, напиши на форум какой результат. Нужно узнать работают ли стрелки после нажатия клавиш ПринтСкрин и Пауза. Обработку клавиатуры я делаю для игры.
Образ диска https://dropmefiles.com/9jsV5

Shaos
02.09.2021, 20:16
У меня сейчас Спринтер в разобранном виде (переезжает со стола в ПЦ-корпус) - может Сайман или RomanRom2 смогут позапускать

Sayman
03.09.2021, 09:14
Smalovsky, проверил. после запуска нажал на стрелку вправо. кубик начал движение. как его остановить? при нажатии на esc реакции нет. кубик доезжает до (почти) границы экрана и всё зависает. кубик за собой оставляет какие то полоски, с шагом и возрастанием. потом после ребута запустил снова. нажал на курсор вниз. кубик поехал вниз. далее всё аналогично. реакции на pause или print screen никакой нет.

Дмитрий
03.09.2021, 18:00
Не знаю почему у тебя не работает опрос на прерываниях.
У меня опрос клавиатуры нормально работал, я делал так:
Обработчик прерваний в конце вызывает 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
У кого есть железный Спринтер, если есть возможность, протестируйте программу. Проверьте клавиши со стерлками, ескейп, принтскрин и паузу.
Мне не понятно, почему в эмуляторе программа работает, а на железе не хочет работать.

Shaos
16.09.2021, 10:46
Только первую кнопку отрабатывает - сразу после запуска нажму вниз - едет вниз, а если нажму вправо - едет вправо и всё остальное игнорирует

P.S. По-моему проще 2К файл цеплять на форум как файл, а не грузить 1.4Мб образ дискеты...

Smalovsky
16.09.2021, 18:22
Shaos, спасибо за тестирование. Попробую в отладчике посмотреть работу с клавиатурой системных подпрограмм. Возможно, это поможет разобраться.