HLPSE

HLPSE, или HighLevel PlayStation Emulator, это новая концепция эмуляции Sony PlayStation, позволяющая :
- ускорить эмуляцию до такой степени, что будет возможным запуск игр для PSX даже на компьютерах типа 386. все принципы, позволяющие это сделать, будут приведены далее.
- сделать возможным портирование игр на PC.
возникшие сомнения по поводу работоспособности данного проекта могут быть с легкостью рассеяны отличным примером - эмулятор UltraHLE для Nintendo 64.

основа HLPSE

работа HLPSE основана на широко известной, но мало используемой (для PSX), технологии высокоуровневой эмуляции (HLE). кратко её можно описать так: эмулируем не железо аппаратуры, а программы, которые на нем запускаются. обычно главные претенденты на HLE - это библиотечные функции (они-то как раз и работают с железом, в идеале..). мы можем и не знать, как именно работает та или иная функция, но зато нам известно что она делает. основываясь на этом факте, мы можем сэмулировать конечный результат работы этой функции таким образом, что программа (игра) не заметит никакой подмены.
кроме библиотек, у PSX еще есть BIOS, в котором находится KERNEL, или PlayStation OS (PSOS), которая тоже может быть сэмулирована HLE.
таким образом, чтобы сделать высокоуровневую эмуляцию PSX, нам нужно знать как работают PSOS и библиотечные функции. эта задача не из легких - дело в том, что исходники ядра и библиотек отсутсвуют, и приходится их реверсировать (т.е. восстанавливать исходный код из ассемблера). если в отношении BIOS'а никаких проблем нет (можно считать, что он разобран практически на 100%), то с библиотеками возникают трудности - приходится разбирать большой объём кода, что занимает много времени.

эмуляция памяти

PSX имеет несколько областей в виртуальном 4 GB адресном пространстве. более подробно об этом можно узнать из "память PSX". в обычных эмуляторах на каждую область создаются массивы и при доступе к адресу происходит его трансляция на массив реальной памяти PSX, например:

/* область RAM. размер 2 MB. */
unsigned char ram[0x200000];
/* область BIOS (ROM). размер 512 KB. */
unsigned char rom[0x80000];

/* транслируем адрес 0x80012340 */
real_address = &ram[0x80012340 & 0x1fffff];
/* транслируем адрес 0xBFC01230 */
real_address = &rom[0xBFC01230 & 0x7ffff];

здесь приведен только пример, на самом деле трансляция в общем случае выглядит немного по другому. подробнее см. например в исходниках PCSX. в HLPSE модель памяти значительно упрощается. не нужен BIOS, PIO, scratch. поэтому остается только RAM. в терминологии HLPSE RAM называется "сегмент кода" или text, потому что в него загружается PS-X EXE файл, или эмулируемая программа. эмуляция аппаратных регистров происходит просто : доступ к аппаратным регистрам ЗАПРЕЩЕН! дело в том, что большая часть функций (если не подавляющее большинство) в программе, использующих HW регистры - библиотечные функции. как уже было сказано выше, эти функции эмулируются HLE. поэтому нет необходимости в использовании аппаратных регистров.
трансляция адреса тоже значительно упрощается - нужно всего-лишь сделать одну операцию AND. достоинства такого способа :

 - экономия памяти
 - простота трансляции
 - облегчается контроль за границами дозволенного HLE адресного пространства

примечание : существует большое количество программ, называемых "демками" ;) эти программы иногда написаны на ассемблере и практически все не используют оффициальные библиотеки, заменяя их на собственные варианты. поэтому в этом случае доступ к HW регистрам не стоит игнорировать. однако, у HLPSE есть способ выкрутиться из данного положения. см. ниже про плагины.

эмуляция процессорной системы

центральный процессор PSX R3000A эмулируется оптимизирующим динамическим рекомпилятором. эмуляция COP0 отсутствует, по причине её HLE. GTE интерпретируемый (динамическая рекомпиляция инструкций GTE сильно "загромождает" код). обработка прерываний PSX эмулируется плагинами.

плагины HLPSE

схематически структуру HLPSE можно представить так :

