Mail Archives: djgpp/1998/09/17/18:30:41
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 <dos.h>
#include <dpmi.h>
#include <go32.h>
#include <sys/movedata.h>
#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<Value;Bit0++){
if(Modem[2].TRNSHead!=Modem[2].TRNSTail){
outp(Modem[2].Address+R_IORegister,Modem[2].ModemTRNS[Modem[2].TRNSTail++]);
if(Modem[2].TRNSTail>=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<Value;Bit0++){
if(Modem[3].TRNSHead!=Modem[3].TRNSTail){
outp(Modem[3].Address+R_IORegister,Modem[3].ModemTRNS[Modem[3].TRNSTail++]);
if(Modem[3].TRNSTail>=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<V;t++){
if(Modem[ComPort].TRNSHead!=Modem[ComPort].TRNSTail){
outp(Modem[ComPort].Address+R_IORegister,Modem[ComPort].ModemTRNS[Modem[ComPort].TRNSTail++]);
if(Modem[ComPort].TRNSTail>=Circular) Modem[ComPort].TRNSTail=0;
}
}
}
}
BYTE GrabChar(int ComPort){
}
BYTE GrabString(int ComPort){
}
//--- EndPad ---//
--------------62E86F2B32FE--
- Raw text -