avva: (moose)
[personal profile] avva
x5602 - a simple 6502 CPU emulator

Проект, демонстрирующий очень простой эмулятор микропроцессора 6502 (который широко использовался в самом начале эры персональных компьютеров - Atari, Apple II, Commodore 64...). Если вы знаете язык C даже в общих чертах, и никогда не писали код, симулирующий работу процессора, то этот проект - хорошее введение в то, как к этому вообще подходить.

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

Date: 2013-12-24 11:54 pm (UTC)
From: [identity profile] michk.livejournal.com
XINU? :=-)

Date: 2013-12-25 01:30 am (UTC)
From: [identity profile] xxqs.livejournal.com
один большой switch и более сотни case... не уверен, что именно так и надо писать :)

Date: 2013-12-25 02:12 am (UTC)
From: [identity profile] archaicos.livejournal.com
Можно сделать разбивку инструкций по:
— кодировке инструкции и операндов
— числу и типу операндов
— типу операции (ADD, XOR, CALL, etc)
Это может несколько сократить switch в декодере инструкций, но взамен получатся большие таблицы (или много маленьких) и логика будет в коде менее явная. Останутся всякие switch'и (или, опять же, будут таблицы) для выполнения той или иной операции по её уникальному номеру.

Далее, в зависимости от крутизны процессора, на котором будет происходить эмуляция, организация кода эмулятора может существенно влиять на скорость эмуляции. Один большой switch может оказаться самым эффективным решением.

Даже для эмуляции очень симметричного и простого для декодирования MIPS'а с четырёхбайтовыми инструкциями нужно поддержать около сотни инструкций общего назначения, и это занимает где-то 600+ строк очень компактного C кода (с длинными строками, за 100 символов:).

Кстати, о большом switch'е и MIPS'е... MIPS на MIPS'е эмулируется (если мы не говорим о виртуализации или продвинутых вещах типа бинарной трансляции) лучше всего (с т.з. производительности) с одним большим switch'ем. Бóльшая часть нужных переменных (в т.ч. временных, создаваемых компилятором) помещается в регистры (штук 20 из 32-х доступны), а если ещё и почти не вызывать ф-ций изнутри этого switch'а, получаются минимальные накладные расходы на переливание из пустого в порожнее и на переходы туда-сюда-обратно. Можно получить всего около 25 инструкций эмулятора на эмуляцию одной инструкции. Сильно структурированный красивый и «правильный» код может раздуть эти 25 до 75-100. Не уверен, что так и надо писать. :)

