root/syscalls.s

/* [<][>][^][v][top][bottom][index][help] */
        SLEEPINT = 2

        .include "memory.inc"
        .include "kstructs.inc"
        .include "macros.s"

        .text

        .global SysCalls

CallNo: 
        .quad   PrintString                             # PRINTSTRING
        .quad   PrintDouble                             # PRINTDOUBLE
        .quad   PrintChar                               # PRINTCHAR
        .quad   Newtask                                         # CREATETASK
        .quad   GetTicks                                        # GETTICKS
        .quad   Sleep                                           # SLEEP
        .quad   Alloc_Mem                               # ALLOCMEM
        .quad   Alloc_Message_Port      # ALLOCMSGPORT
        .quad   Send_Message                    # SENDMESSAGE
        .quad   Receive_Message                 # RECEIVEMESSAGE
        .quad   Dealloc_Mem                             # DEALLOCMEM
        .quad   Send_Receive                    # SENDRECEIVE
        .quad   Kill_Task                               # KILLTASK
        .quad NewKerneltask                     # CREATEKTASK
        .quad   Alloc_Shared_Mem                # ALLOCSHAREDMEM
        .quad   NewLPtask                               # CREATELPTASK
        .quad CommandLine                               # GETCOMMANDLINE

SysCalls:
        jmp *(CallNo - 8)(,%r9, 8)

#========================================================
# Print [EDX] as string at position row BH col BL
# Affects RAX, RBX, RDX
#========================================================
PrintString:
        mov $160, %ax
        mul %bh
        mov $0, %bh
        shl $1, %bx
        add %ax, %bx
.isItStringEnd:
        mov (%edx), %ah
        cmp $0, %ah
        je .done
        mov %ah, 0xB8000(%ebx)
        add $2, %bx
        inc %edx
        jmp .isItStringEnd
.done:  sysretq

#========================================================
# Print EDX as hex at position row BH col BL
# Affects RAX, RBX, RDX
#========================================================
PrintDouble:
        push %rcx
        mov $160, %ax
        mul %bh
        mov $0, %bh
        shl $1, %bx
        add %ax, %bx
        mov $8, %rcx
.stillCounting:
        shld $4, %edx, %eax
        shl $4, %edx
        and $0xF, %eax
        add $'0, %al
        cmp $'9, %al
        jle .under10
        add $7, %al
.under10:
        mov  %al, 0xB8000(%ebx)
        add  $2, %bx
        loop .stillCounting
        pop  %rcx
        sysretq

#========================================================
# Print character in AH at position row BH col BL
# Affects RAX, RBX
#========================================================
PrintChar:
        push %ax
        mov  $160, %ax
        mul  %bh
        mov  $0, %bh
        shl  $1, %bx
        add  %ax, %bx
        pop  %ax
        mov  %ah, 0xB8000(%ebx)
        sysretq

#=================================================================
# Create a new task from the file whose name is pointed to by RDI
# Passes environment string in RSI
# Affects RAX, RDI
#=================================================================
Newtask:
        push %rcx
        call NewTask
        int  $20
        pop %rcx
        sysretq

#=============================================================================
# Return in RAX the number of (10ms) clock ticks since the system was started
#=============================================================================
GetTicks:
        mov Ticks, %rax
        sysretq

#=====================================================
# Suspend the current task for for RDI 1ms intervals
#=====================================================
Sleep:  push %rcx
        mov currentTask, %r15
        movb $SLEEPINT, TS.waiting(%r15)
        mov %rdi, TS.timer(%r15)
        mov %r15, %rdi
        call BlockTask
        SWITCH_TASKS                   # The current task is no longer runnable
        pop %rcx
        sysretq

#==============================================================
# Allocate some memory from the heap. RDI = amount to allocate
# Returns in RAX address of allocated memory.
#==============================================================
Alloc_Mem:
        push %rcx
        mov  currentTask, %r15
        mov  TS.firstfreemem(%r15), %rsi
        call AllocMem
        pop  %rcx
        sysretq

#=================================================
# Allocate a message port. Return the port in RAX
#=================================================
Alloc_Message_Port:
        push %rcx
        call AllocMessagePort
        pop %rcx
        sysretq

#===================================
# Send a message to a message port.
# RDI = message port
# RSI = message
#===================================
Send_Message:
        push %rcx
        call SendMessage
        pop %rcx
        sysretq

#===========================================================
# Receive a message on message port RDI
# RSI = Buffer to return message to
# If there is no message on the port block and wait for one
#===========================================================
Receive_Message:
        push %rcx
        call ReceiveMessage
        pop %rcx
        sysretq

#==================================================
# Deallocate the memory at location RDI.
# This will deallocate both user and kernel memory
#==================================================
Dealloc_Mem:
        push %rcx
        call DeallocMem
        pop %rcx
        sysretq

#======================================================
# Send a message to a message port and receive a reply
# RDI = message port
# RSI = message
#======================================================
Send_Receive:
        push %rcx
        call SendReceiveMessage
        pop %rcx
        sysretq

#=========================================================
# Kill the current task, freeing all memory owned by task
# This syscall should never return
#=========================================================
Kill_Task:
        push %rcx
        call KillTask
        pop  %rcx
        sysretq

#=================================================================
# Create a new kernel task from the code pointed to by RDI
# Affects RAX, RDI
# Note - we really, really shouldn't have a system call to create
# a new kernel task! On the other hand, it calls code compiled
# into the kernel, so no real harm done.
#=================================================================
NewKerneltask:
        push %rcx
        call NewKernelTask
        int $20
        pop %rcx
        sysretq

#==============================================================
# Allocate some shared memory. RDI = amount to allocate
# Returns in RAX address of allocated memory.
#==============================================================
Alloc_Shared_Mem:
        push %rcx
        call AllocSharedMem
        pop  %rcx
        sysretq

#=================================================================
# Create the low-priority task from the code pointed to by RDI
# Affects RAX, RDI
# Note - we really, really shouldn't have a system call to create
# this task! We only want it to happen once.
#=================================================================
NewLPtask:
        push %rcx
        call NewLowPriTask
        int $20
        pop %rcx
        sysretq
        
CommandLine:
        mov  currentTask, %r15
        mov  TS.environment(%r15), %rax
        sysretq

/* [<][>][^][v][top][bottom][index][help] */