Вход

Просмотр полной версии : Реверс-инжиниринг УКНЦ (1515ХМ1&2, 1801ВП1, 1801ВМ2)



Страницы : 1 2 3 4 5 6 [7]

Titus
02.12.2020, 22:34
Кажется, я вижу, откуда ножки растут.

Попробуйте сделать тест, в котором команда, предшествующая делению, с простой адресацией типа MOV Rx,Rx:


0776 CLR R0
1000 MOV #2,R3
1004 MOV R3,R3
1006 MUL R3,R7
1010 INC R0

- - - Добавлено - - -

Хотя, нет, не надо делать.

- - - Добавлено - - -

В общем, нашел ошибку.

Блок, который призван идентифицировать двухадресную команду ((код & 0x7FFF)> 0x0FFF), у которой в качестве Rd указан R7, имеет ошибку или особенность следующего плана.

Триггер U577, запоминающий состояние IX1 обновляется при выборке каждой микрокоманды.
А IR_STB выдается только при выборке первой микрокоманды инструкции.
Поэтому в во время первой микрокоманды в инструкции флаг IX1 устанавливается правильно, а уже следующая микрокоманда этот флаг обнуляет.
Таким образом, принять решение о том, что инструкция двухоперандная влияющая на R7 можно только в первой микрокоманде инструкции. Возможно, это где-то задействовано (в двухоперандных командах, до которых я не дошел), но в случае с MUL не работает.


https://pic.maxiol.com/images2/1606936800.2151951043.01.png

- - - Добавлено - - -

https://pic.maxiol.com/images2/1606937655.2151951043.01.png

Vslav
02.12.2020, 23:22
А какое было значение SP?
400

140 000200 . = 200 ; начальная точка входа в тест
141 000200 .blkw 100 ;
142 000400 stack: ;
143 000400 tebuf: .blkw 8. ;
144 000420 012706 000400 entry: mov #stack, SP ;
145 000424 106427 000340 mtps #340 ; запретили прерывания
146 000430 000167 000344 jmp tst0 ; выбираем нужный тест
147 ;
148 001000 . = 1000 ;
149 001000 005000 tst0: clr R0
150 001002 012703 000002 mov #2, R3
151 001006 070603 mul R3, SP
152 001010 005200 inc R0
153
154 001012 .blkw 2000


- - - Добавлено - - -



Блок, который призван идентифицировать двухадресную команду ((код & 0x7FFF)> 0x0FFF), у которой в качестве Rd указан R7, имеет ошибку или особенность следующего плана.

А у команд EIS разве ss и d (вместо dd) не поменяны местами? "ss == R7" идет лесом ?

Alex_K
02.12.2020, 23:25
Таким образом, принять решение о том, что инструкция двухоперандная влияющая на R7 можно только в первой микрокоманде инструкции. Возможно, это где-то задействовано (в двухоперандных командах, до которых я не дошел), но в случае с MUL не работает.
Если в dst используется R7, то это можно решить на уровне микрокода, а вот использование R7 в src надо где-то запомнить. Кстати в src R7 изменяется и при использовании адресаций 6 и 7.

Titus
02.12.2020, 23:32
А у команд EIS разве ss и d (вместо dd) не поменяны местами? "ss == R7" идет лесом ?
Поменяны. Поэтому для этих команд будет dd=R7, а не ss=R7.

Vslav
02.12.2020, 23:46
ix - это РДУ - Регистр Дополнительных условий, он многофункциональный, U643 на твоей схеме это просто OR в роли мультиплексора, сигналы на входах всегда в разных фазах. Это же и в документации написано. Так что признаки там хранится все время исполнения инструкции просто не могут.

Titus
02.12.2020, 23:57
ix - это РДУ - Регистр Дополнительных условий, он многофункциональный, U643 на твоей схеме это просто OR в роли мультиплексора, сигналы на входах всегда в разных фазах. Это же и в документации написано. Так что признаки там хранится все время исполнения инструкции просто не могут.
Документацию не читал, но и так понятно, как он работает. И я уже описывал его многофункциональность.

- - - Добавлено - - -

А признаки там могут хранится, и хранятся. Например, в IX2 хранится признак в течение всей инструкции.

Vslav
03.12.2020, 00:05
Микропрограмма выборки кэшированной инструкции (адрес 0x01) принимает решение о перекешировании, если IX1=1.
IX1=1, если совпало одно из условий:
1. Совпало условие блока условий (BRA=1). В нашем случае неактуально, т.к. проверка условий не запрашивалась.
2. Был активен RCMD_SET. Не разбирался, но это что-то из блока таймаута и блока модификации кэша, когда записали новое значение по адресу, на который указывал R7.

Это да, а вот следующее не работает:


3. Предыдущая инструкция была двухоперандная (в битах 14,13,12 был не 000), при этом в поле приемника (биты 8,6,7) был закодирован R7. Условие двухоперандности совпадает, но вот в поле приемника у нас не R7, а R6.

Потому что когда исполняется 0x01, IR_STB нет.

Titus
03.12.2020, 00:09
Потому что когда исполняется 0x01, IR_STB нет.
Как это нет? IR_STB именно во время 0x01 и есть, т.к. IR_STB инициируется SET_CEND, а SET_CEND устанавливает единственная команда - 0x01.

Vslav
03.12.2020, 00:12
А признаки там могут хранится, и хранятся. Например, в IX2 хранится признак в течение всей инструкции.
Да, 2-ой разряд тактируется от IR_STB и хранит признак двух-адресной инструкции. Но для IX[0..1] это не так, они мультиплексируются, регистр обновляется каждый микроцикл и содержимое интерпретируются каждой микрокомандой по-своему.

- - - Добавлено - - -


Как это нет? IR_STB именно во время 0x01 и есть, т.к. IR_STB инициируется SET_CEND, а SET_CEND устанавливает единственная команда - 0x01.
- модель с тобой не согласна, специально сейчас проверил
- заводская документация с тобой тоже не согласна

Titus
03.12.2020, 00:17
Да, 2-ой разряд тактируется от IR_STB и хранит признак двух-адресной инструкции. Но для IX[0..1] это не так, они мультиплексируются, регистр обновляется каждый микроцикл и содержимое интерпретируются каждой микрокомандой по-своему.
Все так.

- - - Добавлено - - -


- модель с тобой не согласна, специально сейчас проверил
- заводская документация с тобой тоже не согласна
Возможно, все зависит от того, какой итервал ты считаешь за время исполнения одной микрокоманды.
Я считаю то время, когда PLM неизменно:

https://pic.maxiol.com/images2/1606943798.2151951043.01.png

Vslav
03.12.2020, 09:42
Возможно, все зависит от того, какой итервал ты считаешь за время исполнения одной микрокоманды.

М-м-м... Чего?
У нас есть регистр адреса микрокоманды - na. Вот он определяет (среди прочего) что будет выдавать матрица, в том числе адрес следующей микроинструкции.
Так вот, в тот момент когда na == 0x01 (0x76 в моем инвертированном представлении) и происходит анализ IX[1] на предмет перезагрузить инструкцию или нет. IR_STB никогда не возникает при na == 0x01 - это подтверждается моделью и заводской документацией. И это просто противоречит логике работы - по IR_STB будут загружены результаты предекодера, а если инструкции нет (не успела загрузиться, тайм-аут на предвыборке и прочее) или неверная (изменили PC, переход и прочее) то и результаты грузить нельзя. Иначе говоря, нельзя выдавать IR_STB ДО анализа наличия загруженной достоверной следующей инструкции и результатов ее декодирования.

- - - Добавлено - - -

Как-то так:

https://www.1801bm1.com/files/images/vm2na76.png

Titus
03.12.2020, 13:19
Так вот, в тот момент когда na == 0x01 (0x76 в моем инвертированном представлении) и происходит анализ IX[1] на предмет перезагрузить инструкцию или нет. IR_STB никогда не возникает при na == 0x01 - это подтверждается моделью и заводской документацией.
Ты все правильно говоришь, только ты считаешь началом микрокоманды момент изменения NA. Т.е. как NA стал равен 0x01, ты считаешь это началом микрокоманды.
А я считаю началом микрокоманды изменение PLM (фронт MC_STB). Или, иными словами, одна микрокоманда - это от MC_STB до следующего MC_STB.

Vslav
03.12.2020, 16:35
А я считаю началом микрокоманды изменение PLM (фронт MC_STB). Или, иными словами, одна микрокоманда - это от MC_STB до следующего MC_STB.
Это очень узкое понимание. Там конвейер, для исполнительных механизмов есть два строба для фаз чтения и записи - MC_STB и MW_STB, которые фиксируют задание от матрицы и сохраняют результаты в сторадж. А основная матрица рулится другими стробами - SA1 и SA2. И работу IR_STB надо рассматривать в привязке к ним, потому что анализ производится и решение принимается именно в матрице.

Titus
03.12.2020, 16:46
Там конвейер, для исполнительных механизмов есть два строба для фаз чтения и записи - MC_STB и MW_STB, которые фиксируют задание от матрицы и сохраняют результаты в сторадж. А основная матрица рулится другими стробами - SA1 и SA2. И работу IR_STB надо рассматривать в привязке к ним, потому что анализ производится и решение принимается именно в матрице.
Я все это знаю. Если ты посмотришь мои графики, то у меня все это расписано.

Alex_K
03.12.2020, 20:48
Посмотрел по остальным командам EIS, данный глюк есть во всех. Для DIV в качестве аргумента использовал 077777, а для ASH и ASHC - 1.

Titus
03.12.2020, 20:58
Посмотрел по остальным командам EIS, данный глюк есть во всех. Для DIV в качестве аргумента использовал 077777, а для ASH и ASHC - 1.
Логично, ибо стандартная проверка Rd на принадлежность R7 не работает, из-за перепутанности ss и dd в этих командах.
А специальную проверку, судя по всему, во всех EIS-командах не сделали.

Alex_K
03.12.2020, 21:16
Логично, ибо стандартная проверка Rd на принадлежность R7 не работает, из-за перепутанности ss и dd в этих командах.
А специальную проверку, судя по всему, во всех EIS-командах не сделали.
Но это не страшно. Никакой нормальный программист не будет использовать SP и PC, будут использовать с R0 по R5. А благодаря этому глюку можно сделать защиту от пошаговой отладки, главное правильные команды применить и рассчитать все аргументы.

Titus
03.12.2020, 21:24
А благодаря этому глюку можно сделать защиту от пошаговой отладки, главное правильные команды применить и рассчитать все аргументы.
Зачем защищать от нее? )

Alex_K
03.12.2020, 21:29
Зачем защищать от нее? )
Программу можно упаковать, а распаковщик защитить. Такое практиковалось на PC в MS-DOS. На УКНЦ смысла нет. Я просто про возможность применения.

Titus
03.12.2020, 21:36
Программу можно упаковать, а распаковщик защитить. Такое практиковалось на PC в MS-DOS. На УКНЦ смысла нет. Я просто про возможность применения.
Так можно защитить и от эмуляторов)

Alex_K
03.12.2020, 21:41
Так можно защитить и от эмуляторов)
От EmuStudio и UKNCBTL?

Titus
03.12.2020, 21:42
От EmuStudio и UKNCBTL?
А других пока нет)
А эти несовершенны)

Alex_K
03.12.2020, 21:48
Узнать бы ещё - есть этот глюк в 1806ВМ2 или нет.

Alex_K
04.12.2020, 22:45
Решил проверить глюк с командами EIS с использованием регистра R7, если команда располагается в последней ячейке памяти. В этой ситуации по предвыборке должна прочитаться ячейка с адресом 0160000, соответственно чтения не будет. А вот будет ли в этом случае TRAP4?
Сама программа:


157770 005000 CLR R0
157772 012703 MOV #-1,R3
157774 177777
157776 070703 MUL R3,R7

В итоге TRAP4 не произошло, но останов был по адресу 020000, а не 020002. В ячейки 017776 и 020000 занёс команду INC R0. В итоге значение регистра R0 увеличилось на два. При умножении 0160000 на 0177777 получается 020000, это значение заносится в R7. Но из-за того, что по предвыборке не удалось прочесть ячейку 0160000, значение R7 уменьшается на два и происходит переход на адрес 017776, вместо 020000.

Titus
04.12.2020, 23:04
Но из-за того, что по предвыборке не удалось прочесть ячейку 0160000, значение R7 уменьшается на два и происходит переход на адрес 017776, вместо 020000.
Это тоже обьяснимо. Значит неправильная предвыборка устанавливает IX1=1, и тогда уже:


if ((RI=001) & IX1=1) // Если нет запроса на прерывание, и BIR недействительный, то
PC1=PC2=PC1-2
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции

Alex_K
04.12.2020, 23:11
Это тоже обьяснимо. Значит неправильная предвыборка устанавливает IX1=1, и тогда уже:


if ((RI=001) & IX1=1) // Если нет запроса на прерывание, и BIR недействительный, то
PC1=PC2=PC1-2
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции

Из этого следует, что если в ячейке 0157776 будет команда типа MOV R0,R1, то при её исполнении по предвыборке будет попытка чтения ячейки с адресом 0160000. Попытка будет неудачная, тогда получается, что следующая некэшированная инструкция также будет читаться с адреса 0160000. Таким образом получается, что ячейка с адресом 0160000 будет читаться дважды.

Titus
05.12.2020, 00:09
Из этого следует, что если в ячейке 0157776 будет команда типа MOV R0,R1, то при её исполнении по предвыборке будет попытка чтения ячейки с адресом 0160000. Попытка будет неудачная, тогда получается, что следующая некэшированная инструкция также будет читаться с адреса 0160000. Таким образом получается, что ячейка с адресом 0160000 будет читаться дважды.
Вот этого не понял)

Alex_K
05.12.2020, 00:17
Вот этого не понял)
А что конкретно не понятно?

Titus
05.12.2020, 00:32
А что конкретно не понятно?
Целиком фрагмент, который выполнялся.

Alex_K
05.12.2020, 00:34
Целиком фрагмент, который выполнялся.
Какой фрагмент? Та, тестовая программа, что приведена выше, или предположения об исполнении команды MOV R0,R1 в ячейке с адресом 0157776?

Titus
05.12.2020, 00:41
Какой фрагмент? Та, тестовая программа, что приведена выше, или предположения об исполнении команды MOV R0,R1 в ячейке с адресом 0157776?
Все целиком)

Alex_K
05.12.2020, 00:44
Все целиком)
По тестовой программе вроде всё ясно. Чего там непонятного?

CodeMaster
05.12.2020, 09:20
Чего там непонятного?
Пятница, вечер - надо дать мозгу и отдохнуть ;-)

Titus
05.12.2020, 13:31
Из этого следует, что если в ячейке 0157776 будет команда типа MOV R0,R1, то при её исполнении по предвыборке будет попытка чтения ячейки с адресом 0160000. Попытка будет неудачная, тогда получается, что следующая некэшированная инструкция также будет читаться с адреса 0160000. Таким образом получается, что ячейка с адресом 0160000 будет читаться дважды.
Не могу сказать, потому что пока не изучал блок таймаута, какие сигналы и режимы он генерирует.

- - - Добавлено - - -


Пятница, вечер - надо дать мозгу и отдохнуть ;-)
Скорее ночь и десятый сон)

Alex_K
05.12.2020, 13:47
Не могу сказать, потому что пока не изучал блок таймаута, какие сигналы и режимы он генерирует.
Наверное по поводу этих глюков опять надо попросить Vslav-а сделать диаграмму, возможно там будет что-то понятно?

Titus, а когда будут DIV, ASH и ASHC?

Titus
05.12.2020, 14:02
Titus, а когда будут DIV, ASH и ASHC?
DIV я начал, но он очень навороченный)
Там на каждый цикл АЛУ миллион дополнительных действий и модификаторов от EALU.

- - - Добавлено - - -


Наверное по поводу этих глюков опять надо попросить Vslav-а сделать диаграмму, возможно там будет что-то понятно?
Диаграммы никогда не помешают.
Хотя бы для того, чтобы в теоретизировании не уйти от реальности.

Alex_K
05.12.2020, 14:08
Хотя бы для того, чтобы в теоретизировании не уйти от реальности.
Как говорит наш шеф, в нашем деле главное - реализм.

Titus
05.12.2020, 17:11
Итак, гость нашей студии - монстр таёжного рока - команда деления.
Самая массивная из всех команд процессора ВМ2. Она задействует и ресурсы микрокоманд, приостанавливая и запуская несколько раз конвейер заново. И стандартное ALU, и, конечно же, расширенное ALU. Те, ко ее кодировали, конечно, монстры. Я сам разбирался с ней 3 дня и 3 ночи, а еще строил модель на Си для проверки итогового алгоритма, а также просил Ynicky сравнить с моделью.

DIV Rs,Rd:

//================================================== ====================
//
// Команда DIV Rs,Rd
//
//================================================== ====================
0x3B: ACC=Rs // ACC - делитель
// (в данной команде поля Rs и Rd кодируются не стандартно)
//----------------------------------------------------------------------
0x1A: EA1=Rd // EA1 - делимое, старшая часть
//----------------------------------------------------------------------
0x2A: EA2=Rd|1 // EA2 - делимое, младшая часть (EA1.EA2 - делимое)
//----------------------------------------------------------------------
0x27: CTR=0x0014 // Счетчик на 20 итераций
//---------------------------------------------------------------------- CTR=20
0x35: ACC=ACC // Проверка делителя на ноль
if (ACC=0) ZERO_DIV=1 // Если ACC=0, то ZERO_DIV=1 (деление на ноль)
else ZERO_DIV=0 //

TLZ=EA1[15] // TLZ=EA1[15] (знак делимого)

CTR=CTR-1
//---------------------------------------------------------------------- CTR=19
0x09: // Первый цикл деления
if (TLZ^ACC[15]=1) // Если у делимого и делителя разные знаки
EA1=EA1+ACC // EA1=EA1+ACC
else EA1=EA1-ACC // иначе EA1=EA1-ACC

