Этот проект создался как инструмент для решения более общей задачи - реверс-инжиниринг
Бытового Компьютера Лик производства завода Электронмаш, г. Черновцы в 1988 году.
Данная тема была впервые мной заявлена на форуме https://zx-pk.ru 2 мая 2018 года. С тех пор я периодически (запоями) делаю набеги к задачам.
Мое путешествие в мир компьютерной инженерии начался с игр на этом компьютере.
После того как игры перестали загружаться с магнитофонных кассет мне пришлось
освоить Basic. А после того, как ПЗУ микросхема с Basic начала сбоить и Basic больше
не загружался мне пришлось освоиться и в Assembler. Это было очень увлекательно.
Препарирование игрушек, чтобы разобраться как там все устроено. Ночные кодинги и дебаги
перед маленьким мониторчиком, от которого жутко болели глаза.
Сам компьютер достаточно редкий даже в кругу ценителей ретро компьютеров. Я свой экземпляр искал 7 лет. Вскоре он приедет ко мне (UPD: это уже случилось), что даст толчок в реверс-инжиниринге.
Я хочу вернуть молодость!
Так же мне давно хотелось написать свой эмулятор БК Лик на java.
В прошлом я совершал попытки эмулировать процессор и частично реализовал команды,
но позже нашел готовое решение на страничках форума
и порадовался, так как всю эту работу уже сделали до меня. С этого момента начался разбор сырцов.
Так как Java ушла далеко вперед и Applets уже не в моде, после серии попыток
запустить этот проект в Intellij Idea было решено мигрировать его. Google Driven Development
подсказал, что проще всего будет перевести на JNLP технологию (которая так же устарела,
но в отличие от Applets еще может быть запущена в современных браузерах).
Два вечера и завелось. В будущем проект будет переведен на более модерновые UI,
но пока в нем тестов нет - рефачить опасно.
Позже код был отрефакторен полностью, так что связать его с оригинальным кодом
практически не возможно. Мне очень хочется отметить вклад всех Авторов,
а потому был создан этот раздел и все коммиты, которые я смог найти на просторах сети
были добавлены в git history этого проекта. В OpenSource считаю важным не только
делиться, но и помнить всех, кто так или иначе повлиял на тебя в прошлом.
Спасибо всем Авторам!
- Завести проект в любом виде.
- Перевести проект c
AntнаMaven. - Запустить на нем
Монитор-1М/Basic ЛИК V2. - Запустить на нем игру
Клад. - Снабдить документацией.
- Восстановить историческую связь с https://github.com/begoon/jasper
- И тут https://web.archive.org/web/20061229151903/http://www.spectrum.lovely.net/jasp1_1j.zip
- Изучить так же правки сделанные
Авторомтут https://github.com/Arlorean/Jasper - И тут немного истории есть https://github.com/arlorean/casper
- Определиться с наследуемой лицензией и настроить maven плагин. Причем сообщить, что игры не распостраняются под той же лицензией.
- Отформатировать проект по
JCC, сохранив всю документацию. - Сделать переключение
ROMи загрузкуRKSна лету, без перезапуска сервера по хоткею,в областиNumLockзагружаютсяRKSпрограммы, а по хоткею0в областиNumLockпереключаетсяПЗУЛик/Специалист. - Пофиксить серверную версию после добавление
OpenFileDialog. - Покрыть тестами.
- Принять решение, что делать со старым
Spectrumкодом. - Отдебажить, почему не работает игра
Клад. - Отдебажить, почему
Basicглючит (сравнивая с эталонным эмуляторомemu80v4). - Перевести на модерновый
UIфреймворк. Был выбранSwingиjnlp+Swing. Теперь можно запускать приложение cUIизIDEи дебажить в нем. - Добавлены тесты а-ля
Экзорцист. - По тестам
Экзорцистнадо убедиться что все команды работают. - Запустить и отладить второй тест
Экзорцист. - Запустить и отладить третий тест
Экзорцист. - Запустить и отладить четвертый тест
Экзорцист. - Попробовать в бейсике запустить какую-то большую игру и подебажить ошибки.
- TODO #39 Добавить поддержку звука. Закончить попытки и сделать звук красивым.
- TODO #40 закончить с аудио пока отключил для веб версии - там ошибка
- Сделать возможным по рисайзу скейлить окно с содержимым.
- Разделить
GODObjectsна компоненты. - Отрефакторить видео логику, там ужас сейчас как не просто.
- Реализовать сохранение скриншота в
pngфайл. - Написать интеграционные тесты, которые будут тестить разные игрушки на большом количестве тиков.
- Код сильно отрефакторен. Удален старый код
ZX Spectrum, расширенные командыZ80, фичи, которые пока что не сильно нужны. Сильно упрощал везде, где только можно. - Реализовать
ассемблер/дизассемблердля удобного превращенияhexкодов вasmи назад. - Закончить с портированием команд.
- Дописать юнит тесты для каждой не протестированной команды.
-
ACI_XX -
ADC_R -
ADD_R -
ADI_XX -
ANA_R -
ANI_XX -
CALL_XXYY -
CC_XXYY -
CM_XXYY -
CMA -
CMC -
CMP_R -
CNC_XXYY -
CNZ_XXYY -
CP_XXYY -
CPE_XXYY -
CPI_XX -
CPO_XXYY -
CZ_XXYY -
DAA -
DCX_RR -
DI -
EI -
IN_XX -
JC_XXYY -
JM_XXYY -
JMP_XXYY -
JNC_XXYY -
JNZ_XXYY -
JP_XXYY -
JPE_XXYY -
JPO_XXYY -
JZ_XXYY -
ORA_R -
ORI_XX -
OUT_XX -
PCHL -
POP_RS -
PUSH_RS -
RC -
RET -
RM -
RNC -
RNZ -
RP -
RPE -
RPO -
RST_N -
RZ -
SBB_R -
SBI_XX -
SPHL -
STC -
SUB_R -
SUI_XX -
XCHG -
XRA_R -
XRI_XX -
XTHL - Реализовать в
TestMemoryвозможность проверять какие участки памяти поменялись. - Реализовать возможность трейсить выполнение
CPUв рантайме. - Возможность определять зацикливания, вход/выход в процедуры.
- Разобраться как работает
IOPorts. - Поправить все клавиши клавиатуры (они не работали корректно).
- Покрыть
IOPortsтестами с максимальным кавераджем и порефакторить. - Сделать возможным в интеграционных тестах нажимать (програмно) клавиши.
- Перевести все найденные в сети игрушки по
Ликув репозиторий. - Добавить описание к игрушкам
Лика. - Найти еще игрушек для
Специалиста. - Возможность дебажить на
UI. - Сделать два дружественных скрипта для сборки приложения с запуском
jnlpсервера и для запуска клиентского приложения. - Сделать метод печатающий в png заданной высота Range из памяти - полезно будет для отладки.
- Реализовать возможность
record/replayкак прототип. - Сделать
record/replayс форматом записи в файл соответствующего типа.Recordавтоматически просиходит при запуске эмулятора. А вотreplayпо клавише/в областиNumLock. - Сделать по хоткею (
*в областиNumLock) максимальное ускорение/замедление эмуляции системы. - Сделать по хоткею (
+,-в областиNumLock) возможность плавно наращивать/уменьшать скорость эмуляции системы. - Реализовать более умную остановку в тесте по достижению некоторого условия,
а не просто спустя
10Mтиков. - Существенно улучшить производительность (как
cpu, так и отрисовки). - В интеграционных тестах большие
trace/cpuassertблоки вынести в отдельные файлы, как сpng. - Реализована загрузка
rksфайлов с помощью эмулятора изOS. - Сделать возможным после запуска
rksсобрать статистическую информацию, в каких ячейках бывал процессор, дабы понять, где есть программа, а где данные. Это на следующем этапе позволит - Реализовать ассемблер как в https://svofski.github.io/pretty-8080-assembler/
- [!] Закончить дизасемблер.
- Реализовать сохранение/загрузку
снепшотовпо хоткеям. Весь стейт должен сохраняться. - Тест
8080ex1.asmне работает во всех местах правильно, смотриcurrent expected crc from emu80 - Сделать распознавалку текста, нарисованного на экране. Попиксельно изучить каждый символ.
- [!] Дезассемблировать
Монитор-1МиБейсик Лик V2и сравнить с эталоном, как в
DizAssemblerTest.testDecompileTest_lik_romZagruzchik. - Распечатка
01_zagr.logв области данных выводит неправильно символы - пофиксить. А вообще надо добавить символов как вAкоманде монитора. - Написать тест на выполнение команды
Bмонитора, и затем провериьПЗУи адресс0000...на идентичность. Бейсик копируется и надо понять насколько точно. И какая подпрограмма монитора это делает. - В
мониторепочему-то не печатаются символы!@#$%^&*()с шифтом. - Если печатать все символы с модификаторами (
alt|shift|ctrl) а потом взять файлrecи прогнать его еще раз, то результат будет совсем другим. Видимо не все записывается, что должно. - TODO #1 Проверить, что в веб версии работает загрузка
rks/recфайлов. - Проверить, что вообще все еще работает в веб версии :) а то давно не запускалось
- TODO #2 продолжить с тестом
cputest, пока что у негоasmневерный. Стоит начать с тестаDizAssemblerTest.testDecompileTest - TODO #3 setup
Gsonto convertDoubletoIntegerautomatically - TODO #4 В классе
Bitesесть дублирование кода между методамиpublic byte[] byteArray(Range range)public Bites array(Range range) - TODO #5 В ряде команд количество тиков зависит от того прошло ли условие или нет, сейчас нет возможности это сделать, т.к. значения захардкоджены. Продумать это.
- TODO #6 В
CpuPerformanceTest.performance_executeчасть команд закомментированы так как не продумано для них точек перехода, остальные команды выполняются последовательно. расскоментировать и продумать программу так, чтобы потестить все команды под нагрузкой. - TODO #6 Не понятно что делают команды
DI/EI. - TODO #7 В
FileRecorder.writeпишется на самом деле не1 байт, а up to4 байтПотому чтоWordMath.hex8для чисел больше0xFFон не работает верно, а возвращает большее число. Надо ли обрезать? То же дляWordMath.hex16для чисел больше0xFFFF. - TODO #8 В тесте
testLik_game_klad_recordingпочему-то в режиме теста game over а в реальной игре если запустить риплей - нет - TODO #9 Изучить почему тест
testLik_keyboardLine1не прошел нормально - риплей или рекорд не работает верно с клавишами - TODO #10 сделать так же для всех остальных линий клавиатуры подробный
testLik_keyboardLine1тест - TODO #11 проблема в
Keyboard.processKeyтакая, что если на незапущенном мониторе переключить язык, то потом при включенном мониторе вместоQWEбудет печататьсяJCU, то есть язык переключается. только при включенном мониторе получается, а не аппаратно - TODO #12 потенциальная проблема в
Keyboard.processKeyпри!key.pressed()потому, чтоLayoutможет сильно исказить картинку и отжимать будем уже не те кнопки - TODO #13 нажатие на
PG_UPпечатает0 - TODO #14 в кириллице нет символа
@, то вместо него возвращаетсяЮ. Так же в кириллице нет символа^, то вместо него возвращаетсяЧ. - TODO #15 в реальной клавиатуре в
cyrдолжен быть№но в ЛИКе нет такого символа - TODO #16 так у самого
ЛИКаc shift0 - TODO #17 должен быть прочерк, но его кода не нашел
- TODO #18 нет такого
ъзнака вЛИКе - TODO #19 вот не совсем понятно надо ли тут так сложно
- TODO #20 тут должно быть
\но в кириллице там вылетаетЭвместо\ - TODO #21 тут должно быть
|но такого символа нет вЛИКе - TODO #22 если в
NONE.ticksпоставить0, тогдаPCсчетчик будет неправильно бегать, на1больше - TODO #23 в
RomLoaderсделать преобразовательmem->rks - TODO #24 в
RomLoaderреализовать проверку контрольной суммы вrks - TODO #25 в
TapeFormat.kristato add cast to byte fromint - TODO #26 а точно в
Timings.willResetнадо так заморачиваться с многопоточностью - TODO #27 в
Util.toTargetEncodingне используется логика, убить весь связанній мертвй код - TODO #28 в
WhereIsData.markCommandwhy I cant set here if(info.command == null) info.command(command);This will improve performance - TODO #29 Некоторые игры не дизассеблируются без ошибок, надо разбраться что с ними не так.
- TODO #29
pilot - TODO #29
reversi - TODO #29
tip-top2 - TODO #29
zoo - TODO #29
blobcop - TODO #29
chess - TODO #29
basic - TODO #29
basic2 - TODO #30 Разобраться как загружать правильно другую версию
Basic\src\main\resources\arch\emu80.org\extracted\lik_spc1\BASIC\SPEC\BASSPEC.RKSИзвестно, что оно грузится по адресуCnstants.BASIC_V1_PROGRAM_START - TODO #31 Разобраться, почему не работает программа
presidentнаBasic, можетBasicне тот? - TODO #32 Добавить всех команд в
BasicCompilerсейчас там не все присутствуют. Плюс проверить все256символов и посортировтаь - TODO #32 Там осталось еще немного символов, которые скорее всего ничего не значат.
- Сделать парсилку
Basicкоманд в машинном коде в текст - TODO #33 Сделать в
BasicCompilerобратнуую декомпиляцию программы наBasicв машинный код - TODO #34 Перенести тест в отдельный класс для тестирования
BasicCompilerи там генерировать исходный код программы на бейсике для всехbssфайлов. - TODO #35 Проверить, что
\src\main\resources\arch\Alex_B\ROM_LIK.ZIP\ROMLIK\ROMLIK.BINсоответствует мержу6частей пзуЛИКа. - Прогнать все варианты запуска эмулятора:
jetty,jnlp,jar. Ни один из них не работает. - TODO #36 rename to
testGenerateWavefromtestLik_generateWave - TODO #37 А точно тут надо для всех типов файлов делать загрузку монитора и команд
J/G? - TODO #38 Почему-то не работает
cputest.asmв js версии тестов. - Завести
jetty/jnlpсервер, поправитьbatch/bashскрипты, прописатьrun configurationsвIntellij Ideaдля запуска сервера и клиента и описать их тут в этом файле. - Сделать по хоткею копирования текста экрана в буфер обмена с помощью
PngScreenToText. - Сделать по клику в
windowsна файл определенного типа загрузку его в эмуляторjar. - TODO #41 этот костыыль надо при загрузке снепшота из командной строки по полному
пути там под windows не работает добавление
base - Сделать
/build/open-file.regгенерируемым изbat/shс правильнымми путями. - TODO #42 Во все места конкатенации
baseиfileдобавить проверку на то что там между ними будетслеш. - TODO #43 Надо сохранить так же и этот стейт в
снепшот - TODO #44 Почему-то
Integration testsстали запускаться дольше после последних изменений в звуке и таймингах - исследовать после какого коммита поломалось:2025-02-15-2025-02-17 - TODO #45 Почему-то тут
NPEпроскакивает порой - TODO #46 Кажется эти все константы между собой связаны,
покуритькак именно - Поему-то висит версия в браузере с
CheerpJотрисовка происходит только если остановить скрипт в браузере а10кinterruptsпроисхоидт5секунд - TODO #47 Надо инкапсулировать результат ассемблирования в объект а не Map
- TODO #48 Я пока не понимаю что это за данные, как пойму - смогу их установить разумно
- Сделать что-то еще...
- И еще что-то...
- Проект иначально взят тут http://sgu-wap.narod.ru/SP_MX/SPECOLD/Spec1987.zip, но у него большая история.
- Спасибо всем по цепочке fork'ов, благодаря которым эту код базу могу подхватить дальше.
- Clive Sinclair за создание (Sinclair ZX Spectrum)[https://en.wikipedia.org/wiki/ZX_Spectrum]. Если по правде, именно с него я начинал играть на компьютере, но я почему-то этого почти не помню, т.к. был мал. Эта платформа вдохновила тысячи людей на создание своих проектов. Это одна из историй.
- Andrew Pollard за первые наработки
эмулятора
Z80на платформеMotorola 68000, с последующим портом кода наC. - Adam Davidson за порт этого эмулятора на
Javaи создание Jasper. - Philip M. Scull за вторую жизнь Jasper.
- Alexander Demin за третью жизнь Jasper.
- Lavr
за проделанную работу по запуску
Специалист'а(старший братЛик'а) и подробные комментарии в коде.
- Спасибо Организаторам и комьюнити за возможность держать связь с коллегами по цеху:
- форума nedopc.org.
- форума zx-pk.ru (именно на этом форуме я и купил свой второй Лик).
- Спасибо
svofskiза чудный assembler редактор. - Спасибо
Viktor Pykhonin (vpyk)за крутой эмулятор.- Отдельное спасибо за исходники
и
emu80дебаггер они очень помогли в поиске отличий между процессоромZ80иi8080.
- Отдельное спасибо за исходники
и
- Спасибо Автору статьи Различия между процессорами i8080 (он же КР580ВМ80А) и Z80.
- Спасибо
Диме Вилюжанинуза то, что помог купить реальныйЛик. - Спасибо моему Папе за то, что привил мне любовь к инженерии.
- Спасибо инженерам Черновицкого завода
ЭлектронмашзаЛик. - Спасибо
Лищинскому К.Вза римейк игры Клад на Лик'е. - Спасибо Авторам за картинку
- Спасибо
OracleзаJava. - Спасибо
Markdownза то, что я не мучаюсь с версткой этой странички.
- Для запуска необходимо установить
java8версии. - Прописать переменную окружения
JAVA_HOMEссылающуюся на папку с установленнойjava. - Затем добавить в Path переменную
JAVA_HOME/bin. - Выполнить команду в консоли
java -versionи увидеть версию java. - Часть конфигураций
IDE(Intellij Idea) настроена на использованиеC:\Java\git\git-bash.exeв качестве интерпретатора командной строки. Рекомендуется установить git в папкуC:\Java\gitлибо поменять конфигурации.
-
Для открытия проекта в
IDEстоит импортировать его какmavenпроект. -
Запустить класс
spec.Mainили выполнитьrun-emulator-likиз run configurations для запуска платформыЛИКилиrun-emulator-specialistдля платформыСпециалист. -
Для Intellij Idea есть конфигурации запуска в папке
.run. -
В проекте присутствуют unit/integration тесты с хорошим code-coverage - рекомендуем начать работу с их запуска
test-all-java. -
Так же присутствуют javascript код и тесты к нему - их можно запустить через конфигурацию
test-all-js. -
Для генерации для всех приложений ассемблерного кода стоит запустить конфигурацию
generate-asm, что вызовет тестDisAssemblerTest.testDecompileTestа он в свою очередь сделает все необходимое. -
Для генерации для всех приложений
waveстоит запустить конфигурациюgenerate-wave, что вызовет тестWaveTest.testWaveTestа он в свою очередь сделает все необходимое.
-
Для этого стоит запустить скрипт
build/build-client.sh. Если нет linux можно использовать тулы типаcygwin/mingw. Так же можно запустить скриптbuild/build-client.batдляwindows. -
Того же можно добиться выполнив конфигурацию
bash-build-clientиз IDE дляlinux, илиbatch-build-clientдляwindows. -
В процессе сборки создастся папка
build/outв которой будет все необходимое для запуска. -
Следом скрипт
build/out/run.sh(илиbuild/out/run.batдля windows) запустится автоматически. -
В будущем не стоит пересобирать все приложение - для запуска достаточно запуска скрипта
build/out/run.shили конфигурацииbash-run-clientиз IDE дляlinux, илиbuild/out/run.bat/batch-run-clientдляwindows. -
Эти скрипты принимают на вход 4 опциональных параметра:
base- базовая папка, где лежат все файлы (не обязательно, по умолчанию.)platform- платформа, которую надо запустить:likилиspecialist(не обязательно, по умолчаниюlik)rom- путь к файлу с программой, которую надо запустить (не обязательно, по умолчанию пусто)command- команда, которую надо выполнить в мониторе платформы, напримерJ000(не обязательно, по умолчанию пусто). Для демонстрации запуска команды рассмотрите конфигурациюrun-emulator-budi-outкоторая эмулятор с./src/main/resources/ lik lik/apps/budi/budi.rks O=QWE,0000,6DFF, что приведет к эмуляции вывода области памяти программы на магнитофон.
-
Для сборки jar из IDE стоит выполнить
maven-jar-with-dependenciesиз run configurations. -
Или выполнить команду
mvn clean package -DskipTests=true -Pjar-with-dependencies. -
В результате мы получаем
jarсо всеми зависимостями и платформамиlikиspecialistвнутри. -
Файл
jarбудет лежать в папкеsrc/main/webappи называтьсяemulator-1.0.jar. -
Файл не будет кандидатом в коммиты в
gitтак как добавлен в.gitignore. -
Его размер внушительный из за файлов платформ и зависимостей.
-
Запустить
jarможно командойjava -jar .\emulator-1.0.jar "./" "lik" "lik/apps/klad/klad.rks". Как біло сказано ранее, каждый параметр тут опционален. -
При запуске
jarвсе файлы платформ будут скопированы на хостовую машину рядом с jar для возможности открывать их с помощью втроенного диалога открытия файлов эмулятора. -
Так же рядом создадутся новые папки:
recordsдля записи/воспроизведения файлов.snapshotsдля сохранения/загрузки стейтов машины.screenshotsдля сохранения скриншотов экрана.
-
Прежде всего стоит прояснить что в браузере приложение появляется только благодаря Cheerpj проекту. Он позволяет запускать java приложения в браузере.
-
Сборка происходит в два этапа.
-
Первый этап - собираем jar со всеми депенденсями как описано тут Другими словами запускаем
maven-jar-with-dependencies. Он запустится автоматически при запуске следующего этапа. -
Второй этап - запускаем
maven-jetty-run, что приведет к поднятию сервера на порту8080. -
Того же можно добиться выполнив конфигурацию
bash-build-serverиз IDE дляlinux, илиbatch-build-serverдляwindows. -
Скрипт в какой-то момент остановится (сервер запустился) - окно закрывать не стоит, его закрытие приведет к остановке сервера.
[INFO] Started ServerConnector@7cec8fb0{HTTP/1.1, (http/1.1)}{localhost:8080}
[INFO] Started Server@44f7dca8{STARTING}[11.0.7,sto=0] @13087ms
-
Направляемся в браузер и набираем в адресной строке
http://localhost:8080/. В этот момент приложение попробует загрузиться. -
Для другого URL необходимо править файл
build-server.shв области
eval_echo "HOST=localhost"
eval_echo "PORT=8080"
- Если сервер более не нужен - стоит нажать
Ctrl-Cв консоли, иначе если просто закрыть окно консоли - процесс будет висеть в памяти, не давая запустить сервер второй раз.
-
Для удобства работы с файлами в эмуляторе под windows стоит запустить скрипт
build/open-file.reg. Он добавит в реестр windows ключи для открытия файлов с расширениямиcom,rom,bin,rks,snp,bss,bs1,memиasm. -
Этот файл генерируется автоматически при запуске скрипта
build/open-file.batс поздставлением путей к собранному приложениюjarи папке с ресурсами. -
Для рализации этого подхода нужно предварительно собрать jar со всеми депенденсями как описано тут
- Приветствуем надпись
* RUN"COM:" - Жмем на клавиатуре клавишу
Pause/Break, затемEnd, затемEnter. - Приветствуем надпись
* RUN"COM:"
* МОНИТОР-1М *
===>
- Нажимаем клавишу
B, затемEnter. - Приветствуем надпись
* BASIC ЛИК V2 *
OK
- Нажимаем на клавиатуре клавишу
Pause/Break, затемEnd, затемEnter. - Нажимаем на клавиатуре клавишу
.(точка), затемEnter. - Откроется диалог выбора файла. Выбираем файл
klad.rksиз папкиsrc/main/resources/roms/lik/apps. - Нажимаем на клавиатуре клавишу
J, затемEnter. - Радуемся игре
Клад. - Для запуска этой замечательной игры так же создан отдельная конфигурация
run-emulator-kladв IDE.
- Для загрузки других ROM/RKS стоит запустить класс
spec.Mainс третьим параметром, путь которого является любым типом:comзагрузится в область0x0100.rom,binв область0xC000.rksзагрузится в область указанную в самом файле.snpзагрузит весь сохраненный стейт машины и передаст управление на место где был сохранен стейт.bssзагрузится вBASIC_LIK_V2_PROGRAM_START/0x1E60область.bs1загрузится вBASIC_V1_PROGRAM_START/0x2000область.memили любой другой файл загрузится в0x0000область.asmсассемблирует программу и загрузит в соответсвующую область памяти.
- При этом так же стоит понимать, что по-умолчанию загружается платформа
ЛИК, но и на это можно повлиять указав второй параметр классаspec.Mainодин из двух вариантовlikилиspecialist. - Первый же параметр - это папка с ресурсами
src/main/resources/, где расположены все файлы платформ. - Так же можно добавить иную платформу реализовав интерфейс
Platform. - В консоли можно увидеть как и куда происходит загрузка:
Loading 'file:/C:/Java/8080-emulator/src/main/resources/lik/roms/01_zagr.bin' into [C000:C7FF]
Loading 'file:/C:/Java/8080-emulator/src/main/resources/lik/roms/02_mon-1m.bin' into [C800:CFFF]
Loading 'file:/C:/Java/8080-emulator/src/main/resources/lik/roms/03_mon-1m_basicLik.bin' into [D000:D7FF]
Loading 'file:/C:/Java/8080-emulator/src/main/resources/lik/roms/04_basicLik.bin' into [D800:DFFF]
Loading 'file:/C:/Java/8080-emulator/src/main/resources/lik/roms/05_basicLik.bin' into [E000:E7FF]
Loading 'file:/C:/Java/8080-emulator/src/main/resources/lik/roms/06_basicLik.bin' into [E800:EFFF]
После того как приложение запущено, есть несколько вариантов как влиять на работу эмулятора.
Большинство манипуляций осуществляются через number pad - NumLock должен быть включен.
-
Pause/Break- Сброс процессора. После сброса процессора, загружается монитор (ЛИК или Специалист). -
End- Эмуляция клавишиStopна клавиатуре.
-
NumPad 0- Переключение ПЗУ Лик/Специалист. -
NumPad .- Загрузка бинарного файла в память. Откроется диалогData fileи можно выбрать файлcom,rom,bin,rks,mem,bss,bs1илиasm.com- загружаеся в область памяти0x0100.romиbin- загружается в область памяти0xC000.rks- загружается в область памяти указанный в самом файле - первые 4 байта файла отвечают за это: lo(START), hi(START), lo(END), hi(END). Затем идут данные. Последние два байта - контрольная сумма: lo(CRC), hi(CRC).mem- загружается в область памяти0x0000.bss- загружается в область памяти0x1E60, что соответствуетBASIC_LIK_V2_PROGRAM_START.bs1- загружается в область памяти0x2000, что соответствуетBASIC_V1_PROGRAM_START.asm- ассемблирует программу и загружает в соответствующую область памяти.
После загрузки файла в память, происходит
resetпроцессора, загружается монитор (ЛИК или Специалист), а затем выполняется командаJXXXX(ЛИК) илиGXXXX(Специалист) для запуска программы, гдеXXXX- адрес начала программы.
-
NumPad 3- Запуск replay режима. Откроется диалогRecording fileв котором можно выбрать файлrecс записью. После выбора файла эмулятор выполнитresetи начнет воспроизведение записи. Формат файла текстовый, показывает все нажатые клавиши в зависимости от тика процессора.after(138119).down(0x23); after(57046).up(0x23); after(56044).down(0x0A); after(58289).up(0x0A); after(238600).down(0x4A); after(51332).up(0x4A); after(226480).down(0x0A); after(87217).up(0x0A);В данном примере на 138119й тик после сброса процессора нажата клавиша
0x23, затем еще после 57046 тиков она отпущена. Потом через 56044 тика нажата клавиша0x0Aи так далее. Когда файл закончится, эмулятор перейдет в нормальный режим, но будет продолжать записывать все новые нажатия в исходный файл. -
NumPad 2- Останавливает воспроизведение/запись replay. -
NumPad 1- Зарезервировано для будущего использования.
-
NumPad 6- Загрузка состояния машины из папкиsnapshots. При этом заружаются все регистры CPU, IO порты и состояния клавиатуры, а так же вся память. Выполнение продолдается с места на котором было сохранено состояние. -
NumPad 5- Сохранение состояния машины в папкуsnapshots. При этом сохраняются все регистры CPU, IO порты и состояния клавиатуры, а так же вся память. Сохранение происходит в файл с расширениемsnp. Егоjsonструктура такая:let json = { "Cpu": { "PC": "2345", // `PC` (hex low byte, hex high byte) "SP": "6789", // `SP` (hex low byte, hex high byte) "AF": "1216", // `AF` (hex low byte, hex high byte) "BC": "5678", // `BC` (hex low byte, hex high byte) "DE": "9ABC", // `DE` (hex low byte, hex high byte) "HL": "DEF0", // `HL` (hex low byte, hex high byte) "interrupt": 4630, // `interrupt` "tick": 448585456, // `tick` "tact": 305419896 // `tact` }, "Timings": { "interrupt": 1234, // `interrupt` "refreshRate": 100, // `refreshRate` "willReset": 0, // `willReset` 1 if true, 0 otherwise "last": 1733699664007, // `last` "delay": 135659, // `delay` "fullSpeed": 1, // `fullSpeed` 1 if true, 0 otherwise "time": 1733699156833 // `time` }, "IOPorts": { "Ain": 0, // `Ain` 1 if true, 0 otherwise "Bin": 0, // `Bin` 1 if true, 0 otherwise "C0in": 1, // `C0in` 1 if true, 0 otherwise "C1in": 0 // `C1in` 1 if true, 0 otherwise }, "RomSwitcher": { "platform": "specialist" // `platform` `specialist` or `lik` }, "Keyboard": { "keyStatus": [ // array key matrix (1 - pressed, 0 - released) "110101001110", // size 12 x 6 + shift + reset "011100101001", "101000001100", "000100011111", "001110010101", "100010000110" ], "shift": 1, // `shift` 1 if true, 0 otherwise "alt": 0, // `alt` 1 if true, 0 otherwise "ctrl": 1, // `ctrl` 1 if true, 0 otherwise "shiftEmu": 0, // `shiftEmu` 1 if true, 0 otherwise "cyrLat": 1 // `cyrLat` 1 if true, 0 otherwise }, "GraphicControl": { "ioDrawMode": 3 // `ioDrawMode` // `0` Border highlights active window (and audio mode) // `1` Border highlights writing byte to Port A // `2` Border highlights writing byte to Port B // `3` Border highlights writing byte to Port C // `4` Border highlights writing byte to Port RgSYS }, "AudioDriver": { "audioMode": 1, // `audioMode` 1 if true (AUDIO_MODE_LINE_OUT) // 0 otherwise (AUDIO_MODE_SPEAKER) "allowDataSkip" : 0 // `allowDataSkip` 1 if true (CAN_SKIP_DATA) // 0 otherwise (DO_NOT_SKIP_DATA) // this allow to increase emulation speed }, "Memory": { "data": [ // memory in hex " 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ", // fist line - address "0000: C3 00 40 21 00 00 22 E1 8F 21 00 13 22 3A 0F 21 ", // second line - data "0010: 00 07 22 3E 0F 0E 1F CD 37 C0 3E 05 32 53 0F AF ", // ... // ... ] } }
-
NumPad 4- Зарезервировано для будущего использования.
-
NumPad 9- Переключение режимов вывода звука:- Вывод на магнитофон
AUDIO_MODE_LINE_OUT - Вывод на динамик
AUDIO_MODE_SPEAKER(по умолчанию).
- Вывод на магнитофон
-
Ctrl+NumPad 9- Переключение режимов потери звука при ускорении:- Звук теряется при ускорении
CAN_SKIP_DATA - Звук не теряется при ускорении
DO_NOT_SKIP_DATA(по умолчанию) Это атуально и критично дляAUDIO_MODE_LINE_OUT, а так же странным образом стабилизирует тайминги во время ускорения эмуляции не давая выполняться быстрее, чем положено для воспроизведения. Это еще предстоит разобрать, но так как это максимально точно передает оригинальный компьютер - я оставил по умолчанию эту опцию и поставил задержкуCPU_INTERRUPT_DELAY, которая чуть меньше чем надо.
- Звук теряется при ускорении
-
NumPad 8- Создает скринотшот в папкеscreenshotsс именем содержащим текущую дату. -
Ctrl+NumPad 8- Копирует в буффер обмена распознанное содержимое экрана. -
NumPad 7- Режим вывода бордюра (цветной рамки). Работает цилично.ioDrawMode = 0- бордюр подсвечивает активно ли окно эмулятора и какой режим вывода звукаioDrawMode = 1- бордюр подсвечивает запись байта в порт АioDrawMode = 2- бордюр подсвечивает запись байта в порт BioDrawMode = 3- бордюр подсвечивает запись байта в порт CioDrawMode = 4- бордюр подсвечивает запись байта в порт RgSYS
-
NumPad /- Приостановка/Запуск процессора. -
NumPad *- Ускорение/Замедление эмуляции. По умолчанию эмуляция происходит в реальном времени. При нажатии клавиши происходит максимальное возможное ускорение эмуляции. При этом отключается звук, так как он достаточно сильно замедляет эмуляцию, а экран обновляется в разы реже (см.MINIMAL_SCREEN_EACH_INTERRUPT) При повторном нажатии происходит возврат к реальному времени. -
NumPad -- Плавное уменьшение скорости эмуляции до минимальной. -
NumPad +- Плавное наращивание скорости эмуляции до максимальной.
Разновидность 1 для ПК Специалист:
- 2 байта - адресс начала памяти (low byte, high byte)
- 2 байта - адресс конца памяти (low byte, high byte)
- массив байтов прпограммы длинной между началом и концом
- 2 байта - контрольная сумма (low byte, high byte)
Разновидность 2
- 4 байта -
0x700x8F0x820x8F(префикс) - 16 байт -
0x00 - 1 байт -
0xBC - 2 байта - контрольная сумма (low byte, high byte)
- 255 байт -
0x00 - 1 байт -
0xE6 - 2 байта - адресс начала памяти (low byte, high byte)
- 2 байта - адресс конца памяти (low byte, high byte)
- массив байтов прпограммы длинной между началом и концом
В эмуляторе есть возможность генерировать Wave файлы. Тестовый класс WaveGeneratorTest служит для генерации
wave для всех игр всех платформ.
В эмуляторе есть возможность дизассемблировать приложения. Тестовый класс DisassemblerTest служит для генерации
asm файлов для всех игр всех платформ.
В эмуляторе есть возможность декодировать тексты програм на бейсике из машинных кодов.
Класс BasicCompiler служит этой цели.
public static void main(String[] args) throws IOException {
BasicCompiler basic = new BasicCompiler();
// загружаем программу в память
Memory memory = new Memory(0x10000);
RomLoader roms = new RomLoader(memory);
URL base = new File(".").toURI().toURL();
Range range = roms.loadBSS(base, "src/main/resources/lik/apps/basic/program/president/president.bss");
// получаем исходники
List<String> source = basic.getSource(memory.all(), range);
// сохраняем в файл
String program = StringUtils.join(source, "\n");
FileUtils.writeByteArrayToFile(new File("target/program.bas"), program.getBytes());
// выводим на экран
System.out.println(program);
// напечатает
// 0 REM ..........................
// 1 REM : ** NEW PRESIDENT ** :
// 2 REM : :
// 3 REM : ВЕРСИЯ - II. :
// 4 REM : ИСПРАВЛЕННАЯ ВЕРСИЯ-I. :
// 5 REM : БОЛТАЕВСКИЙ АЛЕКСАНДР.:
// 6 REM : КРАСНОЯРСК-1992. *BAI*:
// 7 REM :........................:
// 8 GOSUB 7000
// 10 CLS0:CUR40,120
// 20 INPUT"ВВЕДИТЕ ВРЕМЯ ЧАС,МИН";X,Y:GOSUB9000
// 30 FORI=0TOX+Y:Z=RND(1):NEXTI
// ...
}Для распознавания текста на экране используется класс PngScreenToText. Пример использования в main методе.
Возможна и обратная процедура.
Так же логику работы изучить с помощью теста PngScreenToTextest там есть примеры использования.
public static void main(String[] args) {
PngScreenToText scanner = new PngScreenToText("src/main/resources");
// парсим картинку в текст
String parse = scanner.parse("./src/test/resources/IntegrationTest/testLik/smoke/7_exit.png");
// печатаем на экран
System.out.println(parse);
// 0 1 2 3 4 5 6 7 01234567
// 8 9 A B C D E F 89ABCDEF
// 9000: 00 00 00 00 00 00 00 00 ........
// 9008: 00 00 00 00 00 00 00 00 ........
// 9010: 00 00 00 00 00 00 00 00 ........
// 9018: 00 00 00 00 00 00 00 38 .......8
// 9020: 45 45 3D 05 09 70 00 00 EE=..П..
// 9028: 00 38 45 45 3D 05 09 70 .8EE=..П
// 9030: 00 00 00 38 45 45 3D 05 ...8EE=.
// 9038: 09 70 00 00 00 38 45 45 .П...8EE
// 9040: 3D 05 09 70 00 00 00 38 =..П...8
// 9048: 45 45 3D 05 09 70 00 00 EE=..П..
// 9050: 00 38 45 45 3D 05 09 70 .8EE=..П
// 9058: 00 00 00 38 45 45 3D 05 ...8EE=.
// 9060: 09 70 00 00 00 38 45 45 .П...8EE
// 9068: 3D 05 09 70 00 00 00 38 =..П...8
// 9070: 45 45 3D 05 09 70 00 00 EE=..П..
// 9078: 00 38 45 45 3D 05 09 70 .8EE=..П
// ===>
// * MOHИTOP-1M *
// ===>█
// сохраняем текст в картинку
scanner.draw(parse, new File("target/screen.txt").getAbsolutePath());
}Для компиляции asm в bin используется класс svofski.Assembler. Пример использования в main методе.
Детали в Различные тесты CPU
From site: http://www.spectrum.lovely.net/
Jasper V1.1 is now available with the following enhancements:
- Screen updating is now much faster thanks to David Dawkins image handling tips.
- The class files have been shrunk to speed download times.
- Progress of snapshot loading uses a progress bar thanks to Adam Doppelt.
- The screen is double buffered for smoother display of games which use scrolling.
- Click on progress bar to toggle between
FullandSlowspeed (slow to100%). - Saving snapshots has been removed to save on class file size.
- The emulator has been updated to handle JDK1.1 as well as
JDK1.02. - Source code is now available for download.
Jasper.classnow replacesSpectrumApplet.classas the main class file.
For a Quick Start try out Manic Miner.
After seeing Jasper, a friend of ours, David Dawkins,
decided to do an Atari ST Emulator. So far, it is looking very good. Look
at his website for more details.
The Sinclair ZX Spectrum (TS 2068 for those in the US) was a home computer
released in 1982 by a British company called Sinclair Research Limited.
The chip inside the Spectrum was a Z80 clocking in at 3.5Mhz, not quite
the 1GHz of todays Intel machines. It only had 48Kb of memory, PC speaker
style sound and only audio cassette tape for storage, but in the 1980's it
was the business.
Due to demand, we've added a zip file to save downloading the .class files each
time, jasp1_1c.zip.
The source code is now available for download, jasp1_1j.zip.
We haven't included any game snapshots with this so you'll have to download these
yourself from ftp://ftp.nvg.unit.no/pub/spectrum/snaps/games .
With the old version
you can convert between .z80 and .sna snapshot formats.
Jasper automatically detects which type to load and saves by default as a .z80,
unless you add a .sna extension to the end (PgUp/PgDn do LOAD and SAVE).
LOAD and SAVE also work from within BASIC but are limited to 10 characters for
the filename.
Gamelan say this applet is cool. Thanks to them and to everyone else who has sent us email, the response has been greatly appreciated.
The Java(tm) Centre, who I can't seem to find their web address anymore,
have given us a Golden Duke award for this applet.
Java(tm) Review Service
have rated us as a top 1% applet.
This version contains support for old Netscape/JDK implementations by providing
a sleep statement every Z80 interrupt (5 milliseconds by default), so that other
threads are not blocked. If you are running Internet Explorer 3.0 or Netcsape 3.0
then click on the Speed: 100%, Sleep:5 text at the foot of the screen to speed things up.
If you click on the progress bar at the foot of the screen, it will speed
up the emulator although on some systems you may find that this locks up
your browser. If it works, subsequent clicks on the progress bar will toggle
between Fast and Slow modes. In Fast mode the Spectrum will try to consume
as much CPU time as it can, making the Spectrum run as fast as possible. In
Slow mode if the Spectrum is running over 100% (faster than the
original Spectrum) it will try to slow itself down to be closer to 100%.
The AMDProgressBar class was written by Adam Doppelt.
Comments: Adam Doppelt [email protected]
Comments: Adam Davidson [email protected].
From site: https://github.com/Arlorean/Jasper
A friend of mine originally wrote this emulator in 68000 assembler
in order to play Steve Davies Snooker
on his Atari ST back in 1988.
He then ported it to C. At this point I was keen to play
Match Day with two players,
each on their own Sun Sparcstation 1 that we used at University
at the time in 1991. This was done using X-Windows windows on
different displays while running the emulator as a server process
updating the independent X-Displays.
Time then passed until Sun released their first version of Java in
1996 and I was hooked. I instantly started porting the C code to
Java and created an applet that could eventually run in a browser,
if they were ever supported.
Competition is a great thing. In 1997 Netscape and Internet Explorer
both released browsers with Java applet support baked in. I took a
week vacation and got the emulator up and running and it was slow as
anything, unplayable on the 133Mhz Pentium that I had at the time.
Shortly afterwards though the JIT compilers arrived and suddenly the
applet ran in real-time (most of the time) and we decided to release
it and put up a webpage.
I tried contacting the original firms that wrote some of the games to
ask if they were OK with us putting up a snapshot of their game on our
site for people to play. Contacting companies that wrote software in
the 1982-1986 timeframe was VERY hard. We got some OKs but many just
ignored us. In the end we put up a selection of games and waited to
see what would happen.
Surprisingly we were contacted by Sun Microsystem's lawyers with a
cease and desist letter because we called in Java ZX Spectrum Emulator!
Of all the companies I thought would complain, I didn't expect Sun to
be one of them as they were trying to promote Java heavily at the time.
We had to change the name to Jasper (JAva SPectrum EmulatoR).
The original browser applet APIs didn't really have support for sound
in the way we needed it to emulate the ZX Specturm audio correctly
so we never managed to get sound support in there.
Some other kind users have also uploaded the source code we wrote. Many thanks to them for doing that and keeping our names on the repositories.
From site: https://github.com/Arlorean/Casper
This is a C# port of Jasper (Java Spectrum Emulator)
for .NET Standard (2.0.3) and Windows Forms.
This project is a C# port of Jasper (Java Spectrum Emulator)
for .NET Standard (2.0.3), Windows Forms (on .NET Framework 4.6.1),
and now Blazor Server-side
and Blazor Client-side (using WebAssembly)
on .NET Core 3.1.
In 1982 the hugely popular home computer the Sinclair ZX Spectrum
was created by Clive Sinclair.
It seeded a generation of software developers and I owe my entire career
to that one purchasing decision made for me when I was 12 years old. Thanks Mum!
In 1989 my friend Andrew Pollard
created this emulator in Motorola 68000
assembly code in order to play Steve Davis Snooker
on his Atari ST because he was disappointed in the
Atari ST version.
In 1992 Andrew ported the emulator to C code and we then ported it to X Windows
so we could play Match Day where
each of us played on our own Sun SparcStation
with the emulator essentially running as a backend server.
In 1996 Sun released their first version of the Java Develop Kit with the
tag line write once, run anywhere.
I was completely sold, especially when I saw their Web Browser implementation
HotJava written 100% in Java
with a new Java Applet model
for running Java content inside a Web Browser.
I could see that we could resurrent the emulator and port it to Java.
Yes it would be slow, since the Java Bytecode was interpretted,
but Just-in-Time (JIT) compilation was coming and I knew I couldn't wait.
In 1997 during the browser wars Netscape and Internet Explorer
were both viaing to be the best Web Browser on the market and Java Applet performance
was a differentiator for them. They both came our with JIT support for Java Applets around the same
time and suddenly the Java Spectrum Emulator (Jasper) got a new lease of life.
With JIT it ran in real-time on a 133Mhz Pentium in 16Mb RAM. We even got some
interest from the press, Internet Magazine
ran an article on our website in March 1997:
In 2019 in a bid to learn about Blazor I decided to ressurect the old emulator
code again and port it to C#. I did a Windows Forms reference first so I could
make sure things were working as they should be. Then I moved on to the Blazor
version. I could see the same story of interpretted byte code initially with the
promise of JIT or AOT (Ahead-of-Time) compilation hopefully making the
Blazor WebAssembly version run in real-time once again.
I hit a roadblock straight away. The promise of Blazor was that you
didn't have to write JavaScript, you could create an app, in the browser,
with just C# code. However I couldn't see how to write a canvas object in C#
without all the messy JavaScript interop
which I really didn't want to deal with.
In 2020, Coronavirus
lock-down has given us a lot of time for fun projects so I thought I'd revisit this one.
Blazor (or Razor)
is all about DOM manipulation but the HTML Canvas
doesn't have a DOM, it's all immediate.
However I realized that HTML Scalable Vector Graphics (SVG)
does and so I set about creating a Blazor SVG version of the ZX Spectrum Emulator. Crazy, right?!
Andrew Pollard who created the original emulator code and painstakingly went through each Z80 Mnemonic checking that they functioned as they did in the original Zilog Z80.
Amstrad who now own the ZX Spectrum brand are the owners of the
Spectrum.rom file, which is a copy of the original ZX Spectrum 16K ROM code.
In a post on comp.sys.sinclair they requested
this notice be attached whenever their ROM files were redistributed:
Amstrad have kindly given their permission for the redistribution of their copyrighted material but retain that copyright
The font used on the web page is the ZX82 System Font
by Paul van der Laan.
The Keyboard SVG was derived from a PowerPoint of the ZX Spectrum Keyboard by Magnus Krook.
The Manic Miner game was
written by Matthew Smith
and published by Bug Byte Software Limited in 1983.
From site: http://www.liaquay.co.uk/spectrum/index.html
Jasper - ZX Spectrum Emulator
by Adam Davidson & Andrew Pollard
hacked about by Philip M. Scull
Source for Hacked Jasper. Please note this is not an official Jasper release.
Hacked Jasper Source - Release 1.0
Visit the original jasper www.spectrum.lovely.net
Comments, complaints, congratulations to [email protected]
From site: https://github.com/begoon/jasper
This is a fork of the original version of Jasper 1.1j by
Adam Davidson and Andrew Pollard. Previously it was available at
http://spectrum.lovely.net/, but currently this website is unavailable.
Also this fork includes a fix allowing screen scaling using the pixelScale
variable.
From site: http://www.nedopc.org/forum
В принципе его как такового не было... ;) И его так бы и не было, если бы я его не написал.
Исходники доступны ЗДЕСЬ.
К действию меня сподвиг вот этот довольно давно существующий проект:
Jasper - ZX Spectrum Emulator by Adam Davidson & Andrew Pollard
http://www.liaquay.co.uk/spectrum/index.html
Джентельмены Adam Davidson & Andrew Pollard люди не жадные и исходников
своих не прятали. Исходники и сейчас доступны здесь:
The source code is available online from http://www.odie.demon.co.uk/spectrum/jasp1_1j.zip.
The AMDProgressBar class was written by Adam Doppelt. (специально проверил).
Исходники весьма понятны и очень мне помогли при эмуяции ZX Spectrum на
платформе J2M сотовых телефонов.
Задача очень культурно и неглупо разбита на классы:
Z80.class- эмуляция процессора;Spectrum.class- эмуляцияZX Spectrum;Jasper.class- интерфейс с браузером и др.;AMDProgressBar.class- полоска внизу, позволяет регулировать скорость эмуляции и др., в принципе без неё можно обойтись, поправив коды.
Код HTML совершенно прост:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0046)http://www.spectrum.lovely.net/ --><HTML><HEAD><TITLE>ZX Spectrum Emulator</TITLE>
<META content="text/html; charset=windows-1251" http-equiv=Content-Type>
<META content="MSHTML 5.00.2614.3500" name=GENERATOR></HEAD>
<BODY bgColor=black link=red text=yellow vLink=lightgreen>
<CENTER>
<P><IMG alt="Coloured Line" src="ZX_Spectrum.files/linerain.gif"></P></CENTER>
<CENTER>
<H1>«Специалист» Emulator</H1>
<CENTER>
<P><IMG alt="Coloured Line" src="ZX_Spectrum.files/linerain.gif"></P></CENTER>
<CENTER>
<TABLE>
<TBODY>
<TR>
<TD>
<TABLE border=1>
<TBODY>
<TR>
<TD><APPLET code=Jasper.class height=256 width=384>
<PARAM NAME="snapshot" VALUE="DTE">
<PARAM NAME="sleepHack" VALUE="5">
<PARAM NAME="code" VALUE="Jasper.class">
<PARAM NAME="height" VALUE="256">
<PARAM NAME="width" VALUE="384">
<p>Sorry, this browser is not Java(tm)
enabled.</p><p>It either cannot run Java(tm) applets, or
the running of applets is currently disabled in your
browser.</p></APPLET> </TD></TR></TBODY></TABLE>
<TD align=left vAlign=top><PRE><B> Down To Earth</B>
Left Q,E,T,U,O
Right W,R,Y,I,P
Jump SPACE
</PRE></TD></TR></TBODY></TABLE></CENTER>
<CENTER>
<P><IMG alt="Coloured Line" src="ZX_Spectrum.files/linerain.gif"></P></CENTER>
</BODY></HTML>И у меня всё это запросто работало под IE 5.0 без всяких претензий и с
тройным запасом по скорости.
Этого никак не скажешь о сегодняшних эмуляторах на JS:
- http://code.google.com/p/radio86/
- и вдохновляющий прототип http://jsspeccy.zxdemo.org/ И броузеры - им не броузеры, и скорости эмуляции как у спринтерских черепах...
Поскольку Специалист по идеологии очень близок к ZX Spectrum, мне
хотелось написать его эмулятор самому. По моим прикидкам это всё вполне
осуществимо на основе имеющихся исходников.
Если Ленин хотел реорганизовать рабкрин, то здесь придётся в основном
реорганизовать экран и карту памяти. ;)
Вижу я, что всё по жизни сам не успеешь - возможно кому-то этот проект будет интересен.
PS. Идеи глупо держать под подушкой, там они гниют и тухнут. Хороший слоган!: http://easy-coding.blogspot.com/ Поэтому, кому надо - вот исходники «Специалиста» на Java.
Please scroll up and read Intro.


