From: Leif Newsgroups: comp.os.msdos.djgpp Subject: Re: Serial ISRs Date: Thu, 17 Sep 1998 15:19:39 -0700 Organization: NorthWest Nexus Inc. Lines: 413 Message-ID: <36018AFB.3FC8@hotmail.com> References: <35F52BDC DOT A7402210 AT res DOT raytheon DOT com> NNTP-Posting-Host: blv-pm105-ip19.halcyon.com Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------62E86F2B32FE" To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk This is a multi-part message in MIME format. --------------62E86F2B32FE Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Heres my modem Include File I made. > I can't seem to get a buzz from my ports. Does anyone have some sample > code for doing this sort of thing so that I can stop chasing my tail? > I'm using a pentium under DOS (yeah, yeah, I know) with plenty of memory There might be a couple bugs in it still. U might need to change the ISR a little. When I was writing it however, it took me forever to figure out why it wasnt responding.. I dont know if its related to yer problem but... My problem was I had to set -OUT2 high in order to send the interupts to the PIC. Also make sure U got the IMR set up appropriately and mask the PIC correctly. Well either way. All U have to do is include this file and call InitModem() InitModem(ComPortNumber,IRQNumber,BAUDRATE,DataFormat); my modem is on Com3 Irq9 and is 56K so I do InitModem(3,9,56000,D_8 | P_None | S_1); At end of program do UnInitModem(3); 3 because its com3 In yer loop to find out if U got some data check if Modem[3].RCVHead == Modem[3].RCVTail if they dont equal each other then U got some data. To get the next char do: BYTE=Modem[3].Modem[Modem[3].RCVTail++]; if(Modem[3].RCVTail>=Circular) Modem[3].RCVTail=0; If U having problems with my include ask me at LeifDude AT Hotmail DOT com --------------62E86F2B32FE Content-Type: text/plain; charset=us-ascii; name="mymodem.h" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="mymodem.h" #include #include #include #include #define Circular 32768 #define BYTE unsigned char //------Register BaseAddress Offsets------ #define R_IORegister 0 #define R_Divisor 0 #define R_IntEnable 1 #define R_IntID 2 #define R_FifoControl 2 #define R_LineControl 3 #define R_ModemControl 4 #define R_LineStatus 5 #define R_ModemStatus 6 #define R_Scratch 7 //------Parity------ #define P_None 0 #define P_Odd 8 #define P_Even 24 #define P_Mark 40 #define P_Space 56 //------StopBits------ #define S_1 0 #define S_2 4 //------DataBits------ #define D_5 0 #define D_6 3 #define D_7 2 #define D_8 3 BYTE InitModem(BYTE ComPort,BYTE IRQ,unsigned long BaudRate,BYTE DataFlags); void UnInitModem(int ComPort); void InitUART(int LineNum); void UnInitUART(int LineNum); void ModemIntOn(int LineNum); void ModemIntOff(int LineNum); void ModemHandler2(void); void ModemHandler3(void); void SendChar(int LineNum,BYTE Char); void SendString(int ComPort,BYTE *Buff,unsigned int Length); BYTE GrabChar(int ComPort); BYTE GrabString(int ComPort); BYTE PicIRQOn[16] = {254,253,251,247,239,223,191,127, 254,253,251,247,239,223,191,127}; BYTE PicIRQOff[16] = {1,2,4,8,16,32,64,128, 1,2,4,8,16,32,64,128}; BYTE IRQVector[16] = {8,9,10,11,12,13,14,15, 112,113,114,115,116,117,118,119}; struct MyModem{ unsigned int Address,Divisor,RCVHead,RCVTail,TRNSHead,TRNSTail; __dpmi_paddr OldHandler,NewHandler; _go32_dpmi_seginfo ModemWrapper; BYTE Active,IRQOn,IRQOff,IRQVector,IRQ,DataFlags,Status,FIFOOn; BYTE ModemRCV[Circular],ModemTRNS[Circular],Temp[Circular]; } Modem[4]; void ModemIntOn(int LineNum){ switch(LineNum){ // case 1: Modem[LineNum].ModemWrapper.pm_offset=(int)ModemHandler1; break; case 2: Modem[LineNum].ModemWrapper.pm_offset=(int)ModemHandler2; break; case 3: Modem[LineNum].ModemWrapper.pm_offset=(int)ModemHandler3; break; // case 4: Modem[LineNum].ModemWrapper.pm_offset=(int)ModemHandler4; break; } Modem[LineNum].ModemWrapper.pm_selector=_my_cs(); _go32_dpmi_allocate_iret_wrapper(&Modem[LineNum].ModemWrapper); Modem[LineNum].NewHandler.offset32=Modem[LineNum].ModemWrapper.pm_offset; Modem[LineNum].NewHandler.selector=Modem[LineNum].ModemWrapper.pm_selector; __dpmi_get_protected_mode_interrupt_vector(Modem[LineNum].IRQVector, &Modem[LineNum].OldHandler); // save old __dpmi_set_protected_mode_interrupt_vector(Modem[LineNum].IRQVector, &Modem[LineNum].NewHandler); // set new } void ModemIntOff(int LineNum){ __dpmi_set_protected_mode_interrupt_vector(Modem[LineNum].IRQVector, &Modem[LineNum].OldHandler); // set old _go32_dpmi_free_iret_wrapper(&Modem[LineNum].ModemWrapper); // free wrapper } void InitUART(int LineNum){ BYTE Val; int Port; outp(Modem[LineNum].Address+R_LineControl,128);//DLAB=1 outpw(Modem[LineNum].Address+R_Divisor,Modem[LineNum].Divisor);//Send Divisor outp(Modem[LineNum].Address+R_LineControl,Modem[LineNum].DataFlags);//DLAB=0 & send DataFormat // 8 4-NoFunctionOnPC 2 1 //ModemControl:OUT2=SendInteruptsToPic OUT1=BestToBeActive RTS=1 DTR=1 outp(Modem[LineNum].Address+R_ModemControl,15); outp(Modem[LineNum].Address+R_IntEnable,15);//Interupts we want to receive if(Modem[LineNum].IRQ>7) Port = 0xa1;//Slave PIC OCW1 else Port = 0x21;//Master PIC OCW1 Val=inp(Port);//Get Current OCW1 outp(Port,Val&Modem[LineNum].IRQOn);//Enable IRQ on PIC outp(Modem[LineNum].Address+R_FifoControl,0x0c7);//Try to turn ON FIFO Val=inp(Modem[LineNum].Address+R_FifoControl);//Fifo Support? D6=Yes if((Val & 64)>0) Modem[LineNum].FIFOOn = 1; else{ Modem[LineNum].FIFOOn = 0; outp(Modem[LineNum].Address+R_FifoControl,0);//Turn off FIFO } } void UnInitUART(int LineNum){ BYTE Val; int Port; outp(Modem[LineNum].Address+R_ModemControl,0);//StopIntsToPIC DropRTS outp(Modem[LineNum].Address+R_IntEnable,0);//Clear Interupt Flags if(Modem[LineNum].IRQ>7) Port = 0xa1;//Slave PIC OCW1 else Port = 0x21;//Master PIC OCW1 Val=inp(Port);//Get Current OCW1 outp(Port,Val|Modem[LineNum].IRQOff);//Disable IRQ on PIC } BYTE InitModem(BYTE ComPort,BYTE IRQ,unsigned long BaudRate,BYTE DataFlags){ union REGS r; BYTE Com[8],Ret,LineNumber; LineNumber=ComPort; Ret=0; //---Valid COM Port?--- if((ComPort<1)||(ComPort>4)) return(2); //---Already Initialized?--- if(Modem[LineNumber].Active) Ret=1; //---Usable IRQ Line?--- if((IRQ<3)||(IRQ==6)||(IRQ==8)||(IRQ==14)||(IRQ==13)) Ret+=4; if(Ret) return(Ret); //---Setup all the IRQ junk--- Modem[LineNumber].IRQ = IRQ;//IRQ Number Modem[LineNumber].IRQOn = PicIRQOn[IRQ];//Mask to Enable IRQ on PIC Modem[LineNumber].IRQOff = PicIRQOff[IRQ];//Mask to Disable IRQ on PIC Modem[LineNumber].IRQVector = IRQVector[IRQ];//Interupt Vector Number //---Install ModemHandler--- ModemIntOn(LineNumber); //---Get Base Address of UART from BIOS--- dosmemget(0x00400,8,Com); r.h.al = Com[ (ComPort-1)*2 ];//LSB r.h.ah = Com[ (ComPort-1)*2+1 ];//MSB Modem[LineNumber].Address = r.x.ax; //---Store DataFormat Bits--- Modem[LineNumber].DataFlags = DataFlags; //---Setup the Divisor--- Modem[LineNumber].Divisor = (unsigned int)(115200/BaudRate); //---Setup The UART and the PIC to start getting Interupts--- InitUART(LineNumber); //---Set Current Status--- Modem[LineNumber].Status = inp(Modem[LineNumber].Address+R_ModemStatus); //---Flag this structure instance as initialized--- Modem[LineNumber].Active=1; /* WriteChar(LineNumber,13); WriteChar(LineNumber,10); WriteChar(LineNumber,'a');//atz=DefaultModemState WriteChar(LineNumber,'t'); WriteChar(LineNumber,'z'); WriteChar(LineNumber,13); WriteChar(LineNumber,10); delay(20); Modem[LineNumber].RCVTail = Modem[LineNumber].RCVHead;//Clear RCVBuffer */ return(0);//No Error } void UnInitModem(int ComPort){ if(Modem[ComPort].Active==0) return; Modem[ComPort].Active = 0; UnInitUART(ComPort); ModemIntOff(ComPort); } //If U wanna use COM 1 or 4 copy this loop and change all the Modem[2] to // Modem[4] or Modem[1] and name the loop ModemHandler1 etc.. void ModemHandler2( void ){ int Port,Status; BYTE Value,Bit0,Bit1,Bit2; if(Modem[2].IRQ>7){ Value=inp(0xa1); //Remove IRQ on Slave PIC outp(0xa1,Value|Modem[2].IRQOff); outp(0xa0,0x20); //EOI Slave outp(0x20,0x20); //EOI Master : Master gets interupted when slave does } else{ Value=inp(0x21); //Remove IRQ on Master PIC outp(0x21,Value|Modem[2].IRQOff); outp(0x20,0x20); //EOI Master } //----Which Interupt was it?---- Value = inp(Modem[2].Address+R_IntID); Bit0 = Value & 1; Bit1 = Value & 2; if(Bit1) Bit1=1; Bit2 = Value & 4; if(Bit2) Bit2=1; while(!Bit0){ if(Bit2 && Bit1){//----------Serialization Error or Break------------ printf("Error\n"); outp(Modem[2].Address+R_LineStatus,0); //Clear LineStatusRegister Value=inp(Modem[2].Address+R_LineStatus);//Read LineStatusRegister } if(Bit2 && !Bit1){//---------Data is Waiting to be Read-------------- Value = inp(Modem[2].Address+R_IORegister); Modem[2].ModemRCV[Modem[2].RCVHead++] = Value; if(Modem[2].RCVHead>=Circular) Modem[2].RCVHead=0; } if(!Bit2 && Bit1){//---------Transmit Buffer Empty------------------- Value=1; if(Modem[2].FIFOOn) Value=16; for(Bit0=0;Bit0=Circular) Modem[2].TRNSTail=0; } } } if(!Bit2 && !Bit1){//--------Modem Status Change--------------------- Modem[2].Status = inp(Modem[2].Address+R_ModemStatus); } //----Another Interupt?---- Value = inp(Modem[2].Address+R_IntID); Bit0 = Value & 1; Bit1 = Value & 2; if(Bit1) Bit1=1; Bit2 = Value & 4; if(Bit2) Bit2=1; } if(Modem[2].IRQ>7){ Value=inp(0xa1); //Enable IRQ on PIC Slave outp(0xa1,Value&Modem[2].IRQOn); } else{ Value=inp(0x21); //Enable IRQ on PIC Master outp(0x21,Value&Modem[2].IRQOn); } } void ModemHandler3( void ){ int Port,Status; BYTE Value,Bit0,Bit1,Bit2,Bit6,Bit7; //Remove IRQ on Slave PIC & Send EOI if(Modem[3].IRQ>7){ Value=inp(0xa1); outp(0xa1,Value|Modem[3].IRQOff); outp(0xa0,0x20); //EOI Slave outp(0x20,0x20); //EOI Master : Master gets interupted when slave does } //Remove IRQ on Master PIC & Send EOI else{ Value=inp(0x21); outp(0x21,Value|Modem[3].IRQOff); outp(0x20,0x20); //EOI Master } //----Which Interupt was it?---- Value = inp(Modem[3].Address+R_IntID); Bit0 = Value & 1; Bit1 = Value & 2; if(Bit1) Bit1=1; Bit2 = Value & 4; if(Bit2) Bit2=1; while(!Bit0){ //----------Serialization Error or Break------------ if(Bit2 && Bit1){ outp(Modem[3].Address+R_LineStatus,0); //Clear LineStatusRegister Value=inp(Modem[3].Address+R_LineStatus);//Read LineStatusRegister } //---------Data is Waiting to be Read-------------- if(Bit2 && !Bit1){ Value = inp(Modem[3].Address+R_IORegister); Modem[3].ModemRCV[Modem[3].RCVHead++] = Value; if(Modem[3].RCVHead>=Circular) Modem[3].RCVHead=0; } //-------------Transmiter Holding Register Empty------------- if(!Bit2 && Bit1){ Value=1; if(Modem[3].FIFOOn) Value=16; for(Bit0=0;Bit0=Circular) Modem[3].TRNSTail=0; } } } //---------------------Modem Status Change--------------------- if(!Bit2 && !Bit1) Modem[3].Status = inp(Modem[3].Address+R_ModemStatus); //----Another Interupt?---- Value = inp(Modem[3].Address+R_IntID); Bit0 = Value & 1; Bit1 = Value & 2; if(Bit1) Bit1=1; Bit2 = Value & 4; if(Bit2) Bit2=1; } if(Modem[3].IRQ>7){ Value=inp(0xa1); //Enable IRQ on PIC Slave outp(0xa1,Value&Modem[3].IRQOn); } else{ Value=inp(0x21); //Enable IRQ on PIC Master outp(0x21,Value&Modem[3].IRQOn); } } void SendChar(int LineNum,BYTE Char){ BYTE Val; Val=inp(Modem[LineNum].Address+R_LineStatus) & 32; if((Val>0)&&(Modem[LineNum].TRNSHead==Modem[LineNum].TRNSTail)) outp(Modem[LineNum].Address+R_IORegister,Char); else Modem[LineNum].ModemTRNS[Modem[LineNum].TRNSHead++]=Char; } void SendString(int ComPort,BYTE *Buff,unsigned int Length){ unsigned int Head,Flag,t,V; BYTE *Src,*Dest; Src=Buff; Dest=Modem[ComPort].ModemTRNS; Head=Modem[ComPort].TRNSHead; Flag=0; if(Head==Modem[ComPort].TRNSTail) Flag=1; while(Length--){ *(Dest+Head++)=*Src++; if(Head>=Circular) Head=0; } Modem[ComPort].TRNSHead = Head; if(Flag){ while ((inp(Modem[ComPort].Address+R_LineStatus) & 32) == 0); V=1; if(Modem[ComPort].FIFOOn) V=16; for(t=0;t=Circular) Modem[ComPort].TRNSTail=0; } } } } BYTE GrabChar(int ComPort){ } BYTE GrabString(int ComPort){ } //--- EndPad ---// --------------62E86F2B32FE--