PDA

Просмотр полной версии : Интерфейс эмулятора в коде Z80



CityAceE
12.09.2008, 13:44
Когда я писал эмулятор Спектрума для платформы PalmOS, то столкнулся с проблемой создания интерфейса эмулятора, которую я в итоге так и не решил. А между тем в процессе написания одним из вариантов был написать интерфейс эмулятора, который бы работал в самом эмуляторе, то есть по сути являлся бы программой для Спектрума. Но в итоге я так и не реализовал этот варинат.

А ведь было бы довольно заманчиво иметь некий универсальный (дополнительный или основной) интерфейс для любого эмулятора, который бы поддерживал некий API такого интерфейса.

Можно было бы совместными усилиями написать такой интерфейс и стандартизировать API.

Кто что думает?

boo_boo
12.09.2008, 13:56
имеется в виду интерфейс доступа к фичам эмулятора из Z80-кода? типа вкл/выкл режима максимальной скорости и тп?

Vitamin
12.09.2008, 14:03
В US была такая фича. Через неиспользуемые команды с префиксами. Даже дебаггер показывал. Где-то уже была такая тема вроде...

CityAceE
12.09.2008, 14:55
имеется в виду интерфейс доступа к фичам эмулятора из Z80-кода? типа вкл/выкл режима максимальной скорости и тп?
Ага, именно. Регулировка звука, загрузка снепштотов, смена модели, настройка джойстика и т.д. и т.п.


В US была такая фича. Через неиспользуемые команды с префиксами. Даже дебаггер показывал. Где-то уже была такая тема вроде...
Хм... Честно говоря не видел. Иначе не пропустил бы...

b2m
12.09.2008, 15:13
Обычно используют заведомо свободный порт, и при чтении (или записи в него) выполняют определённые действия, например, взять из памяти блок параметров по адресу из определённого регистра, в зависимости от параметров выполнить определённую команду, поместить в тот-же блок памяти результат выполнения. Другое дело, если реализация процессора универсальная, то нельзя знать заранее, какой порт использовать. Однако, номер порта можно задавать при инициализации процессора.

Vitamin
12.09.2008, 15:16
Хм... Честно говоря не видел. Иначе не пропустил бы...
http://zx.pk.ru/showthread.php?t=2657

CityAceE
12.09.2008, 16:04
А... Это я видел. Но это не совсем то :) Я имел ввиду полноценный интерфейс типа как в эмуляторе X128.

Vitamin
12.09.2008, 16:35
Я имел ввиду полноценный интерфейс типа как в эмуляторе X128
А там как?

У меня были некоторые идеи на эту тему. В простейшем случае- одна точка входа и запрос нужных функций через их коды. Плюс обязательное получение списка поддерживаемых функций. Разумеется, это все требует согласования и стандартизирования...

Alexandr Medvedev
12.09.2008, 17:55
Я имел ввиду полноценный интерфейс типа как в эмуляторе X128.В X128? Нет там никакого интерфейса.
Подобные вещи есть тока в старых версиях UnewalSpeccy (0.19b ... 0.21b3) и Z80Stealth.
Вот кусок документации UnrealSpeccy:
unreal programming interface

unreal API allows you to use emulator more efficiently. here is a
brief description of documented unreal functions. all functions
may be called through executing Z80 invalid opcode EDFF, registers
must contain the following values:
BC=6E75, DE=6572, HL=6C61, A=function_code, IX=param

for example:

UAPI:
ld bc, word ptr [key+0]
ld de, word ptr [key+2]
ld hl, word ptr [key+4]
db 0EDh, 0FFh
ret
key: db 'unreal'

API functions:

0. exit emulator,if you don't want your program to be emulated on unreal speccy

ld a,'q'
ld ix, offset quit_message
jp UAPI ; don't return

; not more then 64 chars, and can't cross 16K page boundary
quit_message: db 'allowed to run only on real hardware',0

1. get emulator version

ld a,'?'
call UAPI
; returns:
; CY=0 [success flag]
; H - major version number
; L - minor version number
; A - bits 0..6 - revision number. bit 7 = 0 - beta version
; unreal 0.19b will return HL=0x0013, A=0x00
; unreal 0.19b2 will return HL=0x0013, A=0x02
; unreal 1.00 will return HL=0x0100, A=0x80 (hopefully:)