EA1.EA2=(EA1.EA2<<1)+EA1[15] // Циклический сдвиг влево
EA2[0]=~EA2[0]^ACC[15] // Инвертируем бит займа и накладываем по XOR знак делителя

FCARRY=EA2[0] // Запомнить первый займ

CTR=CTR-1
//---------------------------------------------------------------------- CTR=18..4 (15 итераций)
0x09: loop:
// Основной цикл деления
if (EA2[0]=0) // Если не было займа, то
EA1=EA1+ACC // EA1=EA1+ACC
else EA1=EA1-ACC // иначе EA1=EA1-ACC

EA1.EA2=(EA1.EA2<<1)+EA1[15] // Циклический сдвиг влево
EA2[0]=~EA2[0]^ACC[15] // Инвертируем бит займа и накладываем по XOR знак делителя

CTR=CTR-1
if (CTR>3) GOTO loop
//---------------------------------------------------------------------- CTR=3
0x31: // Завершающий цикл деления
if (EA2[0]=0) // Если не было займа, то
EA1=EA1+ACC // EA1=EA1+ACC
else EA1=EA1-ACC // иначе EA1=EA1-ACC

ЕА2=(EA2<<1)+EA1[15] // Сдвиг результата влево
EA2[0]=~EA1[0]^ACC[15] // Инвертируем бит займа и накладываем по XOR знак делителя

CTR=CTR-1
//---------------------------------------------------------------------- CTR=2
0x31: // Корректировка остатка
if (EA1=0) // Если EA1=0 (остаток равен 0),
EA1=EA1 // то ничего не делаем
else if (EA2[0]=0) // Иначе если не было займа, то
EA1=EA1+ACC // EA1=EA1+ACC
else EA1=EA1-ACC // иначе EA1=EA1-ACC

CTR=CTR-1
//---------------------------------------------------------------------- CTR=1
0x31: // Корректировка остатка
if (EA1=0) // Если EA1=0 (остаток равен 0),
EA1=EA1 // то ничего не делаем
DIV_Z=1
else
DIV_Z=0 // Иначе
if (TLZ^EA1[15]=0) // Если остаток и делимое одинакового знака, то
EA1=EA1 // ничего не делаем,
else if (ACC[15]^EA1[15]=0) // иначе если остаток и делитель одинакового знака, то
EA1=EA1-ACC // EA1=EA1-ACC
else EA1=EA1+ACC // иначе EA1=EA1+ACC
endif

CTR=CTR-1
//---------------------------------------------------------------------- CTR=0
0x19: // Корректировка результата в зависимости от знаков
if (((TLZ=0) & (ACC[15]=1)) or // Если знак делимого плюс, и знак делителя минус, или
((TLZ=1) & (ACC[15]=0) & (DIV_Z=0)) or // если знак делимого минус, знак делителя плюс, и DIV_Z=0, или
((TLZ=1) & (ACC[15]=1) & (DIV_Z=1))) // если знак делимого минус, знак делителя минус, и DIV_Z=1, то
EA2=EA2+1 NZVC // EA2=EA2+1 с установкой флагов
else EA2=EA2^0 NZVC // Иначе EA2=EA2 с установкой флагов

// Алгоритм установки флагов
C=ZERO_DIV // Флаг C отображает деление на ноль

if ((ZERO_DIV=1) or // Флаг V отображает деление на ноль и арифметическое переполнение
(FCARRY^ACC[15]^TLZ=1) or
(FCARRY^EA2[15]^CARRY))
V=1
else V=0

if (EA2=0) Z=1 // Флаг Z отображает равенство результата нулю
else Z=0

N=EA2[15] // Флаг N отображает знак результата

//---------------------------------------------------------------------- Проверка арифметического переполнения и деления на ноль
0x1E: ACC=PSW&0x02 GET_STATE Z=0 // Если PSW[V]=1 (Z=0), то BRA=1, иначе BRA=0
//----------------------------------------------------------------------
0x2D: NO ALU PI_STB VEC=0x03 RI=100 // Управление: константа вектора 0x0C, используется как константа для АЛУ
if (BRA=1) GOTO 0x2C // Если BRA=1 (V=1) (арифметическое переполнение)
else GOTO 0x0E // Иначе BRA=0 (V=0) (нет переполнения)
//---------------------------------------------------------------------- Нет переполнения и деления на ноль
0x0E: Rd|1=EA1 // EA1 - остаток
//----------------------------------------------------------------------
0x0C: Rd=EA2 // EA2 - частное

if (Rs=R7) GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции
else GOTO 0x01 // Перейти на команду выборки следующей инструкции


//---------------------------------------------------------------------- Арифметическое переполнение или деление на ноль
0x2C: PSW=PSW&~0x0C // Очистить флаги N и Z
//----------------------------------------------------------------------
0x28: CPSW=PSW // Копировать PSW в CPSW, потому что при работе с констатной, CPSW в данном режиме не обновляется
//----------------------------------------------------------------------
0x08: ACC=ACC PLI_REQ // Запросить проверку запросов на прерывание
if X(Rs) or @X(Rs) or (Rs=R7) // Если использовали адресацию по R7, то
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции
else // Иначе
GOTO 0x01 // Перейти на команду выборки следующей инструкции




Заметки к процедуре деления:

1. На проверку флага V в PLM проверки условий (PLM_BRA), видимо, уже не хватало места, и проверку флага V сделали через проверку флага Z (PSW & 0x02). Что на 4 такта замедляет деление, но ввиду и так достаточно длинного его выполнения, особой роли не играет.
2. В конце деления запись результата в R7 проверяется стандартным для обычных двухоперандных инструкций методом. Однако, ввиду того, что Rd и Rs у команд EALU поменяны местами, эта проверка является некорректной.
3. Не смотря на то, что я всячески стараюсь не менять названия сигналов, данные Vslav'ом, тут все же пришлось заменить /WAIT_DIV на DIV_Z, ибо никак не соответствует.
4. Каждый из столь емких шагов EALU делается за 4 такта, за исключением проверки флагов, которая всегда делается за 8 тактов.
5. В блоке констант не нашлось констатны 0xF3, поэтому для этого пришлось воспользоваться хитрым образом констатной из блока векторов прерываний 0x0C (BPT), инвертируя ее.
6. Из-за того, что в случае деления на ноль или переполнения, используется модификация PSW (сброс флагов N и Z), а так же нестандартное копирование PSW в CPSW, блокировка CPSW при запрещенных прерываниях в HALT-режиме не сработает.

MiX
05.12.2020, 17:12
Узнать бы ещё - есть этот глюк в 1806ВМ2 или нет.
Как проверить?

Alex_K
05.12.2020, 17:33
Как проверить?
В пультовом отладчике. Таймер желательно выключить, запускать с запретом прерываний, т.е. RS=340. Программка проверки занимает несколько слов, так быстрее проверить так.

- - - Добавлено - - -


0x28: CPSW=PSW
Ох! Очень интересно! Получается, что при арифметическом переполнении результат PSW обязательно копируется в CPSW, даже несмотря на HALT с запрещёнными прерываниями. Надо обязательно проверить.

Titus
05.12.2020, 17:43
Добавил пукнт 6 в заметки. Теперь можно проверить деление на ноль в HALT-режиме с запрещенными прерываниями, и убедиться, что деление портит CPSW.

- - - Добавлено - - -


Ох! Очень интересно! Получается, что при арифметическом переполнении результат PSW обязательно копируется в CPSW, даже несмотря на HALT с запрещёнными прерываниями. Надо обязательно проверить.
Да, именно это я и хотел предложить)

А все потому, что приляпывали деление, когда вся основная структура процессора уже была сформирована.
Нет проверки V? Не беда, проверим через Z.
Нет блока обнуления N и Z. Тоже ерунда, занулим через константу. Нет констатны? Возьмем из блока прерываний. CPSW не обновится... тогда принудительно обновим CPSW. А... тогда в HALT-режиме с запрещенными прерываниями испортится CPSW. Да, плевать, кто заметит)

MiX
05.12.2020, 18:35
В пультовом отладчике.
R7/000000

Alex_K
05.12.2020, 19:18
Да, именно это я и хотел предложить)
Ну что ж, диагноз товарища Саахова полностью подтвердился.
Сама программа, запускается с RS=600 (HALT с запрещёнными прерываниями):


1000 012700 MOV #777,R0
1002 000777
1004 000034 WCPS
1006 012703 MOV #1,R3
1010 000001
1012 005000 CLR R0
1014 071303 DIV R3,R3
1016 000024 RCPS
1020 106701 MFPS R1
1022 000000 HALT

При значении R3=1 происходит переполнение, а при R3=0 - деление на ноль. Если R3=0177777, то операция завершается нормально. При переполнении и делении на ноль CPSW изменяется, при нормальном завершении остаётся неизменным.

- - - Добавлено - - -


R7/000000
А на каком тесте?

- - - Добавлено - - -


1. На проверку флага V в PLM проверки условий (PLM_BRA), видимо, уже не хватало места, и проверку флага V сделали через проверку флага Z (PSW & 0x02).
А вот с этим я не согласен. Используется четыре флага - NZVC.
N = 0x08, 010
Z = 0x04, 004
V = 0x02, 002
C = 0x01, 001
Так что проверяют именно флаг переполнения V, и флаг Z тут вообще не при чём.

Titus
05.12.2020, 19:41
А вот с этим я не согласен. Используется четыре флага - NZVC.
N = 0x08, 010
Z = 0x04, 004
V = 0x02, 002
C = 0x01, 001
Так что проверяют именно флаг переполнения V, и флаг Z тут вообще не при чём.

Да нет, не в том дело.
Чтобы проверить флаг V, делается ACC=PSW&0x02.
Затем уже по результату этой операции устанавливается или не устанавливается флаг Z. На регистр PSW это никак не влияет, потому что результат в PSW обратно не копируется.
А потом уже по этому флагу Z принимается решение, туда идем, или сюда.
Просто в матрице PLM_BRA нет комбинаций, позволяющих проверить отдельно флаг V. Но есть комбинации, позволяющие проверить флаг Z. Поэтому и едет поезд в Киев через Магадан.

Alex_K
05.12.2020, 19:49
Просто в матрице PLM_BRA нет комбинаций, позволяющих проверить отдельно флаг V. Но есть комбинации, позволяющие проверить флаг Z. Поэтому и едет поезд в Киев через Магадан.
Так при копировании в аккумулятор могут только установится флаги N и Z. Да и то, как я понимаю, флаги временные, вне PSW.

Titus
05.12.2020, 19:54
Так при копировании в аккумулятор могут только установится флаги N и Z. Да и то, как я понимаю, флаги временные, вне PSW.
Правильно. Что тут противоречит моему описанию? )
Еще раз на пальцах.
В регистре PSW имеем установленный бит V. T.e. 0x0002.
Делаем ACC = PSW & 0x0002.
Если в результате ACC = 0 (бит V не был установлен в регистре PSW), то устанавливается флаг Z.
Если в результате ACC = 2 (бит V был установлен в регистре PSW), то флаг Z обнуляется.

Alex_K
05.12.2020, 19:59
Правильно. Что тут противоречит моему описанию? )
Так если при копировании в аккумулятор не устанавливается флаг V, то вышли как могли. А почему нет комбинаций, которые проверяют флаг V, вон условных переходов BRx целая куча?

Titus
05.12.2020, 20:06
Так если при копировании в аккумулятор не устанавливается флаг V, то вышли как могли. А почему нет комбинаций, которые проверяют флаг V, вон условных переходов BRx целая куча?
Флаг V и не должен устанавливаться. Устанавливается флаг Z по которому определяется, был ли установлен флаг V.

Видимо, потому что сначала закодировали матрицу PLM_BRA, а потом оказалось, что расширенной арифметике этого не хватает.
Для команды SOB была написана проверка флага Z. Ей и воспользовались.

Напомню:


NA4 = 1, NA5 = 1: // Для команды выборки инструкции 0x01


0.000.x00.1xx BR
0.000.xx1.1xx Z=1 BEQ, BLE
x.000.x01.1xx Z=1 BEQ, BLOS
1.000.x11.0xx C=0 BCC
1.000.xx1.1xx C=1 BCS, BLOS
1.000.x00.0xx N=0 BPL
1.000.x00.1xx N=1 BMI
1.000.x10.0xx V=0 BVC
1.000.x10.1xx V=1 BVS
0.000.x10.0xx V=1,N=1 BGE
0.000.x10.0xx V=0,N=0 BGE
0.000.x1x.1xx V=1,N=0 BLT, BLE
0.000.x1x.1xx V=0,N=1 BLT, BLE


NA4 = 1: // Для команды выборки инструкции 0x01 и других(?)
// Проверка NA5=1 упразднена, т.к. пересечение с командой SOB тоже проверяет Z=0

0.000.x01.0xx Z=0, BNE
1.000.x01.0xx C=0,Z=0 BHI
0.000.x11.0xx V=1,Z=0,N=1 BGT
0.000.x1x.0xx V=0,Z=0,N=0 BGT, BGE


NA4 = 0, NA5 = 1: // RTI, RTT

BIT_13 & BIT_14 & BIT_15 = 1


NA4 = 1, NA5 = 0: // Для команды SOB, DIV

Z=0


NA4 = 0, NA5 = 0: // Для команды CODE030, FIS?

N=0

MiX
05.12.2020, 21:25
А на каком тесте?
В этом. (https://zx-pk.ru/threads/30964-revers-inzhiniring-uknts-(1515khm1-amp-2-1801vp1-1801vm2).html?p=1092443&viewfull=1#post1092443)

Alex_K
05.12.2020, 21:45
В этом. (https://zx-pk.ru/threads/30964-revers-inzhiniring-uknts-(1515khm1-amp-2-1801vp1-1801vm2).html?p=1092443&viewfull=1#post1092443)
Тут надо ещё смотреть значение R6 до выполнения и после выполнения, желательно настроить вектор 4, чтобы узнать, был ли TRAP4.

- - - Добавлено - - -


В этом. (https://zx-pk.ru/threads/30964-revers-inzhiniring-uknts-(1515khm1-amp-2-1801vp1-1801vm2).html?p=1092443&viewfull=1#post1092443)
Начинать желательно с этого (https://zx-pk.ru/threads/30964-revers-inzhiniring-uknts-(1515khm1-amp-2-1801vp1-1801vm2).html?p=1091953&viewfull=1#post1091953).

MiX
05.12.2020, 22:30
ут надо ещё смотреть значение R6 до выполнения и после выполнения, желательно настроить вектор 4, чтобы узнать, был ли TRAP4.
Напишите как надо всё по порядку.

Alex_K
05.12.2020, 23:18
Напишите как надо всё по порядку.
А можно получить доступ по Telnet?

MiX
06.12.2020, 00:34
А можно получить доступ по Telnet?
Можно, но только настроить нужно. А ещё вспомнить как настроить.
Сейчас другой роутер стоит, и есть ли там DMZ пока не проверял.

Hunta
06.12.2020, 10:49
А можно получить доступ по Telnet?
1201.02 пойдёт? :):)

Alex_K
06.12.2020, 10:52
1201.02 пойдёт? :):)
Он то как раз и нужен, но с 1806ВМ2 на борту. 1801ВМ2 я имею в своих УКНЦ, так что протестировать могу. А MiX ставил в свою МС1201.02 именно 1806ВМ2.

Hunta
06.12.2020, 11:46
Нуу.... Где то у меня был 1806вм2 на переходнике.. и вроде была плата с процом в панельке... Чуть позже гляну и отпишусь

- - - Добавлено - - -

Облом.. Единственная плата с процом на панельке - не рабочая...

svinka
06.12.2020, 11:47
1801вм3 проверьте
небось тоже глюкалово

Hunta
06.12.2020, 11:56
Алкоголики ВМ3 не делали



***** ДОСТУПНОЕ ОЗУ - 3,7 M*
@ 001000
@1000/000000 5000
00001002/000000 12703
00001004/000000 2
00001006/000000 70703
00001010/000000 5200
@1000G
@ 002022
@$0/000000

Alex_K
06.12.2020, 11:59
Алкоголики ВМ3 не делали
Но зато исполнение EIS у ВМ3 и ВМ2 отличается. Где-то было в теме про тесты, но очень долго искать. Была какая-то разница или в установке флагов, или в результате.

svinka
06.12.2020, 12:00
кстати 1801вм2 с ромбом никто не видел? фото нет ни у кого?
скорее всего он не прошел приемку...
или его не заказывали трезвенники???

Vslav
06.12.2020, 13:15
Он то как раз и нужен, но с 1806ВМ2 на борту.
Я вижу, раз есть интерес к 1806 надо замутить переходник для него на плату DE0, чтобы тестировать процессор можно было.

Alex_K
06.12.2020, 13:27
Я вижу, раз есть интерес к 1806 надо замутить переходник для него на плату DE0, чтобы тестировать процессор можно было.
Неплохо было бы. Можно узнать какие глюки починили, а какие остались. Глюка с адресацией @PC уже нет, код 030 исполняется как 020 (RSEL). Возможно уже нет глюка при записи по адресу предвыборки, если адрес записи и PC отличаются разным значением бита 0 (чёт и нечёт). Вот про глюки с записью R7 в EIS и записью CPSW при переполнении в DIV до этого было неизвестно, вскрылось только сейчас.

Titus
06.12.2020, 14:32
Ну, и финальная вишенка на торте команд расширенной арифметики - это 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-битными словами.

Alex_K
06.12.2020, 14:43
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



Как-то непонятно, в первой итерации сдвиги в одну сторону, в последующие - в другую.

Titus
06.12.2020, 14:46
Как-то непонятно, в первой итерации сдвиги в одну сторону, в последующие - в другую.
Исправил.

