75 lines
2.1 KiB
C
75 lines
2.1 KiB
C
|
#include<stdint.h>
|
||
|
#include<stdlib.h>
|
||
|
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();
|
||
|
}
|
||
|
}
|