Вход

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



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

Vslav
09.10.2020, 18:17
На сколько я понимаю, Ynicky брал мои схемы, и прекрасно безо всяких проблем делал по ним HDL.
Ты просто не знаешь что такое по-настоящему прекрасно. Если бы ты меня послушал и нарисовал бы схему в БФЯ, то мы напустили бы мой генератор HDL на эту схему и уже давно имели бы референсную модель всех ХМ-ок.
Автоматически. А потом, имея рабочий моделируемый референс приводили бы схему в человеческий вид. Как это было, например, с ВП1-037. Но ты пошел своим путем и приходится закат солнца делать вручную. Времени же у нас вагон, девать некуда, да?

Hunta
09.10.2020, 18:18
Сразу и без ошибок ничего не делается.
Правда. А кто тут утверждал

На сколько я понимаю, @Ynicky брал мои схемы, и прекрасно безо всяких проблем делал по ним HDL.
Так есть в них ошибки или нет?

Vslav
09.10.2020, 18:23
Так есть в них ошибки или нет?
Пока неизвестно. Но маршрут выбран тяжелый, с большим количеством ручного труда, вероятность ошибок заметная. Если бы делали как я предлагал (послушали бы опытного человека), то рисовали бы точно по БФЯ как сделаны ВП1, там маппинг 1-в-1, вероятность ошибок заметно меньше, ручного труда минимум, автоматическая сверка с топологией, сразу моделируются времянки реальном микросхемы (можно вычислить из модели примерные Tsu, Th и прочие, увидеть пички и всяко разно) да еще и мгновенно автоматически генерируется верилог. Но кому оно надо? Наш путь - страдание...

Titus
09.10.2020, 18:29
Если бы делали как я предлагал
Уверен, что Ynicky делал HDL ВП1-120 по моей оптимизированной схеме, а не по базовой, которую делал ты. С чего бы это? Может потому, что моя удобнее для понимания)

Vslav
09.10.2020, 18:33
Кстати, Degate обновили, уже должен работать под Windows. Я попытаюсь участвовать в разработке, но время, время...

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


Уверен, что Ynicky делал HDL ВП1-120 по моей оптимизированной схеме, а не по базовой, которую делал ты. С чего бы это? Может потому, что моя удобнее для понимания)
Угу, а мою модельку вообще делать было не надо. Для начала и так заработала бы.

Titus
09.10.2020, 18:36
Угу, а мою модельку вообще делать было не надо. Для начала и так заработала бы.
А что, была модель? Не знал.

Vslav
09.10.2020, 18:41
А что, была модель? Не знал.
? И не только модели для всех ВП1, но и тестбенчи.
Есть простой автоматический генератор Verilog, ему достаточно скормить любую мою схему в БФЯ и получить модель, с кучей реальных плюшек. Автоматически. Минуя стадии ручного труда и не внося никакх ошибок.
Машинный генератор против твоей человеческой уверенности "я так думаю" :)
Ну внутри выглядят эти модельки не очень, но это референс, пишешь на ее основе свою, и постоянно сравниваешь с референсом. Качество проекта определяется не наличием ошибок, а умением инженеров их обезвреживать. Вот этот референс и есть отличный и автоматизируемый путь ошибки выловить, в простой и понятный способ.

Titus
09.10.2020, 19:23
Каждый занимается хобби прежде всего для себя.
Мне для себя нужны логические схемы, и ничто иное.
Мне для себя интересно понимание по схемам всех нюансов работы.
Если это полезно не только мне, но и другим, я выкладываю.

Vslav
09.10.2020, 19:37
Каждый занимается хобби прежде всего для себя.
Мне для себя нужны логические схемы, и ничто иное.
Мне для себя интересно понимание по схемам всех нюансов работы.

Вижу только "себя". Так тоже можно, имеешь право. Но... Командная работа? Синергия? Не, не слышал...
Реверс - это очень ресурсоемкое занятие, объединение или хотя бы координация усилий тут помогли бы. Но это не твой случай...

Titus
09.10.2020, 19:50
Вижу только "себя". Так тоже можно, имеешь право. Но... Командная работа? Синергия? Не, не слышал...
Реверс - это очень ресурсоемкое занятие, объединение или хотя бы координация усилий тут помогли бы. Но это не твой случай...

Конечно, командная.
Ты сделал фотки чипов, я реверсил.
Ты сделал реверс ВМ2 в транзисторах, я перевел еще и в логику.
Каждый сделал то, что умеет.
Того и гляди появится ФПГА УКНЦ, основанная на вкладе каждого. А каждый делал то, что умеет, и то, что ему близко.
И, кстати, я не говорю, что ты не так что-то делаешь ни разу, между прочим) Хотя тоже имею свой взгляд на реверс)

TheGWBV
09.10.2020, 19:57
>Того и гляди появится ФПГА УКНЦ
То-то уже искрит в воздухе :)

Vslav
09.10.2020, 19:59
Конечно, командная.
Ты сделал фотки чипов, я реверсил.

Вот и прикинь что если бы я фотки ХМ1 не сделал. А зачем?
Мне оно для себя не надо, УКНЦ у меня никогда не было, еще время и бензин тратить, 80км в два конца химику новые чипы везти...



Ты сделал реверс ВМ2 в транзисторах, я перевел еще и в логику.
Каждый сделал то, что умеет.
Того и гляди появится ФПГА УКНЦ

И ты никого не услышал. Поварился сам в своем котле и просто свалил все на других.
А услышал бы и сделал бы нормально в БФЯ - у нас УЖЕ была бы модель УКНЦ.
Ты как плотник который умеет только гвозди забивать:
- А может быть HDL шурупы попробуешь?"
- Не, это же отверткой научится пользоваться придется!!
- Мне для себя нужны логические схемы гвозди, и ничто иное.

Хм, ты еще работаешь? В ай-ти? Как же оно без нового? :)

PS. Новые XM1/2 химику отвезу, не переживайте.

Titus
09.10.2020, 20:18
Хм, ты еще работаешь? В ай-ти? Как же оно без нового?
Оно не новое, оно мне не нужное.
Зачем мне HDL, если я не делаю FPGA-версии?
Я эмуляторщик. Для эмуляции мне нужна четкая схема, четкое описание. Я это делаю.
HDL мне для этого все равно, что козе боян, как ты этого понять не можешь)

Vslav
09.10.2020, 20:38
что козе боян, как ты этого понять не можешь)
Конечно не могу, изучать что-то новое - это и есть самый фан и поддержание мозга в тонусе. Мы уже с тобой люди не особо молодые, перестанем учиться - и подковы можно будет сдирать. Verilog - оно мне тоже не нужное, я сейчас вообще чистым SWE работаю. Но как оно дальше в жизни повернется - неизвестно, а я в тонусе и у меня постоянно растет процент жиров в масле расширяется кругозор и растет список скиллов.

Titus
09.10.2020, 20:40
Конечно не могу, изучать что-то новое - это и есть самый фан и поддержание мозга в тонусе.
Вообще-то у меня куча проектов помимо УКНЦ)
Не говоря уже о работе, где куча языков и не только.
Так что тонуса там предостаточно)

Vslav
09.10.2020, 20:55
Вообще-то у меня куча проектов помимо УКНЦ)
Да ну? Извини, сложно догадаться - судя по щедрому расходу времени на перерисовывание уже пережеванного.


Так что тонуса там предостаточно)
То не тонус, то спазм - перерисовывать готовую схему у кого хошь такое будет :)
Тонус был бы, если бы изучил HDL и сделал бы УКНЦ in smart way.
В-общем, непонятно мне это абсолютно, изучить новое, сэкономить свое личное время, поучаствовать в новой разработке - "не, мне это не надо, я гвозди люблю".
Вот перерисовал ты ВМ2, что на выходе? На что повлияет? Ну изучил ты внутренности, через полгода забудешь, наглухо (я лично забыл). Модель новая появится? Маловероятно. Времянки модельнутся? Не-а. Кто-то еще принцип посмотрит? Так их можно было и на заводской схеме палить.

Titus
09.10.2020, 20:59
Вот перерисовал ты ВМ2, что на выходе?
На выходе понятная и удобная логическая схема, и мое понимание всего, что мне надо)

Тебе бы агитатором работать) Меня бы, конечно, не завербовал, но думаю, человек 9 из 10 точно)

Vslav
09.10.2020, 21:08
На выходе понятная и удобная логическая схема, и мое понимание всего, что мне надо)
Чорт, надо мне репку сделать приватной. Буду реверсить себе процессоры потихоньку, получать только мне понятный фан, и никому больше не показывать :)

hobot
09.10.2020, 21:18
Неужели раскол в двух шагах до победы?

Titus
09.10.2020, 21:18
Чорт, надо мне репку сделать приватной. Буду реверсить себе процессоры потихоньку, получать только мне понятный фан, и никому больше не показывать
Не утрируй, дорогой друг)

Vslav
09.10.2020, 21:26
Неужели раскол в двух шагах до победы?
Да какой раскол, просто долго это все тянется, времени реально надо много, вот хочется ускорить процесс. Мне :)

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


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

Titus
09.10.2020, 21:32
Ну вот я представил что я так сделал (закрыл репку) и поржал. Ну вообще шиза же.
У меня все открыто. Все, что делаю - раздаю)

TheGWBV
10.10.2020, 00:05
Прям какие-то 80-е... видик показывает китайскую фильму про две разные школы Кунг-Фу ))
в итоге побеждает дружба против японской школы каратЭ :v2_lol:

Titus
17.10.2020, 10:51
Перевел на похожий на человеческий язык PLM предварительного декодера команд.


Instruction NA ___ MOP
FEDCBA9876543210 543210 01 RTT BYTE IX2

00: 0000000000000110 000000 00 1 RTT

12: 000000001.000... 110000 00 1 RTS, SWAB R0?
34: 00000000.1...... 010000 00 1 JMP, SWAB?
36: .000110111...... 010000 00 1 MFPS, SXT?
30: 1000110100...... 010000 01 1 MTPS
37: 0000100......... 010000 11 1 JSR
33: .0001100........ 010000 00 1 ASR(B), ASL(B), ROR(B), ROL(B)
42: .000101......... 010000 00 1 CLR(B), COM(B), INC(B), DEC(B), NEG(B), TST(B), ADC(B), SBC(B)

38: 1.0............. 000000 00 1 Группы команд с байтовым доступом (установленный бит 15, кроме команды SUB и дополнительных команд 17xxxx)
44: 10.............. 000000 00 1 Группы команд с байтовым доступом (установленный бит 15, кроме команды SUB и дополнительных команд 17xxxx)

32: .0000..00....... 000000 11 ???
13: 0000.0.000...... 000000 10 ???
26: 0001............ 000000 10 MOV
28: 0000..01........ 000000 10 BR, BLT, JSR?, MARK, SXT?
43: 01110........... 101100 01 MUL, DIV, ASH, ASHC
16: .000101111...... 000000 01 TST(B)
47: .01............. 001000 01 BIT(B), CMP(B)

01: 1000110100000... 100000 00 MTPS Rn
08: .000110111000... 100000 00 MFPS Rn, SXT Rn
11: .0001100..000... 100000 00 ASR(B) Rn, ASL(B) Rn, ROR(B) Rn, ROL(B) Rn
25: .000101...000... 100000 00 CLR(B) Rn, COM(B) Rn, INC(B) Rn, DEC(B) Rn, NEG(B) Rn, TST(B) Rn, ADC(B) Rn, SBC(B) Rn

06: 0111100...000... 010000 00 XOR Rn,Rm
04: 01110.....000... 010000 00 MUL Rn,Rm; DIV Rn,Rm; ASH Rn,Rm; ASCH Rn,Rm
09: .0.1000...000... 010000 00 MOV(B) Rn,Rm; BIT(B) Rn,Rm
14: .10.000...000... 010000 00 BIC(B) Rn,Rm; BIS(B) Rn,Rm
23: ..10000...000... 010000 00 CMP(B) Rn,Rm; ADD Rn,Rm; SUB Rn,Rm

15: 0000000000000011 000010 00 BPT
17: 0000000000000.01 000010 00 WAIT, RESET
10: 0000000000001... 000010 00 START, STEP
03: 000000000001.... 000010 00 WCPS, WCPC
02: 0000110100...... 000010 00 MARK
05: 00000000101..... 000010 00 Clear/Set flags (CLC and e.t.c.)
07: 01111010000..... 000010 00 CIS?

45: ..01............ 001000 00 MOV(B), BIS(B)
46: .1.0............ 001000 00 BIC(B), ADD, SUB

21: .0000..0000....0 000010 00 Branch?
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 BVC, BVS, BCC, BCS, BGE, BLT, BGT, BLE

19: 0000100...000... 100111 00 JSR Rn,Rm
20: 0000000001000... 100111 00 JMP Rn

27: 0111111......... 001010 00 SOB

39: 0111100......... 101100 00 XOR

35: .10.000......... 100100 00 BIC(B), BIS(B)
40: .0.1000......... 100100 00 MOV(B), BIT(B)
41: ..10000......... 100100 00 CMP(B), ADD, SUB


Условные обозначения:
Instruction - это код команды (0 - это 0, 1 - это 1, а точка - это любое значение).
NA - это 6-битный адрес микрокоманды с которого начнется исполнение микропрограммы для данной инструкции
MOP 0 и 1 - это какой-то модификатор, значение которого я пока не знаю.
RTT - модификатор для команды RTT.
BYTE - это означает, что команда байтовая.
IX2 - тоже какой-то модификатор, значение которого я пока не знаю.


Не очень понятными оказались несколько записей, а именно:


32: .0000..00....... 000000 11 ???
13: 0000.0.000...... 000000 10 ???
07: 01111010000..... 000010 00 CIS?
21: .0000..0000....0 000010 00 Branch?

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

Alex_K
17.10.2020, 15:49
07: 01111010000..... 000010 00 CIS?
075000 - 075037 - это не CIS, это FIS, т.е. Float Instruction Set, FADD (07500*), FSUB (07501*), FMUL (07502*), FDIV (07503*).

А что это за циферки перед двоеточием?

Titus
17.10.2020, 15:59
А что это за циферки перед двоеточием?
Это номер столбца в ПЛМ. 0..47. Они не имеют значения.

В общем, пока не могу идентифицировать закономерность этих 4-х записей. Оно как бы попадает и в категорию и условных переходов, и специальных команд. Но логики единой не вижу.

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

Хорошо бы список команд PDP отсортированный по коду инструкции, а не по мнемонике или еще каким-то группам.

Alex_K
17.10.2020, 17:32
Хорошо бы список команд PDP отсортированный по коду инструкции, а не по мнемонике или еще каким-то группам.
000000 HALT
000001 WAIT
000002 RTI
000003 BPT
000004 IOT
000005 RESET
000006 RTT
000007 TRAP10
000010 000013 START
000014 000017 STEP
000020 000020 RSEL
000021 000021 MFUS
000022 000023 RCPC
000024 000027 RCPS
000030 000030 CODE030
000031 000031 MTUS
000032 000033 WCPC
000034 000037 WCPS
000040 000077 TRAP10
000100 000177 JMP
000200 000207 RTS
000210 000237 TRAP10
000240 000257 CLx
000260 000277 SEx
000300 000377 SWAB
000400 000777 BR
001000 001377 BNE
001400 001777 BEQ
002000 002377 BGE
002400 002777 BLT
003000 003377 BGT
003400 003777 BLE
004000 004777 JSR
005000 005077 CLR
005100 005177 COM
005200 005277 INC
005300 005377 DEC
005400 005477 NEG
005500 005577 ADC
005600 005677 SBC
005700 005777 TST
006000 006077 ROR
006100 006177 ROL
006200 006277 ASR
006300 006377 ASL
006400 006477 MARK
006500 006677 TRAP10
006700 006777 SXT
007000 007777 TRAP10
010000 017777 MOV
020000 027777 CMP
030000 037777 BIT
040000 047777 BIC
050000 057777 BIS
060000 067777 ADD
070000 070777 MUL
071000 071777 DIV
072000 072777 ASH
073000 073777 ASHC
074000 074777 XOR
075000 075037 FIS
075040 076777 TRAP10
077000 077777 SOB
100000 100377 BPL
100400 100777 BMI
101000 101377 BHI
101400 101777 BLOS
102000 102377 BVC
102400 102777 BVS
103000 103377 BCC/BHIS
103400 103777 BCS/BLO
104000 104377 EMT
104400 104777 TRAP
105000 105077 CLRB
105100 105177 COMB
105200 105277 INCB
105300 105377 DECB
105400 105477 NEGB
105500 105577 ADCB
105600 105677 SBCB
105700 105777 TSTB
106000 106077 RORB
106100 106177 ROLB
106200 106277 ASRB
106300 106377 ASLB
106400 106477 MTPS
106500 106677 TRAP10
106700 106777 MFPS
107000 107777 TRAP10
110000 117777 MOVB
120000 127777 CMPB
130000 137777 BITB
140000 147777 BICB
150000 157777 BISB
160000 167777 SUB
170000 177777 TRAP10

Titus
17.10.2020, 21:13
В общем, остались три подозрительные записи:


21: .0000..0000....0 000010 00 ???
32: .0000..00....... 000000 11 JMP, BNE+, BPL+, BVC+, BCC+, BGE+, BGT+, BHI+, HALT-TRAP10?
13: 0000.0.000...... 000000 10 HALT-TRAP10? BNE? JSR? CLC? ???

Нет ничего общего, чтобы могло обьединить команды внутри каждой записи.
Вариантов ответов несколько:
1. Ошибка в реверсе у Vslav'а.
2. Ошибка в реверсе у меня (нет, я проверил).
3. Ошибка у разработчиков, которая принципиально не повлияла на работу.
4. Чего-то я не понимаю.
5. Хрен знает еще что)

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

p.s.: Захотел проверить оригинальную матрицу по фотке ВМ2, а оказалось, что там ряды идут в другой последовательности, а какие где это только Vslav'у известно)

Titus
19.10.2020, 20:35
Благодаря таблице с диапзаонами кодов команд от Alex_К, я написал абсолютно программный генератор всех комбинаций команд преддекодера, и наконец-то все более менее встало на свои места:


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)

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

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

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(!)
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

Флаг байтовой операции, кроме команд XOR, ADD и SUB, а так же побочные:
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

Пояснения в мнемониках команд:
(B) - это означает, что команда может быть как байтовой, так и словной.
(!) - это означает, что декодирование команды неполное. А именно - часть команд с этим знаком будет декодированна данной записью, а часть нет, в зависимости от дополнительных бит.

Вот как раз знак (!) - это самое интересное. Он сразу дает понять, на какие команды ориентированна данная запись в таблице преддекодера. А именно, команды, помеченные (!) скорее всего являются просто побочным эффектом декодирования.

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

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

На колонку с кодом инструкции уже можно не смотреть. Значимым является только адрес микропрограммы, параметры MOP0,1 (отвечающее за то, надо ли записывать операнды обратно, и прочее действие с операндами. Еще не анализировал точно), и остальные параметры.


Instruction NA ___ MOP
FEDCBA9876543210 543210 01 RTT BYTE IX2

Флаг байтовой операции, кроме команд XOR, ADD и SUB, а так же побочные:
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


00: 0000000000000110 000000 00 1 RTT

28: 0000..01........ 000000 10 TRAP10_6500, TRAP10_6600
000000 11 TRAP10_7, TRAP10_40

000010 00 FIS, CLx, SEx, EMT, TRAP
000010 10 MARK
000010 11 HALT, WAIT, RTI, BPT, IOT, RESET, RTT, START, STEP, RSEL, MFUS, RCPC, RCPS, CODE30, MTUS, WCPC, WCPS,

000011 00 BPL, BR, BMI, BNE, BEQ, BHI, BLOS, BGE, BLT, BGT, BLE, BVC, BVS, BCC, BCS
000011 10 BR, BLT
000011 11 BNE(!), BGE(!), BGT(!), BPL(!), BHI(!), BVC(!), BCC(!)

45: ..01............ 001000 00 MOVB, BIS(B), BIC(B), ADD, SUB
47: .01............. 001000 01 CMP(B), BIT(B)
001000 10 MOV

27: 0111111......... 001010 00 SOB

011000 00 MOVB Rs,Rd, BIS(B) Rs,Rd, BIC(B) Rs,Rd, ADD Rs,Rd, SUB Rs,Rd
09: .0.1000...000... 011000 01 CMP(B) Rs,Rd, BIT(B) Rs,Rd
011000 10 MOV Rs,Rd

34: 00000000.1...... 010000 00 1 SWAB, MFPS
33: .0001100........ 010000 00 1 ROR(B), ROL(B), ASR(B), ASL(B)
42: .000101......... 010000 00 1 CLRB, COM(B), INC(B), DEC(B), NEG(B), ADC(B), SBC(B)
30: 1000110100...... 010000 01 1 MTPS, TST(B)
010000 10 1 CLR, SXT
37: 0000100......... 010000 11 1 JMP, JSR

11: .0001100..000... 110000 00 1 ROR(B) Rn, ROL(B) Rn, ASR(B) Rn, ASL(B) Rn
25: .000101...000... 110000 00 1 CLRB Rn, COM(B) Rn, INC(B) Rn, DEC(B) Rn, NEG(B) Rn, ADC(B) Rn, SBC(B) Rn
110000 01 1 MTPS Rn, TST(B) Rn
110000 10 1 CLR Rn, SXT Rn

35: .10.000......... 101100 00 MOVB Rs,dd, BIS(B) Rs,dd, BIC(B) Rs,dd, ADD Rs,dd, SUB Rs,dd
101100 01 CMP(B) Rs,dd, BIT(B) Rs,dd
101100 10 MOV Rs,dd

39: 0111100......... 101100 00 XOR
43: 01110........... 101100 01 MUL, DIV, ASH, ASHC

19: 0000100...000... 101111 11 1 JMP Rn, JSR Rs,Rd

12: 000000001.000... 110000 00 1 RTS, SWAB Rn, MFPS Rn

06: 0111100...000... 111100 00 XOR Rs,Rd
111100 01 MUL Rs,Rd, DIV Rs,Rd, ASH Rs,Rd, ASHC Rs,Rd

Reset by ACLO 111000
Abort by Timer 111001


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

Предварительно могу предположить, что IX2 - это флаг однооперандной команды.

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

Предварительное значение поля MOP01:


00 - цикл чтения и записи
01 - цикл чтения
10 - цикл записи
11 - ни чтения, ни записи

Vslav
19.10.2020, 21:45
Так что, эти заявления:



1. Ошибка в реверсе у Vslav'а.
2. Ошибка в реверсе у меня (нет, я проверил).
3. Ошибка у разработчиков, которая принципиально не повлияла на работу.


дезавуируются? :)

Titus
19.10.2020, 21:50
Так что, эти заявления:

дезавуируются? :)

Думаю, что да, так как теперь все четко и логично) Просто недоанализировано было, и своей оторванностью от общей картины вводило в замешательство.

Vslav
19.10.2020, 22:43
Эх, предекодер ВМ2 неактуален давно, и табличка с выходными микроадресами у меня где-то валяется, не стал уж мешать тебе.
А вот ВМ3 был бы интереснее, зря ты отказываешься :). В ближайшее время буду писать оптимальный анализатор для основной ПЛМ ВМ3, там входное слово пошире будет, скорость нужна - SSE2/AVX + многоядерник, к новым райзенам присматриваюсь под это дело.

Titus
19.10.2020, 22:50
А вот ВМ3 был бы интереснее, зря ты отказываешься . В ближайшее время буду писать оптимальный анализатор для основной ПЛМ ВМ3, там входное слово пошире будет, скорость нужна - SSE2/AVX + многоядерник, к новым райзенам присматриваюсь под это дело.
У меня задачи проще, никаких SSE, на все скорости хватает)

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


Эх, предекодер ВМ2 неактуален давно, и табличка с выходными микроадресами у меня где-то валяется, не стал уж мешать тебе.
И правильно)

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

Вот бы достать чипы от Амиги, я бы в них поковырялся)