Alex_K
06.12.2020, 14:49
// Если ASH(C) RIGHT, то V=0
// Если ASH(C) LEFT, то для первой итерации V=0
иначе V=TLZ^~EA1[15]
Тут такое дело, если во время сдвига произошло изменение знакового разряда, то флаг V устанавливается постоянно. Естественно возможно только при сдвиге влево.

Titus
06.12.2020, 14:52
Тут такое дело, если во время сдвига произошло изменение знакового разряда, то флаг V устанавливается постоянно. Естественно возможно только при сдвиге влево.
Ну да, а в чем противоречие?
Флаги устанавливаются заново во время каждой итерации.

Alex_K
06.12.2020, 14:56
Ну да, а в чем противоречие?
Флаги устанавливаются заново во время каждой итерации.
Значение 0100 0000 0000 0000 сдвигаю влево на три разряда. При первом сдвиге фиксируется изменение знака, результат 1000 0000 0000 0000. При втором сдвиге фиксируется изменение знака, результат 0000 0000 0000 0000. При третьем сдвиге изменения знака нет, но флаг V должен стоять.

Titus
06.12.2020, 15:01
При третьем сдвиге изменения знака нет, но флаг V должен стоять.
А стоит ли он в реале? )

- - - Добавлено - - -

Точно, там стоит RS-триггер. И V один раз установившись, больше не сбрасывается.

- - - Добавлено - - -

Исправил.

Alex_K
06.12.2020, 15:11
А стоит ли он в реале? )
Проверил на реале.


1000 012701 MOV #40000,R1
1002 040000
1004 012700 MOV #3,R0
1006 000003
1010 072100 ASH R0,R1
1012 106702 MFPS R2

После исполнения установлены биты Z и V.

- - - Добавлено - - -


Точно, там стоит RS-триггер. И V один раз установившись, больше не сбрасывается.
А не влияет ли наличие RS-триггера на исполнение других команд EIS?

Titus
06.12.2020, 15:15
А не влияет ли наличие RS-триггера на исполнение других команд EIS?
Нет, не влияет. Он стоит только в цепи отвечающей за сдвиг влево в расширенной арифметике.
В первой итерации он всегда сбрасывается, а в остальных устанавливается, если была смена знака.

Titus
09.12.2020, 22:22
Двухоперандные команды с регистром источником формата ALU Rs,dd.

В эту же группу входят команды расширенной арифметики формата EALU Rd,ss.

MOV(B), BIS(B), BIC(B), ADD, SUB, CMP(B), BIT(B), XOR,
MUL, DIV, ASH, ASHC:

//================================================== ====================
//
// Oперации с двумя операндами вида Rs,nn
//
// MOV(B), BIS(B), BIC(B), ADD, SUB, CMP(B), BIT(B),
// XOR, MUL, DIV, ASH, ASHC
//
// step=1 для байтовых команд, если dd<>R6 и dd<>R7
// step=2 для всх остальных команд
//
// Циклы шины IO_X001 для:
//
// CMP(B), BIT(B), MUL, DIV, ASH, ASHC
// Read (IO_RD, IO_IN) - Инициировать цикл чтения шины в регистр BRD
//
// MOV:
// Write (IO_WR) - Инициировать цикл записи BRD на шину
//
// MOVB, BIS(B), BIC(B), ADD, SUB, XOR:
// R-M-W (IO_RD, IO_WR, IO_IN) - Инициировать цикл чтения шины в регистр BRD
// с последующим циклом записи по готовности BRD
//
//================================================== ====================
0x2B: RS=Rs
//----------------------------------------------------------------------
0x17: if (Rn) RA=Rn IO_X001 // Инициировать цикл шины
Rn=Rn
GOTO 0x33

if (Rn)+ and (RI0=0) // Если Rn<>R7
RA=Rn IO_X001 // Инициировать цикл шины
Rn=Rn+step
GOTO 0x33

if (Rn)+ and (RI0=1) and (IX0=1) // Если Rn=R7, и работа со словом
PC1=PC2 DISABLE_CACHE // Запретить кэш и включить режим использования BIR как данных
// Фактически PC1=PC1+2
BRD=BIR IO_X001 // Подготовить, но не начинать цикл шины
GOTO 0x33

if (Rn)+ and (RI0=1) and (IX0=0) // Если Rn=R7, и работа с байтом
PC1=PC2 DISABLE_CACHE // Запретить кэш и включить режим использования BIR как данных
// Фактически PC1=PC1+2
RA=PC1-2 IO_X001 // Инициировать цикл шины
GOTO 0x33

if -(Rn) Rn=Rn-step
RA=Rn IO_X001 // Инициировать цикл шины
GOTO 0x33

if @-(Rn) Rn=Rn-2
RA=Rn IO_RD, IO_IN // Инициировать цикл чтения шины в регистр BRD
GOTO 0x22

if @(Rn)+ and (RI0=0) // Если Rn<>R7
Rn=Rn+2
RA=Rn IO_RD, IO_IN // Инициировать цикл чтения шины в регистр BRD
GOTO 0x22

if @(Rn)+ and (RI0=1) // Если Rn=R7
PC1=PC2 DISABLE_CACHE // Запретить кэш и включить режим использования BIR как данных
// Фактически PC1=PC1+2
RA=BIR IO_X001 // Инициировать цикл шины
GOTO 0x33

if X(Rn) PC1=PC2 DISABLE_CACHE // Запретить кэш и включить режим использования BIR как данных
RA=Rn+BIR IO_X001 // Инициировать цикл шины
GOTO 0x33

if @X(Rn) PC1=PC2 DISABLE_CACHE // Запретить кэш и включить режим использования BIR как данных
RA=Rn+BIR IO_RD, IO_IN // Инициировать цикл чтения шины в регистр BRD

//---------------------------------------------------------------------- Прочитана ячейка с адресом операнда
0x22: PC1=PC2 DISABLE_CACHE // Запретить кэш и включить режим использования BIR как данных
WAIT_BRD // Ожидание готовности чтения BRD
RA=BRD IO_X001 // Инициировать цикл шины
ENABLE_CACHE // Разрешить кэш

//---------------------------------------------------------------------- Операнд прочитан из памяти, если цикл шины Read или RMW
0x33: WAIT_BRD // Ожидание готовности чтения BRD
if MUL,DIV,ASH(C)
ACC=BRD
if MUL GOTO 0x18 // Если MUL, то перейти на шаг 0x18 микропрограммы выполнения умножения
if DIV GOTO 0x1A // Если DIV, то перейти на шаг 0x1A микропрограммы выполнения деления
if ASH(C) GOTO 0x1A // Если ASH(C), то перейти на шаг 0x1A микропрограммы выполнения циклического сдвига

ALU RS,BRD // Операции ALU из шага 0x3B, в качестве приемника BRD, в качестве источника RS

// Если используется цикл записи Write или RMW, то по записи в BRD, продолжается цикл записи
ENABLE_CACHE // Разрешить кэш
PLI_REQ // Запросить проверку запросов на прерывание
if X(Rn) or @X(Rn) or (Rn=R7) // Если использовали адресацию по R7, то
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции
else // Иначе
GOTO 0x01 // Перейти на команду выборки следующей инструкции

Alex_K
09.12.2020, 23:00
Двухоперандные команды с регистром источником формата ALU Rs,dd.
Остались двухоперандные команды вида ALU ss,dd?

Titus
09.12.2020, 23:02
Остались двухоперандные команды вида ALU ss,dd?
Да, только они.

Vslav
09.12.2020, 23:45
Кстати, а слабо исходники микрокода 1801 сгенерить? А потом собрать своим метаассемблером?
Меня это интересует давно, я не понимал как это сделано. Сейчас, по итогам М4, у меня соображения появились, что микрокод для серии 1801 писался с гораздо более широким выходным словом, на которое навесили нужные мультиплексоры и согласователи для стыковки с АЛУ и потом это все оптимизировали в матрицу машинным способом. Потому что разобрать и проанализировать матрицу - это еще понять можно, но синтез руками - сделать сложно. Так что вероятность процентов 90 что так и было. На момент разработки 1801 метассмеблеры уже были, секционники вовсю проектировались, оптимизировать тоже понятно как, так что это именно оно - недостающее звено. Надо Отрохова и Подорова поспрашивать, как оно реально было.

Titus
10.12.2020, 00:15
Кстати, а слабо исходники микрокода 1801 сгенерить? А потом собрать своим метаассемблером?
Не слабо, но для этого надо реверсить ВМ1.
А с меня уже и ВМ2 достаточно пока что. Это вам не бином Ньютона)

Vslav
10.12.2020, 00:20
Не слабо, но для этого надо реверсить ВМ1.
Зачем? Можно и ВМ2, он предположительно точно по тому же маршруту делался.

Titus
10.12.2020, 00:22
Зачем? Можно и ВМ2, он предположительно точно по тому же маршруту делался.
Тогда я не понимаю, что означает 'сгенерить исходники'.
Я и так расписал практически весь микрокод в самом, что ни на есть, понятном виде.

Vslav
10.12.2020, 00:29
Тогда я не понимаю, что означает 'сгенерить исходники'.
Я и так расписал практически весь микрокод в самом, что ни на есть, понятном виде.
Ну что такое ассемблерный исходник представляешь? А что такое ассемблер? Тут то же самое, написать микрокод, в виде исходника, как я сделал для М4, и написать компилятор, на выходе получить сгенерированное состояние перемычек матрицы - P и SoP.

Titus
10.12.2020, 00:34
Ну что такое ассемблерный исходник представляешь? А что такое ассемблер? Тут то же самое, написать микрокод, в виде исходника, как я сделал для М4, и написать компилятор, на выходе получить сгенерированное состояние перемычек матрицы - P и SoP.
Это лишняя работа. Зачем, если и так все уже расшифровано.
Я и это-то хочу поскорее закончить, ибо надоело уже)

Vslav
10.12.2020, 00:43
Это лишняя работа.
Тю, я думал тебе оно интересно, ты же вон код вручную разбирал - это как пруд чайной ложкой копать :).

Зачем, если и так все уже расшифровано.
Не, компилируемый исходник это исходник - можно вносить серьезные изменения и дополнения.
Да и вдруг удастся переоптимизировать. Хотя вряд ли, алгоритмам оптимизации типа карт Карно в обед тыщу лет.

Titus
10.12.2020, 00:55
Тю, я думал тебе оно интересно, ты же вон код вручную разбирал - это как пруд чайной ложкой копать .
У меня интерес исключительно практический - понять в точности, как все работает, чтобы если захочется сделать точный эмулятор. А может и не захочется. У нас УКНЦ-шников на форуме все меньше и меньше. К тому времени, пока его напишешь, и оставшиеся 3 человека пропадут)

- - - Добавлено - - -


Не, компилируемый исходник это исходник - можно вносить серьезные изменения и дополнения.
Для понимания принципа работы, изменения вносить не нужно.
Да и зачем изменения? Микрокод в высшей степени оптимален. А исправлять ошибки в нем - нет смысла, ибо потеряется совместимость с оригиналом.

Vslav
10.12.2020, 00:58
Для понимания принципа работы, изменения вносить не нужно.

Неа, высшая степень понимания - это когда ты можешь что-то поменять. Вот только когда предпринимаешь попытку изменения - тогда и понимаешь что ничего не понимаешь.

Titus
10.12.2020, 01:12
Неа, высшая степень понимания - это когда ты можешь что-то поменять. Вот только когда предпринимаешь попытку изменения - тогда и понимаешь что ничего не понимаешь.
Для каждого свое)
В том, что я разобрал, я вполне себе все понимаю)

Titus
10.12.2020, 19:20
И, наконец, финальная вишенка на торте описания микрокода ВМ2 - это команды с двумя операндами, расположенными в памяти.


MOV(B), BIS(B), BIC(B), ADD, SUB, CMP(B), BIT(B):

//================================================== ====================
//
// Oперации с двумя операндами вида ss,dd
//
// MOV(B), BIS(B), BIC(B), ADD, SUB, CMP(B), BIT(B)
//
// step=1 для байтовых команд, если dd<>R6 и dd<>R7
// step=2 для всх остальных команд
//
// RI2=1, если адресация ss: (R7), (R7)+, -(R7), @(R7)+, @-(R7), X(Rn), @X(Rn)
//
// Циклы шины IO_X001 для:
//
// CMP(B), BIT(B)
// Read (IO_RD, IO_IN) - Инициировать цикл чтения шины в регистр BRD
//
// MOV:
// Write (IO_WR) - Инициировать цикл записи BRD на шину
//
// MOVB, BIS(B), BIC(B), ADD, SUB:
// R-M-W (IO_RD, IO_WR, IO_IN) - Инициировать цикл чтения шины в регистр BRD
// с последующим циклом записи по готовности BRD
//
//================================================== ====================
0x0F: if (Rn) RA=Rs IO_RD, IO_IN // Инициировать цикл чтения шины
Rs=Rs

if (Rn)+ and (IX1=0) // Если Rn<>R7
RA=Rs
Rs=Rs+step

if (Rn)+ and (IX1=1) and (IX0=1) // Если Rn=R7, и работа со словом
PC1=PC2 DISABLE_CACHE // Запретить кэш и включить режим использования BIR как данных
// Фактически PC1=PC1+2
ACC=Rs // Пустая операция
// Чтение BRD не инициируется, т.к. в нем уже и так находится требуемое слово

if (Rn)+ and (IX1=1) and (IX0=0) // Если Rn=R7, и работа с байтом
PC1=PC2 DISABLE_CACHE // Запретить кэш и включить режим использования BIR как данных
// Фактически PC1=PC1+2
ACC=PC1-2 // ACC=PC1-2 (коррекция, т.к. PC1 опережает реальное значение R7 на 2)
RA=ACC IO_RD, IO_IN // Инициировать цикл чтения шины

if -(Rn) Rs=Rs-step
RA=Rs IO_RD, IO_IN // Инициировать цикл чтения шины

if @(Rn)+ and (IX1=0) // Если Rn<>R7
RA=Rs IO_RD, IO_IN // Инициировать цикл чтения шины
Rs=Rs+2
GOTO 0x32

if @(Rn)+ and (IX1=1) // Если Rn=R7
WAIT_BRD // Ожидание готовности чтения BRD (на самом деле BIR)
PC1=PC2 DISABLE_CACHE // Запретить кэш и включить режим использования BIR как данных
// Фактически PC1=PC1+2
ACC=BIR
RA=ACC IO_RD, IO_IN // Инициировать цикл чтения шины

if @-(Rn) Rs=Rs-2
RA=Rs IO_RD, IO_IN // Инициировать цикл чтения шины
GOTO 0x32

if X(Rn) WAIT_BRD // Ожидание готовности чтения BRD (на самом деле BIR)
PC1=PC2 DISABLE_CACHE // Запретить кэш и включить режим использования BIR как данных
ACC=Rs+BIR
RA=ACC IO_RD, IO_IN // Инициировать цикл чтения шины

if @X(Rn) WAIT_BRD // Ожидание готовности чтения BRD (на самом деле BIR)
PC1=PC2 DISABLE_CACHE // Запретить кэш и включить режим использования BIR как данных
ACC=Rs+BIR
RA=ACC
GOTO 0x32

if (dd=Rn) and (RI2=0) // Если приемник - регистр и ss не использует R7
GOTO 0x13
if (dd=Rn) and (RI2=1) // Если приемник - регистр и ss использует R7
GOTO 0x12
else GOTO 0x03 // Иначе приемник - память

//---------------------------------------------------------------------- Чтение операнда из памяти
0x32: WAIT_BRD // Ожидание готовности чтения BRD
ACC=BRD
RA=ACC IO_RD, IO_IN // Инициировать цикл чтения шины

if (dd=Rn) and (RI2=0) // Если приемник - регистр и ss не использует R7
GOTO 0x13
if (dd=Rn) and (RI2=1) // Если приемник - регистр и ss использует R7
GOTO 0x12
else GOTO 0x03 // Иначе приемник - память

//---------------------------------------------------------------------- Приемник - регистр, ss использует R7
0x12: WAIT_BRD // Ожидание готовности чтения BRD
RS=BRD
//---------------------------------------------------------------------- Кэширование следующей команды
0x10:
RA=PC2 IO_RD, IO_IN, IO_RCD // Инициировать цикл чтения шины в регистр BIR и BRD одновременно (кеширование следующей команды/данных)
PC1=PC2 // Фактически имитация PC1=PC+2
PC2=PC2+2

//---------------------------------------------------------------------- Приемник - регистр
0x13:
if (RI2=0) WAIT_BRD // Если ss не использует R7, то oжидание готовности чтения BRD
ALU BRD,Rd // Операции ALU из шага 0x3B, в качестве приемника Rd, в качестве источника BRD
else // Иначе ss использует R7
ALU RS,Rd // Операции ALU из шага 0x3B, в качестве приемника Rd, в качестве источника RS
endif
PLI_REQ // Запросить проверку запросов на прерывание
if (Rd=R7) // Если Rd=R7, то
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции
else // Иначе
GOTO 0x01 // Перейти на команду выборки следующей инструкции


//---------------------------------------------------------------------- Приемник - память
0x03: WAIT_BRD // Ожидание готовности чтения BRD
RS=BRD
if (RI2=0) GOTO 0x17 // Если ss не использует R7, то перейти на шаг 0x17 операции с двумя операндами

//---------------------------------------------------------------------- ss использует R7
0x16: // Кэширование следующей команды (для того, чтобы адресация dd по R7 работала корректно)
RA=PC2 IO_RD, IO_IN, IO_RCD // Инициировать цикл чтения шины в регистр BIR и BRD одновременно (кеширование следующей команды/данных)
PC1=PC2 // Фактически имитация PC1=PC+2
PC2=PC2+2

GOTO 0x17 // Перейти на шаг 0x17 операции с двумя операндами
//----------------------------------------------------------------------


Больше в микрокоде ничего нет, так что на этом, это самое, мои полномочия всё... закончены)

