English version draft

Assisted-by: Claude:claude-4.6-sonnet
This commit is contained in:
Andrei Solodovnikov
2026-04-12 13:53:25 +03:00
parent 63260f434e
commit f3fcd27387
74 changed files with 5133 additions and 5875 deletions

View File

@@ -9,40 +9,40 @@ 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 # загружаем маску в регистр маски
# Initialize register values
0: 030000b7 li x1 , 0x03000000 # save keyboard base address
4: 02000137 li x2 , 0x02000000 # save LED controller base address
8: 0e000193 li x3 , 0x000000e0 # save scan code e0
0с: 00000593 li x11, 0x00000000 # save zero
10: 02800293 la x5, trap_handler # the la pseudo-instruction loads a number similarly to li,
14: 00028293 # but in the case of la the number is the address
# of the specified location (the trap handler address);
# this pseudo-instruction will be split into two
# instructions: lui and addi
18: 30529073 csrw mtvec, x5 # set the interrupt vector
1c: 000102b7 li x5 , 0x00010000 # prepare the interrupt mask for the single
# (zeroth) input
20: 30429073 csrw mie, x5 # load the mask into the mask register
# Вызов функции main
# Call main function
main:
24: 00000063 beq x0, x0, main # бесконечный цикл, аналогичный while (1);
24: 00000063 beq x0, x0, main # infinite loop, equivalent to while (1);
# ОБРАБОТЧИК ПЕРЕХВАТА
# Без стороннего вмешательства процессор никогда не перейдет к инструкциям ниже,
# однако в случае прерывания в программный счетчик будет загружен адрес первой
# нижележащей инструкции.
# Сохраняем используемые регистры на стек
# TRAP HANDLER
# Without external intervention the processor will never reach the instructions below;
# however, upon an interrupt the program counter will be loaded with the address of
# the first instruction below.
# Save used registers to the stack
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)
# что означает возврат в бесконечный цикл
28: 0000a383 lw x7, 0(x1) # load scan code
2c: 00338663 beq x7, x3, change_mode # if scan code is e0, toggle LED mode
30: 00712023 sw x7, 0(x2) # output scan code to LEDs
34: 30200073 mret # return control to the program (pc = mepc),
# which means returning to the infinite loop
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)
# что означает возврат в бесконечный цикл
38: 00412403 lw x8, 4(x2) # read the current mode value
3c: 00144413 xori x8, x8, 1 # invert its least significant bit
40: 00812223 sw x8, 4(x2) # write the inverted mode back
44: 30200073 mret # return control to the program (pc = mepc),
# which means returning to the infinite loop