Mail Archives: djgpp/2002/01/18/18:31:35
If no page fault and after certain time program continues to operate
normally.
I lock the whole memory.
It seems that freezing occures more often when the program tries to save or
read e.g. 60 times few (2 to 60) bytes in a loop during transmition even the
transmittion is slow ( 50 Bd), that is program switch very often from
protected to real mode and back.
I just continue to observe the behaviour of the program.
Just for Your convinience I sent a short version of program, which works
under both environment:
Thanks for Your help.
Petr
#include <dpmi.h>
#include <go32.h>
class DJGPP_INTERRUPT {
int irq_no,ino,set;
_go32_dpmi_seginfo si_pm_oldisr; /* original prot-mode key IRQ */
_go32_dpmi_seginfo si_pm_isr; /* prot-mode interrupt segment info
*/
_go32_dpmi_seginfo si_rm_oldisr; /* original real mode key IRQ */
_go32_dpmi_seginfo si_rm_isr; /* real mode interrupt segment info
*/
_go32_dpmi_registers rm_regs;
public:
DJGPP_INTERRUPT() {init();};
~DJGPP_INTERRUPT() {if(set) uninstall();};
int install_irq(int irq_no,unsigned long pm_isr,unsigned long rm_isr=0);
int install_vec(int vec_no,unsigned long pm_isr,unsigned long rm_isr=0);
void uninstall();
void init();
int daj_set() {return set;};
};
#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <bios.h>
#include <unistd.h>
#include <sys/farptr.h>
#include <dpmi.h>
#include <go32.h>
#include <pc.h>
#include <io.h>
#include <crt0.h>
#include <sys/nearptr.h>
#include "kp_seria.h"
void DJGPP_INTERRUPT::init()
{
set = irq_no = ino = 0;
memset(&si_pm_oldisr, 0, sizeof(si_pm_oldisr));
memset(&si_pm_isr , 0, sizeof(si_pm_isr));
memset(&si_rm_oldisr, 0, sizeof(si_rm_oldisr));
memset(&si_rm_isr, 0, sizeof(si_rm_isr));
memset(&rm_regs, 0, sizeof(rm_regs));
}
int DJGPP_INTERRUPT::install_irq(int irq_no,unsigned long isr,unsigned long
rm_isr)
{
return install_vec(_go32_info_block.master_interrupt_controller_base +
irq_no,
isr,rm_isr);
}
int DJGPP_INTERRUPT::install_vec(int vec_no,unsigned long isr,unsigned long
rm_isr)
{
if(set) uninstall();
init();
ino = vec_no;
/* get and allocate pm handler */
_go32_dpmi_get_protected_mode_interrupt_vector(ino, &si_pm_oldisr);
si_pm_isr.pm_selector = _go32_my_cs();
si_pm_isr.pm_offset = isr;
if (_go32_dpmi_allocate_iret_wrapper(&si_pm_isr) != 0)
goto error;
#ifdef PM_11_01_2002
#else
rm_isr = 0;
#endif
/* get and allocate rm handler */
if (rm_isr)
{
_go32_dpmi_get_real_mode_interrupt_vector(ino, &si_rm_oldisr);
si_rm_isr.pm_selector = _go32_my_cs();
si_rm_isr.pm_offset = rm_isr;
if (_go32_dpmi_allocate_real_mode_callback_iret(&si_rm_isr,
&rm_regs) != 0)
goto error;
}
/* set pm handler */
if (_go32_dpmi_set_protected_mode_interrupt_vector(ino, &si_pm_isr) != 0)
goto error;
/* set rm handler */
if (rm_isr)
_go32_dpmi_set_real_mode_interrupt_vector(ino, &si_rm_isr);
set = 1;
return 0;
error:
init();
return -1;
}
void DJGPP_INTERRUPT::uninstall()
{
if(!set) return;
int r = 0;
int final=1;
disable();
if (si_pm_oldisr.pm_selector != 0 || si_pm_oldisr.pm_offset != 0)
r |= _go32_dpmi_set_protected_mode_interrupt_vector(ino,
&si_pm_oldisr);
if (si_rm_oldisr.rm_segment != 0 || si_rm_oldisr.rm_offset != 0)
r |= _go32_dpmi_set_real_mode_interrupt_vector(ino, &si_rm_oldisr);
if (final && r == 0)
{
if (si_pm_isr.pm_selector != 0 || si_pm_isr.pm_offset != 0)
_go32_dpmi_free_iret_wrapper(&si_pm_isr);
if (si_rm_isr.size)
_go32_dpmi_free_real_mode_callback(&si_rm_isr);
init();
}
enable();
}
#define IIR_0 0
#define IIR_2 2
#define IIR_4 4
#define IIR_6 6
#define IIR_0xc 0xc
#define STATUS_COM_PRJ_PRET_BUF 1
#define ZRUS_PRJ_ZN_POCAS_VYSIELANIA
#define CHAR_TIM_TIK_DELAY 4 //cim menej, tym rychl. bude MKP reagovat
//ale tym viac bude zamestnavany procesor
//MKP a program bude menej pruzny
//na pomalsich PC tu treba davat vyssie hodnoty
#define ISR_START static void
#define INCL_ISR_START void
#define ISR_PAR _go32_dpmi_registers *regs
#define TEST_ISR_INSTALLED djgpp_isr.daj_set()
static const int HWDRV_BUF_LEN = 256;
typedef unsigned char uchar;
typedef unsigned short uint16;
typedef short int16;
typedef unsigned long uint32;
typedef long int32;
uchar *anal_char = 0;
template<typename T>
T min(T t1,T t2) { return t1 < t2 ? t1 : t2;}
template<typename T1,typename T2>
T1 min(T1 t1,T2 t2) { return t1 < t2 ? t1 : t2;}
void hwdrv_init_u(struct HWDRV_COM *uhw_com);
void hwdrv_reset_p(struct HWDRV_COM *uhw_com);
struct HWDRV_COM {
uchar* uk_buf_vys,*uk_buf_prj;
uchar buf_prj[HWDRV_BUF_LEN];
uint16 BASE_0, BASE_1, BASE_2, BASE_3, BASE_4, BASE_5, BASE_6;
volatile uint16 uz_prj,tuz_prj, //tuz_prj -> testovacie ukazovatko
kt. zvysuje testovacia rutina
uv_prj, d_prj, p_ignoruj_prj;
volatile uint32 u_vys,d_vys;
int32 p_vys_zn, p_prj_zn,p_irq;
int32 rychl,sk_rychl;
uint16
p_vys,p_prj,p_mod_ch,p_prj_ch,p_pret,p_chpov,p_ch_r,p_char_tim;
uint16 p_tim,p_tim_p,p_opak,p_O_K,p_i_err,i_err_id;
#define ST_TIM_NONE 0 //timeout nepouzity
#define ST_TIM_RESP 1 //cakanie na odpoved
#define ST_TIM_CHAR_VYS 2 //cakanie na vyslanie 1 znaku
#define ST_TIM_CHAR_PRJ 3 //cakanie na prijem 1 znaku
#define ST_TIM_ONES 4 //oneskorenie vysielania
int16 timeout,st_tim;
int16 timeout_resp_set,timeout_char_set,timeout_vys_char_set;
int16 IRQ;
uchar LSR,LSRE,LSRLE,LCR; //Line Status/Control Register
uchar MSR,MCR; //Modem Status/Control Register
uchar FCR,FLen,FTrig; //Fifo Control Register, Fifo len
char IER,IIR; //Interrupt Enable/Identification
Register
char status;
DJGPP_INTERRUPT djgpp_isr;
INCL_ISR_START (*new_handle)(ISR_PAR);
};
static const int POCET_HW_COM = 2;
struct HWDRV_COM hw_com[POCET_HW_COM];
struct HWDRV_COM *hw_com1 = &hw_com[0];
struct HWDRV_COM *hw_com2 = &hw_com[1];
ISR_START HWDRV_COM1_ISR (ISR_PAR);
ISR_START HWDRV_COM2_ISR (ISR_PAR);
void hwdrv_enable_irq(int16 irq)
{
uchar m21=inportb(0x21);
outportb(0x21,m21 & ((1 << irq) ^ 0xff));
}
void hwdrv_disable_irq(int16 irq)
{
uchar m21=inportb(0x21);
outportb(0x21,m21 | (1 << irq));
}
void hwdrv_install_isr(struct HWDRV_COM *uhw_com)
{
uhw_com->djgpp_isr.install_irq(uhw_com->IRQ,(unsigned
long)uhw_com->new_handle,(unsigned long)uhw_com->new_handle);
hwdrv_enable_irq(uhw_com->IRQ);
}
void hwdrv_uninstall_isr(struct HWDRV_COM *uhw_com)
{
hwdrv_disable_irq(uhw_com->IRQ);
uhw_com->djgpp_isr.uninstall();
}
void hwdrv_posli_tlg(struct HWDRV_COM *hwcom,uchar *buf,int32 len,int16
p_ignoruj_prj)
{
if(!hwcom) return;
// outportb(hwcom->BASE_1,0);
// if(hwcom->IRQ) hwdrv_disable_irq(hwcom->IRQ);
hwcom->p_ignoruj_prj = p_ignoruj_prj;
hwcom->u_vys = 0;
hwcom->d_vys = len;
hwcom->uv_prj = hwcom->uz_prj =
hwcom->tuz_prj = hwcom->d_prj = 0;
hwcom->uk_buf_vys = buf;
hwcom->timeout_vys_char_set = hwcom->timeout_char_set *
min(len,hwcom->FLen);
hwcom->p_char_tim = 0;
hwcom->timeout = hwcom->timeout_char_set * min(len,hwcom->FLen);
hwcom->st_tim = ST_TIM_CHAR_VYS;
hwcom->IER |= 2;
#ifdef ZRUS_PRJ_ZN_POCAS_VYSIELANIA
hwcom->IER &= 0xfa; //test - zakazem prijem !!!
#endif
outportb(hwcom->BASE_1,hwcom->IER);
}
void hwdrv_init_com(struct HWDRV_COM *hwcom,int16 n_p_tim_p)
{
//rychlost je viazana na rychlost hodin v uart, st. je to 1843200 Hz,
//z tohto kmitoctu sa vypocita deliaci pomer pre zodpovedajucu rychlost,
//kedze pre vyslanie 1 bitu je potrebnych 16 zakmitov => 16 * 115200 =
1843200
//(ak je vyssia rychlost hodin, je mozne dosiahnut vyssej prenosovej
rychlosti)
unsigned int i;
uint16 uart_delicka;
uchar b_l,b_h;
uchar FTrig[4]={1,4,8,14};
if(hwcom->st_tim == ST_TIM_RESP)
{
hwcom->p_tim_p++;
if(n_p_tim_p && ((hwcom->p_tim_p % n_p_tim_p)!=0))
goto END_INIT_COM; //bude sa inicializovat az pri n-tom timeoute
prijmu
}
hwcom->sk_rychl = hwcom->rychl;
if(hwcom->sk_rychl<2) hwcom->sk_rychl = 50;
else
if(hwcom->sk_rychl>115200L) hwcom->sk_rychl = 115200L;
uart_delicka = (int16) (115200L / hwcom->sk_rychl);
b_l = (uchar) 0xFF & uart_delicka;
b_h = (uchar) 0xFF & ( uart_delicka >> 8 );
hwcom->sk_rychl = 115200L / uart_delicka;
hwcom->MCR = 0;
outportb(hwcom->BASE_4,hwcom->MCR = 0);
outportb(hwcom->BASE_1,hwcom->IER = 0); // zakaz vsetkych preruseni
for(i=0xFFFFU;i;i--)
{
hwcom->LSR = inportb(hwcom->BASE_5);
if(hwcom->LSR & 0x1f) inportb(hwcom->BASE_0); else break;
}
inportb(hwcom->BASE_6);
outportb(hwcom->BASE_4,3);
outportb(hwcom->BASE_3,0x80); // inicializace prenosove rychlosti
outportb(hwcom->BASE_0,b_l);
outportb(hwcom->BASE_1,b_h);
outportb(hwcom->BASE_3,hwcom->LCR);
outportb(hwcom->BASE_4,hwcom->MCR = 10); //treba nastavovat druhy
bit(RTS),
//aby na kabloch, kde su prepojene
//RTS -> CTS fungovala komunikacia
!!
outportb(hwcom->BASE_2,hwcom->FCR); //0xc7=fifo
hwcom->FLen = ((inportb(hwcom->BASE_2) & 0xC0)==0xC0) &&
hwcom->FCR ? 16 : 1;
hwcom->FTrig = FTrig[hwcom->FCR>>6];
END_INIT_COM:
hwcom->timeout_char_set = (int16)((18.2 * 11) / hwcom->rychl) +
CHAR_TIM_TIK_DELAY;
hwcom->timeout = 0;
hwcom->st_tim = ST_TIM_NONE;
hwcom->status = 0;
}
void hwdrv_base_init_com(struct HWDRV_COM *uhw_com,int16 BASE,
int32 rychlost,uchar LCR,uchar FCR,int16 timeout_resp_set,
int16 IRQ)
{
hwdrv_init_u(uhw_com);
hwdrv_reset_p(uhw_com);
uhw_com->IRQ = IRQ;
uhw_com->BASE_0 = BASE;
uhw_com->BASE_1 = BASE+1;
uhw_com->BASE_2 = BASE+2;
uhw_com->BASE_3 = BASE+3;
uhw_com->BASE_4 = BASE+4;
uhw_com->BASE_5 = BASE+5;
uhw_com->BASE_6 = BASE+6;
uhw_com->rychl = rychlost;
uhw_com->LCR = LCR;
uhw_com->FCR = FCR;
uhw_com->timeout_resp_set = timeout_resp_set;
uhw_com->uk_buf_prj = uhw_com->buf_prj;
hwdrv_init_com(uhw_com,0);
}
struct HWDRV_COM *hwdrv_instaluj_COM_handle(int16 BASE,int16 IRQ,uchar
LCR,int32 rychlost)
{
struct HWDRV_COM *uhw_com;
if(hw_com1->IRQ==0)
{
uhw_com = hw_com1;
uhw_com->new_handle = HWDRV_COM1_ISR;
}
else
if(hw_com2->IRQ==0)
{
uhw_com = hw_com2;
uhw_com->new_handle = HWDRV_COM2_ISR;
}
else
return 0;
hwdrv_base_init_com(uhw_com,BASE,rychlost,LCR,0,2000,IRQ);
hwdrv_install_isr(uhw_com);
return uhw_com;
}
void hwdrv_odinstaluj_COM_handle(struct HWDRV_COM *uhw_com)
{
if((uhw_com==NULL) ||
(uhw_com->IRQ<=0) ||
(!uhw_com->TEST_ISR_INSTALLED))
return;
outportb(uhw_com->BASE_1,uhw_com->IER = 0);
hwdrv_uninstall_isr(uhw_com);
}
void fifo_com_isr(struct HWDRV_COM *uhw_com)
{
static int p;
static uchar fl;
static unsigned in;
uhw_com->p_irq++;
p=1000;
while(1)
{
p--;if(!p) {uhw_com->p_i_err++;uhw_com->i_err_id = 4;break;}
fl = 0xf & inportb(uhw_com->BASE_2);
// uhw_com->IIR = fl;
if(fl & 1) break;
uhw_com->IIR = fl;
switch (fl)
{
case IIR_0:uhw_com->p_mod_ch++;inportb(uhw_com->BASE_6);break;
case IIR_2:if((uhw_com->IER & 2) == 0)
{outportb(uhw_com->BASE_1,uhw_com->IER);break;}
uhw_com->LSR = inportb(uhw_com->BASE_5);
if(uhw_com->LSR & 0x20) //vyst. reg. prazdny
{ static int i;
uhw_com->timeout = 0;
for(i=0;i<uhw_com->FLen;i++)
{
if(uhw_com->u_vys < uhw_com->d_vys)
{
outportb(uhw_com->BASE_0,uhw_com->uk_buf_vys[uhw_com->u_vys]);
uhw_com->u_vys++;
}
else
{
uhw_com->IER &= 0xfd; //zakaz vysielania
#ifdef ZRUS_PRJ_ZN_POCAS_VYSIELANIA
while(inportb(uhw_com->BASE_5) & 1)
inportb(uhw_com->BASE_0);
uhw_com->IER |= 5; //povolenie prerusenia od
prijmu
#endif
outportb(uhw_com->BASE_1,uhw_com->IER);
uhw_com->p_vys++;
uhw_com->st_tim = ST_TIM_RESP;
uhw_com->timeout = uhw_com->timeout_resp_set;
break;
}
}
uhw_com->timeout += uhw_com->timeout_char_set * i;
uhw_com->p_vys_zn += i;
}
break;
case IIR_0xc:
case IIR_4:
while(1)
{
p--;if(!p) {uhw_com->p_i_err++;uhw_com->i_err_id =
5;break;}
uhw_com->LSR = inportb(uhw_com->BASE_5);
if(!(uhw_com->LSR & 1)) break;//pripr. prj. dat
if(!(uhw_com->IER & 1) || !uhw_com->uk_buf_prj)
{
inportb(uhw_com->BASE_0);
outportb(uhw_com->BASE_1,uhw_com->IER &= ~1);
break;
}
in = uhw_com->uz_prj;
uhw_com->uk_buf_prj[in] = inportb(uhw_com->BASE_0);
if(uhw_com->p_ignoruj_prj)
{uhw_com->p_ignoruj_prj--;break;}
in++;
uhw_com->p_prj_zn++;
uhw_com->d_prj++;
if(in>=HWDRV_BUF_LEN) in = 0;
uhw_com->uz_prj = in;
if(in == uhw_com->uv_prj)
uhw_com->status |= STATUS_COM_PRJ_PRET_BUF;
uhw_com->st_tim = ST_TIM_CHAR_PRJ;
uhw_com->timeout =
uhw_com->timeout_char_set*uhw_com->FTrig;
}
break;
case IIR_6:
while(1)
{
p--;//if(!p) {uhw_com->p_i_err++;uhw_com->i_err_id =
6;break;}
in = inportb(uhw_com->BASE_5);
uhw_com->LSR = in;
if(in & 1) inportb(uhw_com->BASE_0);
if(in & 0x1E) //chyba prijmu
{
uhw_com->LSRE = uhw_com->LSRLE = in;
uhw_com->p_prj_ch++;
}
else
break;
//in = inportb(uhw_com->BASE_5);
//if(in & 1) inportb(uhw_com->BASE_0);
//if(!(in & 0x1E)) break; //ziadna chyba
//uhw_com->LSR = uhw_com->LSRE = uhw_com->LSRLE =
in;
//uhw_com->p_prj_ch++;
}
break;
}
}
}
ISR_START HWDRV_COM1_ISR(ISR_PAR)
{
static int p = 0;
*anal_char = 'a';
p++;
anal_char[2] = (p / 100000) % 10 + '0';
anal_char[4] = (p / 10000) % 10 + '0';
anal_char[6] = (p / 1000) % 10 + '0';
anal_char[8] = (p / 100) % 10 + '0';
anal_char[10] = (p / 10) % 10 + '0';
anal_char[12] = p % 10 + '0';
fifo_com_isr(hw_com1);
outportb(0x20,0x20);
*anal_char = 'A';
}
ISR_START HWDRV_COM2_ISR(ISR_PAR)
{
anal_char[4] = 'b';
if((anal_char[6]<'0') || (anal_char[6]>'8'))
anal_char[6] = '0';
else
anal_char[6]++;
fifo_com_isr(hw_com2);
outportb(0x20,0x20);
anal_char[4] = 'B';
}
void hwdrv_init_u(struct HWDRV_COM *uhw_com)
{
if(!uhw_com) return;
uhw_com->u_vys = uhw_com->uz_prj = uhw_com->uv_prj = 0;
uhw_com->d_vys = 0;
uhw_com->d_prj = 0;
}
void hwdrv_reset_p(struct HWDRV_COM *uhw_com)
{
if(!uhw_com) return;
uhw_com->p_vys_zn = uhw_com->p_prj_zn = uhw_com->p_irq = 0;
uhw_com->p_vys = uhw_com->p_prj = uhw_com->p_mod_ch =
uhw_com->p_prj_ch = uhw_com->p_chpov = uhw_com->p_pret =
uhw_com->p_tim = uhw_com->p_tim_p = uhw_com->p_opak =
uhw_com->p_O_K = uhw_com->p_i_err = uhw_com->i_err_id = 0;
uhw_com->LSRLE = 0;
uhw_com->p_ch_r = 0;
}
int _crt0_startup_flags = _CRT0_FLAG_LOCK_MEMORY;
int main()
{
if ( !(_crt0_startup_flags & _CRT0_FLAG_NEARPTR) )
__djgpp_nearptr_enable ();
if ( _crt0_startup_flags & _CRT0_FLAG_NEARPTR)
{
anal_char = (uchar *)(0xb8000 + __djgpp_conventional_base);
*anal_char = 's';
}
struct HWDRV_COM *uhw_com = hwdrv_instaluj_COM_handle(0x3F8,4,0x1B,50);
if(!uhw_com) return -1;
#define VYS_LEN 100
uchar p[VYS_LEN];
for(int i=0;i<VYS_LEN;i++) p[i] = i;
//hwdrv_posli_tlg(uhw_com,p,VYS_LEN,0);
int fi = _creat("test.txt",_A_ARCH);
int pp = 0;
hwdrv_posli_tlg(uhw_com,p,8,0);
for(int i = 0; i< 100;)
{
pp++;
_write(fi,p,16);
if(uhw_com->u_vys == 8)
{
hwdrv_posli_tlg(uhw_com,p,8,0);
delay(10);
i++;
}
_write(fi,p,16);
}
printf("pp = %d\n",pp);
_close(fi);
hwdrv_odinstaluj_COM_handle(uhw_com);
return 0;
}
"Charles Sandmann" <sandmann AT clio DOT rice DOT edu> píše v diskusním příspěvku
news:3c479438 DOT sandmann AT clio DOT rice DOT edu...
> > I have program, which runs correctly under win95 dpmi server,
> > but under clear dos v 7.0 with csdpmi5 server has strange behaviour:
>
> If you get a page fault you may have one of two problems:
> 1) null pointers (not caught with W95)
> 2) unlocked memory
>
> Posting the entire error message would be helpful. You need to als make
> sure you are not using any "extended" interrupts which expect
> pointers to be automatically handled.
>
> > I am looking for some tips as I have tried several test without success.
> > I even created a small version of this program, but it works without any
> > problems also in DOS.
>
> Keep adding features till you find what's broken.
- Raw text -