os-z80/kernel/tasking.c

75 lines
2.1 KiB
C
Raw Permalink Normal View History

2023-01-29 11:03:53 -06:00
#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();
}
}