/* ----------------------------------------------------------------------------- * 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: 050000b7 li x1, 0x05000000 # сохраняем базовый адрес uart_rx 4: 02000137 li x2, 0x02000000 # сохраняем базовый адрес светодиодов 8: 0001c1b7 li x3, 0x0001c200 # устанавливаем бодрейт 115200 c: 20018193 10: 0030a623 sw x3, 0x0c(x1) 14: 00100213 li x4, 0x00000001 # устанавливаем parity_bit 18: 0040a823 sw x4, 0x10(x1) 1c: 000011b7 li x3, 0x00000D0D # сохраняем спец-код для режима моргания 20: d0d18193 24: 00008237 li x4, 0x00000808 # сохраняем спец-код для сброса 28: f7f20213 2c: 0ff00493 li x9, 0x000000ff # сохраняем маску для обнуления старшей части 30: 00100313 li x6, 0x00000001 # сохраняем единицу 34: 00100293 li x5, 0x00000001 # подготавливаем маску прерывания единственного # (нулевого) входа 38: 30429073 csrw mie, x5 # загружаем маску в регистр маски 3c: 04c00293 la x5, trap_handler # псевдоинструкция la аналогично li загружает число, 40: 00028293 # только в случае la — это число является адресом 40: 00028293 # указанного места (адреса обработчика перехвата) # данная псевдоинструкция будет разбита на две # инструкции: lui и addi 44: 30529073 csrw mtvec, x5 # устанавливаем вектор прерывания # Вызов функции main main: 48: 00000063 beq x0, x0, main # бесконечный цикл, аналогичный while (1); # ОБРАБОТЧИК ПЕРЕХВАТА # Без стороннего вмешательства процессор никогда не перейдет к инструкциям ниже, # однако в случае прерывания в программный счетчик будет загружен адрес первой # нижележащей инструкции. # Сохраняем используемые регистры на стек trap_handler: 4c: 0000a383 lw x7, 0(x1) # загружаем значение из uart rx 50: 00947433 and x8, x8, x9 # обнуляем старые 3 байта 54: 00841413 slli x8, x8, 8 # Сдвигаем регистр x8 на 1 байт влево 58: 00746433 or x8, x8, x7 # записываем считанный из rx байт на освободившееся место 5c: 00340863 beq x8, x3, blink_mode # если пришел спец-код моргания, переходим в blink_mode 60: 00440a63 beq x8, x4, reset # если пришел спец-код сброса, переходим в reset 64: 00812023 sw x8, 0(x2) # записываем значением с переключателей в светодиоды 68: 30200073 mret # возвращаем управление программе (pc = mepc) # что означает возврат в бесконечный цикл blink_mode: 6c: 00612223 sw x6, 4(x2) # записываем 1 в led_mode 70: 30200073 mret reset: 74: 02612223 sw x6, 0x24(x2) # записываем 1 в led_reset 78: 30200073 mret