X-Authentication-Warning: delorie.com: mailnull set sender to djgpp-bounces using -f From: "Petr Maxa" Newsgroups: comp.os.msdos.djgpp Subject: Re: strange problem with dos DPMI Date: Sat, 19 Jan 2002 00:19:14 +0100 Lines: 610 Message-ID: References: <3c479438 DOT sandmann AT clio DOT rice DOT edu> NNTP-Posting-Host: dial241.za.euroweb.sk (195.72.5.241) X-Trace: fu-berlin.de 1011396150 33512552 195.72.5.241 (16 [127824]) X-Newsreader: Microsoft Outlook Express 5.50.4522.1200 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4522.1200 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com 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 #include 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 #include #include #include #include #include #include #include #include #include #include #include #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 T min(T t1,T t2) { return t1 < t2 ? t1 : t2;} template 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;iFLen;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;iu_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" 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.