0000 (OP) - арифметическая или логическая операция (далее 4 бита для регистра результата, 4 бита для регистра первого аргумента, 4 бита для регистра второго аргумента, 4 бита на код подоперации над старшим байтом данных, 4 бита на код подоперации над младшим байтом данных);
0001 (JUMP) - переход на 20-битный адрес в памяти программ;
0010 (CALL) - вызов подпрограммы по 20-битному адресу (стек адресов возврата спрятан и имеет ограниченную глубину);
0011 (RET) - возврат из подпрограммы (далее 4 бита для регистра куда надо записать следующие 16 бит);
0100 (LOAD) - чтение из памяти данных в регистр (далее 4 бита для кода регистра и 16 бит на младшую часть адреса данных);
0101 (SAVE) - запись регистра в память данных (далее 4 бита для кода регистра и 16 бит на младшую часть адреса данных);
0110 (INIT) - загрузить 16-битное число в регистр (далее 4 бита для кода регистра и 16 бит на записываемое число);
0111 (COPY) - копирование с перестановкой (опишу позже);
1000 (CLR) - сбросить отдельный бит в регистре, а также записать байт в другой регистр (4 бита код регистра для сброса и 4 бита задают номер бита для сброса, далее 4 бита код регистра для записи данных и 8 бит сами данные);
1001 (SET) - установить отдельный бит в регистре, а также записать байт в другой регистр (4 бита код регистра для установки и 4 бита задают номер бита для установки, далее 4 бита код регистра для записи данных и 8 бит сами данные);
1010 (SKIP0) - проверить состояние бита в регистре и пропустить следующую команду если 0, а также записать байт в другой регистр (4 бита код регистра для тестирования и 4 бита задают номер бита для тестирования, далее 4 бита код регистра для записи данных, далее 8 бит сами данные);
1011 (SKIP1) - проверить состояние бита в регистре и пропустить следующую команду если 1, а также записать байт в другой регистр (4 бита код регистра для тестирования и 4 бита задают номер бита для тестирования, далее 4 бита код регистра для записи данных, далее 8 бит сами данные);
1100 (ILOAD) - косвенное чтение из памяти данных в регистр (далее 4 бита задают регистр куда читать, далее 4 бита задают регистр со старшей частью адреса - из него берётся только младший байт, далее 4 бита задают регистр с младшей частью адреса и следующие 8 бит задают смещение);
1101 (ISAVE) - косвенная запись регистра в память данных (далее 4 бита задают регистр откуда читать, далее 4 бита задают регистр со старшей частью адреса - из него берётся только младший байт, далее 4 бита задают регистр с младшей частью адреса и следующие 8 бит задают смещение);
1110 (TEST) - проверить состояние битов регистра по маске (далее 4 бита для кода регистра и 16 бит на маску по AND - меняется только флаг Z);
1111 (EXT) - заререзрвировано для будущих расширений.
Подробнее об арифметических и логических операциях - особенностью предлагаемого дизайна является возможность одновременно выполнять РАЗНЫЕ операции над двумя однобайтовыми половинками регистров (т.е. этот 16-разрядный процессор в каком-то смысле можно рассматривать как два 8-разрядных), причём оба аргумента и приёмник могут быть тремя разными регистрами (указывание R0 в качестве аргумента означает 0, а в качестве результата означает игнорирование результата). Коды арифметических и логических подопераций:
Code: Select all
0000 - MOV (копирование из первого аргумента);
0001 - MOV2 (копирование из второго аргумента);
0010 - INV (копирование с инверсией из первого аргумента);
0011 - INV2 (копирование с инверсией из второго аргумента);
0100 - RRC (копирование со сдвигом вправо через флаг C первого аргумента);
0101 - RRC2 (копирование со сдвигом вправо через флаг C второго аргумента);
0110 - RLC (копирование со сдвигом влево через флаг C первого аргумента);
0111 - RLC2 (копирование со сдвигом влево через флаг C второго аргумента);
1000 - NAND (логическая побитовая операция И-НЕ);
1001 - XOR (логическая побитовая операция ИСКЛЮЧАЮЩЕЕ ИЛИ);
1010 - AND (логическая побитовая операция И);
1011 - OR (логическая побитовая операция ИЛИ);
1100 - ADI (прибавить к содержимому первого регистра число, хранящееся на месте второго и сохранить результат);
1101 - SBI (вычесть из содержимого первого регистра число, хранящееся на месте второго и сохранить результат);
1110 - ADC (сложение с использованием флага C);
1111 - SBC (вычитание с использованием флага C).
S - sign (результат оказался отрицательным)
Z - zero (результат оказался нулевым)
V - overflow (было переполнение при сложении или вычитании)
B - borrow (было заимствование при вычитании)
C - carry (был перенос при сложении или сдвиге)
H - half carry (был перенос между байтами при сложении или сдвиге)
O - stack overflow (было переполнение стека адресов возвратов)
D - dummy flag (нулевой флаг используемый для пустых операций с битами)
Если взять R15 как способ добраться до младших 16 битов PC, то появится возможность делать интересный трюк switch/cases - либо через возврат слова в RET, либо путём дальнейшего перехода по JMP из таблицы, правда при этом необходимо, чтобы таблица, куда мы идём через непосредственную запись в R15, располагалась в том же 64К сегменте памяти, откуда был осуществлён такой переход (т.к. старшие 4 бита адреса не меняются).
Думаю сделать обращение к флагам через R14 (старшей его части) - причём там же (в младшем байте) можно держать один байт старшей части адреса данных (будет переключать банки по 64К).
И как я уже говорил выше - регистр R0 всегда будет возвращать 0, а любая попытка записи в него будет проигнорирована.
P.S. 01-11-2015: Переставил кое-какие поля. Последняя версия дизайна проца всегда будет тут: http://www.nedopc.org/nedopc/1/Core