2. set video mode

ld a,'v'
ld ix,mode
call UAPI
; flag CY=1 - mode not found, CY=0 - ok

mode equ 0 ; normal
mode equ 'c'+100h*'2' ; chunky 2x2
mode equ 'c'+100h*'4' ; chunky 4x4
mode equ 'C'+100h*'2' ; chunky 2x2, filtered
mode equ 'C'+100h*'4' ; chunky 4x4, filtered
mode equ 'n'+100h*'f' ; noflic (pseudo-gigascreen)
mode equ 'f'+100h*'c' ; flash-color
mode equ 'x'+100h*'2' ; 512x192
mode equ 'b'+100h*'i' ; bilinear
mode equ 'a'+100h*'c' ; AlCo 384x304
mode equ 't'+100h*'v' ; TV emulation
mode equ 's'+100h*'c' ; scaling (**)
; note: ** - may be removed in next versions

3. set soundchip type

ld xh, chip ; 'a' - AY-3-8910, 'y' - YM2149F, 'd' - digital, '0' - none
ld xl, stereo ; 'b' - ABC, 'c' - ACB, '0' - mono, '?' - custom
ld a,'m'
call UAPI
; flag CY=1 - bad parameter, CY=0 - ok

4. quick save 48/128K snapshot

ld a,'s'
call UAPI
; CY=1 - error, CY=0 - ok

5. quick load 48/128K snapshot

ld a,'l'
call UAPI
; CY=1 - error, probably 'quick save' not called
; CY=0 - impossible (snapshot is running, not this code)
А вот кусок документации Z80Stealth
╔═════════════════════════════════════════════════ ═════════╗
║ Как вытащить из программы на Спектруме понравившуюся ║
║ мелодию для музыкального сопроцессора при помощи трэпов? ║
╚═════════════════════════════════════════════════ ═════════╝
От вас потребуется знание ассемблера Z80 и умение взламывать программы для
ZX-Spectrum. Прежде всего, в конфигурационном файле впишите PSGTRAP=YES.
Типичная программа, проигрывающая музыку на музыкальном сопроцессоре,
содержит нехитрый "плеер" - кодовый блок, на который возлагается всё
программирование AY-3-8910 или YM2149F.

 Сразу же после инициализации плеера "подсуньте" Z80 код
ED F9. Такое "подсовывание" можно произвести, наример, в отладчике
эмулятора. Выполнение в Z80Stealth этого кода при PSGTRAP=YES
приведёт к тому, что эмулятор создаст файл dump.psg и будет
копировать в него все данные, поступающие в регистры AY/YM. Формат
файла (PSG или EPSG) вы можете выбрать в конфигурационном файле.
 Обычно в плеере есть код, обеспечивающий "зацикливание" - переход
к началу (или к произвольному месту) мелодии при достижении конца.
Впишите вместо этого кода ED FA - по этой псевдоинструкции
Z80Stealth закроет файл и завершит работу, и вы вернётесь в ДОС.
 Файл dump.psg - в вашем распоряжении. Кстати, для быстрой выгрузки
PSG-файла можно воспользоваться опцией MAXSPEED=YES.

DZh
12.09.2008, 20:00
Очень интересная идея, когда то посещавшая и меня. Вот мои соображения на счёт стандартизации:

1. Использовать какую-нибудь свободную префиксную инструкцию (EDxx) - ОДНУ!

2. После этой инструкции ввести идентификатор, например EmuControl (10 байт).
Это во избежание случайных выполнений EDxx.

3. Далее будет стоять код команды, которая будет определять действие - загрузка/выгрузка файлов, всевозможные переключения моделей/режимов эмуляции и т.д. В зависимости от типа команды, за ней могут следовать дополнительные значения для возможности задания дополнительных параметров. Они могут быть как числовые (порядковый номер модели), так и текстовые (имена файлов). В общем - огромный полигон для фантазии.

4. Стандартизировать коды команд для дефолтного определения эмулятором их размера.

5. По завершении выполнения команды - возврат на адрес следующий ПОСЛЕ НЕЁ (не после EDxx!). Исключение - команда выхода из эмулятора например.

