Habr-страничка (информация немного устарела) Запуск онлайн-эмулятора (режим с произвольным размером кода) Классический режим (один байт - одна команда) Автозапуск демонстрационной программы Автозапуск в "Классическом режиме" Автозапуск программы, загруженной листингом с gist'а GitHub (LogiSim-модель и прочее) Verilog-модель (неактуальная версия) Эмулятор Кой-Машины для процессора i8080 Всё началось более года назад, когда решено было всерьёз разработать собственную RISC-архитектуру в рамках симулятора Atanua. Но затем за основной инструмент был выбран LogiSim по ряду причин (лёгкость, простота, удобный интерфейс) против тех же KiCAD, Proteus или OrCAD. Хотя изначально схема имела скромную шуточную Гарвардскую RISC-архитектуру и 2-4 такта на операцию, но по мере развития и усложнения получилась гибридная пародия на CISC с Принстонской архитектурой до 20-30 тактов на операцию. Задача повышения производительности не ставилась принципиально, так как все силы были сосредоточены на разработке интуитивно понятного машинного кода, где код в дампе своим шестнадцатеричным представлением в байте команды несёт в себе визуально понятную смысловую нагрузку, чтобы имелась возможность кодирования программы в её естественном виде - байт-кодом. С другой стороны, данный Кой-Процессор также задумывался как некое универсальное ядро для эмуляции любых других процессоров (i8080, z80, i8086, MOS 6502 и т.п.), пусть даже с крайне низкой производительностью. На странице эмулятора уже более-менее видна задуманная архитектура в действии. В качестве демонстрации была выбрана пародия на игру Автослалом (ИМ-23), где производительность не важна и можно обойтись считанными килогерцами. (Можно заметить, что демо-код ничего не рисует, а лишь включает/выключает соответствующие сегменты на импровизированном ЖК-экране: Не всякое изображение подходит, а предварительно обработанное и подготовленное с индексацией групп пикселей под тот или иной сегмент.) В настоящее время ведётся пассивная отладка самого HTML-интерфейса и доработка JavaScript-оболочки, чтобы более чётче отловить многие подводные камни самой архитектуры и применить опыт в переработке Verilog-модели. Разрядность Хотя описание и эмуляция выполнены 8-битным исполнением, ничто не мешает все регистры сделать 4-битными - минимализм. А также 16-битными или 32-битными, так как всё проектировалось так, чтобы архитектура была масштабируемой. Из-за чего, как можно заметить в режиме отладки, команд загрузки непосредственных констант нет в принципе, а всё выполняет особый пользовательский код разнообразными INT-вызовами. Устройства Ввода-Вывода Хотя можно спроецировать интерфейсные устройства в память, но изначально под них выделены Регистры Общего Назначения D0…D9, чтобы не было никаких In/Out или обращения к памяти. Карта УВВ планировалась также максимально очевидной: Какой BCD-код в D9, такой и номенклатурный индекс самой ИМС: Для доступа к i8255/580ВВ55 помещаем код 0x55 в D9, а через регистры D0…D3 уже работаем с самой этой ИМС. (В демонстрации буфер клавиатуры считывается имитацией (не эмуляцией или симуляцией) i8279/580ВВ79 с индексом 0x79 в D9.) Развитие Если Pico-8, Gigatron и Simpleton разрабатываются в первую очередь и в основном как игровые с поддержкой графики. В то же время, как можно заметить, Кой-Машина проектировалась как автомат, способный управлять теплицей или инкубатором в технологическом стиле 70-х, где графика не особо нужна. А так как Кой-Программу можно выполнять даже на процессорах, типа i8080/z80, то она может в какой-то мере служить альтернативой известной Java-машине, так как Койяанискаци-Код легко можно поддерживать на любых ЭВМ. Онлайн Тематический форум Discord-канал Спасибо за внимание! С уважением. Аликберов
Кaк известно, в архитектуре x86 одну операцию можно выполнить разными способами, что способствовало не только гибкости архитектуры, но и быстрому перерасходу командного пространства в таблице кодирования инструкций и исключения целых блоков с переходом на x64. Койяанискаци прорабатывается в этом плане довольно строго, чтобы беречь пространство кодирования и зарезервировать побольше инструкций, так как концептуально кодирование одной команды не является самым компактным из всех архитектур. Так как под ALU изначально выделен набор в 60 кодов, ведётся тщательный анализ мусорных сочетаний регистров, который не имеет смысла и должен выполнять особую роль. Аналог x86-SHR Чепуха «MOV Ri,[RAM],Rj»: Запись регистра Rj в память с чтением Ri из памяти - бессмыслица. Теперь «ORD Ri,[RAM],Rj»: Упорядочить память (минимум) с регистром (максимум) и вернуть среднее арифметическое. IF RAM[] > Rj THEN SWAP RAM[],RjRi = (Rj - RAM[]) >> 1 Аналог x86-XLAT Чепуха «MOV Ri,[RAM],Ri»: Запись регистра в память с чтением того же регистра из памяти - бессмыслица. Теперь «LEX Ri,[RAM],Ri»: Чтение регистра из таблицы в памяти со смещением - перекодировка. Ri = RAM[Ri] Аналог x86-LEA Чепуха «MOV Di,[RAM],Di»: Запись регистровой пары в память и чтение той же пары из памяти - бессмыслица. Теперь «LEA Di,[PTR]»: Вычисление эффективного адреса. Аналог x86-XCHG Чепуха «MOV A0,[RAM],Ri»: Загрузка PSW-регистра через загрузку в память регистра - бессмыслица. Теперь «SWP [RAM],Ri»: Обменяться значениями между ячейкой памяти и регистром. Проверка порта на ввод Чепуха «MOV A0,Di»: Загрузка PSW-регистра из порта - бессмыслица. Теперь «INF Di»: Анализ порта с установкой информации во флагах PSW. Проверка порта на вывод Чепуха «MOV Di,A0»: Выгрузка PSW-регистра в порт - бессмыслица. Теперь «OUT Di»: Анализ порта с установкой информации во флагах PSW. Безусловные/Условные унарные операции Чепуха «ALU Ri,A0»: Любая операция АЛУ с регистром PSW - бессмыслица. Теперь «UNAR Ri»: Пять унарных операций (INC/DEC/CLR/SET/NOT) с регистром. Чепуха «ALU A0,[RAM],A0»: Любая операция АЛУ с регистром PSW - бессмыслица. Теперь «UNAR [RAM]»: Пять унарных операций (INC/DEC/CLR/SET/NOT) с ячейкой в памяти.
Прошло столько времени, а концепт процессорного устройства всё ещё сырой и имеет недоработки для полного описания в JavaScript или Verilog HDL... Начнём с классики - IA-32, так как на примерах с x86 любому будет легче понять концептуальные проблемы и ограничения. «LEA EBX,[EBX+2*EBX+34]» - вполне нормальная инструкция "умножения EBX на 3 с приращением" «ADD EBX,[EBX+2*EBX+34]» - а вот тут получаем исключение, так как базовый и индексный регистры - один EBX В моём случае это проявилось тоже, когда я вводил механизмы формирования адреса. А так как я занимаюсь проработкой архитектуры самостоятельно в духе "сам себе инженер", к проблеме таких указателей решил подойти со всей серьёзностью и строгостью, чтобы найти способ обойти такие ситуации и исключить их в принципе. Естественно, идти по стопам Intel и "генерировать исключение" здесь совсем неуместно. Для начала был введён флаг сигнализации об обнаружении указателя "из ряда вон" - "маргинального адреса". Условно говоря, в концепцию ввелись "маргиналы" - расширители инструкций, замаскированные под указатели. Аппаратно в Verilog'е они отлавливаются довольно легко и сохраняются в отдельном слове. Чтобы легче понять суть, продемонстрирую "маргинализацию" указателя на гипотетическом примере: «ADD EBX,[EBX+2*EBX+34]» работает как «ADD EBX,(EBX+2*EBX+34)»: Работает как «EBX += EBX+2*EBX+34» «ADD [EBX+2*EBX+34],EBX» работать как «ADD (EBX+2*EBX+34),EBX» не может: Как «EBX+2*EBX+34 += EBX» понимать? «ADD BL,[EBX+2*EBX+34]» работать как «ADD BL,(EBX+2*EBX+34)» не может: BL - 8-битный, а сумма справа - 32-битная Как видите, так или иначе, странных ситуаций возникает ещё больше. Те же Intel в своей IA-64 не стали разбираться с корректным выполнением инструкций типа «ADD DX,AX» и вообще обнуляют старшие 32 бита RDX в таких случаях. И здесь по стопам Intel мне совсем ни к чему. Просто на аппаратном уровне такие ситуации также отлавливаются и устанавливаются ещё один флаг. К тому же, регистр A0 у меня выполняет функцию PSW: Использовать его в вычислениях бессмысленно. И регистры группы D0-D9 ссылаются либо к портам УВВ (Devices), либо к регистровым парам (как DX - это DH и DL). Если «MOV BL,BL» работает как «NOP», то мне такие «пустышки» в большом количестве не нужны - такие ситуации также отлавливаются. Как результат, шесть инструкций «ADD / SUB / AND / OR / EOR / MOV» дешифратором с учётом всех комбинаций операндов синтезируются в три десятка различных инструкций. Тем самым, к АЛУ подтягивается уже не три бита кода операции, а все 11, из-за чего программно доступно уже большее число разнообразных инструкций всех видов. Ознакомиться с кодированием инструкций, учитывая все описанные выше нюансы и с "маргиналами" можно по ссылке. Ниже, скриншот со схемой на ИМС ТТЛ для вычисления эффективного адреса/"маргиналов" и Verilog-модель отлаживаемого модуля. По числу ИМС на схеме я оцениваю, на сколько сложен этот блок - более 40 ИМС. --- Сообщение объединено, 24 июн 2023 --- Например, вот фрагмент логов отладчика дешифратора команд: M# / M - последовательность "маргиналов" VV / V - наличие корректного вектора IC - код инструкции E - флаг использования одного регистра за приёмник и за транслятор AD - флаги наличия A0/PSW или D со стороны приёмника или транслятора Код (Text): _IP_:M#[VV]IC M_V_AD_E_AD_F RC<>TR _ASM ..OPERANDS.. _REAL INSTRUCTION_ 0000: AA 0_0_x0_x_0x_0:A?!=0? ARG A,A 0001: A0 0_0_x0_x_00_0:A?!=AA REG A0 0002:03# A0 1_0_10_0_00_0:@0!=AA REG3 A0 0005: 0F 0_0_10_1_10_1:@0==@0 --- ??? ; MOV A0,A0 0006: 0E 0_0_10_1_10_0:@0==@0 --- ??? ; EOR A0,A0 0007: 0D 0_0_10_1_10_0:@0==@0 --- ??? ; DIS A0,A0 0008: 0C 0_0_10_1_10_0:@0==@0 --- ??? ; CON A0,A0 0009: 0B 0_0_10_1_10_0:@0==@0 --- ??? ; SUB A0,A0 000A: 0A 0_0_10_1_10_0:@0==@0 --- ??? ; ADD A0,A0 000B: 34 0F 0_1_10_1_10_1:@0==@0 MOV PSW,D3+4 ; MOV A0,D3+4,A0 000D: 34 0E 0_1_10_1_10_0:@0==@0 NOT D3+4 ; EOR A0,D3+4,A0 000F: AD 0_0_10_0_00_0:@0!=AA ARG A,D 0010: 5F 0_0_10_0_01_1:@0!=#5 INF D5 ; MOV A0,D5 0011: 5E 0_0_10_0_01_0:@0!=#5 NOT D5 ; EOR A0,D5 0012: 34 5F 0_1_10_0_01_1:@0!=#5 SWP D3+4,D5 ; MOV A0,D3+4,D5 0014: 34 5E 0_1_10_0_01_0:@0!=#5 EOR D3+4,D5 ; EOR A0,D3+4,D5 0016: AC 0_0_10_0_01_0:@0!=#a ARG A,C 0017: 5F 0_0_10_0_00_1:@0!=C5 MOV PSW,C5 ; MOV A0,C5 0018: 5E 0_0_10_0_00_0:@0!=C5 NOT C5 ; EOR A0,C5 0019: 34 5F 0_1_10_0_00_1:@0!=C5 SWP D3+4,C5 ; MOV A0,D3+4,C5 001B: 34 5E 0_1_10_0_00_0:@0!=C5 EOR D3+4,C5 ; EOR A0,D3+4,C5 001D: DA 0_0_10_0_00_0:@0!=CD ARG D,A 001E: D1 0_0_01_0_00_0:#x!=AD REG D1 001F: 0F 0_0_01_0_10_1:#1!=@0 OUF D1 ; MOV D1,A0 0020: 0E 0_0_01_0_10_0:#1!=@0 NOT D1,CF ; EOR D1,A0 0021: 34 0F 0_1_01_0_10_1:#1!=@0 MOV D1,D3+4 ; MOV D1,D3+4,A0 0023: 34 0E 0_1_01_0_10_0:#1!=@0 EOR D1,D3+4 ; EOR D1,D3+4,A0 0025: CA 0_0_01_0_00_0:#1!=AC ARG C,A 0026: C2 0_0_00_0_00_0:C?!=AC REG C2 0027: 0F 0_0_00_0_10_1:C2!=@0 MOV C2,PSW ; MOV C2,A0 0028: 0E 0_0_00_0_10_0:C2!=@0 NOT C2,CF ; EOR C2,A0 0029: 34 0F 0_1_00_0_10_1:C2!=@0 MOV C2,D3+4 ; MOV C2,D3+4,A0 002B: 34 0E 0_1_00_0_10_0:C2!=@0 EOR C2,D3+4 ; EOR C2,D3+4,A0 002D: DD 0_0_00_0_00_0:C2!=AD ARG D,D 002E: 1F 0_0_01_1_01_1:#1==#1 ??? D1 ; MOV D1,D1 002F: 1E 0_0_01_1_01_0:#1==#1 NEG D1 ; EOR D1,D1 0030: 1D 0_0_01_1_01_0:#1==#1 STD D1 ; DIS D1,D1 0031: 1C 0_0_01_1_01_0:#1==#1 CLN D1 ; CON D1,D1 0032: 1B 0_0_01_1_01_0:#1==#1 SUB D1 ; SUB D1,D1 0033: 1A 0_0_01_1_01_0:#1==#1 ADD D1 ; ADD D1,D1 0034:06#34 5F 1_1_01_0_01_1:#1!=#5 ORD6 D1,D3+4,D5 ; MOV D1,D3+4,D5 0038: 34 5E 0_1_01_0_01_0:#1!=#5 EOR D1,D3+4,D5 ; EOR D1,D3+4,D5 003A: 34 1F 0_1_01_1_01_1:#1==#1 LEA D1,D3+4 ; MOV D1,D3+4,D1 003C: 34 1E 0_1_01_1_01_0:#1==#1 RRC D1,D3+4,D1 ; EOR D1,D3+4,D1 003E: 34 1D 0_1_01_1_01_0:#1==#1 SAL D1,D3+4,D1 ; DIS D1,D3+4,D1 0040: 34 1C 0_1_01_1_01_0:#1==#1 SAR D1,D3+4,D1 ; CON D1,D3+4,D1 0042: 34 1B 0_1_01_1_01_0:#1==#1 SUB D1,D3+4,D1 ; SUB D1,D3+4,D1 0044: 34 1A 0_1_01_1_01_0:#1==#1 MUL D1,D3+4,D1 ; ADD D1,D3+4,D1 0046: DB 0_0_01_0_01_0:#1!=#d ARG D,B 0047: 5F 0_0_01_0_00_1:#1!=B5 OUT D1,B5 ; MOV D1,B5 0048: 5E 0_0_01_0_00_0:#1!=B5 EOR D1,B5 ; EOR D1,B5 0049: 34 5F 0_1_01_0_00_1:#1!=B5 LEX D1,D3+4,B5 ; MOV D1,D3+4,B5 004B: 34 5E 0_1_01_0_00_0:#1!=B5 EOR D1,D3+4,B5 ; EOR D1,D3+4,B5 004D: CD 0_0_01_0_00_0:#1!=BC ARG C,D 004E: 5F 0_0_00_0_01_1:C2!=#5 MOV C2,D5 ; MOV C2,D5 004F: 5E 0_0_00_0_01_0:C2!=#5 EOR C2,D5 ; EOR C2,D5 0050: 34 5F 0_1_00_0_01_1:C2!=#5 ??? C2,D3+4,D5 ; MOV C2,D3+4,D5 0052: 34 5E 0_1_00_0_01_0:C2!=#5 EOR C2,D3+4,D5 ; EOR C2,D3+4,D5 0054: CC 0_0_00_0_01_0:C2!=#c ARG C,C 0055: 2F 0_0_00_1_00_1:C2==C2 MOV C2,C2 ; MOV C2,C2 0056: 2E 0_0_00_1_00_0:C2==C2 NEG C2,C2 ; EOR C2,C2 0057: 2D 0_0_00_1_00_0:C2==C2 STD C2,C2 ; DIS C2,C2 0058: 2C 0_0_00_1_00_0:C2==C2 CLN C2,C2 ; CON C2,C2 0059: 2B 0_0_00_1_00_0:C2==C2 SUB C2,C2 ; SUB C2,C2 005A: 2A 0_0_00_1_00_0:C2==C2 ADD C2,C2 ; ADD C2,C2 005B: 34 2F 0_1_00_1_00_1:C2==C2 LEX C2,D3+4,C2 ; MOV C2,D3+4,C2 005D: 34 2E 0_1_00_1_00_0:C2==C2 RRC C2,D3+4,C2 ; EOR C2,D3+4,C2 005F: 34 2D 0_1_00_1_00_0:C2==C2 SAL C2,D3+4,C2 ; DIS C2,D3+4,C2 0061: 34 2C 0_1_00_1_00_0:C2==C2 SAR C2,D3+4,C2 ; CON C2,D3+4,C2 0063: 34 2B 0_1_00_1_00_0:C2==C2 SUB C2,D3+4,C2 ; SUB C2,D3+4,C2 0065: 34 2A 0_1_00_1_00_0:C2==C2 MUL C2,D3+4,C2 ; ADD C2,D3+4,C2 0067: 34 5F 0_1_00_0_00_1:C2!=C5 ORD C2,D3+4,C5 ; MOV C2,D3+4,C5 0069: 34 5E 0_1_00_0_00_0:C2!=C5 EOR C2,D3+4,C5 ; EOR C2,D3+4,C5 006B: DB 0_0_00_0_00_0:C2!=CD ARG D,B 006C: B7 0_0_01_0_00_1:#1!=BB MOV D1,B7 006D: C7 0_0_01_0_00_1:#1!=BC MOV D1,C7 006E: CF 0_0_01_0_00_1:#1!=BC NOT CF ; CMC 006F: CE 0_0_01_0_00_0:#1!=BC ERA CF ; CLC 0070: 34 CF 0_1_01_0_00_1:#1!=BC JCF D3+4 ; JC D3+4 0072: 34 CE 0_1_01_0_00_0:#1!=BC JCE D3+4 ; JNC D3+4 --- Сообщение объединено, 24 июн 2023 --- Вот эскиз ТТЛ вычислителя вектора.
ТЕ ЕЩЁ МАРГИНАЛЫ Как сказано выше, указание неверного указателя на аппаратном уровне обрабатываются в особенном виде, из-за чего программист может использовать эти резервные механизмы по своему усмотрению. Однако, эти самые маргиналы местами просто слишком маргинальны. Например, рассмотрим несколько странных инструкций: код «00» - команда останова «HLT»: Переход на адрес 0000 с сохранением точки останова в D0 (регистровой паре B0:C0) код «10 00» - команда останова «HLT [D1+0]»: Безусловный переход на адрес [D1] с сохранением точки останова в D0 код «10 10 00» - команда останова «HLT1» или «HLT#1»: Здесь присутствует маргинал - непонятная операция… код «10 10 10 00» - команда останова «HLT 1#D1+0» или «HLT 1#[D1+0]»: Присутствует маргинальный указатель - ещё страннее… Нетрудно заметить, что на одной только операции Останова с частной комбинацией префиксов уже довольно неясная ситуация. Даже если браться обрабатывать такие комбинации на самом высоком уровне - эмуляцией в JavaScript, не совсем понятно, что именно с этим безобразием делать… МАРГИНАЛЬНЫЕ КАНАЛЫ Так как «маргинальные индексы» временно помечались в ассемблере/дизассемблере с «решёткой-шарпом», то это напомнило некоторую аналогию с каналами в Бейсиках (у ZX-Spectrum также имеются). Так, есть такой GW-Basic - оператор OPEN - вполне хороший пример. Тем самым, вполне можно: код «10 10 00» - команду «HLT#1» можно условно обозначать за «CLOSE#1»… код «10 10 10 00» - команду «HLT#1 [D1]» можно условно обозначать за «OPEN#1 "/dev/…"»… Тем самым, у процессора на программном уровне в системе команд появляются две, хоть и побочные, но весьма любопытные операции. Программист получает основные операции работы с файловой системой уже на самом низком уровне. Сам процессор может продолжать игнорировать такие операции и ничего не делать. Тогда как внешняя периферия и т.н. сопроцессор может перехватывать все эти «маргинальные конструкции инструкций» и производить соответствующую настройку. В таком случае, если в системе будут присутствовать «сетевой сопроцессор», «графический сопроцессор» или «математический сопроцессор», уже на уровне ассемблера предоставляется довольно мощное окружение… МАРГИНАЛЬНАЯ ЭМУЛЯЦИЯ КАНАЛОВ Естественно, о поддержке «маргинального окружения» на аппаратном уровне думать не приходится в принципе! Тем самым, следует продумать механизмы прерываний, чтобы поддерживать все эти «маргинальные каналы» на программном уровне драйверов операционной системы. Ещё во времена DOS и IBM PC-XT существовали библиотеки эмуляции отсутствующего FPU. Здесь - примерно то же самое… ПРИМЕР Если мы настроили «Маргинал #1» указателем на строку, типа "/dev/ega/320x240/" как открытия непосредственной проекции EGA-графики, то код Код (Text): 10 10 80 90 80 80 90 80 80 80 80 80 80 A7 будет означать «MOV 1#[D8+320D9],A7», что буквально «*(BYTE *)(D8 + 320 * D9) = A7», где D8 - координата X и D9 - координата Y. Получается одна длинная операция пиксельной записи в графическую плоскость.
Странная архитектура какая-то получается… Не успел разобраться как следует с маргиналами, как решил попытаться навести порядок с регистрами наткнулся ещё на одно… Но, обо всём по порядку. ДЕМОКРАТИЯ x86 Обычно, в подавляющем большинстве процессоров разбором подтекста программного кода никак не занимаются. Например: Серия команд «CLC + STC + CLC + CMC + CLC» - бессмысленна, но может служить как обфускации кода Серия команд «STD + CLD + CLD + STD + STD» - может иметь лишь смысл как «Морзянка», несущая тайное послание исследователю кода Серия команд «INC EAX + NEG EAX + MOV EAX,ECX + NOT EAX + MOV EAX,EAX + MOV EAX,[EBX]» - та же тайнопись для эзотерического замусоривания конвейера Думаяю уже понятно, к чему я подталкиваю тематику… РЕЗИНОВЫЙ РЕГИСТРОВЫЙ ФАЙЛ В прототипе процессора схематикой Logisim за 2019 год было всё очень просто и каждый код выполняться столько раз в подряд, сколько попадается в программе. Серия команд «REG A1 + REG A2 + REG A3» последовательно перебирала коды выбора одного из Аккумуляторов и в демонстрации служила в качестве светового шоу (схема подсвечивала активные РОН) Серия команд «CMC + CLC + CMC» также просто играла флагами и практически не имеет никакого применения, кроме как комбинированная «STC» Как можно уже догадаться, в рамках отладочной Verilog-модели появились механизмы, помогающие дешифратору команд оглядываться назад и корректировать функцию исполняемой команды (как и в случае со сбойными указателями, которые теперь маргинализуются). Относительно недавно были введены правила, где указывать регистр группы A нельзя, если он не указан как операнд-приёмник командой ARG: Команды «ARG A,B + REG A1» последовательно указывают, что в АЛУ-операциях фигурируют регистры A как приёмники результата и B как источник данных. Причём, приёмником указывается именно регистр A1 Команды «ARG A,B + REG B1» уже не переключат в группе B активность на регистр B1, так как он не в левой части операндов В таких случаях последовательность кода «AB A1 B1» как команды «ARG A,B + REG A1 + REG B1» уже буквально работает как «MOV A1,B1», так как дешифратором команд просто проверяется условие аргументированного выбора регистра-приёмника. Но, если идти ещё дальше и усложнять дешифратор команд, то уже появляются любопытнейшие функции: Код «A1 A2 A3» как цепочка команд «REG A1 + REG A2 + REG A3» уже становится на втором коде командой «REG A12», а на третьем - «REG A123» Код «B4 B5 B6» в этом контексте, как «MOV A123,B4 + MOV A123,B5 + MOV A123,B6» в конечном итоге выполняется как «MOV A123,B456» Несложно догадаться, что непосредственная адресация регистров-приёмников и регистров-источников стала чуточку строже, но теперь программист может оперировать не десятками РОН, а тысячами и миллионами! Получается уже какой-то восьмибитный HAL-9000 или CRAY… Это что за архитектура такая мною исследуется и развивается? ПРОБЛЕМА ДИЗАЙНА ЯДРА Понятное дело, что нужно снова переписывать весь Verilog, так как модель заточена именно как Принстонская и имеет свои нюансы. Уже подошло всё к тому рубежу, когда Ядро должно стать универсальным и не зависеть от внешних шин. Иначе говоря, если кто-нибудь заинтересуется так или иначе этой архитектурой, не должен испытывать особых проблем с организацией хоть миллионного регистрового файла, хоть вынести регистры во внешний кэш. По-сути говоря, процессор этот - не строго 8-битный. Так как 8-битный только его код. Его легко сделать и 4-битным, и 16-битным, и 64-битным. Но, даже в эмуляции 16-бит - это 32-битная адресация ОЗУ (4 Гб), что слишком много. Именно поэтому отлаживаемая модель - 8-битная, как золотая середина. Не забываем, что память адресуется через D0…D9, которые просто адресуют спаренные регистры B0:C0…B9:C9, которые (для простоты) 8-битные P.S.: Даже не знаю теперь, как и опыта не имею, как начать описывать чистое ядро, независимое от размера Регистрового Файла и внешних шин…