Документация эмулятора rk86.ru

Данный документ находится в разработке.

Об ошибках и проблемах можно сообщить через трекер. Вопросы, предложения и замечания можно обсудить на форуме.

Обновления

2021.03.20: возможность делать "моментальные снимки" эмулятора в форме снапшотов и последущей разрузки их обратно

2021.03.14: новая реализация полноэкранного режима через Fullscreen API , эмуляция кнопки РУС/ЛАТ перенесена c ESC на F10, так как теперь ESC используется для выхода из полноэкранного режима

2021.03.11: загрузка локальных файлов

2021.03.10: световое перо

2021.03.09: загрузка внешних файлов в эмулятор

2021.03.01: эмуляция записи на магнитную ленту

2021.01.27: поддержка звука

2021.01.20: возможность сохранения памяти эмулятора в виде файла

2012.10.30: visualizer и режим полного экрана

2012.10.23: эмулятор переехал на отдельный домен rk86.ru

2012.10.22: отладочная консоль

2012.10.14: онлайновый каталог игр и остальных программ со скринами и описаниями


Оглавнение


Загрузка локальных файлов в эмулятор

Селектор справа от надписи "Built-in:" позволяет выбрать файл из встроенного каталога эмулятора. После того, как файл выбран, его можно либо запустить кнопкой "Run", либо загрузить без запуска кнопкой "Load". После загрузки, файл можно запустить командой "G".

Кнопка "Choose file" позволяет выбрать файл с локального диска. После выбора файла справа от кнопки появится имя выбранного файла. После того, как файл выбран, его можно либо запустить кнопкой "Run", либо загрузить в без запуска кнопкой "Load". После загрузки, файл можно запустить командой "G".

Примечание: Если селектор файла, загруженного с локального диска, содержит имя файла, то есть какой-то файл был выбран и загружен, то кнопки "Run" и "Load" будут работать именно с этим файлом, а не с файлом из селектора "Built-in".

Чтобы кнопки "Run" и "Load" работали с файлом из селектора "Built-in" (встроенный каталог эмулятора), необходимо очистить селектор "Local" путем нажатия кнопки "X".

С локального диска можно загружать как двоичные файлы, так и файлы в текстовом формате.

Загрузка внешних файлов в эмулятор

Имя файла может быть либо локальным, либо сетевым.

Локальное имя стоит только из имени и расширения, например, RESCUE.GAM. В этом случае файл "RESCUE.GAM" берется из встроенного каталога файлов эмулятора.

Сетевое имя представляет собой полный URL файла. В этом случае файл скачивается из сети по указанному URL.

Имя вшенего файла необходимо задать в параметре "fle=" URL эмулятора.

Пример запуска эмулятора с локальным именем файла: https://rk86.ru/index.html?file=RESCUE.GAM

Пример запуска эмулятора с полным сетевым именем файла: https://rk86.ru/index.html?file=https://gist.githubusercontent.com/begoon/f4a4e82968d7f581668f218bc17f9ec6/raw/sokoban.bin

Определение адреса загрузки файла и стартового адреса

Если расширение файла ".bin" или отсутсвует, то файл рассматривается без заголовка РК в виде кода E6, начального и конечного адресов. Такой файл загружается с адреса 0000.

Исключение составляют файлы, имя которых начинается с "mon", например, "mon32.bin". Такие файлы загружаются и запускаются с адреса "0x10000 - 'длина файла'". Например, файл "mon32.bin" длиной 0800 (2048) будет загружен и запущен с адреса F800.

Если у файла есть расширениe (.GAM, .PKI, .RK, .RKR), то этот файл разбирается с учетом заголовка РК: байт E6, начальный адрес (2 байта) и конечный адрес (2 байта). Длина вычисляется из начального и конечного адресов. Стартовым адресом является начальный адрес.

Если загружаемый файл является текстовым, то адрес загрузки и стартовый адрес могут быть заданы в тегах заголовка, "start" и "entry" соотвественно.

Текстовые файлы

По умолчанию, загружаемые файлы рассматриваются как двоичные. Если же файл начинается со строки "!#rk86" (байты [35, 33, 114, 107, 56, 54] или [0x23, 0x21, 0x72, 0x6B, 0x38, 0x36]), то далее этот файл рассматривается как шестнадцатеричный дамп.

Например:

    #!rk86
    0000 E6 10 00 20 00 AA BB CC 11 22 33 44 55 66 77 88
    0010 11 22 33 44 55 66 77 88
  

Первые четыре символа каждой строки, показывающие смещение, являются чисто информативными и не используются для разбора. Оставшаяся часть каждой строки рассматривается как последовательность шестнадцатеричных кодов (от 00 до FF). Количество кодов в строке может быть любое. Все коды будут рассмотрены как единая последовательность байт.

В данном примере, это будет последовательность "E6 10 00 20 00 AA BB CC 11 22 33 44 55 66 77 88 11 22 33 44 55 66 77 88".

Строки, начитающиеся с '#', является комментариями и игнорируются при разборе байт.

После преобразования всех строк в последовательность байт, данный файл уже рассматривается как обычный двоичный файл, правила загрузки которого описаны ранее.