https://www.youtube.com/watch?v=GM4gSoRnbvg

Alex_K
10.12.2020, 19:38
Больше в микрокоде ничего нет, так что на этом, это самое, мои полномочия всё... закончены)
А где глюк с @PC?

Titus
10.12.2020, 19:39
А где глюк с @PC?
У меня нет ссылки на этот тест.

Alex_K
10.12.2020, 19:55
У меня нет ссылки на этот тест.
Titus, вы же сами об этом спрашивали полмесяца назад - здесь (https://zx-pk.ru/threads/30964-revers-inzhiniring-uknts-(1515khm1-amp-2-1801vp1-1801vm2)/page144.html).

Titus
10.12.2020, 19:58
Titus, вы же сами об этом спрашивали полмесяца назад - здесь.
По ссылке я увидел только этот (https://zx-pk.ru/threads/23978-tsifrovaya-arkheologiya-1801-i-vse-vse-vse.html?p=999094&viewfull=1#post999094) тест, но он тестирует компаратор адреса.

Alex_K
10.12.2020, 20:16
По ссылке я увидел только этот (https://zx-pk.ru/threads/23978-tsifrovaya-arkheologiya-1801-i-vse-vse-vse.html?p=999094&viewfull=1#post999094) тест, но он тестирует компаратор адреса.
Читать надо внимательно, там ссылка на страницу с тестами - здесь (https://zx-pk.ru/threads/14702-raschjot-tochnogo-vremeni-vypolneniya-komand-razlichnymi-protsessorami-arkhitektury-pdp-11/page19.html). Там много чего есть.

- - - Добавлено - - -

А вот и конкретные тесты (https://zx-pk.ru/threads/14702-raschjot-tochnogo-vremeni-vypolneniya-komand-razlichnymi-protsessorami-arkhitektury-pdp-11/page24.html).

Titus
10.12.2020, 20:25
А вот и конкретные тесты.
Я так понял, что описание глюка здесь (https://zx-pk.ru/threads/14702-raschjot-tochnogo-vremeni-vypolneniya-komand-razlichnymi-protsessorami-arkhitektury-pdp-11.html?p=581167&viewfull=1#post581167).

Vslav
10.12.2020, 20:26
Вот тут (https://github.com/1801BM1/cpu11/blob/master/vm2/tst/pcbug.mac) у меня полный набор тестов для предвыборки ВМ2, включая "суперглюк" с его описанием.

Titus
10.12.2020, 22:49
Вот тут у меня полный набор тестов для предвыборки ВМ2, включая "суперглюк" с его описанием.
Непонятны точные причины и накладки.
Вроде бы на первый взгляд на микрокод накладки быть не может.
Нужно два графика на асинхронной модели. На одной с быстрой памятью, на другой с медленной, чтобы точно сказать.

Alex_K
13.12.2020, 15:18
Больше в микрокоде ничего нет, так что на этом, это самое, мои полномочия всё... закончены)
Кстати, вроде не встречались следующие адреса: 02,06,07,0A,OB,14,15,1B,24,29,30,3A,3F.

И не обнаружил (может где-то пропустил) исполнение команд JMP и JSR с регистровой адресацией, должен быть TRAP4.

Titus
13.12.2020, 16:40
И не обнаружил (может где-то пропустил) исполнение команд JMP и JSR с регистровой адресацией, должен быть TRAP4.
Действительно, забыл описать.

JMP Rn, JSR Rs,Rd:

//================================================== ====================
//
// Команды JMP Rn, JSR Rs,Rd
//
//================================================== ====================

0x30: NO ALU PI_STB VEC=0x04 RI=100 // Управление: запрос программного прерывания по вектору 0x04 в режиме USER
GOTO 0x01 // Перейти на команду выборки следующей инструкции

Alex_K
13.12.2020, 17:08
Действительно, забыл описать.
Спасибо! Так что остаётся по адресам 02,06,07,0A,OB,14,15,1B,24,29,3A,3F?

Titus
13.12.2020, 17:57
0x02 - дублирует шаг 0x03
0x06 - не используется
0x07 - это TRAP10_7, TRAP10_40, TRAP10_6500, TRAP10_6600
0x0A - не используется
0x0B - не используется
0x14 - отсутствует
0x15 - отсутствует
0x1B - дублирует шаг 0x3B
0x24 - отсутствует
0x29 - дублирует шаг 0x09
0x3A - не используется
0x3F - не используется

Замечу, что просьба к Vslav'у о диаграммах из предпредыущего поста (https://zx-pk.ru/threads/30964-revers-inzhiniring-uknts-(1515khm1-amp-2-1801vp1-1801vm2).html?p=1093487&viewfull=1#post1093487) все еще в силе)

Alex_K
13.12.2020, 18:14
0x07 - это TRAP10_7, TRAP10_40, TRAP10_6500, TRAP10_6600
Но по описанию они были на адресе 0x05. А где TRAP10_0000210, TRAP10_070000,TRAP10_075040,TRAP10_1065000,TRAP10_ 107000,TRAP10_170000?

Titus
13.12.2020, 18:26
Но по описанию они были на адресе 0x05.
На шаге 0x07 та же самая команда, что и на 0x05, поэтому я обьединил в одну.

- - - Добавлено - - -


А где TRAP10_0000210, TRAP10_070000,TRAP10_075040,TRAP10_1065000,TRAP10_ 107000,TRAP10_170000?
Ну и размахнулись вы с нулями)
Похоже, я про эти трапы просто забыл)

Titus
13.12.2020, 20:34
А где TRAP10_0000210, TRAP10_070000,TRAP10_075040,TRAP10_1065000,TRAP10_ 107000,TRAP10_170000?

Еще раз сгенерил базовую таблицу преддекодера и не нашел в ней ни одной записи совпадающей с 0xF000 (TRAP 170000):


Instruction NA ___ MOP
FEDCBA9876543210 543210 01 RTT BYTE IX2

00: 0000000000000110 000000 00 1 RTT
12: 000000001.000... 110000 00 1 RTS, SWAB Rn
34: 00000000.1...... 010000 00 1 JMP, SWAB
36: .000110111...... 010000 00 1 SXT, MFPS
30: 1000110100...... 010000 01 1 MTPS
37: 0000100......... 010000 11 1 JSR
33: .0001100........ 010000 00 1 ROR(B), ROL(B), ASR(B), ASL(B)
42: .000101......... 010000 00 1 CLR(B), COM(B), INC(B), DEC(B), NEG(B), ADC(B), SBC(B), TST(B)
32: .0000..00....... 000000 11 HALT, WAIT, RTI, BPT, IOT, RESET, RTT, TRAP10_7, START, STEP, RSEL, MFUS, RCPC, RCPS, CODE30, MTUS, WCPC, WCPS, TRAP10_40, JMP, BNE(!), BGE(!), BGT(!), BPL(!), BHI(!), BVC(!), BCC(!)
13: 0000.0.000...... 000000 10 HALT, WAIT, RTI, BPT, IOT, RESET, RTT, TRAP10_7, START, STEP, RSEL, MFUS, RCPC, RCPS, CODE30, MTUS, WCPC, WCPS, TRAP10_40, BNE(!), JSR(!), CLR
26: 0001............ 000000 10 MOV
28: 0000..01........ 000000 10 BR, BLT, MARK, TRAP10_6500, TRAP10_6600, SXT
16: .000101111...... 000000 01 TST(B)
47: .01............. 001000 01 CMP(B), BIT(B)
43: 01110........... 101100 01 MUL, DIV, ASH, ASHC
01: 1000110100000... 100000 00 MTPS Rn
08: .000110111000... 100000 00 SXT Rn, MFPS Rn
11: .0001100..000... 100000 00 ROR(B) Rn, ROL(B) Rn, ASR(B) Rn, ASL(B) Rn
25: .000101...000... 100000 00 CLR(B) Rn, COM(B) Rn, INC(B) Rn, DEC(B) Rn, NEG(B) Rn, ADC(B) Rn, SBC(B) Rn, TST(B) Rn
06: 0111100...000... 010000 00 XOR Rs,Rd
04: 01110.....000... 010000 00 MUL Rs,Rd, DIV Rs,Rd, ASH Rs,Rd, ASHC Rs,Rd
09: .0.1000...000... 010000 00 MOV(B) Rs,Rd, BIT(B) Rs,Rd
14: .10.000...000... 010000 00 BIC(B) Rs,Rd, BIS(B) Rs,Rd
23: ..10000...000... 010000 00 CMP(B) Rs,Rd, ADD Rs,Rd, SUB Rs,Rd
15: 0000000000000011 000010 00 BPT
17: 0000000000000.01 000010 00 WAIT, RESET
10: 0000000000001... 000010 00 START, STEP
03: 000000000001.... 000010 00 RSEL, MFUS, RCPC, RCPS, CODE30, MTUS, WCPC, WCPS
02: 0000110100...... 000010 00 MARK
07: 01111010000..... 000010 00 FIS
05: 00000000101..... 000010 00 CLx, SEx
45: ..01............ 001000 00 MOV(B), BIS(B)
46: .1.0............ 001000 00 BIC(B), ADD, SUB
21: .0000..0000....0 000010 00 HALT, RTI, IOT, RTT, START(!), STEP(!), RSEL, RCPC(!), RCPS(!), CODE30, WCPC(!), WCPS(!), BNE(!), BGE(!), BGT(!), BPL(!), BHI(!), BVC(!), BCC(!)
18: 10000000........ 000001 00 BPL
24: 1000.00......... 000010 00 BPL, BMI, EMT, TRAP
22: .0000001........ 000011 00 BR, BMI
29: .000001......... 000011 00 BNE, BEQ, BHI, BLOS
31: .00001.......... 000011 00 BGE, BLT, BGT, BLE, BVC, BVS, BCC, BCS
19: 0000100...000... 100111 00 JSR Rs,Rd
20: 0000000001000... 100111 00 JMP Rn
27: 0111111......... 001010 00 SOB
39: 0111100......... 101100 00 XOR
35: .10.000......... 100100 00 BIC(B) Rs,dd, BIS(B) Rs,dd
40: .0.1000......... 100100 00 MOV(B) Rs,dd, BIT(B) Rs,dd
41: ..10000......... 100100 00 CMP(B) Rs,dd, ADD Rs,dd, SUB Rs,dd
38: 1.0............. 000000 00 1 BPL, BMI, BHI, BLOS, BVC, BVS, BCC, BCS, EMT, TRAP, MTPS, TRAP10_106500, TRAP10_106600, MFPS, TRAP10_107000
44: 10.............. 000000 00 1 BPL, BMI, BHI, BLOS, BVC, BVS, BCC, BCS, EMT, TRAP, MTPS, TRAP10_106500, TRAP10_106600, MFPS, TRAP10_107000

Alex_K
13.12.2020, 21:05
Еще раз сгенерил базовую таблицу преддекодера и не нашел в ней ни одной записи совпадающей с 0xF000 (TRAP 170000):
Ну и что процессор будет делать в этом случае?

Titus
13.12.2020, 21:12
Ну и что процессор будет делать в этом случае?

Пойдет по адресу по умолчанию, а именно по адресу 0x07.

Alex_K
13.12.2020, 21:15
Пойдет по адресу по умолчанию, а именно по адресу 0x07.
А там TRAP10? В адресе последние три бита инвертированы?

Titus
13.12.2020, 21:24
А там TRAP10? В адресе последние три бита инвертированы?
Да, поэтому адресу тусуются остальные трапы: TRAP10_6500, TRAP10_6600, TRAP10_7, TRAP10_40.

- - - Добавлено - - -

Остаются два бесхозных трапа 210 и 75040.

- - - Добавлено - - -

Я думаю, они идут по тому же адресу, т.к. преддекодер их не выделяет. Стало быть все трапы обрабатываются едино.

Vslav
13.12.2020, 21:35
Замечу, что просьба к Vslav'у о диаграммах из предпредыущего поста (https://zx-pk.ru/threads/30964-revers-inzhiniring-uknts-(1515khm1-amp-2-1801vp1-1801vm2).html?p=1093487&viewfull=1#post1093487) все еще в силе)
У меня в теме разбирали этот глюк уже и диаграммы там должны быть. ОК, какие сигналы тебе нужны - все на экран не влазят?

Titus
13.12.2020, 21:49
У меня в теме разбирали этот глюк уже и диаграммы там должны быть. ОК, какие сигналы тебе нужны - все на экран не влазят?
Я думаю, что нужны AD, SYNC, AR, DIN, RPLY, RDAT,
WR7, MDFY, BUF_RES, IO_RCD, IO_CMD, IO_RD, IO_IN, WR1, WR2, RCMD_SET, THANG, IO_RCD1, CREQ, IOCMD_ST4, IOCMD_ST3, IOCMD_ST0, ABORT, ALU_WR, IO_START, IOP_STB, ALL_RDY, IORD_ST1, BIR_STB, BRD_WQ, MC_DRDY, SK, BRA, BRA_REQ.

Регистры: PC1, PC2, PC, PSW, CPSW, регистры с кооторыми работает сама команда.

Надеюсь, этого хватит.

Alex_K
13.12.2020, 23:05
Я думаю, они идут по тому же адресу, т.к. преддекодер их не выделяет. Стало быть все трапы обрабатываются едино.
Кстати, а обрабатываются начальный пуск и прерывание TRAP4?

Titus
13.12.2020, 23:11
Кстати, а обрабатываются начальный пуск и прерывание TRAP4?
У микропрограммного автомата две точки принудительного старта.
Одна по ABORT - 0x01
другая по RESET - 0x00

А что с TRAP4 непонятного?

Alex_K
13.12.2020, 23:23
А что с TRAP4 непонятного?
Да вроде ни ABORT, ни RESET не расписаны.

Titus
13.12.2020, 23:27
Да вроде ни ABORT, ни RESET не расписаны.

Расписаны. ABORT с адресом 0x01 - это обычная команда выборки следующей инструкции
RESET с адресом 0x00 - это пустая команда, тоже была описана.

Alex_K
13.12.2020, 23:43
ABORT с адресом 0x01 - это обычная команда выборки следующей инструкции
Выборка кэшированной инструкции. Если есть запрос на прерывание, то переход к обработке запроса, а там прерывание по приоритету. Т.к. у TRAP4 самый высокий приоритет, то оно и исполнится.

RESET с адресом 0x00 - это пустая команда, тоже была описана.
А после отпускания DCLO как там ожидается прямой фронт ACLO? И как будет установлен запрос на прерывание по нулевому вектору HALT?

Vslav
14.12.2020, 00:17
Сигналы ABORT и THANG тебе не нужны, они неактивны при проявлении бага.

Фрагмент исполняемого кода, на диаграммах показан момент после MUL


180 000434 012700 000001 tst0: mov #1, R0 ; тест ошибки предвыборки
181 000440 012701 000002 mov #2, R1 ;
182 000444 012702 000003 mov #3, R2 ;
183 000450 012703 000004 mov #4, R3 ;
184 000454 070400 mul R0, R4 ;
185 000456 011704 mov @PC, R4 ;
186 000460 005200 inc R0 ;
187 000462 005201 inc R1 ;
188 000464 005202 inc R2 ;
189 000466 005203 inc R3 ;
190 000470 000000 halt ;

Быстрая шина, баг не проявляется

https://www.1801bm1.com/files/images/vm2_bug_fast_bus.png

Медленная шина (+5 тактов), баг проявляется

https://www.1801bm1.com/files/images/vm2_bug_slow_bus.png


- - - Добавлено - - -



А после отпускания DCLO как там ожидается прямой фронт ACLO? И как будет установлен запрос на прерывание по нулевому вектору HALT?
После аппаратного сброса матрица прерываний выдает специальный код, и оно крутится на первом адресе пока ACLO не деактивируется, все остальные прерывания не обрабатываются.

Titus
14.12.2020, 00:19
Медленная шина (+5 тактов), баг не проявляется
Так проявляется или не проявляется?
Мне надо, чтобы проявился)

Vslav
14.12.2020, 00:21
Так проявляется или не проявляется?
Мне надо, чтобы проявился)
А на диаграмму посмотреть? :)
На результат в R0

Alex_K
14.12.2020, 00:26
Медленная шина (+5 тактов), баг проявляется
Кстати, по прошлым исследованиям, если после команды с адресацией @PC, употреблялись команды снятия/установки признаков (CLx, SEx), то там баг тоже проявлялся. При этом по тестам мы ничего не смогли понять. Можно посмотреть историю исследований, там были эти тесты.

Titus
14.12.2020, 00:34
А после отпускания DCLO как там ожидается прямой фронт ACLO? И как будет установлен запрос на прерывание по нулевому вектору HALT?
В таблице векторов прерываний, которую я расшифровывал, все описано же было.
Высший приоритет имеет прерывание по спаду ACLO, вектор 0x00 в режиме HALT.
А по фронту ACLO, как я понимаю из той же таблицы, идет удержание состояние WAIT.

- - - Добавлено - - -


А на диаграмму посмотреть?
На результат в R0
Я доверчивый. Мне говорят - не проявляется, я и верю)

Vslav
14.12.2020, 00:36
А по фронту ACLO, как я понимаю из той же таблицы, идет удержание состояние WAIT.

Не совсем, там блокирована матрица прерываний входом AC0. По nDCLO он активируется, и пока не будет фронта nACLO - микрокод будет зациклен.

Titus
14.12.2020, 00:45
Не совсем, там блокирована матрица прерываний входом AC0. По nDCLO он активируется, и пока не будет фронта nACLO - микрокод будет зациклен.
Этот сигнал я не отслеживал пока что.

Titus
14.12.2020, 17:29
Медленная шина (+5 тактов), баг проявляется
А где баг-то?
Все счетчики PC1 и PC2 после MOV @PC,Rн одинаковые что в первом примере, что во втором.

