Я вижу, раз есть интерес к 1806 надо замутить переходник для него на плату DE0, чтобы тестировать процессор можно было.
Вид для печати
Неплохо было бы. Можно узнать какие глюки починили, а какие остались. Глюка с адресацией @PC уже нет, код 030 исполняется как 020 (RSEL). Возможно уже нет глюка при записи по адресу предвыборки, если адрес записи и PC отличаются разным значением бита 0 (чёт и нечёт). Вот про глюки с записью R7 в EIS и записью CPSW при переполнении в DIV до этого было неизвестно, вскрылось только сейчас.
Ну, и финальная вишенка на торте команд расширенной арифметики - это ASH(C).
По сравнению с MUL и DIV простая до неприличия. Даже проверять не стал.
ASH(C):
- - - Добавлено - - -Код://======================================================================
//
// Команда ASH(C) Rs,Rd
//
//======================================================================
0x3B: ACC=Rs // ACC - счетчик
//----------------------------------------------------------------------
0x1A: // (в данной команде поля Rs и Rd кодируются нестандартно)
EA1=Rd // EA1 - старшее слово (единственное для ASH)
if ASH GOTO 0x27
//---------------------------------------------------------------------- ASHC
0x2A: EA2=Rd|1 // EA2 - младшее слово
//----------------------------------------------------------------------
0x27: if (ACC[5]=0) CTR=ACC // Сдвиг влево
else CTR=~ACC // Сдвиг вправо
// CTR - счетчик итераций 0..31
TLZ=EA1[15] // TLZ - знак старшего слова
//----------------------------------------------------------------------
0x35: // Первая итерация
if LEFT EA1.EA2=EA1.EA2 NZVC // Если сдвиг влево, то первая итерация ничего не делает
else EA1.EA2=EA1.EA2>>1 NZVC
if (CTR=0)
if ASH GOTO 0x0C
else GOTO 0x0E
//----------------------------------------------------------------------
0x35: loop: CTR=CTR-1 // Все последующие итерации
if LEFT EA1.EA2=EA1.EA2<<1 NZVC
else EA1.EA2=EA1.EA2>>1 NZVC // Арифметический сдвиг вправо
if (CTR<>0) GOTO loop
// Влияние на флаги:
// N=EA1[15] (знак результата)
// Если ASHC, и EA1.EA2=0, то Z=1
// Если ASH, и EA1=0, то Z=1
// Иначе Z=0
// Если ASHC RIGHT, то C=ЕА2'[0] (предыдущее значение EA2[0])
// Если ASH RIGHT, то C=ЕА1'[0] (предыдущее значение EA1[0])
// Если ASH(C) LEFT, то C=ЕА1'[15] (предыдущее значение EA1[15])
// Если ASH(C) RIGHT, то V=0
// Если ASH(C) LEFT, то для первой итерации V=0
иначе если хотя бы в одной итерации TLZ^EA1[15]=1, то V=1
if ASH GOTO 0x0C
//---------------------------------------------------------------------- ASHC
0x0E: Rd=EA1 // Rd=ЕА1 - старшее слово
//----------------------------------------------------------------------
0x0C: if ASHC Rd|1=EA2 // Rd|1=ЕА2 - младшее слово
if ASH Rd=EA1 // Rd=EA1 - слово для ASH
PLI_REQ // Запросить проверку запросов на прерывание
if X(Rs) or @X(Rs) or (Rs=R7) // Если использовали адресацию по R7, то
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции
else // Иначе
GOTO 0x01 // Перейти на команду выборки следующей инструкции
Из интересненького: как видно из алгоритма, сдвиг 32-битного слова всего на 8 тактов медленнее, чем сдвих 16-битного, независимо от числа итераций.
Поэтому, если требуется работа с большими данными, лучше оперировать сразу с 32-битными словами.
Значение 0100 0000 0000 0000 сдвигаю влево на три разряда. При первом сдвиге фиксируется изменение знака, результат 1000 0000 0000 0000. При втором сдвиге фиксируется изменение знака, результат 0000 0000 0000 0000. При третьем сдвиге изменения знака нет, но флаг V должен стоять.
Проверил на реале.
После исполнения установлены биты Z и V.Код:1000 012701 MOV #40000,R1
1002 040000
1004 012700 MOV #3,R0
1006 000003
1010 072100 ASH R0,R1
1012 106702 MFPS R2
- - - Добавлено - - -
А не влияет ли наличие RS-триггера на исполнение других команд EIS?