Ah found the code. Not pasting the whole thing, but here's the relevant bits of the task switching. Keep in mind this was me with a few years of programming in general under my belt so yeah, still bit of a noob.
type
task_type = record
stack: array[0..1023] of byte;
eax, ebx, ecx, edx, esi, edi, ebp, esp, eip, flags: longint;
es, ds, cs, ss, fs, gs: word;
end;
task_type_ptr = ^task_type;
procedure MTaskHandler; assembler;
asm
cli
{ save vital information }
{
eax, ebx, ecx, edx, esi, edi, ebp, esp, eip, dflags: longint;
es, ds, cs, ss, fs, gs: word;
}
db $66; mov word ptr [@@tmp], ax
db $66; mov word ptr [@@tmp+4], bx
db $66; mov word ptr [@@tmp+8], cx
db $66; mov word ptr [@@tmp+12], dx
db $66; mov word ptr [@@tmp+16], si
db $66; mov word ptr [@@tmp+20], di
{ get ip }
db $66; xor ax, ax
pop ax { pop the ip from stack }
db $66; mov word ptr [@@tmp+32], ax { ip }
{ get cs }
pop dx
{ get flags }
db $66; pushf
db $66; pop ax
pop ax
db $66; mov word ptr [@@tmp+36], ax { dflags }
{ save bp and sp after the modification }
db $66; mov word ptr [@@tmp+24], bp
db $66; mov word ptr [@@tmp+28], sp
mov word ptr [@@tmp+40], es
mov word ptr [@@tmp+42], ds
mov word ptr [@@tmp+44], dx { cs }
mov word ptr [@@tmp+46], ss
{ setup own stack }
db $66; mov word ptr [@@bp], bp
db $66; mov word ptr [@@sp], sp
mov word ptr [@@ss], ss
db $66; xor bp, bp
db $66; xor sp, sp
mov sp, offset Stack + 1022
mov bp, sp
mov ax, seg Stack
mov ss, ax
{ restore data segment }
mov ax, seg @data
mov ds, ax
{ call old interrupt }
pushf
call dword ptr Int8_Save
{ save task info }
mov dx, word ptr [@@cur_t]
mov bx, dx
shl bx, 2
les di, dword ptr Tasks[bx]
{ skip stack }
add di, 1024
{ save register info }
mov cx, 13
push ds
mov ax, cs
mov ds, ax
mov si, offset @@tmp
db $66; rep movsw
pop ds
{ get next task }
mov dx, word ptr [@@cur_t]
@@task_loop:
inc dx
and dx, 7
mov bx, dx
shl bx, 2
{ load task info pointer }
les di, dword ptr Tasks[bx]
{ if valid task, go out }
mov ax, es
cmp ax, 0
jne @@got_task
{ if looped, exit }
cmp dx, word ptr [@@cur_t]
je @@exit
jmp @@task_loop
@@got_task:
{ save new task id }
mov word ptr [@@cur_t], dx
jmp @@exit
@@exit:
{ restore information }
mov dx, es
mov si, di
{ skip stack }
add si, 1024
{ save register info }
mov cx, 13
mov ds, dx
mov ax, cs
mov es, ax
mov di, offset @@tmp
db $66; rep movsw
{ restore registers from prev. task }
db $66; mov bx, word ptr [@@tmp+4]
db $66; mov cx, word ptr [@@tmp+8]
db $66; mov dx, word ptr [@@tmp+12]
db $66; mov si, word ptr [@@tmp+16]
db $66; mov di, word ptr [@@tmp+20]
db $66; mov bp, word ptr [@@tmp+24]
db $66; mov sp, word ptr [@@tmp+28]
mov es, word ptr [@@tmp+40]
mov ds, word ptr [@@tmp+42]
mov ax, word ptr [@@tmp+46]
mov ss, ax
xor ax, ax
xor ax, ax
{ set new return address and return the proper way }
mov ax, word ptr [@@tmp+36]
push ax
mov ax, word ptr [@@tmp+44]
push ax
mov ax, word ptr [@@tmp+32]
push ax
{ restore used register }
db $66; mov ax, word ptr [@@tmp]
iret
{ temporary storage }
@@tmp:
{
eax, ebx, ecx, edx, esi, edi, ebp, esp, eip, dflags: longint;
es, ds, cs, ss, fs, gs: word;
}
dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
dw 0, 0, 0, 0, 0, 0
{ current task }
@@cur_t:
dw 0
@@bp:
dd 0
@@sp:
dd 0
@@ss:
dw 0
end;