/* -----------------------------------------------------------------------------
* Project Name   : Architectures of Processor Systems (APS) lab work
* Organization   : National Research University of Electronic Technology (MIET)
* Department     : Institute of Microdevices and Control Systems
* Author(s)      : Andrei Solodovnikov
* Email(s)       : hepoh@org.miet.ru

See https://github.com/MPSU/APS/blob/master/LICENSE file for licensing details.
* ------------------------------------------------------------------------------
*/
_start:
# Инициализируем начальные значения регистров
 0: 030000b7       li x1 , 0x03000000      # сохраняем базовый адрес клавиатуры
 4: 02000137       li x2 , 0x02000000      # сохраняем базовый адрес led-контроллера
 8: 0e000193       li x3 , 0x000000e0      # сохраняем сканкод e0
0с: 00000593       li x11, 0x00000000      # сохраняем ноль
10: 02800293       la x5, trap_handler     # псевдоинструкция la аналогично li загружает число,
14: 00028293                               # только в случае la — это число является адресом
                                           # указанного места (адреса обработчика перехвата)
                                           # данная псевдоинструкция будет разбита на две
                                           # инструкции: lui и addi
18: 30529073       csrw mtvec, x5          # устанавливаем вектор прерывания
1c: 000102b7       li x5 , 0x00010000      # подготавливаем маску прерывания единственного
                                           # (нулевого) входа
20: 30429073       csrw mie, x5            # загружаем маску в регистр маски

# Вызов функции main
main:
24: 00000063       beq x0, x0, main        # бесконечный цикл, аналогичный while (1);

# ОБРАБОТЧИК ПЕРЕХВАТА
# Без стороннего вмешательства процессор никогда не перейдет к инструкциям ниже,
# однако в случае прерывания в программный счетчик будет загружен адрес первой
# нижележащей инструкции.
# Сохраняем используемые регистры на стек
trap_handler:
28: 0000a383       lw  x7, 0(x1)           # загружаем сканкод
2c: 00338663       beq x7, x3, change_mode # если сканкод e0, переключаем режим светодиодов
30: 00712023       sw  x7, 0(x2)           # выводим сканкод на светодиоды
34: 30200073       mret                    # возвращаем управление программе (pc = mepc)
                                           # что означает возврат в бесконечный цикл

change_mode:
38: 00412403       lw   x8, 4(x2)          # считываем значение текущего режима
3c: 00144413       xori x8, x8, 1          # инвертируем его младший бит
40: 00812223       sw   x8, 4(x2)          # записываем инвертированный режим
44: 30200073       mret                    # возвращаем управление программе (pc = mepc)
                                           # что означает возврат в бесконечный цикл