центральной частью являются, взаимодействующие между друг другом, динамический рекомпилятор и геометрический сопроцессор. они вместе делят между собой регистры R3000 и его адресное пространство (вместе это называется "контекст HLPSE"). естественно, ничего бы не работало без PSX программы, которая находится в PS-X EXE файле и загружается в сегмент кода. и наконец, для эмуляции аппаратуры используются система HLPSE плагинов, которая будет описана ниже.

небольшое замечание : контекст HLPSE является ключевой структурой. он используется как связуещее звено между главным HLPSE модулем (HLPSE.EXE) и набором доступных плагинов. на схеме видно, что обе "половинки" связаны между собой посредством контекста.
также без доступа к контексту стало бы невозможным сделать высокоуровневую эмуляцию и аппаратную абстракцию.

теперь непосредственно о плагинах. плагин HLPSE - это DLL программа, которая предоставляет ядру эмулятора набор функций. функции каждого плагина делятся на индивидуальные и общие. к примеру в системе PSEmuPro-плагинов у GPU-плагина, общие это PSEgetLibType, PSEgetLibName и PSEgetLibVersion, а индивидуальные это GPUwriteData, GPUupdateLace и пр. общие методы (функции) HLPSE-плагинов:

Ident - для опознавания плагина. возвращает строку-идентификатор "I_HLPSE_PLUG".
Init - вызывается при запуске эмулятора. на входе передается контекст HLPSE.
Shutdown - вызывается при выходе из эмулятора.

если плагину не удалось инициализироваться, он возвращает 0, иначе 1. к общим функциям относится всё множество высокоуровневых вариантов библиотечных функций, например такие функции, как ResetCallback, VSync, PadRead находятся в библиотеке libetc.lib. следовательно их высокоуровневые аналоги hle_ResetCallback, hle_VSync и hle_PadRead будут находиться в плагине libetc.dll. причем ядру не важно в каком плагине находится та или иная функция. главное, чтобы она была там, где ей удобнее всего, и чтобы она корректно обрабатывала HLE-запрос. если в плагинах не найдется требуемой ядру функции, то она рекомпилируется посредством дин.река.

с "демками" вопрос обстоит просто : в них ищутся те функции, которые работают с железом, переписываются в HLE и помещаются в специальный плагин - misc.dll. на самом деле HLPSE рассчитан больше на эмуляцию игр, чем на небольшие программки, собранные "на коленке".

контекст HLPSE

контекст HLPSE - это набор свойств и методов, для поддержания целостности и свободному доступу к состоянию эмулируемой машины (т.е. в данном случае PSX). ранее было сказано, что в контекст входят такие свойства, как регистры общего назначения R3000 или GPR и сегмент кода или text. полная структура контекста :

/* HLPSE Context */
typedef struct {
    /* Emulator Context */
    u_long  *GPR;
    void    *text;
    HWND    hwnd;

    /* Emulator Interface */
    int  (*RegisterMessage)(UINT, LRESULT (*)(HWND, UINT, WPARAM, LPARAM));
    void (*SysError)(char *, ...);
    void (*Shutdown)();
 FARPROC (*Recompile)(u_long);
    void (*Execute)(u_long);
 FARPROC (*SendHLERequest)(char *);
    void (*Interrupt)(); (*)
    char*(*Dasm)(u_long, u_long); (*)
    void (*Printf)(char *, ...); (*)
} HLPSE_State;

(*) помечены внешние методы контекста и они всегда предопределены (находятся в одних и тех же плагинах). основными методами являются : Recompile, Execute, SendHLERequest и Interrupt.

карта EXE

немаловажной частью является способ определения адресов библиотечных функций. при использовании HLE-сканера размер и сложность эмулятора сильно увеличится. вместо этого используется карта PS-X EXE или map. она имеет вид:

[address] [name]
[address] [name]
...

например:
8007B6A0 printf
800856B0 CD_vol
80085F60 puts
80087020 ResetCallback
80087050 InterruptCallback

таким образом нахождение адресов для каждой эмулируемой PSX программы лежит целиком на плечах программиста. может быть этот метод покажется более трудоемким, чем HLE-сканер, но время, затраченное на написание качественного HLE-сканера (mapper'а) превысит "ручной" поиск.
обработка карты EXE осуществляется на этапе запуска эмулятора, после подключения и инициализации всех плагинов. примечание: приставка hle_ в имени функции, в карте не указывается.

назад...

Hosted by uCoz