CityAceE
13.09.2008, 02:45
В X128? Нет там никакого интерфейса.
Я имел ввиду, что там не сделано именно то, о чём я говорю, а внешний вид: всё выводится в Спектрумовском разрешении, Спектрумовским же шрифтом. Ещё в Спектрумовском разрешении, но другим шрифтом всё выводится, кажется, в R80.

Очень интересная идея, когда то посещавшая и меня.
Не "и меня", а именно тебя! :) Я не говорил, что это моя идея. Это было как раз твоё предложение.

Alexandr Medvedev
13.09.2008, 11:30
Я имел ввиду, что там не сделано именно то, о чём я говорюНичего не понял.
внешний вид: всё выводится в Спектрумовском разрешении, Спектрумовским же шрифтом. Ещё в Спектрумовском разрешении, но другим шрифтом всё выводится, кажется, в R80.Указанные эмули работают в разрешении 320x200 (которое по умалчанию и его можно поменять) и никакое оно не "Спектрумовское" просто на нём рисуется экран 256x192 Шрифт тоже НЕ из ПЗУ берётся, а просто похож и выводится естественно не средствами эмулируемого Z80 а самими эмулем.
Я так и не понял предлагается рисовать интерфейс эмулятора (диалоги открытия файлов, выбора модели, настроек) средствами самого Z80 что-ли?

Добавлено через 6 минут

2. После этой инструкции ввести идентификатор, например EmuControl (10 байт).В UnrealAPI сделано почти так, только идентификатор передаётся через регистры, в котрые (BC, DE, HL) перед вызовом API кладутся 6 байт "unreal". Такой способ более наглядный.

DZh
13.09.2008, 11:54
Не "и меня", а именно тебя! :) Я не говорил, что это моя идея. Это было как раз твоё предложение.

Если честно, то я уже и призабыл :) впрочем, это не столь важно.


Я так и не понял предлагается рисовать интерфейс эмулятора (диалоги открытия файлов, выбора модели, настроек) средствами самого Z80 что-ли?

Именно так. Прямо в процессе эмуляции.


Добавлено через 6 минут
В UnrealAPI сделано почти так, только идентификатор передаётся через регистры, в котрые (BC, DE, HL) перед вызовом API кладутся 6 байт "unreal". Такой способ более наглядный.

Это уже дело вкуса. Я всего лишь набросал основу идеи. :)

Vitamin
13.09.2008, 16:38
Именно так. Прямо в процессе эмуляции.
А смысл? А дисковые операции тоже эмулить? И много контролов управления влезет в очко 256х192?

boo_boo
13.09.2008, 17:03
предлагается рисовать интерфейс эмулятора (диалоги открытия файлов, выбора модели, настроек) средствами самого Z80 что-ли?
Именно так. Прямо в процессе эмуляции. идея достаточно безумная, мне нравится :) даже можно расширить концепт -- эмулить z80 средствами самого z80! (сорри за сарказм :v2_wink:)

насчет интерфейса для вызова расширенных ф-й. способ, предложенный DZh IMO интрузивен и ест много памяти. в эмуляторе, не поддерживающем эту фичу, прога обвалится..
мне кажется, лучше через порты. к примеру, суем в некий порт сигнатуру (байта 3), означающую, что дальше пойдут команды. потом гоним в порт собсно команды, потом суем сигнатуру, запускающую выполнение введенного.
технически, запиханные в порт данные команд кладутся эмулем последовательно в буфер, и по сигнатуре выполнения это дело интерпретируется. можно ввести дополнительные меры чтоб исключить случайную запись чего-то в этот порт, но ИМХО такая вероятность и без того невелика :)

DZh
13.09.2008, 18:32
А смысл? А дисковые операции тоже эмулить? И много контролов управления влезет в очко 256х192?

Смысл - сделать GUI. Что лучше - эмуль с таким GUI или вообще без него?
Ничего постороннего эмулить не надо, всё происходит внутри эмуляции спека, выходя за рамки эмуляции только во время выполнения специфических команд, изменяющих настройки эмулятора. А 256x192 тоже не проблема. Если не вместится в один экран, то можно организовать многостраничность.

Добавлено через 15 минут

