Это понятно из описания процессора. Я имел ввиду, в каких случаях это произойдет на УКНЦ? При условии отсутствия глюков железа.
Вид для печати
Если программа обращается к несуществующей памяти. Для примера - написана программа для УКНЦ, она обращается к каналу 2. Попытались запустить ее на ДВК, там канала 2 нет, соответственно прерывание по вектору 4. Обычно это прерывание используется, чтобы узнать объем памяти (не всегда было 56К), присутствие регистров внешних устройств на магистрали.
Понятно, значит обращение, скажем к памяти по адресу 160000 в режиме USER, должно вызвать зависание. А двойное зависание как устроить на УКНЦ?
Правильно. А вот если перед этим в R6 загнать 170000, то тогда будет двойное зависание. Сперва произойдет зависание при обращении к 160000, ставится признак обработки зависания, соответственно текущие PC и SP должны положиться в стек, но при операции заноса в стек также происходит зависание. Но т.к. в данный момент происходит обработка зависания (стоит флаг), то уже произойдет двойное зависание.
Более сложный пример. SP будет нормальный, но по вектору 4 занесем 170000 (п/п обработки зависания находится в несуществующей памяти), в ячейке 6 должно быть 200 (запрет прерываний). При обращении к 160000 происходит зависание, ставится флаг обработки, сохраняются PC и SP в стеке (успешно). Из ячеек 4 и 6 читается вектор и начинает исполняться программа обработки прерывания. Т.к. еще не было успешного чтения кода команды, то флаг обработки прерывания не сброшен. Но чтение первой команды неуспешное, флаг стоит - в итоге двойное зависание.
А как зависнуть в режиме HALT, если в этом режиме все 64кб - это память?
У процессора 1801ВМ1 (если не ошибаюсь) в этом случае произойдёт циклический вход в обработчик зависания, который будет заносить PC и SP в стек до тех пор, пока указатель стека не вылезет из границ ОЗУ и только тогда произойдёт "нормальное" двойное зависание.
Допускаю, что и у 1801ВМ2 дела обстоят так же, но при тестировании этот тонкий момент не был должным образом отслежен.
Насчет 1801ВМ1 не скажу, нет его у меня. Если его и тестировать, то только на МС1201.01, на БК этот тонкий момент не проловишь. А вот у 1801ВМ2 дела обстоят именно так, все тестировалось на реальной машине, чтобы узнать когда формируется двойное зависание. В эмуляторе этот момент учтен.
Проверка простая. В ячейки 4 и 6 занести 170000 и 200 соответственно. С адреса 1000 занести команду TST @#160000 (коды 005737 и 160000). Запустить обязательно с помощью ИСП. В итоге двойное зависание, R6 равен 774 (если до этого он был 1000), R7 равен 170002.
Тогда это существенное отличие от ВМ1.
У 1801ВМ1 дела обстоят так:
Цитата:
? Patron - 14 февраля 23:51
А что насчёт поведения 1801ВМ1 при обработке прерывания зависания в USER-моде с несуществующим адресом в ячейке 04 ?
Если при этом не произойдёт переход в HALT-моду, то процессор войдёт в цикл бесконечного зависания.
? anonymous - 15 февраля 00:05
Да, пока указатель стека не затрет всю память и не перейдет через 0, после чего возникнет двойная ошибка шины с выходом в пульт, но данные в памяти ниже первоначального значения указателя стека будут утрачены.
? anonymous - 15 февраля 00:18
@4/002016 177000
000006/000000 340
@R6/000416 4
@1000/001000 5737
001002/001002 177000
001004/001004 0
@1000G
177002
@M000013
@R6/177774
@0/001004
000002/000340
000004/177000
@
Коды команды M:
х0 - переключатель пульт, инструкция HALT
х1 - ошибка передачи вектора
х2 - ошибка регенерации озу, в ДВК не реализовано
х3 - двойное зависание
х4 - ошибка микрокода процессора, в ДВК не реализовано
Думаю, проверка номера вектора не входит в логику обработки двойного зависания ни в ВМ1, ни в ВМ2.
Судя по всему, в ВМ1 двойное зависание означает просто два таймаута шины подряд, а в ВМ2 использован более продвинутый алгоритм, дополнительно учитывающий последовательные зависания при выборке команд.
А вот по всей видимости входит. Команды JMP Rx и JSR Rx также трапаются по 4-му вектору. Но алгоритм обработки на ситуацию двойного зависания другой.
Если в 4 и 6 занести 2000 и 200, в R6 - 170000. Сперва по адресу 1000 занесем команду TST @#160000. При исполнении R6 будет равен 167774. Т.е. при исполнении команды произошло зависание, произошло оно и при занесении параметров в стек. В итоге - двойное зависание. Кстати у ВМ2 указатель стека всегда уменьшается на 4. Если по адресу 1000 записать JMP R0 и исполнить, то будет двойное зависание и R6 уже будет равен 167770. Т.е. при исполнении команды произойдет прерывание по 4-му вектору, возникает зависание при заносе параметров в стек. Здесь снова прерывание по 4-му вектору, но при очередном занесении в стек - уже двойное зависание.
При этом между зависаниями было вполне успешное чтение 4-го вектора. Так что проще задействовать какой-нибудь триггер. Произошло зависание - установили. У ВМ2 прочли код команды успешно - сбросили.
Есть еще один тест - а если произошло зависание при чтении 4-го вектора? На МС1201.01 вроде можно отключать банки памяти, но если только плата запуститься с отключенным нулевым банком.
И аппаратное прерывание, и прерывание по резервному коду, и любое командное прерывание (типа EMT, IOT и т.п.) даст при плохом стеке точно такой же эффект даже на ВМ1. Чтение вектора ни на первом, ни на втором шаге процессор выполнить не успевает.
Но похоже, что действительно у ВМ2 за формирование признака двойного зависания отвечает не контроллер шины (как у ВМ1), а блок прерываний. Ведь контроллер шины не может отличить циклы DATI при чтении ячеек 04 и 06 от таких же циклов чтения при выборке команды.
Мне такой тест организовать пока не удалось. Было бы весьма интересно, если бы кто-то такое осуществил.Цитата:
Есть еще один тест - а если произошло зависание при чтении 4-го вектора? На МС1201.01 вроде можно отключать банки памяти, но если только плата запустится с отключенным нулевым банком.
Тут уж сложно сказать, кто за что отвечает. Возможно в ВМ1 при обращении к шине имеется счетчик зависаний, и если два зависания подряд - то тогда двойное зависание. В ВМ2 это не так, при хорошем стеке двойное зависание может быть и при неуспешном чтении команды.
У ВМ2 есть еще особенность - при заносе в стек PC и PS указатель стека всегда уменьшается на 4, независимо от того, удалось занести параметры в стек или нет. Делал даже опыты со сначением R6, равным 160002. Естественно в 160000 занести не удалось, прерывание по зависанию. Но после успешного прерывания по вектору 4 указатель стека был равен 157772. Т.е. данные прерванного процесса по зависанию были успешно занесены в ячейки 157772 и 157774. Ячейка 157776 оставалась нетронутой. Как с этим обстоят дела на ВМ1?
Так же, при любой причине прерывания.
Кстати, в начале теста любопытно, что при установке бита разрешения прерываний в регистре статуса любого готового устройства - прерывание происходит строго через одну команду при любом значении тактовой частоты процессора.Цитата:
Interrupts Test #1
BIS #100,@#TTPS
MOV #160004,SP
>>> Trap to 004 <<<
SP/157774
MOV #160004,SP
IOT
>>> Trap to 004 <<<
SP/157774
MOV #160004,SP
MFPT
>>> Trap to 004 <<<
SP/157774
Program completed.
Исходник теста прилагается.
Если в конфигурации тестируемого компьютера нет порта терминала или его адрес отличается от используемого в тесте - нужно:
1. Изменить в исходнике константу TTPS (при отсутствии порта терминала - на адрес регистра статуса любого устройства, в котором после включения питания устанавливается бит готовности 0200 ):
2. При отсутствии порта терминала - скорректировать подпрограмму StrOut ( вывод строки ASCIZ с адресом в R0 без использования прерываний ):Код:;
; INTT1.MAC - Interrupts Test #1
;
;===============================================
.MCall .Exit
TTKS =: 0177560
TTKB =: 0177562
TTPS =: 0177564
TTPB =: 0177566
Код:StrOut:
TstB @#TTPS ; Ждать готовности терминала.
BPl .-4.
MovB (R0)+,R1
BEq 1$
BMi 2$
MovB R1, @#TTPB ; Вывести байт.
Br StrOut
1$:
MovB #015,@#TTPB ; Вывести <CR>
TstB @#TTPS
BPl .-4.
MovB #012,@#TTPB ; Вывести <LF>
TstB @#TTPS
BPl .-4.
2$:
Return
Titus, внимательно почитайте мой пост. Там говориться о том, что второе слово не заносится. Т.е. сначала SP=160002, уменьшается на 2, заносится в стек первое слово (в 160000). Здесь происходит зависание. Несмотря на это, SP еще уменьшается на 2, и хотя в 157776 уже можно занести, но второе слово не заносится в стек.
Чтобы точно определить, заказывает ли блок прерываний второй цикл DATO ( для записи в стек содержимого PC ) сразу после неудачи записи в стек содержимого PSW или просто уменьшает SP ещё на 2 - можно осуществить следующий тест:
Если по завершении теста в ячейке 0157776 окажется записан не 0, а PC из первого прерывания - значит при входе в прерывание блок прерываний выполняет два последовательных цикла DATO без реакции на возможное зависание в первом из этих двух циклов.Код:Mov #160002,SP
CLR @#157776
MFPT
Причём, если это окажется справедливо не только для ВМ2, но и для ВМ1 - то это будет означать, что два последовательных зависания при входе в прерывание с плохим стеком не формируют признака двойного зависания ( как если бы блок прерываний не заказывал второй цикл DATO и вместо попытки записи PC в стек после неудачи записи PSW - просто уменьшал SP ещё на 2).
Т.е. в предлагаемом тесте в ячейке 0157776 так и останется ноль..
Иначе и быть не могло - ведь тогда контроллер шины ВМ1 не мог бы формировать признак двойного зависания.
Кстати, в моей модели ВМ1 релизация блока прерываний USER-моды выглядит так:
Любопытно, что у 1801ВМ1 чтение нового значения PSW из вектора прерывания происходит с копированием младшего байта и обнулением старшего, что является очевидной ошибкой.Код:try
{
SP -= 2;
word wSP = SP;
SP -= 2;
CheckAddrWrite(wSP);
WORD( wSP &(~1) ) = PSW;
CheckAddrWrite(SP);
WORD( SP &(~1) ) = PC;
}
catch(int)
{
return TrapTo_4();
}
PC = WORD( wVector );
PSW = BYTE( wVector +2 );
Из-за этого процессор 1801ВМ1 вываливается из HALT-моды каждый раз, когда срабатывает блок прерываний USER-моды. Поэтому в HALT-моде процессора 1801ВМ1 допустимы только два прерывания: HALT (после команды HALT или сигнала IRQ1) и ЗАВИСАНИЕ, тогда как и любое аппаратное прерывание, и T-Trap, и Tpap_To_010 (например, после MFPT), и Trap_To_04 (например, после JSR R0) и любое программное прерывание типа EMT, IOT и т.п. - моментально выносят ВМ1 из HALT-моды.
Ну скриншоты с УКНЦ, там ВМ2.
---------- Post added at 16:59 ---------- Previous post was at 16:40 ----------
Кстати в ВМ2 точно также. Так как процессор имеет полноценное разделение на режимы HALT и USER (в отличии от ВМ1), то каждый режим имеет свое адресное пространство. Соответственно вектора для каждого режима находятся в своем адресном пространстве. В ВМ2 также введены регистры копии счетчика команд (CPC) и состояния процессора (CPSW). Эти регистры-копии повторяют значения PC и PSW, только когда в PSW не установлены одновременно два бита - 7 (запрет прерываний) и 8 (HALT), изменяются CPC и CPSW при изменении PC и младшего байта PSW. При установке этих двух битов CPC и CPSW "замораживаются". Соответственно, если из HALT-режима возникает прерывание USER-режима, то процессор переключается в USER-режим сбросом бита 8 в PSW, т.к. этот бит находится в старшем байте, то CPSW не изменяется. Далее уже в стек ложаться CPSW и CPC (да, у ВМ2 так, в любом режиме), читается вектор USER-режима (здесь в PSW копируется только младший байт, бит 8 уже сброшен), ну и обрабатывается прерывание. Здесь есть одно но! Прерывание USER-режима должно происходить при разрешенных прерываниях (бит 7=0), иначе CPC и CPSW будут "замороженными" и возвратиться назад не удасться. Также из USER-режима возможен возврат в HALT-режим, если адрес возврата равен или больше 160000. При адресе >=160000 в PSW копируются все 9 бит, а иначе только 8, восьмой бит остается неизменным.
Когда-то я делал описание ВМ2, выложу еще раз.
Думаю, что не совсем "точно" так же..
У процессора 1801ВМ1 работа и с аппаратными, и с программными прерываниями в HALT-моде полностью исключена.
Наверное, это и не ошибка - ведь ВМ1 при переходе в HALT-моду не переключает младшие страницы памяти, из-за чего находящиеся там вектора не годятся для использования в HALT-моде.
Тогда как у ВМ2 (насколько я понимаю) - работа с аппаратными и программными прерываниями в HALT-моде вполне возможна.
Как это исключена? Неужто в HALT-режиме невозможно выполнить команду EMT?
Какое переключение? У ВМ1 независимо от режима одно адресное пространство. Действительно при переходе в HALT процессор устанавливает бит 3 в регистре 177716, но это уже особенности архитектуры компьютера.
Процессор 1801ВМ1 в HALT-режиме отрабатывает прерывание зависания не по вектору 04, а по вектору SEL1+02.
Это единственное (если не ошибаюсь) отличие поведения процессора 1801ВМ1 в HALT-режиме от поведения в USER-режиме.
Команду EMT можно выполнить в HALT-режиме, но её нельзя использовать в коде, который должен РАБОТАТЬ в HALT-режиме, поскольку запуск блока прерываний, вызванный командой EMT, немедленно переключит процессор в USER-режим.
Вот почему работа и с аппаратными, и с программными прерываниями в HALT-режиме процессора 1801ВМ1 полностью исключена.
В ВМ2 также обработка зависания зависит от того, в каком режиме находится процессор.
А вот здесь давайте внимательно рассмотрим эту ситуацию. Я опишу как все это работает на ВМ2 и задам Вам вопросы по поводу ВМ1.
Начнем. 1. Процессор работает в HALT-режиме (бит 8 PSW установлен). Разрешим прерывания сбросом бита 7 для того, чтобы изменялись CPC и CPSW. Насколько я понимаю HALT-режим у ВМ1 устанавливается установкой бита 10 в PSW, он же вроде запрещает одновременно и аппаратные прерывания. Наш процесс будет выполняться в адресах старше 160000.
2. Выполняем команду EMT. Так как у ВМ2 это прерывание USER-режима, то процессор вываливается в режим USER, сохраняет в стеке CPC и CPSW, читает в PC и PSW значение вектора 30(так как это вектор USER-режима, то в PSW записывается только младший байт) и запускает процесс на исполнение. Соответственно сохраненный в стеке CPSW содержит установленный бит 8 (режим HALT).
Вопрос:Как у ВМ1 в стеке сохраняется PSW - только младший байт или целиком весь?
3. Процесс по EMT выполнился, выходим по RTI. Так как точка возврата больше 160000, то в PSW копируются все 9 битов и мы снова в режиме HALT.
Вопрос:Как у ВМ1 по командам RTI/RTT происходит установка PSW - всего целиком или только младшего байта?
Вся соль ситуации еще состоит в том, что у ВМ2 всего один регистр R6, он общий, независимо от режима. Т.е. не так как у ВМ3. Соответственно в архитектуре должно быть предусмотрено общее пространство ОЗУ для USER/HALT или при работе в HALT не надо трогать R6. Либо если тронули, то возвратить обратно, если возможна ситуация переключения в USER.
В стеке сохраняются все биты PSW.Цитата:
Как у ВМ1 в стеке сохраняется PSW - только младший байт или целиком весь?
При установке PSW по команде RTI/RTT - старший байт PSW обнуляется, а младший копируется из стека.Цитата:
Как у ВМ1 по командам RTI/RTT происходит установка PSW - всего целиком или только младшего байта?
Добавилось четыре игры из архива Арсения, описания и картинки из игрушек тут.
Подправил в эмуляторе:
1. Теперь при отжатии клавиша дает скэн-код того алфавита, при котором была нажата. Должны прекратиться зависания клавиатуры в текстовых играх, которые активно переключают алфавит с помощью управляющих кодов РУС(14) и ЛАТ(15).
2. Реализована поддержка ловушки адреса. Вроде бы работает. Можно опробовать на диске GD.DSK, который выкладывал Vamos. Надеюсь он будет очень рад.
На диске GD.DSK стоит посмотреть две демонстрашки - очень красиво.
Грузимся с диска GD.DSK. Там есть два логических диска TST1.DSK и TST2.DSK. Автоматом при загрузке они не монтируются. Поэтому введем две команды:
MOUNT LD0 TST1
MOUNT LD1 TST2
После загрузим драйвер GD командой: SET GD ON.
Для первой демонстрашки введем:
ASS LD0 DK
RU TST1
В пакете научной графики запускаем демонстрацию командой: @DEM1
После демонстрашки выход в RT-11 команда: EXIT.
Соответственно для второй демонстрашки:
ASS LD1 DK
RU TST2
@DEM2
EXIT
Вот это прогресс!!! =) По поводу кнопок проверю прямо сейчас !!!
---------- Post added at 22:43 ---------- Previous post was at 22:34 ----------
(!!!) Нет, если в Патруле быстрого залипания я не дождался, то в "Косынке" (пасьянс)
пробел залип прямо сразу !!! Там постоянно идёт РУС\ЛАТ - видно по системной надписи !!!
В любом случае погоняю подробнее игрушки в сегодняшней сборке (там где на русский регистр идёт переключение)
и если из всех игр останется только Пасьянс - может быть дело уже в самой игре. Посмотрим.
(!!!) Хэлп! У меня диск после загрузки просто вешает эмулятор,
потом отлипает, как-будто настоящий дисковод подвисает, вот скрин
А другово образа gd.dsk у меня нет, есть только другая сборка эмулятора:confused_std:
меня на ты очень даже можно, так проще ведь? Да возможно я не дождался в патруле и сталкере (там где рус\лат) и ещё где-то было постоянно, но если повторится этот глюк я погоняю сегодня игрушки и отпишу.
Образ GD.DSK переткнул в дисковод 1 и вроде заработало. Так и должно быть? Почему в 0 дисководе не читается, или только у меня так?
(*Первая картинка когда дискета в 0 дисководе,
вторая и третья - запустился при загрузке в дисководе 1)
Красиво, да! Надо-бы видео сделать :wink: