Все так как я и описал. Сперва 512 тактов на RESET, и в это время держится DIN. А потом отрабатывает нормальный тайм-аут.
Вид для печати
Продолжаем.
Пока что простые операции.
MOV(B), BIS(B), BIC(B), ADD, SUB, CMP(B), BIT(B), XOR:
Код://======================================================================
//
// Операции с двумя операндами
// и регистровой адресацией Rs,Rd
//
// MOV(B), BIS(B), BIC(B), ADD, SUB, CMP(B), BIT(B), XOR
//
//======================================================================
0x3B: if BIC(B) Rd(.B)=Rd&~Rs VZN
if BIS(B) Rd(.B)=Rd|Rs VZN
if ADD Rd=Rd+Rs CVZN
if SUB Rd=Rd+~Rs+1 CVZN
if CMP(B) ACC(.B)=~Rd+Rs+1 CVZN
if BIT(B) ACC(.B)=Rd&Rs VZN
if XOR Rd=Rd^Rs VZN
if MOV Rd=Rs VZN
if MOVB Rd=SIGNEXT(Rs) VZN
endif
PLI_REQ // Запросить проверку запросов на прерывание
if (Rd=R7) GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции
else GOTO 0x01 // Перейти на команду выборки следующей инструкции
Это еще что.
Вот как работает EALU - это песня.
Фактически работает тот же микропрограммный автомат вместе с обычным АЛУ, в то время, как блок расширенного АЛУ беспощадно ими управляет, подбрасывая лишние данные, зацикливая, добавляя регистры в цепочку сдвига, организуя цикл, приостанавливая микропрограмму на время. Как дирижер вбежавший в слаженный ансамбль, и заставляющий играть его по-своему.
Вот и понят один из столпов расширенной арифметики - умножение.
Достаточно сложно было собирать его логику по всей схеме. Все очень запутано и специфично. Пришлось даже попросить уважаемого @Ynicky прогнать умножение на модели, чтобы сравнить, не накосячил ли я в общих чертах.
После чего я написал на Си модель того, что описано ниже, и прогнал на всех комбинациях. Все сошлось в точности.
Интересная особенность EALU в том, что когда счетчик числа итераций CTR загружается новым значением, микропрограммный автомат останавливается, и АЛУ каждый шаг выполняет одну и ту же заданную микропрограммой математическо-логическую операцию, но на которую в широком диапазоне может влиять автомат EALU. После окончания счета, микропрограмма продолжается далее.
MUL:
- - - Добавлено - - -Код://======================================================================
//
// Команда MUL Rs,Rd
//
//======================================================================
0x3B: ACC=Rs // (в данной команде поля Rs и Rd кодируются не стандартно)
//----------------------------------------------------------------------
0x18: EA1=0
//----------------------------------------------------------------------
0x27: EA2=ACC // EA2 - Rs
//----------------------------------------------------------------------
0x35: CTR=0x10 // Счетчик на 16 итераций
//----------------------------------------------------------------------
0x1A: // Этот шаг АЛУ повторяет 16 раз
if (EA2[0]=1) EA1=EA1+Rd
else EA1=EA1
ЕА1.ЕА2=EA1.EA2>>1 // Арифметический сдвиг вправо с сохранением знака
EA1[15]=EA1[15]^c15^c14 // Если при сложении был перенос из 15-го бита, или
// перенос из 14-го бита (арифметическое переполнение),
// то знак меняется на противоположный
CTR=CTR-1
if (CTR>0) GOTO 0x1A
//----------------------------------------------------------------------
0x2A: // CTR=0
if (ACC[15]=1) EA1=EA1-Rd // Если ACC<0, то коррекция результата
else EA1=EA1
CVZN // Флаги устанавливаются согласно алгоритму MUL:
// N=EA1[15]
// if (((EA1=0x0000) and (EA2[15]=0)) or
// ((EA1=0xFFFF) and (EA2[15]=1))) C=0
// else C=1
// if (EA1.EA2=0) Z=1
// V=0
//----------------------------------------------------------------------
0x0E: Rd=EA1 // Старшая часть результата
//----------------------------------------------------------------------
0x0C: Rd|1=EA2 // Младшая часть результата
// Дальнейшая проверка рудиментарная, и наследуется от других команд
if (Rs=R7) GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции
else GOTO 0x01 // Перейти на команду выборки следующей инструкции
Следует обратить внимание на то, что в конце проверяется Rs=R7, и исходя из этого делается перекеширование.
Хотя в случае умножения, следует проверять Rd|1=R7, что, как видно, не делается.
А значит в этом случае имеем глюк. Хотя, в процессоре есть блок, отвечающий за запись в R7, возможно, он спасет в этом случае. Пока что с ним не разбирался.
А может всё-таки записываем в Rd, а не в Rs. Ведь Rs - source, источник, а Rd - destination, приёмник. А так нужна проверка на Rd|1=R7. Надо попробовать воспроизвести глюк на реальной УКНЦ, нужно только правильные множители подобрать, в смысле значения регистров R6 и R7.
Что то мне кажется, что проверять надо и Rd=R7 и Rd|1=R7 ибо MUL #10, SP и MUL #10, R7