Newsgroups: comp.os.msdos.djgpp From: elj AT sky1 DOT elj DOT org (Edwin Johnson) Subject: Re: Interrupt handled RS232 References: <5137-Fri02Nov2001111121+0200-eliz AT is DOT elta DOT co DOT il> Message-ID: User-Agent: slrn/0.9.7.0 (Linux) NNTP-Posting-Host: 32.100.53.132 Date: 2 Nov 2001 17:03:34 GMT X-Trace: 2 Nov 2001 17:03:34 GMT, 32.100.53.132 Organization: Global Network Services - Remote Access Mail & News Services Lines: 200 X-Complaints-To: abuse AT prserv DOT net To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com On Fri, 02 Nov 2001 11:11:21 +0200, Eli Zaretskii wrote: > Please post the important parts here. In particular, the code which > installs the interrupt handler is the crucial detail. > > I suggest to begin with the variant which installs protected-mode > handler, since it should be the most straightforward one. > > In case you didn't already, please read section 18.9 of the DJGPP FAQ > list, perhaps it will give some clues. Oh yes, many times have I read that. :) Below are relevant portions of code for the installation of protected mode interrupt handler for rs232 port 1. The uart is setup via an assembly call program, the ISR is in assembly. Both of these routines are in a large assembly block of code containing other utilities to be used later and locked with 'lock initcom'. The data section for all of this is locked via the 'lock data_area' line. In the ISR I am setting the newb flag byte to 1 and passing back to C the byte input from the uart in rsbyte. For test I set the newb byte to 1 at the beginning of the ISR just to see if the program was going to the ISR and it isn't. I've probably missed something here, but am not seeing it. Both setup and ISR routines in assembly are very complete and work fine in the real mode. It is as if the vectors for the handler aren't actually being written for the new handler address. Perhaps I'm missing some step or have coded this incorrectly. The stack setup was copied verbatim from Jeronimo's link, but not sure I understand if it is correct or not. Most of the material came from a page by Frederico Jeronimo, a link on the djgpp site. -------------- the C program: #define STACK_SIZE 1024 extern void handler_wrapper(), handler_wrapper_end(); extern void rs232_handler(), rs232_handler_end(); extern void data_area(), data_area_end(); extern void initcom(short,short,short), initcom_end(); extern void bdrate(short); short newb, rsbyte; long handler; unsigned char *stack; int main() { unsigned char ch; char eljs[]="T"; short brate = 6, cardtype=31, numbrs = 0xf, portn = 1; __dpmi_paddr newhandler, oldhandler; stack = (char *)malloc(STACK_SIZE); handler = (long)rs232_handler; if (stack){ _go32_dpmi_lock_data(stack,STACK_SIZE); _go32_dpmi_lock_data(&stack, sizeof(stack)); stack += STACK_SIZE - 32; } /* coded for serial port 1, which is 0x3f8 with IRQ 4 */ __dpmi_get_protected_mode_interrupt_vector(4,&oldhandler); newhandler.selector = _my_cs(); newhandler.offset32 = (long)handler_wrapper; newb = 0; rsbyte = 0; LOCK_VARIABLE(newb); LOCK_VARIABLE(rsbyte); LOCK_VARIABLE(handler); LOCK_FUNCTION(initcom); LOCK_FUNCTION(data_area); LOCK_FUNCTION(handler_wrapper); printf("\nInstalling the handlers using the NASM assembler\n"); __dpmi_set_protected_mode_interrupt_vector(4,&newhandler); /* initcom is an assembly routine to setup the uart, I passed back for checking in newb and rsbyte two of the uart register contents (those being required for interrupts) and feel the uart is setup correctly. */ initcom(cardtype,numbrs,portn); printf("The newb is %d\n",newb); printf("The rsbyte is %d\n",rsbyte); /* remove the mask for the interrupt for serial port 1 - start */ ch = inportb(0x21); outportb(0x21,ch & 0x0ef); /* strt232(); an assembly call to do the same as above (have tried this)*/ newb=1; rsbyte = 65; while (!kbhit()){ if (newb == 1){ printf("data received - "); eljs[0] = rsbyte; printf("%s\n",eljs); newb = 0; } } /* mask the interrupt bit for serial port 1 - stop */ ch = inportb(0x21); outportb(0x21,ch | 0x10); /* end232(); an assembly call to do the same as above */ __dpmi_set_protected_mode_interrupt_vector(4,&oldhandler); /* One final step is required. We should always unlock everything that was locked. */ UNLOCK_VARIABLE(newb); UNLOCK_VARIABLE(rsbyte); UNLOCK_VARIABLE(handler); UNLOCK_FUNCTION(initcom); UNLOCK_FUNCTION(data_area); UNLOCK_FUNCTION(handler_wrapper); } -------------- the NASM wrapper: [BITS 32] extern ___djgpp_ds_alias extern _stack extern _rs232_handler extern _handler [SECTION .text] align 4 global _handler_wrapper _handler_wrapper: push word ds push word es push word fs push word gs pusha mov word ax, [___djgpp_ds_alias] ; Set up a valid selector mov word ds, ax mov word es, ax mov word fs, ax mov word gs, ax lea long ebx, [_stack] cmp long[ebx],0 jz over mov long ecx,esp mov long edx,ss mov long esp,[ebx] mov word ss,eax mov long [ebx],0 push long edx push long ecx push long ebx cld mov long eax, _handler call [eax] cli pop long ebx ; Pop old stack pop long ecx pop long edx mov long [ebx], esp ; Restore old stack mov word ss, edx mov long esp, ecx over: popa pop word gs pop word fs pop word es pop word ds sti iret global _handler_wrapper_end _handler_wrapper_end: ret -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~ Edwin Johnson ....... elj AT shreve DOT net ~ ~ http://www.shreve.net/~elj ~ ~ ~ ~ "Once you have flown, you will walk the ~ ~ earth with your eyes turned skyward, ~ ~ for there you have been, there you long ~ ~ to return." -- da Vinci ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~