Различия между версиями 6 и 7
Версия 6 от 2019-05-26 12:37:45
Размер: 7504
Редактор: FrBrGeorge
Комментарий:
Версия 7 от 2019-05-26 12:43:58
Размер: 7501
Редактор: FrBrGeorge
Комментарий:
Удаления помечены так. Добавления помечены так.
Строка 33: Строка 33:
Пример проигрыша (в качестве сообщения используется тот же индикатор, но это не обязательно):
 [[https://vk.com/video57713803_456239024]] // {[[attachment:out0.ogv]]
Пример выигрыша:
 [[https://vk.com/video577
13803_456239023]] // [[attachment:out1.ogv]]
 * [[https://vk.com/video57713803_456239024|Пример проигрыша]] (в качестве сообщения используется тот же индикатор, но это не обязательно, [[attachment:out0.ogv]] )
 * [[https://vk.com/video57713803_456239023|Пример выигрыша]] ([[attachment:out1.ogv]])

Практический экзамен

Для сдачи экзамена необходимо решить все домашние задания

  • Скачать, установить и запустить программу на Python3 (в некоторых дистрибутивах понадобится дополнительно установить модуль tkinter)

    • $ wget --content-disposition "http://uneex.ru/LecturesCMC/ArchitectureAssembler2019?action=AttachFile&do=get&target=grzad-0.0.1-py3-none-any.whl"
      $ pip3 install --user grzad-0.0.1-py3-none-any.whl
      $ python3 -m grzad

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

  • Следовать указаниям программы-генератора задач
    • Это задача на рисование в MARS Bitmap Display
    • Не забыть включить в код решения (в качестве комментария) номер задания, иначе проверка может оказаться недействительной

    • Критерий качества: картинки MARS и задачки-генератора должны быть очень похожи ;)

Offline-вариант

  • Решить предыдущее задание (самостоятельно)
  • Решить задание Разряди бобму! (самостоятельно):

Разряди бобму! (исследовательская задача)

Оказывается, Digital Lab Sim умеет тоже работать по прерываниям, причём даже лучше. чем консоль.

Во-первых, если в регистр 0xffff0012 записать 0x80 (7-й бит) вместо бита строки, включится прерывание активации клавиши ( 11, т. е. 11-й бит 13-го регистра управляющего сопросессора Cause, 0x800). При этом для сканирования строк потом всё равно надо записывать туда 1,2,4 или 8 (точнее, 0x81, 0x82, 0x84 или 0x8, чтобы не запретить прерывание), но в этой задаче это не понадобится. Таким образом, активацию клавиши можно отловить обработчиком прерываний (в котором проверить, что 11-бит cause действительно 1).

Во-вторых, что ещё интереснее, если в регистр 0xffff0013 записать не 0 (например, 1), Digital Lab через каждые 30 выполненных Mars-ом инструкций будет генерировать прерывание № 10 (10-й бит регистра Cause, 0x400).

Таким образом можно:

  • организовать какое-нибудь периодическое действие, например, смену значений в цифровом индикаторе каждые 3000 инструкций
  • организовать асинхронную обработку нажатия на клавишу (всё равно какую)

Итак, задание. Написать программу, которая запускает обратный отчёт от 9 до 0 примерно посекундно и изображает соответствующие цифры на индикаторе (см. решение задачи «Осваиваем Digital Lab»). Если пользователь успел нажать клавишу, ему выводится одно сообщение (например. красивое окошко "Win!" с помощью syscall 55), а если не успел — другое (например, "Boom!"), после чего программа завершается.

Подсказка 1: не забывайте нажимать Reset перед каждым запуском, а не то возможны артефакты.

Подсказка 2: Оба прерывания могут произойти одновременно, тогда в регистре Cause окажутся оба бита (0xc00 с возможными другими).

Как я решал эту задачу

  • (необязательно) Вычислил примерное количество инструкций в секунду. Для этого
    • запомнил с помощью sycall 30 текущее время в милисекундах (достаточно $a0)
    • обнулил ($gp)
    • разрешил прерывание по счётчику, уменьшающее ($gp) на 1 (так будет надо в дальнейшем)
    • в цикле проверял, пока текущее время не превысит запомненное на 1000 (что примерно соответствует 1 секунде)
    • в ($gp) при этом оказалось отрицательное число обработанных прерываний, домножил его на -1, получил примерное количество прерываний счётчика в секунду, запомнил, домножил на 10 секунд, записал в ($gp)

  • Обнулил 4($gp) — флаг срабатывания прерывания от кнопки, и разрешил прерывания от кнопки
  • Запустил цикл, в котором:
    • Если произошло прерывание от кнопки (ненулевой значение 4($gp)), показал пользователю "Win" и вышел
    • Если в ($gp) лежит уже не положительное число (прерывание по счётчику, которое уменьшает на ! ($gp), никто не отменял ☺), показал пользователю "Boom" и вышел
    • Поделил ($gp) на количество прерываний в секунду, получил номер цифры
    • Если номер цифры не совпадает с предыдущим, взял новую цифру из массива (который я скопировал из «Осваиваем Digital Lab»), записал её в индикатор
  • Обработчик прерываний
    • проверяет бит 0x400 в Cause, и если да, уменьшает ($gp) на единицу
    • проверяет бит 0x800 в Cause, и если да, записывает в 4($gp) какой-нибудь не 0 (например, этот самый 0x800)

Вообще-то всё

LecturesCMC/ArchitectureAssembler2019/Exam (последним исправлял пользователь FrBrGeorge 2019-05-26 12:43:58)