Vslav
20.10.2020, 07:26
У меня задачи проще, никаких SSE, на все скорости хватает)
Дык, это предекодер, тут всего 16 бит на входе, 64K вариантов перебрать.
Вот анализатор (https://github.com/1801BM1/cpu11/blob/next/am4/rom/tools/plm.py) предекодера М4, он вообще на питоне по-быстрому написан.

Titus
20.10.2020, 09:58
Да и для декодера 32 бит хватит. Там 16 + 6 + 6.

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


Дык, это предекодер, тут всего 16 бит на входе, 64K вариантов перебрать.
Кстати, я и не перебирал все 65536 комбинаций. Всего лишь где-то около 80-90 (не помню, сколько инструкций у ВМ2) для каждого столбца. Потому что сравнивал не коды команд, а группы с масками.

Vslav
20.10.2020, 10:11
Кстати, я и не перебирал все 65536 комбинаций. Всего лишь где-то около 80-90 (не помню, сколько инструкций у ВМ2) для каждого столбца. Потому что сравнивал не коды команд, а группы с масками.
Так легко что-то пропустить и потом писать на форуме что у Vslav ошибка в реверсе, полное покрытие надежнее.

Titus
20.10.2020, 10:21
Так легко что-то пропустить и потом писать на форуме что у Vslav ошибка в реверсе, полное покрытие надежнее.
Нет, как раз именно так все встало на свои места)

А про предположительные нестыковки я писал, когда разбирал это все ручками) До автоматического анализа)

Titus
22.10.2020, 19:45
Вот так красивенько выглядит PLM микрокоманд (часть AND):

200 записей (на самом деле 198), в каждой - код инструкции (16 бит), адрес микрокоманды (6 бит), и несколько дополнительных параметров (6 бит).



..1........1.................1.........1.....0.... ........1.0.....1..........0....................0. 1...0.......10.................................... ........1.........................................
..1........1.1...............1...............0.0.. ................0.......1..0....................0. 0...0.......01.........0.....................1.... ......1.....1.....................................
..1......1.1.0..................1.......0....0.... 0.......1.......0..........0.......1........0...1. 0...0.......0................1.................... ..1.........0.....................................
........01...1....0......0...0...0...0.11....1.... 1......10.1.....00.........0......01.....1......0. 1...0..1....00..................0...10..0.......1. ..............1....0...........0.0....1...........
...11...01...1....0......0...0...0...0.1.....11... 0......00.1.....0..........101...........1......0. 10..0..0....10...............1..0...0...........1. ............1.1....1.............1................
...11...00...0....0......0...0...0..10.0.....00... 0......00.0.....00..........01.....0.....0......0. 01..0..1............................00..0.......1. ..............0....1.............0................
.....0.............1.......................1...... ...............1......11.........0..1........1.0.0 .................0...1.........................1.. ..........0.......0..........0......1.............
.....1.0...........0.......0...1...........1...... ....1..........1....1......0.....0.............1.0 ......1.....00.......1...1...0.............0...... ............01...............1......0.............
.....0.0...........11......1...00.......0..1...0.. ....................1..........1.1........1.01...0 .................1...1.........................0.. .............0....0..........1....................
.....1....1.1.0....1.0......0.....10.....1.....0.. ...0..0....01...........0........10..0........1..1 ........0.1..........1.01......0.0.0.....1.0.00... .....0...1.1.1.1......1..0.1.1.....11.0...........
.......1..0.0.1.....00......1.....10.....101....0. ...0.......10.....1......0...........1..1....1.... .....1..0........10.....1......0...0......10.001.0 ....11.1.0......0.1...1..1.1................1.....
.....1...00..00..1....1.....00......0.....0..00... .......00..00..00.1.....0..0......0.0..........00. 0...0.......000...1....00....0....110.....10...1.1 1...00...10.0..01.1...0..1.1...0......0.........0.
......0.........11...11.00......0......0........1. 0..1.....10........1.........0.0...00.00....0....0 .0......1.....1.............1.0...1.....0.....1... ..........0..0..............00.0....0.............
......1.........0.....1.0......................... ...1.....1......................0......1.......0.. ..............1...............1................... .............0...............0......0.............
................1..0..1.1...............0......... ...1.....0.....0.......................0.....0.... ..............1...............1................... .............0...............0......0.............
......0....................................1...... .............................................0.... .................................................. .1................................................
..10.0001000100.00100101000..001001100000100100010 0.101110000.01000001.0..011000100000101010.0000000 001.0000001000001001000000110000010000110100000000 00000.000.1.000010000.011.0.10001000010110.10.0111
..101.0001000110010.110000000110101010.01.0.011110 0010.0011000111.1001010.100100.10010100010.01.1.1. 101011.0110111001001101100101.00001.101.0000110.01 110110010011.00011.0100000101.0110.1.1100101100.10
...1..1.100.00011.1.00101011.0010.010.10.1..100100 00110000010.001.00011110111000001.1010.110010.000. 00010100.11100110.010.01..10101.01.100000001110.01 10.1...0..110.0011.001.11.1.0.011001.010000111010.
..0101.1111..11..11110.1.1100100100010111001111000 111.00011.1010011110010010111111.101010.0100111111 111110.1110111.101110111001101.010111111.011101110 11.110.1.001111101110.010010010001001001100.010100
..1.10000110110100001101010.111.011011010010011010 11001101101101001010.1.100010110001101100011001010 1100101001101101001010101.100101010010011010.01001 01010101010010010.001111010110.01001001.10011.1011
..1010.0010.1101.0001....00.110.01..11100.1011111. 011.10111.010000110....10.011010.0.0.01..11.001010 100011110..111.0100010001.0011.11.001101010011001. 01.001.1.1.01010.1010110.111.001010.00.1.101.1...1
............................1..................... .................1................................ .................................................. .....0...........................0................
.................1..........1.1.........0......... ...........0......0...........0.............1..... .......................11..............1..1.11.... .....1...........0....0........0..................
.....0.0...........0......1................0...... ...............0................10...........0...0 ..............1..0...0........1....0.......0...0.. .............0....0..........0......0.............
.................................................. .................1...0...................0........ ..0..................................01.....1..... ...1..........1..1...............1................
.........1...1.........1.....................10... .......0.............0.....1...................... 1..........01.......................1.......0..... ...0.............0........1.......................
........1......1.......1.........1....0........... .....................0............................ .........1..................................0..... ...0.............0................................

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

Ну, а вот так выглядит часть OR (или сумма):

Тут 200 записей, и 37 выходов. А именно адрес следующей микрокоманды, индексы регистров, коды ALU, и прочее, и прочее.


.............................1..1.............1... .1.....11.....1.1.......................1.......1. ....1..............1..............1............... .1..................1.............................
.......................1.....1.........1.....111.1 11...1.1....1....111.1.....11111..1111...1.1..111. 111.1111111111111...1.11..1111..111111111111111.11 11.11..1..111.1111.111.11.1.1..11111..11.1111.1111
.................1........................1....... .....1..1..1..............1.1............1........ 1.1.1..1....11..........1......11....1.......1..1. 1..1.1...11...1.1..1..11.1.1..11.11...1..11.......
............................1...1...1...1......... ..1..1...11...............1............11......... 1.1....1......1...1..1..1......11..1.....1.1....1. .....1.1.1....1.11.1...1.1.1..1..11....1.11.......
.......................................1....1..... 1...........11...111.1..1..1.11...11.1.....1..1... .1.1....1111...11.1...1....11....1....1..1....1... ...........1...1.....1.11.1...1.1.11.1..11.1......
.........................1.............1.......... 1.1..1......11....1..1..1..1.111..111.....1...1... 11.1.1...1.111.11.1...1...11........1.11.11.11...1 1.11...1..1.....11.....1..1...111.1..11111111.....
.........................1.............1.......... ....11....1....................1....11.....1...... ...1..1.1....1..1.1.......11........1..1..1.11...1 1..1..11..1....111...1.1......11.....111.11.1..1..
............1........1...1........1....1.......... ............1.....1..1.1...1..1.....1......1..1... 1..1.1...11.1..11.1...1...111.......1.11..1.1.1..1 ...1...11........1...1.1......1...1..111.1.11..1..
..........1.........................1........1.... 1.1..1.....1.1...1.1.............1.1.....1..11...1 1.1....11..111..1...11..1..111.11...11.1.11.11..1. 1..1.1.1.11.111.11.1..1..111.1.1111.1111.11.......
..........................1................1.....1 ..................1..1..1..1.111..1.11.......11... .11..1..11.....1.1....1...11.......11.111..1..1..1 ....1......11..1..........1..1.....11...11.1.1..11
...........................1..........1....111...1 1............1...11111..1..1.111.111111.......11.1 .11..1...1.1...111...11.1.11.1.....11.1.1..1..1.11 ...........11.11...1.1...1.11...1..1.1..11.11.....
..........................1....1...............1.. 1....11..........1..1...1.........111.1..1..1..1.. 1....1.11...11..1...1....11111..1..111..11.111..1. 1..1......1.111.11.1......1.11.1111.1.111.1..111..
..........................1.......1............111 .....1...........11..11.1..1.111..1..11..1...111.. 11...1.1111.11.1......111.11........1.1.111.111.11 1..1.1.1.1111.1111.1..1..1111..1.111..111.1111.1..
................1..1..1.1..........1.............. ..1..1..11.1.1...............1...1.....1.1..1....1 11.....1....11......11......1.1111...1.1.11.11..1. 1..1.1.1.111.1..11.1..1..1.1.1.1.111.111.11.......
.....11..1...1..............1......1....1.1....... ..1.......111..11.........1.1....1....11.1..1..1.. ............111..11.........1....1...1.1.....1.11. 1..1...1..11.....111..11.1.1..111.111.11.1........
........................1......................... .........1...11..................................1 .1.......................................1........ .....................................1............
................1................................. .............................1.................... .................................................. ..................................................
.........1...1.....11...1...1......1....1.1....... ..1..1....1111.1..........1.1.........1..1..1..1.. 11..1..1....111..11.1.......1.1111...1.1..1.11.11. 1..1.1.1.111.1..1111..11.111.1111111..11.11.......
.......1............1..........................1.. ......1........1.................................. ...................1.............................. ...................................1..............
...............................................1.. ......1.........................................1. ...................1...1.......................1.. .1.................................1..............
...................................1..........1... .1.....1.......................................... ...................1..............1............... .1................1...............................
.................................................. ..1..............1.........11.................1... 1........1..1...................1....11........... ..............1..1.1...1.........1.....1..........
..........................................1....... ..1........1..............11.............1....1... ..1....1.1..11..........1......1......1......1..1. 1..1.1...11......1....1..1.1..11..1...11.1........
.................................................. ..1..1............................................ 1.....................................1........... ................11.....................1..1.......
..........................................1....... ...........1.....1........111............1....1... ..1....1.1...1..........1......11....11......1..1. 1....1...11...1....1..11.1.1..11.11......1........
......................1.................1..1...... .........1.....1................11.....1.....1...1 .....................1......1.1..1.............1.. ....1........1....1..........1......1.............
.........................1..............1......... ......1...1....1.................1.....1....1....1 ..................1.11......1.1..1.......1.....1.. ....1............11..........1......1.............
......................................1.....1....1 .................1......1.........1............... ...1.1.....1......1.....1.1.............1.......1. ..............1....1.1.1.111..1.........1.........
.........................1...1..1...1.....1..111.. 11...1111.11111.1..1....1..11..1..11.1..11.11.111. 1.1.1..111111111111.1..1..111..11111111..1.1111... 11.11..1.111...111..11111.1.1.111.11.111111.1..1.1
.........1...1..............1.......1...1......1.. ......1..11...............1...........11.......1.. ..1...........1..11..1.11..........1.....1.1....1. ....11.1......1....1...1.1.1..1.111......1........
............................1.............1....... ...........1.....1........1.1..................... ........................1......11....1............ .....1........1....1...1.1.......1................
........1......1.................1.......1..1..1.. .....1.......1...........1..............11.....1.. ..1....11..1..1.11.........11....1.1.......1....1. ....1....1......11..1.1...11..1.1.1......11......1
..............1..............11.1......11..11.1..1 .1.1..11111.1.111.1..1.......11111.111.11...11.111 .11.11...1.....1.111.111..11.11...11...111111111.1 11.1...1...111.1.11.......1.11111..1111.11111...11
.............................1..1......111.1..1..1 11.1...1.1..1..1111..1..11..1111111.1..111..11.111 .11.11.111....1..1...111.....11.1.11.1.11.1111.111 11.1.......1111..111...1....11.111.11.1.11.11.111.
.........................1......1........1.....1.. ............11...........1.....1........1......1.. ........1..1..1.11.....1..1.1....1.1..1..1.1.1.... 1...1.....11....1...1.....1.1...1....1..1.1......1
..................1......1...........1......1..1.. ..1..11...1......1..........1......1.1.....11..1.. ........11.1..1..11....1..111...1..1.1.....1..1... 1......1.111..11...1.111..11...1.1.1.1.11.1.1.....
..111......1..................1.....1........1...1 1....11.1.1..11..1.1....1..11.....1111...1..1.1... 1.1..1.1..1111.11.1.1.1...11....1...1111.11.1.1.11 .......1.1....11...1..111.11..11.111....11..1.....

Titus
22.10.2020, 22:32
Вообще, на первый взгляд, расшифровать микрокод - это еще та жесть)
В том смысле, что это не привычная в программировании последовательность команд, располагающаяся друг за другом.
Это совсем другой принцип.

Titus
23.10.2020, 00:53
Просьба к Vslav или Ynicky записать диаграммы работы небольшого количества команд, с отображением IA0..IA5, и обязательно указать, какие команды исполнялись.

Vslav
23.10.2020, 01:44
Вообще, на первый взгляд, расшифровать микрокод - это еще та жесть)



; 210 : s = _mm_setzero_si128();
; 211 : z = _mm_setzero_si128();
; 212 : do {
; 213 : x = _mm_load_si128(&p->xor);
; 214 : a = _mm_load_si128(&p->and);
; 215 : t = _mm_load_si128(&p->sop[0]);
; 216 : x = _mm_xor_si128(x, v);

00022 f3 41 0f 6f 08 movdqu xmm1, XMMWORD PTR [r8]

; 217 : x = _mm_and_si128(x, a);
; 218 : x = _mm_cmpeq_epi32(x, z);
; 219 : a = _mm_unpacklo_epi32(x, x);
; 220 : a = _mm_and_si128(a, t);
; 221 : t = _mm_load_si128(&p->sop[1]);
; 222 : s = _mm_or_si128(s, a);
; 223 : a = _mm_unpackhi_epi32(x, x);
; 224 : a = _mm_and_si128(a, t);
; 225 : s = _mm_or_si128(s, a);
; 226 : ++p;

00027 4d 8d 40 50 lea r8, QWORD PTR [r8+80]
0002b 66 0f ef cb pxor xmm1, xmm3
0002f 66 41 0f db 48
c0 pand xmm1, XMMWORD PTR [r8-64]
00035 66 0f 76 cc pcmpeqd xmm1, xmm4
00039 66 0f 6f c1 movdqa xmm0, xmm1
0003d 66 0f 62 c1 punpckldq xmm0, xmm1
00041 66 41 0f db 40
e0 pand xmm0, XMMWORD PTR [r8-32]
00047 66 0f 6a c9 punpckhdq xmm1, xmm1
0004b 66 0f eb c2 por xmm0, xmm2
0004f 66 41 0f db 48
f0 pand xmm1, XMMWORD PTR [r8-16]
00055 66 0f 6f d0 movdqa xmm2, xmm0
00059 66 0f eb d1 por xmm2, xmm1


На выходные постараюсь написать пост как я анализировал ВМ1 и выложу процедуры для анализатора.
Вон сверху написана оптимизация под SSE2 (мир как бы далеко от PDP-11 уже ушел, надо новенькое осваивать :)), ускорило процесс в x2.5 раза, доделаю AVX2 и М-арные деревья и расскажу как на эти матрицы смотреть :)

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


записать диаграммы работы небольшого количества команд, с отображением IA0..IA5
Это тебе не поможет. Никак. Там надо статанализ делать, с полным покрытием вариантов.

Titus
23.10.2020, 02:41
Это тебе не поможет. Никак. Там надо статанализ делать, с полным покрытием вариантов.
Я совершенно не занимаюсь перебором всех возможных комбинаций, поэтому мне SSE не нужно)

А пример с адресами IA0..IA5 прошу для сравнения с моими теоретическими выкладками, поэтому оно мне поможет, поверь)

Vslav
23.10.2020, 09:40
Я совершенно не занимаюсь перебором всех возможных комбинаций
Конечно, ты собираешься меня заставить это делать в ручном режиме - будешь просить потом - "а запусти для этой инструкции, а запусти для этого адреса". Извини, но я на такое не подписываюсь. Чтобы до тебя дошло, давай конкретный список, полную спецификацию чего на входе и что тебе отдать на выходе, обработаю _ОДИН_ раз, может быть, если список будет умеренный.

Ты реально думаешь что для полусотни инструкций/адресов кто-то будет из диаграмм циферки выковыривать? Я для этого писал сначала спецмодельку на верилоге, потом увидел что покрытие плохое и медленное, перешел на Си, а теперь и на SSE/AVX. И эти же функции вычисления матриц будут нужны любому приличному эмулятору который микрокод эмулирует.

Titus
23.10.2020, 09:50
Мне нужен пример на нескольких ЛЮБЫХ инструкциях. Если тебе хочется конкретики, то пусть это будет. XOR R0,R1; ADD R0,(R2); SUB (R3),2(R4); CLC.

yu.zxpk
23.10.2020, 16:53
Тема как-то сползла с обсуждения БМК на 1801 и "все такое"

Titus
23.10.2020, 18:59
Тема как-то сползла с обсуждения БМК на 1801 и "все такое"
А она уже давно называется 'реверс БМК и ВМ2'

Ynicky
23.10.2020, 20:31
Просьба к Vslav или Ynicky записать диаграммы работы небольшого количества команд, с отображением IA0..IA5, и обязательно указать, какие команды исполнялись.

Это что за сигналы IA0..IA5?
reg [5:0] ia; // microinstuction address register
Эти?

Vslav
23.10.2020, 20:53
А она уже давно называется 'реверс БМК и ВМ2'
Так это не сам реверс ВМ2, это его осмысление :)
Сейчас домучаю М-арные деревья и дам тебе функции матрицы, "ты ж программист" - сам себе адреса посчитаешь, против Си у тебя же нет предубеждений? :)
Там был очень красивый случай рекурсии, редкий, когда она полезна - организация цикла с вложенностью определяемой через #define, позвал дочку и вместе написали и оно даже заработало :).

Titus
23.10.2020, 21:50
Это что за сигналы IA0..IA5?
reg [5:0] ia; // microinstuction address register
Эти?
Эти да. Сделай, буду признателен) Любые несколько команд процессора, только подпиши, какие это были команды.

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


Сейчас домучаю М-арные деревья и дам тебе функции матрицы, "ты ж программист" - сам себе адреса посчитаешь, против Си у тебя же нет предубеждений?
Вообще-то я просил диаграммы адресов на примере нескольких команд)

Ynicky
23.10.2020, 22:04
В текстовом файле команды, в скриншотах подряд выполнение этих команд.
https://cloud.mail.ru/public/5CSG/356TQPNvB

Vslav
23.10.2020, 22:43
Вообще-то я просил диаграммы адресов на примере нескольких команд)
Та да, кто-то должен:
- все бросить
- написать программку на MAC
- скомпилировать ее
- скормить модели
- скомпилировать модель
- запустить симулятор
- потом снять скриншот
- обрезать скриншот
- выложить на хостинг
- написать пост, вставив ссылку

"И чего только люди не придумают, лишь бы верилог не учить программку на Си не запустить на картошку не ехать" (c)

Titus
23.10.2020, 23:23
В текстовом файле команды, в скриншотах подряд выполнение этих команд.
https://cloud.mail.ru/public/5CSG/356TQPNvB
Я не очень понял, чего на скриншотах)

Мне нужны диаграммы, где будет видно сразу 6 линий IA0..IA5 при выполнении последовательности команд. А у тебя линии IA не раскрыты, а свернуты.

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


Та да, кто-то должен:
Ты сто раз так делал)

И Ynicky тоже сделал почти)

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

Я понял, там IA свернуто, но в восьмеричном виде на диаграмме число, которое на линиях IA0..IA5?

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

Хм... честно говоря, на шине AD в диаграмме не увидел ничего, что указанно в листинге.
Может исполнялся совсем другой код?

Alex_K
23.10.2020, 23:26
Хм... честно говоря, на шине AD в диаграмме не увидел ничего, что указанно в листинге.
Может исполнялся совсем другой код?
А может быть он в инверсном виде?

Titus
23.10.2020, 23:44
А может быть он в инверсном виде?
Тогда должен быть знак n на конце названия сигнала, по идее.

Titus
25.10.2020, 19:21
В текстовом файле команды, в скриншотах подряд выполнение этих команд.
https://cloud.mail.ru/public/5CSG/356TQPNvB

Все замечательно, только у меня почему-то не совпадает адрес следующей команды (NA).

Попробуй, пожалуйста, сделать те же самые графики, но добавить в них сигналы I0..I15 (это код команды), RI0..RI2, IX0..IX2, а также выход PL0..PL36. Тогда точно будет все понятно.

Ynicky
26.10.2020, 17:50
Не знаю что за сигналы I0..I15, поэтому добавил следующие:
wire [15:0] ad; // internal address/data bus
reg [15:0] ireg; // primary instruction register
reg [15:0] breg; // prefetch instruction register
reg [5:0] ia; // microinstuction address register
reg [2:0] ri; // interrupt acknowlegement register
reg [2:0] ix; // auxiliary conditions register
wire [36:0] pla; //

https://cloud.mail.ru/public/2fec/2qiXWrHUc

Titus
26.10.2020, 19:52
Не знаю что за сигналы I0..I15, поэтому добавил следующие:
I0..I15 - это то, что идет на матрицу PLM1, 2, 3, вместе с сигналами IA, RI и IX.

Спасибо, буду смотреть!

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

Хм... это уже вопрос теперь к Vslav'у.

Сравнил - получилось, что генератор PLM у меня считает тоже самое, что и у Ynicky на диаграммах. Но при этом адрес следующей микрокоманды на диаграмме другой!

Например, команда: MOV #010000,R2
На диаграмме у нее адреса шагов микропрограммы следующие: 60, 55, 57, 54, 76.
У меня адрес первого шага всегда правильный, в данном случае 60. На первом шаге получаем ответ от PLM - 1243777333425. На диаграмме ответ такой же, т.е. и тут совпадение.
В двоичном виде это: 1010100011111111111011011011100010101.
Выделяем из этого только адрес следующей команды (PL36..PL31), т.е. 6 старших бит, получаем 101010 (52 в восьмеричном). Но это никак не 101101 (55), который указан в диаграмме.
Выглядит, будто младшие 3 бита инвертированы... хм... Проверю, может я упустил инверсию в схеме для младших трех бит.

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

Точно, младшие 3 бита инвертированы. Вот я лапоть)
Промучился несколько дней из-за того, что изначально нарисовал все 6 триггеров для NA одинаковыми, хотя три из них были инверсные. Но на схеме при беглом взгляде это не бросилось в глаза.

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

Большое спасибо Ynicky за диаграммы! Без них бы я еще неизвестно сколько это искал)

Vslav
27.10.2020, 00:35
Точно, младшие 3 бита инвертированы.

Там еще хинт есть - то что в NA[5:0] на верилоге и на схеме - надо инвертировать полностью.
Тогда после аппаратного сброса оно стартует с нуля (а не с 0x3F), а по аборту транзакции оно впадает в 0x01 (а не 0x3E).
Просто когда реверсишь такие вещи - сразу непонятно прямое там значение или обратное, а потом уже переколбасить схему сложно.

Titus
27.10.2020, 00:43
Тогда после аппаратного сброса оно стартует с нуля (а не с 0x3F), а по аборту транзакции оно впадает в 0x01 (а не 0x3E).
Это я заметил.
https://pic.maxiol.com/images2/1603748547.2151951043.01.jpg

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

Vslav
27.10.2020, 09:01
нет большой разницы, в каком виде, инверсном или прямом его воспринимать.
Для схемы разницы в нотации нет, для человека - есть. Микрокод разрабатывался людьми, и, скорее всего, была использована инверсная нотация, и это оказало свое влияние на разработку. Поэтому я предпочел быть ближе к вероятному оригинальному коду. Мы же читаем программы сверху вниз, и программный счетчик для следующего шага обычно увеличивается, а не уменьшается. Код то горизонтальный, но мелкие кусочки последовательностей есть, и если смотреть в инверсном виде, то там будет именно uPC++, а не uPC--