Тестовые файл могут иметь специальный тэги, заданные в строках-комментариях.

Например:

    #!rk86 !name=file.rk !start=1000 !entry=1005
    0000 E6 10 00 20 00 AA BB CC 11 22 33 44 55 66 77 88
    0010 11 22 33 44 55 66 77 88
  

Теги можно задавать на разных строках.

Тег "!name" задает имя загружаемого файла. Если тег не задан, что имя файла берется из URL. Некоторые хостинги, например, pastebin.pl, не позволяют контролировать URL, поэтому имя (и расширение) файла в окончании URL может быть произвольным, но имя файла, а точнее его расширение, определяют типа файла: либо двоичный, если расширение ".bin" или пустое, либо файл в формате ленты РК. Тип файла определяет, как файл будет разобран и загружен. Тег "!name" позволяет задать имя и расширение файла вне зависимости от URL.

Тег "!start" позволяет задать адрес загрузки файл для двоичных файлов (файлов с расширениям ".bin" или пустым расширением). Для файлов в формате ленты РК данный тег значение не имеет. Адрес загрузки файлов в формате РК всегда берется из заголовка файла.

Тег "!entry" позволяется задать адрес запуск файла. Данный тег работает и для двоичных файлов, и для файлов формате ленты РК.

Примеры загрузки тестовых файлов из интернета

Сокобан

https://rk86.ru/index.html?file=https://gist.githubusercontent.com/begoon/f4a4e82968d7f581668f218bc17f9ec6/raw/sokoban.bin

исходный текст загружаемого файла

Примечание: Файл sokoban.bin является двоичным, то есть не имеет заголовка ленты РК. Имя файла "sokoban.bin" сохранено в URL хостинга, поэтому файл распознается как двоичный и использование тега "name" в данном случае не является необходимым.

Volcano

https://rk86.ru/index.html?file=https://gist.githubusercontent.com/begoon/e76c4446a4fd4151f7557191bf4faee6/raw/volcano.rkr

исходный текст загружаемого файла

Примечание: В данном случае файл "volcano.rkr" является файлом в формате ленты РК, поэтому его расширение ".rkr" обязательно. Хостинг сохранил имя "volcano.rkr", поэтому для корректной загрузки файла использование тега "!name=volcano.rkr" не является необходимым, хотя и задано для примера.

Показательным использованием тегов может быть загрузка Монитора mon32x4.bin.

Это расширенный Монитор, которые занимает не два килобайта с F800 по FFFF, а четыре: с F000 по FFFF. Стартовым адресом этого монитора должен оставаться адресс F800.

Для загрузки этого Монитора через текстовый режим, необходимые задать следующие теги:

    #!rk86 !name=mon32x4 !start=f000 !entry=f800
  

https://rk86.ru/index.html?file=https://gist.githubusercontent.com/begoon/879cee0cbe6ecca7117a840bf45d8901/raw/mon32x4.bin

исходный текст загружаемого файла

Использование CORS прокси

Некоторые хостинги не позволяют скачивать выложенные файлы со страниц, которые пытаются скачать файл с помощью javascript. Это так называемая CORS защита.

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

Например, если воспользоваться cors-filter.herokuapp.com, то путь к файлу в адресе эмулятора будет такой:

https://rk86.ru/index.html?file=https://cors-filter.herokuapp.com/https://gist.githubusercontent.com/begoon/e76c4446a4fd4151f7557191bf4faee6/raw/volcano.rkr

Эмуляция записи на магнитную ленту

Эмулятор отслеживает обращения к порту 8002 в режиме вывода. Этот порт используется в РК для записи данных на ленту. Если начинается серия команд записи в этот порт, эмулятор запоминает результаты, и когда серия заканчивается (команды записи прекращают поступать), эмулятор выгружает результаты записи в виде файла.

Например, если в Мониторе выполнить команду "OF800,F8FF", после после окончания вывода первых 256 байт Мониторе на ленту, эмулятор сохранит эти 256 байты в виде файла rk86-tape.bin.

Эмуляция звука

Эмуляция звука работает через Web Audio API. Эмулятор ловит обращения на команды EI/DI и так рассчитывает период звука. Расчеты ведутся по тикам i8080, то есть частоты вычисляются на 100% точно, и от плавающей скорости эмулятора ничего не зависит.

Звук проверен на Chrome 88+, Firefox 85+, Safari 14+, Opera 74+.

Cохранение памяти эмулятора в виде файла

Сохранить текущее состояние памяти эмулятора можно двумя способами:

Visualizer

Visualizer показывает исполняемые в данный момент команды процессора. Запускается кнопкой "V". Для полного выключения вижуалайзера надо полность перезагрузить страницу эмулятора.

Режим полного экрана

Кнопка "Full screen" переводит эмулятор в режим полного экрана. Выход из режима полного экрана - ESC.

Полноэкранный режим проверен на Chrome 88+, Firefox 85+, Safari 14+, Opera 74+.

Консоль

Описание команд отладочной консоли находится в разработке

Как взламывать игры в эмуляторе

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