насчет интерфейса для вызова расширенных ф-й. способ, предложенный DZh IMO интрузивен и ест много памяти. в эмуляторе, не поддерживающем эту фичу, прога обвалится..


И где здесь много памяти? Всего одна подпрограмма:

#EDxx ;ловушка
#C9 ;это чтобы не обвалилась прога
$G ;в совокупности С9 GUI - идентификатор (4 байта)
$U
$I
#yy ;код команды
#yy ;параметры команды,
#yy ;если требуются
#..
#C9

Всё! Остаётся только заполнять yy нужной командой и вызывать эту подпрограмму. А лучше вместо последнего С9 поставить 0 в качестве маркера конца команды, а возврат осуществлять по первому С9.

Vitamin
13.09.2008, 19:07
Смысл - сделать GUI. Что лучше - эмуль с таким GUI или вообще без него?
Остальные эмули такой гуй не поддерживают. Отсюда следует, что они вообще без гуя чтоли?

Это может быть разве что фичей. Типа спецверсия ПЗУ, которая использует расширенное апи по взаимодействию с эмулятором и позволяет такую штуку. Основной гуй эмулятора это не отменяет.

DZh
13.09.2008, 19:27
Остальные эмули такой гуй не поддерживают. Отсюда следует, что они вообще без гуя чтоли?

Это может быть разве что фичей. Типа спецверсия ПЗУ, которая использует расширенное апи по взаимодействию с эмулятором и позволяет такую штуку. Основной гуй эмулятора это не отменяет.

Речь не об остальных эмулях, а об одном. А ПЗУ совершенно не нужно изменять, чтобы не нарушать совместимость. Естественно, при желании авторы уже имеющих GUI эмулей могут поддержать и эту фичу, не отменяя основной GUI.

Alexandr Medvedev
14.09.2008, 12:52
Именно так. Прямо в процессе эмуляции.Типа долой Win32 GUI из всех эмуляторов, да здравствует ZX Windows.

Vitamin
14.09.2008, 13:53
Речь не об остальных эмулях, а об одном. А ПЗУ совершенно не нужно изменять, чтобы не нарушать совместимость. Естественно, при желании авторы уже имеющих GUI эмулей могут поддержать и эту фичу, не отменяя основной GUI.
Если ПЗУ не нужно подменять, то откуда будет выполяться код, который будет рисовать этот гуй и взаимодействовать с эмулятором?
Плюс не стоит забывать, что эмулируемый гуй подвержен большему числу опасностей, нежели основной. Так что без основного гуя не обойтись никак.

CityAceE
14.09.2008, 15:39
Если ПЗУ не нужно подменять, то откуда будет выполяться код, который будет рисовать этот гуй и взаимодействовать с эмулятором?
Предполагается (по крайней мере мной), что по нажатию клавиши вызова интерфейса, работающая программа будет выгружаться, а на её место будет загружаться интерфейс. При выходе из интерфейса всё будет происходить в обратном порядке.

Мой эмулятор под Палм не имеет вообще никакого интерфеса. Если бы в моём распоряжении была бы такая штука, то и ситуация была бы несколько другой...

Vitamin
14.09.2008, 15:43
Предполагается (по крайней мере мной), что по нажатию клавиши вызова интерфейса, работающая программа будет выгружаться, а на её место будет загружаться интерфейс. При выходе из интерфейса всё будет происходить в обратном порядке.
Предлагаю оценить трудоемкость написания и отлаживания этого интерфейса и сравнить ее с трудоемкостью написания нативного гуя. Плюс не стоит забывать об опасностях (случайный останов процессора, включение максимальной скорости- и все, остается только перезапускать эмулятор).

DZh
14.09.2008, 18:39
Предлагаю оценить трудоемкость написания и отлаживания этого интерфейса и сравнить ее с трудоемкостью написания нативного гуя. Плюс не стоит забывать об опасностях (случайный останов процессора, включение максимальной скорости- и все, остается только перезапускать эмулятор).

В данном случае написание нативного полностью отпадает. При качественно написанном ZXGUI никаких опасностей просто быть не может. Все описанные причины никак не повлияют на его работу. (см. предыдущий от твоего пост).

Добавлено через 3 минуты

Типа долой Win32 GUI из всех эмуляторов, да здравствует ZX Windows.