Titus
27.10.2020, 13:17
Поэтому я предпочел быть ближе к вероятному оригинальному коду. Мы же читаем программы сверху вниз, и программный счетчик для следующего шага обычно увеличивается, а не уменьшается. Код то горизонтальный, но мелкие кусочки последовательностей есть, и если смотреть в инверсном виде, то там будет именно uPC++, а не uPC--

На самом деле я так и анализирую в инверсном виде, т.к. сразу увиделось что это ближе к первоисточнику)

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


Не знаю что за сигналы I0..I15, поэтому добавил следующие:
На досуге, если будет не сложно, сделай команды: ADD R0,R1; BCC куда-нибудь

Ynicky
28.10.2020, 18:00
На досуге, если будет не сложно, сделай команды: ADD R0,R1; BCC куда-нибудь

https://cloud.mail.ru/public/3nLG/3FdtCPZJH

Titus
28.10.2020, 18:22
https://cloud.mail.ru/public/3nLG/3FdtCPZJH
Все замечательно, спасибо!
Нашел у себя одну ошибочку оптимизации в таблице преддекодера.

Titus
29.10.2020, 01:34
Ура, нашел еще одну избыточность в процессоре)

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

Titus
29.10.2020, 14:23
ALU производит операции над операндами, получаемых с двух внутренних шин X и Y. Операнд приемник (dd) выставляется на шину X, операнд источник (ss) на шину Y. Также на шину Y может выставляться регистр-константа или регистр-переменная для однооперандных команд.

ALU состоит из нескольких ступеней:

1. Входная ступень, здесь возможно инвертирование операндов X или Y, а также обнуление одного из операндов.
2. Вычисление промежуточных логических функций OR, AND, а также их комбинаций - XOR и CLR (обнуление результата).
3. Опциональная ступень ускоренного вычисления переносов для функции сложения.
4. Сложение по модулю два (XOR) результата ступеней 2 и 3.
5. Опциональный сдвиг результата вправо или влево с опциональным использованием флага переноса.


Кодирование операций ALU:

Однооперандные операции (PL13=0):

PL17 PL14 OPX OPY
0 0 0 Y
0 1 /X 0 COM
1 0 0 /Y
1 1 X 0 ROL, ROR, ASL, ASR

Двухоперандные операции (PL13=1):

PL17 PL14 OPX OPY ALU_G ALU_CIN
0 0 X Y 0 0 BIS, BIT, CLR, XOR, TST
0 1 /X Y 1 1 NEG
1 0 X /Y 1 1 SUB, DEC, SBC, BIC
1 1 X Y 1 0 ADD, INC, ADC

ALU_G - сумматор
ALU_CIN - входящий перенос для сумматора

Логические функции:

PL16 PL15
0 0 Функция XOR (является составной частью сложения)
0 1 Функция AND
1 0 Функция OR
1 1 Функция CLR (не используется, результат равен 0)

Сдвиг результата:

PL20 PL19
0 0 Нет сдвига (NSHIFT)
0 1 Сдвиг влево (LSHIFT)
1 0 Сдвиг вправо (RSHIFT)
1 1 Запрещенная комбинация

PL15 - Блокирует линию OR, а также блокирует сумматор (ALU_G и ALU_CIN)
PL16 - Блокирует линию AND
PL18 - Разрешает флаг преноса для сдвигов

Если PL17=0, PL14=0 и PL13=0, то расширение знака блокируется (SXT_Y0 = 0)

Все варианты операций с ALU:


PL17 PL16 PL15 PL14 PL13
0 1 0 0 1 BIS: AF = X | Y
0 0 1 0 1 BIT: AF = X & Y
0 0 1 0 1 CLR: AF = X & Y = X & 0 = 0 (Y=0)
1 0 1 0 1 BIC: AF = X & ~Y
0 0 0 0 1 XOR: AF = (X & Y) | ~(X | Y) = X ^ Y
0 0 0 0 1 TST: AF = (X & Y) | ~(X | Y) = X ^ Y = X ^ 0 = X (Y=0)
1 0 0 1 1 ADD: AF = X + Y
1 0 0 1 1 INC: AF = X + Y = X + 1 (Y=1)
1 0 0 1 1 ADC: AF = X + Y = X + C (Y=C)
1 0 0 0 1 SUB: AF = X + ~Y + 1 = X - Y
1 0 0 0 1 DEC: AF = X + ~Y + 1 = X - Y = X - 1 (Y=1)
1 0 0 0 1 SBC: AF = X + ~Y + 1 = X - Y = X - C (Y=C)
0 0 0 1 1 NEG: AF = ~X + Y + 1 = ~X + 0 + 1 = ~X + 1 (Y=0)

0 0 0 1 0 COM: AF = ~X ^ 0 = ~X (Y=C)
1 0 0 1 0 Shift: AF = X ^ 0 = X

Полная маска команд, получаемая от PLM:

3222222222211111111110000000000
0987654321098765432109876543210 Номер линии PL00-30
w PPIIIISSCAAAAAyyyYYxxxXW B Назначение линии
__ ________ Инверсия линии

.....1...........1............. XOR
.....1........1..1............. BIS
.....1.......1.1.1............. BIC
....11.......1...1............. SUB
....11.......1..11............. ADD
.1..11..........11.........1... CMP
.1...1.........1.1.........1... BIT

....11.........1.1..1.1........ CLR (Y=0)
.....1.......1...1.1..1........ DEC (Y=1) (ALT_CNST=0)
.....1.......1..11.1..1........ INC (Y=1) (ALT_CNST=0)
....11..........11..1.1........ NEG (Y=0)
....11.......1..11.1.11........ ADC (Y=PSW0) (Бит C)
....11.......1...1.1.11........ SBC (Y=PSW0) (Бит C)
.1..11...........1..1.1....1... TST (Y=0)
....11..........1..1.11........ COM (Y=PSW0) (Бит C)
....11.....1.1..1.............. ASL (LSHIFT)
....11.....111..1.............. ROL (LSHIFT) (CARRY)
....11....1..1..1.............. ASR (RSHIFT)
....11....1.11..1.............. ROR (RSHIFT) (CARRY)

Немного замечаний:
1. Не смотря на то, что ALU может опционально обнулять один из операндов, такие инструкции, как CLR, NEG и TST эту возможность не используют, а используют в качестве операнда Y - регистр констант, равный нулю.
2. Такие инструкции, как CMP, BIT и TST используют блокировку обратной записи результата в операнд-приемник (PL3=1 и PL29=1).
3. Не все операции выглядят рациональными. Например COM использует в качестве операнда Y регистр констант равный флагу C (Y=C), но в самом ALU операнд Y обнуляется.

Titus
29.10.2020, 20:15
Заодно подоспела вылизанная логическая схема ALU и EALU:

1801VM2-Optimized [ALU & EALU] - rev 43.pdf (https://yadi.sk/i/f374wjc2pukSXA)

hobot
29.10.2020, 21:22
Заодно подоспела вылизанная логическая схема ALU и EALU:

1801VM2-Optimized [ALU & EALU] - rev 43.pdf (https://yadi.sk/i/f374wjc2pukSXA)

Ув. д.г.к. Titus , очень прошу вас дать мне знать, когда будет готов финальный пакет ваших разборок по этой теме,
поскольку предлагаю разместить копию в библиотеке на сайте архива.
Спасибо.

Titus
29.10.2020, 21:26
Ув. д.г.к. @Titus , очень прошу вас дать мне знать, когда будет готов финальный пакет ваших разборок по этой теме
Сложно ставить точку в теме реверса, оптимизации и понимания работы этих чипов.
Кроме того, Vslav еще не сфоткал альтернативные ХМ-ки. Так что раньше, чем через год, и не рассчитывай)

Titus
30.10.2020, 03:00
Нашел ошибочку в схеме сдвига. Исправил, но обновлять не буду до будущих обновлений. Все равно никто не интересуется)

Titus
01.11.2020, 12:10
Vslav, посмотрел микропрограмму в ВМ2. Очень хорошо понятна, и расшифровывается без глобального перебора всех комбинаций.
Мало того, перебор всех комбинаций я считаю даже вредным, потому что ты имеешь вход и выход, но не знаешь, почему получился этот выход.
А при логическом анализе микропрограммы, все, как на ладони, чуть ли не с комментариями.
Кроме того, есть шаги микропрограммы, которые не относятся к исполнению элементов инструкций. Например, команда ABORT имеет 10 шагов.
И все эти шаги надо понимать, зачем они и почему.

Vslav
01.11.2020, 12:16
Vslav, посмотрел микропрограмму в ВМ2. Очень хорошо понятна, и расшифровывается без глобального перебора всех комбинаций.
Документация по микропрограмме, подобная той что я написал для ВМ1 будет? Или так, на форуме побалакать?
И да, ВМ2 матрица заметно попроще, потому что там предекодер и точки входа известны, у ВМ1 чуток не так.

Titus
01.11.2020, 12:17
Документация по микропрограмме, подобная той что я написал для ВМ1 будет? Или так, на форуме побалакать?
Для чистоты эксперимента я не смотрел твою документацию по ВМ1. Равно как и не заглядываю в заводскую документацию по ВМ2, которую я сам же и раздобыл когда-то)

Vslav
01.11.2020, 12:23
Для чистоты эксперимента я не смотрел твою документацию по ВМ1. Равно как и не заглядываю в заводскую документацию по ВМ2, которую я сам же и раздобыл когда-то)
Как там у классика?

"- ты сказал один раз - я тебе поверил"
"- ты сказал второй раз - я начал сомневаться"
"- повторил в третий- я тебе не верю" (c)

Документацию напиши, с доказательством что оно именно так ходит.
Перебор - это просто один из инструментов, показывает что в матрице нет ошибки и пойдет именно так.
Кстати, один из стандартных методов функциональной верификации, а отнюдь не мной придуман.

Titus
01.11.2020, 12:24
И да, ВМ2 матрица заметно попроще, потому что там предекодер и точки входа известны, у ВМ1 чуток не так.
Но сказать, что там все просто - тоже не могу. Понятно, но не просто)

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


Как там у классика?
Классики много чего говорят, и далеко не всегда их высказывания истинны)

Vslav
01.11.2020, 13:23
Классики много чего говорят, и далеко не всегда их высказывания истинны)
Разумный подход при решении любой проблемы - это изучить материалы по вопросу, посмотреть что и как сделано предшественниками, и на имеющейся базе продолжить. Игнорирование документации звучит странно и нелогично. Вот если бы ВМ3 так разобрал, на который ни вылизанной схемы, ни документации, сомнений не было бы. А так...
А я по твоей схеме написал бы верилог, я то перерисовывать точно не буду, но если есть готовая схема - надо пользоваться :)

S_V_B
01.11.2020, 13:52
Вот товарисч Титус. ты перед Vslav заискиваешь.., а на нас бедолаг... какать хотел.. не уивляйся что и тебя отшили:)

Vslav
01.11.2020, 13:57
не уивляйся что и тебя отшили:)
Ну как отшили... У меня просто пригорает, что куча есть нового и не сделанного, и когда и как это делать непонятно. А тут толковый человек время на пережевывание тратит, а мог бы и полезное чего поделать. Раз нравится перерисовывать - не вопрос. Вот схема ВМ3 - пойдет. Когда реверсишь, не всегда понятно где границы блока и какая цепь значимая и глобальная и ее имеет смысл обозвать, а какая может быть внутриблочной и ей выделять имя вообще не надо. Блок ввода-вывода в ВМ3 еще служит для обслуживания обмена сопроцессора, вот там наворочено много и запутано, тут перерисовка была бы полезна. Раз есть умельцы делать это без документации - самое оно скиллы свои приложить.

S_V_B
01.11.2020, 14:02
А я о чем.. для тебя он такая же букашка... как мы для него.. мог бы потратить свое время лучшим образом, а не выеживаться типа читайте документацию:)

Hunta
01.11.2020, 14:12
А тут толковый человек время на пережевывание тратит
Не всем дано понять FPGA :)

Titus
01.11.2020, 14:16
Вот схема ВМ3 - пойдет. Когда реверсишь, не всегда понятно где границы блока и какая цепь значимая и глобальная и ее имеет смысл обозвать, а какая может быть внутриблочной и ей выделять имя вообще не надо. Блок ввода-вывода в ВМ3 еще служит для обслуживания обмена сопроцессора, вот там наворочено много и запутано, тут перерисовка была бы полезна. Раз есть умельцы делать это без документации - самое оно скиллы свои приложить.
ВМ3 я ковырять не буду, потому что он мне никак не интересен.
ВМ2 интересен исключительно как ядро УКНЦ. И ХМ-ки тоже.
Каждый применяет себя там, где умеет, и где ему интересно.

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


Не всем дано понять FPGA
Я программист изначально, а не железячник.
И эмуляторщик, а не ФПГА'шник)

Vslav
01.11.2020, 14:27
Не всем дано понять FPGA :)
Дык, речь не про FPGA - перерисовывается схема. Для уже сделанного ВМ2 это полностью бессмысленно, просто развлечение для отдельно взятого человека. Вот даже внятной документации по микрокоду ВМ2, видимо, не появится. Я микрокод ВМ2 вообще особо не разбирал - просто написал в модели логгер, и теперь любой вопрос (например как с командой 000030) моделированием закрывается за 10 минут.
Для ВМ3 на данном этапе перерисовывание схемы имело бы смысл - там есть небольшой затык по блоку ввода-вывода. Ну, я со временем разберу, но перерисовывание с определением и именованием значимых связей могло бы дело упростить.

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



ВМ2 интересен исключительно как ядро УКНЦ.

Результат "интереса" какой? Новое ядро напишешь? Спаяешь на рассыпухе?


И ХМ-ки тоже.

Вот по ХМ вообще никаких вопросов, только благодарность. Нравится мне формат схемы - не нравится, кушай что дают или делай сам. А не можешь сам (все равно по каким причинам) - сиди тихо :)

Hunta
01.11.2020, 14:28
Я программист изначально, а не железячник.
Да да, виноград ещё зелёный.
Я тоже изначально программер - и что? Мне проще будет посмотреть в код Vslav, что бы понять - чего и как - ибо это БЛИЖЕ к программированию, чем твои - не железячника(!) - картинки.
И уверенности в правильности у Vslav, у меня больше - ибо проверено, чем в твоих ("я художник, я так вижу") картинках

Titus
01.11.2020, 14:31
Дык, речь не про FPGA - перерисовывается схема. Для уже сделанного ВМ2 это полностью бессмысленно, просто развлечение для отдельно взятого человека.
Мы все тут интеллектуально и творчески развлекаемся)

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


Результат "интереса" какой? Новое ядро напишешь? Спаяешь на рассыпухе?
Эмуляция. Рассыпуха - это жесть) Шкаф займет)

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


Вот по ХМ вообще никаких вопросов, только благодарность.
Что там по растворению в кислоте остальных чипов?

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


И уверенности в правильности у Vslav, у меня больше - ибо проверено, чем в твоих ("я художник, я так вижу") картинках
Ну так я и не закончил еще.
А работа ХМ'ок проверяется Ynicky на ФПГА.
Кстати, как там прогресс?

Hunta
01.11.2020, 14:33
Дык, речь не про FPGA - перерисовывается схема.
Не совсем точно выразился, речь шла больше про VHDL и Verilog, но в случае FPGA это всё достаточно тесно связано, вот по привычки и написал - FPGA


ВМ2 интересен исключительно как ядро УКНЦ.

Раз нравится перерисовывать - не вопрос.

Все равно никто не интересуется)
Ибо всё уже нарисовано и ВМ2 интересен в перерисованном варианте только ему

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


Ну так я и не закончил еще.
Даже когда закончишь


А работа ХМ'ок проверяется @Ynicky на ФПГА
ибо - кто проверять то будет

Vslav
01.11.2020, 14:42
Мы все тут интеллектуально и творчески развлекаемся)
Да. Но это не значит что на осмысленность и результативность развлечения следует забить.


Эмуляция. Рассыпуха - это жесть) Шкаф займет)
Да не должно бы, пару-тройку больших плат на серии 74HC. Если бы ты еще схему в стандартных 74-ых рисовал, а не в своих мифических элементах, мы и оценку числа корпусов имели бы.



Что там по растворению в кислоте остальных чипов?

Собираюсь скоро к химику съездить.

Titus
01.11.2020, 14:53
Да не должно бы, пару-тройку больших плат на серии 74HC. Если бы ты еще схему в стандартных 74-ых рисовал, а не в своих мифических элементах, мы и оценку числа корпусов имели бы.
Да тут в одном ВМ2 у меня получилось более 1000 логических элементов.
А ВМ2 - 2 штуки в УКНЦ.
Плюс ХМ'ки.
На рассыпухе это была бы жесть)

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


Собираюсь скоро к химику съездить.
Ура!:v2_dizzy_dance:

Ynicky
02.11.2020, 19:45
А работа ХМ'ок проверяется Ynicky на ФПГА.
Кстати, как там прогресс?
Проект не забросил. Перевожу реверсы в синхронный вид. Моделирую все сигналы и сравниваю между собой. Пока осилил только CSM.

Titus
02.11.2020, 20:06
Проект не забросил. Перевожу реверсы в синхронный вид. Моделирую все сигналы и сравниваю между собой. Пока осилил только CSM.
Эх, все же не удалось удержаться)

Я бы все же сперва добился работы УКНЦ, а потом модернизировал.

Ynicky
02.11.2020, 20:34
Да не работает она в железе, что только не делал. И квартусы ставил разные, вплоть до 18, и моуделсимы с квестосимами, и использовал чиппланеры с лоджилоками, и таймквесты использовал для анализа. А в документации вычитал, что для MAX10 нет поддержки временного моделирования и хоть ты тресни. Потому и пошел на крайние меры.

Titus
02.11.2020, 20:36
А в документации вычитал, что для MAX10 нет поддержки временного моделирования и хоть ты тресни. Потому и пошел на крайние меры.
Ну у тебя же работали все чипы в общем-то, и даже экран формировался правильно.
Может надо было найти конкретный баг, и именно эту часть сделать синхронной?

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

Временное моделирование - это что?

Hunta
02.11.2020, 21:02
Да не работает она в железе, что только не делал.
Не удивительно

xolod
02.11.2020, 21:55
Ynicky, могу дать MIST может на нем получится запустить. Там Cyclone EP3C25

Ynicky
02.11.2020, 22:25
Ynicky, могу дать MIST может на нем получится запустить. Там Cyclone EP3C25
А там HDMI есть?

xolod
02.11.2020, 22:30
А там HDMI есть?

Нет только VGA. HDMI есть в MISTER. Но там немного трудней будет переность ядро на него.

Ynicky
02.11.2020, 22:38
Для VGA придется городить VGA контроллер, а это еще сложней.

xolod
02.11.2020, 22:45
Для VGA придется городить VGA контроллер, а это еще сложней.

Нет там просто разьем VGA которовый поключен к fpga через простой видео DAC из резисторов.
Можно подключить vga монитор или телевизор.
Все остальное зависит от вашего ядра.

Ynicky
02.11.2020, 22:53
У меня в проекте используется видеовыход -136 зашивки, который идет напрямую на HDMI контроллер, а там всего 288 строк. Для VGA придется делать какой-нибудь скандаблер.

xolod
02.11.2020, 22:57
У меня в проекте используется видеовыход -136 зашивки, который идет напрямую на HDMI контроллер, а там всего 288 строк. Для VGA придется делать какой-нибудь скандаблер.

Варианта три
1. Поключить MIST через скарт к ТВ.
2. Могу дать монитор LCD который умеент 15кгц, 50гц.
3. Поключить через сканд балер внешний например GBS8200(тоже есть) к обычному VGA монитору.

Titus
02.11.2020, 23:02
Может не стоит уходить от HDMI, если так уже удачно с ним получилось?
Да и HDMI сейчас есть у каждой домохозяйки, а VGA имеют не только лишь все.

xolod
02.11.2020, 23:06
Может не стоит уходить от HDMI, если так уже удачно с ним получилось?
Это только на этапе отладки.

Vslav
02.11.2020, 23:52
Да не работает она в железе, что только не делал. И квартусы ставил разные, вплоть до 18, и моуделсимы с квестосимами, и использовал чиппланеры с лоджилоками, и таймквесты использовал для анализа. А в документации вычитал, что для MAX10 нет поддержки временного моделирования и хоть ты тресни. Потому и пошел на крайние меры.
На старых FPGA можно попробовать, на Cyclone I или ACEX-1K там. У них есть асинхронный сброс-установка триггеров, может быть там латч нормально синтезируется. Ну вдруг. Но как по мне - выброшенное время.

Titus
03.11.2020, 00:02
На старых FPGA можно попробовать, на Cyclone I или ACEX-1K там. У них есть асинхронный сброс-установка триггеров, может быть там латч нормально синтезируется. Ну вдруг. Но как по мне - выброшенное время.
А как вообще люди синтезируют схемы на латчах, если современные FPGA так плохо к ним относятся?
И почему на условной рассыпухе или ПЛМ таких проблем не было?

Vslav
03.11.2020, 00:31
А как вообще люди синтезируют схемы на латчах, если современные FPGA так плохо к ним относятся?
Никак. Только синхронный дизайн.

Titus
03.11.2020, 00:55
Никак. Только синхронный дизайн.
Но ты не ответил, почему на рассыпухе все норм, а в ФПГА не норм.

И как моделируют всякие старые схемы, которые асинхронны? Сперва переделывают их в синхронные?

Vslav
03.11.2020, 09:15
Но ты не ответил, почему на рассыпухе все норм, а в ФПГА не норм.
Какой рассыпухе? 555 серия? Там есть латчи есть в виде готовых элементов - ТМ7 там, или ИР22. В FPGA ничего подобного нет, есть только флип-флопы - TM8 и ИР23.
Даже нельзя надежно имитировать латч на элементах И-НЕ, потому что таковых элементов в FPGA тоже нет. Например, LUT в Cyclone-IV - это два регистра по 8 бит, записываются из конфигурации, и потом два мультиплексора 8-в-1 на проходной логике, которые могут объединяться в 16-в-1. А между двумя LUT - длиннющие каналы для соединения ячеек. Чисто теоретически латч можно на этом всем колхозе, но на практике работает плохо и нестабильно - топология нехорошая выходит, сильно зависит от трассировки (которая обычно автоматическая и меняется на 200 процентов при добавлении строчки в HDL), помехи ловит, повторяемости нет.



И как моделируют всякие старые схемы, которые асинхронны?

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

Есть старые серии ПЛИС, ACEX-1K, например, там триггеры типа ТМ2 - "the programmable flipflop in the LE can be configured for D, T, JK, or SR operation", вот там латчи можно попробовать. Но тут еще проблема времянок влезает, как оно топологически по ячейкам раскладывается - контролировать можно, но очень занудно и для сложных дизайнов затратно, а вот с синхронным тактированием все предсказуемо и понятно. Поэтому асинхронный дизайн умер в массе своей, ну и FPGA по архитектуре подтянулись. Периодически вылезают мутные стартапы, которые обещают асинхронные ПЛИС с в-о-о-о-о-т такой скоростью, и все быстро затихает - не получается надежно проектировать сложные схемы при таком подходе.

Hunta
03.11.2020, 09:31
Я пробовал развлекаться с асинхронным дизайном и пришёл к выводу - теоретически можно, но малейшее изменение - и схема может (и скорее всего) не взлететь - именно из-за того, что ячейки по другому легли и времянка поменялась, а точно её предсказать по всяким внутренним задержкам - не получится - слишком велик (для этого дела) разброс между кристаллами.

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

Хотя, конечно, идея привлекает - именно тем, что быстродействие должно получится больше :)

Vslav
03.11.2020, 10:19
точно её предсказать по всяким внутренним задержкам - не получится - слишком велик (для этого дела) разброс между кристаллами.
Стартапы именно с этим и вылезают - смотрите, у нас новая архитектура ПЛИС и новый софт который позволяет разрабатывать асинхронный дизайн. Что-то простое получается, демки выходят, инвестиции получают, а доходит до полного временного анализа и сложного дизайна - не конкурентно.

