Просмотр полной версии : PyZX - эмулятор ZX Spectrum, полностью написанный на Python
CityAceE
01.12.2018, 10:54
Во вложении PyZX (https://www.pygame.org/project-PyZX-173-.html) с моими доработками:
- Перевёл программу с Python 2 на современный Python 3
- Причесал текст и максимально, где это было возможно, привёл к стандарту PEP 8
- Добавил возможность загрузки снепшотов в формате SNA
- Починил проблемы с обработкой яркости и ускорил перерисовку экрана (в оригинале 50 экранов рисовались за 1.58 сек, а моя процедура делает то же самое за 1.22 сек).
Данный эмулятор может представлять сегодня лишь академический интерес, так как он медленный, без звука, не имеет интерфейса, поддерживает только 48К модель, а уровень эмуляции оставляет желать лучшего.
Я полез в него только потому, что мне очень интересен язык программирования Python и меня посетила мыль написать свой эмулятор на этом языке. Я прикидывал удастся ли сделать эмулятор, который будет иметь 100%-ную скорость эмуляции. Я уже писал эмулятор (https://zx-pk.ru/threads/21181-emulyator-zx-pilot-dlya-palm-os.html) в условиях низкого быстродействия и, думаю, что если применить многие из моих ловок, к которым я ранее прибегал, то есть шанс получить эмулятор на Python со 100%-ной скоростью эмуляции. Вот только нужно ли оно?
P.S. Написал целую простыню текста с кучей рассуждений, ссылок (https://github.com/fjpena/sword-of-ianna-zx/tree/master/python_src) и т.д., а потом случайно задел на мышке кнопку "Back" и в итоге вернулся назад на страницу, потеряв всё то, что писал в течение часа. Автосохранение почему-то не сработало. Второй раз писать то же самое я не решился.
К проекту подключился Q-Master и свои доработки выкладывает на GitHub: https://github.com/Q-Master/PyZX
CodeMaster
01.12.2018, 11:40
P.S. Написал целую простыню текста с кучей рассуждений, ссылок и т.д., а потом случайно задел на мышке кнопку "Back" и в итоге вернулся назад на страницу, потеряв всё то, что писал в течение часа.
Я всегда в этом момент думаю: это хуже чем когда молоток соскальзывает с гвоздя на палец? И не всегда нахожу однозначного ответа.
Спасибо!
Первый фича реквест: возможность цивилизованного выхода из программы ;) По крайней мере я не нашел, как это сделать. Alt-F4 не работает, Ctrl-C в окне консоли тоже игнорируется.
В README написано про Питон 2.4, наверное устаревший текст? Я пробовал на 3.7.0.
CityAceE
01.12.2018, 12:27
В README написано про Питон 2.4, наверное устаревший текст? Я пробовал на 3.7.0.
Ну да, исходная версия и была рассчитана только на Python 2. Думаю, что в 2008 году только такой Python и был доступен. Я же перевёл его на Python 3.
sergio78
01.12.2018, 13:01
, так как он медленный,
то что пишут на питоне, всё медленное. это основная фишка данного языка. даже жаба по моему быстрее, а ещё медленнее только лишь GO.
ZX_NOVOSIB
01.12.2018, 13:48
sergio78, это ты ещё спектрум-бейсик не видел.
CityAceE
01.12.2018, 14:57
то что пишут на питоне, всё медленное.
Да, но при этом всё пишется ОЧЕНЬ БЫСТРО в силу особенностей языка. К тому же не все программы требуют высокого быстродействия. Например, какой-нибудь графический редактор требует вычислений только в момент клика мыши, а всё остальное время крутится холостой цикл.
sergio78
01.12.2018, 18:23
этом всё пишется ОЧЕНЬ БЫСТРО
это лично мое мнение, но мне очень не нравиться подобный низкий порог вхождения, я сторонник элитарности программирования и не доступности его основной массе населения. этим делом должны заниматься исключительно единицы, а всех остальных нужно лопатой отгонять. во первых демпфируется рынок труда. а во вторых, вот из за того, что сейчас каждый бывший сапожник или домохозяйка например на смартфоне что то там пишет, вернее наковыривает, засран весь интернет, в тот же гугольстор зайти нельзя, сколько там разного мусора и фекалий. и отыскать что то стоящее очень трудно, когда на тебя льется поток подобного мусора.
SaintTurnip
01.12.2018, 22:47
я сторонник элитарности программирования и не доступности его основной массе населения. этим делом должны заниматься исключительно единицы, а всех остальных нужно лопатой отгонять
И крепостное право вернуть. Кто знает джаву - по ста крепостных выдать, за c# уже пять сотен, а ассемблерщиков сразу сенаторами и губернаторами назначать - в зависимости ARM или x86.
Конечно нужно, так как позволит запускать эмулятор в любой системе, имеющей python3. А еще такой проект существует: http://skoolkit.ca
sergio78
02.12.2018, 11:25
И крепостное право вернуть
ну вообще, без рабовладельчества все аграрные экономики моментально хереют. если хотим фураж и силос на международный рынок поставлять, тогда можно и крепостное право возворачивать. а вот если высокотехнологические програмки на бирже с бешенной добавочной стоимостю, тут увы нужно развивать свободолюбивое разнообразное образование, но и создавать жесточайший отборочный фильтр выпускников.
SaintTurnip
02.12.2018, 11:48
ну вообще, без рабовладельчества все аграрные экономики моментально хереют
и шут с ними
- - - Добавлено - - -
то что пишут на питоне, всё медленное. это основная фишка данного языка. даже жаба по моему быстрее, а ещё медленнее только лишь GO.
sergio78, это ты ещё спектрум-бейсик не видел.
Надо замутить честный бенчмарк: или спектрум бейсик запустить на 3.5ГГц, или питон на 3.5 МГц (архитектурами и машинными циклами пренебрежем for fuck's sake)
Первое трудоемко, поэтому будем замедлять питон.
Надо:
питон для MS DOS (http://www.caddit.net/pythond/)
[?] эмулятор 386 с возможностью устанавливать мегагерцы (http://spc-emu.uphero.com/) (UPD: здесь ниже 8МГц никак! продолжаем поиск)
[_] алгоритм бенчмарка
Bedazzle
03.12.2018, 08:10
Данный эмулятор может представлять сегодня лишь академический интерес
Он может быть как первая ступенька для переноса софта на пц. Когда хуками перехватываются некоторые процедуры, и отрабатывает уже не спектрумский бинарник, а новый код. Потом больше, и в результате - от спека нужны только ресурсы с табличками и текстами.
SaintTurnip
03.12.2018, 08:24
Он может быть как первая ступенька для переноса софта на пц. Когда хуками перехватываются некоторые процедуры, и отрабатывает уже не спектрумский бинарник, а новый код. Потом больше, и в результате - от спека нужны только ресурсы с табличками и текстами.
Какой замысловатый эмулятор! :)
Но идея очень крутая.
Q-Master
03.12.2018, 22:59
это лично мое мнение, но мне очень не нравиться подобный низкий порог вхождения, я сторонник элитарности программирования и не доступности его основной массе населения. этим делом должны заниматься исключительно единицы, а всех остальных нужно лопатой отгонять. во первых демпфируется рынок труда. а во вторых, вот из за того, что сейчас каждый бывший сапожник или домохозяйка например на смартфоне что то там пишет, вернее наковыривает, засран весь интернет, в тот же гугольстор зайти нельзя, сколько там разного мусора и фекалий. и отыскать что то стоящее очень трудно, когда на тебя льется поток подобного мусора.
Тут есть нюансы. Дело в том, что питон имеет определенные требования по оформлению кода и по реализациям тех или иных вещей (PEP), которые очень здорово ограничивают количество непотребного кода в программах. "Илитарность" обеспечивается не порогом вхождения в язык, а умениями и качеством и нормальный питон-программер стоит нифига недешево и дешевле не становится. Пример с мобильниками не очень.
- - - Добавлено - - -
Посмотрел я код эмуля. С первого взгляда код не понравился. pack/unpack автору явно незнаком, numpy тоже. По мне так очень похоже на прямое переложение с какого-то другого языка (С возможно) без каких-либо оптимизаций.
s_kosorev
04.12.2018, 02:01
даже жаба по моему быстрее, а ещё медленнее только лишь GO.
Глупость сморозил, но она очень четко показывает твои экспертные знания
perestoronin
04.12.2018, 09:00
без рабовладельчества
А что, волонтерство сейчас модно среди обеспеченных, да и опенсорс тоже дышет, и кто-то даже на пирожок себе зарабатывает за год.
PS. Может флудить удобнее будет в разделе флейм?, а здесь лучше по теме пишите, если не сложно :)
CityAceE
04.12.2018, 14:13
Посмотрел я код эмуля. С первого взгляда код не понравился. pack/unpack автору явно незнаком, numpy тоже. По мне так очень похоже на прямое переложение с какого-то другого языка (С возможно) без каких-либо оптимизаций.
Да вот, собственно, автор и не скрывает, всё честно написав в прилагаемой документации:
"Thanks to Jasper(http://www.spectrum.lovely.net/) for real great Java emulator of ZX Spectrum. Big amount of code was just automatically translated from Java into Python, so we need more optimization/rewriting to reach good speed of emulation."
Q-Master
04.12.2018, 20:22
Да вот, собственно, автор и не скрывает, всё честно написав в прилагаемой документации:
"Thanks to Jasper(http://www.spectrum.lovely.net/) for real great Java emulator of ZX Spectrum. Big amount of code was just automatically translated from Java into Python, so we need more optimization/rewriting to reach good speed of emulation."
Хех я угадал ибо как истинный Ъ по ссылкам не хожу и доки не читаю :).
PS: Поковырял сегодня код - код ужасен в принципе и сразу вобщем-то понятно почему оно тормозит. Более того, в коде есть ошибки которые должны приводить к падениям по исключению, т.к. там есть ссылки на переменные, которых нет. Мне чот стало забавно поковыряться, попробую со скуки чуть улучшить характеристики, да и некоторые явные кривуляки убрать.
CityAceE
05.12.2018, 04:15
pack/unpack автору явно незнаком, numpy тоже.
Стало любопытно в каких местах PyZX это можно было бы применить?
Мне чот стало забавно поковыряться, попробую со скуки чуть улучшить характеристики, да и некоторые явные кривуляки убрать.
А у меня после копания в коде PyZX возникло желание написать что-то своё, хотя это будет существенно дольше.
Q-Master
05.12.2018, 19:48
Стало любопытно в каких местах PyZX это можно было бы применить?
Так все байтодрочерство однозначно надо в pack/unpack зафигачивать и в memoryview(bytearray). По большому счету, timeit.timeit много интересных моментов расскажет про скорости выполнения того или иного куска кода.
А у меня после копания в коде PyZX возникло желание написать что-то своё, хотя это будет существенно дольше.
Писать долго. А тут возможно еще привести в порядок, но скорости конечно не будет. Ускорить можно если написать на Cython основные моменты, но это уже будет не так интересно.
CityAceE
13.12.2018, 09:25
@Q-Master, как успехи? Или не стал связываться с PyZX?
А я всё-таки взялся за свой эмулятор с нуля. Не уверен, что доведу его до конца - уж больно муторно сидеть и все команды эмулировать. Хотя когда-то я уже это проходил.
Q-Master
13.12.2018, 19:38
@Q-Master, как успехи? Или не стал связываться с PyZX?
А я всё-таки взялся за свой эмулятор с нуля. Не уверен, что доведу его до конца - уж больно муторно сидеть и все команды эмулировать. Хотя когда-то я уже это проходил.
Ну как успехи:
1. Там есть ошибки в коде, которые вообще не понятно как позволяли ему работать. Реально используются переменные, которые нигде не объявлены.
2. Сейчас переписываю эмуль проца с if/if/if/if на dict (аналог switch/case получится).
3. Переписал часть медленных битовых операций на куда более быстрое деление с остатком.
4. Поковырялся с регистрами, но пока ничего там еще не сделал толком. Надо подключать битфилды для флагов и memoryview для остальных регистров.
п.2 пипец долгий и нудный. Я максимум еще только треть сделал...
Bedazzle
13.12.2018, 23:59
Я максимум еще только треть сделал...
Дело хорошее!
CityAceE
14.12.2018, 00:53
Q-Master, отличные новости! Только, судя по всему, от PyZX там уже мало что останется :) Но это, наверное, даже хорошо!
Ну, а треть п.2 так это, как мне кажется, очень даже неплохой результат! Ждём дальнейших новостей!
Q-Master
05.01.2019, 00:35
Пока ситуация такова:
1. Я осилил переписать код Z80 и пока не особо заморачивался с оптимизацией.
2. Я напрочь забыл какой ужос эти ваши флаги. :) Подозреваю что у меня сейчас там все плохо касательно 16-битных операций.
3. Я дописал огромный кусок, который автор исходного варианта вообще не делал (ddcb/fdcb).
4. Вычистил кучу помоев относительно ругани линтера.
5. Убрал из файлов виндовый перенос строк.
Самая вишенка: я не проверял работает это вообще или нет :)
PS: Да почините уже форум, чтобы он принимал файлы *.tar.*. Я уже задолбался пережимать архивы.
CityAceE
05.01.2019, 04:01
Q-Master, пока не получилось запустить - ты, видимо, не все файлы из своего проекта в архиве освежил. Хотя первая же ошибка -это внутренняя ошибка в z80.py из-за того, что переменные задаются уже после их первого использования. Запускаю - получаю ошибку, правлю - получаю следующую и т.д.
Q-Master
08.01.2019, 18:59
"Я починиль" (С)
Вобщем граблей было очень много и до сих пор я не все выловил, НО
1. В исходном эмуляторе неверно отрабатывл обсчет тактов для команд типа *IR. Я исправил и теперь прерывание может придти даже поперек LDIR(к примеру) и такты вычисляются для всех *IR верно.
2. Исправил неверное расположение регистров в памяти.
3. Исправил неприятный косячек с относительными переходами. PC вычислялось неверно.
4. Исправил загрузку sna (z80 вероятно пока не работает) и более верно поддерживается заголовок.
5. Переделал загрузку z80, но пока не отлаживал и не проверял.
6. Добавил включение отладки через прописывание Z80.show_debug_info = True
Из проблем:
1. Видимо, что-то не так с флагами и эксолон не работает как надо.
2. Не работает загрузка z80
3. 100% упадет на HALT
ИМХО работает пошустрее оригинала, но надо оптимизировать видеовывод.
Bedazzle
09.01.2019, 08:10
1. Видимо, что-то не так с флагами и эксолон не работает как надо.
Для теста пересохранил эксолон в Z80 через спекулятор, на старой версии pyzx.0.2 работает.
CityAceE
09.01.2019, 14:10
4. Исправил загрузку sna (z80 вероятно пока не работает) и более верно поддерживается заголовок.
Загрузку SNA делал я на скорую руку, так как мой набор "идеальных" снепшотов был в формате SNA. Я когда-то делал эти снепшоты из TZX-файлов: после загрузки последнего байта с "магнитофона", я передавал управление в крохотную подпрограмму опроса клавиатуры, расположенную в стеке. После того, как нажимается любая клавиша, программа переходит на адрес запуска игры. Таким образом пользователь имеет возможность посмотреть заставку и при этом не портится сама игра. Я проверил несколько таких своих снепшотов и у меня всё грузилось в PyZX.
Заметил, что в эмуляторе нет защиты записи в область ПЗУ. Вообще, чтобы всё корректно работало, и чтобы потом можно было безболезненно расширить эмулятор до 128 Кб и выше нужно, чтобы все команды чтения или записи в память использовали соответствующую процедуру, а не просто напрямую записывали или читали память. Это же потом поможет ускорить вывод графики - не придётся обновлять целиком экран. Q-Master, сделаешь?
Вон, например, как я сделал у себя в эмуляторе Intel 8080 (write_mem и read_mem):
def b00110010(): # LD (nn),A / STA nn
global pc, ticks
write_mem(read_mem(inc_pc(2)) * 256 + read_mem(inc_pc()), reg_a[0])
pc = inc_pc(3)
ticks += 13
return
def b00111010(): # LD A,(nn) / LDA nn
global pc, ticks
reg_a[0] = read_mem(read_mem(inc_pc(2)) * 256 + read_mem(inc_pc()))
pc = inc_pc(3)
ticks += 13
return
Q-Master
09.01.2019, 21:48
CityAceE, да, работу с памятью надо чинить, чтобы была возможность работать со страницами и ПЗУ и другой вопрос, что я пока не придумал как это сделать красиво. Думаю, что это вообще не проблемы Z80-core, а должно устанавливаться соответствующими хуками снаружи для бОльшей реюзабельности самого кора. Но это все позже, а сейчас надо поправить таки команды и флаги, а то стыдоба - переделал как лучше, а оно не работает как надо. :)
Bedazzle, ага, оно сломано в новой версии. Я что-то там начудил с распаковкой.
Q-Master
19.01.2019, 23:53
Прогресс таков:
Починил загрузку z80 и sna
Починил работу Z80-core
Кажется починил везде флаги ( не на 100% уверен )
Есть сомнения в HALT и прерываниях вообще.
Пока не правил работу с памятью.
Надо думать как править отрисовку, т.к. она пипец какая небыстрая.
CityAceE
20.01.2019, 04:36
Пока ещё подглючивает:
https://pic.maxiol.com/images/1547948118.90463878.exolon.gif
Надо думать как править отрисовку
Только выносить в отдельные процедуры чтение/запись ячеек памяти, что поможет решить не только вывод на экран, но и попутно много чего ещё.
Q-Master
27.01.2019, 22:20
Хм, надо покопать где я что забыл или напутал. Память - да, надо править
P.S. Написал целую простыню текста с кучей рассуждений, ссылок и т.д., а потом случайно задел на мышке кнопку "Back" и в итоге вернулся назад на страницу, потеряв всё то, что писал в течение часа. Автосохранение почему-то не сработало. Второй раз писать то же самое я не решился.
Жаль что не решился, было бы интересно почитать. Да и репостнуть в vk/zxspectrum
Q-Master
30.01.2019, 21:57
Прогресс:
1. Очень сильно оптимизирован видео-вывод
2. Сделал гитхаб проект https://github.com/Q-Master/PyZX
На всякий, прикладываю новую версию архивом и сюда
Bedazzle
31.01.2019, 00:44
На всякий, прикладываю новую версию архивом и сюда
мусор со спрайтами
https://i.imgur.com/Pt8Vii4.png
Q-Master
31.01.2019, 22:07
мусор со спрайтами
Это не от видео, а где-то косяки с коркой Z80. Пока не нашел.
Q-Master
01.02.2019, 22:07
Нашел один косячек копипасты, но это не от него проблема. Надо искать в чем дело дальше. Возможно буду сличать дампы регистров и флагов обоих эмулей, т.к. есть подозрение что где-то либо с флагами косяк, либо с кодами команд.
Q-Master
04.02.2019, 00:54
Обновление:
1. Перенес всю работу с памятью в отдельный модуль и закрыл ПЗУ на запись.
2. Думаю что стало чуть медленнее чем было, но не думаю что критично.
3. Исчезла проблема с мусором в спрайтах (похоже какие-то команды первой версии были реализованы неверно и ничего никуда не писали, а я поправил и все сломалось).
В аттаче новая версия и все актуальненько на гитхабе.
Bedazzle
14.02.2019, 08:13
2. Думаю что стало чуть медленнее чем было, но не думаю что критично.
Я ещё не щупал, что за зверь, но есть шанс, что Pythran (https://proglib.io/p/pythran/) поможет?
CodeMaster
14.02.2019, 09:20
но есть шанс, что Pythran поможет?
Поможет, но это вечный спор компилятор vs. интерпретатор.
Q-Master
14.02.2019, 21:55
Я ещё не щупал, что за зверь, но есть шанс, что Pythran (https://proglib.io/p/pythran/) поможет?
Ну так можно и pypy использовать в принципе-то.
CityAceE
15.02.2019, 02:58
Ну так можно и pypy использовать в принципе-то.
У меня Pypy не получилось подружить с pygame :(
Q-Master
17.02.2019, 17:35
У меня Pypy не получилось подружить с pygame :(
Вариант https://stackoverflow.com/questions/13635144/using-pygame-with-pypy
CityAceE
18.02.2019, 15:18
Поработал немного над PyZX. За основу взял исходники Q-Master'а c GitHub.
1. Изменил заголовок окна. Теперь там отображается название эмулятора и FPS (можно отключить, изменив значение переменной).
2. Добавил иконку. Странно, но она отображается только в заголовке окна, а в панели задач нет. Победить проблему не смог, хотя на моём другом проекте всё отображается, как положено, в обои местах.
3. Добавил бордюр и его эмуляцию. Пришлось вбить костыль, потому что заготовка под обработку портов, которую сделал Q-Master, не работает должным образом. Обратил внимание на то, что где-то в основном коде эмуляции есть ошибка - при подаче команд BORDER 0...7, нижняя строка основного экрана закрашивается в цвет бордюра только в районе текста, а не целиком.
4. Исправил ошибку с яркими цветами чернил - чернильные цвета всегда отображались с выключенной яркостью.
5. Увеличил на несколько кадров FPS, максимально разгрузив от любых вычислений процедуру преобразования ZX-экрана в поверхность. Все данные берутся из заранее просчитанных табличек, а массив пишется в буфер за раз.
6. Сделал масштабирование экрана 1x, 2x и 3x. Переключать масштаб можно на лету клавишами F1-F3. По умолчанию эмулятор запускается с картинкой в двойном размере (можно изменить, откорректировав соответствующую константу).
Q-Master
18.02.2019, 21:39
Поработал немного над PyZX. За основу взял исходники Q-Master'а c GitHub.
1. Изменил заголовок окна. Теперь там отображается название эмулятора и FPS (можно отключить, изменив значение переменной).
2. Добавил иконку. Странно, но она отображается только в заголовке окна, а в панели задач нет. Победить проблему не смог, хотя на моём другом проекте всё отображается, как положено, в обои местах.
3. Добавил бордюр и его эмуляцию. Пришлось вбить костыль, потому что заготовка под обработку портов, которую сделал Q-Master, не работает должным образом. Обратил внимание на то, что где-то в основном коде эмуляции есть ошибка - при подаче команд BORDER 0...7, нижняя строка основного экрана закрашивается в цвет бордюра только в районе текста, а не целиком.
4. Исправил ошибку с яркими цветами чернил - чернильные цвета всегда отображались с выключенной яркостью.
5. Увеличил на несколько кадров FPS, максимально разгрузив от любых вычислений процедуру преобразования ZX-экрана в поверхность. Все данные берутся из заранее просчитанных табличек, а массив пишется в буфер за раз.
6. Сделал масштабирование экрана 1x, 2x и 3x. Переключать масштаб можно на лету клавишами F1-F3. По умолчанию эмулятор запускается с картинкой в двойном размере (можно изменить, откорректировав соответствующую константу).
А пулл-реквестик зафигачить?
PS: заготовка, да, пока не работает как надо, т.к. основная идея сделать поддержку ленты и загрузки с нее. Я сейчас там сильно.
- - - Добавлено - - -
CityAceE:
Посмотрел код и не понял зачем костыль если можно было поправить xOutFE?
Заберу твой код в мастер на гитхабе, не возражаешь?
- - - Добавлено - - -
Еще раз посмотрел кусок с видео. Что не понял совсем:
1. Странное копирование скринов и при смене режима один из скринов остается старого размера. Чем тебе не угодила ф-ция init и почему при каждом импорте будет дергаться весь цикл заполнения всех таблиц и пересоздание скринов - неясно.
2. Зачем-то выполняется лишнее копирование в fill_screen_map() которого я, как-раз, старался избежать. Я не понял зачем гонять данные туда-сюда, учитывая что bytearray через + заполняется не просто медленно, а адово медленно. Понятнее было-бы однократное создание массива нужной длины и его уже заполнения.
CityAceE
19.02.2019, 02:07
А пулл-реквестик зафигачить?
...
Заберу твой код в мастер на гитхабе, не возражаешь?
Выложил эту версию сюда по большей части для тебя, чтобы ты посмотрел и, если что-то приглянулось, перетянул бы к себе на GitHub. Твой опыт в Python существенно больше моего, поэтому скорее всего ты сможешь сделать лучше, чем то, как я сделал. Поэтому я и не стал делать pullrequest. А так, конечно, что нужно забирай!
Посмотрел код и не понял зачем костыль если можно было поправить xOutFE?
Это первое, куда я сунулся. Прежде всего я поставил туда print(port, value) и начал из Basic менять цвет бордюра. Но, к сожалению, в эту процедуру доходит только 254, 254. Разбираться что к чему я не стал, поэтому закостылил, чтобы ты потом сделал правильно.
Странное копирование скринов и при смене режима один из скринов остается старого размера.
Есть три поверхности:
1. Основной экран - он может масштабироваться, его мы и видим в окне.
2. Второй экран, он же бордюр, его размер всегда 384х256.
3. Экран Спектрума, его размер всегда 256х192.
Вывод происходит следующим образом:
1. Экран Спектрума копируется на центр экран бордюра. На выходе получаем картинку Спектрума с бордюром размером 384х256.
2. Накладываем этот бутерброд на основной экран, предварительно растянув его:
screen.blit(pygame.transform.scale(second_screen, current_mode), (0, 0))
Чем тебе не угодила ф-ция init и почему при каждом импорте будет дергаться весь цикл заполнения всех таблиц и пересоздание скринов - неясно.
Как раз для того, чтобы исключить include video из spectrum.py я и упразднил её. Хотя, возможно, перед этим я в другие файлы проекта этот include добавил по необходимости. В твоём варианте всё равно все таблицы рассчитывались вне процедур и, соответственно, генерировались каждый раз при include. Я думаю, что генерацию таблиц нужно выносить в отдельную процедуру.
Зачем-то выполняется лишнее копирование в fill_screen_map() которого я, как-раз, старался избежать.
Не совсем понимаю о чём ты. В fill_screen_map() сейчас идёт заполнение zx_array, чтобы потом его разом записать в буфер. Так получилось быстрее по сравнению с тем, что было у тебя. Я когда всё это делал, всё время держал под рукой твою версию и сверял скорость с ней, чтобы не дай бог не получилось медленнее, а вообще я, естественно, старался сделать чуть быстрее и в итоге удалось выиграть несколько FPS.
Я не понял зачем гонять данные туда-сюда, учитывая что bytearray через + заполняется не просто медленно, а адово медленно.
Да, в какой-то момент после разворачивания циклов перестал работать append. В итоге нарисовались две альтернативы: + и extend. Я провёл замеры и оказалось, что "+" чуть-чуть быстрее, чем extend. И это даже быстрее, чем append в цикле или 8 append'ов подряд. Это место меня, конечно, тоже расстроило.
Понятнее было-бы однократное создание массива нужной длины и его уже заполнения.
Так?
def fill_screen_map():
zx_videoram = Z80.memory.mem[16384:16384 + 6912]
zx_array = bytearray(49152)
mem = 0
for line_numb in range(192):
pix_addr = addr_pix[line_numb]
attr_addr = addr_attr[line_numb]
for i in range(32):
zx_array[mem:mem + 8] = pixelmap[zx_videoram[attr_addr + i]][zx_videoram[pix_addr + i]]
mem += 8
return bytes(zx_array)
Замеры показывают, что скорости эти не добавляет. Скорее всего нужно придумывать что-то другое.
---
Выкачал сейчас твой обновлённый вариант и сравнил по скорости со своим. Например, в Basic мой вариант примерно на 1 FPS показывает больше. Примерно та же ситуация и на титульном экране Exolon'а.
---
Проверил кусок кода, который я привёл вышел. И на моём другом проекте скорость поднялась не просто чуть-чуть, а вдвое! Старый вариант c "+" выдавал 72 FPS, а в новом варианте FPS поднялся до 144!
Bedazzle
19.02.2019, 08:06
2. Добавил иконку. Странно, но она отображается только в заголовке окна, а в панели задач нет. Победить проблему не смог, хотя на моём другом проекте всё отображается, как положено, в обои местах.
В панели отображается.
Win7, Python 3.6, pygame 1.9.4
https://i.imgur.com/RhUpPtz.png
CityAceE
19.02.2019, 08:26
В панели отображается.
Странно... У меня в Win10 именно в этом проекте не отображается на двух компах.
Q-Master
20.02.2019, 23:18
Выложил эту версию сюда по большей части для тебя, чтобы ты посмотрел и, если что-то приглянулось, перетянул бы к себе на GitHub. Твой опыт в Python существенно больше моего, поэтому скорее всего ты сможешь сделать лучше, чем то, как я сделал. Поэтому я и не стал делать pullrequest. А так, конечно, что нужно забирай!
Я часть забрал. Спасиб.
Это первое, куда я сунулся. Прежде всего я поставил туда print(port, value) и начал из Basic менять цвет бордюра. Но, к сожалению, в эту процедуру доходит только 254, 254. Разбираться что к чему я не стал, поэтому закостылил, чтобы ты потом сделал правильно.
Да. Там была смешная ошибка, которую я починил почти сразу.
Есть три поверхности:
1. Основной экран - он может масштабироваться, его мы и видим в окне.
2. Второй экран, он же бордюр, его размер всегда 384х256.
3. Экран Спектрума, его размер всегда 256х192.
Вывод происходит следующим образом:
1. Экран Спектрума копируется на центр экран бордюра. На выходе получаем картинку Спектрума с бордюром размером 384х256.
2. Накладываем этот бутерброд на основной экран, предварительно растянув его:
screen.blit(pygame.transform.scale(second_screen, current_mode), (0, 0))
У тебя 4 поверхности и 1 из них сильно лишняя. Я вообще сократил все до 2х.
Как раз для того, чтобы исключить include video из spectrum.py я и упразднил её. Хотя, возможно, перед этим я в другие файлы проекта этот include добавил по необходимости. В твоём варианте всё равно все таблицы рассчитывались вне процедур и, соответственно, генерировались каждый раз при include. Я думаю, что генерацию таблиц нужно выносить в отдельную процедуру.
Ну собственно я хочу вообще слегка исправить эмуль в архитектурном плане. Сейчас основным является Z80, но это неверно. Основным должен стать spectrum и из себя дергать уже все остальное. Я убрал часть под процедуры и вернул инит. :)
Не совсем понимаю о чём ты. В fill_screen_map() сейчас идёт заполнение zx_array, чтобы потом его разом записать в буфер. Так получилось быстрее по сравнению с тем, что было у тебя. Я когда всё это делал, всё время держал под рукой твою версию и сверял скорость с ней, чтобы не дай бог не получилось медленнее, а вообще я, естественно, старался сделать чуть быстрее и в итоге удалось выиграть несколько FPS.
Штука в моей версии такова, что потерей 1 фпс я с легкостью могу развернуть этот цикл в линию и попробовать даже мультиколоры показать. :) Хотя это можно и в твоей версии сделать, но чуть веселее.
Да, в какой-то момент после разворачивания циклов перестал работать append. В итоге нарисовались две альтернативы: + и extend. Я провёл замеры и оказалось, что "+" чуть-чуть быстрее, чем extend. И это даже быстрее, чем append в цикле или 8 append'ов подряд. Это место меня, конечно, тоже расстроило.
Так?
def fill_screen_map():
zx_videoram = Z80.memory.mem[16384:16384 + 6912]
zx_array = bytearray(49152)
mem = 0
for line_numb in range(192):
pix_addr = addr_pix[line_numb]
attr_addr = addr_attr[line_numb]
for i in range(32):
zx_array[mem:mem + 8] = pixelmap[zx_videoram[attr_addr + i]][zx_videoram[pix_addr + i]]
mem += 8
return bytes(zx_array)
Замеры показывают, что скорости эти не добавляет. Скорее всего нужно придумывать что-то другое.
---
Выкачал сейчас твой обновлённый вариант и сравнил по скорости со своим. Например, в Basic мой вариант примерно на 1 FPS показывает больше. Примерно та же ситуация и на титульном экране Exolon'а.
Ну вот смотри, твоя процедура за время своей работы 2 раза копирует данные: 1 - из pixelmap в zx_array, 2 - из него в поверхность. У меня копирование происходит по 8 точек за раз и только 1 раз. Да, чуть медленнее чем скопом, но твой вариант в целом делает то-же самое. У меня есть предположение что если пользоваться не buffer.write, а достать непосредственно мап на поверхность, то я легко верну тот 1 фпс.
Проверил кусок кода, который я привёл вышел. И на моём другом проекте скорость поднялась не просто чуть-чуть, а вдвое! Старый вариант c "+" выдавал 72 FPS, а в новом варианте FPS поднялся до 144!
[/QUOTE]
Ну вот тут ничего не могу сказать. Если попробовать еще memoryview подключить - возможно еще вырастет.
- - - Добавлено - - -
Странно... У меня в Win10 именно в этом проекте не отображается на двух компах.
У меня все норм. Правда не на твоей версии, а на моей, но в принципе там ничего не изменено связанное с иконкой
- - - Добавлено - - -
CityAceE, я немного извратился с твоим вариантом и возможно чуть ускорил его даже.
Bedazzle
21.02.2019, 00:49
там ничего не изменено связанное с иконкой
/кастую глюки pygame
CityAceE
21.02.2019, 03:16
Ну вот тут ничего не могу сказать. Если попробовать еще memoryview подключить - возможно еще вырастет.
Спасибо за совет! Добавил сверху ещё какое-то невероятное количество FPS (см. ниже), сделав вот так:
zx_array = memoryview(bytearray(49152))
def fill_screen_map(zx_videoram=zx_screen):
mem = 0
for line_numb in range(192):
pix_addr = addr_pix[line_numb]
attr_addr = addr_attr[line_numb]
for i in range(32):
zx_array[mem:mem + 8] = pixelmap[zx_videoram[attr_addr + i]][zx_videoram[pix_addr + i]]
mem += 8
return zx_array.tobytes()
У меня все норм. Правда не на твоей версии, а на моей, но в принципе там ничего не изменено связанное с иконкой
А у меня твоя версия выглядит во так:
https://pic.maxiol.com/images/1550707747.3254906935..png
А вот так выглядит мой проект:
https://pic.maxiol.com/images/1550707879.3254906935..png
Попытался твою процедуру вывода на экран целиком к себе поместить, чтобы замерить скорость и сравнить. Но она сходу не заработала (экран оставался чёрным). Потыкался, сразу разобраться не получилось в чём проблем и я бросил. Но я успел увидеть, что FPS по сравнению с тем, что у меня было ранее (144) просел где-то на 10-15 кадров.
Q-Master, у меня есть пакет "идеальных" файлов SNA, которые я делал уже давно. Я уже писал ранее, что получал их из TZX, поставив на паузу сразу после загрузки последнего байта и потратив несколько байтов стека кассетного загрузчика. Так вот из 36 файлов корректно запустилось на текущей версии PyZX гораздо меньше половины :( Не работают игры по-разному: какие-то сбрасывают виртуальный Спектрум, какие-то зависают, какие-то портят экран, из-за некоторых вылетает эмулятор, какая-то одна игра заставила что-то выводить в консоль. В общем, вот этот пакет снепшотов (https://yadi.sk/d/7g0AOpSrjKAfIA). Посмотри, вдруг удастся оперативно отыскать и профиксить ошибки эмуляции.
Q-Master
21.02.2019, 21:06
Спасибо за совет! Добавил сверху ещё какое-то невероятное количество FPS (см. ниже), сделав вот так:
zx_array = memoryview(bytearray(49152))
def fill_screen_map(zx_videoram=zx_screen):
mem = 0
for line_numb in range(192):
pix_addr = addr_pix[line_numb]
attr_addr = addr_attr[line_numb]
for i in range(32):
zx_array[mem:mem + 8] = pixelmap[zx_videoram[attr_addr + i]][zx_videoram[pix_addr + i]]
mem += 8
return zx_array.tobytes()
Попытался твою процедуру вывода на экран целиком к себе поместить, чтобы замерить скорость и сравнить. Но она сходу не заработала (экран оставался чёрным). Потыкался, сразу разобраться не получилось в чём проблем и я бросил. Но я успел увидеть, что FPS по сравнению с тем, что у меня было ранее (144) просел где-то на 10-15 кадров.
Ну вообще странно. Я пробовал перетаскивать твою процедуру целиком и не заметил изменений по фпс. Я вчера еще по разному игрался и пробовал вообще избавиться от конвертаций типов, но по фпс ничего не добился, а вот картинку испортил.
Q-Master, у меня есть пакет "идеальных" файлов SNA, которые я делал уже давно. Я уже писал ранее, что получал их из TZX, поставив на паузу сразу после загрузки последнего байта и потратив несколько байтов стека кассетного загрузчика. Так вот из 36 файлов корректно запустилось на текущей версии PyZX гораздо меньше половины :( Не работают игры по-разному: какие-то сбрасывают виртуальный Спектрум, какие-то зависают, какие-то портят экран, из-за некоторых вылетает эмулятор, какая-то одна игра заставила что-то выводить в консоль. В общем, вот этот пакет снепшотов (https://yadi.sk/d/7g0AOpSrjKAfIA). Посмотри, вдруг удастся оперативно отыскать и профиксить ошибки эмуляции.
Качнул, надо проверить что там не так. 146% что с флагами лажа где-то. :)
CityAceE
22.02.2019, 02:23
Ну вообще странно. Я пробовал перетаскивать твою процедуру целиком и не заметил изменений по фпс. Я вчера еще по разному игрался и пробовал вообще избавиться от конвертаций типов, но по фпс ничего не добился, а вот картинку испортил.
Видимо, потому в PyZX процедура рисования экрана отнимает лишь жалкую часть от всего времени эмуляции. Соответственно, минимальные колебания скорости построения экрана слишком сложно заметить. Поэтому и нужно тестировать скорость этой процедуры отдельно от эмулятора - строть N-ное количество экранов и сравнивать с временем построения такого же количеств экранов, но уже по другому алгоритму. На всякий случай проговорил эту очевидную вещь, хотя убеждён, что ты это и сам прекрасно знаешь.
Bedazzle
24.02.2019, 20:36
Видимо, потому в PyZX процедура рисования экрана отнимает лишь жалкую часть от всего времени эмуляции.
Загнал в профайлер, сижу, медитирую на результат.
Кто-нибудь может пояснить, с чего начать?
https://i.imgur.com/muxtmT8.png
Q-Master
25.02.2019, 21:15
Загнал в профайлер, сижу, медитирую на результат.
Кто-нибудь может пояснить, с чего начать?
https://i.imgur.com/muxtmT8.png
А вобщем тут и нечего начинать. Ожидаемо что nxtpcb и execute жрут максимум ресурсов. Это z80-core и там мало что можно для оптимизации сделать, я уже там и так извращался как мог. Тут только переписывать на каком-нить компилируемом языке, но это уже неспортивно.
Bedazzle
26.02.2019, 08:49
А вобщем тут и нечего начинать.
Не, я к тому - куда смотреть, чтобы начать понимать табличку.
Q-Master
26.02.2019, 20:54
Не, я к тому - куда смотреть, чтобы начать понимать табличку.
Можно вот тут почитать https://habr.com/ru/company/mailru/blog/202832/
CodeMaster
18.03.2019, 21:41
а Питон на чём запускать?
Компиль надо или какая Среда?
Нельзя из Этого ехешник сделать?
На предыдущей странице.
Bedazzle
19.03.2019, 07:50
Эмуль на Питоне, а Питон на чём запускать?
Компиль надо или какая Среда?
Нельзя из Этого ехешник сделать?
Думаю, если вам неизвестен Питон, то лучше взять другой эмулятор.
Будет и по скорости быстрее, и по возможностям богаче.
Bedazzle
14.01.2020, 09:47
Забрал с гитхаба файлики, Exolon работает.
Сделал в EmuzWin снапшот, гружу в PyZX - появляется начальное меню, после нажатия на клавишу вылетает.
https://i.imgur.com/6bisLSg.png
P.S.
Fuse и SpecEmu с этим (https://www.dropbox.com/s/h025036ikratp2x/heavy.SNA?dl=0) снапом работают нормально.
CityAceE
14.01.2020, 21:28
Сделал в EmuzWin снапшот, гружу в PyZX - появляется начальное меню, после нажатия на клавишу вылетает.
Там ещё много ошибок, но, похоже, что Q-Master забросил дальнейшие улучшения...
Вот, по-быстрому закостылил, чтобы эта игра не вылетала. Файл из вложения нужно распаковать и заменить им тот, что есть в проекте.
Bedazzle
14.01.2020, 23:12
Там ещё много ошибок, но, похоже, что Q-Master забросил дальнейшие улучшения...
Вот, по-быстрому закостылил, чтобы эта игра не вылетала. Файл из вложения нужно распаковать и заменить им тот, что есть в проекте.
Я тоже нашёл. Пропущена документированная RLD
_eddict
нужно добавить
, 111: rld
по ходу, там ещё косяки в командах CB
например, куча RES, и вообще нет SET.
Если я сделаю фикс, его на гитхаб как пуллреквест пихать, или что?
P.S.
проверил ED/CD команды,
Обрабатывается ряд недокументированных для ED префикса:
76, 78, 84, 85, 92, 93, 100, 101, 102, 108, 109, 110, 113, 116, 117, 118, 124, 125, 126
если смотреть по http://clrhome.org/table/
то команды 93, 109, 125 это retn, а в эмуле обрабатываются reti
если смотреть по https://www.ime.usp.br/~einar/z80table/
то должно быть reti
кто может подтвердтить или опровергнуть правильность?
Кроме rld #ED, #6F (237, 111) - в коде вызывается rlda
вероятно также глюк с rrd #ED, #67 (237, 103) - в коде вызывается rrda
CityAceE
15.01.2020, 07:44
по ходу, там ещё косяки
Судя по протестированным играм, там ещё полным полно косяков! И очень здорово, что ты какие-то из них выявил!
Если я сделаю фикс, его на гитхаб как пуллреквест
Да, именно так.
Q-Master, ты как-то планируешь дальше эмулятор развивать?
Bedazzle
15.01.2020, 22:36
Так, ещё поломашку нашёл. Валится загрузка *.Z80
Чтобы пофиксить, в load.py
добавить
import ports
...
заменить
#Z80.outb(254, ((tbyte >> 1) % 8)) # border
на
ports.port_out(254, ((tbyte >> 1) % 8)) # border
И ещё команда adc16
гадит через print
P.S.
запустил тест, даже до конца не отработал, уже тяжко
https://i.imgur.com/erPLUwf.png
CityAceE
16.01.2020, 20:22
Да уж, в каждой группе проблемы. Может быть там везде баг одной природы?
Bedazzle, чувствуешь в себе силы поискать и пофиксить хотя бы часть?
Shadow Maker
16.01.2020, 21:56
Если я сделаю фикс, его на гитхаб как пуллреквест пихать, или что?
Чтобы сделать пулл-реквест, ты всё равно сначала должен к себе склонировать, напушить коммитов с фиксами, а потом уже пулл-реквест с ними в основную репу. Так что просто клонируй и делай фиксы, как нафиксишься - можно пулл-реквест делать. Люди смогут с твоей репы забирать данные в то же время.
Bedazzle
17.01.2020, 00:58
Да уж, в каждой группе проблемы. Может быть там везде баг одной природы?
Bedazzle, чувствуешь в себе силы поискать и пофиксить хотя бы часть?
Попробую.
Bedazzle
11.12.2020, 00:55
Я тоже нашёл. Пропущена документированная RLD
_eddict
нужно добавить
, 111: rld
....
Кроме rld #ED, #6F (237, 111) - в коде вызывается rlda
вероятно также глюк с rrd #ED, #67 (237, 103) - в коде вызывается rrda
Всё там правильно с вызовом rlda/rrda.
Вызываются правильные функции.
А вот что rlda() не делает return 18 - есть косяк.
CityAceE
11.12.2020, 09:14
Bedazzle, я так понимаю, снова полез в исходники?
Bedazzle
11.12.2020, 10:35
Bedazzle, я так понимаю, снова полез в исходники?
Да, у меня отвалилась очередная игра, пробую пофиксить.
CityAceE
11.12.2020, 10:43
Bedazzle, отлично! А где твои фиксы брать?
Bedazzle
11.12.2020, 12:53
Bedazzle, отлично! А где твои фиксы брать?
На гит положу. Но сначала дочиню, чтобы работала Bards tale.
Bedazzle
12.12.2020, 01:12
set3fromhl()
содержит peekb вместо pokeb, из-за этого Captain Trueno вылетает, если добежать вправо до упора.
Похоже, многие игры валятся из-за того, что 31й порт не реализован.
Bedazzle
21.12.2020, 00:30
Поменял выборку адреса по регистру I.
Взять можно тут (https://github.com/Bedazzle/PyZX)
Эти игрушки запускаются, и на первый взгляд, играются.
Action Reflex.sna
Ball Breaker 1.sna
Ball Breaker 2.sna
Bards Tale.sna
Batty.sna
Bomb Jack.sna
Bruce Lee.sna
Capitan Trueno 1.sna
Cybernoid 1.sna
Cybernoid 2.sna
Cyclone.sna
Eric And The Floaters.sna
Exolon.sna
Freddy Hardest 1.sna
Frost Byte.sna
Head Over Heels.sna
Heavy on the magick.sna
Legions Of Death.sna
Lord Of The Rings (Part 1).sna
Mermaid Madness.sna
Monty On The Run.sna
Movie.sna
Nebulus.sna
Penetrator.sna
Rick Dangerous.sna
Ruff and Reddy.sna
Saboteur 1.sna
Saboteur 2.sna
Scuba Dive.sna
Three Weeks In Paradise.sna
Yogi Bear.sna
Zynaps.sna
У этих явные проблемы с отображением спрайтов (исчезают вообще, или дико мерцают)
Arkanoid 2.sna
Batman.sna
Dizzy7.sna
Puzznic.sna
Storm Lord.sna
Валится с ошибкой чтения (возможно, криво снятый снап)
Ramparts.sna
Q-Master
18.01.2021, 00:37
Поменял выборку адреса по регистру I.
Взять можно тут
А сделай мне пулл-реквест плиз. Я в основную репу заберу.
Bedazzle
21.01.2021, 00:14
А сделай мне пулл-реквест плиз. Я в основную репу заберу.
Сделал.
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot