Приставки > Железо
А как память то эмулировать
(1/1)
ajak:
Привет всем. Знатоки помогайте. Если с эмуляцией основной программы, ЦПУ, видео-проца, джойстика и портов i/o всё понятно, то мне не понятно как эмулировать память. Как это сделать. Нужно обращаться к памяти в той же области памяти в которой висит прога или как-то специально выделять. Просто если взять денди - она адресует мало, с этим легко справиться, а взять к примеру xbox, уже так не получиться. Нужно что, динамически выделять? И ещё такой вопрос. Кто может доходчиво объяснить что такое динамическая рекомпиляция или просто рекомпиляция кода, а то чёт не пойму. Это лучше эмуляции чтоль? Да и какое значение эта штука имеет к эмуляции памяти?
HardWareMan:
Вопрос - баян.
Память мулим по разному. Например, карта памяти Sega MegaDrive:
000000-3FFFFF - ROM
A00000-A0FFFF - Z80
A10000-A113FF - IO
C00000-C0001F - VDP
FF0000-FFFFFF - RAM
То на Delphi я бы сделал так:

--- Код: ---function ReadByte(Adr:longint):byte;
var  ad:byte;
begin
       ad:=(Adr and $FF0000) shr 16;
       case ad of
         00..3F : ReadByte:=ROM[Adr and $3FFFFF];
            A0   : ReadByte:=ReadZ80Byte(Adr and $00FFFF);
            A1   : ReadByte:=ReadIOByte(Adr and $00FFFF);
            C0   : ReadByte:=ReadVDPByte(Adr and $00FFFF);
            FF   : ReadByte:=RAM[Adr and $00FFFF];
         end;
end;

--- Конец кода ---
ROM - массив в 4Мб, куда грузится образ картриджа, RAM - массив в 64Кб ОЗУ приставки. Как видно, лишнюю память эмулировать не надо. Эту процедуру должен использовать эмуль процессора, когда хочет получить байт. Так же, можно написать для Word'а и обращение на запись.
Это все упрощённо и грубо, но идея, думаю, понятна.
ajak:
Ща буду вдуплять.  ;)
А как же быть с современными некст генами консолями
HardWareMan:

--- Цитата: ajak от 05 Январь 2008, 13:08:49 ---А как же быть с современными некст генами консолями
--- Конец цитаты ---
А что с ними?
ajak:
Ну они же больше адресуют. Я так понимаю, что нужно создать массив, и чем новее система  - тем больше она памяти использует и тем больше массив будет. Или я ошибаюсь?Всмысле как массив инициализируется? Вот. Как он распределяется, динамически чтоли?
Исправляю баги по просьбе Администрции.
Vegas:
Оффтоп
2 ajak
Хоть убей, не понимаю. Как ты можешь кодить, если ты даже грамотно писать не умеешь?
Энд оф Оффтоп
ajak:
Мне компилятор помогает, исправляет за меня ошибки. А где я ошибся?  :? Э.. я печатаю - на клаву не смотрю. У меня что граматика лагает? :cool:
Vegas:
ГраММатика у тебя хромает, а не лагает. Пользуйся текстовым редактором, дитя прогресса.
ajak:
 :) Пасибки
Wind:

--- Цитата: ajak от 05 Январь 2008, 13:49:41 ---Ну они же больше адресуют. Я так понимаю, что нужно создать массив, и чем новее система  - тем больше она памяти использует и тем больше массив будет. Или я ошибаюсь?Всмысле как массив инициализируется? Вот. Как он распределяется, динамически чтоли?
--- Конец цитаты ---

Памяти выделяешь ровно столько сколько нужно сразу и боже упаси ее динамически на ходу выделять. Ну да чем современее система, тем больше у нее оперативной, видео и т.п. памяти, ну вместо нескольких кб у той же Sega MegaDrive, несколько мб PS2. Трасляция памяти не изменится, как траслировать тебе уже показали простейший пример.