Vslav
14.12.2020, 19:48
А где баг-то?
Все счетчики PC1 и PC2 после MOV @PC,Rн одинаковые что в первом примере, что во втором.
Инструкция "inc R0" выполняется дважды

Titus
14.12.2020, 20:16
Первый график короток по времени, чтобы понять, сколько раз.
И да, еще раз повторюсь, счетчики после неправильной команды не сбиты.

Alex_K
14.12.2020, 21:32
И да, еще раз повторюсь, счетчики после неправильной команды не сбиты.
Плохо смотрите. Во время исполнения INC R0 все счетчики команд увеличиваются два раза и команда INC R0 исполняется два раза.

Titus
15.12.2020, 02:37
Плохо смотрите. Во время исполнения INC R0 все счетчики команд увеличиваются два раза и команда INC R0 исполняется два раза.
Примерно глянул на графики. Заодно нашел у себя в описаниях ошибку связанную с IO_CMD. Если бы знал ее раньше, то может быть и без графиков догадался, где собака порылась)

Я думаю, что проблема в том, что блок ввода-вывода, работающий асинхронно, в конце команды MOV @PC,Rn выдает результат кеширования следующей инструкции в регистр BIR (по сигналу BIR_STB) прям в тот момент, когда этот регистр уже используется. Т.е. если память быстрая, то BIR (кэш инструкции) успевает обновиться до того, как будет использован для декодирования следующей инструкции INC R0. А если память медленная, то инструкция уже декодируется, и в этот момент прилетает новое значение BIR, накладываясь на старое. Подробно изучать сейчас не будут, ибо поздно, но сто процентов, что собака порылась именно здесь. Но думаю, что возможных накладок после подобной команды может быть больше и интереснее.

- - - Добавлено - - -

Да, так и поехало.
В нормальном режиме сперва прилетает новое значение в BIR (кэш), и после этого оно защелкивается и декодируется по IR_STB.
А в ненормальном все меняется местами. В BIR уже есть значение, оно защелкивается по IR_STB, и тут сразу же прилетает новое значение BIR с опозданием. В результате попадаем в порочный круг, когда значение в кэше всегда отстает на одно значение от реально ожидаемого, т.к. прилетает после IR_STB. А так как сбившийся кэш сбросить некому, все так и идет по кругу. И, естественно, INC R0 выполняется два раза. При этом счетчики PC1 и PC2 не портятся и никуда не отстают. Это ложная теория. Сбросить неправильный кэш помогут две команды, которые делают это принудительно посредством IO_CMD. Это команда STEP. И любая команда начинающаяся с перекеширования инструкции (адрес микрокоманды 0x21).

hobot
15.12.2020, 02:44
Да, так и поехало.
я хочу уточнить - надо ли подобные ошибки переносить\копировать в модель процессора (эмулятор) или можно\нужно поправлять? Как же система и программы работают? У родных процессоров вряд ли такой же момент ?
В общем это очень интересно и главное как с этим быть?

Titus
15.12.2020, 02:59
я хочу уточнить - надо ли подобные ошибки переносить\копировать в модель процессора (эмулятор) или можно\нужно поправлять?
Я думаю, что все надо переносить, если нужна 100% совместимость с реальной УКНЦ.

Alex
15.12.2020, 08:32
Лучше в эмуляторе, в настройках, галочку поставить... По умолчанию, ошибка включена, но если кому надо - галочку снять можно :)

Vslav
15.12.2020, 08:58
я хочу уточнить - надо ли подобные ошибки переносить\копировать в модель процессора (эмулятор) или можно\нужно поправлять? Как же система и программы работают? У родных процессоров вряд ли такой же момент ?

У меня для ВМ2 сделано исправление этого бага по флагу компиляции. Каждый сам может решить и выбрать нужен ли ему это баг в системе или нет.

- - - Добавлено - - -


При этом счетчики PC1 и PC2 не портятся и никуда не отстают. Это ложная теория.
Здрасьте, приехали. Там именно теряется одно обновление PC2+2 из-за перезаписи PC2 при выдаче адреса в фазе @PC и предвыборка делается по адресу на 2 меньшему чем должно быть. В итоге поток инструкций отстает на 1 слово в отличие от нормального исполнения. Если поставить два графика рядом, то это не очень хорошо видно из-за разного быстродействия памяти, но если сравнить по циклам микроинструкций, то видна вставка исполнения inc R0 вместо исполнения следующей inc R1. Схема полагает что прочитано 2(PC2), то есть следующая inc R1, а реально читается @PC2, то есть inc R0. Я сделал фикс в виде блокировки перезаписи PC2 и он прекрасно работает.

Titus
15.12.2020, 12:34
Там именно теряется одно обновление PC2+2 из-за перезаписи PC2 при выдаче адреса в фазе @PC и предвыборка делается по адресу на 2 меньшему чем должно быть.
Сравни сам два графика. На обоих к моменту исполнения INC R0 значения счетчиков PC2 и PC1 правильные.

Vslav
15.12.2020, 13:03
Сравни сам два графика. На обоих к моменту исполнения INC R0 значения счетчиков PC2 и PC1 правильные.
Ну, сравнил:

https://www.1801bm1.com/files/images/vm2_pc2_compare.png

Верхний график в вдвое меньшем масштабе, поэтому вот то PC2=460 длится ВДВОЕ дольше чем на нижнем графике. Там-то и выполняется лишнее присваивание PC2=460 и выполняется лишний INC R0. Ты видишь тут только последовательность: 460, 462, 460, 462, 464. Это ситуация верная, если нет ошибки. А реально, в случае глюка, это: 460, 462, 460, 460, 462, 464.

- - - Добавлено - - -

Я вечером сделаю диаграмму с PC2 привязанным к шине и микрокоду, там будет виднее.

Titus
15.12.2020, 13:03
Верхний график в вдвое меньшем масштабе, поэтому вот то PC2=460 длится ВДВОЕ дольше чем на нижнем графике.
Это не то место. Смотри далее на значения счетчиков в момент выполнения первого INC R0.
А оно одинаковое для обоих случаев.

Vslav
15.12.2020, 13:15
Это не то место. Смотри далее на значения счетчиков в момент выполнения первого INC R0.
А оно одинаковое для обоих случаев.
И это абсолютно правильно. Попросили инструкцию по 460 - получили INC R0. Попросили два раза по адресу 460 - получили два раза. Баг не в том что неправильный счетчик в момент исполнения инструкции, а в том что сначала исполняется инструкция для которой завершилась поздняя предвыборка, а потом она выбирается и исполняется еще раз.

Vslav
15.12.2020, 19:55
Пересобрал диаграммы с действительно нужными сигналами, а не со запрошенной свалкой.
Код тоже немного поменял, интересно как оно себя дальше ведет:

180 000434 012700 000001 tst0: mov #1, R0 ; тест ошибки предвыборки
181 000440 012701 000002 mov #2, R1 ;
182 000444 012702 000003 mov #3, R2 ;
183 000450 012703 000004 mov #4, R3 ;
184 000454 070400 mul R0, R4 ;
185 000456 011704 mov @PC, R4 ;
186 000460 005200 inc R0 ;
187 000462 005201 inc R1 ;
188 ; inc R2 ;
189 ; inc R3 ;
190 000464 000401 br 1$ ;
191 000466 000000 halt ;
192 000470 000000 1$: halt ;
193 ;_________________________________________________ ____________________________
194 ;
195 000472 012700 000001 tst1: mov #1, R0 ; тест ошибки предвыборки
196 000476 012701 000002 mov #2, R1 ;

Процессор здорового человека:

https://www.1801bm1.com/files/images/vm2_pcbug_no.png

Процессор курильщика.

https://www.1801bm1.com/files/images/vm2_pcbug_yes.png

Там проблема в фазах bir_stb и ir_stb.
Последовательность на шине такая:
- исполняется mov @PC, R4
- читаем 460, предвыборка inc R0
- читаем 460, это чтение по @PC из ьщм @PC, R4
- читаем 460, снова запущенная предвыборка inc R0
И тут начинается самое интересное, мы приходим на 00 (77 на диаграмме), и там формируется Конец Команды (set_cend).
Если предвыборка 460 завершилась, то все хорошо, код inc R0 попадет в регистр инструкций и все исполнится как обычно.
Но если предвыборка НЕ завершилась, то процессор все равно берет код инструкции из буферного регистра (там был inc R0 от предыдущей предвыборки) и выполняет его. Следующая инструкция будет по результатам второй предвыборки 460 которая перед этим не завершилась. Таким образом, в IREG inc R0 попадает дважды. А дальше оно уже по факту смещено. Процессор запускает предвыборку по адресу 462, но на самом деле еще выполняется предвыборка по адресу 460, и вместо помещенной в конвейер запущенной 462 будут получены сначала 460-ые и исполнены, и только затем 462-ые.

Titus
16.12.2020, 20:00
Особенности работы кэша

Любая команда перед декодированием попадает в кэш команд BIR (буферный регистр инструкций). Если кэш команд недействительный (предыдущее значение уже использовано, а новое еще не загружено), то блок декодирования команды будет ожидать загрузки нового значения в BIR. Существует несколько событий и состояний процессора, делающих кэш команд недействительным.
События отличаются от состояния тем, что события имеют кратковременный характер и длятся не более 1-2 тактов CLCI, а состояния могу длиться более продолжительное время.

События сбрасывающие кэш:


RESET - событие сброса микропроцессора по ACLO.
CLR_CEND - происходит после защелкивания текущего значения кэша по сигналу IR_STB в регистре инструкций IR. Это необходимо для того, чтобы сообщить кэшу, что кэшированную команду использовали, и можно кэшировать новую.


Состояния сбрасывающие кэш:


BUF_RES - возникает в двух случаях:


Если при записи в память, регистр адреса RA совпал регистром PC1. А регистр PC1 всегда указывает на следующее слово команды, в независимости от того, кэшировано оно в BIR или нет.
От блока таймаута пришло событие TO_RPLY.

Отменяется это событие по RESET или же по записи в регистр R7, кроме шагов микропрограммы 0x01 (выборка кэшированной инструкции), и шагов 0x10 и 0x16 (кэширование следующего слова команды/данных в некоторых операциях с двумя операндами, когда источник расположен в памяти).


WORD27 - состояние запрета кэша команд. Запрашивается некоторыми методами адресации, чтобы использовать кэшированное слово следующей инструкции в качестве данных.
Отменяется по RESET или ABORT, либо же по микрокоманде ожидания готовности BRD. Упрощенно использование этого состояния микропрограммой выглядит так:


Запретить кэш. При этом автоматически PC1=PC2 (в обычном режиме PC2 опережает PC1 на 2, и указывает на следующий за кэшированным словом адрес).
Использовать BIR по своему усмотрению, например, как смещение для адресации X(Rn).
Запросить чтение в BRD какого-то слова (необязательный шаг).
Ожидать готовности BRD (момента, когда слово прочитано) и отменить запрещение кэша.

Следует заметить, что отмена события запрещения кэша не делает содержимое кэша действительным, и микропрограмма выборки следующей команды должна быть запрошена не по адресу 0x01 (выборка кэшированной инструкции), а по адресу 0x21 (выборка некэшированной инструкции). Только после этого кэш команд станет опять действительным и может быть использован.


IO_CMD - принудительный сброс BIR в микрокомандах 0x21 (выборка некэшированной инструкции) и в инструкции процессора RESET. Состояние длится до тех пор, пока блок ввода-вывода не освободится, и не начнет операцию чтения (кэширования) команды (сигнал IOP_STB). На протяжении всего этого состояния всякое завершение возможного предыдущего асинхронного цикла чтения в регистр BIR будет игнорироваться. Это сделано для того, чтобы не произошла ситуация следующего рода - в команде кэширования (0x21) запросили чтение BIR, а предыдущая микрокоманда тоже читала BIR, и асинхронный результат этого чтения с запозданием прилетел в кэш и нарушил всю логику работы.


Теперь перейдем к единственному сoбытию, которое делает кэш действительным. Это завершение чтения регистра BIR. Если ни одно из предыдущих событий и состояний не активно, то после чтения BIR, кэш становится действительным и может быть использован для декодирования команды. Чтение BIR запрашивается в следующих микрокомандах:


0x01 (выборка кэшированной инструкции). В момент защелкивания из BIR кода инструкции в регистр инструкции IR сразу инициализируется запрос чтения в BIR следующего слова.
0x10 и 0x16 (кэширование следующего слова команды/данных) в некоторых операциях с двумя операндами, когда источник расположен в памяти.



Ошибки использования кэша:

В некоторых микрокомандах содержатся ошибки, приводящие к сбою или ошибкам в работе кэша. Ошибка - это однократное событие, сбой - это устойчивое состояние.


Ошибка команд расширенной арифметики EIS (MUL, DIV, ASH и ASHC). Из-а того, что порядок кодирования операндов в слове инструкции поменян местами относительно всех остальных команд, стандартные схемы определения модификации R7, если этот регистр задействован в качестве приемника - не работают. Из-за чего после окончания EIS-инструкции идет переход на микрокоманду 0x01 (выборка кэшированной инструкции) а не на микрокоманду 0x21 (выборка некэшированной инструкции). Это приводит к тому, что даже если R7 в ходе выполнения инструкции изменился, выборка следующей инструкции будет из кэша BIR, а там находится инструкция следующая за EIS. Однако, далее работа кэша восстанавливает в нормальном режиме.


Ошибка адресации (R7) в качестве источника в двухоперандных команд, приводящая к сбою в работе кэша.
При работе с кэшем обязательно соблюдать следующее правило - сперва сделать недействительным текущее значение кэша (не важно, использовалось оно или нет), и только потом запрашивать чтение нового значения в кэш. Если эту последовательность не соблюсти, то произойдет ситуация наложения новых данных в кэше на старые, результат которого будет зависеть от времени прихода асинхронного ответа на запрос чтения контроллера ввода-вывода.
Выполнение микрокоманды 0x01 (выборка кэшированной инструкции) может начинаться как минимум тремя способами (четвертый относится к блоку таймаута, и здесь не рассматривается):


Кэш недействительный, ожидаем чтение нового значения BIR, которое запросила предыдущая микрокоманда 0x21 (выборка некэшированной инструкции).
Кэш действительный, можно сразу использовать значение BIR. Фоновых асинхронных запросов чтения шины нет.
Кэш действительный, можно сразу использовать значение BIR. Не окончен фоновой запрос чтения шины в регистр BIR. Является последствием сбоя в работе кэша.

Рассмотрим возникновение ситуации описанной в третьем пункте.
Микрокоманда выполнения операции с двумя операндами, когда источник находится в памяти, имеет ошибку следующего вида:
Типы адресаций источника (R7)+, @(R7)+, X(Rn) и @X(Rn) имеют специальные обработчики, использующие BIR в качестве данных и сбрасывающие кэш.
Типы адресаций источника (R7), -(R7), @-(Rn) специальных обработчиков не имеют, и выполняются для всех регистров одинаково. Кэш не сбрасывается.
Вторым этапом микропрограмма определяет, нужно ли делать кэширование только что использованного BIR, или не надо. И определяет она это по признаку RI2, который установлен, если адресация источника (R7), (R7)+, -(R7), @(R7)+, @-(R7), X(Rn), @X(Rn). Как видно, адресации (R7), -(R7), @-(Rn) тоже попадают в обработчик компенсации, хотя кэш НЕ использовали и НЕ сбрасывали.
Обработчик компенсации запрашивает цикл чтения BIR по адресу PC2, затем делает PC1=PC2, и PC2=PC2+2.
Далее, если приемник - регистр, выполняется цикл ALU для заданной инструкции, и если приемник не равен R7, идет переход на адрес 0x01 (выборка кэшированной инструкции). Таким образом, если асинхронный цикл чтения BIR, запрошенный обработчиком компенсации, успел завершиться до защелкивания BIR в IR, кэш продолжит нормальную работу. Если же цикл чтения BIR завершился после защелкивания уже имеющегося BIR в IR, то кэш сразу же станет действительным, но все равно будет выдан запрос чтения BIR. Таким образом, декодироваться и выполняться будет инструкция запрошенная в предыдущем цикле, т.е. с отставанием на одно слово. И этот процесс будет повторяться, пока какая-либо команда не сделает кэш недействительным одним из описанных выше способов.
В случае, если приемник - память, то после компенсации будет переход на микрокоманду 0x17 и декодирование адресации приемника.

Что происходит с указателями PC1 и PC2 после обработки адресаций источника (R7), -(R7), @-(Rn):

(R7):
RA=PC1 IO_RD, IO_IN // Инициировать цикл чтения шины
PC2=PC1
-(R7):
PC2=PC1-2
RA=PC2 IO_RD, IO_IN // Инициировать цикл чтения шины
@-(R7):
PC2=PC1-2
RA=PC2 IO_RD, IO_IN // Инициировать цикл чтения шины
//----------------------------------------------------------------------
WAIT_BRD // Ожидание готовности чтения BRD
ACC=BRD
RA=ACC IO_RD, IO_IN // Инициировать цикл чтения шины

Как видно, никакого нарушения в логике работы в этих местах не будет, и все последующие нарушения происходят исключительно из-за отсутствия сброса кэша.

Vslav
16.12.2020, 20:37
Я в свое время пытался отфильтровать на RI2 адресацию (PC), но оно не помогло, крашилось. Похоже что там еще нужное в "компенсаторе" делается, нельзя его просто так скипнуть.

Titus
16.12.2020, 20:47
Я в свое время пытался отфильтровать на RI2 адресацию (PC), но оно не помогло, крашилось. Похоже что там еще нужное в "компенсаторе" делается, нельзя его просто так скипнуть.
Конечно нельзя, потому что если просто отфильтровать, PC2 станет равным PC1, но при этом выборка следующей команды все равно будет как кэшированная.
Я думаю, что помочь может автоматический сброс кэша команд, если RI2=1, а адрес микрокоманды 0x0F.

