*** ВНИМАНИЕ: Блог переехал на другой адрес - demin.ws ***

пятница, 25 сентября 2009 г.

Эмулятор Радио-86РК на JavaScript

Первым компьютером, на котором я начал программировать, был Радио-86РК. Его собрал мой брат и... понеслась, и несется до сих пор.

Поэтому я до сих пор питаю слабость к данному раритету. К результат этой слабости я постоянно писал эмуляторы этого компьютера.

Первый был под ДОС. Оригинальный сайт сего творения я храню до сих пор в неизменном виде. Этот эмулятор был весьма неплох: там был и встроенный отладчик, и метода взлома игр и т.д. Но ДОС ушел, поэтому данный эмулятор работает теперь разве что в DosBox'e. Исходники творения можно скачать.

Вторая реинкарнация любимого РК была уже под Windows и работала через SDL. Тут уже не было встроенного отладчика, да и проект так и остался сырым (хотя и работающим), поэтому на публике лежит только бинарь с комплектом игр.

И вот, пару дней назад я наткнулся вот на это - эмулятор Спектрума на чистом JavaScript'е! - ни апплетов, ни activex'ов.

Так я от этой темы завелся, что за день-два оживил старого монстра РК на платформе JavaScript. Оказывается правильные браузеры дают весьма недурственную скорость скриптования. 2d графика реализуется через тэг canvas из HTML5.

Получился проект - Эмулятор Радио-86РК на JavaScript.

Эмулятор и набор игр живут в одном единственном файле radio86.html. Можно нажать на ссылку, и эмулятор запустится в браузере. Внизу есть селектор для выбора игры, и возможность поиграться со размерами экрана и скоростью.

Эмуляция происходит на уровне команд процессора Intel 8080.

Скриншот классической игры Volcano, сделанный в этом эмуляторе.



На текущий момент я проверял только в Google Chrome 4.*. Думаю, я не буду заморачиваться особо на тему совместимости с другими браузерами, хотя посмотрим, как пойдет. В IE точно работать не будет, а вот про FF и Оперу ничего сказать не могу, пока.

Волшебный мир Радио-86РК снова вернулся!

P.S. К слову сказать, лучший эмулятор РК (и множества совместимых моделей), что я видел - это эмулятор Виктора Пыхонина. Может и он мигрирует на модную платформу со временем.

Update: Обновил эмулятор до версии 0.2. Изменения незначительные: добавил некоторые системные программы (языки программирования, отладчики, редакторы и т.д.) и немного улучшил селектор выбора игры, который теперь срабатывает при нажатии кнопки "Run".

Update: Обновил эмулятор до версии 0.3. Отрисовка экране теперь работает значительно быстрее и не так грузит процессор.

Update: В версии 0.4 теперь встроенный ассемблер. Можно писать и ассемблировать прямо в окне эмулятора. После есть возможно загрузить результат в сам эмулятор и запустить командой "G" в Мониторе.

Скриншот этого ассемблера:



Update: В версии 0.6 теперь есть встроенный дизассемблер. Им можно просматривать не только программый код, но и данные.

Скриншот дизассемблера:

