/*
    exDOS - Experimental 32 Bit protected mode scripted operating system
    (C) 2005 Jason Hunt
    
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    Contact: nulluser@gmail.com

    File: system.s

    All assembly language glue code is in here 
*/


.include "include/asm.inc"


/* Scroll the display up one line */
export vga_screen_up
        pushl   %edi
        pushl   %ecx
        pushl   %eax
        movl    $0xb8140, %esi          /* Start of line 2 */    
        movl    $0xb80A0, %edi          /* Start of line 1 */
        movl    $(23*40), %ecx          /* Number of dwords */
        rep     movsd
                                        /* setup to clear bottom line */       
        movl    $0x0720, %eax           /* edi is setup from the last sequence */
        movl    $0x28, %ecx             /* 40 double words to modify */
        rep     stosl                   /* Fill the line with words */
        popl   %eax
        popl   %ecx
        popl   %edi
        ret
/* End of _vga_screen_up */


/* Scroll the display up one line */
export vga_clear_screen
        pushl   %edi
        pushl   %ecx
        pushl   %eax
        movl    $0xb8000, %edi          /* Start of line 1 */
        movl    $0x3e8, %ecx
        movl    0x20f0, %eax
        rep     stosl                   /* Fill the line with words */
        popl   %eax
        popl   %ecx
        popl   %edi
        ret
/* End of _vga_screen_up */


/* Return the stack pointer */
export get_esp
        mov     %esp, %eax
        ret
/* End of get_esp */        
        

/* Disable interrupts */
export cli
        cli
        ret
/* End of cli */
        
        
/* Enable interrupts */
export sti
        sti
        ret
/* End of sti */
        

/* Gets a value from an IO port */
export in_byte
	movl    4(%esp), %edx       /* Get port number   */
	in      %dx, %al            /* Get value from port */
	ret
/* End of in_byte */    

    
/* Writes a byte to an IO port */
export out_byte
	movl    4(%esp), %edx       /* Get port number */
	movl    8(%esp), %eax       /* Get value */
	out     %al, %dx            /* Output the byte */
	ret
/* End of out_byte */    
     

/* Wait for keyboard input buffer empty */
export wait_in
        inb     $0x64, %al
        and     $0x02, %al
        jne      wait_in
        ret
/* End of wait_in */


/* Reboot the computer */
export reboot
        call    wait_in
        mov     $0xd1, %al
        outb    %al, $0x64
        call    wait_in

        mov     $0x00, %al
        outb    %al, $0x60
        jmp     reboot
/* End of reboot */


/* Load the interrupt descriptor table */
export load_idt
        cli
        movl    4(%esp), %esi       /* Get address */
        lidt    (%esi)              /* Load table */
        sti
        ret
/* End of load_idt */


/* Exception holder */    
export empty_exception

        iret
/* End of empty_exception */


/* Empty hardware interrupt 0x20-0x27 */
export empty_intr_0_7
        pusha
 
        movb     $0x20, %al
	out      %al, $0x20		/* Ackknowledge the interrupt */

        popa
        iret
/* End of empty_intr_0_7 */
        

/* Empty hardware interrupt 0x20-0x27 */
/* Ack different, these are chained */
export empty_intr_8_F
        pusha
        
        movb     $0xa0, %al
	out      %al, $0x20		/* Ackknowledge the interrupt */
        movb     $0x20, %al
	out      %al, $0x20		/* Ackknowledge the interrupt */

        popa

        iret
/* End of empty_intr_8_F: */


            
/*  Assembly wraper for the keyboard interrupt */
export keyboard_intr_wrap
        pusha

        ex_call    key_intr            
    
        movb    $0x20, %al
	out     %al, $0x20		/* Ackknowledge the interrupt */

        popa
        iret
/* End of keyboard_intr_wrap */



        
/* Assembly wraper for the timer interrupt */
export timer_intr_wrap
                                        /* save return frame and registers */
        pusha                           /* save registers to local stack */
        movl    _cur_process, %eax      /* get pointer to process info */
        movl    %esp, (%eax)

        ex_call timer_intr              /* Call the actuall interrupt function */

        ex_call process_update          /* reschedual */

        movb    $0x20, %al
	outb    %al, $0x20		/* Ackknowledge the interrupt */

        movl    _cur_process, %eax
        movl   (%eax), %esp

        popa

        iret           /* return using the pushed IP */
/* End of timer_intr_wrap */
                   


/*  Assembly wraper for the system call interface */
export syscall_intr_wrap
        pusha

        ex_call    kernel_syscall            

        popa
        iret
/* End of syscall_intr_wrap  */


        
/* Assembly wraper for the floppy interrupt */
export floppy_intr_wrap
        pusha
        pushf

        ex_call    floppy_intr;    
    
        movb     $0x20, %al
        out      %al, $0x20		/* Ackknowledge the interrupt */

        popf
        popa
        iret
/* End of timer_intr_wrap */
                   



