/* -----------------------------------------------------------------------------
* 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: 04000137       li x2 , 0x04000000      # сохраняем базовый адрес hex-контроллера
 8: 0e000193       li x3 , 0x000000e0      # сохраняем сканкод e0
 c: 0f000213       li x4 , 0x000000f0      # сохраняем сканкод f0
10: 00e00413       li x8 , 0x0000000e      # сохраняем значение e
14: 00f00493       li x9 , 0x0000000f      # сохраняем значение f
18: 00000593       li x11, 0x00000000      # сохраняем ноль
1c: 03400293       la x5, trap_handler     # псевдоинструкция la аналогично li загружает число,
20: 00028293                               # только в случае la — это число является адресом
                                           # указанного места (адреса обработчика перехвата)
                                           # данная псевдоинструкция будет разбита на две
                                           # инструкции: lui и addi
24: 30529073       csrw mtvec, x5          # устанавливаем вектор прерывания
28: 000102b7       li x5 , 0x00010000      # подготавливаем маску прерывания единственного
                                           # (нулевого) входа
2c: 30429073       csrw mie, x5            # загружаем маску в регистр маски

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

# ОБРАБОТЧИК ПЕРЕХВАТА
# Без стороннего вмешательства процессор никогда не перейдет к инструкциям ниже,
# однако в случае прерывания в программный счетчик будет загружен адрес первой
# нижележащей инструкции.
# Сохраняем используемые регистры на стек
trap_handler:
34: 0000a383       lw x7, 0(x1)            # загружаем сканкод
38: 04338263       beq x7, x3, print_e0    # если сканкод e0, отображаем с помощью print_e0
3c: 04438c63       beq x7, x4, print_f0    # если сканкод f0, отображаем с помощью print_f0
40: 00700333       add x6, x0, x7          # дублируем сканкод
44: 00435313       srl x6, x6, 4           # сдвигаем на 4, чтобы получить старший нибл
48: 00612223       sw  x6, 4(x2)           # записываем старший нибл в первый семисегментник
4c: 00f3f393       andi x7, x7, 0xf        # маскируем с f, чтобы получить младший нибл
50: 00712023       sw  x7,  0(x2)          # записываем младший нибл в нулевой семисегментник
54: 00b04c63       blt x0, x11, print_code # пропускаем обнуление старших хексов
58: 00012a23       sw  x0, 20(x2)
5c: 00012823       sw  x0, 16(x2)          # обнуляем 2-5 семисегментники
60: 00012623       sw  x0, 12(x2)
64: 00012423       sw  x0,  8(x2)
68: 00300513       addi x10, x0, 3

print_code:
6c: 000005b3       add x11, x0, x0         # обнуляем счетчик
70: 00356513       ori x10, x10, 3         # инициализируем маску, включающую 2 младших хекса
74: 02a12023       sw  x10, 32(x2)         # записываем маску
78: 30200073       mret                    # возвращаем управление программе (pc = mepc)
                                           # что означает возврат в бесконечный цикл
print_e0:
7c: 00812a23       sw x8, 20(x2)           # записываем e в 5ый семисегментник
80: 00012823       sw x0, 16(x2)           # записываем 0 в 4ый семисегментник
84: 03056513       ori x10, x10, 0x30      # включаем отображение 4-5 хексов в маске
88: 02a12023       sw  x10, 32(x2)         # записываем маску
8c: 00158593       addi x11, x11, 1        # инкрементируем счетчик
90: 30200073       mret

print_f0:
94: 00912623       sw x9, 12(x2)           # записываем f в 3ый семисегментник
98: 00012423       sw x0, 8(x2)            # записываем 0 в 2ый семисегментник
9c: 00c56513       ori x10, x10, 0xc       # включаем отображение 3-2 хексов в маске
a0: 02a12023       sw  x10, 32(x2)         # записываем маску
a4: 00158593       addi x11, x11, 1        # инкрементируем счетчик
a8: 30200073       mret