Mail Archives: djgpp/1995/08/04/14:20:28
Dear DJGPP gurus,
I am making my first serious foray into using DJGPP (1.12m4 for
those keeping track) and am having trouble converting a program
that was running under the Intel Codebuilder compiler. I have
made some attempts to figure this out with the FAQ, the mail
archive, and looking at examples, but apologize anyway for
what will probably be well known to all the cognoscenti.
The following fragment (mis)uses a DOS function which performs
an "event_wait" function; usually, after the specifed time the
flag is set. This will not happen in my example, since I have
replaced the interrupt at 0x70. During my interrupt, the "clear_int"
routine reprograms the real-time clock chip.
My machine hangs when I execute this code (either manually or
stepping through it with gdb or ladybug).
Here are a few things that I am particularly uncertain about:
Does "clear_in.s" need more/different pro and post-log ops (i.e. register
saving and restoring, stack adjusting, etc)?
Where do I need enable/disable calls? (Also, why does the sblaster
example code #define replacements for these? Is that important?)
Thanks,
Andy S.
#include <bios.h>
#include <malloc.h>
#include <dos.h>
#include <stdarg.h>
#include <pc.h>
#include <dpmi.h>
#include <go32.h>
int wait_flag = 0;
static _go32_dpmi_registers dinregs;
void event_wait(void);
int int_cntr = 0;
static _go32_dpmi_seginfo rm_si;
static _go32_dpmi_seginfo oldirq_rm;
static _go32_dpmi_registers rm_regs;
static _go32_dpmi_seginfo pm_si;
static _go32_dpmi_seginfo oldirq_pm;
void int8_isr(void)
{
int_cntr++;
clear_int();
enable();
}
#define TIM_IRQ 0x70
void install_tim_vect(void)
{
int ret;
disable();
_go32_dpmi_get_real_mode_interrupt_vector( TIM_IRQ, &oldirq_rm);
rm_si.pm_offset = (int) int8_isr;
ret = _go32_dpmi_allocate_real_mode_callback_iret(
&rm_si, &rm_regs);
if ( ret != 0 ) printf(" cannot alloc real mode callback\n");
ret = _go32_dpmi_set_real_mode_interrupt_vector( TIM_IRQ, &rm_si);
if ( ret != 0 ) printf(" cannot set real mode vector\n");
_go32_dpmi_get_protected_mode_interrupt_vector( TIM_IRQ, &oldirq_pm);
pm_si.pm_offset = (int) int8_isr;
ret = _go32_dpmi_allocate_iret_wrapper(
&pm_si);
if ( ret != 0 ) printf(" cannot alloc iret wrapper\n");
ret = _go32_dpmi_set_protected_mode_interrupt_vector(
TIM_IRQ, &pm_si);
if ( ret != 0 ) printf(" cannot set prot mode vector\n");
enable();
event_wait();
}
void event_wait(void)
{
dinregs.x.ax = 0x8300; /* Event wait with es:bx = pointer to user flag */
dinregs.x.cx = 0x0; /* cx,dx = Number of microseconds */
dinregs.x.dx = 0x3d1;
dinregs.x.es = 0L;
dinregs.x.bx = 0L;
/* Execute int 15 interrupt */
_go32_dpmi_simulate_int( 0x15, &dinregs);
}
/*;======================================================================
; io.asm -- assembly language i/o subroutines
; attempt by AES to convert to AT&T form for GAS
;*/
.data
.text
.align 4
.globl _clear_int
_clear_int:
pushl %eax
mov $0ch,%al
out %al,$70h
nop
nop
nop
nop
nop
in $71h,%al
mov $20h,%al
out %al,$0a0h
out %al,$20h
popl %eax
ret
- Raw text -