Для сравнения файлов можно, например, воспользоваться программой cmp.py

Как компилировать программы для РК локально и запускать на эмуляторе

Пример простого цикла разработки.

Допустим, есть ваша программа rk86_example.asm:

    org 0
    
    lxi h, msg
    call 0f818h
    jmp 0f86ch
    
    msg db 'EXAMPLE', 0dh, 0ah, 0
  

Создаете репозиторий rk86-example.

Кладете туда исходник и создаете Makefile:

    TARGET=rk86_example
    RUN=https://rk86.ru/index.html?file=
    
    all: build hex
    
    build:
        zasm --asm8080 -l0 $(TARGET).asm
    
    hex:
        python rk86_hex.py -i $(TARGET).rom -o $(TARGET).bin
    
    run:
        open $(RUN)https://raw.githubusercontent.com/begoon/rk86-example/main/$(TARGET).bin
    
    clean:
        -rm $(TARGET).rom
  

Далее цикл разработки выглядит так:

Для данного "Makefile" требуется ассемблер zasm и программа rk86_hex.py

Как собрать zasm

Проверялось на Mac.

    cd your/development/folder
    git clone git@github.com:Megatokio/zasm.git
    git clone git@github.com:Megatokio/Libraries.git
    cd zasm
    make
    ./zasm
  

Должно вывести что-то вроде:

    zasm - 8080/z80/z180 assembler (c) 1994 - 2021 Günter Woigk.
    version 4.4.8, 2021-03-09, for Unix-MacOSX.
  

Световое перо

Световое перо эмулируется через мышь. Положение мыши на экране задает положение пера. Левая кнопка мыши определяет, активно перо или нет.

Чтение из ячейки С001 в бите 4 (маска 0001000) возвращает 1, если перо активно (леваа кнопка мышь нажата), 0 в противном случае.

Запись 60h в ячейку С001 активизирует считывание положения пера. Последующие две операции чтения из ячейки C000 возвращают сначала положения пера по горизонтали (от 0 до 77), а потом положение по вертикали (от 0 до 29).

Снапшоты

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

Снапшот сохраняет состояние процессора, памяти (полные 64КБ), клавиатуры (состояние всех клавиш, включая РУС/ЛАТ, УС и СС), экрана (размер экрана, адрес экранной области, положение курсора).

Снапшот сохраняется в стандартном формате JSON.

Поля "start" и "end" являются чисто информативными и не используются при загрузке снапшота. Секция "memory" состоит из строк по 16 байт. Адресное поле задает адрес загрузки данной строки в память. Не обязательно все возможные адреса должны присутствовать. Если снапшот создается вручную, можно указывать только используемые фрагменты памяти.

Кнопка "Snapshot" сохраняет снапшот на локальный диск. Загрузка снапшота производится либо через селектор выбора локального файла, либо из сети через параметр "file=" в адресной строке эмулятора.

Имитация клавиатурных нажатий

Снапшот позволят задать последовательность нажатий на кнопки клавиатуры, которая будет выполнена сразу после загрузки снапшота.

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

Секция "boot/keyboard" имеет следующий формат. Пример ниже показывает сценарий, когда после загрузки снапшота происходит:

Замечание: в тексте ниже есть комментарии, но они приведены тут только для примера. В реальном файле их не должно быть.

Количество секций в списке "keyboard" неограничено.

    "keyboard": [
      {
        "keys": [               ; Секция "keys" задает последовательность клавиш
          68,                   ; "d"
          188,                  ; ","
          70,                   ; "f"
          70,                   ; "f"
          70                    ; "f"
        ],
        "duration": 100,        ; 100мс на нажание и 100мс отпускание каждой клавиши
        "action": "press"       ; нажать/подождать/отпустить/подождать
      },
      {
        "keys": [               ; данная секция может быть объединена
          13                    ; с предыдущей и приведена в виде отдельной
        ],                      ; секции для примера
        "duration": 100,        ; 100мс на нажание и 100 на отпускание каждой клавиши
        "action": "press"       ; нажать/подождать/отпустить/подождать
      },
      {
        "keys": 0,              ; для секции типа "pause" данное поле игнорируется
        "duration": 300,        ; длительность пауза 100мс
        "action": "pause"       ; пауза
      },
      {
        "keys": [               ; данная секция показывает возможность нажатия клавиш
          17,                   ; "УС"
          67                    ; "c"
        ],
        "duration": 20,         ; 20мс задержки после нажатий всех клавиш
        "action": "down"        ; последовательно нажать клавиши
      },
      {
        "keys": [               ; данная секция показывает возможность отпускания клавиш
          67,                   ; "c"
          17                    ; "УС"
        ],
        "duration": 100,        ; 100мс задержки после отпускания всех клавиш
        "action": "up"          ; последовательно отпустить клавиши
      }
    ]
  

Пояснения по полю "action":

Коды клавиш в "keys" являются стандартными кодами PC, которые можно узнать, например, на сайте keycode.info. Кнопка эмулятора "About/Keyboard" показывает подсказку по соответствию клавиш PC и РК.

Примеры снапшотов


Конец документа