delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2001/07/28/08:09:46

Message-ID: <20010728120851.75182.qmail@web8005.mail.in.yahoo.com>
Date: Sat, 28 Jul 2001 13:08:51 +0100 (BST)
From: "=?iso-8859-1?q?SHRUTHI=20M.K.?=" <shruthi_mk AT yahoo DOT co DOT in>
Subject: C program + assembly code
To: djgpp AT delorie DOT com
MIME-Version: 1.0
Reply-To: djgpp AT delorie DOT com

Hello,
I am Shruthi from R & D Dept. of IRA Pvt.Ltd.Can
anyone guide me as how to
write an assembly code in  a C program. 
This is a program to recieve data from serial
ports.The C program should have 
assembly code to write Interrupt service routine
because to use  the function
_go32_dpmi_get_protected_mode_interrupt_vector  no
'long jumps' & no
printf functions can be used. To recieve the data the
Interrupt service routine
has to be written in assembly only.The C code for this
routine is given below. 

************************************************************
************************************************************
unsigned char simple_serial_read(void)
         {

             while(!((unsigned
char)read_UART(PORT_COM1,REG_LSR)<<7)){}
             return(read_UART(PORT_COM1,REG_RHR));
         }

***********************************************************
***********************************************************
This is the C file in which  assembly code has to be
written
in place of  LINE1,LINE2,LINE3.
********************************************************
********************************************************
/* All the include files*/
#include<stdio.h>
#include<dpmi.h>
#include<io.h>
#include <unistd.h>
#include<pc.h>
#include<go32.h>
#include<stdio.h>
#include<dos.h>
#include<sys/segments.h>
#include<sys/farptr.h>
#define ON_RHRI 1
#define ON_THRI 2
#define ON_RLSI 4
#define ON_MSI  8
#define REG_RHR 0
#define REG_THR 0
#define REG_IER 1
#define REG_IIR 2
#define REG_LCR 3
#define REG_MCR 4
#define REG_LSR 5
#define REG_MSR 6
#define REG_SCRATCH 8
#define PARITY_NONE 0
#define PARITY_ODD  8
#define PARITY_EVEN 24
#define PARITY_MARK 20
#define PARITY_SPACE 28
#define PORT_COM1 0x3f8
#define PORT_COM2 0x2f8
#define PORT_COM3 0x3e8
#define PORT_COM4 0x2e8
#define BITS_5    0
#define BITS_6    1
#define BITS_7    2
#define BITS_8    3
#define DLR_ON    128
#define STOP_ONE 0
#define STOP_TWO 4

//old_ISR & new_ISR are the handlers
 _go32_dpmi_seginfo old_ISR;
  _go32_dpmi_seginfo new_ISR;

//write your ISR for processing serial events

void my_ISR(void){
 
  asm("cli;push a");
/* LINE 1
    LINE 2
    LINE 3*/
  asm("popa;sti");
                 }
void end_my_ISR(void) {}

void write_UART(int COM_port,int reg,int data)
{
     outp((COM_port+reg),data);
}
int read_UART(int COM_port,int reg)
{
        return(inp(COM_port+reg));
}

int serial_interrupt(int COM_port,unsigned char
conditions)
{
 unsigned char data;
      write_UART(COM_port,REG_MCR,0x08);
      write_UART(COM_port,REG_IER,(int)conditions);
  
//warning:You should lock any data accessed from
within
 //an interrupt handler using _go32_dpmi_lock_data();

  _go32_dpmi_lock_data(my_ISR,(unsigned
long)(end_my_ISR - my_ISR));
  
  /*The `pm_offset' and `pm_selector' fields
      of INFO must be filled in (_go32_my_cs.). */
      

 new_ISR.pm_offset=(int)my_ISR;
     
 new_ISR.pm_selector=_go32_my_cs();

      switch(COM_port)
      {
                case PORT_COM1:

  /*This function puts the selector and offset of the
specified interrupt vector into the `pm_selector' and
`pm_offset' fields of INFO.  This can be saved and
later passed to
 `_go32_dpmi_get_protected_mode_interrupt_vector' to
restore a vector.*/

_go32_dpmi_get_protected_mode_interrupt_vector(0x0b,&old_ISR);
              
 /*This function creates a small assembler function
that handles the overhead of servicing an interrupt. 
To use, put the address of your servicing function in
the `pm_offset' field of INFO and call this function. 
The `pm_field' will get replaced with the address of
the wrapper function, which you pass to both
      `_go32_dpmi_set_protected_mode_interrupt_vector'
and `_go32_dpmi_free_iret_wrapper'.*/

    _go32_dpmi_allocate_iret_wrapper(&new_ISR);
 
 /*This function sets the protected mode interrupt
vector specified to point to the given function.  The
`pm_offset' and `pm_selector' fields
of INFO must be filled in (_go32_my_cs.). */


_go32_dpmi_set_protected_mode_interrupt_vector(0x0b,&new_ISR);

         data=inportb(0x21);   //get PIC IMR

       data&=0xf7;             //zero bit 4
       outportb(0x21,data);  //write PIC IMR
        break;
     
 case PORT_COM2:
_go32_dpmi_get_protected_mode_interrupt_vector(0x0c,&old_ISR);
       _go32_dpmi_allocate_iret_wrapper(&new_ISR);
              
_go32_dpmi_set_protected_mode_interrupt_vector(0x0c,&new_ISR);

                data=inportb(0x21);    //get PIC IMR
                data&=0xef;               //zero bit 3
                outportb(0x21,data);  //write PIC IMR

                break;

      default:
                return 0;
      }                           //switch
    return 1;
}     //int serial_interrupt(int COM_port,unsigned
char conditions)

void set_irpt_conditions(int COM_port,unsigned char
conditions)
    {

        write_UART(COM_port,REG_IER,(int)conditions);

    }

int stop_serial_irpt(int COM_port)
{
    unsigned char data;
    data = read_UART(COM_port,REG_MCR);
    data&=0x08;
    write_UART(COM_port,REG_MCR,(int)data);
    
      // disable interrupts
    write_UART(COM_port,REG_IER,0x00);
    if(COM_port==PORT_COM1)
    {
     
_go32_dpmi_set_protected_mode_interrupt_vector(0x0b,&old_ISR);
/* This function frees the memory used by the wrapper
created by`_go32_dpmi_allocate_iret_wrapper'. You
should not free a wrapper that is still in use.*/

     _go32_dpmi_free_iret_wrapper(&new_ISR);
                return 1;      
//if(COM_port==PORT_COM2)
     }
     if(COM_port==PORT_COM2)
     {
               
_go32_dpmi_set_protected_mode_interrupt_vector(0x0c,&old_ISR);
                          /*   This function frees the
memory used by the wrapper created by
`_go32_dpmi_allocate_iret_wrapper'.  You should not
free a wrapper that is still in use. */
  _go32_dpmi_free_iret_wrapper(&new_ISR);
                return 1;
     }   //if(COM_port==PORT_COM2)
     return 0; //stop_serial_irpt(int COM_port)
}

main(void)
{
        clrscr();
        serial_interrupt(PORT_COM1,ON_RHRI);
        set_irpt_conditions(PORT_COM1,ON_RHRI);
        stop_serial_irpt(PORT_COM1);

}
   
   



____________________________________________________________
Do You Yahoo!?
For regular News updates go to http://in.news.yahoo.com

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019