Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; ***********************************************************
- ; ** NyaOS Sample **
- ; ***********************************************************
- ; http://teplofizik.diary.ru/p179560849.htm
- AREA |.text|, CODE, READONLY
- EXPORT nyaos_Stub
- EXPORT nyaos_Start
- EXPORT SysTick_Handler
- IMPORT ProcessTable
- IMPORT ContextTable
- IMPORT CurrentProcess
- IMPORT ProcessMaxCount
- IMPORT Started
- GET system.inc
- CONTEXT_SIZE EQU (9 * 4)
- PROCESS_SIZE EQU (4 * 4)
- ; Диспетчер
- ; Переключение задач
- SysTick_Handler PROC
- ; Запомним код выхода в обычный режим
- MOV R12, LR
- MOV32 R0, Started
- LDR R1, [R0]
- ; Если не начинали...
- CMP R1, #0
- BEQ _sysh_start
- ; Загрузим адрес таблицы контекстов
- MOV32 R0, ContextTable
- ; Загрузим номер текущего процесса (по таблице)
- MOV32 R1, CurrentProcess
- LDR R1, [R1] ; Прочитаем номер процесса
- MOV R3, R1 ; Запомним номер
- ; Выберем нужную запись
- MOV R2, #CONTEXT_SIZE
- MUL R1, R1, R2
- ADD R1, R1, R0
- ; Сохраним состояние старших регистров
- STR SP, [R1, #0x00]
- STR R4, [R1, #0x04]
- STR R5, [R1, #0x08]
- STR R6, [R1, #0x0C]
- STR R7, [R1, #0x10]
- STR R8, [R1, #0x14]
- STR R9, [R1, #0x18]
- STR R10, [R1, #0x1C]
- STR R11, [R1, #0x20]
- B _sysh_loadptable
- _sysh_start
- ; Начали...
- MOV R1, #1
- STR R1, [R0]
- ; Текущий Process: 0
- MOV R3, #0
- _sysh_loadptable
- ; Запомним номер процесса
- MOV R0, R3
- ; Загрузим таблицу процессов
- MOV32 R2, ProcessTable
- ; И размер одной записи...
- MOV R5, #PROCESS_SIZE
- ; Загрузим ограничение на количество
- MOV32 R4, ProcessMaxCount
- LDR R4, [R4]
- ; Ищем свободный PID
- _sysh_next
- ADD R0, #1
- ; Проверим на границу диапазона
- CMP R0, R4
- ; Загрузим 1, если вылезли (0 для Idle)
- IT EQ
- MOVEQ R0, #1
- ; Сравним с номером, с которого начинали
- CMP R0, R3
- ; Если он - загрузим процесс Idle (0).
- ITT EQ
- MOVEQ R0, #0
- BEQ _sysh_found
- ; Нет, не он. Проверим PID
- ; Считаем смещение до элемента
- MOV R6, R0
- MUL R6, R6, R5
- ADD R6, R2
- ; Грузим PID
- LDR R6, [R6, #0]
- ; Если ноль, ищем дальше.
- CMP R6, #0
- BEQ _sysh_next
- _sysh_found ; Процесс выбран
- ; Сохраним номер выбранного процесса
- MOV32 R1, CurrentProcess
- STR R0, [R1]
- ; Выбираем контекст
- MOV32 R1, ContextTable
- MOV R2, #CONTEXT_SIZE
- MUL R2, R0, R2
- ADD R1, R2
- ; Загружаем регистры и указатель стека
- LDR SP, [R1, #0x00]
- LDR R4, [R1, #0x04]
- LDR R5, [R1, #0x08]
- LDR R6, [R1, #0x0C]
- LDR R7, [R1, #0x10]
- LDR R8, [R1, #0x14]
- LDR R9, [R1, #0x18]
- LDR R10, [R1, #0x1C]
- LDR R11, [R1, #0x20]
- ; Выход из прерывания уже по новому PC
- BX R12
- ENDP
- ; Заглушка на всякий случай, если вдруг какому-либо процессу захочется выйти с помощью записи LR в PC.
- ; В дальнейшем может быть добавлен код для каноничного завершения такого процесса с ошибкой.
- ; Аргументы: нет
- ; Результаты: нет
- nyaos_Stub PROC
- B .
- ENDP
- ; Запуск ОС
- ; Аргументы: нет
- ; Результаты: нет
- nyaos_Start PROC
- ; Диспетчер ещё не работал
- MOV32 R1, Started
- MOV R0, #0
- STR R0, [R1]
- ; Разрешить прерывания от таймера
- MOV R0, #1
- BL SysTickInterruptEnable
- ; По прерыванию выполнение перейдёт к процессу
- __mainloop
- ; На очередной круг
- B __mainloop
- ENDP
- END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement