Ozkan Sezer (sezeroz@gmail.com) [via djgpp@delorie.com]
2024-02-23 21:11:46 UTC
Hi everyone:
Does the following DJGPP port of SBEMU detection look correct?
It is an adaptation from a WatcomC (32 bit flat) code in here:
https://github.com/wbcbz7/sndlib-watcom/blob/master/sndlib.cpp#L41-L71
(I'm fairly rusty in gcc inline asm and djgpp address mapping, etc,
thanks in advance.)
int sndlib_sbemu_detect(void)
{
__dpmi_raddr addr;
uint32_t r_addr;
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;
/* scan all multiplexes of INT 2D */
for (mx = 0; mx < 256; mx++)
{
__asm__ __volatile__ ("movb %0,%%ah"::"m"(mx));
__asm__ __volatile__ (
"xorb %al, %al\n"
"int $0x2d\n"
"cmpb $0xFF, %al\n" /* is this a free multiplex? */
"jz _found\n"
"xorw %dx, %dx\n" /* it is, return NULL pointer */
"xorw %di, %di\n"
"_found:\n");
__asm__ __volatile__ ("movw %%dx,%0":"=m"(addr.segment));
__asm__ __volatile__ ("movw %%di,%0":"=m"(addr.offset16));
/* check for SBEMU application string */
r_addr = ((uint32_t)addr.segment<<4) + (uint32_t)addr.offset16;
if (!r_addr) continue;
appstring = (char *)real2ptr(r_addr);
if (memcmp(appstring + 8,"SBEMU",5) == 0)
return mx;
}
return -1;
}
P.S.: real2ptr() in there actually returns
(void *) (real += __djgpp_conventional_base)
after a successful __djgpp_nearptr_enable()
--
O.S.
Does the following DJGPP port of SBEMU detection look correct?
It is an adaptation from a WatcomC (32 bit flat) code in here:
https://github.com/wbcbz7/sndlib-watcom/blob/master/sndlib.cpp#L41-L71
(I'm fairly rusty in gcc inline asm and djgpp address mapping, etc,
thanks in advance.)
int sndlib_sbemu_detect(void)
{
__dpmi_raddr addr;
uint32_t r_addr;
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;
/* scan all multiplexes of INT 2D */
for (mx = 0; mx < 256; mx++)
{
__asm__ __volatile__ ("movb %0,%%ah"::"m"(mx));
__asm__ __volatile__ (
"xorb %al, %al\n"
"int $0x2d\n"
"cmpb $0xFF, %al\n" /* is this a free multiplex? */
"jz _found\n"
"xorw %dx, %dx\n" /* it is, return NULL pointer */
"xorw %di, %di\n"
"_found:\n");
__asm__ __volatile__ ("movw %%dx,%0":"=m"(addr.segment));
__asm__ __volatile__ ("movw %%di,%0":"=m"(addr.offset16));
/* check for SBEMU application string */
r_addr = ((uint32_t)addr.segment<<4) + (uint32_t)addr.offset16;
if (!r_addr) continue;
appstring = (char *)real2ptr(r_addr);
if (memcmp(appstring + 8,"SBEMU",5) == 0)
return mx;
}
return -1;
}
P.S.: real2ptr() in there actually returns
(void *) (real += __djgpp_conventional_base)
after a successful __djgpp_nearptr_enable()
--
O.S.