#include #include typedef int uint24_t; typedef struct Process { uint16_t stack_pointer; uint24_t stack_pointer_frame; struct Process* next_process; struct Process* prev_process; uint16_t pid; uint24_t page_mappings[16]; } Process; static Process* ready_to_run_head = NULL; static Process* ready_to_run_tail = NULL; static Process* current_process = NULL; static uint16_t next_pid = 0; Process processes[4]; extern uint24_t get_free_frame(); extern void switch_to_process_asm(); extern Process* switch_to_process_asm_arg; void new_process(uint24_t* page_mappings, uint16_t entry_point) { uint16_t pid = next_pid; next_pid++; processes[pid].pid = pid; processes[pid].stack_pointer_frame = get_free_frame(); set_frame(0xE, processes[pid].stack_pointer_frame); processes[pid].stack_pointer = 0xFFEA; *((uint16_t*)(0xEFFE)) = entry_point; for (int i = 0; i<16; i++) { processes[pid].page_mappings[i] = page_mappings[i]; } processes[pid].next_process = NULL; processes[pid].prev_process = NULL; if (ready_to_run_head) { ready_to_run_head->prev_process = &processes[pid]; processes[pid].next_process = ready_to_run_head; ready_to_run_head = &processes[pid]; } else if (current_process) { ready_to_run_head = &processes[pid]; ready_to_run_tail = &processes[pid]; } else { current_process = &processes[pid]; } } void yield() { if (ready_to_run_head) { Process* process = ready_to_run_head; ready_to_run_head = ready_to_run_head->next_process; if (ready_to_run_head==NULL) { ready_to_run_head = current_process; ready_to_run_tail = current_process; } else { ready_to_run_head->prev_process = current_process; current_process->next_process = ready_to_run_head; ready_to_run_head = current_process; } process->prev_process=NULL; process->next_process=NULL; for (int i=0; i<16; i++) { current_process->page_mappings[i] = get_frame(i); } for (int i=0; i<16; i++) { set_frame(i, process->page_mappings[i]); } switch_to_process_asm_arg = process; switch_to_process_asm(); } }