2010-03-10

Sinclair ZX80 Emulator

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

Телеграмма
----------


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

Ведь именно в 80х, небезызвестной фирмой Sinclair Research (в то время ещё Science of Cambridge Ltd.) был произведён компьютер Sinclair ZX80 (фотография - Daniel Ryde, Skövde 2004-08-31):


По сравнению с ZX81 или ZX-Spectrum, ZX80 не пользовался особой популярностью (что не помешало продать более 50 000 экземпляров). Столь высокие (на то время) продажи, очевидно, обусловлены низкой ценой компьютера (менее $200).

В ZX80 использовалось около 20 микросхем, 4 из корорых - ОЗУ (2 штуки), ПЗУ и процессор. В отличии от следующих моделей (ZX81 и Spectrum), не использовалось никаких ПЛМ (ULA), а только простые, доступные микросхемы.

В компьютере, по сути, не было никакого видеоконтроллера, и изображение формировалось специальной подпрограммой в ПЗУ.

Благодаря этой "особенности", изображение было не всё время, а только когда компьютер ничем не занят. Если же исполнялась программа, то изображение пропадало (да оно пропадало даже при наборе текста! Если бы у меня был реальный ZX80, меня бы это жутко бесило).

JavaScript

Javascript-а на ZX80 не было :)

Вдохновлённый эмулятором NES и ZX-Spectrum 48 на javascript, я решил сделать эмулятор Sinclair ZX80. Так как ZX80 предельно прост, то компонентов всего два - эмулятор Z80 и эмулятор компьютера.

zame-js-z80

У меня уже было ядро Z80, написанное для моего нового эмулятора ZX-Spectrum. Правда, у него был один большой недостаток - оно написано на C :) , но через несколько часов беспрерывной работы, я получил вариант на javascript.

Так как javascript гораздо медленнее, чем компилированный код на C, пришлось узнать много нового о внутреннем представлении чисел в javascript, и освежить в памяти приоритеты операторов.

Я был очень рад тому, что [ -1 & 0xFF = 0xFF ]. Это позволило упростить выражения вида [ (a - b +  0x100) & 0xFF ] до [ (a - b) & 0xFF ]
(эх, а на C всего лишь [ (uint_8)(a - b) ])

Не менее рад я был тому, что [ a + b & 0xFF = (a + b) & 0xFF ], это позволило убрать много ненужных скобочек (я не уверен, что все JS движки способны убирать лишние скобки на этапе компиляции)

Затем я прогнал код через пост-процессор, который используя всю мощь регэкспов, заменил всё что можно посчитать заранее, на готовые значения (например, 0x80 | 0x01 -> 0x81), ведь я ещё менее уверен, что все JS движки способны производить такие оптимизации.

И наконец, я более чем уверен, что JS движки не будут оптимизировать код вида:

var a = 2;
alert(a + 1);

до

alert(3)

(хотя, кажется, Google closure compiler это умеет), так что в критичных местах все переменные, которые не меняют своего значения, были заменени просто цифрами.

js-zx8x

Эмулятор самого компьютера прост как топор. Единственное, что пришлось сделать, так это чтобы нажатая кнопка оставалась нажатой некоторое время, даже если её отпустили (o_O), так как обычный жалкий кусок мяса успевает отпустить кнопку быстрее, чем код в ПЗУ ZX80 на неё отреагировать.

NoCanvas

И самое главное, как вывести изображение без канваса?

На самом деле очень просто - экран в ZX80 текстовый, так что при большом желании, можно выводить изображение хоть в textarea :) , однако, технология CSS-Sprites позволяет достить гораздо большего реализма.

P.S.

В хроме работает на отличненько, кушает от 30% до 50% процессора.
В опере тоже достаточно хорошо (а говорят, что в новой версии оперы совсем летать всё будет).
В файрфоксе заметно притормаживает.
В IE... работает.

Так как я никогда не видел ZX80 вживую, то не могу сказать насколько скорость эмуляции соответствует реальности. По сравнению с другими эмуляторами (теми что я смог найти под Linux), работает быстрее чем положено.

Manual

На случай если вы никогда не имели дела с ZX80, ZX81 или ZX-Spectrum, даю инструкцию по запуску единственной игры для ZX80, которую мне удалось найти (для ZX81 их гораздо больше, а уж под спектрум так совсем уйма);

1) После загрузки страницы, дождитесь появления буквы K на чёрном фоне у углу эмулятора.
2) Нажмите кнопку "Load game" (справа от эмулятора), появится листинг программы
3) Нажмите на кнопку R - должно напечататься RUN
4) Нажмите на ENTER и ожидайте инициализации игры

В самой игре: 6 - влево, 8 - вправо, 0 - стрелять.
Удачного спасения земли от космических пришельцев :)

Links

Поностальгировать - http://nocanvas.zame-dev.org/0004/
Сорсы - http://nocanvas.zame-dev.org/0004/js-zx8x-src.tar.gz

P.P.S.
Выверять текст и дописывать мелочи буду завтра.

1 comment:

  1. Good work. I tried a ZX81 rom on it. It partially works. Commands are OK but not extended. Example PRINT 10-3 gives 1. Did you tried with a ZX81 rom?
    Yours

    ReplyDelete