Hunta
03.11.2020, 10:35
а доходит до полного временного анализа и сложного дизайна
И хрен поймёшь - то ли накосячил в изменении, то ли ЛЕ по другому разбросаны и соединены и времянка задержек другой стала, а из за особенностей латчей софт не можешь просчитать времянок. Вопчем, пободавшись с этой заманчивой идеей, решил, что не стоит она потраченного времени. Проще смотреть на максимальную частоту, которую квартус после синтеза-анализа времянок покажет и стараться её поднять :)

Titus
03.11.2020, 13:07
Раз уж такой жесткач, и современные ФПГА не вариант для асинхронного дизайна, Ynicky мог бы попросить меня, чтобы я перерисовал схемы ХМ-ок в синхронный дизайн, т.к. я очень хорошо в теме, и понимаю, что надо изменить, чтобы все не окривело.

Vslav
03.11.2020, 13:50
Раз уж такой жесткач, и современные ФПГА не вариант для асинхронного дизайна, Ynicky мог бы попросить меня, чтобы я перерисовал схемы ХМ-ок в синхронный дизайн, т.к. я очень хорошо в теме, и понимаю, что надо изменить, чтобы все не окривело.
Это слишком ненадежно, легко привнести ошибки. Нужна именно эталонная асинхронная схема, которая точно моделируется, и уже только потом можно переписывать на синхронный дизайн, пошагово изменяя, и сравнивая диаграммы с эталоном. То, что ты порисовал свои элементы вместо БФЯ, уже потенциальный источник ошибок (и абстракция другая и нет автоматической машинной трансляции), но приходится пользоваться тем что есть ...

Titus
03.11.2020, 13:52
То, что ты порисовал свои элементы вместо БФЯ, уже потенциальный источник ошибок (и абстракция другая и нет автоматической машинной трансляции), но приходится пользоваться тем что есть ...
Мои элементы - это четкая копия БФЯ, просто собрано в блоки (регистры и прочее), и оптимизировано. Без какого-либо изменения логики.

Vslav
03.11.2020, 14:06
Мои элементы - это четкая копия БФЯ, просто собрано в блоки (регистры и прочее), и оптимизировано. Без какого-либо изменения логики.
Это не так. Ты нарисовал "как ты видишь" 4 (четыре (sic!) схемы), а теперь ты спрашиваешь "где рабочая УКНЦ на FPGA?" и "A какие проблемы с асинхронными схемами на ПЛИС?" Потому что дальше одного шага ты не видел и никого не слушал.

Скажи, ты хорошо понимаешь мои слова "автоматическая генерация HDL по схеме"? Ты хорошо осознаешь, что я могу взять любую пикадовскую схему 1801ВП1, за одну минуту получить нетлист, за вторую минуту получить верилог этой микросхемы, а на третью минуту увидеть все диаграммы в модельсиме, причем с задержками вносимыми реальной микросхемой? При этом нет никакой отсебятины, группирования, ручного перерисовывания и прочего, плюс имеем сквозной контроль с топологией. Ynicky сейчас просто пишет ХМ-ки практически заново опираясь на сомнительные эталоны. Были бы схемы нарисованы с БФЯ - сомнительность эталонов была бы значительно ниже и получены были бы они мгновенно по готовности схемы.

Titus
03.11.2020, 14:19
Были бы схемы нарисованы с БФЯ - сомнительность эталонов была бы значительно ниже и получены были бы они мгновенно по готовности схемы.
Вообще-то у меня для каждой ХМ-ки есть и оригинальные БФЯ-схемы. Единственное отличие - это триггеры сразу нарисованы триггерами. Но тоже без отсебятины.

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

А вот как раз где можно насовать отсебятины - это переписывая асинхронную модель на синхронную.
Я еще не уверен, что твой синхронный ВМ2 соответствует оригиналу ;-) Может даже поймаю это на тестах, если будет модель УКНЦ на ФПГА с твоей синхронной моделью ВМ2.

Vslav
03.11.2020, 14:25
Вообще-то у меня для каждой ХМ-ки есть и оригинальные БФЯ-схемы. Единственное отличие - это триггеры сразу нарисованы триггерами. Но тоже без отсебятины.
Так чего же не выложил?

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



А вот как раз где можно насовать отсебятины - это переписывая асинхронную модель на синхронную.

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


Я еще не уверен, что твой синхронный ВМ2 соответствует оригиналу ;-) Может даже поймаю это на тестах, если будет модель УКНЦ на ФПГА с твоей синхронной моделью ВМ2.

Да я только рад буду, ошибки всегда возможны, дополнительная верификация всегда на пользу.

Titus
03.11.2020, 14:36
Так чего же не выложил?
Все выложено в этой теме. Оригинальная схема на БФЯ, и оптимизированная схема для каждой из ХМ-ок.

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


Твоя отсебятина - волюнтаристкая, а моя вынужденная


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

yu.zxpk
03.11.2020, 15:31
Все выложено в этой теме. Оригинальная схема на БФЯ, и оптимизированная схема для каждой из ХМ-ок.


А можно попросить выложить в 1м посте, чтоб не вычитывать по кругу 137 страниц этой темы?

Hunta
03.11.2020, 15:45
У меня ещё вопрос, а после составления схемы как будет проходить верификация?
Это же не проц на котором можно просто имеющиеся тесты прогнать.
"Мамой килянусь" (с) сами знаете чей :)

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

Да, и на дату вопрос советую посмотреть

Titus
03.11.2020, 16:39
А можно попросить выложить в 1м посте, чтоб не вычитывать по кругу 137 страниц этой темы?
Можно. Выложу ссылки.

Vslav
03.11.2020, 19:34
Все выложено в этой теме. Оригинальная схема на БФЯ, и оптимизированная схема для каждой из ХМ-ок.
1. Присоединяюсь к просьбе выложить все ценное в первом посте этой темы.
2. Я посмотрел бфяшную схему ХМ2-001, там у тебя опять изысканный волюнтаризьм с библиотекой :). Чтобы не страдать с ее написанием на верилоге хорошо бы иметь правильные имена типов, например если ячейка типа 621 то и тип должен быть 621 и три гетерогенных гейта с нумерацией, а не просто NOT. Второй момент - внутренние цепи должны быть поименованные, иначе это автоматически помоделировать можно - а вот осознать - нет :). Так шо - пусть оно уже идет как идет.

Titus
03.11.2020, 20:14
Второй момент - внутренние цепи должны быть поименованные, иначе это автоматически помоделировать можно - а вот осознать - нет . Так шо - пусть оно уже идет как идет.
Такие извращенцы, которым кушают только схему в БФЯ пусть сами и переименовывают, как им нравится. И за это скажите спасибо)

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

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

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

S_V_B
03.11.2020, 20:30
:)

Titus
03.11.2020, 20:40
Alex_K, Vslav, интересную особенность заметил в микрокоде ВМ2, но пока подробно в этом не разбирался.

В режимах HALT и USER по разному анализируется ситуации при выборке следующей команды, когда адресация регистра-источника модифицирует R7, и когда регистр приемник использует R7. Хотя, казалось бы, какая разница, какой режим, HALT или USER.

Alex_K
03.11.2020, 21:39
@Alex_K (https://zx-pk.ru/member.php?u=3184), @Vslav (https://zx-pk.ru/member.php?u=7624), интересную особенность заметил в микрокоде ВМ2, но пока подробно в этом не разбирался.

В режимах HALT и USER по разному анализируется ситуации при выборке следующей команды, когда адресация регистра-источника модифицирует R7, и когда регистр приемник использует R7. Хотя, казалось бы, какая разница, какой режим, HALT или USER.
Это при выборке следующей команды или предвыборке следующей команды? Какие типы адресаций - 67 и 77? Если используется 67 или 77, то по идее процессор может использовать предвыбранную команду в качестве индексного значения для адресации. Да, и в режиме HALT с запрещёнными прерываниями CPC и CPSW не обновляются.

Titus
03.11.2020, 22:16
Да, и в режиме HALT с запрещёнными прерываниями CPC и CPSW не обновляются.
А, вот, наверное, с этим и связано.

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


Это при выборке следующей команды или предвыборке следующей команды? Какие типы адресаций - 67 и 77?
Пока еще не разбирался.
Но там два условия, обозначенных признаками RI0 и RI2:
RI0 - dd использует R7 (любая адресация, с использованием R7)
RI2 - ss модифицирует R7 (любая адресация по (R7), либо индексная адресация)

T.e. ss = (R7), (R7)+, -(R7), @(R7)+, @-(R7), X(Rn), @X(Rn)

Alex_K
03.11.2020, 22:20
Да, и в режиме HALT с запрещёнными прерываниями CPC и CPSW не обновляются.

А, вот, наверное, с этим и связано.
Обновление CPSW происходит не на уровне микрокода, а на аппаратном уровне. Запрещается при установленных битах 7 и 8 в PSW. А вот обновление CPC, не смотрел как происходит. Да и счетчиков команд там целых три.

Titus
03.11.2020, 22:24
Обновление CPSW происходит не на уровне микрокода, а на аппаратном уровне. Запрещается при установленных битах 7 и 8 в PSW. А вот обновление CPC, не смотрел как происходит. Да и счетчиков команд там целых три.
Тоже пока не смотрел, просто заметил это разветвление.
Типа, если USER, то мы проверяем адресацию по R7, если HALT, то мы ничего не проверяем, но идем другим путем.

Titus
08.11.2020, 19:38
Коротко об интересном.

В процессоре ВМ2 дофигищи 16-битных регистров. Гораздо больше, чем доступно посредством инструкций PDP-11.
Если бы микрокод был другим, то, я думаю, процессор мог быть гораздо интереснее и богаче по возможностям.

Интересно, что на шину X АЛУ может выставляться один из 16 регистров,
А на шину Y АЛУ может выставляться один из 32 регистров/констатнт/частей слова инструкции:


0 - R0
1 - R1
2 - R2
3 - R3
4 - R4
5 - R5
6 - R6
7 - PC1
8 - EA1
9 - EA2
10 - нет регистра
11 - RS
12 - PSW
13 - ACC
14 - RA
15 - BRD
16 - IR & 0x000F
17 - IR & 0x003F
18 - 0x0001 (если ALT_CNST=0 (байтовый инкремент))), 0x0002 (если ALT_CNST=1 (словный инкремент)) (константа автоинкремента при формировании исполнительного адреса)
19 - 0x0002
20 - 0x0000
21 - 0x0004
22 - CPSW
23 - BIR
24 - IR & 0x00FF с расширением знака до 16 бит
25 - 0x0000 (если PSW3=0), 0xFFFF (если PSW3=1) (флаг N)
26 - PSW0 & 0x0001 (флга C)
27 - 0x0000
28 - выбор константы вектора прерывания
29 - 0x0014
30 - PC
31 - PC

В списке нет, например, PC2, который может читаться только на шину X АЛУ.

Alex_K
08.11.2020, 22:54
Интересно, что на шину X АЛУ может выставляться один из 16 регистров
А какие регистры?

Titus
08.11.2020, 23:41
А какие регистры?


0 - R0
1 - R1
2 - R2
3 - R3
4 - R4
5 - R5
6 - R6
7 - PC1 (если RA_FR1 = 0) или PC2 (если RA_FR1 = 1)
8 - EA1
9 - EA2
10 - нет регистра
11 - RS
12 - PSW
13 - ACC
14 - нет регистра
15 - BRD

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

Кроме того, есть запись результата обратно в регистр, который выставлялся на X или на Y:

Обратная запись для X:

0 - R0
1 - R1
2 - R2
3 - R3
4 - R4
5 - R5
6 - R6
7 - PC2
8 - EA1
9 - EA2
10 - EA_CTLD (счетчик для расширенной арифметики)
11 - RS
12 - PSW (если /NA0=1, то запись и в PSW4), (если операция со словом (BYTE=0), то запись в PSW4 и PSW8). Работа с константой (PL8=1) блокирует WR_PSW.
13 - ACC
14 - нет регистра
15 - BRD (если QD_SWAP=1, то QSWP=1) (обмен байт при обращении по нечетному адресу)


Обратная запись для Y:

0 - R0
1 - R1
2 - R2
3 - R3
4 - R4
5 - R5
6 - R6
7 - PC2
8 - EA1
9 - EA2
10 - EA_CTLD (счетчик для расширенной арифметики)
11 - RS
12 - PSW (если /NA0=1, то запись и в PSW4), (если операция со словом (BYTE=0), то запись в PSW4 и PSW8). Работа с константой (PL8=1) блокирует WR_PSW.
13 - ACC
14 - нет регистра
15 - BRD (если QD_SWAP=1, то QSWP=1) (обмен байт при обращении по нечетному адресу)
16 - R0
17 - R1
18 - R2
19 - R3
20 - R4
21 - R5
22 - CPSW
23 - R7
24 - EA1
25 - EA2
26 - EA_CTLD (счетчик для расширенной арифметики)
27 - RS
28 - PSW (если /NA0=1, то запись и в PSW4), (если операция со словом (BYTE=0), то запись в PSW4 и PSW8). Работа с константой (PL8=1) блокирует WR_PSW.
29 - ACC
30 - PC
31 - PC

Titus
14.11.2020, 20:11
Краткое описание ядра и основного цикла процессора 1801ВМ2.

Описание составлено исключительно по оригинальной потранзисторной схеме Vslav'a, за которую ему огромная благодарность.

Все сигналы имеют те же наименования, что и на транзисторной схеме Vslav'a. За исключением сигналов NA0..NA5 (адрес следующей микрокоманды), и сигналов PL0..PL36 (выход ПЛМ микрокоманд), которые при описании микрокоманды и адреса микрокоманды приведены в инверсном виде, что более точно отражает суть информации, заложенной в них. Кроме того, добавлено некоторое количество сигналов, не именованых на схеме Vslav'а.

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

Основным времязадающим и управляющим узлом процессора является микропрограммный автомат, который непосредственно управляет АЛУ и блоком ввода-вывода. Управление АЛУ синхронное, т.е. можно сказать, что АЛУ является частью микропрограммного автомата. Управление блоком ввода-вывода асинхронное.

Каждая инструкция процессора выполняется как минимум за две микрокоманды. Первой из которых всегда является команда выборки и преддекодирования инструкции. Цикл микрокоманды равен 4-м тактам входной частоты процессора CLCI. В дальнейшем тактом будет называться один цикл CLCI, а полутактом - половина цикла CLCI. Цикл АЛУ в большинстве случаев также выполняется за 4 такта синхронно с микророграммным автоматом. АЛУ используется как для выполнения математическо-логических операций, так и для вычисления исполнительного адреса. Цикл чтения шины AD блока вввода-вывода, при отсутствии задержек доступа к внешнему устройству, выполняется за 8 тактов. Исключение составляет недокументированный режим чтения шины с опережающим RPLY, который выполняется за 6 тактов, и рассматриваться здесь не будет.
Для выполнения простейшей инструкции процессора требуется две микрокоманды (8 тактов), и один один цикл ввода (8 тактов). Блок ввода-вывода работает в параллель с микропрограммным автоматом, поэтому общее время выполнения простейшей инструкции также составляет 8 тактов.

Микропрограммный автомат может приостанавливаться в некоторых случаях. Чаще всего это происходит, когда буферный регистр инструкции (BIR) еще не содержит действительных данных. Выполнение микропрограммы приостанавливается, пока блок ввода-вывода не прочитает с шины слово инструкции и не обновит BIR.

Микропрограмма находится в ПЛМ микрокоманд, и состоит из 198-ми записей, которые, в свою очередь, условно обьединены примерно в 64 микрокоманды. Та или иная запись выбирается в зависимости от условий, передаваемых в ПЛМ в виде адреса инструкции (16 бит), получаемого с преддекодера адреса микрокоманды (6 бит) и двух трехбитных модификаторов RI0,RI1,RI2 и IX0,IX1,IX2. Преддекодер для упрощения пока что не рассматриваем.
В зависимости от входных данных, выбирается одна или несколько записей ПЛМ, которые обьединяются по логическому ИЛИ (OR), и поступают на выход матрицы в виде сигналов PL0..PL36. В сигналах PL закодированы следующие данные:

1. Номер регистра для шины X АЛУ.
2. Номер регистра или константы для шины Y АЛУ.
3. Математическо-логическая функция для АЛУ.
4. Функция сдвига для АЛУ.
5. Тип операции ввода-вывода.
6. Группа модификаторов, влияющих на выполнение команды.

Трехбитный модификатор выборки микрокоманды RI имеет многофункциональное назначение. В микрокоманде выборки слова инструкции значение следующее:

RI0 - поле dd инструкции использует R7 (любая адресация, с использованием R7)
RI1 - HALT-режим (PSW[8]=1)
RI2 - поле ss модифицирует R7 (адресация (R7), (R7)+, -(R7), @(R7)+, @-(R7), X(Rn), @X(Rn))

Другие значения поля RI будут рассмотрены в отдельной главе.

Трехбитный модификатор выборки микрокоманды IX может меняться для каждого шага микрокоманды и означает:

IX0 - идентификатор словной двухоперандной инструкции записи
IX1 - двухоперандная инструкция использующя R7, выполнено условие условного перехода, или RCMD (требует уточнения)
IX2 - некоторые двухоперандные инструкции

Кроме того, блок преддекодера выдает следующие сигналы, влияющие на исполнение микрокоманд:

DC_RTT - инструкция RTT
DC_FB - инструкция работает с байтом, а не словом
DC_MOP0 и DC_MOP1 - кодирует тип цикла инструкции:


DC_MOP1 DC_MOP0 Операция ввода-вывода Цикл памяти
0 0 IO_RD, IO_IN, IO_WR RMW
0 1 IO_WR W
1 0 IO_RD, IO_IN R
1 1 NOWRA -

Часть сигналов PL, получаемых с выхода ПЛМ микрокоманд используется для выбора режима работы микрокоманды. Большинство же запоминаются в регистре слова микрокоманды (REG_MCMD_WORD), и доступны в виде PLM0..PLM36. Часть сигналов инвертируется.

Диаграммы работы микропрограммного автомата, АЛУ и блока ввода-вывода на примере выполнения простейшей инструкции типа регистр-регистр.
Слева пример с нулевой задержкой памяти, справа пример с задержкой памяти на 2 такта:

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


Для каждой инструкции выполняется микрокоманда с адресом 0x01 (выборка инструкции), и микрокоманда исполнения самой инструкции.
Для наглядности приведен только один цикл АЛУ, и один цикл блока ввода-вывода.


Полутакт:

7 - Готовы сигналы PL с ПЛМ микрокоманд.
Модификатор микрокоманды SET_CEND, означающий выборку следующей инструкции.
Адрес микрокоманды 0x01.
8 - Начало микрокоманды. Регистр BIR (буферный регистр инструкции) содержит действительны данные,
поэтому безо всякой задержки запускается конвейер преддекодера инструкции.
9 - Данные с преддекодера инструкций выставляются на шину PLD.
10 - Данные с преддекодера инструкций стабильны и могут быть защелкнуты в регистре инструкций.
Они содержат слово инструкции, адрес первой микрокоманды инструкции, модификаторы IX, RI.
В соответствии с микрокомандой на шину X АЛУ выдается PC2 (опережающий счетчик команд),
а на шину Y АЛУ выдается константа 0x0002.
11 - В соответствии с микрокомандой формируется операция ввода-вывода IO_RD (чтение шины AD),
IO_IN (данные предназначены для BIR), IO_RCD (сохранять данные также в BRD (буферный региср данных)
12 - RA (регистр адреса) = PC2. Запросить цикл шины IO_RD.
Блок ввода-вывода свободен, поэтому сразу начинается операция ввода.
На шину адреса выставляется регистр адреса RA, в котором содержится значение опережающего счетчика команд PC2.
13 - PC=PC1=PC2 (действие операции IO_RCD).
16 - PC2=PC2+2 (результат работы АЛУ).
Выставляется сигнал SYNC (адрес выставлен на шине).
Сразу получаем в ответ сигнал AR (подтверждение получени адреса).
В этом же полутакте начинается исполнение следующей микрокоманды, собственно и выполняющей инструкцию.
18 - Выставляется сигнал DIN (ввод информации с шины).
20 - Получено подтверждение RPLY.
22 - Данные на шине AD стабильны, и начинают записываться в регистры BIR и BRD.
24 - Начало следующей микрокоманды, извлекающей инструкцию из регистра BIR.
26 - Снимается сигнал DIN. Шина AD может быть освобождена.
28 - В ответ внешнее устройство снимает SYNC, AR и RPLY. Возможна новая операция ввода-вывода.

Titus
15.11.2020, 19:38
Одиним из случаев приостановки работы АЛУ и микропрограммы является удержание регистра адреса RA.

Регистра RA содержит адрес, выставляемый на шину AD в цикле чтения/записи. Ввиду того, что этот реигстр не буферизирован, а транслируется на шину напрямую, он требует защиты от перезаписи в то время, пока адрес удерживается на шине AD. За защиту RA от перезаписи отвечает сигнал RA_HOLD.

Работа АЛУ с регистром RA отличается от работы с другими регистрами следующими особенностями:

1. Регистр RA может обновлятся не только в конце цикла АЛУ (по WR2), сохраняя результат математическо-логической операции, но и в самом начале цикла АЛУ (по ALU_WR). Такая возможность позволяет более удобно и быстро реализовывать постинкрементные режимы адресации, когда одна операция АЛУ сперва выдает исполнительный адрес блоку ввода-вывода, а затем инкрементирует адрес, в то время, как блок ввода-вывода уже работает.
2. Каждая запись в регистр RA сразу же запрашивает цикл ввода-вывода. И если блок ввода-вывода свободен, начинается обмен.
3. Как только запрошен цикл ввода-вывода, регистр RA блокируется сигналом RA_HOLD до тех, пор, пока не будет получен ответ AR (подтверждение адреса), с задержкой до 2-х тактов (по заднему фронту сигнала RTA). Если RA заблокирован, то любой следующий цикл АЛУ/микрокоманды, обновляющий RA, будет приостановлен до тех пор, пока не будет снят сигнал RA_HOLD. Цикл, не обновляющий RA, будет работать без задержки.

На графике приведены примеры блокировки регистра RA.
1. Слева RA обновляется в начале цикла АЛУ (по ALU_WR). Задержка следующей микрокоманды 2 такта.
2. Справа RA обновляется в конце цикла АЛУ (по WR2). Задержка следующей микрокоманды 4 такта.

https://pic.maxiol.com/images2/1605457731.2151951043.ra.png

p.s.: Предыдущий пост тоже обновлен и дополнен.

Titus
18.11.2020, 02:16
Расшифровал и составикл карту аппаратных прерываний.

Справа-налево:

1. Номер записи в ПЛМ прерываний
2. Группа условий для срабатывания прерывания
3. Служебные флаги
4. Вектор и описание, приоритет в квадратных скобках

Комбинации поля RI:

000 - режим WAIT
001 - нет запроса на прерывание
100 - прерывание в режиме USER
110 - прерывание в режиме HALT
111 - начальный пуск

Примечание: TOVF - зависание, TOVF2 - двойное зависание
Замечание: Во всех случаях, если не указано иное, AC0_ECHO=1



[0]
Подготовка начального пуска?
10: AC0_ECHO=0 ALCO_FALL=0 VECID=0x0, RI=000 AC0 WAIT?

Начальный пуск
1: AC0_ECHO=0 ALCO_FALL=1 VECID=0xF, RI=111 ACLO_ACK VEC=0x00 (Начальный пуск)

[1.0]
Зависание при приеме АВП
6: TOVF=1 VEC=1 VECID=0x4, RI=110, TOVF_ACK VEC=0xBC (Зависание при приеме АВП)

[1.1]
Двойное зависание
2: TOVF=1 VEC=0 TOVF2=1 VECID=0xC, RI=110, TOVF_ACK VEC=0x7C (Двойное зависание)

Зависание
0: TOVF=1 VEC=0 TOVF2=0 VECID=0xD, RI=100, TOVF_ACK VEC=0x04 (Зависание в режиме USER)
0,18: TOVF=1 VEC=0 TOVF2=0 PSW8=1 VECID=0xD, RI=110, TOVF_ACK VEC=0x04 (Зависание в режиме HALT)

[3]
Прерывание по T-разряду
8: TOVF=0 WAIT/TBIT=01 VECID=0xA, RI=100 VEC=0x0C (T-разряд)
8,12: TOVF=0 WAIT/TBIT=01 RTT=1 VECID=0xA, RI=001 VEC=0x0C (Т-разряд + RTT) (Нет прерывания?)

[4]
Сигнал ACLO в режиме HALT с запрещенными прерываниями
13: TOVF=0 ALCO_RISE=1 PSW87=11 WAIT/TBIT=00 VECID=0x0, RI=001 Нет прерывания
17: TOVF=0 ALCO_RISE=1 PSW87=11 WAIT=1 VECID=0x0, RI=000 WAIT

Сигнал АCLO не в режиме HALT с запрещенными прерываниями
15,22: TOVF=0 ALCO_RISE=1 PSW87!=11 WAIT/TBIT!=01 VECID=0x0, RI=100, ACLO_ACK VEC=0x14 (ACLO)

[5]
Прерывание по сигналу HALT в режиме USER
7,9: TOVF=0 ALCO_RISE=0 HALT=1 PSW8=0 WAIT/TBIT!=01 VECID=0x2, RI=110 VEC=0x78 (HALT)

Прерывание по сигналу HALT в режиме HALT
11: TOVF=0 ALCO_RISE=0 HALT=1 PSW8=1 WAIT/TBIT=00 VECID=0x0, RI=001 Нет прерывания
21: TOVF=0 ALCO_RISE=0 HALT=1 PSW8=1 WAIT=1 VECID=0x0, RI=000 WAIT

[5.1]
Прерывания запрещены, не обрабатывать EVNT и VIRQ
4: TOVF=0 ALCO_RISE=0 HALT=0 PSW7=1 WAIT/TBIT=00 VECID=0x0, RI=001 Нет прерывания
16: TOVF=0 ALCO_RISE=0 HALT=0 PSW7=1 WAIT=1 VECID=0x0, RI=000 WAIT

[6]
Прерывание по событию EVNT
3,5: TOVF=0 ALCO_RISE=0 HALT=0 EVNT_RISE=1 PSW7=0 WAIT/TBIT!=01 VECID=0x3, RI=100 EVNT_ACK VEC=0x40 (EVNT)

[7]
Векторное прерывание VIRQ
19,23: TOVF=0 ALCO_RISE=0 HALT=0 EVNT_RISE=0 VIRQ=1 PSW7=0 WAIT/TBIT!=01 VECID=0x0, RI=101

[8]
Всякий режим, когда нет ни одного запроса прерывания
14: TOVF=0 ALCO_RISE=0 HALT=0 EVNT_RISE=0 VIRQ=0 WAIT/TBIT=00 VECID=0x0, RI=001 Нет прерывания
20: TOVF=0 ALCO_RISE=0 HALT=0 EVNT_RISE=0 VIRQ=0 WAIT=1 VECID=0x0, RI=000 WAIT

Titus
18.11.2020, 21:57
Модификатор выборки микрокоманды RI.

Трехбитный модификатор выборки микрокоманды RI имеет многофункциональное назначение, в зависимости от выбранного режима.

1. Режим выборки инструкции (стробируется сигналом IR_STB). Инициируется сигналом SET_CEND (PL26=1, PL25=0, /NA=0), и используется только в одной микрокоманде с адресом 0x01.

RI0 - поле dd инструкции использует R7 (любая адресация, с использованием R7)
RI1 - HALT-режим (PSW[8]=1)
RI2 - поле ss модифицирует R7 (адресация (R7), (R7)+, -(R7), @(R7)+, @-(R7), X(Rn), @X(Rn))

2. Режим разбора запроса аппаратного прерывания (стробируется сигналом PLI_ACK). Инициируется сигналом PLI_REQ (PL27=0, /NA1=0). Обычно инициируется в последней микрокоманде каждой инструкции, перед переходом на микрокоманду 0x01.

RI2.RI1.RI0:

000 - режим WAIT
001 - нет запроса на прерывание
100 - прерывание в режиме USER
110 - прерывание в режиме HALT
111 - начальный пуск

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

нет описания

Замечание. В режиме (1) RI0 может только сбрасываться, а RI1 и RI2 только устанавливаться. Потому микрокоманда выборки инструкции чаще всего вызывается после микрокоманды инициирующей разбор запроса прерывания, со входящим значением RI равным 001.

p.s.: Предыдущие статьи тоже обновились.

Alex_K
18.11.2020, 23:07
TOVF - зависание, TOVF2 - двойное зависание
А вот здесь интересный момент. При возникновении зависания должен устанавливаться какой-то флаг. Если снова происходит зависание при уже установленном флаге, то производится прерывание по двойному зависанию. Соответственно вопрос - при каких условиях сбрасывается этот флаг? По идее он должен сбросится, если операция ввода-вывода прошла нормально, т.е. есть ответ по RPLY. Но по моим опытам получалось, что данный флаг сбрасывался только при успешном чтении команды.

Titus
18.11.2020, 23:19
прерывание по двойному зависанию. Соответственно вопрос - при каких условиях сбрасывается этот флаг?
Сбрасывается по микрокоманде чтения следующей инструкции или по reset'у.
А флаг простого зависания сбрасывается при вызове обработчика прерывания по зависанию.

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


А вот здесь интересный момент. При возникновении зависания должен устанавливаться какой-то флаг.
Это и есть флаги.
TOVF - флаг обычного зависания,
TOVF2 - флаг двойного зависания

Alex_K
18.11.2020, 23:33
Сбрасывается по микрокоманде чтения следующей инструкции или по reset'у.
А флаг простого зависания сбрасывается при вызове обработчика прерывания по зависанию.
Ага! Конкретный пример: Указатель стека равен 01000, в 4-м векторе находится адрес 0170000. Ячейка 0170000 нечитаемая, нет ответа RPLY, должно произойти прерывание по вектору 4.
Командой TST @#170000 читаем ячейку с адресом 0170000. Ответа по RPLY нету, потому производится прерывание по вектору 4. Сначала в стек по адресам 0774 и 0776 ложатся текущие CPC и CPSW. Запись в стек происходит нормально, нет никакого зависания. Далее из ячеек 4 и 6 читаются новые значения PC и PSW. Здесь тоже всё нормально, без зависаний. А вот далее интересней. Т.к. новая команда находится по адресу 0170000, то при её чтении произойдёт зависание, а т.к. флаг не сброшен, то будет двойное зависание. Вроде так.

Titus
18.11.2020, 23:43
Вроде так.
Такая сложная цепочка меня запутала, но, наверное, так)

Alex_K
18.11.2020, 23:54
Такая сложная цепочка меня запутала, но, наверное, так)
Ну по моим опытам получалось так. И ещё один вопрос - по моим опытам также получалось, что при прерываниях режима USER в стек ложатся именно CPC и CPSW, а не PC и PSW.

Titus
19.11.2020, 00:23
по моим опытам также получалось, что при прерываниях режима USER в стек ложатся именно CPC и CPSW, а не PC и PSW.
Вот до разбора микрокода обработки прерываний я еще не дошел.

Alex_K
19.11.2020, 00:24
Вот до разбора микрокода обработки прерываний я еще не дошел.
Жду с нетерпением.

Titus
19.11.2020, 00:36
Жду с нетерпением.
Там работы немало, скажу я вам)

Вообще, процессор в целом весьма сложная штуковина. Я думаю, какой-нибудь Z80 явно в разы попроще.
Тут и независимые блоки, и конвейеры в каждом блоке, сложные зависимости.
И, самое интересное, есть много вещей, которые словно приляпывались поверх уже существующих. Я не говорю о расширенной арифметике, которая именно так и сделана.
Например, модификаторы для микрокоманды сделаны совершено по-разному. Этому один бит, этому два, этому три, и все эти биты разбросаны, перемешаны и доляпаны друг к другу. Не говоря уже о том, то, видимо, за нехваткой разрядности микрокода, в качестве модификаторов использовались даже отдельные биты адреса следующей микрокоманды (NA5..NA0). Так что сборной солянки для расшифровки там не мало.
Ну, и, конечно же многофункциональное поле RI, сделанное в виде трехпортового трехбитного регистра, при этом третий порт работает в виде reset/set/set, как описано чуть выше.
Полно было триггеров, которых надо было проверять, не встанут ли они в третье состояние.
Словом, распутано и приведено в человеческий вид многое, но еще не все.

Я вообще не понимаю, как Vslav разбирается в потранзисторной схеме, или же в ее аналоге на VHDL. Запускать это можно, отследить любые сигналы можно, но разобраться во всей поднаготной и систематизировать реверс, при этом не теряя всю общую картину, по такой схеме для меня было бы нереально.

CodeMaster
19.11.2020, 12:02
но разобраться во всей поднаготной и систематизировать реверс
Думацо, он не ставил такой цели. Можно же реверс разделить на несколько этапов:
1. Чтоб работало как оригинал;
2. Чтоб понять как работает оригинал;
3. Чтоб понять почему оригинал сделали именно так.

Titus
19.11.2020, 12:32
2. Чтоб понять как работает оригинал;
3. Чтоб понять почему оригинал сделали именно так.
Вот мне как раз важно 2-е.
Ибо, я эмуляторщик, и если соберусь писать потактовый УКНЦ, то без второго пункта можно даже не пробовать.
Естественно, писать даже потактовую эмуляцию в виде эмуляции всех вентилей - это абсурд и дикие тормоза.
А, стало быть, надо понять ВСЮ структуру процессора до мелочей, и преобразовать в тот вид, когда это уже можно эмулировать, а не просто тупо повентильно симулировать.
Поэтому, опять же, верилог для основы мне не подходит.

Titus
19.11.2020, 23:06
Alex_K, интересное наблюдение.
При обработке прерывания безадресный регистр (SEL) читается в любом случае, независимо от того, в режиме USER обрабатывается прерывание или в режиме HALT.

Alex_K
19.11.2020, 23:16
@Alex_K (https://zx-pk.ru/member.php?u=3184), интересное наблюдение.
При обработке прерывания безадресный регистр (SEL) читается в любом случае, независимо от того, в режиме USER обрабатывается прерывание или в режиме HALT.
Да, это уже известно. Было обнаружено при моделировании процессора. Да и в официальной документации описано, рис.51 во второй части ТО.

Titus
19.11.2020, 23:33
Да, это уже известно.
А я уж думал, что открыл Америку)

Видимо, решили не заморачиваться, и для упрощения микрокода сделали чтение SEL для всех прерываний, а потом уже разбор, какому прерыванию по какой ветке идти. Тем более, что чтение SEL занимает всего 4 такта.

Alex_K
19.11.2020, 23:34
А я уж думал, что открыл Америку)

Видимо, решили не заморачиваться, и для упрощения микрокода сделали чтение SEL для всех прерываний, а потом уже разбор, какому прерыванию по какой ветке идти. Тем более, что чтение SEL занимает всего 4 такта.
Вероятнее всего, что так и есть. Это, кстати, сохранено и в 1806ВМ2. А куда читается SEL?

Titus
19.11.2020, 23:53
Вероятнее всего, что так и есть. Это, кстати, сохранено и в 1806ВМ2. А куда читается SEL?
Все, что читается с шины, размещается в BRD (буферный регистр данных).
А если читается код следующей инструкции, то он размещается и в BRD, и в BIR (буферный регистр инструкций) одновременно.

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

Уточню - все, что я уже рассмотрел. Но могут быть режимы, до которых я еще не добрался.

Titus
20.11.2020, 16:30
Чтение вектора прерывания в документации от Alex_K нарисовано неправильно:

https://pic.maxiol.com/images2/1605878838.2151951043.iak0.png


На самом деле происходит так:

https://pic.maxiol.com/images2/1605878860.2151951043.iak1.png

То есть, данные с шины защелкиваются внутри активного DIN, а точнее внутри RDAT.

А если ответить RPLY не дожидаясь IAKO, то можно сократить время чтения на два такта,
хотя практической пользы от этого, видимо, никакой.

https://pic.maxiol.com/images2/1605878971.2151951043.iak2.png

Titus
21.11.2020, 07:34
Цикл записи шины в процессоре ВМ2 (12 тактов) значительно медленнее, чем цикл чтения (8 тактов).
Кроме того, невозможно задать опережающий RPLY, таким же образом, как в цикле чтения, чтобы сократить время доступа к шине. Это связано с тем, что 'увидев' RPLY на шине, контроллер не выдаст данные. Поэтому, если мы хотим ускорить запись опережающим RPLY, выдавать его нужно после того, как на шину выставлены данные, но до того, как появился сигнал DOUT.
Как же этого добиться? В принципе, такое возможно.
Например, после получения адреса сперва ожидаем появление на шине значения 0x0000, затем ожидаем любого изменения на шине, либо же появления сигнала DOUT. После чего выдаем RPLY.
В случае, если записывается число 0x0000, опережающего RPLY выдать не получится. При записи любого другого числа, RPLY будет с опережением, и цикл записи сократится до 10 тактов.
Конечно, это усложнит контроллер памяти, но позволит ускорить запись.

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

Titus
23.11.2020, 23:05
Все, что вы хотели узнать о команде CODE030, но боялись спросить :v2_wink2:

Пояснения:

1. На флаги VZNC влияют все микрокоманды, однако переписывают их в PSW только те, у которых это отдельно указано.
2. Режим проверки условий GET_STATE устроен таким образом, что условия проверяются по окончании микрокоманды,
добавляя к ней еще 4 такта (а что делать, надо же прокачать PLM проверки условий),
а результат проверки (BRA=1, если условие совпало) доступен уже в следующей микрокоманде.
В начале следующей микрокоманды условие будет сброшено (BRA=0), в независимости от того, воспользовались им или нет.
3. SEXT() - расширение знака байта до слова.


//================================================== ====================
//
// Команда CODE030 (000030)
//
//================================================== ====================

Адрес Микрокоманда PSW Дополнительно Комментарий

0x05: R0=0
//----------------------------------------------------------------------
0x27: ACC.B=R2 GET_STATE N=0 // Если N=0, то BRA=1, иначе BRA=0
//---------------------------------------------------------------------- Начало цикла
0x35: if (BRA=1) // Если BRA=1 (в прошлой команде N=0)
R0.B=R0+1 GET_STATE N=0 // Если N=0, то BRA=1, иначе BRA=0
else // Иначе
ACC=R0 VZNC PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x01 // и перейти на команду выборки следующей инструкции
//----------------------------------------------------------------------
0x31: if (BRA=1) // Если BRA=1 (в прошлой команде N=0)
R1=R1<<1
else // Иначе
ACC=R0 VZNC PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x01 // и перейти на команду выборки следующей инструкции
//----------------------------------------------------------------------
0x19: R3=(R3<<1)|PSW[0]
//----------------------------------------------------------------------
0x1E: R2=SEXT((R2<<1)|PSW[0]) GET_STATE N=0 // Если N=0, то BRA=1, иначе BRA=0
GOTO 0x35 // Перейти на команду 0x35

Alex_K
23.11.2020, 23:23
Все, что вы хотели узнать о команде CODE030, но боялись спросить
Ну в общем мой алгоритм, выясненный методом научного тыка, оказался правильным:

Алгоритм:
R0:=0;
while ((R0[7]==0) && (R2[7]==0))
{
R1:=R1<<1 | 0; R2[07:00]:=R2[07:00]<<1 | C;
R2[15:08]:=R2[7]; R3:=R3<<1 | C; R0++;
}
N:=0; Z:=(R0==0); V:=0; C:=0

Описание: По этой команде сперва очищается регистр R0. Далее исполняется цикл, окончанием которого является установка в разряде 07 R0 или R2 единицы. В цикле над регистрами проводятся следующие действия: регистры с R1 по R3 сдвигаются влево, при этом в R1 в младший разряд вдвигается ноль, а в R2 и R3 – содержимое разряда C, при этом старшая часть R2 расширяется знаковым разрядом младшей части, R0 инкрементируется. Так как останов исполнения команды производится при наличии единицы в разряде 7 в R0 или R2, то после исполнения команды R0 может принимать значения от 0 до 108 или 2008. Значение 2008 получается в том случае, если до исполнения операции младшая часть R2 была равна нулю и был сброшен бит С.
Признаки: N – очищается, Z – устанавливается, если значение в R0 равно нулю, в противном случае очищается, V – очищается, C – очищается.

Вопрос в другом. Это наверное разработчики так промахнулись или как? Команды с кодами от 020 до 027 используются для чтения, а с кодами от 030 до 037 для записи. Но записи регистра SEL нету, потому команда 030 должна выполняться также, как и 020. В 1806ВМ2 эту ошибку уже исправили. Тут надо смотреть, как производится дешифрация и исполнение кодов от 020 до 037.

Titus
23.11.2020, 23:27
Тут надо смотреть, как производится дешифрация и исполнение кодов от 020 до 037.
Нет, не промахивались. Абсолютно четко написан микрокод именно для этой команды. Никакая другая команда целиком, или частично его не использует.

Alex_K
23.11.2020, 23:33
Нет, не промахивались. Абсолютно четко написан микрокод именно для этой команды. Никакая другая команда целиком, или частично его не использует.
Ну тогда большая загадка. Для чего нужен этот алгоритм? И почему тогда отказались от этой команды в 1806ВМ2?

И всё таки как при дешифрации команд с 020 по 037 получаются начальные адреса микрокода? Кстати, эти команды работают только в HALT-режиме, потому должно быть условие при дешифрации - в TRAP10 или на исполнение.

Titus
23.11.2020, 23:40
И дешифрация идет совершенно четкая, а в микрокоманде, где CODE030 должна быть не перепутана с остальными из диапазона 00020..00030, она дешифруется по маске ....0.....011000.
Как видно, это покрывает весь диапазон от 00 до 77, и путаницы частичной дешифрации тут быть не может.

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


И всё таки как при дешифрации команд с 020 по 037 получаются начальные адреса микрокода? Кстати, эти команды работают только в HALT-режиме, потому должно быть условие при дешифрации - в TRAP10 или на исполнение.
Сначала преддекодером выделяется группа особых команд:


000101 00 FIS, CLx, SEx, EMT, TRAP
000101 10 MARK
000101 11 HALT, WAIT, RTI, BPT, IOT, RESET, RTT, START, STEP, RSEL, MFUS, RCPC, RCPS, CODE30, MTUS, WCPC, WCPS,

Им задается стартовый адрес микрокоманды 0x05:

А в микрокоманде 0x05 они уже сортируются, и каждая идет своим путем:


NA: 0x05 [0] HALT, WAIT, RTI, BPT, IOT, RESET, RTT, START, STEP,
RSEL, MFUS, RCPC, RCPS, CODE30, MTUS, WCPC, WCPS,
CLx, SEx, MARK, FIS, EMT, TRAP



46: ....0.....01.... 111010 .0. ... ...11. ..1.......1..................11 USER: RSEL, MFUS, RCPC, RCPS, CODE030, MTUS, WCPC, WCPS
57: ....0.....001... 111010 .0. ... ...11. ..1.......1..................11 USER: START, STEP
77: ....0...0..10000 111010 .1. ... 1..... ..1...1.11........1.11.1.11..1. HALT: RSEL (IO_SEL, IO_RD, IO_IN)
112: ....0...0..10001 111010 .1. ... 1..... ..1.....11...1..1111..11.1..11. HALT: MFUS (IO_ALT, IO_RD, IO_IN)
136: ....0.....001... 111010 .1. ... 1..... ..1...............11111111...1. HALT: START, STEP
45: ....0.....011000 111010 .1. ... 1..... ..1.................1.1......1. HALT: CODE030
X=R0, Y=0, R0=XQ=Y=0
100: ....0.....011001 111010 .1. ... 1..... ..1....1.1...1...111..11.1.111. HALT: MTUS (IO_ALT, IO_WR)
13: ....0.....01101. 111010 .1. ... ...... .1...........1..1.............. HALT: WCPC
9: ....0.....0111.. 111010 .1. ... ...... .1...........1..1.............. HALT: WCPS

162: ....0...0..1.01. 1110.0 ... ... ...11. ..................11111......1. RCPC, WCPC
129: ....0...0..1.1.. 1110.0 ... ... ...11. ...................11.1......1. RCPS, WCPS
104: ....0.....000000 111010 ... ... ...11. ..1..........1..............111 HALT
66: ....0.....000001 111010 ... ... ...11. ..1.............1.............1 WAIT
113: ....0...0..00.10 111010 ... ... 1..... ..1...1.1....1..1111..1.11..11. RTI, RTT (IO_RD, IO_IN)
29: ....0.....000.11 111010 ... ... ...11. ..1..........................11 BPT
98: ....0.....000100 111010 ... ... ...11. ..1........1.................11 IOT
58: ....0.....0001.1 111010 ... ... 1...1. ..1..............1..........1.1 RESET

36: ....0.....1..... 111010 ... ... 1..... .11...................1....1... CLx, SEx
106: ........1....... 11.0.0 ... ... ...... ........................1....1. CLx, SEx
157: .....1.......... 111010 ... ... 11..1. .11..........1..111...1111.1.1. MARK
96: ......1......... 111010 ... ... 1..... ..1...1.11........1.11.1.11..1. FIS (IO_SEL, IO_RD, IO_IN)
151: 1............... 111010 ... ... ...11. ..1.......11.................11 EMT, TRAP
20: .....0.1........ 111010 ... ... ...... ............11................. TRAP

Следующий шаг: HALT: START, STEP, RSEL, MFUS, CODE030, MTUS - 0x27
HALT: WCPS, WCPC, RCPS, RCPC - 0x01
USER: RSEL, MFUS, RCPC, RCPS, CODE030, MTUS, WCPC, WCPS, START, STEP - 0x01
CLx, SEx, RTI, RTT, FIS - 0x27
RESET - 0x25
MARK - 0x35
EMT, TRAP - 0x01

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


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

Alex_K
23.11.2020, 23:43
А в микрокоманде 0x05 они уже сортируются, и каждая идет своим путем:
Идёт на адрес 45, а в описании выше всё начинается с 05, там же и очистка R0.

Titus
23.11.2020, 23:48
Идёт на адрес 45, а в описании выше всё начинается с 05, там же и очистка R0.
Не совсем понял вопрос.
Первый шаг с адресом 0x05. На нем сортируются инструкции, выделяется CODE030 и для нее выполняется R0=0. Затем идет на шаг 0x27.
На шаге 0x27 опять идет сортировка, выделение CODE030, и для нее выполняется ACC.B=R2. И идет на шаг 0x35.
Ну и так далее.

Alex_K
23.11.2020, 23:52
Не совсем понял вопрос.
Первый шаг с адресом 0x05. На нем сортируются инструкции, выделяется CODE030 и для нее выполняется R0=0. Затем идет на шаг 0x27.
На шаге 0x27 опять идет сортировка, выделение CODE030, и для нее выполняется ACC.B=R2. И идет на шаг 0x35.
Ну и так далее.


NA: 0x05 [0] HALT, WAIT, RTI, BPT, IOT, RESET, RTT, START, STEP,
RSEL, MFUS, RCPC, RCPS, CODE30, MTUS, WCPC, WCPS,
CLx, SEx, MARK, FIS, EMT, TRAP

45: ....0.....011000 111010 .1. ... 1..... ..1.................1.1......1. HALT: CODE030
X=R0, Y=0, R0=XQ=Y=0

Titus
23.11.2020, 23:56
45 - это не шаг, это номер записи в PLM. От 0 до 199.
В каждой команде таких записей может быть несколько. Из них выбираются те, что совпадают с заданными условиями - маска кода инструкции и много дополнительных условий, включая режим HALT/USER.

Alex_K
24.11.2020, 00:07
Это же сколько надо было потрудиться, чтобы выловить алгоритм работы этой команды методом нучного тыка)
Выловил я эту команду давно. Выловил в пультовом отладчике при нулевых регистрах. Понятное дело, что при нулевых регистрах получалось значение 0200. И я даже был уверен, что это значение PSW для старта. Ну типа того, что по коду 020 получаем 0160000, это стартовый вектор. Ну и по 030 получается начальное значение PSW при включении питания до чтения стартового вектора. Сомнения были в том, почему не установлен бит H. Да и заметил, что после исполнения 030 меняется PSW, что очень меня смутило. Несколько лет я этой проблемой не занимался. Ну а потом как-то решил поисполнять эту команду с различными начальными значениями регистров. Ну тут и понеслось, а когда заметил, что ещё влияние оказывает бит C в PSW, то вообще весело стало.

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