Date: 2013-12-25 02:16 am (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Даже для эмуляции очень симметричного и простого для декодирования MIPS'а...

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

Date: 2013-12-25 02:21 am (UTC)
From: [identity profile] archaicos.livejournal.com
30+ тысяч строк кода на C.

Date: 2013-12-25 02:26 am (UTC)
spamsink: (Default)
From: [personal profile] spamsink
По данным разведки, один из победителей недавно завершившегося конкурса IOCCC, объявленный как "IBM PC emulator", умеет и графический режим c помощью SDL, и позволяет играть, в частности, в сьерровские игрушки и во флайт симулятор. Верхний предел размера кода, согласно правилам конкурса - 4096 байт.

Date: 2013-12-25 02:55 am (UTC)
From: [identity profile] archaicos.livejournal.com
Как я понимаю, чтобы подобное влезло в 4K нужно это делать той же платформе x86, много чего упростить/вырезать/не доделать, использовать особенности и функциональность ОС и сторонних библиотек. Моя оценка была для общего случая, когда халявы минимум и надо делать почти всё самому. Там, поди, порты CGA/EGA/VGA не особо эмулируются внутри этих 4K (кроме портов для установки палитры), а эмулируется сразу int 0x10 для установки режима?

Date: 2013-12-25 03:23 am (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Через неделю-другую, когда обещали выложить - посмотрим. По-моему, если использовать особенности ОС, код, наоборот, раздувается. Но даже не считая графики, упихать всю систему команд в меньше, чем 4К - очень круто.

Date: 2013-12-25 03:45 am (UTC)
From: [identity profile] archaicos.livejournal.com
А она не упихана. Там бóльшая часть инструкций исполняется почти напрямую. Иначе — никак.

Ты частично декодируешь инструкцию, немного её модифицируешь (добавляешь или убираешь префиксы размера операнда и адреса, выбрасываешь сегментные префиксы, меняешь адрес, закодированный в инструкции в полях ModR/M, SIB, disp), запихиваешь её в специально подготовленный буфер, где уже есть инструкции до и после, которые загружают регистры значениями из эмулятора и потом выгружают результат обратно. После этого передаёшь управление на буфер. Вот и готова одна инструкция типа ADD AX, [BX] без полного декодирования и полной честной эмуляции.

Понятно, что нужно отлавливать инструкции типа системных и тех, которые трогают вещи, которые нельзя трогать (сегменты, флаги, IP (передача управления), SP и пр.), и их уже честнее эмулировать. И ещё деление нужно специально обрабатывать чтобы эмулятор вдруг не упал сам.

Так ещё можно сделать. Но это трюк не пройдёт на другом железе.

Date: 2013-12-25 12:41 pm (UTC)
From: [identity profile] xxqs.livejournal.com
я бы скорее подумал, как 256-разрядное дерево запилить для декодинга. Понятно, что без вызова 1-2 функций на каждую инструкцию не обойтись, но по идее это будет дешевле, чем 100 сравнений в switch/case. Ну и это ещё и простенький процессор.

Date: 2013-12-25 12:51 pm (UTC)
From: [identity profile] archaicos.livejournal.com
Толковые современные компиляторы уже умеют раскладывать switch не на сто сравнений аргумента с сотней констант, а на дерево (или несколько), несколько инструкций и переход(ы) по таблице(-ам). Загляните в код, сгенерированный компилятором.

Date: 2013-12-25 12:56 pm (UTC)
From: [identity profile] xxqs.livejournal.com
интересно, мерси. Увы, заниматься таким ресерчем некогда, поверю на слово :)

Date: 2013-12-25 03:39 am (UTC)
From: [identity profile] e2pii1.livejournal.com
> код, симулирующий работу процессора, то этот проект - хорошее введение в то, как к этому вообще подходить

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

Пишем структуру данных соответствуюшую регистрам, флагам и прочему, и реализуем инструкции процессора по документации. Что еще ?

Date: 2013-12-25 03:55 am (UTC)
From: [identity profile] archaicos.livejournal.com
Иногда хочется быстро или очень быстро.

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

Иногда хочется имеющиеся особенности и глюки существующего железа полностью повторить (например, знаете что именно процессор сделает со сдвигаемым регистром, если счётчик сдвига содержит слишком большое число, и документация на процессор, говорит, что в этой ситуации результат не определён? Или что-то типа MOV EAX, SS — знаете что процессор положит в старшие 16 бит EAX на процессоре более старом, чем Pentium? И т.д.).

Кроме всего этого, документация часто содержит неточности и ошибки. Например, на x86 я сверял документацию Intel с документацией AMD и с тем, что на самом деле делал процессор. Много чего нашёл.

Т.е. вроде так ничего особенного, но часто это прорва работы, и не каждому под силу, особенно начинающему программисту.

Date: 2013-12-27 03:39 pm (UTC)
From: [identity profile] pesec.livejournal.com
Иногда хочется быстро или очень быстро.

Есть что-то более мощное, чем threaded code (http://en.wikipedia.org/wiki/Threaded_code) или JIT?

Date: 2013-12-28 05:18 am (UTC)
From: [identity profile] archaicos.livejournal.com
На данный момент, как я понимаю, лучше JIT может быть только лучший JIT. :)

Date: 2013-12-25 06:33 am (UTC)
From: [identity profile] lyuden.livejournal.com
Не могу не пропиарить

http://pythontutor.com/visualize.html#

Он работает конечно на повыше. Но позволяет пошагово визуализировать исполнение достаточно сложных вещей.

Date: 2013-12-25 11:49 am (UTC)
From: [identity profile] begemotv2718.livejournal.com
Надеюсь, все видели
http://www.visual6502.org/JSSim/

January 2026

S M T W T F S
    1 2 3
4 5 6 7 8 910
11121314151617
18192021222324
25262728293031

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 10th, 2026 12:30 pm
Powered by Dreamwidth Studios