/*
    TM8254TimerAsm.S, Copyright  (c) by Lukas Ruf, lr@lpr.ch,
    Swiss Federal Institute of Technology,
    Computer Engineering and Networks Laboratory.

    TOPSY -- A Teachable Operating System.
             Implementation of a tiny and simple
             micro kernel for teaching purposes.

    For further information, please visit http://www.tik.ee.ethz.ch/~topsy

    This software is provided under the terms of the GNU General Public Licence.

    A full copy of the GNU GPL is provided in the file COPYING found in the 
    development root of Topsy.
*/
/*
	
	File:                  $Source: /home/ruf/cvs_Topsy/cvs/Topsy/Threads/ia32/TMClockAsm.S,v $
 	Author(s):             Lukas Ruf, lr@lpr.ch
 	Affiliation:           ETH Zuerich, TIK
 	Version:               $Revision: 3014 $
 	Creation Date:         
 	Last Date of Change:   $Date: 2007-04-24 19:39:58 +0200 (Die, 24 Apr 2007) $      by: $Author: sryffel $
	
	
	$Log: TM8254TimerAsm.S,v $
	Revision 1.4  2001/02/08 08:29:48  lukas
	FRAME to ASM_PROC_FRAME renamed due to definition conflicts with ETHERNET FRAME defintion
	
	Revision 1.3  2000/11/15 10:13:34  ruf
	ia32Debug and Repository Reorganisation
	
	Revision 1.2  1999/12/13 21:48:34  ruf
	GNU General Public Licence Update
	
	Revision 1.1  1999/05/13 17:05:48  jeker
	Initial revision
	
*/
#include "asm.h"                /* Macros */

#define __SASM__
#include "TMHalAsm.h"
#undef  __SASM__


.section .sasm
.align 4,0x9090

// void _timerSet(ushort pDIVISOR);
/* void _timerSet(unsigned short pDIVISOR, 
                  unsigned char  pCtrlWord,
                  unsigned char  pTimerChannel); */
ASM_PROC_FRAME(__timerSet)
        ENTER
        pushl   %eax
        pushl   %edx
        
       /*
        * // binary, mode 2, LSB/MSB, ch 0
        * // Write Counter 0,     Write LSB+MSB,  Mode 2, Binary Coded Value
        * //      00              11              010     0 
        * // =>   = 00110100b = 0x34 
        * movl    $0x34,%eax 
        * outb    %al,$0x43 
        */
        
        movl    ARG2,%eax               /* Control Word */
        outb    %al,$TIMER_MODE         /* Write Control Port */

        jmp     _timerSetn1             /* let bus settle */
_timerSetn1:

        movl    ARG3,%edx               /* get the channel to write */

        /* send LSB */
        movl    ARG1,%eax
        outb    %al,%dx

        jmp     _timerSetn2             /* let bus settle */
_timerSetn2:

        // send MSB
        movb    %ah,%al
        outb    %al,%dx
        
        popl    %edx
        popl    %eax
        LEAVE

/* Below this point there are general support functions */      
////
// ulong _get8254V();
ASM_PROC_FRAME(__get8254V)
        ENTER
        pushl   %ebx

        xorl    %ebx,%ebx
        
        // 11100010b = 226 = 0xE2
        movl    $0xE2,%eax
        outb    %al,$0x43               // return STATE of Channel 0
        inb     $0x40,%al
        shll    $16,%eax

        movb    $0x00,%al
        outb    %al,$0x43               // return DIVISOR in locked LATCH
        inb     $0x40,%al               // get LSB
        movb    %al,%bl
        inb     $0x40,%al               // get MSB
        movb    %al,%ah
        movb    %bl,%al
        
        popl    %ebx
        LEAVE