Titus
17.12.2020, 01:02
Просьба к Vslav'у сделать несколько диаграмм со следующими командами:

1. Простая MOV R1,R0, за которой следует отсутствующая ячейка памяти.
2. Команда MOV #1234,R0, причем слово аргумента (1234) находится уже в отсутствующей ячейке памяти.
3. Команда MOV (R1),R0, за которой следует существующая ячейка памяти, а R1 ссылается на несуществующую ячейку памяти.
4. Команда BRA куда-нибудь в существующую ячейку памяти, так что после BRA сразу идет отсутствующая ячейка памяти
5. Можно еще для чистоты эксперимента сделать MOV R0,R7, за которой следует отсутствующая ячейка памяти, а R0 указывает на существующую ячейку памяти.

Сигналы нужны все те же, что и в диаграммах ошибки кэша, только добавить к ним: TO_RPLY, TOVF, ABORT, THANG, TEVENT, RCMD_SET, TO_BLOCK, IOCMD_ST0..4.

Vslav
17.12.2020, 01:08
1. Простая MOV R1,R0, за которой следует отсутствующая ячейка памяти.

MOV выполнится, потом будет исключение.



2. Команда MOV #1234,R0, причем слово аргумента (1234) находится уже в отсутствующей ячейке памяти.

Тут сразу значение PC при исключении не скажу.


3. Команда MOV (R1),R0, за которой следует существующая ячейка памяти, а R1 ссылается на несуществующую ячейку памяти.

Будет исключение по выборке по адресу R1.



4. Команда BRA куда-нибудь в существующую ячейку памяти, так что после BRA сразу идет отсутствующая ячейка памяти

Переход выполнится нормально, без исключений.



5. Можно еще для чистоты эксперимента сделать MOV R0,R7, за которой следует отсутствующая ячейка памяти, а R0 указывает на существующую ячейку памяти.

Должно тоже пройти нормально, без исключений. Я все это уже тестировал, диаграмки завтра постараюсь сделать, увидим сильно ли я ошибся :)

Titus
17.12.2020, 01:37
Мне нужны именно точные диаграммы на асинхронной модели)

Titus
19.12.2020, 16:14
Vslav, ты не забыл про диаграммы?

Vslav
19.12.2020, 16:44
Vslav, ты не забыл про диаграммы?
Не забыл, просто сейчас М4 отлаживаю, пока не буду переключаться, на твою байду час потратить надо. Сегодня надеюсь М4 закончить и выложить, потом диаграммы.

Titus
19.12.2020, 16:51
на твою байду час потратить надо
Не Байда, а Трамп-пам-па))) Шутка)

Vslav
19.12.2020, 17:30
Не Байда, а Трамп-пам-па))) Шутка)
Не обижайся, просто я это давно уже пережевал, по второму разу жевать - не очень интересно этим заниматься. Так что - с моей стороны это подвиг - цени :)
Давно бы уже сам лопату Modelsim освоил, там на гитхабе у меня простая инструкция, на пять строчек, как проект запустить.
Update: M4 выложил, поужинаю и сделаю диаграммы.

Titus
19.12.2020, 20:34
Давно бы уже сам лопату Modelsim освоил, там на гитхабе у меня простая инструкция, на пять строчек, как проект запустить.
Да уж осталось-то добить ВМ2 немного, поэтому легче попросить помощь зала или звонок другу)

Vslav
19.12.2020, 22:32
Да уж осталось-то добить ВМ2 немного, поэтому легче попросить помощь зала или звонок другу)
Ну... Проекты приходят и уходят, а навык владения лопатой - остается.

Тестовый код:

47 040000 memlim = 40000 ; лимит тестовой памяти

353 ;_________________________________________________ ____________________________
354 ;
355 ; Дополнительные тесты исполнения, вызывающие ошибку шины на предвыборке
356 ;
357 001404 012705 037774 tst6: mov #memlim-4, R5 ;
358 001410 013725 001546 mov @#cmd15, (R5)+ ;
359 ;
360 001414 012737 001432 000004 mov #1$, @#trap4 ;
361 001422 013715 001532 mov @#cmd10, (R5) ;
362 001426 000165 177776 jmp -2(R5) ;
363 ;
364 001432 012737 001450 000004 1$: mov #2$, @#trap4 ;
365 001440 013715 001534 mov @#cmd11, (R5) ;
366 001444 000165 177776 jmp -2(R5) ;
367 ;
368 001450 012737 001472 000004 2$: mov #3$, @#trap4 ;
369 001456 013715 001540 mov @#cmd12, (R5) ;
370 001462 012701 040004 mov #memlim+4, R1 ;
371 001466 000165 177776 jmp -2(R5) ;
372 ;
373 001472 012700 001512 3$: mov #4$, R0 ;
374 001476 010037 000004 mov R0, @#trap4 ;
375 001502 013715 001542 mov @#cmd13, (R5) ;
376 001506 000165 177776 jmp -2(R5) ;
377 ;
378 001512 012737 001530 000004 4$: mov #5$, @#trap4 ;
379 001520 013715 001544 mov @#cmd14, (R5) ;
380 001524 000165 177776 jmp -2(R5) ;
381 ;
382 001530 000000 5$: halt ;
383 ;
384 001532 010100 cmd10: mov R1, R0 ;
385 001534 012700 001234 cmd11: mov #1234, R0 ;
386 001540 011100 cmd12: mov @R1, R0 ;
387 001542 010007 cmd13: mov R0, PC ;
388 001544 000776 cmd14: br .-2 ;
389 001546 000240 cmd15: nop ;
390 ;

Диаграммы (https://www.1801bm1.com/files/images/vm2_1500-22000.pdf)

hobot
20.12.2020, 03:22
Не Байда, а Трамп-пам-па))) Шутка)

Ну... Проекты приходят и уходят, а навык владения лопатой - остается.
гармония профессионалов ! )

Alex_K
20.12.2020, 16:58
Решил попробовать адресацию -(PC) (код 47). Интересный результат получился.
Бесконечный цикл не получился. Выполнилось по два раза INC R0 и INC R1, останов случился на адресе 01030, а не 01026.

- - - Добавлено - - -

Довольно интересные результаты дают команды снятия/установки признаков, некоторые команды могут и не исполнится.

Titus
20.12.2020, 16:58
Бесконечный цикл не получился. Выполнилось по два раза INC R0 и INC R1, останов случился на адресе 01030, а не 01026.
Лучше примеры приводить на языке людей ассемблера, чтобы все сразу видели, что за пример.

Alex_K
20.12.2020, 17:12
Лучше примеры приводить на языке людей ассемблера, чтобы все сразу видели, что за пример.
Вроде бы у PDP-11 специально и употребляется восьмеричная система счисления, чтобы всё было ясно без слов. Ну так уж и быть:
1.

1000 CLR R0
1002 CLR R1
1004 CLR R2
1006 CLR R3
1010 MOV R5,R5
1012 MOV -(PC),R5
1014 INC R0
1016 INC R1
1020 INC R2
1022 INC R3
1024 HALT

2.

1000 CLR R0
1002 CLR R1
1004 CLR R2
1006 CLR R3
1010 MOV R5,R5
1012 MOV -(PC),R5
1014 NOP
1016 INC R0
1020 NOP
1022 INC R2
1024 INC R3
1026 HALT

Titus
20.12.2020, 17:15
Довольно интересные результаты дают команды снятия/установки признаков, некоторые команды могут и не исполнится.
Что странного, и что может не исполниться?

Alex_K
20.12.2020, 17:21
Что странного, и что может не исполниться?
Во втором примере два раза исполнился INC R0, один раз - INC R3, а вот INC R2 ни разу не исполнился. Там же на фото после исполнения значения регистров.

Titus
20.12.2020, 18:14
Я думаю, что проблема с командами, использующими IR (регистр инструкций) может происходить из-за того, что в цикле IR_STB, когда BIR защелкивается в IR, при сбитом кэше может прилететь новое значение, и, таким образом, получится, что команда выполняется предыдущая, а поле IR используется от следующей команды.
Для команд:
1. SEx, CLx - это младшие 4 бита, определяющие маску флагов.
2. SOB, BRA, Bcc - поле смещения перехода
3. MARK - тоже самое.

Но для этого нужно, чтобы время памяти было такое, что BIR_STB прилетает именно в момент IR_STB. Ни раньше (тогда кэш исправится), ни позже, тогда будет просто выполнение предыдущей команды.

- - - Добавлено - - -

Ну и еще небольшая ложечка дёгтя, если мое предположение верное.
Команда BRA/Bcc тоже использует BIR, то можно предположить, что подобная накладка, когда BIR прилетает во время IR_STB, спутает все карты.
А именно, выполняться будет Bcc, до этого находящаяся в BIR, а анализироваться блоком условий будет следующая команда.
Т.е. допустим, идут две команды BRA, BEQ. Выполняться будет BRA, т.к. она уже в кэше, а условие и смещение будет от BEQ.
Большая путаница может быть, когда следующая команда не является командой перехода, но все равно совпадает с маской условий для Bcc.
Например, маска для BEQ, BLOS = x.000.x01.1xxx.xxx.xxx (условие Z=1). Но в нее попадает, например, и команда NEG.
Таким образом, если идет BRA, затем NEG, то для BRA будет условие Z=1, а смещение перехода будет взято из младшего байта NEG.

Alex_K
20.12.2020, 22:08
Ещё интересное наблюдение - команда MOV -(PC),R5 в регистр R5 ложит не саму себя, как должно быть, а следующую за ней команду.

Titus
21.12.2020, 00:44
Ещё интересное наблюдение - команда MOV -(PC),R5 в регистр R5 ложит не саму себя, как должно быть, а следующую за ней команду.
А вот это очень странно, потому что вычитание 2 должно делаться из PC1, а не из PC2. А PC1 указывает на следующую команду.
Надо просить сделать тест с графиком на асинхронной модели у Vslav'a.

AFZ
21.12.2020, 07:32
Ещё интересное наблюдение - команда MOV -(PC),R5 в регистр R5 ложит не саму себя, как должно быть, а следующую за ней команду.Странно. По идее, эта команда должна намертво зациклить. У меня в контроллере AZ всё весело работает Или это связано с R5? Мой AZ выдает при считывании из регистра 17777226 последовательно коды 106447, 340, 14700, 10000, 14720, 240, 14720, <очередная команда загрузчика> ... 14720, <последняя команда загрузчика>, 14707, 10000. Первый код - это команда MTPS, далее код, который пересылается в PS, далеее в R0 пересылается адрес начала загрузчика - 10000, далее первая и очередные команды загрузчика, далее в PC пересылается адрес начала загрузчика и далее начинает работать сам загрузчик.

Идея этого, так сказать, аппаратного загрузчика, была опубликована в МПСС, для ЦП М2, но работает оно и на М6, и на ВМ1, и на ВМ2, и на ВМ3, и на 11/73 - это где оно проверено. Хотя нет, скорее всего при чтении из страницы ввода-вывода просто блокируются предвыборки...

Alex
21.12.2020, 09:55
Ещё интересное наблюдение - команда MOV -(PC),R5 в регистр R5 ложит не саму себя, как должно быть, а следующую за ней команду.

Тут такое дело, даже у DEC разные процессоры ведут себя в таких и подобных случаях по разному. При этом в примечаниях про процессоры это говорится. Вещь известная.

Hunta
21.12.2020, 10:17
Тут такое дело, даже у DEC разные процессоры ведут себя в таких и подобных случаях по разному. При этом в примечаниях про процессоры это говорится. Вещь известная.
Не совсем так - разное поведение, когда используется Rx и -(Rx) или (Rx)+ - то есть регистр и автоинкремент/автодекремент с этим же регистром. А тут регистры разные.

Alex
21.12.2020, 10:22
Именно про -(PC) или (PC)+ тож...
По идее и в книжках одно, а по факту... :(
Возможно проблема в конвейере...

Hunta
21.12.2020, 10:43
Именно про -(PC) или (PC)+ тож..
Нет. Из документации

1. 2x и 4x
OPR %R,(R)+ ; OPR %R,-(R) using SAME register as both source and destination

2. 3x и 5x
OPR %R, @(R)+ ; OPR %R, @-(R) using SAME register as both source and destination

3. 6x, 7x, 67 и 77
OPR PC, X(R) ; OPR PC, @X(R) ; OPR PC,@A; OPR PC,A

-(PC) и (PC)+ попадает только под первый сценарий, но в нем нужен вариант типа MOV PC, -(PC)

- - - Добавлено - - -

Поскольку я вожусь с ДП, у меня как раз открыты эти страницы - где отличия описываются ;)

- - - Добавлено - - -

Собственно, OPR PC,@A; OPR PC,A в сценарий можно было и не включать, ибо это частный случай 6x и 7x

Alex_K
21.12.2020, 21:20
Мой AZ выдает при считывании из регистра 17777226
Если регистра 0177230 не существует, то при неудачной предвыборке (несуществующий регистр) кэш сбрасывается и проблемы не существует. Также проблемы нет, если между DIN и RPLY было менее четырёх тактов.

AFZ
21.12.2020, 22:22
Если регистра 0177230 не существует, то при неудачной предвыборке (несуществующий регистр) кэш сбрасывается и проблемы не существует. Также проблемы нет, если между DIN и RPLY было менее четырёх тактов.Хм. Не поленился, включил свой 1201/03 (ВМ3).

***** ДОСТУПНОЕ ОЗУ - 256 K *
@ 001000
@1000/000000 14705
00001002/000000 240
00001004/000000
@1000G

<здесь ВМ3 в цикле исполняет этот самый MOV -(R7),R5 пока не активируешь К ОСТ Н (B HALT L) >

@ 001000
@R5/014705

Alex_K
21.12.2020, 22:35
Хм. Не поленился, включил свой ВМ3.
В 1801ВМ3 проблемы предвыборки при исполнении команд типа OPR @PC,Rx, OPR -(PC),Rx и OPR @-(PC),Rx может и нет. Данная тема про реверс-инжиниринг и исследование чипов, входящих в УКНЦ. Вот у процессора 1801ВМ2 обнаружилась данная проблема, она обнаружилась ещё в 2013 году. Вот здесь и исследуется.
Я также не поленился и набрал на УКНЦ и запустил следующую программу:


157770 005000 CLR R0
157772 005001 CLR R1
157774 010505 MOV R5,R5
157776 014705 MOV -(PC),R5

Программа зациклилась на адресе 0157776, т.к. ячейки с адресом 0160000 не существует, то предвыборка сбрасывается и глюк не проявляется.

Посмотрел описание AZ, регистра 0177230 не существует, потому проблемы у вас и нет. А если бы был этот регистр и между DIN и RPLY было бы более четырёх тактов, то проблема у вас появилась бы.

Titus
21.12.2020, 22:50
Программа зациклилась на адресе 0157776, т.к. ячейки с адресом 0160000 не существует, то предвыборка сбрасывается и глюк не проявляется.
А глюк с тем, что R5 содержит не текущую команду, а следующую, когда проявляется?

AFZ
21.12.2020, 22:55
Не поленился, воткнул 1201.02 (ВМ2). Так он и по К ОСТ Н (B HALT L) не останавливается. Набрал коды, 1000G и тишина, даже на ОСТ не реагирует. На УСТ реагирует. Если занести коды, заранее активировать ОСТ и запустить, то стоит на адресе 1000, хоть после 1000G, хоть после любого числа нажатий P, если же ОСТ погасить и нажать P, то больше его не остановишь. Да, в R5 14705. Загрузка с AZ идет нормально.

ВМ1 вставлять не буду.

Alex_K
21.12.2020, 23:01
А глюк с тем, что R5 содержит не текущую команду, а следующую, когда проявляется?
Когда следующая ячейка существует и во время предвыборки время между DIN и RPLY составляло более четырёх тактов. Две страницы назад есть и тексты программ и скриншоты с экрана.

- - - Добавлено - - -


Не поленился, воткнул 1201.02 (ВМ2). Так он и по К ОСТ Н (B HALT L) не останавливается. Набрал коды, 1000G и тишина, даже на ОСТ не реагирует. На УСТ реагиркет. Если занести коды, заранее активировать ОСТ и запустить, то стоит на адресе 1000, хоть плсде 1000G, хотьб после любого числа нажатий P, если же ОСТ погасить и нажать P, то больше его не остановишь. Да, в R5 14705. Загрузка с AZ идет нормально.
AFZ, пожалуйста внимательно перечитайте тему. Проблема появляется именно на 1801ВМ2 и если во время предвыборки время между DIN и RPLY было более четырёх тактов. В УКНЦ память разделяется между процессором и видеоадаптером, видеоадаптер имеет приоритет, потому и выборка медленная. А в МС1201.02 память монопольно используется 1801ВП1-013, выборка быстрая, проблема не наблюдается.

AFZ
21.12.2020, 23:15
Понятно. Так детально я не вникал.

Titus
21.12.2020, 23:58
Когда следующая ячейка существует и во время предвыборки время между DIN и RPLY составляло более четырёх тактов. Две страницы назад есть и тексты программ и скриншоты с экрана.
Вряд ли это может быть связано с эффектом глюка конвейера, т.к. выборка по адресу -(PC) делается до того, как могут начаться глюки из-за конвейера.

Alex_K
22.12.2020, 22:04
Вряд ли это может быть связано с эффектом глюка конвейера, т.к. выборка по адресу -(PC) делается до того, как могут начаться глюки из-за конвейера.
Ну тут раз на раз не приходится. Иногда выбирается слово за командой (это и есть глюк), а иногда и сама команда, что правильно. На фото выше приведены примеры с глюком.

Titus
22.12.2020, 22:46
Иногда выбирается слово за командой (это и есть глюк), а иногда и сама команда, что правильно. На фото выше приведены примеры с глюком.
Вообще страннно.
А не может быть так, что вы уже начинаете выполнять последовательность после глюка?

