diff --git a/Labs/13. Peripheral units/firmware/mem_files/lab_13_ps2_led_instr.mem b/Labs/13. Peripheral units/firmware/mem_files/lab_13_ps2_led_instr.mem new file mode 100644 index 0000000..1a9fb7e --- /dev/null +++ b/Labs/13. Peripheral units/firmware/mem_files/lab_13_ps2_led_instr.mem @@ -0,0 +1,18 @@ +030000b7 +02000137 +0e000193 +00000593 +00100293 +30429073 +02800293 +00028293 +30529073 +00000063 +0000a383 +00338663 +00712023 +30200073 +00412403 +00144413 +00812023 +30200073 diff --git a/Labs/13. Peripheral units/firmware/software/ps2_led.S b/Labs/13. Peripheral units/firmware/software/ps2_led.S new file mode 100644 index 0000000..3753a95 --- /dev/null +++ b/Labs/13. Peripheral units/firmware/software/ps2_led.S @@ -0,0 +1,48 @@ +/* ----------------------------------------------------------------------------- +* 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: 00100293 li x5 , 0x00000001 # подготавливаем маску прерывания единственного + # (нулевого) входа +14: 30429073 csrw mie, x5 # загружаем маску в регистр маски +18: 02800293 la x5, trap_handler # псевдоинструкция la аналогично li загружает число, +1c: 00028293 # только в случае la — это число является адресом + # указанного места (адреса обработчика перехвата) + # данная псевдоинструкция будет разбита на две + # инструкции: lui и addi +20: 30529073 csrw mtvec, 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: 00812023 sw x8, 0(x2) # записываем инвертированный режим +44: 30200073 mret # возвращаем управление программе (pc = mepc) + # что означает возврат в бесконечный цикл