Блок таймаута всю правду расскажет)
А что там была за история со сбиванием счетчиков PC2 и PC1, когда после какой-то команды, следующие начинали извлекаться со смещением?
Вид для печати
Как дойдет до разбора методов адресации, может и само все всплывет. Они же тоже целиком в микрокоде запрограммированы.
Дошёл - читать отсюда.
Непростые команды, использующие почти все возможные ухищирения, чтобы каждой командой сделать побольше.
Тут у нас и кэш сбрасывается, а регистр 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.
Может толком и не увидел, но при записи по адресу, равному текущему PC, предвыборка должна сбрасываться. Адрес проверяется полностью на все 16 разрядов. Потому существует глюк, если записывать в адрес PC+1, то предвыборка не сбрасывается и исполняется инструкция, которая была там до записи.