Alex_K
22.12.2020, 22:49
А не может быть так, что вы уже начинаете выполнять последовательность после глюка?
Не понял, переведите.

Titus
22.12.2020, 23:00
Не понял, переведите.
Если предположить, что кэш слетел раньше, чем начала выполняться эта команда, тогда можно логически обьяснить, что в R5 попадает не та команда.
Стоп. А ведь так и может быть. Выполняется MOV -(PC),R5, в R5 попадает правильное значение, но конвейер слетает, выполняется предвыбранная команда, а уже после нее MOV -(PC),R5, и уже на этот раз она загружает в R5 неправильное значение.

Alex_K
22.12.2020, 23:09
Стоп. А ведь так и может быть. Выполняется MOV -(PC),R5, в R5 попадает правильное значение, но конвейер слетает, выполняется предвыбранная команда, а уже после нее MOV -(PC),R5, и уже на этот раз она загружает в R5 неправильное значение.
Согласен. Всё может быть.
Правильно Vslav сказал, что надо пользоваться лопатой, только где её взять...

Vslav
22.12.2020, 23:16
По ходу мой фикс с PC2 не работает как надо. Придется таки разбираться и патчить микрокод.

Titus
22.12.2020, 23:27
По ходу мой фикс с PC2 не работает как надо. Придется таки разбираться и патчить микрокод.
Даже не думай, почти сизифов труд)

- - - Добавлено - - -

Фикс PC2 и не поможет, т.к. не он виной, а сбой кэша.

- - - Добавлено - - -


Согласен. Всё может быть.
Надо сделать тест типа ADD -(PC),R5, тогда мы хотя бы косвенно сможем понять, сколько раз эта команда выполнилась по итоговой сумме.

Titus
23.12.2020, 02:24
Посмотрел я пример Alex_K, просчитал его теоретически по микропрограмме, и все сошлось:


1012 MOV -(PC),R5
1014 INC R0
1016 INC R1
1020 INC R2
1022 INC R3


1012 MOV -(PC),R5 // PC1=1012, R5=14705 В кэше: INC R0 Запрос кэширования: MOV -(PC),R5
1012 INC R0 // R0=1 В кэше: MOV -(PC),R5 Запрос кэширования: INC R0
1014 MOV -(PC),R5 // PC1=1014, R5=5200 В кэше: INC R0 Запрос кэширования: INC R1
В кэше: INC R1 Запрос кэширования: INC R0
1014 INC R1 // R1=1 В кэше: INC R0 Запрос кэширования: INC R1
1016 INC R0 // R0=2 В кэше: INC R1 Запрос кэширования: INC R2
1020 INC R1 // R1=2 В кэше: INC R2 Запрос кэширования: INC R3
1022 INC R2 // R2=1 и т.д.

Titus
23.12.2020, 16:15
Что же касается второго примера с NOP'ами, то там непонятно, почему INC R2 не сработала, т.к. R2 в итоге = 0.
Нужны какие-то еще тесты с NOP'ами, чтобы понять что не так.



1012 MOV -(PC),R5
1014 NOP
1016 INC R0
1020 NOP
1022 INC R2
1024 INC R3

Titus
23.12.2020, 20:44
Ну... Проекты приходят и уходят, а навык владения лопатой - остается.

Тестовый код:
А чего это сигналы CREQ и RCMD_SET всегда пустые во всех комбинациях?

Vslav
23.12.2020, 23:55
А чего это сигналы CREQ и RCMD_SET всегда пустые во всех комбинациях?
Наверное добавил их уже после прогона, вот он и не получили данные.

Titus
24.12.2020, 00:08
Наверное добавил их уже после прогона, вот он и не получили данные.
А они очень нужны)

Vslav
24.12.2020, 00:36
А они очень нужны)
Ты думаешь я настройки сохранил?

Titus
24.12.2020, 01:06
Ты думаешь я настройки сохранил?
Я надеюсь на это)

- - - Добавлено - - -

Ибо, это два важнейших сигнала из-за которых все и затевалось)

- - - Добавлено - - -

Впрочем, ладно, думаю, можно обойтись и без них, и так видно логически что на них происходит.

Titus
24.12.2020, 03:24
В общем, интересные моменты в блоке таймаута.

Например, выполняется команда MOV R1,R0, за которой следует несуществующая ячейка памяти.
После выполнения инструкции на микрокоманде 0x01 (выборка следующей инструкции) происходит ошибка таймаута памяти (т.к. запрошенное кэширование инструкции в предыдущей команде 0x01 не получило ответа).
Блок таймаута смотрит и говорит - ага, ошибка чтения чтения была в цикле IO_RCD (а этот цикл генерируется только в командах 0x01, 0x10 и 0x16 для кэширования следующей инструкции). После чего блок таймаута дает фальшивый RPLY (TO_RPLY), который завершает цикл чтения, затем дает сигнал ABORT (сбросить микропрограммный автомат и стартовать с микрокоманды 0x01). При этом устанавливается флаг IX1=1, что говорит микропрограмме, что чтение в кэш накрылось медным тазом, и надо отмотать PC на два байта назад, и начать с команды 0x21. После чего выполняется команда 0x21 (запрос кэширования инструкции), и затем опять 0x01.
Но повторный цикл чтения несуществующей ячейки уже выполняется не в цикле IO_RCD, а в цикле IO_CMD, т.к. запрошен из команды 0x21. Поэтому когда наступает таймаут, блок таймаута не генерирует фальшивый RPLY, a сразу дает ABORT и TOVF (запрос прерывания по ошибке шины).

И тут возникают некоторые нюансы.
1. Ошибочный цикл чтения запрошенный командой 0x01 не порождает прерывание по ошибке шины, а делает повторную попытку прочитать инструкцию, но уже микрокомандой 0x21.
2. Если цикл чтения был изначально запрошен командой 0x21 (например, после любой команды, сбрасывающей кэш, т.к. использует его содержимое или меняет PC), то прерывание по ошибке шины произойдет сразу.

Если во время ошибочного цикла чтения пришел запрос на какое-то прерывание, то:
1. В случае команды 0x01 это прерывание нормально обработается сразу после окончания ошибочного цикла.
2. В случае команды 0x21 сперва будет вызвано прерывание по ошибке шины, и только потом может быть обработано запрошенное прерывание.

И еще несколько нюансов.
1. Если во время команды 0x01 была ошибка шины и при этом был запрос прерывания, то этот запрос обработается нормально, но PC будет с опережением на 2, т.к. в начале следующей повторной команды 0x01 не выполняется коррекция PC=PC-2, а сразу уходит на обработку прерывания.
2. На сколько я понимаю, с обработчиком прерывания по ошибке шины происходит та же фигня - PC на 2 больше, чем адрес ошибки.

Vslav
24.12.2020, 10:57
Ибо, это два важнейших сигнала из-за которых все и затевалось)

Ну если так - перекачай (https://www.1801bm1.com/files/images/vm2_1500-22000.pdf), я обновил диаграммы.

Titus
24.12.2020, 14:11
Ну если так - перекачай , я обновил диаграммы.
Мои теоретические графики совпали)

Vslav
24.12.2020, 14:17
Мои теоретические графики совпали)
Не может быть! Это ты уже отмечать начал? :)

hobot
24.12.2020, 14:17
Ну если так - перекачай (https://www.1801bm1.com/files/images/vm2_1500-22000.pdf), я обновил диаграммы.


Мои теоретические графики совпали)


https://youtu.be/mVSnfz5tgP4

Titus
24.12.2020, 14:25
Не может быть! Это ты уже отмечать начал?
Я не пью от слова совсем)

Alex_K
26.12.2020, 23:38
Надо сделать тест типа ADD -(PC),R5, тогда мы хотя бы косвенно сможем понять, сколько раз эта команда выполнилась по итоговой сумме.
Сделал. Сама программа:


1000 005000 CLR R0
1002 005001 CLR R1
1004 005002 CLR R2
1006 005003 CLR R3
1010 005005 CLR R5
1012 010505 MOV R5,R5
1014 064705 ADD -(PC),R5
1016 005200 INC R0
1020 005201 INC R1
1022 005202 INC R2
1024 005003 INC R3
1026 000000 HALT

На первом рисунке УКНЦ ещё не прогрелся, потому и результаты плавают: то R1 увеличится не на два, то оба регистра R0 и R1 увеличатся только на один. Потом всё устаканилось (на втором рисунке) - складываются сама команда ADD -(PC),R5 и следующая за ней команда INC R0. На первом рисунке есть случай, что прибавилась только команда INC R0.

Titus
27.12.2020, 00:03
На первом рисунке УКНЦ ещё не прогрелся, потому и результаты плавают
А чего это они плавают, у нас же цепочка задержки по SYNC стоит только у ПП, а у ЦП не стоит?

- - - Добавлено - - -

По тестам все верно выходит, ADD -(PC),R5 выполняется два раза, как я и описывал выше.

- - - Добавлено - - -

Может быть и тот второй тест с NOP'ами поэтому я не мог разложить на микрокод, т.к. там плавали времянки как в первом скриншоте тут?

Alex_K
27.12.2020, 00:07
А чего это они плавают, у нас же цепочка задержки по SYNC стоит только у ПП, а у ЦП не стоит?
Хоть стоят и кварцевые генераторы, но при нагреве частота чуть уплывает, становится медленнее. Да и задержка чтения памяти в ЦП определяется видеоадаптером, а они с ЦП тактируются по разному. Так что задержка по SYNC тут особо и не при чём, тут сказывается задержка между DIN и RPLY.

Titus
27.12.2020, 00:27
Хоть стоят и кварцевые генераторы, но при нагреве частота чуть уплывает, становится медленнее. Да и задержка чтения памяти в ЦП определяется видеоадаптером, а они с ЦП тактируются по разному. Так что задержка по SYNC тут особо и не при чём, тут сказывается задержка между DIN и RPLY.
Тут чего-то не так.
Уплывание частоты на кварцевом резонаторе столь ничтожное, что сказываться не может.
Тактируются по-разному, но оба кварцами, тоже уплывать нечему.
Единственный вариант, это ПП плавая сам, утягивает за собой все остальные времянки, т.к. когда он пишет в видеопамять, отбирается временной слот памяти у ЦП.
Хорошо бы тесты проводить при ПП крутящемся в холостом цикле.

Alex_K
27.12.2020, 00:40
Единственный вариант, это ПП плавая сам, утягивает за собой все остальные времянки, т.к. когда он пишет в видеопамять, отбирается временной слот памяти у ЦП.
Хорошо бы тесты проводить при ПП крутящемся в холостом цикле.
Titus, что вы пишете? Ведь сами разбирали видеоадаптер по кирпичикам. Выделяются окна по 320 нс, одно видеоадаптеру, другое процессору. Потому чтение в ЦП занимает время от 320 нс (весьма повезло) до 960 нс (не повезло), но надо корректировать с учётом частоты ЦП.

А по поводу отнятия слота памяти, то тесты я провожу в пультовом отладчике, во время его работы ПП не лезет в память ЦП через регистры 0177010/0177014. Хотя при запуске один раз залазит, чтобы сбросить флаг в системном ОЗУ ЦП, сообщает пультовому отладчику, что сигнал HALT снят, можно запускать программу. А при исполнении программы вообще не лезет.

- - - Добавлено - - -


Может быть и тот второй тест с NOP'ами поэтому я не мог разложить на микрокод, т.к. там плавали времянки как в первом скриншоте тут?
Там ситуация почище бывает. Иногда, редко, происходит TRAP10. Вот как это объяснить?

Titus
27.12.2020, 00:46
Titus, что вы пишете? Ведь сами разбирали видеоадаптер по кирпичикам. Выделяются окна по 320 нс, одно видеоадаптеру, другое процессору. Потому чтение в ЦП занимает время от 320 нс (весьма повезло) до 960 нс (не повезло), но надо корректировать с учётом частоты ЦП.
Все я помню.
Но эти биения они не должны меняться с нагревом, т.к. нечему уплывать. Нет в цепи видеоконтроллера и ЦП времязадающих цепочек на конденсаторах. А уплывание ПП не должно на них сказываться.

- - - Добавлено - - -


Там ситуация почище бывает. Иногда, редко, происходит TRAP10. Вот как это объяснить?
Вот этого я не знаю. Надо делать разные тесты с NOP'ами, от самых просйтейших.
И смотреть, как это можно обьяснить с помощью микрокода и знаниях о схеме.

Ynicky
31.01.2021, 10:00
Вроде немного оклемался после перенесенной болезни (COVID-19) и месяца восстановления. Стал вспоминать на чем остановился. Частично (что получилось) перевел зашивки в синхронный дизайн. Остановился на том, что в тестовой программе выдачи цветных вертикальных полос работает как ПП, так и ЦП. Т.е. программа из ПП переписывается в память ЦП и ЦП стартует и отрабатывает эту программу. При зашивке штатной ПЗУ видно следующее:

https://www.youtube.com/watch?v=9r3_iCToY0U
Даже основная область экрана заполняется голубым цветом, но потом все исчезает и
заполняется полосами. Хочу пока оставить проект как есть (пока дышит) и проверить логику зашивок. Но у меня не хватает знаний для написания тестовых программ. Если поможете, то создам новую тему, где можно будет это обсуждать.

Hunta
31.01.2021, 12:13
С выздоровлением!

Titus
31.01.2021, 14:37
Даже основная область экрана заполняется голубым цветом, но потом все исчезает и
заполняется полосами. Хочу пока оставить проект как есть (пока дышит) и проверить логику зашивок. Но у меня не хватает знаний для написания тестовых программ. Если поможете, то создам новую тему, где можно будет это обсуждать.
С тестами лучше всего поможет, наверное, Alex_K.

Ynicky
16.05.2021, 19:05
Titus, что означает такой знак? В ГОСТе я такого не нашел.
75418

Titus
16.05.2021, 19:15
Titus, что означает такой знак? В ГОСТе я такого не нашел.
75418

Тактирование по переднему фронту.
Так обозначается в P-CAD'е.

Ynicky
16.05.2021, 19:23
Меня смутило такое:
75419

Titus
16.05.2021, 19:43
Меня смутило такое:
75419

А что именно смутило?

Ynicky
16.05.2021, 20:20
А что именно смутило?
Сигнал по уровню отрицательной полярности.

Titus
16.05.2021, 20:26
Сигнал по уровню отрицательной полярности.

В P-CAD'е это иначе.

newart
08.01.2022, 19:36
А спектрумовские БМК кто-нибудь пробовал реверсить или хотя бы фотографировать?

Я про:

КА1515ХМ1-216
КА1515ХМ1-458
КА1515ХМ1-433
КА1515ХМ1-6004
КА1515ХМ1-6003
КА1515ХМ1-6108
КА1515ХМ1-6006
КА1515ХМ1-6008
КБ01ВГ1-2
КН1854ВГ5
СК1
И185

Titus
08.01.2022, 21:37
По умолчанию

А спектрумовские БМК кто-нибудь пробовал реверсить или хотя бы фотографировать?

Скорее всего этот вопрос лучше задать в разделе Цифровая археология (https://zx-pk.ru/threads/23978-tsifrovaya-arkheologiya-1801-i-vse-vse-vse.html)

Vslav
09.01.2022, 00:32
Скорее всего этот вопрос лучше задать в разделе Цифровая археология (https://zx-pk.ru/threads/23978-tsifrovaya-arkheologiya-1801-i-vse-vse-vse.html)
Это почему? Там тема для серии 1801 :)

Titus
09.01.2022, 01:06
Это почему? Там тема для серии 1801

А здесь для УКНЦ) Не гони человека, дай ему наводку)

Vslav
09.01.2022, 01:56
А здесь для УКНЦ) Не гони человека, дай ему наводку)
Я не гоню, было бы что дать :)

electroscat
07.06.2022, 02:23
Доброго времени ! Недавно столкнулся с проблемой, 1515ХМ1-031 не могу найти, нашел только на развандаленных горелкой донорах, но увы, одна оказалась с оборванными пинами входов клавиатуры, вторая вообще не заработала. Ну и вернув первую - в целом тоже не получил ничего, прогрев феном оказался критичным. Вижу этот форум, пока не изучил его весь, но наверняка это произойдет в ближайшее время. Тем не менее, если позволите - практичный вопрос - имея схему 1515ХМ2-001 или 1515ХМ1-031 (похоже она есть в этой ветви) - как мне ее практично запихать в плис и припаять к мат. плате УКНЦ ? Ну то есть, я готов потестировать теорию на практике. Есть уже такой опыт у кого то ?

Sandro
07.06.2022, 08:01
"Практично" -- по всей видимости, никак. Для запихивания в ПЛИС нужно описание на языке высокого уровня, то есть VHDL или Verilog. Причём синтезируемое. То есть, не содержащее таких конструкций языка, которые невозможно реализовать в физическом железе. Насколько мне известно, дело до этого так и не дошло.
Можешь попробовать сделать такое сам :)

Hunta
07.06.2022, 08:29
Насколько мне известно, дело до этого так и не дошло.
Дело дошло, но до конца не доделано, так как - не взлетало

andrews
07.06.2022, 10:11
Можно дохлых потрошить 1515ХМ2-001 или 1515ХМ1-031(но их много надо и дорого это), а можно живых обследовать. Это тоже долго и муторно. Можно из воздуха "сочинять по мотивам" частично функционально. И вряд ли найдется чел или контора триединый во всех этих амплуа.

Radon17
07.06.2022, 11:08
как мне ее практично запихать в плис и припаять к мат. плате УКНЦ ?
Не имеет совершенно никакого смысла. УКНЦ столько сделали, что легче найти донора или вообще машину на замену.
Если уж говорить про ПЛИС, то надо пихать туда всю машину целиком, как это уже сделали с ДВК. Так сказать, для будущих поколений.

Sandro
07.06.2022, 19:36
Не нужно ничего сочинять из воздуха, есть же реверс всех кристаллов вроде как. Просто этот реверс ты в FPGA не запихаешь без дополнительной работы.