Первый шаг с адресом 0x05. На нем сортируются инструкции, выделяется CODE030 и для нее выполняется R0=0.
R0 очищается только для 030?

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


Это же сколько надо было потрудиться, чтобы выловить алгоритм работы этой команды методом нучного тыка)
Titus, мой труд это ничто, по сравнению с вашими и Vslav-а. Так ещё вам ОГРОМНОЕ СПАСИБО.

Titus
24.11.2020, 00:17
R0 очищается только для 030?
В данной команде да.
Уверяю, CODE030 не совмещен ни в одной команде с другими инструкциями. Для него четко написана эта логика. Причем, эта логика не явялется мусором. Другой вопрос, что в нее заложено и зачем. Возможно, что-то тестовое. Или хотели сделать одно, а получилось другое. Но то, что четко хотели - это однозначно.

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


Titus, мой труд это ничто, по сравнению с вашими и Vslav-а. Так ещё вам ОГРОМНОЕ СПАСИБО.
Все друг другу помогают.
Мой реверс ВМ2 в виде логической схемы, и выведенного из него понимания работы, стоит на трех китах, построенных Vslav'ом, который днями и ночами, а иногда и после полудня трудился, переводя схему с фотографии в транзисторный вид. А потом еще подписывая цепи.

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

Я, честно говоря, когда засел за ВМ2 в августе, думал, что я щас быстренько переведу все в логику и пойму, как работает.
Фигушки. Перевел я может и быстро, но вот оказался он таким монстром, что если бы я знал заранее, может быть и не брался бы) Ну нафиг)

Alex_K
24.11.2020, 00:24
Уверяю, CODE030 не совмещен ни в одной команде с другими инструкциями. Для него четко написана эта логика. Причем, эта логика не явялется мусором. Другой вопрос, что в нее заложено и зачем. Возможно, что-то тестовое. Или хотели сделать одно, а получилось другое. Но то, что четко хотели - это однозначно.
Вот в том и вопрос. А ответа наверное щас уже и не получить. По документации чётко написано, что 020 и 030 исполняются одинаково. Да и в 1806ВМ2 это убрали, там 030 исполняется как 020.

Titus
24.11.2020, 00:52
Вот в том и вопрос. А ответа наверное щас уже и не получить. По документации чётко написано, что 020 и 030 исполняются одинаково. Да и в 1806ВМ2 это убрали, там 030 исполняется как 020.
Если только удастся понять логически, чтобы это могло быть, и какую функцию могло выполнять.
Ясно, что что-то циклическое. Счетчик в R0. Он не может превысить 128. При выходе устанавливает флаги, значит они зачем-то могут быть нужны.
Может подсчитывает позицию первого значимого бита в R2.
Смотрите, если R2[7]=1 при входе, значит впереди числа 0 значащих бит. R0=0.
А дальше в цикле двигается и проверяется, пока первый ненулевой бит в R2 не достиг позиции 7. Тогда цикл прекращается и выдает в R0, сколько нулевых бит было до первого значащего бита.
Так же цикл ограничен 128 итерациями на случай, если человек задал неправильные данные.
А установленный бит C позволяет остановить все, если R2 был равен 0.

Игого, устанавливаем бит C=1, пишем в R2 любое число, и получаем на выходе в R0 число ведущих нулевых бит. И еще в Z получаем условие, не ноль ли там было бит ведущих.
Другой вопрос, почему эта команда только для HALT-режима. Даешь USER'ам равные с HALT'ом права на использование полезных инструкций!

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

Возможно, это хотели использовать для целей преобразования целого числа в число с плавающей точкой.
Таким образом можно было узнать порядок числа. Но, может быть не понадобилось, или получилось с ошибкой. Например, хотели двигать циклически R2<<R3<<R1, а написали неправильно, и забили потом.

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

Смотрите, допустим сдвиг действительно должен был быть циклическим, тогда:
R2.R3.R1 - начальное целое число.
после выполнения инструкции, R0 показывает число ведущих нулевых бит (порядок), а R2.R3.R1 сдвигается до упора влево, выравниваясь по левому краю мантиссы. Очень все логично.
Но накосячили, и цикличность не получилась.

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

Да, я уже уверен, что это для этого и было предназначено.

Alex_K
24.11.2020, 00:52
Смотрите, допустим сдвиг действительно должен был быть циклическим, тогда:
R2.R3.R1 - начальное целое число.
после выполнения инструкции, R0 показывает число ведущих нулевых бит (порядок), а R2.R3.R1 сдвигается до упора влево, выравниваясь по левому краю мантиссы. Очень все логично.
Но накосячили, и цикличность не получилась.
Мысль очень здравая, целиком поддерживаю. А косячность получилась в том, что между регистрами перенос не поддерживался, в итоге в R3 и R2 всё время вдвигался бит C с PSW. А так, да сдвиг влево мантиссы - это её нормализация. В R0 получаем на сколько надо прибавить порядок. Но это только одна часть. Иногда для нормализации мантиссу надо двигать вправо, а это вроде не реализовано. Ну и эмуляция FIS производится в HALT-режиме, потому и эта команда работает только в HALT.

Titus
24.11.2020, 00:55
Мысль очень здравая, целиком поддерживаю. А косячность получилась в том, что между регистрами перенос не поддерживался, в итоге в R3 и R2 всё время вдвигался бит C с PSW. А так, да сдвиг влево мантиссы - это её нормализация. В R0 получаем на сколько надо прибавить порядок. Но это только одна часть. Иногда для нормализации мантиссу надо двигать вправо, а это вроде не реализовано. Ну и эмуляция FIS производится в HALT-режиме, потому и эта команда работает только в HALT.

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

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

Перенос можно было сделать легко, прописав запись бита C в PSW[0] после каждой команды сдвига.
Но не шмогли.

Titus
24.11.2020, 21:20
Микропрограммы для SOB, RTI и RTT:

SOB:

//================================================== ====================
//
// Команда SOB Rn,mm (077xxx)
//
//================================================== ====================

0x0D: Rn=Rn-1 GET_STATE Z=0 // Если Z=0, то BRA=1, иначе BRA=0
//----------------------------------------------------------------------
0x27: if (BRA=1) // Если BRA=1 (в прошлой команде Z=0)
PC1=PC2=PC1-((IR&0x003F)*2) PLI_REQ // Изменить адрес PC1, запросить проверку запросов на прерывание
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции
else // Иначе
ACC=ACC PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x01 // Перейти на команду выборки следующей инструкции


RTI, RTT:

//================================================== ====================
//
// Команды RTI, RTT (000002, 000006)
//
//================================================== ====================

0x05: (RTT) // Для команды RTT уснанавливается флаг DC_RTT (уточнить действие)
RA=R6 IO_RD, IO_IN // Инициировать цикл чтения шины в регистр BRD
R6=R6+2
//---------------------------------------------------------------------- (обработка частично совмещена с RSEL, MFUS)
0x27: WAIT_BRD // Ожидание готовности чтения BRD
PC1=PC2=BRD GET_STATE (XQ15&XQ14&XQ13) // Если PC2&0xE000 = 0xE000, то BRA=1, иначе BRA=0
//----------------------------------------------------------------------
0x19: if (BRA=1) // Если BRA=1 (PC2>=0xE000)
RA=R6 IO_RD, IO_IN // Инициировать цикл чтения шины в регистр BRD
R6=R6+2
GOTO 0x09
else // Иначе
RA=R6 IO_RD, IO_IN // Инициировать цикл чтения шины в регистр BRD
R6=R6+2
GOTO 0x31
//---------------------------------------------------------------------- (для PC1>=0xE000)
0x09: WAIT_BRD // Ожидание готовности чтения BRD
PSW=BRD
GOTO 0x23
//---------------------------------------------------------------------- (для PC1<0xE000)
0x31: WAIT_BRD // Ожидание готовности чтения BRD
PSW.B=BRD
//---------------------------------------------------------------------- (обработка совмещена со START)
0x23: ACC=ACC // Зачем? Какие-то процессы должны завершится?
//---------------------------------------------------------------------- (завершение обработки определенной группы команд)
0x25: ACC=ACC PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции

Alex_K
24.11.2020, 21:30
По поводу RTT - если в новом PSW установлен бит T, то после исполнения RTT проверки запросов на прерывание не производится, следующая команда обязательно исполняется. Такой же эффект и при исполнении команды STEP, но там нет условия в установке бита T.

Titus
24.11.2020, 22:51
По поводу RTT - если в новом PSW установлен бит T, то после исполнения RTT проверки запросов на прерывание не производится, следующая команда обязательно исполняется. Такой же эффект и при исполнении команды STEP, но там нет условия в установке бита T.
Похоже, но пока что еще не разбирался.

Интересно, что после составления карты ПЛМ, разработчики пропустили ее через оптимизатор, который выкинул проверку всех незначащих бит, избавившись при этом от лишних транзисторов. Меньше транзисторов - меньше ток.
Однако, для анализа это более сложно, чем полное декодирование с 'невыкинутыми' битами.

Для примера, тот же RTI, RTT имеет маску в ПЛМ: ....0...0..00.10, а не 0000000000000.10
Оставлены только те биты, которые позволяют отличить RTI, RTT от других инструкций в микрокоманде 0x05.
Зато сколько лишних транзисторов освободилось)

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

Микропрограммы для START и STEP:

START:

//================================================== ====================
//
// Команда START (000010-000013)
//
//================================================== ====================

0x05: PC1=PC2=PC
//----------------------------------------------------------------------
0x27: PSW=CPSW
//---------------------------------------------------------------------- (обработка совмещена со RTI, RTT)
0x23: ACC=ACC // Зачем? Какие-то процессы должны завершится?
//---------------------------------------------------------------------- (завершение обработки определенной группы команд)
0x25: ACC=ACC PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции




STEP:

//================================================== ====================
//
// Команда STEP (000014-000017)
//
//================================================== ====================

0x05: PC1=PC2=PC
//----------------------------------------------------------------------
0x27: PSW=CPSW
//----------------------------------------------------------------------
0x35: NO ALU PI_STB RI0=1 // Управление: Сообщить последующей команде выборки инструкции, что нет запроса на прерывание
//----------------------------------------------------------------------
0x09: RA=PC1 IO_RD, IO_CMD // Инициировать цикл чтения шины в регистр BRI (инициализация кэширования инструкции)
PC1=PC2=PC1+2
GOTO 0x01 // Перейти на команду выборки следующей инструкции

Alex_K
24.11.2020, 23:02
Микропрограммы для START и STEP:
А PC1 это и есть CPC?

Titus
24.11.2020, 23:06
Немного подправил предыдущие микропрограммы.
Везде, где обновляется PC1, там же обновляется и PC2.

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


А PC1 это и есть CPC?

Наоборот. CPC - это PC. Исправил.

Alex_K
24.11.2020, 23:08
Наоборот. CPC - это PC. Исправил.
Ну а CPC обновляется на аппаратном уровне, в зависимости от состояния разрядов 7 и 8 PSW. Также обновляется и CPSW.

Titus
25.11.2020, 02:28
Ну а CPC обновляется на аппаратном уровне, в зависимости от состояния разрядов 7 и 8 PSW. Также обновляется и CPSW.
Да, все так PC и CPSW обновляются всегда, кроме случаев когда:
1. PSW[8]=1, PSW[7]=1
2. Кроме случаев работы с константой (сделано специально для удержания PC и CPSW в обработчике прерывания HALT).
3. Также есть отдельный случай влияющий на копирование PC1->PC, но я с ним пока не разбирался.

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

Продолжение банкета:

RSEL:

//================================================== ====================
//
// Команда RSEL (000020) (HALT)
//
//================================================== ====================

0x05: ACC=ACC IO_RD, IO_IN, IO_SEL // Инициировать цикл чтения безадресного регистра в регистр BRD
//---------------------------------------------------------------------- (совмещено с MFUS, и частично с RTI, RTT)
0x27: WAIT_BRD // Ожидание готовности чтения BRD
R0=BRD PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x01 // Перейти на команду выборки следующей инструкции



MFUS:

//================================================== ====================
//
// Команда MFUS (000021) (HALT)
//
//================================================== ====================

0x05: RA=R5 IO_RD, IO_IN, IO_ALT // Инициировать альтернативный цикл чтения шины в регистр BRD
// Отличие от обычного цикла в том, что вывoд SEL=~PSW[8]
R5=R5+2
//---------------------------------------------------------------------- (совмещено с RSEL, и частично с RTI, RTT)
0x27: WAIT_BRD // Ожидание готовности чтения BRD
R0=BRD PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x01 // Перейти на команду выборки следующей инструкции




MTUS:

//================================================== ====================
//
// Команда MTUS (000031) (HALT)
//
//================================================== ====================

0x05: RA=R5=R5-2 IO_WR, IO_ALT // Инициировать альтернативный цикл записи BRD на шину (SEL=~PSW[8])
//----------------------------------------------------------------------
0x27: BRD=R0 PLI_REQ // Инициилизировать BRD и продолжить цикл записи
// Запросить проверку запросов на прерывание
GOTO 0x01 // Перейти на команду выборки следующей инструкции



WCPC:

//================================================== ====================
//
// Команда WCPC (000032-000033) (HALT)
//
//================================================== ====================

0x05: PC=R0 PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x01 // Перейти на команду выборки следующей инструкции


WCPS:

//================================================== ====================
//
// Команда WCPS (000034-000037) (HALT)
//
//================================================== ====================

0x05: CPSW=R0 PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x01 // Перейти на команду выборки следующей инструкции

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

RCPC:


//================================================== ====================
//
// Команда RCPC (000022-000023) (HALT)
//
//================================================== ====================

0x05: R0=PC PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x01 // Перейти на команду выборки следующей инструкции


RCPS:

//================================================== ====================
//
// Команда RCPS (000024-000027) (HALT)
//
//================================================== ====================

0x05: R0=CPSW PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x01 // Перейти на команду выборки следующей инструкции

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

MARK:

//================================================== ====================
//
// Команда MARK (0063NN)
//
//================================================== ====================

0x05: ACC=PC1+((IR&0x003F)*2)
//----------------------------------------------------------------------
0x35: R6=ACC
//----------------------------------------------------------------------
0x09: PC1=PC2=R5
//----------------------------------------------------------------------
0x31: RA=R6 IO_RD, IO_IN // Инициировать цикл чтения шины в регистр BRD
R6=R6+2
//----------------------------------------------------------------------
0x19: WAIT_BRD // Ожидание готовности чтения BRD
R5=BRD PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции




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

CLx:

//================================================== ====================
//
// Команда CLx (000240-000257)
//
//================================================== ====================

0x05: ACC=IR&0x000F // Совмещено с SEx
//----------------------------------------------------------------------
0x27: PSW=PSW&~ACC PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x01 // Перейти на команду выборки следующей инструкции


SEx:

//================================================== ====================
//
// Команда SEx (000260-000277)
//
//================================================== ====================

0x05: ACC=IR&0x000F // Совмещено с CLx
//----------------------------------------------------------------------
0x27: PSW=PSW|ACC PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x01 // Перейти на команду выборки следующей инструкции

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

BRA, Bcc:

//================================================== ====================
//
// Команда BRA, Bcc (000400-003777)
// (100000-103777)
//
//================================================== ====================

0x04: // На входе уже проверенные условия (BRA), сделанные во время команды выборки кода инструкции (0x01)
if (BRA=1) // Если BRA=1 (условия совпали)
PC1=PC2=PC1+SIGNEXT((IR&0x00FF)<<1) PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции
else // Иначе
ACC=ACC PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x01 // Перейти на команду выборки следующей инструкции

Titus
25.11.2020, 18:24
Одно из самых таинственных действий процессора 1801ВМ2, скрытое под покровами микрокода - это выборка инструкции и обработка прерываний.


Выборка иструкции:

//================================================== ====================
//
// Пустая команда (не используется?)
//
//================================================== ====================

0x00: ACC=ACC PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x01 // Перейти на команду выборки следующей инструкции



//================================================== ====================
//
// Команда выборки некэшированной инструкции
//
// Входные данные: PC1 - указывает на адрес инструкции
//
//================================================== ====================

0x21: if (RI=001) // Если нет запроса на прерывание, то
RA=PC1 IO_RD, IO_CMD // Инициировать цикл чтения шины в регистр BRI (инициализация кэширования инструкции)
PC1=PC2=PC1+2
GOTO 0x01 // Перейти на команду выборки следующей инструкции

if (RI=000) // Если режим WAIT, то
ACC=ACC PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x01 // Перейти на команду выборки следующей инструкции

if (RI2=1) // Если есть запрос на прерывание, то
ACC=ACC IO_RD, IO_IN, IO_SEL // Инициировать цикл чтения безадресного регистра в регистр BRD
GOTO 0x11 // Перейти на команду обработки прерывания


//================================================== ====================
//
// Команда выборки кэшированной инструкции
//
// Входные данные: PC2 - указывает на адрес инструкции + 2
// PC1 - указывает на адрес инструкции
// или на адрес инструкции + 2
//
//================================================== ====================

0x01: if ((RI=001) & IX1=0) // Если нет запроса на прерывание, и BIR действительный, то
SET_CEND // Если в BIR еще нет слова текущей инструкции, то ждать готовности BIR,
// затем преддекодер декодирует инструкцию и устанавливает начальные параметры для микропрограммы
BRA_REQ // Запросить проверку условий по значениям BIR и PSW, которые могут быть
// использованы, если следующей командой будет условный переход
IO_RCD1 // Особое управление блоком таймаута
RA=PC2 IO_RCD // Инициировать цикл чтения шины в регистр BIR и BRD одновременно (кеширование следующей команды/данных)
PC1=PC2 // Фактически имитация PC1=PC+2
PC2=PC2+2
GOTO 0x00 // На самом деле переход осуществляется на первую команду новой инструкции

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

if (RI=000) // Если режим WAIT, то
ACC=ACC PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x01 // Перейти на команду выборки следующей инструкции

if (RI2=1) // Если есть запрос на прерывание, то
ACC=ACC IO_RD, IO_IN, IO_SEL // Инициировать цикл чтения безадресного регистра в регистр BRD
GOTO 0x11 // Перейти на команду обработки прерывания


Обработка прерывания:

//================================================== ====================
//
// Обработка запроса на прерывание
//
//================================================== ====================

0x11: if (RI1=0) // Если запрос на прерывание в режиме USER, то
WAIT_BRD // Ожидание готовности чтения BRD
PSW=0
GOTO 0x3E // Перейти на обработку прерывания в режиме USER
if (RI1=1) // Если запрос на прерывание в режиме HALT
WAIT_BRD // Ожидание готовности чтения BRD
PSW=0xFFEF
//----------------------------------------------------------------------
0x3C: // Обработка прерывания HALT. В регистре BRD находится считанный безадресный регистр
BRD.L=0
//----------------------------------------------------------------------
0x1D: ACC=BRD+вектор // Вектор прерывания устанавливается блоком запроса прерываний
RA=ACC IO_RD, IO_IN // Инициировать цикл чтения шины в регистр BRD
GOTO 0x20 // Перейти на продолжение обработки прерываний
//----------------------------------------------------------------------
0x3Е: // Обработка прерываний USER
RA=R6=R6-2 IO_WR, IO_CMD // Инициировать цикл записи BRD на шину
//----------------------------------------------------------------------
0x1C: BRD=CPSW // Инициилизировать BRD и продолжить цикл записи
//----------------------------------------------------------------------
0x2E: RA=R6=R6-2 IO_WR, IO_CMD // Инициировать цикл записи BRD на шину
//----------------------------------------------------------------------
0x36: BRD=PC // Инициилизировать BRD и продолжить цикл записи
//----------------------------------------------------------------------
0x34: if (RI0=0) // Если не векторное прерывание (VIRQ), то
ACC=вектор // Вектор прерывания устанавливается блоком запроса прерываний
RA=ACC IO_RD, IO_IN // Инициировать цикл чтения шины в регистр BRD
GOTO 0x20 // Перейти на продолжение обработки прерываний
else // Иначе векторное прерывание (VIRQ)
ACC=ACC IO_RD, IO_IN, IO_IAK // Инициировать цикл чтения вектора прерывания IAK в регистр BRD
//----------------------------------------------------------------------
0x2F: WAIT_BRD // Ожидание готовности чтения BRD
RA=ACC=BRD IO_RD, IO_IN // Инициировать цикл чтения шины в регистр BRD
//----------------------------------------------------------------------
0x20: // Продолжение обработки прерывания общее для всех
WAIT_BRD // Ожидание готовности чтения BRD
PC1=PC2=BRD
//----------------------------------------------------------------------
0x3D: ACC=ACC+2 // ACC - вектор прерывания + 2
RA=ACC IO_RD, IO_IN // Инициировать цикл чтения шины в регистр BRD
//----------------------------------------------------------------------
0x26: // Ожидание готовности чтения BRD
if (RI=11x) // Если прерывание в режиме HALT/начальный пуск, то
PSW=BRD
else // Иначе прерывание в режиме USER
PSW.B=BRD
//----------------------------------------------------------------------
0x39: NO ALU PI_STB CLR_WAIT RI=000 // Управление: отменить режим WAIT (влияет на режим флага Т?)
//---------------------------------------------------------------------- (Общий шаг для многих команд)
0x25: ACC=ACC PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции

Titus
26.11.2020, 01:58
Следующая часть Мерлезонского балета.

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


RTS:

//================================================== ====================
//
// Команда RTS (000200-000207)
//
//================================================== ====================

0x37: PC1=PC2=Rn
//----------------------------------------------------------------------
0x28,0x38: RA=R6 IO_RD, IO_IN // Инициировать цикл чтения шины в регистр BRD
R6=R6+2
//----------------------------------------------------------------------
0x1F: WAIT_BRD // Ожидание готовности чтения BRD
Rn=BRD PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции




FIS:

//================================================== ====================
//
// Команда FIS (075000-075037)
//
//================================================== ====================

0x05: ACC=ACC IO_RD, IO_IN, IO_SEL // Инициировать цикл чтения безадресного регистра в регистр BRD
//----------------------------------------------------------------------
0x27: WAIT_BRD // Ожидание готовности чтения BRD
ACC.B=BRD GET_STATE N=0 // Если N=0, то BRA=1, иначе BRA=0
//----------------------------------------------------------------------
0x35: if (BRA=1) // Если BRA=1 (в прошлой команде N=0)
NO ALU PI_STB VEC=0x08 RI=110 // Управление: запрос программного прерывания по вектору 0x08 в режиме HALT
GOTO 0x01 // Перейти на команду выборки следующей инструкции
else // Иначе
NO ALU PI_STB VEC=0x08 RI=100 // Управление: запрос программного прерывания по вектору 0x08 в режиме USER
GOTO 0x01 // Перейти на команду выборки следующей инструкции




WAIT:

//================================================== ====================
//
// Команда WAIT (000001)
//
//================================================== ====================

0x05: NO ALU PI_STB WAIT RI=000 // Управление: установить режим WAIT, сообщить о режиме WAIT блоку прерываний
GOTO 0x01 // Перейти на команду выборки следующей инструкции




RESET:

//================================================== ====================
//
// Команда RESET (000005)
//
//================================================== ====================

0x05: NO ALU PI_STB INIT RI=010 // Управление: инициировать INIT
//---------------------------------------------------------------------- (Общий шаг для многих команд)
0x25: ACC=ACC PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции



HALT:

//================================================== ====================
//
// Команда HALT (000000)
//
//================================================== ====================

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




Все однотипные программные прерывания:
USER: RSEL, MFUS, RCPC, RCPS, CODE030, MTUS, WCPC, WCPS, START, STEP
BPT, IOT, EMT, TRAP:

//================================================== ====================
//
// Команды
// USER: RSEL, MFUS, RCPC, RCPS, CODE030, MTUS, WCPC, WCPS, START, STEP
// TRAP10_7, TRAP10_40, TRAP10_6500, TRAP10_6600
//
//================================================== ====================


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