Пожалуйста, не нужно приписывать слова Windows, Win32 и т.д. Это никоим образом не касается данной проблемы.

Vitamin
14.09.2008, 18:47
При качественно написанном ZXGUI никаких опасностей просто быть не может.
Ну предположим, у нас абсолютно безбажный код (что само по себе невозможно), есть возможость отката настроек если чтото пошло не так.
Как, например, будет делаться навигация по дереву файлов?

DZh
14.09.2008, 21:04
Ну предположим, у нас абсолютно безбажный код (что само по себе невозможно), есть возможость отката настроек если чтото пошло не так.
Как, например, будет делаться навигация по дереву файлов?

Навигация по дереву файлов - это дело техники программирования под конкретную платформу. Если имеется в виду вопрос передачи данных в память ZX, то в ней можно либо выделить буфер по умолчанию, либо в параметрах команды указывать адрес/размер передаваемых данных. Я не вижу никаких препятствий в реализации такого типа GUI. На практике это можно реализовать как два раздельных режима: эмуляция для софта и эмуляция для GUI. Отличие будет лишь во включенном/выключенном бите в области переменных эмулятора. В этом случае отпадает необходимость в идентификаторе после EDxx. Также это исключит выполнение вредоносного кода в режиме софта, а режим GUI делаем недоступным для пользователя.

Black_Cat
14.09.2008, 23:37
Господа, вы не думали о том, что такой интерфейс можно было-бы применить для общения реального Спектрума с РС? Может сразу заложить и эту возможность, чтоб потом не делать всё заново.

boo_boo
15.09.2008, 02:45
не понимаю все же.. зачем Z80-API управления фичами эмулятора, ясно. а зачем рисовать эмульский GUI средствами эмулируемого спека -- нет. у такого варианта есть какие-то плюсы? вроде, сплошные минусы кругом :)


можно было-бы применить для общения реального Спектрума с РС? это ж проще можно устроить, через COM-порт например.


И где здесь много памяти? 4-байтовый идентификатор придется повторять много раз -- для каждой команды. плюс по 3 байта на CALL (см ниже)


#C9 ;это чтобы не обвалилась прога прога-то не обвалится, но писать ее станет неудобно. каждый раз при необходимости подачи команды делать RET.. сталбыть перед этим делать туда CALL, и опять-таки для каждой команды, брр...

CityAceE
15.09.2008, 02:51
Предлагаю оценить трудоемкость написания и отлаживания этого интерфейса и сравнить ее с трудоемкостью написания нативного гуя.
Как раз именно по этой причине и возникла эта идея! Посняю, что мой, что эмулятор Дмитрия написаны на чистом ассемблере. Лично для меня оказалось не подъёмным писать интерфейс эмулятора под PalmOS на ассемблере, хотя я пытался. Для меня было бы гораздо проще создать такой интерфейс именно в коде Z80. Так что вопрос трудоёмкости весьма относительный...

Black_Cat
15.09.2008, 03:04
это ж проще можно устроить, через COM-порт например.Физический интерфейс может быть разным - СОМ, LPT, ISA - эт вопрос уже драйвера, вопрос в том чтоб была такая возможность прицепить соответствующий драйвер и юзать хоть в эмуле, хоть на реале один и тот же универсальный программный интерфейс.

DZh
15.09.2008, 20:23
не понимаю все же.. зачем Z80-API управления фичами эмулятора, ясно. а зачем рисовать эмульский GUI средствами эмулируемого спека -- нет. у такого варианта есть какие-то плюсы? вроде, сплошные минусы кругом

Не вижу минусов. Интерфейс как интерфейс, только слегка необычный. Плюс - каждый может написать свой интерфейс на свой вкус, если реализовать загрузку GUI-файла в эмуль также как и ROM-файлов.


4-байтовый идентификатор придется повторять много раз -- для каждой команды. плюс по 3 байта на CALL (см ниже)

Идентификатор не нужно повторять много раз. Он будет находиться в одном месте. Да и вызовов не требуется слишком много - при грамотной реализации алгоритма всё должно выглядеть компактно. Но разве у нас на счету каждый байт? Ведь в распоряжении GUIшки может быть вся память ZX, включая даже область ПЗУ!