Mail Archives: djgpp/2024/02/24/02:02:36
> From: "Ozkan Sezer (sezeroz AT gmail DOT com) [via djgpp AT delorie DOT com]" <djgpp AT delorie DOT com>
> Date: Sat, 24 Feb 2024 03:08:59 +0300
>
> On Sat, Feb 24, 2024 at 12:49 AM J.W. Jagersma (jwjagersma AT gmail DOT com)
> [via djgpp AT delorie DOT com] <djgpp AT delorie DOT com> wrote:
> [...]
> > > __asm__ __volatile__ ("movw %%dx,%0":"=m"(addr.segment));
> > > __asm__ __volatile__ ("movw %%di,%0":"=m"(addr.offset16));
> >
> > This doesn't look right - you can't assume gcc preserves registers
> > between asm blocks.
>
> OK, should have been like this then, yes?
It is better to avoid inline assembly at all. I'm guessing Watcom did
that for speed or something, but does speed really matter here?
> Is the following correct ??
>
> int sndlib_sbemu_detect(void)
> {
> __dpmi_raddr addr;
> uint32_t r_addr;
> __dpmi_regs regs;
> char* appstring;
> int mx;
>
> /* check for INT2D vector == NULL */
> __dpmi_get_real_mode_interrupt_vector(0x2D, &addr);
> r_addr = ((uint32_t)addr.segment<<4) + (uint32_t)addr.offset16;
> if (!r_addr) return -1;
Instead of the above bit juggling to get r_addr, you could simply test
both segment and offset to be zero. After all, how else you'd get
zero in the linear address?
> /* scan all multiplexes of INT 2D */
> for (mx = 0; mx < 256; mx++)
> {
> memset(®s, 0, sizeof(regs));
> regs.h.ah = mx;
> __dpmi_int(0x2D, ®s);
> if (regs.h.al != 0xFF)
> continue;
>
> /* check for SBEMU application string */
> r_addr = ((uint32_t)regs.x.dx<<4) + (uint32_t)regs.x.di;
> if (!r_addr) continue;
> appstring = (char *)real2ptr(r_addr);
> if (memcmp(appstring + 8,"SBEMU",5) == 0)
> return mx;
You cannot access conventional (below 1MB) memory like that. You need
to use one of the techniques described in the node "Xfer" in the
DJGPPFAQ Info manual, to fetch the 5 bytes to protected-mode memory
first. In your case, _dosmemget seems to be the best method.
- Raw text -