//================================================== ====================
//
// Команда BPT (000003)
//
//================================================== ====================

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



//================================================== ====================
//
// Команда IOT (000004)
//
//================================================== ====================

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



//================================================== ====================
//
// Команда EMT (104000-104377)
//
//================================================== ====================

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



//================================================== ====================
//
// Команда TRAP (104400-104777)
//
//================================================== ====================

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

Titus
26.11.2020, 16:42
Как ни странно, все служебные команды кончились, и начались математическо-логические.

Однооперандные с регистровой адресацией Rn:

INC(B), DEC(B), CLR(B), NEG(B), COM(B), ADC(B), SBC(B),
ASR(B), ROR(B), ASL(B), ROL(B), TST(B), SWAB, SXT, MFPS:

//================================================== ====================
//
// Математическо-логические операции с одним операндом
// и регистровой адресацией Rn
//
// INC(B), DEC(B), CLR(B), NEG(B), COM(B), ADC(B), SBC(B),
// ASR(B), ROR(B), ASL(B), ROL(B), TST(B), SWAB, SXT, MFPS
//
//================================================== ====================

0x37: if INC(B) Rn(.B)=Rn+1 VZN
if DEC(B) Rn(.B)=Rn+~1+1 VZN
if CLR(B) Rn(.B)=Rn&0 VZNC
if NEG(B) Rn(.B)=~Rn+1 VZNC
if COM(B) Rn(.B)=~Rn^0 VZNC
if ADC(B) Rn(.B)=Rn+C VZNC
if SBC(B) Rn(.B)=Rn+~C+1 VZNC
if ASR(B) Rn(.B)=(Rn^0)>>1 VZNC
if ROR(B) Rn(.B)=((Rn^0)>>1)|(C<<7) VZNC
if ASL(B) Rn(.B)=(Rn^0)<<1 VZNC
if ROL(B) Rn(.B)=((Rn^0)<<1)|C VZNC
if TST(B) ACC(.B)=Rn^0 VZNC
if SWAB Rn=SWAB(Rn^0) VZNC
if SXT if (N) Rn=0^0xFFFF VZNC
else Rn=0^0 VZN
if MFPS Rn=SIGNEXT(PSW) VZN
endif
PLI_REQ // Запросить проверку запросов на прерывание
if (Rn=R7) GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции
else GOTO 0x01 // Перейти на команду выборки следующей инструкции




MTPS Rn

//================================================== ====================
//
// Команда MTPS Rn (1064SS)
//
//================================================== ====================

0x37: PSW.B=Rn Бит T не изменяется
//----------------------------------------------------------------------
0x18,0x38: PI_STB RI=001 // Управление: нет запроса на прерывание (не имеет эффекта, т.к. следующая команда перезапишет RI)
//----------------------------------------------------------------------
0x08 ACC=ACC PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x01 // Перейти на команду выборки следующей инструкции

Непонятно и специфически устроена команда MTPS, хотя я и догадываюсь почему.
Дело в том, что модификация бита T в регистре PSW управляется отдельно, и одним из условий, позволяющем не трогать бит Т является /NA=0. Или, иными словами, чтобы адрес следующей микрокоманды был четным. Однако, если мы закончим обработку стандартно, и перейдем на адрес 0x01, то флаг T тоже изменится. Поэтому сделан обходной маневр по четным адресам, добавляющий 8(!) лишних тактов к инструкции. Вот такие вот костыли на ровном месте, казалось бы. А все из-за экономии места в PLM, и непрофильном использовании бит, относящихся к другим данным, в данном случае к адресу следующей микрокоманды.

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

Если через 100 лет вас кто-то спросит - дедушка, а почему MFPS выполняется 8 тактов, а MTPS 16? А вы и ответите - бит не хватило, пришлось ехать в Киев через Магадан.

Alex_K
26.11.2020, 20:15
Начнём:


MFUS:
0x05: RA=R5 IO_RD, IO_IN, IO_ALT
По данной команде регистр R5 должен увеличиваться на 2.


Обработка прерывания:

0x11: if (RI1=0) // Если запрос на прерывание в режиме USER, то
WAIT_BRD // Ожидание готовности чтения BRD
PSW=0
GOTO 0x3E // Перейти на обработку прерывания в режиме USER
if (RI1=1) // Если запрос на прерывание в режиме HALT
WAIT_BRD // Ожидание готовности чтения BRD
PSW=0xFFEF
Ух! Неужто для режима USER PSW становится равным нулю, а в режиме HALT 0177757? Я думал, что только очищается/ставится бит 8. И кстати регистр PSW вроде 9-разрядный.



0x3Е: // Обработка прерываний USER
RA=R6=R6-2 IO_WR, IO_CMD // Инициировать цикл записи BRD на шину
//----------------------------------------------------------------------
0x1C: BRD=CPSW // Инициилизировать BRD и продолжить цикл записи
//----------------------------------------------------------------------
0x2E: RA=R6=R6-2 IO_WR, IO_CMD // Инициировать цикл записи BRD на шину
По моим данным при сохранении в стеке, значение SP всегда уменьшается на 4, даже если при первой записи произошёл TRAP4.


FIS:
0x27: WAIT_BRD // Ожидание готовности чтения BRD
ACC=BRD GET_STATE N=0 // Если N=0, то BRA=1, иначе BRA=0
Вроде бы в качестве условия присутствия эмулятора FIS выступает сброшенное значение разряда 7 в SEL.

Titus
26.11.2020, 20:24
Ух! Неужто для режима USER PSW становится равным нулю, а в режиме HALT 0177757? Я думал, что только очищается/ставится бит 8. И кстати регистр PSW вроде 9-разрядный.
Да, 9 разрядов. Остальные незадействованы.

Чтобы очистить/поставить бит 8, нужна константа 0x0100. А ее в блоке констант нет. Гораздо проще все в 0, или все в 0xFFFF установить.

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


Вроде бы в качестве условия присутствия эмулятора FIS выступает сброшенное значение разряда 7 в SEL.
А в чем несостыковка?
Если бит 7 установлен, то то идет прерывание в режиме USER по вектору 0x08 (резервный код).
А если не установлен, то в режиме HALT по вектору SEL+0x08.

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


По моим данным при сохранении в стеке, значение SP всегда уменьшается на 4, даже если при первой записи произошёл TRAP4.
Там не может быть уменьшения на 4, т.к. все константы равны 2.
Да и запись в стек идет последовательно. Какой смысл уменьшать его на 4?

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


По данной команде регистр R5 должен увеличиваться на 2.
Да, все так. Пропустил одну строчку. Исправлю.

Спасибо за проверку)

Alex_K
26.11.2020, 20:55
Да, 9 разрядов. Остальные незадействованы.

Чтобы очистить/поставить бит 8, нужна константа 0x0100. А ее в блоке констант нет. Гораздо проще все в 0, или все в 0xFFFF установить.
Так всё таки 0xFFFF или 0xFFEF, т.е. бит T очищен или нет.

А в чем несостыковка?
Если бит 7 установлен, то то идет прерывание в режиме USER по вектору 0x08 (резервный код).
А если не установлен, то в режиме HALT по вектору SEL+0x08.
А нестыковка в том, какое сравнение делается - словное или байтовое?

Там не может быть уменьшения на 4, т.к. все константы равны 2.
Да и запись в стек идет последовательно. Какой смысл уменьшать его на 4?
По моим опытам получается, что если при первой записи в стек произойдёт TRAP4, то значение SP всегда уменьшается на 4.
Пример: поставим SP равным 0160002. Дадим команду EMT или TRAP. Текущие значения CPC и CPSW сохраняются в стеке. Сперва SP уменьшается на два и в ячейку 0160000 записывается CPSW, запись не удаётся, должен быть TRAP4. TRAP4 происходит, и значения CPC и CPSW пишутся уже в ячейки 0157772 и 0157774. Ячейка 0157776 остаётся нетронутой.

Titus
26.11.2020, 21:07
Так всё таки 0xFFFF или 0xFFEF, т.е. бит T очищен или нет.
0xFFEF. А точнее, инверсная константа 0x0010.

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


По моим опытам получается, что если при первой записи в стек произойдёт TRAP4, то значение SP всегда уменьшается на 4.
Пример: поставим SP равным 0160002. Дадим команду EMT или TRAP. Текущие значения CPC и CPSW сохраняются в стеке. Сперва SP уменьшается на два и в ячейку 0160000 записывается CPSW, запись не удаётся, должен быть TRAP4. TRAP4 происходит, и значения CPC и CPSW пишутся уже в ячейки 0157772 и 0157774. Ячейка 0157776 остаётся нетронутой.
Не могу сказать, почему это происходит, т.е. еще не изучал блок таймаута. Он навороченный.

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


А нестыковка в том, какое сравнение делается - словное или байтовое?
Да, байтовое, тоже исправлю.

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


Пример: поставим SP равным 0160002. Дадим команду EMT или TRAP. Текущие значения CPC и CPSW сохраняются в стеке. Сперва SP уменьшается на два и в ячейку 0160000 записывается CPSW, запись не удаётся, должен быть TRAP4. TRAP4 происходит, и значения CPC и CPSW пишутся уже в ячейки 0157772 и 0157774. Ячейка 0157776 остаётся нетронутой.
Если бегло поразмыслить, то скорее всего блок таймаута дает некий фиктивный RPLY, который называется TO_RPLY. Таким образом операция ввода-вывода завершается, и начинается вторая, уменьшающая SP на 2. Но дальше уже все прерывается.

Alex_K
26.11.2020, 21:15
Если бегло поразмыслить, то скорее всего блок таймаута дает некий фиктивный RPLY, который называется TO_RPLY. Таким образом операция ввода-вывода завершается, и начинается вторая, уменьшающая SP на 2. Но дальше уже все прерывается.
Либо перед следующим выводом SP уже успевает уменьшится на 2 (итого на 4), а так как предыдущий вывод закончился неуспешно, то прерывание по TRAP4.

Titus
26.11.2020, 21:18
Либо перед следующим выводом SP уже успевает уменьшится на 2 (итого на 4), а так как предыдущий вывод закончился неуспешно, то прерывание по TRAP4.
Блок таймаута всю правду расскажет)

А что там была за история со сбиванием счетчиков PC2 и PC1, когда после какой-то команды, следующие начинали извлекаться со смещением?

Alex_K
26.11.2020, 21:24
А что там была за история со сбиванием счетчиков PC2 и PC1, когда после какой-то команды, следующие начинали извлекаться со смещением?
В двухадресных командах с адресацией источника @PC (17), если ожидание RPLY превышало 4 такта. Историю можно найти в теме про тестирование, также потом Vslav разбирался с этой проблемой.

Titus
26.11.2020, 21:26
В двухадресных командах с адресацией источника @PC (17), если ожидание RPLY превышало 4 такта. Историю можно найти в теме про тестирование, также потом Vslav разбирался с этой проблемой.
Ссылки нет точной, чтобы все не перелопачивать?

Alex_K
26.11.2020, 21:29
Ссылки нет точной, чтобы все не перелопачивать?
Так и я точно не помню, тоже надо перелопачивать, пока вот листаю тему про Цифровую археологию.

Titus
26.11.2020, 21:31
Как дойдет до разбора методов адресации, может и само все всплывет. Они же тоже целиком в микрокоде запрограммированы.

Alex_K
26.11.2020, 21:37
Так и я точно не помню, тоже надо перелопачивать, пока вот листаю тему про Цифровую археологию.
Дошёл - читать отсюда (https://zx-pk.ru/threads/23978-tsifrovaya-arkheologiya-1801-i-vse-vse-vse/page149.html).

Titus
27.11.2020, 21:02
Непростые команды, использующие почти все возможные ухищирения, чтобы каждой командой сделать побольше.
Тут у нас и кэш сбрасывается, а регистр BIR (буфер для слова инструкции) используется, как данные. И прочее.
Плюс большая универсальность, т.к. одной микропрограммой обрабатывается множество вариантов адресаций и команд.


INC(B), DEC(B), CLR(B), NEG(B), COM(B), ADC(B), SBC(B),
ASR(B), ROR(B), ASL(B), ROL(B), TST(B), SWAB, SXT, MTPS, MFPS,
JMP, JSR:

//================================================== ====================
//
// Oперации с одним операндом
// расположенном в памяти
//
// INC(B), DEC(B), CLR(B), NEG(B), COM(B), ADC(B), SBC(B),
// ASR(B), ROR(B), ASL(B), ROL(B), TST(B), SWAB, SXT, MTPS, MFPS
// JMP, JSR
//
// step=1 для байтовых команд, если dd<>R6 и dd<>R7
// step=2 для всх остальных команд
//
// Циклы шины IO_X001 для:
//
// TST(B), MTPS:
// Read (IO_RD, IO_IN) - Инициировать цикл чтения шины в регистр BRD
//
// CLR, SXT:
// Write (IO_WR) - Инициировать цикл записи BRD на шину
//
// CLRB, COM(B), INC(B), DEC(B), NEG(B), ADC(B), SBC(B),
// ROR(B), ROL(B), ASR(B), ASL(B), SWAB, MFPS:
// R-M-W (IO_RD, IO_WR, IO_IN) - Инициировать цикл чтения шины в регистр BRD
// с последующим циклом записи по готовности BRD
//
// JMP, JSR:
// нет цикла шины
//
//================================================== ====================

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, и операция чтения слова (TST)
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 (JMP/JSR) // Если команда JMP/JSR
ACC=RA
ENABLE_CACHE // Разрешить кэш
GOTO 0x18
else
ALU BRD // Операции ALU из шага 0x37, в качестве операнда используется BRD
// Если используется цикл записи Write или RMW, то по записи в BRD, продолжается цикл записи
ENABLE_CACHE // Разрешить кэш
if MTPS GOTO 0x18 // Завершить команду MTPS особым способом
PLI_REQ // Запросить проверку запросов на прерывание
if X(Rn) or @X(Rn) or (Rn=R7) // Если использовали адресацию по R7, то
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции
else // Иначе
GOTO 0x01 // Перейти на команду выборки следующей инструкции


//---------------------------------------------------------------------- Обработка JMP/JSR
0x18: if (MTPS) PI_STB RI=001 // Управление: нет запроса на прерывание (не имеет эффекта, т.к. следующая команда перезапишет RI)
GOTO 0x08 // Перейти на холостую команду и выборку следующей инструкции
if (JMP) // Если JMP
PC1=PC2=RA PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции
else // Иначе JSR
RA=R6=R6-2 IO_WR, IO_CMD // Инициировать цикл записи BRD на шину

//---------------------------------------------------------------------- Обработка JSR
0x0E: BRD=Rs // Инициилизировать BRD и продолжить цикл записи
//----------------------------------------------------------------------
0x0C: Rs=PC1
//----------------------------------------------------------------------
0x09: PC1=ACC PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции

//---------------------------------------------------------------------- Завершение MTPS
0x08: ACC=ACC PLI_REQ // Запросить проверку запросов на прерывание
if X(Rn) or @X(Rn) or (Rn=R7) // Если использовали адресацию по R7, то
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции
else // Иначе
GOTO 0x01 // Перейти на команду выборки следующей инструкции

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

Просьба специалиста по PDP Alex_K проверить эти адресации.

Также исправил на предыдущей странице микрокод для однооперандных регистровых инструкций. Добавил случай, когда Rn=R7.

Alex_K
27.11.2020, 23:04
// step=1 для байтовых команд, и
// step=2 для словных команд
Для адресаций (Rn)+ и -(Rn), если используются регистры R6 и R7 (SP и PC), то step всегда должен быть равен двум, независимо от того, байтовая или словная команда.

Titus
27.11.2020, 23:12
Для адресаций (Rn)+ и -(Rn), если используются регистры R6 и R7 (SP и PC), то step всегда должен быть равен двум, независимо от того, байтовая или словная команда.
Да, у меня это в заметках помечено, просто забыл сюда написать.


Регистр Y18 равен 0x02, а не 0x01 (ALT_CNST=1), если
1. Команда словная (DC_FB=0)
2. Команда байтовая (DC_FB=1), и PL6=1, PL5=1 (регистр dd R6 или R7)

Alex_K
27.11.2020, 23:21
Может толком и не увидел, но при записи по адресу, равному текущему PC, предвыборка должна сбрасываться. Адрес проверяется полностью на все 16 разрядов. Потому существует глюк, если записывать в адрес PC+1, то предвыборка не сбрасывается и исполняется инструкция, которая была там до записи.

Titus
27.11.2020, 23:23
Может толком и не увидел, но при записи по адресу, равному текущему PC, предвыборка должна сбрасываться. Адрес проверяется полностью на все 16 разрядов. Потому существует глюк, если записывать в адрес PC+1, то предвыборка не сбрасывается и исполняется инструкция, которая была там до записи.
Да, есть схема сравнения, и она действительно сравнивает все 16 бит. Но она как бы особняком стоит, и ее потом опишу, когда руки дойдут.
Глюк классный, не знал о нем)

Alex_K
27.11.2020, 23:30
//---------------------------------------------------------------------- Обработка JMP/JSR
0x18: if (JMP) // Если JMP
PC1=PC2=RA PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции
else // Иначе JSR
RA=R6=R6-2 IO_WR, IO_CMD // Инициировать цикл записи BRD на шину

//---------------------------------------------------------------------- Обработка JSR
0x0E: BRD=Rs // Инициилизировать BRD и продолжить цикл записи
//----------------------------------------------------------------------
0x0C: Rs=PC1
//----------------------------------------------------------------------
0x09: PC1=ACC PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции
Да здесь тоже это видно. Особенность исполнения команды JSR. Из моего описания:
Алгоритм: tmp := dst; –(SP) := R; R := PC; PC := tmp
tmp := dst; –(SP) := PC; PC := tmp
Описание: Содержимое указанного регистра пересылается в стековую память и заполняется содержимым счётчика команд, который указывает на ячейку, следующую за командой JSR. Новое содержимое счётчика команд определяется адресом операнда. Так как регистр R указывает на слово, следующее за инструкцией JSR, то это даёт возможность расположить после инструкции параметры подпрограммы, которые должны быть извлечены с применением автоинкрементной или косвенно-автоинкрементной адресации через регистр R. Использование регистровой адресации вызывает прерывание программы по условию «запрещённый код» через вектор 48, так как переход на регистры невозможен. При исполнении команды сначала вычисляется адрес dst, и если при вычислении адреса происходит зависание, то исполнение команды прекращается и соответственно занос регистра в стек и присвоение ему значения счётчика команд не выполняются. Если вычисление адреса операнда завершилось успешно, а зависание произошло во время занесения в стек содержимого регистра, то не смотря на зависание, процессор копирует в регистр значение счётчика команд, а в счётчик команд адрес операнда, и только после этого прерывается по зависанию. При использовании в качестве регистра счётчика команд алгоритм исполнения инструкции состоит в занесении в стек старого значения счётчика команд, а новое значение счётчика команд равно адресу операнда.
Признаки: не изменяются.

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


Да, есть схема сравнения, и она действительно сравнивает все 16 бит. Но она как бы особняком стоит, и ее потом опишу, когда руки дойдут.
Глюк классный, не знал о нем)
Описан с программой теста - здесь (https://zx-pk.ru/threads/23978-tsifrovaya-arkheologiya-1801-i-vse-vse-vse.html?p=999094&viewfull=1#post999094).

Titus
27.11.2020, 23:36
Вообще, наличие кэша, расширенной арифметики и всего с этим связанного, усложнили процессор раза в 2. Если не в 2, то полтора точно.

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


и только после этого прерывается по зависанию.
Ну так если это прерывание, то оно и может наступить лишь после PLI_REQ.
Хотя, повторюсь, я блок таймаута еще не разбирал.

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

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

Это окончание цикла чтения автомат будет ждать. А конец цикла записи он не ждет.
Та же самая особенность, вероятно, и в обработчике прерывания, когда стек уменьшается на 4.

Alex_K
27.11.2020, 23:37
Вообще, наличие кэша, расширенной арифметики и всего с этим связанного, усложнили процессор раза в 2. Если не в 2, то полтора точно.
Скажите спасибо, что FIS сюда не впихнули. А ещё могли и пультовый отладчик впихнуть, как в оригинальных процессорах DEC.

Titus
27.11.2020, 23:38
Скажите спасибо, что FIS сюда не впихнули. А ещё могли и пультовый отладчик впихнуть, как в оригинальных процессорах DEC.
Это спасибо пусть Vslav говорит, который взялся за ВМ3, где много чего впихнули)

Alex_K
27.11.2020, 23:39
А, ну все же понятно. Цикл записи идет, а микропрограммный автомат его не ждет, идет дальше, пока не упрется в занятость блока ввода-вывода.
А так как таймаут зависания достаточно долгий, то за это время успевает выполниться вся микропрограмма до конца.

Это окончание цикла чтения автомат будет ждать. А конец цикла записи он не ждет.
Та же самая особенность, вероятно, и в обработчике прерывания, когда стек уменьшается на 4.
Вот-вот. Это то, о чём так долго говорили большевики.

Titus
27.11.2020, 23:51
Вот-вот. Это то, о чём так долго говорили большевики.
Вы навели меня на интересную мысль.
Я все думал, зачем блок таймаута так жестко себя ведет, и подает сигнал ABORT по которому микропрограммный автомат сбрасывается, чего бы он не делал.
А сейчас подумал, ведь застрять из-за таймаута можно только в четко определенных местах. Если был цикл записи, то перед следующим циклом шины. Если цикл чтения, то опять же, место ожидания конца чтения определено. А так как таймаут большой по сравнению даже с самой большой микропрограммой, то к моменту его наступления, автомат будет стоять в строго определенных позициях.

Другой вопрос с внешним сбросом. Там циклы оборвутся в самых непредсказуемых местах.

Alex_K
28.11.2020, 00:14
Вы навели меня на интересную мысль.
Я все думал, зачем блок таймаута так жестко себя ведет, и подает сигнал ABORT по которому микропрограммный автомат сбрасывается, чего бы он не делал.
А сейчас подумал, ведь застрять из-за таймаута можно только в четко определенных местах. Если был цикл записи, то перед следующим циклом шины. Если цикл чтения, то опять же, место ожидания конца чтения определено. А так как таймаут большой по сравнению даже с самой большой микропрограммой, то к моменту его наступления, автомат будет стоять в строго определенных позициях.

Другой вопрос с внешним сбросом. Там циклы оборвутся в самых непредсказуемых местах.
Вот-вот. Если это чтение с шины, то его результата надо ждать в любом случае. А если запись, то засунул в BRD что надо, дал задание и щёлкай дальше. ГЫ. В чём-то напоминает SMARTDRV.

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


Я все думал, зачем блок таймаута так жестко себя ведет, и подает сигнал ABORT по которому микропрограммный автомат сбрасывается, чего бы он не делал.
Тут есть ещё тонкость с чтением предвыборки. Например у нас в ячейке 0157776 команда BR куда-то назад. После её чтения и начала декодирования, будет читаться следующая инструкция по адресу 0160000. Но в данном случае TRAP4 не произойдёт. Т.е. при чтении предвыборки TRAP4 отложенный получается.

Titus
28.11.2020, 00:16
Т.е. при чтении предвыборки TRAP4 отложенный получается.
Это тоже надо рассмотреть отдельно.

Vslav
28.11.2020, 02:37
Я все думал, зачем блок таймаута так жестко себя ведет, и подает сигнал ABORT по которому микропрограммный автомат сбрасывается, чего бы он не делал.

Там еще интереснее. По ошибкам шины на предвыборке ABORT не генерируется, вместо этого подается фантомный REPLY. А исключение будет генерироваться только при попытке использовать результаты неудавшейся предвыборки. Например, если есть команда mov (R0)+, @#50, и слово адрес приемника находится вне памяти, то будет выполнено:
- предвыборка слова 50, с фантомным тайм-аутом
- чтение по адресу регистра R0
- инкремент регистра R0
- исключение
У меня на гитхабе специальные тесты под предвыборку понаписаны, сложная она.

Titus
28.11.2020, 03:37
Там еще интереснее. По ошибкам шины на предвыборке ABORT не генерируется, вместо этого подается фантомный REPLY.
А я-то думаю, зачем там и ABORT и TO_RPLY.
Просто пока руки не дошли до этого блока. Слишком много всего в ВМ2.