23 комментария:

  1. А нельзя ли туда вместе с играми загрузить интерпретатор бейсика и языка форт ?
    Я поищу исходники если у вас нет.

    ОтветитьУдалить
  2. Бейсик у меня есть, причем разный. Про форт - не уверен. Если у вас есть, то присылайте. Будет здорово. Добавлю к играм.

    ОтветитьУдалить
  3. Casufi: Обновил эмулятор до версии 0.2. Добавил системные программы, в том числе бейсики разные и форт.

    ОтветитьУдалить
  4. Этот комментарий был удален автором.

    ОтветитьУдалить
  5. Не плохо тормозил на P4-2.4GHz, пока цикл обновления экрана не исправил, прорисовывая именно те знакоместа, куда производилась запись. Тогда всё просто стало летать!
    Писал я когда-то подобный эмул в Си. Правда ВГ75 и ВТ57 я там отработал основательно и при записи "плохого" кода в экранную память, экран начинал сбоить - медленно "плыть" влево. Почти 100% эмуляции. Правда на Pentium-90MHz это сильно подвешивало всю систему, несмотря на ассемблерные рендеринг и ядро ВМ80А... Жалко, что ядро я тогда не отладил: Бейсик выдавал ересь в арифметике, а Цирк дальше заставки не шёл. Хотя пара десятков других игр работала и звуки были.

    ОтветитьУдалить
  6. Спасибо за мысль. Только что выложил версию 0.3, которая отрисовывает только изменения. Теперь все работает значительно живее.

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

    ОтветитьУдалить
  7. Да. Теоритически я ожидал нестабильность скорости, а на практике сразу убедился: Клавиатура реагировала пачкой символов и печатать директивы было сложнее.
    Выход: new Date() и брать миллисекунды. По числу тактов расчитывать интервал и т.д.
    Гипотетически можно реализовать, а теоритически ещё не сообразил механизм. :)

    Кстати, когда я эмулятор впервые запустил, то в борьбе с тормозами стал серии case для инструкций mov r,r переколачивать в
    i8080["bcdehlma".charAt(opcode >> 3)] = i8080["bcdehlma".charAt(opcode & 7)] на скорую руку. Потом взялся за вычислительные...
    И только потом взялся за цикл экрана :)

    ОтветитьУдалить
  8. А у меня как-то нормально, а даже наоборот - игры стали более отзывчивые. Если слишком быстро, то можно поиграться с константой задержки.

    ОтветитьУдалить
  9. Кстати, если у вас есть интересные наработки по модификации эмулятора, может их пустить как новую ветку? Можно клонировать проект и поместить в клоне всякие новые фичи.

    ОтветитьУдалить
  10. Этот комментарий был удален автором.

    ОтветитьУдалить
  11. Конечно интересно.

    Где бы еще найти программу для тестирования всех команд i8080.

    ОтветитьУдалить
  12. Этот комментарий был удален автором.

    ОтветитьУдалить
  13. Добавил в эмулятор встроенный ассемблер.

    ОтветитьУдалить
  14. > Где бы еще найти программу для тестирования всех команд i8080.

    http://www.idb.me.uk/sunhillow/8080exerciser/index.html

    ОтветитьУдалить
  15. К сожалению, этот тест не дает четкого ответа, какая именно команда глючит.

    ОтветитьУдалить
  16. Наконец-то открыл черновик относительно выше сказанного
    http://code.google.com/p/x80/

    ОтветитьУдалить
  17. Добавил в эмулятор встроенный дизассемблер.

    ОтветитьУдалить
  18. В эмуляторе оптимальнее вместо гигантского case сделать массив безымянных функций. Я это уже сделал для версии 0.1 -- могу выслать.

    Версия 0.6 работает значительно быстрее 0.1. Как удалось этого добиться?

    ОтветитьУдалить
  19. Присылайте, конечно. Интересно будет посмотреть.

    А основное ускорения за счет оптимизации отрисовки экрана.

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

    Даже наоборот, я сейчас неспешно работаю над структурными улучшениями эмулятора, типа вместо хардкодинга команд INR A, INR B, INR C и т.д. будет одна функция, инкрементирующая любой регистр и т.д. То есть в объеме код эмулятора уменьшится, хотя по скорости может и проиграть из-за дополнительных вызовов. Но будет значительно проще тестировать. Просто изначально я практически взял без изменения код от эмулятора Спектрума и адаптировал его от Z80 До I8080. Но тот эмулятор тоже не был написан руками с нуля, а был хитрым образом сконвертирован из Си-шного эмулятора FUSE в JavaScript. Поэтому в коде так много практически одинаковых кусков. Если писать все с нуля, то конечно так писать никто не будет. Хотя наличие уже готового кода, который пусть и далек от идеала проще постепенно улучшать и покрывать тестами, чем писать с нуля.

    Я выловил как минимум десяток собственных опечаток от конвертации при отладке, а тестировать эмулятор процессора весьма сложно. Одну единственную неверную команду искать можно очень долго. Я нашел небольшую тестовую программу (она есть в списке игр - I8080TST), и с помощью нее чудом понял, что "DAD H" неправильно выставляла флаги, но остальные DAD команды работали правильно. Ну и т.д.

    Да компьютеры все быстрее и быстрее. Хром все быстрее и быстрее -- зачем оптимизировать мелочи, когда лучше бороться за структурные улучшения ;-).

    ОтветитьУдалить
  20. На днях закончил переделку эмулятора:

    Ядро процессора поддерживает x80-префиксы и регистры. Дизассемблер отображает инструкции в x80-виде. Сейчас работаю над ассемблером. К сожалению переделать встроенный готовый ассемблер не получилось. Поэтому всю эту неделю писал собственный с нуля. К данному моменту он работает, хотя многие синтаксические выражения стандартного не реализованы. Думаю, скоро выложу свой вариант этого эмулятора.
    Поддерживает "защищённый" режим.

    ОтветитьУдалить
  21. То есть план сначал сделать (диз)ассемблер, а затем уже собственно эмулятор? или эмулятор будет в железе?

    ОтветитьУдалить
  22. За основу я просто взял Ваш эмулятор и переделал ядро процессора под свой лад. А именно, просто сделал перехват кодов-префиксов 40 49 52 5B 64 6D 7F и вызов под-ядра. Под-ядро - копия ядра, но инструкции многие сильно изменены. И на этом всё. Программы РК при этом работают, значит в них нет тех кодов.

    Чтобы хоть как-то ориентироваться, я переделал опят-таки Ваш дизассемблер почти полностью. Сохранив оригинальную структуру, но переименовав инструкции/регистры. Стало очень удобно отлаживать свой x80-код. Но всё равно не легче.

    Поэтому я взялся за встроенный Ваш ассемблер. Но там столько специфичных ньюансов, что легче было написать свой с нуля. Что я и сделал.

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

    ОтветитьУдалить
  23. Ясно, ну чего - здорово. Будет готово - интересно будет посмотреть.

    А ассемблер там не мой, если копирайт посмотреть. Просто он мне понравился своей интерактивностью, поэтому я его прикрутил. Для нормальной разработки нужно что-то попроще, без свистелок. Тут вы правы.

    ОтветитьУдалить