Вот читай также по теме, писал давно, так что много чего нужно править, но лень, да и писатель во мне давно умер, впрочем никогда и не рождался %)
http://emu-russia.km.ru/forum/viewtopic.php?f=13&t=64
http://emu-russia.km.ru/forum/viewtopic.php?f=13&t=67
masyanya:

--- Цитата: Vegas от 05 Январь 2008, 14:03:34 ---Оффтоп
2 ajak
Хоть убей, не понимаю. Как ты можешь кодить, если ты даже грамотно писать не умеешь?
Энд оф Оффтоп

--- Конец цитаты ---
ajak Извини конечно но Vegas прав, я тожа не понимаю как ты программиш, что значит цитирую "компилятор исправляет"?  0_0
Как вот такое исправит компилятор? >:(:
(Dreamcast Windows CE Compiller 8.01)
void MyFunc_TryToCorrectMe_MrCompiller(void)
{
     CRITICAL_SECTION lpCriticalSection;
     DWORD FourByteBuffer;
     LPBYTE MangledBuffer = (LPBYTE)&FourByteBuffer;
     BYTE ByByBy[5]={0,1,2,3,4};
     HANDLE write_thread=NULL;
     DWORD ex_code;

     IsAssertionValid(&MangledBuffer );

     InitializeCriticalSection(&lpCriticalSection);
     ASSERT(&lpCriticalSection);
     EnterCriticalSection(&lpCriticalSection);  ;Ай яй яй... критическая секция начинается...

     write_thread = CreateThread (NULL, 0, (PTHREAD_START_ROUTINE)(SetRomData),(LPVOID &tgt,CREATE_SUSPENDED,&ex_code);// Есть, треад...  :-\
     SetThreadPriority (write_thread, THREAD_PRIORITY_NORMAL);
     ResumeThread (write_thread);
     WaitForSingleObject (write_thread, 100);
     
     memcpy(MangledBuffer,ByByBy,5);  // o_0 зачупато!!!!

     LeaveCriticalSection(&lpCriticalSection);

     TerminateThread (&write_thread);//Вот тоже неплохо
}
 Пару раз вызовешь нихрена не произойдет, и 50 раз вызовешь эту процедуру тоже ничего, но в конечном итоге это закончиться синим экраном смерти... Поймаешь хвостиком адресное пространство двайвера и привет...
 Вот из за таких шуток гамезы и вылетают в самом ответственном месте.
В каждой строчке где вызываются функции хотя бы одна фатальная ошибка, однако компилятор ничего не скажет.
 По моей личной шкале некомпитентности от 0 до 50, пожалуй этот код на 47 точно тянет.
 При этом заметь я проверяю ассертами для дебагера... так что вот... я в шоке... я прсто... мда... лучше промолчу... Румата опять ругаться будет... :blush:

Добавлено позже:
Хотя, про грамматику, эт скорее описки... с кем не бывает-то... :)

Добавлено позже:

--- Цитата: Wind от 05 Январь 2008, 17:11:32 ---Памяти выделяешь ровно столько сколько нужно сразу и боже упаси ее динамически на ходу выделять.
--- Конец цитаты ---
Тоже забавная фраза... не пробовали книжки писать?
Например: Освой выделение памяти за 30 уроков...
 А если мне надо выделять строго определенную область, например сразу за виртуальным пространством прогруженного исполняемого кода? Тогда мне нужно будет полюбому предусмотреть выделение на лету, если не будет влезать мой буффер, локнул и передвинул адресацию уже прогруженных системных файлов... Ну это замудреный метод, так сразу и не скажу где такое нужно, но пример есть интересней, загрузка в поверхности директ Х своего формата файлов... там придеться динамить массив... мда может конечно я чего не понимаю? А вот мне интересно, как NWN грузиться? У него размер локаций разный... короче, я незнаю ак ваще программить если бы передо мной поставили задачу, - "Парься как хочешь, но никаких динамических массивов..." ... я бы уволися... <_<

Добавлено позже:
Кидайте в меня тапками!!!! Я злой сегодня какой-то!!!!  :blush:
Wind:

--- Цитата: masyanya от 07 Январь 2008, 01:21:07 ---Например: Освой выделение памяти за 30 уроков...
 А если мне надо выделять строго определенную область, например сразу за виртуальным пространством прогруженного исполняемого кода? Тогда мне нужно будет полюбому предусмотреть выделение на лету, если не будет влезать мой буффер, локнул и передвинул адресацию уже прогруженных системных файлов... Ну это замудреный метод, так сразу и не скажу где такое нужно, но пример есть интересней, загрузка в поверхности директ Х своего формата файлов... там придеться динамить массив... мда может конечно я чего не понимаю? А вот мне интересно, как NWN грузиться? У него размер локаций разный... короче, я незнаю ак ваще программить если бы передо мной поставили задачу, - "Парься как хочешь, но никаких динамических массивов..." ... я бы уволися...
--- Конец цитаты ---
Речь идет о конкретоно эмуляции, нужно искать алгоритмы который не превратит эмулятор в тестер менеджера памяти. Ну  а без динамических масивов, можно обойтись практически всегда, пишу практически, лишь потому что, а вдруг когда-то и нельзя, но сам такой случай представить не могу!
ajak:

--- Цитата ---function ReadByte(Adr:longint):byte;
var  ad:byte;
begin
       ad:=(Adr and $FF0000) shr 16;
       case ad of
         00..3F : ReadByte:=ROM[Adr and $3FFFFF];
            A0   : ReadByte:=ReadZ80Byte(Adr and $00FFFF);
            A1   : ReadByte:=ReadIOByte(Adr and $00FFFF);
            C0   : ReadByte:=ReadVDPByte(Adr and $00FFFF);
            FF   : ReadByte:=RAM[Adr and $00FFFF];
         end;
end;

--- Конец цитаты ---
Это вроде, как способ доступа к памяти согласно карте памяти. А я говорю о самой её организации. Это что  - большой массив? Просто чем сложнее система и современнее, тем массив будет очень большим. Вот и как тогда поступить?
Wind:

--- Цитата: ajak от 07 Январь 2008, 12:54:03 ---Это вроде, как способ доступа к памяти согласно карте памяти. А я говорю о самой её организации. Это что  - большой массив? Просто чем сложнее система и современнее, тем массив будет очень большим. Вот и как тогда поступить?

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

вот читаем чтение из ROM "ReadByte:=ROM[Adr and $3FFFFF]; ", а тут из RAM "ReadByte:=RAM[Adr and $00FFFF];", ROM и RAM два отдельных масива, а не единый регион как ты себе это вбил в голову.
HardWareMan:
И процессор будет видеть как единый массив (и, кстати, должен так делать), но в реале - это разные области данных. Думаю, все понимают, что MIPS R3000 в ЗЫЧе имеет 32х битную адресацию. И что, ты будешь лочить непрерывный массив в 4Гб, при том, что у него всего пара-тройка областей, которые не превышают 8-16Мб в сумме? А как ты собираешься эмулировать отражение областей (некоторые программы это используют иногда)? Вот проще выделить небольшую область и читать данные из нее, выделив младшие биты адреса и игнорируя старшие. Все автоматом будет. %)
ajak:
Спасибо. :)
masyanya:

--- Цитата: Wind от 07 Январь 2008, 10:38:28 ---пишу практически, лишь потому что, а вдруг когда-то и нельзя, но сам такой случай представить не могу!

--- Конец цитаты ---
:) Ну мне тожа на вскидочку если, в голову приходят тока упаковщики кода, типа Petite и прочего...  ;)
Навигация
Главная страница сообщений

Перейти к полной версии