Titus
28.11.2020, 17:01
Интересная особенность у блока программного сброса по команде RESET (000005).
Таймингами генерации INIT в этом случае заведует блок таймаута. Вот такая унивесальность.
Когда активируется программный INIT, на выход процессора выдается сигнал INIT и блок таймаута начинает считать, а микропрограммный автомат приостанавлвиается.
Когда блок таймаута досчитал до 53 (сигнал TOUT), с выхода процессора снимается INIT, но микропрограмма все еще стоит на месте.
Видимо, в этом интервале внешнем устройствам дается время переинициализироваться после INIT.
Далее блок таймаута достчитывает до 512 (спад сигнала TINIT), и работа процессора продолжается.

Кстати, сигнал PLI_NRDY - это вовсе не сигнал неготовности ПЛМ прерываний, как можно подумать из названия. Он как раз и отвечает за альтернативный режим работы таймера, и приостановку микропрограммы на это время. Но переименовывать его я конечно же не стану)

Из такого алгоритма работы INIT, использующего таймер, возникает определенный вопрос. А что если при выборке команды RESET, была предвыборка следующей команды с несуществующего адреса, и начался отсчет таймаута. А тут бац, и INIT решила воспользоваться таймером. Накладочка получается)

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

Далее можно порассуждать. Вот у нас завис DIN из-за того, что шина не отвечает. При этом включился режим INIT.
Приоритет у INIT выше, поэтому событие TEVENT (таймаут шины) по достижении таймером значения 53 - не произойдет.
В общем, программный INIT отработает полностью, затем таймер таймаута пойдет считать по кругу, и уже на втором круге возьмет свое.
Таким образом, если случился таймаут по предвыборке следующей команды после RESET, то DIN зависнет на 565 тактов.
А учитывая, что внешние устройства при этом сбросятся, еще не известно, как они среагирует на этот активный DIN.

Alex_K
28.11.2020, 18:48
Далее можно порассуждать. Вот у нас завис DIN из-за того, что шина не отвечает. При этом включился режим INIT.
Приоритет у INIT выше, поэтому событие TEVENT (таймаут шины) по достижении таймером значения 53 - не произойдет.
В общем, программный INIT отработает полностью, затем таймер таймаута пойдет считать по кругу, и уже на втором круге возьмет свое.
Таким образом, если случился таймаут по предвыборке следующей команды после RESET, то DIN зависнет на 565 тактов.
А учитывая, что внешние устройства при этом сбросятся, еще не известно, как они среагирует на этот активный DIN.
На реальной УКНЦ нормально срабатывает. Занёс в 0157776 команду RESET и запустил. Был TRAP4, в стеке адрес 0160002. А что там в реальности происходит неизвестно, надо запросить моделирование.

Titus
28.11.2020, 20:51
На реальной УКНЦ нормально срабатывает. Занёс в 0157776 команду RESET и запустил. Был TRAP4, в стеке адрес 0160002. А что там в реальности происходит неизвестно, надо запросить моделирование.
Так он и должен нормально срабатывать, только все это время, пока удерживается INIT и еще после него значительное время, должен быть активным сигнал DIN.

Alex_K
28.11.2020, 21:03
Так он и должен нормально срабатывать, только все это время, пока удерживается INIT и еще после него значительное время, должен быть активным сигнал DIN.
Ну я написал, что надо запросить моделирование.

Alex_K
29.11.2020, 14:30
ВМ2: Адресации однооперадных команд

INC(B), DEC(B), CLR(B), NEG(B), COM(B), ADC(B), SBC(B),
ASR(B), ROR(B), ASL(B), ROL(B), TST(B), SWAB, SXT, MFPS,
JMP, JSR:
Как-то ту не совсем понятно с MTPS. В начальном описании её нет, но в алгоритме исполнения микрокода она упоминается.

// TST(B), MTPS:
// Read (IO_RD, IO_IN) - Инициировать цикл чтения шины в регистр BRD
Далее интереснее:

if MTPS GOTO 0x18 // Завершить команду MTPS особым способом
А по адресу 0x18 обработка JMP/JSR:

//---------------------------------------------------------------------- Обработка JMP/JSR
0x18: if (JMP) // Если JMP
PC1=PC2=RA PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции
else // Иначе JSR
RA=R6=R6-2 IO_WR, IO_CMD // Инициировать цикл записи BRD на шину
Я конечно понимаю, что здесь много общего с MTPS Rn, но на этом как-то не акцентируется внимание.

Titus
29.11.2020, 14:44
Как-то ту не совсем понятно с MTPS. В начальном описании её нет, но в алгоритме исполнения микрокода она упоминается.
Забыл в шапке ее вписать. Конечно, она есть.

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


А по адресу 0x18 обработка JMP/JSR:
Тут видится несостыковка потому что по адресу 0x18 находится И обработчик JMP/JSR, и обработчик окончания MTPS.
Попробую это обозначить специально.

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

Исправил описание, добавил MTPS.

Alex_K
29.11.2020, 14:49
Исправил описание, добавил MTPS.
Ещё бы продублировать, что там будет на GOTO 0x08.

А когда будут двухоперандные команды?

Titus
29.11.2020, 14:55
Ещё бы продублировать, что там будет на GOTO 0x08.
Можно

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


А когда будут двухоперандные команды?
Как дойду до них)
Вон, некоторые микрокод по году расшифровывают, а вы от меня хотите за месяц все сразу)

Alex_K
29.11.2020, 15:13
Как дойду до них)
Вон, некоторые микрокод по году расшифровывают, а вы от меня хотите за месяц все сразу)

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

А уж команды EIS, самое интересное. Большой интерес представляют алгоритмы знакового умножения и деления. С беззнаковыми числами проще.

Titus
29.11.2020, 15:15
А уж команды EIS, самое интересное. Большой интерес представляют алгоритмы знакового умножения и деления. С беззнаковыми числами проще.
А чего там интересного, все же и так известно.

Vslav
29.11.2020, 15:16
А уж команды EIS, самое интересное. Большой интерес представляют алгоритмы знакового умножения и деления. С беззнаковыми числами проще.
Оно не микро-кодовое, для управления блоков EIS есть отдельный счетчик циклов и на нем построен генератор состояний, микрокод очень слабо вовлечен, в отличие от микрокодовой реализации на ВМ1Г.

Alex_K
29.11.2020, 15:17
А чего там интересного, все же и так известно.
Как это реализовано на уровне микрокода.

Vslav
29.11.2020, 15:19
Вон, некоторые микрокод по году расшифровывают, а вы от меня хотите за месяц все сразу)
Ты книжку похожую на мою напиши, полную и для ВСЕХ, а не просто "личные заметки на полях", тогда про сроки поговорим. И ВМ1 матрица чуток сложнее, там декодирование команд в нее встроено, а не тупо предекодер указывает точки входа.

Titus
29.11.2020, 15:29
Ты книжку похожую на мою напиши, полную и для ВСЕХ, а не просто "личные заметки на полях", тогда про сроки поговорим. И ВМ1 матрица чуток сложнее, там декодирование команд в нее встроено, а не тупо предекодер указывает точки входа.
Книжки это не для меня)

Это, конечно, не заметки на полях. Но и этого бы я делать не стал, если бы не было заинтересованных лиц. Для себя самого мне и более беглых записей хватило бы.

Alex_K
29.11.2020, 15:32
Но и этого бы я делать не стал, если бы не было заинтересованных лиц.
Расшифруйте, пожалуйста.

Titus
29.11.2020, 15:39
Расшифруйте, пожалуйста.
Если бы я один интересовался ВМ2, и не было бы форума, то я бы ограничился более скромными заметками лично для себя.

Vslav
29.11.2020, 19:17
Ну я написал, что надо запросить моделирование.
Написал и промоделировал такой тестик:
- памяти только 16К, 37776 последний доступный адрес RAM, обращение на 40000 уже вызывает тайм-аут шины
- по адресу 37776 записал код 000005 (RESET)
- перешел на 37776
Вот тайм-аут обращения оно отрабатывало очень долго, по ходу как для окончания INIT. Ну как бы проблема несущественная, все равно RESET должен закончится до исключения, нo SYNC/DIN держаться активными все это время. И по окончанию RESET оно еще раз чтение 40000 запрашивает, потом нормальный тайм-аут, и уже потом переход по вектору 4.

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

Alex_K
29.11.2020, 19:28
Вот тайм-аут обращения оно отрабатывало очень долго, по ходу как для окончания INIT. Ну как бы проблема несущественная, все равно RESET должен закончится до исключения, нo SYNC/DIN держаться активными все это время. И по окончанию RESET оно еще раз чтение 40000 запрашивает, потом нормальный тайм-аут, и уже потом переход по вектору 4.
Согласен, проблема несущественная. Вряд ли кто так программировать будет. А повторный запрос инструкции есть, разработчики предусмотрели это. По алгоритму команды RESET, который описал Titus, потом идёт запрос некэшированной инструкции:


//================================================== ====================
//
// Команда RESET (000005)
//
//================================================== ====================

0x05: NO ALU PI_STB INIT RI=010 // Управление: инициировать INIT
//---------------------------------------------------------------------- (Общий шаг для многих команд)
0x25: ACC=ACC PLI_REQ // Запросить проверку запросов на прерывание
GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции

Vslav
29.11.2020, 19:30
А повторный запрос инструкции есть
И это вполне логично, потому что по RESET могла измениться карта памяти (кто его знает чего на плате наворотить могли) и надо бы инструкцию перечитать.

Titus
29.11.2020, 19:34
Вот тайм-аут обращения оно отрабатывало очень долго, по ходу как для окончания INIT.
Все так как я и описал. Сперва 512 тактов на RESET, и в это время держится DIN. А потом отрабатывает нормальный тайм-аут.

Hunta
29.11.2020, 20:27
И это вполне логично, потому что по RESET могла измениться карта памяти
И не только карта, но и содержимое ячейки - классический пример - всякие ПЗУ загрузки-тестирования (аха, область 165xxx и 173xxx) со страничной организацией (здравствуй, J11 и не только) и сбросом по сбросу регистра маппинга.

Titus
29.11.2020, 20:53
Продолжаем.
Пока что простые операции.

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

//================================================== ====================
//
// Операции с двумя операндами
// и регистровой адресацией Rs,Rd
//
// MOV(B), BIS(B), BIC(B), ADD, SUB, CMP(B), BIT(B), XOR
//
//================================================== ====================

0x3B: if BIC(B) Rd(.B)=Rd&~Rs VZN
if BIS(B) Rd(.B)=Rd|Rs VZN
if ADD Rd=Rd+Rs CVZN
if SUB Rd=Rd+~Rs+1 CVZN
if CMP(B) ACC(.B)=~Rd+Rs+1 CVZN
if BIT(B) ACC(.B)=Rd&Rs VZN
if XOR Rd=Rd^Rs VZN
if MOV Rd=Rs VZN
if MOVB Rd=SIGNEXT(Rs) VZN
endif
PLI_REQ // Запросить проверку запросов на прерывание
if (Rd=R7) GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции
else GOTO 0x01 // Перейти на команду выборки следующей инструкции

Alex_K
29.11.2020, 21:42
Пока что простые операции.
Сначала подумал, нифига себе двухоперандные команды простые, потом посмотрел на алгоритм, что-то уж слишком мало. А уже потом заметил, что это с двумя регистрами.

Titus
29.11.2020, 22:33
Сначала подумал, нифига себе двухоперандные команды простые
Это еще что.
Вот как работает EALU - это песня.
Фактически работает тот же микропрограммный автомат вместе с обычным АЛУ, в то время, как блок расширенного АЛУ беспощадно ими управляет, подбрасывая лишние данные, зацикливая, добавляя регистры в цепочку сдвига, организуя цикл, приостанавливая микропрограмму на время. Как дирижер вбежавший в слаженный ансамбль, и заставляющий играть его по-своему.

Alex_K
29.11.2020, 22:46
Как дирижер вбежавший в слаженный ансамбль, и заставляющий играть его по-своему.
И ведь прекрасно играет. По моим тестам каких-либо ошибок в EIS не обнаружено. Вроде всё чётко.

Titus
01.12.2020, 02:55
Вот и понят один из столпов расширенной арифметики - умножение.

Достаточно сложно было собирать его логику по всей схеме. Все очень запутано и специфично. Пришлось даже попросить уважаемого Ynicky прогнать умножение на модели, чтобы сравнить, не накосячил ли я в общих чертах.
После чего я написал на Си модель того, что описано ниже, и прогнал на всех комбинациях. Все сошлось в точности.

Интересная особенность EALU в том, что когда счетчик числа итераций CTR загружается новым значением, микропрограммный автомат останавливается, и АЛУ каждый шаг выполняет одну и ту же заданную микропрограммой математическо-логическую операцию, но на которую в широком диапазоне может влиять автомат EALU. После окончания счета, микропрограмма продолжается далее.


MUL:

//================================================== ====================
//
// Команда MUL Rs,Rd
//
//================================================== ====================
0x3B: ACC=Rs // (в данной команде поля Rs и Rd кодируются не стандартно)
//----------------------------------------------------------------------
0x18: EA1=0
//----------------------------------------------------------------------
0x27: EA2=ACC // EA2 - Rs
//----------------------------------------------------------------------
0x35: CTR=0x10 // Счетчик на 16 итераций
//----------------------------------------------------------------------
0x1A: // Этот шаг АЛУ повторяет 16 раз
if (EA2[0]=1) EA1=EA1+Rd
else EA1=EA1

ЕА1.ЕА2=EA1.EA2>>1 // Арифметический сдвиг вправо с сохранением знака
EA1[15]=EA1[15]^c15^c14 // Если при сложении был перенос из 15-го бита, или
// перенос из 14-го бита (арифметическое переполнение),
// то знак меняется на противоположный
CTR=CTR-1
if (CTR>0) GOTO 0x1A
//----------------------------------------------------------------------
0x2A: // CTR=0
if (ACC[15]=1) EA1=EA1-Rd // Если ACC<0, то коррекция результата
else EA1=EA1
CVZN // Флаги устанавливаются согласно алгоритму MUL:
// N=EA1[15]
// if (((EA1=0x0000) and (EA2[15]=0)) or
// ((EA1=0xFFFF) and (EA2[15]=1))) C=0
// else C=1
// if (EA1.EA2=0) Z=1
// V=0

//----------------------------------------------------------------------
0x0E: Rd=EA1 // Старшая часть результата
//----------------------------------------------------------------------
0x0C: Rd|1=EA2 // Младшая часть результата
// Дальнейшая проверка рудиментарная, и наследуется от других команд
if (Rs=R7) GOTO 0x21 // Перейти на команду выборки следующей некэшированной инструкции
else GOTO 0x01 // Перейти на команду выборки следующей инструкции

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

Следует обратить внимание на то, что в конце проверяется Rs=R7, и исходя из этого делается перекеширование.
Хотя в случае умножения, следует проверять Rd|1=R7, что, как видно, не делается.
А значит в этом случае имеем глюк. Хотя, в процессоре есть блок, отвечающий за запись в R7, возможно, он спасет в этом случае. Пока что с ним не разбирался.

Alex_K
01.12.2020, 18:48
//----------------------------------------------------------------------
0x0E: Rs=EA1 // Старшая часть результата
//----------------------------------------------------------------------
0x0C: Rs|1=EA2 // Младшая часть результата

Следует обратить внимание на то, что в конце проверяется Rd=R7, и исходя из этого делается перекеширование.
Хотя в случае умножения, следует проверять Rs|1=R7, что, как видно, не делается.
А значит в этом случае имеем глюк. Хотя, в процессоре есть блок, отвечающий за запись в R7, возможно, он спасет в этом случае. Пока что с ним не разбирался.
А может всё-таки записываем в Rd, а не в Rs. Ведь Rs - source, источник, а Rd - destination, приёмник. А так нужна проверка на Rd|1=R7. Надо попробовать воспроизвести глюк на реальной УКНЦ, нужно только правильные множители подобрать, в смысле значения регистров R6 и R7.

Hunta
01.12.2020, 18:57
Что то мне кажется, что проверять надо и Rd=R7 и Rd|1=R7 ибо MUL #10, SP и MUL #10, R7

Alex_K
01.12.2020, 19:08
Что то мне кажется, что проверять надо и Rd=R7 и Rd|1=R7 ибо MUL #10, SP и MUL #10, R7
Зачем такая избыточность. Достаточно проверить Rd|1=R7, ибо R6|1=R7 и R7|1=R7.

Hunta
01.12.2020, 19:25
Достаточно проверить
Согласен
Но по любому

Rd=R7
не понятно

Titus
01.12.2020, 20:00
А может всё-таки записываем в Rd, а не в Rs
Я исходил из того, что поле 00R00 - это всегда источник, а поле 000NN - это приемник, поэтому так и назвал.
Хотя, в командах расширенной арифметики получается, что наоборот.

Можно переименовать в микрокоде, если смущает.

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

Проверка 'if (Rd=R7) GOTO 0x21' на шаге 0x0C - это универсальный рудимент от других команд, использующих же этот шаг.
Для MUL он бессмысленный.

Alex_K
01.12.2020, 20:29
Я исходил из того, что поле 00R00 - это всегда источник, а поле 000NN - это приемник, поэтому так и назвал.
Хотя, в командах расширенной арифметики получается, что наоборот.
Код команды 070RSS, так что SS - это источник, а регистр R - приёмник.

Titus
01.12.2020, 20:38
Код команды 070RSS, так что SS - это источник, а регистр R - приёмник.
Это я вижу, но декодируется все универсально и одними и теми же методами. Правое поле универсализировано, как источник.
Поэтому и проверка в конце команды Rd=R7, предполагая, что Rd закодирован правым полем.

Перепишу микрокод для MUL, чтобы не путать общественность)

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

Поменял поля местами в описании

Alex_K
01.12.2020, 22:03
Поменял поля местами в описании
Так всё-таки проверяет Rs?

Titus
01.12.2020, 22:14
Так всё-таки проверяет Rs?
Он проверяет тот регистр, который закодирован правым полем.
Во всех командах там Rd, а в MUL - Rs. Поэтому проверяет он Rs, т.е. то, чего проверять не надо.

Alex_K
01.12.2020, 22:22
Он проверяет тот регистр, который закодирован правым полем.
Во всех командах там Rd, а в MUL - Rs. Поэтому проверяет он Rs, т.е. то, чего проверять не надо.
Забавный глюк должен получиться, если в качестве R будет R6 или R7. Надо попробовать на реале.

Titus
01.12.2020, 22:26
Забавный глюк должен получиться, если в качестве R будет R6 или R7. Надо попробовать на реале.
Ну, как я уже говорил выше, в процессоре есть схема, которая отслеживает запись в R7 независимо от того, чего понаписано в микрокоманде.
Я не разбирался в деталях еще, но судя по всему, она сбрасывает кеширование, так что все будет разрулено.

Alex_K
01.12.2020, 22:29
Ну, как я уже говорил выше, в процессоре есть схема, которая отслеживает запись в R7 независимо от того, чего понаписано в микрокоманде.
Я не разбирался в деталях еще, но судя по всему, она сбрасывает кеширование, так что все будет разрулено.
А зачем тогда проверка в микрокомандах идёт, и переход или на 0x01 или на 0x21?

Titus
01.12.2020, 22:35
А зачем тогда проверка в микрокомандах идёт, и переход или на 0x01 или на 0x21?
Я думаю, что это сделано для ускорения.
Если отдать все на откуп стандартной микропрограмме извлечения следующей инструкции, то будет:
0x01 - попытка выборки кэшированного слова, но его нет. Тогда перейдем на 0x21
0x21 - кэшировать слово
0x01 - попытка номер два. Бинго!
А если проверка будет в самом обработчике конкретной инструкции, то сразу пойдем на шаг 0x21, не делая лишних телодвижений через недействительный шаг 0x01.
Таким образом, проверка в конце команды ускоряет выполнение на 4 такта, в случае, если кэш недействительный из-за записи результата в R7.

Alex_K
01.12.2020, 23:35
И всё-таки глюк есть. Короткая программа:


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

При умножении происходит переход на адрес 02020, останов на 02022, но перед этим исполняется INC R0, которая читается по предвыборке.

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

Ещё интереснее, если вместо INC R0 поставить команду перехода BR, код 0410. Тогда адрес останова становится равным 02042. Во как.

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

А если поставить команду CLR PC (код 005007), то переход на адрес 0, останов на 2.

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

А если в ячейку 01010 занести код 0137 (JMP @#....), а в ячейку 02020 значение 05000, то произойдёт переход на адрес 05000.

Titus
02.12.2020, 02:04
И всё-таки глюк есть. Короткая программа:
Надо запросить у Vslav'а модель для данных случаев.

hobot
02.12.2020, 04:31
Возможно тесты Patron'а пригодятся, ПКМ ссылка в данной теме лишней не будет?
http://archive.pdp-11.org.ru/ukdwk_archive/ukncbtlwebcomplekt/TESTY_FORUM/

Hunta
02.12.2020, 08:12
На J-11 ошибки нет :)

Titus
02.12.2020, 11:41
На J-11 ошибки нет :)
Не удивительно, ведь ВМ2 не является ни чьей копией, а свой собственный)

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


И всё-таки глюк есть. Короткая программа:

Проанализируем ситуацию.
Микропрограмма выборки кэшированной инструкции (адрес 0x01) принимает решение о перекешировании, если IX1=1.
IX1=1, если совпало одно из условий:
1. Совпало условие блока условий (BRA=1). В нашем случае неактуально, т.к. проверка условий не запрашивалась.
2. Был активен RCMD_SET. Не разбирался, но это что-то из блока таймаута и блока модификации кэша, когда записали новое значение по адресу, на который указывал R7.
3. Предыдущая инструкция была двухоперандная (в битах 14,13,12 был не 000), при этом в поле приемника (биты 8,6,7) был закодирован R7. Условие двухоперандности совпадает, но вот в поле приемника у нас не R7, а R6.

Итого, условие перекеширования невыполнено. А значит используем кэш (BIR), а там у нас предыбранная команда по старому адресу.

Поэтому и получается, что первое слово выбирается по адресу следующему за MUL, а следующее по адресу перехода.
Причем, именно по адресу перехода, а не по адресу перехода + 2, как можно было бы предположить.
А все потому, что был пропущен шаг 0x21, который занимается перекешированием инструкции по адресу PC2, затем делает PC2=PC2+2.
Поэтому при отработке шага 0x01 у нас в PC2 все еще адрес перехода, а не адрес перехода+2.

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

Я думаю, что если задать регистр приемник R7, а не R6, то глюка не будет.

Vslav
02.12.2020, 12:52
Надо запросить у Vslav'а модель для данных случаев.
Вечером прогоню.

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

Я думаю, что если задать регистр приемник R7, а не R6, то глюка не будет.
Titus, а где это вы видел в моём тест использование R6? В качестве приёмника я использовал именно R7, чтобы не портить указатель стека, и чтобы использовался только один регистр, а не два.

Titus
02.12.2020, 19:34
Titus, а где это вы видел в моём тест использование R6? В качестве приёмника я использовал именно R7, чтобы не портить указатель стека, и чтобы использовался только один регистр, а не два.
Действительно)
Значит нужен тест с R6)

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

Тогда нужен тест на модели, и чтобы обязательно был видны поля NA и IX и RI.

Vslav
02.12.2020, 19:38
Все подтверждается:


148 001000 . = 1000 ;
149 001000 005000 tst0: clr R0
150 001002 012703 000002 mov #2, R3
151 001006 070703 mul R3, PC
152 001010 005200 inc R0
153
154 001012 .blkw 2000


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


Вариант с br (410)


148 001000 . = 1000 ;
149 001000 005000 tst0: clr R0
150 001002 012703 000002 mov #2, R3
151 001006 070703 mul R3, PC
152 001010 000410 .word 410
153 001012 005200 inc R0
154
155 001014 .blkw 2000


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


Вариант mul R3,SP

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

Alex_K
02.12.2020, 20:05
Все подтверждается:
Как я понимаю, пока читается ячейка с адресом 02020 (считается по предвыборке), исполняется команда из ячейки 01010, потому и BR переходит на адрес 02020+010*2.

Вариант mul R3,SP
А какое было значение SP?