Arseny
07.06.2022, 19:40
Тем не менее, если позволите - практичный вопрос - имея схему 1515ХМ2-001 или 1515ХМ1-031 (похоже она есть в этой ветви) - как мне ее практично запихать в плис и припаять к мат. плате УКНЦ ? Ну то есть, я готов потестировать теорию на практике. Есть уже такой опыт у кого то ?
Читай УКНЦ отсутствие микросхемы (https://zx-pk.ru/threads/29614-uknts-otsutstvie-mikroskhemy.html). Камрад ZPilot делал замену на основе МК - пообщайся с ним.

BlaireCas
10.09.2022, 16:48
Даже не знаю где спросить. Поэтому тут возможно даже подходящая тема.
Почитав документацию на процессор 1801ВМ2 - обнаружил что команда MTPS байтовая. То-есть якобы бесполезно писать что-то навроде mtps #600 мол она не "скушает" старший байт.
Но в дизассемблерном ПЗУ от УКНЦ именно такое и есть!

(код с http://www.emuverse.ru/wiki/%D0%A3%D0%9A%D0%9D%D0%A6_ROM_disasm_6)


; Обработка выхода из пультового отладчика (УПР-C)
161206$:TST R4 ; Пультовый монитор работает под упр. ПП ?
BMI 161034$ ; Нет
CLR @#22550
MTPS #600
MOV @#7144,SP ; Восстановить стек режима УСТАНОВКА
CLR R0
$MTPS$ ; PS = 0
$MTPC$ ; PC = 0

Это как? Ошибка разработчика или что-то другое? Командой mtps можно перевести процессор в HALT-режим?

Alex_K
10.09.2022, 17:55
Это как? Ошибка разработчика или что-то другое? Командой mtps можно перевести процессор в HALT-режим?
Да, команда MTPS действительно только байтовая, как и MFPS. Потому перевести процессор с помощью неё в HALT-режим невозможно, так же как и узнать с помощью MFPS, работает ли процессор в HALT-режиме.
Так что эту команду в системном ПЗУ можно считать ошибкой разработчика. А может так специально сделали для наглядности, ведь пультовый отладчик всегда работает в HALT-режиме.

BlaireCas
10.09.2022, 18:21
А может так специально сделали для наглядности
Там еще есть mtps #340 (битовое 1110 0000, флаги P**TNZVC). То-есть два флага неясно зачем ставят. Они "вроде" ни на что не влияют в регистре состояния. Может конечно быть из то-же серии "работает же, не трожь!"

Alex_K
10.09.2022, 18:31
Там еще есть mtps #340 (битовое 1110 0000, флаги P**TNZVC). То-есть два флага неясно зачем ставят. Они "вроде" ни на что не влияют в регистре состояния. Может конечно быть из то-же серии "работает же, не трожь!"
Ну это сделали для совместимости с другими процессорами. Так как адаптер локальной сети сделан на 1801ВП1-065, то загрузчик и тест могли взять с других мест. А эти общие места могли работать и на 1801ВМ3, там только MTPS #340. К тому же биты 5 и 6 реально присутствуют в PSW, только они ни на что не влияют.
Так же MTPS #340 есть и подпрограмме печати экрана, но она написана на Си.

Sandro
10.09.2022, 19:06
КМК, с ВП1-65 это не связано :)
Просто принято писать именно MTPS #340, чтобы заведомо работало везде, да.

BlaireCas
16.09.2022, 20:10
Еще момент заметил. Если в периферийном процессоре при обработке прерывания от клавиатуры не считать каким-либо образом регистр (tst @#177702 хотя-бы) - то почему-то потом контроллер клавиатуры (возможно это одна из этих микросхем) "портится".
Сделал свое прерывание на клавиатуру, пытался поначалу просто определять факт того что оно сработало (что-то нажали). Ничего не читая из регистра и выходя в RT-11. Получилось как-то "не очень", кнопки "зависли". (а в EmuStudio кстати пофиг, там не зависли, зависли на реале и unkcbtl)

Alex_K
16.09.2022, 20:54
Еще момент заметил. Если в периферийном процессоре при обработке прерывания от клавиатуры не считать каким-либо образом регистр (tst @#177702 хотя-бы) - то почему-то потом контроллер клавиатуры (возможно это одна из этих микросхем) "портится".
Сделал свое прерывание на клавиатуру, пытался поначалу просто определять факт того что оно сработало (что-то нажали). Ничего не читая из регистра и выходя в RT-11. Получилось как-то "не очень", кнопки "зависли". (а в EmuStudio кстати пофиг, там не зависли, зависли на реале и unkcbtl)
Есть в УКНЦ особенности работы с прерываниями на аппаратном уровне в некоторых микросхемах.
А можно поподробнее что было дальше: возникло прерывание, регистр 0177702 не считали, вышли в RT-11... А вектор восстановили? Бит разрешения прерывания дергали?

BlaireCas
16.09.2022, 21:55
Есть в УКНЦ особенности работы с прерываниями на аппаратном уровне в некоторых микросхемах.
А можно поподробнее что было дальше: возникло прерывание, регистр 0177702 не считали, вышли в RT-11... А вектор восстановили? Бит разрешения прерывания дергали?

Вектор восстановлен. Ничего не дергалось. Процесс был запущен как-обычно в диспетчере процессов ПП, прерывание там рядом переназначено. После возникновения прерывания был выход с него (тупо inc KeyDwn; rti). Далее в диспетчере задач по дохождению до кода было видно что что-то нажали, был выход из диспетчера и затем ЦП давал команду на очистку памяти ПП. Вообщем обычное дело.
Ну так вот - если не делать считывание из ячейки по возникновению прерывания - затем блокировались например .ttyin (висело в бесконечном цикле) в ЦП. Нажатия клавиш тоже не слышно было.

Помогло в прерывании тупо сделать считывание с ячейки (пометка что вызвалось нажатие клавиши как и раньше оставалась) и rti потом. Без считывания с ячейки происходил факап какой-то.
Я делал это в соседней теме про косичку от Manwe для БК-0010 чтобы по возникновению прерывания тупо выйти из всего в RT-11. Вот без считывания выходит "косячно". Если в прерывании считывать адрес - выходит нормально.

Вот такой код прокатил:

; 'keyboard' interrupt
INTKB1: mov R0, -(SP)
mov @#177702, R0
; TODO: change drawing variables in CPU from pressed keys
inc KEYPR0
mov (SP)+, R0
rti

Закомментировав строку с mov @#177702.. - уже не прокатывает.

Правда есть момент - я не менял ВЕСЬ вектор. Только адрес прерывания, и восстанавливал его также. Но думается это иррелевантно что там в PS проца запишется, как и раньше оставалось-же.

Весь код (он большой конечно и может быть там косяки?) где-то тут: https://raw.githubusercontent.com/blairecas/kosich/master/kosich.mac
Но сама рисовка там в ЦПУ ничего не портит. А в ПП достаточно закомментить считывание по прерыванию из 177702 и после выхода в RT-11 ничего больше не нажмешь.

Alex_K
16.09.2022, 22:11
Вектор восстановлен. Ничего не дергалось. Процесс был запущен как-обычно в диспетчере процессов ПП, прерывание там рядом переназначено. После возникновения прерывания был выход с него (тупо inc KeyDwn; rti). Далее в диспетчере задач по дохождению до кода было видно что что-то нажали, был выход из диспетчера и затем ЦП давал команду на очистку памяти ПП. Вообщем обычное дело.
Ну так вот - если не делать считывание из ячейки по возникновению прерывания - затем блокировались например .ttyin (висело в бесконечном цикле) в ЦП. Нажатия клавиш тоже не слышно было.

Помогло в прерывании тупо сделать считывание с ячейки (пометка что вызвалось нажатие клавиши как и раньше оставалась) и rti потом. Без считывания с ячейки происходил факап какой-то.
Я делал это в соседней теме про косичку от Manwe для БК-0010 чтобы по возникновению прерывания тупо выйти из всего в RT-11. Вот без считывания выходит "косячно". Если в прерывании считывать адрес - выходит нормально.
Естественно считывать ячейку 0177702 нужно обязательно. Сигнал запроса на прерывание устанавливается по фронту сигналов IE & RDY, т.е. если предыдущее значение бита готовности .И. разрешения прерывания было нулём, а новое стало единицей, то контроллер выставляет сигнал запроса на прерывание. Сбрасывается этот запрос удовлетворением прерывания, т.е. контроллер передаёт вектор, вызывается подпрограмма обработки. Вот если в подпрограмме обработки не считали регистр, то IE & RDY останутся единицей, и нового запроса на прерывание не будет, даже если нажмут клавишу. А при чтении регистра происходит сброс бита готовности, поэтому при новом нажатии снова возникнет фронт сигнала IE & RDY и будет выставлен новый запрос на прерывание.

BlaireCas
16.09.2022, 22:33
Я в железках не очень понимаю, но вообщем тут все сложно :) Ух кошмар. Какие-то люди давно сделали на этих там вон плис или как оно называется - цельный спектрум. А тут жуть какая-т. (да и не нужно никому :(
Что-ж делать когда эти все микросхемы сдохнут.. эээ.. ну ладно. Не надо о грустном.

Никита вон сделает авось эмуль на джаваскрипт (уже!) и может и нормас.

(извиняюсь заранее, несколько эдаким "быдло-стайл" языком тут пишу, что удивительно для человека пишущего код на макро-11, но как-то так, не обижайтесь, это всё случайности, когда перечитываю сам в шоке)

nzeemin
18.09.2022, 22:57
Я в железках не очень понимаю, но вообщем тут все сложно :) Ух кошмар. Какие-то люди давно сделали на этих там вон плис или как оно называется - цельный спектрум. А тут жуть какая-т. (да и не нужно никому :(
Что-ж делать когда эти все микросхемы сдохнут.. эээ.. ну ладно. Не надо о грустном.

Никита вон сделает авось эмуль на джаваскрипт (уже!) и может и нормас.

Как раз таки, я очень очень надеюсь, что кто-нибудь всё же пройдёт эту дорогу и сделает полнеценно работающий УКНЦ в ПЛИС.
Выглядит так, что все кусочки для этого уже есть.

Оффтопик: Эмулятор УКНЦ на JavaScript есть, но он писан не мной - там чисто код на Си++ переписан в JS. А я делал эмулятор на основе WebAssembly - это тот же Си++ код ядра UKNCBTL, собранный через Emscripten.

randomizer
19.09.2022, 00:40
Что-ж делать когда эти все микросхемы сдохнут.. эээ.. ну ладно. Не надо о грустном.
Распереживавшись, что могу остаться без УКНЦ, как то со временем обзавёлся несколькими комплектами БМК, и несколькими рабочими платами.
Сейчас всё же думаю что есть зерно истины в словах: - "УКНЦ наделали столько, что несмотря на металлистов, и нам и нашим детям хватит")

Я не к тому, что не нужно увековечивать УКНЦ в FPGA.
Просто к радости немногих любителей, она оказалась наиболее массово производившимся компьютером.

Titus
19.09.2022, 02:04
Выглядит так, что все кусочки для этого уже есть.
Не выглядит, а есть.

И даже один форумчанин начал собирать это дело в ПЛИС, но что-то пошло не так, и рабочий результат пока не получен.

ZPilot
19.09.2022, 17:42
Не выглядит, а есть.
А где можно посмотреть на эти кусочки?

nzeemin
19.09.2022, 19:28
А где можно посмотреть на эти кусочки?

В том числе в этой теме.

Я пытался выписывать текущее состояние, но наверное нужно обновлять: http://www.emuverse.ru/wiki/%D0%A3%D0%9A%D0%9D%D0%A6_%D0%91%D0%9C%D0%9A

Да, ещё процессор вот тут: https://github.com/1801BM1/cpu11

newart
20.09.2022, 10:37
Сейчас всё же думаю что есть зерно истины в словах: - "УКНЦ наделали столько, что несмотря на металлистов, и нам и нашим детям хватит")
Это правда, в год их всплывает по несколько сотен. Как минимум треть с обычными конденсаторами, поэтому для утилизаторов большого интереса не представляют.

ZPilot
20.09.2022, 14:40
Я пытался выписывать текущее состояние, но наверное нужно обновлять: http://www.emuverse.ru/wiki/%D0%A3%D...91%D0%9C%D0%9A
Было бы очень здорово. Спасибо!

nzeemin
06.10.2022, 14:28
Уже очень давно (13 лет назад) у Феликса были наработки по работе УКНЦ в ПЛИС:
https://github.com/troosh/ukncbtl/tree/master/hw/ukfpga
https://github.com/troosh/ukncbtl/tree/master/hw/ukfpgadxp
Это как-то можно использовать?

Вообще, рассказал бы кто знающий, чего сейчас нехватает для того чтобы УКНЦ работал на каком-нибудь современном ПЛИСе?

Titus
06.10.2022, 17:19
Вообще, рассказал бы кто знающий, чего сейчас нехватает для того чтобы УКНЦ работал на каком-нибудь современном ПЛИСе?
Не хватает только желания перевести отреверсенные схемы из ХМ-ок в ПЛИС, добавить к ним уже готовый ВМ2 и почти все.

- - - Добавлено - - -


Уже очень давно (13 лет назад) у Феликса были наработки по работе УКНЦ в ПЛИС:
Сомневаюсь, т.к. это не на основе реверса.

Titus
30.03.2024, 14:45
Нашел небольшую ошибочку в реверсе 1515ХМ2-001.

Выход OUT4 (ножка 62) должен быть комплиментарный, а не с открытым коллектором, как нарисовано сейчас.

Вот так правильно:
https://pic.maxiol.com/images2/1711799120.1595417148.out4.png

Alex_K
25.08.2024, 18:39
3. Режим разбора запроса программного прерывания (стробируется сигналом PI_STB). Инициируется, если PLM0=1. Используется в инструкциях программных прерываний.

нет описания
А описание будет?

Titus
25.08.2024, 19:42
А описание будет?
Не дописал я его?
Пока занимаюсь другими проектами, а этот вообще забыл)
Наверное, проще вам самим посмотреть по логической схеме, как это работает.

predatoralpha
24.09.2024, 00:11
Всем привет! Грандиозная работа!
Решил вспомнить студенчество и курсовую по 1515, решил по приколу разобрать пару ячеек:

Возник вопрос по V ячейке. Догадываюсь, что это мультиплексор аналоговый, вижу кроссоединение затворов, соединение посередине двух стоков, но не вижу куда идет соединение от двух внутренних полишин, такое ощущение что они от внутренних переходных ни с чем не соединены, хотя сигнал снаружи явно приходит.... Кто-то может помочь?

https://s1.hostingkartinok.com/uploads/thumbs/2024/09/3a1965160b4e8abc34a46e680b8e7dbf.png (https://hostingkartinok.com/show-image.php?id=3a1965160b4e8abc34a46e680b8e7dbf)

https://hostingkartinok.com/show-image.php?id=3a1965160b4e8abc34a46e680b8e7dbf

Пересмотрел пару десятков таких элементов, нигде нет и следа перехода метализации к этим отверстиям. Заметил, что во многих элементах тоже есть такая тенденция - завод сигнала на полишину, а к переходному внутри нет метализации. Причем шина явно не сквозная, между разными зонами коммутации - с другой стороны выхода нет.
Похоже, эти полишины часть транзистора.

predatoralpha
01.10.2024, 00:25
Разобрался. Транзисторы внутри соединены, подобно NAND памяти, а пары переходных отверстий запаралелены. Я упорно искал связи между транзисторами на поверхности в слое метализации... )))

felix
10.10.2024, 17:06
Уже очень давно (13 лет назад) у Феликса были наработки по работе УКНЦ в ПЛИС:

Как давно это было... =)
Врядли это поможет - это я начал писать на основе документации а не реверса

shattered
04.01.2025, 15:27
Отличия 035/065 от DL11-E с точки зрения программиста, по материалам

- "Микpопpоцессоpы и микpопpоцессоpные комплекты интегpальных микpосхем" Шахнова, том 2 (1988)
- "МикроЭВМ в 8-ми книгах", книга 2 (1988)
- https://github.com/1801BM1/k1801/blob/master/065/
- http://www.ibiblio.org/pub/academic/computer-science/history/pdp-11/hardware/micronotes/numerical/micronote33.txt
- EK-DL11-TM-003_DL11_Asynchronous_Line_Interface_Manual_Sep75. pdf

035 и 065:

всегда посылают 2 стоп-бита
не реализованы биты RCVR ACT (11) и RDR ENB (0) в RCSR
биты ошибок -- в RCSR, не RBUF, и не очищаются новыми данными -- только по INIT или чтению RBUF
при переполнении в RBUF остаются предыдущие данные
запись RBUF не делает ничего
INIT не выставляет DONE в TCSR (это делает только DCLO)
чтение TBUF возвращает вектор прерывания
выход EVNT (2) выдает сигнал частотой 50 гц

035:

выход HALT (31) отражает состояние приемника BREAK (для останова центрального процессора)

065:

поддерживает full duplex и rts/cts handshaking -- вход nBSYD (29) и выход nRR (31)
не поддерживает формат слова 5 бит
выход HALT отсутствует, состояние BREAK отражается в бите 0 RCSR

Alex
09.01.2025, 10:55
в -035 только один флаг, по этому на платах с -035 стоит перемычка. И посмотреть можно только подкнут кабель или нет.
Кабель стоит - готовность есть... Нет кабеля - нет готовности.

в -065 реализованы оба флага(готовности как приёмника, так и передатчика), по этому можно использовать как аппаратную информацию о переполнении буфера.
Бывает, что на флаги плюют, всё всегда готово... Разбираются что да как программно.

В УКНЦ со С2(RS-232) интересно поступили, так как в -065 всего два флага, остальные флаги реализовали дополнительной аппаратурой. Чисто как биты ввода-вывода.