Важная информация

User Tag List

Страница 1 из 2 12 ПоследняяПоследняя
Показано с 1 по 10 из 15

Тема: Вставляем паузу в SNA-файлы

  1. #1
    Administrator Аватар для CityAceE
    Регистрация
    13.01.2005
    Адрес
    г. Москва
    Сообщений
    4,574
    Записей в дневнике
    7
    Спасибо Благодарностей отдано 
    399
    Спасибо Благодарностей получено 
    1,207
    Поблагодарили
    394 сообщений
    Mentioned
    48 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию Вставляем паузу в SNA-файлы

    Когда-то давно я писал эмулятор ZX Spectrum под PalmOS. Единственным форматом файлов, который поддерживал мой эмулятор, был формат SNA. Он был выбран в силу своей простоты и достаточной распространённости. Несмотря на то, что SNA грузится моментально, в этом формате почти всегда отсутствуют заставки, игры уже настроены под определённый тип машины и т.д. Я решил хотя бы частично решить данные проблемы, и для своего эмулятора я подготовил пачку "идеальных" снепшотов. Я делал их вручную из файлов TZX. Процесс заключался в следующем: я начинал загружать TZX, выходил в отладчик и далее трассировал загрузку до того момента, пока с "ленты" не загружался последний байт. После этого я сохранял SNA. И вроде всё хорошо, но сохранённую в этих снепшотах заставку невозможно было разглядеть, так как игра сразу же стартовала. Я выкрутился тем, что внедрял в эти снепшоты коротенькую процедуру, которая крутилась в цикле и ждала нажатия любой клавиши. Эту процедуру я клал на стек, пересчитывал адрес запуска и сохранял модифицированный снепшот. Таким образом, после загрузки такого обработанного снепшота мы видели на экране заставку и могли её рассматривать до тех пор, пока не была нажата клавиша. Около десятка байт, записанных на стеке, в данных условиях я не считаю слишком большой ценой.

    Всё это я делал вручную, производя расчёты на калькуляторе и меняя байты снепшота прямо в HEX-редакторе. Потом, помнится, мне несколько раз нужно было получить такие же снепшоты с паузой перед запуском, но мне было лень заново разбираться, какие я расчёты производил и как всё делал. И вот сейчас я решил всё восстановить и автоматизировать процесс, чтобы любой желающим мог вставлять паузу перед запуском снепшота. Такие снепшоты могут использоваться, например, для прошивания их в ROM-диск или картридж. А кроме того, новая прошивка для Scropion ZS-256 научилась запускать SNA-файлы непосредственно с жёсткого диска. В общем, применение найти можно.

    В результате у меня получится скрипт, написанный на языке Python. Использовать его достаточно просто:

    Код:
    C:\>python pause2sna.py filename.sna
    На выходе мы моментально получим файл filename_paused.sna с установленной паузой.

    Скрипт поддерживает несколько ключей. И в зависимости от них, процедура паузы может помещаться в разные места памяти, а также изменяться в зависимости от других условий. И прежде чем перейти к описанию ключей, я приведу текст самой процедуры. В её самом "жирном" виде процедура выглядит так:

    Код:
        PUSH AF
        XOR A
    M1  IN A,(#FE)
        OR #E0
        INC A
        JR Z,M1
        POP AF
        EI
        JP START
    Итого 14 байт

    Очевидно, что некоторые команды могут быть сокращены. Так, чаще всего нам не потребуется сохранение регистровой пары AF (PUSH и POP). А если прерывания были запрещены, то нам не потребуется их разрешать (EI). Если регистр A перед записью снепшота и так содержал 0, то команда XOR будет лишней. А кроме того, у нас есть возможность поместить процедуру паузы на месте кассетного загрузчика, непосредственно перед текущим адресом запуска, и тогда JP START тоже будет лишней. В итоге процедура превратится просто в:

    Код:
    M1  IN A,(#FE)
        OR #E0
        INC A
        JR Z,M1
    Итого 7 байт

    Что касается команд XOR A и EI, то на их наличие из отсутствие в процедуре мы непосредственно повлиять не можем - они по необходимости вставляются автоматически. XOR A добавляется, если в снепшоте регистр A не равен нулю. А EI добавляется, если в перед сохранением снепшота были разрешены прерывания. При этом после вставления паузы прерывания в самом снепшоте запрещаются.

    Теперь перейдём непосредственно к ключам. Собственно, их всего три:

    Код:
    - h или --help
    Этот ключ выводит небольшое описание по формату использования скрипта и его ключам.

    Код:
    - f или --flag
    Этот ключ не имеет дополнительных параметров, в просто своим наличием указывается скрипту добавить в процедуру команды PUSH AF и POP AF для сохранения регистра А и флагового регистра F. Это может потребоваться, если снепшот снимается где-то в середине игры, и исходное значение этих регистров, которые портятся процедурой паузы, является критичным.

    Код:
    - a или --address
    Этот ключ указывает скрипту где нужно разместить процедуру паузы. По умолчанию процедура размещается в области стека, сразу ниже его вершины. Это хорошо с той точки зрения, что с высокой степенью вероятности данная процедура не затрёт ни единого байта каких-то полезных данных. Но основной минус заключается в том, что такой снепшот более нельзя модифицировать, записывая что-то на стек. Например, запускальщик файлов SNA на Scorpion ZS-256 перед запуском некоторые данные помещает на стек. Таким образом, данные снепшоты не смогут быть запущены на Скорпионе. Также снепшот окажется неработоспособным, если его второй раз прогнать через данный скрипт, поставив вторую паузу поверх уже существующей способом по умолчанию.

    Выходом может служить вариант, когда вместо адреса мы укажем ноль (-а 0). В этом случае скрипт отступит несколько байт назад относительно текущего адреса запуска и поместит адрес запуска на начало процедуры. Такой вариант можно использовать с случае сохранения снепшота сразу после загрузки данных с ленты. В этом случае процедура паузы затрёт несколько байт кассетного загрузчика, который уже больше не понадобится.

    Ну, и если вы знаете точное место в ОЗУ, где нет никаких данных и куда можно поместить процедуру паузы, то вы можете указать этот адрес. Например, это может быть адрес буфера принтера (-а 23296) или область где-то в экранном ОЗУ (-а 16384). Если вы укажете слишком высокий адрес в районе 65535, куда не поместится скрипт, то он ругнётся и укажет максимальное значение допустимого адреса.

    Если же указать адрес, расположенный в пределах ПЗУ (кроме 0), то процедура будет размещена в области стека, как и есть по умолчанию.

    Для желающих поэкспериментировать помимо самого скрипта прилагаю к этому сообщению снепшот игры Marauder, как раз сохранённый сразу же после загрузки последнего байта с "ленты" (TZX).
    Вложения Вложения
    Последний раз редактировалось CityAceE; 31.07.2023 в 22:54.
    С уважением, Станислав.

  2. Эти 2 пользователя(ей) поблагодарили CityAceE за это полезное сообщение:

    Djoni (03.08.2023), Eltaron (31.07.2023)

  3. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  4. #2
    Banned
    Регистрация
    22.05.2011
    Адрес
    г. Дзержинск, Украина
    Сообщений
    6,841
    Спасибо Благодарностей отдано 
    483
    Спасибо Благодарностей получено 
    658
    Поблагодарили
    512 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от CityAceE Посмотреть сообщение
    Ну, и если вы знаете точное место в ОЗУ, где нет никаких данных и куда можно поместить процедуру паузы, то вы можете указать этот адрес.
    можно было бы даже поискать свободное место на афтомате

    ато старые игры моггут юзать рамочки который вообще загружены с ленты вместе с заставкой
    и которые вообще никогда не востанавливаютсо потом

  5. #3
    Sinclair User Аватар для Eltaron
    Регистрация
    16.01.2005
    Адрес
    Ekaterinburg
    Сообщений
    2,045
    Записей в дневнике
    7
    Спасибо Благодарностей отдано 
    144
    Спасибо Благодарностей получено 
    463
    Поблагодарили
    326 сообщений
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Интересная идея. Жаль только трассировать загрузчик, чтобы создать исходный снапшот, придется руками. Теоретически можно запарить эмулятор грузить TZX до момента, когда будет прочитан последний бит последнего блока данных, правда, если там доп. уровни в TZX лежат, то это не сработает.
    Граф Дракула наш кумир, патамушта он вомпир!
    VKINK 9 : BORDER NOT PI

  6. #4
    Banned
    Регистрация
    22.05.2011
    Адрес
    г. Дзержинск, Украина
    Сообщений
    6,841
    Спасибо Благодарностей отдано 
    483
    Спасибо Благодарностей получено 
    658
    Поблагодарили
    512 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Eltaron Посмотреть сообщение
    доп. уровни в TZX лежат, то это не сработает.
    а бутта так много таких игр
    да их видно по размеру эттого тап-а

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

    а "на кассетах" эти игры вообще ходили иннгда без этих "уровней" в компплекте

  7. #5
    Sinclair User Аватар для Eltaron
    Регистрация
    16.01.2005
    Адрес
    Ekaterinburg
    Сообщений
    2,045
    Записей в дневнике
    7
    Спасибо Благодарностей отдано 
    144
    Спасибо Благодарностей получено 
    463
    Поблагодарили
    326 сообщений
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от NEO SPECTRUMAN Посмотреть сообщение
    а бутта так много таких игр
    Ну да, тем более, что смысла делать из них снапшоты тоже немного.
    Граф Дракула наш кумир, патамушта он вомпир!
    VKINK 9 : BORDER NOT PI

  8. #6
    Administrator Аватар для CityAceE
    Регистрация
    13.01.2005
    Адрес
    г. Москва
    Сообщений
    4,574
    Записей в дневнике
    7
    Спасибо Благодарностей отдано 
    399
    Спасибо Благодарностей получено 
    1,207
    Поблагодарили
    394 сообщений
    Mentioned
    48 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Eltaron Посмотреть сообщение
    Жаль только трассировать загрузчик, чтобы создать исходный снапшот, придется руками.
    Да, но это довольно несложно, особенно если загрузчик нестандартный.
    С уважением, Станислав.

  9. #7
    Guru
    Регистрация
    27.02.2005
    Адрес
    москва
    Сообщений
    13,774
    Записей в дневнике
    1
    Спасибо Благодарностей отдано 
    143
    Спасибо Благодарностей получено 
    1,179
    Поблагодарили
    775 сообщений
    Mentioned
    18 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от CityAceE Посмотреть сообщение
    мой эмулятор
    а не проще было сделать в нём аппаратную паузу перед запуском файла ?
    Цитата Сообщение от CityAceE Посмотреть сообщение
    новая прошивка для Scropion ZS-256 научилась запускать SNA-файлы непосредственно с жёсткого диска.
    тут также можно загрузив данные для экрана сделать паузу и потом догружать остальное
    (собственно в esxdos так и сделано)

  10. #8
    Banned
    Регистрация
    22.05.2011
    Адрес
    г. Дзержинск, Украина
    Сообщений
    6,841
    Спасибо Благодарностей отдано 
    483
    Спасибо Благодарностей получено 
    658
    Поблагодарили
    512 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Eltaron Посмотреть сообщение
    Жаль только трассировать загрузчик, чтобы создать исходный снапшот, придется руками.
    в каждом третьем эмуляторе есть автонабор load""
    в каждом первом есть tape traps или быстрая перемотка для tzx-ов
    любой эмулятор можно наизична превратить в такой конвертор...

  11. #9
    Master Аватар для LW
    Регистрация
    05.09.2007
    Адрес
    Орск
    Сообщений
    950
    Спасибо Благодарностей отдано 
    228
    Спасибо Благодарностей получено 
    1,005
    Поблагодарили
    319 сообщений
    Mentioned
    18 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от CityAceE Посмотреть сообщение
    По умолчанию процедура размещается в области стека, сразу ниже его вершины.
    при таком раскладе push af затрёт команду jp start
    а вот если отступить от вершины стэка на 11 байт вниз, то и push af не причинит вреда и на скорпионе запустится

  12. #10
    Veteran
    Регистрация
    26.11.2013
    Адрес
    г. Новосибирск
    Сообщений
    1,042
    Спасибо Благодарностей отдано 
    934
    Спасибо Благодарностей получено 
    227
    Поблагодарили
    122 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Вообще то не надо записывать коды команд PUSH AF, XOR A; надо просто поместить в стек AF, и обнулить A.

Страница 1 из 2 12 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Расширение .sna
    от ondas в разделе Программирование
    Ответов: 10
    Последнее: 10.08.2023, 14:36
  2. Программное создание SNA
    от Dwa83 в разделе Программирование
    Ответов: 7
    Последнее: 26.08.2019, 22:46
  3. Распилитель sna
    от Alex Rider в разделе Утилиты
    Ответов: 3
    Последнее: 22.07.2012, 18:22
  4. Игры в sna
    от DRILL в разделе Игры
    Ответов: 17
    Последнее: 30.03.2010, 22:43
  5. ПОМОГИТЕ!! (SNA to AY...)
    от newart в разделе Музыка
    Ответов: 44
    Последнее: 07.10.2005, 22:10

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •