Малый эмулятор RISC
Я пытаюсь встроить виртуальную машину в игру, и мне было интересно, если бы кто-нибудь знал о каких-то очень простых виртуальных машинах (я думал, что RISC/PIC был близок к тому, что я хотел), которые обычно используются для встроенных проектов, таких как управление роботами, двигателями, датчики и т. д. Моя главная проблема заключается в том, чтобы написать компилятор / ассемблер, если я сверну свой. Было бы неплохо использовать инструменты, которые уже существуют или в простейшей форме, просто компилятор C, который может скомпилировать его:-p.
Я действительно не хочу изобретать колесо здесь, но мне также нужны тысячи таких, которые бегают по виртуальному миру, поэтому они должны быть максимально простыми и быстрыми. Как уже упоминал один человек, меня тоже не волнуют проблемы реального времени, такие как время, автобусы и все такое веселье. Я думаю, что их виртуальные часы будут ограничены чем-то довольно медленным; и в конце концов мне, вероятно, придется взглянуть на нативную компиляцию, чтобы заставить их работать еще быстрее, но сейчас я просто собираю прототипы, чтобы получить общее подтверждение концепции.
В качестве входных данных я планирую установить датчики расстояния, света, материала и касания, установленные вокруг цилиндрического корпуса (16, может быть, 32 из них), а затем просто 2 двигателя для направленного вывода для управления своего рода колесом с каждой стороны. по сути, обработка не будет слишком напряженной, и мир будет достаточно простым, чтобы машине не приходилось тратить много вычислительной мощности на простые задачи.
С точки зрения памяти, я бы хотел, чтобы они могли хранить достаточно данных, чтобы их можно было оставить на пару дней без вмешательства для построения карт и сбора статистики. Мне не нравится, что 8-битная система может быть использована для обработки или памяти, но 16-битная версия определенно будет претендентом. 32 и 64 бита просто подталкивали его, и у них не было бы больше, чем 1 МБ памяти, вероятно, ближе к 256-512 КБ. (Билл один сказал, что 640k будет достаточно, так почему я не могу!!)
5 ответов
Если вы хотите что-то внедрить в реальный мир, одним из наиболее часто используемых встроенных микроконтроллеров RISC является семейство PIC. Google дает несколько эмуляторов, но я не думаю, что источник доступен для большинства.
другая возможность - QEMU, которая уже подражает нескольким разновидностям ARM.
и, конечно же, если вы не заинтересованы в эмуляции реальных устройств, гораздо проще и эффективнее будет работать самостоятельно. только с тем, что вам нужно, и не попадать в кучу флагов состояния, битов переполнения, ограниченной ширины шины, таймингов ОЗУ и т. д.
Я написал Wren для друга, который хотел, чтобы язык виртуальных машин работал на встроенном контроллере с 16K RAM. (Но он разрешает до 64 Кб на процесс в написанном коде.) Он включает в себя компилятор для небольшого тупого языка программирования. Все это довольно просто и не очень полезно, но это именно то, что вы описали в первом абзаце.
ФОРТ "виртуальная машина" примерно так же проста, как и они. 16-битное адресное пространство (обычно), 16-битные слова данных, два стека, память. "Многопоточные языки интерпретации" Лоилигера многое рассказывают о том, как создать интерпретатор FORTH на Z80.
Если вы хотите просто, рассмотрите Manchester Mark I. См. Стр. 15 этого PDF. Машина имеет 7 инструкций. Требуется около часа, чтобы написать переводчика. К сожалению, инструкции довольно ограничены (именно поэтому почти полная спецификация машины может поместиться на одной странице).
Подход Хавьера к собственной работе очень прагматичен. Проектирование и создание крошечной машины - двухдневная задача, если это так. Я построил крошечную виртуальную машину для проекта несколько лет назад, и мне потребовалось два дня, чтобы написать виртуальную машину с помощью простого визуального отладчика.
Кроме того - это должен быть RISC? Вы можете выбрать, скажем, 68K, для которых есть эмуляторы с открытым исходным кодом, а 68K была хорошо понятной целью для gcc.
Многие люди, пишущие игровые программы и другие приложения, встраивают язык в приложение, чтобы позволить пользователям писать небольшие программы.
Насколько я могу судить, наиболее популярными встраиваемыми языками в очень грубо-популярном порядке первого порядка (хотя "более популярный" не обязательно означает "лучше"), по-видимому, являются:
- предметно-ориентированный язык, разработанный специально для этого конкретного приложения и нигде не используемый
- Луа а
- Tcl
- Python a b, часто упрощенное подмножество, такое как PyMite c
- вперед
- JavaScript
- шепелявость
- AngelScript
- XPL0 a b
- Белка
- Haskell a b
- NPCI (Нано Псевдо C Интерпретированный)
- RoboTalk
- интерпретация некоторого аппаратного машинного языка (почему это наименее популярный выбор? по уважительным причинам, описанным ниже).
Возможно, вы захотите проверить Gamedev StackExchange, в частности такие вопросы, как "Как добавить язык сценариев в игру?",
Вы можете проверить некоторые вопросы здесь, на Stackru с тегом "встроенный язык"; такие как "Выбор встроенного языка", "Какой хороший встраиваемый язык я могу использовать для написания сценариев внутри моего программного обеспечения?" "Альтернативы Lua как встроенному языку?" "Какой язык сценариев игры лучше использовать: Lua или Python?", так далее.
Многие реализации этих языков используют своего рода байт-код для внутреннего использования. Часто две разные реализации одного и того же языка программирования высокого уровня, такого как JavaScript, используют два совершенно разных языка байт-кода внутри ( a). Часто несколько языков программирования высокого уровня компилируются с одним и тем же базовым языком байт-кода - например, реализация Python в Jython, реализация JavaScript в Rhino, реализация Tcl в Jacl и несколько других реализаций Scheme, а также несколько реализаций Pascal; все компилируются в один и тот же байт-код JVM.
подробности
Зачем использовать язык сценариев, а не интерпретировать какой-то аппаратный машинный язык?
Почему "Альтернативные жесткие и мягкие слои"? Чтобы получить простоту и более быстрое развитие.
более быстрое развитие
Люди обычно работают быстрее с языками сценариев, а не скомпилированными языками.
Приступить к работе с первоначальным прототипом, как правило, гораздо быстрее - интерпретатор обрабатывает за кулисами кучу вещей, которые машинный язык вынуждает вас явно записывать: установка начальных значений переменных на ноль, подпрограмма-пролог и код подпрограммы-эпилог malloc и realloc и free и связанные с ними средства управления памятью, увеличение размера контейнеров при их заполнении и т. д.
Когда у вас есть первоначальный прототип, добавление новых функций происходит быстрее: языки сценариев имеют быстрые циклы edit-execute-debug, поскольку они избегают стадии "compile" циклов edit-compile-execute-debug скомпилированных языков.
простота
Мы хотим, чтобы язык встроенного языка был "простым" двумя способами:
Если пользователь хочет написать небольшой код, который выполняет некоторую концептуально тривиальную задачу, мы не хотим пугать этого человека сложным языком, который требует 20 фунтов книг и месяцев обучения, чтобы написать "Hello, $USER". msgstr "без переполнения буфера.
Поскольку мы реализуем язык, мы хотим что-то простое в реализации. Возможно, несколько простых базовых инструкций, для которых мы можем выбить простой интерпретатор на выходных, и, возможно, какой-то уже существующий компилятор, который мы сможем использовать с минимальной настройкой.
Когда люди строят процессоры, аппаратные ограничения всегда ограничивают набор инструкций. Многие концептуально "простые" операции - вещи, которые люди используют постоянно - в конечном итоге требуют выполнения множества инструкций на машинном языке.
Встраиваемые языки не имеют этих аппаратных ограничений, что позволяет нам реализовывать более сложные "инструкции", которые делают вещи, которые (для человека) кажутся концептуально простыми. Это часто делает систему проще обоими способами, упомянутыми выше:
Люди, пишущие непосредственно на языке (или люди, пишущие компиляторы для языка), заканчивают тем, что пишут намного меньше кода, тратят меньше времени на пошаговое выполнение кода, отлаживая его и т. Д.
Для каждой такой высокоуровневой операции мы переносим сложность с компилятора на реализацию инструкции внутри интерпретатора. Вместо того, чтобы (вы пишете код), компилятор разбивает некоторую высокоуровневую операцию на короткий цикл на промежуточном языке (и многократно повторяет этот цикл в вашем интерпретаторе во время выполнения), компилятор выдает одну инструкцию на промежуточном языке (и вы напишите ту же серию операций в реализации этой промежуточной "инструкции" вашего интерпретатора). Со всеми компонентами, интенсивно использующими процессор, реализованными на вашем скомпилированном языке ("внутри" сложных инструкций), чрезвычайно простые интерпретаторы часто более чем достаточно быстры. (То есть вы избегаете тратить много времени на создание JIT или на попытки ускорить процесс другими способами).
По этим и другим причинам многие программисты игр используют язык "сценариев" в качестве "встроенного языка".
(Теперь я вижу, что Хавьер уже рекомендовал "использовать встроенный язык сценариев", так что это превратилось в долгую разглагольствование о том, почему это хорошая альтернатива интерпретации аппаратного машинного языка и указании альтернатив, когда один конкретный язык сценариев не кажется подходящее).