PDA

Просмотр полной версии : Код эмуляции i8080 на С



medvdv
03.01.2015, 02:04
Вот, написал i8080 для своих проектов - если кто то хочет использовать - на здоровье, не жалко. Код проходит все тесты которые я нашел, прост в использовании и короткий (понятный). по скорости он тоже не плохой, все флаги считаются по таблицам

если вы хотите использовать - на здоровье, если какие вопросы - пишите тут или на medvdv@me.com отвечу

если найдете ошибки или какие то штуки которые я не сэмулировал как положено - буду страшно рад и исправлю

есть маленький отладчик и дизассемблер - если надо что то посмотреть в эмуляторе по ходу разработки

для примера приложу использующие этот i8080 эмуляторы Орион 128 и РК-86 на C/SDL2 - очень простенькие - как тест этой эмуляции =) только там пути к биосу и образам дисков вбиты жестко - надо поменять на ваши =)) ну я их писал для внутреннего использования и поэтому они сыроваты и без какого либо интерфейса удобного

написал и компилировал на в Xcode но по идее должно везде работать где есть SDL2 а если чуть поменять вывод из буферов кадра то и где угодно =)

Eagle
03.01.2015, 02:13
А недокументированные команды эмулируются?

balu_dark
03.01.2015, 03:31
а на 8080 разве были такие команды ?

Eagle
03.01.2015, 03:40
а на 8080 разве были такие команды ?
В КР580ВМ80А есть, и некоторые умники их использовали.

balu_dark
03.01.2015, 12:20
А где почитать про это ?

marinovsoft
03.01.2015, 13:27
http://zx-pk.ru/showpost.php?p=149162&postcount=8

medvdv
03.01.2015, 20:37
Ну в таком смысле да - все опкоды которые приводят к тем же командам я сделал

Но реально новых команд в нем нет насколько я понимаю просто некоторые декодируются частично и имеют по 2/4 кода

Я все недокументированное поведение которое нашел воплотил

Вот когда я Z80 делал - там с этим я намучился, очень много нюансов подковерных и всякие странные биты во флагах недокументированные надо вычислять

Выложу и его на днях, там вот тоже все тесты которые нашел он проходит включая недокументированное все

---------- Post added at 19:37 ---------- Previous post was at 19:29 ----------

Там в рк-86 есть еще DMA и VG - я делал по документации буржуйской и если честно по VG есть еще вопросы, буду его допиливать может у кого то есть документация по нему какая то дополнительная? Кроме родного даташита?

Я доведу их до независимых библиотек удобных и тоже выложу

uart
06.01.2015, 03:47
Я в своем эмуляторе не придумал, как сделать корректную эмуляцию DMA для РК86 при покомандной эмуляции 8080. Ведь цикл DMA может быть в любом цикле команды процессора и в зависимости от него отжирает разное количество тактов.

Patron
06.01.2015, 04:06
Я в своем эмуляторе не придумал, как сделать корректную эмуляцию DMA при покомандной эмуляцииНа мой взгляд, если использовать Fibers ( сопрограммы ) - можно легко превратить покомандную эмуляцию в "поцикловую".

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

medvdv
08.01.2015, 03:06
Я в своем эмуляторе не придумал, как сделать корректную эмуляцию DMA для РК86 при покомандной эмуляции 8080. Ведь цикл DMA может быть в любом цикле команды процессора и в зависимости от него отжирает разное количество тактов.

можем подумать вместе как нибудь =))

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

я не знаю как у тебя эмуляция синхронизируется? я когда делал ямаху и спектрум - там по строчкам развертки точнее даже видимая область и бордюр отдельно по сути соотв внутри строчки синхронизация звука и видео делается уже хитро - вычитанием времени что осталось, и не всегда честная в итоге.

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

это будет достаточно эффективно в плане нагрузки

более тонко я использовал для VDP в ямахе там у меня эмуль проца после каждой команды звал хендлер VDP и он запускал и VDP

можно так и дма тут вкрячить прямо в проц или звать хендлер

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

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

скайп на днях? а я пока оформлю идею :smile: + мне любопытно про апогей поспрашивать чуть

---------- Post added at 02:06 ---------- Previous post was at 02:01 ----------


На мой взгляд, если использовать Fibers

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

ну не дословно конечно оформить в коде можно как угодно но суть в том что главный луп эмуляции реально потактовый

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

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

Ну видимо я и имел ввиду эмуляцию по циклам процессора или шины, не по совсем уж тактам физически =) - тут терминология просто разошлась

вообще если гнаться за реальной точностью эмуляции по какой либо причине - то это скорее всего будет PC и там если честно в наше время глубоко все равно хватит и по циклам и даже по тактам если с умом написать - не суть важно - скорее важно чтобы было проще разрабатывать и отлаживать

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

uart
10.01.2015, 15:52
У себя я использую не такты процессора, а "такты" кварца. Процессор берет их с *коэффициентом 9, ВГ75 - 12. Выполнение каждой команды это обязательный вызов FETCH плюс, в зависимости от кода команды, необязательные обрамленные RD и/или WR. Из этих трех функциях и вызывается DMA, а заодно и обслуживание ВГ75.
Но реализовано немного кривовато, в лоб, поэтому интересно было бы посмотреть на другую реализация. :)
На оптимизацию пока забил, IMHO больше времени тратится на прорисовку эмуляции ВГ75, чем на все остальное. Да и все равно с большим запасом хватает...

medvdv
25.03.2015, 02:10
У себя я использую не такты процессора, а "такты" кварца.

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

скажем есть текущее время в каких то условных тиках которые мельче любых устройств в машине

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

clock = 0

while emulationOn {
next_clock = 0
foreach chip in chips[] {
if chip.local_clock <= clock { chip.local_clock += chip.execute() }
if (next_clock == 0) || (next_clock > chip.local_clock) { next_clock = chip.local_clock }
}
clock = next_clock
}

chip.execute() возвращает количество проэмулированных тиков и мы плюсуем их к локальному времени устройства

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

теперь можно сделать что CPU будет не покомандно работать а по своим там внутренним циклам или просто потактно а можно и по старинке покомандно - это не меняет сути самого секвенсера и спрятано внутри объекта цпу или иного устройства

вот как то так видится

а внутри того же CPU в .execute() просто меняются стейты FETCH / DECODE / EXECUTE / RD / WR
так же внутри DMA и прочих устройств

ticks cpu::execute()
{
switch(.state) {
case FETCH: ... .state = DECODE; return 4;
case DECODE:
case RD:
case EXECUTE:
case WR:
}

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

Т.е. у меня не эмулируется "наперёд", а наоборот, откладывается на некоторое время. Это важно, поскольку если устройства взаимодействуют между собой, то "доэмулировать" до нужного времени (до момента, когда происходит взаимодействие) можно, а вот откатить назад - нафиг надо.

medvdv
27.03.2015, 04:43
Т.е. у меня не эмулируется "наперёд", а наоборот, откладывается на некоторое время. Это важно, поскольку если устройства взаимодействуют между собой, то "доэмулировать" до нужного времени (до момента, когда происходит взаимодействие) можно, а вот откатить назад - нафиг надо.

Хорошо значит сделано :v2_dizzy_vodka3:

Ну это уже вопрос терминологии / трактовки внутри объекта - можно сказать что вернул сколько ему спать дальше, или насколько тиков текущий стейт будет валиден, так то понятно что считаться надо до текушего времени <= clock скорее чем clock + еще сколькото, это верно, раз-ся