; stacks.s
%pragma once
bits 16

; __genstacks :: void -> bool
__genstacks:
    enter 0,0
    pusha

    ; dx:ax =
        palloc(1)
    jc .errphy
    ; half will go to the kernel stack, half to the device stack (ring1)
    mov bx,dx       ; bx=phy hi

    ; ax =
        valloc(bx, 0xffff, (P|Ring0|S|D|W), 0x7fff)
    jc .errvir
    mov cx,ax       ; cx=vir r0

    ; ax =
        valloc(bx, 0x7fff, (P|Ring1|S|D|W), 0x0000)
    jc .errvir2
    mov si,ax       ; si=vir r1
    
    ; dx:ax=
        palloc(1)
    jc .errphy2
    ; ring 3 will get a whole segment for stack

    ; ax =
        valloc(dx, 0xffff, (P|Ring3|S|D|W), 0x0000)
    jc .errvir3
    mov di,ax       ; di=vir r3
    
    chseg(ds,csselector)
        xor bx,bx

        ; ring 0
        mov word ds:[bx+confseg.stack0ss],cx
        mov word ds:[bx+confseg.stack0sp],0x7ffe

        ; ring 1
        mov word ds:[bx+confseg.stack1ss],si
        mov word ds:[bx+confseg.stack1sp],0x7ffe

        ; ring 3
        mov word ds:[bx+confseg.stack3ss],di
        mov word ds:[bx+confseg.stack3sp],0xfffe
    sret(ds)
    jmp .end

 .errphy2:
    ; vfree(si)
    ; vfree(cx)
    ; pfree(bx)
 .errphy:
    popa
    mov ax,0x0001
    jmp .err
 .errvir3:
    ; pfree(dx)
    ; vfree(si)
 .errvir2:
    ; vfree(cx)
 .errvir:
    ; pfree(bx)
    popa
    mov ax,0x0002
    jmp .err
 .err:
    stc
    leave
    ret

 .end:
    popa
    xor ax,ax
    clc
    leave
    ret

; __printstacks :: void - void
__printstacks:
    enter 0,0
    pusha

    xor bx,bx
    chseg(ds,csselector)
        mov word cx,ds:[bx+confseg.stack0ss]
        mov word dx,ds:[bx+confseg.stack0sp]
    sret(ds)
    pf "kernel stack = %x:",cx
    pfln "0x%x",dx

    xor bx,bx
    chseg(ds,csselector)
        mov word cx,ds:[bx+confseg.stack1ss]
        mov word dx,ds:[bx+confseg.stack1sp]
    sret(ds)
    pf "device stack = %x:",cx
    pfln "0x%x",dx

    xor bx,bx
    chseg(ds,csselector)
        mov word cx,ds:[bx+confseg.stack3ss]
        mov word dx,ds:[bx+confseg.stack3sp]
    sret(ds)
    pf "userland stack = %x:",cx
    pfln "0x%x",dx

    popa
    xor ax,ax
    clc
    leave
    ret

