Last active
May 13, 2020 10:07
-
-
Save Alikberov/4c5da210ff1a862e6469e403b95767de to your computer and use it in GitHub Desktop.
x80 Emulator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<meta http-equiv='refresh' content='50000' /> | |
<title>x80 - Rebused Instruction Set Computer</title> | |
<!-- | |
- 1 1 1 3 1 1 1 | |
2 5 1 1 1 1 1 1 | |
2 2 5 1 1 1 1 1 | |
2 2 2 5 1 1 1 1 | |
3 2 2 2 7 1 1 1 | |
2 2 2 2 2 6 1 1 | |
2 2 2 2 2 2 6 1 | |
2 2 2 2 2 2 2 6 | |
- - - - - - - - - - - - - - - - | |
- - - - - - - - - - - - - - - - | |
- - - - - - - - - - - - - - - - | |
- - - - - - - - - - - - - - - - | |
0 0 0 0 0 0 0 0 0 0 4 5 6 7 1 2 | |
0 0 0 0 0 0 0 0 0 0 4 5 6 7 1 2 | |
0 0 0 0 0 0 0 0 0 0 4 5 6 7 1 2 | |
0 0 0 0 0 0 0 0 0 0 4 5 6 7 1 2 | |
1010 100 | |
1011 101 | |
1100 110 | |
1101 111 | |
1110 | |
1111 | |
Пользовательские операции | |
========================= | |
Контекст задачи имеет область статической памяти под хранение кодов инструкций | |
программируемых приложением, с возможностью определить до десяти команд в семь | |
операций каждая с максимальной скоростью выполнения до одной команды в 1 такт. | |
Для линейного определения пользовательской инструкции имеется особая операция, | |
трюковая комбинация WAIT+FIX, которыми подготавливается сегмент буфер, ячейкам | |
определённой цепочки присваивается соответствующая маска к оперативному вводу. | |
-- | |
B8 FE|WAIT __ .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F ______ | |
44 F7 |INT 47 |70:?? ?? FF FF FF FF FF FF FF FF 00 00 00 00 00 00|SKIP 4 | |
04 |MOV AL,[BX]|70:?? ?? 04 00 FF FF FF FF FF FF 00 00 00 00 00 00|3 ticks | |
70 |MOV [BX],DL|70:?? ?? 04 00 70 00 FF FF FF FF 00 00 00 00 00 00|2 ticks | |
47 |MOV DL,AL |70:?? ?? 04 00 70 00 47 00 FF FF 00 00 00 00 00 00|1 tick | |
77 CB |ADD BX,DX |70:?? ?? 04 00 70 00 47 00 CB E0 00 00 00 00 00 00|1 tick | |
______________________________________________________________________________ | |
============================================================================== | |
Представляемая концепция процессорного устройства базируется на переработанной | |
системе команд процессора i8080 с полной утратой совместимости уровня машинных | |
команд и с частично достигнутой совместимостью с ассемблером процессора i8086. | |
______________________________________________________________________________ | |
Таблица системы команд процессора была расчитана под интуитивное восприятие на | |
принципе ассоциативных предпосылок субъективного уровня с учитыванием реальной | |
возможной частоты использования различных инструкций в построениях алгоритмов. | |
Некоторые из инструкций, в силу морального устаревания и потерей актуальности, | |
были изначально исключены или получили более комплексный код редкой комбинации | |
обычных команд, чтобы не засорять таблицу и сохранять перспективу наращивания. | |
Регистр статуса процессора был переорганизован и флажки АЛУ получили частичную | |
связь на дешифратор команд с возможностью управлять периодом выполнения команд | |
для явного объявления условно реактивных и ленивых участков программного кода. | |
______________________________________________________________________________ | |
Инструкции: Система команд процессора | |
===================================== | |
Дешифратор команд имеет 18 разрядов, имеющий условно разделённо-группированных | |
восемь проименованных шин и каждая из них имеет своё назначение для дешифрации | |
всех поддерживаемых архитектурой инструкций с перспективой явного наращивания. | |
Всего набор команд представляется таблицей команд с восемью слоями и имеющих в | |
своей структуре до восьми подслоёв, половина из которых доступна лишь основной | |
программе высшего уровня привелегий, выполняющей роль ядра операционной среды. | |
В состав процессора входит сверхоперативный контекстный файл с ёмкостью до 128 | |
страниц, каждая из которых вмещает по 256 слов и обеспечивает сохранность всех | |
значений регистров общего назначения независимо для каждой страницы контекста. | |
Страница контекста имеет до 160 слов хранения операций реактивного исполнений, | |
вызываемых трюковым способом из любого места программы и требующих как минимум | |
от 1 такта на своё выполнение, позволяющих организовывать комплексные команды. | |
______________________________________________________________________________ | |
Регистры Общего Назначения (РОН) | |
================================ | |
Каждой исполняемой задаче доступен собственный независимый набор регистров, из | |
которых можно выделить несколько особенных, имеющих механизмы контроля ошибок, | |
автоматического инкремента/декремента и организации ленивых вычислений/циклов. | |
Так, регистры BH:BL / CH:CL / DH:DL составляют набор регистровых пар BX/CX/DX, | |
позволяющих организовывать косвенную и индексную адресацию для доступа к любой | |
из всех ячеек предоставляемой операционной средой памяти в оперативном режиме. | |
Несколько иначе организован регистр аккумулятора AL, имеющий условную половину | |
AH(FX) косвенно-условной доступности, позволяющего обеспечивать условные петли | |
и безусловные циклы, а также и опциональные линейные селекторы или вычисления. | |
________________ _________________ _________________ _________________ | |
| AX | | BX | | CX | | DX | | |
+---------+------+ +--------+--------+ +--------+--------+ +--------+--------+ | |
| AH(FX) | AL | | BH | BL | | CH | CL | | DH | DL | | |
+----+----+------+ +--------+--------+ +--------+--------+ +--------+--------+ | |
| FH | FL \ | |
| == | == \________ | |
|0:--|0000: ------- \____________________________________________ | |
|1:BH|0001:-- -- ZF # Zeroed result | | |
|2:CH|0010:-- CF -- # Carry Flag | | |
|3:DH|0011:-- CF ZF # Zero with Carry | | |
|4:AL|0100:PF -- -- # Odd Parity Flag | | |
|5:BL|0101:{SKIP FH}# Skip mode (upto x8..x15 times/x1..x7 times) | | |
|6:CL|0110:PF CF -- # Odd Parity with Carry | | |
|7:DL|0111:{SKIP FH}# Skip mode (upto x8..x15 times/x1..x7 times) | | |
|8:--|1000:SF -- -- # Signed result | | |
|9:x1|1001:{LOOP FH}# Loop mode (register counter / x1..x7 times) | | |
|A:x2|1010:SF CF -- # Signed result with Carry | | |
|B:x3|1011:{LOOP FH}# Loop mode (register counter / x1..x7 times) | | |
|C:..|1100:SF PF -- # Signed result with odd Parity | | |
|D:BX|1101:{ ----- }# | | |
|E:CX|1110:SF PF CF # Signed result with odd Parity and Carry | | |
|F:DX|1111:{WAIT FH}# Wait mode (register counter / x1..x7 times) | | |
+----+------------------------------------------------------------ | |
______________________________________________________________________________ | |
Регистровые указатели | |
===================== | |
Указатель инструкций IP имеет опциональный указатель JP, у стековых указателей | |
SP и BP младший бит имеет опциональное назначение для отслеживания критических | |
ситуаций или управления автоматическим инкрементом/декрементом значений SI/DI. | |
+----------------+ +---------------+-+ +---------------+-+ +-----------------+ | |
|______ IP ______| | SP /EF| | BP /FF| |_____ SI/DI _____| | |
| \__/ | | +-----+ / | | +-----+ / | | \++|--/ | | |
| JP | | /Error-Flag| | /Fault-Flag| |Auto-Inc|Auto-Dec| | |
+----------------+ | / /increment| +-----+-----------+ +-----------------+ | |
+----+------------+ | |
______________________________________________________________________________ | |
Флаги: Регистр состояния процессора/АЛУ | |
======================================= | |
Регистр состояния FX является старшим AH в AX, разделён на два ниббла FH и FL. | |
Старшим нибблом хранится индекс опционального регистра/указателя или итерации. | |
Младшим нибблом отражается комбинация режима дешифратора инструкций с флажками | |
результата действий команд АЛУ. Правилами постулатов исполнения вычислительных | |
операций исключаются вариации нуля нечётного паритета или отрицательного нуля. | |
Ноль нечётного паритета запрещает регистрирование результата выполнения потока | |
дешифрируемых инструкций на период с декрементацией опционального регистра или | |
итерации в старшем ниббле, позволяя опционально пропускать цепочку инструкций. | |
Отрицательный ноль приостанавливает считывание следующих инструкций, организуя | |
цикл на период с полной или условной декрементацией опционального регистра или | |
итерации в старшем ниббле, позволяя опционально ставить цикл и режим ожидания. | |
Через режим условного ожидания организуется возможность доступа к интерфейсным | |
устройствам ввода/вывода или внешней шине состояния сигналов событий ресурсов, | |
чтобы описывать алгоритмы своевременной обработки всех допускаемых прерываний. | |
______________________________________________________________________________ | |
Обработка программных и аппаратных прерываний | |
============================================= | |
Архитектурой процессора не предусматривается возможность оперативной реакции в | |
режиме реального времени на любые внешние сигналы от периферии с генерацией по | |
их запросам определённых прерываний на обращение к соответствующим процедурам. | |
После включения ядра процессора и аппаратного сброса, управление передаётся на | |
нулевой контекст программы по вектору 0xFF00 с возможностью прямого доступа ко | |
всем ресурсам среды системы, всем контекстным файлам и к регистрам управления. | |
В обязанности кода основного процесса входит необходимость настройки периферии | |
и соответствующего реагирования на любые внешние сигналы с её стороны, а также | |
организации поддержки интерфейса с другим прикладным программным обеспечением. | |
Процесс ядра системы не имеет возможность непосредственного опроса внешних шин | |
и считывания их состояния без организации исполнения кода прикладного уровня с | |
поддержанием его нормального исполнения и надлежащего предоставления ресурсов. | |
______________________________________________________________________________ | |
Доступ к внешним устройствам и регистрам контекстного файла | |
=========================================================== | |
Системой команд не предусматриваются непосредственные команды доступа к портам | |
ввода/вывода для взаимодействия с устройствами периферии или доступа к ячейкам | |
контекстного файла и управляющим регистрам представления контекстной проекции. | |
Подобные операции находятся за пределами области задач прикладного уровня и не | |
засоряют таблицу команд как специализированные инструкции, используемые крайне | |
редко в зонах временной необходимости сервисных процедур операционной системы. | |
Процессором имеется достаточное количество префиксов для организации трюкового | |
достижения необходимых системных ресурсов в рамках кода операционной системы и | |
ограниченного контролируемого прикладного трюкового доступа к нужным ресурсам. | |
В момент попытки доступа приложения к порту ввода/вывода, исполнение программы | |
временно приостанавливается и управление передаётся ядру системы с загрузкой в | |
историю регистра-приёмника индекса порта, байта данных и режимом доступа в CF. | |
______________________________________________________________________________ | |
Регистр селектора контекста (CS - Context Select Register) | |
========================================================== | |
Для непосредственного доступа к контексту любой имеющейся прикладной задачи на | |
уровне системного процесса доступен регистр CS, служащего переключателем задач | |
в системной среде и управляющего привелегиями для текущего активного процесса. | |
Базовая реализация процессора поддерживает от трёх независимых контекстов, под | |
которыми может выполняться непосредственно код системного ядра, код диспетчера | |
системных ресурсов с аппаратным интерфейсом и другой код прикладной программы. | |
Контекст ядра всегда имеет индекс с базой 0, диспетчерам ресурсов определяются | |
контексты с индексами от 127 до 100 в сторону уменьшения номера, тогда как все | |
приложения индексируются контекстами от 1 до 99 в сторону возрастания номеров. | |
------------------------------------------------------------------------------ | |
00000000 0 :База(0) - Системный код с высоким уровнем привелегий. | |
0XXXXXXX 1-99 :База(1) - Прикладной код с низким уровнем привелегий. | |
011XXXXX 100-127:База(127)-Средний уровень диспетчера системных ресурсов. | |
1XXXXXXX 128-255:Зеркала контекста №0 под высоким системным уровнем привелегий | |
______________________________________________________________________________ | |
Счётчик выдержки исполнения прикладного кода (TX - Ticks Counter: TL & TH) | |
=========================================================================== | |
Старший бит регистра CS управляет блокировкой прохождения тактов к регистру TX | |
и на уровне приложений ведётся обратный отсчёт, окончание которого установит в | |
CS бит блокировки счёта с переключением контекста в высокий системный уровень. | |
Если при переключении с ядра к приложению счётчик TX был обнулён, ни один байт | |
прикладного кода не будет выполнен и управление получит вновь ядро с возвратом | |
кода состояния внешней периферийной шины через аккумклятор и флаг переноса CF. | |
Если в момент переключения на контекст приложения счётчик TX готов отсчитать 1 | |
такт, будет выполнена одна единственная операция приложения и управление снова | |
получит ядро, что позволяет организовывать пошаговый режим отладчика программ. | |
______________________________________________________________________________ | |
Математические вычисления | |
============================================================================== | |
Операции умножения/деления изначально отсутствуют в системе команд процессора, | |
но достигаются трюковым способом посредством режима цикла условного ожидания с | |
элементарной арифметической операцией с пошаговыми приближениями к результату. | |
Если вычислительная периферия в системе присутствует и поддерживает инструкции | |
аппаратно, итеративного испольнения цикла не будет и он будет линейно прерван, | |
позволяя программно определить наличие соответствующей поддерживающей системы. | |
______________________________________________________________________________ | |
Расширитель опции вызова подпрограмм | |
============================================================================== | |
Совмещение команд обращения к подпрограммам с префиксами инструкционного цикла | |
переключает дешифратор команд на пропуск опционального числа операций на входе | |
в подпрограмму, позволяя выбирать из подфункций вызываемого процедурного кода. | |
..::: Context File Layout :::::::::::::::::::::::::::::::::::::::::::::::::::: | |
.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F | |
00:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 0:Up to 7 opcodes | |
10:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 1:---"--- | |
20:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 2:---"--- | |
30:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 3:---"--- | |
40:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 4:---"--- | |
50:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 5:---"--- | |
60:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 6:---"--- | |
70:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 7:---"--- | |
80:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 8:---"--- | |
90:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 9:---"--- | |
A0:AL>>LO>>Стек истории --|AH>>HI>> ++ .. -- -- --|AX-Stack | |
B0:BL>>LO>>модификации- --|BH>>HI>> ++ .. -- -- --|BX-Stack | |
C0:CL>>LO>>всех РОН- -- --|CH>>HI>> ++ .. -- -- --|CX-Stack | |
D0:DL>>LO>> ++ .. -- -- --|DH>>HI>> ++ .. -- -- --|DX-Stack | |
E0:SP>LO/BP>LO/SI>LO/DI>LO|SP>HI/BP>HI/SI>HI/DI>HI|SP/BP/SI/DI-Stack | |
F0:IP>>LO>> ++/.. ../JP.LO|IP>>HI>> ++/.. ../JP.HI|IP/JP | |
+0:CS -- -- -- -- -- TL.TH |Control Registers | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;; Примерная трюковая цепочка ;;; Макрос псевдонима мнемоники с описанием ;;; | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;;;;;; MOV [0],DL ;;; Запись индекса проекции контекста | |
HLT DL ; Указываем регистр источника индекса | |
WAIT ; Приступаем к ожиданию системной операции | |
HLT ; Инструкция работает лишь в проекции системы | |
;;;;;;; MOV DL,[0] ;;; Чтение индекса проекции контекста | |
HLT ; Выбираем индекс считываемого регистра | |
WAIT ; Приступаем к ожиданию системной операции | |
HLT DL ; Считываем в регистр индекс проекции | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;;;;;; MOV DL,[DL] ;;; Читаем байт файла контекста | |
HLT DL ; Указываем принимающий регистр | |
WAIT ; Готовимся читать данные | |
HLT DL ; В регистр DL | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;;;;;; MOV [DL],AL ;;; Пишем байт в файл контекста | |
HLT DL ; Указываем регистр выбора ячейки | |
WAIT ; Готовимся писать данные | |
HLT AL ; в ячейку DL из регистра AL | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;;;;;; MOV DL,[1] ;;; Читаем байт регистра контроля | |
HLT 1 ; Указываем индекс считываемого регистра | |
WAIT ; Готовимся читать данные | |
HLT DL ; Указываем принимающий регистр | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;;;;;; MOV [1],DL ;;; Пишем байт в регистр контроля | |
HLT DL ; в ячейку из регистра DL | |
WAIT ; Готовимся писать данные | |
HLT 1 ; Указываем регистр контроля | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;;;;;; IN DH ;;; Читаем данные с порта | |
HLT 1 ; Вибираем индекс регистра BH с индексом порта | |
WAIT ; Готовимся читать данные | |
HLT 1 ; В регистр BH | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;;;;;; OUT [DH],CH ;;; Пишем данные в порт | |
HLT 1 ; Выбираем регистр BH с записуемым байтом | |
WAIT ; Готовимся писать данные | |
HLT 2 ; в порт CH из регистра BH | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;; Примеры инструкций с расширением их возможностей опциональными битами ;;;; | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
MOV AL,[DI+1] ; Считывает данные с базовым смещением, | |
; работает во всех стандартных режимах (EF==0) | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
MOV AL,[DI+1] ; Считывает данные без смещения, но производит | |
; пост-инкремент указателя, лишь когда (EF==1) | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;; Примеры трюковых цепочек для выполнения вычислений с проверкой ускорения ; | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;;;;;; MUL AL,CH,CL ; Умножение с суммированием: AL+=CH*CL | |
HLT CL ; Указываем регистр множителя CL | |
WAIT ; Готовимся к вычислению | |
ADD AL,CH ; Приближаемся к результату через множимое CH | |
AND CL,CL ; Проверка участия регистра множителя в цикле | |
JZ .software ; Если он обнулён - аппаратной поддержки нет | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;;;;;; DIV AL,CH,CL ; Деление: CL=255 :: CL-=AL/CH | |
HLT CL ; Указываем регистр дополненного частного CL | |
WAIT ; Готовимся к вычислению | |
SUB AL,CH ; Приближаемся к результату через делитель CH | |
JC .software ; Если признак CF - аппаратной поддержки нет | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;; Примерный набросок кода запуска управляющего ядра операционной системы ;;; | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
ORG 0xFEFB ; Следующий макрос занимает 5 байтов | |
KERNEL: ;;;;;;;;;;;;;;;;;;;;;;;;; Переключатель контекста на прикладной код | |
.yield: MOV [0],AL ; Макрос переключения контекста регистром CR0 | |
;HLT AL ; Регистр AL указывает контекст/принимает код | |
;WAIT ; JMP $ - Переход в условный цикл | |
;HLT 0 ; HLT - Привелегированная операция для CR[0] | |
;;;;;;;;;;;;;;;;;;;;;;;;; | |
; Здесь располагается селектор с пропуском до 7 инструкций и передачей | |
; управления соответствующей ситуации процедуре | |
.body: ;;;;;;;;;;;;;;;;;;;;;;;;; Тело обработчика прерываний - адрес : FF00h | |
JMP .overhead ; Запрос к стандартному API | |
JMP .acclaim ; Обращение к программным прерываниям INT 0-79 | |
JMP .buffer ; Буферная зона - прослойка диспетчера памяти | |
JMP .context ; Диспетчер переключения контекстов процессов | |
JMP .device ; Запрос ко внешнему устройству ввода/вывода | |
JMP .error ; Обработчик программных/аппаратных ошибок | |
JMP .force ; Внешние форсированные события/прерывания | |
JMP .garret ; Загрузочная область поверхностного уровня | |
.context: ;;;;;;;;;;;;;;;;; Тело диспетчера контекста | |
XOR AL,AL ; Подготавливаем регистр к чтению регистра CR | |
HLT AL ; Определяем его как приёмник | |
WAIT ; Переход в условный цикл | |
HLT 7 ; Считываем содержимое CR[7] в AL | |
;;; ;;; ;;; ; Оперативные действия с контекстом | |
MOV AL,0x01 ; Выставляем индекс выбираемого контекста | |
CMP AL,AL ; Сброс флага переноса CF | |
CMC ; Устанавливаем флаг, если требуется протокол | |
JMP .yield ; | |
.device: ;;;;;;;;;;;;;;;;; Тело диспетчера периферии | |
HLT___________________________________________________________________________ | |
00 :HLT ;Останов. Команда не работает на системном уровне | |
nn 00 :HLT Rn ;Захват регистра за опциональный | |
nn nn :HLT Pn/n ;Захват указателя или числового индекса | |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
MOV___________________________________________________________________________ | |
yx :MOV Rx,Ry ;Пересылка между регистрами | |
44 yx :MOV Px,Py ;Пересылка между указателями | |
Ax ii:MOV Rx,i ;Загрузка непосредственной константы в регистр | |
nn Ax ii:MOV Rx,[Pn+i] ;Загрузка с базовым смещением | |
nn Bx ii:MOV [Pn+i],Rx ;Выгрузка в базовое смещиние | |
r# nn Bx ii:MOV [Pn+=i],Rx ;Выгрузка по смещению и итерационным шагом | |
w# xx :MOV Rx,[Rx] ;Чтение с контекста | |
w# yx :MOV [Rx],Ry ;Запись в контекст | |
w# nn nn :MOV Rw,[n] ;Чтение управляющего регистра | |
w# ?? 00 :MOV [?],Rw ;Запись в управляющий регистр | |
w# 00 :MOV [0],Rw ;Переключение контекста | |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
JMP___________________________________________________________________________ | |
B8 ii:JMP $+i ;Ветвление с относительной адресацией -128..+127 | |
nn B8 ii:JMP $+n+i ;Ветвление с относительной адресацией -1024..+1023 | |
nn 8m ii FF:JMP n+m+i ;Ветвление с абсолютной адресацией 0..65535 | |
w# 00 :JMP Rw ;Переключение контекста | |
------------------------------------------------------------------------------ | |
WAIT__________________________________________________________________________ | |
B8 FE:WAIT ;Ветвление с замыканием в режим условного ожидания | |
nn nn B8 FE:WAIT n ;Пример режима ожидания с указанием длительности | |
nn 00 B8 FE:WAIT Rn ;Пример режима ожидания с указанием счётчика | |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
______________________________________________________________________________ | |
r# - означает префикс повтора командами LOOP n/Rn/[Rn] | |
w# - означает префикс ожидания командами WAIT n/Rn | |
------------------------------------------------------------------------------ | |
ПРИМЕРЫ_______________________________________________________________________ | |
44 00 B8 FE 55 55:MOV AL,[5] ;Чтение управляющего регистра | |
44 00 B8 FE 55 00:MOV [5],AL ;Запись в управляющий регистр | |
44 00 B8 FE 00 :JMP AL ;Переключение на контекст задачи | |
44 FС 22 B6 03 :MOV [SI+=3],CL ;Запись с итерационным шагом счётчика AL | |
44 FC 22 A6 7D :MOV CL,[BX+2*AL];Чтение с двойной шириной по базе | |
[DI+0..99] .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
[DI+100..127] AL BL CL DL BH CH DH DX CX DX | |
+100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 | |
................................................. 1*BX 1*BH 1*CH 1*DH 1*AL 1*BL 1*CL 1*DL 1*CX 1*DX 2*BX 2*BH 2*CH 2*DH 2*AL 2*BL 2*CL 2*DL | |
0:+0 | |
1:+1 | |
2:+2 | |
3: | |
4: | |
5: | |
6: | |
7: | |
8: | |
9: | |
10:BX*1 | |
11:BH*1 | |
12:CH*1 | |
13:DH*1 | |
14:AL*1 | |
15:BL*1 | |
16:CL*1 | |
17:DL*1 | |
18:CX*1 | |
19:DX*1 | |
20:BX*2 | |
21:BH*2 | |
22:CH*2 | |
23:DH*2 | |
24:AL*2 | |
25:BL*2 | |
26:CL*2 | |
27:DL*2 | |
28:CX*2 | |
29:DX*2 | |
30:-2 | |
31:-1 | |
;;;;;;; IN DH | |
WAIT | |
MOV DH,[BX] | |
;;;;;;; OUT DH,DL | |
WAIT | |
MOV DH,DL | |
;;;;;;; MOV AL,[AL] | |
WAIT | |
MOV AL,[ | |
00000000 0 : | |
0XXXXXXX 1-99 : | |
011XXXXX 100-127: | |
1XXXXXXX 128-255:Зеркала контекста №0 под высоким системным уровнем привелегий | |
00000000|Kernel Mode Execution | |
0xxxxxxx|Kernel Mode Access | |
10000000| | |
1xxxxxxx|User Mode Execution | |
--> | |
<!-- | |
span.CPU_Group__ { | |
background-color: #012; | |
cursor : pointer; | |
} | |
span.CPU_Group_A { | |
background-color: #771; | |
} | |
span.CPU_Group_B { | |
background-color: #751; | |
} | |
span.CPU_Group_C { | |
background-color: #411; | |
} | |
span.CPU_Group_D { | |
background-color: #551; | |
} | |
span.CPU_Group_E { | |
background-color: #161; | |
} | |
span.CPU_Group_F { | |
background-color: #157; | |
} | |
--> | |
<!-- | |
span.CPU_Group__ { | |
background-color: #012; | |
cursor : pointer; | |
} | |
span.CPU_Group_A { | |
background-color: blue; | |
} | |
span.CPU_Group_B { | |
background-color: brown; | |
} | |
span.CPU_Group_C { | |
background-color: cyan; | |
} | |
span.CPU_Group_D { | |
background-color: red; | |
} | |
span.CPU_Group_E { | |
background-color: #161; | |
} | |
span.CPU_Group_F { | |
background-color: magenta; | |
} | |
--> | |
<!-- | |
A:ALU | |
B:Branch | |
C:Control | |
D:Dubbed register pair | |
E:Stack | |
F:Flip-flop move | |
--> | |
<style> | |
span[class^=CPU_Group_] { | |
border : none; | |
color : brightgreen; | |
cursor : default; | |
margin : 0px 0px 0px 0px; | |
padding : none; | |
} | |
span.active { | |
text-decoration : overline underline; | |
} | |
span.halted { | |
color : magenta; | |
cursor : cell; | |
} | |
span.CPU_Group__ { | |
background-color: #012; | |
cursor : pointer; | |
} | |
span.CPU_Group_A { | |
background-color: #772; <!-- ALU - AND/XOR/CMP 772--> | |
} | |
span.CPU_Group_B { | |
background-color: #764; <!-- Branching - Ccnd/Jcnd 752--> | |
} | |
span.CPU_Group_C { | |
background-color: #888; <!-- Controls - HLT/NOP 888--> | |
} | |
span.CPU_Group_D { | |
background-color: #663; <!-- Dubbed/Pair - INC/DEC 552--> | |
} | |
span.CPU_Group_E { | |
background-color: #363; <!-- Xchg/Stack - POP/PUSH 262--> | |
} | |
span.CPU_Group_F { | |
background-color: #367; <!-- Flip-Flop - MOV 257--> | |
} | |
span.CPU_Group_X { | |
background-color: #437; <!-- X-Code - --- 437--> | |
} | |
span.CPU_Group_Z { | |
background-color: #444; <!-- X-Code - --- 437--> | |
} | |
body { | |
background-color: black; | |
color : lightgreen; | |
padding : 0 0 0 2; | |
margin : 0 0 0 0; | |
overflow : auto; | |
} | |
input { | |
border : none; | |
border-spacing : 0px 0px; | |
background-color: grey; | |
font-family : Courier New; | |
font-size : 9px; | |
margin : 0 0 0 0; | |
padding : 0 0 0 0; | |
} | |
table { | |
border : none; | |
border-spacing : 0px 0px; | |
font-family : Courier New; | |
font-size : 9px; | |
} | |
tr { | |
margin : 10px 10px 10px 10px; | |
padding : none; | |
} | |
td { | |
border-top : none; | |
border-left : none; | |
border-right : thin green solid; | |
border-bottom : thin green solid; | |
} | |
button { | |
padding : 0 0 0 0; | |
margin : 0 0 0 0; | |
font-size : 7px; width: 4em; | |
} | |
pre#state { | |
padding : 0 0 0 0; | |
margin : 0 0 0 0; | |
} | |
pre { | |
margin : 0px 0px 0px 0px; | |
} | |
textarea { | |
border : none; | |
padding : 0 0 0 0; | |
margin : 0px 0px 0px 0px; | |
font-family : Courier; | |
font-height : 19px; | |
font-size : 8px; | |
} | |
textarea#Files { | |
display : none; | |
} | |
pre#Screen { | |
margin : 0px 0px 0px 0px; | |
font-family : Courier; | |
font-size : 10px; | |
font-width : 14px; | |
//border : thick grey inset; | |
} | |
pre#commands { | |
cursor : default; | |
} | |
var { | |
display : none; | |
} | |
span.prefix { | |
cursor : pointer; | |
} | |
span.prefix:hover { | |
color : yellow; | |
font-weight : bolder; | |
} | |
select { | |
font-family : Courier New; | |
font-size : 9px; | |
} | |
</style> | |
<script> | |
/****************************************************************************/ | |
Number.prototype.Hex = function(n) { | |
return (n < 0 ? "0x" : "") + ((((this >> 16) & 0x0000FFFF) | 0x00010000).toString(16) + ((this & 0x0000FFFF) | 0x00010000).toString(16).substr(1)).substr(-Math.abs(n)).toUpperCase(); | |
} | |
Number.prototype.hi = function(n) { | |
if(isFinite(n)) | |
return (this & 0x00FF) | ((n & 0x00FF) << 8); | |
return (this >> 8) & 0x00FF; | |
} | |
Number.prototype.lo = function(n) { | |
if(isFinite(n)) | |
return (this & 0xFF00) | (n & 0x00FF); | |
return this & 0x00FF; | |
} | |
Number.prototype.hl = function(hi, lo) { | |
return (lo & 0x00FF) | ((hi & 0x00FF) << 8); | |
} | |
String.prototype.Mul = function(n, j) {var s = this, buf = ""; while(n > 0) { if(n&1) buf+=s; s+=(j?j:"")+s; n >>= 1; } return buf; } | |
/* | |
.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F | |
00:STACK/Batch User Layer Loadings Execution Table|INT 0-bullet | |
10:STACK/-- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 1 | |
20:STACK/-- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 2 | |
30:STACK/-- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 3 | |
40:STACK/-- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 4 | |
50:STACK/-- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 5 | |
60:STACK/-- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 6 | |
70:STACK/-- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 7 | |
80:STOCK/-- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 8 | |
90:STOCK/-- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 9 | |
A0:AL>>LO>> ++/SP>LO/.. ..|AH>>HI>> ++/SP>HI/.. ..|AX / SP / | |
B0:BL>>LO>> ++/BP>LO/.. ..|BH>>HI>> ++/BP>HI/.. ..|BX / BP / | |
C0:CL>>LO>> ++/SI>LO/IP>LO|CH>>HI>> ++/SI>HI/IP>HI|CX / SI / IP | |
D0:DL>>LO>> ++/DI>LO/JP>LO|DH>>HI>> ++/DI>HI/JP>HI|DX / DI / JP | |
E0:-- I7 I6 I5 I4 I3 I2 I1|-- P7 P6 P5 P4 P3 P2 P1| | |
F0:-- D7 D6 D5 D4 D3 D2 D1|-- -- -- -- -- -- -- --| | |
+0:CI -- -- -- -- -- TL.TH |Control Registers | |
--- | |
PORT(ADDR) = ACC | |
DATA[ADDR] = ACC | |
DATA[ADDR ++] = ACC | |
DATA[-- ADDR] = ACC | |
ACC = PORT(ADDR) | |
ACC = DATA[ADDR] | |
ACC = DATA[ADDR ++] | |
ACC = DATA[-- ADDR] | |
WAIT | |
INT 79 ; 7-instructions of Function #9 | |
; SP.0 = 1; FL=0Fh; FH=017 | |
.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F | |
00:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 0 | |
10:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 1 | |
20:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 2 | |
30:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 3 | |
40:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 4 | |
50:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 5 | |
60:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 6 | |
70:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 7 | |
80:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 8 | |
90:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|INT 9 | |
A0:AL>>LO>>Стек истории --|AH>>HI>> ++ .. -- -- --|AX-Stack | |
B0:BL>>LO>>модификации- --|BH>>HI>> ++ .. -- -- --|BX-Stack | |
C0:CL>>LO>>всех РОН- -- --|CH>>HI>> ++ .. -- -- --|CX-Stack | |
D0:DL>>LO>> ++ .. -- -- --|DH>>HI>> ++ .. -- -- --|DX-Stack | |
E0:SP>LO/BP>LO/SI>LO/DI>LO|SP>HI/BP>HI/SI>HI/DI>HI|SP/BP/SI/DI-Stack | |
F0:IP>>LO>> ++/.. ../JP.LO|IP>>HI>> ++/.. ../JP.HI|IP/JP | |
+0:CI -- -- -- -- -- TL.TH |Control Registers | |
CI - Context Index Register | |
=========================== | |
For immediate access to the context file of any executive applications task on | |
the system level process is available the services register CI, selects a task | |
in the system environment and sets the all prefers for current active process. | |
Для непосредственного доступа к контексту любой имеющейся прикладной задачи на | |
уровне системного процесса доступен регистр CI, служащего переключателем задач | |
в системной среде и управляющего привелегиями для текущего активного процесса. | |
Базовая реализация процессора поддерживает от трёх независимых контекстов, под | |
которыми может выполняться непосредственно код системного ядра, код диспетчера | |
системных ресурсов с аппаратным интерфейсом и другой код прикладной программы. | |
Контекст ядра всегда имеет индекс с базой 0, диспетчерам ресурсов определяются | |
контексты с индексами от 127 до 100 в сторону уменьшения номера, тогда как все | |
приложения индексируются контекстами от 1 до 99 в сторону возрастания номеров. | |
______________________________________________________________________________ | |
00000000 0 :База(0) - Системный код с высоким уровнем привелегий. | |
0XXXXXXX 1-99 :База(1) - Прикладной код с низким уровнем привелегий. | |
011XXXXX 100-127:База(127)-Средний уровень диспетчера системных ресурсов. | |
1XXXXXXX 128-255:Зеркала контекста №0 под высоким системным уровнем привелегий | |
*/ | |
Array.prototype.Dump = function(a, n) { | |
var s = [], t = "__", d = "INT 0|INT 1|INT 2|INT 3|INT 4|INT 5|INT 6|INT 7|INT 8|INT 9|AX-File(AL:AH)|BX-File(BL:BH)|CX-File(CL:CH)|DX-File(DL:DH)|SP/BP/SI/DI|IP/JP|Services Masking".split("|"); | |
if(isFinite(a)) | |
while(n --) | |
s.push(this[a ++ & 0xFFFF].Hex(2)); | |
else { | |
n = this.length; | |
for(a = 0; a < 16; ++ a) | |
t += " ." + a.Hex(1); | |
for(a = 0; a < n; ++ a) { | |
s.push(this[a].Hex(2)); | |
if((a & 15) == 15) | |
if(a >= 0xE0 && a <= 0xEF) | |
t += "\r\n" + (a & 0xF0).Hex(2) + ":" + s.slice(0, 2).join(" ") + "/" + s.slice(2, 4).join(" ") + "/" + s.slice(4, 6).join(" ") + "/" + s.slice(6, 8).join(" "), | |
t += "|" + s.slice(8, 10).join(" ") + "/" + s.slice(10, 12).join(" ") + "/" + s.slice(12, 14).join(" ") + "/" + s.slice(14, 16).join(" ") + ";" + d.shift(), | |
s = []; | |
else | |
t += "\r\n" + (a & 0xF0).Hex(2) + ":" + s.slice(0, 8).join(" ") + "|" + s.slice(8, 16).join(" ") + ";" + d.shift(), | |
s = []; | |
else | |
if(a == n - 1) | |
t += "\r\n+0:" + s.join(" ") + ";" + d.shift(); | |
} | |
return t; | |
} | |
return s.join(" "); | |
} | |
Array.prototype.Text = function(a, n) {var s = "", c; while(n --) c = this[a ++ & 0xFFFF], s += "&#" + /*String.fromCharCode*/(c >= 32 && c <= 127 ? c : 0xB7) + ";"; return s; } | |
Array.prototype.Chr = function(a, n, m, xy) { | |
var i, buf = ""; | |
var smb = [ 0xB7, 0x255D, 0x255A, 0x2569, 0x2554, 0x256A, 0x2560, 0x2510, 0xB7, 0x263A, 0xB7, 0x25B2, 0xB7, 0xB7, 0x25BA, 0x25BC, //0xB7, 0x2598, 0x259D, 0x2580, 0x2597, 0x259A, 0x2590, 0x259C, 0xB7, 0x263A, 0xB7, 0x25B2, 0xB7, 0xB7, 0x25BA, 0x25BC, | |
0x2557, 0x2563, 0x256B, 0x250C, 0x2566, 0x2514, 0x2518, 0x256C, 0xB7, 0xB7, 0xB7, 0x2551, 0x2550, 0x25C4, 0xB7, 0xB7, //0x2596, 0x258C, 0x259E, 0x259B, 0x2584, 0x2599, 0x259F, 0x2588, 0xB7, 0xB7, 0xB7, 0x2551, 0x2550, 0x25C4, 0xB7, 0xB7, | |
0x20, 0x21, 0x22, 0x23, 0xA4, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, | |
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, | |
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B ,0x4C, 0x4D, 0x4E, 0x4F, | |
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, | |
0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, | |
0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x25A0]; | |
if(isFinite(m)) | |
m *= n; | |
else | |
m = n; | |
xy = isFinite(xy) ? xy : -1; | |
for(i = 0; i < m; ++ i, ++ a, -- xy) | |
buf += (xy ? "&#" : "<u>&#") + (this[a] >= 0 && this[a] < 128 ? smb[this[a]] : smb[0]) + (xy ? ";" : ";</u>") + (i % n == n - 1 && m != n ? "<br />" : ""); | |
return buf; | |
} | |
/****************************************************************************/ | |
var lastModified = document.lastModified; | |
var | |
AudioAPI = 0, | |
AudioScript = 0, | |
AudioStream = [], | |
AudioAPIscript = 0, | |
amp = [], | |
osc = []; | |
var noteFreq = [ // freq = 2 ** (n / 12) * 440 | |
16.352, 17.324, 18.354, 19.445, 20.602, 21.827, 23.125, 24.500, 25.957, 27.500, 29.135, 30.868, | |
32.703, 34.648, 36.708, 38.891, 41.203, 43.654, 46.249, 48.999, 51.913, 55.000, 58.270, 61.735, | |
65.406, 69.296, 73.416, 77.782, 82.406, 87.307, 92.499, 97.999, 103.83, 110.00, 116.54, 123.47, | |
130.81, 138.59, 146.83, 155.56, 164.81, 174.81, 185.00, 196.00, 207.65, 220.00, 233.08, 246.84, | |
261.63, 277.18, 293.67, 311.13, 329.63, 349.23, 369.99, 392.00, 415.30, 440.00, 466.16, 493.88, // #1 | |
523.25, 554.37, 587.33, 622.25, 659.26, 698.46, 739.99, 783.99, 830.61, 880.00, 932.33, 987.77, // #2 | |
1046.5, 1108.7, 1174.7, 1244.5, 1318.5, 1396.9, 1480.0, 1568.0, 1661.2, 1760.0, 1864.7, 1975.5, // #3 | |
2093.0, 2217.5, 2349.3, 2489.0, 2637.0, 2793.8, 2960.0, 3136.0, 3322.4, 3520.0, 3729.3, 3951.1, // #4 | |
4186.0, 4434.9, 4698.6, 4978.0, 5274.0, 5587.7, 5919.9, 6271.9, 6644.9, 7040.0, 7458.6, 7902.1, // #5 | |
8372.0, 8869.8, 9397.3, 9956.1, 10548 , 11175 , 11840 , 12544 , 13290 , 14080 , 14917 , 15804 // #6 | |
]; | |
function AudioCallBack(e) { | |
try { | |
var i, addr = 0xA0; | |
var input = e.inputBuffer.getChannelData(0); | |
var output = e.outputBuffer.getChannelData(0); | |
var frq = typeof cpu.iox[addr] == "object" ? cpu.iox[addr].data() : cpu.iox[addr]; | |
var evl = 0; | |
var dur = 0; | |
document.title = (frq = 440); | |
dur = AudioStream.length > 0 ? AudioStream[0] : 0; | |
try { | |
for(i = 0; i < input.length; ++ i) { | |
output[i] = dur > 0 ? 255 : 0; | |
if(dur > 0) | |
dur --; | |
if(dur < 0) | |
dur ++; | |
if(dur == 0 && AudioStream.length > 0) { | |
dur = AudioStream.shift(); | |
} | |
} | |
if(dur != 0) | |
AudioStream[0] = dur; | |
} catch(e) { | |
while(i < input.length) | |
output[i ++] = (Math.random() % 255 - 128) / 128; | |
} | |
} catch (e) { | |
//window.status = e.message; | |
} | |
} | |
// | |
function AudioInit() { | |
try { | |
AudioAPI = new AudioContext(); | |
} catch(err) { | |
AudioAPI = 0; | |
return; | |
} | |
//AudioAPIanalyser = AudioAPI.createAnalyser(); | |
//AudioAPIanalyser.connect(AudioAPI.destination); | |
AudioAPIfilter = AudioAPI.createBiquadFilter(); | |
AudioAPIfilter.type = 1; // High-pass filter (Тип фильтра) | |
AudioAPIfilter.frequency.value = 96000; // Cutoff to 1kHZ (Базовая частота) | |
AudioAPIfilter.frequency.Q = 1.1; // Quality factor (Добротность) | |
AudioAPIfilter.connect(AudioAPI.destination);//(AudioAPIanalyser); | |
(amp[0] = AudioAPI.createGain()).connect(AudioAPIfilter); /*amp[0].connect(anl)*/; amp[0].gain.value = 1.0; | |
(osc[0] = AudioAPI.createOscillator()).connect(amp[0]); osc[0].frequency.value = 440; | |
try { | |
osc[0].noteOn(0); | |
} catch(err) { | |
osc[0].start(0); | |
// osc[0].stop(3); | |
// osc[0].start(7); | |
} | |
/* if(!AudioAPI.createScriptProcessor) | |
AudioAPIscript = AudioAPI.createJavaScriptNode(1 << 10, 1, 1); | |
else | |
AudioAPIscript = AudioAPI.createScriptProcessor(1 << 10, 1, 1); | |
AudioAPIscript.onaudioprocess = AudioCallBack; | |
// connect the ScriptProcessorNode with the input audio | |
amp[0].connect(AudioAPIscript); | |
// if the ScriptProcessorNode is not connected to an output the "onaudioprocess" event is not triggered in chrome | |
AudioAPIscript.connect(amp[0]);*/ | |
}; | |
var | |
VK = { | |
BACK_SPACE :0x08, | |
TAB :0x09, | |
RETURN :0x0D, | |
BREAK :0x13, | |
CAPITAL :0x14, | |
ESC :0x1B, | |
PREV :0x21, | |
NEXT :0x22, | |
END :0x23, | |
HOME :0x24, | |
LEFT :0x25, | |
UP :0x26, | |
RIGHT :0x27, | |
DOWN :0X28, | |
PRINT :0x2C, | |
INSERT :0x2D, | |
DELETE :0x2E, | |
CONTEXT :0x5D, | |
F1 :0x70, | |
F2 :0x71, | |
F3 :0x72, | |
F4 :0x73, | |
F5 :0x74, | |
F6 :0x75, | |
F7 :0x76, // Assembly | |
F8 :0x77, | |
F9 :0x78, // Break point on/off | |
F10 :0x79, | |
F11 :0x7A, | |
F12 :0x7B, | |
BROWSE_BACK :0xA6, | |
BROWSE_FORWARD :0xA7, | |
BROWSE_REFRESH :0xA8, | |
BROWSE_STOP :0xA9, | |
BROWSE_SEARCH :0xAA, | |
BROWSE_HOME :0xAC, | |
PLAYER_FORWARD :0xB0, // Emulation IP ++ | |
PLAYER_REWIND :0xB1, // Emulation IP -- | |
PLAYER_STOP :0xB2, // Emulation stop/step | |
PLAYER_PLAY :0xB3, // Emulation stop/start | |
BROWSE_MAIL :0xB4, | |
}; | |
var X80 = | |
function(descriptions) { | |
var _CPU_ID_ = "x80-CPU"; | |
var preset = { // Initial tables | |
instructions :[], // Instructions set: code -> group, mnemonic, operands, expression | |
mnemonics :[], // Mnemonical codes: name -> operands -> code | |
alias :[], // Mnemonical alias: name -> byte codes | |
files :[], | |
ascii :[], // ASCII-Graphics memory | |
}; | |
var trace = { | |
callback :null, | |
timer :null, | |
active :true, | |
ready :true, | |
reply :false, | |
step :false, | |
is_port :false, | |
is_context :false, | |
is_debug :false, | |
is_freeze :true, | |
fixing :-1, | |
expressions :["", "", "", "", "", "", "", "", "", ""], | |
expression :0, | |
clock :1024, | |
scale :8192, | |
pointer :0, | |
address :0xF800, | |
lines :67, | |
flash :25, | |
stamps :[0, 0], | |
halt :[], | |
text :[], | |
labels :[], // Assembly idents: address -> name || name -> address | |
}; | |
var watch = { | |
active :"", | |
sAdjust :"IPC", | |
iAdjust :0, | |
nAdjust :1, | |
dirty :7, | |
instructions :null, | |
disassembly :null, | |
registers :null, | |
address :null, | |
mnemonic :null, | |
remark :null, | |
context :null, | |
c2d :null, | |
fontCnv :null, | |
fonts :null, | |
fontBit :null, | |
}; | |
var $CTX = null, | |
$BRK = false, | |
$IP = 0|0, | |
$IE = 0|0, // iteration extension mode neo:[1:Skip; 2:Loop; 3:Wait] | |
$IF = 0|0, // iteration flag | |
$IR = 0|0, // iterative register | |
$IT = 0|0, // iteration tick | |
$A = 0|0, // immediate short address | |
$B = 0|0, // immediate unsigned data | |
$C = 0|0, // immediate signed data | |
$EV = 0|0; // event value | |
var DO_OVERHEAD = 0, | |
DO_ACCLAIM = 1, | |
DO_BUFFER = 2, | |
DO_CONTEXT = 3, | |
DO_DEVICE = 4, | |
DO_ERROR = 5, | |
DO_FORCE = 6, | |
DO_GARRET = 7; | |
var i, j; | |
var irq = -1; | |
var ram; | |
var ctx = new Array(128); | |
var cr = [255, 0, 0, 0, 0, 0, 0, 0]; | |
var user = {}; | |
var display = function() {}; | |
var hTimer = null; | |
this.$EV = $EV; | |
this.DO_OVERHEAD = DO_OVERHEAD; | |
this.DO_ACCLAIM = DO_ACCLAIM; | |
this.DO_BUFFER = DO_BUFFER; | |
this.DO_CONTEXT = DO_CONTEXT; | |
this.DO_DEVICE = DO_DEVICE; | |
this.DO_ERROR = DO_ERROR; | |
this.DO_FORCE = DO_FORCE; | |
this.DO_GARRET = DO_GARRET; | |
// | |
Number.prototype.Hex = function(n) { | |
return (n < 0 ? "0x" : "") + ((((this >> 16) & 0x0000FFFF) | 0x00010000).toString(16) + ((this & 0x0000FFFF) | 0x00010000).toString(16).substr(1)).substr(-Math.abs(n)).toUpperCase(); | |
} | |
Number.prototype.hi = function(n) { | |
if(isFinite(n)) | |
return (this & 0x00FF) | ((n & 0x00FF) << 8); | |
return (this >> 8) & 0x00FF; | |
} | |
Number.prototype.lo = function(n) { | |
if(isFinite(n)) | |
return (this & 0xFF00) | (n & 0x00FF); | |
return this & 0x00FF; | |
} | |
Number.prototype.hl = function(hi, lo) { | |
return (lo & 0x00FF) | ((hi & 0x00FF) << 8); | |
} | |
String.prototype.Mul = function(n, j) {var s = this, buf = ""; while(n > 0) { if(n&1) buf+=s; s+=(j?j:"")+s; n >>= 1; } return buf; } | |
Array.prototype.Dump = function(a, n) { | |
var s = [], m, t = "__", d = "INT 0|INT 1|INT 2|INT 3|INT 4|INT 5|INT 6|INT 7|INT 8|INT 9|AX-File(AL:AH)|BX-File(BL:BH)|CX-File(CL:CH)|DX-File(DL:DH)|SP/BP/SI/DI|IP/JP|Services Masking".split("|"); | |
if(isFinite(a)) | |
while(n --) | |
s.push(this[a ++ & 0xFFFF].Hex(2)); | |
else { | |
n = this.length; | |
m = microdis(); | |
for(a = 0; a < 16; ++ a) | |
t += " ." + a.Hex(1); | |
for(a = 0; a < n; ++ a) { | |
s.push(this[a].Hex(2)); | |
if((a & 15) == 15) | |
if(a >= 0xE0 && a <= 0xEF) | |
t += "\r\n" + (a & 0xF0).Hex(2) + ":" + s.slice(0, 2).join(" ") + "/" + s.slice(2, 4).join(" ") + "/" + s.slice(4, 6).join(" ") + "/" + s.slice(6, 8).join(" "), | |
t += "|" + s.slice(8, 10).join(" ") + "/" + s.slice(10, 12).join(" ") + "/" + s.slice(12, 14).join(" ") + "/" + s.slice(14, 16).join(" ") + ";" + d.shift(), | |
s = []; | |
else | |
t += "\r\n" + (a & 0xF0).Hex(2) + ":" + s.slice(0, 8).join(" ") + "|" + s.slice(8, 16).join(" ") + ";" + d.shift() + (a > 16 && a <= 0x7F ? "|" + m.shift() : ""), | |
s = []; | |
} | |
for(a = 0; a < 8; ++ a) | |
s.push(cr[a].Hex(2)); | |
s.push("" + trace.expression); | |
s = s.concat(trace.expressions[trace.expression].replace(/(.{64})/g, "$1\r\n").split(/\r?\n/)); | |
t += "\r\n+0:" + s.join(" ") + ";" + d.shift(); | |
return t; | |
} | |
return s.join(" "); | |
} | |
function log() { | |
if(trace.active && arguments) { | |
var args = Array.prototype.slice.call(arguments); | |
var level = args[0].charAt(0); | |
var group = args[0].replace(/^[!#@]?/, "\1" + _CPU_ID_).split("/"); | |
for(var i = 1; i < group.length; ++ i) | |
console.group(group[i - 1]); | |
args.shift(); | |
args.unshift(group.pop()) | |
switch(level) { | |
case "!": | |
console.warn.apply(this, args) | |
break; | |
case "#": | |
console.info.apply(this, args) | |
break; | |
case "@": | |
console.error.apply(this, args) | |
break; | |
default: | |
if(trace.active) | |
console.log.apply(this, args) | |
break; | |
} | |
while(i --) | |
console.groupEnd(); | |
} | |
} | |
// | |
this.IRQ = function(type) { | |
if(cr[0] > 127) { | |
ctx[0][0xA8] = 0x85 | (DO_FORCE << 4); | |
CR(0, CR(0) & 127); | |
} | |
} | |
function DEBUG_TIMER(on) { | |
if(on) | |
log("!/TIMER ON"), | |
trace.stamps[0] = (new Date()).getTime(); | |
else | |
log("!/TIMER OFF"), | |
trace.stamps[0] = -Math.abs(trace.stamps[0]); | |
return 0; | |
} | |
function CTW(index, address, data) { | |
index &= 0xF; | |
address &= 0xFF; | |
if(isFinite(data)) | |
ctx[index][address] = data.lo(), | |
ctx[index][address ^ 8] = data.hi(); | |
return Number().hl(ctx[index][address ^ 8], ctx[index][address ^ 0]); | |
} | |
function CR(index, data) { | |
if(isFinite(index)) { | |
index &= 7; | |
if(isFinite(data)) { | |
log("!/CR:%s %s", index.Hex(2), data.Hex(2)); | |
data &= 0xFF; | |
if(!!((data ^ cr[0]) & 128) && !index) { | |
$CTX = ctx[data < 128 ? 0 : data & 127]; | |
$IE = 0, $IR = 0, $BRK = true; | |
if(data & 128) | |
$CTX[0xA8] = ($CTX[0xA8] & 0x02) | (ctx[0][0xA8] & 0x02); | |
} | |
if(!index) | |
trace.expressions = ["", "", "", "", "", "", "", "", "", ""]; | |
return cr[index] = data & 0xFF; | |
} | |
return cr[index]; | |
} | |
return cr[0] < 128 ? 0 : cr[0] & 0x7F; | |
} | |
function CTX(index, data) { | |
//log("/CTX(%d, %d)", index, data); | |
if(isFinite(data)) | |
ctx[cr[0] & 127][index & 0xFF] = data & 0xFF; | |
return ctx[cr[0] & 127][index & 0xFF]; | |
} | |
function FIX(width, index) { // Prepare micro | |
trace.expressions[index % 10] = ""; | |
index = ((index % 10) << 4) + 1; | |
width = (width << 1) + 1; | |
trace.fixing = index + width; | |
while(++ index & 15) | |
$CTX[index] = (index & 15) <= width ? 0xFF : 0x00; | |
} | |
function FLY(index) { | |
var tmp, action; | |
if(trace.expressions[index] == "") { | |
tmp = ((index) << 4) + 15; | |
while(!$CTX[tmp] && !$CTX[tmp - 1] && (tmp & 14)) | |
tmp -= 2 | |
while(tmp & 14) { | |
$B = $CTX[tmp --]; | |
action = $CTX[tmp --] + (($B << 3) & 0x700); | |
$C = ($B & 31) - ($B & 16) * 2; | |
$A = $B - ($B & 128) * 2; | |
$B &= 255; | |
trace.expressions[index] += preset.instructions[action].expression | |
.replace(/(\$B)/g, "" + $B) | |
.replace(/(\$C)/g, "" + $C) | |
.replace(/(\$A)/g, "" + $A) | |
.replace(/true/g, "false") + ";\r\n"; | |
} | |
log("!/EVAL %s", trace.expressions[index]); | |
} | |
trace.is_freeze = true; | |
eval(trace.expressions[index]); | |
log("!/IT=%s IR=%s REG=%s", $IT.Hex(2), $IR.Hex(2), REG($IR).Hex(2)); | |
if(!(($IT != 8) && (!$IR || (REG($IR) != 1)))) | |
FL(FL() | 2); | |
//$EV = this.DO_CONTEXT; | |
//log("!/%d %d %d", it, ir, REG(ir)); | |
} | |
function GET(index) { // Get data from kernel accumulator history | |
return ctx[0][0xA8 + (ctx[0][0xA8] & 0x30) - ((ctx[0][0xA8] >> 3) & 0x08) + (index & 7)]; | |
} | |
function PUT(data) { // Put data to kernel accumulator history | |
var index = 0xA8 + (ctx[0][0xA8] & 0x30) - ((ctx[0][0xA8] >> 3) & 0x08); | |
ctx[0].splice(index + 7, 1); | |
ctx[0].splice(index + 1, 0, data &= 0xFF); | |
return data; | |
} | |
function ACC(data) { // Holded register | |
var index = ($CTX[0xA8] >> 4) & 7; | |
index = 0xA8 + (index & 3) * 16 - (index & 4) * 2; | |
if(isFinite(data)) | |
data &= 0xFF, | |
$CTX[index] = data; | |
else | |
data = $CTX[index]; | |
return data; | |
} | |
/*this.__defineGetter__("ACC", function() { | |
var index = (this.$CTX[0xA8] >> 4) & 7; | |
index = 0xA8 + (index & 3) * 16 - (index & 4) * 2; | |
data = this.$CTX[index]; | |
return data; | |
}); | |
this.__defineSetter__("ACC", function(data) { | |
var index = (this.$CTX[0xA8] >> 4) & 7; | |
index = 0xA8 + (index & 3) * 16 - (index & 4) * 2; | |
data &= 0xFF, | |
this.$CTX[index] = data; | |
return data; | |
});*/ | |
function REG(index, data) {// Register[AH,BH,CH,DH,AL,BL,CL,DL] | |
index &= 7; | |
index = 0xA8 + (index & 3) * 16 - (index & 4) * 2; | |
if(isFinite(data)) | |
data &= 0xFF, | |
$CTX[index] = data; | |
else | |
data = $CTX[index]; | |
return data; | |
} | |
function DST(data) { // Holded pointer | |
var index = ($CTX[0xA8] >> 4) & 7; | |
if(index & 4) | |
index = 0xA0 + 16 * (index & 3); | |
else | |
index = 0xE0 + index; | |
if(isFinite(data)) | |
data &= 0xFFFF, | |
$CTX[index] = data.lo(), | |
$CTX[index + 8] = data.hi(); | |
else | |
data = Number().hl($CTX[index + 8], $CTX[index]); | |
return data; | |
} | |
function PTR(index, data) {// Pointer[SP,BP,SI,DI,AX,BX,CX,DX] | |
index &= 7; | |
if(index & 4) | |
index = 0xA0 + 16 * (index & 3); | |
else | |
index = 0xE0 + index; | |
if(isFinite(data)) | |
data &= 0xFFFF, | |
$CTX[index] = data.lo(), | |
$CTX[index + 8] = data.hi(); | |
else | |
data = Number().hl($CTX[index + 8], $CTX[index]); | |
return data; | |
} | |
function DROP(index) { | |
if(!isFinite(index)) | |
index = $CTX[0xA8]; | |
index &= 7; | |
index = 0xA8 + (index & 3) * 16 - (index & 4) * 2; | |
$CTX.splice(index + 7, 0, $CTX.splice(index, 1)[0]); | |
return $CTX[index + 7]; | |
} | |
function DUP(index) { | |
if(!isFinite(index)) | |
index = $CTX[0xA8]; | |
index &= 7; | |
index = 0xA8 + (index & 3) * 16 - (index & 4) * 2; | |
$CTX.splice(index + 7, 1), $CTX.splice(index, 0, $CTX[index]); | |
return $CTX[index + 7]; | |
} | |
function JP(index, address) { | |
index &= 1; | |
if(isFinite(address)) | |
$CTX[0xFE + index] = address.hi(), | |
$CTX[0xF6 + index] = address.lo(); | |
else | |
address = Number().hl($CTX[0xFE + index], $CTX[0xF6 + index]); | |
return address & 0xFFFF; | |
} | |
function IP(address) { | |
if(isFinite(address)) | |
$CTX.splice(0xF3, 1), $CTX.splice(0xF0, 0, address.lo()), | |
$CTX.splice(0xFB, 1), $CTX.splice(0xF8, 0, address.hi()), | |
address = Number().hl($CTX[0xF9], $CTX[0xF1]); | |
else | |
address = Number().hl($CTX[0xF8], $CTX[0xF0]); | |
return address & 0xFFFF; | |
} | |
function IPnext(address) { | |
var further; | |
if(isFinite(address)) | |
further = address; | |
else | |
address = Number().hl($CTX[0xF8], $CTX[0xF0]), | |
further = address + 1; | |
$CTX[0xF0] = further.lo(), $CTX[0xF8] = further.hi(); | |
return address & 0xFFFF; | |
} | |
function SP(address) { | |
if(isFinite(address) && trace.is_freeze) | |
$CTX[0xE0] = address.lo(), $CTX[0xE8] = address.hi(); | |
else | |
if(isFinite(address)) | |
$CTX.splice(0xE1, 1), $CTX.splice(0xE0, 0, address.lo()), | |
$CTX.splice(0xE9, 1), $CTX.splice(0xE8, 0, address.hi()), | |
address = Number().hl($CTX[0xE8], $CTX[0xE0]); | |
else | |
address = Number().hl($CTX[0xE8], $CTX[0xE0]); | |
return address & 0xFFFF; | |
} | |
function SPnext() { | |
var address = Number().hl($CTX[0xE8], $CTX[0xE0]), | |
further = address + 1; | |
$CTX[0xE0] = further.lo(), $CTX[0xE8] = further.hi(); | |
return address & 0xFFFF; | |
} | |
function SPback() { | |
var address = Number().hl($CTX[0xE8], $CTX[0xE0]), | |
further = address - 1; | |
$CTX[0xE0] = further.lo(), $CTX[0xE8] = further.hi(); | |
return address & 0xFFFF; | |
} | |
function _SP_(data) { | |
var address = Number().hl($CTX[0xE8], $CTX[0xE0]); | |
if(isFinite(data)) | |
DW(address, data); | |
else | |
data = DW(address); | |
return data; | |
} | |
function HEAP(data) { | |
var address = Number().hl($CTX[0xE8], $CTX[0xE0]); | |
if(isFinite(data)) | |
DW(address -= 2, data); | |
else | |
data = DW(address), | |
address += 2; | |
$CTX[0xE0] = address.lo(), $CTX[0xE8] = address.hi(); | |
return data; | |
} | |
function BP(address) { | |
if(isFinite(address) && trace.is_freeze) | |
$CTX[0xE2] = address.lo(), $CTX[0xEA] = address.hi(); | |
else | |
if(isFinite(address)) | |
$CTX.splice(0xE3, 1), $CTX.splice(0xE2, 0, address.lo()), | |
$CTX.splice(0xEB, 1), $CTX.splice(0xEA, 0, address.hi()); | |
else | |
address = Number().hl($CTX[0xEA], $CTX[0xE2]); | |
return address & 0xFFFF; | |
} | |
function SI(address) { | |
if(isFinite(address) && trace.is_freeze) | |
$CTX[0xE4] = address.lo(), $CTX[0xEC] = address.hi(); | |
else | |
if(isFinite(address)) | |
$CTX.splice(0xE5, 1), $CTX.splice(0xE4, 0, address.lo()), | |
$CTX.splice(0xED, 1), $CTX.splice(0xEC, 0, address.hi()); | |
else | |
address = Number().hl($CTX[0xEC], $CTX[0xE4]); | |
return address & 0xFFFF; | |
} | |
function DI(address) { | |
if(isFinite(address) && trace.is_freeze) | |
$CTX[0xE6] = address.lo(), $CTX[0xEE] = address.hi(); | |
else | |
if(isFinite(address)) | |
$CTX.splice(0xE7, 1), $CTX.splice(0xE6, 0, address.lo()), | |
$CTX.splice(0xEF, 1), $CTX.splice(0xEE, 0, address.hi()); | |
else | |
address = Number().hl($CTX[0xEE], $CTX[0xE6]); | |
return address & 0xFFFF; | |
} | |
function AX(address) { | |
if(isFinite(address) && trace.is_freeze) | |
$CTX[0xA0] = address.lo(), $CTX[0xA8] = address.hi(); | |
else | |
if(isFinite(address)) | |
$CTX.splice(0xAF, 1), $CTX.splice(0xA0, 0, address.lo()), $CTX[0xA8] = address.hi(); | |
else | |
address = Number().hl($CTX[0xA8], $CTX[0xA0]); | |
return address & 0xFFFF; | |
} | |
function BX(address) { | |
if(isFinite(address) && trace.is_freeze) | |
$CTX[0xB0] = address.lo(), $CTX[0xB8] = address.hi(); | |
else | |
if(isFinite(address)) | |
$CTX.splice(0xBF, 1), $CTX.splice(0xB0, 0, address.lo()), $CTX[0xB8] = address.hi(); | |
else | |
address = Number().hl($CTX[0xB8], $CTX[0xB0]); | |
return address & 0xFFFF; | |
} | |
function _BX_(data) { | |
if(isFinite(data)) | |
DB(Number().hl($CTX[0xB8], $CTX[0xB0]), data); | |
else | |
data = DB(Number().hl($CTX[0xB8], $CTX[0xB0])); | |
return data; | |
} | |
function CX(address) { | |
if(isFinite(address) && trace.is_freeze) | |
$CTX[0xC0] = address.lo(), $CTX[0xC8] = address.hi(); | |
else | |
if(isFinite(address)) | |
$CTX.splice(0xCF, 1), $CTX.splice(0xC0, 0, address.lo()), $CTX[0xC8] = address.hi(); | |
else | |
address = Number().hl($CTX[0xC8], $CTX[0xC0]); | |
return address & 0xFFFF; | |
} | |
function DX(address) { | |
if(isFinite(address) && trace.is_freeze) | |
$CTX[0xD0] = address.lo(), $CTX[0xD8] = address.hi(); | |
else | |
if(isFinite(address)) | |
$CTX.splice(0xDF, 1), $CTX.splice(0xD0, 0, address.lo()), $CTX[0xD8] = address.hi(); | |
else | |
address = Number().hl($CTX[0xD8], $CTX[0xD0]); | |
return address & 0xFFFF; | |
} | |
function _AL_(data) { | |
if(isFinite(data)) | |
$CTX.splice(0xA7, 1), $CTX.splice(0xA0, 0, data.lo()); | |
else | |
data = $CTX[0xA0]; | |
data -= (data & 0x80) << 1; | |
return data & 0xFFFF; | |
} | |
function AL(data) { | |
if(isFinite(data) && trace.is_freeze) | |
$CTX[0xA0] = data & 0xFF; | |
else | |
if(isFinite(data)) | |
$CTX.splice(0xA7, 1), $CTX.splice(0xA0, 0, data.lo()); | |
else | |
data = $CTX[0xA0]; | |
return data & 0x00FF; | |
} | |
function AH(data) { | |
if(isFinite(data) && trace.is_freeze) | |
$CTX[0xA8] = data & 0xFF; | |
else | |
if(isFinite(data)) | |
$CTX.splice(0xAF, 1), $CTX.splice(0xA8, 0, data.lo()); | |
else | |
data = $CTX[0xA8]; | |
return data & 0x00FF; | |
} | |
function BL(data) { | |
if(isFinite(data) && trace.is_freeze) | |
$CTX[0xB0] = data & 0xFF; | |
else | |
if(isFinite(data)) | |
$CTX.splice(0xB7, 1), $CTX.splice(0xB0, 0, data.lo()); | |
else | |
data = $CTX[0xB0]; | |
return data & 0x00FF; | |
} | |
function BH(data) { | |
if(isFinite(data) && trace.is_freeze) | |
$CTX[0xB8] = data & 0xFF; | |
else | |
if(isFinite(data)) | |
$CTX.splice(0xBF, 1), $CTX.splice(0xB8, 0, data.lo()); | |
else | |
data = $CTX[0xB8]; | |
return data & 0x00FF; | |
} | |
function CL(data) { | |
if(isFinite(data) && trace.is_freeze) | |
$CTX[0xC0] = data & 0xFF; | |
else | |
if(isFinite(data)) | |
$CTX.splice(0xC7, 1), $CTX.splice(0xC0, 0, data.lo()); | |
else | |
data = $CTX[0xC0]; | |
return data & 0x00FF; | |
} | |
function CH(data) { | |
if(isFinite(data) && trace.is_freeze) | |
$CTX[0xC8] = data & 0xFF; | |
else | |
if(isFinite(data)) | |
$CTX.splice(0xCF, 1), $CTX.splice(0xC8, 0, data.lo()); | |
else | |
data = $CTX[0xC8]; | |
return data & 0x00FF; | |
} | |
function DL(data) { | |
if(isFinite(data) && trace.is_freeze) | |
$CTX[0xD0] = data & 0xFF; | |
else | |
if(isFinite(data)) | |
$CTX.splice(0xD7, 1), $CTX.splice(0xD0, 0, data.lo()); | |
else | |
data = $CTX[0xD0]; | |
return data & 0x00FF; | |
} | |
function DH(data) { | |
if(isFinite(data) && trace.is_freeze) | |
$CTX[0xD8] = data & 0xFF; | |
else | |
if(isFinite(data)) | |
$CTX.splice(0xDF, 1), $CTX.splice(0xD8, 0, data.lo()); | |
else | |
data = $CTX[0xD8]; | |
return data & 0x00FF; | |
} | |
function FL(data) { | |
if(isFinite(data) && trace.is_freeze) | |
log("!/GLAG %s %s", $IP.Hex(4), data.Hex(2)), | |
$CTX[0xA8] = ($CTX[0xA8] & 0xF0) | (data & 0x0F); | |
else | |
if(isFinite(data)) | |
$CTX.splice(0xAF, 1), $CTX.splice(0xA8, 0, ($CTX[0xA8] & 0xF0) | (data & 0x0F)); | |
else | |
data = $CTX[0xA8]; | |
return data & 0x000F; | |
} | |
function FH(data) { | |
if(isFinite(data) && trace.is_freeze) | |
$CTX[0xA8] = ($CTX[0xA8] & 0x0F) | ((data << 4) & 0xFF); | |
else | |
if(isFinite(data)) | |
$CTX.splice(0xAF, 1), $CTX.splice(0xA8, 0, ($CTX[0xA8] & 0x0F) | (data << 4).lo()); | |
else | |
data = $CTX[0xA8] >> 4; | |
return data & 0x000F; | |
} | |
function ADC(data, bits) { | |
var flags; // SF PF CF ZF | |
data = data.lo() + bits.lo() + ((FL() >> 1) & 1); | |
flags = data ^ (data >> 4); | |
flags ^= flags << 2; | |
flags ^= flags >> 1; | |
flags &= 4; | |
flags |= (data >> 7) & 2; | |
data &= 0xFF; | |
flags |= (((data ^ 0xFF) + 1) >> 8) & 1; | |
flags |= (data >> 4) & 8; | |
//log("ALU:ADC"); | |
return data + (flags << 8); | |
} | |
function SBB(data, bits) { | |
var flags; // SF PF CF ZF | |
data = data.lo() - bits.lo() - ((FL() >> 1) & 1); | |
flags = data ^ (data >> 4); | |
flags ^= flags << 2; | |
flags ^= flags >> 1; | |
flags &= 4; | |
flags |= (data >> 7) & 2; | |
data &= 0xFF; | |
flags |= (((data ^ 0xFF) + 1) >> 8) & 1; | |
flags |= (data >> 4) & 8; | |
//log("ALU:SBB"); | |
return data + (flags << 8); | |
} | |
function ADD(data, bits) { | |
var flags; // SF PF CF ZF | |
data = data.lo() + bits.lo(); | |
flags = data ^ (data >> 4); | |
flags ^= flags << 2; | |
flags ^= flags >> 1; | |
flags &= 4; | |
flags |= (data >> 7) & 2; | |
data &= 0xFF; | |
flags |= (((data ^ 0xFF) + 1) >> 8) & 1; | |
flags |= (data >> 4) & 8; | |
//log("ALU:ADD"); | |
return data + (flags << 8); | |
} | |
function SUB(data, bits) { | |
var flags; // SF PF CF ZF | |
data = data.lo() - bits.lo(); | |
flags = data ^ (data >> 4); | |
flags ^= flags << 2; | |
flags ^= flags >> 1; | |
flags &= 4; | |
flags |= (data >> 7) & 2; | |
data &= 0xFF; | |
flags |= (((data ^ 0xFF) + 1) >> 8) & 1; | |
flags |= (data >> 4) & 8; | |
//log("ALU:SUB"); | |
return data + (flags << 8); | |
} | |
function AND(data, bits) { | |
var flags; // SF PF CF ZF | |
data = data.lo() & bits.lo(); | |
flags = data ^ (data >> 4); | |
flags ^= flags << 2; | |
flags ^= flags >> 1; | |
flags &= 4; | |
flags |= FL() & 2; | |
flags |= (((data ^ 0xFF) + 1) >> 8) & 1; | |
flags |= (data >> 4) & 8; | |
//log("ALU:AND"); | |
return data + (flags << 8); | |
} | |
function OR(data, bits) { | |
var flags; // SF PF CF ZF | |
data = data.lo() | bits.lo(); | |
flags = data ^ (data >> 4); | |
flags ^= flags << 2; | |
flags ^= flags >> 1; | |
flags &= 4; | |
flags |= FL() & 2; | |
flags |= (((data ^ 0xFF) + 1) >> 8) & 1; | |
flags |= (data >> 4) & 8; | |
//log("ALU:OR"); | |
return data + (flags << 8); | |
} | |
function XOR(data, bits) { | |
var flags; // SF PF CF ZF | |
data = data.lo() ^ bits.lo(); | |
flags = data ^ (data >> 4); | |
flags ^= flags << 2; | |
flags ^= flags >> 1; | |
flags &= 4; | |
flags |= FL() & 2; | |
flags |= (((data ^ 0xFF) + 1) >> 8) & 1; | |
flags |= (data >> 4) & 8; | |
//log("ALU:XOR"); | |
return data + (flags << 8); | |
} | |
function CMP(bits, data) { | |
var flags; // SF PF CF ZF | |
data = bits.lo() - data.lo(); | |
flags = data ^ (data >> 4); | |
flags ^= flags << 2; | |
flags ^= flags >> 1; | |
flags &= 4; | |
flags |= (data >> 7) & 2; | |
data &= 0xFF; | |
flags |= (((data ^ 0xFF) + 1) >> 8) & 1; | |
flags |= (data >> 4) & 8; | |
//log("ALU:CMP"); | |
return bits.lo() + (flags << 8); | |
} | |
function NOT(data) { // Bitwise not | |
var flags; // SF PF CF ZF | |
data = data.lo() ^ 0xFF; | |
flags = data ^ (data >> 4); | |
flags ^= flags << 2; | |
flags ^= flags >> 1; | |
flags &= 4; | |
flags |= (data >> 7) & 2; | |
data &= 0xFF; | |
flags |= (((data ^ 0xFF) + 1) >> 8) & 1; | |
flags |= (data >> 4) & 8; | |
//log("ALU:NOT"); | |
return data + (flags << 8); | |
} | |
function RAR(data) { // Roll Arithmetic Right | |
var flags; // SF PF CF ZF | |
data = (data.lo() >> 1) | ((data & 1) << 8) | (data & 0x80); | |
flags = data ^ (data >> 4); | |
flags ^= flags << 2; | |
flags ^= flags >> 1; | |
flags &= 4; | |
flags |= (data >> 7) & 2; | |
data &= 0xFF; | |
flags |= (((data ^ 0xFF) + 1) >> 8) & 1; | |
flags |= (data >> 4) & 8; | |
//log("ALU:RAR"); | |
return data + (flags << 8); | |
} | |
function RCL(data) { // Roll Cyclic Left | |
var flags; // SF PF CF ZF | |
data = (data.lo() << 1) | ((data >> 7) & 1); | |
flags = data ^ (data >> 4); | |
flags ^= flags << 2; | |
flags ^= flags >> 1; | |
flags &= 4; | |
flags |= (data >> 7) & 2; | |
data &= 0xFF; | |
flags |= (((data ^ 0xFF) + 1) >> 8) & 1; | |
flags |= (data >> 4) & 8; | |
//log("ALU:RCL"); | |
return data + (flags << 8); | |
} | |
function RCR(data) { // Roll Cyclic Right | |
var flags; // SF PF CF ZF | |
data = (data.lo() >> 1) | ((data & 1) << 7); | |
flags = data ^ (data >> 4); | |
flags ^= flags << 2; | |
flags ^= flags >> 1; | |
flags &= 4; | |
flags |= (data >> 6) & 2; | |
data &= 0xFF; | |
flags |= (((data ^ 0xFF) + 1) >> 8) & 1; | |
flags |= (data >> 4) & 8; | |
//log("ALU:RCR"); | |
return data + (flags << 8); | |
} | |
function ROL(data) { // Roll Overflow Left | |
var flags; // SF PF CF ZF | |
data = (data.lo() << 1) | ((FL >> 1) & 1); | |
flags = data ^ (data >> 4); | |
flags ^= flags << 2; | |
flags ^= flags >> 1; | |
flags &= 4; | |
flags |= (data >> 7) & 2; | |
data &= 0xFF; | |
flags |= (((data ^ 0xFF) + 1) >> 8) & 1; | |
flags |= (data >> 4) & 8; | |
//log("ALU:ROL"); | |
return data + (flags << 8); | |
} | |
function ROR(data) { // Roll Overflow Right | |
var flags; // SF PF CF ZF | |
data = (data.lo() >> 1) | ((data & 1) << 8) | ((FL & 2) << 7); | |
flags = data ^ (data >> 4); | |
flags ^= flags << 2; | |
flags ^= flags >> 1; | |
flags &= 4; | |
flags |= (data >> 7) & 2; | |
data &= 0xFF; | |
flags |= (((data ^ 0xFF) + 1) >> 8) & 1; | |
flags |= (data >> 4) & 8; | |
//log("ALU:ROR"); | |
return data + (flags << 8); | |
} | |
var FileIndex = 0; | |
var FileSeek = 0; | |
var Value = 0; | |
var Resume = 0; | |
var FileMode = 0; | |
/* cpu.preset.files.push({ | |
name :file.id.substr(5), | |
text :file.innerText, | |
code :{ | |
name :"", | |
begin :65535, | |
end :0, | |
bin :[] | |
} | |
*/ function PORT(index, data) { | |
if(cr[0] & 0x80) { | |
if(isFinite(data)) { | |
this.ready = false; | |
if(ctx[0][0xA8] & 0x02) { | |
FL((FL() & 0xD) | (ctx[0][0xA8] & 0x2)), | |
ctx[0][0xA8] &= 0xFD; | |
return data; | |
} | |
PUT(data & 0xFF); | |
PUT(index); | |
ctx[0][0xA8] |= 0x02; | |
// IPnext($IP); | |
$EV = DO_DEVICE; | |
return index; | |
} else { | |
//console.log("!/INPUT %s %s ", index.Hex(2), $EV); | |
trace.ready = false; | |
if(ctx[0][0xA8] & 0x02) { | |
trace.ready = true; | |
FL((FL() & 0xD) | (ctx[0][0xA8] & 0x2)), | |
ctx[0][0xA8] &= 0xFD; | |
return GET(1); | |
} | |
PUT(index), | |
ctx[0][0xA8] &= 0xFD; | |
// IPnext($IP); | |
$EV = DO_DEVICE; | |
return index; | |
} | |
} | |
if(isFinite(data)) | |
log("!/OUT %s,%s", index.Hex(2), data.Hex(2)); | |
else | |
log("!/IN %s", index.Hex(2)); | |
switch(index) { | |
case 0xF5: | |
if(isFinite(data)) { | |
switch(data) { | |
case 0xC0: case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7: case 0xC8: case 0xC9: case 0xCA: case 0xCB: case 0xCC: case 0xCD: case 0xCE: case 0xCF: | |
Value = ((Value << 4) & 0xFFF0) | (data & 15); | |
log("!PORT/FILE/Code %s", data.Hex(2)); | |
break; | |
case 0xD1: | |
FileIndex = Value; | |
log("!PORT/FILE/File %s", Value.Hex(2)); | |
break; | |
case 0xD5: | |
FileSeek = Value; | |
log("!PORT/FILE/Seek %s", Value.Hex(2)); | |
break; | |
case 0xD3: | |
FileMode = Value; | |
log("!PORT/FILE/Mode %s", Value.Hex(2)); | |
break; | |
} | |
Resume = -1; | |
trace.ready = true; | |
} else { | |
trace.ready = true; | |
switch(FileMode) { | |
case 0: | |
Resume = Resume >= 0 ? Resume : preset.files.length; | |
data = Resume & 255; | |
Resume >>= 8; | |
log("!PORT/FILE/Get File Number"); | |
break; | |
case 1: | |
Resume = Resume >= 0 ? Resume : 0; | |
data = preset.files[FileIndex].code.name.charCodeAt(Resume); | |
Resume ++; | |
log("!PORT/FILE/Get File Name"); | |
if(Resume >= preset.files[FileIndex].code.name.length) | |
trace.ready = false; | |
break; | |
case 2: | |
Resume = Resume >= 0 ? Resume : preset.files[FileIndex].begin; | |
data = Resume & 255; | |
Resume >>= 8; | |
log("!PORT/FILE/Get File Start"); | |
break; | |
case 3: | |
Resume = Resume >= 0 ? Resume : preset.files[FileIndex].end; | |
data = Resume & 255; | |
Resume >>= 8; | |
log("!PORT/FILE/Get File End"); | |
break; | |
case 4: | |
Resume = Resume >= 0 ? Resume : preset.files[FileIndex].code.begin; | |
data = preset.files[FileIndex].code.bin[Resume]; | |
log("!PORT/FILE/Get File Data"); | |
if(Resume < preset.files[FileIndex].code.end) | |
++ Resume; | |
else | |
trace.ready = false; | |
break; | |
} | |
} | |
break; | |
case 0xDB: | |
if(isFinite(data)) | |
DEBUG_TIMER(!!data); | |
else | |
data = Math.floor((core.trace.stamps[1] - core.trace.stamps[0]) / 1000) & 0xFF; | |
FL(FL() | 0x2); | |
break; | |
case 0xFD: | |
if(isFinite(data)) { | |
} else { | |
if(document.getElementById("KeyBoard").value == "") | |
FL(FL() & 0x0D), | |
trace.ready = false, | |
data = 255; | |
else { | |
data = document.getElementById("KeyBoard").value.charCodeAt(0), document.getElementById("KeyBoard").value = document.getElementById("KeyBoard").value.substr(1); | |
FL(FL() | 0x02), | |
trace.ready = true; | |
if(data == 0x60) { | |
data = document.getElementById("KeyBoard").value.charCodeAt(0), document.getElementById("KeyBoard").value = document.getElementById("KeyBoard").value.substr(1); | |
if(data > 0x40 && data <= 0x5F) | |
data &= 0x1F; | |
else | |
data = 0x7F; | |
} | |
} | |
} | |
break; | |
default: | |
data = 0; | |
} | |
return data; | |
} | |
function DB(addr, data) { | |
if(isFinite(data)) { | |
addr &= 0xFFFF, | |
data &= 0xFF; | |
if(trace.is_context && trace.is_port) { | |
log("#/CONTROL:%s <= %s", addr.Hex(2), data.Hex(2)); | |
if(cr[0] & 15) { | |
cr[1] |= 1 << 0; | |
log("!/IRQ %d", type & 7); | |
IPnext($IP); | |
cr[0] = ((cr[0] << 4) & 0xF0); | |
HEAP(IP()); | |
HEAP(AX()); | |
FH(type | 8); | |
FL(7); | |
IPnext(JP(0)); | |
} | |
cr[addr & 7] = data; | |
trace.is_context = false; | |
trace.is_port = false; | |
} else | |
if(trace.is_context) { | |
log("#/CONTEXT:%s <= %s", addr.Hex(2), data.Hex(2)); | |
trace.is_context = false; | |
trace.is_port = false; | |
} else | |
if(trace.is_port) { | |
log("#/PORT:%s <= %s", addr.Hex(2), data.Hex(2)); | |
trace.is_port = false; | |
data = PORT(addr.lo(), data); | |
} else { | |
trace.ready = true; | |
ram[addr] = data; | |
} | |
} else { | |
if(isFinite(addr)) | |
addr &= 0xFFFF; | |
else | |
if(trace.is_context || trace.is_port) { | |
log("@/:TEST IP = %s ERROR", IP().Hex(4)); | |
trace.is_debug = true; | |
trace.is_context = false; | |
trace.is_port = false; | |
data = Math.random() & 0xFF; | |
return data; | |
} else | |
addr = IPnext(); | |
if(trace.is_context && trace.is_port) { | |
data = cr[addr & 7]; | |
log("#/CONTROL:%s <= %s", addr.Hex(2), data.Hex(2)); | |
trace.is_context = false; | |
trace.is_port = false; | |
if(cr[0] & 15) { | |
log("!/IRQ %d", type & 7); | |
IPnext($IP); | |
cr[0] = ((cr[0] << 4) & 0xF0); | |
HEAP(IP()); | |
HEAP(AX()); | |
FH(type | 8); | |
FL(7); | |
IPnext(JP(0)); | |
} | |
} else | |
if(trace.is_context) { | |
data = 0x55; | |
log("#/CONTEXT:%s <= %s", addr.Hex(2), data.Hex(2)); | |
trace.is_context = false; | |
trace.is_port = false; | |
data = 0x55; | |
} else | |
if(trace.is_port) { | |
data = PORT(addr.lo()); | |
log("#/PORT:%s => %s", addr.Hex(2), data.Hex(2)); | |
trace.is_port = false; | |
} else { | |
trace.ready = true; | |
data = ram[addr].lo(); | |
} | |
} | |
return data; | |
} | |
function DW(addr, data) { | |
if(isFinite(data)) { | |
addr &= 0xFFFF, | |
data &= 0xFFFF; | |
ram[addr ++] = data.lo(); | |
data &= 0xFFFF; | |
ram[addr] = data.hi(); | |
} else { | |
data = ram[addr ++ & 0xFFFF]; | |
data = Number().hl(ram[addr & 0xFFFF], data); | |
} | |
return data; | |
} | |
this.$CTX = $CTX; | |
this.CTW = CTW; | |
this.CTX = CTX; | |
this.CR = CR; | |
this.ACC = ACC; | |
this.DST = DST; | |
this.PTR = PTR; | |
this.REG = REG; | |
this.DROP = DROP; | |
this.DUP = DUP; | |
this.JP = JP; | |
this.IP = IP; | |
this.IPnext = IPnext; | |
this.SP = SP; | |
this.SPnext = SPnext; | |
this.SPback = SPback; | |
this._SP_ = _SP_; | |
this.HEAP = HEAP; | |
this.BP = BP; | |
this.SI = SI; | |
this.DI = DI; | |
this.AX = AX; | |
this.BX = BX; | |
this._BX_ = _BX_; | |
this.CX = CX; | |
this.DX = DX; | |
this._AL_ = _AL_; | |
this.AL = AL; | |
this.BL = BL; | |
this.CL = CL; | |
this.DL = DL; | |
this.AH = AH; | |
this.BH = BH; | |
this.CH = CH; | |
this.DH = DH; | |
this.FL = FL; | |
this.FH = FH; | |
this.ADC = ADC; | |
this.SBB = SBB; | |
this.ADD = ADD; | |
this.SUB = SUB; | |
this.AND = AND; | |
this.OR = OR; | |
this.XOR = XOR; | |
this.CMP = CMP; | |
this.NOT = NOT; | |
this.RAR = RAR; | |
this.RCL = RCL; | |
this.RCR = RCR; | |
this.ROL = ROL; | |
this.ROR = ROR; | |
this.PORT = PORT; | |
this.DB = DB; | |
this.DW = DW; | |
function flags(d) { | |
var fx = AH(); | |
if(!isFinite(d)) { | |
var d = fx; | |
s = AL().Hex(2) + " " + AH().Hex(2) + "(AX)" + "----------- USING_BH/BP USING_CH/SI USING_DH/DI USE_AL/[SP] USING_BL/BX USING_CL/CX USING_DL/DX ??????????? INDEX_OF_x1 INDEX_OF_x2 INDEX_OF_x3 INDEX_OF_x4 INDEX_OF_x5 INDEX_OF_x6 INDEX_OF_x7".split(" ")[(d >> 4) & 15].replace(/_/g, " "); | |
switch(fx & 0xF) { | |
case 0x5: s += "|SKIP:Missed"; break; | |
case 0x7: s += "|SKIP:MISSED"; break; | |
case 0x9: s += "|LOOP:Cycled"; break; | |
case 0xB: s += "|LOOP:CYCLED"; break; | |
case 0xD: s += "|WAIT:Bused "; break; | |
case 0xF: s += "|WAIT:Ready "; break; | |
default: | |
s += "|sf pf cf zf".replace(/.f/g, function(str) { | |
str = d & 0x08 ? str.toUpperCase() : str.toLowerCase(); | |
d <<= 1; | |
return str; | |
}); | |
} | |
d = (fx >> 4) & 15; | |
d = d < 8 ? REG(d) : d + 248; | |
s += "|" + ctx[0][0xA1].Hex(2) + ":" + ctx[0][0xA2].Hex(2) + (ctx[0][0xA8] & 2 ? "Ready/Output" : "Bused/Input"); | |
//s += ("|EXx" + (d & 256 ? "#" + d.Hex(1) : d.Hex(2)) + ":" + (isFinite(this.r.ex[d]) ? this.r.ex[d].Hex(2) : "--")); | |
/*s += (" JPx" + this.r.jp.Hex(4)); | |
s += (" SXx" + this.r.asx[(this.r.ax & 0x8000 ? 248 + (this.r.ax >> 12) : this.reg(this.r.ax >> 12)) % 264].Hex(4)); | |
s += (" TXx" + this.r.atx[(this.r.ax & 0x8000 ? 248 + (this.r.ax >> 12) : this.reg(this.r.ax >> 12)) % 264].Hex(4)); | |
s += (" SRx" + this.r.sr.Hex(4));*/ | |
return s; | |
} | |
fx = ((d << 3) & 0x0400) | | |
(d & 255 ? 0 : 0x100) | | |
((d << 1) & 0x0200); | |
d ^= d >> 4; | |
d ^= d << 2; | |
d ^= d << 1; | |
} | |
this.reset = function(address) { | |
log("!/CORE:RESET"); | |
CR(0, 0); | |
IPnext(address); | |
$CTX[0xA8] = 0xF7; | |
trace.pointer = address; | |
trace.active = true; | |
trace.freeze = true; | |
clearTimeout(hTimer); | |
step.bind(this).call(); | |
} | |
function step() { | |
"use asm"; | |
var ic = 0|0; // instruction prefix/code | |
var code = 0|0; // instruction selected code | |
var action = 0|0; // instruction actions | |
var scale = 0|0; | |
var i = 0|0; | |
var tmp = 0|0; | |
var ctrl = 0|0; | |
var $FH = 0|0; | |
var tick = 0|0; | |
hTimer = setTimeout(this.step.bind(this), 1000 / trace.clock); | |
scale = !trace.active || trace.step ? trace.step ? 1 : trace.scale : 0; | |
if((trace.step && !trace.active && !trace.halt[IP()])) | |
trace.active = true, | |
disassm(); | |
if((!trace.step && !trace.active && trace.halt[IP()])) | |
disassm(); | |
if(tmp = CR()) | |
tick = Number().hl(cr[7], cr[6]) & 0xFFFF; | |
else | |
tick = -1; | |
$EV = -DO_CONTEXT; | |
$FH = FH(); | |
try { | |
while(!!(($IP = IP()) || (ready = true)) && (trace.step || (!trace.halt[$IP] && !trace.active)) && (scale -- > 0) && ((tick != 0) && tick --) && ($EV < 0)) { | |
trace.is_port = false; // Not port access | |
trace.is_context = false; // Not context access | |
$BRK = false; // No context break | |
$A = $B = $C = 0; // Reset instruction Byte/Value/Word | |
$IR = $IT = FH(); // Iterable Register/Times load | |
$IR &= $IR & 8 ? 0 : 15; // Select between | |
$IT &= $IT & 8 ? 15 : 0; // Register or Times | |
$IE = FL(); | |
$IF = false; | |
if(!!($IE >> 2) && !!($IE & 1)) // Instruction Extension: 0-None, 1-Skip, 2-Loop, 3-Wait | |
$IE >>= 2; | |
else | |
$IE = 0; | |
ic = DB(); // Read instruction code and prefix | |
if(((ic >> 4) == (ic & 0x07)) && (ic || cr[0] < 128)) | |
ic = (ic ? (ic & 0x07) << 8 : 0x0800) | DB(); | |
if((ic & 0xC0) == 0x80) // Read immediate data | |
$B = DB(), | |
$C = $B - (($B & 0x0080) << 1), | |
$A = $C + ((ic & 0x0700) - ((ic & 0x0400) << 1)); | |
// Supevisor mode control | |
ctrl = !(cr[0] & 0x80) && ($IE == 3) && ((ic.lo() == 0) || ((ic.hi() * 0x11) == ic.lo())); | |
$FH = -1; | |
if($IT && $IE && !ctrl) { // Test for Iteration Timer and Extension | |
i = -- $IT; | |
if(i == 8) // Timer clear test | |
FL(FL() & 0xE), | |
FH(0), | |
$IT = $IE == 1 || $IE == 3 ? 8 : 0, | |
$IE = $IE == 1 || $IE == 3 ? $IE : 0; | |
else | |
$FH = i;//FH(i); | |
} else | |
if(($IT == 8) && !ctrl) | |
FH(0), | |
$IT = !ctrl ? 0 : 8; | |
else | |
if($IR && !REG($IR) && !ctrl) | |
$IE = 0; | |
switch($IE) { | |
case 3: ic |= CR() < 128 ? 0x7000 : 0x3000; break; // WAIT:011 | |
case 2: ic |= CR() < 128 ? 0x6000 : 0x2000; break; // LOOP:010 | |
default: ic |= CR() >= 128 ? 0x4000 : 0x0000; | |
} | |
ic |= $A == -2 ? 0x0800 : 0x0000; | |
document.title = ic.Hex(4) + '/' + $IE; | |
code = preset.instructions[ic]; // Get instruction circuit | |
if(code && code.expression) { | |
trace.is_freeze = (!!$IR || !!$IT) && !!$IE || !(cr[0] & 0x80) || !(ctx[0][0xA8] & 0x02); | |
//trace.is_freeze = true; | |
if(ctrl) { | |
code.envelope(this, $IP, $B, $C, $A, $IE, $IR, $IT); | |
if($BRK) { | |
log("!/LOG $BRK"); | |
trace.pointer = IP(); | |
break; | |
} | |
//log("!/CLR (ic.lo = %d) || (ic.hi = %d) ", ic.lo(), ic.hi()); | |
$IE = 0, | |
// $IT = 0, | |
$IR = 0; | |
if(CR() < 128) | |
FL(FL() & 0xE); | |
//trace.expression = ""; | |
} else | |
if($IT != 8 && $IE != 1) { | |
ctrl = FL() & 0x0D; | |
/*if(((ic & 0xFF) >= 0xF0) && ((ic & 0xFF) <= 0xF9) && ($IE == 3)) { | |
trace.expression = ic & 0x0F; | |
if(ic >= 0x100) { | |
tmp = ((ic & 0xF) << 4) + 15; | |
i = ((ic >> 7) & 14) + 1; | |
while(i < 14) | |
$CTX[++ i] = 0, | |
$CTX[++ i] = 0; | |
while(tmp & 14) | |
$CTX[tmp] = $CTX[tmp -- & 15], | |
$CTX[tmp] = $CTX[tmp -- & 15]; | |
FL(FL() & 0xE); | |
$IE = 0; | |
trace.expressions[ic & 15] = ""; | |
} else { | |
if(trace.expressions[ic & 15] == "") { | |
tmp = ((ic & 0xF) << 4) + 15; | |
while(!$CTX[tmp] && !$CTX[tmp - 1] && (tmp & 14)) | |
tmp -= 2 | |
while(tmp & 14) { | |
$B = $CTX[tmp --]; | |
action = $CTX[tmp --] + (($B << 3) & 0x700); | |
$C = ($B & 31) - ($B & 16) * 2; | |
$A = $B - ($B & 128) * 2; | |
$B &= 255; | |
trace.expressions[ic & 15] += preset.instructions[action].expression | |
.replace(/(\$B)/g, "" + $B) | |
.replace(/(\$C)/g, "" + $C) | |
.replace(/(\$A)/g, "" + $A) | |
.replace(/true/g, "false") + ";\r\n"; | |
} | |
log("!/EVAL %s", trace.expressions[ic & 15]); | |
} | |
trace.is_freeze = true; | |
eval(trace.expressions[ic & 15]); | |
log("!/IT=%s IR=%s REG=%s", $IT.Hex(2), $IR.Hex(2), REG($IR).Hex(2)); | |
if(!(($IT != 8) && (!$IR || (REG($IR) != 1)))) | |
FL(FL() | 2); | |
//$EV = this.DO_CONTEXT; | |
//log("!/%d %d %d", it, ir, REG(ir)); | |
} | |
} else */{ | |
//if($IE == 3) | |
// $EV = this.DO_DEVICE;//scale = -scale; | |
eval(code.expression); | |
//code.envelope(this, $IP, $B, $C, $A, $IE, $IR, $IT); | |
//trace.expression = ""; | |
} | |
if($EV == DO_DEVICE) { | |
log("!/LOG $BRK"); | |
trace.pointer = IP(); | |
break; | |
} | |
if($EV == DO_ACCLAIM) { | |
log("!/LOG $HLT/INT"); | |
trace.pointer = IP(); | |
break; | |
} | |
tmp = FL(); | |
if($IE == 2 || $IE == 3) | |
log("!/FL %s %s", tmp.Hex(2), ctrl.Hex(2)), | |
FL((tmp & 0x2) | ctrl); | |
} else { // skip & fix | |
//$CTX.splice(0x0E, 2), | |
//$CTX.splice(0x02, 0, (ic & 0xFF), ((ic >> 3) & 0xE0) | ($A & 0x1F)); | |
if((trace.fixing > 1) && ((trace.fixing & 15) > 1)) { | |
$CTX[-- trace.fixing] = ((ic >> 3) & 0xE0) | ($A & 0x1F); | |
$CTX[-- trace.fixing] = ic & 0xFF; | |
} | |
} | |
if($IF && ($IE > 1)) { | |
FL((FL() & 2) | 5); | |
continue; | |
} | |
if($IE != 0) { | |
if((!!$IR || !!$IT) && ($IE == 2)) | |
//log("!/LOOP %d %s %s", it, $IP, $IP.Hex(4)), | |
IPnext($IP); | |
else | |
if((!!$IR || !!$IT) && ($IE == 3)) { | |
//log("!/WAIT %d %s %s - %s %s", it, $IP, $IP.Hex(4), FL().Hex(2), trace.ready); | |
if(!(FL() & 2)) { | |
IPnext($IP); | |
} else | |
//log("!/CLEAR FL"), | |
FL(FL() & 0x0E); | |
} | |
if(!$IR && !$IT) | |
if(!!(FL() >> 2) && !!(FL() & 1)) | |
FL(FL() & 0x0E); | |
else | |
FL(tmp); | |
} | |
} | |
if($FH >= 0) | |
log("de"), | |
FH($FH); | |
if($IR) { | |
if((i = REG($IR)) && $IE >= 1) | |
REG($IR, -- i); | |
if(i == 0 && $IE >= 1) | |
FL(FL() & 0xE); | |
} | |
/* if(tick < 2 && CR()) { | |
trace.active = true; | |
break; | |
} | |
*/ } | |
} catch(e) { | |
trace.active = true; | |
log("@/CORE/%s %s %s:%s ($C:%s $A:%s) %s\r\n%s", $IP.Hex(4), ic.Hex(3), $B.Hex(2), code.instruction, $C.Hex(2), $A.Hex(4), e, code.expression); | |
} | |
if(($EV == DO_DEVICE)) { | |
IPnext($IP); | |
FL(0x0D); | |
log("!/IPnext"); | |
} | |
if(($EV == DO_ACCLAIM)) { | |
IPnext($IP); | |
FL(0x0D); | |
log("!/IPnext"); | |
} | |
if(!!CR() && !$BRK) { | |
//log("!TASK#%d", CR()); | |
if(tick == 0 || $EV >= 0) { | |
$EV = $EV < 0 ? -$EV : +$EV; | |
console.log($EV); | |
switch($EV) { | |
case DO_OVERHEAD:log("!/CORE OVERHEAD");break; | |
case DO_ACCLAIM :log("!/CORE ACCLAIM"); break; | |
case DO_BUFFER :log("!/CORE BUFFER"); break; | |
case DO_CONTEXT :log("!/CORE CONTEXT"); break; | |
case DO_DEVICE :log("!/CORE DEVICE %s:%s", ctx[0][0xA8].Hex(2), $CTX[0xA8].Hex(2)); break; | |
case DO_ERROR :log("!/CORE ERROR"); break; | |
case DO_FORCE :log("!/CORE FORCE"); break; | |
case DO_GARRET :log("!/CORE GARRET"); break; | |
} | |
cr[1] |= 1 << $EV; | |
CR(0, CR(0) & 0x7F); | |
FL((FL() & 0x2) | 0x5), FH(0x8 | $EV); | |
log("!/CORE DEVICE %s", ctx[0][0xA8].Hex(2)); | |
} | |
//log("!TASK#%d", CR()); | |
} | |
if(tick >= 0) | |
//log("!/CORE tick"), | |
cr[6] = tick.lo(), | |
cr[7] = tick.hi(); | |
trace.step = false; | |
trace.pointer = IP(); | |
if(watch.active == "") | |
disassm(); | |
} | |
this.CR = CR; | |
this.step = step; | |
this.ram = function(handle, data) { | |
var ok = false; | |
var addr; | |
if(isFinite(handle) && typeof handle == "number") { | |
addr = handle; | |
if(isFinite(data)) { | |
log("#/RAM/[%04X]=%02X", addr, data); | |
return ram[addr & 0xFFFF] = data; | |
} else { | |
data = DB(addr); | |
log("#/RAM/[%04X]:%02X", addr, data); | |
return data; | |
} | |
} else | |
if(handle) { | |
try { | |
ram = handle; | |
for(addr = 0; addr < 65536; ++ addr) | |
trace.halt[addr] = false, | |
ram[addr] = isFinite(data) ? data : Math.random() * 256 & 0x97; | |
log("#/RAM/Initializing successful for %d bytes", addr); | |
ok = true; | |
} catch(e) { | |
log("@/Initializing crashed... %d", 5); | |
} | |
} else | |
return ram; | |
if(!ok) | |
throw new Error("654"); | |
return true; | |
} | |
function command_set(prefix, large) { | |
if(prefix && typeof prefix != "number") | |
return user.command_table = prefix; | |
var ic, ib, code, icx, | |
cols = 7, | |
i = 0, | |
dump = [], | |
Instructions = [], | |
operands = [], | |
Operation, Instruction, Operands; | |
var hPref = document.getElementById("Prefixes"), | |
hReps = document.getElementById("Repeats"); | |
var iPref = parseInt(hPref.value), | |
iReps = parseInt(hReps.value); | |
if(iPref >= 0) { | |
ib = iPref & 0xFF, | |
prefix = (iPref & 0x0F00) | (iReps); | |
} else | |
if(isFinite(prefix)) | |
ib = (prefix & 0x0E) == 0x0E ? prefix | 0xF0 : -257, | |
prefix = (prefix & 0x0E) == 0x0E ? 0 : (prefix & 0x7F) << 8, | |
ic = -1; | |
else { | |
prefix = 0x0000; | |
dump = parseInt(watch.address.value, 16); | |
if(!isFinite(dump)) | |
dump = 0xFF00; | |
if(ram[dump - 2] == 0xB8 && (ram[dump - 1] & 0xFE) == 0xFE) | |
prefix |= (ram[dump - 1] & 0x0E) << 8; | |
dump = watch.address.value.replace(/[0-9A-F]{4}/g, "").match(/([0-9A-F]{2})/g); | |
if(!dump) | |
dump = []; | |
dump.push(0, 0); | |
ic = parseInt(dump.shift(), 16); | |
if((ic || (cr[0] < 128)) && ic < 0x80 && (ic & 7) == (ic >> 4)) | |
prefix = ic ? (ic & 7) << 8 : 0x0800, | |
ic = parseInt(dump.shift(), 16), | |
ib = parseInt(dump.shift(), 16); | |
else | |
ib = parseInt(dump.shift(), 16), | |
prefix |= 0; | |
//prefix |= (FL() & 1 ? FL() >> 2 : 0) << 12; | |
prefix |= cr[0] < 128 ? 0x4000 : 0x0000; | |
dump = []; | |
} | |
for(code = 0; code < 256; ++ code) { | |
icx = prefix | code | ((ib & 0xFE) == 0xFE && code >= 0xB0 && code <= 0xBF && (prefix & 0x0F00) == 0x0000 ? (ib & 0x0F) << 8 : 0x0000); | |
Operation = preset.instructions[icx]; | |
if(!Operation) | |
Operation = { | |
instruction :"fault", | |
operands :"empty", | |
remark :"" | |
}; | |
Instruction = Operation.instruction + " ".Mul(cols); | |
Operands = Operation.operands.replace(/ACC/, "-- BH CH DH AL BL CL DL".split(" ")[(FL() >> 4) & 7]); | |
len = Operands.length - cols; | |
if(len > 0) | |
Instruction = Instruction.substr(0, cols - len) + Operands, | |
Operands = Operands.substr(-cols); | |
Instruction += " ", | |
Operands += " "; | |
over = Operation.remark; | |
// if(Operation.expression.indexOf("// ") >= 0) | |
// over = " title='" + Operation.expression.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">") + "'"; | |
// over = Operation.expression.substr(3 + Operation.expression.indexOf("// ")) + ((code >> 4) == (code & 15) && !(code & 8) && !prefix ? "\r\n[ALT+" + (code & 7) + "]" :"") + "\r\n"; | |
if(large) | |
over = " onmouseover='document.getElementById(\"Context\").innerText=cpu.preset.instructions[" + (prefix+code) + "].expression'"; | |
html = "<span title='" + over + "'class=CPU_Group_" + Operation.color + " " + ((code >> 4) == (code & 15) && code < 0x80 ? "onclick='cpu.command_set(" + (code & 7) + "," + large + ")'" : "") + over + ">#</span>"; | |
Instruction = Instruction.substr(0, cols); | |
Operands = Operands.substr(0, cols).replace(/(?:\$)(\+[1-7])/, function(str, high) { | |
high = parseInt(high); | |
return high < 4 ? "$+" + high : "$" + (high - (high & 4) * 2); | |
}).replace(/(\+)(IB)/, "\xB1$2"); | |
Instructions.push(html.replace("#", (ic == code ? "<b style=background-color:white><u style=color:black>" + Instruction + "</u></b>" : Instruction))); | |
operands.push(html.replace("#", (ic == code ? "<b style=background-color:white><u style=color:black>" + Operands.replace("IB", ib.Hex(2)) + "</u></b>" : Operands))); | |
if((code & 15) == 15) | |
dump.push("║" + ((large || code <= 0x10 ? "" : "<span style=text-decoration:overline>") + (code >> 4).Hex(1) + "║" + Instructions.join("│") + (large ? "" : "</span>") + "║<br />") | |
+ ("║ ║"+ operands.join("│") + "║").replace(/(IB|XX)/g, "<b style=color:cyan>$1</b>")), | |
Instructions = [], operands = []; | |
} | |
prefix >>= 8; | |
for(code = 0; code < 16; ++ code) | |
operands.push("╝" + code.Hex(1) + "╚════"); | |
watch.instructions.innerHTML = ("__lwSBLWS".charAt(prefix >> 4)) + (prefix & 15 ? (prefix & 7) + "+" : "__") + "╔═╗ ".Mul(16) + "<br />" + | |
"╔═╦" + operands.join("╤") + "╗<br />" + | |
dump.join(large ? "<br />╟─╫" + "─".Mul(cols).Mul(16, "┼") + "╢<br />" : "<br />") + | |
"<br />╚═╩" + "═".Mul(cols).Mul(16, "╧") + "╝"; | |
} | |
this.preset=preset; | |
//////// Assembler /////////////////////////////////////////// | |
this.assembly = function(listing, files) { | |
var text = listing.split(/\r?\n/), | |
Acc = 0, | |
Regs = { | |
BH :1, | |
CH :2, | |
DH :3, | |
AL :4, | |
BL :5, | |
CL :6, | |
DL :7 | |
}, | |
line, part, regs, args, code, regz, regy, regw, | |
val_nnIB, val_sxIB, val_s_IB, | |
instr, ins, | |
tmp, | |
dbg = true, // Debug mode | |
hlt = false, // Halting flag | |
arg, val, | |
rego, cnt, | |
regas, regaz, regay, regaw, regao, | |
ip, ipx, | |
labels = {}, // All labels | |
label, // Current label | |
labelz = {}, | |
laps = 8, | |
lap = laps, | |
prc = 0, | |
prcs = text.length * laps, | |
title = document.title, | |
file = { | |
name :"", | |
begin :65535, | |
end :0, | |
bin :[] | |
}, | |
bin = !files ? ram : file.bin; | |
log("!/ASSM/START"); | |
do { | |
ip = -1; label = []; | |
for(line in text) { | |
++ prc; | |
if(files && !lap && ip >= 0 && file.begin > ip) | |
file.begin = ip; | |
part = text[line]; | |
part = /([^:;"'`\s]*(?::| ?))?(?:\s)*([^\s;]*)(?:\s*)([^\s,;"'`]*)(?:[,\s]*)?([^\s,;"'`]*)(?:[,\s]*)?(?:(?:("(?:\\.|.)*?")|('(?:\\.|.)*?')|(`(?:\\.|.)*?`)|[^;"'`]*)*)*(\.*)/.exec(part); | |
if(part[1]) { | |
part[1] = part[1].replace(/[ :]$/, ""); | |
tmp = part[1].replace(/:/g, "..").match(/(\.*)(.*)/); | |
label = label.slice(0, tmp[1].length).concat(tmp[2].split(".")); | |
part[1] = label.join("."); | |
if(trace.labels[part[1]] != ip) | |
delete trace.labels[trace.labels[part[1].toUpperCase()]]; | |
trace.labels[ip] = part[1], | |
trace.labels[part[1].toUpperCase()] = ip; | |
/*labelz = {}; | |
cnt = 1 << 8; | |
do { | |
var idn = ""; | |
for(var id in trace.labels) | |
if((id.length > idn.length) && (id.substr(-1) != " ") && !labelz[id]) | |
idn = id; | |
else | |
continue; | |
//idn = (id.length > idn.length) && (id.substr(-1) != " ") && !labelz[id] ? id : idn; | |
if(idn != "") | |
labelz[idn] = trace.labels[idn]; | |
} while((cnt --) && (idn != ""));*/ | |
} | |
instr = part[2].toUpperCase(); | |
if(instr.substr(-1) == "?" || instr.substr(-1) == "!") { | |
if((dbg || (instr.substr(-1) == "!")) && !lap) | |
trace.halt[ip] = true; | |
instr = instr.substr(0, instr.length - 1); | |
} | |
regs = [part[2], part[3]].join(" ").toUpperCase(); | |
if(part[4]) | |
regs += "," + part[4].toUpperCase(); | |
if((regs = preset.alias[regs]) || (regs = preset.alias[instr])) { | |
regs = regs.split(" "); | |
for(var i in regs) { | |
if(typeof(regs[i]) == "string") | |
ram[ip ++] = parseInt(regs[i], 16); | |
} | |
continue; | |
} | |
part[3] = part[3].replace(/^(\.+)/, function(str, data) { | |
var data = data.length; | |
return label.slice(0, data).join(".") + "."; | |
}); | |
part[4] = part[4].replace(/^(\.+)/, function(str, data) { | |
var data = data.length; | |
return label.slice(0, data).join(".") + "."; | |
}); | |
regs = part[3]; | |
if(part[4]) | |
regs += "," + part[4]; | |
args = []; | |
try{ | |
regs = regs.replace(/(\.*)([A-Z_a-z][A-Z_a-z.0-9]*)/g, function(str, nest, tag) { | |
var tmp = trace.labels[label.slice(0, nest.length).concat(tag.split(".")).join(".").toUpperCase()]; | |
//console.log(ip.Hex(4) + " " +str + "::" + nest + ":" + tag + "=" + tmp); | |
if(isFinite(tmp)) | |
return Number(tmp).Hex(-4); | |
return nest + tag; | |
}); | |
/*for(var i in labelz) { | |
regs = regs.replace(new RegExp("("+i.replace(/(\.)/g, "\\.")+")", "gi"), function(str, data) { | |
return "0x" + Number(labelz[i]).Hex(4); | |
}); | |
}*/ | |
}catch(e){} | |
rego = regs; ipx = false; | |
regs = regs.replace(/\$([+-](0x[0-9A-F]+|[0-9]+))/g, function(str, data) { | |
ipx = true; | |
data = (ip + parseInt(data) - 1) & 0xFFFF; | |
args.push(data); | |
return "0x" + data.Hex(4); | |
}); | |
regs = regs.replace(/(0x[0-9A-F]+|[0-9]+)(\*|\/)(0x[0-9A-F]+|[0-9]+)+/g, function(str, x, op, y) { | |
return (op == "*" ? parseInt(x) * parseInt(y) : op == "/" && !!parseInt(y) ? parseInt(x) / parseInt(y) : 0x8000).Hex(-4); | |
}); | |
regs = regs.replace(/(0x[0-9A-F]+|[0-9]+)([+-])(0x[0-9A-F]+|[0-9]+)+/g, function(str, x, op, y) { | |
return (op == "+" ? parseInt(x) + parseInt(y) : parseInt(x) - parseInt(y)).Hex(-4); | |
}); | |
regs = regs.replace(/([-+](0x[0-9A-F]+|[0-9]+))/g, function(str, data) { | |
return "+" + (parseInt(data) + 256).Hex(-2); | |
}); | |
regs = regs.replace(/\+[ABCD][LH][-+]/i, (str) => { | |
Acc = Regs[str.substr(1, 2).toUpperCase()]; | |
return "+ACC" + str.substr(-1); | |
}); | |
ins = preset.mnemonics[instr]; | |
code = -1; | |
if(instr == "NOP") | |
console.log("mov"); | |
if(ins && (regs in ins)) | |
code = ins[regs]; | |
else | |
if(ins && (([part[3].toUpperCase(), "ACC"].join(",") in ins) || (["ACC", part[4].toUpperCase()].join(",") in ins))) { | |
console.log("ACC", part[3], part[4]); | |
if(part[4].toUpperCase() in preset.mnemonics["HLT"]) { | |
code = preset.mnemonics["HLT"][part[4].toUpperCase()]; | |
console.log(code.Hex(4)); | |
code = 0x00008000 | code | (ins[[part[3].toUpperCase(), "ACC"].join(",")] << 16) | 0x20000000; | |
console.log(code.Hex(8)); | |
} else | |
if(part[3].toUpperCase() in preset.mnemonics["HLT"]) { | |
code = preset.mnemonics["HLT"][part[3].toUpperCase()]; | |
console.log(code.Hex(4)); | |
code = 0x00008000 | code | (ins[["ACC", part[4].toUpperCase()].join(",")] << 16) | 0x20000000; | |
console.log(code.Hex(8)); | |
} | |
} else { | |
arg_nnIB = regs.replace(/(0x[0-9A-F]+)|([0-9]+)/gi, function(str, data) { // nnIB | |
var bin0 = parseInt(data); | |
var tag0 = regs.replace(/\+(0x[0-9A-F]+|[0-9]+)/, "+IB"); | |
var bin1 = parseInt(data); | |
var tag1 = bin1.hi().Hex(2) + "IB"; | |
var bin2 = parseInt(data) + (ipx ? -ip- 3 : -ip - 2); | |
var tag2 = "$+IB"; | |
var bin3 = parseInt(data) + (ipx ? -ip- 4 : -ip - 3); | |
var bin3a = bin3 + (bin3 < -128 ? +(bin3 & 0x80) * 2 : bin3 >= 128 ? +(bin3 & 0x80) * 2 : 0); | |
var tag3 = "$+" + ((bin3a >> 8) & 7) + "IB"; | |
if(ins) { | |
if(tag0 in ins) | |
return args.push(bin0) ? "IB" : "IB"; | |
if(tag1 in ins) | |
return args.push(bin1) ? tag1 : tag1; | |
if(bin2 >= -128 && bin2 < 128 && (tag2 in ins)) | |
return args.push(bin2.lo()) ? tag2 : tag2; | |
if(((bin3 >= -1024 && bin3 < -128) || (bin3 >= 128 && bin3 <= 895)) && (tag3 in ins)) | |
return args.push(bin3.lo()) ? tag3 : tag3; | |
if("IB" in ins) | |
return args.push(bin1) ? "IB" : "IB"; | |
if(part[4] && (regs.split(",")[0] + ",IB") in ins) | |
return (code = ins[part[3] + ",IB"]) && args.push(bin1) ? "" : ""; | |
if("" in ins) | |
return ""; | |
} | |
args.push(bin1); | |
return ""; | |
}); | |
if(ins && (arg_nnIB in ins)) | |
code = ins[arg_nnIB]; | |
else | |
if(part[4] && ins && ([part[4].toUpperCase(), part[3].toUpperCase()].join(",") in ins)) | |
code = ins[[part[4].toUpperCase(), part[3].toUpperCase()].join(",")]; | |
else | |
if(part[4] && ins && (part[3].toUpperCase() in ins) && (part[4].toUpperCase() in ins)) | |
code = ins[part[3].toUpperCase()] | (ins[part[4].toUpperCase()] << 16); | |
else | |
if(ins && (part[3].toUpperCase() in ins)) | |
code = ins[part[3].toUpperCase()]; | |
else | |
if(part[4] && ins && (regs.toUpperCase() in ins)) | |
code = ins[regs.toUpperCase()]; | |
else | |
if(ins && ((arg_nnIB = arg_nnIB.replace(/(\[[A-Z]{2})(\])/ig, "$1+IB$2")) in ins)) | |
code = ins[arg_nnIB], args.unshift(0); | |
} | |
switch(instr) { | |
case "FILE": file.name = regs; continue; | |
case "DEBUG":dbg = !!parseInt(regs); continue; | |
case "ORG": ip = args.shift(); continue; | |
case "EQU": labels[part[1].toUpperCase()] = args.shift(); continue; | |
case "BRK": if(files && dbg && !lap) trace.halt[ip] = !!parseInt(regs); continue; | |
case "DB": | |
if(part[5]) { | |
args = part[5].replace(/Ё/ig, "Е").replace(/[абвгдеёжзийклмнопрстуфхцчшщъыьэюя]/ig, function(str, ascii) { | |
var koi7ru = "ЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ", | |
data = koi7ru.indexOf(ascii); | |
if(data < 0) | |
return ascii; | |
return String.fromCharCode(ascii + 0x60); | |
}).split(""); | |
args.shift(); args.pop(); | |
while(args.length) { | |
tmp = args.shift(); | |
code = tmp.charCodeAt(0); | |
if(tmp == "\\") | |
switch(tmp = args.shift()) { | |
case '0': code = 0x00; break; | |
case 't': code = 0x09; break; | |
case 'n': code = 0x0A; break; | |
case 'h': code = 0x0C; break; | |
case 'r': code = 0x0D; break; | |
case 'e': code = 0x1B; break; | |
case '_': code = 0x1F; break; | |
case '<': code = 0x08; break; | |
case '>': code = 0x18; break; | |
case '^': code = 0x19; break; | |
case 'v': code = 0x1A; break; | |
default: code = tmp.charCodeAt(0); | |
} | |
trace.text[ip] = true, | |
bin[ip ++] = code; | |
} | |
} else | |
while(args.length) | |
trace.text[ip] = true, | |
bin[ip ++] = args.shift(); | |
continue; | |
case "DW": | |
while(args.length) | |
tmp = args.shift(), | |
trace.text[ip] = true, | |
bin[ip ++] = tmp.lo(), | |
trace.text[ip] = true, | |
bin[ip ++] = tmp.hi(); | |
continue; | |
} | |
hlt = !lap; | |
if((code & 0x0E00) == 0x0E00) | |
args.unshift((0xF000 | code) >> 8); | |
if(code >= 0) { | |
do { | |
if(!files) | |
trace.halt[ip] &= hlt; | |
switch(code & 0x3000) { | |
case 0x2000: | |
trace.text[ip] = false, | |
bin[ip ++] = 0xE0 + Acc, | |
trace.halt[ip] = false; | |
break; | |
case 0x3000: | |
trace.text[ip] = false, | |
bin[ip ++] = 0xB8, | |
trace.halt[ip] = false, | |
trace.text[ip] = false, | |
bin[ip ++] = 0xFE, | |
trace.halt[ip] = false; | |
break; | |
} | |
if((code & 0x0F00) == 0x0800) | |
bin[ip ++] = 0x00; | |
if((code & 0x0F00) > 0x0000 && (code & 0x0F00) <= 0x0700) | |
trace.text[ip] = false, | |
bin[ip ++] = ((code >> 8) & 7) * 0x11, | |
trace.halt[ip] = false; | |
trace.text[ip] = false, | |
bin[ip ++] = code & 0xFF; | |
if(((code & 0x00C0) == 0x080) && args.length > 0) | |
trace.text[ip] = false, | |
trace.halt[ip] = false, | |
bin[ip ++] = args.shift(); | |
} while((code & 0x8000) && (code >>= 16)); | |
} | |
if(files && !lap && ip >= 0 && file.end < end) | |
file.end = ip; | |
//if(Math.floor(100 * prc / prcs) <= 100) | |
// document.title = Math.floor(100 * prc / prcs) + "%"; | |
} | |
} while(lap --); | |
document.title = title; | |
log("!/ASSM/FINISH"); | |
disassm(); | |
if(files) | |
return file; | |
} | |
function microdis() { | |
var i, ic, ib, z, asm; | |
var cmd = []; | |
i = (trace.expression << 4); | |
return cmd;//////////////////////////////////////////////////////////////////////////// | |
while((i += 2) & 0x0F) { | |
ic = $CTX[i] & 0xFF, ib = $CTX[i + 1] & 0xFF; | |
ic |= (ib & 0xE0) << 3; | |
ib = (ib & 0x1F) - (ib & 0x10) * 2; | |
z = preset.instructions[ic]; | |
asm = (z.instruction + " ").substr(0, 5) + z.operands; | |
asm = asm.replace(/([^$])\+IB/, function(str, ptr, rel) { | |
return ib < 128 ? ptr + "+" + ib : ptr + (ib - 256); | |
}); | |
asm = asm.replace(/([0-9A-F]{2})IB/, "0x$1" + ib.Hex(2)); | |
asm = asm.replace(/(\$\+)?([0-7]?IB)/, function(str, rel) {//$+0IB $+IB 0IB | |
var data, len = str.length; | |
data = (len == 3 || len == 5 ? +(str.substr(-3, 1)) * 256 : 0); | |
if(len == 3 || len == 5) | |
data = (data - (data & 0x400) * 2) + (ib - (ib & 0x80) * 2); | |
else | |
data = (data - (data & 0x80) * 2) + (ib - (ib & 0x80) * 2); | |
//data -= (len == 3 || len == 5 ? data & 0x400 : len == 2 ? 0 : data & 0x80) * 2; | |
//data += (ib - (ib & 128) * 2);// - (len == 2 ? 0 : (ib & 128) * 2); | |
return rel ? (i + data).Hex(-4) : data.Hex(len == 3 || len == 5 ? -3 : -2); | |
}); | |
cmd.unshift(asm); | |
} | |
return cmd; | |
} | |
//////// Disassembler //////////////////////////////////////// | |
function disassm() { | |
var i, j, | |
addr = (trace.pointer &= 0xFFFF), // active IP | |
ip = trace.address & 0xFFFF, lines = trace.lines, next = ip, | |
jp, | |
alias, walias, | |
list = [], lp, width, | |
regs = [], | |
ips = [], | |
lid, // label id | |
ic, ib = 0, ie, asm, | |
active = addr.Hex(4) + " " + ram[addr].Hex(2), | |
extend = "", | |
color, | |
rem = "", row, halt, | |
cmm = "", | |
acc = "???", cnt = 0, Cnt = "", wait = false; | |
if(ip > addr) | |
ip = trace.address = (addr + 0xFFF0) & 0xFFFF; | |
if("PTR".indexOf(watch.active) >= 0) { | |
i = 2; | |
active = true||this.w.rg < 0 ? " style=background-color:#252>" : this.w.xx == this.r16(this.w.rg) ? " style=background-color:blue>" : " style=background-color:red>"; | |
if(extend) | |
regs.push(extend); | |
else | |
regs.push((jp = SP()).Hex(4) + " <u>" + ram.Dump(jp - i, i)+ "</u>[SP]" + ram.Dump(jp, 8) + "|" + ram.Dump(jp + 8, 8) + "<u>" + ram.Text(jp - i, i) + "</u>" + ram.Text(jp, 16)); | |
jp = BP(), rem = "BP", regs.push(jp.Hex(4) + " <u>" + ram.Dump(jp - i, i)+ "</u>[" + rem + "]" + ram.Dump(jp, 8) + "|" + ram.Dump(jp + 8, 8) + "<u>" + ram.Text(jp - i, i) + "</u>" + ram.Text(jp, 16)); | |
jp = SI(), rem = "SI", regs.push(jp.Hex(4) + " <u>" + ram.Dump(jp - i, i)+ "</u>[" + rem + "]" + ram.Dump(jp, 8) + "|" + ram.Dump(jp + 8, 8) + "<u>" + ram.Text(jp - i, i) + "</u>" + ram.Text(jp, 16)); | |
jp = DI(), rem = "DI", regs.push(jp.Hex(4) + " <u>" + ram.Dump(jp - i, i)+ "</u>[" + rem + "]" + ram.Dump(jp, 8) + "|" + ram.Dump(jp + 8, 8) + "<u>" + ram.Text(jp - i, i) + "</u>" + ram.Text(jp, 16)); | |
regs.push(AX().Hex(4) + " " + flags()); | |
jp = BX(), rem = "BX", regs.push(jp.Hex(4) + " <u>" + ram.Dump(jp - i, i)+ "</u>[" + rem + "]" + ram.Dump(jp, 8) + "|" + ram.Dump(jp + 8, 8) + "<u>" + ram.Text(jp - i, i) + "</u>" + ram.Text(jp, 16)); | |
jp = CX(), rem = "CX", regs.push(jp.Hex(4) + " <u>" + ram.Dump(jp - i, i)+ "</u>[" + rem + "]" + ram.Dump(jp, 8) + "|" + ram.Dump(jp + 8, 8) + "<u>" + ram.Text(jp - i, i) + "</u>" + ram.Text(jp, 16)); | |
jp = DX(), rem = "DX", regs.push(jp.Hex(4) + " <u>" + ram.Dump(jp - i, i)+ "</u>[" + rem + "]" + ram.Dump(jp, 8) + "|" + ram.Dump(jp + 8, 8) + "<u>" + ram.Text(jp - i, i) + "</u>" + ram.Text(jp, 16)); | |
jp = IP(), rem = "IP", regs.push(jp.Hex(4) + " <u>" + ram.Dump(jp - 0, i)+ "</u>[" + rem + "]" + ram.Dump(jp & 0xFFF0, 8) + "|" + ram.Dump((jp & 0xFFF0) + 8, 8) + " " + ram.Text(jp & 0xFFF0, 16)); | |
//jp = IP() + 16, rem = "IP", regs.push(jp.Hex(4) + " <u>" + ram.Dump(jp - 0, i)+ "</u>[" + rem + "]" + ram.Dump(jp & 0xFFF0, 8) + "|" + ram.Dump((jp & 0xFFF0) + 8, 8) + " " + ram.Text(jp & 0xFFF0, 16)); | |
//jp = IP() + 32, rem = "IP", regs.push(jp.Hex(4) + " <u>" + ram.Dump(jp - 0, i)+ "</u>[" + rem + "]" + ram.Dump(jp & 0xFFF0, 8) + "|" + ram.Dump((jp & 0xFFF0) + 8, 8) + " " + ram.Text(jp & 0xFFF0, 16)); | |
//jp = IP() + 48, rem = "IP", regs.push(jp.Hex(4) + " <u>" + ram.Dump(jp - 0, i)+ "</u>[" + rem + "]" + ram.Dump(jp & 0xFFF0, 8) + "|" + ram.Dump((jp & 0xFFF0) + 8, 8) + " " + ram.Text(jp & 0xFFF0, 16)); | |
regs = regs.concat(ctx[cr[0] & 127].Dump().split(/\r?\n/)); | |
command_set(); | |
} | |
lines -= regs.length; | |
for(i = 0, jp = ip; i < lines - 2 || jp < addr; ++ i) { | |
ie = 0; | |
ips.push(jp); | |
ic = ram[jp], jp = (jp + 1) & 0xFFFF; | |
if((ic || !(cr[0] & 0x80)) && (ic & 7) == (ic >> 4)) | |
ie |= ic & 7 ? ic & 7 : 8; | |
if(ie) | |
ic = ram[jp], jp = (jp + 1) & 0xFFFF; | |
if((ic & 0xC0) == 0x80) | |
jp = (jp + 1) & 0xFFFF; | |
} | |
if(ips.length > lines - 2) | |
ip = trace.address = ips.pop(); | |
walias = 0; | |
while(lines -- > 0) { | |
if(!lines) | |
this.DIP = ip, ip = addr & 0xFFFF; | |
jp = ip; | |
row = [ip.Hex(4)]; | |
rem = ""; | |
cmm = []; | |
ie = 8; | |
if(typeof trace.labels[ip] == "string") | |
cmm[1] = trace.labels[ip] + ":"; | |
if(walias < 1) { | |
alias = ""; | |
walias = 6; | |
data = [ram[ip].lo().Hex(2), ram[(ip + 1) & 65535].lo().Hex(2), ram[(ip + 2) & 65535].lo().Hex(2), ram[(ip + 3) & 65535].lo().Hex(2), ram[(ip + 4) & 65535].lo().Hex(2), ram[(ip + 5) & 65535].lo().Hex(2)].join(""); | |
do { | |
if(data in preset.alias) { | |
alias = preset.alias[data]; | |
rem = alias.split(/\t/)[1]; | |
alias = alias.split(/\t/)[0]; | |
extend = alias.split(/\s|!/); | |
if(extend[1]) { | |
extend = extend[1].replace(/(?:\[)([0-7])(?:\])/g, "$1").split(/[\s\t,]/); | |
extend.push("--", "--"); | |
if(rem) | |
rem = rem.replace(/\%X/g, extend[0]).replace(/\%Y/g, extend[1]); | |
break; | |
} | |
} | |
data = data.substr(0, -- walias * 2); | |
} while(walias); | |
} | |
halt = true && trace.halt[ip]; | |
lp = ip == addr; | |
if(trace.text[ip]) { | |
i = 0; | |
while(i < 29 && trace.text[ip]) { | |
if(ram[ip] < 32 || ram[ip] > 128) | |
row.push(ram[ip].Hex(2)); | |
lp |= ip == addr; | |
++ i, ++ ip; | |
} | |
row.push("..", "..", ".."); | |
asm = ram.Text(ip - i, i) + String.fromCharCode(0xB7).Mul(29 - i); | |
asm = row.slice(0, 4).join("\\") + "|" + asm + "|Text"; | |
if(lines) | |
list.push("<span class=CPU_Group_Z>" + asm + "</span>"); | |
if(lp) | |
active = asm; | |
continue; | |
} | |
if((ram[ip - 2] & 0xFF) == 0xB8 && (ram[ip - 1] & 0xFF) == 0xFE) | |
ie = 0x30;//(ram[ip - 1] & 0x0F) << 8; | |
else | |
ie = 0x00; | |
ic = ram[ip].lo(), ip = (ip + 1) & 0xFFFF, | |
walias --; | |
if((ic || !(cr[0] & 0x80)) && (ic & 7) == (ic >> 4)) | |
ie |= ic & 7 ? ic & 7 : 8, | |
lp |= ip == addr, | |
halt |= true && trace.halt[ip], | |
row.push(ic.Hex(2)), | |
ic = ram[ip].lo(), ip = (ip + 1) & 0xFFFF, | |
row.push(ic.Hex(2)), | |
acc = ic == 0 ? "?? BH CH DH AL BL CL DL".split(" ")[ie & 7] : acc, | |
cnt = ic & 7, | |
walias --; | |
else | |
row.push(" ", ic.Hex(2)); | |
if((ic & 0xC0) == 0x80) | |
lp |= ip == addr, | |
halt |= true && trace.halt[ip], | |
ib = ram[ip].lo(), ip = (ip + 1) & 0xFFFF, | |
ie |= (ic & 0xF0) == 0xB0 && (ib & 0xFE) == 0xFE && (ie & 7) == 0 ? ib & 0x0F : 0x00, | |
row.push(ib.Hex(2)), | |
walias --; | |
if(Cnt != "" && preset.instructions[(ie << 8) | ic | 0x2000]) | |
ic |= 0x2000; | |
z = preset.instructions[(ie << 8) | ic]; | |
if(!z) | |
z = { | |
instruction :"fault", | |
operands :"empty" | |
}; | |
asm = (z.instruction + " ").substr(0, 5) + z.operands; | |
asm = asm.replace(/(ACC)/, function() { return Cnt != "" ? Cnt : acc; }); | |
asm = asm.replace(/(CNT)/, function() { return cnt; }); | |
if(z.instruction == "HLT" && z.operands != "") | |
acc = z.operands; | |
asm = asm.replace(/([^$])\+IB/, function(str, ptr, rel) { | |
return ib < 128 ? ptr + "+" + ib : ptr + (ib - 256); | |
}); | |
asm = asm.replace(/([0-9A-F]{2})IB/, "0x$1" + ib.Hex(2)); | |
asm = asm.replace(/(\$\+)?([0-7]?IB)/, function(str, rel) {//$+0IB $+IB 0IB | |
var data, len = str.length; | |
data = (len == 3 || len == 5 ? +(str.substr(-3, 1)) * 256 : 0); | |
if(len == 3 || len == 5) | |
data = (data - (data & 0x400) * 2) + (ib - (ib & 0x80) * 2); | |
else | |
data = (data - (data & 0x80) * 2) + (ib - (ib & 0x80) * 2); | |
//data -= (len == 3 || len == 5 ? data & 0x400 : len == 2 ? 0 : data & 0x80) * 2; | |
//data += (ib - (ib & 128) * 2);// - (len == 2 ? 0 : (ib & 128) * 2); | |
return rel ? (ip + data).Hex(-4) : data.Hex(len == 3 || len == 5 ? -3 : -2); | |
}); | |
if(ic > 0xE0 && ic <= 0xE7) | |
cnt = ic & 7, Cnt = "-- BH CH DH AL BL CL DL".split(" ")[cnt]; | |
else | |
Cnt = ""; | |
//cmm[1] = (ie+ic).Hex(4); | |
if(!cmm[1]) { | |
lid = asm.match(/(0x[0-9A-F]{4})/); | |
if(lid) { | |
// log("!/DIS:%s %s", lid[0], trace.labels[parseInt(lid[0])]); | |
if(typeof trace.labels[parseInt(lid[0])] == "string") | |
cmm[1] = "(" + trace.labels[parseInt(lid[0])] + ")"; | |
}; | |
} | |
width = row.length; | |
while(row.length < 4) | |
row.push(" "); | |
// if(!cmm[1]) | |
// cmm = z.expression.split("// "); | |
if(!cmm[1]) | |
cmm[1] = z.remark; | |
if(alias != "") { | |
data = alias.split(/[!\s]/); | |
asm = asm.split(/\s+/); | |
asm = asm.join(" ".Mul(5 - asm[0].length)); | |
asm = (data[0] + " ".Mul(4)).substr(0, 5) + (data[1] + " ".Mul(7)).substr(0, 7) + ";" + (asm + " ".Mul(16)).substr(0, 16);//, rem = ""; | |
//asm = (data.replace("!", "") + " ".Mul(7)).substr(0, 9) + (" ".Mul(16) + asm.replace(/\s+/g, " ")).substr(-18), rem = ""; | |
} | |
if(rem == "") | |
if(cmm[1]) { | |
if(rem.split(" ")[0] == z.instruction) | |
asm += "/" + rem.split(" ")[1]; | |
else | |
if(rem) | |
asm += " ".Mul(16 - asm.length) + ";" + rem; | |
else | |
rem = cmm[1];//z.expression.substr(3 + z.expression.indexOf("// ")); | |
} | |
if(walias >= 0 && alias == "") | |
asm = row.join(" ") + "|" + " ".Mul(12) + ";" + (asm + " ".Mul(16)).substr(0, 16) + "|" + rem; | |
else | |
asm = row.join(" ") + "|" + (asm + " ".Mul(29)).substr(0, 29) + "|" + rem; | |
alias = ""; | |
if(lp) | |
active = asm; | |
color = (watch.dirty || (watch.active == "")) && (walias < 0) ? z.color : "Z"; | |
asm = "<span class='CPU_Group_" + color + (halt ? " halted" : "") + (lp ? " active" : "") + "' onclick='cpu.trace.halt[" + jp + "] ^= true; cpu.disassm()' ondblclick='cpu.trace.pointer = " + jp + "'>" + asm + "</span>"; | |
// asm = "<span class='CPU_Group_" + z.color + (halt ? " halted" : "") + (lp ? " active" : "") + " title='style=text-decoration:overline><u'>" + asm + "</span>"; | |
if(lp) { | |
/* if(ie && (ic & 0xEF) == 0xEA) { | |
i = (AX() >> 12) & 15; | |
i = i < 8 ? this.reg(i) : i + 248; | |
extend = (i & 256 ? "EX#" + i.Hex(1) : "Ex" + i.Hex(2)) + " <u>"; | |
{ | |
extend += (i >= 256 && i > 257) || (i < 256 && i >= 2) ? this.r.ex[i - 2].Hex(2) + " " : "?? "; | |
extend += (i >= 256 && i > 256) || (i < 256 && i >= 1) ? this.r.ex[i - 1].Hex(2) : "??"; | |
extend += "</u>[RX]"; | |
for(j = 0; j < 16; ++ j) | |
extend += (j ? (j & 0xFF) == 1 ? "|" : " " : "") + ((i < 256 && i + j < 256) || (i >= 256 && i + j < 264) ? this.r.ex[i + j].Hex(2) : "??"); | |
extend += " "; | |
for(j = 0; j < 16; ++ j) | |
extend += String.fromCharCode(i >= 256 | (i + j) > 255 ? 0xB7 : this.r.ex[i + j] >= 32 && this.r.ex[i + j] < 127 ? this.r.ex[i + j] : 0xB7); | |
} | |
}*/ | |
}// else asm = "<span class=CPU_Group_" + z.color + " onclick='document.getElementById(\"DebugAddr\").value=(cpu.DR=" + parseInt(asm, 16) + ").Hex(4)' title='Set break point'>" + asm + "</span>"; | |
//if(halt) | |
// asm = "<s>" + asm + "</s>"; | |
//asm = "<span class=prefix onclick='document.getElementById(\"DebugAddr\").value=(cpu.DR=" + parseInt(asm, 16) + ").Hex(4)' title='Set break point'>" + asm + "</span>"; | |
if(!list.length) | |
next = ip; | |
if(lines) | |
list.push(asm); | |
} | |
watch.disassembly.innerHTML = list.concat(regs).join("<br />"); | |
var inter = active.split("|"); | |
if(watch.active != "P") | |
watch.address.value = inter.shift().replace(/\s+$/, ""); | |
else | |
inter.shift(); | |
if(watch.active != "T") | |
watch.mnemonic.value = inter.shift().replace(/\s+/g, "\t").replace(/\s+(\(.*)?$/, ""); | |
else | |
inter.shift(); | |
if(watch.active != "R") | |
watch.remark.value = inter.shift().replace(/\s+$/, ""); | |
if(!(watch.active in "012345678".split(""))) | |
command_set(); | |
//watch.dirty = true; | |
} | |
this.display = function(callback) { | |
display = callback; | |
display(this); | |
} | |
this.interface = function(controls) { | |
watch.instructions = controls.instructions || watch.instructions; | |
watch.disassembly = controls.disassembly || watch.disassembly; | |
watch.registers = controls.registers || watch.registers; | |
watch.address = controls.address || watch.address; | |
watch.mnemonic = controls.mnemonic || watch.mnemonic; | |
watch.remark = controls.remark || watch.remark; | |
watch.context = controls.context || watch.context; | |
} | |
////////////////////////////////////// | |
this.command_set = command_set; | |
this.disassm = disassm; | |
this.JP = JP; | |
this.trace = trace; | |
this.watch = watch; | |
this.log = log; | |
this.ctx = ctx; | |
this.preset = preset; | |
////////////////////////////////////// | |
i = ctx.length; | |
while(i --) { | |
ctx[i] = new Array(j = 256); | |
while(j --) | |
ctx[i][j] = Math.random() * 0*256 & 255; | |
} | |
log("!/POWER/CONTEXT[%d]", ctx.length); | |
DEBUG_TIMER(true); | |
if(descriptions) { | |
var instructions = /^([0X1_]{19,})([A-F_X])\t([^:+\t]+)(\+?)\t*([^:\t]*?)\t*:(.*)(\/\/.*)$/gm; | |
var Register = []; // Register alias | |
var Logic = []; // Logic alias | |
var text = []; | |
var Pin = { | |
$M :0, | |
$T :0, | |
$U :0, | |
$V :0, | |
$W :0, | |
$X :0, | |
$Y :0, | |
$Z :0 | |
}; | |
var Pins = []; | |
var Registers = []; | |
var Logics = []; | |
var schema = descriptions; | |
var decoder = schema.match(instructions); | |
for(var id in Pin) | |
Pins.push(id); | |
schema = schema.replace(/^ASCx([0-9A-F]{4})(( ([0-9A-F]{2})){16})/gm, function(str, address, bytes) { | |
var addr = parseInt(address, 16); | |
bytes.substr(1).split(" ").forEach(function(code) { | |
preset.ascii[addr ++] = parseInt(code, 16); | |
}); | |
return ""; | |
}); | |
schema = schema.replace(/^([A-Z]+[0-9 A-Z\[,\]!]*)\t+?\@([0-9A-F\s\t]+?(\t.*)?)$/gm, function(str, alias, instr) { | |
preset.alias[alias.replace(/(!)(.)/, " $2").replace(/!/, "")] = instr.replace(/\t.*/, ""); | |
instr = instr.split(/\t+/); | |
preset.alias[instr[0].replace(/\s+/g, "")] = alias + (instr[1] ? "\t" + instr[1] : ""); | |
//console.log(alias + "=" + instr + " / (" + alias.replace(/(!)(.)/, " $2").replace(/!/, "") + ")"); | |
return ""; | |
}); | |
schema = schema.replace(/^([^\s]{1,13})\t(.*)$/gm, function(str) { | |
var str = str.split(/\t+/); | |
Registers.push(str[0]); | |
Register[str[0]] = str[1]; | |
if(str[3]) | |
Logics.unshift(str[0] + "!"), | |
Logic[str[0] + "!"] = str[3]; | |
if(str[2]) | |
Logics.push(str[0]), | |
Logic[str[0]] = str[2]; | |
text.push([str].join("\t")); | |
return ""; | |
}); | |
Pins = new RegExp("(" + Pins .join("|").replace(/(\$)/g, "\\$1") + ")", "g"); | |
Registers = new RegExp("(" + Registers .join("|").replace(/(\$)/g, "\\$1") + ")", "g"); | |
Logics = new RegExp("(" + Logics .join("|").replace(/(\$)/g, "\\$1") + ")", "g"); | |
var base, | |
over, | |
last, | |
mix, | |
bits, | |
laps, | |
lap, | |
counter, cnt, | |
mask; | |
var $D, // MMMLLLKZZZJYYYIXXX | |
$X, // ---------------XXX | |
$I, // --------------I--- | |
$Y, // -----------YYY---- | |
$J, // ----------J------- | |
$Z, // -------ZZZ-------- | |
$K, // ------K----------- | |
$L, // ---LLL------------ | |
$M; // MMM--------------- | |
var $1, $2; | |
var instruction, | |
operand, | |
expression, | |
description, | |
alias, xalias, | |
logic; | |
decoder.forEach(function(str) { | |
str.replace(instructions, | |
function(str, pins, groups, mnemonics, few, operands, expressions, descriptions) { | |
pins = pins.replace(/_+/g, ""); | |
base = parseInt(pins.replace(/X/g, "0"), 2), // 0XX1X0X1XX -> 0001000100 | |
over = parseInt(pins.replace(/X/g, "1"), 2), // 0XX1X0X1XX -> 0111101111 | |
last = parseInt(pins.replace(/./g, "1"), 2), // 0XX1X0X1XX -> 1111111111 | |
mix = base ^ over ^ last; // 1001010100 | |
/*bits = [], | |
laps = 1, | |
mask = parseInt(pins.replace(/X/g, | |
function(str, position, digits) { | |
bits.push(1 << (digits.length - position - 1)); | |
laps <<= 1; | |
return "0"; | |
}), 2); | |
for(lap = 0; lap < laps; ++ lap) { | |
counter = bits.length, | |
$D = mask, cnt = lap; | |
while(counter --) | |
$D |= cnt & 1 ? bits[counter] : 0, | |
cnt >>= 1;*/ | |
for($D = base; $D <= over; $D = ((($D | mix) + 1) & ~mix) | base) { | |
$X = 0x07 & ($D >> 0), | |
$I = 0x01 & ($D >> 3), | |
$Y = 0x07 & ($D >> 4), | |
$J = 0x01 & ($D >> 7), | |
$Z = 0x0F & ($D >> 8), | |
$z = 0x07 & ($D >> 8), | |
$L = 0x07 & ($D >> 12), | |
$M = $J ? ($Y < 4 ? $Y : !$I ? 4 : 4 | [0, 0, 1, 3, 3, 3, 2, 2][$X]) | |
: (!$Y && ($X == $Z)) || (!$X && ($Y == $Z)) ? 3 | |
: ($X == $Y ? $Y == ($L & 4 ? $Z : $z) ? 7 : $Y > $z ? 5 : 6 : $X < $Y ? 1 : 2), | |
Pin.$T = $Z * 10 + ($D & 15), | |
Pin.$U = $Z ? (($Z - ($Z & 4) * 2) & 7).Hex(1) : "", | |
Pin.$V = ($Z * 16 ^ ($D & 15) ^ (($D & 16) ? 0xF0 : 0x00)).Hex(2), | |
Pin.$W = ($D & 31).Hex(2), | |
Pin.$X = $X, | |
Pin.$Y = $Y, | |
Pin.$Z = $Z; | |
Pin.$M=$M; | |
/// console.log($D.Hex(5) + ":" + $M); | |
if(((($D >> 15) & 7) == ($M & 7)) && !preset.instructions[$D & 0x7FFF]) { | |
instruction = mnemonics .replace(Pins ,function(str, id) { return Pin[id]; }); | |
operand = operands .replace(Pins ,function(str, id) { return Pin[id]; }); | |
expression = expressions .replace(Pins ,function(str, id) { return Pin[id]; }); | |
description = descriptions .replace(Pins ,function(str, id) { return Pin[id]; }); | |
instruction = instruction .replace(Registers ,function(str, id) { return Register[id]; }); | |
operand = operand .replace(Registers ,function(str, id) { return Register[id]; }); | |
description = description .replace(Registers ,function(str, id) { return Register[id]; }); | |
expression = expression .replace(Logics | |
,function(str, id) { | |
logic = Logic[id]; | |
if(typeof logic == "string") | |
logic = logic .replace(Pins ,function(str, id) { return Pin[id]; }); | |
return logic; | |
}); | |
if(mnemonics == "HLT") | |
console.log(`M :${$M}`); | |
//console.log(expression); | |
// console.log([groups, ("0".Mul(17) + ($D & 0x7FFF).toString(2)).substr(-18), instruction, operand, expression, description].join("\t")); | |
/*if(operand.indexOf(" ") > 0) { | |
console.log(operand); | |
$1 = operand.split(",")[0].split(/\s/); | |
$2 = operand.split(",")[1].split(/\s/); | |
if($1[0] in preset.mnemonics) { | |
} else | |
if($2[0] in preset.mnemonics) { | |
console.log($2[0] + "(" + $2[1] + ")"); | |
console.log(preset.mnemonics[$2[0]]); | |
for(var N = 1; N <= 7; ++ N) { | |
$2[1] = "" + N;//$2[1].replace(/(\$N)/g, function(str, n) {console.log(str,n,N); return "/"+N;});//.replace(Pins ,function(str, id) { return Pin[id]; }); | |
console.log(N + ":" + $2); | |
console.log(preset.mnemonics[$2[0]][$2[1]]); | |
} | |
} | |
}*/ | |
try { | |
preset.instructions[$D & 0x7FFF] = { | |
color : groups, | |
instruction : instruction, | |
operands : operand.replace(/\{0\}/, "").replace(/\{(.+)\}/, "$1"), | |
expression : expression, | |
envelope : new Function("_, $IP, $B, $C, $A, $IE, $IR, $IT", "with(_) {" + expression + ";} return true;"), | |
remark : description.replace(/^\/\//, "") | |
}; | |
} catch(e) { | |
console.log($D.Hex(4) + ":" + expression); | |
} | |
if(!preset.mnemonics[instruction]) | |
preset.mnemonics[instruction] = []; | |
operand.split("/").forEach(function(operand) { | |
if(!(operand in preset.mnemonics[instruction])) | |
preset.mnemonics[instruction][operand] = ($D & 0x7FFF); | |
}); | |
} | |
} | |
}); | |
}); | |
/* schema.replace(instructions, function(str, pattern, color, Instruction, Few, Operands, Expression) { | |
var bits = [], | |
chop = 0, | |
laps = 1, | |
counter, code, | |
mask = parseInt(pattern.replace(/X/g, function(str, position, digits) { | |
bits.unshift(1 << (digits.length - position - 1)); | |
chop |= position < 2 ? bits[0] : 0; | |
laps <<= 1; | |
return "0"; | |
}), 2); | |
for(var lap = 0; lap < laps; ++ lap) { | |
counter = bits.length, | |
code = mask; | |
while(counter --) | |
code |= (lap >> counter) & 1 ? bits[counter] : 0; | |
var _z = 0x07 & (code >> 8), | |
_y = 0x07 & (code >> 4), | |
_x = 0x07 & (code >> 0), | |
locker = code & 0x80 | |
? ((0x3EA80 >> (_y & 2)) >> (_x << 1)) & (code & 8 ? 3 : 0) | (_x > 1 && _x < 6 && _y < 4 ? 4 : 0) | |
: (((_x == _y ? 0 : 3) | (_z == 0 ? 0 : _x == _z ? 0 : _x > _z ? 1 : _z > _x ? 2 : 3)) | (_x < _y ? 4 : 0)), | |
helpers = { | |
"#T": ((code >> 8) & 7) * 10 + (code & 15), | |
"#U": ((code >> 8) & 7) ? ((_z - (_z & 4) * 2) & 7).Hex(1) : "", | |
"#V": (((code >> 8) & 7) * 16 ^ (code & 15) ^ ((code & 16) ? 0xF0 : 0x00)).Hex(2), | |
"#W": ((code >> 0) & 31).Hex(2), | |
"#X": ((code >> 0) & 7), | |
"#Y": ((code >> 4) & 7), | |
"#Z": ((code >> 8) & 7) | |
}; | |
if(!preset.instructions[code & 0x07FF] && (((code >> 11) == locker))) { | |
var instruction = Instruction, | |
operands = Operands, | |
expression = Expression; | |
for(counter in helpers) { | |
var alias = new RegExp(counter, "g"); | |
instruction = instruction.replace(alias, helpers[counter]), | |
operands = operands.replace(alias, helpers[counter]), | |
expression = expression.replace(alias, helpers[counter]); | |
} | |
for(counter in Registers) | |
instruction = instruction.replace(new RegExp(counter, "g"), Registers[counter]), | |
operands = operands.replace(new RegExp(counter, "g"), Registers[counter]); | |
for(counter in Logics) { | |
var logic = Logics[counter]; | |
if(typeof logic == "string") { | |
for(var cnt in helpers) { | |
var alias = new RegExp(cnt, "g"); | |
logic = logic.replace(alias, helpers[cnt]); | |
} | |
} | |
expression = expression.replace(new RegExp(counter, "g"), logic); | |
} | |
//console.log(expression); | |
preset.instructions[code & 0x07FF] = { | |
color : color, | |
instruction : instruction, | |
operands : operands, | |
expression : expression.replace(/\s*\/\/.*(?#---)/, ""), | |
envelope : new Function("_, $IP, $IB, $IV, $IW, $IE, $IR, $IT", "with(_) {" + expression.replace(/\s*\/\/.*(?#---)/, ";} return true;")), | |
remark : expression.replace(/^.*?\/\/\s(.*)/, "$1") | |
}; | |
if(!preset.mnemonics[instruction]) | |
preset.mnemonics[instruction] = []; | |
preset.mnemonics[instruction][operands] = (code & 0x07FF) | (Few ? 0x0800 : 0x0000); | |
text.push([color, (code & 0x0FFF).Hex(4), instruction, operands, expression].join("\t")); | |
} | |
} | |
});*/ | |
var w, h, c, b, j, x, y, z, p, q, d, a; | |
watch.fontCnv = document.createElement("canvas"); | |
watch.fontCnv.width = 256 * 8 * 2; | |
watch.fontCnv.height = 16 * 8 * 2; | |
watch.fonts = watch.fontCnv.getContext("2d"); | |
watch.fontBit = watch.fonts.getImageData(0, 0, watch.fontCnv.width, watch.fontCnv.height); | |
d = watch.fontBit.data; | |
w = watch.fontCnv.width; | |
q = w * 4 * 8; | |
for(i = 0; i < 256; ++ i) { | |
x = i * 16; | |
for(y = 0; y < 8; ++ y) { | |
a = preset.ascii[i * 8 + y]; | |
p = (x + y * w + 7) * 4; | |
for(z = 0; z < 8; ++ z, p -= 4, a >>= 1) { | |
b = a & 1 ? 0 : 0xFF000000; | |
c = a & 1 ? 0xFF000000 : 0; | |
d[p + q * 0 + 0] = (c >> 0) & 255; d[p + q * 1 + 0] = (b >> 0) & 255; | |
d[p + q * 0 + 1] = (c >> 8) & 255; d[p + q * 1 + 1] = (b >> 8) & 255; | |
d[p + q * 0 + 2] = (c >> 16) & 255; d[p + q * 1 + 2] = (b >> 16) & 255; | |
d[p + q * 0 + 3] = (c >> 24) & 255; d[p + q * 1 + 3] = (b >> 24) & 255; | |
b = a & 1 ? 0 : 0xFF0000FF; | |
c = a & 1 ? 0xFF0000FF : 0; | |
d[p + q * 2 + 0] = (c >> 0) & 255; d[p + q * 3 + 0] = (b >> 0) & 255; | |
d[p + q * 2 + 1] = (c >> 8) & 255; d[p + q * 3 + 1] = (b >> 8) & 255; | |
d[p + q * 2 + 2] = (c >> 16) & 255; d[p + q * 3 + 2] = (b >> 16) & 255; | |
d[p + q * 2 + 3] = (c >> 24) & 255; d[p + q * 3 + 3] = (b >> 24) & 255; | |
b = a & 1 ? 0 : 0xFF00FF00; | |
c = a & 1 ? 0xFF00FF00 : 0; | |
d[p + q * 4 + 0] = (c >> 0) & 255; d[p + q * 5 + 0] = (b >> 0) & 255; | |
d[p + q * 4 + 1] = (c >> 8) & 255; d[p + q * 5 + 1] = (b >> 8) & 255; | |
d[p + q * 4 + 2] = (c >> 16) & 255; d[p + q * 5 + 2] = (b >> 16) & 255; | |
d[p + q * 4 + 3] = (c >> 24) & 255; d[p + q * 5 + 3] = (b >> 24) & 255; | |
b = a & 1 ? 0 : 0xFF00FFFF; | |
c = a & 1 ? 0xFF00FFFF : 0; | |
d[p + q * 6 + 0] = (c >> 0) & 255; d[p + q * 7 + 0] = (b >> 0) & 255; | |
d[p + q * 6 + 1] = (c >> 8) & 255; d[p + q * 7 + 1] = (b >> 8) & 255; | |
d[p + q * 6 + 2] = (c >> 16) & 255; d[p + q * 7 + 2] = (b >> 16) & 255; | |
d[p + q * 6 + 3] = (c >> 24) & 255; d[p + q * 7 + 3] = (b >> 24) & 255; | |
b = a & 1 ? 0 : 0xFFFF0000; | |
c = a & 1 ? 0xFFFF0000 : 0; | |
d[p + q * 8 + 0] = (c >> 0) & 255; d[p + q * 9 + 0] = (b >> 0) & 255; | |
d[p + q * 8 + 1] = (c >> 8) & 255; d[p + q * 9 + 1] = (b >> 8) & 255; | |
d[p + q * 8 + 2] = (c >> 16) & 255; d[p + q * 9 + 2] = (b >> 16) & 255; | |
d[p + q * 8 + 3] = (c >> 24) & 255; d[p + q * 9 + 3] = (b >> 24) & 255; | |
b = a & 1 ? 0 : 0xFFFF00FF; | |
c = a & 1 ? 0xFFFF00FF : 0; | |
d[p + q * 10 + 0] = (c >> 0) & 255; d[p + q * 11 + 0] = (b >> 0) & 255; | |
d[p + q * 10 + 1] = (c >> 8) & 255; d[p + q * 11 + 1] = (b >> 8) & 255; | |
d[p + q * 10 + 2] = (c >> 16) & 255; d[p + q * 11 + 2] = (b >> 16) & 255; | |
d[p + q * 10 + 3] = (c >> 24) & 255; d[p + q * 11 + 3] = (b >> 24) & 255; | |
b = a & 1 ? 0 : 0xFFFFFF00; | |
c = a & 1 ? 0xFFFFFF00 : 0; | |
d[p + q * 12 + 0] = (c >> 0) & 255; d[p + q * 13 + 0] = (b >> 0) & 255; | |
d[p + q * 12 + 1] = (c >> 8) & 255; d[p + q * 13 + 1] = (b >> 8) & 255; | |
d[p + q * 12 + 2] = (c >> 16) & 255; d[p + q * 13 + 2] = (b >> 16) & 255; | |
d[p + q * 12 + 3] = (c >> 24) & 255; d[p + q * 13 + 3] = (b >> 24) & 255; | |
b = a & 1 ? 0 : 0xFFFFFFFF; | |
c = a & 1 ? 0xFFFFFFFF : 0; | |
d[p + q * 14 + 0] = (c >> 0) & 255; d[p + q * 15 + 0] = (b >> 0) & 255; | |
d[p + q * 14 + 1] = (c >> 8) & 255; d[p + q * 15 + 1] = (b >> 8) & 255; | |
d[p + q * 14 + 2] = (c >> 16) & 255; d[p + q * 15 + 2] = (b >> 16) & 255; | |
d[p + q * 14 + 3] = (c >> 24) & 255; d[p + q * 15 + 3] = (b >> 24) & 255; | |
} | |
} | |
} | |
watch.fonts.putImageData(watch.fontBit, 0, 0); | |
} | |
}; | |
/*X80.prototype = { | |
get _Acc() { | |
var index = ($CTX[0xA8] >> 4) & 7; | |
index = 0xA8 + (index & 3) * 16 - (index & 4) * 2; | |
data = $CTX[index]; | |
return data; | |
}, | |
set _Acc(data) { | |
var index = ($CTX[0xA8] >> 4) & 7; | |
index = 0xA8 + (index & 3) * 16 - (index & 4) * 2; | |
data &= 0xFF, | |
$CTX[index] = data; | |
return data; | |
} | |
} | |
/* | |
80..87: | |
*/ | |
var Reset = 0, | |
Source = ""; | |
var cpu; | |
var cnv; | |
var c2d; | |
var img; | |
var date = new Date(); | |
function display(core) { | |
var row = [], ram, i, p, h, w, x, y, cx = -1, cy = -1, c, d, u, f = 7, g = 0, col = 7, gnd = 0, s = ""; | |
var oldSeconds = date.getSeconds(); | |
date = new Date(); | |
core.trace.stamps[1] = date.getTime(); | |
var ms = (date.getMilliseconds() % 500 > 250); | |
if(date.getSeconds() != oldSeconds) | |
;//core.IRQ(core.DO_FORCE); | |
setTimeout(display, 1000 / cpu.trace.flash, cpu); | |
ram = core.ram(); | |
cx = ram[0x76CF].lo(), cy = ram[0x76CE].lo(); | |
if(document.getElementById("Display").style.display != "none") { | |
w = 78, h = 30; | |
x = 0, y = 0, p = 0x76D0; | |
f <<= 4, g <<= 4; | |
while(y < h) { | |
c = ram[p]; | |
d = c & 255; | |
if(d >= 0x80 && d <= 0x87) | |
f = (c & 7) << 4; | |
if(d >= 0x90 && d <= 0x97) | |
g = (c & 7) << 4; | |
d = x == cx && y == cy ? 0 : 8; | |
if(true || c < 255 || d == 0) { | |
c &= 255; | |
d = ms ? d | 8 : d; | |
core.watch.c2d.drawImage(core.watch.fontCnv, c * 16 + 2, 8 ^ g ^ d, 6, 8, x * 6, y * 8, 6, 8), | |
core.watch.c2d.drawImage(core.watch.fontCnv, c * 16 + 2, 0 ^ f ^ d, 6, 8, x * 6, y * 8, 6, 8); | |
ram[p] = ms || !d ? c : c | 256; | |
} | |
ram[p] = c | 256; | |
if(++ x >= w) | |
f = 7 << 4, | |
g = 0 << 4, | |
x = 0, | |
++ y; | |
++ p; | |
} | |
} else { | |
for(i = 0, w = 78, h = 30, x, y, c, u; i < w * h * 0; ++ i) | |
x = i % w, y = Math.floor(i / w), | |
c = ram[(i + 0x76D0) & 0xFFFF], | |
ram[(i + 0x76D0) & 0xFFFF] = (c | 256), | |
u = c < 256 ? "<span style=color:red>" : (c &= 255, "<span>"), | |
row[y] = (x ? row[y] : "") + u + | |
(x == ram[0x76CF].lo() && y == ram[0x76CE].lo() && (new Date()).getMilliseconds() % 500 > 250 | |
? "<u>&#" + (c < 32 || c > 127 ? 0xB7 : c == 127 ? 0x2588 : c) + ";</u>" | |
: "&#" + (c < 32 || c > 127 ? 0xB7 : c == 127 ? 0x2588 : c) + ";") + "</span>"; | |
document.getElementById("Screen").innerHTML = row.join("<br />");//ram.Chr(0x76D0, 78, 30, (new Date()).getMilliseconds() % 500 > 250 ? ram[0x76CF] + ram[0x76CE] * 78 : -1);//row.join("<br />"); | |
} | |
c = core.watch.iAdjust, i = 1; | |
document.getElementById("state").innerHTML = [ "FPS: IPC: IPS: ".replace(/([A-Z]+)/g, function(str, tag) { return ++ i && c -- ? tag : "<u>" + (s = tag) + "</u>"; }), | |
(" " + core.trace.flash).substr(-2) + " " | |
+ (" " + core.trace.scale).substr(-6) + " " | |
+ (" " + core.trace.clock).substr(-4) | |
].join("\r\n"); | |
core.watch.nAdjust = i, | |
core.watch.sAdjust = s; | |
if(core.trace.active) | |
core.watch.dirty = 7; | |
if(core.watch.dirty > 0) | |
-- core.watch.dirty, | |
core.disassm(); | |
if(core.trace.stamps[0] >= 0) { | |
i = Math.floor((core.trace.stamps[1] - core.trace.stamps[0]) / 1000); | |
document.getElementById("Context").innerText = core.CR(0).Hex(2) + "#" + ("0" + Math.floor(i / 60)).substr(-2) + ":" + ("0" + (i % 60)).substr(-2); | |
} | |
//core.watch.active = core.watch.active.toUpperCase(); | |
//core.disassm(); | |
//document.getElementById("Dumper").innerHTML = this.state.isHalt || !this.state.isRun || this.state.scale == 1 || this.state.isHint ? this.r.ex.Dump() : ""; | |
} | |
var x80 = | |
function(description) { | |
var _CPU_ID_ = "x80-CPU"; | |
var preset = { | |
instructions :"pop", | |
} | |
function AL() { | |
console.log("AL " + preset.instructions); | |
} | |
function step() { | |
AL(); | |
setTimeout(this.step, 1250); | |
} | |
this.step = step; | |
} | |
var Switches = { | |
"ALT+1|11+": function() {cpu.watch.active = cpu.watch.active == "1" ? "0" : "1"; cpu.command_set(+cpu.watch.active);}, | |
"ALT+2|22+": function() {cpu.watch.active = cpu.watch.active == "2" ? "0" : "2"; cpu.command_set(+cpu.watch.active);}, | |
"ALT+3|33+": function() {cpu.watch.active = cpu.watch.active == "3" ? "0" : "3"; cpu.command_set(+cpu.watch.active);}, | |
"ALT+4|44+": function() {cpu.watch.active = cpu.watch.active == "4" ? "0" : "4"; cpu.command_set(+cpu.watch.active);}, | |
"ALT+5|55+": function() {cpu.watch.active = cpu.watch.active == "5" ? "0" : "5"; cpu.command_set(+cpu.watch.active);}, | |
"ALT+6|66+": function() {cpu.watch.active = cpu.watch.active == "6" ? "0" : "6"; cpu.command_set(+cpu.watch.active);}, | |
"ALT+7|77+": function() {cpu.watch.active = cpu.watch.active == "7" ? "0" : "7"; cpu.command_set(+cpu.watch.active);}, | |
"ALT+8|00+": function() {cpu.watch.active = cpu.watch.active == "8" ? "0" : "8"; cpu.command_set(+cpu.watch.active);}, | |
"ALT+L|Loop+": function() {cpu.command_set(parseInt(cpu.watch.active) | 0x20);}, | |
"ALT+W|Wait+": function() {cpu.command_set(parseInt(cpu.watch.active) | 0x30);}, | |
"ALT+A|Assm": function() {document.getElementById("Assm").style.visibility = document.getElementById("Assm").style.visibility == "hidden" ? "visible" : "hidden"}, | |
"ALT+B|Buffer": function() {}, | |
"ALT+C|Context":function() {cpu.command_set(parseInt(cpu.watch.active) | 0x40);}, | |
"ALT+D|Deprive":function() {cpu.command_set(parseInt(cpu.watch.active) | 0x50);}, | |
"ALT+E|Enlist": function() {cpu.command_set(parseInt(cpu.watch.active) | 0x0E);}, | |
"ALT+F|Forcing":function() {cpu.command_set(parseInt(cpu.watch.active) | 0x0F);}, | |
}; | |
//A0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | |
function main() { | |
/* t = document.createElement("pre"); | |
i = 256*8; | |
for($D = 0x00; i --; ++ $D) { | |
$X = 0x07 & ($D >> 0), | |
$I = 0x01 & ($D >> 3), | |
$Y = 0x07 & ($D >> 4), | |
$J = 0x01 & ($D >> 7), | |
$Z = 0x07 & ($D >> 8), | |
$K = 0x01 & ($D >> 11), | |
$L = 0x07 & ($D >> 12), | |
$M = $J ? ($Y < 4 ? $Y : !$I ? 4 : 4 | [0, 0, 1, 3, 3, 3, 2, 2][$X]) | |
: ($X == $Y ? $Y == $Z ? 7 : $Y > $Z ? 3 : 0 : $X < $Y ? 1 : 2); | |
t.innerText += $M + (($D & 15) == 15 ? ($D & 255) == 255 ? "\r\n\r\n" : "\r\n" : " "); | |
} | |
document.body.appendChild(t); | |
return;//*/ | |
var i, hClear = setTimeout("window.location.reload()", 150000); | |
var Selector = document.getElementById("Selector"); | |
var hFiles = document.getElementsByTagName("pre"); | |
cpu = new X80(document.getElementById("Schema_x80").innerText); | |
cpu.interface({ | |
instructions :document.getElementById("Instructions"), | |
disassembly :document.getElementById("Disassembly"), | |
registers :document.getElementById("Registers"), | |
address :document.getElementById("Address"), | |
mnemonic :document.getElementById("Mnemonic"), | |
remark :document.getElementById("Remark"), | |
context :document.getElementById("Context") | |
}); | |
document.getElementById("Prelude").style.display = "none"; | |
document.getElementById("Terminal").style.display = "block"; | |
if(i = window.location.href.match(/instructions([1-7])?/)) { | |
cpu.command_set(document.getElementById("commands")); | |
cpu.command_set(isFinite(i[1]) ? parseInt(i[1]) : 0, true); | |
return clearTimeout(hClear); | |
} | |
for(var file, i = 0; i < hFiles.length; ++ i) { | |
file = hFiles[i]; | |
if(file.id.substr(0, 5) == "FILE:") { | |
Selector.add( | |
new Option(file.id.substr(5), Files.length), | |
null | |
); | |
cpu.preset.files.push({ | |
name :file.id.substr(5), | |
text :file.innerText, | |
code :{ | |
name :"", | |
begin :65535, | |
end :0, | |
bin :[] | |
} | |
}); | |
} | |
} | |
var Triggers = document.getElementById("Triggers"); | |
//for(var i = 0, btn, spn; i < 16; ++ i) { | |
var i = 0; | |
/* for(var id in Switches) { | |
spn = document.createElement("span"); | |
spn.innerText = " ".Mul(i ++ ? 8 : 6); | |
btn = document.createElement("button"); | |
btn.style.position = "absolute"; | |
btn.onclick = Switches[id]; | |
id = id.split("|"); | |
btn.innerText = id[1]; | |
btn.title = id[0]; | |
btn.style.zIndex = 0; | |
btn.accessKey = id[0].substr(-1); | |
Triggers.appendChild(spn); | |
Triggers.appendChild(btn); | |
}*/ | |
Selector.onchange = function(e) { | |
document.getElementById("Assm").value = cpu.preset.files[this.selectedIndex].text; | |
if(cpu.preset.files[this.selectedIndex].code.length > 0) | |
document.getElementById("Action").innerText = "Save It"; | |
else | |
document.getElementById("Action").innerText = "Compile"; | |
} | |
document.getElementById("Action").onclick = function(e) { | |
var i = document.getElementById("Selector").selectedIndex; | |
if(cpu.preset.files[i].code.bin.length > 0) { | |
this.innerText = "Compiling..."; | |
cpu.preset.files[i].code = cpu.assembly(cpu.preset.files[i].text, true); | |
this.innerText = "Save It"; | |
} else { | |
cpu.preset.files[i].code = cpu.assembly(cpu.preset.files[i].text); | |
this.innerText = "Compile"; | |
cpu.preset.files[i].text = document.getElementById("Assm").value; | |
cpu.preset.files[i].bin.length = 0; | |
} | |
} | |
cpu.ram([]); | |
cpu.reset(0xFF00); | |
cnv = document.getElementById("Display"); | |
cnv.width = 6 * 80; | |
cnv.height = 8 * 30; | |
cpu.watch.c2d = cnv.getContext("2d"); | |
cpu.display(display); | |
cpu.command_set(document.getElementById("commands")); | |
cpu.disassm(); | |
document.getElementById("KeyBoard").focus(); | |
cpu.command_set(4, false); | |
setTimeout("cpu.assembly(document.getElementById('BootSection').innerText), cpu.reset(0xFF00)", 1); | |
clearTimeout(hClear); | |
///////////////////////////////// | |
document.getElementById("Address").onkeydown = function(e) { | |
var pointer, i, codes, n = -1; | |
var regs = "ALAHBLBHCLCHDLDHAXBXCXDXSPBPSIDIIPJP".match(/../g); | |
var re = new RegExp("((" + regs.join("|") + ")[1-7]?)" + "|" + "([0-9A-F]+)" + "|" + "(<<|--|>>|\\+\\+)", "g"); | |
switch(e.keyCode) { | |
case VK.UP: | |
cpu.trace.pointer -= 1; | |
window.event.returnValue = false; | |
cpu.disassm(); | |
break; | |
case VK.DOWN: | |
cpu.trace.pointer += 1; | |
window.event.returnValue = false; | |
cpu.disassm(); | |
break; | |
case VK.RETURN: | |
pointer = -1; | |
codes = this.value.match(re); | |
codes.forEach(function(code) { | |
if(("<<-->>++".indexOf(code) & 1) == 0) | |
switch(code) { | |
case "--": | |
cpu.ctx[cpu.CR()][0xFFFF & pointer] = (cpu.ctx[cpu.CR()][0xFFFF & pointer] - 1) & 0xFF; | |
if(pointer >= 0x100A0 && pointer <= 0x100FF && (pointer & 0x08) == 0 && cpu.ctx[cpu.CR()][0xFFFF & pointer] == 0xFF && n >= 8) | |
cpu.ctx[cpu.CR()][0xFFFF & (pointer + 8)] = (cpu.ctx[cpu.CR()][0xFFFF & (pointer + 8)] - 1) & 0xFF; | |
pointer ++; | |
break; | |
case "++": | |
cpu.ctx[cpu.CR()][0xFFFF & pointer] = (cpu.ctx[cpu.CR()][0xFFFF & pointer] + 1) & 0xFF; | |
if(pointer >= 0x100A0 && pointer <= 0x100FF && (pointer & 0x08) == 0 && cpu.ctx[cpu.CR()][0xFFFF & pointer] == 0x00 && n >= 8) | |
cpu.ctx[cpu.CR()][0xFFFF & (pointer + 8)] = (cpu.ctx[cpu.CR()][0xFFFF & (pointer + 8)] + 1) & 0xFF; | |
pointer ++; | |
break; | |
} | |
else | |
if((n = regs.join("").indexOf(code.substr(0, 2)) >> 1) >= 0) | |
pointer = 0x10000 + (n < 8 ? 0xA0 + n * 8 : n < 12 ? 0xA0 + (n - 8) * 16 : 0xE0 + (n - 12) * 2 + (n < 12 ? 0 : 8)) + parseInt("0" + code.charAt(2)), console.log("n:" + n + "/" + pointer.Hex(-5)); | |
else | |
if(code.length == 1) | |
pointer = 0x10100 + parseInt(code, 16); | |
else | |
if(code.length == 4) { | |
n = parseInt(code, 16); | |
if(pointer < 0) | |
cpu.trace.pointer = pointer = parseInt(code, 16); | |
else | |
if(pointer <= 0xFFFE) | |
cpu.ram[pointer ++] = n.lo(), | |
cpu.ram[pointer ++] = n.hi(); | |
else | |
if(pointer <= 0x1009F) | |
cpu.ctx[cpu.CR()][0xFFFF & pointer ++] = n.lo(), | |
cpu.ctx[cpu.CR()][0xFFFF & pointer ++] = n.hi(); | |
else | |
if(pointer <= 0x100FF) | |
cpu.ctx[cpu.CR()][0xFFFF & pointer] = n.lo(), | |
cpu.ctx[cpu.CR()][0xFFFF & (8 + pointer ++)] = n.hi(); | |
} else | |
if(code.length == 2) | |
if(pointer < 0) | |
pointer = 0x10000 + parseInt(code, 16); | |
else | |
if(pointer < 0x10000) | |
cpu.ram(pointer ++, parseInt(code, 16)); | |
else | |
if(pointer < 0x10100) | |
cpu.ctx[cpu.CR()][0xFFFF & pointer ++] = parseInt(code, 16); | |
else | |
if(pointer < 0x10108) | |
cpu.CR(0x0007 & pointer ++, parseInt(code, 16)); | |
}); | |
cpu.disassm(); | |
} | |
}; | |
document.getElementById("Mnemonic").onkeydown = function(e) { | |
switch(e.keyCode) { | |
case VK.UP: | |
cpu.trace.pointer -= 1; | |
window.event.returnValue = false; | |
cpu.watch.active = cpu.watch.active.toLowerCase(); | |
cpu.disassm(); | |
break; | |
case VK.DOWN: | |
cpu.trace.pointer += 1; | |
window.event.returnValue = false; | |
cpu.watch.active = cpu.watch.active.toLowerCase(); | |
cpu.disassm(); | |
break; | |
case VK.RETURN: | |
window.event.returnValue = false; | |
cpu.watch.active = cpu.watch.active.toLowerCase(); | |
cpu.assembly("\tORG\t" + parseInt(document.getElementById("Address").value, 16).Hex(-4) + "\r\n\t" + this.value); | |
cpu.disassm(); | |
break; | |
default: | |
cpu.watch.active = cpu.watch.active.toUpperCase(); | |
} | |
}; | |
document.getElementById("Remark").onkeydown = function(e) { | |
switch(e.keyCode) { | |
case VK.TAB: | |
window.event.returnValue = false; | |
document.getElementById("Address").focus(); | |
break; | |
} | |
} | |
document.getElementById("KeyBoard").onkeydown = function(e) { | |
window.event.returnValue = false; | |
switch(e.keyCode) { | |
case VK.TAB: this.value += "`I"; break; | |
case VK.ESC: this.value += "`["; break; | |
case VK.BACK_SPACE: this.value += "`{"; break; | |
case VK.LEFT: this.value += "`H"; break; | |
case VK.RETURN: this.value += "`M"; break; | |
default: | |
window.event.returnValue = true; | |
} | |
} | |
document.getElementById("KeyBoard").onkeyup = function(e) { | |
window.event.returnValue = false; | |
switch(e.keyCode) { | |
case VK.TAB: | |
case VK.ESC: | |
case VK.BACK_SPACE: | |
case VK.LEFT: | |
case VK.RETURN: break; | |
default: | |
window.event.returnValue = true; | |
} | |
} | |
document.body.onkeydown = function(e) { | |
//document.title = e.keyCode; | |
switch(e.keyCode) { | |
/* case VK.ESC: // ESC | |
cpu.iox[0xFD].data(0x1B); break; | |
cpu.preset.command_cycles = -Math.abs(cpu.preset.command_cycles), cpu.do_tick(true); break; | |
case VK.LEFT: // <-- | |
cpu.iox[0xFD].data(0x08); break; | |
case VK.UP: // //\ | |
cpu.iox[0xFD].data(0x19); break; | |
case VK.RIGHT: // --> | |
cpu.iox[0xFD].data(0x18); break; | |
case VK.DOWN: // \// | |
cpu.iox[0xFD].data(0x1A); break; | |
case VK.BACK_SPACE: // \// | |
cpu.iox[0xFD].data(0x7F); break; | |
*/ //////////////////////////////////// | |
case VK.BREAK: // Break-point | |
cpu.trace.halt[Number().hl(cpu.CTX(0xF8), cpu.CTX(0xF0))] ^= true; | |
if(e.shiftKey) | |
cpu.trace.halt[(Number().hl(cpu.CTX(0xF8), cpu.CTX(0xF0)) + 1) & 0xFFFF] = false; | |
cpu.disassm(); | |
break; | |
case VK.F1: // Step | |
if(e.ctrlKey) { // Start cycle | |
/*var ip = cpu.r.ip; | |
cpu.do_tick(true); | |
cpu.r.qp = ip; | |
cpu.trace.active = false;*/ | |
} else | |
if(e.shiftKey) | |
cpu.step(), | |
cpu.trace.active = true; | |
else | |
if(e.altKey) | |
cpu.state.isHint ^= true; | |
else | |
cpu.trace.step = true;//cpu.do_tick(true); | |
// cpu.disassm(); | |
window.event.returnValue = false; | |
break; | |
case VK.F7: | |
cpu.watch.iAdjust = (cpu.watch.iAdjust + 1) % cpu.watch.nAdjust; | |
window.event.returnValue = false; | |
break; | |
case VK.F6: // IP -- | |
switch(cpu.watch.sAdjust) { | |
case "FPS": | |
cpu.trace.flash -= cpu.trace.flash > 1 ? 1 : 0; | |
break; | |
case "IPS": | |
cpu.trace.clock >>= cpu.trace.clock & 1 ? 0 : 1; | |
break; | |
case "IPC": | |
cpu.trace.scale >>= cpu.trace.scale & 1 ? 0 : 1; | |
break; | |
default: | |
var txt = document.getElementById("Logger").value.split(/\r?\n/).pop().toUpperCase().split(/[\s\t]+/); | |
cpu.do_regs(txt[0], -1); | |
cpu.trace.active = true; | |
} | |
cpu.disassm(); | |
break; | |
case VK.F8: // IP ++ | |
switch(cpu.watch.sAdjust) { | |
case "FPS": | |
cpu.trace.flash += cpu.trace.flash < 50 ? 1 : 0; | |
break; | |
case "IPS": | |
cpu.trace.clock <<= cpu.trace.clock < 1000 ? 1 : 0; | |
break; | |
case "IPC": | |
cpu.trace.scale <<= cpu.trace.scale < 500000 ? 1 : 0; | |
break; | |
default: | |
var txt = document.getElementById("Assm").value.split(/\r?\n/).pop().toUpperCase().split(/[\s\t]+/); | |
cpu.do_regs(txt[0], +1); | |
cpu.trace.active = true; | |
} | |
cpu.disassm(); | |
break; | |
case VK.F5: // Assembly/Reset | |
window.event.returnValue = false; | |
if(e.ctrlKey) // Reset | |
cpu.JP(0, 0xF800), | |
cpu.JP(1, 0xE000), | |
cpu.reset(0xFF00); | |
else // Assembly | |
cpu.trace.active = true, | |
cpu.assembly(document.getElementById("Assm").value); | |
cpu.disassm(); | |
break; | |
case VK.F4: // Start/Break emulation | |
if(e.shiftKey) | |
cpu.trace.active = false; | |
else | |
cpu.trace.active = !cpu.trace.active; | |
cpu.disassm(); | |
break; | |
case VK.F3: | |
if(e.ctrlKey) | |
cpu.stack(cpu.r.ip); | |
else | |
if(e.shiftKey) | |
cpu.r.ip = cpu.stack(); | |
cpu.disassm(); | |
window.event.returnValue = false; | |
break; | |
case VK.RETURN: | |
if(e.shiftKey); | |
break; | |
default: | |
if(e.ctrlKey && e.keyCode > 48 && e.keyCode <= 56) | |
cpu.CR(0, e.keyCode & 7); | |
break;if(e.altKey && e.keyCode >= 48 && e.keyCode <= 55) | |
cpu.command_set(e.keyCode & 7, false); | |
//cpu.iox[0xFD].data(e.keyCode); | |
} | |
} | |
document.body.onkeyup = function(e){ | |
switch(e.keyCode) { | |
case VK.F1: // Help | |
case VK.F3: // Push/Pop | |
case VK.F5: // Assembly | |
window.event.returnValue = false; | |
break; | |
default: | |
//cpu.iox[0xFD].data(0xFF); break; | |
} | |
} | |
document.getElementById("Assm").onkeydown = function(e) { | |
if(e.keyCode == 13) { | |
if(e.ctrlKey) { | |
var txt = document.getElementById("Assm").value.split(/\r?\n/).pop().toUpperCase().split(/[\s\t]+/); | |
cpu.do_regs(txt[0], txt[1]); | |
cpu.disassm(); | |
} else | |
if(e.shiftKey) { | |
var keybrd = document.getElementById("Assm"), | |
start = keybrd.selectionStart, | |
ascii; | |
if(keybrd.value.length > start) { | |
//ascii = keybrd.value.charAt(start).toUpperCase(); | |
//cpu.iox[0xFD].data( | |
document.getElementById("KeyBoard").value = keybrd.value.substr(start).replace(/[Ёё]/igm, "Е").replace(/[Ъъ]/igm, "'").replace(/(`[A-Z@\[\\\]\^_\x01-\x1F]|.)/gm, | |
function(str, ascii) { | |
// alert(str + '...........'+ascii); | |
ascii = ascii.toUpperCase(); | |
if(ascii.length == 2) | |
return "`" + ascii.charAt(1); | |
var koi7ru = "ЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ", | |
data = koi7ru.indexOf(ascii); | |
if(data < 0) | |
return ascii.charCodeAt(0) < 0x7F && ascii.charCodeAt(0) >= 32 ? ascii.toUpperCase() : ascii.charCodeAt(0) < 32 ? "`" + String.fromCharCode(ascii.charCodeAt(0) + 64) : ""; | |
return String.fromCharCode(96 + data); | |
} | |
); | |
}/* | |
alert("1$"+cpu.iox[0xFD].text); | |
alert("1#"+cpu.iox[0xFD].data()); | |
alert("1@"+cpu.port(0xFD)); | |
alert("2$"+cpu.iox[0xFD].text); | |
alert("2#"+cpu.iox[0xFD].data()); | |
alert("2@"+cpu.port(0xFD)); | |
alert("3$"+cpu.iox[0xFD].text); | |
alert("3#"+cpu.iox[0xFD].data()); | |
alert("3@"+cpu.port(0xFD));*/ | |
window.event.returnValue = false; | |
} | |
} else | |
if(e.keyCode == 9) { | |
var start = this.selectionStart, end = this.selectionEnd; | |
this.value = this.value.substr(0, start) + "\t" + this.value.substr(end), | |
this.selectionStart = start + 1, | |
this.selectionEnd = start + 1, | |
window.event.returnValue = false; | |
} | |
} | |
document.getElementById("Assm").onkeyup = function(e) { | |
if(e.keyCode == 9) { | |
window.event.returnValue = false; | |
} | |
} | |
return; | |
//return; | |
/*var part = "F800 JMP 0xF701" | |
.split(/\s|\t/), | |
arg_nnIB, | |
ip = parseInt(part[0], 16), | |
ipx = ip*0, | |
instr = part[1], | |
regs = part[2], | |
args = [], | |
ins = { "$+IB": {}, | |
"$+1IB": {}, | |
"$+2IB": {}, | |
"$+3IB": {}, | |
"$+4IB": {}, | |
"$+5IB": {}, | |
"$+6IB": {}, | |
"$+7IB": {}, }; | |
arg_nnIB = regs.replace(/(0x[0-9A-F]+)|([0-9]+)/gi, function(str, data) { // nnIB | |
var bin0 = parseInt(data); | |
var tag0 = regs.replace(/\+(0x[0-9A-F]+|[0-9]+)/, "+IB"); | |
var bin1 = parseInt(data); | |
var tag1 = bin1.hi().Hex(2) + "IB"; | |
var bin2 = parseInt(data) - (ip + 2) - ipx; | |
// bin2 -= (bin2 & 32768) * 2; | |
var tag2 = "$+IB"; | |
var bin3 = parseInt(data) - (ip + 3) - ipx; | |
//bin3 += (bin3 & 32768) * 2; | |
//bin3 += (bin3 < -128 ? +(bin3 & 0x80) * 2 : bin3 >= 128 ? +(bin3 & 0x80) * 2 : 0); | |
var bin3a = bin3 + (bin3 < -128 ? +(bin3 & 0x80) * 2 : bin3 >= 128 ? +(bin3 & 0x80) * 2 : 0); | |
var tag3 = "$+" + ((bin3a >> 8) & 7) + "IB"; | |
console.log([ip.Hex(4), "bin0", instr, str, bin0.Hex(4), bin0, "?" + ins + "?" + tag0].join(" ")); | |
console.log([ip.Hex(4), "bin1", instr, str, bin1.Hex(4), bin1, "?" + ins + "?" + tag1].join(" ")); | |
console.log([ip.Hex(4), "bin2", instr, str, bin2.Hex(4), bin2, "?" + ins + "?" + tag2].join(" ")); | |
console.log([ip.Hex(4), "bin3", instr, str, bin3.Hex(4), bin3, "?" + ins + "?" + tag3].join(" ")); | |
console.log([ip.Hex(4), "bin3a", instr, str, bin3a.Hex(4), bin3a, "?" + ins + "?" + tag3].join(" ")); | |
if(ins) { | |
if(tag0 in ins) { | |
console.log("0"); | |
return args.push(bin0) ? "IB" : "IB"; | |
} | |
if(tag1 in ins) { | |
console.log("1"); | |
return args.push(bin1) ? tag1 : tag1; | |
} | |
if(bin2 >= -128 && bin2 < 128 && (tag2 in ins)) { | |
console.log("2"); | |
return args.push(bin2.lo()) ? tag2 : tag2; | |
} | |
if(((bin3 >= -1024 && bin3 < -128) || (bin3 >= 128 && bin3 <= 895)) && (tag3 in ins)) {//console.log("bin3="+bin3+""); | |
console.log("3"); | |
return args.push(bin3.lo()) ? tag3 : tag3; //}//else console.log("bin3="+bin3+" tag3=" + tag3 + "/" + (tag3 in ins)); | |
} | |
if("IB" in ins) { | |
console.log("4"); | |
return args.push(bin1) ? "IB" : "IB"; | |
} | |
if(part[4] && (regs.split(",")[0] + ",IB") in ins) { | |
console.log("5"); | |
return (code = ins[part[3] + ",IB"]) && args.push(bin1) ? "" : ""; | |
} | |
if("" in ins) | |
return ""; | |
} | |
args.push(bin1); | |
//console.log([ip.Hex(4), "nnIB//", instr, str, bin1.Hex(4), bin1].join(" ")); | |
return ""; | |
}); | |
console.log(arg_nnIB); | |
console.log(args[0].Hex(4) + "=" + (args[0] - (args[0] & 32768) * 2)); | |
return;*/ | |
var url = window.location.href, match = 0, i; | |
Source = document.getElementById("Listing").innerText; | |
cpu.preset.command_speed = +((match = url.match(/speed=([^&]+)/)) ? match[1] : .1*0+500); | |
cpu.preset.command_cycles = +((match = url.match(/cycle=([^&]+)/)) ? match[1] : 1); | |
cpu.preset.command_reset = +((match = url.match(/reset=([^&]+)/)) ? match[1] : 1); | |
cpu.init(document.getElementById("Schema").innerText); | |
if(url.match(/instructions/)) { | |
var body = document.createElement("body"); | |
cpu.preset.command_table = document.createElement("pre"); | |
var span = document.createElement("span"); | |
cpu.preset.command_table.id = "commands"; | |
span.id = "expression"; | |
body.appendChild(cpu.preset.command_table); | |
body.appendChild(span); | |
body.style.backgroundColor = "steelblue"; | |
document.body = body; | |
cpu.command_set(0, true); | |
return; | |
} | |
for(i = 0; i < 264; ++ i) | |
cpu.preset.regs.asx[i] = 0, | |
cpu.preset.regs.atx[i] = 0; | |
for(i = 0x0000; i <= 0xFFFF; ++ i) | |
cpu.halt[i] = false; | |
for(i = 0x0000; i <= 0x00FF; ++ i) { | |
if(!isFinite(cpu.iox[i]) && !cpu.iox[i]) | |
cpu.iox[i] = 0x80; | |
} | |
//alert(cpu.iox[0xD0].data().Hex(2)); | |
for(i = 0x76CE; i <= 0x7FF3; ++ i) | |
cpu.ram[i] = Math.random() * 256 & 0; | |
cpu.iox[0xF1].data(document.getElementById("Files").innerText); | |
cpu.do_reset(); | |
i = 0; | |
document.getElementById("Listing").innerText.replace(/\s*;.*/gm, "").replace(/([0-9A-F]{4})(?:\:)|([0-9A-F]{2})(?:\s)/gm, function(str, p1, p2) { | |
if(p1) | |
i = parseInt(p1, 16); | |
if(p2) | |
cpu.ram[i ++] = parseInt(p2, 16); | |
return "_"; | |
}); | |
cpu.preset.command_table = document.getElementById("commands"); | |
cpu.command_set(Math.floor((new Date()).getSeconds() / 3) % 11 * 0); | |
cpu.display(); | |
cpu.disassm(); | |
//////////////////////////////////////// | |
setTimeout(function() { | |
// cpu.assembly(Source); | |
document.getElementById("Logger").value = Source;//\ | |
" ORG 0xF780\ | |
\rgoe: NOP\ | |
\r ORG 0xF800\ | |
\rgo: NOP\ | |
\r JC $-1\ | |
\r NOP\ | |
\r JMP goal\ | |
\r NOP\ | |
\r DW 0xB977\ | |
\r DB 0x01\ | |
\r NOP\ | |
\r JS goe\ | |
\r NOP\ | |
\r ORG 0xF903\ | |
\rgoal: NOP\ | |
\r!IP 0x100"; | |
cpu.assembly(document.getElementById("Logger").value); | |
cpu.disassm(); | |
document.getElementById("Logger").focus(); | |
//cpu.state.hTimer = setInterval("cpu.do_tick()", 1500); | |
//AudioInit(); | |
}, 1); | |
//cpu.assembly(" ORG 0xF800\r\nStart:\r\n INC BX_DX\r\n POP AX_CX\r\n"); | |
document.body.onkeypress = function(e) { | |
cpu.iox[0xFD].data(e.keyCode);//e.charCode; | |
document.title+=" _"+e.keyCode.Hex(4); | |
// window.event.returnValue = false; | |
} | |
document.body.onkeyup = function(e){ | |
switch(e.keyCode) { | |
case VK.F1: // Help | |
case VK.F3: // Push/Pop | |
case VK.F5: // Assembly | |
window.event.returnValue = false; | |
break; | |
default: | |
//cpu.iox[0xFD].data(0xFF); break; | |
} | |
document.title+=" ^"+e.keyCode.Hex(4); | |
} | |
} | |
</script> | |
</head> | |
<body onload='setTimeout(main,1000)'> | |
<var id=Schema_x80> | |
<!-- | |
$A:Address (-2048..2047) | |
$B:Byte (0..255) | |
$C:Character(-128..127) | |
$D:Decoder (0..255) | |
$K:Keep-mode (00..07) .0:Normal, .1:Express, .2:Loop, .3:Wait, 4:System... | |
$X:Low Nibble (00..07) | |
$Y:High Nibble(00..07) | |
$Z:Zip-prefix (00..07) | |
+---------------=> $L:Lock-mask | |
| +------------=> $K:Keep code | |
| | +---------=> $Z:PREFIX #Z | |
| | | +-------=> $J: | |
| | | | +-----=> $Y: | |
| | | | | +---=> $I: | |
| | | | | | +-=> $X: | |
| | | | | | | | |
/|\/|\/|\|/|\|/|\ | |
LLLKKKZZZJYYYIXXX_ | |
XXX11100000000000C MOV [0],ACC : | |
XXX1XX00000000000C HLT 0 : | |
XXXXXX00000000000C HLT : | |
000XXX0000XXX0XXX_ PREFIX R$X/P$Y : | |
A:ALU | |
B:Branch | |
C:Control | |
D:Dubbed register pair | |
E:Stack | |
F:Flip-flop move | |
$D<128 | |
000: | |
001: $X < $Y | |
010: $X > $Y | |
011: $X = $Y | |
100: $Z | |
101: $Z < $X = $Y | |
110; $Z > $X = $Y | |
111: $Z = $X = $Y | |
x>y?1 | |
y>x?2 | |
x=y?x>z?3:7 | |
7 1 1 1 3 1 1 1 | |
2 5 1 1 1 1 1 1 | |
2 2 5 1 1 1 1 1 | |
2 2 2 5 1 1 1 1 | |
3 2 2 2 7 1 1 1 | |
2 2 2 2 2 6 1 1 | |
2 2 2 2 2 2 6 1 | |
2 2 2 2 2 2 2 6 | |
- - - - - - - - - - - - - - - - | |
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | |
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 | |
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 | |
4 4 4 4 4 4 4 4 4 4 5 7 7 7 6 6 | |
4 4 4 4 4 4 4 4 4 4 5 7 7 7 6 6 | |
4 4 4 4 4 4 4 4 4 4 5 7 7 7 6 6 | |
4 4 4 4 4 4 4 4 4 4 5 7 7 7 6 6 | |
$M = $J ? ($Y < 4 ? $Y : !$I ? 4 : 4 | [0, 0, 1, 3, 3, 3, 2, 2][$X]) | |
: (!$Y && ($X == $Z)) || (!$X && ($Y == $Z)) ? 3 | |
: ($X == $Y ? $Y == $Z ? 7 : $Y > $Z ? 5 : 6 : $X < $Y ? 1 : 2) | |
ZF=0 - BF:JF - Fictional | |
ZF=1 - BE:JE - Equivalent | |
CF=0 - BD:JD - Discarded | |
CF=1 - BC:JC - Carrier | |
SF=0 - BB:JB - Bigger | |
SF=1 - BA:JA - Among | |
PF=1 - B0:JO - Odd parity | |
MMMLLLZZZZJYYYIXXX_ -- | |
0XXXXX100000000000C HLT :return 0 //HALT the Application | |
1XXXXX10000XXX0XXX_ PREFIX R$X/P$Y :return 0 //Prefix | |
111X00XXXX0XXX0XXXC HLT P$Z/$Z :FH($Z | 8) //Hold P$Z!/$Z | |
1XXX00XXXX00000000C HLT R$Z :FH($Z | 0) //Hold R$Z! | |
101XXX0XXX0XXX0XXXF XCHG R$Z,R$Y :$1=R$Z(),R$Z(R$Y()),R$Y($1) //Exchange R$Z! and R$Y! | |
110XXX0XXX0XXX0XXXF XCHG P$Z,P$Y :$1=P$Z(),P$Z(P$Y()),P$Y($1) //Exchange P$Z! and P$Y! | |
XXXXXX1XXX0XXX0XXXF MOV R$X,R$Y :R$X(R$Y()) //Move R$Y! to R$X! | |
XXXX000XXX11101011C LOOP [R$Z] :FH(R$Z()|8),FL((FL() & 0x02) | 0x09) //Forcing next operation by R$Z bits | |
XXXX000XXX11101100C LOOP R$Z :FH($Z), FL((FL() & 0x02) | 0x09) //Forcing next operation by R$Z counter | |
XXXX000XXX11101101C LOOP $Z :FH($Z | 8), FL((FL() & 0x02) | 0x09) //Forcing next operation by $Z times | |
XXXXXXXXXXXXXXXXXXX Y$Y_X$X ($M) :0 //reserved | |
<!-- | |
MMM_LLL_ZZZZ_JYYY_IXXX_ --> | |
0XX_0XX_0000_0000_0000C HLT :(CR(0,CR(0)&255)),$EV = DO_ACCLAIM //HALT | |
XXX_1XX_0000_0000_0000_ PREFIX SUPER :return 0 //Super Prefix | |
1XX_XXX_0000_0XXX_0XXX_ PREFIX R$X/P$Y :return 0 //Prefix | |
XXX_X00_0XXX_0000_0000C HLT R$Z :FH($Z | 0) //Hold R$Z! | |
111_X00_0XXX_0XXX_0XXXC HLT P$Z/$Z :FH($Z | 8) //Hold P$Z!/$Z | |
XXX_000_1000_0000_0000X .$Y$X :return 0 // | |
XXX_X00_1000_0XXX_0000C MOV [0],R$Y :CR(0,R$Y())+ FL(0),$IE=0 //CR[$Y] = ACC | |
XXX_X10_0100_0000_0XXXF MOV R$X,[$Y] :R$X(CR($Y))+ FL(0),$IE=0 //R$X = CR[$Z] | |
1XX_X10_0100_0XXX_0XXXF MOV R$X,[R$Y] :R$X(CTX(R$Y()))+ FL(0) //Context | |
XXX_X10_0100_0XXX_0XXXF MOV [R$X],R$Y :CTX(R$X(), R$Y())+ FL(0),$IE=0 //Context | |
101_X00_0XXX_0XXX_0XXXF XCHG R$Z,R$Y :$1=R$Z(),R$Z(R$Y()),R$Y($1) //Exchange R$Z! and R$Y! | |
110_X00_0XXX_0XXX_0XXXF XCHG P$Z,P$Y :$1=P$Z(),P$Z(P$Y()),P$Y($1) //Exchange P$Z! and P$Y! | |
XXXX1XXXXX0XXX0000X .Y$Y :0 //reserved | |
XXXX1XXXXX00000XXXX .X$X :0 //reserved | |
1XX_X11_X100_0XXX_0XXXC IN R$X :R$X(PORT(R$X())) //Input from port | |
XXX_X11_X100_0XXX_0XXXC OUT R$X,R$Y :PORT(R$X(),R$Y()) //Output to port | |
001X1XX0000XXX0000F .Y$Y R$X;[R$Y] :0 //reserved | |
010X1XX00000000XXXF .X$X [R$X];R$Y :0 //reserved | |
XXXX01X10000000100C MOV :$CTX.splice(0xAF, 1), $CTX.splice(0xA9, 0, FH()),$IE=0 //Set argument | |
XXXX01X1000XXX0000C MOV $Y :FH($CTX[0xA8 + $Y]),$IE=0 //Get argument | |
XXX_XXX_0100_0XXX_1XXXA BIT R$X,$Y :$1=FL(),FL($1&0xFE)|((R$X()>>$Y)&1),R$X(~(~R$X()|(1<<$Y)))/*>*/ //Bit exchange | |
0XX_X00_0000_0XXX_0XXXF MOV R$X,R$Y :R$X(R$Y()) //Move R$Y! to R$X! | |
XXX_X00_0XXX_0000_0XXXF MOV R$X,[$Z] :R$X(CR($Z)) //Move [$Z] to R$X! | |
XXX_X00_0XXX_0XXX_0000F MOV [$Z],R$Y :CR($Z,R$Y()) //Move R$X! to [$Z] | |
0XX_X00_0100_0XXX_0XXXF MOV P$X,P$Y :P$X(P$Y()) //Move P$Y! vector to P$X! | |
XXX_X10_0100_0XXX_1XXXX -- Z$Y :$1=ALU$X(DROP($Y),REG($Y)),REG($Y,$1),FL($1.hi()) //ALU$X! with Z$Y! and retained | |
XXX_XXX_0XXX_0XXX_1XXXA ALU$X Z$Z,R$Y :$1=ALU$X(Z$Z(),R$Y()),Z$Z($1),FL($1.hi()) //ALU$X! with Z$Z! and R$Y! | |
XXX_XXX_0100_1010_1XXXA ADC P$X,IB :$1=ALU$X(DROP(FH()),$B),ACC($1),FL($1.hi()) //ALU$X! with retained and immediate | |
XXX_XXX_0XXX_1010_1XXXA ALU$X Z$Z,IB :$1=ALU$X(Z$Z(),$B),Z$Z($1),FL($1.hi()) //ALU$X! with Z$Z! and byte | |
XXX_X00_0XXX_100X_XXXXE PUSH $VIB :HEAP(0x$V00 + $B) //Push immediate data into stack | |
XXX_XXX_0000_1110_1110C NOP :$Z //Hollow operation | |
XXX_XXX_0XXX_1110_1110C NOP $Z :$Z //Hollow operation | |
XXX_X0X_0000_1111_1110B DBG 0 :HEAP($IP)+IP(JP(10>$T?0:1)) ;$IF=true //Interruption | |
XXX_X0X_0000_1111_1111B DBG :HEAP($IP)+IP(JP(10>$T?0:1)) ;$IF=true //Interruption | |
111_XXX_0000_1100_1XXXD INC Q$X :Q$X(Q$X()+1) //Increment Q$X! | |
111_XXX_0000_1101_1XXXD DEC Q$X :Q$X(Q$X()-1) //Decrement Q$X! | |
XXX_X00_0000_1100_1111A CMC :FL(FL() ^ 2) //Complement carry flag | |
-XXX_XXX_0XXX_1100_1110X Y$Y_X$X ($M) :0 //reserved | |
-XXX_XXX_0XXX_1100_1110D ADC BX,T$Z :$1=BX()+T$Z()+(_CF?1:0),$2=($1>>15)&2,FL((FL()& 0xD)|$2), BX($1) //Addition register pair with carry | |
111_XXX_0XXX_1100_1XXXD ADD Q$X,P$Z :$1=Q$X()+P$Z()+(_CF?0:0),$2=($1>>15)&2,FL((FL()& 0xD)|$2), Q$X($1) //Addition register pair | |
-XXX_XXX_0XXX_1101_1110X Y$Y_X$X ($M) :0 //reserved | |
-XXX_XXX_0XXX_1101_1110D SBB BX,T$Z :$1=BX()-T$Z()-(_CF?1:0),$2=($1>>15)&2,FL((FL()& 0xD)|$2), BX($1) //Subtraction register pair with borrow | |
111_XXX_0XXX_1101_1XXXD SUB Q$X,P$Z :$1=Q$X()-P$Z()-(_CF?0:0),$2=($1>>15)&2,FL((FL()& 0xD)|$2), Q$X($1) //Subtraction register pair | |
XXXX00X00011001010A XCHG :$1=ACC(); for($2=0,$0=0;8>$0;++$0,$1>>=1) $2=($2<<1)+($1&1); ACC($2)>0 //Exchange retained bits by mirror | |
XXXX00XXXX11001010A XCHG P$Z :$1=DST(),DST(P$Z()),P$Z($1) //Exchange P$Z! with retained pair | |
XXXX00XXXX11001111A XCHG R$Z :$1=ACC(),ACC(R$Z()),R$Z($1) //Exchange R$Z! with retained register | |
XXX_XXX_0000_1101_1110C DOZ :CND7?(FH(1 | 8), FL((FL() & 0x02) | 0x05)):0 //Execute next operation if CF | |
XXX_XXX_0000_1101_1111C DONZ :CND6?(FH(1 | 8), FL((FL() & 0x02) | 0x05)):0 //Execute next operation if no CF | |
XXX_XXX_0XXX_1101_111XX --- :return 0 // | |
XXX_XXX_0100_110X_1XXXX --- :$1=ACC(ALU$W(ACC())),FL($1.hi()) //ALU$W! with retained | |
XXX_XXX_0XXX_1100_1110A ALU1F Z$Z :$1=Z$Z(ALU1F(Z$Z())),FL($1.hi()) //ALU$W! with Z$Z! | |
XXX_XXX_0XXX_110X_1XXXA ALU$W Z$Z :$1=Z$Z(ALU$W(Z$Z())),FL($1.hi()) //ALU$W! with Z$Z! | |
XXX_X00_0000_1010_0XXXF MOV R$X,IB :R$X($B) //Move immediate data into R$X! | |
XXXX0X10001011000XC BCND$X :CND$X?0:FL((FL() & 0x02) | 0x05) ;$IF=true //Conditional do | |
XXXX0X00001011000XB BCND$X $+$UIB :CND$X?IP(IP()+$A):0 ;$IF=true //Relative branching if CND$X! | |
XXX_X00_X100_1011_0000E PUSH $+IB :HEAP(IP()+$A) //Push instruction based relative address | |
XXX_X0X_O000_1011_0XXXB CCND$X :CND$X?($1=P$Z(),P$Z(DW(SP())), DW(SP(), $1)):HEAP() ;$IF=true //Condition call | |
XXX_X0X_0000_1011_0XXXB CCND$X $+IB :CND$X?HEAP(IP())+IP(IP()+$A):0 ;$IF=true //Relative call if CND$X! | |
XXX_XXX_0000_1100_0XXXA INC R$X :$1=ADD(R$X(),1),R$X($1),FL($1.hi()) //Increment R$X! | |
XXX_XXX_0000_1101_0XXXA DEC R$X :$1=SUB(R$X(),1),R$X($1),FL($1.hi()) //Decrement R$X! | |
XXX_XXX_0XXX_1100_0XXXA ADD P$Z,R$X :$1=(P$Z()+R$X()),P$X($1),FL($1.hi()) //Increment R$X! | |
XXX_XXX_0XXX_1101_0XXXA SUB P$Z,R$X :$1=(P$Z()+R$X()),P$X($1),FL($1.hi()) //Increment R$X! | |
XXX_XXX_0XXX_1101_0XXXA DEC R$X :$1=SUB(R$X(),1),R$X($1),FL($1.hi()) //Decrement R$X! | |
XXX_X00_0XXX_1010_0000E POP [P$Z+IB] :DW(P$Z()+$C,HEAP()) //Pop data into memory indexed by P$Z | |
XXX_X00_0XXX_1010_0XXXF MOV R$X,[P$Z+IB] :R$X(DB(P$Z()+$C)) //Move memory data by P$Z pointer into R$X | |
XXX_X00_111X_1011_0000E PUSH [P$Z+IB] :HEAP(DW(P$Z()+$C)) //Push data from memory indexed by P$Z | |
XXX_X00_0XXX_1011_0000E PUSH [P$Z+IB] :HEAP(DW(P$Z()+$C)) //Push data from memory indexed by P$Z | |
XXX_X00_0XXX_1011_0XXXF MOV [P$Z+IB],R$X :DB(P$Z()+$C,R$X()) //Move R$X register data into memory by P$Z | |
XXX_X10_0XXX_1010_0XXXF MOV R$X,[P$Z+ACC+IB]:R$X(DB(P$Z()+ACC()+$C)),FL(0),$IE=0 //Move R$X register data into memory by P$Z | |
XXX_X10_0XXX_1011_0XXXF MOV [P$Z+ACC+IB],R$X:DB(P$Z()+ACC()+$C,R$X()),FL(0),$IE=0 //Move R$X register data into memory by P$Z | |
XXX_XXX_X100_1011_1XXXX --- IB :return 0 //Reserved extended code | |
XXX_X00_X100_1011_1010E LEA +IB :DST(DST()+$B) //Load retained effective address | |
XXX_X00_X100_1011_1XXXF MOV [U$X],IB :DB(U$X(),$B) //Load immediate data into memory by U$X | |
XXX_X00_1110_1011_1000C WAIT :FL((FL() & 0x02) | 0x0D),trace.expression=0 //Wait | |
XXX_X00_1111_1011_1000B RET :IP(HEAP()) //Return | |
XXX_X0X_0XXX_1011_1000B JMP $+$UIB :IP(IP()+$A) ;$IF=true //Unonditional relative branching | |
XXXX0X0XXX10111001B CALL $+$UIB :$A==-2?0:HEAP(IP(IP()+$A)) ;$IF=true //Unconditional relative call | |
XXXX0X1XXX10111XXXC BCND$X :CND$X?0:FL((FL() & 0x02) | 0x05) ;$IF=true //Conditional do | |
XXXX00100010111001X . :0 //reserved | |
XXXX00100010111XXXX . :0 //reserved | |
XXX_XXX_0XXX_1011_1XXXB JCND$X $+$UIB :CND$X?IP(IP()+$A):0 ;$IF=true //Branching if CND$X! | |
XXX_XXX_1111_1011_1XXXB RCND$X :CND$X?IP(HEAP()):0 //Return if CND$X | |
1X1_X00_0000_1110_1XXXE PUSH U$X :HEAP(U$X()) //Push U$X! into stack | |
1X1_X00_0000_1111_1XXXE POP U$X :U$X(HEAP()) //Pop U$X! from stack | |
XXXX00X10011101110F XCHG [SP] :$1=DST(),DST(DW($2=SP())), DW($2, $1) //Exchange retained pair with stack heap | |
XXX_X00_XXXX_1110_1111F XCHG P$Z,[SP] :$1=P$Z(),P$Z(DW(SP())), DW(SP(), $1) //Exchange pair P$Z! with stack heap | |
XXXX00X10011101111E PUSH :HEAP(DST()) //Push retained pair | |
XXXX00XXXX11101111E PUSH S$Z :HEAP(S$Z()) //Push service S$Z register pair to stack | |
XXXX00X10011111111E POP :DST(HEAP()) //Pop retained pair | |
XXXX0XXXXX11111111E POP S$Z :S$Z(HEAP()) ;$IF=true //Pop service S$Z register pair from stack | |
XXXX00XXXX11101010E PUSH R$Z :DUP($Z) //Dup R$Z register history | |
XXX_X00_0000_1110_0000C SKIP :FH(1 | 8), FL((FL() & 0x02) | 0x05) //Exclude next operation | |
XXX_X10_0000_1110_0000C SKIP ACC :FH(1 | 8), FL((FL() & 0x02) | 0x05) //Exclude next operation | |
XXX_X00_0000_1110_0XXXC LOOP $X :FH($X | 8), FL((FL() & 0x02) | 0x09) //Forcing next operation by $X times | |
XXX_X00_0000_1110_1000C DOC :CND5?(FH(1 | 8), FL((FL() & 0x02) | 0x05)):0 //Execute next operation if CF | |
XXX_X00_0000_1110_1001C DONC :CND4?(FH(1 | 8), FL((FL() & 0x02) | 0x05)):0 //Execute next operation if no CF | |
XXX_X00_0XXX_1110_1011C LOOP [R$Z] :FH(R$Z()|8),FL((FL() & 0x02) | 0x09) //Forcing next operation by R$Z bits | |
XXX_X00_0XXX_1110_1100C LOOP R$Z :FH($Z), FL((FL() & 0x02) | 0x09) //Forcing next operation by R$Z counter | |
XXXX000XXX11101101C LOOP $Z :FH($Z | 8), FL((FL() & 0x02) | 0x09) //Forcing next operation by $Z times | |
XXXX00XXXX11111010E POP R$Z :DROP($Z) //Drop R$Z register history | |
XXX_X00_0XXX_1111_1011C SKIP [R$Z] :FH(R$Z()|8),FL((FL() & 0x02) | 0x05) //Exclude next operations by R$Z bits | |
XXX_X00_0XXX_1111_1100C SKIP R$Z :FH($Z), FL((FL() & 0x02) | 0x05) //Exclude next operations by R$Z counter | |
XXX_X00_0XXX_1111_1101C SKIP $Z :FH($Z | 8), FL((FL() & 0x02) | 0x05) //Exclude next operations by $Z times | |
100X10X0001111XXXXB FLY $T :FLY($T) //Fix the alias | |
100X10XXXX1111XXXXB FIX $T :FH($Z | 8), FL((FL() & 0x02) | 0x05),$IE=0;FIX($Z, $T) //Fix the alias | |
100_X0X_0XXX_1111_XXXXB INT $T :HEAP($IP)+IP(JP(10>$T?0:1)) ;$IF=true //Interruption | |
XXX_XXX_1000_10XX_XXXXX Y$Y_X$X IB :return 0 // | |
XXX_XXX_XXXX_XXXX_XXXXX Y$Y_X$X ($M) :0 //reserved | |
<!-- | |
+----------------=> $M[17:15]:Mask | |
| +-------------=> $L[14:12]:Loop mode(0:Normal; 1:Wait+Fn; 2:Loop; 3:Wait; 4+:System+...) (asm: LOOP/WAIT) | |
| +-------------=> $L[14:12]:Loop mode(0:Normal; 1:Loop; 2:Wait; 3:Wait+Fn; 4+:System+...) (asm: LOOP/WAIT) | |
| | +-----------=> $K[ 11 ]:Keep open(1:$Z==FH/$B==-2) (asm: HLT $Z + WAIT) | |
| | | +---------=> $Z[10:8 ]:PREFIX $Z | |
| | | | +-------=> $J[ 7 ]: | |
| | | | | +-----=> $Y[ 6:4 ]: | |
| | | | | | +---=> $I[ 3 ]: | |
| | | | | | | +-=> $X[ 2:0 ]: | |
| | | | | | | | | |
/|\/|\|/|\|/|\|/|\ | |
MMMLLLKZZZJYYYIXXX_ --><!-- | |
XXXX00X00000000000C HLT :return 0 //HALT | |
111X00XXXX0XXX0XXXC HLT P$Z/$Z :FH($Z | 8) //Hold P$Z!/$Z | |
1XXX00XXXX00000000C HLT R$Z :FH($Z | 0) //Hold R$Z! | |
XXXX10X0000XXX0000C MOV [$Y],ACC :CR($Y,ACC())+ FL(0),$IE=0 //CR[$Y] = ACC | |
0XXX10XXXX00000XXXF MOV R$X,[$Z] :R$X(CR($Z))+ FL(0),$IE=0 //R$X = CR[$Z] | |
011X10XXXX0XXX0000F MOV R$Z,[R$Z] :R$Z(CTX(R$Z()))+ FL(0) //Context | |
0XXX10XXXX0XXX0000F MOV [R$Z],R$Y :CTX(R$Z(), R$Y())+ FL(0),$IE=0 //Context | |
1XXXXXX0000XXX0XXX_ PREFIX R$X/P$Y :return 0 //Prefix | |
101X00XXXX0XXX0XXXF XCHG R$Z,R$Y :$1=R$Z(),R$Z(R$Y()),R$Y($1) //Exchange R$Z! and R$Y! | |
110X00XXXX0XXX0XXXF XCHG P$Z,P$Y :$1=P$Z(),P$Z(P$Y()),P$Y($1) //Exchange P$Z! and P$Y! | |
XXXX1XXXXX0XXX0000X .Y$Y :0 //reserved | |
XXXX1XXXXX00000XXXX .X$X :0 //reserved | |
1XXX1XX1000XXX0XXXC IN R$X :R$X(PORT(R$X())) //Input from port | |
XXXX1XX1000XXX0XXXC OUT R$X,R$Y :PORT(R$X(),R$Y()) //Output to port | |
001X1XX0000XXX0000F .Y$Y R$X;[R$Y] :0 //reserved | |
010X1XX00000000XXXF .X$X [R$X];R$Y :0 //reserved | |
XXXX01X10000000100C MOV :$CTX.splice(0xAF, 1), $CTX.splice(0xA9, 0, FH()),$IE=0 //Set argument | |
XXXX01X1000XXX0000C MOV $Y :FH($CTX[0xA8 + $Y]),$IE=0 //Get argument | |
XXXX00X0000XXX0XXXF MOV R$X,R$Y :R$X(R$Y()) //Move R$Y! to R$X! | |
0XXX00X1000XXX0XXXF MOV P$X,T$Y :P$X(T$Y()) //Move T$Y! vector to P$X! | |
XXXXXXX1000XXX1XXXA ALU$X Z$Y :$1=ALU$X(DROP($Y),REG($Y)),REG($Y,$1),FL($1.hi()) //ALU$X! with Z$Y! and retained | |
XXXXXXXXXX0XXX1XXXA ALU$X Z$Z,R$Y :$1=ALU$X(Z$Z(),R$Y()),Z$Z($1),FL($1.hi()) //ALU$X! with Z$Z! and R$Y! | |
XXXXXXX10010101XXXA ALU$X IB :$1=ALU$X(DROP(FH()),$B),ACC($1),FL($1.hi()) //ALU$X! with retained and immediate | |
XXXXXXXXXX10101XXXA ALU$X Z$Z,IB :$1=ALU$X(Z$Z(),$B),Z$Z($1),FL($1.hi()) //ALU$X! with Z$Z! and byte | |
XXXX00XXXX100XXXXXE PUSH $VIB :HEAP(0x$V00 + $B) //Push immediate data into stack | |
XXXX0XX00011111110C NOP :$Z //Hollow operation | |
XXXX0XXXXX11111110C NOP {$Z} :$Z //Hollow operation | |
111XXXX00011001XXXD INC Q$X :Q$X(Q$X()+1) //Increment Q$X! | |
111XXXX00011011XXXD DEC Q$X :Q$X(Q$X()-1) //Decrement Q$X! | |
XXXX00X00011001111A CMC :FL(FL() ^ 2) //Complement carry flag | |
XXXXXXXXXX11001110D ADC BX,T$Z :$1=BX()+T$Z()+(_CF?1:0),$2=($1>>15)&2,FL((FL()& 0xD)|$2), BX($1) //Addition register pair with carry | |
111XXXXXXX11001XXXD ADD Q$X,T$Z :$1=Q$X()+T$Z()+(_CF?0:0),$2=($1>>15)&2,FL((FL()& 0xD)|$2), Q$X($1) //Addition register pair | |
XXXXXXXXXX11011110D SBB BX,T$Z :$1=BX()-T$Z()-(_CF?1:0),$2=($1>>15)&2,FL((FL()& 0xD)|$2), BX($1) //Subtraction register pair with borrow | |
111XXXXXXX11011XXXD SUB Q$X,T$Z :$1=Q$X()-T$Z()-(_CF?0:0),$2=($1>>15)&2,FL((FL()& 0xD)|$2), Q$X($1) //Subtraction register pair | |
XXXX00X00011001010A XCHG :$1=ACC(); for($2=0,$0=0;8>$0;++$0,$1>>=1) $2=($2<<1)+($1&1); ACC($2)>0 //Exchange retained bits by mirror | |
XXXX00XXXX11001010A XCHG P$Z :$1=DST(),DST(P$Z()),P$Z($1) //Exchange P$Z! with retained pair | |
XXXX00XXXX11001111A XCHG R$Z :$1=ACC(),ACC(R$Z()),R$Z($1) //Exchange R$Z! with retained register | |
XXXXXXX100110X1XXXA ALU$W :$1=ACC(ALU$W(ACC())),FL($1.hi()) //ALU$W! with retained | |
XXXXXXXXXX110X1XXXA ALU$W Z$Z :$1=Z$Z(ALU$W(Z$Z())),FL($1.hi()) //ALU$W! with Z$Z! | |
XXXX00X00010100XXXF MOV R$X,IB :R$X($B) //Move immediate data into R$X! | |
XXXX0X10001011000XC BCND$X :CND$X?0:FL((FL() & 0x02) | 0x05) ;$IF=true //Conditional do | |
XXXX0X00001011000XB BCND$X $+$UIB :CND$X?IP(IP()+$A):0 ;$IF=true //Relative branching if CND$X! | |
XXXX00X10010111001E BIAS $+IB :HEAP(IP()+$A) //Push instruction based relative address | |
XXXX0X100010110XXXB CCND$X :CND$X?($1=P$Z(),P$Z(DW(SP())), DW(SP(), $1)):HEAP() ;$IF=true //Condition call | |
XXXX0XX00010110XXXB CCND$X $+IB :CND$X?HEAP(IP())+IP(IP()+$A):0 ;$IF=true //Relative call if CND$X! | |
XXXXXXX00011000XXXA INC R$X :$1=ADD(R$X(),1),R$X($1),FL($1.hi()) //Increment R$X! | |
XXXXXXX00011010XXXA DEC R$X :$1=SUB(R$X(),1),R$X($1),FL($1.hi()) //Decrement R$X! | |
XXXX00XXXX10100000E POP [P$Z+IB] :DW(P$Z()+$C,HEAP()) //Pop data into memory indexed by P$Z | |
XXXX00XXXX10100XXXF MOV R$X,[P$Z+IB] :R$X(DB(P$Z()+$C)) //Move memory data by P$Z pointer into R$X | |
XXXX00XXXX10110000E PUSH [P$Z+IB] :HEAP(DW(P$Z()+$C)) //Push data from memory indexed by P$Z | |
XXXX00XXXX10110XXXF MOV [P$Z+IB],R$X :DB(P$Z()+$C,R$X()) //Move R$X register data into memory by P$Z | |
XXXXXXX10010111XXXX --- IB :return 0 //Reserved extended code | |
XXXX00X10010111010E LEA +IB :DST(DST()+$B) //Load retained effective address | |
XXXX00X10010111XXXF MOV [U$X],IB :DB(U$X(),$B) //Load immediate data into memory by U$X | |
XXXX00100010111000C WAIT :FL((FL() & 0x02) | 0x0D) //Wait | |
XXXX0X0XXX10111000B JMP $+$UIB :$A==-2?(FL((FL() & 0x02) | 0x0D),trace.expression=0):IP(IP()+$A);$IF=true //Unonditional relative branching | |
XXXX0X0XXX10111001B CALL $+$UIB :$A==-2?0:HEAP(IP(IP()+$A)) ;$IF=true //Unconditional relative call | |
XXXX0X1XXX10111XXXC BCND$X :CND$X?0:FL((FL() & 0x02) | 0x05) ;$IF=true //Conditional do | |
XXXX00100010111001X . :0 //reserved | |
XXXX00100010111XXXX . :0 //reserved | |
XXXX0X0XXX10111XXXB BCND$X $+$UIB :CND$X?IP(IP()+$A):0 ;$IF=true //Branching if CND$X! | |
1X1X00X00011101XXXE PUSH U$X :HEAP(U$X()) //Push U$X! into stack | |
1X1X00X00011111XXXE POP U$X :U$X(HEAP()) //Pop U$X! from stack | |
XXXX00X10011101110F XCHG [SP] :$1=DST(),DST(DW($2=SP())), DW($2, $1) //Exchange retained pair with stack heap | |
XXXX00XXXX11101110F XCHG P$Z,[SP] :$1=P$Z(),P$Z(DW(SP())), DW(SP(), $1) //Exchange pair P$Z! with stack heap | |
XXXX00X10011101111E PUSH :HEAP(DST()) //Push retained pair | |
XXXX00XXXX11101111E PUSH S$Z :HEAP(S$Z()) //Push service S$Z register pair to stack | |
XXXX00X10011111111E POP :DST(HEAP()) //Pop retained pair | |
XXXX0XXXXX11111111E POP S$Z :S$Z(HEAP()) ;$IF=true //Pop service S$Z register pair from stack | |
XXXX00XXXX11101010E PUSH R$Z :DUP($Z) //Dup R$Z register history | |
XXXX00XXXX11101011C LOOP [R$Z] :FH(R$Z()|8),FL((FL() & 0x02) | 0x09) //Forcing next operation by R$Z bits | |
XXXX00XXXX11101100C LOOP R$Z :FH($Z), FL((FL() & 0x02) | 0x09) //Forcing next operation by R$Z counter | |
XXXX00XXXX11101101C LOOP $Z :FH($Z | 8), FL((FL() & 0x02) | 0x09) //Forcing next operation by $Z times | |
XXXX00XXXX11111010E POP R$Z :DROP($Z) //Drop R$Z register history | |
XXXX00XXXX11111011C SKIP [R$Z] :FH(R$Z()|8),FL((FL() & 0x02) | 0x05) //Exclude next operations by R$Z bits | |
XXXX00XXXX11111100C SKIP R$Z :FH($Z), FL((FL() & 0x02) | 0x05) //Exclude next operations by R$Z counter | |
XXXX00XXXX11111101C SKIP $Z :FH($Z | 8), FL((FL() & 0x02) | 0x05) //Exclude next operations by $Z times | |
100X10X0001111XXXXB FLY $T :FLY($T) //Fix the alias | |
100X10XXXX1111XXXXB FIX $T :FH($Z | 8), FL((FL() & 0x02) | 0x05),$IE=0;FIX($Z, $T) //Fix the alias | |
100X0XXXXX1111XXXXB INT $T :HEAP($IP)+IP(JP(10>$T?0:1)) ;$IF=true //Interruption | |
XXXXXXXXXXXXXXXXXXX Y$Y_X$X ($M) :0 //reserved | |
--> | |
000X11XXX0XXX0XXXC MOV [$X],ACC :CR($X, ACC()) //CR[$X] = ACC | |
XXXXXX00000000000C HLT :return 0 // HALT | |
XXXXXXXXX00000000C HLT R$Z :IS_WAIT ? FH() == $Z ? ACC(CTX(ACC())) : $IR ? CTX(ACC(),R$Z()) : R$Z(CR(FH())) : FH($Z) // Hold R$Z!/P$Z! as retained | |
000XXX0000XXX0XXX_ PREFIX R$X/P$Y :return 0 // PREFIX | |
XXXXXX00011111110C NOP :$B==$B // | |
X10XXX00011101XXXE PUSH U$X :HEAP(U$X()) // | |
X10XXX00011111XXXE POP U$X :U$X(HEAP()) // | |
XXXXXXXXX11111110C NOP $Z :return $Z //Hollow operation til $Z ticks | |
XXXXXX10010101XXXA ALU$X IB :$1=ALU$X(DROP(FH()),$B),ACC($1),FL($1.hi()) //ALU$X! with retained and immediate | |
XXXXXXXXX10101XXXA ALU$X Z$Z,IB :$1=ALU$X(Z$Z(),$B),Z$Z($1),FL($1.hi()) //ALU$X! with Z$Z! and byte | |
XXXXXX1000XXX1XXXA ALU$X Z$Y :$1=ALU$X(DROP($Y),REG($Y)),REG($Y,$1),FL($1.hi()) //ALU$X! with Z$Y! and retained | |
XXXXXXXXX0XXX1XXXA ALU$X Z$Z,R$Y :$1=ALU$X(Z$Z(),R$Y()),Z$Z($1),FL($1.hi()) //ALU$X! with Z$Z! and R$Y! | |
000000XXX0XXX0XXXC HLT $Z :FH($Z+8) //Hold $Z index number | |
X10XXX00011001XXXD INC Q$X :Q$X(Q$X()+1) // Increment Q$X! | |
X10XXX00011011XXXD DEC Q$X :Q$X(Q$X()-1) // Decrement Q$X! | |
XXXXXX00011001111A CMC :FL(FL() ^ 2) // Complement carry flag | |
XXXXXXXXX11001110D ADC BX,T$Z :$1=BX()+T$Z()+(_CF?1:0),$2=($1>>15)&2,FL((FL()& 0xD)|$2), BX($1) // Addition register pair with carry | |
X10XXXXXX11001XXXD ADD Q$X,T$Z :$1=Q$X()+T$Z()+(_CF?0:0),$2=($1>>15)&2,FL((FL()& 0xD)|$2), Q$X($1) // Addition register pair | |
XXXXXXXXX11011110D SBB BX,T$Z :$1=BX()-T$Z()-(_CF?1:0),$2=($1>>15)&2,FL((FL()& 0xD)|$2), BX($1) // Subtraction register pair with borrow | |
X10XXXXXX11011XXXD SUB Q$X,T$Z :$1=Q$X()-T$Z()-(_CF?0:0),$2=($1>>15)&2,FL((FL()& 0xD)|$2), Q$X($1) // Subtraction register pair | |
XXXXXX00011001010A XCHG :$1=ACC(); for($2=0,$0=0;8>$0;++$0,$1>>=1) $2=($2<<1)+($1&1); ACC($2)>0 // Exchange retained bits by mirror | |
XXXXXXXXX11001010A XCHG P$Z :$1=DST(),DST(P$Z()),P$Z($1) // Exchange P$Z! with retained pair | |
XXXXXXXXX11001111A XCHG R$Z :$1=ACC(),ACC(R$Z()),R$Z($1) // Exchange R$Z! with retained register | |
XXXXXX100110X1XXXA ALU$W :$1=ACC(ALU$W(ACC())),FL($1.hi()) // ALU$W! with retained | |
XXXXXXXXX110X1XXXA ALU$W Z$Z :$1=Z$Z(ALU$W(Z$Z())),FL($1.hi()) // ALU$W! with Z$Z! | |
X11XXX1000XXX0000A MUL R$Y :return 0 // | |
X11XXX10000000XXXF XCHG R$X :$1=ACC(),ACC(R$X()),R$X($1) // Exchange R$Z! with retained register | |
X11XXX1000XXX0100F XCHG P$Y :$1=DST(),DST(P$Y()),P$Y($1) // Exchange P$Z! with retained pair | |
X11XXX1000XXX0XXXF MOV P$X,T$Y :P$X(T$Y()) // Move T$Y! vector to P$X! | |
000X110000XXX0XXXC IN R$X :R$X(PORT(R$X())) //Input from port | |
XXXX110000XXX0XXXC OUT R$X,R$Y :PORT(R$X(),R$Y()) //Output to port | |
XXXXXX0000XXX0XXXF MOV R$X,R$Y :R$X(R$Y()) //Move data | |
XXXXXX00010110000B JCND$X $+IB :CND$X?IP(IP()+$A):0 // Relative branching if CND$X! | |
XXXXXX00010100XXXF MOV R$X,IB :R$X($B) // Move immediate data into R$X! | |
XXXXXX00010110001E BIAS $+IB :HEAP(IP()+$A) // Push instruction based relative address | |
XXXXXX00010110XXXB CCND$X $+IB :CND$X?HEAP(IP())+IP(IP()+$A):0 // Relative call if CND$X! | |
XXXXXX00011000XXXA INC R$X :$1=ADD(R$X(),1),R$X($1),FL($1.hi()) // Increment R$X! | |
XXXXXX00011010XXXA DEC R$X :$1=SUB(R$X(),1),R$X($1),FL($1.hi()) // Decrement R$X! | |
X00X00XXX1111XXXXB INT $T :HEAP($IP)+IP(JP($T<10?0:1))>0 // Programm interruption indexed by $T | |
XXXX0010011101110F XCHG [SP] :$1=DST(),DST(DW($2=SP())), DW($2, $1) // Exchange retained pair with stack heap | |
XXXX00XXX11101110F XCHG P$Z,[SP] :$1=P$Z(),P$Z(DW(SP())), DW(SP(), $1) // Exchange pair P$Z! with stack heap | |
001X00XXX0XXX0XXXF XCHG P$Z,P$Y :$1=P$Z(),P$Z(P$Y()),P$Y($1) // Exchange P$Z! and P$Y! | |
010X00XXX0XXX0XXXF XCHG R$Z,R$Y :$1=R$Z(),R$Z(R$Y()),R$Y($1) // Exchange R$Z! and R$Y! | |
XXXX00XXX10100000E POP [P$Z+IB] :DW(P$Z()+$C,HEAP()) // Pop data into memory indexed by P$Z | |
XXXX00XXX10100XXXF MOV R$X,[P$Z+IB] :R$X(DB(P$Z()+$C)) // Move memory data by P$Z pointer into R$X | |
XXXX00XXX10110000E PUSH [P$Z+IB] :HEAP(DW(P$Z()+$C)) // Push data from memory indexed by P$Z | |
XXXX00XXX10110XXXF MOV [P$Z+IB],R$X :DB(P$Z()+$C,R$X()) // Move R$X register data into memory by P$Z | |
XXXX0010011101111E PUSH :HEAP(DST()) // Push retained pair | |
XXXX00XXX11101111E PUSH S$Z :HEAP(S$Z()) // Push service S$Z register pair to stack | |
XXXX0010011111111E POP :DST(HEAP()) // Pop retained pair | |
XXXX00XXX11111111E POP S$Z :S$Z(HEAP()) // Pop service S$Z register pair from stack | |
XXXX00XXX11101010E PUSH R$Z :DUP($Z) // Dup R$Z register history | |
XXXX00XXX11101011C SKIP [R$Z] :FH(R$Z()|8),FL((FL() & 0x02) | 0x05) // Exclude next operations by R$Z bits | |
XXXX00XXX11101100C SKIP R$Z :FH($Z), FL((FL() & 0x02) | 0x05) // Exclude next operations by R$Z counter | |
XXXX00XXX11101101C SKIP $Z :FH($Z | 8), FL((FL() & 0x02) | 0x05) // Exclude next operations by $Z times | |
XXXX00XXX11111010E POP R$Z :DROP($Z) // Drop R$Z register history | |
XXXX00XXX11111011C LOOP [R$Z] :FH(R$Z()|8),FL((FL() & 0x02) | 0x09) // Forcing next operation by R$Z bits | |
XXXX00XXX11111100C LOOP R$Z :FH($Z), FL((FL() & 0x02) | 0x09) // Forcing next operation by R$Z counter | |
XXXX00XXX11111101C LOOP $Z :FH($Z | 8), FL((FL() & 0x02) | 0x09) // Forcing next operation by $Z times | |
XXXX00XXX100XXXXXE PUSH $VIB :HEAP(0x$V00 + $B) // Push immediate data into stack | |
0XXXXX10010111XXXX --- IB :return 0 // Reserved extended code | |
XXXX0010010111010E LEA +IB :DST(DST()+$B) // Load retained effective address | |
X10X0010010111XXXF MOV [U$X],IB :DB(U$X(),$B) // Load immediate data into memory by U$X | |
XXXX00XXX10111000B JMP $+$UIB :$A==-2?(FL((FL() & 0x02) | 0x0D),trace.expression=0):IP(IP()+$A) // Unonditional relative branching | |
XXXX00XXX10111001B CALL $+$UIB :$A==-2?0:HEAP(IP(IP()+$A)) // Unconditional relative call | |
XXXX00XXX10111XXXB JCND$X $+$UIB :CND$X?IP(IP()+$A):0 // Branching if CND$X! | |
XXXXXXXXXXXXXXXXXX --- :return 0 // Reserved code | |
XXX00000000000C HLT :IS_BOOT ? IS_WAIT ? CR(0, ACC()) : FH(8) : (CR(CR(0) & 0xF0), FH(0xB), FL(0x5)) // Halting | |
XXX00011111110C NOP :$IB==$IB // No operation | |
0000000XXX0XXX_ PREFIX R#X/P#X :0 // Prefix for R#X!/P#X! | |
X1000011101XXXE PUSH+ U#X :HEAP(U#X()) // Push pointer into stack | |
X1000011111XXXE POP+ U#X :U#X(HEAP()) // Pop pointer from stack | |
XXXXXX11111110C NOP #Z :#Z // Hollow operation through #Z ticks | |
XXX10010101XXXA ALU#X IB :$1=ALU#X(DROP(FH()),$IB),ACC($1),FL($1.hi()) // ALU#X! with retained and immediate | |
XXXXXX10101XXXA ALU#X Z#Z,IB :$1=ALU#X(Z#Z(),$IB),Z#Z($1),FL($1.hi()) // ALU#X! with Z#Z! and byte | |
XXX1000XXX1XXXA ALU#X Z#Y :$1=ALU#X(DROP(#Y),REG(#Y)),REG(#Y,$1),FL($1.hi()) // ALU#X! with Z#Y! and retained | |
XXXXXX0XXX1XXXA ALU#X Z#Z,R#Y :$1=ALU#X(Z#Z(),R#Y()),Z#Z($1),FL($1.hi()) // ALU#X! with Z#Z! and R#Y! | |
000XXX0XXX0XXXC HLT #Z :IS_BOOT && IS_WAIT ? FH()==(#Z+8) ? ACC(PORT(ACC())) : FH()>=8 ? PORT(R#Z(),ACC()) : CR(#Z,ACC()) : FH(#Z+8) // Hold #Z index number | |
X1000011001XXXD INC+ Q#X :Q#X(Q#X()+1) // Increment Q#X! | |
X1000011011XXXD DEC+ Q#X :Q#X(Q#X()-1) // Decrement Q#X! | |
XXX00011001111A CMC :FL(FL() ^ 2) // Complement carry flag | |
XXXXXX11001110D ADC BX,T#Z :$1=BX()+T#Z()+(_CF?1:0),$2=($1>>15)&2,FL((FL()& 0xD)|$2), BX($1) // Addition register pair with carry | |
X10XXX11001XXXD ADD Q#X,T#Z :$1=Q#X()+T#Z()+(_CF?0:0),$2=($1>>15)&2,FL((FL()& 0xD)|$2), Q#X($1) // Addition register pair | |
XXXXXX11011110D SBB BX,T#Z :$1=BX()-T#Z()-(_CF?1:0),$2=($1>>15)&2,FL((FL()& 0xD)|$2), BX($1) // Subtraction register pair with borrow | |
X10XXX11011XXXD SUB Q#X,T#Z :$1=Q#X()-T#Z()-(_CF?0:0),$2=($1>>15)&2,FL((FL()& 0xD)|$2), Q#X($1) // Subtraction register pair | |
XXX00011001010A XCHG :$1=ACC(); for($2=0,$0=0;$0<8;++$0,$1>>=1) $2=($2<<1)+($1&1); ACC($2)>0 // Exchange retained bits by mirror | |
XXXXXX11001010A XCHG P#Z :$1=DST(),DST(P#Z()),P#Z($1) // Exchange P#Z! with retained pair | |
XXXXXX11001111A XCHG R#Z :$1=ACC(),ACC(R#Z()),R#Z($1) // Exchange R#Z! with retained register | |
XXX100110X1XXXA ALU#W :$1=ACC(ALU#W(ACC())),FL($1.hi()) // ALU#W! with retained | |
XXXXXX110X1XXXA ALU#W Z#Z :$1=Z#Z(ALU#W(Z#Z())),FL($1.hi()) // ALU#W! with Z#Z! | |
X111000XXX0000A MUL R#Y :0 // | |
X1110000000XXXF XCHG R#X :$1=ACC(),ACC(R#X()),R#X($1) // Exchange R#Z! with retained register | |
X111000XXX0100F XCHG P#Y :$1=DST(),DST(P#Y()),P#Y($1) // Exchange P#Z! with retained pair | |
X111000XXX0XXXF MOV P#X,T#Y :P#X(T#Y()) // Move T#Y! vector to P#X! | |
01110000000XXXD_PUSH+ T#X+[T#Y] :HEAP(T#X()+DW(T#Y())) // Correct effective address in stack | |
0111000XXX0XXXD_PUSH+ T#X+T#Y :HEAP(T#X()+T#Y()) // Push effective address into stack | |
1111000XXX0000D_PUSH+ [T#X]-T#Y :HEAP(HEAP()-T#Y()) // Correct effective address in stack | |
1111000XXX0XXXD_PUSH+ T#X-T#Y :HEAP(T#X()-T#Y()) // Push effective address into stack | |
XXXXXX00000000C HLT R#Z :IS_WAIT ? FH() == #Z ? ACC(CTX(ACC())) : $IR ? CTX(ACC(),R#Z()) : R#Z(CR(FH())) : FH(#Z) // Hold R#Z!/P#Z! as retained | |
XXX0000XXX0XXXF MOV R#X,R#Y :IS_WAIT && true ? #Y == 0 ? ($1=PORT(R#X()),trace.eady?R#X($1):0) : PORT(R#X(),R#Y()) : R#X(R#Y()) // Move R#Y! data into R#X! | |
X11XXX0XXX0XXXD_ALU#Z P#X,T#Y :0 // | |
XXX00010110000B JCND#X $+IB :CND#X?IP(IP()+$IV):0 // Relative branching if CND#X! | |
XXX00010100XXXF MOV R#X,IB :R#X($IB) // Move immediate data into R#X! | |
XXX00010110001E BIAS $+IB :HEAP($IP+$IV) // Push instruction based relative address | |
XXX00010110XXXB CCND#X $+IB :CND#X?HEAP(IP())+IP(IP()+$IV):0 // Relative call if CND#X! | |
XXX00011000XXXA INC+ R#X :$1=ADD(R#X(),1),R#X($1),FL($1.hi()) // Increment R#X! | |
XXX00011010XXXA DEC+ R#X :$1=SUB(R#X(),1),R#X($1),FL($1.hi()) // Decrement R#X! | |
X00XXX1111XXXXB INT #T :HEAP($IP)+IP(JP(#T<10?0:1))>0 // Programm interruption indexed by #T | |
XXX10011101110F XCHG [SP] :$1=DST(),DST(DW($2=SP())), DW($2, $1) // Exchange retained pair with stack heap | |
XXXXXX11101110F XCHG P#Z,[SP] :$1=P#Z(),P#Z(DW(SP())), DW(SP(), $1) // Exchange pair P#Z with stack heap | |
001XXX0XXX0XXXF XCHG P#Z,P#Y :$1=P#Z(),P#Z(P#Y()),P#Y($1) // Exchange P#Z! and P#Y! | |
010XXX0XXX0XXXF XCHG R#Z,R#Y :$1=R#Z(),R#Z(R#Y()),R#Y($1) // Exchange R#Z! and R#Y! | |
011XXX0XXX0XXXD LEA P#Z,T#X+T#Y :P#Z(T#X()+T#Y()) // Load T#X!+T#Y! effective address into P#Z | |
111XXX0XXX0XXXD LEA P#Z,T#X-T#Y :P#Z(T#X()-T#Y()) // Load T#X!-T#Y! effective address into P#Z | |
XXXXXX10100000E POP+ [P#Z+IB] :DW(P#Z()+$IV,HEAP()) // Pop data into memory indexed by P#Z | |
XXXXXX10100XXXF MOV R#X,[P#Z+IB] :trace.is_port=IP_BP; trace.is_context=IP_SP; R#X(DB(P#Z()+$IV)) // Move memory data by P#Z pointer into R#X | |
XXXXXX10110000E PUSH+ [P#Z+IB] :HEAP(DW(P#Z()+$IV)) // Push data from memory indexed by P#Z | |
XXXXXX10110XXXF MOV [P#Z+IB],R#X :trace.is_port=IP_BP; trace.is_context=IP_SP; DB(P#Z()+$IV,R#X()) // Move R#X register data into memory by P#Z | |
XXX10011101111E PUSH :HEAP(DST()) // Push retained pair | |
XXXXXX11101111E PUSH+ S#Z :HEAP(S#Z()) // Push service S#Z register pair to stack | |
XXX10011111111E POP :DST(HEAP()) // Pop retained pair | |
XXXXXX11111111E POP+ S#Z :S#Z(HEAP()) // Pop service S#Z register pair from stack | |
XXXXXX11101010E PUSH+ R#Z :DUP(#Z) // Dup R#Z register history | |
XXXXXX11101011C SKIP [R#Z] :FH(R#Z()|8),FL((FL() & 0x02) | 0x05) // Exclude next operations by R#Z bits | |
XXXXXX11101100C SKIP R#Z :FH(#Z), FL((FL() & 0x02) | 0x05) // Exclude next operations by R#Z counter | |
XXXXXX11101101C SKIP #Z :FH(#Z | 8), FL((FL() & 0x02) | 0x05) // Exclude next operations by #Z times | |
XXXXXX11111010E POP+ R#Z :DROP(#Z) // Drop R#Z register history | |
XXXXXX11111011C LOOP [R#Z] :FH(R#Z()|8),FL((FL() & 0x02) | 0x09) // Forcing next operation by R#Z bits | |
XXXXXX11111100C LOOP R#Z :FH(#Z), FL((FL() & 0x02) | 0x09) // Forcing next operation by R#Z counter | |
XXXXXX11111101C LOOP #Z :FH(#Z | 8), FL((FL() & 0x02) | 0x09) // Forcing next operation by #Z times | |
XXXXXX100XXXXXE PUSH+ #VIB :HEAP(0x#V00 + $IB) // Push immediate data into stack | |
0XX10010111XXXX --- IB :return 0 // Reserved extended code | |
XXX10010111010E LEA +IB :DST(DST()+$IB) // Load retained effective address | |
X1010010111XXXF MOV [U#X],IB :DB(U#X(),$IB) // Load immediate data into memory by U#X | |
XXXXXX10111000B JMP $+#UIB :$IW==-2?(FL((FL() & 0x02) | 0x0D),trace.expression=0):IP(IP()+$IW) // Unonditional relative branching | |
XXXXXX10111001B CALL $+#UIB :$IW==-2?0:HEAP(IP(IP()+$IW)) // Unconditional relative call | |
XXXXXX10111XXXB JCND#X $+#UIB :CND#X?IP(IP()+$IW):0 // Branching if CND#X! | |
XXXXXXXXXXXXXXX --- :return 0 // Reserved code | |
// Helpers | |
ALU08 ROL ROL Roll Overflow Left | |
ALU09 RCL RCL Roll Cyclic Left | |
ALU0A XCHG | |
ALU0F NEG 0 | |
ALU18 ROR ROR Roll Overflow Right | |
ALU19 RCR RCR Roll Cyclic Right | |
ALU1A RAR RAR Roll Arithmetic Right | |
ALU1F NOT NOT Bitwise NOT | |
ALU0 ADC ADC Addition with carry | |
ALU1 SBB SBB Subtract with borrow | |
ALU2 ADD ADD Addition | |
ALU3 SUB SUB Subtract | |
ALU4 AND AND Bitwise AND/conjunct | |
ALU5 OR OR Bitwise OR/disjunct | |
ALU6 XOR XOR Bitwise eXclusive OR | |
ALU7 CMP CMP Comparation | |
// Register descriptions | |
// Pointers | |
P14 -- -- -- | |
P15 -- -- -- | |
P0 IP IP IP | |
P1 BP BP BP | |
P2 SI SI SI | |
P3 DI DI DI | |
P4 SP SP SP | |
P5 BX BX DX | |
P6 CX CX CX | |
P7 DX DX DX | |
// Quad | |
Q3 BX BX BX | |
Q4 CX CX CX | |
Q5 DX DX DX | |
Q6 SP SP SP | |
// Regular | |
R0 [BX] _BX_ [BX] | |
R1 BH BH BH | |
R2 CH CH CH | |
R3 DH DH DH | |
R4 AL AL AL | |
R5 BL BL BL | |
R6 CL CL CL | |
R7 DL DL DL | |
// Special | |
S0 IP IP IP | |
S1 BP BP BP | |
S2 SI SI SI | |
S3 DI DI DI | |
S4 [SP] _SP_ [SP] | |
S5 EX Extend Ex | |
S6 SX SX Sx | |
S7 TX Timers Tx | |
// Tabular | |
T0 SP SP SP | |
T1 BP BP BP | |
T2 SI SI SI | |
T3 DI DI DI | |
T4 AL _AL_ AL | |
T5 BX BX BX | |
T6 CX CX CX | |
T7 DX DX DX | |
// Unical | |
U2 AX AX AX | |
U3 BX BX BX | |
U4 CX CX CX | |
U5 DX DX DX | |
Z0 AL AL AL | |
Z1 BH BH BH | |
Z2 CH CH CH | |
Z3 DH DH DH | |
Z4 AL AL AL | |
Z5 BL BL BL | |
Z6 CL CL CL | |
Z7 DL DL DL | |
Z8 AL AL AL | |
_ZF ZF !!(FL() & 1) | |
_CF CF !!(FL() & 2) | |
_PF PF !!(FL() & 4) | |
_SF SF !!(FL() & 8) | |
// Conditional | |
CND0 PO !!(FL() & 4) Parity is Odd | |
CND1 PE !(FL() & 4) Parity is Even | |
CND2 S !!(FL() & 8) result is Among | |
CND3 NS !(FL() & 8) result is Bigger | |
CND4 C !!(FL() & 2) result with Carry | |
CND5 NC !(FL() & 2) result Carry Discarded | |
CND6 Z !!(FL() & 1) result is Equal | |
CND7 NZ !(FL() & 1) result is Fictional | |
IS_BOOT IS_BOOT (!(CR() & 128)) | |
IS_WAIT IS_WAIT ($IE == 3) | |
IP_BP IP_BP (BP().hi()==IP().hi() && (($Z==1)||($Z==4))) | |
IP_SP IP_SP (SP().hi()==IP().hi() && ($Z==4)) | |
CLC! @BD 01 CF Clear CARRY FLAG | |
STC! @BC 01 CF Store CARRY FLAG | |
RPE! @B0 FF Return by EVEN PARITY | |
RPO! @B1 FF Return by ODD PARITY | |
RS! @BA FF Return by Positive | |
RNS! @BB FF Return by Negative | |
RC! @BC FF Return by CARRY | |
RNC! @BD FF Return by not CARRY | |
RZ! @BE FF Return by ZERO | |
RNZ! @BF FF Return by not ZERO | |
RET! @B8 FF Return from subroutine | |
<!-- | |
// Aliases | |
HLT 0 @00 | |
HLT BP @11 00 | |
HLT SI @22 00 | |
HLT DI @33 00 | |
HLT [SP] @44 00 | |
HLT BX @55 00 | |
HLT CX @66 00 | |
HLT DX @77 00 | |
WAIT!0 @B8 FE F0 Express Function #0 | |
WAIT!1 @B8 FE F1 Express Function #1 | |
WAIT!2 @B8 FE F2 Express Function #2 | |
WAIT!3 @B8 FE F3 Express Function #3 | |
WAIT!4 @B8 FE F4 Express Function #4 | |
WAIT!5 @B8 FE F5 Express Function #5 | |
WAIT!6 @B8 FE F6 Express Function #6 | |
WAIT!7 @B8 FE F7 Express Function #7 | |
WAIT!8 @B8 FE F8 Express Function #8 | |
WAIT!9 @B8 FE F9 Express Function #9 | |
CALL![SP] @EE Call subroutine | |
WAIT! @B8 FE Waitable mode | |
MOV!BX,CX @21 65 Load %Y register pair to %X | |
MOV!BX,DX @31 75 Load %Y register pair to %X | |
MOV!CX,BX @12 56 Load %Y register pair to %X | |
MOV!CX,DX @31 76 Load %Y register pair to %X | |
MOV!DX,BX @13 57 Load %Y register pair to %X | |
MOV!DX,CX @23 67 Load %Y register pair to %X | |
MOV!BP,SI @22 EF 11 FF Load %Y register pair to %X | |
MOV!BP,DI @33 EF 11 FF Load %Y register pair to %X | |
MOV!BP,BX @EB 11 FF Load %Y register pair to %X | |
MOV!BP,CX @EC 11 FF Load %Y register pair to %X | |
MOV!BP,DX @ED 11 FF Load %Y register pair to %X | |
MOV!SI,BP @11 EF 22 FF Load %Y register pair to %X | |
MOV!SI,DI @33 EF 22 FF Load %Y register pair to %X | |
MOV!SI,BX @EB 22 FF Load %Y register pair to %X | |
MOV!SI,CX @EC 22 FF Load %Y register pair to %X | |
MOV!SI,DX @ED 22 FF Load %Y register pair to %X | |
MOV!DI,BP @11 EF 33 FF Load %Y register pair to %X | |
MOV!DI,SI @22 EF 33 FF Load %Y register pair to %X | |
MOV!DI,BX @EB 33 FF Load %Y register pair to %X | |
MOV!DI,CX @EC 33 FF Load %Y register pair to %X | |
MOV!DI,DX @ED 33 FF Load %Y register pair to %X | |
MOV!BX,BP @11 EF FB Load %Y register pair to %X | |
MOV!BX,SI @22 EF FB Load %Y register pair to %X | |
MOV!BX,DI @33 EF FB Load %Y register pair to %X | |
MOV!CX,BP @11 EF FC Load %Y register pair to %X | |
MOV!CX,SI @22 EF FC Load %Y register pair to %X | |
MOV!CX,DI @33 EF FC Load %Y register pair to %X | |
MOV!DX,BP @11 EF FD Load %Y register pair to %X | |
MOV!DX,SI @22 EF FD Load %Y register pair to %X | |
MOV!DX,DI @33 EF FD Load %Y register pair to %X | |
MOV [0],BH @11 00 B8 FE 00 Set control register #%X by %Y | |
MOV [0],CH @22 00 B8 FE 00 Set control register #%X by %Y | |
MOV [0],DH @33 00 B8 FE 00 Set control register #%X by %Y | |
MOV [0],AL @44 00 B8 FE 00 Set control register #%X by %Y | |
MOV [0],BL @55 00 B8 FE 00 Set control register #%X by %Y | |
MOV [0],CL @66 00 B8 FE 00 Set control register #%X by %Y | |
MOV [0],DL @77 00 B8 FE 00 Set control register #%X by %Y | |
MOV [1],BH @11 00 B8 FE 11 11 Set control register #%X by %Y | |
MOV [1],CH @22 00 B8 FE 11 11 Set control register #%X by %Y | |
MOV [1],DH @33 00 B8 FE 11 11 Set control register #%X by %Y | |
MOV [1],AL @44 00 B8 FE 11 11 Set control register #%X by %Y | |
MOV [1],BL @55 00 B8 FE 11 11 Set control register #%X by %Y | |
MOV [1],CL @66 00 B8 FE 11 11 Set control register #%X by %Y | |
MOV [1],DL @77 00 B8 FE 11 11 Set control register #%X by %Y | |
MOV [2],BH @11 00 B8 FE 22 22 Set control register #%X by %Y | |
MOV [2],CH @22 00 B8 FE 22 22 Set control register #%X by %Y | |
MOV [2],DH @33 00 B8 FE 22 22 Set control register #%X by %Y | |
MOV [2],AL @44 00 B8 FE 22 22 Set control register #%X by %Y | |
MOV [2],BL @55 00 B8 FE 22 22 Set control register #%X by %Y | |
MOV [2],CL @66 00 B8 FE 22 22 Set control register #%X by %Y | |
MOV [2],DL @77 00 B8 FE 22 22 Set control register #%X by %Y | |
MOV [3],BH @11 00 B8 FE 33 33 Set control register #%X by %Y | |
MOV [3],CH @22 00 B8 FE 33 33 Set control register #%X by %Y | |
MOV [3],DH @33 00 B8 FE 33 33 Set control register #%X by %Y | |
MOV [3],AL @44 00 B8 FE 33 33 Set control register #%X by %Y | |
MOV [3],BL @55 00 B8 FE 33 33 Set control register #%X by %Y | |
MOV [3],CL @66 00 B8 FE 33 33 Set control register #%X by %Y | |
MOV [3],DL @77 00 B8 FE 33 33 Set control register #%X by %Y | |
MOV [4],BH @11 00 B8 FE 44 44 Set control register #%X by %Y | |
MOV [4],CH @22 00 B8 FE 44 44 Set control register #%X by %Y | |
MOV [4],DH @33 00 B8 FE 44 44 Set control register #%X by %Y | |
MOV [4],AL @44 00 B8 FE 44 44 Set control register #%X by %Y | |
MOV [4],BL @55 00 B8 FE 44 44 Set control register #%X by %Y | |
MOV [4],CL @66 00 B8 FE 44 44 Set control register #%X by %Y | |
MOV [4],DL @77 00 B8 FE 44 44 Set control register #%X by %Y | |
MOV [5],BH @11 00 B8 FE 55 55 Set control register #%X by %Y | |
MOV [5],CH @22 00 B8 FE 55 55 Set control register #%X by %Y | |
MOV [5],DH @33 00 B8 FE 55 55 Set control register #%X by %Y | |
MOV [5],AL @44 00 B8 FE 55 55 Set control register #%X by %Y | |
MOV [5],BL @55 00 B8 FE 55 55 Set control register #%X by %Y | |
MOV [5],CL @66 00 B8 FE 55 55 Set control register #%X by %Y | |
MOV [5],DL @77 00 B8 FE 55 55 Set control register #%X by %Y | |
MOV [6],BH @11 00 B8 FE 66 66 Set control register #%X by %Y | |
MOV [6],CH @22 00 B8 FE 66 66 Set control register #%X by %Y | |
MOV [6],DH @33 00 B8 FE 66 66 Set control register #%X by %Y | |
MOV [6],AL @44 00 B8 FE 66 66 Set control register #%X by %Y | |
MOV [6],BL @55 00 B8 FE 66 66 Set control register #%X by %Y | |
MOV [6],CL @66 00 B8 FE 66 66 Set control register #%X by %Y | |
MOV [6],DL @77 00 B8 FE 66 66 Set control register #%X by %Y | |
MOV [7],BH @11 00 B8 FE 77 77 Set control register #%X by %Y | |
MOV [7],CH @22 00 B8 FE 77 77 Set control register #%X by %Y | |
MOV [7],DH @33 00 B8 FE 77 77 Set control register #%X by %Y | |
MOV [7],AL @44 00 B8 FE 77 77 Set control register #%X by %Y | |
MOV [7],BL @55 00 B8 FE 77 77 Set control register #%X by %Y | |
MOV [7],CL @66 00 B8 FE 77 77 Set control register #%X by %Y | |
MOV [7],DL @77 00 B8 FE 77 77 Set control register #%X by %Y | |
MOV BH,[0] @00 B8 FE 11 00 Get control register #%Y to %X | |
MOV CH,[0] @00 B8 FE 22 00 Get control register #%Y to %X | |
MOV DH,[0] @00 B8 FE 33 00 Get control register #%Y to %X | |
MOV AL,[0] @00 B8 FE 44 00 Get control register #%Y to %X | |
MOV BL,[0] @00 B8 FE 55 00 Get control register #%Y to %X | |
MOV CL,[0] @00 B8 FE 66 00 Get control register #%Y to %X | |
MOV DL,[0] @00 B8 FE 77 00 Get control register #%Y to %X | |
MOV BH,[1] @11 11 B8 FE 11 00 Get control register #%Y to %X | |
MOV CH,[1] @11 11 B8 FE 22 00 Get control register #%Y to %X | |
MOV DH,[1] @11 11 B8 FE 33 00 Get control register #%Y to %X | |
MOV AL,[1] @11 11 B8 FE 44 00 Get control register #%Y to %X | |
MOV BL,[1] @11 11 B8 FE 55 00 Get control register #%Y to %X | |
MOV CL,[1] @11 11 B8 FE 66 00 Get control register #%Y to %X | |
MOV DL,[1] @11 11 B8 FE 77 00 Get control register #%Y to %X | |
MOV BH,[2] @22 22 B8 FE 11 00 Get control register #%Y to %X | |
MOV CH,[2] @22 22 B8 FE 22 00 Get control register #%Y to %X | |
MOV DH,[2] @22 22 B8 FE 33 00 Get control register #%Y to %X | |
MOV AL,[2] @22 22 B8 FE 44 00 Get control register #%Y to %X | |
MOV BL,[2] @22 22 B8 FE 55 00 Get control register #%Y to %X | |
MOV CL,[2] @22 22 B8 FE 66 00 Get control register #%Y to %X | |
MOV DL,[2] @22 22 B8 FE 77 00 Get control register #%Y to %X | |
MOV BH,[3] @33 33 B8 FE 11 00 Get control register #%Y to %X | |
MOV CH,[3] @33 33 B8 FE 22 00 Get control register #%Y to %X | |
MOV DH,[3] @33 33 B8 FE 33 00 Get control register #%Y to %X | |
MOV AL,[3] @33 33 B8 FE 44 00 Get control register #%Y to %X | |
MOV BL,[3] @33 33 B8 FE 55 00 Get control register #%Y to %X | |
MOV CL,[3] @33 33 B8 FE 66 00 Get control register #%Y to %X | |
MOV DL,[3] @33 33 B8 FE 77 00 Get control register #%Y to %X | |
MOV BH,[4] @44 44 B8 FE 11 00 Get control register #%Y to %X | |
MOV CH,[4] @44 44 B8 FE 22 00 Get control register #%Y to %X | |
MOV DH,[4] @44 44 B8 FE 33 00 Get control register #%Y to %X | |
MOV AL,[4] @44 44 B8 FE 44 00 Get control register #%Y to %X | |
MOV BL,[4] @44 44 B8 FE 55 00 Get control register #%Y to %X | |
MOV CL,[4] @44 44 B8 FE 66 00 Get control register #%Y to %X | |
MOV DL,[4] @44 44 B8 FE 77 00 Get control register #%Y to %X | |
MOV BH,[5] @55 55 B8 FE 11 00 Get control register #%Y to %X | |
MOV CH,[5] @55 55 B8 FE 22 00 Get control register #%Y to %X | |
MOV DH,[5] @55 55 B8 FE 33 00 Get control register #%Y to %X | |
MOV AL,[5] @55 55 B8 FE 44 00 Get control register #%Y to %X | |
MOV BL,[5] @55 55 B8 FE 55 00 Get control register #%Y to %X | |
MOV CL,[5] @55 55 B8 FE 66 00 Get control register #%Y to %X | |
MOV DL,[5] @55 55 B8 FE 77 00 Get control register #%Y to %X | |
MOV BH,[6] @66 66 B8 FE 11 00 Get control register #%Y to %X | |
MOV CH,[6] @66 66 B8 FE 22 00 Get control register #%Y to %X | |
MOV DH,[6] @66 66 B8 FE 33 00 Get control register #%Y to %X | |
MOV AL,[6] @66 66 B8 FE 44 00 Get control register #%Y to %X | |
MOV BL,[6] @66 66 B8 FE 55 00 Get control register #%Y to %X | |
MOV CL,[6] @66 66 B8 FE 66 00 Get control register #%Y to %X | |
MOV DL,[6] @66 66 B8 FE 77 00 Get control register #%Y to %X | |
MOV BH,[7] @77 77 B8 FE 11 00 Get control register #%Y to %X | |
MOV CH,[7] @77 77 B8 FE 22 00 Get control register #%Y to %X | |
MOV DH,[7] @77 77 B8 FE 33 00 Get control register #%Y to %X | |
MOV AL,[7] @77 77 B8 FE 44 00 Get control register #%Y to %X | |
MOV BL,[7] @77 77 B8 FE 55 00 Get control register #%Y to %X | |
MOV CL,[7] @77 77 B8 FE 66 00 Get control register #%Y to %X | |
MOV DL,[7] @77 77 B8 FE 77 00 Get control register #%Y to %X | |
MOV BH,[BH] @11 00 B8 FE 11 00 Read context cell [%X] to %X | |
MOV CH,[CH] @22 00 B8 FE 22 00 Read context cell [%X] to %X | |
MOV DH,[DH] @33 00 B8 FE 33 00 Read context cell [%X] to %X | |
MOV AL,[AL] @44 00 B8 FE 44 00 Read context cell [%X] to %X | |
MOV BL,[BL] @55 00 B8 FE 55 00 Read context cell [%X] to %X | |
MOV CL,[CL] @66 00 B8 FE 66 00 Read context cell [%X] to %X | |
MOV DL,[DL] @77 00 B8 FE 77 00 Read context cell [%X] to %X | |
MOV [BH],CH @11 00 B8 FE 22 00 Write %Y to context cell [%X] | |
MOV [BH],DH @11 00 B8 FE 33 00 Write %Y to context cell [%X] | |
MOV [BH],AL @11 00 B8 FE 44 00 Write %Y to context cell [%X] | |
MOV [BH],BL @11 00 B8 FE 55 00 Write %Y to context cell [%X] | |
MOV [BH],CL @11 00 B8 FE 66 00 Write %Y to context cell [%X] | |
MOV [BH],DL @11 00 B8 FE 77 00 Write %Y to context cell [%X] | |
MOV [CH],BH @22 00 B8 FE 11 00 Write %Y to context cell [%X] | |
MOV [CH],DH @22 00 B8 FE 33 00 Write %Y to context cell [%X] | |
MOV [CH],AL @22 00 B8 FE 44 00 Write %Y to context cell [%X] | |
MOV [CH],BL @22 00 B8 FE 55 00 Write %Y to context cell [%X] | |
MOV [CH],CL @22 00 B8 FE 66 00 Write %Y to context cell [%X] | |
MOV [CH],DL @22 00 B8 FE 77 00 Write %Y to context cell [%X] | |
MOV [DH],BH @33 00 B8 FE 11 00 Write %Y to context cell [%X] | |
MOV [DH],CH @33 00 B8 FE 22 00 Write %Y to context cell [%X] | |
MOV [DH],AL @33 00 B8 FE 44 00 Write %Y to context cell [%X] | |
MOV [DH],BL @33 00 B8 FE 55 00 Write %Y to context cell [%X] | |
MOV [DH],CL @33 00 B8 FE 66 00 Write %Y to context cell [%X] | |
MOV [DH],DL @33 00 B8 FE 77 00 Write %Y to context cell [%X] | |
MOV [AL],BH @44 00 B8 FE 11 00 Write %Y to context cell [%X] | |
MOV [AL],CH @44 00 B8 FE 22 00 Write %Y to context cell [%X] | |
MOV [AL],DH @44 00 B8 FE 33 00 Write %Y to context cell [%X] | |
MOV [AL],BL @44 00 B8 FE 55 00 Write %Y to context cell [%X] | |
MOV [AL],CL @44 00 B8 FE 66 00 Write %Y to context cell [%X] | |
MOV [AL],DL @44 00 B8 FE 77 00 Write %Y to context cell [%X] | |
MOV [BL],BH @55 00 B8 FE 11 00 Write %Y to context cell [%X] | |
MOV [BL],CH @55 00 B8 FE 22 00 Write %Y to context cell [%X] | |
MOV [BL],DH @55 00 B8 FE 33 00 Write %Y to context cell [%X] | |
MOV [BL],AL @55 00 B8 FE 44 00 Write %Y to context cell [%X] | |
MOV [BL],CL @55 00 B8 FE 66 00 Write %Y to context cell [%X] | |
MOV [BL],DL @55 00 B8 FE 77 00 Write %Y to context cell [%X] | |
MOV [CL],BH @66 00 B8 FE 11 00 Write %Y to context cell [%X] | |
MOV [CL],CH @66 00 B8 FE 22 00 Write %Y to context cell [%X] | |
MOV [CL],DH @66 00 B8 FE 33 00 Write %Y to context cell [%X] | |
MOV [CL],AL @66 00 B8 FE 44 00 Write %Y to context cell [%X] | |
MOV [CL],BL @66 00 B8 FE 55 00 Write %Y to context cell [%X] | |
MOV [CL],DL @66 00 B8 FE 77 00 Write %Y to context cell [%X] | |
MOV [DL],BH @77 00 B8 FE 11 00 Write %Y to context cell [%X] | |
MOV [DL],CH @77 00 B8 FE 22 00 Write %Y to context cell [%X] | |
MOV [DL],DH @77 00 B8 FE 33 00 Write %Y to context cell [%X] | |
MOV [DL],AL @77 00 B8 FE 44 00 Write %Y to context cell [%X] | |
MOV [DL],BL @77 00 B8 FE 55 00 Write %Y to context cell [%X] | |
MOV [DL],CL @77 00 B8 FE 66 00 Write %Y to context cell [%X] | |
IN BH @B8 FE 01 Input to %X from port %X | |
IN CH @B8 FE 02 Input to %X from port %X | |
IN DH @B8 FE 03 Input to %X from port %X | |
IN AL @B8 FE 04 Input to %X from port %X | |
IN BL @B8 FE 05 Input to %X from port %X | |
IN CL @B8 FE 06 Input to %X from port %X | |
IN DL @B8 FE 07 Input to %X from port %X | |
OUT BH,CH @B8 FE 21 Output %Y to port %X | |
OUT BH,DH @B8 FE 31 Output %Y to port %X | |
OUT BH,AL @B8 FE 41 Output %Y to port %X | |
OUT BH,BL @B8 FE 51 Output %Y to port %X | |
OUT BH,CL @B8 FE 61 Output %Y to port %X | |
OUT BH,DL @B8 FE 71 Output %Y to port %X | |
OUT CH,BH @B8 FE 12 Output %Y to port %X | |
OUT CH,DH @B8 FE 32 Output %Y to port %X | |
OUT CH,AL @B8 FE 42 Output %Y to port %X | |
OUT CH,BL @B8 FE 52 Output %Y to port %X | |
OUT CH,CL @B8 FE 62 Output %Y to port %X | |
OUT CH,DL @B8 FE 72 Output %Y to port %X | |
OUT DH,BH @B8 FE 13 Output %Y to port %X | |
OUT DH,CH @B8 FE 23 Output %Y to port %X | |
OUT DH,AL @B8 FE 43 Output %Y to port %X | |
OUT DH,BL @B8 FE 53 Output %Y to port %X | |
OUT DH,CL @B8 FE 63 Output %Y to port %X | |
OUT DH,DL @B8 FE 73 Output %Y to port %X | |
OUT AL,BH @B8 FE 14 Output %Y to port %X | |
OUT AL,CH @B8 FE 24 Output %Y to port %X | |
OUT AL,DH @B8 FE 34 Output %Y to port %X | |
OUT AL,BL @B8 FE 54 Output %Y to port %X | |
OUT AL,CL @B8 FE 64 Output %Y to port %X | |
OUT AL,DL @B8 FE 74 Output %Y to port %X | |
OUT BL,BH @B8 FE 15 Output %Y to port %X | |
OUT BL,CH @B8 FE 25 Output %Y to port %X | |
OUT BL,DH @B8 FE 35 Output %Y to port %X | |
OUT BL,AL @B8 FE 45 Output %Y to port %X | |
OUT BL,CL @B8 FE 65 Output %Y to port %X | |
OUT BL,DL @B8 FE 75 Output %Y to port %X | |
OUT CL,BH @B8 FE 16 Output %Y to port %X | |
OUT CL,CH @B8 FE 26 Output %Y to port %X | |
OUT CL,DH @B8 FE 36 Output %Y to port %X | |
OUT CL,AL @B8 FE 46 Output %Y to port %X | |
OUT CL,BL @B8 FE 56 Output %Y to port %X | |
OUT CL,DL @B8 FE 76 Output %Y to port %X | |
OUT DL,BH @B8 FE 17 Output %Y to port %X | |
OUT DL,CH @B8 FE 27 Output %Y to port %X | |
OUT DL,DH @B8 FE 37 Output %Y to port %X | |
OUT DL,AL @B8 FE 47 Output %Y to port %X | |
OUT DL,BL @B8 FE 57 Output %Y to port %X | |
OUT DL,CL @B8 FE 67 Output %Y to port %X | |
--> | |
ASCx0000 FF FF FF FF FF FF FF FF C7 C7 C7 C7 FF FF FF FF | |
ASCx0010 F8 F8 F8 F8 FF FF FF FF C0 C0 C0 C0 FF FF FF FF | |
ASCx0020 FF FF FF FF F8 F8 F8 F8 C7 C7 C7 C7 F8 F8 F8 F8 | |
ASCx0030 F8 F8 F8 F8 F8 F8 F8 F8 C0 C0 C0 C0 F8 F8 F8 F8 | |
ASCx0040 FF FF FF FF FF FF FF FF F3 F3 C0 D2 F3 F3 ED DE | |
ASCx0050 FF FF FF FF FF FF FF FF F3 E1 C0 F3 F3 F3 F3 F3 | |
ASCx0060 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | |
ASCx0070 F7 F3 D1 C0 C0 D1 F3 F7 F3 F3 F3 F3 F3 C0 E1 F3 | |
ASCx0080 FF FF FF FF C7 C7 C7 C7 C7 C7 C7 C7 C7 C7 C7 C7 | |
ASCx0090 F8 F8 F8 F8 C7 C7 C7 C7 C0 C0 C0 C0 C7 C7 C7 C7 | |
ASCx00A0 FF FF FF FF C0 C0 C0 C0 C7 C7 C7 C7 C0 C0 C0 C0 | |
ASCx00B0 F8 F8 F8 F8 C0 C0 C0 C0 C0 C0 C0 C0 C0 C0 C0 C0 | |
ASCx00C0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | |
ASCx00D0 FF FF FF FF FF FF FF FF F3 F3 F3 F3 F3 F3 F3 F3 | |
ASCx00E0 FF FF FF C0 C0 FF FF FF FB F3 E2 C0 C0 E2 F3 FB | |
ASCx00F0 C7 DF DF D8 C2 FA FA FA FF FF FF FF FF FF FF FF | |
ASCx0100 FF FF FF FF FF FF FF FF FB FB FB FB FB FF FB FF | |
ASCx0110 F5 F5 F5 FF FF FF FF FF F5 F5 E0 F5 E0 F5 F5 FF | |
ASCx0120 FB F0 EB F1 FA E1 FB FF E7 E6 FD FB F7 EC FC FF | |
ASCx0130 FB F5 F5 F3 EA ED F2 FF F9 F9 FD FB FF FF FF FF | |
ASCx0140 FD FB F7 F7 F7 FB FD FF F7 FB FD FD FD FB F7 FF | |
ASCx0150 FF FB EA F1 EA FB FF FF FF FB FB E0 FB FB FF FF | |
ASCx0160 FF FF FF F3 F3 FB F7 FF FF FF FF E0 FF FF FF FF | |
ASCx0170 FF FF FF FF FF F3 F3 FF FF FE FD FB F7 EF FF FF | |
ASCx0180 F1 EE EC EA E6 EE F1 FF FB F3 FB FB FB FB F1 FF | |
ASCx0190 F1 EE FE F9 F7 EF E0 FF E0 FE FD F9 FE EE F1 FF | |
ASCx01A0 FD F9 F5 ED E0 FD FD FF E0 EF E1 FE FE EE F1 FF | |
ASCx01B0 F8 F7 EF E1 EE EE F1 FF E0 FE FD FB F7 F7 F7 FF | |
ASCx01C0 F1 EE EE F1 EE EE F1 FF F1 EE EE F0 FE FD E3 FF | |
ASCx01D0 FF F3 F3 FF FF F3 F3 FF F3 F3 FF F3 F3 FB F7 FF | |
ASCx01E0 FD FB F7 EF F7 FB FD FF FF FF E0 FF E0 FF FF FF | |
ASCx01F0 F7 FB FD FE FD FB F7 FF F1 EE FE FD FB FF FB FF | |
ASCx0200 F1 EE EC EA E8 EF F1 FF FB F5 EE EE E0 EE EE FF | |
ASCx0210 E1 EE EE E1 EE EE E1 FF F1 EE EF EF EF EE F1 FF | |
ASCx0220 E1 F6 F6 F6 F6 F6 E1 FF E0 EF EF E1 EF EF E0 FF | |
ASCx0230 E0 EF EF E1 EF EF EF FF F1 EE EF EF EC EE F0 FF | |
ASCx0240 EE EE EE E0 EE EE EE FF F1 FB FB FB FB FB F1 FF | |
ASCx0250 FE FE FE FE EE EE F1 FF EE ED EB E7 EB ED EE FF | |
ASCx0260 EF EF EF EF EF EE E0 FF EE E4 EA EA EE EE EE FF | |
ASCx0270 EE EE E6 EA EC EE EE FF F1 EE EE EE EE EE F1 FF | |
ASCx0280 E1 EE EE E1 EF EF EF FF F1 EE EE EE EA ED F2 FF | |
ASCx0290 E1 EE EE E1 EB ED EE FF F1 EE EF F1 FE EE F1 FF | |
ASCx02A0 E0 FB FB FB FB FB FB FF EE EE EE EE EE EE F1 FF | |
ASCx02B0 EE EE EE F5 F5 FB FB FF EE EE EE EA EA EA F5 FF | |
ASCx02C0 EE EE F5 FB F5 EE EE FF EE EE F5 FB FB FB FB FF | |
ASCx02D0 E0 FE FD F1 F7 EF E0 FF F1 F7 F7 F7 F7 F7 F1 FF | |
ASCx02E0 FF EF F7 FB FD FE FF FF F1 FD FD FD FD FD F1 FF | |
ASCx02F0 F1 EE FF FF FF FF FF FF FF FF FF FF FF FF E0 FF | |
ASCx0300 ED EA EA E2 EA EA ED FF FB F5 EE EE E0 EE EE FF | |
ASCx0310 E0 EF EF E1 EE EE E1 FF ED ED ED ED ED E0 FE FF | |
ASCx0320 F9 F5 F5 F5 F5 E0 EE FF E0 EF EF E1 EF EF E0 FF | |
ASCx0330 FB E0 EA EA E0 FB FB FF E0 EE EF EF EF EF EF FF | |
ASCx0340 EE EE F5 FB F5 EE EE FF EE EE EC EA E6 EE EE FF | |
ASCx0350 EA EE EC EA E6 EE EE FF EE ED EB E7 EB ED EE FF | |
ASCx0360 F8 F6 F6 F6 F6 F6 F6 FF EE E4 EA EA EE EE EE FF | |
ASCx0370 EE EE EE E0 EE EE EE FF F1 EE EE EE EE EE F1 FF | |
ASCx0380 E0 EE EE EE EE EE EE FF F0 EE EE F0 FA F6 EE FF | |
ASCx0390 E1 EE EE E1 EF EF EF FF F1 EE EF EF EF EE F1 FF | |
ASCx03A0 E0 FB FB FB FB FB FB FF EE EE EE F5 FB F7 EF FF | |
ASCx03B0 EE EA EA F1 EA EA EE FF E1 EE EE E1 EE EE E1 FF | |
ASCx03C0 EF EF EF E1 EE EE E1 FF EE EE EE E6 EA EA E6 FF | |
ASCx03D0 F1 EE EE F9 FE EE F1 FF EE EA EA EA EA EA E0 FF | |
ASCx03E0 F1 EE FE F8 FE EE F1 FF EA EA EA EA EA E0 FE FF | |
ASCx03F0 EE EE EE E0 FE FE FE FF C0 C0 C0 C0 C0 C0 C0 FF | |
ASCx0400 FF FF FF FF FF FF FF FF C7 C7 C7 C7 FF FF FF FF | |
ASCx0410 F8 F8 F8 F8 FF FF FF FF C0 C0 C0 C0 FF FF FF FF | |
ASCx0420 FF FF FF FF F8 F8 F8 F8 C7 C7 C7 C7 F8 F8 F8 F8 | |
ASCx0430 F8 F8 F8 F8 F8 F8 F8 F8 C0 C0 C0 C0 F8 F8 F8 F8 | |
ASCx0440 FF FF FF FF FF FF FF FF F3 F3 C0 D2 F3 F3 ED DE | |
ASCx0450 FF FF FF FF FF FF FF FF F3 E1 C0 F3 F3 F3 F3 F3 | |
ASCx0460 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | |
ASCx0470 F7 F3 D1 C0 C0 D1 F3 F7 F3 F3 F3 F3 F3 C0 E1 F3 | |
ASCx0480 FF FF FF FF C7 C7 C7 C7 C7 C7 C7 C7 C7 C7 C7 C7 | |
ASCx0490 F8 F8 F8 F8 C7 C7 C7 C7 C0 C0 C0 C0 C7 C7 C7 C7 | |
ASCx04A0 FF FF FF FF C0 C0 C0 C0 C7 C7 C7 C7 C0 C0 C0 C0 | |
ASCx04B0 F8 F8 F8 F8 C0 C0 C0 C0 C0 C0 C0 C0 C0 C0 C0 C0 | |
ASCx04C0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | |
ASCx04D0 FF FF FF FF FF FF FF FF F3 F3 F3 F3 F3 F3 F3 F3 | |
ASCx04E0 FF FF FF C0 C0 FF FF FF FB F3 E2 C0 C0 E2 F3 FB | |
ASCx04F0 C7 DF DF D8 C2 FA FA FA FF FF FF FF FF FF FF FF | |
ASCx0500 FF FF FF FF FF FF FF FF FB FB FB FB FB FF FB FF | |
ASCx0510 F5 F5 F5 FF FF FF FF FF F5 F5 E0 F5 E0 F5 F5 FF | |
ASCx0520 FB F0 EB F1 FA E1 FB FF E7 E6 FD FB F7 EC FC FF | |
ASCx0530 FB F5 F5 F3 EA ED F2 FF F9 F9 FD FB FF FF FF FF | |
ASCx0540 FD FB F7 F7 F7 FB FD FF F7 FB FD FD FD FB F7 FF | |
ASCx0550 FF FB EA F1 EA FB FF FF FF FB FB E0 FB FB FF FF | |
ASCx0560 FF FF FF F3 F3 FB F7 FF FF FF FF E0 FF FF FF FF | |
ASCx0570 FF FF FF FF FF F3 F3 FF FF FE FD FB F7 EF FF FF | |
ASCx0580 F1 EE EC EA E6 EE F1 FF FB F3 FB FB FB FB F1 FF | |
ASCx0590 F1 EE FE F9 F7 EF E0 FF E0 FE FD F9 FE EE F1 FF | |
ASCx05A0 FD F9 F5 ED E0 FD FD FF E0 EF E1 FE FE EE F1 FF | |
ASCx05B0 F8 F7 EF E1 EE EE F1 FF E0 FE FD FB F7 F7 F7 FF | |
ASCx05C0 F1 EE EE F1 EE EE F1 FF F1 EE EE F0 FE FD E3 FF | |
ASCx05D0 FF F3 F3 FF FF F3 F3 FF F3 F3 FF F3 F3 FB F7 FF | |
ASCx05E0 FD FB F7 EF F7 FB FD FF FF FF E0 FF E0 FF FF FF | |
ASCx05F0 F7 FB FD FE FD FB F7 FF F1 EE FE FD FB FF FB FF | |
ASCx0600 EF F7 FB FF FF FF FF FF FF FF F1 ED ED ED F2 FF | |
ASCx0610 F7 F7 F1 F6 F6 F6 F1 FF FF FF F8 F7 F7 F7 F8 FF | |
ASCx0620 FE FE F8 F6 F6 F6 F8 FF FF FF F9 F6 F1 F7 F8 FF | |
ASCx0630 F9 F6 F7 E3 F7 F7 F7 FF FF FF F8 F6 F8 FE F1 FF | |
ASCx0640 F7 F7 F1 F6 F6 F6 F6 FF FD FF F9 FD FD FD F8 FF | |
ASCx0650 FE FF FE FE FE F6 F9 FF F7 F7 F6 F5 F3 F5 F6 FF | |
ASCx0660 F9 FD FD FD FD FD F8 FF FF FF E5 EA EA EA EA FF | |
ASCx0670 FF FF F1 F6 F6 F6 F6 FF FF FF F9 F6 F6 F6 F9 FF | |
ASCx0680 FF FF F1 F6 F6 F1 F7 FF FF FF F8 F6 F6 F8 FE FF | |
ASCx0690 FF FF F1 F6 F7 F7 F7 FF FF FF F8 F7 F9 FE F1 FF | |
ASCx06A0 F7 F7 E3 F7 F7 F6 F9 FF FF FF EE EE EE EE F1 FF | |
ASCx06B0 FF FF EE EE EE F5 FB FF FF FF EE EE EA EA F5 FF | |
ASCx06C0 FF FF EE F5 FD F5 EE FF FF FF F6 F6 F8 FE F1 FF | |
ASCx06D0 FF FF F0 FE F9 F7 F0 FF FE FD FD FB FD FD FE FF | |
ASCx06E0 F7 F7 F7 FF F7 F7 F7 FF EF F7 F7 FB F7 F7 EE FF | |
ASCx06F0 FF FF F7 F3 F0 FC FE FF F7 F3 E1 C0 E1 F3 FB FF | |
ASCx0700 FF FF ED EA E2 EA ED FF FF FF F1 FE F8 F6 F9 FF | |
ASCx0710 FF FF F8 F7 F1 F6 F1 FF FF FF ED ED ED ED E0 FE | |
ASCx0720 FF FF F9 F6 F8 FE F0 FF FF FF F9 F6 F1 F7 F8 FF | |
ASCx0730 FF FF FB F1 EA F1 FB FB FF FF F0 F7 F7 F7 F7 FF | |
ASCx0740 FF FF F6 F9 F9 F6 F6 FF FF FF F6 F6 F4 F2 F6 FF | |
ASCx0750 F9 FF F6 F6 F4 F2 F6 FF FF FF F6 F5 F3 F5 F6 FF | |
ASCx0760 FF FF FC FA F6 F6 F6 FF FF FF EE E4 EA EA EE FF | |
ASCx0770 FF FF F6 F6 F0 F6 F6 FF FF FF F9 F6 F6 F6 F9 FF | |
ASCx0780 FF FF F0 F6 F6 F6 F6 FF FF FF F8 F6 F8 FA F6 FF | |
ASCx0790 FF FF F1 F6 F1 F7 F7 F7 FF FF F8 F7 F7 F7 F8 FF | |
ASCx07A0 FF FF E0 FB FB FB FB FF FF FF F6 F6 F8 FE F1 FF | |
ASCx07B0 FF FF EA EA F1 EA EA FF FF FF F1 F6 F1 F6 F1 FF | |
ASCx07C0 FF FF F7 F7 F1 F6 F1 FF FF FF EE EE E6 EA E6 FF | |
ASCx07D0 FF FF F9 F6 FD FE F1 FF FF FF EA EA EA EA E0 FF | |
ASCx07E0 FF FF F1 FE F8 FE F1 FF FF FF D5 D5 D5 D5 C0 FE | |
ASCx07F0 FF FF F6 F6 F0 FE FE FF FF E7 E7 81 81 E7 E7 FF | |
</var> | |
<h2 id=Prelude style='position:absolute; top:0; left:40%; width:20%;'>Prepare…</h2> | |
<table id=Terminal style=display:none><tr valign=top> | |
<td colspan=2><pre style=position:absolute><br /> | |
<textarea id=Assm rows=28 cols=108 style=visibility:hidden> | |
Intuitive clear mnemonic to quick memorize: | |
|Codes|Key|Elementary description__________ | |
00 :Nil-Null of instructions queue / HLT | |
xA..xB:A/B-Add / Subtract | |
xC..xD:C/D-Conjunction / Disjunction | |
xE : E -Exclusive bitwise OR | |
A0..A7: A -Access to bytes | |
A8..AF:A/A-Access to ALU | |
B0..B7: B -Branches to nearest substitutes | |
B8..BF:B/F-Branches to near labels by flags | |
C0..C7: C -Increment | |
CA :RAL-Concatenate Access roll | |
CF :C/F-Complement for Carry Flag | |
D0..D7: D -Decrement | |
DA :RAR-Descended Access roll | |
DF :D/F-Data Formation by NOT | |
+EC/ED:Exclude operations by Counter/Data | |
F0..F9:F/x-Functions of BIOS-API | |
+FC/FD:Forcing operation by Counter/Data | |
FE :F/E-Fiction Execute / NOP | |
FF :F/F-Finalize the Function / RET | |
Simplest protection from errors in code: | |
Examples|Macros||Codes|Description | |
BE FF |RZ ||B2 FE|Microcode#4 | |
BF FF |RNZ ||B2 FF|Microcode#5 | |
BE FE |REPZ ||B3 FE|Microcode#6- | |
BF FE |REPNZ ||B6 FF|Microcode#14 | |
CF BC FD|CLC ||B7 FE|Microcode#15 | |
CF BD FD|STC ||B7 FF|Microcode#16 | |
</textarea><br /> | |
</pre><pre id='Instructions'></pre><pre id=Triggers style=position:absoluter></pre> | |
<input id=KeyBoard size=100 value='D000,36BF' type=text accessKey=K title='keyboard buffer [ALT+K]' onblur='cpu.watch.active=""' onfocus='cpu.watch.active="K"' /><span id=Context></span></td> | |
<!--pre id='commands'></pre></td--> | |
<td rowspan=2> | |
<pre id=Disassembly></pre> | |
<nobr><input id=Address size=13 style=color:cyan value='' type=text accessKey=P title='Pointer/Poking data [ALT+P]' onblur='cpu.watch.active=""' onfocus='cpu.watch.active="P"' | |
/><input id=Mnemonic size=27 style=color:lightgreen value='' type=text accessKey=T title='Translation/Translator [ALT+T]' onblur='cpu.watch.active=""' onfocus='cpu.watch.active="T"' | |
/><input id=Remark size=37 style=color:yellow value='' type=text accessKey=R title='Remark/Remote [ALT+R]' onblur='cpu.watch.active=""' onfocus='cpu.watch.active="R"' /></nobr> | |
<pre id=FILE:Xonix style=display:none> | |
ORG 0x0000 | |
Xonix: | |
RET | |
</pre> | |
<pre id=FILE:Tetris style=display:none> | |
ORG 0x0000 | |
Tetris: | |
RET</pre> | |
<pre id=BootSection style=display:none | |
alt='.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F'><!-- | |
;F810:11 BF FF 11 BF 01 00 00 77 BF FF 77 BF 01 | |
;F820:22 BF FF 22 BF 01 00 00 66 BF FF 66 BF 01 | |
;F830:33 BF FF 33 BF 01 00 00 55 BF FF 55 BF 01 | |
;F840:44 BF FF 44 BF 01 00 00 | |
; Seq Blank X Y SX SY PX PY BELL SCREEN Mul78 | |
;7650:00 00 00 00 00 00 41 19 08 03 F0 05 D0 76 E7 FD | |
; Val Page | |
;7660:DE FD CC FD 50 76 | |
; ansistd outstd | |
;F800:A4 7F A5 02 5A | |
; F0 | |
; 5A | |
; F0 | |
; 5A | |
<!-- > ORG 0xFEFD | |
NOP | |
NOP | |
NOP | |
NOP | |
NOP | |
NOP | |
NOP | |
NOP | |
NOP | |
NOP 7 | |
NOP | |
NOP 1 | |
HLT DL | |
MOV [0],AL | |
MOV [1],AL | |
NOP 2 | |
MOV AL,[0] | |
MOV AL,[1] | |
NOP 3 | |
MOV [7],AL | |
NOP 4 | |
MOV AL,[7] | |
NOP 5 | |
MOV [CL],AL | |
NOP 6 | |
MOV AL,[AL] | |
<!--> DEBUG 0x00 | |
<!-- ORG 0x0000 | |
Zeroed: PUSH 0x0015 | |
POP BX | |
MOV CL,0x09 | |
LOOP CL | |
ADD BX,BX | |
MOV AL,0x01 | |
LOOP 7 | |
RCL AL | |
SKIP 3 | |
DEC AL | |
DEC AL | |
DEC AL | |
DEC AL | |
NOP | |
ADD BX,BX | |
MOV AL,0x80 | |
MOV CL,0x03 | |
HLT CL | |
STR | |
MOV AL,0x81 | |
MOV CL,0x03 | |
HLT CL | |
STB | |
MOV AL,0x82 | |
MOV CL,0x03 | |
HLT CL | |
SKIP | |
INC AL | |
INC AL | |
INC AL | |
INC AL | |
MOV AL,0x83 | |
MOV CL,0x03 | |
HLT CL | |
SKIB | |
INC AL | |
INC AL | |
INC AL | |
INC AL | |
MOV AL,0x84 | |
MOV CL,0x03 | |
HLT CL | |
REP | |
INC AL | |
MOV AL,0x85 | |
MOV CL,0x03 | |
HLT CL | |
REB | |
INC AL | |
;;;;;;;;;;;;;;;;; | |
ORG 0xE000 | |
INT_XX: NOP 1 | |
NOP 2 | |
NOP 3 | |
NOP 4 | |
NOP 5 | |
NOP 6 | |
NOP 7 | |
SKIP 2 | |
MOV AL,0x01 | |
SKIP 1 | |
SKIP 2 | |
MOV AL,0x02 | |
NOP | |
XCHG BX,[SP] | |
PUSH AX | |
MOV AL,[BX] | |
LOOP 4 | |
RCR AL | |
BIA .basic | |
CMP AL,[BX] | |
BIF .basic | |
MOV AL,[BX+1] | |
SUB AL,0xF0 | |
BIC .other | |
CMP AL,0x0A | |
BID .other | |
MOV AL,[BX] | |
INC BX | |
SKIP [AL] | |
NOP | |
JMP .memory | |
JMP .string | |
JMP .audio | |
JMP .data | |
JMP .unic | |
JMP .file | |
JMP .window | |
.basic: MOV AL,[BX] | |
SUB AL,0xF0 | |
BIC .other | |
CMP AL,0x0A | |
BID .other | |
SKIP AL | |
JMP .x0 | |
JMP .x1 | |
JMP .x2 | |
JMP .x3 | |
JMP .x4 | |
JMP .x5 | |
JMP .x6 | |
JMP .x7 | |
JMP .x8 | |
JMP .x9 | |
.memory:NOP 1 | |
.string:NOP 2 | |
.audio: NOP 3 | |
.data: NOP 4 | |
.unic: NOP 5 | |
.file: NOP 6 | |
BIAS .exit | |
RET | |
.other: NOP | |
JMP .other | |
.window:MOV AL,[BX] | |
INC BX | |
SKIP [AL] | |
JMP .exit | |
JMP .putc | |
JMP .putxt | |
JMP .getc | |
JMP .exit | |
JMP .puthx | |
JMP .exit | |
JMP .exit | |
JMP .exit | |
JMP .exit | |
.putc: POP AX | |
XCHG BX,[SP] | |
PUSH BIOS.PutChr | |
RET | |
.putxt: HLT BX | |
PUSH BIOS.PutMsg | |
XCHG IP,[SP] | |
POP AX | |
XCHG BX,[SP] | |
RET | |
.getc: POP AX | |
XCHG BX,[SP] | |
PUSH BIOS.GetChar | |
RET | |
.puthx: POP AX | |
XCHG BX,[SP] | |
PUSH BIOS.PutHex | |
RET | |
.exit: NOP | |
JMP .exit | |
INTS: XCHG BX,[SP] | |
PUSH DX | |
PUSH AX | |
MOV DL,[BX] | |
AND DL,DL | |
BIE .halt | |
INC BX | |
MOV DH,DL | |
LOOP 4 | |
RCR DH | |
CMP DL,DH | |
BIF .lo | |
AND DH,0x0F | |
CMP DH,0x08 | |
BID .lo | |
MOV DL,[BX] | |
INC BX | |
.lo: CMP DL,0xFA | |
BID .hard | |
SUB DL,0xF0 | |
BIC .hard | |
HLT DH | |
CALL .switch | |
DW .basic | |
DW .memory | |
DW .string | |
DW .audio | |
DW .data | |
DW .unic | |
DW .file | |
DW .window | |
.basic: NOP | |
.memory:NOP 1 | |
.string:NOP 2 | |
.audio: NOP 3 | |
.data: NOP 4 | |
.unic: NOP 5 | |
.file: NOP 6 | |
BASE .exit | |
RET | |
; 77+F0: | |
; 77+F1: | |
; 77+F2:AL=IsChar() | |
; 77+F3:AL=GetChr() | |
; 77+F4: | |
; 77+F5:PutHex(AL) | |
; 77+F6: | |
; 77+F7: | |
; 77+F8:PutMsg(BX) | |
; 77+F9:PutChr(CL) | |
.window:SKIP [DL] | |
JMP .exit | |
JMP ..putc | |
JMP ..putxt | |
JMP ..getc | |
JMP .exit | |
JMP .exit | |
JMP .exit | |
JMP .exit | |
..putc: POP AX,DX ; 77 F1 | |
XCHG BX,[SP] | |
PUSH BIOS.PutChr | |
RET | |
..putxt:POP AX,DX ; 77 F2 | |
HLT BX | |
PUSH BIOS.PutMsg | |
XCHG IP,[SP] | |
XCHG BX,[SP] | |
RET | |
..getc: POP AX,DX ; 77 F3 | |
XCHG BX,[SP] | |
PUSH BIOS.GetChar | |
RET | |
.exit: POP AX,DX | |
XCHG BX,[SP] | |
RET | |
.hard: POP AX,DX | |
XCHG BX,[SP] | |
RET | |
.halt: POP AX,DX | |
INT 72 | |
DB "\r\nHALT AT \0" | |
HLT BX | |
PUSH BIOS.PutPtr | |
XCHG IP,[SP] | |
PUSH BIOS.Prompt | |
RET | |
.switch:XCHG BX,[SP] | |
XCHG AL | |
ADD AL,AL | |
LEA BX,BX+AL | |
XCHG AL | |
PUSH [BX+0x00] | |
POP BX | |
XCHG BX,[SP] | |
RET | |
;;;;;;;;;;;;;;;;;;;;;;; | |
ORG 0x1000 | |
;;;;;;;;;;;;;;;;;;;;;;; | |
ORG 0x0100 | |
USER: ; USER API BY INT 0-9 | |
RET | |
DEBUG 0x1 | |
ORG 0xF7FF | |
NOP | |
;;;;;;;;;;;;;;; | |
ORG 0xF000 | |
TIMER: MOV BH,0x77 | |
MOV BL,0x1E | |
XCHG SP,BX | |
.x_____:MOV BL,0x30 | |
._x____:MOV BH,0x30 | |
.__x___:MOV CL,0x30 | |
.___x__:MOV CH,0x30 | |
.____x_:MOV DL,0x30 | |
._____x:MOV DH,0x30 | |
MOV AL,0xFF | |
.______:PUSH DX,CX | |
PUSH BX | |
POP [SP] | |
POP [SP] | |
POP [SP] | |
DEC AL | |
BIF .______ | |
MOV AL,0x39 | |
INC DH | |
CMP AL,DH | |
BID .______ | |
INC DL | |
CMP AL,DL | |
BID ._____x | |
INC CH | |
CMP AL,CH | |
BID .____x_ | |
INC CL | |
CMP AL,CL | |
BID .___x__ | |
INC BH | |
CMP AL,BH | |
BID .__x___ | |
INC BL | |
CMP AL,BL | |
BID ._x____ | |
JMP .x_____ | |
;;;;;;;;;;;;;;; | |
ORG 0xF600 | |
SPEEDO: SKIP 5 | |
MOV AL,CL | |
XOR AL,[BX] | |
MOV [BX],AL | |
DEC BX | |
CMP DH,BH | |
MOV DH,0x76 | |
MOV DL,0xD4 | |
XCHG SP,DX | |
.x___: MOV CL,0x30 | |
._x__: MOV CH,0x30 | |
.__x_: MOV BL,0x30 | |
.___x: MOV BH,0x30 | |
.____: XOR AL,AL | |
MOV DH,AL | |
MOV DL,AL | |
ADD DX,SP | |
PUSH BX,CX | |
MOV BH,0x7F | |
MOV BL,0xF3 | |
MOV CL,0x7F | |
.loop: XOR AL,AL | |
;CMC | |
HLT 7 | |
WAIT | |
NOP 5 | |
CMP BH,DH | |
BIF .loop | |
POP CX,BX | |
MOV AL,0x39 | |
INC BH | |
CMP AL,BH | |
BID .____ | |
INC BL | |
CMP AL,BL | |
BID .___x | |
INC CH | |
CMP AL,CH | |
BID .__x_ | |
INC CL | |
CMP AL,CL | |
BID ._x__ | |
JMP .x___ | |
;;;;;;;;;;;;;;;;; | |
ORG 0xF700 | |
SPEEDY: MOV DH,0x76 | |
MOV DL,0xD4 | |
XCHG SP,DX | |
.x___: MOV CL,0x30 | |
._x__: MOV CH,0x30 | |
.__x_: MOV BL,0x30 | |
.___x: MOV BH,0x30 | |
.____: XOR AL,AL | |
MOV DH,AL | |
MOV DL,AL | |
ADD DX,SP | |
PUSH BX,CX | |
MOV BH,0x7F | |
MOV BL,0xF3 | |
.loop: MOV AL,[BX] | |
XOR AL,0x7F | |
MOV [BX],AL | |
DEC BX | |
CMP BL,DL | |
BID .loop | |
CMP BH,DH | |
BIF .loop | |
POP CX,BX | |
MOV AL,0x39 | |
INC BH | |
CMP AL,BH | |
BID .____ | |
INC BL | |
CMP AL,BL | |
BID .___x | |
INC CH | |
CMP AL,CH | |
BID .__x_ | |
INC CL | |
CMP AL,CL | |
BID ._x__ | |
JMP .x___ | |
;;;;;;;;;;;;;;;;; | |
ORG 0xF300 | |
Help: | |
.List: DB "\n[A]BAC - CALCULATOR\r" | |
DB "\n[B]OOT - DOS-BOOTER\r" | |
DB "\n[C]OPY - COPY MEMORY\r" | |
DB "\n[D]UMP - DUMP OF MEMORY\r" | |
DB "\n[E]DIT - EDIT DUMP\r" | |
DB "\n[F]IND - FIND IN MEMORY\r" | |
DB "\n[G]OTO - GOTO ADDRESS\r" | |
DB "\n[I]DLE - STREAM ECHO\r" | |
DB "\n[J]OIN - JOIN\r" | |
DB "\n[K]EEP - KEEP\r" | |
DB "\n[L]IST - FILE LIST\r" | |
DB "\n[M]OVE - MOVE MEMORY DATA\r" | |
DB "\n[N]OTE - NOTE\r" | |
DB "\n[O]PEN - OPEN\r" | |
DB "\n[Q]UIT - REBOOT\r" | |
DB "\n[R]EAD - READ\r" | |
DB "\n[S]AVE - SAVE\r" | |
DB "\n[T]EXT - TEXT\r" | |
DB "\n[U]NIT - DEVICES LIST\r" | |
DB "\n[V]ANE - CPU FANS OUT\r" | |
DB "\n[W]AVE - WAVE\r" | |
DB "\n[X]TRA - EXTRA\r" | |
DB "\n[Y]AMP - Y-AMPLITUDE\r" | |
DB "\n[Z]ERO - CLEAR MEMORY\0" | |
ORG 0xF800 | |
BIOS: MOV! BH,0x76 | |
MOV BL,0xCE | |
XCHG SP,BX | |
PUSH 0x7600 | |
POP BP | |
PUSH 0xE000 | |
POP BX | |
MOV AL,0xF7 | |
CMP AL,0xF0 | |
MOV [AL],BL | |
ADD AL,0x08 | |
;CMC | |
MOV [AL],BH | |
LOOP 4 | |
INT 72 | |
DB "\_X80-BIOS V0.1\0" | |
.prompt: | |
PUSH BX | |
MOV BH,0x76 | |
MOV BL,0xCE | |
XCHG SP,BX | |
PUSH 0x7600 | |
POP BP | |
; | |
MOV DH,0xFF | |
HLT DH | |
MOV DL,0xDB | |
MOV! AL,0x00 | |
OUT DL,AL | |
IN DL | |
PUSH .OutDec | |
XCHG IP,[SP] | |
INT 72 | |
DB "\r\n/>\0" | |
..cmd: INT 73 | |
CMP AL,0x5B | |
BID ..cmd | |
MOV CL,AL | |
SUB AL,0x41 | |
BIC ..cmd | |
HLT CL | |
INT 71 | |
PUSH .words | |
POP BX | |
ADD AL,AL | |
ADD AL,AL | |
MOV DL,AL | |
XOR DH,DH | |
LEA BX,DX+BX | |
PUSH [BX+2] | |
PUSH [BX+0] | |
POP BX | |
MOV CL,0x03 | |
..loop: MOV AL,BH | |
ROR AL | |
ROR AL | |
AND AL,0x1F | |
ADD AL,0x40 | |
HLT AL | |
INT 71 | |
LOOP 5 | |
ADD BX,BX | |
DEC CL | |
BIF ..loop | |
POP DI | |
HLT AL | |
MOV AL,0x20 | |
INT 71 | |
PUSH ..hexas | |
POP SI | |
XOR CH,CH | |
MOV CL,0x01 | |
..hexa: PUSH [SI+0x00] | |
POP BX | |
MOV AL,CH | |
AND AL,CL | |
ADD AL,0xFF | |
PUSH .GetHex | |
XCHG IP,[SP] | |
SBB DL,DL | |
CMP AL,0x0D | |
BIE ..next | |
CMP AL,0x1B | |
BIE .prompt | |
CMP AL,0x7F | |
BIF ..next | |
NOT! CH | |
OR CH,CL | |
NOT CH | |
RAR CL | |
AND CL,CL | |
;JZ .prompt | |
;CMP CL,0x01 | |
BIE ..hexa | |
MOV AL,CH | |
AND AL,CH | |
BIE ..clr | |
MOV AL,0x08 | |
HLT AL | |
INT 72 | |
DB "\< \<\0";> | |
CMP CL,0x01 | |
BIE ..hexa | |
..clr: XCHG SI,BX | |
DEC BX | |
DEC BX | |
XCHG SI,BX | |
BIF ..hexa | |
..next: HLT AL | |
INT 71 | |
ADD DL,DL | |
BID ..next1 | |
PUSH BX | |
POP [SI+0x00] | |
XCHG SI,BX | |
INC BX | |
INC BX | |
XCHG SI,BX | |
OR CH,CL | |
..next1:ADD CL,CL | |
CMP AL,0x0D | |
BIF ..hexa | |
..exec: PUSH ..hexas | |
POP SI | |
PUSH [SI+0x04] | |
PUSH [SI+0x02] | |
PUSH [SI+0x00] | |
MOV DL,0xDB | |
MOV AL,0xFF | |
OUT DL,AL | |
MOV AL,CH | |
ADD AL,CL | |
ADD AL,CL | |
POP BX,DX | |
POP CX | |
PUSH DI | |
XCHG IP,[SP] | |
XOR AL,AL | |
BIE .prompt | |
NOP 7 | |
SBB DL,DL | |
CMP AL,0x7F | |
XOR AL,AL | |
BIE .prompt | |
INT 71 | |
PUSH 0x76D0 | |
PUSH 0x78FF | |
POP DX,BX | |
PUSH! .HexDmp | |
XCHG IP,[SP] | |
PUSH .hello | |
POP BX | |
PUSH .PutMsg | |
HLT BX | |
XCHG IP,[SP] | |
PUSH .PutPtr | |
XCHG IP,[SP] | |
; MOV DL,0x08 | |
; MOV DH,0x06 | |
; INT 71 | |
; INT 9S | |
; HLT 3 | |
..hexas:DW 0x0000 | |
DW 0x0000 | |
DW 0x0000 | |
DW 0x0000 | |
DW 0x0000 | |
DW 0x0000 | |
DW 0x0000 | |
DW 0x0000 | |
.loopy: PUSH .PutChr | |
PUSH .GetChar | |
XCHG IP,[SP] | |
HLT AL | |
XCHG IP,[SP] | |
CMP AL,0x60 | |
;JZ .stop | |
CMP AL,0x0D | |
BIF .loopy | |
INT 72 | |
DW 0x0808 | |
DW 0x0808 | |
DB 0x08 | |
DB ":\0" | |
PUSH TX | |
POP BX | |
PUSH .PutPtr | |
XCHG IP,[SP] | |
JMP .loopy | |
.stop: PUSH? BIOS.API.fn | |
XCHG IP,[SP] | |
HLT | |
HLT | |
NOP 5 | |
.hello: DB "\h\^\^BIOS\r\n/>\0" | |
.words: DW 0x0823,..none ;ABAC | |
DW 0x3DF4,..none ;BOOT | |
DW 0x3E19,..none ;COPY | |
DW 0x55B0,.HexDmp ;DUMP | |
DW 0x1134,..none ;EDIT | |
DW 0x25C4,..none ;FIND | |
DW 0x3E8F,..Goto ;GOTO | |
DW 0x1590,..Help ;HELP | |
DW 0x1185,..Idle ;IDLE | |
DW 0x3D2E,..none ;JOIN | |
DW 0x14B0,..none ;KEEP | |
DW 0x2674,..List ;LIST | |
DW 0x3EC5,..none ;MOVE | |
DW 0x3E85,..none ;NOTE | |
DW 0x40AE,..none ;OPEN | |
DW 0x3039,..none ;PLAY | |
DW 0x5534,0xF800 ;QUIT | |
DW 0x1424,..none ;READ | |
DW 0x06C5,..none ;SAVE | |
DW 0x1714,..none ;TEXT | |
DW 0x3934,..none ;UNIT | |
DW 0x05C5,..none ;VANE | |
DW 0x06C5,..none ;WAVE | |
DW 0x5241,..xtra ;XTRA | |
DW 0x06F0,..pan ;YAwP | |
DW 0x164F,..Zero ;ZERO | |
..pan: SKIP 5 | |
MOV DL,AL | |
MOV AL,[BX] | |
MOV [BX],DL | |
ADD BX,CX | |
CMC | |
WAIT | |
INT 50 | |
MOV BH,0x7F | |
MOV BL,0XF3 | |
MOV CH,0xFF | |
MOV CL,0xB2 | |
...loop:PUSH BX | |
MOV DH,0x4E | |
...rows:PUSH DX,BX | |
MOV DH,0x1E | |
HLT DH | |
WAIT | |
INT 0 | |
POP BX,DX | |
DEC BX | |
DEC DH | |
JNZ ...rows | |
POP BX | |
JMP ...loop | |
;;;;;;;;;;;;;;;;;;;;;;;;; | |
..Edit: INT 72 | |
DB "\r\n" | |
..Goto: PUSH BX | |
RET | |
..Help: PUSH! Help.List | |
POP BX | |
HLT BX | |
PUSH BIOS.PutMsg | |
RET | |
..none: INT 72 | |
DB "\n!!! RESERVED DIRECTIVE\0" | |
RET | |
..xtra: XCHG! SP,BX | |
LOOP DL | |
PUSH EX | |
XCHG SP,BX | |
RET | |
..List: PUSH .FileIn | |
RET | |
..Zero: | |
..Idle: INT 73 | |
CMP AL,0x1B | |
RZ | |
HLT AL | |
INT 71 | |
BIF ..Idle | |
.GetHex:PUSH CX | |
SBB CH,CH | |
BIC ..addr | |
..inkey:INT 73 | |
CMP AL,0x08 | |
BIE ..back | |
CMP AL,0x20 | |
BIE ..addr | |
CMP AL,0x30 | |
BIE ..exit | |
CMP AL,0x7F | |
BIE ..clear | |
CMP AL,0x47 | |
BID ..exit | |
CMP AL,0x3A | |
BIC ..nibble | |
CMP AL,0x41 | |
BIC ..exit | |
SUB AL,0x07 | |
..nibble:AND AL,0x0F | |
LOOP 4 | |
ADD BX,BX | |
OR BL,AL | |
..addr: AND CH,CH | |
BIE ..ptr | |
INT 72 | |
DB "\<\<\<\<\0";> | |
..ptr: HLT BX | |
PUSH .PutPtr | |
XCHG IP,[SP] | |
OR CH,0xFF | |
BIF ..inkey | |
..exit: ADD CH,CH | |
POP CX | |
RET | |
..clear:ADD CH,CH | |
POP CX | |
RNC | |
INT 72 | |
DB "\< \<\< \<\< \<\< \<\0";> | |
AND AL,AL | |
RET | |
..back: HLT BH | |
XCHG | |
HLT BL | |
XCHG | |
XCHG BL,BH | |
LOOP 4 | |
ADD BX,BX | |
XCHG BL,BH | |
HLT BH | |
XCHG | |
HLT BL | |
XCHG | |
AND BL,BL | |
JMP ..addr | |
.OutDec:;;;;;;;;;;;;;;;;;; | |
PUSH AX | |
PUSH CX | |
XCHG AL | |
HLT CL | |
MOV CL,0x09 | |
MOV CH,CL | |
INC CH | |
WAIT | |
ADD AL,0x9C | |
ADD AL,0x64 | |
SUB CH,CL | |
ADD CH,0x30 | |
HLT CH | |
CALL .PutChr | |
HLT CL | |
MOV CL,0x09 | |
MOV CH,CL | |
INC CH | |
WAIT | |
ADD AL,0xF6 | |
ADD AL,0x0A | |
SUB CH,CL | |
ADD CH,0x30 | |
HLT CH | |
CALL .PutChr | |
CALL .PutHex.nibble | |
POP CX | |
POP AX | |
RET | |
;;;;;;;;;;;;;;;;;; | |
.MulBxD: | |
;;;;;;;;;;;;;;;;;; | |
.TestBX:CMP BL,DL | |
RNZ | |
CMP BH,DH | |
RET | |
.HexDmp:PUSH BX | |
PUSH AX | |
..addr: HLT BX | |
CALL .PutPtr | |
AND BL,0xF0 | |
..loop: MOV AL,0x20 | |
HLT AL | |
CALL .PutChr | |
MOV AL,[BX] | |
CALL .PutHex | |
CALL .TestBX | |
BIE ..end | |
INC BX | |
MOV AL,BL | |
AND AL,0x0F | |
BIF ..loop | |
MOV AL,0x0D | |
CALL .PutChr | |
MOV AL,0x0A | |
CALL .PutChr | |
BIE ..addr | |
..end: POP AX | |
POP BX | |
RET | |
.PutMsg:PUSH BX | |
PUSH AX | |
PUSH | |
POP BX | |
HLT AL | |
..loop: MOV AL,[BX] | |
INC BX | |
AND AL,AL | |
CIF .PutChr | |
BIF ..loop | |
POP AX | |
XCHG BX,[SP] | |
POP | |
RET | |
.PutPtr:PUSH BX | |
PUSH AX | |
PUSH | |
POP BX | |
HLT AL | |
PUSH .PutHex | |
PUSH [SP+0x00] | |
MOV AL,BH | |
XCHG IP,[SP] | |
MOV AL,BL | |
XCHG IP,[SP] | |
POP AX | |
POP BX | |
RET | |
.PutHex:PUSH AX | |
PUSH .PutChr.reada | |
XCHG AL | |
PUSH AX | |
LOOP 4 | |
RAR AL | |
CALL ..nibble | |
POP AX | |
..nibble:AND AL,0x0F | |
CMP AL,0x0A | |
BIC ..number | |
ADD AL,0x07 | |
..number:ADD AL,0x30 | |
HLT AL | |
.PutChr:PUSH AX | |
PUSH BX | |
PUSH CX | |
PUSH DX | |
PUSH BP | |
XCHG CL | |
PUSH [BP+0x64] | |
POP BP | |
MOV CH,[BP+0x0] | |
AND CH,CH | |
CALL ..main | |
PUSH BX | |
POP [BP+0x4] | |
PUSH [BP+0x8] | |
POP DX | |
ADD BX,DX | |
PUSH [BP+0xC];3 | |
POP DX;1 | |
DEC AL;1 | |
DEC DX;1 | |
XCHG BX,DX ;2 | |
MOV AL,DL ;2 | |
..exit: MOV [BX],AL ;1 | |
DEC BX ;1 | |
MOV [BX],DH ;1 | |
..leave:MOV AL,CH | |
..ready:MOV [BP+0x0],AL | |
POP BP | |
POP DX | |
POP CX | |
POP BX | |
..reada:POP AX | |
RET | |
..main: PUSH [BP+0x4] | |
POP BX | |
PUSH [BP+0x6] | |
POP DX | |
BIF ..ansi | |
MOV AL,CL | |
CMP AL,0x1B | |
BIF ..out | |
MOV [BP+0xFF],CH | |
DEC CH | |
RET | |
..left: DEC BL | |
RNS | |
MOV BL,DL | |
DEC BL | |
..up: DEC BH | |
RNS | |
MOV BH,DH | |
DEC BH | |
RET | |
..right:INC BL | |
CMP BL,DL | |
RC | |
XOR BL,BL | |
..down: INC BH | |
CMP BH,DH | |
RC | |
XOR BH,BH | |
RET | |
..clrscr:XOR CL,CL | |
MOV BH,CL | |
MOV BL,CL | |
INC BH | |
...loop:CALL ..put | |
BIF ...loop | |
DEC DL | |
..home: XOR BH,BH | |
..return:MOV AL,0x20 | |
..set_x:SUB AL,0x20 | |
...loop:MOV BL,AL | |
SUB AL,DL | |
BID ...loop | |
XOR CH,CH | |
RET | |
..quit: BE ..exit | |
..out: CMP AL,0x0A | |
BIE ..scroll | |
CMP AL,0x0D | |
BIE ..return | |
CMP AL,0x08 | |
BIE ..left | |
CMP AL,0x18 | |
BIE ..right | |
CMP AL,0x19 | |
BIE ..up | |
CMP AL,0x1A | |
BIE ..down | |
CMP AL,0x0C | |
BIE ..home | |
PUSH [BP+0x12] | |
RET | |
;..clear:JZ ..clrscr | |
..put: PUSH BX | |
PUSH CX | |
PUSH [BP+0xE] | |
XCHG IP,[SP] | |
POP CX | |
MOV AL,[BP+0x3] | |
ADD AL,CL | |
MOV [BX],AL | |
POP BX | |
INC BL | |
..tab: CMP BL,DL | |
RC | |
XOR BL,BL | |
..scroll:INC BH | |
CMP BH,DH | |
RC | |
MOV BH,DH | |
DEC BH | |
PUSH BX | |
XOR BL,BL | |
PUSH BX | |
PUSH [BP+0xE] | |
XCHG IP,[SP] | |
XCHG BX,[SP] | |
INC BH | |
PUSH [BP+0xE] | |
XCHG IP,[SP] | |
POP CX | |
SUB CX,BX | |
;SKIP 5 | |
...rows:FIX! 50 | |
ADD BX,CX | |
CMC | |
MOV DL,AL | |
MOV AL,[BX] | |
MOV [BX],DL | |
HLT 2 | |
CMC! | |
;INT 50 | |
; DEC DH | |
; JNZ ...rows | |
HLT DH | |
...cols:PUSH DX | |
PUSH BX | |
MOV AL,[BP+0x3] | |
FLY 0 | |
POP BX | |
POP DX | |
INC BX | |
DEC DL | |
BIF ...cols | |
POP BX | |
MOV CH,DL | |
RET | |
..ansi: MOV AL,CL | |
CMP CH,0xF3 | |
BID ..code | |
DEC CH | |
CMP CH,0xF0 | |
BIE ..set_x | |
BID ..set_y | |
INC CH | |
PUSH [BP+0xE] | |
RET | |
..code: MOV AL,CL | |
CMP AL,0x3A | |
BID ..set_y.call | |
SUB AL,0x30 | |
BIC ..set_y.call | |
MOV CL,AL | |
POP AX | |
MOV BL,CH | |
XOR BH,BH | |
ADD BX,BP | |
MOV AL,[BX] | |
ADD AL,AL | |
ADD AL,AL | |
ADD AL,[BX] | |
ADD AL,AL | |
ADD AL,CL | |
XOR DH,DH | |
BIE ..quit | |
..outstd:PUSH ..clrscr | |
CMP CL,0x1F | |
RZ | |
CMP CL,0x09 | |
BIE ...tab | |
POP [SP+0] | |
PUSH ..put | |
RET | |
...std: MOV CH,0xF2 | |
CMP AL,0x59 | |
RZ | |
XOR CH,CH | |
RET | |
...tab: POP [SP+0x00] | |
OR BL,0x07 | |
INC BL | |
BIF ..tab | |
..set_y:SUB AL,0x20 | |
...loop:MOV BH,AL | |
SUB AL,DH | |
BID ...loop | |
RET | |
...call:PUSH [BP+0x10] | |
XCHG IP,[SP] | |
PUSH [BP+0x4] | |
POP BX | |
RET | |
..mul78:PUSH [BP+0x8] | |
POP CX | |
ADD BX,CX | |
MOV AL,BL | |
MOV BL,BH | |
XOR BH,BH | |
ADD BX,BX | |
MOV CH,BH | |
MOV CL,BL | |
ADD BX,BX | |
ADD BX,BX | |
ADD BX,CX | |
ADD BX,BX | |
ADD BX,BX | |
ADD BX,BX | |
SUB BX,CX | |
XOR CH,CH | |
MOV CL,AL | |
ADD BX,CX | |
PUSH [BP+0xC] | |
POP CX | |
ADD BX,CX | |
RET | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
; DL = Port Index[7F:PortIn] | |
; AL = Data | |
; DBG 0x01 | |
; BRK 0x01 | |
.PortIO:PUSH DX | |
CMP DL,0x80 | |
SBB DH,DH | |
ADD DL,0x81 | |
BIE ..input | |
XCHG SP,DX | |
DEC SP | |
BIB ..lower | |
INC SP | |
MOV [SP+127],AL | |
BIA ..ready | |
..lower:MOV [SP+128],AL | |
BIB ..ready | |
..input:CMP AL,0x80 | |
SBB DH,DH | |
ADD AL,0x81 | |
MOV DL,AL | |
XCHG SP,DX | |
BIE ..ready | |
BIA ..higher | |
DEC SP | |
MOV AL,[SP+128] | |
BIB ..ready | |
..higher:MOV AL,[SP+127] | |
..ready:XCHG SP,DX | |
POP DX | |
RET | |
;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
; CX - Register Index | |
; DX - Register Data | |
.CPU_In:PUSH CX | |
PUSH BX | |
XOR BH,BH | |
MOV BL,BH | |
DEC BX | |
XCHG SP,BX | |
.loop: POP DX | |
DEC CX | |
MOV AL,CL | |
OR AL,CH | |
BIF .loop | |
XCHG SP,BX | |
POP BX | |
POP CX | |
RET | |
;;;;;;;;;;;;;;;;;;;;;; | |
.PortIn:PUSH BX | |
BIAS ..input | |
POP BX | |
MOV BL,AL | |
XCHG BP,BX | |
..input:MOV AL,[BP+0] | |
XCHG BP,BX | |
POP BX | |
RET | |
;;;;;;;;;;;;;;;;;;;;;; | |
.WaitOut:PUSH BX,CX;DL = Data | |
XCHG CL | |
BIAS ..input | |
POP BX | |
MOV BL,AL | |
XCHG BP,BX | |
SUB AL,AL | |
HLT CL | |
WAIT | |
..input:MOV [BP+0],DL | |
ADD CL,0xFF | |
XCHG BP,BX | |
POP CX,BX | |
RET | |
.WordOut: | |
;;;;;;;;;;;;;;;;;;;;;; | |
.OutByte:PUSH DX,AX;XH = Time, XL = Port, AL = Byte | |
PUSH | |
POP DX | |
CALL ..next | |
POP AX,DX | |
RET | |
..next: PUSH AX | |
LOOP 4 | |
RCR AL | |
CALL ..loop | |
POP AX | |
..loop: AND AL,0x0F | |
ADD AL,0xC0 | |
.Output:PUSH DX,BX;XH = Time, XL = Port, AL = Data | |
PUSH | |
POP DX | |
BIAS ..loop | |
POP BX | |
MOV BL,DL | |
XCHG BP,BX | |
SUB DL,DL | |
HLT DH | |
WAIT | |
..loop: MOV [BP+0],AL | |
ADD DH,0xFF | |
XCHG BP,BX | |
POP BX,DX | |
RET | |
;;;;;;;;;;;;;;;;;;;;;; | |
.FileIn:INT 72 | |
DB "\r\nFILE LIST - \0" | |
MOV! DL,0xFD | |
MOV DH,0x02 | |
HLT DX | |
MOV AL,0x00 | |
CALL .OutByte | |
MOV AL,0x00 | |
CALL .OutByte | |
MOV AL,0xD3 | |
CALL! .Output | |
CALL .WaitIn | |
..loop: PUSH AX | |
INT 72 | |
DB "\r\n#\0" | |
HLT AL | |
PUSH BIOS.PutHex | |
XCHG IP,[SP] | |
INT 72 | |
DB " - \0" | |
MOV AL,0xFD | |
MOV CL,0x02 | |
MOV DL,0x00 | |
HLT CL | |
CALL .WaitOut | |
CALL .WaitOut | |
CALL .WaitOut | |
MOV DL,[SP+0] | |
AND DL,0x0F | |
OR DL,0xC0 | |
CALL .WaitOut | |
MOV DL,0xD1 | |
CALL .WaitOut | |
..print:CALL .WaitIn | |
HLT AL | |
INT 71 | |
BIC ..print | |
HLT | |
;;;;;;;;;;;;;;;;;;;;;; | |
.WaitIn:PUSH BX,CX | |
XCHG CL | |
BIAS ..input | |
POP BX | |
MOV BL,AL | |
XCHG BP,BX | |
SUB AL,AL | |
HLT CL | |
WAIT | |
..input:MOV! AL,[BP+0] | |
ADD CL,0xFF | |
XCHG BP,BX | |
POP CX,BX | |
RET | |
;;;;;;;;;;;;;;;;;;;;;; | |
.GetChar:XOR AL,AL | |
..loop: CALL .Inkey | |
BID ..loop | |
PUSH AX | |
PUSH CX | |
MOV CL,0x50 | |
MOV CH,0xF0;01;0xF0 | |
XOR AL,AL | |
CE .beep | |
POP CX | |
POP AX | |
RET | |
.Inkey: PUSH DX | |
MOV AL,0x7F | |
MOV DL,0xFD | |
MOV DH,0x80 | |
HLT! DH | |
IN DL | |
MOV AL,DL | |
;;;;;;; PUSH BIOS.WaitIn | |
;;;;;;; XCHG IP,[SP] | |
POP DX | |
RET | |
.beep: PUSH DX | |
MOV DL,0x0A | |
MOV AL,CL | |
PUSH .PortIO | |
XCHG IP,[SP] | |
MOV AL,CH | |
LOOP AL | |
NOP | |
PUSH .PortIO | |
XCHG IP,[SP] | |
POP DX | |
RET | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> | |
ORG 0xFEFA | |
KERM: NOP 1 | |
NOP 1 | |
NOP 1 | |
NOP 1 | |
NOP 1 | |
NOP 1 | |
ORG 0xFEFE | |
KERN: MOV [0],AL | |
JMP .overhead ; Запрос к стандартному API | |
JMP .acclaim ; Обращение к программным прерываниям INT 0-79 | |
JMP .buffer ; Буферная зона - прослойка диспетчера памяти | |
JMP .context_next ; Диспетчер переключения контекста процессов | |
JMP .device ; Запрос ко внешнему устройству ввода/вывода | |
JMP .error ; Обработчик программных/аппаратных ошибок | |
JMP .force ; Внешние форсированные события/прерывания | |
.garret:MOV DL,0x00 ; Загрузочная область поверхностного уровня | |
MOV DH,0xD0 | |
MOV BX,DX | |
XCHG SP,DX | |
..scan: XOR AL,AL | |
MOV [SP+AL-1],BH | |
MOV CH,[SP+AL-1] | |
MOV CL,0xF0 | |
MOV CH,0xF8 | |
PUSH BX | |
..load: INC AL | |
ADD BL,0x10 | |
MOV [0],AL | |
MOV DL,[BX] | |
MOV DH,[BX+1] | |
MOV [CL],DL | |
MOV [CH],DH | |
OR DL,DH | |
JNZ ..load | |
MOV AL,0x80 | |
POP BX | |
.context:PUSH AX | |
PUSH BX | |
.context_next: | |
..next: INC AL | |
ADD BL,0x10 | |
MOV DL,[BX+2] | |
MOV DH,[BX+3] | |
MOV [6],DL | |
MOV [7],DH | |
MOV CL,[BX] | |
MOV CH,[BX+1] | |
OR CL,CH | |
JNZ KERN | |
POP BX | |
POP AX | |
JMP .context | |
.device:JC ..write | |
PUSH AX | |
XOR AL,AL | |
MOV [0],AL | |
POP AL | |
MOV CH,0xFF | |
HLT CH | |
IN AL | |
PUSH AL | |
SBB CH,CH | |
POP AX | |
CMP AL,CH | |
JMP KERN | |
..write:PUSH AX | |
XOR AL,AL | |
MOV [0],AL | |
POP AL | |
MOV CL,AL | |
POP AL | |
MOV CH,0xFF | |
HLT CH | |
OUT CL,AL | |
POP AX | |
JMP KERN | |
.overhead: | |
.acclaim: | |
.buffer: | |
.error: | |
.force: PUSH BX,AX | |
MOV BH,0x7F | |
MOV BL,0xEE | |
MOV AL,[BX] | |
INC AL | |
MOV [BX],AL | |
POP AX,BX | |
CMP AL,AL | |
CMC | |
JMP KERN | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
ORG 0x7650 | |
DW 0x0000 ; Value .Sequency | |
DW 0x0000 ; Page .Blank | |
DW 0x0000 ; PosY .PosX | |
DW 0x1E48;0x1E4E; 0x1940 ; Rows .Columns | |
DW 0x0000;0x0308 ; FromY .FromX | |
DW 0x05F0 ; Bell .Tone | |
DW 0x76D0 | |
DW BIOS.PutChr.mul78 | |
DW BIOS.PutChr.OutStd.std | |
DW BIOS.PutChr.OutStd | |
DW 0x7650 | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
ORG 0xD000 | |
PROCESS:DW 0x0000,0x0000 ;#0 | |
DW 0xF800,0xFFFF ;#1 | |
DW 0xF000,0x000 ;#2 | |
DW 0x0000,0x0000 | |
ORG 0xD000 | |
DW 0x0000,0x0000 | |
DB " " | |
DW 0xF800,0xFFFF | |
DB " " | |
DW 0x0000,0x0000 | |
DB " " | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
ORG 0xFF00 | |
; NOP | |
; NOP 1 | |
; RIE | |
ORG 0x0000 | |
SCRO: PUSH 0x76D0 | |
POP DX | |
SCROLL: MOV SP,DX | |
XCHG BX,[SP] | |
INC DX | |
CMP DH,0x80 | |
JNZ SCROLL | |
JMP SCRO | |
;<!-- --> | |
</pre> | |
</td> | |
<td rowspan='2'><pre> | |
Rebused Instructions Set Computer Emulator | |
</pre><hr /><pre> | |
F1: Step / ^Cycle / $Stop | |
F3: ^Push IP / $Pop IP | |
F4: Start/Stop / $Start | |
F5: Assembly / ^Reset | |
F6: Rewind IP/Speed/Cycles | |
F7: Toggle switch | |
F8: Forward IP/Speed/Cycles | |
F9: | |
Break: Toggle break-point | |
</pre><hr /><pre> | |
$ - Shift+ | |
^ - Ctrl+ | |
@ - Alt+ | |
</pre><hr /><pre> | |
Intuitive clear mnemonic to quick memorize | |
|Codes|Key|Elementary description_________ | |
00 :Nil-Null of instruction queue / HLT | |
xA..xB:A/B-Add / Subtract | |
xC..xD:C/D-Conjunction / Disjunction | |
xE : E -Exclusive bitwise OR | |
A0..A7: A -Access to bytes | |
A8..AF:A/A-Access to ALU | |
B0..B7: B -Branches to nearest substitutes | |
B8..BF:B/F-Branches to near labels by flag | |
C0..C7: C -Increment | |
CA :RAL-Concatenate Access roll | |
CF :C/F-Carry Flag complement | |
D0..D7: D -Decrement | |
DA :RAR-Descended Access roll | |
DF :D/F-Data Formation by NOT | |
EE :E/E-Exchange | |
F0..F9:F/x-Functions of BIOS-API | |
FE :F/E-Fiction Execute / NOP | |
FF :F/F-Finalize the Function / RET | |
+EC/ED:Exclude operations by Counter/Data | |
+FC/FD:Forcing operation by Counter/Data | |
+EF :E/F-Enter register Feature | |
+FF :F/F-Flush register Feature | |
Simplest protection from errors in code: | |
Examples|Macros | |
CF BC FD|CLC ; Clear the Carry Flag | |
CF BD FD|STC ; Store the Carry Flag | |
BE FF |RZ ; Return by Zero Flag | |
BF FF |RNZ ; Return by no Zero Flag | |
</pre> | |
</td> | |
</tr> | |
<tr valign=top><td><canvas id=Display style=position:absolute onblur='cpu.watch.active=""' onfocus='cpu.watch.active="S"'></canvas><pre id=Screen style=width:40em></pre> | |
<span style='background-color:silver; display:inline-block; color:black; height:33em'> | |
</span> | |
</td> | |
<td style='background-color:silver; color:black'> | |
<select id=Selector></select><button id=Action value=Files></button><br /> | |
<select id=Repeats> | |
<option value='0x0000'>No Loop</option> | |
<option value='0x2000'>Loop+</option> | |
<option value='0x3000'>Wait+</option> | |
</select> | |
<select id=Prefixes> | |
<option value='-1'>Auto Prefix</option> | |
<option value='0x0000'>Regular</option> | |
<option value='0x0100'>11+</option> | |
<option value='0x0200'>22+</option> | |
<option value='0x0300'>33+</option> | |
<option value='0x0400'>44+</option> | |
<option value='0x0500'>55+</option> | |
<option value='0x0600'>66+</option> | |
<option value='0x0700'>77+</option> | |
<option value='0x4800'>00+</option> | |
<option value='0x00FE'>+FE</option> | |
<option value='0x00FF'>+FF</option> | |
</select> | |
<pre id=state></pre> | |
</td> | |
</tr></table> | |
<textarea id='Files' cols='80' rows='50'> | |
FILE XONIX | |
ORG 0x0100 | |
Xonix: PUSH 0xF800 | |
POP BX | |
RET | |
;NEXT-FILE; | |
FILE TETRIS | |
ORG 0x0100 | |
Tetris: INC BX | |
RET | |
</textarea> | |
<!-- | |
i8275 CRT-Controller: Simply version | |
00000000: | |
000000nn: | |
000001nn: | |
00001nnn: | |
0001nnnn: | |
0010nnnn: | |
0100nnnn: Lines [1..16]-1 | |
01nnnnnn: Rows [16..64]-1 | |
1000nnnn: | |
1nnnnnnn: Cols [16..80]-1 | |
1101nnnn: | |
1110nnnn: | |
1111nnnn: | |
40..4F: Set Lines [1..16] | |
50..7F: Set Rows [16..64] | |
90..CF: Set Cols [16..80] | |
=== PORTS === | |
SP:0000 | |
[SP-1] =FFFF -> Port $FF | |
[SP-128]=FF80 -> Port $80 | |
SP:FFFF | |
[SP+1] =0000 -> Port $00 | |
[SP+127]=007E -> Port $7E | |
;;;;;;;; | |
; DL = Port Index[7F:PortIn] | |
; AL = Data | |
PortIO: PUSH DX | |
CMP DL,128 | |
SBB DH,DH | |
ADD DL,129 | |
JZ .input | |
XCHG SP,DX | |
JNS .lower | |
MOV [SP+127],AL | |
JS .ready | |
.lower: MOV [SP-128],AL | |
JNS .ready | |
.input: CMP AL,128 | |
SBB DH,DH | |
ADD AL,129 | |
MOV DL,AL | |
JZ .ready | |
XCHG SP,DX | |
JS .higher | |
MOV AL,[SP-128] | |
JNS .ready | |
.higher:MOV AL,[SP+127] | |
.ready: XCHG SP,DX | |
POP DX | |
RET | |
;;;;;;;;;;;;;;;;;;;;;;;;; | |
Port #253 #0xFD #-3 : Keyboard Code | |
;;;;;;;;;;;;;;;;;;;;;;;;; | |
x0 x1 x2 x3 x4 x5 x6 x7 | |
-- BP SI DI SP BX CX DX | |
55 76 -> PREFIX BX + MOV CL,DL -> PREFIX BX + MOV CX,DX -> LEA BX,[CX+DX] | |
55 21 -> PREFIX BX + MOV BH,CH -> PREFIX BX + MOV BP,SI -> LEA BX,[BP+SI] | |
55 10 -> PREFIX BX + MOV [BX],BH -> PREFIX BX + MOV XX,BP -> LEA BX,[[SP]+BP] | |
///////////////////////////////////////////////////////////////////////////// | |
Service Registers: | |
================== | |
1. Select the service segment: | |
1.1. Set SP to 0x0001 | |
1.2. Set APR (one of BX,CX,DX) to wanted index | |
1.3. Do PUSH instruction of this APR | |
2. Select the service register: | |
2.1. Set SP to 0x0000 | |
2.2. Set AL to wanted index | |
2.3. Do PUSH AX | |
2.4. If wanted index greater than 256, repeat the step #2.3 many times | |
3. Write to service register: | |
3.1. Set SP to 0x0000 | |
3.2. Do PUSH instruction with any of APR (BX,CX,DX) | |
4. Read the service register: | |
4.1. Set SP to 0xFFFF | |
4.2. Do POP instruction with any of APR (BX,CX,DX) | |
-F80..-FFF: Service Layer #1 | |
0000..00FF: Service Layer #0 | |
0100..01FF: 6502-Stack Mode | |
0200..FDFF: Regular Stack | |
FE00..FEFF: Service Layer #2 | |
FF00..FFFF: Service Layer #3 | |
+000..+07E: Service Layer #1 | |
00000000XXXXXXXX: Service Layer #0 | |
00000001XXXXXXXX: 6502-Stack Layer | |
XXXXXXXXXXXXXXXX: Regulat Stack Layer | |
11111110XXXXXXXX: Service Layer #2 | |
11111111XXXXXXXX: Service Layer #3 | |
┌───┬───┬───┬───┬───┬───┬───┬───┐┌───┬───┬───┬───┬───┬───┬───┬───┐┌───┬───┬───┬───┬───┬───┬───┬───┐ | |
│ - - - - - - - - ││ 0 └──SRC──┘ 0 └──DST──┘ ││ - - - - - - - - │: | |
└───────────────────────────────┘└───────────────────────────────┘└───────────────────────────────┘ | |
SPCZ | |
0000 | |
0001 | |
0010 | |
0011 | |
0100 | |
0110 | |
1000 | |
1010 | |
1100 | |
1110 | |
0###sP?Z| Parity Zero: | |
0###Sp?Z| Signed Zero:Skip # instructions | |
0###SP?Z| Spouts Zero:Loop instruction # times | |
1###sP?Z| Parity Zero: | |
1###Sp?Z| Signed Zero:Skip # instructions | |
1###SP?Z| Spouts Zero:Loop instruction # times | |
LOOP : | |
LOOP n:Loop instruction n-times |FX=0nnn11?1 | |
LOOP R:Loop instruction R-n time|FX=1rrr11?1 | |
MOV R:Using R-register |FX=1rrr???? | |
NOP n:Skip n instructions |FX=0nnn10?1 | |
Bx nn: 0000..007F FF80..FFFF | |
11 Bx nn: 0100..017F 0080..00FF | |
22 Bx nn: 0200..027F 0180..01FF | |
33 Bx nn: 0300..037F 0280..02FF | |
44 Bx nn: Services | |
55 Bx nn: FD00..FD7F FC80..FCFF | |
66 Bx nn: FE00..FE7F FD80..FDFF | |
77 Bx nn: FF00..FF7F FE80..FEFF | |
Fn: |Basic library: | |
11 Fn: |Memory library: | |
22 Fn: "|String library: | |
33 Fn: #|Sound library: | |
44 Fn: D|Data process: | |
55 Fn: U| | |
66 Fn: f|File system: | |
77 Fn: w|Window service: | |
//////////////////////////////////////////////////////////////////////////////// | |
EX-Register | |
__ .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F | |
00:Ячейки управления распределением страниц памяти|RAM Dispatcher | |
10:Ячейки управления распределением страниц памяти|RAM Dispatcher | |
20:Ячейки управления ловушками в процессе отладки-|Debug Managing | |
30:Счётчики тактов, циклов, прерываний и т.д.-- --|Process Counters | |
40:JP>>LO>> ++ .. -- -- -- JP>>HI>> ++ .. -- -- --|JP-File | |
50:SP>>LO>> ++ .. -- -- -- SP>>HI>> ++ .. -- -- --|SP-File | |
60:BP>>LO>> ++ .. -- -- -- BP>>HI>> ++ .. -- -- --|BP-File | |
70:IP>>LO>> ++ .. -- -- -- IP>>HI>> ++ .. -- -- --|IP-File | |
80:SI>>LO>> ++ .. -- -- -- SI>>HI>> ++ .. -- -- --|SI-File | |
90:DI>>LO>> ++ .. -- -- -- DI>>HI>> ++ .. -- -- --|DI-File | |
A0:AL>>LO>>Стек истории -- AH>>HI>> ++ .. -- -- --|AX-File | |
B0:BL>>LO>>модификации- -- BH>>HI>> ++ .. -- -- --|BX-File | |
C0:CL>>LO>>всех РОН- -- -- CH>>HI>> ++ .. -- -- --|CX-File | |
D0:DL>>LO>> ++ .. -- -- -- DH>>HI>> ++ .. -- -- --|DX-File | |
E0:Стек конвейера с историей исполненных операций-|Execution Pipeline | |
F0:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|Execution Pipeline | |
+0:Зона особого назначения ???????????????????????|Service context | |
EX-Регистр - хранит контекст процессора. | |
Ячейками с 50h по DFh непосредственно связаны все РОН в режиме стекового файла с | |
глубиной до 8 уровней. Тем самым, когда какой-либо регистр изменяется, автоматом | |
история его изменений циклически сдвигается от ячейки с x0h/x8h к ячейке x7h/xFh | |
соответственно. Это позволяет в отладчике частично прокрутить историю исполнения | |
кода в обратном направлении. Так, ячейки 0-FFh доступны программе в произвольном | |
доступе. Ячейка +0 - это 256 управляющая ячейка управления переключением страниц | |
контекста, доступная только операционной системе, хранящая маску доступности для | |
остальных ячеек +1..+7 (257..263). | |
Битами этих сервисных ячеек можно "заморозить" историю контекста, чтобы получить | |
произвольный и точный доступ ко всем доступным моментам или сохранить контекст и | |
подготовить его для переключения к следующей задаче. | |
//////////////////////////////////////////////////////////////////////////////// | |
Порты: Доступ к устройствам ввода/вывода | |
======================================== | |
Пользовательский уровень: | |
Доступ к устройствам операционной среды достигается префикс-инструкц | |
0###sP?Z| Parity Zero:Пропускать следующие инструкции на период декрементации; | |
0###Sp?Z| Signed Zero:Повторять следующую инструкцию в периоде декрементации; | |
0###SP?Z| Spouts Zero:Повторять следующую инструкцию в ожидании декрементации; | |
1###sP?Z| Parity Zero: | |
1###Sp?Z| Signed Zero:Skip # instructions | |
1###SP?Z| Spouts Zero:Loop instruction # times | |
//////////////////////////////////////////////////////////////////////////////// | |
--> | |
<pre id='List'> | |
</pre> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment